1/*
2Copyright (C) 1996-1997 Id Software, Inc.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19*/
20#include <go32.h>
21#include "mpdosock.h"
22
23//#include "types.h"
24typedef unsigned char BYTE;
25typedef unsigned short WORD;
26typedef unsigned long DWORD;
27
28//#include "lpc.h"
29typedef struct {
30   short  version;            // version of LPC requested
31   short  sizeOfArgs;         // size of arguments
32   short  service;            // service # requested
33   char   Data[1];            // data
34} LPCData;
35
36typedef struct {
37   short version;             // LPC version
38   short sizeOfReturn;        // return data size
39   short error;               // any error codes
40   short noRet;               // number of returns
41   char  Data[1];             // data
42} LPCReturn;
43
44//#include "services.h"
45#define  MAXSOCKETS  20
46
47// services
48#define LPC_SOCKBIND        4
49#define LPC_SOCKGETHOSTBYNAME   5
50#define LPC_SOCKGETHOSTNAME     6
51#define LPC_SOCKGETHOSTBYADDR   7
52#define LPC_SOCKCLOSE           8
53#define LPC_SOCKSOCKET          9
54#define LPC_SOCKRECVFROM        10
55#define LPC_SOCKSENDTO          11
56#define LPC_SOCKIOCTL           12
57#define LPC_SOCKGETSOCKNAME     13
58#define LPC_SOCKFLUSH           14
59#define LPC_SOCKSETOPT          15
60#define LPC_SOCKGETLASTERROR    16
61#define LPC_SOCKINETADDR        17
62
63// htons, ntohs, htonl, ntohl implemented locally
64
65// errors
66#define LPC_UNRECOGNIZED_SERVICE  -1
67#define LPC_NOERROR                0
68
69// structures for support
70typedef struct {
71   SOCKET s;
72   int    namelen;
73   char   name[1];
74} BindArgs;
75
76typedef struct {
77   SOCKET s;
78   long   cmd;
79   char   data[1];
80} IoctlArgs;
81
82typedef struct {
83   int retVal;
84   int namelen;
85   char name[1];
86} GetSockNameRet;
87
88typedef GetSockNameRet GetHostNameRet;
89
90typedef struct {
91   int   retVal;
92   int   h_addr_0;    // that's the only important value
93} GetHostByNameRet;
94
95typedef struct {
96   int   len;
97   int   type;
98   char  addr[1];
99} GetHostByAddrArgs;
100
101typedef struct {
102   int   retVal;
103   char  h_name[1];  // h_name is the only important value
104} GetHostByAddrRet;
105
106typedef struct {
107   SOCKET s;
108   int flags;
109} RecvFromArgs;
110
111typedef struct {
112   int  retVal;
113   int  errCode;
114   int  len;   // message len
115   struct sockaddr    sockaddr;
116   int  sockaddrlen;
117   char Data[1];
118} RecvFromRet;
119
120typedef struct {
121   SOCKET s;
122   int    flags;
123   int    len;
124   struct sockaddr sockaddr;
125   int    sockaddrlen;
126   char   Data[1];
127} SendToArgs;
128
129typedef struct {
130   int   retVal;
131   int   errCode;
132} SendToRet;
133
134typedef struct {
135   int     bufflen;
136   SOCKET  s;
137   int     len;
138   int     sockaddrlen;
139   struct sockaddr    address;
140   char               data[1];
141} SocketChannelData;
142
143typedef struct {
144   int af;
145   int type;
146   int protocol;
147} SocketArgs;
148
149typedef struct {
150   SOCKET s;
151   int len;
152   int flags;
153   int addrlen;
154   struct sockaddr addr;
155   char data[1];
156} WinSockData;
157
158typedef struct {
159   SOCKET s;
160   int level;
161   int optname;
162   int optlen;
163   char optval[1];
164} SetSockOptArgs;
165
166typedef struct {
167   SOCKET   sock[MAXSOCKETS];
168} SocketMap;
169
170//#include "rtq.h"
171#define RTQ_NODE struct rtq_node
172
173RTQ_NODE
174   {
175      RTQ_NODE *self; // Ring zero address of this node
176      RTQ_NODE *left; // Ring zero address of preceding node
177      RTQ_NODE *right; // Ring zero address of succeding node
178      BYTE *      rtqDatum;  // Ring 3 Datum of Buffer (start of preface)
179      BYTE *      rtqInsert; // Ring 3 insertion position
180      WORD     rtqLen; // Length of buffer, excluding preface
181      WORD     rtqUpCtr;  // Up Counter of bytes used so far
182      WORD     rtqQCtr;   // number of nodes attached
183      WORD     padding;   // DWORD alignment
184   };
185
186#define RTQ_PARAM_MOVENODE struct rtq_param_movenode
187RTQ_PARAM_MOVENODE
188   {
189      WORD     rtqFromDQ;
190      WORD     rtqToDQ;
191   };
192
193RTQ_NODE* rtq_fetch(RTQ_NODE*, RTQ_NODE*); // To, From
194
195//#include "mplib.h"
196// give up time slice
197void Yield(void);
198void MGenWakeupDll(void);
199
200// post a message to win32 side
201void PostWindowsMessage(void);
202
203// get # of items on qNo
204int MGenGetQueueCtr(int qNo);
205
206// move first node from qFrom to qTo
207RTQ_NODE *MGenMoveTo(int qFrom, int qTo);
208
209// get first node from q
210RTQ_NODE *MGenGetNode(int q);
211
212// get master node, returning size of RTQ_NODE for size verification
213RTQ_NODE *MGenGetMasterNode(unsigned *size);
214
215// move all nodes from qFrom to qTo
216RTQ_NODE *MGenFlushNodes(int qFrom, int qTo);
217
218// count number of nodes in queues designated by bitmask
219// lowerOrderBits == 0..31, upperOrderBits == 32-63
220int MGenMCount(unsigned lowerOrderBits, unsigned upperOrderBits);
221
222// perform consistency check on chunnel address space
223int MGenSanityCheck(void);
224
225#include <stdio.h>
226#include <sys/farptr.h>
227
228extern short flat_selector;
229
230#define SOCKET_MAP_QUEUE  41
231
232#define IDLE_QUEUE    44
233#define REC_QUEUE     45
234#define SEND_QUEUE    46
235
236//  queue sizes
237#define FREEQBASE      58
238#define FREEQ64        58
239#define FREEQ128       59
240#define FREEQ256       60
241#define FREEQ512       61
242#define FREEQ1024      62
243#define FREEQ2048      63
244
245#define NFREEQ         6
246
247#define QLIMIT         10
248
249#define PRIVATEQ       50
250
251#define FARPKL(x)  (_farnspeekl((unsigned long) x))
252#define FARPKB(x)  (_farnspeekb((unsigned long) x))
253#define FARPKS(x)  (_farnspeekw((unsigned long) x))
254
255#define FARPOKL(x, y) (_farnspokel((unsigned long) x, (unsigned long) y))
256#define FARPOKB(x, y) (_farnspokeb((unsigned long) x, (unsigned char) y))
257
258int Qsizes[] = { 64, 128, 256, 512, 1024, 2048 };
259
260int SocketError = 0;
261
262SocketMap *SockMap;
263
264#define HOSTENT_ALIAS_LIMIT    5
265#define HOSTENT_STRLEN_LIMIT   50
266#define HOSTENT_ADDR_LIST_LIMIT   5
267
268struct hostent  HostEnt;
269
270char HostEnt_hname[HOSTENT_STRLEN_LIMIT];
271char *HostEnt_h_aliases[HOSTENT_ALIAS_LIMIT];
272char HostEnt_names[HOSTENT_ALIAS_LIMIT][HOSTENT_STRLEN_LIMIT];
273struct in_addr* HostEnt_addr_list[HOSTENT_ADDR_LIST_LIMIT];
274struct in_addr HostEnt_addrs[HOSTENT_ADDR_LIST_LIMIT];
275
276void
277fmemcpyto(void *to, const void *from, int length)
278{
279   movedata(_my_ds(), (unsigned)from, flat_selector, (unsigned)to, length);
280}
281
282void
283fmemcpyfrom(void *to, const void *from, int length)
284{
285   movedata(flat_selector, (unsigned)from, _my_ds(), (unsigned)to, length);
286}
287
288void
289fstrcpyto(char *to, const char *from)
290{
291   while (*from) {
292      FARPOKB(to, *from);
293      to++; from++;
294   }
295   FARPOKB(to, 0);
296}
297
298void
299fstrncpyto(char *to, const char *from, int len)
300{
301   while (*from && len) {
302      FARPOKB(to, *from);
303      to++; from++; len--;
304   }
305   FARPOKB(to, 0);
306}
307
308void
309fstrcpyfrom(char *to, const char *from)
310{
311   while (FARPKB(from)) {
312      *to = FARPKB(from);
313      from++; to++;
314   }
315   *to = 0;
316}
317
318void
319fstrncpyfrom(char *to, const char *from, int len)
320{
321   while (FARPKB(from) && len) {
322      *to =  FARPKB(from);
323      from++; to++; len--;
324   }
325   *to = 0;
326}
327
328void
329GetSocketMap(void)
330{
331   RTQ_NODE *n = MGenGetNode(SOCKET_MAP_QUEUE);
332
333   SockMap = (SocketMap *) FARPKL(&n->rtqDatum);
334}
335
336void *
337GetFreeBufferToQueue(int q, int bufSize)
338{
339   int i;
340
341   for (i = 0; i < NFREEQ; i++) {
342      if (Qsizes[i] >= bufSize && MGenGetQueueCtr(i+FREEQBASE)) {
343         RTQ_NODE *n = MGenMoveTo(i+FREEQBASE, q);
344         if (!n)
345            continue;
346         FARPOKL(&n->rtqUpCtr, bufSize);
347         return (void *) FARPKL(&n->rtqDatum);
348      }
349   }
350
351   return 0;
352}
353
354void
355FreeBufferFromQueue(int q)
356{
357   int i;
358   RTQ_NODE *n = MGenGetNode(q);
359
360   for (i = 0; i < NFREEQ; i++) {
361      if (Qsizes[i] == FARPKS(&n->rtqLen)) {
362         MGenMoveTo(q, i+FREEQBASE);
363         return;
364      }
365   }
366}
367
368void
369SetLPCData(LPCData *lpc)
370{
371
372   FARPOKL(&(lpc->version), 1);
373   FARPOKL(&(lpc->sizeOfArgs), 0);
374   FARPOKL(&(lpc->service), 0);
375}
376
377int
378bind(SOCKET s, const struct sockaddr *name, int namelen)
379{
380   RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
381   LPCData  *p;
382   LPCReturn *r;
383   BindArgs  *bargs;
384   int       retVal;
385
386   _farsetsel(flat_selector);
387   SocketError = 0;
388   p = (LPCData *) FARPKL(&n->rtqDatum);
389   SetLPCData(p);
390   FARPOKL(&p->service, LPC_SOCKBIND);
391   bargs = (BindArgs *) p->Data;
392   FARPOKL(&bargs->s, s);
393   FARPOKL(&bargs->namelen, namelen);
394   fmemcpyto(bargs->name, name, namelen);
395   MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
396   PostWindowsMessage();
397
398   while ((n = MGenGetNode(REC_QUEUE)) == 0)
399      Yield();
400
401   r = (LPCReturn *) FARPKL(&n->rtqDatum);
402
403   if (FARPKS(&r->error) != LPC_NOERROR) {
404      return -1;
405   }
406
407   retVal = FARPKL(r->Data);
408
409   // get ready for next call
410   MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
411
412   return retVal;
413}
414
415int
416closesocket(SOCKET s)
417{
418   RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
419   LPCData  *p;
420   LPCReturn *r;
421   int       retVal;
422
423   _farsetsel(flat_selector);
424   SocketError = 0;
425   p = (LPCData *) FARPKL(&n->rtqDatum);
426   SetLPCData(p);
427   FARPOKL(&p->service, LPC_SOCKCLOSE);
428   FARPOKL(p->Data, s);
429
430   MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
431   PostWindowsMessage();
432
433   while ((n = MGenGetNode(REC_QUEUE)) == 0)
434      Yield();
435
436   r = (LPCReturn *) FARPKL(&n->rtqDatum);
437
438   if (FARPKS(&r->error) != LPC_NOERROR) {
439      return -1;
440   }
441
442   retVal = FARPKL(r->Data);
443
444   // get ready for next call
445   MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
446
447   return retVal;
448}
449
450void
451ZapHostEnt()
452{
453   // do nothing
454}
455
456void
457ReconstructHostEnt(struct hostent *s, void *flattened)
458{
459   struct hostent   *old = (struct hostent *) flattened;
460   int i;
461   char **ptr;
462
463
464   s->h_name = HostEnt_hname;
465   fstrncpyfrom(s->h_name, (char *) FARPKL(&old->h_name), HOSTENT_STRLEN_LIMIT-1);
466   s->h_name[HOSTENT_STRLEN_LIMIT-1] = 0;
467
468   s->h_aliases = HostEnt_h_aliases;
469   ptr = (char **) FARPKL(&old->h_aliases);
470   for (i = 0; i < (HOSTENT_ALIAS_LIMIT-1) && FARPKL(ptr); i++, ptr++) {
471      s->h_aliases[i] = HostEnt_names[i];
472      // fstrncpyfrom(s->h_aliases[i], (void *) FARPKL(ptr), HOSTENT_STRLEN_LIMIT-1);
473      s->h_aliases[i][HOSTENT_STRLEN_LIMIT-1] = 0;
474   }
475   s->h_aliases[i] = 0;
476
477   s->h_addrtype = FARPKS(&old->h_addrtype);
478   s->h_length = FARPKS(&old->h_length);
479
480   if (FARPKS(&old->h_length) != sizeof(struct in_addr)) {
481      printf("Error!\n");
482      exit(0);
483   }
484
485   s->h_addr_list = (char **) HostEnt_addr_list;
486   ptr = (char **) FARPKL(&old->h_addr_list);
487   for (i = 0; i < (HOSTENT_ADDR_LIST_LIMIT - 1) && FARPKL(ptr); i++, ptr++) {
488      s->h_addr_list[i] = (char *) &(HostEnt_addrs[i]);
489      fmemcpyfrom(s->h_addr_list[i], (void *) FARPKL(ptr), s->h_length);
490   }
491   s->h_addr_list[i] = 0;
492}
493
494
495int
496getsockname(SOCKET s, struct sockaddr *name, int *namelen)
497{
498   RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
499   LPCData  *p;
500   LPCReturn *r;
501   GetSockNameRet  *ret;
502   int       retVal;
503
504   SocketError = 0;
505   _farsetsel(flat_selector);
506   p = (LPCData *) FARPKL(&n->rtqDatum);
507   SetLPCData(p);
508   FARPOKL(&p->service, LPC_SOCKGETSOCKNAME);
509   FARPOKL(p->Data, s);
510
511   MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
512   PostWindowsMessage();
513
514   while ((n = MGenGetNode(REC_QUEUE)) == 0)
515      Yield();
516
517
518   r = (LPCReturn *) FARPKL(&n->rtqDatum);
519
520   if (FARPKS(&r->error) != LPC_NOERROR) {
521      return -1;
522   }
523
524   ret = (GetSockNameRet *) r->Data;
525   retVal = FARPKL(&ret->retVal);
526   fmemcpyfrom(name, ret->name, FARPKL(&ret->namelen));
527   *namelen = FARPKL(&ret->namelen);
528
529   // get ready for next call
530   MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
531
532   return retVal;
533}
534
535int
536gethostname(char *name, int namelen)
537{
538   RTQ_NODE *n;
539   LPCData  *p;
540   LPCReturn *r;
541   GetHostNameRet  *ret;
542   int       retVal;
543   char  *s;
544
545   _farsetsel(flat_selector);
546   SocketError = 0;
547   n = (RTQ_NODE *) MGenGetNode(IDLE_QUEUE);
548   p = (LPCData *) FARPKL(&n->rtqDatum);
549   SetLPCData(p);
550   FARPOKL(&p->service,LPC_SOCKGETHOSTNAME);
551   MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
552   PostWindowsMessage();
553
554   while ((n = (RTQ_NODE *) (MGenGetNode(REC_QUEUE))) == 0)
555      Yield();
556
557   r = (LPCReturn *) FARPKL(&n->rtqDatum);
558
559   if (FARPKS(&r->error) != LPC_NOERROR) {
560      return -1;
561   }
562
563   ret = (GetHostNameRet *) r->Data;
564
565   retVal = FARPKL(&ret->retVal);
566
567   s = ret->name;
568
569   fstrncpyfrom(name, s, namelen);
570
571#if 0
572   len = strlen(ret->name);
573
574   if (len > namelen)
575      memcpy(name, ret->name, ret->namelen);
576   else
577      strcpy(name, ret->name);
578#endif
579
580   // get ready for next call
581   MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
582
583   return retVal;
584}
585
586struct hostent *
587gethostbyname(const char *name)
588{
589   RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
590   LPCData  *p;
591   LPCReturn *r;
592   struct hostent *retVal;
593
594   _farsetsel(flat_selector);
595   SocketError = 0;
596   p = (LPCData *) FARPKL(&n->rtqDatum);
597   SetLPCData(p);
598   FARPOKL(&p->service, LPC_SOCKGETHOSTBYNAME);
599   fstrcpyto(p->Data, name);
600
601   MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
602   PostWindowsMessage();
603
604   while ((n = MGenGetNode(REC_QUEUE)) == 0)
605      Yield();
606
607   r = (LPCReturn *) FARPKL(&n->rtqDatum);
608   retVal = (struct hostent *) r->Data;
609
610   if (FARPKL(&retVal->h_name) == 0) {
611      retVal = 0;
612   } else {
613      ZapHostEnt();
614      ReconstructHostEnt(&HostEnt, (void *) retVal);
615      retVal = &HostEnt;
616   }
617
618   // get ready for next call
619   MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
620
621   return retVal;
622}
623
624struct hostent *
625gethostbyaddr(const char *addr, int len, int type)
626{
627   RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
628   LPCData  *p;
629   LPCReturn *r;
630   GetHostByAddrArgs *args;
631   struct hostent *retVal;
632
633   SocketError = 0;
634   _farsetsel(flat_selector);
635   p = (LPCData *) FARPKL(&n->rtqDatum);
636   SetLPCData(p);
637   FARPOKL(&p->service, LPC_SOCKGETHOSTBYADDR);
638   args = (GetHostByAddrArgs *) p->Data;
639   FARPOKL(&args->len, len);
640   FARPOKL(&args->type, type);
641   fmemcpyto(args->addr, addr, len);
642
643   MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
644   PostWindowsMessage();
645
646   while ((n = MGenGetNode(REC_QUEUE)) == 0)
647      Yield();
648   r = (LPCReturn *) FARPKL(&n->rtqDatum);
649   retVal = (struct hostent *) r->Data;
650
651   if (FARPKL(&retVal->h_name) == 0) {
652      retVal = 0;
653   } else {
654      ZapHostEnt();
655
656      ReconstructHostEnt(&HostEnt, (void *) retVal);
657      retVal = &HostEnt;
658   }
659
660   // get ready for next call
661   MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
662
663   return retVal;
664}
665
666
667SOCKET
668socket(int af, int type, int protocol)
669{
670   RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
671   LPCData  *p;
672   LPCReturn *r;
673   SocketArgs  *args;
674   int       retVal;
675
676   _farsetsel(flat_selector);
677   SocketError = 0;
678   p = (LPCData *) FARPKL(&n->rtqDatum);
679   SetLPCData(p);
680   FARPOKL(&p->service, LPC_SOCKSOCKET);
681   args = (SocketArgs *) p->Data;
682   FARPOKL(&args->af, af);
683   FARPOKL(&args->type, type);
684   FARPOKL(&args->protocol, protocol);
685
686   MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
687   PostWindowsMessage();
688
689   while ((n = MGenGetNode(REC_QUEUE)) == 0)
690      Yield();
691
692   r = (LPCReturn *) FARPKL(&n->rtqDatum);
693
694
695   if (FARPKS(&r->error) != LPC_NOERROR) {
696      return -1;
697   }
698
699   retVal = FARPKL(r->Data);
700
701   // get ready for next call
702   MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
703
704   return retVal;
705}
706
707void
708sockets_flush(void)
709{
710   RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
711   LPCData  *p;
712
713   SocketError = 0;
714   p = (LPCData *) FARPKL(&n->rtqDatum);
715   SetLPCData(p);
716   FARPOKL(&p->service, LPC_SOCKFLUSH);
717
718   MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
719   PostWindowsMessage();
720
721   while ((n = MGenGetNode(REC_QUEUE)) == 0)
722      Yield();
723
724   MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
725}
726
727int
728recvfrom(SOCKET s, char *buf, int len, int flags, struct sockaddr *from,
729         int *fromlen)
730{
731   int i;
732   RTQ_NODE *n;
733   WinSockData  *data;
734   int  bytesRead;
735
736   SocketError = 0;
737   _farsetsel(flat_selector);
738   if (!SockMap)
739      GetSocketMap();
740
741   for (i = 0; i < MAXSOCKETS; i++) {
742      if (FARPKL(&(SockMap->sock[i])) == s)
743         break;
744   }
745
746   if (i == MAXSOCKETS)
747      return SOCKET_ERROR;
748
749   // pick up node
750   n = MGenGetNode(i);
751   if (n == 0) {
752      SocketError = WSAEWOULDBLOCK;
753      return -1;
754   }
755
756   data = (WinSockData *) FARPKL(&n->rtqDatum);
757   bytesRead = FARPKL(&data->len);
758
759   if (from) {
760      fmemcpyfrom(from, &data->addr, sizeof(struct sockaddr));
761   }
762
763   if (fromlen) {
764      *fromlen = FARPKL(&data->addrlen);
765   }
766
767   fmemcpyfrom(buf, data->data, len > bytesRead ? bytesRead : len);
768
769   if ((flags & MSG_PEEK) == 0) {
770      FreeBufferFromQueue(i);
771   }
772
773   return bytesRead;
774}
775
776int
777sendto(SOCKET s, const char *buf, int len, int flags, const struct sockaddr *to, int tolen)
778{
779   int i;
780   int outQ;
781   WinSockData *data;
782
783   SocketError = 0;
784   _farsetsel(flat_selector);
785   if (!SockMap)
786      GetSocketMap();
787
788   for (i = 0; i < MAXSOCKETS; i++) {
789      if (FARPKL(&SockMap->sock[i]) == s) {
790         break;
791      }
792   }
793
794   if (i == MAXSOCKETS) {
795      SocketError = WSAENOTSOCK;
796      return SOCKET_ERROR;
797   }
798
799   outQ = i + MAXSOCKETS;
800
801   if (MGenGetQueueCtr(outQ) >= QLIMIT) {
802      SocketError = WSAEWOULDBLOCK;
803      return SOCKET_ERROR;
804   }
805
806   data = GetFreeBufferToQueue(PRIVATEQ, len + sizeof(WinSockData));
807
808   if (!data) {
809      SocketError = WSAEWOULDBLOCK;
810      return SOCKET_ERROR;
811   }
812
813   FARPOKL(&data->s, s);
814   FARPOKL(&data->len, len);
815   if (to) {
816      fmemcpyto(&data->addr, to, tolen);
817      FARPOKL(&data->addrlen, tolen);
818   } else {
819      FARPOKL(&data->addrlen, 0);
820   }
821
822   FARPOKL(&data->flags, flags);
823
824   fmemcpyto(data->data, buf, len);
825
826   MGenMoveTo(PRIVATEQ, outQ);
827
828   return len;
829}
830
831int
832ioctlsocket(SOCKET s, long cmd, unsigned long *argp)
833{
834   RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
835   LPCData  *p;
836   LPCReturn *r;
837   IoctlArgs  *args;
838   int       retVal;
839
840   SocketError = 0;
841   _farsetsel(flat_selector);
842   p = (LPCData *) FARPKL(&n->rtqDatum);
843   SetLPCData(p);
844   FARPOKL(&p->service, LPC_SOCKIOCTL);
845   args = (IoctlArgs *) p->Data;
846   FARPOKL(&args->s, s);
847   FARPOKL(&args->cmd, cmd);
848
849   switch(cmd) {
850   case FIONBIO:
851      FARPOKL(args->data, *argp);
852      break;
853   default:
854      return SOCKET_ERROR;
855   }
856
857   MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
858   PostWindowsMessage();
859
860   while ((n = MGenGetNode(REC_QUEUE)) == 0)
861      Yield();
862
863   r = (LPCReturn *) FARPKL(&n->rtqDatum);
864
865
866   retVal = FARPKL(r->Data);
867
868   // get ready for next call
869   MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
870
871   return retVal;
872}
873
874int
875setsockopt(SOCKET s, int level, int optname, const char *optval, int optlen)
876{
877   RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
878   LPCData  *p;
879   LPCReturn *r;
880   SetSockOptArgs  *args;
881   int       retVal;
882
883   SocketError = 0;
884   _farsetsel(flat_selector);
885   p = (LPCData *) FARPKL(&n->rtqDatum);
886   SetLPCData(p);
887   FARPOKL(&p->service, LPC_SOCKSETOPT);
888   args = (SetSockOptArgs *) p->Data;
889   FARPOKL(&args->s, s);
890   FARPOKL(&args->level, level);
891   FARPOKL(&args->optname, optname);
892   FARPOKL(&args->optlen, optlen);
893   fmemcpyto(args->optval, optval, optlen);
894
895   MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
896   PostWindowsMessage();
897
898   while ((n = MGenGetNode(REC_QUEUE)) == 0)
899      Yield();
900
901   r = (LPCReturn *) FARPKL(&n->rtqDatum);
902
903   retVal = FARPKL(r->Data);
904
905   // get ready for next call
906   MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
907
908   return retVal;
909}
910
911int
912WSAGetLastError(void)
913{
914   RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
915   LPCData  *p;
916   LPCReturn *r;
917   int       retVal;
918
919
920   _farsetsel(flat_selector);
921   if (SocketError) {
922      int err = SocketError;
923
924      SocketError = 0;
925      return err;
926   }
927
928   p = (LPCData *) FARPKL(&n->rtqDatum);
929   SetLPCData(p);
930   FARPOKL(&p->service, LPC_SOCKGETLASTERROR);
931
932   MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
933   PostWindowsMessage();
934
935   while ((n = MGenGetNode(REC_QUEUE)) == 0)
936      Yield();
937
938   r = (LPCReturn *) FARPKL(&n->rtqDatum);
939
940
941   retVal = FARPKL(r->Data);
942
943   // get ready for next call
944   MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
945
946   return retVal;
947}
948
949unsigned long inet_addr(const char *cp)
950{
951	int ret;
952	unsigned int ha1, ha2, ha3, ha4;
953	unsigned long ipaddr;
954
955	ret = sscanf(cp, "%d.%d.%d.%d", &ha1, &ha2, &ha3, &ha4);
956	if (ret != 4)
957		return -1;
958	ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4;
959	return ipaddr;
960#if 0
961   RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
962   LPCData  *p;
963   LPCReturn *r;
964   int       retVal;
965
966   SocketError = 0;
967   _farsetsel(flat_selector);
968   p = (LPCData *) FARPKL(&n->rtqDatum);
969   SetLPCData(p);
970   FARPOKL(&p->service, LPC_SOCKINETADDR);
971
972   fstrcpyto(p->Data, cp);
973
974   MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
975   PostWindowsMessage();
976
977   while ((n = MGenGetNode(REC_QUEUE)) == 0)
978      Yield();
979
980   r = (LPCReturn *) FARPKL(&n->rtqDatum);
981
982   if (FARPKS(&r->error) != LPC_NOERROR) {
983      return -1;
984   }
985
986   retVal = FARPKL(r->Data);
987
988   // get ready for next call
989   MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
990
991   return retVal;
992 #endif
993}
994
995char *inet_ntoa (struct in_addr in)
996{
997	static char buf [32];
998
999	sprintf(buf, "%u.%u.%u.%u", in.S_un.S_un_b.s_b1, in.S_un.S_un_b.s_b2, in.S_un.S_un_b.s_b3, in.S_un.S_un_b.s_b4);
1000	return buf;
1001}
1002