X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=transact.c;h=5449e56e0139682e78d95fa7beafcbcf15c95c83;hb=21ac960a3e648cd53c155bd2b724f72f0164416f;hp=9667bd25a7041408826168a3bc1bf1714509ccd2;hpb=47c05b10018f5ec7493e4bd9f521aaa18d96f1e2;p=~andy%2Ffetchmail diff --git a/transact.c b/transact.c index 9667bd25..5449e56e 100644 --- a/transact.c +++ b/transact.c @@ -487,7 +487,6 @@ int readheaders(int sock, char *sp, *tp; set_timeout(mytimeout); - SockTimeout(sock, mytimeout); if ((n = SockRead(sock, buf, sizeof(buf)-1)) == -1) { set_timeout(0); free(line); @@ -1384,6 +1383,28 @@ process_headers: return PS_SOCKET; } +/** Convenience function factored out from readbody(): + * send buffer \a buf via stuffline() and handle errors and progress. + * Store return value in \a *n, and return PS_IOERR for failure or + * PS_SUCCESS otherwise. */ +static int rb_send(struct query *ctl, char *buf, int *n) +{ + *n = stuffline(ctl, buf); + + if (*n < 0) + { + report(stdout, GT_("error writing message text\n")); + release_sink(ctl); + return(PS_IOERR); + } + else if (want_progress()) + { + fputc('*', stdout); + fflush(stdout); + } + return PS_SUCCESS; +} + int readbody(int sock, struct query *ctl, flag forward, int len) /** read and dispose of a message body presented on \a sock */ /** \param ctl query control record */ @@ -1409,7 +1430,6 @@ int readbody(int sock, struct query *ctl, flag forward, int len) while (protocol->delimited || len > 0) { set_timeout(mytimeout); - SockTimeout(sock, mytimeout); /* XXX FIXME: for undelimited protocols that ship the size, such * as IMAP, we might want to use the count of remaining characters * instead of the buffer size -- not for fetchmail 6.3.X though */ @@ -1437,7 +1457,15 @@ int readbody(int sock, struct query *ctl, flag forward, int len) * so we might end truncating messages prematurely. */ if (!protocol->delimited && linelen > len) { + /* FIXME: HACK ALERT! This \r\n is only here to make sure the + * \n\0 hunt works later on. The \n generated here was not + * part of the original message! + * The real fix will be to use buffer + length strings, + * rather than 0-terminated C strings. */ + inbufp[len++] = '\r'; + inbufp[len++] = '\n'; inbufp[len] = '\0'; + linelen = len; } len -= linelen; @@ -1472,7 +1500,7 @@ int readbody(int sock, struct query *ctl, flag forward, int len) /* ship out the text line */ if (forward && (!issoftline)) { - int n; + int n, err; inbufp = buf; /* guard against very long lines */ @@ -1480,22 +1508,31 @@ int readbody(int sock, struct query *ctl, flag forward, int len) buf[MSGBUFSIZE+2] = '\n'; buf[MSGBUFSIZE+3] = '\0'; - n = stuffline(ctl, buf); - - if (n < 0) - { - report(stdout, GT_("error writing message text\n")); - release_sink(ctl); - return(PS_IOERR); - } - else if (want_progress()) - { - fputc('*', stdout); - fflush(stdout); - } + err = rb_send(ctl, buf, &n); + if (err != PS_SUCCESS) + return err; } } + /* Flush buffer -- bug introduced by ESR on 1998-03-20 before + * release 4.4.1 when ESR did not sufficiently audit Henrik + * Storner's patch. + * Trouble reported in June 2011 by Lars Hecking, with + * text/html quoted-printable messages generated by + * Outlook/Exchange that got mutilated by fetchmail. + */ + if (forward && issoftline) + { + int n; + + /* force proper line termination */ + inbufp[0] = '\r'; + inbufp[1] = '\n'; + inbufp[2] = '\0'; + + return rb_send(ctl, buf, &n); + } + return(PS_SUCCESS); } @@ -1553,7 +1590,6 @@ va_dcl va_end(ap); snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "\r\n"); - SockTimeout(sock, mytimeout); SockWrite(sock, buf, strlen(buf)); if (outlevel >= O_MONITOR) @@ -1574,7 +1610,6 @@ int gen_recv(int sock /** socket to which server is connected */, phase = SERVER_WAIT; set_timeout(mytimeout); - SockTimeout(sock, mytimeout); if (SockRead(sock, buf, size) == -1) { set_timeout(0); @@ -1688,7 +1723,6 @@ int gen_recv_split(int sock /** socket to which server is connected */, phase = SERVER_WAIT; set_timeout(mytimeout); - SockTimeout(sock, mytimeout); rr = SockRead(sock, buf + n, size - n); set_timeout(0); phase = oldphase; @@ -1760,7 +1794,6 @@ va_dcl va_end(ap); snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "\r\n"); - SockTimeout(sock, mytimeout); ok = SockWrite(sock, buf, strlen(buf)); if (ok == -1 || (size_t)ok != strlen(buf)) { /* short write, bail out */