char *sp, *tp;
set_timeout(mytimeout);
- SockTimeout(sock, mytimeout);
if ((n = SockRead(sock, buf, sizeof(buf)-1)) == -1) {
set_timeout(0);
free(line);
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 */
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 */
* 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;
/* ship out the text line */
if (forward && (!issoftline))
{
- int n;
+ int n, err;
inbufp = buf;
/* guard against very long lines */
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);
}
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)
phase = SERVER_WAIT;
set_timeout(mytimeout);
- SockTimeout(sock, mytimeout);
if (SockRead(sock, buf, size) == -1)
{
set_timeout(0);
phase = SERVER_WAIT;
set_timeout(mytimeout);
- SockTimeout(sock, mytimeout);
rr = SockRead(sock, buf + n, size - n);
set_timeout(0);
phase = oldphase;
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 */