aboutsummaryrefslogtreecommitdiffstats
path: root/WinQuake/mplpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'WinQuake/mplpc.c')
-rw-r--r--WinQuake/mplpc.c2002
1 files changed, 1001 insertions, 1001 deletions
diff --git a/WinQuake/mplpc.c b/WinQuake/mplpc.c
index 10bc564..57d2ffd 100644
--- a/WinQuake/mplpc.c
+++ b/WinQuake/mplpc.c
@@ -1,1001 +1,1001 @@
-/*
-Copyright (C) 1996-1997 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-*/
-#include <go32.h>
-#include "mpdosock.h"
-
-//#include "types.h"
-typedef unsigned char BYTE;
-typedef unsigned short WORD;
-typedef unsigned long DWORD;
-
-//#include "lpc.h"
-typedef struct {
- short version; // version of LPC requested
- short sizeOfArgs; // size of arguments
- short service; // service # requested
- char Data[1]; // data
-} LPCData;
-
-typedef struct {
- short version; // LPC version
- short sizeOfReturn; // return data size
- short error; // any error codes
- short noRet; // number of returns
- char Data[1]; // data
-} LPCReturn;
-
-//#include "services.h"
-#define MAXSOCKETS 20
-
-// services
-#define LPC_SOCKBIND 4
-#define LPC_SOCKGETHOSTBYNAME 5
-#define LPC_SOCKGETHOSTNAME 6
-#define LPC_SOCKGETHOSTBYADDR 7
-#define LPC_SOCKCLOSE 8
-#define LPC_SOCKSOCKET 9
-#define LPC_SOCKRECVFROM 10
-#define LPC_SOCKSENDTO 11
-#define LPC_SOCKIOCTL 12
-#define LPC_SOCKGETSOCKNAME 13
-#define LPC_SOCKFLUSH 14
-#define LPC_SOCKSETOPT 15
-#define LPC_SOCKGETLASTERROR 16
-#define LPC_SOCKINETADDR 17
-
-// htons, ntohs, htonl, ntohl implemented locally
-
-// errors
-#define LPC_UNRECOGNIZED_SERVICE -1
-#define LPC_NOERROR 0
-
-// structures for support
-typedef struct {
- SOCKET s;
- int namelen;
- char name[1];
-} BindArgs;
-
-typedef struct {
- SOCKET s;
- long cmd;
- char data[1];
-} IoctlArgs;
-
-typedef struct {
- int retVal;
- int namelen;
- char name[1];
-} GetSockNameRet;
-
-typedef GetSockNameRet GetHostNameRet;
-
-typedef struct {
- int retVal;
- int h_addr_0; // that's the only important value
-} GetHostByNameRet;
-
-typedef struct {
- int len;
- int type;
- char addr[1];
-} GetHostByAddrArgs;
-
-typedef struct {
- int retVal;
- char h_name[1]; // h_name is the only important value
-} GetHostByAddrRet;
-
-typedef struct {
- SOCKET s;
- int flags;
-} RecvFromArgs;
-
-typedef struct {
- int retVal;
- int errCode;
- int len; // message len
- struct sockaddr sockaddr;
- int sockaddrlen;
- char Data[1];
-} RecvFromRet;
-
-typedef struct {
- SOCKET s;
- int flags;
- int len;
- struct sockaddr sockaddr;
- int sockaddrlen;
- char Data[1];
-} SendToArgs;
-
-typedef struct {
- int retVal;
- int errCode;
-} SendToRet;
-
-typedef struct {
- int bufflen;
- SOCKET s;
- int len;
- int sockaddrlen;
- struct sockaddr address;
- char data[1];
-} SocketChannelData;
-
-typedef struct {
- int af;
- int type;
- int protocol;
-} SocketArgs;
-
-typedef struct {
- SOCKET s;
- int len;
- int flags;
- int addrlen;
- struct sockaddr addr;
- char data[1];
-} WinSockData;
-
-typedef struct {
- SOCKET s;
- int level;
- int optname;
- int optlen;
- char optval[1];
-} SetSockOptArgs;
-
-typedef struct {
- SOCKET sock[MAXSOCKETS];
-} SocketMap;
-
-//#include "rtq.h"
-#define RTQ_NODE struct rtq_node
-
-RTQ_NODE
- {
- RTQ_NODE *self; // Ring zero address of this node
- RTQ_NODE *left; // Ring zero address of preceding node
- RTQ_NODE *right; // Ring zero address of succeding node
- BYTE * rtqDatum; // Ring 3 Datum of Buffer (start of preface)
- BYTE * rtqInsert; // Ring 3 insertion position
- WORD rtqLen; // Length of buffer, excluding preface
- WORD rtqUpCtr; // Up Counter of bytes used so far
- WORD rtqQCtr; // number of nodes attached
- WORD padding; // DWORD alignment
- };
-
-#define RTQ_PARAM_MOVENODE struct rtq_param_movenode
-RTQ_PARAM_MOVENODE
- {
- WORD rtqFromDQ;
- WORD rtqToDQ;
- };
-
-RTQ_NODE* rtq_fetch(RTQ_NODE*, RTQ_NODE*); // To, From
-
-//#include "mplib.h"
-// give up time slice
-void Yield(void);
-void MGenWakeupDll(void);
-
-// post a message to win32 side
-void PostWindowsMessage(void);
-
-// get # of items on qNo
-int MGenGetQueueCtr(int qNo);
-
-// move first node from qFrom to qTo
-RTQ_NODE *MGenMoveTo(int qFrom, int qTo);
-
-// get first node from q
-RTQ_NODE *MGenGetNode(int q);
-
-// get master node, returning size of RTQ_NODE for size verification
-RTQ_NODE *MGenGetMasterNode(unsigned *size);
-
-// move all nodes from qFrom to qTo
-RTQ_NODE *MGenFlushNodes(int qFrom, int qTo);
-
-// count number of nodes in queues designated by bitmask
-// lowerOrderBits == 0..31, upperOrderBits == 32-63
-int MGenMCount(unsigned lowerOrderBits, unsigned upperOrderBits);
-
-// perform consistency check on chunnel address space
-int MGenSanityCheck(void);
-
-#include <stdio.h>
-#include <sys/farptr.h>
-
-extern short flat_selector;
-
-#define SOCKET_MAP_QUEUE 41
-
-#define IDLE_QUEUE 44
-#define REC_QUEUE 45
-#define SEND_QUEUE 46
-
-// queue sizes
-#define FREEQBASE 58
-#define FREEQ64 58
-#define FREEQ128 59
-#define FREEQ256 60
-#define FREEQ512 61
-#define FREEQ1024 62
-#define FREEQ2048 63
-
-#define NFREEQ 6
-
-#define QLIMIT 10
-
-#define PRIVATEQ 50
-
-#define FARPKL(x) (_farnspeekl((unsigned long) x))
-#define FARPKB(x) (_farnspeekb((unsigned long) x))
-#define FARPKS(x) (_farnspeekw((unsigned long) x))
-
-#define FARPOKL(x, y) (_farnspokel((unsigned long) x, (unsigned long) y))
-#define FARPOKB(x, y) (_farnspokeb((unsigned long) x, (unsigned char) y))
-
-int Qsizes[] = { 64, 128, 256, 512, 1024, 2048 };
-
-int SocketError = 0;
-
-SocketMap *SockMap;
-
-#define HOSTENT_ALIAS_LIMIT 5
-#define HOSTENT_STRLEN_LIMIT 50
-#define HOSTENT_ADDR_LIST_LIMIT 5
-
-struct hostent HostEnt;
-
-char HostEnt_hname[HOSTENT_STRLEN_LIMIT];
-char *HostEnt_h_aliases[HOSTENT_ALIAS_LIMIT];
-char HostEnt_names[HOSTENT_ALIAS_LIMIT][HOSTENT_STRLEN_LIMIT];
-struct in_addr* HostEnt_addr_list[HOSTENT_ADDR_LIST_LIMIT];
-struct in_addr HostEnt_addrs[HOSTENT_ADDR_LIST_LIMIT];
-
-void
-fmemcpyto(void *to, const void *from, int length)
-{
- movedata(_my_ds(), (unsigned)from, flat_selector, (unsigned)to, length);
-}
-
-void
-fmemcpyfrom(void *to, const void *from, int length)
-{
- movedata(flat_selector, (unsigned)from, _my_ds(), (unsigned)to, length);
-}
-
-void
-fstrcpyto(char *to, const char *from)
-{
- while (*from) {
- FARPOKB(to, *from);
- to++; from++;
- }
- FARPOKB(to, 0);
-}
-
-void
-fstrncpyto(char *to, const char *from, int len)
-{
- while (*from && len) {
- FARPOKB(to, *from);
- to++; from++; len--;
- }
- FARPOKB(to, 0);
-}
-
-void
-fstrcpyfrom(char *to, const char *from)
-{
- while (FARPKB(from)) {
- *to = FARPKB(from);
- from++; to++;
- }
- *to = 0;
-}
-
-void
-fstrncpyfrom(char *to, const char *from, int len)
-{
- while (FARPKB(from) && len) {
- *to = FARPKB(from);
- from++; to++; len--;
- }
- *to = 0;
-}
-
-void
-GetSocketMap(void)
-{
- RTQ_NODE *n = MGenGetNode(SOCKET_MAP_QUEUE);
-
- SockMap = (SocketMap *) FARPKL(&n->rtqDatum);
-}
-
-void *
-GetFreeBufferToQueue(int q, int bufSize)
-{
- int i;
-
- for (i = 0; i < NFREEQ; i++) {
- if (Qsizes[i] >= bufSize && MGenGetQueueCtr(i+FREEQBASE)) {
- RTQ_NODE *n = MGenMoveTo(i+FREEQBASE, q);
- if (!n)
- continue;
- FARPOKL(&n->rtqUpCtr, bufSize);
- return (void *) FARPKL(&n->rtqDatum);
- }
- }
-
- return 0;
-}
-
-void
-FreeBufferFromQueue(int q)
-{
- int i;
- RTQ_NODE *n = MGenGetNode(q);
-
- for (i = 0; i < NFREEQ; i++) {
- if (Qsizes[i] == FARPKS(&n->rtqLen)) {
- MGenMoveTo(q, i+FREEQBASE);
- return;
- }
- }
-}
-
-void
-SetLPCData(LPCData *lpc)
-{
-
- FARPOKL(&(lpc->version), 1);
- FARPOKL(&(lpc->sizeOfArgs), 0);
- FARPOKL(&(lpc->service), 0);
-}
-
-int
-bind(SOCKET s, const struct sockaddr *name, int namelen)
-{
- RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
- LPCData *p;
- LPCReturn *r;
- BindArgs *bargs;
- int retVal;
-
- _farsetsel(flat_selector);
- SocketError = 0;
- p = (LPCData *) FARPKL(&n->rtqDatum);
- SetLPCData(p);
- FARPOKL(&p->service, LPC_SOCKBIND);
- bargs = (BindArgs *) p->Data;
- FARPOKL(&bargs->s, s);
- FARPOKL(&bargs->namelen, namelen);
- fmemcpyto(bargs->name, name, namelen);
- MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
- PostWindowsMessage();
-
- while ((n = MGenGetNode(REC_QUEUE)) == 0)
- Yield();
-
- r = (LPCReturn *) FARPKL(&n->rtqDatum);
-
- if (FARPKS(&r->error) != LPC_NOERROR) {
- return -1;
- }
-
- retVal = FARPKL(r->Data);
-
- // get ready for next call
- MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
-
- return retVal;
-}
-
-int
-closesocket(SOCKET s)
-{
- RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
- LPCData *p;
- LPCReturn *r;
- int retVal;
-
- _farsetsel(flat_selector);
- SocketError = 0;
- p = (LPCData *) FARPKL(&n->rtqDatum);
- SetLPCData(p);
- FARPOKL(&p->service, LPC_SOCKCLOSE);
- FARPOKL(p->Data, s);
-
- MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
- PostWindowsMessage();
-
- while ((n = MGenGetNode(REC_QUEUE)) == 0)
- Yield();
-
- r = (LPCReturn *) FARPKL(&n->rtqDatum);
-
- if (FARPKS(&r->error) != LPC_NOERROR) {
- return -1;
- }
-
- retVal = FARPKL(r->Data);
-
- // get ready for next call
- MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
-
- return retVal;
-}
-
-void
-ZapHostEnt()
-{
- // do nothing
-}
-
-void
-ReconstructHostEnt(struct hostent *s, void *flattened)
-{
- struct hostent *old = (struct hostent *) flattened;
- int i;
- char **ptr;
-
-
- s->h_name = HostEnt_hname;
- fstrncpyfrom(s->h_name, (char *) FARPKL(&old->h_name), HOSTENT_STRLEN_LIMIT-1);
- s->h_name[HOSTENT_STRLEN_LIMIT-1] = 0;
-
- s->h_aliases = HostEnt_h_aliases;
- ptr = (char **) FARPKL(&old->h_aliases);
- for (i = 0; i < (HOSTENT_ALIAS_LIMIT-1) && FARPKL(ptr); i++, ptr++) {
- s->h_aliases[i] = HostEnt_names[i];
- // fstrncpyfrom(s->h_aliases[i], (void *) FARPKL(ptr), HOSTENT_STRLEN_LIMIT-1);
- s->h_aliases[i][HOSTENT_STRLEN_LIMIT-1] = 0;
- }
- s->h_aliases[i] = 0;
-
- s->h_addrtype = FARPKS(&old->h_addrtype);
- s->h_length = FARPKS(&old->h_length);
-
- if (FARPKS(&old->h_length) != sizeof(struct in_addr)) {
- printf("Error!\n");
- exit(0);
- }
-
- s->h_addr_list = (char **) HostEnt_addr_list;
- ptr = (char **) FARPKL(&old->h_addr_list);
- for (i = 0; i < (HOSTENT_ADDR_LIST_LIMIT - 1) && FARPKL(ptr); i++, ptr++) {
- s->h_addr_list[i] = (char *) &(HostEnt_addrs[i]);
- fmemcpyfrom(s->h_addr_list[i], (void *) FARPKL(ptr), s->h_length);
- }
- s->h_addr_list[i] = 0;
-}
-
-
-int
-getsockname(SOCKET s, struct sockaddr *name, int *namelen)
-{
- RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
- LPCData *p;
- LPCReturn *r;
- GetSockNameRet *ret;
- int retVal;
-
- SocketError = 0;
- _farsetsel(flat_selector);
- p = (LPCData *) FARPKL(&n->rtqDatum);
- SetLPCData(p);
- FARPOKL(&p->service, LPC_SOCKGETSOCKNAME);
- FARPOKL(p->Data, s);
-
- MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
- PostWindowsMessage();
-
- while ((n = MGenGetNode(REC_QUEUE)) == 0)
- Yield();
-
-
- r = (LPCReturn *) FARPKL(&n->rtqDatum);
-
- if (FARPKS(&r->error) != LPC_NOERROR) {
- return -1;
- }
-
- ret = (GetSockNameRet *) r->Data;
- retVal = FARPKL(&ret->retVal);
- fmemcpyfrom(name, ret->name, FARPKL(&ret->namelen));
- *namelen = FARPKL(&ret->namelen);
-
- // get ready for next call
- MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
-
- return retVal;
-}
-
-int
-gethostname(char *name, int namelen)
-{
- RTQ_NODE *n;
- LPCData *p;
- LPCReturn *r;
- GetHostNameRet *ret;
- int retVal;
- char *s;
-
- _farsetsel(flat_selector);
- SocketError = 0;
- n = (RTQ_NODE *) MGenGetNode(IDLE_QUEUE);
- p = (LPCData *) FARPKL(&n->rtqDatum);
- SetLPCData(p);
- FARPOKL(&p->service,LPC_SOCKGETHOSTNAME);
- MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
- PostWindowsMessage();
-
- while ((n = (RTQ_NODE *) (MGenGetNode(REC_QUEUE))) == 0)
- Yield();
-
- r = (LPCReturn *) FARPKL(&n->rtqDatum);
-
- if (FARPKS(&r->error) != LPC_NOERROR) {
- return -1;
- }
-
- ret = (GetHostNameRet *) r->Data;
-
- retVal = FARPKL(&ret->retVal);
-
- s = ret->name;
-
- fstrncpyfrom(name, s, namelen);
-
-#if 0
- len = strlen(ret->name);
-
- if (len > namelen)
- memcpy(name, ret->name, ret->namelen);
- else
- strcpy(name, ret->name);
-#endif
-
- // get ready for next call
- MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
-
- return retVal;
-}
-
-struct hostent *
-gethostbyname(const char *name)
-{
- RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
- LPCData *p;
- LPCReturn *r;
- struct hostent *retVal;
-
- _farsetsel(flat_selector);
- SocketError = 0;
- p = (LPCData *) FARPKL(&n->rtqDatum);
- SetLPCData(p);
- FARPOKL(&p->service, LPC_SOCKGETHOSTBYNAME);
- fstrcpyto(p->Data, name);
-
- MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
- PostWindowsMessage();
-
- while ((n = MGenGetNode(REC_QUEUE)) == 0)
- Yield();
-
- r = (LPCReturn *) FARPKL(&n->rtqDatum);
- retVal = (struct hostent *) r->Data;
-
- if (FARPKL(&retVal->h_name) == 0) {
- retVal = 0;
- } else {
- ZapHostEnt();
- ReconstructHostEnt(&HostEnt, (void *) retVal);
- retVal = &HostEnt;
- }
-
- // get ready for next call
- MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
-
- return retVal;
-}
-
-struct hostent *
-gethostbyaddr(const char *addr, int len, int type)
-{
- RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
- LPCData *p;
- LPCReturn *r;
- GetHostByAddrArgs *args;
- struct hostent *retVal;
-
- SocketError = 0;
- _farsetsel(flat_selector);
- p = (LPCData *) FARPKL(&n->rtqDatum);
- SetLPCData(p);
- FARPOKL(&p->service, LPC_SOCKGETHOSTBYADDR);
- args = (GetHostByAddrArgs *) p->Data;
- FARPOKL(&args->len, len);
- FARPOKL(&args->type, type);
- fmemcpyto(args->addr, addr, len);
-
- MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
- PostWindowsMessage();
-
- while ((n = MGenGetNode(REC_QUEUE)) == 0)
- Yield();
- r = (LPCReturn *) FARPKL(&n->rtqDatum);
- retVal = (struct hostent *) r->Data;
-
- if (FARPKL(&retVal->h_name) == 0) {
- retVal = 0;
- } else {
- ZapHostEnt();
-
- ReconstructHostEnt(&HostEnt, (void *) retVal);
- retVal = &HostEnt;
- }
-
- // get ready for next call
- MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
-
- return retVal;
-}
-
-
-SOCKET
-socket(int af, int type, int protocol)
-{
- RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
- LPCData *p;
- LPCReturn *r;
- SocketArgs *args;
- int retVal;
-
- _farsetsel(flat_selector);
- SocketError = 0;
- p = (LPCData *) FARPKL(&n->rtqDatum);
- SetLPCData(p);
- FARPOKL(&p->service, LPC_SOCKSOCKET);
- args = (SocketArgs *) p->Data;
- FARPOKL(&args->af, af);
- FARPOKL(&args->type, type);
- FARPOKL(&args->protocol, protocol);
-
- MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
- PostWindowsMessage();
-
- while ((n = MGenGetNode(REC_QUEUE)) == 0)
- Yield();
-
- r = (LPCReturn *) FARPKL(&n->rtqDatum);
-
-
- if (FARPKS(&r->error) != LPC_NOERROR) {
- return -1;
- }
-
- retVal = FARPKL(r->Data);
-
- // get ready for next call
- MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
-
- return retVal;
-}
-
-void
-sockets_flush(void)
-{
- RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
- LPCData *p;
-
- SocketError = 0;
- p = (LPCData *) FARPKL(&n->rtqDatum);
- SetLPCData(p);
- FARPOKL(&p->service, LPC_SOCKFLUSH);
-
- MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
- PostWindowsMessage();
-
- while ((n = MGenGetNode(REC_QUEUE)) == 0)
- Yield();
-
- MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
-}
-
-int
-recvfrom(SOCKET s, char *buf, int len, int flags, struct sockaddr *from,
- int *fromlen)
-{
- int i;
- RTQ_NODE *n;
- WinSockData *data;
- int bytesRead;
-
- SocketError = 0;
- _farsetsel(flat_selector);
- if (!SockMap)
- GetSocketMap();
-
- for (i = 0; i < MAXSOCKETS; i++) {
- if (FARPKL(&(SockMap->sock[i])) == s)
- break;
- }
-
- if (i == MAXSOCKETS)
- return SOCKET_ERROR;
-
- // pick up node
- n = MGenGetNode(i);
- if (n == 0) {
- SocketError = WSAEWOULDBLOCK;
- return -1;
- }
-
- data = (WinSockData *) FARPKL(&n->rtqDatum);
- bytesRead = FARPKL(&data->len);
-
- if (from) {
- fmemcpyfrom(from, &data->addr, sizeof(struct sockaddr));
- }
-
- if (fromlen) {
- *fromlen = FARPKL(&data->addrlen);
- }
-
- fmemcpyfrom(buf, data->data, len > bytesRead ? bytesRead : len);
-
- if ((flags & MSG_PEEK) == 0) {
- FreeBufferFromQueue(i);
- }
-
- return bytesRead;
-}
-
-int
-sendto(SOCKET s, const char *buf, int len, int flags, const struct sockaddr *to, int tolen)
-{
- int i;
- int outQ;
- WinSockData *data;
-
- SocketError = 0;
- _farsetsel(flat_selector);
- if (!SockMap)
- GetSocketMap();
-
- for (i = 0; i < MAXSOCKETS; i++) {
- if (FARPKL(&SockMap->sock[i]) == s) {
- break;
- }
- }
-
- if (i == MAXSOCKETS) {
- SocketError = WSAENOTSOCK;
- return SOCKET_ERROR;
- }
-
- outQ = i + MAXSOCKETS;
-
- if (MGenGetQueueCtr(outQ) >= QLIMIT) {
- SocketError = WSAEWOULDBLOCK;
- return SOCKET_ERROR;
- }
-
- data = GetFreeBufferToQueue(PRIVATEQ, len + sizeof(WinSockData));
-
- if (!data) {
- SocketError = WSAEWOULDBLOCK;
- return SOCKET_ERROR;
- }
-
- FARPOKL(&data->s, s);
- FARPOKL(&data->len, len);
- if (to) {
- fmemcpyto(&data->addr, to, tolen);
- FARPOKL(&data->addrlen, tolen);
- } else {
- FARPOKL(&data->addrlen, 0);
- }
-
- FARPOKL(&data->flags, flags);
-
- fmemcpyto(data->data, buf, len);
-
- MGenMoveTo(PRIVATEQ, outQ);
-
- return len;
-}
-
-int
-ioctlsocket(SOCKET s, long cmd, unsigned long *argp)
-{
- RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
- LPCData *p;
- LPCReturn *r;
- IoctlArgs *args;
- int retVal;
-
- SocketError = 0;
- _farsetsel(flat_selector);
- p = (LPCData *) FARPKL(&n->rtqDatum);
- SetLPCData(p);
- FARPOKL(&p->service, LPC_SOCKIOCTL);
- args = (IoctlArgs *) p->Data;
- FARPOKL(&args->s, s);
- FARPOKL(&args->cmd, cmd);
-
- switch(cmd) {
- case FIONBIO:
- FARPOKL(args->data, *argp);
- break;
- default:
- return SOCKET_ERROR;
- }
-
- MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
- PostWindowsMessage();
-
- while ((n = MGenGetNode(REC_QUEUE)) == 0)
- Yield();
-
- r = (LPCReturn *) FARPKL(&n->rtqDatum);
-
-
- retVal = FARPKL(r->Data);
-
- // get ready for next call
- MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
-
- return retVal;
-}
-
-int
-setsockopt(SOCKET s, int level, int optname, const char *optval, int optlen)
-{
- RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
- LPCData *p;
- LPCReturn *r;
- SetSockOptArgs *args;
- int retVal;
-
- SocketError = 0;
- _farsetsel(flat_selector);
- p = (LPCData *) FARPKL(&n->rtqDatum);
- SetLPCData(p);
- FARPOKL(&p->service, LPC_SOCKSETOPT);
- args = (SetSockOptArgs *) p->Data;
- FARPOKL(&args->s, s);
- FARPOKL(&args->level, level);
- FARPOKL(&args->optname, optname);
- FARPOKL(&args->optlen, optlen);
- fmemcpyto(args->optval, optval, optlen);
-
- MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
- PostWindowsMessage();
-
- while ((n = MGenGetNode(REC_QUEUE)) == 0)
- Yield();
-
- r = (LPCReturn *) FARPKL(&n->rtqDatum);
-
- retVal = FARPKL(r->Data);
-
- // get ready for next call
- MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
-
- return retVal;
-}
-
-int
-WSAGetLastError(void)
-{
- RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
- LPCData *p;
- LPCReturn *r;
- int retVal;
-
-
- _farsetsel(flat_selector);
- if (SocketError) {
- int err = SocketError;
-
- SocketError = 0;
- return err;
- }
-
- p = (LPCData *) FARPKL(&n->rtqDatum);
- SetLPCData(p);
- FARPOKL(&p->service, LPC_SOCKGETLASTERROR);
-
- MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
- PostWindowsMessage();
-
- while ((n = MGenGetNode(REC_QUEUE)) == 0)
- Yield();
-
- r = (LPCReturn *) FARPKL(&n->rtqDatum);
-
-
- retVal = FARPKL(r->Data);
-
- // get ready for next call
- MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
-
- return retVal;
-}
-
-unsigned long inet_addr(const char *cp)
-{
- int ret;
- unsigned int ha1, ha2, ha3, ha4;
- unsigned long ipaddr;
-
- ret = sscanf(cp, "%d.%d.%d.%d", &ha1, &ha2, &ha3, &ha4);
- if (ret != 4)
- return -1;
- ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4;
- return ipaddr;
-#if 0
- RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
- LPCData *p;
- LPCReturn *r;
- int retVal;
-
- SocketError = 0;
- _farsetsel(flat_selector);
- p = (LPCData *) FARPKL(&n->rtqDatum);
- SetLPCData(p);
- FARPOKL(&p->service, LPC_SOCKINETADDR);
-
- fstrcpyto(p->Data, cp);
-
- MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
- PostWindowsMessage();
-
- while ((n = MGenGetNode(REC_QUEUE)) == 0)
- Yield();
-
- r = (LPCReturn *) FARPKL(&n->rtqDatum);
-
- if (FARPKS(&r->error) != LPC_NOERROR) {
- return -1;
- }
-
- retVal = FARPKL(r->Data);
-
- // get ready for next call
- MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
-
- return retVal;
- #endif
-}
-
-char *inet_ntoa (struct in_addr in)
-{
- static char buf [32];
-
- 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);
- return buf;
-}
+/*
+Copyright (C) 1996-1997 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+#include <go32.h>
+#include "mpdosock.h"
+
+//#include "types.h"
+typedef unsigned char BYTE;
+typedef unsigned short WORD;
+typedef unsigned long DWORD;
+
+//#include "lpc.h"
+typedef struct {
+ short version; // version of LPC requested
+ short sizeOfArgs; // size of arguments
+ short service; // service # requested
+ char Data[1]; // data
+} LPCData;
+
+typedef struct {
+ short version; // LPC version
+ short sizeOfReturn; // return data size
+ short error; // any error codes
+ short noRet; // number of returns
+ char Data[1]; // data
+} LPCReturn;
+
+//#include "services.h"
+#define MAXSOCKETS 20
+
+// services
+#define LPC_SOCKBIND 4
+#define LPC_SOCKGETHOSTBYNAME 5
+#define LPC_SOCKGETHOSTNAME 6
+#define LPC_SOCKGETHOSTBYADDR 7
+#define LPC_SOCKCLOSE 8
+#define LPC_SOCKSOCKET 9
+#define LPC_SOCKRECVFROM 10
+#define LPC_SOCKSENDTO 11
+#define LPC_SOCKIOCTL 12
+#define LPC_SOCKGETSOCKNAME 13
+#define LPC_SOCKFLUSH 14
+#define LPC_SOCKSETOPT 15
+#define LPC_SOCKGETLASTERROR 16
+#define LPC_SOCKINETADDR 17
+
+// htons, ntohs, htonl, ntohl implemented locally
+
+// errors
+#define LPC_UNRECOGNIZED_SERVICE -1
+#define LPC_NOERROR 0
+
+// structures for support
+typedef struct {
+ SOCKET s;
+ int namelen;
+ char name[1];
+} BindArgs;
+
+typedef struct {
+ SOCKET s;
+ long cmd;
+ char data[1];
+} IoctlArgs;
+
+typedef struct {
+ int retVal;
+ int namelen;
+ char name[1];
+} GetSockNameRet;
+
+typedef GetSockNameRet GetHostNameRet;
+
+typedef struct {
+ int retVal;
+ int h_addr_0; // that's the only important value
+} GetHostByNameRet;
+
+typedef struct {
+ int len;
+ int type;
+ char addr[1];
+} GetHostByAddrArgs;
+
+typedef struct {
+ int retVal;
+ char h_name[1]; // h_name is the only important value
+} GetHostByAddrRet;
+
+typedef struct {
+ SOCKET s;
+ int flags;
+} RecvFromArgs;
+
+typedef struct {
+ int retVal;
+ int errCode;
+ int len; // message len
+ struct sockaddr sockaddr;
+ int sockaddrlen;
+ char Data[1];
+} RecvFromRet;
+
+typedef struct {
+ SOCKET s;
+ int flags;
+ int len;
+ struct sockaddr sockaddr;
+ int sockaddrlen;
+ char Data[1];
+} SendToArgs;
+
+typedef struct {
+ int retVal;
+ int errCode;
+} SendToRet;
+
+typedef struct {
+ int bufflen;
+ SOCKET s;
+ int len;
+ int sockaddrlen;
+ struct sockaddr address;
+ char data[1];
+} SocketChannelData;
+
+typedef struct {
+ int af;
+ int type;
+ int protocol;
+} SocketArgs;
+
+typedef struct {
+ SOCKET s;
+ int len;
+ int flags;
+ int addrlen;
+ struct sockaddr addr;
+ char data[1];
+} WinSockData;
+
+typedef struct {
+ SOCKET s;
+ int level;
+ int optname;
+ int optlen;
+ char optval[1];
+} SetSockOptArgs;
+
+typedef struct {
+ SOCKET sock[MAXSOCKETS];
+} SocketMap;
+
+//#include "rtq.h"
+#define RTQ_NODE struct rtq_node
+
+RTQ_NODE
+ {
+ RTQ_NODE *self; // Ring zero address of this node
+ RTQ_NODE *left; // Ring zero address of preceding node
+ RTQ_NODE *right; // Ring zero address of succeding node
+ BYTE * rtqDatum; // Ring 3 Datum of Buffer (start of preface)
+ BYTE * rtqInsert; // Ring 3 insertion position
+ WORD rtqLen; // Length of buffer, excluding preface
+ WORD rtqUpCtr; // Up Counter of bytes used so far
+ WORD rtqQCtr; // number of nodes attached
+ WORD padding; // DWORD alignment
+ };
+
+#define RTQ_PARAM_MOVENODE struct rtq_param_movenode
+RTQ_PARAM_MOVENODE
+ {
+ WORD rtqFromDQ;
+ WORD rtqToDQ;
+ };
+
+RTQ_NODE* rtq_fetch(RTQ_NODE*, RTQ_NODE*); // To, From
+
+//#include "mplib.h"
+// give up time slice
+void Yield(void);
+void MGenWakeupDll(void);
+
+// post a message to win32 side
+void PostWindowsMessage(void);
+
+// get # of items on qNo
+int MGenGetQueueCtr(int qNo);
+
+// move first node from qFrom to qTo
+RTQ_NODE *MGenMoveTo(int qFrom, int qTo);
+
+// get first node from q
+RTQ_NODE *MGenGetNode(int q);
+
+// get master node, returning size of RTQ_NODE for size verification
+RTQ_NODE *MGenGetMasterNode(unsigned *size);
+
+// move all nodes from qFrom to qTo
+RTQ_NODE *MGenFlushNodes(int qFrom, int qTo);
+
+// count number of nodes in queues designated by bitmask
+// lowerOrderBits == 0..31, upperOrderBits == 32-63
+int MGenMCount(unsigned lowerOrderBits, unsigned upperOrderBits);
+
+// perform consistency check on chunnel address space
+int MGenSanityCheck(void);
+
+#include <stdio.h>
+#include <sys/farptr.h>
+
+extern short flat_selector;
+
+#define SOCKET_MAP_QUEUE 41
+
+#define IDLE_QUEUE 44
+#define REC_QUEUE 45
+#define SEND_QUEUE 46
+
+// queue sizes
+#define FREEQBASE 58
+#define FREEQ64 58
+#define FREEQ128 59
+#define FREEQ256 60
+#define FREEQ512 61
+#define FREEQ1024 62
+#define FREEQ2048 63
+
+#define NFREEQ 6
+
+#define QLIMIT 10
+
+#define PRIVATEQ 50
+
+#define FARPKL(x) (_farnspeekl((unsigned long) x))
+#define FARPKB(x) (_farnspeekb((unsigned long) x))
+#define FARPKS(x) (_farnspeekw((unsigned long) x))
+
+#define FARPOKL(x, y) (_farnspokel((unsigned long) x, (unsigned long) y))
+#define FARPOKB(x, y) (_farnspokeb((unsigned long) x, (unsigned char) y))
+
+int Qsizes[] = { 64, 128, 256, 512, 1024, 2048 };
+
+int SocketError = 0;
+
+SocketMap *SockMap;
+
+#define HOSTENT_ALIAS_LIMIT 5
+#define HOSTENT_STRLEN_LIMIT 50
+#define HOSTENT_ADDR_LIST_LIMIT 5
+
+struct hostent HostEnt;
+
+char HostEnt_hname[HOSTENT_STRLEN_LIMIT];
+char *HostEnt_h_aliases[HOSTENT_ALIAS_LIMIT];
+char HostEnt_names[HOSTENT_ALIAS_LIMIT][HOSTENT_STRLEN_LIMIT];
+struct in_addr* HostEnt_addr_list[HOSTENT_ADDR_LIST_LIMIT];
+struct in_addr HostEnt_addrs[HOSTENT_ADDR_LIST_LIMIT];
+
+void
+fmemcpyto(void *to, const void *from, int length)
+{
+ movedata(_my_ds(), (unsigned)from, flat_selector, (unsigned)to, length);
+}
+
+void
+fmemcpyfrom(void *to, const void *from, int length)
+{
+ movedata(flat_selector, (unsigned)from, _my_ds(), (unsigned)to, length);
+}
+
+void
+fstrcpyto(char *to, const char *from)
+{
+ while (*from) {
+ FARPOKB(to, *from);
+ to++; from++;
+ }
+ FARPOKB(to, 0);
+}
+
+void
+fstrncpyto(char *to, const char *from, int len)
+{
+ while (*from && len) {
+ FARPOKB(to, *from);
+ to++; from++; len--;
+ }
+ FARPOKB(to, 0);
+}
+
+void
+fstrcpyfrom(char *to, const char *from)
+{
+ while (FARPKB(from)) {
+ *to = FARPKB(from);
+ from++; to++;
+ }
+ *to = 0;
+}
+
+void
+fstrncpyfrom(char *to, const char *from, int len)
+{
+ while (FARPKB(from) && len) {
+ *to = FARPKB(from);
+ from++; to++; len--;
+ }
+ *to = 0;
+}
+
+void
+GetSocketMap(void)
+{
+ RTQ_NODE *n = MGenGetNode(SOCKET_MAP_QUEUE);
+
+ SockMap = (SocketMap *) FARPKL(&n->rtqDatum);
+}
+
+void *
+GetFreeBufferToQueue(int q, int bufSize)
+{
+ int i;
+
+ for (i = 0; i < NFREEQ; i++) {
+ if (Qsizes[i] >= bufSize && MGenGetQueueCtr(i+FREEQBASE)) {
+ RTQ_NODE *n = MGenMoveTo(i+FREEQBASE, q);
+ if (!n)
+ continue;
+ FARPOKL(&n->rtqUpCtr, bufSize);
+ return (void *) FARPKL(&n->rtqDatum);
+ }
+ }
+
+ return 0;
+}
+
+void
+FreeBufferFromQueue(int q)
+{
+ int i;
+ RTQ_NODE *n = MGenGetNode(q);
+
+ for (i = 0; i < NFREEQ; i++) {
+ if (Qsizes[i] == FARPKS(&n->rtqLen)) {
+ MGenMoveTo(q, i+FREEQBASE);
+ return;
+ }
+ }
+}
+
+void
+SetLPCData(LPCData *lpc)
+{
+
+ FARPOKL(&(lpc->version), 1);
+ FARPOKL(&(lpc->sizeOfArgs), 0);
+ FARPOKL(&(lpc->service), 0);
+}
+
+int
+bind(SOCKET s, const struct sockaddr *name, int namelen)
+{
+ RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
+ LPCData *p;
+ LPCReturn *r;
+ BindArgs *bargs;
+ int retVal;
+
+ _farsetsel(flat_selector);
+ SocketError = 0;
+ p = (LPCData *) FARPKL(&n->rtqDatum);
+ SetLPCData(p);
+ FARPOKL(&p->service, LPC_SOCKBIND);
+ bargs = (BindArgs *) p->Data;
+ FARPOKL(&bargs->s, s);
+ FARPOKL(&bargs->namelen, namelen);
+ fmemcpyto(bargs->name, name, namelen);
+ MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
+ PostWindowsMessage();
+
+ while ((n = MGenGetNode(REC_QUEUE)) == 0)
+ Yield();
+
+ r = (LPCReturn *) FARPKL(&n->rtqDatum);
+
+ if (FARPKS(&r->error) != LPC_NOERROR) {
+ return -1;
+ }
+
+ retVal = FARPKL(r->Data);
+
+ // get ready for next call
+ MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
+
+ return retVal;
+}
+
+int
+closesocket(SOCKET s)
+{
+ RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
+ LPCData *p;
+ LPCReturn *r;
+ int retVal;
+
+ _farsetsel(flat_selector);
+ SocketError = 0;
+ p = (LPCData *) FARPKL(&n->rtqDatum);
+ SetLPCData(p);
+ FARPOKL(&p->service, LPC_SOCKCLOSE);
+ FARPOKL(p->Data, s);
+
+ MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
+ PostWindowsMessage();
+
+ while ((n = MGenGetNode(REC_QUEUE)) == 0)
+ Yield();
+
+ r = (LPCReturn *) FARPKL(&n->rtqDatum);
+
+ if (FARPKS(&r->error) != LPC_NOERROR) {
+ return -1;
+ }
+
+ retVal = FARPKL(r->Data);
+
+ // get ready for next call
+ MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
+
+ return retVal;
+}
+
+void
+ZapHostEnt()
+{
+ // do nothing
+}
+
+void
+ReconstructHostEnt(struct hostent *s, void *flattened)
+{
+ struct hostent *old = (struct hostent *) flattened;
+ int i;
+ char **ptr;
+
+
+ s->h_name = HostEnt_hname;
+ fstrncpyfrom(s->h_name, (char *) FARPKL(&old->h_name), HOSTENT_STRLEN_LIMIT-1);
+ s->h_name[HOSTENT_STRLEN_LIMIT-1] = 0;
+
+ s->h_aliases = HostEnt_h_aliases;
+ ptr = (char **) FARPKL(&old->h_aliases);
+ for (i = 0; i < (HOSTENT_ALIAS_LIMIT-1) && FARPKL(ptr); i++, ptr++) {
+ s->h_aliases[i] = HostEnt_names[i];
+ // fstrncpyfrom(s->h_aliases[i], (void *) FARPKL(ptr), HOSTENT_STRLEN_LIMIT-1);
+ s->h_aliases[i][HOSTENT_STRLEN_LIMIT-1] = 0;
+ }
+ s->h_aliases[i] = 0;
+
+ s->h_addrtype = FARPKS(&old->h_addrtype);
+ s->h_length = FARPKS(&old->h_length);
+
+ if (FARPKS(&old->h_length) != sizeof(struct in_addr)) {
+ printf("Error!\n");
+ exit(0);
+ }
+
+ s->h_addr_list = (char **) HostEnt_addr_list;
+ ptr = (char **) FARPKL(&old->h_addr_list);
+ for (i = 0; i < (HOSTENT_ADDR_LIST_LIMIT - 1) && FARPKL(ptr); i++, ptr++) {
+ s->h_addr_list[i] = (char *) &(HostEnt_addrs[i]);
+ fmemcpyfrom(s->h_addr_list[i], (void *) FARPKL(ptr), s->h_length);
+ }
+ s->h_addr_list[i] = 0;
+}
+
+
+int
+getsockname(SOCKET s, struct sockaddr *name, int *namelen)
+{
+ RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
+ LPCData *p;
+ LPCReturn *r;
+ GetSockNameRet *ret;
+ int retVal;
+
+ SocketError = 0;
+ _farsetsel(flat_selector);
+ p = (LPCData *) FARPKL(&n->rtqDatum);
+ SetLPCData(p);
+ FARPOKL(&p->service, LPC_SOCKGETSOCKNAME);
+ FARPOKL(p->Data, s);
+
+ MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
+ PostWindowsMessage();
+
+ while ((n = MGenGetNode(REC_QUEUE)) == 0)
+ Yield();
+
+
+ r = (LPCReturn *) FARPKL(&n->rtqDatum);
+
+ if (FARPKS(&r->error) != LPC_NOERROR) {
+ return -1;
+ }
+
+ ret = (GetSockNameRet *) r->Data;
+ retVal = FARPKL(&ret->retVal);
+ fmemcpyfrom(name, ret->name, FARPKL(&ret->namelen));
+ *namelen = FARPKL(&ret->namelen);
+
+ // get ready for next call
+ MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
+
+ return retVal;
+}
+
+int
+gethostname(char *name, int namelen)
+{
+ RTQ_NODE *n;
+ LPCData *p;
+ LPCReturn *r;
+ GetHostNameRet *ret;
+ int retVal;
+ char *s;
+
+ _farsetsel(flat_selector);
+ SocketError = 0;
+ n = (RTQ_NODE *) MGenGetNode(IDLE_QUEUE);
+ p = (LPCData *) FARPKL(&n->rtqDatum);
+ SetLPCData(p);
+ FARPOKL(&p->service,LPC_SOCKGETHOSTNAME);
+ MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
+ PostWindowsMessage();
+
+ while ((n = (RTQ_NODE *) (MGenGetNode(REC_QUEUE))) == 0)
+ Yield();
+
+ r = (LPCReturn *) FARPKL(&n->rtqDatum);
+
+ if (FARPKS(&r->error) != LPC_NOERROR) {
+ return -1;
+ }
+
+ ret = (GetHostNameRet *) r->Data;
+
+ retVal = FARPKL(&ret->retVal);
+
+ s = ret->name;
+
+ fstrncpyfrom(name, s, namelen);
+
+#if 0
+ len = strlen(ret->name);
+
+ if (len > namelen)
+ memcpy(name, ret->name, ret->namelen);
+ else
+ strcpy(name, ret->name);
+#endif
+
+ // get ready for next call
+ MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
+
+ return retVal;
+}
+
+struct hostent *
+gethostbyname(const char *name)
+{
+ RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
+ LPCData *p;
+ LPCReturn *r;
+ struct hostent *retVal;
+
+ _farsetsel(flat_selector);
+ SocketError = 0;
+ p = (LPCData *) FARPKL(&n->rtqDatum);
+ SetLPCData(p);
+ FARPOKL(&p->service, LPC_SOCKGETHOSTBYNAME);
+ fstrcpyto(p->Data, name);
+
+ MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
+ PostWindowsMessage();
+
+ while ((n = MGenGetNode(REC_QUEUE)) == 0)
+ Yield();
+
+ r = (LPCReturn *) FARPKL(&n->rtqDatum);
+ retVal = (struct hostent *) r->Data;
+
+ if (FARPKL(&retVal->h_name) == 0) {
+ retVal = 0;
+ } else {
+ ZapHostEnt();
+ ReconstructHostEnt(&HostEnt, (void *) retVal);
+ retVal = &HostEnt;
+ }
+
+ // get ready for next call
+ MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
+
+ return retVal;
+}
+
+struct hostent *
+gethostbyaddr(const char *addr, int len, int type)
+{
+ RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
+ LPCData *p;
+ LPCReturn *r;
+ GetHostByAddrArgs *args;
+ struct hostent *retVal;
+
+ SocketError = 0;
+ _farsetsel(flat_selector);
+ p = (LPCData *) FARPKL(&n->rtqDatum);
+ SetLPCData(p);
+ FARPOKL(&p->service, LPC_SOCKGETHOSTBYADDR);
+ args = (GetHostByAddrArgs *) p->Data;
+ FARPOKL(&args->len, len);
+ FARPOKL(&args->type, type);
+ fmemcpyto(args->addr, addr, len);
+
+ MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
+ PostWindowsMessage();
+
+ while ((n = MGenGetNode(REC_QUEUE)) == 0)
+ Yield();
+ r = (LPCReturn *) FARPKL(&n->rtqDatum);
+ retVal = (struct hostent *) r->Data;
+
+ if (FARPKL(&retVal->h_name) == 0) {
+ retVal = 0;
+ } else {
+ ZapHostEnt();
+
+ ReconstructHostEnt(&HostEnt, (void *) retVal);
+ retVal = &HostEnt;
+ }
+
+ // get ready for next call
+ MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
+
+ return retVal;
+}
+
+
+SOCKET
+socket(int af, int type, int protocol)
+{
+ RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
+ LPCData *p;
+ LPCReturn *r;
+ SocketArgs *args;
+ int retVal;
+
+ _farsetsel(flat_selector);
+ SocketError = 0;
+ p = (LPCData *) FARPKL(&n->rtqDatum);
+ SetLPCData(p);
+ FARPOKL(&p->service, LPC_SOCKSOCKET);
+ args = (SocketArgs *) p->Data;
+ FARPOKL(&args->af, af);
+ FARPOKL(&args->type, type);
+ FARPOKL(&args->protocol, protocol);
+
+ MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
+ PostWindowsMessage();
+
+ while ((n = MGenGetNode(REC_QUEUE)) == 0)
+ Yield();
+
+ r = (LPCReturn *) FARPKL(&n->rtqDatum);
+
+
+ if (FARPKS(&r->error) != LPC_NOERROR) {
+ return -1;
+ }
+
+ retVal = FARPKL(r->Data);
+
+ // get ready for next call
+ MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
+
+ return retVal;
+}
+
+void
+sockets_flush(void)
+{
+ RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
+ LPCData *p;
+
+ SocketError = 0;
+ p = (LPCData *) FARPKL(&n->rtqDatum);
+ SetLPCData(p);
+ FARPOKL(&p->service, LPC_SOCKFLUSH);
+
+ MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
+ PostWindowsMessage();
+
+ while ((n = MGenGetNode(REC_QUEUE)) == 0)
+ Yield();
+
+ MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
+}
+
+int
+recvfrom(SOCKET s, char *buf, int len, int flags, struct sockaddr *from,
+ int *fromlen)
+{
+ int i;
+ RTQ_NODE *n;
+ WinSockData *data;
+ int bytesRead;
+
+ SocketError = 0;
+ _farsetsel(flat_selector);
+ if (!SockMap)
+ GetSocketMap();
+
+ for (i = 0; i < MAXSOCKETS; i++) {
+ if (FARPKL(&(SockMap->sock[i])) == s)
+ break;
+ }
+
+ if (i == MAXSOCKETS)
+ return SOCKET_ERROR;
+
+ // pick up node
+ n = MGenGetNode(i);
+ if (n == 0) {
+ SocketError = WSAEWOULDBLOCK;
+ return -1;
+ }
+
+ data = (WinSockData *) FARPKL(&n->rtqDatum);
+ bytesRead = FARPKL(&data->len);
+
+ if (from) {
+ fmemcpyfrom(from, &data->addr, sizeof(struct sockaddr));
+ }
+
+ if (fromlen) {
+ *fromlen = FARPKL(&data->addrlen);
+ }
+
+ fmemcpyfrom(buf, data->data, len > bytesRead ? bytesRead : len);
+
+ if ((flags & MSG_PEEK) == 0) {
+ FreeBufferFromQueue(i);
+ }
+
+ return bytesRead;
+}
+
+int
+sendto(SOCKET s, const char *buf, int len, int flags, const struct sockaddr *to, int tolen)
+{
+ int i;
+ int outQ;
+ WinSockData *data;
+
+ SocketError = 0;
+ _farsetsel(flat_selector);
+ if (!SockMap)
+ GetSocketMap();
+
+ for (i = 0; i < MAXSOCKETS; i++) {
+ if (FARPKL(&SockMap->sock[i]) == s) {
+ break;
+ }
+ }
+
+ if (i == MAXSOCKETS) {
+ SocketError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+
+ outQ = i + MAXSOCKETS;
+
+ if (MGenGetQueueCtr(outQ) >= QLIMIT) {
+ SocketError = WSAEWOULDBLOCK;
+ return SOCKET_ERROR;
+ }
+
+ data = GetFreeBufferToQueue(PRIVATEQ, len + sizeof(WinSockData));
+
+ if (!data) {
+ SocketError = WSAEWOULDBLOCK;
+ return SOCKET_ERROR;
+ }
+
+ FARPOKL(&data->s, s);
+ FARPOKL(&data->len, len);
+ if (to) {
+ fmemcpyto(&data->addr, to, tolen);
+ FARPOKL(&data->addrlen, tolen);
+ } else {
+ FARPOKL(&data->addrlen, 0);
+ }
+
+ FARPOKL(&data->flags, flags);
+
+ fmemcpyto(data->data, buf, len);
+
+ MGenMoveTo(PRIVATEQ, outQ);
+
+ return len;
+}
+
+int
+ioctlsocket(SOCKET s, long cmd, unsigned long *argp)
+{
+ RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
+ LPCData *p;
+ LPCReturn *r;
+ IoctlArgs *args;
+ int retVal;
+
+ SocketError = 0;
+ _farsetsel(flat_selector);
+ p = (LPCData *) FARPKL(&n->rtqDatum);
+ SetLPCData(p);
+ FARPOKL(&p->service, LPC_SOCKIOCTL);
+ args = (IoctlArgs *) p->Data;
+ FARPOKL(&args->s, s);
+ FARPOKL(&args->cmd, cmd);
+
+ switch(cmd) {
+ case FIONBIO:
+ FARPOKL(args->data, *argp);
+ break;
+ default:
+ return SOCKET_ERROR;
+ }
+
+ MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
+ PostWindowsMessage();
+
+ while ((n = MGenGetNode(REC_QUEUE)) == 0)
+ Yield();
+
+ r = (LPCReturn *) FARPKL(&n->rtqDatum);
+
+
+ retVal = FARPKL(r->Data);
+
+ // get ready for next call
+ MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
+
+ return retVal;
+}
+
+int
+setsockopt(SOCKET s, int level, int optname, const char *optval, int optlen)
+{
+ RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
+ LPCData *p;
+ LPCReturn *r;
+ SetSockOptArgs *args;
+ int retVal;
+
+ SocketError = 0;
+ _farsetsel(flat_selector);
+ p = (LPCData *) FARPKL(&n->rtqDatum);
+ SetLPCData(p);
+ FARPOKL(&p->service, LPC_SOCKSETOPT);
+ args = (SetSockOptArgs *) p->Data;
+ FARPOKL(&args->s, s);
+ FARPOKL(&args->level, level);
+ FARPOKL(&args->optname, optname);
+ FARPOKL(&args->optlen, optlen);
+ fmemcpyto(args->optval, optval, optlen);
+
+ MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
+ PostWindowsMessage();
+
+ while ((n = MGenGetNode(REC_QUEUE)) == 0)
+ Yield();
+
+ r = (LPCReturn *) FARPKL(&n->rtqDatum);
+
+ retVal = FARPKL(r->Data);
+
+ // get ready for next call
+ MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
+
+ return retVal;
+}
+
+int
+WSAGetLastError(void)
+{
+ RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
+ LPCData *p;
+ LPCReturn *r;
+ int retVal;
+
+
+ _farsetsel(flat_selector);
+ if (SocketError) {
+ int err = SocketError;
+
+ SocketError = 0;
+ return err;
+ }
+
+ p = (LPCData *) FARPKL(&n->rtqDatum);
+ SetLPCData(p);
+ FARPOKL(&p->service, LPC_SOCKGETLASTERROR);
+
+ MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
+ PostWindowsMessage();
+
+ while ((n = MGenGetNode(REC_QUEUE)) == 0)
+ Yield();
+
+ r = (LPCReturn *) FARPKL(&n->rtqDatum);
+
+
+ retVal = FARPKL(r->Data);
+
+ // get ready for next call
+ MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
+
+ return retVal;
+}
+
+unsigned long inet_addr(const char *cp)
+{
+ int ret;
+ unsigned int ha1, ha2, ha3, ha4;
+ unsigned long ipaddr;
+
+ ret = sscanf(cp, "%d.%d.%d.%d", &ha1, &ha2, &ha3, &ha4);
+ if (ret != 4)
+ return -1;
+ ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4;
+ return ipaddr;
+#if 0
+ RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
+ LPCData *p;
+ LPCReturn *r;
+ int retVal;
+
+ SocketError = 0;
+ _farsetsel(flat_selector);
+ p = (LPCData *) FARPKL(&n->rtqDatum);
+ SetLPCData(p);
+ FARPOKL(&p->service, LPC_SOCKINETADDR);
+
+ fstrcpyto(p->Data, cp);
+
+ MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
+ PostWindowsMessage();
+
+ while ((n = MGenGetNode(REC_QUEUE)) == 0)
+ Yield();
+
+ r = (LPCReturn *) FARPKL(&n->rtqDatum);
+
+ if (FARPKS(&r->error) != LPC_NOERROR) {
+ return -1;
+ }
+
+ retVal = FARPKL(r->Data);
+
+ // get ready for next call
+ MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
+
+ return retVal;
+ #endif
+}
+
+char *inet_ntoa (struct in_addr in)
+{
+ static char buf [32];
+
+ 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);
+ return buf;
+}