From 68c3f1308db0fd8a62855d812fbd34c0a80fb35d Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 5 Oct 1996 17:41:37 +0000 Subject: Multiple queries to same server with different users work now. svn path=/trunk/; revision=228 --- NEWS | 4 +++ fetchmail.c | 109 ++++++++++++++++++++++++++++++++++++++++++++---------------- fetchmail.h | 13 +++++--- options.c | 25 -------------- 4 files changed, 93 insertions(+), 58 deletions(-) diff --git a/NEWS b/NEWS index ab7a8643..b7fe8307 100644 --- a/NEWS +++ b/NEWS @@ -33,6 +33,10 @@ fetchmail-1.6 (): * Allow program to generate correct lockfiles under zsh. +* You can now have multiple entries for the same server but different + users, and the right thing will happen (each user's mailbox will + be queried). + fetchmail-1.5 (Thu Oct 3 04:35:15 EDT 1996): * Naturally, my decision to announce 1.4 on comp.os.linux.announce diff --git a/fetchmail.c b/fetchmail.c index c91b10a0..42389932 100644 --- a/fetchmail.c +++ b/fetchmail.c @@ -74,16 +74,16 @@ int versioninfo; /* emit only version info */ static void termhook(); static char *lockfile; static int popstatus; -static struct hostrec *hostp, *hostlist = (struct hostrec *)NULL; +static struct hostrec *hostp; main (argc,argv) int argc; char **argv; { - int mboxfd, st, sargc; - struct hostrec cmd_opts, def_opts; + int mboxfd, st; + struct hostrec def_opts; int parsestatus, implicitmode; - char *servername, *user, *home, *tmpdir, tmpbuf[BUFSIZ], *sargv[64]; + char *servername, *user, *home, *tmpdir, tmpbuf[BUFSIZ]; FILE *tmpfp; pid_t pid; @@ -121,40 +121,91 @@ char **argv; outlevel = O_NORMAL; - if (argc > sizeof(sargv)) - exit(PS_SYNTAX); - for (sargc = 0; sargc < argc; sargc++) - sargv[sargc] = argv[sargc]; - - if ((parsestatus = parsecmdline(sargc,sargv,&cmd_opts)) < 0) + if ((parsestatus = parsecmdline(argc,argv,&cmd_opts)) < 0) exit(PS_SYNTAX); if (versioninfo) showversioninfo(); + /* this builds the host list */ if (prc_parse_file(rcfile) != 0) exit(PS_SYNTAX); - if (implicitmode = (optind >= sargc)) - append_server_names(&sargc, sargv, sizeof(sargv)); - - /* build in-core data list on all hosts */ - while ((servername = getnextserver(sargc,sargv,&parsestatus)) != (char *)0) + if (implicitmode = (optind >= argc)) { - if (strcmp(servername, "defaults") == 0) - continue; - - hostp = (struct hostrec *)xmalloc(sizeof(struct hostrec)); - - prc_mergeoptions(servername, &cmd_opts, &def_opts, hostp); - strcpy(hostp->servername, servername); + for (hostp = hostlist; hostp; hostp = hostp->next) + hostp->active = 1; + } + else + for (; optind < argc; optind++) + { + int found; + + /* + * If hostname corresponds to a host known from the rc file, + * simply declare it active. Otherwise synthesize a host + * record from command line and defaults + */ + found = FALSE; + for (hostp = hostlist; hostp; hostp = hostp->next) + if (strcmp(hostp->servername, argv[optind]) == 0) + { + found = TRUE; + break; + } + + if (found) + hostp->active = TRUE; + else + { + hostp = (struct hostrec *)xmalloc(sizeof(struct hostrec)); + + memcpy(hostp, &cmd_opts, sizeof(struct hostrec)); + strcpy(hostp->servername, argv[optind]); + hostp->active = TRUE; + + /* append to end of list */ + if (hosttail != (struct hostrec *) 0) + hosttail->next = hostp; + else + hostlist = hostp; + hosttail = hostp; + } + } - hostp->next = hostlist; - hostlist = hostp; + /* merge in defaults for empty fields, then lose defaults record */ + if (strcmp(hostlist->servername, "defaults") == 0) + { + optmerge(hostlist, &def_opts); + for (hostp = hostlist; hostp; hostp = hostp->next) + optmerge(hostp, hostlist); + hostlist = hostlist->next; } - /* expand MDA commands */ + /* do sanity checks and prepare internal fields */ for (hostp = hostlist; hostp; hostp = hostp->next) + { + /* if rc file didn't supply a localname, default appropriately */ + if (!hostp->localname[0]) + strcpy(hostp->localname, hostp->remotename); + + /* sanity checks */ + if (hostp->port < 0) + { + (void) fprintf(stderr, + "%s configuration invalid, port number cannot be negative", + hostp->servername); + exit(PS_SYNTAX); + } + if (hostp->protocol == P_RPOP && hostp->port >= 1024) + { + (void) fprintf(stderr, + "%s configuration invalid, can't do RPOP to an unprivileged port\n", + hostp->servername); + exit(PS_SYNTAX); + } + + /* expand MDA commands */ if (hostp->mda[0]) { int argi; @@ -179,6 +230,7 @@ char **argv; if ((argp = strrchr(hostp->mda_argv[1], '/')) != (char *)NULL) hostp->mda_argv[1] = argp + 1 ; } + } /* set up to do lock protocol */ if ((tmpdir = getenv("TMPDIR")) == (char *)NULL) @@ -199,7 +251,8 @@ char **argv; if (outlevel == O_VERBOSE) printf("Lockfile at %s\n", tmpbuf); for (hostp = hostlist; hostp; hostp = hostp->next) { - dump_params(hostp); + if (hostp->active && !(implicitmode && hostp->skip)) + dump_params(hostp); } if (hostlist == NULL) (void) fprintf(stderr, @@ -254,7 +307,7 @@ char **argv; /* pick up interactively any passwords we need but don't have */ for (hostp = hostlist; hostp; hostp = hostp->next) - if (!(implicitmode && hostp->skip) && !hostp->password[0]) + if (hostp->active && !(implicitmode && hostp->skip) && !hostp->password[0]) { (void) sprintf(tmpbuf, "Enter password for %s@%s: ", hostp->remotename, hostp->servername); @@ -287,7 +340,7 @@ char **argv; */ do { for (hostp = hostlist; hostp; hostp = hostp->next) { - if (!implicitmode || !hostp->skip) + if (hostp->active && !(implicitmode && hostp->skip)) popstatus = query_host(hostp); } diff --git a/fetchmail.h b/fetchmail.h index 9c7f0e9f..caa6fee2 100644 --- a/fetchmail.h +++ b/fetchmail.h @@ -75,6 +75,7 @@ struct hostrec int skip; /* internal use */ + int active; struct hostrec *next; /* next host in chain */ char digest [DIGESTLEN]; }; @@ -99,6 +100,9 @@ struct method #define TAGLEN 6 extern char tag[TAGLEN]; +/* list of hosts assembled from run control file and command line */ +extern struct hostrec cmd_opts, *hostlist, *hosttail; + /* controls the detail level of status/progress messages written to stderr */ extern int outlevel; /* see the O_.* constants above */ extern int yydebug; /* enable parse debugging */ @@ -124,18 +128,17 @@ int doPOP3 (struct hostrec *); int doIMAP (struct hostrec *); int parsecmdline (int, char **, struct hostrec *); -char *getnextserver (int argc, char **, int *); +void optmerge(struct hostrec *, struct hostrec *); char *MD5Digest (char *); int openmailpipe (struct hostrec *); -void append_server_names(int *, char **, int); int daemonize(const char *, void (*)(int)); #else -char *getnextserver(); char *MD5Digest (); -void append_server_names (); -int daemonize (); +void optmerge(); #endif +#define FALSE 0 +#define TRUE 1 diff --git a/options.c b/options.c index 6649142c..0704a359 100644 --- a/options.c +++ b/options.c @@ -239,28 +239,3 @@ struct hostrec *queryctl; return(optind); } -/****************************************************************** - function: getnextserver - description: read next server name from the command line. - arguments: - argc from main() - argv from main() - optind as returned by parsecmdline and this function. - - ret. value: next server name from command line or NULL if all - server names have been retrieved. - globals: none. - calls: none. - *****************************************************************/ -char *getnextserver (argc,argv,optind) -int argc; -char **argv; -int *optind; -{ - if (*optind >= argc) { - /* no more servers */ - return((char *) 0); - } - else - return(argv[(*optind)++]); -} -- cgit v1.2.3