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);  | 
