#include <stdio.h>
#include <string.h>
#include <ctype.h>
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif /* HAVE_MEMORY_H */
-#if defined(STDC_HEADERS)
#include <stdlib.h>
-#endif
-#if defined(HAVE_UNISTD_H)
#include <unistd.h>
-#endif
-#if defined(HAVE_STDARG_H)
#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
#include <limits.h>
#include <assert.h>
-#ifdef HAVE_NET_SOCKET_H
-#include <net/socket.h>
-#endif
#include <sys/socket.h>
#include <netdb.h>
#include "fm_md5.h"
-#include "i18n.h"
+#include "gettext.h"
#include "socket.h"
#include "fetchmail.h"
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.
}
/* check for RFC822 continuations */
- SockTimeout(sock, mytimeout);
+ set_timeout(mytimeout);
ch = SockPeek(sock);
+ set_timeout(0);
} while
(ch == ' ' || ch == '\t'); /* continuation to next line? */
* 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;
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))
{
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)
{
- 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)
* 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);
}
}
}
-#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;
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);
{
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();
buf[--n] = '\0';
if (outlevel >= O_MONITOR)
report(stdout, "%s< %s\n", protocol->name, buf);
+ phase = oldphase;
return(PS_SUCCESS);
}
}
}
/** @} */
-#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];
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);