diff options
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | driver.c | 40 | ||||
-rw-r--r-- | fetchmail.c | 18 | ||||
-rw-r--r-- | fetchmail.h | 2 | ||||
-rw-r--r-- | tunable.h | 4 |
5 files changed, 50 insertions, 15 deletions
@@ -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. @@ -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; diff --git a/fetchmail.c b/fetchmail.c index 95848491..b36c2d83 100644 --- a/fetchmail.c +++ b/fetchmail.c @@ -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 */ diff --git a/fetchmail.h b/fetchmail.h index 9b4f03b5..d40f25da 100644 --- a/fetchmail.h +++ b/fetchmail.h @@ -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 */ @@ -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 - |