]> Pileus Git - ~andy/fetchmail/blobdiff - driver.c
Before the IDLE patch.
[~andy/fetchmail] / driver.c
index 563a68ba908247180ce173f99a08deb754e4d46d..4a4f4d3faee0d118866c2ca8063b307048acaafc 100644 (file)
--- a/driver.c
+++ b/driver.c
@@ -89,34 +89,31 @@ void set_timeout(int timeleft)
 #endif
 }
 
-static void timeout_handler (int signal)
+static RETSIGTYPE timeout_handler (int signal)
 /* handle SIGALRM signal indicating a server timeout */
 {
     timeoutcount++;
     longjmp(restart, THROW_TIMEOUT);
 }
 
-static void sigpipe_handler (int signal)
+static RETSIGTYPE sigpipe_handler (int signal)
 /* handle SIGPIPE signal indicating a broken stream socket */
 {
     longjmp(restart, THROW_SIGPIPE);
 }
 
-/* ignore SIGALRM signal indicating a timeout during cleanup */
-static void cleanup_timeout_handler (int signal) { }
-
 #define CLEANUP_TIMEOUT 60 /* maximum timeout during cleanup */
 
 static int cleanupSockClose (int fd)
 /* close sockets in maximum CLEANUP_TIMEOUT seconds during cleanup */
 {
     int scerror;
-    void (*alrmsave)(int);
-    alrmsave = signal(SIGALRM, cleanup_timeout_handler);
+    SIGHANDLERTYPE alrmsave;
+    alrmsave = set_signal_handler(SIGALRM, null_signal_handler);
     set_timeout(CLEANUP_TIMEOUT);
     scerror = SockClose(fd);
     set_timeout(0);
-    signal(SIGALRM, alrmsave);
+    set_signal_handler(SIGALRM, alrmsave);
     return (scerror);
 }
 
