X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=transact.c;h=2b8d04f8ec15e8b5256d90f2aa5545954340d722;hb=f16d8d23439b5569f0c2e1af22494708b507f277;hp=9667bd25a7041408826168a3bc1bf1714509ccd2;hpb=47c05b10018f5ec7493e4bd9f521aaa18d96f1e2;p=~andy%2Ffetchmail diff --git a/transact.c b/transact.c index 9667bd25..2b8d04f8 100644 --- a/transact.c +++ b/transact.c @@ -9,31 +9,17 @@ #include #include #include -#ifdef HAVE_MEMORY_H -#include -#endif /* HAVE_MEMORY_H */ -#if defined(STDC_HEADERS) #include -#endif -#if defined(HAVE_UNISTD_H) #include -#endif -#if defined(HAVE_STDARG_H) #include -#else -#include -#endif #include #include -#ifdef HAVE_NET_SOCKET_H -#include -#endif #include #include #include "fm_md5.h" -#include "i18n.h" +#include "gettext.h" #include "socket.h" #include "fetchmail.h" @@ -487,7 +473,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); @@ -689,15 +674,6 @@ eoh: * We will just check if the first message in the mailbox has an * X-IMAP: header. */ -#ifdef POP2_ENABLE - /* - * We disable this check under POP2 because there's no way to - * prevent deletion of the message. So at least we ought to - * forward it to the user so he or she will have some clue - * that things have gone awry. - */ - if (servport("pop2") != servport(protocol->service)) -#endif /* POP2_ENABLE */ if (num == 1 && !strncasecmp(line, "X-IMAP:", 7)) { free(line); retain_mail = 1; @@ -890,24 +866,6 @@ eoh: else if (!strncasecmp("Resent-Sender:", line, 14) && (strchr(line, '@') || strchr(line, '!'))) resent_sender_offs = (line - msgblk.headers); -#ifdef __UNUSED__ - else if (!strncasecmp("Message-Id:", line, 11)) - { - if (ctl->server.uidl) - { - char id[IDLEN+1]; - - line[IDLEN+12] = 0; /* prevent stack overflow */ - sscanf(line+12, "%s", id); - if (!str_find( &ctl->newsaved, num)) - { - struct idlist *newl = save_str(&ctl->newsaved,id,UID_SEEN); - newl->val.status.num = num; - } - } - } -#endif /* __UNUSED__ */ - /* if multidrop is on, gather addressee headers */ if (MULTIDROP(ctl)) { @@ -1384,6 +1342,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 +1389,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 +1416,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 +1459,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 +1467,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); } @@ -1526,15 +1522,10 @@ static void enshroud(char *buf) } } -#if defined(HAVE_STDARG_H) /** assemble command in printf(3) style and send to the server */ -void gen_send(int sock, const char *fmt, ... ) -#else -void gen_send(sock, fmt, va_alist) -int sock; /** socket to which server is connected */ -const char *fmt; /** printf-style format */ -va_dcl -#endif +void gen_send(int sock/** socket to which server is connected */, + const char *fmt /** printf-style format */, + ...) { char buf [MSGBUFSIZE+1]; va_list ap; @@ -1544,16 +1535,11 @@ va_dcl else buf[0] = '\0'; -#if defined(HAVE_STDARG_H) va_start(ap, fmt); -#else - va_start(ap); -#endif vsnprintf(buf + strlen(buf), sizeof(buf)-2-strlen(buf), fmt, ap); 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 +1560,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 +1673,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; @@ -1729,15 +1713,10 @@ int gen_recv_split(int sock /** socket to which server is connected */, } /** @} */ -#if defined(HAVE_STDARG_H) -int gen_transact(int sock, const char *fmt, ... ) -#else -int gen_transact(int sock, fmt, va_alist) -int sock; /** socket to which server is connected */ -const char *fmt; /** printf-style format */ -va_dcl -#endif /** assemble command in printf(3) style, send to server, fetch a response */ +int gen_transact(int sock /** socket to which server is connected */, + const char *fmt /** printf-style format */, + ...) { int ok; char buf [MSGBUFSIZE+1]; @@ -1751,16 +1730,11 @@ va_dcl else buf[0] = '\0'; -#if defined(HAVE_STDARG_H) va_start(ap, fmt) ; -#else - va_start(ap); -#endif vsnprintf(buf + strlen(buf), sizeof(buf)-2-strlen(buf), fmt, ap); 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 */