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

Last change on this file since 4 was 4, checked in by ktk, 26 years ago

Import

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