aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--driver.c40
-rw-r--r--fetchmail.c18
-rw-r--r--fetchmail.h2
-rw-r--r--tunable.h4
5 files changed, 50 insertions, 15 deletions
diff --git a/NEWS b/NEWS
index a58d8988..e1b1d79a 100644
--- 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.
diff --git a/driver.c b/driver.c
index f13f7b01..11ea4d49 100644
--- 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;
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 */
diff --git a/tunable.h b/tunable.h
index 9ee1e6c9..8046afc1 100644
--- 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
-