Home | History | Annotate | Download | only in WinQuake
      1 /*
      2 Copyright (C) 1996-1997 Id Software, Inc.
      3 
      4 This program is free software; you can redistribute it and/or
      5 modify it under the terms of the GNU General Public License
      6 as published by the Free Software Foundation; either version 2
      7 of the License, or (at your option) any later version.
      8 
      9 This program is distributed in the hope that it will be useful,
     10 but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     12 
     13 See the GNU General Public License for more details.
     14 
     15 You should have received a copy of the GNU General Public License
     16 along with this program; if not, write to the Free Software
     17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     18 
     19 */
     20 #include <go32.h>
     21 #include "mpdosock.h"
     22 
     23 //#include "types.h"
     24 typedef unsigned char BYTE;
     25 typedef unsigned short WORD;
     26 typedef unsigned long DWORD;
     27 
     28 //#include "lpc.h"
     29 typedef struct {
     30    short  version;            // version of LPC requested
     31    short  sizeOfArgs;         // size of arguments
     32    short  service;            // service # requested
     33    char   Data[1];            // data
     34 } LPCData;
     35 
     36 typedef struct {
     37    short version;             // LPC version
     38    short sizeOfReturn;        // return data size
     39    short error;               // any error codes
     40    short noRet;               // number of returns
     41    char  Data[1];             // data
     42 } LPCReturn;
     43 
     44 //#include "services.h"
     45 #define  MAXSOCKETS  20
     46 
     47 // services
     48 #define LPC_SOCKBIND        4
     49 #define LPC_SOCKGETHOSTBYNAME   5
     50 #define LPC_SOCKGETHOSTNAME     6
     51 #define LPC_SOCKGETHOSTBYADDR   7
     52 #define LPC_SOCKCLOSE           8
     53 #define LPC_SOCKSOCKET          9
     54 #define LPC_SOCKRECVFROM        10
     55 #define LPC_SOCKSENDTO          11
     56 #define LPC_SOCKIOCTL           12
     57 #define LPC_SOCKGETSOCKNAME     13
     58 #define LPC_SOCKFLUSH           14
     59 #define LPC_SOCKSETOPT          15
     60 #define LPC_SOCKGETLASTERROR    16
     61 #define LPC_SOCKINETADDR        17
     62 
     63 // htons, ntohs, htonl, ntohl implemented locally
     64 
     65 // errors
     66 #define LPC_UNRECOGNIZED_SERVICE  -1
     67 #define LPC_NOERROR                0
     68 
     69 // structures for support
     70 typedef struct {
     71    SOCKET s;
     72    int    namelen;
     73    char   name[1];
     74 } BindArgs;
     75 
     76 typedef struct {
     77    SOCKET s;
     78    long   cmd;
     79    char   data[1];
     80 } IoctlArgs;
     81 
     82 typedef struct {
     83    int retVal;
     84    int namelen;
     85    char name[1];
     86 } GetSockNameRet;
     87 
     88 typedef GetSockNameRet GetHostNameRet;
     89 
     90 typedef struct {
     91    int   retVal;
     92    int   h_addr_0;    // that's the only important value
     93 } GetHostByNameRet;
     94 
     95 typedef struct {
     96    int   len;
     97    int   type;
     98    char  addr[1];
     99 } GetHostByAddrArgs;
    100 
    101 typedef struct {
    102    int   retVal;
    103    char  h_name[1];  // h_name is the only important value
    104 } GetHostByAddrRet;
    105 
    106 typedef struct {
    107    SOCKET s;
    108    int flags;
    109 } RecvFromArgs;
    110 
    111 typedef struct {
    112    int  retVal;
    113    int  errCode;
    114    int  len;   // message len
    115    struct sockaddr    sockaddr;
    116    int  sockaddrlen;
    117    char Data[1];
    118 } RecvFromRet;
    119 
    120 typedef struct {
    121    SOCKET s;
    122    int    flags;
    123    int    len;
    124    struct sockaddr sockaddr;
    125    int    sockaddrlen;
    126    char   Data[1];
    127 } SendToArgs;
    128 
    129 typedef struct {
    130    int   retVal;
    131    int   errCode;
    132 } SendToRet;
    133 
    134 typedef struct {
    135    int     bufflen;
    136    SOCKET  s;
    137    int     len;
    138    int     sockaddrlen;
    139    struct sockaddr    address;
    140    char               data[1];
    141 } SocketChannelData;
    142 
    143 typedef struct {
    144    int af;
    145    int type;
    146    int protocol;
    147 } SocketArgs;
    148 
    149 typedef struct {
    150    SOCKET s;
    151    int len;
    152    int flags;
    153    int addrlen;
    154    struct sockaddr addr;
    155    char data[1];
    156 } WinSockData;
    157 
    158 typedef struct {
    159    SOCKET s;
    160    int level;
    161    int optname;
    162    int optlen;
    163    char optval[1];
    164 } SetSockOptArgs;
    165 
    166 typedef struct {
    167    SOCKET   sock[MAXSOCKETS];
    168 } SocketMap;
    169 
    170 //#include "rtq.h"
    171 #define RTQ_NODE struct rtq_node
    172 
    173 RTQ_NODE
    174    {
    175       RTQ_NODE *self; // Ring zero address of this node
    176       RTQ_NODE *left; // Ring zero address of preceding node
    177       RTQ_NODE *right; // Ring zero address of succeding node
    178       BYTE *      rtqDatum;  // Ring 3 Datum of Buffer (start of preface)
    179       BYTE *      rtqInsert; // Ring 3 insertion position
    180       WORD     rtqLen; // Length of buffer, excluding preface
    181       WORD     rtqUpCtr;  // Up Counter of bytes used so far
    182       WORD     rtqQCtr;   // number of nodes attached
    183       WORD     padding;   // DWORD alignment
    184    };
    185 
    186 #define RTQ_PARAM_MOVENODE struct rtq_param_movenode
    187 RTQ_PARAM_MOVENODE
    188    {
    189       WORD     rtqFromDQ;
    190       WORD     rtqToDQ;
    191    };
    192 
    193 RTQ_NODE* rtq_fetch(RTQ_NODE*, RTQ_NODE*); // To, From
    194 
    195 //#include "mplib.h"
    196 // give up time slice
    197 void Yield(void);
    198 void MGenWakeupDll(void);
    199 
    200 // post a message to win32 side
    201 void PostWindowsMessage(void);
    202 
    203 // get # of items on qNo
    204 int MGenGetQueueCtr(int qNo);
    205 
    206 // move first node from qFrom to qTo
    207 RTQ_NODE *MGenMoveTo(int qFrom, int qTo);
    208 
    209 // get first node from q
    210 RTQ_NODE *MGenGetNode(int q);
    211 
    212 // get master node, returning size of RTQ_NODE for size verification
    213 RTQ_NODE *MGenGetMasterNode(unsigned *size);
    214 
    215 // move all nodes from qFrom to qTo
    216 RTQ_NODE *MGenFlushNodes(int qFrom, int qTo);
    217 
    218 // count number of nodes in queues designated by bitmask
    219 // lowerOrderBits == 0..31, upperOrderBits == 32-63
    220 int MGenMCount(unsigned lowerOrderBits, unsigned upperOrderBits);
    221 
    222 // perform consistency check on chunnel address space
    223 int MGenSanityCheck(void);
    224 
    225 #include <stdio.h>
    226 #include <sys/farptr.h>
    227 
    228 extern short flat_selector;
    229 
    230 #define SOCKET_MAP_QUEUE  41
    231 
    232 #define IDLE_QUEUE    44
    233 #define REC_QUEUE     45
    234 #define SEND_QUEUE    46
    235 
    236 //  queue sizes
    237 #define FREEQBASE      58
    238 #define FREEQ64        58
    239 #define FREEQ128       59
    240 #define FREEQ256       60
    241 #define FREEQ512       61
    242 #define FREEQ1024      62
    243 #define FREEQ2048      63
    244 
    245 #define NFREEQ         6
    246 
    247 #define QLIMIT         10
    248 
    249 #define PRIVATEQ       50
    250 
    251 #define FARPKL(x)  (_farnspeekl((unsigned long) x))
    252 #define FARPKB(x)  (_farnspeekb((unsigned long) x))
    253 #define FARPKS(x)  (_farnspeekw((unsigned long) x))
    254 
    255 #define FARPOKL(x, y) (_farnspokel((unsigned long) x, (unsigned long) y))
    256 #define FARPOKB(x, y) (_farnspokeb((unsigned long) x, (unsigned char) y))
    257 
    258 int Qsizes[] = { 64, 128, 256, 512, 1024, 2048 };
    259 
    260 int SocketError = 0;
    261 
    262 SocketMap *SockMap;
    263 
    264 #define HOSTENT_ALIAS_LIMIT    5
    265 #define HOSTENT_STRLEN_LIMIT   50
    266 #define HOSTENT_ADDR_LIST_LIMIT   5
    267 
    268 struct hostent  HostEnt;
    269 
    270 char HostEnt_hname[HOSTENT_STRLEN_LIMIT];
    271 char *HostEnt_h_aliases[HOSTENT_ALIAS_LIMIT];
    272 char HostEnt_names[HOSTENT_ALIAS_LIMIT][HOSTENT_STRLEN_LIMIT];
    273 struct in_addr* HostEnt_addr_list[HOSTENT_ADDR_LIST_LIMIT];
    274 struct in_addr HostEnt_addrs[HOSTENT_ADDR_LIST_LIMIT];
    275 
    276 void
    277 fmemcpyto(void *to, const void *from, int length)
    278 {
    279    movedata(_my_ds(), (unsigned)from, flat_selector, (unsigned)to, length);
    280 }
    281 
    282 void
    283 fmemcpyfrom(void *to, const void *from, int length)
    284 {
    285    movedata(flat_selector, (unsigned)from, _my_ds(), (unsigned)to, length);
    286 }
    287 
    288 void
    289 fstrcpyto(char *to, const char *from)
    290 {
    291    while (*from) {
    292       FARPOKB(to, *from);
    293       to++; from++;
    294    }
    295    FARPOKB(to, 0);
    296 }
    297 
    298 void
    299 fstrncpyto(char *to, const char *from, int len)
    300 {
    301    while (*from && len) {
    302       FARPOKB(to, *from);
    303       to++; from++; len--;
    304    }
    305    FARPOKB(to, 0);
    306 }
    307 
    308 void
    309 fstrcpyfrom(char *to, const char *from)
    310 {
    311    while (FARPKB(from)) {
    312       *to = FARPKB(from);
    313       from++; to++;
    314    }
    315    *to = 0;
    316 }
    317 
    318 void
    319 fstrncpyfrom(char *to, const char *from, int len)
    320 {
    321    while (FARPKB(from) && len) {
    322       *to =  FARPKB(from);
    323       from++; to++; len--;
    324    }
    325    *to = 0;
    326 }
    327 
    328 void
    329 GetSocketMap(void)
    330 {
    331    RTQ_NODE *n = MGenGetNode(SOCKET_MAP_QUEUE);
    332 
    333    SockMap = (SocketMap *) FARPKL(&n->rtqDatum);
    334 }
    335 
    336 void *
    337 GetFreeBufferToQueue(int q, int bufSize)
    338 {
    339    int i;
    340 
    341    for (i = 0; i < NFREEQ; i++) {
    342       if (Qsizes[i] >= bufSize && MGenGetQueueCtr(i+FREEQBASE)) {
    343          RTQ_NODE *n = MGenMoveTo(i+FREEQBASE, q);
    344          if (!n)
    345             continue;
    346          FARPOKL(&n->rtqUpCtr, bufSize);
    347          return (void *) FARPKL(&n->rtqDatum);
    348       }
    349    }
    350 
    351    return 0;
    352 }
    353 
    354 void
    355 FreeBufferFromQueue(int q)
    356 {
    357    int i;
    358    RTQ_NODE *n = MGenGetNode(q);
    359 
    360    for (i = 0; i < NFREEQ; i++) {
    361       if (Qsizes[i] == FARPKS(&n->rtqLen)) {
    362          MGenMoveTo(q, i+FREEQBASE);
    363          return;
    364       }
    365    }
    366 }
    367 
    368 void
    369 SetLPCData(LPCData *lpc)
    370 {
    371 
    372    FARPOKL(&(lpc->version), 1);
    373    FARPOKL(&(lpc->sizeOfArgs), 0);
    374    FARPOKL(&(lpc->service), 0);
    375 }
    376 
    377 int
    378 bind(SOCKET s, const struct sockaddr *name, int namelen)
    379 {
    380    RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
    381    LPCData  *p;
    382    LPCReturn *r;
    383    BindArgs  *bargs;
    384    int       retVal;
    385 
    386    _farsetsel(flat_selector);
    387    SocketError = 0;
    388    p = (LPCData *) FARPKL(&n->rtqDatum);
    389    SetLPCData(p);
    390    FARPOKL(&p->service, LPC_SOCKBIND);
    391    bargs = (BindArgs *) p->Data;
    392    FARPOKL(&bargs->s, s);
    393    FARPOKL(&bargs->namelen, namelen);
    394    fmemcpyto(bargs->name, name, namelen);
    395    MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
    396    PostWindowsMessage();
    397 
    398    while ((n = MGenGetNode(REC_QUEUE)) == 0)
    399       Yield();
    400 
    401    r = (LPCReturn *) FARPKL(&n->rtqDatum);
    402 
    403    if (FARPKS(&r->error) != LPC_NOERROR) {
    404       return -1;
    405    }
    406 
    407    retVal = FARPKL(r->Data);
    408 
    409    // get ready for next call
    410    MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
    411 
    412    return retVal;
    413 }
    414 
    415 int
    416 closesocket(SOCKET s)
    417 {
    418    RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
    419    LPCData  *p;
    420    LPCReturn *r;
    421    int       retVal;
    422 
    423    _farsetsel(flat_selector);
    424    SocketError = 0;
    425    p = (LPCData *) FARPKL(&n->rtqDatum);
    426    SetLPCData(p);
    427    FARPOKL(&p->service, LPC_SOCKCLOSE);
    428    FARPOKL(p->Data, s);
    429 
    430    MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
    431    PostWindowsMessage();
    432 
    433    while ((n = MGenGetNode(REC_QUEUE)) == 0)
    434       Yield();
    435 
    436    r = (LPCReturn *) FARPKL(&n->rtqDatum);
    437 
    438    if (FARPKS(&r->error) != LPC_NOERROR) {
    439       return -1;
    440    }
    441 
    442    retVal = FARPKL(r->Data);
    443 
    444    // get ready for next call
    445    MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
    446 
    447    return retVal;
    448 }
    449 
    450 void
    451 ZapHostEnt()
    452 {
    453    // do nothing
    454 }
    455 
    456 void
    457 ReconstructHostEnt(struct hostent *s, void *flattened)
    458 {
    459    struct hostent   *old = (struct hostent *) flattened;
    460    int i;
    461    char **ptr;
    462 
    463 
    464    s->h_name = HostEnt_hname;
    465    fstrncpyfrom(s->h_name, (char *) FARPKL(&old->h_name), HOSTENT_STRLEN_LIMIT-1);
    466    s->h_name[HOSTENT_STRLEN_LIMIT-1] = 0;
    467 
    468    s->h_aliases = HostEnt_h_aliases;
    469    ptr = (char **) FARPKL(&old->h_aliases);
    470    for (i = 0; i < (HOSTENT_ALIAS_LIMIT-1) && FARPKL(ptr); i++, ptr++) {
    471       s->h_aliases[i] = HostEnt_names[i];
    472       // fstrncpyfrom(s->h_aliases[i], (void *) FARPKL(ptr), HOSTENT_STRLEN_LIMIT-1);
    473       s->h_aliases[i][HOSTENT_STRLEN_LIMIT-1] = 0;
    474    }
    475    s->h_aliases[i] = 0;
    476 
    477    s->h_addrtype = FARPKS(&old->h_addrtype);
    478    s->h_length = FARPKS(&old->h_length);
    479 
    480    if (FARPKS(&old->h_length) != sizeof(struct in_addr)) {
    481       printf("Error!\n");
    482       exit(0);
    483    }
    484 
    485    s->h_addr_list = (char **) HostEnt_addr_list;
    486    ptr = (char **) FARPKL(&old->h_addr_list);
    487    for (i = 0; i < (HOSTENT_ADDR_LIST_LIMIT - 1) && FARPKL(ptr); i++, ptr++) {
    488       s->h_addr_list[i] = (char *) &(HostEnt_addrs[i]);
    489       fmemcpyfrom(s->h_addr_list[i], (void *) FARPKL(ptr), s->h_length);
    490    }
    491    s->h_addr_list[i] = 0;
    492 }
    493 
    494 
    495 int
    496 getsockname(SOCKET s, struct sockaddr *name, int *namelen)
    497 {
    498    RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
    499    LPCData  *p;
    500    LPCReturn *r;
    501    GetSockNameRet  *ret;
    502    int       retVal;
    503 
    504    SocketError = 0;
    505    _farsetsel(flat_selector);
    506    p = (LPCData *) FARPKL(&n->rtqDatum);
    507    SetLPCData(p);
    508    FARPOKL(&p->service, LPC_SOCKGETSOCKNAME);
    509    FARPOKL(p->Data, s);
    510 
    511    MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
    512    PostWindowsMessage();
    513 
    514    while ((n = MGenGetNode(REC_QUEUE)) == 0)
    515       Yield();
    516 
    517 
    518    r = (LPCReturn *) FARPKL(&n->rtqDatum);
    519 
    520    if (FARPKS(&r->error) != LPC_NOERROR) {
    521       return -1;
    522    }
    523 
    524    ret = (GetSockNameRet *) r->Data;
    525    retVal = FARPKL(&ret->retVal);
    526    fmemcpyfrom(name, ret->name, FARPKL(&ret->namelen));
    527    *namelen = FARPKL(&ret->namelen);
    528 
    529    // get ready for next call
    530    MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
    531 
    532    return retVal;
    533 }
    534 
    535 int
    536 gethostname(char *name, int namelen)
    537 {
    538    RTQ_NODE *n;
    539    LPCData  *p;
    540    LPCReturn *r;
    541    GetHostNameRet  *ret;
    542    int       retVal;
    543    char  *s;
    544 
    545    _farsetsel(flat_selector);
    546    SocketError = 0;
    547    n = (RTQ_NODE *) MGenGetNode(IDLE_QUEUE);
    548    p = (LPCData *) FARPKL(&n->rtqDatum);
    549    SetLPCData(p);
    550    FARPOKL(&p->service,LPC_SOCKGETHOSTNAME);
    551    MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
    552    PostWindowsMessage();
    553 
    554    while ((n = (RTQ_NODE *) (MGenGetNode(REC_QUEUE))) == 0)
    555       Yield();
    556 
    557    r = (LPCReturn *) FARPKL(&n->rtqDatum);
    558 
    559    if (FARPKS(&r->error) != LPC_NOERROR) {
    560       return -1;
    561    }
    562 
    563    ret = (GetHostNameRet *) r->Data;
    564 
    565    retVal = FARPKL(&ret->retVal);
    566 
    567    s = ret->name;
    568 
    569    fstrncpyfrom(name, s, namelen);
    570 
    571 #if 0
    572    len = strlen(ret->name);
    573 
    574    if (len > namelen)
    575       memcpy(name, ret->name, ret->namelen);
    576    else
    577       strcpy(name, ret->name);
    578 #endif
    579 
    580    // get ready for next call
    581    MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
    582 
    583    return retVal;
    584 }
    585 
    586 struct hostent *
    587 gethostbyname(const char *name)
    588 {
    589    RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
    590    LPCData  *p;
    591    LPCReturn *r;
    592    struct hostent *retVal;
    593 
    594    _farsetsel(flat_selector);
    595    SocketError = 0;
    596    p = (LPCData *) FARPKL(&n->rtqDatum);
    597    SetLPCData(p);
    598    FARPOKL(&p->service, LPC_SOCKGETHOSTBYNAME);
    599    fstrcpyto(p->Data, name);
    600 
    601    MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
    602    PostWindowsMessage();
    603 
    604    while ((n = MGenGetNode(REC_QUEUE)) == 0)
    605       Yield();
    606 
    607    r = (LPCReturn *) FARPKL(&n->rtqDatum);
    608    retVal = (struct hostent *) r->Data;
    609 
    610    if (FARPKL(&retVal->h_name) == 0) {
    611       retVal = 0;
    612    } else {
    613       ZapHostEnt();
    614       ReconstructHostEnt(&HostEnt, (void *) retVal);
    615       retVal = &HostEnt;
    616    }
    617 
    618    // get ready for next call
    619    MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
    620 
    621    return retVal;
    622 }
    623 
    624 struct hostent *
    625 gethostbyaddr(const char *addr, int len, int type)
    626 {
    627    RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
    628    LPCData  *p;
    629    LPCReturn *r;
    630    GetHostByAddrArgs *args;
    631    struct hostent *retVal;
    632 
    633    SocketError = 0;
    634    _farsetsel(flat_selector);
    635    p = (LPCData *) FARPKL(&n->rtqDatum);
    636    SetLPCData(p);
    637    FARPOKL(&p->service, LPC_SOCKGETHOSTBYADDR);
    638    args = (GetHostByAddrArgs *) p->Data;
    639    FARPOKL(&args->len, len);
    640    FARPOKL(&args->type, type);
    641    fmemcpyto(args->addr, addr, len);
    642 
    643    MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
    644    PostWindowsMessage();
    645 
    646    while ((n = MGenGetNode(REC_QUEUE)) == 0)
    647       Yield();
    648    r = (LPCReturn *) FARPKL(&n->rtqDatum);
    649    retVal = (struct hostent *) r->Data;
    650 
    651    if (FARPKL(&retVal->h_name) == 0) {
    652       retVal = 0;
    653    } else {
    654       ZapHostEnt();
    655 
    656       ReconstructHostEnt(&HostEnt, (void *) retVal);
    657       retVal = &HostEnt;
    658    }
    659 
    660    // get ready for next call
    661    MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
    662 
    663    return retVal;
    664 }
    665 
    666 
    667 SOCKET
    668 socket(int af, int type, int protocol)
    669 {
    670    RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
    671    LPCData  *p;
    672    LPCReturn *r;
    673    SocketArgs  *args;
    674    int       retVal;
    675 
    676    _farsetsel(flat_selector);
    677    SocketError = 0;
    678    p = (LPCData *) FARPKL(&n->rtqDatum);
    679    SetLPCData(p);
    680    FARPOKL(&p->service, LPC_SOCKSOCKET);
    681    args = (SocketArgs *) p->Data;
    682    FARPOKL(&args->af, af);
    683    FARPOKL(&args->type, type);
    684    FARPOKL(&args->protocol, protocol);
    685 
    686    MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
    687    PostWindowsMessage();
    688 
    689    while ((n = MGenGetNode(REC_QUEUE)) == 0)
    690       Yield();
    691 
    692    r = (LPCReturn *) FARPKL(&n->rtqDatum);
    693 
    694 
    695    if (FARPKS(&r->error) != LPC_NOERROR) {
    696       return -1;
    697    }
    698 
    699    retVal = FARPKL(r->Data);
    700 
    701    // get ready for next call
    702    MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
    703 
    704    return retVal;
    705 }
    706 
    707 void
    708 sockets_flush(void)
    709 {
    710    RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
    711    LPCData  *p;
    712 
    713    SocketError = 0;
    714    p = (LPCData *) FARPKL(&n->rtqDatum);
    715    SetLPCData(p);
    716    FARPOKL(&p->service, LPC_SOCKFLUSH);
    717 
    718    MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
    719    PostWindowsMessage();
    720 
    721    while ((n = MGenGetNode(REC_QUEUE)) == 0)
    722       Yield();
    723 
    724    MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
    725 }
    726 
    727 int
    728 recvfrom(SOCKET s, char *buf, int len, int flags, struct sockaddr *from,
    729          int *fromlen)
    730 {
    731    int i;
    732    RTQ_NODE *n;
    733    WinSockData  *data;
    734    int  bytesRead;
    735 
    736    SocketError = 0;
    737    _farsetsel(flat_selector);
    738    if (!SockMap)
    739       GetSocketMap();
    740 
    741    for (i = 0; i < MAXSOCKETS; i++) {
    742       if (FARPKL(&(SockMap->sock[i])) == s)
    743          break;
    744    }
    745 
    746    if (i == MAXSOCKETS)
    747       return SOCKET_ERROR;
    748 
    749    // pick up node
    750    n = MGenGetNode(i);
    751    if (n == 0) {
    752       SocketError = WSAEWOULDBLOCK;
    753       return -1;
    754    }
    755 
    756    data = (WinSockData *) FARPKL(&n->rtqDatum);
    757    bytesRead = FARPKL(&data->len);
    758 
    759    if (from) {
    760       fmemcpyfrom(from, &data->addr, sizeof(struct sockaddr));
    761    }
    762 
    763    if (fromlen) {
    764       *fromlen = FARPKL(&data->addrlen);
    765    }
    766 
    767    fmemcpyfrom(buf, data->data, len > bytesRead ? bytesRead : len);
    768 
    769    if ((flags & MSG_PEEK) == 0) {
    770       FreeBufferFromQueue(i);
    771    }
    772 
    773    return bytesRead;
    774 }
    775 
    776 int
    777 sendto(SOCKET s, const char *buf, int len, int flags, const struct sockaddr *to, int tolen)
    778 {
    779    int i;
    780    int outQ;
    781    WinSockData *data;
    782 
    783    SocketError = 0;
    784    _farsetsel(flat_selector);
    785    if (!SockMap)
    786       GetSocketMap();
    787 
    788    for (i = 0; i < MAXSOCKETS; i++) {
    789       if (FARPKL(&SockMap->sock[i]) == s) {
    790          break;
    791       }
    792    }
    793 
    794    if (i == MAXSOCKETS) {
    795       SocketError = WSAENOTSOCK;
    796       return SOCKET_ERROR;
    797    }
    798 
    799    outQ = i + MAXSOCKETS;
    800 
    801    if (MGenGetQueueCtr(outQ) >= QLIMIT) {
    802       SocketError = WSAEWOULDBLOCK;
    803       return SOCKET_ERROR;
    804    }
    805 
    806    data = GetFreeBufferToQueue(PRIVATEQ, len + sizeof(WinSockData));
    807 
    808    if (!data) {
    809       SocketError = WSAEWOULDBLOCK;
    810       return SOCKET_ERROR;
    811    }
    812 
    813    FARPOKL(&data->s, s);
    814    FARPOKL(&data->len, len);
    815    if (to) {
    816       fmemcpyto(&data->addr, to, tolen);
    817       FARPOKL(&data->addrlen, tolen);
    818    } else {
    819       FARPOKL(&data->addrlen, 0);
    820    }
    821 
    822    FARPOKL(&data->flags, flags);
    823 
    824    fmemcpyto(data->data, buf, len);
    825 
    826    MGenMoveTo(PRIVATEQ, outQ);
    827 
    828    return len;
    829 }
    830 
    831 int
    832 ioctlsocket(SOCKET s, long cmd, unsigned long *argp)
    833 {
    834    RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
    835    LPCData  *p;
    836    LPCReturn *r;
    837    IoctlArgs  *args;
    838    int       retVal;
    839 
    840    SocketError = 0;
    841    _farsetsel(flat_selector);
    842    p = (LPCData *) FARPKL(&n->rtqDatum);
    843    SetLPCData(p);
    844    FARPOKL(&p->service, LPC_SOCKIOCTL);
    845    args = (IoctlArgs *) p->Data;
    846    FARPOKL(&args->s, s);
    847    FARPOKL(&args->cmd, cmd);
    848 
    849    switch(cmd) {
    850    case FIONBIO:
    851       FARPOKL(args->data, *argp);
    852       break;
    853    default:
    854       return SOCKET_ERROR;
    855    }
    856 
    857    MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
    858    PostWindowsMessage();
    859 
    860    while ((n = MGenGetNode(REC_QUEUE)) == 0)
    861       Yield();
    862 
    863    r = (LPCReturn *) FARPKL(&n->rtqDatum);
    864 
    865 
    866    retVal = FARPKL(r->Data);
    867 
    868    // get ready for next call
    869    MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
    870 
    871    return retVal;
    872 }
    873 
    874 int
    875 setsockopt(SOCKET s, int level, int optname, const char *optval, int optlen)
    876 {
    877    RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
    878    LPCData  *p;
    879    LPCReturn *r;
    880    SetSockOptArgs  *args;
    881    int       retVal;
    882 
    883    SocketError = 0;
    884    _farsetsel(flat_selector);
    885    p = (LPCData *) FARPKL(&n->rtqDatum);
    886    SetLPCData(p);
    887    FARPOKL(&p->service, LPC_SOCKSETOPT);
    888    args = (SetSockOptArgs *) p->Data;
    889    FARPOKL(&args->s, s);
    890    FARPOKL(&args->level, level);
    891    FARPOKL(&args->optname, optname);
    892    FARPOKL(&args->optlen, optlen);
    893    fmemcpyto(args->optval, optval, optlen);
    894 
    895    MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
    896    PostWindowsMessage();
    897 
    898    while ((n = MGenGetNode(REC_QUEUE)) == 0)
    899       Yield();
    900 
    901    r = (LPCReturn *) FARPKL(&n->rtqDatum);
    902 
    903    retVal = FARPKL(r->Data);
    904 
    905    // get ready for next call
    906    MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
    907 
    908    return retVal;
    909 }
    910 
    911 int
    912 WSAGetLastError(void)
    913 {
    914    RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
    915    LPCData  *p;
    916    LPCReturn *r;
    917    int       retVal;
    918 
    919 
    920    _farsetsel(flat_selector);
    921    if (SocketError) {
    922       int err = SocketError;
    923 
    924       SocketError = 0;
    925       return err;
    926    }
    927 
    928    p = (LPCData *) FARPKL(&n->rtqDatum);
    929    SetLPCData(p);
    930    FARPOKL(&p->service, LPC_SOCKGETLASTERROR);
    931 
    932    MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
    933    PostWindowsMessage();
    934 
    935    while ((n = MGenGetNode(REC_QUEUE)) == 0)
    936       Yield();
    937 
    938    r = (LPCReturn *) FARPKL(&n->rtqDatum);
    939 
    940 
    941    retVal = FARPKL(r->Data);
    942 
    943    // get ready for next call
    944    MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
    945 
    946    return retVal;
    947 }
    948 
    949 unsigned long inet_addr(const char *cp)
    950 {
    951 	int ret;
    952 	unsigned int ha1, ha2, ha3, ha4;
    953 	unsigned long ipaddr;
    954 
    955 	ret = sscanf(cp, "%d.%d.%d.%d", &ha1, &ha2, &ha3, &ha4);
    956 	if (ret != 4)
    957 		return -1;
    958 	ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4;
    959 	return ipaddr;
    960 #if 0
    961    RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
    962    LPCData  *p;
    963    LPCReturn *r;
    964    int       retVal;
    965 
    966    SocketError = 0;
    967    _farsetsel(flat_selector);
    968    p = (LPCData *) FARPKL(&n->rtqDatum);
    969    SetLPCData(p);
    970    FARPOKL(&p->service, LPC_SOCKINETADDR);
    971 
    972    fstrcpyto(p->Data, cp);
    973 
    974    MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
    975    PostWindowsMessage();
    976 
    977    while ((n = MGenGetNode(REC_QUEUE)) == 0)
    978       Yield();
    979 
    980    r = (LPCReturn *) FARPKL(&n->rtqDatum);
    981 
    982    if (FARPKS(&r->error) != LPC_NOERROR) {
    983       return -1;
    984    }
    985 
    986    retVal = FARPKL(r->Data);
    987 
    988    // get ready for next call
    989    MGenMoveTo(REC_QUEUE, IDLE_QUEUE);
    990 
    991    return retVal;
    992  #endif
    993 }
    994 
    995 char *inet_ntoa (struct in_addr in)
    996 {
    997 	static char buf [32];
    998 
    999 	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);
   1000 	return buf;
   1001 }
   1002