diff options
author | Eric S. Raymond <esr@thyrsus.com> | 1996-11-06 04:03:49 +0000 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 1996-11-06 04:03:49 +0000 |
commit | 238cf89924fe33f03ceea5e4997d2ba0776530d3 (patch) | |
tree | 7b31a64cb01e8c22fcbc5d02c4a60779f7bdc31a /socket.c | |
parent | f7af7a861c301ac43600e2da965692233e877d4d (diff) | |
download | fetchmail-238cf89924fe33f03ceea5e4997d2ba0776530d3.tar.gz fetchmail-238cf89924fe33f03ceea5e4997d2ba0776530d3.tar.bz2 fetchmail-238cf89924fe33f03ceea5e4997d2ba0776530d3.zip |
Back out the attempt to use stdio.
svn path=/trunk/; revision=488
Diffstat (limited to 'socket.c')
-rw-r--r-- | socket.c | 107 |
1 files changed, 98 insertions, 9 deletions
@@ -7,8 +7,10 @@ #include <config.h> #include <stdio.h> +#include <string.h> #include <sys/types.h> #include <sys/socket.h> +#include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #if defined(STDC_HEADERS) @@ -17,6 +19,12 @@ #if defined(HAVE_UNISTD_H) #include <unistd.h> #endif +#if defined(HAVE_STDARG_H) +#include <stdarg.h> +#else +#include <varargs.h> +#endif +#include "socket.h" #ifndef INADDR_NONE #ifdef INADDR_BROADCAST @@ -26,9 +34,7 @@ #endif #endif -#define INTERNAL_BUFSIZE 2048 - -FILE *sockopen(host, clientPort) +FILE *Socket(host, clientPort) char *host; int clientPort; { @@ -36,8 +42,7 @@ int clientPort; unsigned long inaddr; struct sockaddr_in ad; struct hostent *hp; - FILE *sockfp; - + memset(&ad, 0, sizeof(ad)); ad.sin_family = AF_INET; @@ -56,16 +61,100 @@ int clientPort; sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) return (FILE *)NULL; - if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) < 0) { close(sock); return (FILE *)NULL; } + return fdopen(sock, "r+"); +} + + +#if defined(HAVE_STDARG_H) +int SockPrintf(FILE *sockfp, char* format, ...) +{ +#else +int SockPrintf(sockfp,format,va_alist) +FILE *sockfp; +char *format; +va_dcl { +#endif + + va_list ap; + char buf[8192]; + +#if defined(HAVE_STDARG_H) + va_start(ap, format) ; +#else + va_start(ap); +#endif + vsprintf(buf, format, ap); + va_end(ap); + return SockWrite(buf, strlen(buf), sockfp); + +} + +/* + * FIXME: This needs to be recoded to use stdio, if that's possible. + * + * If you think these functions are too slow and inefficient, you're + * absolutely right. I wish I could figure out what to do about it. + * The ancestral popclient used static buffering here to cut down on the + * number of read(2) calls, but we can't do that because we can have + * two or more sockets open at a time. + * + * The right thing to do would be to use stdio for internal per-socket + * buffering here (which is why Socket() returns a file pointer) but + * this causes mysterious lossage. In case someone ever finds a way + * around this, a note on Carl Harris's original implementation said: + * + * Size of buffer for internal buffering read function + * don't increase beyond the maximum atomic read/write size for + * your sockets, or you'll take a potentially huge performance hit + * + * #define INTERNAL_BUFSIZE 2048 + * + */ + +int SockWrite(buf,len,sockfp) +char *buf; +int len; +FILE *sockfp; +{ + int n, wrlen = 0; + + while (len) + { + n = write(fileno(sockfp), buf, len); + if (n <= 0) + return -1; + len -= n; + wrlen += n; + buf += n; + } + return wrlen; +} - sockfp = fdopen(sock, "r+"); - setvbuf(sockfp, NULL, _IOLBF, INTERNAL_BUFSIZE); - return sockfp; +int SockGets(buf, len, sockfp) +char *buf; +int len; +FILE *sockfp; +{ + int rdlen = 0; + + while (--len) + { + if (read(fileno(sockfp), buf, 1) != 1) + return -1; + else + rdlen++; + if (*buf == '\n') + break; + if (*buf != '\r') /* remove all CRs */ + buf++; + } + *buf = 0; + return rdlen; } /* socket.c ends here */ |