imapext-2007

view 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 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: TOPS-20 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: 1 August 1988
26 * Last Edited: 13 January 2008
27 */
30 /* Dedication:
31 * This file is dedicated with affection to the TOPS-20 operating system, which
32 * set standards for user and programmer friendliness that have still not been
33 * equaled by more `modern' operating systems.
34 * Wasureru mon ka!!!!
35 */
37 static char *tcp_getline_work (TCPSTREAM *stream,unsigned long *size,
38 long *contd);
40 /* TCP/IP manipulate parameters
41 * Accepts: function code
42 * function-dependent value
43 * Returns: function-dependent return value
44 */
46 void *tcp_parameters (long function,void *value)
47 {
48 return NIL;
49 }
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 */
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 port &= 0xffff; /* erase flags */
66 /* domain literal? */
67 if (host[0] == '[' && host[strlen (host)-1] == ']') {
68 if (((i = strtoul (s = host+1,&s,10)) <= 255) && *s++ == '.' &&
69 ((j = strtoul (s,&s,10)) <= 255) && *s++ == '.' &&
70 ((k = strtoul (s,&s,10)) <= 255) && *s++ == '.' &&
71 ((l = strtoul (s,&s,10)) <= 255) && *s++ == ']' && !*s) {
72 argblk[3] = (i << 24) + (j << 16) + (k << 8) + l;
73 sprintf (tmp,"[%lu.%lu.%lu.%lu]",i,j,k,l);
74 }
75 else {
76 sprintf (tmp,"Bad format domain-literal: %.80s",host);
77 mm_log (tmp,ERROR);
78 return NIL;
79 }
80 }
81 else { /* host name */
82 argblk[1] = _GTHPN; /* get IP address and primary name */
83 argblk[2] = (int) (host-1); /* pointer to host */
84 argblk[4] = (int) (tmp-1);
85 if (!jsys (GTHST,argblk)) { /* first try DEC's domain way */
86 argblk[1] = _GTHPN; /* get IP address and primary name */
87 argblk[2] = (int) (host-1);
88 argblk[4] = (int) (tmp-1);
89 if (!jsys (GTDOM,argblk)){/* try the CHIVES domain way */
90 argblk[1] = _GTHSN; /* failed, do the host table then */
91 if (!jsys (GTHST,argblk)) {
92 sprintf (tmp,"No such host as %s",host);
93 mm_log (tmp,ERROR);
94 return NIL;
95 }
96 argblk[1] = _GTHNS; /* convert number to string */
97 argblk[2] = (int) (tmp-1);
98 /* get the official name */
99 if (!jsys (GTHST,argblk)) strcpy (tmp,host);
100 }
101 }
102 }
104 sprintf (file,"TCP:.%o-%d;PERSIST:30;CONNECTION:ACTIVE",argblk[3],port);
105 argblk[1] = GJ_SHT; /* short form GTJFN% */
106 argblk[2] = (int) (file-1); /* pointer to file name */
107 /* get JFN for TCP: file */
108 if (!jsys (GTJFN,argblk)) fatal ("Unable to create TCP JFN");
109 jfn = argblk[1]; /* note JFN for later */
110 /* want 8-bit bidirectional I/O */
111 argblk[2] = OF_RD|OF_WR|(FLD (8,monsym("OF%BSZ")));
112 if (!jsys (OPENF,argblk)) {
113 sprintf (file,"Can't connect to %s,%d server",tmp,port);
114 mm_log (file,ERROR);
115 return NIL;
116 }
117 /* create TCP/IP stream */
118 stream = (TCPSTREAM *) fs_get (sizeof (TCPSTREAM));
119 stream->host = cpystr (tmp); /* copy official host name */
120 argblk[1] = _GTHNS; /* convert number to string */
121 argblk[2] = (int) (tmp-1);
122 argblk[3] = -1; /* want local host */
123 if (!jsys (GTHST,argblk)) strcpy (tmp,"LOCAL");
124 stream->localhost = cpystr (tmp);
125 stream->port = port; /* save port number */
126 stream->jfn = jfn; /* init JFN */
127 return stream;
128 }
130 /* TCP/IP authenticated open
131 * Accepts: NETMBX specifier
132 * service name
133 * returned user name buffer
134 * Returns: TCP/IP stream if success else NIL
135 */
137 TCPSTREAM *tcp_aopen (NETMBX *mb,char *service,char *usrbuf)
138 {
139 return NIL;
140 }
142 /* TCP receive line
143 * Accepts: TCP stream
144 * Returns: text line string or NIL if failure
145 */
147 char *tcp_getline (TCPSTREAM *stream)
148 {
149 unsigned long n,contd;
150 char *ret = tcp_getline_work (stream,&n,&contd);
151 if (ret && contd) { /* got a line needing continuation? */
152 STRINGLIST *stl = mail_newstringlist ();
153 STRINGLIST *stc = stl;
154 do { /* collect additional lines */
155 stc->text.data = (unsigned char *) ret;
156 stc->text.size = n;
157 stc = stc->next = mail_newstringlist ();
158 ret = tcp_getline_work (stream,&n,&contd);
159 } while (ret && contd);
160 if (ret) { /* stash final part of line on list */
161 stc->text.data = (unsigned char *) ret;
162 stc->text.size = n;
163 /* determine how large a buffer we need */
164 for (n = 0, stc = stl; stc; stc = stc->next) n += stc->text.size;
165 ret = fs_get (n + 1); /* copy parts into buffer */
166 for (n = 0, stc = stl; stc; n += stc->text.size, stc = stc->next)
167 memcpy (ret + n,stc->text.data,stc->text.size);
168 ret[n] = '\0';
169 }
170 mail_free_stringlist (&stl);/* either way, done with list */
171 }
172 return ret;
173 }
175 /* TCP receive line or partial line
176 * Accepts: TCP stream
177 * pointer to return size
178 * pointer to return continuation flag
179 * Returns: text line string, size and continuation flag, or NIL if failure
180 */
182 static char *tcp_getline_work (TCPSTREAM *stream,unsigned long *size,
183 long *contd)
184 {
185 int argblk[5];
186 unsigned long n,m;
187 char *ret,*stp,*st;
188 *contd = NIL; /* assume no continuation */
189 argblk[1] = stream->jfn; /* read from TCP */
190 /* pointer to buffer */
191 argblk[2] = (int) (stream->ibuf - 1);
192 argblk[3] = BUFLEN; /* max number of bytes to read */
193 argblk[4] = '\012'; /* terminate on LF */
194 if (!jsys (SIN,argblk)) return NIL;
195 n = BUFLEN - argblk[3]; /* number of bytes read */
196 /* got a complete line? */
197 if ((stream->ibuf[n - 2] == '\015') && (stream->ibuf[n - 1] == '\012')) {
198 memcpy ((ret = (char *) fs_get (n)),stream->ibuf,*size = n - 2);
199 ret[n - 2] = '\0'; /* tie off string with null */
200 return ret;
201 }
202 /* copy partial string */
203 memcpy ((ret = (char *) fs_get (n)),stream->ibuf,*size = n);
204 /* special case of newline broken by buffer */
205 if ((stream->ibuf[n - 1] == '\015') && jsys (BIN,argblk) &&
206 (argblk[2] == '\012')) { /* was it? */
207 ret[n - 1] = '\0'; /* tie off string with null */
208 }
209 /* otherwise back up */
210 else if (!jsys (BKJFN,argblk)) fs_give ((void **) &ret);
211 else *contd = LONGT; /* continuation needed */
212 return ret;
213 }
215 /* TCP/IP receive buffer
216 * Accepts: TCP/IP stream
217 * size in bytes
218 * buffer to read into
219 * Returns: T if success, NIL otherwise
220 */
222 long tcp_getbuffer (TCPSTREAM *stream,unsigned long size,char *buffer)
223 {
224 int argblk[5];
225 argblk[1] = stream->jfn; /* read from TCP */
226 argblk[2] = (int) (buffer-1); /* pointer to buffer */
227 argblk[3] = -size; /* number of bytes to read */
228 if (!jsys (SIN,argblk)) return NIL;
229 buffer[size] = '\0'; /* tie off text */
230 return T;
231 }
234 /* TCP/IP send string as record
235 * Accepts: TCP/IP stream
236 * string pointer
237 * Returns: T if success else NIL
238 */
240 long tcp_soutr (TCPSTREAM *stream,char *string)
241 {
242 int argblk[5];
243 argblk[1] = stream->jfn; /* write to TCP */
244 argblk[2] = (int) (string-1); /* pointer to buffer */
245 argblk[3] = 0; /* write until NUL */
246 if (!jsys (SOUTR,argblk)) return NIL;
247 return T;
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 int argblk[5];
261 argblk[1] = stream->jfn; /* write to TCP */
262 argblk[2] = (int) (string-1); /* pointer to buffer */
263 argblk[3] = -size; /* write this many bytes */
264 if (!jsys (SOUTR,argblk)) return NIL;
265 return T;
266 }
268 /* TCP/IP close
269 * Accepts: TCP/IP stream
270 */
272 void tcp_close (TCPSTREAM *stream)
273 {
274 int argblk[5];
275 argblk[1] = stream->jfn; /* close TCP */
276 jsys (CLOSF,argblk);
277 /* flush host names */
278 fs_give ((void **) &stream->host);
279 fs_give ((void **) &stream->localhost);
280 fs_give ((void **) &stream); /* flush the stream */
281 }
284 /* TCP/IP return host for this stream
285 * Accepts: TCP/IP stream
286 * Returns: host name for this stream
287 */
289 char *tcp_host (TCPSTREAM *stream)
290 {
291 return stream->host; /* return host name */
292 }
295 /* TCP/IP return remote host for this stream
296 * Accepts: TCP/IP stream
297 * Returns: host name for this stream
298 */
300 char *tcp_remotehost (TCPSTREAM *stream)
301 {
302 return stream->host; /* return host name */
303 }
306 /* TCP/IP return port for this stream
307 * Accepts: TCP/IP stream
308 * Returns: port number for this stream
309 */
311 unsigned long tcp_port (TCPSTREAM *stream)
312 {
313 return stream->port; /* return port number */
314 }
317 /* TCP/IP return local host for this stream
318 * Accepts: TCP/IP stream
319 * Returns: local host name for this stream
320 */
322 char *tcp_localhost (TCPSTREAM *stream)
323 {
324 return stream->localhost; /* return local host name */
325 }
327 /* TCP/IP return canonical form of host name
328 * Accepts: host name
329 * Returns: canonical form of host name
330 */
332 char *tcp_canonical (char *name)
333 {
334 int argblk[5];
335 static char tmp[MAILTMPLEN];
336 /* look like domain literal? */
337 if (name[0] == '[' && name[strlen (name) - 1] == ']') return name;
338 argblk[1] = _GTHPN; /* get IP address and primary name */
339 argblk[2] = (int) (name-1); /* pointer to host */
340 argblk[4] = (int) (tmp-1); /* pointer to return destination */
341 if (!jsys (GTHST,argblk)) { /* first try DEC's domain way */
342 argblk[1] = _GTHPN; /* get IP address and primary name */
343 argblk[2] = (int) (name-1);
344 argblk[4] = (int) (tmp-1);
345 if (!jsys (GTDOM,argblk)) { /* try the CHIVES domain way */
346 argblk[1] = _GTHSN; /* failed, do the host table then */
347 if (!jsys (GTHST,argblk)) return name;
348 argblk[1] = _GTHNS; /* convert number to string */
349 argblk[2] = (int) (tmp-1);
350 /* get the official name */
351 if (!jsys (GTHST,argblk)) return name;
352 }
353 }
354 return tmp;
355 }
358 /* TCP/IP get client host name (server calls only)
359 * Returns: client host name
360 */
362 char *tcp_clienthost ()
363 {
364 return "UNKNOWN";
365 }

UW-IMAP'd extensions by yuuji