1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, 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"
24 typedef unsigned char BYTE;
25 typedef unsigned short WORD;
26 typedef unsigned long DWORD;
27
28 //#include "lpc.h"
29 typedef 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
36 typedef 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
70 typedef struct {
71 SOCKET s;
72 int namelen;
73 char name[1];
74 } BindArgs;
75
76 typedef struct {
77 SOCKET s;
78 long cmd;
79 char data[1];
80 } IoctlArgs;
81
82 typedef struct {
83 int retVal;
84 int namelen;
85 char name[1];
86 } GetSockNameRet;
87
88 typedef GetSockNameRet GetHostNameRet;
89
90 typedef struct {
91 int retVal;
92 int h_addr_0; // that's the only important value
93 } GetHostByNameRet;
94
95 typedef struct {
96 int len;
97 int type;
98 char addr[1];
99 } GetHostByAddrArgs;
100
101 typedef struct {
102 int retVal;
103 char h_name[1]; // h_name is the only important value
104 } GetHostByAddrRet;
105
106 typedef struct {
107 SOCKET s;
108 int flags;
109 } RecvFromArgs;
110
111 typedef 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
120 typedef struct {
121 SOCKET s;
122 int flags;
123 int len;
124 struct sockaddr sockaddr;
125 int sockaddrlen;
126 char Data[1];
127 } SendToArgs;
128
129 typedef struct {
130 int retVal;
131 int errCode;
132 } SendToRet;
133
134 typedef struct {
135 int bufflen;
136 SOCKET s;
137 int len;
138 int sockaddrlen;
139 struct sockaddr address;
140 char data[1];
141 } SocketChannelData;
142
143 typedef struct {
144 int af;
145 int type;
146 int protocol;
147 } SocketArgs;
148
149 typedef struct {
150 SOCKET s;
151 int len;
152 int flags;
153 int addrlen;
154 struct sockaddr addr;
155 char data[1];
156 } WinSockData;
157
158 typedef struct {
159 SOCKET s;
160 int level;
161 int optname;
162 int optlen;
163 char optval[1];
164 } SetSockOptArgs;
165
166 typedef struct {
167 SOCKET sock[MAXSOCKETS];
168 } SocketMap;
169
170 //#include "rtq.h"
171 #define RTQ_NODE struct rtq_node
172
173 RTQ_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
187 RTQ_PARAM_MOVENODE
188 {
189 WORD rtqFromDQ;
190 WORD rtqToDQ;
191 };
192
193 RTQ_NODE* rtq_fetch(RTQ_NODE*, RTQ_NODE*); // To, From
194
195 //#include "mplib.h"
196 // give up time slice
197 void Yield(void);
198 void MGenWakeupDll(void);
199
200 // post a message to win32 side
201 void PostWindowsMessage(void);
202
203 // get # of items on qNo
204 int MGenGetQueueCtr(int qNo);
205
206 // move first node from qFrom to qTo
207 RTQ_NODE *MGenMoveTo(int qFrom, int qTo);
208
209 // get first node from q
210 RTQ_NODE *MGenGetNode(int q);
211
212 // get master node, returning size of RTQ_NODE for size verification
213 RTQ_NODE *MGenGetMasterNode(unsigned *size);
214
215 // move all nodes from qFrom to qTo
216 RTQ_NODE *MGenFlushNodes(int qFrom, int qTo);
217
218 // count number of nodes in queues designated by bitmask
219 // lowerOrderBits == 0..31, upperOrderBits == 32-63
220 int MGenMCount(unsigned lowerOrderBits, unsigned upperOrderBits);
221
222 // perform consistency check on chunnel address space
223 int MGenSanityCheck(void);
224
225 #include <stdio.h>
226 #include <sys/farptr.h>
227
228 extern 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
258 int Qsizes[] = { 64, 128, 256, 512, 1024, 2048 };
259
260 int SocketError = 0;
261
262 SocketMap *SockMap;
263
264 #define HOSTENT_ALIAS_LIMIT 5
265 #define HOSTENT_STRLEN_LIMIT 50
266 #define HOSTENT_ADDR_LIST_LIMIT 5
267
268 struct hostent HostEnt;
269
270 char HostEnt_hname[HOSTENT_STRLEN_LIMIT];
271 char *HostEnt_h_aliases[HOSTENT_ALIAS_LIMIT];
272 char HostEnt_names[HOSTENT_ALIAS_LIMIT][HOSTENT_STRLEN_LIMIT];
273 struct in_addr* HostEnt_addr_list[HOSTENT_ADDR_LIST_LIMIT];
274 struct in_addr HostEnt_addrs[HOSTENT_ADDR_LIST_LIMIT];
275
276 void
fmemcpyto(void * to,const void * from,int length)277 fmemcpyto(void *to, const void *from, int length)
278 {
279 movedata(_my_ds(), (unsigned)from, flat_selector, (unsigned)to, length);
280 }
281
282 void
fmemcpyfrom(void * to,const void * from,int length)283 fmemcpyfrom(void *to, const void *from, int length)
284 {
285 movedata(flat_selector, (unsigned)from, _my_ds(), (unsigned)to, length);
286 }
287
288 void
fstrcpyto(char * to,const char * from)289 fstrcpyto(char *to, const char *from)
290 {
291 while (*from) {
292 FARPOKB(to, *from);
293 to++; from++;
294 }
295 FARPOKB(to, 0);
296 }
297
298 void
fstrncpyto(char * to,const char * from,int len)299 fstrncpyto(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
308 void
fstrcpyfrom(char * to,const char * from)309 fstrcpyfrom(char *to, const char *from)
310 {
311 while (FARPKB(from)) {
312 *to = FARPKB(from);
313 from++; to++;
314 }
315 *to = 0;
316 }
317
318 void
fstrncpyfrom(char * to,const char * from,int len)319 fstrncpyfrom(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
328 void
GetSocketMap(void)329 GetSocketMap(void)
330 {
331 RTQ_NODE *n = MGenGetNode(SOCKET_MAP_QUEUE);
332
333 SockMap = (SocketMap *) FARPKL(&n->rtqDatum);
334 }
335
336 void *
GetFreeBufferToQueue(int q,int bufSize)337 GetFreeBufferToQueue(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
354 void
FreeBufferFromQueue(int q)355 FreeBufferFromQueue(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
368 void
SetLPCData(LPCData * lpc)369 SetLPCData(LPCData *lpc)
370 {
371
372 FARPOKL(&(lpc->version), 1);
373 FARPOKL(&(lpc->sizeOfArgs), 0);
374 FARPOKL(&(lpc->service), 0);
375 }
376
377 int
bind(SOCKET s,const struct sockaddr * name,int namelen)378 bind(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
415 int
closesocket(SOCKET s)416 closesocket(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
450 void
ZapHostEnt()451 ZapHostEnt()
452 {
453 // do nothing
454 }
455
456 void
ReconstructHostEnt(struct hostent * s,void * flattened)457 ReconstructHostEnt(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
495 int
getsockname(SOCKET s,struct sockaddr * name,int * namelen)496 getsockname(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
535 int
gethostname(char * name,int namelen)536 gethostname(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
586 struct hostent *
gethostbyname(const char * name)587 gethostbyname(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
624 struct hostent *
gethostbyaddr(const char * addr,int len,int type)625 gethostbyaddr(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
667 SOCKET
socket(int af,int type,int protocol)668 socket(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
707 void
sockets_flush(void)708 sockets_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
727 int
recvfrom(SOCKET s,char * buf,int len,int flags,struct sockaddr * from,int * fromlen)728 recvfrom(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
776 int
sendto(SOCKET s,const char * buf,int len,int flags,const struct sockaddr * to,int tolen)777 sendto(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
831 int
ioctlsocket(SOCKET s,long cmd,unsigned long * argp)832 ioctlsocket(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
874 int
setsockopt(SOCKET s,int level,int optname,const char * optval,int optlen)875 setsockopt(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
911 int
WSAGetLastError(void)912 WSAGetLastError(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
inet_addr(const char * cp)949 unsigned 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
inet_ntoa(struct in_addr in)995 char *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