home *** CD-ROM | disk | FTP | other *** search
/ ftp.uv.es / 2014.11.ftp.uv.es.tar / ftp.uv.es / pub / unix / pine4.10.tar.gz / pine4.10.tar / pine4.10 / imap / src / osdep / tops-20 / tcp_t20.c < prev    next >
C/C++ Source or Header  |  1998-09-28  |  10KB  |  334 lines

  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.  
  32.  
  33. /* Dedication:
  34.  * This file is dedicated with affection to the TOPS-20 operating system, which
  35.  * set standards for user and programmer friendliness that have still not been
  36.  * equaled by more `modern' operating systems.
  37.  * Wasureru mon ka!!!!
  38.  */
  39.  
  40. /* TCP/IP manipulate parameters
  41.  * Accepts: function code
  42.  *        function-dependent value
  43.  * Returns: function-dependent return value
  44.  */
  45.  
  46. void *tcp_parameters (long function,void *value)
  47. {
  48.   return NIL;
  49. }
  50.  
  51. /* TCP/IP open
  52.  * Accepts: host name
  53.  *        contact service name
  54.  *        contact port number
  55.  * Returns: TCP stream if success else NIL
  56.  */
  57.  
  58. TCPSTREAM *tcp_open (char *host,char *service,unsigned long port)
  59. {
  60.   char *s,tmp[MAILTMPLEN];
  61.   TCPSTREAM *stream = NIL;
  62.   int argblk[5],jfn;
  63.   unsigned long i,j,k,l;
  64.   char file[MAILTMPLEN];
  65.                 /* domain literal? */
  66.   if (host[0] == '[' && host[strlen (host)-1] == ']') {
  67.     if (((i = strtoul (s = host+1,&s,10)) <= 255) && *s++ == '.' &&
  68.     ((j = strtoul (s,&s,10)) <= 255) && *s++ == '.' &&
  69.     ((k = strtoul (s,&s,10)) <= 255) && *s++ == '.' &&
  70.     ((l = strtoul (s,&s,10)) <= 255) && *s++ == ']' && !*s) {
  71.       argblk[3] = (i << 24) + (j << 16) + (k << 8) + l;
  72.       sprintf (tmp,"[%lu.%lu.%lu.%lu]",i,j,k,l);
  73.     }
  74.     else {
  75.       sprintf (tmp,"Bad format domain-literal: %.80s",host);
  76.       mm_log (tmp,ERROR);
  77.       return NIL;
  78.     }
  79.   }
  80.   else {            /* host name */
  81.     argblk[1] = _GTHPN;        /* get IP address and primary name */
  82.     argblk[2] = (int) (host-1);    /* pointer to host */
  83.     argblk[4] = (int) (tmp-1);
  84.     if (!jsys (GTHST,argblk)) {    /* first try DEC's domain way */
  85.       argblk[1] = _GTHPN;    /* get IP address and primary name */
  86.       argblk[2] = (int) (host-1);
  87.       argblk[4] = (int) (tmp-1);
  88.       if (!jsys (GTDOM,argblk)){/* try the CHIVES domain way */
  89.     argblk[1] = _GTHSN;    /* failed, do the host table then */
  90.     if (!jsys (GTHST,argblk)) {
  91.       sprintf (tmp,"No such host as %s",host);
  92.       mm_log (tmp,ERROR);
  93.       return NIL;
  94.     }
  95.     argblk[1] = _GTHNS;    /* convert number to string */
  96.     argblk[2] = (int) (tmp-1);
  97.                 /* get the official name */
  98.     if (!jsys (GTHST,argblk)) strcpy (tmp,host);
  99.       }
  100.     }
  101.   }
  102.  
  103.   sprintf (file,"TCP:.%o-%d;PERSIST:30;CONNECTION:ACTIVE",argblk[3],port);
  104.   argblk[1] = GJ_SHT;        /* short form GTJFN% */
  105.   argblk[2] = (int) (file-1);    /* pointer to file name */
  106.                 /* get JFN for TCP: file */
  107.   if (!jsys (GTJFN,argblk)) fatal ("Unable to create TCP JFN");
  108.   jfn = argblk[1];        /* note JFN for later */
  109.                 /* want 8-bit bidirectional I/O */
  110.   argblk[2] = OF_RD|OF_WR|(FLD (8,monsym("OF%BSZ")));
  111.   if (!jsys (OPENF,argblk)) {
  112.     sprintf (file,"Can't connect to %s,%d server",tmp,port);
  113.     mm_log (file,ERROR);
  114.     return NIL;
  115.   }
  116.                 /* create TCP/IP stream */
  117.   stream = (TCPSTREAM *) fs_get (sizeof (TCPSTREAM));
  118.   stream->host = cpystr (tmp);    /* copy official host name */
  119.   argblk[1] = _GTHNS;        /* convert number to string */
  120.   argblk[2] = (int) (tmp-1);
  121.   argblk[3] = -1;        /* want local host */
  122.   if (!jsys (GTHST,argblk)) strcpy (tmp,"LOCAL");
  123.   stream->localhost = cpystr (tmp);
  124.   stream->port = port;        /* save port number */
  125.   stream->jfn = jfn;        /* init JFN */
  126.   return stream;
  127. }
  128.  
  129. /* TCP/IP authenticated open
  130.  * Accepts: NETMBX specifier
  131.  *        service name
  132.  *        returned user name buffer
  133.  * Returns: TCP/IP stream if success else NIL
  134.  */
  135.  
  136. TCPSTREAM *tcp_aopen (NETMBX *mb,char *service,char *usrbuf)
  137. {
  138.   return NIL;
  139. }
  140.  
  141. /* TCP/IP receive line
  142.  * Accepts: TCP/IP stream
  143.  * Returns: text line string or NIL if failure
  144.  */
  145.  
  146. char *tcp_getline (TCPSTREAM *stream)
  147. {
  148.   int argblk[5];
  149.   int n,m;
  150.   char *ret,*stp,*st;
  151.   argblk[1] = stream->jfn;    /* read from TCP */
  152.                 /* pointer to buffer */
  153.   argblk[2] = (int) (stream->ibuf-1);
  154.   argblk[3] = BUFLEN;        /* max number of bytes to read */
  155.   argblk[4] = '\012';        /* terminate on LF */
  156.   if (!jsys (SIN,argblk)) return NIL;
  157.   n = BUFLEN - argblk[3];    /* number of bytes read */
  158.                 /* got a complete line? */
  159.   if ((stream->ibuf[n - 2] == '\015') && (stream->ibuf[n - 1] == '\012')) {
  160.     memcpy ((ret = (char *) fs_get (n)),stream->ibuf,n - 2);
  161.     ret[n - 2] = '\0';    /* tie off string with null */
  162.     return ret;
  163.   }
  164.                 /* copy partial string */
  165.   memcpy ((stp = ret = (char *) fs_get (n)),stream->ibuf,n);
  166.                 /* special case of newline broken by buffer */
  167.   if ((stream->ibuf[n - 1] == '\015') && jsys (BIN,argblk) &&
  168.       (argblk[2] == '\012')) {    /* was it? */
  169.     ret[n - 1] = '\0';        /* tie off string with null */
  170.   }
  171.                 /* recurse to get remainder */
  172.   else if (jsys (BKJFN,argblk) && (st = tcp_getline (stream))) {
  173.     ret = (char *) fs_get (n + 1 + (m = strlen (st)));
  174.     memcpy (ret,stp,n);        /* copy first part */
  175.     memcpy (ret + n,st,m);    /* and second part */
  176.     fs_give ((void **) &stp);    /* flush first part */
  177.     fs_give ((void **) &st);    /* flush second part */
  178.     ret[n + m] = '\0';        /* tie off string with null */
  179.   }
  180.   return ret;
  181. }
  182.  
  183. /* TCP/IP receive buffer
  184.  * Accepts: TCP/IP stream
  185.  *        size in bytes
  186.  *        buffer to read into
  187.  * Returns: T if success, NIL otherwise
  188.  */
  189.  
  190. long tcp_getbuffer (TCPSTREAM *stream,unsigned long size,char *buffer)
  191. {
  192.   int argblk[5];
  193.   argblk[1] = stream->jfn;    /* read from TCP */
  194.   argblk[2] = (int) (buffer-1);    /* pointer to buffer */
  195.   argblk[3] = -size;        /* number of bytes to read */
  196.   if (!jsys (SIN,argblk)) return NIL;
  197.   buffer[size] = '\0';        /* tie off text */
  198.   return T;
  199. }
  200.  
  201.  
  202. /* TCP/IP send string as record
  203.  * Accepts: TCP/IP stream
  204.  *        string pointer
  205.  * Returns: T if success else NIL
  206.  */
  207.  
  208. long tcp_soutr (TCPSTREAM *stream,char *string)
  209. {
  210.   int argblk[5];
  211.   argblk[1] = stream->jfn;    /* write to TCP */
  212.   argblk[2] = (int) (string-1);    /* pointer to buffer */
  213.   argblk[3] = 0;        /* write until NUL */
  214.   if (!jsys (SOUTR,argblk)) return NIL;
  215.   return T;
  216. }
  217.  
  218.  
  219. /* TCP/IP send string
  220.  * Accepts: TCP/IP stream
  221.  *        string pointer
  222.  *        byte count
  223.  * Returns: T if success else NIL
  224.  */
  225.  
  226. long tcp_sout (TCPSTREAM *stream,char *string,unsigned long size)
  227. {
  228.   int argblk[5];
  229.   argblk[1] = stream->jfn;    /* write to TCP */
  230.   argblk[2] = (int) (string-1);    /* pointer to buffer */
  231.   argblk[3] = -size;        /* write this many bytes */
  232.   if (!jsys (SOUTR,argblk)) return NIL;
  233.   return T;
  234. }
  235.  
  236. /* TCP/IP close
  237.  * Accepts: TCP/IP stream
  238.  */
  239.  
  240. void tcp_close (TCPSTREAM *stream)
  241. {
  242.   int argblk[5];
  243.   argblk[1] = stream->jfn;    /* close TCP */
  244.   jsys (CLOSF,argblk);
  245.                 /* flush host names */
  246.   fs_give ((void **) &stream->host);
  247.   fs_give ((void **) &stream->localhost);
  248.   fs_give ((void **) &stream);    /* flush the stream */
  249. }
  250.  
  251.  
  252. /* TCP/IP return host for this stream
  253.  * Accepts: TCP/IP stream
  254.  * Returns: host name for this stream
  255.  */
  256.  
  257. char *tcp_host (TCPSTREAM *stream)
  258. {
  259.   return stream->host;        /* return host name */
  260. }
  261.  
  262.  
  263. /* TCP/IP return remote host for this stream
  264.  * Accepts: TCP/IP stream
  265.  * Returns: host name for this stream
  266.  */
  267.  
  268. char *tcp_remotehost (TCPSTREAM *stream)
  269. {
  270.   return stream->host;        /* return host name */
  271. }
  272.  
  273.  
  274. /* TCP/IP return port for this stream
  275.  * Accepts: TCP/IP stream
  276.  * Returns: port number for this stream
  277.  */
  278.  
  279. unsigned long tcp_port (TCPSTREAM *stream)
  280. {
  281.   return stream->port;        /* return port number */
  282. }
  283.  
  284.  
  285. /* TCP/IP return local host for this stream
  286.  * Accepts: TCP/IP stream
  287.  * Returns: local host name for this stream
  288.  */
  289.  
  290. char *tcp_localhost (TCPSTREAM *stream)
  291. {
  292.   return stream->localhost;    /* return local host name */
  293. }
  294.  
  295. /* TCP/IP return canonical form of host name
  296.  * Accepts: host name
  297.  * Returns: canonical form of host name
  298.  */
  299.  
  300. char *tcp_canonical (char *name)
  301. {
  302.   int argblk[5];
  303.   static char tmp[MAILTMPLEN];
  304.                 /* look like domain literal? */
  305.   if (name[0] == '[' && name[strlen (name) - 1] == ']') return name;
  306.   argblk[1] = _GTHPN;        /* get IP address and primary name */
  307.   argblk[2] = (int) (name-1);    /* pointer to host */
  308.   argblk[4] = (int) (tmp-1);    /* pointer to return destination */
  309.   if (!jsys (GTHST,argblk)) {    /* first try DEC's domain way */
  310.     argblk[1] = _GTHPN;        /* get IP address and primary name */
  311.     argblk[2] = (int) (name-1);
  312.     argblk[4] = (int) (tmp-1);
  313.     if (!jsys (GTDOM,argblk)) {    /* try the CHIVES domain way */
  314.       argblk[1] = _GTHSN;    /* failed, do the host table then */
  315.       if (!jsys (GTHST,argblk)) return name;
  316.       argblk[1] = _GTHNS;    /* convert number to string */
  317.       argblk[2] = (int) (tmp-1);
  318.                 /* get the official name */
  319.       if (!jsys (GTHST,argblk)) return name;
  320.     }
  321.   }
  322.   return tmp;
  323. }
  324.  
  325.  
  326. /* TCP/IP get client host name (server calls only)
  327.  * Returns: client host name
  328.  */
  329.  
  330. char *tcp_clienthost ()
  331. {
  332.   return "UNKNOWN";
  333. }
  334.