From 6452b2c571c21a1c396656a4b1ab10d62958782e Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 5 Mar 2001 13:14:09 +0000 Subject: [PATCH] Tolerate flaky servers better. svn path=/trunk/; revision=3204 --- NEWS | 5 +++ driver.c | 115 +++++++++++++++++++++++++++++++++++--------------- fetchmail.h | 3 ++ fetchmail.man | 2 + pop3.c | 4 ++ 5 files changed, 95 insertions(+), 34 deletions(-) diff --git a/NEWS b/NEWS index 855dd68c..4cadf2f2 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,11 @@ (The `lines' figures total .c, .h, .l, and .y files under version control.) +* Incorporate SA_LEN patch from Red Hat. +* HMH's "no spambounce" patch for fetchmaiolconf. +* John Bartlett's patch to make the driver code more tolerant of flaky POP3 + servers. + fetchmail-5.7.2 (Sun Mar 4 19:05:57 EST 2001), 20167 lines: * NLS build fixed under Linux -- thanks to Nicolás Lichtmaier. diff --git a/driver.c b/driver.c index 1fbd992a..275b7760 100644 --- a/driver.c +++ b/driver.c @@ -1820,32 +1820,58 @@ const int maxfetch; /* maximum number of messages to fetch */ report(stderr, _("Lock-busy error on %s@%s\n"), ctl->remotename, ctl->server.truename); - else if (ok == PS_AUTHFAIL) - { - report(stderr, _("Authorization failure on %s@%s\n"), + else if (ok == PS_SERVBUSY) + report(stderr, _("Server busy error on %s@%s\n"), ctl->remotename, ctl->server.truename); + else if (ok == PS_AUTHFAIL) + { + report(stderr, _("Authorization failure on %s@%s%s\n"), + ctl->remotename, + ctl->server.truename, + (ctl->wehaveauthed ? " (previously authorized)" : " ") + ); /* * If we're running in background, try to mail the * calling user a heads-up about the authentication * failure once it looks like this isn't a fluke * due to the server being temporarily inaccessible. - * When we get third failure, we notify the user. After - * that, once we get authorization we let the user know - * service is restored. + * When we get third succesive failure, we notify the user + * but only if we haven't already managed to get + * authorization. After that, once we get authorization + * we let the user know service is restored. */ if (run.poll_interval - && ++ctl->authfailcount == 3 + && ctl->wehavesentauthnote + && ((ctl->wehaveauthed && ++ctl->authfailcount == 10) + || ++ctl->authfailcount == 3) && !open_warning_by_mail(ctl, (struct msgblk *)NULL)) { + ctl->wehavesentauthnote = 1; stuff_warning(ctl, - _("Subject: fetchmail authentication failed\r\n")); + _("Subject: fetchmail authentication failed\r\n")); stuff_warning(ctl, - _("Fetchmail could not get mail from %s@%s.\r\n"), - ctl->remotename, - ctl->server.truename); - stuff_warning(ctl, _("\ + _("Fetchmail could not get mail from %s@%s.\r\n"), + ctl->remotename, + ctl->server.truename); + if (ctl->wehaveauthed) + stuff_warning(ctl, _("\ +The attempt to get authorization failed.\r\n\ +Since we have already succeeded in getting authorization for this\r\n\ +connection, this is probably another failure mode (such as busy server)\r\n\ +that fetchmail cannot distinguish because the server didn't send a useful\r\n\ +error message.\r\n\ +\r\n\ +However, if you HAVE changed you account details since starting the\r\n\ +fetchmail daemon, you need to stop the daemon, change your configuration\r\n\ +of fetchmail, and then restart the daemon.\r\n\ +\r\n\ +The fetchmail daemon will continue running and attempt to connect\r\n\ +at each cycle. No future notifications will be sent until service\r\n\ +is restored.")); + else + stuff_warning(ctl, _("\ The attempt to get authorization failed.\r\n\ This probably means your password is invalid, but some servers have\r\n\ other failure modes that fetchmail cannot distinguish from this\r\n\ @@ -1859,34 +1885,55 @@ is restored.")); } else report(stderr, _("Unknown login or authentication error on %s@%s\n"), - ctl->remotename, - ctl->server.truename); + ctl->remotename, + ctl->server.truename); goto cleanUp; } else { - if (ctl->authfailcount >= 3) - { - report(stderr, - _("Authorization OK on %s@%s\n"), - ctl->remotename, - ctl->server.truename); - if (!open_warning_by_mail(ctl, (struct msgblk *)NULL)) - { - stuff_warning(ctl, - _("Subject: fetchmail authentication OK\r\n")); - stuff_warning(ctl, - _("Fetchmail was able to log into %s@%s.\r\n"), - ctl->remotename, - ctl->server.truename); - stuff_warning(ctl, - _("Service has been restored.\r\n")); - close_warning_by_mail(ctl, (struct msgblk *)NULL); + /* + * This connection has given us authorization + * at least once. + * + * There are dodgy server (clubinternet.fr for + * example) that give spurious authorization + * failures on patently good account/password + * details, then 5 minutes later let you in! + * + * This is meant to build in some tolerance of + * such nasty bits of work + */ + ctl->wehaveauthed = 1; + /*if (ctl->authfailcount >= 3)*/ + if (ctl->wehavesentauthnote) + { + ctl->wehavesentauthnote = 0; + report(stderr, + _("Authorization OK on %s@%s\n"), + ctl->remotename, + ctl->server.truename); + if (!open_warning_by_mail(ctl, (struct msgblk *)NULL)) + { + stuff_warning(ctl, + _("Subject: fetchmail authentication OK\r\n")); + stuff_warning(ctl, + _("Fetchmail was able to log into %s@%s.\r\n"), + ctl->remotename, + ctl->server.truename); + stuff_warning(ctl, + _("Service has been restored.\r\n")); + close_warning_by_mail(ctl, (struct msgblk *)NULL); - } - ctl->authfailcount = 0; - } + } + } + /* + * Reporting only after the first three + * consecutive failures, or ten consecutive + * failures after we have managed to get + * authorization. + */ + ctl->authfailcount = 0; } } diff --git a/fetchmail.h b/fetchmail.h index dff81d18..6c9a4919 100644 --- a/fetchmail.h +++ b/fetchmail.h @@ -92,6 +92,7 @@ #define PS_DNS 11 /* fatal DNS error */ #define PS_BSMTP 12 /* output batch could not be opened */ #define PS_MAXFETCH 13 /* poll ended by fetch limit */ +#define PS_SERVBUSY 14 /* server is busy */ /* leave space for more codes */ #define PS_UNDEFINED 23 /* something I hadn't thought of */ #define PS_TRANSIENT 24 /* transient failure (internal use) */ @@ -297,6 +298,8 @@ struct query const char *destaddr; /* destination host for this query */ int errcount; /* count transient errors in last pass */ int authfailcount; /* count of authorization failures */ + int wehaveauthed; /* We have managed to logon at least once! */ + int wehavesentauthnote; /* We have sent an authorization failure note */ int wedged; /* wedged by auth failures or timeouts? */ char *smtphost; /* actual SMTP host we connected to */ int smtp_socket; /* socket descriptor for SMTP connection */ diff --git a/fetchmail.man b/fetchmail.man index 8663c872..0ac3e451 100644 --- a/fetchmail.man +++ b/fetchmail.man @@ -1968,6 +1968,8 @@ a DNS lookup at startup and could not proceed. BSMTP batch file could not be opened. .IP 13 Poll terminated by a fetch limit (see the --fetchlimit option). +.IP 14 +Server busy indication. .IP 23 Internal error. You should see a message on standard error with details. diff --git a/pop3.c b/pop3.c index 304bec8f..ea3000c1 100644 --- a/pop3.c +++ b/pop3.c @@ -99,6 +99,10 @@ int pop3_ok (int sock, char *argbuf) /* these are blessed by RFC 2449 */ || strstr(bufp,"[IN-USE]")||strstr(bufp,"[LOGIN-DELAY]")) ok = PS_LOCKBUSY; + else if ((strstr(bufp,"Service") + || strstr(bufp,"service")) + && (strstr(bufp,"unavailable"))) + ok = PS_SERVBUSY; else ok = PS_AUTHFAIL; /* -- 2.43.2