diff options
| author | Travis Bradshaw <travis.bradshaw@idsoftware.com> | 2012-01-31 14:32:09 -0600 |
|---|---|---|
| committer | Travis Bradshaw <travis.bradshaw@idsoftware.com> | 2012-01-31 14:32:09 -0600 |
| commit | 0023db327bc1db00068284b70e1db45857aeee35 (patch) | |
| tree | 01dd8366d20bd674741cfe8ceb069d82a2e33973 /WinQuake/mplpc.c | |
| download | quake-pum-0023db327bc1db00068284b70e1db45857aeee35.tar.gz | |
The Quake sources as originally release under the GPL license on December 21, 1999
Diffstat (limited to 'WinQuake/mplpc.c')
| -rw-r--r-- | WinQuake/mplpc.c | 1001 |
1 files changed, 1001 insertions, 0 deletions
diff --git a/WinQuake/mplpc.c b/WinQuake/mplpc.c new file mode 100644 index 0000000..10bc564 --- /dev/null +++ b/WinQuake/mplpc.c @@ -0,0 +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; +} |
