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