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

网络编程

开发平台:

Unix_Linux

  1. /*
  2.  * Program: VMS TCP/IP routines for Netlib.
  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: 2 August 1994
  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 available
  24.  * "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. /* Thanks to Yehavi Bourvine at The Hebrew University of Jerusalem who
  36.    contributed the original VMS code */
  37. #include <descrip.h>
  38. /* TCP/IP manipulate parameters
  39.  * Accepts: function code
  40.  *     function-dependent value
  41.  * Returns: function-dependent return value
  42.  */
  43. void *tcp_parameters (long function,void *value)
  44. {
  45.   return NIL;
  46. }
  47.  
  48. /* TCP/IP open
  49.  * Accepts: host name
  50.  *     contact service name
  51.  *     contact port number
  52.  * Returns: TCP/IP stream if success else NIL
  53.  */
  54. TCPSTREAM *tcp_open (char *host,char *service,unsigned long port)
  55. {
  56.   TCPSTREAM *stream = NIL;
  57.   unsigned long sock;
  58.   int status;
  59.   char tmp[MAILTMPLEN];
  60. /* hostname to connect to */
  61.   struct dsc$descriptor HostDesc = { 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL };
  62. /* assign a local socket */
  63.   if (!((status = net_assign (&sock)) & 0x1)) {
  64.     sprintf (tmp,"Unable to assign to net, status=%d",status);
  65.     mm_log (tmp,ERROR);
  66.     return NIL;
  67.   }
  68.   if (!((status = net_bind (&sock,1)) & 0x1)) {
  69.     sprintf (tmp,"Unable to create local socket, status=%d",status);
  70.     mm_log (tmp,ERROR);
  71.     return NIL;
  72.   }
  73. /* open connection */
  74.   HostDesc.dsc$w_length = strlen (host);
  75.   HostDesc.dsc$a_pointer = host;
  76.   if (!((status = tcp_connect (&sock,&HostDesc,port)) & 0x1)) {
  77.     sprintf (tmp,"Can't connect to %.80s,%lu: %s",host,port,strerror (errno));
  78.     mm_log (tmp,ERROR);
  79.     return NIL;
  80.   }
  81. /* create TCP/IP stream */
  82.   stream = (TCPSTREAM *) fs_get (sizeof (TCPSTREAM));
  83.   stream->host = cpystr (host); /* copy official host name */
  84. /* copy local host name */
  85.   stream->localhost = cpystr (mylocalhost ());
  86.   stream->port = port; /* copy port number */
  87. /* init sockets */
  88.   stream->tcpsi = stream->tcpso = sock;
  89.   stream->ictr = 0; /* init input counter */
  90.   return stream; /* return success */
  91. }
  92. /* TCP/IP authenticated open
  93.  * Accepts: NETMBX specifier
  94.  *     service name
  95.  *     returned user name buffer
  96.  * Returns: TCP/IP stream if success else NIL
  97.  */
  98. TCPSTREAM *tcp_aopen (NETMBX *mb,char *service,char *usrbuf)
  99. {
  100.   return NIL;
  101. }
  102. /* TCP/IP receive line
  103.  * Accepts: TCP/IP stream
  104.  * Returns: text line string or NIL if failure
  105.  */
  106. char *tcp_getline (TCPSTREAM *stream)
  107. {
  108.   int n,m;
  109.   char *st,*ret,*stp;
  110.   char c = '';
  111.   char d;
  112. /* make sure have data */
  113.   if (!tcp_getdata (stream)) return NIL;
  114.   st = stream->iptr; /* save start of string */
  115.   n = 0; /* init string count */
  116.   while (stream->ictr--) { /* look for end of line */
  117.     d = *stream->iptr++; /* slurp another character */
  118.     if ((c == '15') && (d == '12')) {
  119.       ret = (char *) fs_get (n--);
  120.       memcpy (ret,st,n); /* copy into a free storage string */
  121.       ret[n] = ''; /* tie off string with null */
  122.       return ret;
  123.     }
  124.     n++; /* count another character searched */
  125.     c = d; /* remember previous character */
  126.   }
  127. /* copy partial string from buffer */
  128.   memcpy ((ret = stp = (char *) fs_get (n)),st,n);
  129. /* get more data from the net */
  130.   if (!tcp_getdata (stream)) return NIL;
  131. /* special case of newline broken by buffer */
  132.   if ((c == '15') && (*stream->iptr == '12')) {
  133.     stream->iptr++; /* eat the line feed */
  134.     stream->ictr--;
  135.     ret[n - 1] = ''; /* tie off string with null */
  136.   }
  137. /* else recurse to get remainder */
  138.   else if (st = tcp_getline (stream)) {
  139.     ret = (char *) fs_get (n + 1 + (m = strlen (st)));
  140.     memcpy (ret,stp,n); /* copy first part */
  141.     memcpy (ret + n,st,m); /* and second part */
  142.     fs_give ((void **) &stp); /* flush first part */
  143.     fs_give ((void **) &st); /* flush second part */
  144.     ret[n + m] = ''; /* tie off string with null */
  145.   }
  146.   return ret;
  147. }
  148. /* TCP/IP receive buffer
  149.  * Accepts: TCP/IP stream
  150.  *     size in bytes
  151.  *     buffer to read into
  152.  * Returns: T if success, NIL otherwise
  153.  */
  154. long tcp_getbuffer (TCPSTREAM *stream,unsigned long size,char *buffer)
  155. {
  156.   unsigned long n;
  157.   char *bufptr = buffer;
  158.   while (size > 0) { /* until request satisfied */
  159.     if (!tcp_getdata (stream)) return NIL;
  160.     n = min (size,stream->ictr);/* number of bytes to transfer */
  161. /* do the copy */
  162.     memcpy (bufptr,stream->iptr,n);
  163.     bufptr += n; /* update pointer */
  164.     stream->iptr +=n;
  165.     size -= n; /* update # of bytes to do */
  166.     stream->ictr -=n;
  167.   }
  168.   bufptr[0] = ''; /* tie off string */
  169.   return T;
  170. }
  171. /* TCP/IP receive data
  172.  * Accepts: TCP/IP stream
  173.  * Returns: T if success, NIL otherwise
  174.  */
  175. long tcp_getdata (TCPSTREAM *stream)
  176. {
  177.   char tmp[MAILTMPLEN];
  178.   int i,status;
  179.   /* Note: the doc says we need here dynamic descriptor, but we need static
  180.    * one... */
  181.   struct dsc$descriptor BufDesc = {BUFLEN,DSC$K_DTYPE_T,DSC$K_CLASS_S,
  182.      stream->ibuf};
  183.   static short iosb[4];
  184.   if (stream->tcpsi < 0) return NIL;
  185.   while (stream->ictr < 1) { /* if nothing in the buffer */
  186.     if (!((status = tcp_receive(&(stream->tcpsi), &BufDesc, iosb)) & 0x1)) {
  187.       sprintf (tmp,"Error reading from TcpIp/NETLIB, status=%d",status);
  188.       mm_log (tmp,ERROR);
  189.       return tcp_abort (stream);
  190.     }
  191.     if (iosb[1] > BUFLEN) i = BUFLEN;
  192.     else i = iosb[1];
  193.     if (i < 1) return tcp_abort (stream);
  194.     stream->ictr = i; /* set new byte count */
  195.     stream->iptr = stream->ibuf;/* point at TCP buffer */
  196.   }
  197.   return T;
  198. }
  199. /* TCP/IP send string as record
  200.  * Accepts: TCP/IP stream
  201.  *     string pointer
  202.  * Returns: T if success else NIL
  203.  */
  204. long tcp_soutr (TCPSTREAM *stream,char *string)
  205. {
  206.   return tcp_sout (stream,string,(unsigned long) strlen (string));
  207. }
  208. /* TCP/IP send string
  209.  * Accepts: TCP/IP stream
  210.  *     string pointer
  211.  *     byte count
  212.  * Returns: T if success else NIL
  213.  */
  214. long tcp_sout (TCPSTREAM *stream,char *string,unsigned long size)
  215. {
  216.   int status;
  217.   struct dsc$descriptor_s BufDesc = {strlen(string),DSC$K_DTYPE_T,
  218.        DSC$K_CLASS_S,string };
  219. /* 2 = Do not add rn */
  220.   return ((status = tcp_send (&(stream->tcpso),&BufDesc,2)) & 0x1) ? T :
  221.     tcp_abort (stream);
  222. }
  223. /* TCP/IP close
  224.  * Accepts: TCP/IP stream
  225.  */
  226. void tcp_close (TCPSTREAM *stream)
  227. {
  228.   tcp_abort (stream); /* nuke the stream */
  229. /* flush host names */
  230.   fs_give ((void **) &stream->host);
  231.   fs_give ((void **) &stream->localhost);
  232.   fs_give ((void **) &stream); /* flush the stream */
  233. }
  234. /* TCP/IP abort stream
  235.  * Accepts: TCP/IP stream
  236.  * Returns: NIL always
  237.  */
  238. long tcp_abort (TCPSTREAM *stream)
  239. {
  240.   if (stream->tcpsi >= 0) { /* no-op if no socket */
  241. /* nuke the socket */
  242.     tcp_disconnect (&(stream->tcpsi));
  243.     stream->tcpsi = stream->tcpso = -1;
  244.   }
  245.   return NIL;
  246. }
  247. /* TCP/IP get host name
  248.  * Accepts: TCP/IP stream
  249.  * Returns: host name for this stream
  250.  */
  251. char *tcp_host (TCPSTREAM *stream)
  252. {
  253.   return stream->host; /* return host name */
  254. }
  255. /* TCP/IP get remote host name
  256.  * Accepts: TCP/IP stream
  257.  * Returns: host name for this stream
  258.  */
  259. char *tcp_remotehost (TCPSTREAM *stream)
  260. {
  261.   return stream->host; /* return host name */
  262. }
  263. /* TCP/IP return port for this stream
  264.  * Accepts: TCP/IP stream
  265.  * Returns: port number for this stream
  266.  */
  267. unsigned long tcp_port (TCPSTREAM *stream)
  268. {
  269.   return stream->port; /* return port number */
  270. }
  271. /* TCP/IP get local host name
  272.  * Accepts: TCP/IP stream
  273.  * Returns: local host name
  274.  */
  275. char *tcp_localhost (TCPSTREAM *stream)
  276. {
  277.   return stream->localhost; /* return local host name */
  278. }
  279. /* Return my local host name
  280.  * Returns: my local host name
  281.  */
  282. char *mylocalhost ()
  283. {
  284.   int status;
  285.   char tmp[MAILTMPLEN];
  286.   if (!myLocalHost) { /* have local host yet? */
  287. /* receives local host name */
  288.     struct dsc$descriptor LocalhostDesc = {0,DSC$K_DTYPE_T,DSC$K_CLASS_D,NULL};
  289.     if (!((status = net_get_hostname (&LocalhostDesc)) & 0x1)) {
  290.       sprintf (tmp,"Can't get local hostname, status=%d",status);
  291.       mm_log (tmp,ERROR);
  292.       return "UNKNOWN";
  293.     }
  294.     strncpy (tmp,LocalhostDesc.dsc$a_pointer,LocalhostDesc.dsc$w_length);
  295.     tmp[LocalhostDesc.dsc$w_length] = '';
  296.     str$free1_dx (&LocalhostDesc);
  297.     myLocalHost = cpystr (tmp);
  298.   }
  299.   return myLocalHost;
  300. }
  301. /* TCP/IP return canonical form of host name
  302.  * Accepts: host name
  303.  * Returns: canonical form of host name
  304.  */
  305. char *tcp_canonical (char *name)
  306. {
  307.   return name;
  308. }
  309. /* TCP/IP get client host name (server calls only)
  310.  * Returns: client host name
  311.  */
  312. char *tcp_clienthost ()
  313. {
  314.   return "UNKNOWN";
  315. }