source: trunk/src/wsock32/wsock32.cpp@ 77

Last change on this file since 77 was 51, checked in by sandervl, 26 years ago

* empty log message *

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