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 | |
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
-rw-r--r-- | Makefile.in | 2 | ||||
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | driver.c | 75 | ||||
-rw-r--r-- | fetchmail.h | 2 | ||||
-rw-r--r-- | imap.c | 16 | ||||
-rw-r--r-- | pop2.c | 5 | ||||
-rw-r--r-- | pop3.c | 11 | ||||
-rw-r--r-- | smtp.c | 29 | ||||
-rw-r--r-- | socket.c | 107 | ||||
-rw-r--r-- | socket.h | 35 | ||||
-rw-r--r-- | uid.c | 2 |
11 files changed, 152 insertions, 133 deletions
diff --git a/Makefile.in b/Makefile.in index 96c4013e..a1524a0a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -204,7 +204,7 @@ $(srcdir)/rcfile_l.c: $(srcdir)/rcfile_l.l $(srcdir)/rcfile_y.c: $(srcdir)/rcfile_y.y parser = $(srcdir)/rcfile_l.l $(srcdir)/rcfile_y.y -headers = $(srcdir)/fetchmail.h $(srcdir)/smtp.h \ +headers = $(srcdir)/fetchmail.h $(srcdir)/socket.h $(srcdir)/smtp.h \ $(srcdir)/mx.h $(srcdir)/md5.h $(srcdir)/md5global.h extra = $(srcdir)/alloca.c $(srcdir)/getopt.[ch] $(srcdir)/getopt1.c \ $(srcdir)/strcasecmp.c @@ -2,7 +2,6 @@ pl 1.9.8 (Mon Nov 4 12:28:25 EST 1996): * Don't append spurious NUL to the headers, qmail actually notices it. -* Full dynamic buffering on all socket streams. * Fail cleanly, instead of core-dumping, on mail lacking an RFC822 From line. pl 1.9.7 (Fri Nov 1 10:02:34 EST 1996): @@ -36,6 +36,7 @@ #include <netinet/in.h> /* must be included before "socket.h".*/ #include <netdb.h> #endif /* KERBEROS_V4 */ +#include "socket.h" #include "fetchmail.h" #include "smtp.h" @@ -472,7 +473,7 @@ struct query *ctl; /* if no socket to this host is already set up, try to open one */ if (ctl->smtp_sockfp == (FILE *)NULL) { - if ((ctl->smtp_sockfp = sockopen(ctl->smtphost, SMTP_PORT)) == (FILE *)NULL) + if ((ctl->smtp_sockfp = Socket(ctl->smtphost, SMTP_PORT)) == (FILE *)NULL) return((FILE *)NULL); else if (SMTP_ok(ctl->smtp_sockfp, NULL) != SM_OK || SMTP_helo(ctl->smtp_sockfp, ctl->servername) != SM_OK) @@ -485,27 +486,6 @@ struct query *ctl; return(ctl->smtp_sockfp); } -static int strip_gets(buf, len, sockfp) -/* get a line of input, stripping out \r and \n */ -char *buf; -int len; -FILE *sockfp; -{ - if (fgets(buf, len, sockfp) == (char *)NULL) - return(-1); - else - { - char *sp, *tp; - - for (tp = sp = buf; *sp; sp++) - if (*sp != '\r' && *sp != '\n') - *tp++ = *sp; - *tp++ = '\0'; - - return(strlen(buf)); - } -} - static int gen_readmsg (sockfp, len, delimited, ctl) /* read message content and ship to SMTP or MDA */ FILE *sockfp; /* to which the server is connected */ @@ -527,19 +507,12 @@ struct query *ctl; /* query control record */ oldlen = 0; while (delimited || len > 0) { - char *sp, *tp; - - if (fgets(buf,sizeof(buf),sockfp) == (char *)NULL) + if ((n = SockGets(buf,sizeof(buf),sockfp)) < 0) return(PS_SOCKET); vtalarm(ctl->timeout); - for (tp = sp = buf; *sp; sp++) - if (*sp != '\r' && *sp != '\n') - *tp++ = *sp; - *tp++ = '\0'; - /* write the message size dots */ - if ((n = strlen(buf)) > 0) + if (n > 0) { sizeticker += n; while (sizeticker >= SIZETICKER) @@ -568,9 +541,7 @@ struct query *ctl; /* query control record */ if (!lines) { oldlen = strlen(bufp); - headers = malloc(oldlen + 1); - if (headers == NULL) - return(PS_SYNTAX); + headers = xmalloc(oldlen + 1); (void) strcpy(headers, bufp); bufp = headers; } @@ -582,7 +553,7 @@ struct query *ctl; /* query control record */ * We deal with RFC822 continuation lines here. * Replace previous '\n' with '\r' so nxtaddr * and reply_hack will be able to see past it. - * (We know this is safe because we stripped + * (We know this is safe because SocketGets stripped * out all carriage returns in the read loop above * and we haven't reintroduced any since then.) * We'll undo this before writing the header. @@ -593,7 +564,7 @@ struct query *ctl; /* query control record */ newlen = oldlen + strlen(bufp); headers = realloc(headers, newlen + 1); if (headers == NULL) - return(PS_SYNTAX); + return(PS_IOERR); strcpy(headers + oldlen, bufp); bufp = headers + oldlen; oldlen = newlen; @@ -648,7 +619,8 @@ struct query *ctl; /* query control record */ /* * We go through this in order to be able to handle very - * long lists of users and (re)implement %s. + * long lists of users and (re +)implement %s. */ for (idp = xmit_names; idp; idp = idp->next) nlocals++; @@ -737,7 +709,7 @@ struct query *ctl; /* query control record */ if (ctl->mda[0]) n = write(mboxfd,headers,oldlen); else - n = fwrite(headers, sizeof(char), oldlen, sinkfp); + n = SockWrite(headers, oldlen, sinkfp); if (n < 0) { @@ -754,7 +726,7 @@ struct query *ctl; /* query control record */ /* SMTP byte-stuffing */ if (*bufp == '.' && ctl->mda[0] == 0) - fwrite(".", sizeof(char), 1, sinkfp); + SockWrite(".", 1, sinkfp); /* replace all LFs with CR-LF in the line */ if (!ctl->mda[0]) @@ -769,7 +741,7 @@ struct query *ctl; /* query control record */ if (ctl->mda[0]) n = write(mboxfd,bufp,strlen(bufp)); else - n = fwrite(bufp, sizeof(char), strlen(bufp), sinkfp); + n = SockWrite(bufp, strlen(bufp), sinkfp); if (!ctl->mda[0]) free(bufp); @@ -785,14 +757,6 @@ struct query *ctl; /* query control record */ lines++; } - /* - * Required by Standard C and the Linux stdio library, - * which wants a seek between read and write operations on a - * read/write stream. Without this we got weird lossage - * trying to issue delete commands after reading a long message. - */ - fseek(sockfp, 0L, SEEK_CUR); - if (ctl->mda[0]) { /* close the delivery pipe, we'll reopen before next message */ @@ -911,8 +875,8 @@ const struct method *proto; /* protocol method table */ FILE *sockfp; /* open a socket to the mail server */ - if ((sockfp = sockopen(ctl->servername, - ctl->port ? ctl->port : protocol->port)) == (FILE *)NULL) + if ((sockfp = Socket(ctl->servername, + ctl->port ? ctl->port : protocol->port))<0) { perror("fetchmail, connecting to host"); ok = PS_SOCKET; @@ -1054,10 +1018,13 @@ const struct method *proto; /* protocol method table */ vtalarm(ctl->timeout); if (ok != 0) goto cleanUp; - delete_uid(&ctl->newsaved, num); } else if (outlevel > O_SILENT) + { + /* nuke it from the unseen-messages list */ + delete_uid(&ctl->newsaved, num); fprintf(stderr, " not flushed\n"); + } } /* remove all messages flagged for deletion */ @@ -1119,7 +1086,7 @@ const struct method *proto; /* protocol method table */ } if (ok==PS_SOCKET || ok==PS_AUTHFAIL || ok==PS_SYNTAX || ok==PS_IOERR || ok==PS_ERROR || ok==PS_PROTOCOL || ok==PS_SMTP) - fprintf(stderr, "error while talking to %s\n", ctl->servername); + fprintf(stderr, " error while talking to %s\n", ctl->servername); closeUp: signal(SIGVTALRM, sigsave); @@ -1155,7 +1122,7 @@ va_dcl { va_end(ap); strcat(buf, "\r\n"); - fputs(buf, sockfp); fseek(sockfp, 0L, SEEK_CUR); + SockWrite(buf, strlen(buf), sockfp); if (outlevel == O_VERBOSE) { @@ -1197,7 +1164,7 @@ va_dcl { va_end(ap); strcat(buf, "\r\n"); - fputs(buf, sockfp); fseek(sockfp, 0L, SEEK_CUR); + SockWrite(buf, strlen(buf), sockfp); if (outlevel == O_VERBOSE) { char *cp; diff --git a/fetchmail.h b/fetchmail.h index e23ecfda..eaf11fb0 100644 --- a/fetchmail.h +++ b/fetchmail.h @@ -186,8 +186,6 @@ int openmailpipe (char **); int closemailpipe(int); int daemonize(const char *, void (*)(int)); -FILE *sockopen(char *, int); - int prc_parse_file(const char *); int prc_filecheck(const char *); @@ -13,6 +13,7 @@ #if defined(STDC_HEADERS) #include <stdlib.h> #endif +#include "socket.h" #include "fetchmail.h" static int count, seen, recent, unseen; @@ -26,11 +27,11 @@ FILE *sockfp; seen = 0; do { - if (fgets(buf, sizeof(buf), sockfp) == (char *)NULL) + if (SockGets(buf, sizeof(buf), sockfp) < 0) return(PS_SOCKET); if (outlevel == O_VERBOSE) - fprintf(stderr,"%s",buf); + fprintf(stderr,"%s\n",buf); /* interpret untagged status responses */ if (strstr(buf, "EXISTS")) @@ -120,7 +121,7 @@ int *sizes; char buf [POPBUFSIZE+1]; gen_send(sockfp, "FETCH 1:%d RFC822.SIZE", count); - while (fgets(buf, sizeof(buf), sockfp) != (char *)NULL) + while (SockGets(buf, sizeof(buf), sockfp) >= 0) { int num, size; @@ -133,7 +134,6 @@ int *sizes; else sizes[num - 1] = -1; } - fseek(sockfp, 0L, SEEK_CUR); return(0); } @@ -165,11 +165,10 @@ int *lenp; /* looking for FETCH response */ do { - if (fgets(buf, sizeof(buf), sockfp) == (char *)NULL) + if (SockGets(buf, sizeof(buf), sockfp) < 0) return(PS_SOCKET); } while (sscanf(buf+2, "%d FETCH (RFC822 {%d}", &num, lenp) != 2); - fseek(sockfp, 0L, SEEK_CUR); if (num != number) return(PS_ERROR); @@ -185,13 +184,10 @@ int number; { char buf [POPBUFSIZE+1]; - if (fgets(buf, sizeof(buf), sockfp) == (char *)NULL) + if (SockGets(buf, sizeof(buf), sockfp) < 0) return(PS_SOCKET); else - { - fseek(sockfp, 0L, SEEK_CUR); return(0); - } } static int imap_delete(sockfp, ctl, number) @@ -11,6 +11,7 @@ #if defined(STDC_HEADERS) #include <stdlib.h> #endif +#include "socket.h" #include "fetchmail.h" static int pound_arg, equal_arg; @@ -24,9 +25,9 @@ char *argbuf; char buf [POPBUFSIZE+1]; pound_arg = equal_arg = -1; - if (fgets(buf, sizeof(buf), sockfp) != (char *)NULL) { + if (SockGets(buf, sizeof(buf), sockfp) >= 0) { if (outlevel == O_VERBOSE) - fprintf(stderr,"%s",buf); + fprintf(stderr,"%s\n",buf); if (buf[0] == '+') ok = 0; @@ -15,6 +15,7 @@ #include <stdlib.h> #endif +#include "socket.h" #include "fetchmail.h" #define PROTOCOL_ERROR {fputs("fetchmail: protocol error\n", stderr); return(PS_ERROR);} @@ -30,9 +31,9 @@ char *argbuf; char buf [POPBUFSIZE+1]; char *bufp; - if (fgets(buf, sizeof(buf), sockfp) != (char *)NULL) { + if (SockGets(buf, sizeof(buf), sockfp) >= 0) { if (outlevel == O_VERBOSE) - fprintf(stderr,"%s",buf); + fprintf(stderr,"%s\n",buf); bufp = buf; if (*bufp == '+' || *bufp == '-') @@ -170,7 +171,7 @@ int *countp, *newp; int num; *newp = 0; - while (fgets(buf, sizeof(buf), sockfp) != (char *)NULL) + while (SockGets(buf, sizeof(buf), sockfp) >= 0) { if (outlevel == O_VERBOSE) fprintf(stderr,"%s\n",buf); @@ -182,7 +183,6 @@ int *countp, *newp; if (!uid_in_list(&ctl->oldsaved, id)) (*newp)++; } - fseek(sockfp, 0L, SEEK_CUR); } } } @@ -205,7 +205,7 @@ int *sizes; { char buf [POPBUFSIZE+1]; - while (fgets(buf, sizeof(buf), sockfp) != (char *)NULL) + while (SockGets(buf, sizeof(buf), sockfp) >= 0) { int num, size; @@ -218,7 +218,6 @@ int *sizes; else sizes[num - 1] = -1; } - fseek(sockfp, 0L, SEEK_CUR); return(0); } @@ -9,10 +9,12 @@ * For license terms, see the file COPYING in this directory. */ -#include <config.h> #include <stdio.h> +#include <config.h> +#include <sys/types.h> #include <unistd.h> #include <string.h> +#include "socket.h" #include "fetchmail.h" #include "smtp.h" @@ -21,7 +23,7 @@ int SMTP_helo(FILE *sockfp,char *host) { int ok; - fprintf(sockfp,"HELO %s\r\n", host); + SockPrintf(sockfp,"HELO %s\r\n", host); if (outlevel == O_VERBOSE) fprintf(stderr, "SMTP> HELO %s\n", host); ok = SMTP_ok(sockfp,NULL); @@ -33,7 +35,7 @@ int SMTP_from(FILE *sockfp, char *from) { int ok; - fprintf(sockfp,"MAIL FROM:<%s>\r\n", from); + SockPrintf(sockfp,"MAIL FROM:<%s>\r\n", from); if (outlevel == O_VERBOSE) fprintf(stderr, "SMTP> MAIL FROM:<%s>\n", from); ok = SMTP_ok(sockfp,NULL); @@ -45,7 +47,7 @@ int SMTP_rcpt(FILE *sockfp, char *to) { int ok; - fprintf(sockfp,"RCPT TO:<%s>\r\n", to); + SockPrintf(sockfp,"RCPT TO:<%s>\r\n", to); if (outlevel == O_VERBOSE) fprintf(stderr, "SMTP> RCPT TO:<%s>\n", to); ok = SMTP_ok(sockfp,NULL); @@ -57,7 +59,7 @@ int SMTP_data(FILE *sockfp) { int ok; - fprintf(sockfp,"DATA\r\n"); + SockPrintf(sockfp,"DATA\r\n"); if (outlevel == O_VERBOSE) fprintf(stderr, "SMTP> DATA\n"); ok = SMTP_ok(sockfp,NULL); @@ -69,7 +71,7 @@ int SMTP_quit(FILE *sockfp) { int ok; - fprintf(sockfp,"QUIT\r\n"); + SockPrintf(sockfp,"QUIT\r\n"); if (outlevel == O_VERBOSE) fprintf(stderr, "SMTP> QUIT\n"); ok = SMTP_ok(sockfp,NULL); @@ -81,7 +83,7 @@ int SMTP_eom(FILE *sockfp) { int ok; - fprintf(sockfp,".\r\n"); + SockPrintf(sockfp,".\r\n"); if (outlevel == O_VERBOSE) fprintf(stderr, "SMTP>. (EOM)\n"); ok = SMTP_ok(sockfp,NULL); @@ -91,7 +93,7 @@ int SMTP_eom(FILE *sockfp) void SMTP_rset(FILE *sockfp) /* send a "RSET" message to the SMTP listener */ { - fprintf(sockfp,"RSET\r\n"); + SockPrintf(sockfp,"RSET\r\n"); if (outlevel == O_VERBOSE) fprintf(stderr, "SMTP> RSET\n"); } @@ -102,17 +104,10 @@ static int SMTP_check(FILE *sockfp,char *argbuf) int ok; char buf[SMTPBUFSIZE]; - if (fgets(buf, sizeof(buf)-1, sockfp) != (char *)NULL) { + if ((ok = SockGets(buf, sizeof(buf)-1, sockfp)) > 0) { + buf[ok] = '\0'; if (outlevel == O_VERBOSE) - { - char *sp, *tp; - - for (tp = sp = buf; *sp; sp++) - if (*sp != '\r') - *tp++ = *sp; - *tp++ = '\0'; fprintf(stderr, "SMTP< %s", buf); - } if (argbuf) strcpy(argbuf,buf); if (buf[0] == '1' || buf[0] == '2' || buf[0] == '3') @@ -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 */ @@ -9,20 +9,12 @@ #ifndef SOCKET__ #define SOCKET__ -#ifndef INADDR_NONE -#ifdef INADDR_BROADCAST -#define INADDR_NONE INADDR_BROADCAST -#else -#define INADDR_NONE -1 -#endif -#endif - #if defined(HAVE_PROTOTYPES) /* Create a new client socket -returns < 0 on error +returns (FILE *)NULL on error */ -int Socket(char *host, int clientPort); +FILE *Socket(char *host, int clientPort); /* Get a string terminated by an '\n', delete any '\r' and the '\n'. @@ -30,25 +22,13 @@ Pass it a valid socket, a buffer for the string, and the length of the buffer (including the trailing \0) returns 0 for success. */ -int SockGets(int socket, char *buf, int len); - -/* -Send a nul terminated string to the socket, followed by -a CR-LF. Returns 0 for success. -*/ -int SockPuts(int socket, char *buf); +int SockGets(char *buf, int len, FILE *sockfp); /* Write a chunk of bytes to the socket. Returns 0 for success. */ -int SockWrite(int socket, char *buf, int len); - -/* -Read a chunk of bytes from the socket. -Returns 0 for success. -*/ -int SockRead(int socket, char *buf, int len); +int SockWrite(char *buf, int len, FILE *sockfp); /* Send formatted output to the socket, followed @@ -56,15 +36,10 @@ by a CR-LF. Returns 0 for success. */ #if defined(HAVE_STDARG_H) -int SockPrintf(int socket, char *format, ...) ; +int SockPrintf(FILE *sockfp, char *format, ...) ; #else int SockPrintf(); #endif -/* -Check socket for readability. return 0 for not readable, ->0 for readable. -*/ -int SockStatus(int socket, int seconds); #endif /* defined(HAVE_PROTOTYPES) */ @@ -7,10 +7,10 @@ #include <config.h> #include <stdio.h> -#include <string.h> #if defined(STDC_HEADERS) #include <stdlib.h> +#include <string.h> #endif #if defined(HAVE_UNISTD_H) |