imapext-2007
diff src/osdep/dos/tcp_dwa.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/dos/tcp_dwa.c Mon Sep 14 15:17:45 2009 +0900 1.3 @@ -0,0 +1,344 @@ 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: Waterloo DOS 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: 11 April 1989 1.29 + * Last Edited: 13 January 2008 1.30 + */ 1.31 + 1.32 + 1.33 +/* Global data */ 1.34 + 1.35 +short sock_initted = 0; /* global so others using net can see it */ 1.36 + 1.37 +static char *tcp_getline_work (TCPSTREAM *stream,unsigned long *size, 1.38 + long *contd); 1.39 + 1.40 +/* TCP/IP manipulate parameters 1.41 + * Accepts: function code 1.42 + * function-dependent value 1.43 + * Returns: function-dependent return value 1.44 + */ 1.45 + 1.46 +void *tcp_parameters (long function,void *value) 1.47 +{ 1.48 + return NIL; 1.49 +} 1.50 + 1.51 +/* TCP/IP open 1.52 + * Accepts: host name 1.53 + * contact service name 1.54 + * contact port number 1.55 + * Returns: TCP/IP stream if success else NIL 1.56 + */ 1.57 + 1.58 +TCPSTREAM *TCP_open (char *host,char *service,unsigned long port) 1.59 +{ 1.60 + TCPSTREAM *stream = NIL; 1.61 + tcp_Socket *sock; 1.62 + char *s,tmp[MAILTMPLEN]; 1.63 + unsigned long adr,i,j,k,l; 1.64 + port &= 0xffff; /* erase flags */ 1.65 + /* initialize if first time here */ 1.66 + if (!sock_initted++) sock_init(); 1.67 + /* The domain literal form is used (rather than simply the dotted decimal 1.68 + as with other Unix programs) because it has to be a valid "host name" 1.69 + in mailsystem terminology. */ 1.70 + /* look like domain literal? */ 1.71 + if (host[0] == '[' && host[strlen (host)-1] == ']') { 1.72 + if (((i = strtoul (s = host+1,&s,10)) <= 255) && *s++ == '.' && 1.73 + ((j = strtoul (s,&s,10)) <= 255) && *s++ == '.' && 1.74 + ((k = strtoul (s,&s,10)) <= 255) && *s++ == '.' && 1.75 + ((l = strtoul (s,&s,10)) <= 255) && *s++ == ']' && !*s) 1.76 + adr = (i << 24) + (j << 16) + (k << 8) + l; 1.77 + else { 1.78 + sprintf (tmp,"Bad format domain-literal: %.80s",host); 1.79 + mm_log (tmp,ERROR); 1.80 + return NIL; 1.81 + } 1.82 + } 1.83 + else { /* lookup host name */ 1.84 + if (!(adr = resolve (host))) { 1.85 + sprintf (tmp,"Host not found: %s",host); 1.86 + mm_log (tmp,ERROR); 1.87 + return NIL; 1.88 + } 1.89 + } 1.90 + 1.91 + /* OK to instantiate socket now */ 1.92 + sock = (tcp_Socket *) fs_get (sizeof (tcp_Socket)); 1.93 + /* open connection */ 1.94 + if (!tcp_open (sock,(word) 0,adr,(word) port,NULL)) { 1.95 + sprintf (tmp,"Can't connect to %.80s,%ld",host,port); 1.96 + mm_log (tmp,ERROR); 1.97 + fs_give ((void **) &sock); 1.98 + return NIL; 1.99 + } 1.100 + /* create TCP/IP stream */ 1.101 + stream = (TCPSTREAM *) fs_get (sizeof (TCPSTREAM)); 1.102 + stream->host = cpystr (host); /* official host name */ 1.103 + stream->localhost = cpystr (mylocalhost ()); 1.104 + stream->port = port; /* port number */ 1.105 + stream->tcps = sock; /* init socket */ 1.106 + stream->ictr = 0; /* init input counter */ 1.107 + return stream; /* return success */ 1.108 +} 1.109 + 1.110 +/* TCP/IP authenticated open 1.111 + * Accepts: NETMBX specifier 1.112 + * service name 1.113 + * returned user name buffer 1.114 + * Returns: TCP/IP stream if success else NIL 1.115 + */ 1.116 + 1.117 +TCPSTREAM *tcp_aopen (NETMBX *mb,char *service,char *usrbuf) 1.118 +{ 1.119 + return NIL; /* always NIL on DOS */ 1.120 +} 1.121 + 1.122 +/* TCP receive line 1.123 + * Accepts: TCP stream 1.124 + * Returns: text line string or NIL if failure 1.125 + */ 1.126 + 1.127 +char *tcp_getline (TCPSTREAM *stream) 1.128 +{ 1.129 + unsigned long n,contd; 1.130 + char *ret = tcp_getline_work (stream,&n,&contd); 1.131 + if (ret && contd) { /* got a line needing continuation? */ 1.132 + STRINGLIST *stl = mail_newstringlist (); 1.133 + STRINGLIST *stc = stl; 1.134 + do { /* collect additional lines */ 1.135 + stc->text.data = (unsigned char *) ret; 1.136 + stc->text.size = n; 1.137 + stc = stc->next = mail_newstringlist (); 1.138 + ret = tcp_getline_work (stream,&n,&contd); 1.139 + } while (ret && contd); 1.140 + if (ret) { /* stash final part of line on list */ 1.141 + stc->text.data = (unsigned char *) ret; 1.142 + stc->text.size = n; 1.143 + /* determine how large a buffer we need */ 1.144 + for (n = 0, stc = stl; stc; stc = stc->next) n += stc->text.size; 1.145 + ret = fs_get (n + 1); /* copy parts into buffer */ 1.146 + for (n = 0, stc = stl; stc; n += stc->text.size, stc = stc->next) 1.147 + memcpy (ret + n,stc->text.data,stc->text.size); 1.148 + ret[n] = '\0'; 1.149 + } 1.150 + mail_free_stringlist (&stl);/* either way, done with list */ 1.151 + } 1.152 + return ret; 1.153 +} 1.154 + 1.155 +/* TCP receive line or partial line 1.156 + * Accepts: TCP stream 1.157 + * pointer to return size 1.158 + * pointer to return continuation flag 1.159 + * Returns: text line string, size and continuation flag, or NIL if failure 1.160 + */ 1.161 + 1.162 +static char *tcp_getline_work (TCPSTREAM *stream,unsigned long *size, 1.163 + long *contd) 1.164 +{ 1.165 + unsigned long n; 1.166 + char *s,*ret,c,d; 1.167 + *contd = NIL; /* assume no continuation */ 1.168 + /* make sure have data */ 1.169 + if (!tcp_getdata (stream)) return NIL; 1.170 + for (s = stream->iptr, n = 0, c = '\0'; stream->ictr--; n++, c = d) { 1.171 + d = *stream->iptr++; /* slurp another character */ 1.172 + if ((c == '\015') && (d == '\012')) { 1.173 + ret = (char *) fs_get (n--); 1.174 + memcpy (ret,s,*size = n); /* copy into a free storage string */ 1.175 + ret[n] = '\0'; /* tie off string with null */ 1.176 + return ret; 1.177 + } 1.178 + } 1.179 + /* copy partial string from buffer */ 1.180 + memcpy ((ret = (char *) fs_get (n)),s,*size = n); 1.181 + /* get more data from the net */ 1.182 + if (!tcp_getdata (stream)) fs_give ((void **) &ret); 1.183 + /* special case of newline broken by buffer */ 1.184 + else if ((c == '\015') && (*stream->iptr == '\012')) { 1.185 + stream->iptr++; /* eat the line feed */ 1.186 + stream->ictr--; 1.187 + ret[*size = --n] = '\0'; /* tie off string with null */ 1.188 + } 1.189 + else *contd = LONGT; /* continuation needed */ 1.190 + return ret; 1.191 +} 1.192 + 1.193 +/* TCP/IP receive buffer 1.194 + * Accepts: TCP/IP stream 1.195 + * size in bytes 1.196 + * buffer to read into 1.197 + * Returns: T if success, NIL otherwise 1.198 + */ 1.199 + 1.200 +long tcp_getbuffer (TCPSTREAM *stream,unsigned long size,char *buffer) 1.201 +{ 1.202 + unsigned long n; 1.203 + char *bufptr = buffer; 1.204 + while (size > 0) { /* until request satisfied */ 1.205 + if (!tcp_getdata (stream)) return NIL; 1.206 + n = min (size,stream->ictr);/* number of bytes to transfer */ 1.207 + /* do the copy */ 1.208 + memcpy (bufptr,stream->iptr,(size_t) n); 1.209 + bufptr += n; /* update pointer */ 1.210 + stream->iptr +=n; 1.211 + size -= n; /* update # of bytes to do */ 1.212 + stream->ictr -=n; 1.213 + } 1.214 + bufptr[0] = '\0'; /* tie off string */ 1.215 + return T; 1.216 +} 1.217 + 1.218 + 1.219 +/* TCP/IP receive data 1.220 + * Accepts: TCP/IP stream 1.221 + * Returns: T if success, NIL otherwise 1.222 + */ 1.223 + 1.224 +long tcp_getdata (TCPSTREAM *stream) 1.225 +{ 1.226 + int status; 1.227 + if (!stream->tcps) return NIL;/* no-no nuked socket */ 1.228 + while (stream->ictr < 1) { /* if buffer empty, block for input and read */ 1.229 + if (!_ip_delay1 (stream->tcps,600,NULL,&status)) 1.230 + stream->ictr = sock_fastread (stream->tcps, 1.231 + stream->iptr = stream->ibuf,BUFLEN); 1.232 + else if (status == 1) { /* nuke the socket if closed */ 1.233 + sock_close (stream->tcps); 1.234 + fs_give ((void **) &stream->tcps); 1.235 + return NIL; 1.236 + } 1.237 + } 1.238 + return T; 1.239 +} 1.240 + 1.241 +/* TCP/IP send string as record 1.242 + * Accepts: TCP/IP stream 1.243 + * Returns: T if success else NIL 1.244 + */ 1.245 + 1.246 +long tcp_soutr (TCPSTREAM *stream,char *string) 1.247 +{ 1.248 + /* output the cruft */ 1.249 + sock_puts (stream->tcps,string); 1.250 + return T; /* all done */ 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 + sock_write (stream->tcps,string,(int) size); 1.264 + return T; 1.265 +} 1.266 + 1.267 + 1.268 +/* TCP/IP close 1.269 + * Accepts: TCP/IP stream 1.270 + */ 1.271 + 1.272 +void tcp_close (TCPSTREAM *stream) 1.273 +{ 1.274 + if (stream->tcps){ /* nuke the socket */ 1.275 + sock_close (stream->tcps); 1.276 + _ip_delay2 (stream->tcps,0,NULL,NULL); 1.277 + } 1.278 + fs_give ((void **) &stream->tcps); 1.279 + /* flush host names */ 1.280 + fs_give ((void **) &stream->host); 1.281 + fs_give ((void **) &stream->localhost); 1.282 + fs_give ((void **) &stream); /* flush the stream */ 1.283 +} 1.284 + 1.285 +/* TCP/IP get host name 1.286 + * Accepts: TCP/IP stream 1.287 + * Returns: host name for this stream 1.288 + */ 1.289 + 1.290 +char *tcp_host (TCPSTREAM *stream) 1.291 +{ 1.292 + return stream->host; /* return host name */ 1.293 +} 1.294 + 1.295 + 1.296 +/* TCP/IP get remote host name 1.297 + * Accepts: TCP/IP stream 1.298 + * Returns: host name for this stream 1.299 + */ 1.300 + 1.301 +char *tcp_remotehost (TCPSTREAM *stream) 1.302 +{ 1.303 + return stream->host; /* return host name */ 1.304 +} 1.305 + 1.306 + 1.307 +/* TCP/IP return port for this stream 1.308 + * Accepts: TCP/IP stream 1.309 + * Returns: port number for this stream 1.310 + */ 1.311 + 1.312 +unsigned long tcp_port (TCPSTREAM *stream) 1.313 +{ 1.314 + return stream->port; /* return port number */ 1.315 +} 1.316 + 1.317 + 1.318 +/* TCP/IP get local host name 1.319 + * Accepts: TCP/IP stream 1.320 + * Returns: local host name 1.321 + */ 1.322 + 1.323 +char *tcp_localhost (TCPSTREAM *stream) 1.324 +{ 1.325 + return stream->localhost; /* return local host name */ 1.326 +} 1.327 + 1.328 + 1.329 +/* TCP/IP return canonical form of host name 1.330 + * Accepts: host name 1.331 + * Returns: canonical form of host name 1.332 + */ 1.333 + 1.334 +char *tcp_canonical (char *name) 1.335 +{ 1.336 + return name; 1.337 +} 1.338 + 1.339 + 1.340 +/* TCP/IP get client host name (server calls only) 1.341 + * Returns: client host name 1.342 + */ 1.343 + 1.344 +char *tcp_clienthost () 1.345 +{ 1.346 + return "UNKNOWN"; 1.347 +}