tcp_dwa.c
上传用户:ycwykj01
上传日期:2007-01-04
资源大小:1819k
文件大小:9k
源码类别:

网络编程

开发平台:

Unix_Linux

  1. /*
  2.  * Program: Waterloo DOS TCP/IP routines
  3.  *
  4.  * Author: Mark Crispin
  5.  * Networks and Distributed Computing
  6.  * Computing & Communications
  7.  * University of Washington
  8.  * Administration Building, AG-44
  9.  * Seattle, WA  98195
  10.  * Internet: MRC@CAC.Washington.EDU
  11.  *
  12.  * Date: 11 April 1989
  13.  * Last Edited: 28 September 1998
  14.  *
  15.  * Copyright 1998 by the University of Washington
  16.  *
  17.  *  Permission to use, copy, modify, and distribute this software and its
  18.  * documentation for any purpose and without fee is hereby granted, provided
  19.  * that the above copyright notice appears in all copies and that both the
  20.  * above copyright notice and this permission notice appear in supporting
  21.  * documentation, and that the name of the University of Washington not be
  22.  * used in advertising or publicity pertaining to distribution of the software
  23.  * without specific, written prior permission.  This software is made
  24.  * available "as is", and
  25.  * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
  26.  * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
  27.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
  28.  * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
  29.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  30.  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
  31.  * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
  32.  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  33.  *
  34.  */
  35. /* Global data */
  36. short sock_initted = 0; /* global so others using net can see it */
  37. /* TCP/IP manipulate parameters
  38.  * Accepts: function code
  39.  *     function-dependent value
  40.  * Returns: function-dependent return value
  41.  */
  42. void *tcp_parameters (long function,void *value)
  43. {
  44.   return NIL;
  45. }
  46. /* TCP/IP open
  47.  * Accepts: host name
  48.  *     contact service name
  49.  *     contact port number
  50.  * Returns: TCP/IP stream if success else NIL
  51.  */
  52. TCPSTREAM *TCP_open (char *host,char *service,unsigned long port)
  53. {
  54.   TCPSTREAM *stream = NIL;
  55.   tcp_Socket *sock;
  56.   char *s,tmp[MAILTMPLEN];
  57.   unsigned long adr,i,j,k,l;
  58. /* initialize if first time here */
  59.   if (!sock_initted++) sock_init();
  60.   /* The domain literal form is used (rather than simply the dotted decimal
  61.      as with other Unix programs) because it has to be a valid "host name"
  62.      in mailsystem terminology. */
  63. /* look like domain literal? */
  64.   if (host[0] == '[' && host[strlen (host)-1] == ']') {
  65.     if (((i = strtoul (s = host+1,&s,10)) <= 255) && *s++ == '.' &&
  66. ((j = strtoul (s,&s,10)) <= 255) && *s++ == '.' &&
  67. ((k = strtoul (s,&s,10)) <= 255) && *s++ == '.' &&
  68. ((l = strtoul (s,&s,10)) <= 255) && *s++ == ']' && !*s)
  69.       adr = (i << 24) + (j << 16) + (k << 8) + l;
  70.     else {
  71.       sprintf (tmp,"Bad format domain-literal: %.80s",host);
  72.       mm_log (tmp,ERROR);
  73.       return NIL;
  74.     }
  75.   }
  76.   else { /* lookup host name */
  77.     if (!(adr = resolve (host))) {
  78.       sprintf (tmp,"Host not found: %s",host);
  79.       mm_log (tmp,ERROR);
  80.       return NIL;
  81.     }
  82.   }
  83. /* OK to instantiate socket now */
  84.   sock = (tcp_Socket *) fs_get (sizeof (tcp_Socket));
  85. /* open connection */
  86.   if (!tcp_open (sock,(word) 0,adr,(word) port,NULL)) {
  87.     sprintf (tmp,"Can't connect to %.80s,%ld",host,port);
  88.     mm_log (tmp,ERROR);
  89.     fs_give ((void **) &sock);
  90.     return NIL;
  91.   }
  92. /* create TCP/IP stream */
  93.   stream = (TCPSTREAM *) fs_get (sizeof (TCPSTREAM));
  94.   stream->host = cpystr (host); /* official host name */
  95.   stream->localhost = cpystr (mylocalhost ());
  96.   stream->port = port; /* port number */
  97.   stream->tcps = sock; /* init socket */
  98.   stream->ictr = 0; /* init input counter */
  99.   return stream; /* return success */
  100. }
  101.   
  102. /* TCP/IP authenticated open
  103.  * Accepts: NETMBX specifier
  104.  *     service name
  105.  *     returned user name buffer
  106.  * Returns: TCP/IP stream if success else NIL
  107.  */
  108. TCPSTREAM *tcp_aopen (NETMBX *mb,char *service,char *usrbuf)
  109. {
  110.   return NIL; /* always NIL on DOS */
  111. }
  112. /* TCP/IP receive line
  113.  * Accepts: TCP/IP stream
  114.  * Returns: text line string or NIL if failure
  115.  */
  116. char *tcp_getline (TCPSTREAM *stream)
  117. {
  118.   int n,m;
  119.   char *st,*ret,*stp;
  120.   char c = '';
  121.   char d;
  122. /* make sure have data */
  123.   if (!tcp_getdata (stream)) return NIL;
  124.   st = stream->iptr; /* save start of string */
  125.   n = 0; /* init string count */
  126.   while (stream->ictr--) { /* look for end of line */
  127.     d = *stream->iptr++; /* slurp another character */
  128.     if ((c == '15') && (d == '12')) {
  129.       ret = (char *) fs_get (n--);
  130.       memcpy (ret,st,n); /* copy into a free storage string */
  131.       ret[n] = ''; /* tie off string with null */
  132.       return ret;
  133.     }
  134.     n++; /* count another character searched */
  135.     c = d; /* remember previous character */
  136.   }
  137. /* copy partial string from buffer */
  138.   memcpy ((ret = stp = (char *) fs_get (n)),st,n);
  139. /* get more data from the net */
  140.   if (!tcp_getdata (stream)) return NIL;
  141. /* special case of newline broken by buffer */
  142.   if ((c == '15') && (*stream->iptr == '12')) {
  143.     stream->iptr++; /* eat the line feed */
  144.     stream->ictr--;
  145.     ret[n - 1] = ''; /* tie off string with null */
  146.   }
  147. /* else recurse to get remainder */
  148.   else if (st = tcp_getline (stream)) {
  149.     ret = (char *) fs_get (n + 1 + (m = strlen (st)));
  150.     memcpy (ret,stp,n); /* copy first part */
  151.     memcpy (ret + n,st,m); /* and second part */
  152.     fs_give ((void **) &stp); /* flush first part */
  153.     fs_give ((void **) &st); /* flush second part */
  154.     ret[n + m] = ''; /* tie off string with null */
  155.   }
  156.   return ret;
  157. }
  158. /* TCP/IP receive buffer
  159.  * Accepts: TCP/IP stream
  160.  *     size in bytes
  161.  *     buffer to read into
  162.  * Returns: T if success, NIL otherwise
  163.  */
  164. long tcp_getbuffer (TCPSTREAM *stream,unsigned long size,char *buffer)
  165. {
  166.   unsigned long n;
  167.   char *bufptr = buffer;
  168.   while (size > 0) { /* until request satisfied */
  169.     if (!tcp_getdata (stream)) return NIL;
  170.     n = min (size,stream->ictr);/* number of bytes to transfer */
  171. /* do the copy */
  172.     memcpy (bufptr,stream->iptr,(size_t) n);
  173.     bufptr += n; /* update pointer */
  174.     stream->iptr +=n;
  175.     size -= n; /* update # of bytes to do */
  176.     stream->ictr -=n;
  177.   }
  178.   bufptr[0] = ''; /* tie off string */
  179.   return T;
  180. }
  181. /* TCP/IP receive data
  182.  * Accepts: TCP/IP stream
  183.  * Returns: T if success, NIL otherwise
  184.  */
  185. long tcp_getdata (TCPSTREAM *stream)
  186. {
  187.   int status;
  188.   if (!stream->tcps) return NIL;/* no-no nuked socket */
  189.   while (stream->ictr < 1) { /* if buffer empty, block for input and read */
  190.     if (!_ip_delay1 (stream->tcps,600,NULL,&status))
  191.       stream->ictr = sock_fastread (stream->tcps,
  192.     stream->iptr = stream->ibuf,BUFLEN);
  193.     else if (status == 1) { /* nuke the socket if closed */
  194.       sock_close (stream->tcps);
  195.       fs_give ((void **) &stream->tcps);
  196.       return NIL;
  197.     }
  198.   }
  199.   return T;
  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. /* output the cruft */
  208.   sock_puts (stream->tcps,string);
  209.   return T; /* all done */
  210. }
  211. /* TCP/IP send string
  212.  * Accepts: TCP/IP stream
  213.  *     string pointer
  214.  *     byte count
  215.  * Returns: T if success else NIL
  216.  */
  217. long tcp_sout (TCPSTREAM *stream,char *string,unsigned long size)
  218. {
  219.   sock_write (stream->tcps,string,(int) size);
  220.   return T;
  221. }
  222. /* TCP/IP close
  223.  * Accepts: TCP/IP stream
  224.  */
  225. void tcp_close (TCPSTREAM *stream)
  226. {
  227.   if (stream->tcps){  /* nuke the socket */
  228.     sock_close (stream->tcps);
  229.     _ip_delay2 (stream->tcps,0,NULL,NULL);
  230.   }
  231.   fs_give ((void **) &stream->tcps);
  232. /* flush host names */
  233.   fs_give ((void **) &stream->host);
  234.   fs_give ((void **) &stream->localhost);
  235.   fs_give ((void **) &stream); /* flush the stream */
  236. }
  237. /* TCP/IP get host name
  238.  * Accepts: TCP/IP stream
  239.  * Returns: host name for this stream
  240.  */
  241. char *tcp_host (TCPSTREAM *stream)
  242. {
  243.   return stream->host; /* return host name */
  244. }
  245. /* TCP/IP get remote host name
  246.  * Accepts: TCP/IP stream
  247.  * Returns: host name for this stream
  248.  */
  249. char *tcp_remotehost (TCPSTREAM *stream)
  250. {
  251.   return stream->host; /* return host name */
  252. }
  253. /* TCP/IP return port for this stream
  254.  * Accepts: TCP/IP stream
  255.  * Returns: port number for this stream
  256.  */
  257. unsigned long tcp_port (TCPSTREAM *stream)
  258. {
  259.   return stream->port; /* return port number */
  260. }
  261. /* TCP/IP get local host name
  262.  * Accepts: TCP/IP stream
  263.  * Returns: local host name
  264.  */
  265. char *tcp_localhost (TCPSTREAM *stream)
  266. {
  267.   return stream->localhost; /* return local host name */
  268. }
  269. /* TCP/IP return canonical form of host name
  270.  * Accepts: host name
  271.  * Returns: canonical form of host name
  272.  */
  273. char *tcp_canonical (char *name)
  274. {
  275.   return name;
  276. }
  277. /* TCP/IP get client host name (server calls only)
  278.  * Returns: client host name
  279.  */
  280. char *tcp_clienthost ()
  281. {
  282.   return "UNKNOWN";
  283. }