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

网络编程

开发平台:

Unix_Linux

  1. /*
  2.  * Program: TOPS-20 TCP/IP routines
  3.  *
  4.  * Author: Mark Crispin
  5.  * 6158 Lariat Loop NE
  6.  * Bainbridge Island, WA  98110-2098
  7.  * Internet: MRC@Panda.COM
  8.  *
  9.  * Date: 1 August 1988
  10.  * Last Edited: 28 September 1998
  11.  *
  12.  * Copyright 1998 by Mark Crispin
  13.  *
  14.  *  Permission to use, copy, modify, and distribute this software and its
  15.  * documentation for any purpose and without fee is hereby granted, provided
  16.  * that the above copyright notices appear in all copies and that both the
  17.  * above copyright notices and this permission notice appear in supporting
  18.  * documentation, and that the name of Mark Crispin not be used in advertising
  19.  * or publicity pertaining to distribution of the software without specific,
  20.  * written prior permission.  This software is made available "as is", and
  21.  * MARK CRISPIN DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
  22.  * THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED WARRANTIES OF
  23.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN NO EVENT SHALL
  24.  * MARK CRISPIN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES
  25.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  26.  * WHETHER IN AN ACTION OF CONTRACT, TORT (INCLUDING NEGLIGENCE) OR STRICT
  27.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
  28.  * THIS SOFTWARE.
  29.  *
  30.  */
  31. /* Dedication:
  32.  * This file is dedicated with affection to the TOPS-20 operating system, which
  33.  * set standards for user and programmer friendliness that have still not been
  34.  * equaled by more `modern' operating systems.
  35.  * Wasureru mon ka!!!!
  36.  */
  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 stream if success else NIL
  51.  */
  52. TCPSTREAM *tcp_open (char *host,char *service,unsigned long port)
  53. {
  54.   char *s,tmp[MAILTMPLEN];
  55.   TCPSTREAM *stream = NIL;
  56.   int argblk[5],jfn;
  57.   unsigned long i,j,k,l;
  58.   char file[MAILTMPLEN];
  59. /* domain literal? */
  60.   if (host[0] == '[' && host[strlen (host)-1] == ']') {
  61.     if (((i = strtoul (s = host+1,&s,10)) <= 255) && *s++ == '.' &&
  62. ((j = strtoul (s,&s,10)) <= 255) && *s++ == '.' &&
  63. ((k = strtoul (s,&s,10)) <= 255) && *s++ == '.' &&
  64. ((l = strtoul (s,&s,10)) <= 255) && *s++ == ']' && !*s) {
  65.       argblk[3] = (i << 24) + (j << 16) + (k << 8) + l;
  66.       sprintf (tmp,"[%lu.%lu.%lu.%lu]",i,j,k,l);
  67.     }
  68.     else {
  69.       sprintf (tmp,"Bad format domain-literal: %.80s",host);
  70.       mm_log (tmp,ERROR);
  71.       return NIL;
  72.     }
  73.   }
  74.   else { /* host name */
  75.     argblk[1] = _GTHPN; /* get IP address and primary name */
  76.     argblk[2] = (int) (host-1); /* pointer to host */
  77.     argblk[4] = (int) (tmp-1);
  78.     if (!jsys (GTHST,argblk)) { /* first try DEC's domain way */
  79.       argblk[1] = _GTHPN; /* get IP address and primary name */
  80.       argblk[2] = (int) (host-1);
  81.       argblk[4] = (int) (tmp-1);
  82.       if (!jsys (GTDOM,argblk)){/* try the CHIVES domain way */
  83. argblk[1] = _GTHSN; /* failed, do the host table then */
  84. if (!jsys (GTHST,argblk)) {
  85.   sprintf (tmp,"No such host as %s",host);
  86.   mm_log (tmp,ERROR);
  87.   return NIL;
  88. }
  89. argblk[1] = _GTHNS; /* convert number to string */
  90. argblk[2] = (int) (tmp-1);
  91. /* get the official name */
  92. if (!jsys (GTHST,argblk)) strcpy (tmp,host);
  93.       }
  94.     }
  95.   }
  96.   sprintf (file,"TCP:.%o-%d;PERSIST:30;CONNECTION:ACTIVE",argblk[3],port);
  97.   argblk[1] = GJ_SHT; /* short form GTJFN% */
  98.   argblk[2] = (int) (file-1); /* pointer to file name */
  99. /* get JFN for TCP: file */
  100.   if (!jsys (GTJFN,argblk)) fatal ("Unable to create TCP JFN");
  101.   jfn = argblk[1]; /* note JFN for later */
  102. /* want 8-bit bidirectional I/O */
  103.   argblk[2] = OF_RD|OF_WR|(FLD (8,monsym("OF%BSZ")));
  104.   if (!jsys (OPENF,argblk)) {
  105.     sprintf (file,"Can't connect to %s,%d server",tmp,port);
  106.     mm_log (file,ERROR);
  107.     return NIL;
  108.   }
  109. /* create TCP/IP stream */
  110.   stream = (TCPSTREAM *) fs_get (sizeof (TCPSTREAM));
  111.   stream->host = cpystr (tmp); /* copy official host name */
  112.   argblk[1] = _GTHNS; /* convert number to string */
  113.   argblk[2] = (int) (tmp-1);
  114.   argblk[3] = -1; /* want local host */
  115.   if (!jsys (GTHST,argblk)) strcpy (tmp,"LOCAL");
  116.   stream->localhost = cpystr (tmp);
  117.   stream->port = port; /* save port number */
  118.   stream->jfn = jfn; /* init JFN */
  119.   return stream;
  120. }
  121. /* TCP/IP authenticated open
  122.  * Accepts: NETMBX specifier
  123.  *     service name
  124.  *     returned user name buffer
  125.  * Returns: TCP/IP stream if success else NIL
  126.  */
  127. TCPSTREAM *tcp_aopen (NETMBX *mb,char *service,char *usrbuf)
  128. {
  129.   return NIL;
  130. }
  131. /* TCP/IP receive line
  132.  * Accepts: TCP/IP stream
  133.  * Returns: text line string or NIL if failure
  134.  */
  135. char *tcp_getline (TCPSTREAM *stream)
  136. {
  137.   int argblk[5];
  138.   int n,m;
  139.   char *ret,*stp,*st;
  140.   argblk[1] = stream->jfn; /* read from TCP */
  141. /* pointer to buffer */
  142.   argblk[2] = (int) (stream->ibuf-1);
  143.   argblk[3] = BUFLEN; /* max number of bytes to read */
  144.   argblk[4] = '12'; /* terminate on LF */
  145.   if (!jsys (SIN,argblk)) return NIL;
  146.   n = BUFLEN - argblk[3]; /* number of bytes read */
  147. /* got a complete line? */
  148.   if ((stream->ibuf[n - 2] == '15') && (stream->ibuf[n - 1] == '12')) {
  149.     memcpy ((ret = (char *) fs_get (n)),stream->ibuf,n - 2);
  150.     ret[n - 2] = ''; /* tie off string with null */
  151.     return ret;
  152.   }
  153. /* copy partial string */
  154.   memcpy ((stp = ret = (char *) fs_get (n)),stream->ibuf,n);
  155. /* special case of newline broken by buffer */
  156.   if ((stream->ibuf[n - 1] == '15') && jsys (BIN,argblk) &&
  157.       (argblk[2] == '12')) { /* was it? */
  158.     ret[n - 1] = ''; /* tie off string with null */
  159.   }
  160. /* recurse to get remainder */
  161.   else if (jsys (BKJFN,argblk) && (st = tcp_getline (stream))) {
  162.     ret = (char *) fs_get (n + 1 + (m = strlen (st)));
  163.     memcpy (ret,stp,n); /* copy first part */
  164.     memcpy (ret + n,st,m); /* and second part */
  165.     fs_give ((void **) &stp); /* flush first part */
  166.     fs_give ((void **) &st); /* flush second part */
  167.     ret[n + m] = ''; /* tie off string with null */
  168.   }
  169.   return ret;
  170. }
  171. /* TCP/IP receive buffer
  172.  * Accepts: TCP/IP stream
  173.  *     size in bytes
  174.  *     buffer to read into
  175.  * Returns: T if success, NIL otherwise
  176.  */
  177. long tcp_getbuffer (TCPSTREAM *stream,unsigned long size,char *buffer)
  178. {
  179.   int argblk[5];
  180.   argblk[1] = stream->jfn; /* read from TCP */
  181.   argblk[2] = (int) (buffer-1); /* pointer to buffer */
  182.   argblk[3] = -size; /* number of bytes to read */
  183.   if (!jsys (SIN,argblk)) return NIL;
  184.   buffer[size] = ''; /* tie off text */
  185.   return T;
  186. }
  187. /* TCP/IP send string as record
  188.  * Accepts: TCP/IP stream
  189.  *     string pointer
  190.  * Returns: T if success else NIL
  191.  */
  192. long tcp_soutr (TCPSTREAM *stream,char *string)
  193. {
  194.   int argblk[5];
  195.   argblk[1] = stream->jfn; /* write to TCP */
  196.   argblk[2] = (int) (string-1); /* pointer to buffer */
  197.   argblk[3] = 0; /* write until NUL */
  198.   if (!jsys (SOUTR,argblk)) return NIL;
  199.   return T;
  200. }
  201. /* TCP/IP send string
  202.  * Accepts: TCP/IP stream
  203.  *     string pointer
  204.  *     byte count
  205.  * Returns: T if success else NIL
  206.  */
  207. long tcp_sout (TCPSTREAM *stream,char *string,unsigned long size)
  208. {
  209.   int argblk[5];
  210.   argblk[1] = stream->jfn; /* write to TCP */
  211.   argblk[2] = (int) (string-1); /* pointer to buffer */
  212.   argblk[3] = -size; /* write this many bytes */
  213.   if (!jsys (SOUTR,argblk)) return NIL;
  214.   return T;
  215. }
  216. /* TCP/IP close
  217.  * Accepts: TCP/IP stream
  218.  */
  219. void tcp_close (TCPSTREAM *stream)
  220. {
  221.   int argblk[5];
  222.   argblk[1] = stream->jfn; /* close TCP */
  223.   jsys (CLOSF,argblk);
  224. /* flush host names */
  225.   fs_give ((void **) &stream->host);
  226.   fs_give ((void **) &stream->localhost);
  227.   fs_give ((void **) &stream); /* flush the stream */
  228. }
  229. /* TCP/IP return host for this stream
  230.  * Accepts: TCP/IP stream
  231.  * Returns: host name for this stream
  232.  */
  233. char *tcp_host (TCPSTREAM *stream)
  234. {
  235.   return stream->host; /* return host name */
  236. }
  237. /* TCP/IP return remote host for this stream
  238.  * Accepts: TCP/IP stream
  239.  * Returns: host name for this stream
  240.  */
  241. char *tcp_remotehost (TCPSTREAM *stream)
  242. {
  243.   return stream->host; /* return host name */
  244. }
  245. /* TCP/IP return port for this stream
  246.  * Accepts: TCP/IP stream
  247.  * Returns: port number for this stream
  248.  */
  249. unsigned long tcp_port (TCPSTREAM *stream)
  250. {
  251.   return stream->port; /* return port number */
  252. }
  253. /* TCP/IP return local host for this stream
  254.  * Accepts: TCP/IP stream
  255.  * Returns: local host name for this stream
  256.  */
  257. char *tcp_localhost (TCPSTREAM *stream)
  258. {
  259.   return stream->localhost; /* return local host name */
  260. }
  261. /* TCP/IP return canonical form of host name
  262.  * Accepts: host name
  263.  * Returns: canonical form of host name
  264.  */
  265. char *tcp_canonical (char *name)
  266. {
  267.   int argblk[5];
  268.   static char tmp[MAILTMPLEN];
  269. /* look like domain literal? */
  270.   if (name[0] == '[' && name[strlen (name) - 1] == ']') return name;
  271.   argblk[1] = _GTHPN; /* get IP address and primary name */
  272.   argblk[2] = (int) (name-1); /* pointer to host */
  273.   argblk[4] = (int) (tmp-1); /* pointer to return destination */
  274.   if (!jsys (GTHST,argblk)) { /* first try DEC's domain way */
  275.     argblk[1] = _GTHPN; /* get IP address and primary name */
  276.     argblk[2] = (int) (name-1);
  277.     argblk[4] = (int) (tmp-1);
  278.     if (!jsys (GTDOM,argblk)) { /* try the CHIVES domain way */
  279.       argblk[1] = _GTHSN; /* failed, do the host table then */
  280.       if (!jsys (GTHST,argblk)) return name;
  281.       argblk[1] = _GTHNS; /* convert number to string */
  282.       argblk[2] = (int) (tmp-1);
  283. /* get the official name */
  284.       if (!jsys (GTHST,argblk)) return name;
  285.     }
  286.   }
  287.   return tmp;
  288. }
  289. /* TCP/IP get client host name (server calls only)
  290.  * Returns: client host name
  291.  */
  292. char *tcp_clienthost ()
  293. {
  294.   return "UNKNOWN";
  295. }