aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS5
-rw-r--r--driver.c28
-rw-r--r--fetchmail.c54
3 files changed, 51 insertions, 36 deletions
diff --git a/NEWS b/NEWS
index fa31b809..ef1b473f 100644
--- a/NEWS
+++ b/NEWS
@@ -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.
diff --git a/driver.c b/driver.c
index 325383ce..11cde20a 100644
--- a/driver.c
+++ b/driver.c
@@ -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)