aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>1996-12-24 19:18:02 +0000
committerEric S. Raymond <esr@thyrsus.com>1996-12-24 19:18:02 +0000
commitc844c9b1341d92c81f71d5e3bd1aae5c9faa3c89 (patch)
tree84d6abb638f73f4aa8f724fcd86cc084a5606c8c
parent284bf515ccc81c2a8102973396516016cb403f2f (diff)
downloadfetchmail-c844c9b1341d92c81f71d5e3bd1aae5c9faa3c89.tar.gz
fetchmail-c844c9b1341d92c81f71d5e3bd1aae5c9faa3c89.tar.bz2
fetchmail-c844c9b1341d92c81f71d5e3bd1aae5c9faa3c89.zip
Drop back to using SockGets/SockWrite.
svn path=/trunk/; revision=683
-rw-r--r--driver.c48
-rw-r--r--imap.c9
-rw-r--r--pop2.c3
-rw-r--r--pop3.c7
-rw-r--r--smtp.c15
-rw-r--r--socket.c99
-rw-r--r--socket.h26
7 files changed, 140 insertions, 67 deletions
diff --git a/driver.c b/driver.c
index 633f29af..49d97c98 100644
--- a/driver.c
+++ b/driver.c
@@ -42,6 +42,7 @@
#endif /* KERBEROS_V4 */
#include "socket.h"
#include "fetchmail.h"
+#include "socket.h"
#include "smtp.h"
/* BSD portability hack...I know, this is an ugly place to put it */
@@ -279,7 +280,7 @@ static FILE *smtp_open(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 = SockOpen(ctl->smtphost, SMTP_PORT)) == (FILE *)NULL)
return((FILE *)NULL);
else if (SMTP_ok(ctl->smtp_sockfp) != SM_OK
|| SMTP_helo(ctl->smtp_sockfp, ctl->servernames->id) != SM_OK)
@@ -292,26 +293,6 @@ static FILE *smtp_open(struct query *ctl)
return(ctl->smtp_sockfp);
}
-static int SockGets(char *buf, int len, FILE *sockfp)
-/* get a LF-terminated line, removing \r characters */
-{
- int rdlen = 0;
-
- while (--len)
- {
- if ((*buf = fgetc(sockfp)) == EOF)
- return -1;
- else
- rdlen++;
- if (*buf == '\n')
- break;
- if (*buf != '\r') /* remove all CRs */
- buf++;
- }
- *buf = 0;
- return rdlen;
-}
-
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 */
@@ -337,10 +318,17 @@ struct query *ctl; /* query control record */
oldlen = 0;
while (delimited || len > 0)
{
- if ((n = SockGets(buf,sizeof(buf),sockfp)) < 0)
+ if (!SockGets(buf,sizeof(buf),sockfp))
return(PS_SOCKET);
+ n = strlen(buf);
vtalarm(ctl->timeout);
+ /* squeeze out all carriage returns */
+ for (fromhdr = tohdr = buf; *fromhdr; fromhdr++)
+ if (*fromhdr != '\r' && *fromhdr != '\n')
+ *tohdr++ = *fromhdr;
+ *tohdr = '\0';
+
/* write the message size dots */
if (n > 0)
{
@@ -664,8 +652,10 @@ struct query *ctl; /* query control record */
/* write all the headers */
n = 0;
- if (sinkfp)
+ if (ctl->mda[0])
n = fwrite(headers, 1, oldlen, sinkfp);
+ else if (sinkfp)
+ n = SockWrite(headers, 1, oldlen, sinkfp);
if (n < 0)
{
@@ -749,8 +739,10 @@ struct query *ctl; /* query control record */
/* ship out the text line */
n = 0;
- if (sinkfp)
+ if (ctl->mda[0])
n = fwrite(bufp, 1, strlen(bufp), sinkfp);
+ else if (sinkfp)
+ n = SockWrite(bufp, 1, strlen(bufp), sinkfp);
if (!ctl->mda[0])
free(bufp);
@@ -902,7 +894,7 @@ const struct method *proto; /* protocol method table */
FILE *sockfp;
/* open a socket to the mail server */
- if ((sockfp = sockopen(ctl->servernames->id,
+ if ((sockfp = SockOpen(ctl->servernames->id,
ctl->port ? ctl->port : protocol->port)) == NULL)
{
error(0, errno, "connecting to host");
@@ -1191,8 +1183,7 @@ va_dcl
va_end(ap);
strcat(buf, "\r\n");
- fputs(buf, sockfp);
- fflush(sockfp); /* sockfp should be linebuffered, but let's be sure */
+ SockWrite(buf, 1, strlen(buf), sockfp);
if (outlevel == O_VERBOSE)
{
@@ -1234,8 +1225,7 @@ va_dcl
va_end(ap);
strcat(buf, "\r\n");
- fputs(buf, sockfp);
- fflush(sockfp); /* sockfp should be linebuffered, but let's be sure */
+ SockWrite(buf, 1, strlen(buf), sockfp);
if (outlevel == O_VERBOSE)
{
diff --git a/imap.c b/imap.c
index 944c246b..f9fdbbaa 100644
--- a/imap.c
+++ b/imap.c
@@ -14,6 +14,7 @@
#include <stdlib.h>
#endif
#include "fetchmail.h"
+#include "socket.h"
static int count, seen, recent, unseen, imap4;
@@ -24,7 +25,7 @@ int imap_ok (FILE *sockfp, char *argbuf)
seen = 0;
do {
- if (!fgets(buf, sizeof(buf), sockfp))
+ if (!SockGets(buf, sizeof(buf), sockfp))
return(PS_SOCKET);
if (buf[strlen(buf)-1] == '\n')
buf[strlen(buf)-1] = '\0';
@@ -121,7 +122,7 @@ static int imap_getsizes(FILE *sockfp, int count, int *sizes)
char buf [POPBUFSIZE+1];
gen_send(sockfp, "FETCH 1:%d RFC822.SIZE", count);
- while (fgets(buf, sizeof(buf), sockfp))
+ while (SockGets(buf, sizeof(buf), sockfp))
{
int num, size;
@@ -172,7 +173,7 @@ static int imap_fetch(FILE *sockfp, int number, int *lenp)
/* looking for FETCH response */
do {
- if (!fgets(buf, sizeof(buf), sockfp))
+ if (!SockGets(buf, sizeof(buf), sockfp))
return(PS_SOCKET);
} while
(sscanf(buf+2, "%d FETCH (RFC822 {%d}", &num, lenp) != 2);
@@ -188,7 +189,7 @@ static int imap_trail(FILE *sockfp, struct query *ctl, int number)
{
char buf [POPBUFSIZE+1];
- if (!fgets(buf, sizeof(buf), sockfp))
+ if (!SockGets(buf, sizeof(buf), sockfp))
return(PS_SOCKET);
else
return(0);
diff --git a/pop2.c b/pop2.c
index 4b389f20..955e634e 100644
--- a/pop2.c
+++ b/pop2.c
@@ -12,6 +12,7 @@
#include <stdlib.h>
#endif
#include "fetchmail.h"
+#include "socket.h"
static int pound_arg, equal_arg;
@@ -22,7 +23,7 @@ int pop2_ok (FILE *sockfp, char *argbuf)
char buf [POPBUFSIZE+1];
pound_arg = equal_arg = -1;
- if (fgets(buf, sizeof(buf), sockfp)) {
+ if (SockGets(buf, sizeof(buf), sockfp)) {
if (buf[strlen(buf)-1] == '\n')
buf[strlen(buf)-1] = '\0';
if (buf[strlen(buf)-1] == '\r')
diff --git a/pop3.c b/pop3.c
index 3ee5489b..0238fc35 100644
--- a/pop3.c
+++ b/pop3.c
@@ -17,6 +17,7 @@
#endif
#include "fetchmail.h"
+#include "socket.h"
#define PROTOCOL_ERROR {error(0, 0, "protocol error"); return(PS_ERROR);}
@@ -29,7 +30,7 @@ int pop3_ok (FILE *sockfp, char *argbuf)
char buf [POPBUFSIZE+1];
char *bufp;
- if (fgets(buf, sizeof(buf), sockfp)) {
+ if (SockGets(buf, sizeof(buf), sockfp)) {
if (buf[strlen(buf)-1] == '\n')
buf[strlen(buf)-1] = '\0';
if (buf[strlen(buf)-1] == '\r')
@@ -168,7 +169,7 @@ static int pop3_getrange(FILE *sockfp, struct query *ctl, int*countp, int*newp)
int num;
*newp = 0;
- while (fgets(buf, sizeof(buf), sockfp))
+ while (SockGets(buf, sizeof(buf), sockfp))
{
if (buf[strlen(buf)-1] == '\n')
buf[strlen(buf)-1] = '\0';
@@ -205,7 +206,7 @@ static int pop3_getsizes(FILE *sockfp, int count, int *sizes)
{
char buf [POPBUFSIZE+1];
- while (fgets(buf, sizeof(buf), sockfp))
+ while (SockGets(buf, sizeof(buf), sockfp))
{
int num, size;
diff --git a/smtp.c b/smtp.c
index cee1841b..a5be0927 100644
--- a/smtp.c
+++ b/smtp.c
@@ -14,6 +14,7 @@
#include <unistd.h>
#include <string.h>
#include "fetchmail.h"
+#include "socket.h"
#include "smtp.h"
int smtp_response; /* numeric value of SMTP response code */
@@ -23,7 +24,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)
error(0, 0, "SMTP> HELO %s", host);
ok = SMTP_ok(sockfp);
@@ -35,7 +36,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)
error(0, 0, "SMTP> MAIL FROM:<%s>", from);
ok = SMTP_ok(sockfp);
@@ -47,7 +48,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)
error(0, 0, "SMTP> RCPT TO:<%s>", to);
ok = SMTP_ok(sockfp);
@@ -59,7 +60,7 @@ int SMTP_data(FILE *sockfp)
{
int ok;
- fprintf(sockfp,"DATA\r\n");
+ SockPrintf(sockfp,"DATA\r\n");
if (outlevel == O_VERBOSE)
error(0, 0, "SMTP> DATA");
ok = SMTP_ok(sockfp);
@@ -71,7 +72,7 @@ int SMTP_quit(FILE *sockfp)
{
int ok;
- fprintf(sockfp,"QUIT\r\n");
+ SockPrintf(sockfp,"QUIT\r\n");
if (outlevel == O_VERBOSE)
error(0, 0, "SMTP> QUIT");
ok = SMTP_ok(sockfp);
@@ -83,7 +84,7 @@ int SMTP_eom(FILE *sockfp)
{
int ok;
- fprintf(sockfp,".\r\n");
+ SockPrintf(sockfp,".\r\n");
if (outlevel == O_VERBOSE)
error(0, 0, "SMTP>. (EOM)");
ok = SMTP_ok(sockfp);
@@ -95,7 +96,7 @@ int SMTP_ok(FILE *sockfp)
{
char buf[SMTPBUFSIZE], *ip;
- while ((ip = fgets(buf, sizeof(buf)-1, sockfp)))
+ while ((ip = SockGets(buf, sizeof(buf)-1, sockfp)))
{
int n = strlen(ip);
diff --git a/socket.c b/socket.c
index 39b9f846..16974b69 100644
--- a/socket.c
+++ b/socket.c
@@ -34,21 +34,13 @@
#endif
#endif
-/*
- * 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
-
-FILE *sockopen(char *host, int clientPort)
+FILE *SockOpen(char *host, int clientPort)
{
int sock;
unsigned long inaddr;
struct sockaddr_in ad;
struct hostent *hp;
- FILE *fp;
-
+
memset(&ad, 0, sizeof(ad));
ad.sin_family = AF_INET;
@@ -72,26 +64,89 @@ FILE *sockopen(char *host, int clientPort)
close(sock);
return (FILE *)NULL;
}
- fp = fdopen(sock, "r+");
+ return fdopen(sock, "r+");
+}
- /* the point of all this mishigoss ... dynamic per-stream buffering */
- setvbuf(fp, NULL, _IOLBF, INTERNAL_BUFSIZE);
- return(fp);
+#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, 1, strlen(buf), sockfp);
+
}
-#ifdef MAIN
/*
- * Use the chargen service to test buffering directly.
+ * 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
+ *
*/
-main()
+
+int SockWrite(char *buf, int size, int len, FILE *sockfp)
{
- FILE *fp = sockopen("localhost", 19);
- char buf[80];
+ int n, wrlen = 0;
+
+ len *= size;
+ while (len)
+ {
+ n = write(fileno(sockfp), buf, len);
+ if (n <= 0)
+ return -1;
+ len -= n;
+ wrlen += n;
+ buf += n;
+ }
+ return wrlen;
+}
- while (fgets(buf, sizeof(buf)-1, fp))
- fputs(buf, stdout);
+char *SockGets(char *buf, int len, FILE *sockfp)
+{
+ int rdlen = 0;
+ char *cp = buf;
+
+ while (--len)
+ {
+ if (read(fileno(sockfp), cp, 1) != 1)
+ return((char *)NULL);
+ else
+ rdlen++;
+ if (*cp++ == '\n')
+ break;
+ }
+ *cp = 0;
+ return buf;
}
-#endif /* MAIN */
/* socket.c ends here */
diff --git a/socket.h b/socket.h
index 11d9e296..6c93c634 100644
--- a/socket.h
+++ b/socket.h
@@ -8,6 +8,30 @@
#define SOCKET__
/* Create a new client socket; returns (FILE *)NULL on error */
-FILE *sockopen(char *host, int clientPort);
+FILE *SockOpen(char *host, int clientPort);
+/*
+Get a string terminated by an '\n' (matches interface of fgets).
+Pass it a valid socket, a buffer for the string, and
+the length of the buffer (including the trailing \0)
+returns buffer on success, NULL on failure.
+*/
+char *SockGets(char *buf, int len, FILE *sockfp);
+
+/*
+Write a chunk of bytes to the socket (matches interface of fwrite).
+Returns number of bytes successfully written.
+*/
+int SockWrite(char *buf, int size, int nels, FILE *sockfp);
+
+/*
+Send formatted output to the socket (matches interface of fprintf).
+Returns number of bytes successfully written.
+*/
+#if defined(HAVE_STDARG_H)
+int SockPrintf(FILE *sockfp, char *format, ...) ;
+#else
+int SockPrintf();
+#endif
+
#endif /* SOCKET__ */