diff options
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | driver.c | 41 | ||||
-rw-r--r-- | fetchmail.c | 26 | ||||
-rw-r--r-- | fetchmail.h | 3 | ||||
-rw-r--r-- | rcfile_y.y | 27 | ||||
-rw-r--r-- | uid.c | 21 |
6 files changed, 61 insertions, 62 deletions
@@ -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 -- @@ -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 @@ -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(¤t.servernames, -1, $2); + current.skip = FALSE;} + | SKIP STRING {current.servernames = (struct idlist *)NULL; + save_uid(¤t.servernames, -1, $2); + current.skip = TRUE;} + | DEFAULTS {current.servernames = (struct idlist *)NULL; + save_uid(¤t.servernames, -1,"defaults");} ; serverspecs : /* EMPTY */ | serverspecs serv_option ; -alias_list : STRING {save_uid(¤t.aka, -1, $1);} - | alias_list STRING {save_uid(¤t.aka, -1, $2);} +alias_list : STRING {save_uid(¤t.servernames, -1, $1);} + | alias_list STRING {save_uid(¤t.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(¤t, '\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); @@ -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); |