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