diff options
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | driver.c | 28 | ||||
-rw-r--r-- | fetchmail.c | 54 |
3 files changed, 51 insertions, 36 deletions
@@ -1,9 +1,10 @@ Release Notes: -pl 1.9.10 (): -* Better error messages on SMTP failure. +pl 1.9.9 (): * Accept Resent-From & Apparently-From a la RFC822. * Include file fixes for Solaris 2.5 and FreeBSD 2.2. +* Improved error notification on SMTP and no-matching-local-address errors. +* Delivery to multidrop mailboxes now always aborts on DNS errors. pl 1.9.8 (Wed Nov 6 16:40:34 EST 1996): * Don't append spurious NUL to the headers, qmail actually notices it. @@ -120,12 +120,16 @@ static int is_host_alias(const char *name, struct query *ctl) return(TRUE); /* - * We treat DNS lookup failure as a negative on the theory that - * the mailserver's DNS server is `nearby' and should be able - * to respond quickly and reliably. Ergo if we get failure, - * the name isn't a mailserver alias. + * We know DNS service was up at the beginning of this poll cycle. + * If it's down, our nameserver has crashed. We don't want to try + * delivering the current message or anything else from this + * mailbox until it's back up. */ - else if ((he = gethostbyname(name)) && strcmp(ctl->canonical_name, he->h_name) == 0) + else if ((he = gethostbyname(name)) == (struct hostent *)NULL) + longjmp(restart, 2); + + /* DNS response is OK */ + else if (strcmp(ctl->canonical_name, he->h_name) == 0) return(TRUE); /* @@ -138,12 +142,15 @@ static int is_host_alias(const char *name, struct query *ctl) mxrecords = getmxrecords(name); + h_errno = 0; if (mxrecords == (struct mxentry *)NULL) if (h_errno == TRY_AGAIN) { sleep(1); continue; } + else if (h_errno) /* fatal error */ + longjmp(restart, 2); else break; @@ -628,7 +635,7 @@ int do_protocol(ctl, proto) struct query *ctl; /* parsed options with merged-in defaults */ const struct method *proto; /* protocol method table */ { - int ok; + int ok, js; void (*sigsave)(); #ifndef KERBEROS_V4 @@ -673,13 +680,20 @@ const struct method *proto; /* protocol method table */ sigsave = signal(SIGVTALRM, vtalarm_handler); vtalarm(mytimeout = ctl->timeout); - if (setjmp(restart) == 1) + if ((js = setjmp(restart)) == 1) { fprintf(stderr, "fetchmail: timeout after %d seconds waiting for %s.\n", ctl->timeout, ctl->servername); ok = PS_ERROR; } + else if (js == 2) + { + fprintf(stderr, + "fetchmail: nameserver evaporated during poll of %s.\n", + ctl->servername); + ok = PS_ERROR; + } else { char buf [POPBUFSIZE+1]; diff --git a/fetchmail.c b/fetchmail.c index 47620dfe..e22568a5 100644 --- a/fetchmail.c +++ b/fetchmail.c @@ -307,6 +307,33 @@ int main (int argc, char **argv) { if (ctl->active && !(implicitmode && ctl->skip)) { +#ifdef HAVE_GETHOSTBYNAME + /* + * This functions partly as an optimization and partly + * as a probe to make sure our nameserver is still up. + * The multidrop case (especially) needs it. + */ + if (ctl->authenticate == A_KERBEROS || MULTIDROP(ctl)) + { + struct hostent *namerec; + + /* compute the canonical name of the host */ + namerec = gethostbyname(ctl->servername); + if (namerec == (struct hostent *)NULL) + { + fprintf(stderr, + "fetchmail: skipping %s poll, nameserver isn't responding\n", + ctl->servername); + continue; + } + else + { + free(ctl->canonical_name); + ctl->canonical_name = xstrdup((char *)namerec->h_name); + } + } +#endif /* HAVE_GETHOSTBYNAME */ + popstatus = query_host(ctl); if (!check_only) update_uid_lists(ctl); @@ -439,10 +466,6 @@ static int load_params(int argc, char **argv, int optind) { if (ctl->active && !(implicitmode && ctl->skip)) { -#ifdef HAVE_GETHOSTBYNAME - struct hostent *namerec; -#endif /* HAVE_GETHOSTBYNAME */ - /* merge in defaults */ optmerge(ctl, &def_opts); @@ -463,29 +486,6 @@ static int load_params(int argc, char **argv, int optind) else ctl->uid = pw->pw_uid; -#ifdef HAVE_GETHOSTBYNAME - /* - * Don't do DNS lookup unless we need to because we're going - * to use Kerberos or process a multidrop box. Some sites - * won't have DNS up at fetchmail initialization time but aren't - * using these features -- avoid hosing them unnecessarily. - */ - if (ctl->authenticate == A_KERBEROS || MULTIDROP(ctl)) - { - /* compute the canonical name of the host */ - namerec = gethostbyname(ctl->servername); - if (namerec == (struct hostent *)NULL) - { - fprintf(stderr, - "fetchmail: can't get canonical name of host %s\n", - ctl->servername); - exit(PS_SYNTAX); - } - else - ctl->canonical_name = xstrdup((char *)namerec->h_name); - } -#endif /* HAVE_GETHOSTBYNAME */ - #if !defined(HAVE_GETHOSTBYNAME) || !defined(HAVE_RES_SEARCH) /* can't handle multidrop mailboxes unless we can do DNS lookups */ if (ctl->localnames && ctl->localnames->next) |