/* | |
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; | |
} |