quakeforge-old/uquake/mplpc.c
Jeff Teunissen c3f5581b0a Created new subdir: uquake. Pick your favorite U word for the meaning --
Unchained, Ultimate, Ultra, Up Yours, Underworld, Underground, Unified,
Unity, etc. You know the drill.

This takes care of the "standalone" problem with the wrong name, and the
recent snafu with multiple developers working on the same files
simultaneously...expect me (and probably others) to start locking dirs when
updates are taking place.

And yes, this update is really as large as it looks. Software only at the
moment, but I will have the makefile updated to build the GL builds as
well.
1999-12-26 13:51:52 +00:00

1001 lines
21 KiB
C

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