WINSK.C
上传用户:qiye66666
上传日期:2007-01-03
资源大小:202k
文件大小:25k
源码类别:

TCP/IP协议栈

开发平台:

Visual C++

  1. #include "winsock.h"  /* Must be included before TCPSTREAM definition */
  2. /* TCP input buffer -- must be large enough to prevent overflow */
  3. #define BUFLEN 512
  4. #define NIL 0                   /* convenient name */
  5. /* TCP I/O stream (must be before osdep.h is included) */
  6. #define TCPSTREAM struct tcp_stream
  7. TCPSTREAM {
  8.   char *host;                   /* host name */
  9.   char *localhost;              /* local host name */
  10.   SOCKET tcps;                   /* tcp socket */
  11.   long ictr;                    /* input counter */
  12.   char *iptr;                   /* input pointer */
  13.   char ibuf[BUFLEN];            /* input buffer */
  14. };
  15. #define __XVT__                 /* To avoid "ERROR redifinition" problem */
  16. /* Private function prototypes */
  17. #include "mail.h"
  18. #include <time.h>
  19. #include <systypes.h>
  20. #include <systimeb.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <memory.h>
  25. #include "debug.h"
  26. #define MEM_SAFETY_DEBUG
  27. // #include <smrtansi.h>
  28. /**** EXTERNALS */
  29. extern void ecs_error(char *);
  30. char *local_hostname = "isa386-15" ;
  31. /* PROTOTYPES of win_* routines */
  32. SOCKET win_socket(int domain, int type, int protocol);
  33. int win_connect(SOCKET s, unsigned long address, unsigned short s_port);
  34. int win_close(SOCKET s);
  35. int win_select(int width, fd_set *readfds,
  36. fd_set *writefds, fd_set *exceptfds, long timeout);
  37. int win_read(SOCKET s, char *buf, int nbyte);
  38. int win_write(SOCKET s, char *buf, int nbyte);
  39. unsigned long win_rhost(char **name);
  40. unsigned long win_htonl(unsigned long hostlong);
  41. unsigned long win_ntohl(unsigned long netlong);
  42. unsigned short win_htons(unsigned short hostshort);
  43. unsigned short win_ntohs(unsigned short netshort);
  44. unsigned long win_inet_addr(char *cp);
  45. void fatal (char *string);
  46. void *fs_get (size_t size);
  47. /* Holds  the addresses of the socket routines in the socket dll */
  48. #define SOCKDLL struct SockDll
  49. SOCKDLL  {
  50.   SOCKET (PASCAL FAR * socket)(int af, int type, int protocol);
  51.   int (PASCAL FAR * connect)(SOCKET s, struct sockaddr FAR *name, int namelen);
  52.   int (PASCAL FAR *closesocket)(SOCKET s);
  53.   int (PASCAL FAR *select)(int nfds, fd_set FAR *readfds, fd_set FAR *writefds, fd_set FAR *exceptfds, struct timeval FAR *timeout);
  54.   int (PASCAL FAR *recv)(SOCKET s, char FAR *buf, int len, int flags);
  55.   int (PASCAL FAR *send)(SOCKET s, char FAR *buf, int len, int flags);
  56.   struct hostent * (PASCAL FAR *gethostbyname)(char FAR *name);
  57.   int (PASCAL FAR *gethostname)(char FAR *name, int namelen);
  58.   unsigned long (PASCAL FAR *inet_addr)(char FAR *cp);
  59.   unsigned long (PASCAL FAR *so_rhost)(char  **cp);
  60.   u_long (PASCAL FAR *htonl)(u_long hostlong);
  61.   u_short (PASCAL FAR *htons)(u_short hostshort);
  62.   u_long (PASCAL FAR *ntohl)(u_long netlong);
  63.   u_short (PASCAL FAR *ntohs)(u_short hostshort);
  64. };
  65. /****** STATIC DATA ******/
  66. static SOCKDLL *sockdll = NULL;            /* Global to this file */
  67. static HANDLE hLibrary = 0;                /* Used to free library */
  68. /* END STATIC DATA ***/
  69. int TCP_init_libs(char *global_dir);
  70. void TCP_free_libs(void);
  71. void TCP_test(char *buf) ;
  72. void tcp_close(TCPSTREAM *stream);
  73. TCPSTREAM *tcp_open (char *host,long port);
  74. long tcp_soutr (TCPSTREAM *stream,char *string);
  75. char *tcp_getline (TCPSTREAM *stream);
  76. long tcp_getbuffer (TCPSTREAM *stream,unsigned long size,char *buffer);
  77. #ifdef MSDOS
  78. int netshut() {};
  79. #endif
  80. /* Global data */
  81. unsigned long rndm = 0xfeed;    /* initial `random' number */
  82. /* Write current time in RFC 822 format
  83.  * Accepts: destination string
  84.  */
  85. char *days[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
  86. /* Copy string to free storage
  87.  * Accepts: source string
  88.  * Returns: free storage copy of string
  89.  */
  90. char *cpystr (char *string)
  91. {
  92.   if (string) {                 /* make sure argument specified */
  93.     char *dst = (char *) fs_get (1+strlen (string));
  94.     strcpy (dst,string);
  95.     return (dst);
  96.   }
  97.   else return NIL;
  98. }
  99. /************************************************************************/
  100. /* Get a block of free storage
  101.  * Accepts: size of desired block
  102.  * Returns: free storage block
  103.  */
  104. void *fs_get (size_t size)
  105. {
  106.   void *block = NULL;
  107.   /* Make sure "size" is within the 64K limit */
  108.   if(size > (size_t)0xffff){
  109.       fatal("Cannot allocate more than 64K memory");
  110.       return(NULL);     /* Should  have already quit */
  111.   }
  112.   block = (void *)malloc(size);  /* Would use smartheap */
  113.   if (!block)
  114.       fatal ("Out of free storage");
  115.   /* Set to zero */
  116.   memset(block, 0, size);
  117.   return (block);
  118. }
  119. /* Resize a block of free storage
  120.  * Accepts: ** pointer to current block
  121.  *          new size
  122.  */
  123. void fs_resize (void **block,size_t size)
  124. {
  125.   if(size > (size_t)0xffff)
  126.       fatal("Can't resize to more than 64k");
  127.   if (!(*block = realloc ((char *)*block,size)))
  128.       fatal ("Can't resize free storage");
  129. }
  130. /* Return a block of free storage
  131.  * Accepts: ** pointer to free storage block
  132.  */
  133. void fs_give (void **block)
  134. {
  135.   if(block && *block)
  136.      free ((char *)*block);  /* Would use smartheap */
  137.   if(block)
  138.      *block = NIL;
  139. }
  140. /* Report a fatal error
  141.  * Accepts: string to output
  142.  */
  143. void fatal (char *string)
  144. {
  145.   debug_trace (string);            /* pass the string */
  146.   debug_trace ("n");
  147.   abort ();                     /* die horribly */
  148. }
  149. /* Copy string with CRLF newlines
  150.  * Accepts: destination string
  151.  *          pointer to size of destination string
  152.  *          source string
  153.  *          length of source string
  154.  */
  155. char *strcrlfcpy (char **dst,unsigned long *dstl,char *src,unsigned long srcl)
  156. {
  157.   if (srcl > *dstl) {           /* resize if not enough space */
  158.     fs_give ((void **) dst);    /* fs_resize does an unnecessary copy */
  159.     *dst = (char *) fs_get ((*dstl = srcl) + 1);
  160.   }
  161. /* copy strings */
  162.   if (srcl) memcpy (*dst,src,srcl);
  163.   *(*dst + srcl) = '';        /* tie off destination */
  164.   return *dst;                  /* return destination */
  165. }
  166. /* Length of string after strcrlfcpy applied
  167.  * Accepts: source string
  168.  *          length of source string
  169.  */
  170. unsigned long strcrlflen (STRING *s)
  171. {
  172.   return SIZE (s);              /* no-brainer on DOS! */
  173. }
  174. /* Server log in (dummy place holder)
  175.  * Accepts: user name string
  176.  *          password string
  177.  *          optional place to return home directory
  178.  * Returns: T if password validated, NIL otherwise
  179.  */
  180. long server_login (char *user,char *pass,char **home)
  181. {
  182.   return NIL;
  183. }
  184. /***************************************************************************
  185. ****************************************************************************/
  186. void TCP_test(char *buf)
  187. {
  188.    TCPSTREAM *stream ;  
  189.    char *string = " " ;
  190.    long port = 143 ;   /* imapd */
  191.    long retval ;
  192.    
  193.    stream = tcp_open("isasun-1", port);
  194.    retval = tcp_soutr (stream, string);
  195.    string = tcp_getline (stream); 
  196.    movmem(string,buf,strlen(string));  
  197.    tcp_close(stream);
  198. }
  199. /***************************************************************************
  200. ****************************************************************************/
  201. /* TCP/IP send string as record
  202.  * Accepts: TCP/IP stream
  203.  * Returns: T if success else NIL
  204.  */
  205. long tcp_soutr (TCPSTREAM *stream,char *string)
  206. {
  207.   int a ;
  208.   long i;
  209.   unsigned long size = strlen (string);
  210.   fd_set fds;
  211.     
  212.   FD_ZERO (&fds);               /* initialize selection vector */
  213.   if (stream->tcps == INVALID_SOCKET) return NIL;
  214.   FD_SET (stream->tcps,&fds);/* set bit in selection vector */
  215.   
  216.   while (size > 0) {            /* until request satisfied */
  217.     if( (win_select (stream->tcps+1,0,&fds,0,0) < 0) ||
  218. ((i = win_write (stream->tcps,string,size)) < 1) )  
  219.     {
  220. win_close (stream->tcps);   /* nuke the socket */
  221. stream->tcps = INVALID_SOCKET;
  222. return NIL;
  223.     }
  224.     size -= i;                  /* count this size */
  225.     string += i;
  226.   }
  227.   return T;                     /* all done */
  228. }
  229. /* TCP/IP send string (Not NULL terminated).
  230.  * Accepts: TCP/IP stream
  231.  * Returns: T if success else NIL
  232.  */
  233. long tcp_sout (TCPSTREAM *stream,char *string,unsigned long size)
  234. {
  235.   size_t i;
  236.   fd_set fds;
  237.   size_t len, MAXLEN = 8192;         /* send no more than this at a time */
  238.   FD_ZERO (&fds);               /* initialize selection vector */
  239.   if (stream->tcps == INVALID_SOCKET) return NIL;
  240.   FD_SET (stream->tcps,&fds);   /* set bit in selection vector */
  241.   len = (size_t)min(size, MAXLEN);
  242.   while (size > 0) {            /* until request satisfied */
  243.     if ((win_select (stream->tcps+1,0,&fds,0,0) < 0) ||
  244. ((i = win_write (stream->tcps,string,len)) < 0)) { /* Send len at a time */
  245.       win_close (stream->tcps);   /* nuke the socket */
  246.       stream->tcps = INVALID_SOCKET;
  247.       return NIL;
  248.     }
  249.     size -= i;                  /* count this size */
  250.     string += i;
  251.   }
  252.   /* Append a "n" */
  253.   if ((win_select (stream->tcps+1,0,&fds,0,0) < 0) ||
  254.       ((i = win_write (stream->tcps,"n",1)) < 0)) {
  255.     win_close (stream->tcps);   /* nuke the socket */
  256.     stream->tcps = INVALID_SOCKET;
  257.     return NIL;
  258.   }
  259.   return T;                     /* all done */
  260. }
  261. /* TCP/IP receive line
  262.  * Accepts: TCP/IP stream
  263.  * Returns: text line string or NIL if failure
  264.  */
  265. char *tcp_getline (TCPSTREAM *stream)
  266. {
  267.   int a;
  268.   long n, m;
  269.   char *st;
  270.   char *ret;
  271.   char *stp;
  272.   char tmp[2];
  273.   fd_set fds;
  274.   FD_ZERO (&fds);               /* initialize selection vector */
  275.   if (stream->tcps == INVALID_SOCKET) return NIL;
  276.   FD_SET (stream->tcps, &fds);   /* set bit in selection vector */
  277.   while (stream->ictr < 1) {   /* if nothing in the buffer */
  278.     /* block and read */
  279.     if( (win_select (stream->tcps+1,&fds,0,0,0) < 0) ||
  280. ((stream->ictr = win_read (stream->tcps,stream->ibuf,BUFLEN)) < 1))
  281.     {
  282.  win_close (stream->tcps);   /* nuke the socket */
  283.  stream->tcps = INVALID_SOCKET;
  284.  return NIL;
  285.     }
  286.     stream->iptr = stream->ibuf;/* point at TCP buffer */
  287.   }
  288.   st = stream->iptr;            /* save start of string */
  289.   n = 0;                        /* init string count */
  290.   
  291.   while (stream->ictr--) {      /* look for end of line */
  292. /* saw the trailing CR? */
  293.     if (stream->iptr++[0] == '15') {
  294.       ret = (char *) fs_get (n+1);
  295.       memcpy (ret,st,n);        /* copy into a free storage string */
  296.       ret[n] = '';            /* tie off string with null */
  297. /* eat the line feed */
  298.       tcp_getbuffer (stream,(unsigned long) 1,tmp);
  299.       return ret;               /* return it to caller */
  300.     }
  301.     ++n;                        /* else count and try next character */
  302.   }
  303.   stp = (char *) fs_get (n);    /* copy first part of string */
  304.   memcpy (stp,st,n);
  305. /* recurse to get remainder */
  306.   if (st = tcp_getline (stream)) {
  307. /* build total string */
  308.     ret = (char *) fs_get (n+1+(m = strlen (st)));
  309.     memcpy (ret,stp,n);         /* copy first part */
  310.     memcpy (ret+n,st,m);        /* and second part */
  311.     ret[n+m] = '';            /* tie off string with null */
  312.     fs_give ((void **) &st);    /* flush partial string */
  313.     fs_give ((void **) &stp);   /* flush initial fragment */
  314.   }
  315.   else ret = stp;               /* return the fragment */
  316.   return ret;
  317. }
  318. /* TCP/IP receive buffer
  319.  * Accepts: TCP/IP stream
  320.  *          size in bytes
  321.  *          buffer to read into
  322.  * Returns: T if success, NIL otherwise
  323.  */
  324. long tcp_getbuffer (TCPSTREAM *stream,unsigned long size,char *buffer)
  325. {
  326.   int a;
  327.   int retval ;
  328.   unsigned long n;
  329.   char *bufptr = buffer;
  330.   fd_set fds ;
  331.   FD_ZERO (&fds);               /* initialize selection vector */
  332.   if (stream->tcps == INVALID_SOCKET) return NIL;
  333.   FD_SET (stream->tcps, &fds);   /* set bit in selection vector */
  334.   while (size > 0) {            /* until request satisfied */
  335.     while (stream->ictr < 1) {  /* if nothing in the buffer */
  336. /* block and read */
  337.       if( (win_select(stream->tcps+1,&fds,0,0,0) < 0) || 
  338.   ((stream->ictr = win_read(stream->tcps,stream->ibuf,BUFLEN)) < 1)) 
  339.       {
  340.    win_close (stream->tcps); /* nuke the socket */
  341.    stream->tcps = INVALID_SOCKET;
  342.    return NIL;
  343.       }
  344. /* point at TCP buffer */
  345.       stream->iptr = stream->ibuf;
  346.     }                           /* inner while */
  347.     n = min (size,stream->ictr);/* number of bytes to transfer */
  348. /* do the copy */
  349.     memcpy (bufptr,stream->iptr,n);
  350.     bufptr += n;                /* update pointer */
  351.     stream->iptr +=n;
  352.     size -= n;                  /* update # of bytes to do */
  353.     stream->ictr -=n;
  354.     bufptr[0] = '';             /* tie off string */
  355.   }                             /* outer while */
  356.   return T;
  357. }
  358. /* TCP/IP close
  359.  * Accepts: TCP/IP stream
  360.  */
  361. void tcp_close (TCPSTREAM *stream)
  362. {
  363. /* nuke the socket */
  364.   if (stream->tcps != INVALID_SOCKET) win_close (stream->tcps);
  365.   stream->tcps = INVALID_SOCKET;
  366. /* flush host names */
  367.   fs_give ((void **) &stream->host);
  368.   fs_give ((void **) &stream->localhost);
  369.   fs_give ((void **) &stream);  /* flush the stream */
  370. }
  371. /* TCP/IP open
  372.  * Accepts: host name
  373.  *          contact port number
  374.  * Returns: TCP/IP stream if success else NIL
  375.  */
  376. TCPSTREAM *tcp_open (char *host,long port)
  377. {
  378.   TCPSTREAM *stream = NIL;
  379.   SOCKET sock;
  380.   unsigned long address;
  381.   unsigned short s_port;
  382.   char *s;
  383.   char tmp[MAILTMPLEN];
  384.   char *hostname = cpystr (host);
  385. /* set default gets routine */
  386. //  if (!mailgets) mailgets = mm_gets
  387.   /* The domain literal form is used (rather than simply the dotted decimal
  388.      as with other Unix programs) because it has to be a valid "host name"
  389.      in mailsystem terminology.
  390.   */
  391.   if (host[0] == '[' && host[(strlen (host))-1] == ']') {
  392.     strcpy (tmp,host+1);        /* yes, copy number part */
  393.     tmp[strlen (tmp)-1] = '';
  394.     if ((address = win_inet_addr (tmp)) == -1) {
  395.       sprintf (tmp,"Invalid post office: "%s" ",host);
  396.       ecs_error(tmp);
  397.       fs_give ((void **)&hostname);
  398.       return NIL;
  399.     }
  400.   }
  401.   else {                        /* lookup host name */
  402.     if ((address = win_rhost (&hostname)) == 0) {
  403.       sprintf (tmp,"Post office not found: "%s" ",host);
  404.       ecs_error(tmp);
  405.       fs_give ((void **)&hostname);
  406.       return NIL;
  407.     }
  408.   }
  409. /* copy port number in network format */
  410.   if (!(s_port = win_htons (port)))
  411.       fatal ("Bad port argument to tcp_open");
  412. /* get a TCP stream */
  413.   sock = win_socket(AF_INET, SOCK_STREAM, 0);
  414.   if (sock < 0) {
  415.     sprintf(tmp, "Cannot connect to post office: "%s" - Unable to create TCP socket", host);
  416.     ecs_error(tmp);
  417.     return NIL;
  418.   }
  419.   /* The local PC's hostname MUST be in the external "local_hostname", else
  420.    * return an error.
  421.    */
  422.   if(local_hostname == NULL){
  423.       ecs_error("Could not get the name or IP address of your PC");
  424.       return NIL;
  425.   }
  426. /* open connection */
  427.   if ((errno = win_connect (sock, address, s_port)) > 10000) {
  428.     switch (errno) {            /* analyze error */
  429. case WSAENETUNREACH: s = "tcp_open failed"; break;
  430. case WSAETIMEDOUT: s = "Timed out"; break;
  431. default: s = "Unknown error"; break;
  432.     }
  433.     sprintf(tmp,"Connect fail to "%s" [%ld] at port %ld. %sn",hostname,address,port,s);
  434.     ecs_error(tmp);
  435.     fs_give ((void **)&hostname);
  436.     win_close (sock);
  437.     return NIL;
  438.   }
  439. /* create TCP/IP stream */
  440.   stream = (TCPSTREAM *) fs_get (sizeof (TCPSTREAM));
  441.   stream->host = hostname;      /* official host name */
  442.   stream->localhost = cpystr (local_hostname);
  443.   stream->tcps = sock;          /* init socket */
  444.   stream->ictr = 0;             /* init input counter */
  445.   
  446.   return stream;                /* return success */
  447. }
  448. /* TCP/IP authenticated open
  449.  * Accepts: host name
  450.  *          service name
  451.  * Returns: TCP/IP stream if success else NIL
  452.  */
  453. TCPSTREAM *tcp_aopen (char *host,char *service)
  454. {
  455.   return NIL;                   /* always NIL on DOS */
  456. }
  457. char *tcp_host (TCPSTREAM *stream)
  458. {
  459.   return stream->host;          /* return host name */
  460. }
  461. /* TCP/IP get local host name
  462.  * Accepts: TCP/IP stream
  463.  * Returns: local host name
  464.  */
  465. char *tcp_localhost (TCPSTREAM *stream)
  466. {
  467.   return stream->localhost;     /* return local host name */
  468. }
  469. /* These functions are only used by rfc822.c for calculating cookies.  So this
  470.  * is good enough.  If anything better is needed fancier functions will be
  471.  * needed.
  472.  */
  473. /* Return host ID
  474.  */
  475. #ifndef PCTCP
  476. unsigned long gethostid ()
  477. {
  478.   return (unsigned long) 0;
  479. }
  480. #endif
  481. /* Return `process ID'
  482.  */
  483. long getpid ()
  484. {
  485.   return 1;
  486. }
  487. /* These two are used for pattern matching in misc.c, but are actually never
  488.  * called in DOS.
  489.  */
  490. /* Dummy re_comp -- always return NIL */
  491. char *re_comp (char *s)
  492. {
  493.   return NIL;
  494. }
  495. /* Dummy re_exec -- always return T */
  496. long re_exec (char *s)
  497. {
  498.   return T;
  499. }
  500. /* Fill in the function pointers in the sockdll structure. The
  501.  * functions to be filled into the "sockdll" structure are:
  502.    - socket,
  503.    - connect,
  504.    - closesocket,
  505.    - select,
  506.    - recv,
  507.    - send,
  508.    - gethostbyname,
  509.    - net_addr,
  510.    - htonl,
  511.    - htons,
  512.    - ntohl,
  513.    - ntohs,
  514. **/
  515. /* Looks for the file "winsock.dll", loads it and extracts the addresses.
  516.  * The returned instance of the library is stored in the static "hLibraray"
  517.  * so it can be free by "TCP_free_libs()"
  518.  */
  519. int TCP_init_libs(char *global_dir)
  520. {
  521.     int (PASCAL FAR *WSAStartup)(WORD wVersionRequired, LPWSADATA lpWSAData);
  522.     WSADATA *lpwsadata;
  523.     int retval;
  524.     WORD our_wsock_version = 257;   /* Version 1.1 of winsock */
  525.     WSAStartup = NULL;
  526.     lpwsadata = NULL;
  527.     if((hLibrary = LoadLibrary("winsock.dll")) <= 32)
  528. return(-1);
  529.     /* Do this for debuggindg */
  530.     {
  531. char *path = fs_get(256);
  532. path[0] = '';
  533. /* Get library's path */
  534. GetModuleFileName(hLibrary, path, 255);
  535. fs_give((void **)&path);
  536.     }
  537.     if((WSAStartup = (int  (FAR PASCAL *)())GetProcAddress(hLibrary, "WSAStartup")) == NULL)
  538. return(-1);
  539.     /* Allocate */
  540.     lpwsadata = fs_get(sizeof(WSADATA));
  541.     /* Initialize the application */
  542.     lpwsadata->wHighVersion = our_wsock_version;  /* In case */
  543.     retval = (*WSAStartup)(lpwsadata->wHighVersion, lpwsadata);
  544.     if(retval != 0)  /* DLL hopefully filled this in!! */
  545. retval = (*WSAStartup)(lpwsadata->wHighVersion, lpwsadata);
  546.     if(retval != 0){    /* Still no success */
  547. char *path = fs_get(256);
  548. char *mess = fs_get(256);
  549. path[0] = '';
  550. mess[0] = '';
  551. /* Get library's path */
  552. if(GetModuleFileName(hLibrary, path, 255) == 0)
  553.     path[0] == '';
  554. switch(retval){
  555.     case 0:  /* All's well */
  556.     break;
  557.     case WSASYSNOTREADY:
  558. sprintf(mess, "Error iniitalizing "%s": system not ready",
  559. path);
  560. ecs_error(mess);
  561.     break;
  562.     case WSAVERNOTSUPPORTED:
  563.     case WSAEINVAL:
  564. sprintf(mess, ""%s" does not support the winsock version 
  565. required by ECS Mail", path);
  566. ecs_error(mess);
  567.     break;
  568. }
  569. fs_give((void **)&path);
  570. fs_give((void **)&mess);
  571. goto error;
  572.     }
  573.     /* Don't need lpwsadata anymore */
  574.     fs_give((void **)&lpwsadata);
  575.     lpwsadata = NULL;
  576.     /* Ok. All's well */
  577.     /* Allocate space */
  578.     if(sockdll == NULL)  /* Should be */
  579. sockdll = (SOCKDLL *)fs_get(sizeof(SOCKDLL));
  580.     /* so_rhost accomodates our B&W shim */
  581.     sockdll->so_rhost = NULL;   /* Set this explicitly */
  582.     /* Get addresses of routines */
  583.     sockdll->so_rhost = (unsigned long  (FAR PASCAL *)())
  584. GetProcAddress(hLibrary, "so_rhost"); /* Could be NULL */
  585.     if((sockdll->socket = (int  (FAR PASCAL *)())
  586. GetProcAddress(hLibrary, "socket")) == NULL)
  587. goto error;
  588.     if((sockdll->connect = (int  (FAR PASCAL *)())GetProcAddress(hLibrary, "connect")) == NULL)
  589. goto error;
  590.     if((sockdll->closesocket = (int  (FAR PASCAL *)())GetProcAddress(hLibrary, "closesocket")) == NULL)
  591. goto error;
  592.     if((sockdll->select = (int  (FAR PASCAL *)())GetProcAddress(hLibrary, "select")) == NULL)
  593. goto error;
  594.     if((sockdll->recv = (int  (FAR PASCAL *)())GetProcAddress(hLibrary, "recv")) == NULL)
  595. goto error;
  596.     if((sockdll->send = (int (FAR PASCAL *)())GetProcAddress(hLibrary, "send")) == NULL)
  597. goto error;
  598.     if((sockdll->gethostbyname = (struct hostent * (PASCAL FAR *)())GetProcAddress(hLibrary, "gethostbyname")) == NULL)
  599. goto error;
  600.     if((sockdll->gethostname = (int (PASCAL FAR *)())GetProcAddress(hLibrary, "gethostname")) == NULL)
  601. goto error;
  602.     if((sockdll->inet_addr = (unsigned long (FAR PASCAL *)())GetProcAddress(hLibrary, "inet_addr")) == NULL)
  603. goto error;
  604.     if((sockdll->htonl = (unsigned long (FAR PASCAL *)())GetProcAddress(hLibrary, "htonl")) == NULL)
  605. goto error;
  606.     if((sockdll->ntohl = (unsigned long (FAR PASCAL *)())GetProcAddress(hLibrary, "ntohl")) == NULL)
  607. goto error;
  608.     if((sockdll->htons = (unsigned short (FAR PASCAL *)())GetProcAddress(hLibrary, "htons")) == NULL)
  609. goto error;
  610.     if((sockdll->ntohs = (unsigned short (FAR PASCAL *)())GetProcAddress(hLibrary, "ntohs")) == NULL)
  611. goto error;
  612.     
  613.     return(0);
  614. error:
  615. if(sockdll)
  616.     fs_give((void **)&sockdll);
  617. sockdll = NULL;
  618. if(lpwsadata)
  619.     fs_give((void **)&lpwsadata);
  620. return(-1);
  621. }
  622. /* Free the socket library */
  623. void TCP_free_libs(void)
  624. {
  625.     int (PASCAL FAR *WSACleanup)(void);
  626.     WSACleanup = NULL;
  627.     if(hLibrary <= 0)
  628. return;
  629.     /* Call WSACleanup now */
  630.     if((WSACleanup = (int  (FAR PASCAL *)())GetProcAddress(hLibrary, "WSACleanup")) != NULL)
  631. (*WSACleanup)();
  632.     /* Free sockdll*/
  633.     if(sockdll)
  634. fs_give((void **)&sockdll);
  635.     sockdll = NULL;
  636. }
  637. /* These routines simply call the address of socket(), etc. */
  638. SOCKET win_socket(int domain, int type, int protocol)
  639. {
  640.     if(sockdll && sockdll->socket)
  641. return((*sockdll->socket)(domain, type, protocol));
  642. }
  643. /* NOTE:  s_port already in network order */
  644. int win_connect(SOCKET s, unsigned long address, unsigned short s_port)
  645. {
  646.     struct sockaddr_in sin;
  647.     sin.sin_family = AF_INET;
  648.     sin.sin_port = s_port;
  649.     sin.sin_addr.s_addr = address;
  650.     if(sockdll && sockdll->connect)
  651. return((*sockdll->connect)(s, (struct sockaddr *)&sin, sizeof(sin)));
  652.     return(-1);
  653. }
  654. int win_close(SOCKET s)
  655. {
  656.     if(sockdll && sockdll->closesocket)
  657. return((*sockdll->closesocket)(s));
  658.     return(-1);
  659. }
  660. /* timwout of 0 means non-blocking */
  661. int win_select(int width, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, long timeout)
  662. {
  663.     struct timeval tval;
  664.     int result ;
  665.     tval.tv_sec = timeout;
  666.     if(tval.tv_sec < 2)
  667. tval.tv_sec = 2;
  668.     tval.tv_usec = 0;
  669.     if(sockdll && sockdll->select)
  670. result = (*sockdll->select)(width, readfds, writefds, exceptfds, &tval);
  671.     if( (result > WSABASEERR) || (result == 0) )
  672. return(-1);
  673.     return(result) ;
  674. }
  675. int win_read(SOCKET s, char *buf, int nbyte)
  676. {
  677.     if(sockdll && sockdll->recv)
  678. return((*sockdll->recv)(s, buf, nbyte, 0));
  679.     return(-1);
  680. }
  681. int win_write(SOCKET s, char *buf, int nbyte)
  682. {
  683.     if(sockdll && sockdll->send)
  684. return((*sockdll->send)(s, buf, nbyte, 0));
  685.     return(-1);
  686. }
  687. /* rhost - a short-cut for gethostbyname.
  688.  * Return 0 on error.
  689.  */
  690. unsigned long win_rhost(char **name)
  691. {
  692.     unsigned long addr;
  693.     struct hostent *h;
  694.     struct in_addr sin_addr;
  695.     if(!(name && *name))
  696. return(0L);
  697.     addr = 0L;
  698.     /* If a so_rhost() is provided by the winsock.dll, use it */
  699.     if(sockdll && sockdll->so_rhost)  /* Use rhost */
  700. addr = (*sockdll->so_rhost)(name);
  701.     if(addr > 0L)
  702. return(addr);
  703.     /* If so_rhost failed, try below */
  704.     if(!(sockdll && sockdll->inet_addr && sockdll->gethostbyname))
  705. return(0L);
  706.     addr = 0L;
  707.     addr = (*sockdll->inet_addr)(*name);
  708.     if (addr == INADDR_NONE)
  709.     {
  710. addr = 0L;
  711. h = (*sockdll->gethostbyname)(*name);
  712. if(h != NULL){
  713.     memcpy((char *)&sin_addr, h->h_addr, h->h_length);
  714.     addr = sin_addr.s_addr;
  715. }
  716.     }
  717.     return(addr);
  718. }
  719. unsigned long win_htonl(unsigned long hostlong)
  720. {
  721.     if(sockdll && sockdll->htonl)
  722. return((*sockdll->htonl)(hostlong));
  723.     return(0L);
  724. }
  725. unsigned long win_ntohl(unsigned long netlong)
  726. {
  727.     if(sockdll && sockdll->ntohl)
  728. return((*sockdll->ntohl)(netlong));
  729.     return(0L);
  730. }
  731. unsigned short win_htons(unsigned short hostshort)
  732. {
  733.     if(sockdll && sockdll->htons)
  734. return((*sockdll->htons)(hostshort));
  735.     return(0);
  736. }
  737. unsigned short win_ntohs(unsigned short netshort)
  738. {
  739.     if(sockdll && sockdll->ntohs)
  740. return((*sockdll->ntohs)(netshort));
  741.     return(0);
  742. }
  743. unsigned long win_inet_addr(char *cp)
  744. {
  745.     if(sockdll && sockdll->inet_addr)
  746. return((*sockdll->inet_addr)(cp));
  747.     return(0L);
  748. }
  749. /** Get local host name or IP address. Use "gethostname".
  750.  * "buf" must be supplied, of length "buflen".
  751.  * These are simply passed to winsock's gethostname().
  752.  * Returns 0 if found, -1 on error.
  753.  */
  754. int ECS_get_local_hostname(char *buf, int buflen)
  755. {
  756.     if(sockdll && sockdll->gethostname)
  757. return((*sockdll->gethostname)(buf, buflen));
  758.     return(-1);
  759. }