aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS5
-rw-r--r--driver.c41
-rw-r--r--fetchmail.c26
-rw-r--r--fetchmail.h3
-rw-r--r--rcfile_y.y27
-rw-r--r--uid.c21
6 files changed, 61 insertions, 62 deletions
diff --git a/NEWS b/NEWS
index e1b80867..b60e8df2 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,6 @@
Release Notes:
-fetchmail-2.1 ():
+fetchmail-2.1 (Thu Nov 28 11:07:48 EST 1996):
features --
@@ -22,7 +22,8 @@ features --
* Added an `aka' option to allow users to declare mailserver aliases at start
of run, so DNS does less work. During a run, cache host matches on the
- aka list so no potential alias has to be DNS-checked more than once.
+ aka list so no potential alias has to be DNS-checked more than once.
+ A server being polled explicitly may be referred to by any of its aliaseses.
bugs --
diff --git a/driver.c b/driver.c
index e90a3e84..d46b6767 100644
--- a/driver.c
+++ b/driver.c
@@ -104,29 +104,26 @@ static int is_host_alias(const char *name, struct query *ctl)
/*
* The first two checks are optimizations that will catch a good
- * many cases. First, check against the hostname the user specified.
- * Odds are good this will either be the mailserver's FQDN or a
- * suffix of it with the mailserver's domain's default host name
- * omitted. Next, check against the mailserver's FQDN, in case
+ * many cases. (1) check against the hostname the user
+ * specified. Odds are good this will either be the mailserver's
+ * FQDN or a suffix of it with the mailserver's domain's default
+ * host name omitted. Then check the rest of the `also known as'
+ * cache accumulated by previous DNS checks. This cache is primed
+ * by the aka list option.
+ *
+ * (2) check against the mailserver's FQDN, in case
* it's not the same as the declared hostname.
*
* Either of these on a mail address is definitive. Only if the
* name doesn't match either is it time to call the bind library.
* If this happens odds are good we're looking at an MX name.
*/
- if (strcmp(name, ctl->servername) == 0)
+ if (uid_in_list(&ctl->lead_server->servernames, name))
return(TRUE);
else if (strcmp(name, ctl->canonical_name) == 0)
return(TRUE);
/*
- * Is it in the `also known as' cache accumulated by previous DNS checks?
- * This cache is primed by the aka list 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
@@ -153,7 +150,7 @@ static int is_host_alias(const char *name, struct query *ctl)
putchar('\n'); /* terminate the progress message */
fprintf(stderr,
"fetchmail: nameserver failure while looking for `%s' during poll of %s.\n",
- name, ctl->servername);
+ name, ctl->servernames->id);
ctl->errcount++;
longjmp(restart, 2); /* try again next poll cycle */
break;
@@ -182,7 +179,7 @@ static int is_host_alias(const char *name, struct query *ctl)
default:
fprintf(stderr,
"fetchmail: nameserver failure while looking for `%s' during poll of %s.\n",
- name, ctl->servername);
+ name, ctl->servernames->id);
ctl->errcount++;
longjmp(restart, 2); /* try again next poll cycle */
break;
@@ -192,7 +189,7 @@ static int is_host_alias(const char *name, struct query *ctl)
match:
/* add this name to relevant server's `also known as' list */
- save_uid(&ctl->lead_server->aka, -1, name);
+ save_uid(&ctl->lead_server->servernames, -1, name);
return(TRUE);
}
@@ -273,7 +270,7 @@ static FILE *smtp_open(struct query *ctl)
if ((ctl->smtp_sockfp = Socket(ctl->smtphost, SMTP_PORT)) == (FILE *)NULL)
return((FILE *)NULL);
else if (SMTP_ok(ctl->smtp_sockfp) != SM_OK
- || SMTP_helo(ctl->smtp_sockfp, ctl->servername) != SM_OK)
+ || SMTP_helo(ctl->smtp_sockfp, ctl->servernames->id) != SM_OK)
{
fclose(ctl->smtp_sockfp);
ctl->smtp_sockfp = (FILE *)NULL;
@@ -336,7 +333,7 @@ struct query *ctl; /* query control record */
if (inheaders)
{
if (!ctl->norewrite)
- reply_hack(bufp, ctl->servername);
+ reply_hack(bufp, ctl->servernames->id);
if (!lines)
{
@@ -804,7 +801,7 @@ const struct method *proto; /* protocol method table */
{
fprintf(stderr,
"fetchmail: timeout after %d seconds waiting for %s.\n",
- ctl->timeout, ctl->servername);
+ ctl->timeout, ctl->servernames->id);
ok = PS_ERROR;
}
else if (js == 2)
@@ -819,7 +816,7 @@ const struct method *proto; /* protocol method table */
FILE *sockfp;
/* open a socket to the mail server */
- if ((sockfp = Socket(ctl->servername,
+ if ((sockfp = Socket(ctl->servernames->id,
ctl->port ? ctl->port : protocol->port)) == NULL)
{
perror("fetchmail, connecting to host");
@@ -863,7 +860,7 @@ const struct method *proto; /* protocol method table */
if (count == 0)
fprintf(stderr, "No mail from %s@%s\n",
ctl->remotename,
- ctl->servername);
+ ctl->servernames->id);
else
{
fprintf(stderr, "%d message%s", count, count > 1 ? "s" : "");
@@ -872,7 +869,7 @@ const struct method *proto; /* protocol method table */
fprintf(stderr,
" from %s@%s.\n",
ctl->remotename,
- ctl->servername);
+ ctl->servernames->id);
}
/* we may need to get sizes in order to check message limits */
@@ -1051,7 +1048,7 @@ const struct method *proto; /* protocol method table */
}
if (ok==PS_SOCKET || ok==PS_AUTHFAIL || ok==PS_SYNTAX || ok==PS_IOERR
|| ok==PS_ERROR || ok==PS_PROTOCOL || ok==PS_SMTP)
- fprintf(stderr, " error while talking to %s\n", ctl->servername);
+ fprintf(stderr, " error while talking to %s\n", ctl->servernames->id);
closeUp:
signal(SIGVTALRM, sigsave);
diff --git a/fetchmail.c b/fetchmail.c
index 05e4beae..c342f73a 100644
--- a/fetchmail.c
+++ b/fetchmail.c
@@ -263,7 +263,7 @@ int main (int argc, char **argv)
else
{
(void) sprintf(tmpbuf, "Enter password for %s@%s: ",
- ctl->remotename, ctl->servername);
+ ctl->remotename, ctl->servernames->id);
(void) strncpy(ctl->password,
(char *)getpassword(tmpbuf),PASSWORDLEN-1);
}
@@ -327,12 +327,12 @@ int main (int argc, char **argv)
/* compute the canonical name of the host */
errno = 0;
- namerec = gethostbyname(ctl->servername);
+ namerec = gethostbyname(ctl->servernames->id);
if (namerec == (struct hostent *)NULL)
{
fprintf(stderr,
"fetchmail: skipping %s poll, ",
- ctl->servername);
+ ctl->servernames->id);
if (errno)
{
perror("general error");
@@ -456,18 +456,18 @@ static int load_params(int argc, char **argv, int optind)
* record from command line and defaults
*/
for (ctl = querylist; ctl; ctl = ctl->next)
- if (strcmp(ctl->servername, argv[optind]) == 0)
+ if (uid_in_list(&ctl->servernames, argv[optind]) == 0)
goto foundit;
ctl = hostalloc(&cmd_opts);
- strcpy(ctl->servername, argv[optind]);
+ strcpy(ctl->servernames->id, argv[optind]);
foundit:
ctl->active = TRUE;
}
/* if there's a defaults record, merge it and lose it */
- if (querylist && strcmp(querylist->servername, "defaults") == 0)
+ if (querylist && strcmp(querylist->servernames->id, "defaults") == 0)
{
for (ctl = querylist; ctl; ctl = ctl->next)
optmerge(ctl, querylist);
@@ -476,7 +476,7 @@ static int load_params(int argc, char **argv, int optind)
/* don't allow a defaults record after the first */
for (ctl = querylist; ctl; ctl = ctl->next)
- if (strcmp(ctl->servername, "defaults") == 0)
+ if (ctl != querylist && strcmp(ctl->servernames->id, "defaults") == 0)
exit(PS_SYNTAX);
/* merge in wired defaults, do sanity checks and prepare internal fields */
@@ -544,7 +544,7 @@ static int load_params(int argc, char **argv, int optind)
/* similarly, compute server leaders for queries */
for (mp = querylist; mp && mp != ctl; mp = mp->next)
- if (strcmp(mp->servername, ctl->servername) == 0)
+ if (strcmp(mp->servernames->id, ctl->servernames->id) == 0)
{
ctl->lead_server = mp->lead_server;
goto no_new_server;
@@ -557,7 +557,7 @@ static int load_params(int argc, char **argv, int optind)
{
(void) fprintf(stderr,
"%s configuration invalid, port number cannot be negative",
- ctl->servername);
+ ctl->servernames->id);
exit(PS_SYNTAX);
}
@@ -651,7 +651,7 @@ static int query_host(struct query *ctl)
time(&now);
fprintf(stderr, "Querying %s (protocol %s) at %s",
- ctl->servername, showproto(ctl->protocol), ctime(&now));
+ ctl->servernames->id, showproto(ctl->protocol), ctime(&now));
}
switch (ctl->protocol) {
case P_AUTO:
@@ -684,17 +684,17 @@ void dump_params (struct query *ctl)
/* display query parameters in English */
{
printf("Options for retrieving from %s@%s:\n",
- ctl->remotename, visbuf(ctl->servername));
+ ctl->remotename, visbuf(ctl->servernames->id));
#ifdef HAVE_GETHOSTBYNAME
if (ctl->canonical_name)
printf(" Canonical DNS name of server is %s.\n", ctl->canonical_name);
#endif /* HAVE_GETHOSTBYNAME */
- if (ctl->aka)
+ if (ctl->servernames->next)
{
struct idlist *idp;
printf(" Predeclared mailserver aliases:");
- for (idp = ctl->aka; idp; idp = idp->next)
+ for (idp = ctl->servernames->next; idp; idp = idp->next)
printf(" %s", idp->id);
putchar('\n');
}
diff --git a/fetchmail.h b/fetchmail.h
index 194b472c..a61744e2 100644
--- a/fetchmail.h
+++ b/fetchmail.h
@@ -61,7 +61,7 @@ struct idlist
struct query
{
/* per-host data */
- char servername [HOSTLEN+1];
+ struct idlist *servernames; /* servername first, then akas*/
struct idlist *localnames;
int wildcard; /* true if unmatched names should be passed through */
int protocol;
@@ -98,7 +98,6 @@ struct query
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
diff --git a/rcfile_y.y b/rcfile_y.y
index 898c560e..0aab45fa 100644
--- a/rcfile_y.y
+++ b/rcfile_y.y
@@ -78,19 +78,22 @@ statement : SET BATCHLIMIT MAP NUMBER {batchlimit = $4;}
| define_server serverspecs userspecs
;
-define_server : POLL STRING {strcpy(current.servername, $2);
- current.skip = FALSE;}
- | SKIP STRING {strcpy(current.servername, $2);
- current.skip = TRUE;}
- | DEFAULTS {strcpy(current.servername,"defaults");}
+define_server : POLL STRING {current.servernames = (struct idlist *)NULL;
+ save_uid(&current.servernames, -1, $2);
+ current.skip = FALSE;}
+ | SKIP STRING {current.servernames = (struct idlist *)NULL;
+ save_uid(&current.servernames, -1, $2);
+ current.skip = TRUE;}
+ | DEFAULTS {current.servernames = (struct idlist *)NULL;
+ save_uid(&current.servernames, -1,"defaults");}
;
serverspecs : /* EMPTY */
| serverspecs serv_option
;
-alias_list : STRING {save_uid(&current.aka, -1, $1);}
- | alias_list STRING {save_uid(&current.aka, -1, $2);}
+alias_list : STRING {save_uid(&current.servernames, -1, $1);}
+ | alias_list STRING {save_uid(&current.servernames, -1, $2);}
;
serv_option : AKA alias_list
@@ -258,9 +261,8 @@ const char *pathname; /* pathname for the configuration file */
static void prc_reset(void)
/* clear the global current record (server parameters) used by the parser */
{
- char savename[HOSTLEN+1];
int saveport, saveproto, saveauth, saveskip;
- struct idlist *saveaka;
+ struct idlist *saveservernames;
/*
* Purpose of this code is to initialize the new server block, but
@@ -268,20 +270,18 @@ static void prc_reset(void)
* preserve server options unless the command-line explicitly
* overrides them.
*/
- (void) strcpy(savename, current.servername);
saveport = current.port;
saveproto = current.protocol;
saveauth = current.authenticate;
saveskip = current.skip;
- saveaka = current.aka;
+ saveservernames = current.servernames;
memset(&current, '\0', sizeof(current));
- (void) strcpy(current.servername, savename);
current.protocol = saveproto;
current.authenticate = saveauth;
current.skip = saveskip;
- current.aka = saveaka;
+ current.servernames = saveservernames;
}
struct query *hostalloc(init)
@@ -337,7 +337,6 @@ void optmerge(struct query *h2, struct query *h1)
/* merge two options records; empty fields in h2 are filled in from h1 */
{
append_uid_list(&h2->localnames, &h1->localnames);
- append_uid_list(&h2->aka, &h1->aka);
#define STR_MERGE(fld, len) if (*(h2->fld) == '\0') strcpy(h2->fld, h1->fld)
STR_MERGE(remotename, USERNAMELEN);
diff --git a/uid.c b/uid.c
index 8797c299..15a06ba3 100644
--- a/uid.c
+++ b/uid.c
@@ -84,7 +84,7 @@ void initialize_saved_lists(struct query *hostlist, const char *idfile)
{
for (ctl = hostlist; ctl; ctl = ctl->next)
{
- if (strcmp(host, ctl->servername) == 0
+ if (strcmp(host, ctl->servernames->id) == 0
&& strcmp(user, ctl->remotename) == 0)
{
save_uid(&ctl->oldsaved, -1, id);
@@ -104,15 +104,18 @@ void initialize_saved_lists(struct query *hostlist, const char *idfile)
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;
+ struct idlist **end;
- new = (struct idlist *)xmalloc(sizeof(struct idlist));
- new->val.num = num;
- new->id = xstrdup(str);
- new->next = *idl;
- *idl = new;
+ /* do it nonrecursively so the list is in the right order */
+ for (end = idl; *end; end = &(*end)->next)
+ continue;
+
+ *end = (struct idlist *)xmalloc(sizeof(struct idlist));
+ (*end)->val.num = num;
+ (*end)->id = xstrdup(str);
+ (*end)->next = NULL;
- return(new);
+ return(*end);
}
void free_uid_list(struct idlist **idl)
@@ -251,7 +254,7 @@ void write_saved_lists(struct query *hostlist, const char *idfile)
for (ctl = hostlist; ctl; ctl = ctl->next) {
for (idp = ctl->oldsaved; idp; idp = idp->next)
fprintf(tmpfp, "%s@%s %s\n",
- ctl->remotename, ctl->servername, idp->id);
+ ctl->remotename, ctl->servernames->id, idp->id);
}
for (idp = scratchlist; idp; idp = idp->next)
fputs(idp->id, tmpfp);