aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--driver.c23
-rw-r--r--fetchmail.c21
-rw-r--r--fetchmail.h18
-rw-r--r--uid.c12
-rw-r--r--xmalloc.c2
5 files changed, 53 insertions, 23 deletions
diff --git a/driver.c b/driver.c
index bdf033f0..af14372e 100644
--- a/driver.c
+++ b/driver.c
@@ -120,13 +120,25 @@ static int is_host_alias(const char *name, struct query *ctl)
return(TRUE);
/*
+ * Is it in the `also known as' cache accumulated by previous DNS checks?
+ * This cache may someday be primed by an aka option.
+ */
+ else if (uid_in_list(&ctl->lead_server->aka, name))
+ return(TRUE);
+
+ /*
* 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)) != (struct hostent *)NULL)
- return(strcmp(ctl->canonical_name, he->h_name) == 0);
+ {
+ if (strcmp(ctl->canonical_name, he->h_name) == 0)
+ goto match;
+ else
+ return(FALSE);
+ }
else
switch (h_errno)
{
@@ -162,7 +174,7 @@ static int is_host_alias(const char *name, struct query *ctl)
case NO_ADDRESS: /* valid, but does not have an IP address */
for (mxp = mxrecords; mxp->name; mxp++)
if (strcmp(name, mxp->name) == 0)
- return(TRUE);
+ goto match;
break;
case NO_RECOVERY: /* non-recoverable name server error */
@@ -177,6 +189,11 @@ static int is_host_alias(const char *name, struct query *ctl)
}
return(FALSE);
+
+match:
+ /* add this name to relevant server's `also known as' list */
+ save_uid(&ctl->lead_server->aka, -1, name);
+ return(TRUE);
}
void find_server_names(hdr, ctl, xmit_names)
@@ -226,7 +243,7 @@ struct idlist **xmit_names; /* list of recipient names parsed out */
static FILE *smtp_open(struct query *ctl)
/* try to open a socket to the appropriate SMTP server for this query */
{
- ctl = ctl->leader; /* go to the SMTP leader for this query */
+ ctl = ctl->lead_smtp; /* go to the SMTP leader for this query */
/* maybe it's time to close the socket in order to force delivery */
if (batchlimit && ctl->smtp_sockfp && batchcount++ == batchlimit)
diff --git a/fetchmail.c b/fetchmail.c
index 5e39b4dc..a3a734be 100644
--- a/fetchmail.c
+++ b/fetchmail.c
@@ -517,21 +517,32 @@ static int load_params(int argc, char **argv, int optind)
*
* In the typical case, there will be only one SMTP host (the
* client machine) and thus just one SMTP leader (and one listener
- * process) through the entire run.
+ * process) through the entire poll cycle.
*/
if (!ctl->mda[0])
{
+ ctl->smtp_sockfp = (FILE *)NULL;
for (mp = querylist; mp && mp != ctl; mp = mp->next)
if (strcmp(mp->smtphost, ctl->smtphost) == 0)
{
- ctl->leader = mp->leader;
+ ctl->lead_smtp = mp->lead_smtp;
goto no_new_leader;
}
- ctl->leader = ctl;
- ctl->smtp_sockfp = (FILE *)NULL;
+ ctl->lead_smtp = ctl;
no_new_leader:;
}
+ /* similarly, compute server leaders for queries */
+ ctl->aka = (struct idlist *)NULL;
+ for (mp = querylist; mp && mp != ctl; mp = mp->next)
+ if (strcmp(mp->servername, ctl->servername) == 0)
+ {
+ ctl->lead_server = mp->lead_server;
+ goto no_new_server;
+ }
+ ctl->lead_server = ctl;
+ no_new_server:;
+
/* sanity checks */
if (ctl->port < 0)
{
@@ -588,7 +599,7 @@ void termhook(int sig)
/* terminate all SMTP connections cleanly */
for (ctl = querylist; ctl; ctl = ctl->next)
- if (ctl->leader == ctl && ctl->smtp_sockfp != (FILE *)NULL)
+ if (ctl->lead_smtp == ctl && ctl->smtp_sockfp != (FILE *)NULL)
SMTP_quit(ctl->smtp_sockfp);
if (!check_only)
diff --git a/fetchmail.h b/fetchmail.h
index 6acd0c99..3765f6f3 100644
--- a/fetchmail.h
+++ b/fetchmail.h
@@ -94,8 +94,10 @@ struct query
int active;
int errcount; /* count transient errors in last pass */
struct query *next; /* next query control block in chain */
- struct query *leader; /* pointer to this query's SMTP leader */
+ struct query *lead_smtp; /* pointer to this query's SMTP leader */
FILE *smtp_sockfp; /* socket descriptor for SMTP connection */
+ struct query *lead_server; /* pointer to lead query for this server */
+ struct idlist *aka; /* server alias list */
unsigned int uid; /* UID of user to deliver to */
char digest [DIGESTLEN]; /* md5 digest buffer */
#ifdef HAVE_GETHOSTBYNAME
@@ -162,7 +164,7 @@ int gen_transact ();
#endif
void *xmalloc(int);
-char *xstrdup(char *);
+char *xstrdup(const char *);
int do_protocol(struct query *, const struct method *);
int doPOP2 (struct query *);
@@ -172,18 +174,18 @@ int doIMAP (struct query *);
void reply_hack(char *, const char *);
char *nxtaddr(const char *);
-void initialize_saved_lists(struct query *, char *);
-struct idlist *save_uid(struct idlist **, int, char *);
+void initialize_saved_lists(struct query *, const char *);
+struct idlist *save_uid(struct idlist **, int, const char *);
void free_uid_list(struct idlist **);
-void save_id_pair(struct idlist **, char *, char *);
+void save_id_pair(struct idlist **, const char *, const char *);
void free_idpair_list(struct idlist **);
int delete_uid(struct idlist **, int);
-int uid_in_list(struct idlist **, char *);
+int uid_in_list(struct idlist **, const char *);
char *uid_find(struct idlist **, int);
-char *idpair_find(struct idlist **, char *);
+char *idpair_find(struct idlist **, const char *);
void append_uid_list(struct idlist **, struct idlist **);
void update_uid_lists(struct query *);
-void write_saved_lists(struct query *, char *);
+void write_saved_lists(struct query *, const char *);
struct query *hostalloc(struct query *);
int parsecmdline (int, char **, struct query *);
diff --git a/uid.c b/uid.c
index b8280b6c..6aaf025a 100644
--- a/uid.c
+++ b/uid.c
@@ -62,7 +62,7 @@
/* UIDs associated with un-queried hosts */
static struct idlist *scratchlist;
-void initialize_saved_lists(struct query *hostlist, char *idfile)
+void initialize_saved_lists(struct query *hostlist, const char *idfile)
/* read file of saved IDs and attach to each host */
{
int st;
@@ -99,7 +99,7 @@ void initialize_saved_lists(struct query *hostlist, char *idfile)
}
}
-struct idlist *save_uid(struct idlist **idl, int num, char *str)
+struct idlist *save_uid(struct idlist **idl, int num, const char *str)
/* save a number/UID pair on the given UID list */
{
struct idlist *new;
@@ -125,7 +125,7 @@ void free_uid_list(struct idlist **idl)
*idl = (struct idlist *)NULL;
}
-void save_id_pair(struct idlist **idl, char *str1, char *str2)
+void save_id_pair(struct idlist **idl, const char *str1, const char *str2)
/* save an ID pair on the given list */
{
struct idlist *new;
@@ -155,7 +155,7 @@ void free_idpair_list(struct idlist **idl)
}
#endif
-int uid_in_list(struct idlist **idl, char *str)
+int uid_in_list(struct idlist **idl, const char *str)
/* is a given ID in the given list? */
{
if (*idl == (struct idlist *)NULL || str == (char *) NULL)
@@ -177,7 +177,7 @@ char *uid_find(struct idlist **idl, int number)
return(uid_find(&(*idl)->next, number));
}
-char *idpair_find(struct idlist **idl, char *id)
+char *idpair_find(struct idlist **idl, const char *id)
/* return the id of the given number in the given list. */
{
if (*idl == (struct idlist *) 0)
@@ -226,7 +226,7 @@ void update_uid_lists(struct query *hostp)
hostp->newsaved = (struct idlist *) NULL;
}
-void write_saved_lists(struct query *hostlist, char *idfile)
+void write_saved_lists(struct query *hostlist, const char *idfile)
/* perform end-of-run write of seen-messages list */
{
int idcount;
diff --git a/xmalloc.c b/xmalloc.c
index 7bdd5303..d9726618 100644
--- a/xmalloc.c
+++ b/xmalloc.c
@@ -31,7 +31,7 @@ xmalloc (int n)
return(p);
}
-char *xstrdup(char *s)
+char *xstrdup(const char *s)
{
char *p;
p = (char *) xmalloc(strlen(s)+1);