imapext-2007

view 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 source
1 /* ========================================================================
2 * Copyright 1988-2008 University of Washington
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 *
11 * ========================================================================
12 */
14 /*
15 * Program: Waterloo DOS TCP/IP routines
16 *
17 * Author: Mark Crispin
18 * Networks and Distributed Computing
19 * Computing & Communications
20 * University of Washington
21 * Administration Building, AG-44
22 * Seattle, WA 98195
23 * Internet: MRC@CAC.Washington.EDU
24 *
25 * Date: 11 April 1989
26 * Last Edited: 13 January 2008
27 */
30 /* Global data */
32 short sock_initted = 0; /* global so others using net can see it */
34 static char *tcp_getline_work (TCPSTREAM *stream,unsigned long *size,
35 long *contd);
37 /* TCP/IP manipulate parameters
38 * Accepts: function code
39 * function-dependent value
40 * Returns: function-dependent return value
41 */
43 void *tcp_parameters (long function,void *value)
44 {
45 return NIL;
46 }
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 */
55 TCPSTREAM *TCP_open (char *host,char *service,unsigned long port)
56 {
57 TCPSTREAM *stream = NIL;
58 tcp_Socket *sock;
59 char *s,tmp[MAILTMPLEN];
60 unsigned long adr,i,j,k,l;
61 port &= 0xffff; /* erase flags */
62 /* initialize if first time here */
63 if (!sock_initted++) sock_init();
64 /* The domain literal form is used (rather than simply the dotted decimal
65 as with other Unix programs) because it has to be a valid "host name"
66 in mailsystem terminology. */
67 /* look like domain literal? */
68 if (host[0] == '[' && host[strlen (host)-1] == ']') {
69 if (((i = strtoul (s = host+1,&s,10)) <= 255) && *s++ == '.' &&
70 ((j = strtoul (s,&s,10)) <= 255) && *s++ == '.' &&
71 ((k = strtoul (s,&s,10)) <= 255) && *s++ == '.' &&
72 ((l = strtoul (s,&s,10)) <= 255) && *s++ == ']' && !*s)
73 adr = (i << 24) + (j << 16) + (k << 8) + l;
74 else {
75 sprintf (tmp,"Bad format domain-literal: %.80s",host);
76 mm_log (tmp,ERROR);
77 return NIL;
78 }
79 }
80 else { /* lookup host name */
81 if (!(adr = resolve (host))) {
82 sprintf (tmp,"Host not found: %s",host);
83 mm_log (tmp,ERROR);
84 return NIL;
85 }
86 }
88 /* OK to instantiate socket now */
89 sock = (tcp_Socket *) fs_get (sizeof (tcp_Socket));
90 /* open connection */
91 if (!tcp_open (sock,(word) 0,adr,(word) port,NULL)) {
92 sprintf (tmp,"Can't connect to %.80s,%ld",host,port);
93 mm_log (tmp,ERROR);
94 fs_give ((void **) &sock);
95 return NIL;
96 }
97 /* create TCP/IP stream */
98 stream = (TCPSTREAM *) fs_get (sizeof (TCPSTREAM));
99 stream->host = cpystr (host); /* official host name */
100 stream->localhost = cpystr (mylocalhost ());
101 stream->port = port; /* port number */
102 stream->tcps = sock; /* init socket */
103 stream->ictr = 0; /* init input counter */
104 return stream; /* return success */
105 }
107 /* TCP/IP authenticated open
108 * Accepts: NETMBX specifier
109 * service name
110 * returned user name buffer
111 * Returns: TCP/IP stream if success else NIL
112 */
114 TCPSTREAM *tcp_aopen (NETMBX *mb,char *service,char *usrbuf)
115 {
116 return NIL; /* always NIL on DOS */
117 }
119 /* TCP receive line
120 * Accepts: TCP stream
121 * Returns: text line string or NIL if failure
122 */
124 char *tcp_getline (TCPSTREAM *stream)
125 {
126 unsigned long n,contd;
127 char *ret = tcp_getline_work (stream,&n,&contd);
128 if (ret && contd) { /* got a line needing continuation? */
129 STRINGLIST *stl = mail_newstringlist ();
130 STRINGLIST *stc = stl;
131 do { /* collect additional lines */
132 stc->text.data = (unsigned char *) ret;
133 stc->text.size = n;
134 stc = stc->next = mail_newstringlist ();
135 ret = tcp_getline_work (stream,&n,&contd);
136 } while (ret && contd);
137 if (ret) { /* stash final part of line on list */
138 stc->text.data = (unsigned char *) ret;
139 stc->text.size = n;
140 /* determine how large a buffer we need */
141 for (n = 0, stc = stl; stc; stc = stc->next) n += stc->text.size;
142 ret = fs_get (n + 1); /* copy parts into buffer */
143 for (n = 0, stc = stl; stc; n += stc->text.size, stc = stc->next)
144 memcpy (ret + n,stc->text.data,stc->text.size);
145 ret[n] = '\0';
146 }
147 mail_free_stringlist (&stl);/* either way, done with list */
148 }
149 return ret;
150 }
152 /* TCP receive line or partial line
153 * Accepts: TCP stream
154 * pointer to return size
155 * pointer to return continuation flag
156 * Returns: text line string, size and continuation flag, or NIL if failure
157 */
159 static char *tcp_getline_work (TCPSTREAM *stream,unsigned long *size,
160 long *contd)
161 {
162 unsigned long n;
163 char *s,*ret,c,d;
164 *contd = NIL; /* assume no continuation */
165 /* make sure have data */
166 if (!tcp_getdata (stream)) return NIL;
167 for (s = stream->iptr, n = 0, c = '\0'; stream->ictr--; n++, c = d) {
168 d = *stream->iptr++; /* slurp another character */
169 if ((c == '\015') && (d == '\012')) {
170 ret = (char *) fs_get (n--);
171 memcpy (ret,s,*size = n); /* copy into a free storage string */
172 ret[n] = '\0'; /* tie off string with null */
173 return ret;
174 }
175 }
176 /* copy partial string from buffer */
177 memcpy ((ret = (char *) fs_get (n)),s,*size = n);
178 /* get more data from the net */
179 if (!tcp_getdata (stream)) fs_give ((void **) &ret);
180 /* special case of newline broken by buffer */
181 else if ((c == '\015') && (*stream->iptr == '\012')) {
182 stream->iptr++; /* eat the line feed */
183 stream->ictr--;
184 ret[*size = --n] = '\0'; /* tie off string with null */
185 }
186 else *contd = LONGT; /* continuation needed */
187 return ret;
188 }
190 /* TCP/IP receive buffer
191 * Accepts: TCP/IP stream
192 * size in bytes
193 * buffer to read into
194 * Returns: T if success, NIL otherwise
195 */
197 long tcp_getbuffer (TCPSTREAM *stream,unsigned long size,char *buffer)
198 {
199 unsigned long n;
200 char *bufptr = buffer;
201 while (size > 0) { /* until request satisfied */
202 if (!tcp_getdata (stream)) return NIL;
203 n = min (size,stream->ictr);/* number of bytes to transfer */
204 /* do the copy */
205 memcpy (bufptr,stream->iptr,(size_t) n);
206 bufptr += n; /* update pointer */
207 stream->iptr +=n;
208 size -= n; /* update # of bytes to do */
209 stream->ictr -=n;
210 }
211 bufptr[0] = '\0'; /* tie off string */
212 return T;
213 }
216 /* TCP/IP receive data
217 * Accepts: TCP/IP stream
218 * Returns: T if success, NIL otherwise
219 */
221 long tcp_getdata (TCPSTREAM *stream)
222 {
223 int status;
224 if (!stream->tcps) return NIL;/* no-no nuked socket */
225 while (stream->ictr < 1) { /* if buffer empty, block for input and read */
226 if (!_ip_delay1 (stream->tcps,600,NULL,&status))
227 stream->ictr = sock_fastread (stream->tcps,
228 stream->iptr = stream->ibuf,BUFLEN);
229 else if (status == 1) { /* nuke the socket if closed */
230 sock_close (stream->tcps);
231 fs_give ((void **) &stream->tcps);
232 return NIL;
233 }
234 }
235 return T;
236 }
238 /* TCP/IP send string as record
239 * Accepts: TCP/IP stream
240 * Returns: T if success else NIL
241 */
243 long tcp_soutr (TCPSTREAM *stream,char *string)
244 {
245 /* output the cruft */
246 sock_puts (stream->tcps,string);
247 return T; /* all done */
248 }
251 /* TCP/IP send string
252 * Accepts: TCP/IP stream
253 * string pointer
254 * byte count
255 * Returns: T if success else NIL
256 */
258 long tcp_sout (TCPSTREAM *stream,char *string,unsigned long size)
259 {
260 sock_write (stream->tcps,string,(int) size);
261 return T;
262 }
265 /* TCP/IP close
266 * Accepts: TCP/IP stream
267 */
269 void tcp_close (TCPSTREAM *stream)
270 {
271 if (stream->tcps){ /* nuke the socket */
272 sock_close (stream->tcps);
273 _ip_delay2 (stream->tcps,0,NULL,NULL);
274 }
275 fs_give ((void **) &stream->tcps);
276 /* flush host names */
277 fs_give ((void **) &stream->host);
278 fs_give ((void **) &stream->localhost);
279 fs_give ((void **) &stream); /* flush the stream */
280 }
282 /* TCP/IP get host name
283 * Accepts: TCP/IP stream
284 * Returns: host name for this stream
285 */
287 char *tcp_host (TCPSTREAM *stream)
288 {
289 return stream->host; /* return host name */
290 }
293 /* TCP/IP get remote host name
294 * Accepts: TCP/IP stream
295 * Returns: host name for this stream
296 */
298 char *tcp_remotehost (TCPSTREAM *stream)
299 {
300 return stream->host; /* return host name */
301 }
304 /* TCP/IP return port for this stream
305 * Accepts: TCP/IP stream
306 * Returns: port number for this stream
307 */
309 unsigned long tcp_port (TCPSTREAM *stream)
310 {
311 return stream->port; /* return port number */
312 }
315 /* TCP/IP get local host name
316 * Accepts: TCP/IP stream
317 * Returns: local host name
318 */
320 char *tcp_localhost (TCPSTREAM *stream)
321 {
322 return stream->localhost; /* return local host name */
323 }
326 /* TCP/IP return canonical form of host name
327 * Accepts: host name
328 * Returns: canonical form of host name
329 */
331 char *tcp_canonical (char *name)
332 {
333 return name;
334 }
337 /* TCP/IP get client host name (server calls only)
338 * Returns: client host name
339 */
341 char *tcp_clienthost ()
342 {
343 return "UNKNOWN";
344 }

UW-IMAP'd extensions by yuuji