tcp_wsk.c   tcp_wsk.c 
/* ======================================================================== /* ========================================================================
* Copyright 1988-2007 University of Washington * Copyright 1988-2008 University of Washington
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* *
* ======================================================================== * ========================================================================
*/ */
skipping to change at line 26 skipping to change at line 26
* *
* Author: Mark Crispin from Mike Seibel's Winsock code * Author: Mark Crispin from Mike Seibel's Winsock code
* Networks and Distributed Computing * Networks and Distributed Computing
* Computing & Communications * Computing & Communications
* University of Washington * University of Washington
* Administration Building, AG-44 * Administration Building, AG-44
* Seattle, WA 98195 * Seattle, WA 98195
* Internet: MRC@CAC.Washington.EDU * Internet: MRC@CAC.Washington.EDU
* *
* Date: 11 April 1989 * Date: 11 April 1989
* Last Edited: 18 December 2007 * Last Edited: 13 January 2008
*/ */
#define TCPMAXSEND 32768 #define TCPMAXSEND 32768
/* Private functions */ /* Private functions */
int tcp_socket_open (struct sockaddr_in *sin,char *tmp,char *hst, int tcp_socket_open (struct sockaddr_in *sin,char *tmp,char *hst,
unsigned long port); unsigned long port);
static char *tcp_getline_work (TCPSTREAM *stream,unsigned long *size,
long *contd);
long tcp_abort (TCPSTREAM *stream); long tcp_abort (TCPSTREAM *stream);
long tcp_close_socket (SOCKET *sock); long tcp_close_socket (SOCKET *sock);
char *tcp_name (struct sockaddr_in *sin,long flag); char *tcp_name (struct sockaddr_in *sin,long flag);
char *tcp_name_valid (char *s); char *tcp_name_valid (char *s);
/* Private data */ /* Private data */
int wsa_initted = 0; /* init ? */ int wsa_initted = 0; /* init ? */
static int wsa_sock_open = 0; /* keep track of open sockets */ static int wsa_sock_open = 0; /* keep track of open sockets */
static tcptimeout_t tmoh = NIL; /* TCP timeout handler routine */ static tcptimeout_t tmoh = NIL; /* TCP timeout handler routine */
skipping to change at line 246 skipping to change at line 248
* Accepts: NETMBX specifier * Accepts: NETMBX specifier
* service name * service name
* returned user name buffer * returned user name buffer
* Returns: TCP/IP stream if success else NIL * Returns: TCP/IP stream if success else NIL
*/ */
TCPSTREAM *tcp_aopen (NETMBX *mb,char *service,char *usrbuf) TCPSTREAM *tcp_aopen (NETMBX *mb,char *service,char *usrbuf)
{ {
return NIL; /* always NIL on Windows */ return NIL; /* always NIL on Windows */
} }
/* TCP/IP receive line /* TCP receive line
* Accepts: TCP/IP stream * Accepts: TCP stream
* Returns: text line string or NIL if failure * Returns: text line string or NIL if failure
*/ */
char *tcp_getline (TCPSTREAM *stream) char *tcp_getline (TCPSTREAM *stream)
{ {
int n,m; unsigned long n,contd;
char *st,*ret,*stp; char *ret = tcp_getline_work (stream,&n,&contd);
char c = '\0'; if (ret && contd) { /* got a line needing continuation? */
char d; STRINGLIST *stl = mail_newstringlist ();
STRINGLIST *stc = stl;
do { /* collect additional lines */
stc->text.data = (unsigned char *) ret;
stc->text.size = n;
stc = stc->next = mail_newstringlist ();
ret = tcp_getline_work (stream,&n,&contd);
} while (ret && contd);
if (ret) { /* stash final part of line on list */
stc->text.data = (unsigned char *) ret;
stc->text.size = n;
/* determine how large a buffer we need */
for (n = 0, stc = stl; stc; stc = stc->next) n += stc->text.size;
ret = fs_get (n + 1); /* copy parts into buffer */
for (n = 0, stc = stl; stc; n += stc->text.size, stc = stc->next)
memcpy (ret + n,stc->text.data,stc->text.size);
ret[n] = '\0';
}
mail_free_stringlist (&stl);/* either way, done with list */
}
return ret;
}
/* TCP receive line or partial line
* Accepts: TCP stream
* pointer to return size
* pointer to return continuation flag
* Returns: text line string, size and continuation flag, or NIL if failure
*/
static char *tcp_getline_work (TCPSTREAM *stream,unsigned long *size,
long *contd)
{
unsigned long n;
char *s,*ret,c,d;
*contd = NIL; /* assume no continuation */
/* make sure have data */ /* make sure have data */
if (!tcp_getdata (stream)) return NIL; if (!tcp_getdata (stream)) return NIL;
st = stream->iptr; /* save start of string */ for (s = stream->iptr, n = 0, c = '\0'; stream->ictr--; n++, c = d) {
n = 0; /* init string count */
while (stream->ictr--) { /* look for end of line */
d = *stream->iptr++; /* slurp another character */ d = *stream->iptr++; /* slurp another character */
if ((c == '\015') && (d == '\012')) { if ((c == '\015') && (d == '\012')) {
ret = (char *) fs_get (n--); ret = (char *) fs_get (n--);
memcpy (ret,st,n); /* copy into a free storage string */ memcpy (ret,s,*size = n); /* copy into a free storage string * /
ret[n] = '\0'; /* tie off string with null */ ret[n] = '\0'; /* tie off string with null */
return ret; return ret;
} }
n++; /* count another character searched */
c = d; /* remember previous character */
} }
/* copy partial string from buffer */ /* copy partial string from buffer */
memcpy ((ret = stp = (char *) fs_get (n)),st,n); memcpy ((ret = (char *) fs_get (n)),s,*size = n);
if (tcp_getdata (stream)) { /* get more data from the net */ /* get more data from the net */
if (!tcp_getdata (stream)) fs_give ((void **) &ret);
/* special case of newline broken by buffer */ /* special case of newline broken by buffer */
if ((c == '\015') && (*stream->iptr == '\012')) { else if ((c == '\015') && (*stream->iptr == '\012')) {
stream->iptr++; /* eat the line feed */ stream->iptr++; /* eat the line feed */
stream->ictr--; stream->ictr--;
ret[n - 1] = '\0'; /* tie off string with null */ ret[*size = --n] = '\0'; /* tie off string with null */
}
/* else recurse to get remainder */
else if (st = tcp_getline (stream)) {
ret = (char *) fs_get (n + 1 + (m = strlen (st)));
memcpy (ret,stp,n); /* copy first part */
memcpy (ret + n,st,m); /* and second part */
fs_give ((void **) &stp); /* flush first part */
fs_give ((void **) &st); /* flush second part */
ret[n + m] = '\0'; /* tie off string with null */
}
} }
else *contd = LONGT; /* continuation needed */
return ret; return ret;
} }
/* TCP/IP receive buffer /* TCP/IP receive buffer
* Accepts: TCP/IP stream * Accepts: TCP/IP stream
* size in bytes * size in bytes
* buffer to read into * buffer to read into
* Returns: T if success, NIL otherwise * Returns: T if success, NIL otherwise
*/ */
long tcp_getbuffer (TCPSTREAM *stream,unsigned long size,char *s) long tcp_getbuffer (TCPSTREAM *stream,unsigned long size,char *s)
 End of changes. 11 change blocks. 
30 lines changed or deleted 54 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/