]> Pileus Git - ~andy/fetchmail/commitdiff
Send notification and wedge the connection on too many timeouts.
authorEric S. Raymond <esr@thyrsus.com>
Fri, 20 Nov 1998 18:20:52 +0000 (18:20 -0000)
committerEric S. Raymond <esr@thyrsus.com>
Fri, 20 Nov 1998 18:20:52 +0000 (18:20 -0000)
svn path=/trunk/; revision=2190

NEWS
driver.c
fetchmail.c
fetchmail.h
tunable.h

diff --git a/NEWS b/NEWS
index a58d8988ccf669e00641f537b54f88787c05d52a..e1b1d79a6a9fdf786925c93b2d7868f81f7bc8b0 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ fetchmail-4.6.7 ():
 * Gerald Britton's patches to enable Hesiod support.
 * Postmaster option fix from Bill Metzenthen <billm@melbpc.org.au>.
 * Socks library support forom Guiseppe Guerini.
+* Notification mail is now sent to the user on 20 consecutive timeouts.
 
 There are 248 people on fetchmail-friends and 306 on fetchmail-announce.
 
index f13f7b01c78c0d04f0815249da9a5ca5461e7ce7..11ea4d49a49b2520c769a33741cf3997cac1463c 100644 (file)
--- a/driver.c
+++ b/driver.c
@@ -65,7 +65,8 @@
 #endif /* KERBEROS_V5 */
 
 #include "socket.h"
-#include  "fetchmail.h"
+#include "fetchmail.h"
+#include "tunable.h"
 
 #if INET6
 #define        SMTP_PORT       "smtp"  /* standard SMTP service port */
@@ -92,6 +93,7 @@ static int tagnum;
 
 static char shroud[PASSWORDLEN];       /* string to shroud in debug output */
 static int mytimeout;                  /* value of nonreponse timeout */
+static int timeoutcount;               /* count consecutive timeouts */
 static int msglen;                     /* actual message length */
 
 void set_timeout(int timeleft)
@@ -100,6 +102,9 @@ void set_timeout(int timeleft)
 #ifndef __EMX__
     struct itimerval ntimeout;
 
+    if (timeleft == 0)
+       timeoutcount = 0;
+
     ntimeout.it_interval.tv_sec = ntimeout.it_interval.tv_usec = 0;
     ntimeout.it_value.tv_sec  = timeleft;
     ntimeout.it_value.tv_usec = 0;
@@ -110,6 +115,7 @@ void set_timeout(int timeleft)
 static void timeout_handler (int signal)
 /* handle server-timeout SIGALRM signal */
 {
+    timeoutcount++;
     longjmp(restart, 1);
 }
 
@@ -1364,11 +1370,37 @@ const struct method *proto;     /* protocol method table */
            close(ctl->smtp_socket);
        if (sock != -1)
            SockClose(sock);
+
+       /*
+        * If we've exceeded our threshold for consecutive timeouts, 
+        * try to notify the user, then mark the connection wedged.
+        */
+       if (timeoutcount > MAX_TIMEOUTS && !open_warning_by_mail(ctl))
+       {
+           stuff_warning(ctl,
+                         "Subject: fetchmail sees repeated timeouts\r\n");
+           stuff_warning(ctl,
+                         "Fetchmail saw more than %d timouts while attempting to get mail from %s@%s.", 
+                         MAX_TIMEOUTS,
+                         ctl->remotename,
+                         ctl->server.truename);
+           stuff_warning(ctl, 
+                         "This could mean that your mailserver is stuck, or that your SMTP listener");
+           stuff_warning(ctl, 
+                         "is wedged, or that your mailbox file on the server has been corrupted by");
+           stuff_warning(ctl, 
+                         "a server error.  You can run `fetchmail -v -v' to diagnose the problem.");
+           stuff_warning(ctl,
+                         "Fetchmail won't poll this mailbox again until you restart it.");
+           close_warning_by_mail(ctl);
+           ctl->wedged = TRUE;
+       }
+
        ok = PS_ERROR;
     }
     else
     {
-       char buf [POPBUFSIZE+1], *realhost;
+       char buf[POPBUFSIZE+1], *realhost;
        int len, num, count, new, bytes, deletions = 0, *msgsizes = NULL;
 #if INET6
        int fetches, dispatches;
@@ -1504,7 +1536,7 @@ const struct method *proto;       /* protocol method table */
                     * failure the first time it happens.
                     */
                    if (run.poll_interval
-                       && !ctl->authfailcount && !open_warning_by_mail(ctl))
+                       && !ctl->wedged && !open_warning_by_mail(ctl))
                    {
                        stuff_warning(ctl,
                               "Subject: fetchmail authentication failed\r\n");
@@ -1517,7 +1549,7 @@ const struct method *proto;       /* protocol method table */
                        stuff_warning(ctl, 
                               "This probably means your password is invalid.");
                        close_warning_by_mail(ctl);
-                       ctl->authfailcount++;
+                       ctl->wedged = TRUE;
                    }
                }
                goto cleanUp;
