Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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.