imapext-2007

diff src/osdep/tops-20/tcp_t20.c @ 0:ada5e610ab86

imap-2007e
author yuuji@gentei.org
date Mon, 14 Sep 2009 15:17:45 +0900
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/osdep/tops-20/tcp_t20.c	Mon Sep 14 15:17:45 2009 +0900
     1.3 @@ -0,0 +1,365 @@
     1.4 +/* ========================================================================
     1.5 + * Copyright 1988-2008 University of Washington
     1.6 + *
     1.7 + * Licensed under the Apache License, Version 2.0 (the "License");
     1.8 + * you may not use this file except in compliance with the License.
     1.9 + * You may obtain a copy of the License at
    1.10 + *
    1.11 + *     http://www.apache.org/licenses/LICENSE-2.0
    1.12 + *
    1.13 + * 
    1.14 + * ========================================================================
    1.15 + */
    1.16 +
    1.17 +/*
    1.18 + * Program:	TOPS-20 TCP/IP routines
    1.19 + *
    1.20 + * Author:	Mark Crispin
    1.21 + *		Networks and Distributed Computing
    1.22 + *		Computing & Communications
    1.23 + *		University of Washington
    1.24 + *		Administration Building, AG-44
    1.25 + *		Seattle, WA  98195
    1.26 + *		Internet: MRC@CAC.Washington.EDU
    1.27 + *
    1.28 + * Date:	1 August 1988
    1.29 + * Last Edited:	13 January 2008
    1.30 + */
    1.31 +
    1.32 +
    1.33 +/* Dedication:
    1.34 + * This file is dedicated with affection to the TOPS-20 operating system, which
    1.35 + * set standards for user and programmer friendliness that have still not been
    1.36 + * equaled by more `modern' operating systems.
    1.37 + * Wasureru mon ka!!!!
    1.38 + */
    1.39 +
    1.40 +static char *tcp_getline_work (TCPSTREAM *stream,unsigned long *size,
    1.41 +			       long *contd);
    1.42 +
    1.43 +/* TCP/IP manipulate parameters
    1.44 + * Accepts: function code
    1.45 + *	    function-dependent value
    1.46 + * Returns: function-dependent return value
    1.47 + */
    1.48 +
    1.49 +void *tcp_parameters (long function,void *value)
    1.50 +{
    1.51 +  return NIL;
    1.52 +}
    1.53 +
    1.54 +/* TCP/IP open
    1.55 + * Accepts: host name
    1.56 + *	    contact service name
    1.57 + *	    contact port number
    1.58 + * Returns: TCP stream if success else NIL
    1.59 + */
    1.60 +
    1.61 +TCPSTREAM *tcp_open (char *host,char *service,unsigned long port)
    1.62 +{
    1.63 +  char *s,tmp[MAILTMPLEN];
    1.64 +  TCPSTREAM *stream = NIL;
    1.65 +  int argblk[5],jfn;
    1.66 +  unsigned long i,j,k,l;
    1.67 +  char file[MAILTMPLEN];
    1.68 +  port &= 0xffff;		/* erase flags */
    1.69 +				/* domain literal? */
    1.70 +  if (host[0] == '[' && host[strlen (host)-1] == ']') {
    1.71 +    if (((i = strtoul (s = host+1,&s,10)) <= 255) && *s++ == '.' &&
    1.72 +	((j = strtoul (s,&s,10)) <= 255) && *s++ == '.' &&
    1.73 +	((k = strtoul (s,&s,10)) <= 255) && *s++ == '.' &&
    1.74 +	((l = strtoul (s,&s,10)) <= 255) && *s++ == ']' && !*s) {
    1.75 +      argblk[3] = (i << 24) + (j << 16) + (k << 8) + l;
    1.76 +      sprintf (tmp,"[%lu.%lu.%lu.%lu]",i,j,k,l);
    1.77 +    }
    1.78 +    else {
    1.79 +      sprintf (tmp,"Bad format domain-literal: %.80s",host);
    1.80 +      mm_log (tmp,ERROR);
    1.81 +      return NIL;
    1.82 +    }
    1.83 +  }
    1.84 +  else {			/* host name */
    1.85 +    argblk[1] = _GTHPN;		/* get IP address and primary name */
    1.86 +    argblk[2] = (int) (host-1);	/* pointer to host */
    1.87 +    argblk[4] = (int) (tmp-1);
    1.88 +    if (!jsys (GTHST,argblk)) {	/* first try DEC's domain way */
    1.89 +      argblk[1] = _GTHPN;	/* get IP address and primary name */
    1.90 +      argblk[2] = (int) (host-1);
    1.91 +      argblk[4] = (int) (tmp-1);
    1.92 +      if (!jsys (GTDOM,argblk)){/* try the CHIVES domain way */
    1.93 +	argblk[1] = _GTHSN;	/* failed, do the host table then */
    1.94 +	if (!jsys (GTHST,argblk)) {
    1.95 +	  sprintf (tmp,"No such host as %s",host);
    1.96 +	  mm_log (tmp,ERROR);
    1.97 +	  return NIL;
    1.98 +	}
    1.99 +	argblk[1] = _GTHNS;	/* convert number to string */
   1.100 +	argblk[2] = (int) (tmp-1);
   1.101 +				/* get the official name */
   1.102 +	if (!jsys (GTHST,argblk)) strcpy (tmp,host);
   1.103 +      }
   1.104 +    }
   1.105 +  }
   1.106 +
   1.107 +  sprintf (file,"TCP:.%o-%d;PERSIST:30;CONNECTION:ACTIVE",argblk[3],port);
   1.108 +  argblk[1] = GJ_SHT;		/* short form GTJFN% */
   1.109 +  argblk[2] = (int) (file-1);	/* pointer to file name */
   1.110 +				/* get JFN for TCP: file */
   1.111 +  if (!jsys (GTJFN,argblk)) fatal ("Unable to create TCP JFN");
   1.112 +  jfn = argblk[1];		/* note JFN for later */
   1.113 +				/* want 8-bit bidirectional I/O */
   1.114 +  argblk[2] = OF_RD|OF_WR|(FLD (8,monsym("OF%BSZ")));
   1.115 +  if (!jsys (OPENF,argblk)) {
   1.116 +    sprintf (file,"Can't connect to %s,%d server",tmp,port);
   1.117 +    mm_log (file,ERROR);
   1.118 +    return NIL;
   1.119 +  }
   1.120 +				/* create TCP/IP stream */
   1.121 +  stream = (TCPSTREAM *) fs_get (sizeof (TCPSTREAM));
   1.122 +  stream->host = cpystr (tmp);	/* copy official host name */
   1.123 +  argblk[1] = _GTHNS;		/* convert number to string */
   1.124 +  argblk[2] = (int) (tmp-1);
   1.125 +  argblk[3] = -1;		/* want local host */
   1.126 +  if (!jsys (GTHST,argblk)) strcpy (tmp,"LOCAL");
   1.127 +  stream->localhost = cpystr (tmp);
   1.128 +  stream->port = port;		/* save port number */
   1.129 +  stream->jfn = jfn;		/* init JFN */
   1.130 +  return stream;
   1.131 +}
   1.132 +
   1.133 +/* TCP/IP authenticated open
   1.134 + * Accepts: NETMBX specifier
   1.135 + *	    service name
   1.136 + *	    returned user name buffer
   1.137 + * Returns: TCP/IP stream if success else NIL
   1.138 + */
   1.139 +
   1.140 +TCPSTREAM *tcp_aopen (NETMBX *mb,char *service,char *usrbuf)
   1.141 +{
   1.142 +  return NIL;
   1.143 +}
   1.144 +
   1.145 +/* TCP receive line
   1.146 + * Accepts: TCP stream
   1.147 + * Returns: text line string or NIL if failure
   1.148 + */
   1.149 +
   1.150 +char *tcp_getline (TCPSTREAM *stream)
   1.151 +{
   1.152 +  unsigned long n,contd;
   1.153 +  char *ret = tcp_getline_work (stream,&n,&contd);
   1.154 +  if (ret && contd) {		/* got a line needing continuation? */
   1.155 +    STRINGLIST *stl = mail_newstringlist ();
   1.156 +    STRINGLIST *stc = stl;
   1.157 +    do {			/* collect additional lines */
   1.158 +      stc->text.data = (unsigned char *) ret;
   1.159 +      stc->text.size = n;
   1.160 +      stc = stc->next = mail_newstringlist ();
   1.161 +      ret = tcp_getline_work (stream,&n,&contd);
   1.162 +    } while (ret && contd);
   1.163 +    if (ret) {			/* stash final part of line on list */
   1.164 +      stc->text.data = (unsigned char *) ret;
   1.165 +      stc->text.size = n;
   1.166 +				/* determine how large a buffer we need */
   1.167 +      for (n = 0, stc = stl; stc; stc = stc->next) n += stc->text.size;
   1.168 +      ret = fs_get (n + 1);	/* copy parts into buffer */
   1.169 +      for (n = 0, stc = stl; stc; n += stc->text.size, stc = stc->next)
   1.170 +	memcpy (ret + n,stc->text.data,stc->text.size);
   1.171 +      ret[n] = '\0';
   1.172 +    }
   1.173 +    mail_free_stringlist (&stl);/* either way, done with list */
   1.174 +  }
   1.175 +  return ret;
   1.176 +}
   1.177 +
   1.178 +/* TCP receive line or partial line
   1.179 + * Accepts: TCP stream
   1.180 + *	    pointer to return size
   1.181 + *	    pointer to return continuation flag
   1.182 + * Returns: text line string, size and continuation flag, or NIL if failure
   1.183 + */
   1.184 +
   1.185 +static char *tcp_getline_work (TCPSTREAM *stream,unsigned long *size,
   1.186 +			       long *contd)
   1.187 +{
   1.188 +  int argblk[5];
   1.189 +  unsigned long n,m;
   1.190 +  char *ret,*stp,*st;
   1.191 +  *contd = NIL;			/* assume no continuation */
   1.192 +  argblk[1] = stream->jfn;	/* read from TCP */
   1.193 +				/* pointer to buffer */
   1.194 +  argblk[2] = (int) (stream->ibuf - 1);
   1.195 +  argblk[3] = BUFLEN;		/* max number of bytes to read */
   1.196 +  argblk[4] = '\012';		/* terminate on LF */
   1.197 +  if (!jsys (SIN,argblk)) return NIL;
   1.198 +  n = BUFLEN - argblk[3];	/* number of bytes read */
   1.199 +				/* got a complete line? */
   1.200 +  if ((stream->ibuf[n - 2] == '\015') && (stream->ibuf[n - 1] == '\012')) {
   1.201 +    memcpy ((ret = (char *) fs_get (n)),stream->ibuf,*size = n - 2);
   1.202 +    ret[n - 2] = '\0';		/* tie off string with null */
   1.203 +    return ret;
   1.204 +  }
   1.205 +				/* copy partial string */
   1.206 +  memcpy ((ret = (char *) fs_get (n)),stream->ibuf,*size = n);
   1.207 +				/* special case of newline broken by buffer */
   1.208 +  if ((stream->ibuf[n - 1] == '\015') && jsys (BIN,argblk) &&
   1.209 +      (argblk[2] == '\012')) {	/* was it? */
   1.210 +    ret[n - 1] = '\0';		/* tie off string with null */
   1.211 +  }
   1.212 +				/* otherwise back up */
   1.213 +  else if (!jsys (BKJFN,argblk)) fs_give ((void **) &ret);
   1.214 +  else *contd = LONGT;		/* continuation needed */
   1.215 +  return ret;
   1.216 +}
   1.217 +
   1.218 +/* TCP/IP receive buffer
   1.219 + * Accepts: TCP/IP stream
   1.220 + *	    size in bytes
   1.221 + *	    buffer to read into
   1.222 + * Returns: T if success, NIL otherwise
   1.223 + */
   1.224 +
   1.225 +long tcp_getbuffer (TCPSTREAM *stream,unsigned long size,char *buffer)
   1.226 +{
   1.227 +  int argblk[5];
   1.228 +  argblk[1] = stream->jfn;	/* read from TCP */
   1.229 +  argblk[2] = (int) (buffer-1);	/* pointer to buffer */
   1.230 +  argblk[3] = -size;		/* number of bytes to read */
   1.231 +  if (!jsys (SIN,argblk)) return NIL;
   1.232 +  buffer[size] = '\0';		/* tie off text */
   1.233 +  return T;
   1.234 +}
   1.235 +
   1.236 +
   1.237 +/* TCP/IP send string as record
   1.238 + * Accepts: TCP/IP stream
   1.239 + *	    string pointer
   1.240 + * Returns: T if success else NIL
   1.241 + */
   1.242 +
   1.243 +long tcp_soutr (TCPSTREAM *stream,char *string)
   1.244 +{
   1.245 +  int argblk[5];
   1.246 +  argblk[1] = stream->jfn;	/* write to TCP */
   1.247 +  argblk[2] = (int) (string-1);	/* pointer to buffer */
   1.248 +  argblk[3] = 0;		/* write until NUL */
   1.249 +  if (!jsys (SOUTR,argblk)) return NIL;
   1.250 +  return T;
   1.251 +}
   1.252 +
   1.253 +
   1.254 +/* TCP/IP send string
   1.255 + * Accepts: TCP/IP stream
   1.256 + *	    string pointer
   1.257 + *	    byte count
   1.258 + * Returns: T if success else NIL
   1.259 + */
   1.260 +
   1.261 +long tcp_sout (TCPSTREAM *stream,char *string,unsigned long size)
   1.262 +{
   1.263 +  int argblk[5];
   1.264 +  argblk[1] = stream->jfn;	/* write to TCP */
   1.265 +  argblk[2] = (int) (string-1);	/* pointer to buffer */
   1.266 +  argblk[3] = -size;		/* write this many bytes */
   1.267 +  if (!jsys (SOUTR,argblk)) return NIL;
   1.268 +  return T;
   1.269 +}
   1.270 +
   1.271 +/* TCP/IP close
   1.272 + * Accepts: TCP/IP stream
   1.273 + */
   1.274 +
   1.275 +void tcp_close (TCPSTREAM *stream)
   1.276 +{
   1.277 +  int argblk[5];
   1.278 +  argblk[1] = stream->jfn;	/* close TCP */
   1.279 +  jsys (CLOSF,argblk);
   1.280 +				/* flush host names */
   1.281 +  fs_give ((void **) &stream->host);
   1.282 +  fs_give ((void **) &stream->localhost);
   1.283 +  fs_give ((void **) &stream);	/* flush the stream */
   1.284 +}
   1.285 +
   1.286 +
   1.287 +/* TCP/IP return host for this stream
   1.288 + * Accepts: TCP/IP stream
   1.289 + * Returns: host name for this stream
   1.290 + */
   1.291 +
   1.292 +char *tcp_host (TCPSTREAM *stream)
   1.293 +{
   1.294 +  return stream->host;		/* return host name */
   1.295 +}
   1.296 +
   1.297 +
   1.298 +/* TCP/IP return remote host for this stream
   1.299 + * Accepts: TCP/IP stream
   1.300 + * Returns: host name for this stream
   1.301 + */
   1.302 +
   1.303 +char *tcp_remotehost (TCPSTREAM *stream)
   1.304 +{
   1.305 +  return stream->host;		/* return host name */
   1.306 +}
   1.307 +
   1.308 +
   1.309 +/* TCP/IP return port for this stream
   1.310 + * Accepts: TCP/IP stream
   1.311 + * Returns: port number for this stream
   1.312 + */
   1.313 +
   1.314 +unsigned long tcp_port (TCPSTREAM *stream)
   1.315 +{
   1.316 +  return stream->port;		/* return port number */
   1.317 +}
   1.318 +
   1.319 +
   1.320 +/* TCP/IP return local host for this stream
   1.321 + * Accepts: TCP/IP stream
   1.322 + * Returns: local host name for this stream
   1.323 + */
   1.324 +
   1.325 +char *tcp_localhost (TCPSTREAM *stream)
   1.326 +{
   1.327 +  return stream->localhost;	/* return local host name */
   1.328 +}
   1.329 +
   1.330 +/* TCP/IP return canonical form of host name
   1.331 + * Accepts: host name
   1.332 + * Returns: canonical form of host name
   1.333 + */
   1.334 +
   1.335 +char *tcp_canonical (char *name)
   1.336 +{
   1.337 +  int argblk[5];
   1.338 +  static char tmp[MAILTMPLEN];
   1.339 +				/* look like domain literal? */
   1.340 +  if (name[0] == '[' && name[strlen (name) - 1] == ']') return name;
   1.341 +  argblk[1] = _GTHPN;		/* get IP address and primary name */
   1.342 +  argblk[2] = (int) (name-1);	/* pointer to host */
   1.343 +  argblk[4] = (int) (tmp-1);	/* pointer to return destination */
   1.344 +  if (!jsys (GTHST,argblk)) {	/* first try DEC's domain way */
   1.345 +    argblk[1] = _GTHPN;		/* get IP address and primary name */
   1.346 +    argblk[2] = (int) (name-1);
   1.347 +    argblk[4] = (int) (tmp-1);
   1.348 +    if (!jsys (GTDOM,argblk)) {	/* try the CHIVES domain way */
   1.349 +      argblk[1] = _GTHSN;	/* failed, do the host table then */
   1.350 +      if (!jsys (GTHST,argblk)) return name;
   1.351 +      argblk[1] = _GTHNS;	/* convert number to string */
   1.352 +      argblk[2] = (int) (tmp-1);
   1.353 +				/* get the official name */
   1.354 +      if (!jsys (GTHST,argblk)) return name;
   1.355 +    }
   1.356 +  }
   1.357 +  return tmp;
   1.358 +}
   1.359 +
   1.360 +
   1.361 +/* TCP/IP get client host name (server calls only)
   1.362 + * Returns: client host name
   1.363 + */
   1.364 +
   1.365 +char *tcp_clienthost ()
   1.366 +{
   1.367 +  return "UNKNOWN";
   1.368 +}

UW-IMAP'd extensions by yuuji