X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=transact.c;h=2b8d04f8ec15e8b5256d90f2aa5545954340d722;hb=40fe452223b5cc0ff5dbae0efa8551d7e96c1a5c;hp=f55bdee2bfdad35e5c01ef55c6266058b7f63b68;hpb=1a794b3b00bd4b2f720f3426a386d5c86cc65ea8;p=~andy%2Ffetchmail diff --git a/transact.c b/transact.c index f55bdee2..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" @@ -486,13 +472,13 @@ int readheaders(int sock, do { char *sp, *tp; - SockTimeout(sock, mytimeout); - n = SockRead(sock, buf, sizeof(buf) - 1); - - if (n == -1) { + set_timeout(mytimeout); + if ((n = SockRead(sock, buf, sizeof(buf)-1)) == -1) { + set_timeout(0); free(line); return(PS_SOCKET); } + set_timeout(0); /* * Smash out any NULs, they could wreak havoc later on. @@ -617,8 +603,9 @@ eoh: } /* check for RFC822 continuations */ - SockTimeout(sock, mytimeout); + set_timeout(mytimeout); ch = SockPeek(sock); + set_timeout(0); } while (ch == ' ' || ch == '\t'); /* continuation to next line? */ @@ -687,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; @@ -888,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)) { @@ -1382,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 */ @@ -1406,16 +1388,17 @@ int readbody(int sock, struct query *ctl, flag forward, int len) */ while (protocol->delimited || len > 0) { - SockTimeout(sock, mytimeout); + set_timeout(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 */ - linelen = SockRead(sock, inbufp, sizeof(buf)-4-(inbufp-buf)); - if (linelen == -1) + if ((linelen = SockRead(sock, inbufp, sizeof(buf)-4-(inbufp-buf)))==-1) { + set_timeout(0); release_sink(ctl); return(PS_SOCKET); } + set_timeout(0); /* write the message size dots */ if (linelen > 0) @@ -1433,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; @@ -1468,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 */ @@ -1476,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); } @@ -1522,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; @@ -1540,11 +1535,7 @@ 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); @@ -1566,15 +1557,13 @@ int gen_recv(int sock /** socket to which server is connected */, { size_t n; int oldphase = phase; /* we don't have to be re-entrant */ - int retval; phase = SERVER_WAIT; - SockTimeout(sock, mytimeout); - retval = SockRead(sock, buf, size); - phase = oldphase; - - if (retval == -1) + set_timeout(mytimeout); + if (SockRead(sock, buf, size) == -1) { + set_timeout(0); + phase = oldphase; if(is_idletimeout()) { resetidletimeout(); @@ -1593,6 +1582,7 @@ int gen_recv(int sock /** socket to which server is connected */, buf[--n] = '\0'; if (outlevel >= O_MONITOR) report(stdout, "%s< %s\n", protocol->name, buf); + phase = oldphase; return(PS_SUCCESS); } } @@ -1723,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]; @@ -1745,11 +1730,7 @@ 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);