index 958484910892ffa63e5ead9f190c43a5f7201f68..b36c2d83a6a217de72b9d02c65efe9a2012a50ed 100644 (file)
@@ -377,8 +377,6 @@ int main (int argc, char **argv)
     /* pick up interactively any passwords we need but don't have */ 
     for (ctl = querylist; ctl; ctl = ctl->next)
     {
-       ctl->authfailcount = 0;
-
        if (ctl->active && !(implicitmode && ctl->server.skip)&&!ctl->password)
        {
            if (ctl->server.preauthenticate == A_KERBEROS_V4 ||
@@ -505,10 +503,10 @@ int main (int argc, char **argv)
        batchcount = 0;
        for (ctl = querylist; ctl; ctl = ctl->next)
        {
-           if (ctl->authfailcount)
+           if (ctl->wedged)
            {
                error(0, -1, 
-                     "poll of %s skipped until authentication is unwedged",
+                     "poll of %s skipped (failed authentication or too many timeouts)",
                      ctl->server.pollname);
                continue;
            }
@@ -603,14 +601,14 @@ int main (int argc, char **argv)
             * should softly and silently vanish away, rather than
             * spinning uselessly.
             */
-           int auth_ok = 0;
+           int unwedged = 0;
 
            for (ctl = querylist; ctl; ctl = ctl->next)
-               if (!ctl->authfailcount)
-                   auth_ok++;
-           if (!auth_ok)
+               if (!ctl->wedged)
+                   unwedged++;
+           if (!unwedged)
            {
-               error(0, -1, "All authentications have failed.  Exiting.");
+               error(0, -1, "All connections are wedged.  Exiting.");
                exit(PS_AUTHFAIL);
            }
 
@@ -896,6 +894,8 @@ static int load_params(int argc, char **argv, int optind)
     /* merge in wired defaults, do sanity checks and prepare internal fields */
     for (ctl = querylist; ctl; ctl = ctl->next)
     {
+       ctl->wedged = FALSE;
+
        if (configdump || (ctl->active && !(implicitmode && ctl->server.skip)))
        {
            /* merge in defaults */
index 9b4f03b5d2cb8c080dee2ba4cb822b8494fe55b6..d40f25da3ff78a556dbf5b451de49d5e3f6b3005 100644 (file)
@@ -255,7 +255,7 @@ struct query
     flag active;               /* should we actually poll this server? */
     const char *destaddr;      /* destination host for this query */
     int errcount;              /* count transient errors in last pass */
-    int authfailcount;         /* count authentication failures this run */
+    int wedged;                        /* wedged by auth failures or timeouts? */
     char *smtphost;            /* actual SMTP host we connected to */
     int smtp_socket;           /* socket descriptor for SMTP connection */
     unsigned int uid;          /* UID of user to deliver to */
index 9ee1e6c935c4efaae8a299a217be66ce251418da..8046afc1746be8ea4e2c26d1094ef538916673bf 100644 (file)
--- a/tunable.h
+++ b/tunable.h
@@ -10,6 +10,8 @@
 /* default timeout period in seconds if server connection dies */
 #define        CLIENT_TIMEOUT          300
 
+/* maximum consecutive timeouts to accept */
+#define MAX_TIMEOUTS           20
+
 /* default skipped message warning interval in seconds */
 #define WARNING_INTERVAL       3600
-