]> Pileus Git - ~andy/fetchmail/blobdiff - driver.c
Critical fix: don't embed NUL in unterminated last IMAP line.
[~andy/fetchmail] / driver.c
index c54bc5c802920a812bb4dec6aa1696071abf0df5..a665e652fea6b81a62539a2d6944eb16382c5cb4 100644 (file)
--- a/driver.c
+++ b/driver.c
@@ -368,7 +368,7 @@ static int fetch_messages(int mailserver_socket, struct query *ctl,
         * could be "auto". */
        switch (ctl->server.protocol)
        {
-           case P_POP3: case P_APOP:
+           case P_POP3:
            fetchsizelimit = 1;
        }
 
@@ -425,14 +425,11 @@ static int fetch_messages(int mailserver_socket, struct query *ctl,
         }
        if (msgcode == MSGLEN_OLD)
        {
-               /* To avoid flooding the syslog when using --keep,
-                * report "Skipped message" only when:
-                *  1) --verbose is on, or
-                *  2) fetchmail does not use syslog
-                */
-           if (   (outlevel >= O_VERBOSE) ||
-                  (outlevel > O_SILENT && !run.use_syslog)
-              )
+           /*
+            * To avoid flooding the logs when using --keep, report
+            * skipping for old messages only when --flush is on.
+            */
+           if (outlevel > O_SILENT && ctl->flush)
            {
                report_build(stdout, 
                             GT_("skipping message %s@%s:%d"),
@@ -602,8 +599,44 @@ static int fetch_messages(int mailserver_socket, struct query *ctl,
                if (separatefetchbody)
                {
                    len = -1;
-                   if ((err=(ctl->server.base_protocol->fetch_body)(mailserver_socket,ctl,num,&len)))
+                   if ((err=(ctl->server.base_protocol->fetch_body)(mailserver_socket,ctl,num,&len))) {
+                       if (err == PS_ERROR && ctl->server.retrieveerror) {
+                           /*
+                            * Mark a message with a protocol error as seen.
+                            * This can be used to see which messages we've attempted
+                            * to download, but failed.
+                            */
+                           if (ctl->server.retrieveerror == RE_MARKSEEN) {
+                               if ((ctl->server.base_protocol->mark_seen)(mailserver_socket,ctl,num)) {
+                                   return(err);
+                               }
+                           }
+
+                           if (ctl->server.retrieveerror != RE_ABORT) {
+                               /*
+                                * Do not abort download session.  Continue with the next message.
+                                *
+                                * Prevents a malformed message from blocking all other messages
+                                * behind it in the mailbox from being downloaded.
+                                *
+                                * Reconnect to SMTP to force this incomplete message to be dropped.
+                                * Required because we've already begun the DATA portion of the
+                                * interaction with the SMTP server (commands are ignored/
+                                * considered part of the message data).
+                                */
+                               abort_message_sink(ctl);
+
+                               // Ensure we don't delete the failed message from the server.
+                               suppress_delete = TRUE;
+
+                               // Bookkeeping required before next message can be downloaded.
+                               goto flagthemail;
+                           }
+                       }
+
                        return(err);
+                   }
+
                    /*
                     * Work around a bug in Novell's
                     * broken GroupWise IMAP server;
@@ -724,16 +757,11 @@ flagthemail:
        }
        else
        {
-           if (   (outlevel >= O_VERBOSE) ||
-                       /* To avoid flooding the syslog when using --keep,
-                        * report "Skipped message" only when:
-                        *  1) --verbose is on, or
-                        *  2) fetchmail does not use syslog, or
-                        *  3) the message was skipped for some other
-                        *     reason than just being old.
-                        */
-                  (outlevel > O_SILENT && (!run.use_syslog || msgcode != MSGLEN_OLD))
-              )
+           /*
+            * To avoid flooding the logs when using --keep, report
+            * skipping of new messages only.
+            */
+           if (outlevel > O_SILENT && msgcode != MSGLEN_OLD)
            report_complete(stdout, GT_(" not flushed\n"));
 
            /* maybe we mark this message as seen now? */
@@ -1019,6 +1047,7 @@ static int do_session(
                    ctl->sslcommonname : realhost, ctl->server.pollname,
                    &ctl->remotename) == -1)
        {
+           set_timeout(0);
            report(stderr, GT_("SSL connection failed.\n"));
            err = PS_SOCKET;
            goto cleanUp;
@@ -1438,7 +1467,7 @@ is restored."));
        msg = GT_("socket");
        break;
     case PS_SYNTAX:
-       msg = GT_("missing or bad RFC822 header");
+       msg = GT_("missing or bad RFC822 header or command line option");
        break;
     case PS_IOERR:
        msg = GT_("MDA");