imapext-2007

view src/osdep/vms/tcp_vmsl.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: VMS TCP/IP routines for Netlib.
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: 2 August 1994
26 * Last Edited: 13 January 2008
27 */
29 /* Thanks to Yehavi Bourvine at The Hebrew University of Jerusalem who
30 contributed the original VMS code */
32 #include <descrip.h>
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 }
49 /* TCP/IP open
50 * Accepts: host name
51 * contact service name
52 * contact port number
53 * Returns: TCP/IP stream if success else NIL
54 */
56 TCPSTREAM *tcp_open (char *host,char *service,unsigned long port)
57 {
58 TCPSTREAM *stream = NIL;
59 unsigned long sock;
60 int status;
61 char tmp[MAILTMPLEN];
62 /* hostname to connect to */
63 struct dsc$descriptor HostDesc = { 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL };
64 port &= 0xffff; /* erase flags */
65 /* assign a local socket */
66 if (!((status = net_assign (&sock)) & 0x1)) {
67 sprintf (tmp,"Unable to assign to net, status=%d",status);
68 mm_log (tmp,ERROR);
69 return NIL;
70 }
71 if (!((status = net_bind (&sock,1)) & 0x1)) {
72 sprintf (tmp,"Unable to create local socket, status=%d",status);
73 mm_log (tmp,ERROR);
74 return NIL;
75 }
76 /* open connection */
77 HostDesc.dsc$w_length = strlen (host);
78 HostDesc.dsc$a_pointer = host;
79 if (!((status = tcp_connect (&sock,&HostDesc,port)) & 0x1)) {
80 sprintf (tmp,"Can't connect to %.80s,%lu: %s",host,port,strerror (errno));
81 mm_log (tmp,ERROR);
82 return NIL;
83 }
84 /* create TCP/IP stream */
85 stream = (TCPSTREAM *) fs_get (sizeof (TCPSTREAM));
86 stream->host = cpystr (host); /* copy official host name */
87 /* copy local host name */
88 stream->localhost = cpystr (mylocalhost ());
89 stream->port = port; /* copy port number */
90 /* init sockets */
91 stream->tcpsi = stream->tcpso = sock;
92 stream->ictr = 0; /* init input counter */
93 return stream; /* return success */
94 }
96 /* TCP/IP authenticated open
97 * Accepts: NETMBX specifier
98 * service name
99 * returned user name buffer
100 * Returns: TCP/IP stream if success else NIL
101 */
103 TCPSTREAM *tcp_aopen (NETMBX *mb,char *service,char *usrbuf)
104 {
105 return NIL;
106 }
108 /* TCP receive line
109 * Accepts: TCP stream
110 * Returns: text line string or NIL if failure
111 */
113 char *tcp_getline (TCPSTREAM *stream)
114 {
115 unsigned long n,contd;
116 char *ret = tcp_getline_work (stream,&n,&contd);
117 if (ret && contd) { /* got a line needing continuation? */
118 STRINGLIST *stl = mail_newstringlist ();
119 STRINGLIST *stc = stl;
120 do { /* collect additional lines */
121 stc->text.data = (unsigned char *) ret;
122 stc->text.size = n;
123 stc = stc->next = mail_newstringlist ();
124 ret = tcp_getline_work (stream,&n,&contd);
125 } while (ret && contd);
126 if (ret) { /* stash final part of line on list */
127 stc->text.data = (unsigned char *) ret;
128 stc->text.size = n;
129 /* determine how large a buffer we need */
130 for (n = 0, stc = stl; stc; stc = stc->next) n += stc->text.size;
131 ret = fs_get (n + 1); /* copy parts into buffer */
132 for (n = 0, stc = stl; stc; n += stc->text.size, stc = stc->next)
133 memcpy (ret + n,stc->text.data,stc->text.size);
134 ret[n] = '\0';
135 }
136 mail_free_stringlist (&stl);/* either way, done with list */
137 }
138 return ret;
139 }
141 /* TCP receive line or partial line
142 * Accepts: TCP stream
143 * pointer to return size
144 * pointer to return continuation flag
145 * Returns: text line string, size and continuation flag, or NIL if failure
146 */
148 static char *tcp_getline_work (TCPSTREAM *stream,unsigned long *size,
149 long *contd)
150 {
151 unsigned long n;
152 char *s,*ret,c,d;
153 *contd = NIL; /* assume no continuation */
154 /* make sure have data */
155 if (!tcp_getdata (stream)) return NIL;
156 for (s = stream->iptr, n = 0, c = '\0'; stream->ictr--; n++, c = d) {
157 d = *stream->iptr++; /* slurp another character */
158 if ((c == '\015') && (d == '\012')) {
159 ret = (char *) fs_get (n--);
160 memcpy (ret,s,*size = n); /* copy into a free storage string */
161 ret[n] = '\0'; /* tie off string with null */
162 return ret;
163 }
164 }
165 /* copy partial string from buffer */
166 memcpy ((ret = (char *) fs_get (n)),s,*size = n);
167 /* get more data from the net */
168 if (!tcp_getdata (stream)) fs_give ((void **) &ret);
169 /* special case of newline broken by buffer */
170 else if ((c == '\015') && (*stream->iptr == '\012')) {
171 stream->iptr++; /* eat the line feed */
172 stream->ictr--;
173 ret[*size = --n] = '\0'; /* tie off string with null */
174 }
175 else *contd = LONGT; /* continuation needed */
176 return ret;
177 }
179 /* TCP/IP receive buffer
180 * Accepts: TCP/IP stream
181 * size in bytes
182 * buffer to read into
183 * Returns: T if success, NIL otherwise
184 */
186 long tcp_getbuffer (TCPSTREAM *stream,unsigned long size,char *buffer)
187 {
188 unsigned long n;
189 char *bufptr = buffer;
190 while (size > 0) { /* until request satisfied */
191 if (!tcp_getdata (stream)) return NIL;
192 n = min (size,stream->ictr);/* number of bytes to transfer */
193 /* do the copy */
194 memcpy (bufptr,stream->iptr,n);
195 bufptr += n; /* update pointer */
196 stream->iptr +=n;
197 size -= n; /* update # of bytes to do */
198 stream->ictr -=n;
199 }
200 bufptr[0] = '\0'; /* tie off string */
201 return T;
202 }
205 /* TCP/IP receive data
206 * Accepts: TCP/IP stream
207 * Returns: T if success, NIL otherwise
208 */
210 long tcp_getdata (TCPSTREAM *stream)
211 {
212 char tmp[MAILTMPLEN];
213 int i,status;
214 /* Note: the doc says we need here dynamic descriptor, but we need static
215 * one... */
216 struct dsc$descriptor BufDesc = {BUFLEN,DSC$K_DTYPE_T,DSC$K_CLASS_S,
217 stream->ibuf};
218 static short iosb[4];
219 if (stream->tcpsi < 0) return NIL;
220 while (stream->ictr < 1) { /* if nothing in the buffer */
221 if (!((status = tcp_receive(&(stream->tcpsi), &BufDesc, iosb)) & 0x1)) {
222 sprintf (tmp,"Error reading from TcpIp/NETLIB, status=%d",status);
223 mm_log (tmp,ERROR);
224 return tcp_abort (stream);
225 }
226 if (iosb[1] > BUFLEN) i = BUFLEN;
227 else i = iosb[1];
228 if (i < 1) return tcp_abort (stream);
229 stream->ictr = i; /* set new byte count */
230 stream->iptr = stream->ibuf;/* point at TCP buffer */
231 }
232 return T;
233 }
235 /* TCP/IP send string as record
236 * Accepts: TCP/IP stream
237 * string pointer
238 * Returns: T if success else NIL
239 */
241 long tcp_soutr (TCPSTREAM *stream,char *string)
242 {
243 return tcp_sout (stream,string,(unsigned long) strlen (string));
244 }
247 /* TCP/IP send string
248 * Accepts: TCP/IP stream
249 * string pointer
250 * byte count
251 * Returns: T if success else NIL
252 */
254 long tcp_sout (TCPSTREAM *stream,char *string,unsigned long size)
255 {
256 int status;
257 struct dsc$descriptor_s BufDesc = {strlen(string),DSC$K_DTYPE_T,
258 DSC$K_CLASS_S,string };
259 /* 2 = Do not add \r\n */
260 return ((status = tcp_send (&(stream->tcpso),&BufDesc,2)) & 0x1) ? T :
261 tcp_abort (stream);
262 }
264 /* TCP/IP close
265 * Accepts: TCP/IP stream
266 */
268 void tcp_close (TCPSTREAM *stream)
269 {
270 tcp_abort (stream); /* nuke the stream */
271 /* flush host names */
272 fs_give ((void **) &stream->host);
273 fs_give ((void **) &stream->localhost);
274 fs_give ((void **) &stream); /* flush the stream */
275 }
278 /* TCP/IP abort stream
279 * Accepts: TCP/IP stream
280 * Returns: NIL always
281 */
283 long tcp_abort (TCPSTREAM *stream)
284 {
285 if (stream->tcpsi >= 0) { /* no-op if no socket */
286 /* nuke the socket */
287 tcp_disconnect (&(stream->tcpsi));
288 stream->tcpsi = stream->tcpso = -1;
289 }
290 return NIL;
291 }
293 /* TCP/IP get host name
294 * Accepts: TCP/IP stream
295 * Returns: host name for this stream
296 */
298 char *tcp_host (TCPSTREAM *stream)
299 {
300 return stream->host; /* return host name */
301 }
304 /* TCP/IP get remote host name
305 * Accepts: TCP/IP stream
306 * Returns: host name for this stream
307 */
309 char *tcp_remotehost (TCPSTREAM *stream)
310 {
311 return stream->host; /* return host name */
312 }
315 /* TCP/IP return port for this stream
316 * Accepts: TCP/IP stream
317 * Returns: port number for this stream
318 */
320 unsigned long tcp_port (TCPSTREAM *stream)
321 {
322 return stream->port; /* return port number */
323 }
326 /* TCP/IP get local host name
327 * Accepts: TCP/IP stream
328 * Returns: local host name
329 */
331 char *tcp_localhost (TCPSTREAM *stream)
332 {
333 return stream->localhost; /* return local host name */
334 }
336 /* Return my local host name
337 * Returns: my local host name
338 */
340 char *mylocalhost ()
341 {
342 int status;
343 char tmp[MAILTMPLEN];
344 if (!myLocalHost) { /* have local host yet? */
345 /* receives local host name */
346 struct dsc$descriptor LocalhostDesc = {0,DSC$K_DTYPE_T,DSC$K_CLASS_D,NULL};
347 if (!((status = net_get_hostname (&LocalhostDesc)) & 0x1)) {
348 sprintf (tmp,"Can't get local hostname, status=%d",status);
349 mm_log (tmp,ERROR);
350 return "UNKNOWN";
351 }
352 strncpy (tmp,LocalhostDesc.dsc$a_pointer,LocalhostDesc.dsc$w_length);
353 tmp[LocalhostDesc.dsc$w_length] = '\0';
354 str$free1_dx (&LocalhostDesc);
355 myLocalHost = cpystr (tmp);
356 }
357 return myLocalHost;
358 }
360 /* TCP/IP return canonical form of host name
361 * Accepts: host name
362 * Returns: canonical form of host name
363 */
365 char *tcp_canonical (char *name)
366 {
367 return name;
368 }
371 /* TCP/IP get client host name (server calls only)
372 * Returns: client host name
373 */
375 char *tcp_clienthost ()
376 {
377 return "UNKNOWN";
378 }

UW-IMAP'd extensions by yuuji