source: trunk/src/wsock32/wsock32.c@ 11

Last change on this file since 11 was 11, checked in by phaller, 26 years ago

Added support for TCP/IP 4.1 + 4.2 headers, cleaned up linker definition file

File size: 27.9 KB
Line 
1/* $Id: wsock32.c,v 1.2 1999-05-31 14:09:47 phaller Exp $ */
2
3/*
4 *
5 * Project Odin Software License can be found in LICENSE.TXT
6 *
7 */
8/*
9 * Win32 SOCK32 for OS/2
10 *
11 * 1998/08/25 Vince Vielhaber
12 *
13 * @(#) wsock32.c 1.0.0 1998/08/25 VV initial release
14 * 1.0.1 1999/04/27 VV cleanup and implement select.
15 * 1.0.2 1999/05/31 PH support for TCP/IP 4.1 + 4.2 headers
16 *
17 */
18
19/* this is for IBM TCP/IP 5.0 headers as present in the current Warp 4 toolkit */
20#define TCPV40HDRS 1
21
22
23#define INCL_DOSPROCESS /* Process and thread values */
24#define INCL_DOSFILEMGR /* for DosRead and DosWrite */
25#define INCL_DOSQUEUES /* for unnamed pipes */
26#define INCL_DOSERRORS /* DOS error values */
27#define INCL_WINMESSAGEMGR /* Window Message Functions */
28#define INCL_WINMENUS /* Window Menu Functions */
29
30#define VV_BSD_SELECT /* undefine this if it interferes with other routines */
31
32#ifdef VV_BSD_SELECT
33# define BSD_SELECT
34#endif
35
36#include <os2.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <stddef.h>
40#include <string.h>
41#include <ctype.h>
42#include <types.h>
43#include <netdb.h>
44#include <sys/socket.h>
45#include <sys/ioctl.h>
46#include <netinet/in.h>
47
48#ifdef VV_BSD_SELECT
49# include <sys/select.h>
50#endif
51
52#include <sys/time.h>
53#include <win32type.h>
54#include "wsock32.h"
55#include "misc.h"
56
57
58#define FAR
59//#define WIN32API APIENTRY
60
61static WHOSTENT whsnt;
62static WSERVENT wsvnt;
63static WPROTOENT wptnt;
64
65 /*+-------------------------------------------------------------------+*/
66 /*| _CRT_init is the C run-time environment initialization function. |*/
67 /*|It will return 0 to indicate success and -1 to indicate failure. |*/
68 /*+-------------------------------------------------------------------+*/
69
70int _CRT_init (void);
71
72 /*+-------------------------------------------------------------------+*/
73 /*| _CRT_term is the C run-time environment termination function. |*/
74 /*+-------------------------------------------------------------------+*/
75
76void _CRT_term (unsigned long);
77
78void _System AsyncLoop(ULONG);
79void CheckThreads(AsyncStatus *);
80void NotifyApp(int,AsyncStatus *);
81int Notify(AsyncStatus *,int);
82
83int NotifyWSA(HWND hw,u_int msg,UINT wp,LONG lp);
84
85void _System WSAFunct(ULONG); // for the wsa database calls
86void SetErrForDatabaseCalls(void);
87
88
89size_t nSize;
90int *pArray;
91
92int MsgSent;
93int LocalErrorNumber = 0;
94
95
96TID tidAsyncLoop = 0; /* ID of AsyncSelect (AsyncLoop) thread */
97
98/*
99
100
101typedef struct AsyncStatus {
102 HWND hwnd; // owner's hwindow
103 u_int msg; // message to send when event occurs
104 long event; // event that may occur
105 SOCKET socket; // the socket
106 int status; // blocking yes/no
107 TID threadID; // Thread ID for async
108 int MsgStat; // has message been sent yet?
109 struct AsyncStatus *Next; // pointer to next AsyncStatus in the list
110 struct AsyncStatus *Prev; // pointer to previous AsyncStatus in the list
111} AsyncStatus;
112
113
114
115*/
116
117AsyncStatus *TopASY = 0;
118
119
120#define BLOCKING 0
121#define NONBLOCKING 1
122
123
124
125typedef struct WSAStruct {
126 int CallingWhat;
127 HWND hw;
128 u_int msg;
129 char *carg1;
130 char *carg2;
131 int iarg1;
132 int iarg2;
133 char *buf;
134 int buflen;
135} WSAStruct;
136
137
138#define GETSERVBYNAME 1
139#define GETSERVBYPORT 2
140#define GETPROTOBYNAME 3
141#define GETPROTOBYNUMBER 4
142#define GETHOSTBYNAME 5
143#define GETHOSTBYADDR 6
144
145
146
147
148typedef struct PipeStruct {
149 AsyncStatus as;
150 int MsgLoop;
151 HFILE rcv;
152 HFILE snd;
153} PipeStruct;
154
155PipeStruct PS;
156
157
158
159#ifdef FD_CLR
160#undef FD_CLR
161#define FD_CLR(x,y) WFD_CLR(x,y)
162#undef FD_SET
163#define FD_SET(x,y) WFD_SET(x,y)
164#undef FD_ZERO
165#define FD_ZERO(x) WFD_ZERO(x)
166#undef FD_ISSET
167#define FD_ISSET(x,y) WFD_SET(x,y)
168#endif
169
170
171
172
173
174
175int WIN32API OS2__WSAFDIsSet(SOCKET fd, Wfd_set FAR *set)
176{
177int i = set->fd_count;
178
179#ifdef DEBUG
180 WriteLog("WSOCK32: __WSAFDIsSet\n");
181#endif
182
183 while (i--)
184 if (set->fd_array[i] == fd)
185 return 1;
186
187return 0;
188}
189
190
191
192AsyncStatus * FindASY(SOCKET s)
193{
194AsyncStatus *as;
195
196 for(as = TopASY; as; as = as->Next)
197 if(as->socket == s)
198 return as;
199
200return 0;
201}
202
203
204
205SOCKET WIN32API OS2accept (SOCKET s, struct sockaddr *addr,
206 int *addrlen) {
207#ifdef DEBUG
208 WriteLog("WSOCK32: accept\n");
209#endif
210
211 return accept(s,addr,addrlen);
212}
213
214int WIN32API OS2bind (SOCKET s, const struct sockaddr *addr, int namelen)
215{
216 int rc;
217
218#ifdef DEBUG
219 WriteLog("WSOCK32: bind\n");
220#endif
221
222 rc = bind(s,(struct sockaddr *)addr,namelen);
223 dprintf(("bind returned %X\n", rc));
224 return(rc);
225}
226
227int WIN32API OS2closesocket (SOCKET s)
228{
229AsyncStatus *as;
230#ifdef DEBUG
231 WriteLog("WSOCK32: closesocket\n");
232#endif
233
234 as = FindASY(s);
235 if(as == NULL) {
236 LocalErrorNumber = 10038;
237 return -1;
238 }
239
240 CheckThreads(as);
241
242#ifdef DEBUG
243 WriteLog("WSOCK32: closesocket\n");
244#endif
245 if(as->Prev && as->Next)
246 as->Prev->Prev = as->Next->Next; // I SURE HOPE THIS IS RIGHT!!!!!!!!
247 free(as);
248
249 return soclose((int)s);
250}
251
252int WIN32API OS2connect (SOCKET s, const struct sockaddr *name, int namelen)
253{
254#ifdef DEBUG
255//char message[512];
256//struct Wsockaddr_in *xname;
257
258 WriteLog("WSOCK32: connect\n");
259
260
261#endif
262
263 return connect(s,(struct sockaddr *)name,namelen);
264}
265
266int WIN32API OS2ioctlsocket (SOCKET s, long cmd, u_long *argp)
267{
268 int rc;
269
270#ifdef DEBUG
271 WriteLog("WSOCK32: ioctlsocket unimplemented\n");
272#endif
273
274 rc = ioctl(s, cmd, argp, 4);
275 dprintf(("ioctl returned %X\n", rc));
276 return(rc);
277}
278
279int WIN32API OS2getpeername (SOCKET s, struct sockaddr *name,
280 int * namelen)
281{
282#ifdef DEBUG
283 WriteLog("WSOCK32: getpeername\n");
284#endif
285
286 return getpeername(s,name,namelen);
287}
288
289int WIN32API OS2getsockname (SOCKET s, struct sockaddr *name,
290 int * namelen)
291{
292#ifdef DEBUG
293 WriteLog("WSOCK32: getsockname\n");
294#endif
295
296 return getsockname(s,name,namelen);
297}
298
299int WIN32API OS2getsockopt (SOCKET s, int level, int optname,
300 char * optval, int *optlen)
301{
302#ifdef DEBUG
303 WriteLog("WSOCK32: getsockopt\n");
304#endif
305
306 return getsockopt(s,level,optname,optval,optlen);
307}
308
309u_long WIN32API OS2htonl (u_long hostlong)
310{
311#ifdef DEBUG
312 WriteLog("WSOCK32: htonl\n");
313#endif
314
315 return htonl(hostlong);
316}
317
318u_short WIN32API OS2htons (u_short hostshort)
319{
320#ifdef DEBUG
321 WriteLog("WSOCK32: htons\n");
322#endif
323
324 return htons(hostshort);
325}
326
327unsigned long WIN32API OS2inet_addr (const char * cp)
328{
329#ifdef DEBUG
330 WriteLog("WSOCK32: inet_addr\n");
331#endif
332
333 return inet_addr(cp);
334}
335
336char * WIN32API OS2inet_ntoa (struct in_addr in)
337{
338#ifdef DEBUG
339 WriteLog("WSOCK32: inet_ntoa\n");
340#endif
341
342 return inet_ntoa(in);
343}
344
345int WIN32API OS2listen (SOCKET s, int backlog)
346{
347#ifdef DEBUG
348 WriteLog("WSOCK32: listen\n");
349#endif
350
351 return listen(s,backlog);
352}
353
354u_long WIN32API OS2ntohl (u_long netlong)
355{
356#ifdef DEBUG
357 WriteLog("WSOCK32: ntohl\n");
358#endif
359
360 return ntohl(netlong);
361}
362
363u_short WIN32API OS2ntohs (u_short netshort)
364{
365#ifdef DEBUG
366 WriteLog("WSOCK32: ntohs\n");
367#endif
368
369 return ntohs(netshort);
370}
371
372int WIN32API OS2recv (SOCKET s, char * buf, int len, int flags)
373{
374unsigned long ii;
375int xx,yy;
376char buff[200];
377AsyncStatus *as;
378#ifdef DEBUG
379 WriteLog("WSOCK32: recv socket: %u\n",(unsigned int)s);
380 WriteLog("WSOCK32: recv len: %d\n",len);
381 WriteLog("WSOCK32: recv flags: %d\n",flags);
382
383#endif
384
385 PS.MsgLoop = 0;
386
387 as = FindASY(s);
388
389 if(as != NULL) as->MsgStat = 2;
390
391
392 xx = recv(s,buf,len,flags);
393
394return xx;
395}
396
397
398
399int WIN32API OS2recvfrom (SOCKET s, char * buf, int len, int flags,
400 struct sockaddr *from, int * fromlen)
401{
402 int rc;
403
404#ifdef DEBUG
405 WriteLog("WSOCK32: recvfrom\n");
406#endif
407
408 rc = recvfrom(s,buf,len,flags,from,fromlen);
409 dprintf(("recvfrom returned %X\n", rc));
410 return(rc);
411}
412
413
414
415#ifdef VV_BSD_SELECT
416
417
418int WIN32API OS2select (int nfds, Wfd_set *readfds, Wfd_set *writefds,
419 Wfd_set *exceptfds, const struct Wtimeval *timeout)
420{
421#ifdef DEBUG
422 WriteLog("WSOCK32: select\n");
423#endif
424
425
426 return select(nfds,readfds,writefds,exceptfds,timeout);
427
428}
429
430
431
432#else
433
434
435int WIN32API OS2select (int nfds, Wfd_set *readfds, Wfd_set *writefds,
436 Wfd_set *exceptfds, const struct Wtimeval *timeout)
437{
438#ifdef DEBUG
439 WriteLog("WSOCK32: select\n");
440#endif
441
442 // NEED TO DO THIS ONE!!!!!
443
444 return 0;
445}
446#endif
447
448
449
450int WIN32API OS2send (SOCKET s, const char * buf, int len, int flags)
451{
452#ifdef DEBUG
453 WriteLog("WSOCK32: send socket: %u\n",(unsigned int)s);
454// WriteLog("WSOCK32: send buf: %s\n",buf);
455 WriteLog("WSOCK32: send len: %d\n",len);
456 WriteLog("WSOCK32: send flags: %d\n",flags);
457#endif
458
459 return send(s,buf,len,flags);
460}
461
462int WIN32API OS2sendto (SOCKET s, const char * buf, int len, int flags,
463 const struct sockaddr *to, int tolen)
464{
465 int rc;
466
467#ifdef DEBUG
468 WriteLog("WSOCK32: sendto\n");
469#endif
470
471 rc = sendto(s,buf,len,flags,to,tolen);
472 dprintf(("sendto returned %X\n", rc));
473 return(rc);
474}
475
476int WIN32API OS2setsockopt (SOCKET s, int level, int optname,
477 const char * optval, int optlen)
478{
479struct Wlinger *yy;
480struct linger xx;
481
482#ifdef DEBUG
483 WriteLog("WSOCK32: setsockopt\n");
484#endif
485
486 if(level == SOL_SOCKET && optname == SO_LINGER) {
487 yy = (struct Wlinger *)optval;
488 xx.l_onoff = (int)yy->l_onoff;
489 xx.l_linger = (int)yy->l_linger;
490
491 return setsockopt(s,level,optname,(const char *)&xx,optlen);
492 }
493
494 else return setsockopt(s,level,optname,optval,optlen);
495
496}
497
498int WIN32API OS2shutdown (SOCKET s, int how)
499{
500#ifdef DEBUG
501 WriteLog("WSOCK32: shutdown\n");
502#endif
503
504 return shutdown(s,how);
505}
506
507SOCKET WIN32API OS2socket (int af, int type, int protocol)
508{
509SOCKET s;
510AsyncStatus *as;
511#ifdef DEBUG
512 WriteLog("WSOCK32: socket\n");
513#endif
514
515 s = (SOCKET)socket(af,type,protocol);
516
517 if(s > 0) {
518 as = (AsyncStatus *)malloc(sizeof(AsyncStatus));
519 if(as != NULL) {
520 as->hwnd = (HWND)0;
521 as->msg = 0;
522 as->event = 0L;
523 as->socket = s;
524 as->status = BLOCKING;
525 as->threadID = 0;
526 as->MsgStat = 0;
527 as->Next = TopASY;
528 as->Prev = NULL;
529 if(TopASY) TopASY->Prev = as;
530 TopASY = as;
531 } else {
532 soclose(s);
533 return -1;
534 }
535 }
536 dprintf(("WSOCK32: socket returned %X\n", s));
537
538return s;
539}
540
541/* Database function prototypes */
542
543
544void SetErrForDatabaseCalls(void)
545{
546
547 switch(h_errno) {
548 case 1:
549 OS2WSASetLastError(11001); // host not found
550 break;
551 case 2:
552 OS2WSASetLastError(11002); // try again later
553 break;
554 case 3:
555 OS2WSASetLastError(11003); // No recovery
556 break;
557 case 4:
558 OS2WSASetLastError(11004); // No address or no data
559 break;
560 default:
561 OS2WSASetLastError(0); // unknown error and should never get here
562#ifdef DEBUG
563WriteLog("WSOCK32: Unknown error condition: %d\n",h_errno);
564#endif
565 break;
566 }
567
568return;
569}
570
571
572
573
574WHOSTENT * WIN32API OS2gethostbyaddr(const char * addr,
575 int len, int type)
576{
577WHOSTENT *yy;
578struct hostent *xx;
579#ifdef DEBUG
580 WriteLog("WSOCK32: gethostbyaddr\n");
581#endif
582
583 xx = gethostbyaddr(addr,len,type);
584
585 if(xx == NULL) {
586 SetErrForDatabaseCalls();
587 return (WHOSTENT *)NULL;
588 }
589
590 whsnt.h_name = xx->h_name;
591 whsnt.h_aliases = xx->h_aliases;
592 whsnt.h_addrtype = (short)xx->h_addrtype;
593 whsnt.h_length = (short)xx->h_length;
594 whsnt.h_addr_list = xx->h_addr_list;
595
596return &whsnt;
597}
598
599
600
601
602WHOSTENT * WIN32API OS2gethostbyname(const char * name)
603{
604WHOSTENT *yy;
605struct hostent *xx;
606#ifdef DEBUG
607 WriteLog("WSOCK32: gethostbyname: %s\n",name);
608#endif
609
610 xx = gethostbyname(name);
611
612 if(xx == NULL) {
613 SetErrForDatabaseCalls();
614 return (WHOSTENT *)NULL;
615 }
616
617 whsnt.h_name = xx->h_name;
618 whsnt.h_aliases = xx->h_aliases;
619 whsnt.h_addrtype = (short)xx->h_addrtype;
620 whsnt.h_length = (short)xx->h_length;
621 whsnt.h_addr_list = xx->h_addr_list;
622
623return &whsnt;
624}
625
626
627
628
629
630
631int WIN32API _OS2gethostname (char * name, int namelen)
632{
633#ifdef DEBUG
634 WriteLog("WSOCK32: _gethostname\n");
635#endif
636
637 return gethostname(name,namelen);
638}
639
640
641
642int WIN32API OS2gethostname (char * name, int namelen)
643{
644#ifdef DEBUG
645 WriteLog("WSOCK32: gethostname\n");
646#endif
647
648 return gethostname(name,namelen);
649}
650
651WSERVENT * WIN32API OS2getservbyport(int port, const char * proto)
652{
653struct servent *xx;
654#ifdef DEBUG
655 WriteLog("WSOCK32: getservbyport\n");
656#endif
657
658 xx = getservbyport(port,proto);
659
660 if(xx == NULL) { // this call doesn't generate an error message
661 return (WHOSTENT *)NULL;
662 }
663
664 wsvnt.s_name = xx->s_name;
665 wsvnt.s_aliases = xx->s_aliases;
666 wsvnt.s_port = (short)xx->s_port;
667 wsvnt.s_proto = xx->s_proto;
668
669return &wsvnt;
670}
671
672WSERVENT * WIN32API OS2getservbyname(const char * name,
673 const char * proto)
674{
675WSERVENT *yy;
676struct servent *xx;
677#ifdef DEBUG
678 WriteLog("WSOCK32: getservbyname\n");
679#endif
680
681 xx = getservbyname(name,proto);
682
683 if(xx == NULL) { // this call doesn't generate an error message
684 return (WHOSTENT *)NULL;
685 }
686
687 wsvnt.s_name = xx->s_name;
688 wsvnt.s_aliases = xx->s_aliases;
689 wsvnt.s_port = (short)xx->s_port;
690 wsvnt.s_proto = xx->s_proto;
691
692return &wsvnt;
693}
694
695WPROTOENT * WIN32API OS2getprotobynumber(int proto)
696{
697struct protoent *xx;
698#ifdef DEBUG
699 WriteLog("WSOCK32: getprotobynumber\n");
700#endif
701
702 xx = getprotobynumber(proto);
703
704 if(xx == NULL) { // this call doesn't generate an error message
705 return (WHOSTENT *)NULL;
706 }
707
708 wptnt.p_name = xx->p_name;
709 wptnt.p_aliases = xx->p_aliases;
710 wptnt.p_proto = (short)xx->p_proto;
711
712return &wptnt;
713}
714
715WPROTOENT * WIN32API OS2getprotobyname(const char * name)
716{
717struct protoent *xx;
718#ifdef DEBUG
719 WriteLog("WSOCK32: getprotobyname\n");
720#endif
721
722 xx = getprotobyname(name);
723
724 if(xx == NULL) { // this call doesn't generate an error message
725 return (WHOSTENT *)NULL;
726 }
727
728 wptnt.p_name = xx->p_name;
729 wptnt.p_aliases = xx->p_aliases;
730 wptnt.p_proto = (short)xx->p_proto;
731
732return &wptnt;
733}
734
735
736
737
738int WIN32API OS2WSAStartup(USHORT wVersionRequired, LPWSADATA lpWsaData)
739{
740APIRET rc;
741int ii;
742#ifdef DEBUG
743 WriteLog("WSOCK32: WSAStartup\n");
744#endif
745 /* Make sure that the version requested is >= 1.1. */
746 /* The low byte is the major version and the high */
747 /* byte is the minor version. */
748
749 if ( LOBYTE( wVersionRequired ) < 1 ||
750 ( LOBYTE( wVersionRequired ) == 1 &&
751 HIBYTE( wVersionRequired ) < 1 )) {
752 return WSAVERNOTSUPPORTED;
753 }
754
755 /* Since we only support 1.1, set both wVersion and */
756 /* wHighVersion to 1.1. */
757
758 lpWsaData->wVersion = MAKEWORD( 1, 1 );
759 lpWsaData->wHighVersion = MAKEWORD( 1, 1 );
760 strcpy(lpWsaData->szDescription,"Win32OS2 WSOCK32.DLL Ver. 1.1");
761 lpWsaData->iMaxUdpDg = 32767;
762 lpWsaData->iMaxSockets = 2048;
763 strcpy(lpWsaData->szSystemStatus,"No Status");
764
765 LocalErrorNumber = 0;
766
767 if(sock_init() == 0) {
768#ifdef DEBUG
769 WriteLog("WSOCK32: WSAStartup sock_init returned 0\n");
770#endif
771 return 0;
772 }
773 else ii = sock_errno();
774#ifdef DEBUG
775 WriteLog("WSOCK32: WSAStartup exiting: %d\n",ii);
776#endif
777return ii;
778}
779
780
781
782
783
784
785int WIN32API OS2WSACleanup(void)
786{
787#ifdef DEBUG
788 WriteLog("WSOCK32: WSACleanup\n");
789#endif
790
791 CheckThreads((AsyncStatus *)NULL);
792
793 return 0;
794}
795
796void WIN32API OS2WSASetLastError(int iError)
797{
798#ifdef DEBUG
799 WriteLog("WSOCK32: WSASetLastError(%d)\n",iError);
800#endif
801
802 LocalErrorNumber = iError;
803
804 return;
805}
806
807int WIN32API OS2WSAGetLastError(void)
808{
809int ii;
810#ifdef DEBUG
811 WriteLog("WSOCK32: WSAGetLastError\n");
812#endif
813
814 if(LocalErrorNumber == 0) {
815 ii = sock_errno(); // WSAGetLastError();
816#ifdef DEBUG
817 WriteLog("WSOCK32: WSAGetLastError: %d\n",ii);
818#endif
819 return ii;
820 }
821 else {
822#ifdef DEBUG
823 WriteLog("WSOCK32: WSAGetLastError: %d\n",LocalErrorNumber);
824#endif
825 return LocalErrorNumber;
826 }
827}
828
829BOOL WIN32API OS2WSAIsBlocking(void)
830{
831#ifdef DEBUG
832 WriteLog("WSOCK32: WSAIsBlocking unimplemented\n");
833#endif
834
835 return -5000; //WSAIsBlocking();
836}
837
838int WIN32API OS2WSAUnhookBlockingHook(void)
839{
840#ifdef DEBUG
841 WriteLog("WSOCK32: WSAUnhookBlockingHook unimplemented\n");
842#endif
843
844 return -5000; //WSAUnhookBlockingHook();
845}
846
847FARPROC WIN32API OS2WSASetBlockingHook(FARPROC lpBlockFunc)
848{
849#ifdef DEBUG
850 WriteLog("WSOCK32: WSASetBlockingHook Unimplemented\n");
851#endif
852
853 return (FARPROC)NULL;
854}
855
856int WIN32API OS2WSACancelBlockingCall(void)
857{
858#ifdef DEBUG
859 WriteLog("WSOCK32: WSACancelBlockingCall unimplemented\n");
860#endif
861
862 return -5000; //WSACancelBlockingCall();
863}
864
865
866
867
868
869// The following 6 calls need to start a new thread, perform
870// the operation, copy ALL the info to the buffer provided then
871// notify the sender.
872
873
874LHANDLE WIN32API OS2WSAAsyncGetServByName(HWND hWnd, u_int wMsg,
875 const char * name,
876 const char * proto,
877 char * buf, int buflen)
878{
879WSAStruct *wsa;
880PFNTHREAD pfnAsyncThread = &WSAFunct; /* Address of thread program */
881ULONG ulThreadParm = 100; /* Parameter to thread routine */
882APIRET rc = NO_ERROR; /* Return code */
883TID tid;
884
885
886OS2WSASetLastError(WSAEWOULDBLOCK);
887return 0;
888
889#ifdef DEBUG
890WriteLog("WSOCK32: WSAAsyncGetServByName. name: %s, proto: %s \n",name,proto);
891#endif
892
893 wsa = (WSAStruct *)malloc(sizeof(WSAStruct));
894 if(wsa == NULL) {
895 OS2WSASetLastError(WSAEWOULDBLOCK);
896 return 0;
897 }
898
899 wsa->CallingWhat = GETSERVBYNAME;
900 wsa->hw = hWnd;
901 wsa->msg = wMsg;
902 wsa->carg1 = strdup(name);
903 wsa->carg2 = strdup(proto);
904 wsa->buf = buf;
905 wsa->buflen = buflen;
906
907 ulThreadParm = (ULONG)wsa;
908
909 rc = DosCreateThread(&tid, /* Thread ID (returned by function) */
910 pfnAsyncThread, /* Address of thread program */
911 ulThreadParm, /* Parameter passed to ThreadProc */
912 CREATE_READY | /* Thread is ready when created */
913 STACK_SPARSE, /* Do not pre-commit stack pages */
914 8192L); /* Stack size, rounded to page bdy */
915 if (rc != NO_ERROR) {
916#ifdef DEBUG
917 WriteLog("WSOCK32: DosCreateThread error in WSAAsyncGetServByName: return code = %u\n", rc);
918#endif
919 OS2WSASetLastError(rc);
920 free(wsa);
921 return 0;
922 }
923
924#ifdef DEBUG
925 WriteLog("WSOCK32 THREAD: DosCreateThread's tid: %lu, ThreadParm = %p\n",(unsigned long)tid,ulThreadParm);
926 WriteLog("WSOCK32 THREAD: hwnd: %p\n",wsa->hw);
927#endif
928
929 return (LHANDLE)tid; //WSAAsyncGetServByName(hWnd,wMsg,name,proto,buf,buflen);
930}
931
932LHANDLE WIN32API OS2WSAAsyncGetServByPort(HWND hWnd, u_int wMsg, int port,
933 const char * proto, char * buf,
934 int buflen)
935{
936#ifdef DEBUG
937 WriteLog("WSOCK32: WSAAsyncGetServByPort unimplemented\n");
938#endif
939
940 return -5000; //WSAAsyncGetServByPort(hWnd,wMsg,port,proto,buf,buflen);
941}
942
943LHANDLE WIN32API OS2WSAAsyncGetProtoByName(HWND hWnd, u_int wMsg,
944 const char * name, char * buf,
945 int buflen)
946{
947#ifdef DEBUG
948 WriteLog("WSOCK32: WSAAsyncGetProtoByName unimplemented\n");
949#endif
950
951 return -5000; //WSAAsyncGetProtoByName(hWnd,wMsg,name,buf,buflen);
952}
953
954LHANDLE WIN32API OS2WSAAsyncGetProtoByNumber(HWND hWnd, u_int wMsg,
955 int number, char * buf,
956 int buflen)
957{
958#ifdef DEBUG
959 WriteLog("WSOCK32: WSAAsyncGetProtoByNumber unimplemented\n");
960#endif
961
962 return -5000; //WSAAsyncGetProtoByNumber(hWnd,wMsg,number,buf,buflen);
963}
964
965LHANDLE WIN32API OS2WSAAsyncGetHostByName(HWND hWnd, u_int wMsg,
966 const char * name, char * buf,
967 int buflen)
968{
969#ifdef DEBUG
970 WriteLog("WSOCK32: WSAAsyncGetHostByName unimplemented\n");
971#endif
972
973 return -5000; //WSAAsyncGetHostByName(hWnd,wMsg,name,buf,buflen);
974}
975
976LHANDLE WIN32API OS2WSAAsyncGetHostByAddr(HWND hWnd, u_int wMsg,
977 const char * addr, int len, int type,
978 char * buf, int buflen)
979{
980#ifdef DEBUG
981 WriteLog("WSOCK32: WSAAsyncGetHostByAddr unimplemented\n");
982#endif
983
984
985
986
987
988 return -5000; //WSAAsyncGetHostByAddr(hWnd,wMsg,addr,len,type,buf,buflen);
989}
990
991
992
993
994
995
996
997int WIN32API OS2WSACancelAsyncRequest(LHANDLE hAsyncTaskHandle)
998{
999TID tid;
1000APIRET rc;
1001#ifdef DEBUG
1002 WriteLog("WSOCK32: WSACancelAsyncRequest unimplemented\n");
1003#endif
1004
1005 rc = 0;
1006
1007 tid = (LHANDLE)hAsyncTaskHandle;
1008
1009 if(tid == 0) rc = WSAEINVAL;
1010
1011 if(!rc) rc = DosKillThread(tid);
1012
1013 switch(rc) {
1014 case 0: // SUCCESS!!
1015 return 0;
1016 case 170:
1017 rc = WSAEINPROGRESS;
1018 break;
1019 case 309:
1020 rc = WSAEINVAL;
1021 break;
1022 default:
1023 rc = -5000;
1024 break;
1025 } // end switch
1026
1027 OS2WSASetLastError(rc);
1028 return SOCKET_ERROR; // ERROR!
1029}
1030
1031
1032
1033
1034
1035int WIN32API OS2WSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg,
1036 long lEvent)
1037{
1038PFNTHREAD pfnAsyncThread = &AsyncLoop; /* Address of thread program */
1039ULONG ulThreadParm = 100; /* Parameter to thread routine */
1040APIRET rc = NO_ERROR; /* Return code */
1041unsigned long ii;
1042AsyncStatus *as;
1043#ifdef DEBUG
1044char buf[150];
1045sprintf(buf,"WSOCK32: WSAAsyncSelect\n Message: %x\n Event: %ld\n hwindow: %x\n",
1046 wMsg,lEvent,(HWND)hWnd);
1047 WriteLog(buf);
1048#endif
1049
1050 as = FindASY(s);
1051
1052 if(as == NULL) return 0;
1053
1054 CheckThreads(as);
1055
1056 as->hwnd = hWnd;
1057 as->msg = wMsg;
1058 as->event = lEvent;
1059
1060 ulThreadParm = (ULONG)as;
1061
1062 rc = DosCreateThread(&(as->threadID), /* Thread ID (returned by function) */
1063 pfnAsyncThread, /* Address of thread program */
1064 ulThreadParm, /* Parameter passed to ThreadProc */
1065 CREATE_READY | /* Thread is ready when created */
1066 STACK_SPARSE, /* Do not pre-commit stack pages */
1067 8192L); /* Stack size, rounded to page bdy */
1068 if (rc != NO_ERROR) {
1069#ifdef DEBUG
1070 WriteLog("WSOCK32: DosCreateThread error: return code = %u\n", rc);
1071#endif
1072 OS2WSASetLastError(rc);
1073 return 0;
1074 }
1075
1076 return 1; //WSAAsyncSelect(s,hWnd,wMsg,lEvent);
1077}
1078
1079
1080
1081void _System AsyncLoop(ULONG ASP)
1082{
1083int socks[1],r,w,e,rc,ii;
1084AsyncStatus *as;
1085
1086 as = (AsyncStatus *)ASP;
1087
1088 r = w = e = 0;
1089 if(as->event & FD_READ) r = 1;
1090 if(as->event & FD_WRITE) w = 1;
1091 if(as->event & FD_OOB) e = 1;
1092
1093 socks[0] = (int)as->socket;
1094
1095 if((r+w+e) == 0) {
1096#ifdef DEBUG
1097 WriteLog("WSOCK32: Turning off async\n");
1098#endif
1099 ii = 0;
1100 rc = ioctl(socks[0],FIONBIO,(char *)&ii,sizeof(ii));
1101 as->threadID = 0;
1102 as->hwnd = 0;
1103 as->msg = 0;
1104 as->event = 0;
1105 as->status = BLOCKING;
1106 return;
1107 } // end if
1108 else
1109 {
1110#ifdef DEBUG
1111 WriteLog("WSOCK32: Setting up non-blocking sockets\n");
1112#endif
1113 ii = 1;
1114 rc = ioctl(socks[0],FIONBIO,(char *)&ii,sizeof(ii));
1115 if(rc != 0) {
1116#ifdef DEBUG
1117 WriteLog("WSOCK32: ioctl failed trying to non-block.\n");
1118#endif
1119 return;
1120 }
1121 as->status = NONBLOCKING;
1122 } // end else
1123
1124 do {
1125 rc = select(socks,r,0,0,0); // ioctl may be better for this.
1126 if(rc > 0) {
1127 rc = ioctl(socks[0],FIONREAD,(char *)&ii,sizeof(ii));
1128 if(rc == 0 && ii > 0) {
1129 /* data is ready */
1130 NotifyApp(FD_READ,as);
1131//#ifdef DEBUG
1132// WriteLog("WSOCK32: Data Waiting\n");
1133//#endif
1134 }
1135 }
1136 if(rc < 0) {
1137 rc = sock_errno();
1138 /* something ain't right */
1139 if(rc == 10038) { // Connection closed
1140 NotifyApp(FD_CLOSE,as);
1141 DosSleep(500);
1142 return;
1143 }
1144#ifdef DEBUG
1145 WriteLog("WSOCK32: Select error: %d\n",rc);
1146#endif
1147 } // end if
1148 DosSleep(50);
1149 } while(1);
1150
1151return;
1152}
1153
1154
1155
1156void CheckThreads(AsyncStatus *as)
1157{
1158AsyncStatus *asy;
1159
1160 if(as != NULL)
1161 if(as->threadID != 0) DosKillThread(as->threadID);
1162
1163 for(asy = TopASY; asy; asy = asy->Next)
1164 if(asy->threadID != 0) DosKillThread(asy->threadID);
1165
1166return;
1167}
1168
1169
1170
1171void NotifyApp(int xx,AsyncStatus *as)
1172{
1173 BOOL fResult; /* message-posted indicator */
1174 unsigned long ii;
1175
1176
1177//#ifdef DEBUG
1178// WriteLog("WSOCK32: Notifying the caller. rc = %d\n",xx);
1179//#endif
1180
1181 if(as->MsgStat == 0) {
1182 fResult = Notify(as,xx);
1183#ifdef DEBUG
1184 WriteLog("WSOCK32: Notify returns: %d\n",fResult);
1185#endif
1186 } // end if
1187
1188 if(as->MsgStat == 2) as->MsgStat = 0;
1189 else as->MsgStat = 1;
1190
1191return;
1192}
1193
1194
1195
1196void _System WSAFunct(ULONG xx)
1197{
1198WSAStruct *wsa;
1199WSERVENT *ooo;
1200char *yy;
1201int ii;
1202size_t ss;
1203UINT wp;
1204LONG lp;
1205int id = *_threadid;
1206
1207 wsa = (WSAStruct *)xx;
1208
1209#ifdef DEBUG
1210 WriteLog("WSOCK32: WSAFunct: xx = %p, hwnd = %p\n",xx,wsa->hw);
1211 WriteLog("WSOCK32: WSAFunct info carg1 = %s, carg2 = %s\n",wsa->carg1,wsa->carg2);
1212 WriteLog("WSOCK32: WSAFunct info buf = %p, %d\n",wsa->buf,wsa->buflen);
1213#endif
1214
1215 switch (wsa->CallingWhat) {
1216 case GETSERVBYNAME:
1217 yy = (char *)OS2getservbyname(wsa->carg1,wsa->carg2);
1218 ss = sizeof(WSERVENT);
1219 break;
1220 case GETSERVBYPORT:
1221 yy = (char *)OS2getservbyport(wsa->iarg1,wsa->carg1);
1222 break;
1223 case GETPROTOBYNUMBER:
1224 yy = (char *)OS2getprotobynumber(wsa->iarg1);
1225 break;
1226 case GETPROTOBYNAME:
1227 yy = (char *)OS2getprotobyname(wsa->carg1);
1228 break;
1229 case GETHOSTBYNAME:
1230 yy = (char *)OS2gethostbyname(wsa->carg1);
1231 break;
1232 case GETHOSTBYADDR:
1233 yy = (char *)OS2gethostbyaddr(wsa->carg1,wsa->iarg1,wsa->iarg2);
1234 break;
1235 default:
1236 yy = (char *)NULL;
1237 OS2WSASetLastError(-5000);
1238 break;
1239 } // end switch
1240
1241#ifdef DEBUG
1242 WriteLog("WSOCK32: THREAD id = %lu\n",(unsigned long)id);
1243 if(yy) {
1244 ooo = (WSERVENT *)yy;
1245 WriteLog("WSOCK32: WSAFunct service name = %s\n",ooo->s_name);
1246 WriteLog("WSOCK32: WSAFunct service port = %d\n",(int)ooo->s_port);
1247 }
1248#endif
1249
1250 wp = id;
1251
1252 if(yy == (char *)NULL) {
1253#ifdef DEBUG
1254 WriteLog("WSOCK32: WSAFunct error\n");
1255 WriteLog("WSOCK32: WSAFunct error carg1 = %s, carg2 = %s\n",wsa->carg1,wsa->carg2);
1256#endif
1257 ii = OS2WSAGetLastError();
1258 lp = OS2WSAMAKEASYNCREPLY(0,ii);
1259 } // end if
1260
1261 else {
1262 if(wsa->buflen < ss) ii = WSAENOBUFS;
1263 else ii = 0;
1264 lp = OS2WSAMAKEASYNCREPLY(ss,ii);
1265 if(ii == 0) memmove(*(wsa->buf),yy,ss);
1266 }
1267
1268#ifdef DEBUG
1269#endif
1270
1271
1272 do {
1273 if(WinQueryAnchorBlock(wsa->hw))
1274 ii = NotifyWSA(wsa->hw,wsa->msg,wp,lp);
1275 } while(ii != TRUE);
1276
1277 free(wsa);
1278
1279return;
1280}
1281
1282
1283
1284
1285
1286int WIN32API OS2WSARecvEx (SOCKET s, char FAR * buf, int len, int FAR *flags)
1287{
1288#ifdef DEBUG
1289 WriteLog("WSOCK32: WSARecvEx not implemented.\n");
1290#endif
1291
1292// return WSARecvEx(s,buf,len,flags);
1293 return 0;
1294}
1295
1296void WIN32API OS2s_perror(char *pszMessage,
1297 void *pUnknown)
1298{
1299 perror(pszMessage);
1300}
1301
1302
1303//typedef struct _TRANSMIT_FILE_BUFFERS {
1304// PVOID Head;
1305// DWORD HeadLength;
1306// PVOID Tail;
1307// DWORD TailLength;
1308//} TRANSMIT_FILE_BUFFERS, *PTRANSMIT_FILE_BUFFERS, *LPTRANSMIT_FILE_BUFFERS;
1309//
1310//BOOL WIN32API OS2TransmitFile (
1311// IN SOCKET hSocket,
1312// IN HANDLE hFile,
1313// IN DWORD nNumberOfBytesToWrite,
1314// IN DWORD nNumberOfBytesPerSend,
1315// IN LPOVERLAPPED lpOverlapped,
1316// IN LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers,
1317// IN DWORD dwReserved)
1318//{
1319// return FALSE;
1320//}
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
Note: See TracBrowser for help on using the repository browser.