@@ -420,7 +417,16 @@ static int fetch_messages(int mailserver_socket, struct query *ctl,
        {
            if ((msgcodes[num-1] == MSGLEN_TOOLARGE) && !check_only)
                mark_oversized(ctl, num, msgsizes[num-1]);
-           if (outlevel > O_SILENT)
+               /* 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 being old.
+                */
+           if (   (outlevel >= O_VERBOSE) ||
+                  (outlevel > O_SILENT && (!run.use_syslog || msgcodes[num-1] != MSGLEN_OLD))
+              )
            {
                report_build(stdout, 
                             GT_("skipping message %s@%s:%d (%d octets)"),
@@ -493,28 +499,33 @@ static int fetch_messages(int mailserver_socket, struct query *ctl,
            err = readheaders(mailserver_socket, len, msgsizes[num-1],
                             ctl, num);
            if (err == PS_RETAINED)
-               suppress_readbody = suppress_forward = suppress_delete = retained = TRUE;
+           {
+               suppress_forward = suppress_delete = retained = TRUE;
+               /* do not read the body only if the underlying protocol
+                * allows the body to be fetched separately */
+               if (ctl->server.base_protocol->fetch_body)
+                   suppress_readbody = TRUE;
+           }
            else if (err == PS_TRANSIENT)
+           {
                suppress_delete = suppress_forward = TRUE;
+               if (ctl->server.base_protocol->fetch_body)
+                   suppress_readbody = TRUE;
+           }
            else if (err == PS_REFUSED)
+           {
                suppress_forward = TRUE;
-#if 0
-           /* 
-            * readheaders does not read the body when it
-            * hits a non-header. It has been recently
-            * fixed to return PS_TRUNCATED (properly) when
-            * that happens, but apparently fixing that bug
-            * opened this one here (which looks like an 
-            * inproper fix from some ancient thinko)
-            */
+               if (ctl->server.base_protocol->fetch_body)
+                   suppress_readbody = TRUE;
+           }
            else if (err == PS_TRUNCATED)
-               suppress_readbody = TRUE;
+           {
+               if (ctl->server.base_protocol->fetch_body)
+                   suppress_readbody = TRUE;
+               len = 0;        /* suppress body processing */
+           }
            else if (err)
                return(err);
-#else
-           else if (err && err != PS_TRUNCATED)
-               return(err);
-#endif
 
            /* 
             * If we're using IMAP4 or something else that
@@ -644,25 +655,6 @@ static int fetch_messages(int mailserver_socket, struct query *ctl,
         * now.
         */
 
-       /*
-        * Tell the UID code we've seen this.
-        * Matthias Andree: only register the UID if we could actually
-        * forward this mail. If we omit this !suppress_delete check,
-        * fetchmail will never retry mail that the local listener
-        * refused temporarily.
-        */
-       if (ctl->newsaved && !suppress_delete)
-       {
-           struct idlist       *sdp;
-
-           for (sdp = ctl->newsaved; sdp; sdp = sdp->next)
-               if ((sdp->val.status.num == num) && (msgcodes[num-1] >= 0))
-               {
-                   sdp->val.status.mark = UID_SEEN;
-                   save_str(&ctl->oldsaved, sdp->id,UID_SEEN);
-               }
-       }
-
        /* maybe we delete this message now? */
        if (retained)
        {
@@ -679,13 +671,32 @@ static int fetch_messages(int mailserver_socket, struct query *ctl,
            err = (ctl->server.base_protocol->delete)(mailserver_socket, ctl, num);
            if (err != 0)
                return(err);
-#ifdef POP3_ENABLE
-           delete_str(&ctl->newsaved, num);
-#endif /* POP3_ENABLE */
        }
-       else if (outlevel > O_SILENT)
+       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 || msgcodes[num-1] != MSGLEN_OLD))
+              )
            report_complete(stdout, GT_(" not flushed\n"));
 
+           /* maybe we mark this message as seen now? */
+           if (ctl->server.base_protocol->mark_seen
+               && !suppress_delete
+               && (msgcodes[num-1] >= 0 && ctl->keep))
+           {
+               err = (ctl->server.base_protocol->mark_seen)(mailserver_socket, ctl, num);
+               if (err != 0)
+                   return(err);
+           }
+       }
+
        /* perhaps this as many as we're ready to handle */
        if (maxfetch && maxfetch <= *fetches && *fetches < count)
        {
@@ -711,8 +722,8 @@ const int maxfetch;         /* maximum number of messages to fetch */
     int err, mailserver_socket = -1;
 #endif /* HAVE_VOLATILE */
     const char *msg;
-    void (*pipesave)(int);
-    void (*alrmsave)(int);
+    SIGHANDLERTYPE pipesave;
+    SIGHANDLERTYPE alrmsave;
 
     ctl->server.base_protocol = proto;
 
@@ -721,11 +732,11 @@ const int maxfetch;               /* maximum number of messages to fetch */
     init_transact(proto);
 
     /* set up the server-nonresponse timeout */
-    alrmsave = signal(SIGALRM, timeout_handler);
+    alrmsave = set_signal_handler(SIGALRM, timeout_handler);
     mytimeout = ctl->server.timeout;
 
     /* set up the broken-pipe timeout */
-    pipesave = signal(SIGPIPE, sigpipe_handler);
+    pipesave = set_signal_handler(SIGPIPE, sigpipe_handler);
 
     if ((js = setjmp(restart)))
     {
@@ -747,7 +758,7 @@ const int maxfetch;         /* maximum number of messages to fetch */
        
        if (js == THROW_SIGPIPE)
        {
-           signal(SIGPIPE, SIG_IGN);
+           set_signal_handler(SIGPIPE, SIG_IGN);
            report(stdout,
                   GT_("SIGPIPE thrown from an MDA or a stream socket error\n"));
            wait(0);
@@ -1091,8 +1102,8 @@ const int maxfetch;               /* maximum number of messages to fetch */
                     */
                    if (run.poll_interval
                        && !ctl->wehavesentauthnote
-                       && ((ctl->wehaveauthed && ++ctl->authfailcount == 10)
-                           || ++ctl->authfailcount == 3)
+                       && ((ctl->wehaveauthed && ++ctl->authfailcount >= 10)
+                           || (!ctl->wehaveauthed && ++ctl->authfailcount >= 3))
                        && !open_warning_by_mail(ctl, (struct msgblk *)NULL))
                    {
                        ctl->wehavesentauthnote = 1;
@@ -1486,8 +1497,9 @@ closeUp:
            err = PS_SYNTAX;
     }
 
-    signal(SIGALRM, alrmsave);
-    signal(SIGPIPE, pipesave);
+    set_timeout(0); /* cancel any pending alarm */
+    set_signal_handler(SIGALRM, alrmsave);
+    set_signal_handler(SIGPIPE, pipesave);
     return(err);
 }