* 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.
#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 */
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)
#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;
static void timeout_handler (int signal)
/* handle server-timeout SIGALRM signal */
{
+ timeoutcount++;
longjmp(restart, 1);
}
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;
* 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");
stuff_warning(ctl,
"This probably means your password is invalid.");
close_warning_by_mail(ctl);
- ctl->authfailcount++;
+ ctl->wedged = TRUE;
}
}
goto cleanUp;
/* 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 ||
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;
}
* 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);
}
/* 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 */
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 */
/* 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
-