mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 12:52:46 +00:00
1033 lines
20 KiB
C
1033 lines
20 KiB
C
|
|
/*
|
|
mplpc.c
|
|
|
|
@description@
|
|
|
|
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:
|
|
|
|
Free Software Foundation, Inc.
|
|
59 Temple Place - Suite 330
|
|
Boston, MA 02111-1307, USA
|
|
|
|
*/
|
|
static const char rcsid[] =
|
|
"$Id$";
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#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>
|
|
|
|
|
|
#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)) {
|
|
Con_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];
|
|
|
|
snprintf (buf, sizeof (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;
|
|
}
|