diff options
author | Eric S. Raymond <esr@thyrsus.com> | 1997-05-15 20:12:53 +0000 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 1997-05-15 20:12:53 +0000 |
commit | dea547a71036ae3445a5a612f6afd00b76ed721a (patch) | |
tree | 21526ebcd03d92a894cdb61b36d33ae56b8c5684 | |
parent | 3dd9a93bd23e0ad36e52ffd79efe2dcbdaf85272 (diff) | |
download | fetchmail-dea547a71036ae3445a5a612f6afd00b76ed721a.tar.gz fetchmail-dea547a71036ae3445a5a612f6afd00b76ed721a.tar.bz2 fetchmail-dea547a71036ae3445a5a612f6afd00b76ed721a.zip |
Add multiple-folder support.
svn path=/trunk/; revision=1012
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | driver.c | 323 | ||||
-rw-r--r-- | etrn.c | 2 | ||||
-rw-r--r-- | fetchmail.c | 15 | ||||
-rw-r--r-- | fetchmail.h | 2 | ||||
-rw-r--r-- | fetchmail.man | 26 | ||||
-rw-r--r-- | imap.c | 9 | ||||
-rw-r--r-- | options.c | 23 | ||||
-rw-r--r-- | pop2.c | 26 | ||||
-rw-r--r-- | pop3.c | 7 | ||||
-rw-r--r-- | rcfile_l.l | 11 | ||||
-rw-r--r-- | rcfile_y.y | 11 | ||||
-rw-r--r-- | sample.rcfile | 4 | ||||
-rw-r--r-- | uid.c | 4 |
14 files changed, 264 insertions, 203 deletions
@@ -18,6 +18,8 @@ every user entry in a multi-user poll declaration. re-code this so --limit is still operative with --fetchall on, but you can turn off the size limit with --limit 0. +* Use the libmd functions for md5 under Free BSD? (Low priority.) + Release Notes: ------------------------------------------------------------------------------ @@ -26,6 +28,8 @@ pl 3.9.5 (): * Add an error notification when an incoming message has embedded NULs. * Throw out >From lines in headers to prevent getting hosed by upstream sendmails with the 'E' option on. +* Enable forcecr to work on the \r\n header terminator line. +* Multiple-folder support for POP2 and IMAP. pl 3.9.4 (Wed May 14 12:27:22 EDT 1997): * Fixed a compilation glitch for systems like SunOS & others without atexit(3). @@ -1248,8 +1248,9 @@ const struct method *proto; /* protocol method table */ { char buf [POPBUFSIZE+1]; int *msgsizes, len, num, count, new, deletions = 0; - int sock, port; - + int sock, port, fetches; + struct idlist *idp; + /* execute pre-initialization command, if any */ if (ctl->preconnect && (ok = system(ctl->preconnect))) { @@ -1381,190 +1382,194 @@ const struct method *proto; /* protocol method table */ set_timeout(ctl->server.timeout); } - /* compute number of messages and number of new messages waiting */ - ok = (protocol->getrange)(sock, ctl, &count, &new); - if (ok != 0) - goto cleanUp; - set_timeout(ctl->server.timeout); + ctl->errcount = fetches = 0; - /* show user how many messages we downloaded */ - if (ctl->mailbox) - (void) sprintf(buf, "%s@%s:%s", - ctl->remotename, realname, ctl->mailbox); - else - (void) sprintf(buf, "%s@%s", ctl->remotename, realname); - if (outlevel > O_SILENT) - if (count == -1) /* only used for ETRN */ - error(0, 0, "Polling %s", buf); - else if (count == 0) - error(0, 0, "No mail at %s", buf); - else - { - if (new != -1 && (count - new) > 0) - error(0, 0, "%d message%s (%d seen) at %s.", - count, count > 1 ? "s" : "", count-new, buf); - else - error(0, 0, "%d message%s at %s.", - count, count > 1 ? "s" : "", buf); - } - - /* we may need to get sizes in order to check message limits */ - msgsizes = (int *)NULL; - if (!ctl->fetchall && proto->getsizes && ctl->limit) + /* now iterate over each folder selected */ + for (idp = ctl->mailboxes; idp; idp = idp->next) { - msgsizes = (int *)alloca(sizeof(int) * count); - - ok = (proto->getsizes)(sock, count, msgsizes); + if (outlevel >= O_VERBOSE) + if (idp->next) + error(0, 0, "selecting folder %s"); + else + error(0, 0, "selecting default folder"); + + /* compute number of messages and number of new messages waiting */ + ok = (protocol->getrange)(sock, ctl, idp->id, &count, &new); if (ok != 0) goto cleanUp; set_timeout(ctl->server.timeout); - } - if (check_only) - { - if (new == -1 || ctl->fetchall) - new = count; - ok = ((new > 0) ? PS_SUCCESS : PS_NOMAIL); - goto cleanUp; - } - else if (count > 0) - { - int force_retrieval, fetches; + /* show user how many messages we downloaded */ + if (idp->id) + (void) sprintf(buf, "%s@%s:%s", + ctl->remotename, realname, idp->id); + else + (void) sprintf(buf, "%s@%s", ctl->remotename, realname); + if (outlevel > O_SILENT) + if (count == -1) /* only used for ETRN */ + error(0, 0, "Polling %s", buf); + else if (count == 0) + error(0, 0, "No mail at %s", buf); + else + { + if (new != -1 && (count - new) > 0) + error(0, 0, "%d message%s (%d seen) at %s.", + count, count > 1 ? "s" : "", count-new, buf); + else + error(0, 0, "%d message%s at %s.", + count, count > 1 ? "s" : "", buf); + } - /* - * What forces this code is that in POP3 and IMAP2BIS you can't - * fetch a message without having it marked `seen'. In IMAP4, - * on the other hand, you can (peek_capable is set to convey - * this). - * - * The result of being unable to peek is that if there's - * any kind of transient error (DNS lookup failure, or - * sendmail refusing delivery due to process-table limits) - * the message will be marked "seen" on the server without - * having been delivered. This is not a big problem if - * fetchmail is running in foreground, because the user - * will see a "skipped" message when it next runs and get - * clued in. - * - * But in daemon mode this leads to the message being silently - * ignored forever. This is not acceptable. - * - * We compensate for this by checking the error count from the - * previous pass and forcing all messages to be considered new - * if it's nonzero. - */ - force_retrieval = !peek_capable && (ctl->errcount > 0); + /* we may need to get sizes in order to check message limits */ + msgsizes = (int *)NULL; + if (!ctl->fetchall && proto->getsizes && ctl->limit) + { + msgsizes = (int *)alloca(sizeof(int) * count); - ctl->errcount = fetches = 0; + ok = (proto->getsizes)(sock, count, msgsizes); + if (ok != 0) + goto cleanUp; + set_timeout(ctl->server.timeout); + } - /* read, forward, and delete messages */ - for (num = 1; num <= count; num++) + if (check_only) { - int toolarge = msgsizes && (msgsizes[num-1] > ctl->limit); - int fetch_it = ctl->fetchall || - (!toolarge && (force_retrieval || !(protocol->is_old && (protocol->is_old)(sock,ctl,num)))); - int suppress_delete = FALSE; + if (new == -1 || ctl->fetchall) + new = count; + ok = ((new > 0) ? PS_SUCCESS : PS_NOMAIL); + goto cleanUp; + } + else if (count > 0) + { + int force_retrieval; - /* we may want to reject this message if it's old */ - if (!fetch_it) - { - if (outlevel > O_SILENT) - { - error_build("skipping message %d", num); - if (toolarge) - error_build(" (oversized, %d bytes)", msgsizes[num-1]); - } - } - else + /* + * What forces this code is that in POP3 and IMAP2BIS you can't + * fetch a message without having it marked `seen'. In IMAP4, + * on the other hand, you can (peek_capable is set to convey + * this). + * + * The result of being unable to peek is that if there's + * any kind of transient error (DNS lookup failure, or + * sendmail refusing delivery due to process-table limits) + * the message will be marked "seen" on the server without + * having been delivered. This is not a big problem if + * fetchmail is running in foreground, because the user + * will see a "skipped" message when it next runs and get + * clued in. + * + * But in daemon mode this leads to the message being silently + * ignored forever. This is not acceptable. + * + * We compensate for this by checking the error count from the + * previous pass and forcing all messages to be considered new + * if it's nonzero. + */ + force_retrieval = !peek_capable && (ctl->errcount > 0); + + /* read, forward, and delete messages */ + for (num = 1; num <= count; num++) { - /* request a message */ - ok = (protocol->fetch)(sock, ctl, num, &len); - if (ok != 0) - goto cleanUp; - set_timeout(ctl->server.timeout); + int toolarge = msgsizes && (msgsizes[num-1] > ctl->limit); + int fetch_it = ctl->fetchall || + (!toolarge && (force_retrieval || !(protocol->is_old && (protocol->is_old)(sock,ctl,num)))); + int suppress_delete = FALSE; - if (outlevel > O_SILENT) + /* we may want to reject this message if it's old */ + if (!fetch_it) { - error_build("reading message %d", num); - if (len > 0) - error_build(" (%d bytes)", len); - if (outlevel == O_VERBOSE) - error_complete(0, 0, ""); - else - error_build(" "); + if (outlevel > O_SILENT) + { + error_build("skipping message %d", num); + if (toolarge) + error_build(" (oversized, %d bytes)", msgsizes[num-1]); + } } - - /* read the message and ship it to the output sink */ - ok = gen_readmsg(sock, - len, - protocol->delimited, - ctl, - realname); - if (ok == PS_TRANSIENT) - suppress_delete = TRUE; - else if (ok) - goto cleanUp; - set_timeout(ctl->server.timeout); - - /* tell the server we got it OK and resynchronize */ - if (protocol->trail) + else { - ok = (protocol->trail)(sock, ctl, num); + /* request a message */ + ok = (protocol->fetch)(sock, ctl, num, &len); if (ok != 0) goto cleanUp; set_timeout(ctl->server.timeout); + + if (outlevel > O_SILENT) + { + error_build("reading message %d", num); + if (len > 0) + error_build(" (%d bytes)", len); + if (outlevel == O_VERBOSE) + error_complete(0, 0, ""); + else + error_build(" "); + } + + /* read the message and ship it to the output sink */ + ok = gen_readmsg(sock, + len, + protocol->delimited, + ctl, + realname); + if (ok == PS_TRANSIENT) + suppress_delete = TRUE; + else if (ok) + goto cleanUp; + set_timeout(ctl->server.timeout); + + /* tell the server we got it OK and resynchronize */ + if (protocol->trail) + { + ok = (protocol->trail)(sock, ctl, num); + if (ok != 0) + goto cleanUp; + set_timeout(ctl->server.timeout); + } + + fetches++; } - fetches++; - } + /* + * At this point in flow of control, either we've bombed + * on a protocol error or had delivery refused by the SMTP + * server (unlikely -- I've never seen it) or we've seen + * `accepted for delivery' and the message is shipped. + * It's safe to mark the message seen and delete it on the + * server now. + */ - /* - * At this point in flow of control, either we've bombed - * on a protocol error or had delivery refused by the SMTP - * server (unlikely -- I've never seen it) or we've seen - * `accepted for delivery' and the message is shipped. - * It's safe to mark the message seen and delete it on the - * server now. - */ + /* maybe we delete this message now? */ + if (protocol->delete + && !suppress_delete + && (fetch_it ? !ctl->keep : ctl->flush)) + { + deletions++; + if (outlevel > O_SILENT) + error_complete(0, 0, " flushed"); + ok = (protocol->delete)(sock, ctl, num); + if (ok != 0) + goto cleanUp; + set_timeout(ctl->server.timeout); + delete_str(&ctl->newsaved, num); + } + else if (outlevel > O_SILENT) + error_complete(0, 0, " not flushed"); - /* maybe we delete this message now? */ - if (protocol->delete - && !suppress_delete - && (fetch_it ? !ctl->keep : ctl->flush)) - { - deletions++; - if (outlevel > O_SILENT) - error_complete(0, 0, " flushed"); - ok = (protocol->delete)(sock, ctl, num); - if (ok != 0) - goto cleanUp; - set_timeout(ctl->server.timeout); - delete_str(&ctl->newsaved, num); + /* perhaps this as many as we're ready to handle */ + if (ctl->fetchlimit && ctl->fetchlimit <= fetches) + goto no_error; } - else if (outlevel > O_SILENT) - error_complete(0, 0, " not flushed"); - - /* perhaps this as many as we're ready to handle */ - if (ctl->fetchlimit && ctl->fetchlimit <= fetches) - break; } - - ok = gen_transact(sock, protocol->exit_cmd); - if (ok == 0) - ok = (fetches > 0) ? PS_SUCCESS : PS_NOMAIL; - set_timeout(0); - close(sock); - goto closeUp; - } - else { - ok = gen_transact(sock, protocol->exit_cmd); - if (ok == 0) - ok = PS_NOMAIL; - set_timeout(0); - close(sock); - goto closeUp; } + no_error: + set_timeout(ctl->server.timeout); + ok = gen_transact(sock, protocol->exit_cmd); + if (ok == 0) + ok = (fetches > 0) ? PS_SUCCESS : PS_NOMAIL; + set_timeout(0); + close(sock); + goto closeUp; + cleanUp: set_timeout(ctl->server.timeout); if (ok != 0 && ok != PS_SOCKET) @@ -117,7 +117,7 @@ int doETRN (struct query *ctl) fprintf(stderr, "Option --flush is not supported with ETRN\n"); return(PS_SYNTAX); } - if (ctl->mailbox) { + if (ctl->mailboxes) { fprintf(stderr, "Option --remote is not supported with ETRN\n"); return(PS_SYNTAX); } diff --git a/fetchmail.c b/fetchmail.c index fbc16d9a..3bea5ab4 100644 --- a/fetchmail.c +++ b/fetchmail.c @@ -650,6 +650,10 @@ static int load_params(int argc, char **argv, int optind) if (ctl->server.envelope == (char *)NULL) ctl->server.envelope = "X-Envelope-To:"; + /* if no folders were specified, set up the null one as default */ + if (!ctl->mailboxes) + save_str(&ctl->mailboxes, -1, (char *)NULL); + /* sanity checks */ if (ctl->server.port < 0) { @@ -849,6 +853,17 @@ void dump_params (struct query *ctl) putchar('\n'); } + if (!ctl->mailboxes->id) + printf(" Default mailbox selected.\n"); + else + { + struct idlist *idp; + + printf(" Selected mailboxes are:"); + for (idp = ctl->mailboxes; idp; idp = idp->next) + printf(" %s", idp->id); + printf("\n"); + } printf(" %s messages will be retrieved (--all %s).\n", ctl->fetchall ? "All" : "Only new", ctl->fetchall ? "on" : "off"); diff --git a/fetchmail.h b/fetchmail.h index a50659e5..879112db 100644 --- a/fetchmail.h +++ b/fetchmail.h @@ -102,7 +102,7 @@ struct query int wildcard; /* should unmatched names be passed through */ char *remotename; char *password; - char *mailbox; + struct idlist *mailboxes; struct idlist *smtphunt; char *smtphost; char *mda; diff --git a/fetchmail.man b/fetchmail.man index e274a79c..6f27538e 100644 --- a/fetchmail.man +++ b/fetchmail.man @@ -164,18 +164,19 @@ The option permits you to specify a TCP/IP port to connect on. This option will seldom be necessary as all the supported protocols have well-established default port numbers. .TP -.B \-r folder, --remote folder -Causes a specified non-default mail folder on the mailserver to be retrieved. -The syntax of the folder name is server dependent, as is the default -behavior when no folder is specified. This option is not available -under POP3 or ETRN. +.B \-r folder, --folder folder +Causes a specified non-default mail folder on the mailserver (or +comma-separated list of folders) to be retrieved. The syntax of the +folder name is server-dependent. This option is not available under +POP3 or ETRN. .SS Delivery Control Options .TP .B \-S host, --smtphost host -Specify a hunt list of hosts to forward mail to. -In ETRN mode, set the host that the mailserver is asked to ship mail to. -Hosts are tried in list order; the first one that is up becomes the -forwarding or ETRN target for the current run. +Specify a hunt list of hosts to forward mail to (one or more +hostnames, comma-separated). In ETRN mode, set the host that the +mailserver is asked to ship mail to. Hosts are tried in list order; +the first one that is up becomes the forwarding or ETRN target for the +current run. .TP .B \-m, \--mda You can force mail to be passed to an MDA directly (rather than @@ -610,7 +611,7 @@ Legal user options are is to password (or pass) - remotefolder (or remote) + folder smtphost (or smtp) mda preconnect @@ -634,7 +635,10 @@ Legal user options are fetchlimit syslog .PP -All options correspond to the obvious command-line arguments except +The 'remotefolder' and 'smtphost' options can take a space- or +comma-separated list of names following them. +.PP +All options correspond to the obvious command-line arguments, except the following: `aka', `is', `to', `dns'/`no dns', `password', \&`preconnect', `localdomains', `stripcr'/`no stripcr' , \&`forcecr'/`no forcecr' and `no received'. @@ -117,16 +117,17 @@ int imap_getauth(int sock, struct query *ctl, char *buf) return(PS_SUCCESS); } -static int imap_getrange(int sock, struct query *ctl, int*countp, int*newp) +static int imap_getrange(int sock, + struct query *ctl, + const char *folder, + int *countp, int *newp) /* get range of messages to be fetched */ { int ok; /* find out how many messages are waiting */ recent = unseen = 0; - ok = gen_transact(sock, - "SELECT %s", - ctl->mailbox ? ctl->mailbox : "INBOX"); + ok = gen_transact(sock, "SELECT %s", folder ? folder : "INBOX"); if (ok != 0) { error(0, 0, "mailbox selection failed"); @@ -41,7 +41,7 @@ #define LA_FLUSH 23 #define LA_NOREWRITE 24 #define LA_LIMIT 25 -#define LA_REMOTEFILE 26 +#define LA_FOLDER 26 #define LA_SMTPHOST 27 #define LA_BATCHLIMIT 28 #define LA_FETCHLIMIT 29 @@ -83,7 +83,7 @@ static struct option longoptions[] = { {"norewrite", no_argument, (int *) 0, LA_NOREWRITE }, {"limit", required_argument, (int *) 0, LA_LIMIT }, - {"remote", required_argument, (int *) 0, LA_REMOTEFILE }, + {"folder", required_argument, (int *) 0, LA_FOLDER }, {"smtphost", required_argument, (int *) 0, LA_SMTPHOST }, {"batchlimit",required_argument, (int *) 0, LA_BATCHLIMIT }, {"fetchlimit",required_argument, (int *) 0, LA_FETCHLIMIT }, @@ -117,6 +117,7 @@ struct query *ctl; /* option record to be initialized */ int ocount = 0; /* count of destinations specified */ int errflag = 0; /* TRUE when a syntax error is detected */ int option_index; + char buf[BUFSIZ], *cp; cmd_daemon = -1; @@ -254,12 +255,22 @@ struct query *ctl; /* option record to be initialized */ ctl->limit = atoi(optarg); break; case 'r': - case LA_REMOTEFILE: - ctl->mailbox = xstrdup(optarg); + case LA_FOLDER: + strcpy(buf, optarg); + cp = strtok(buf, ","); + do { + save_str(&ctl->mailboxes, -1, optarg); + } while + ((cp = strtok((char *)NULL, ","))); break; case 'S': case LA_SMTPHOST: - save_str(&ctl->smtphunt, -1, optarg); + strcpy(buf, optarg); + cp = strtok(buf, ","); + do { + save_str(&ctl->smtphunt, -1, optarg); + } while + ((cp = strtok((char *)NULL, ","))); ocount++; break; case 'b': @@ -343,7 +354,7 @@ struct query *ctl; /* option record to be initialized */ fputs(" -S, --smtphost set SMTP forwarding host\n", stderr); fputs(" -b, --batchlimit set batch limit for SMTP connections\n", stderr); fputs(" -B, --fetchlimit set fetch limit for server connections\n", stderr); - fputs(" -r, --remote specify remote folder name\n", stderr); + fputs(" -r, --folder specify remote folder name\n", stderr); return(-1); } @@ -58,26 +58,32 @@ int pop2_getauth(int sock, struct query *ctl, char *buf) ctl->remotename, ctl->password)); } -static int pop2_getrange(int sock, struct query *ctl, int*countp, int*newp) +static int pop2_getrange(int sock, struct query *ctl, const char *folder, int*countp, int*newp) /* get range of messages to be fetched */ { - /* - * We should have picked up a count of messages in the user's - * default inbox from the pop2_getauth() response. - */ - if (pound_arg == -1) - return(PS_ERROR); - /* maybe the user wanted a non-default folder */ - if (ctl->mailbox) + if (folder) { - int ok = gen_transact(sock, "FOLD %s", ctl->mailbox); + int ok = gen_transact(sock, "FOLD %s", folder); if (ok != 0) return(ok); if (pound_arg == -1) return(PS_ERROR); } + else + /* + * We should have picked up a count of messages in the user's + * default inbox from the pop2_getauth() response. + * + * Note: this logic only works because there is no way to select + * both the unnamed folder and named folders within a single + * fetchmail run. If that assumption ever becomes invalid, the + * pop2_getauth code will have to stash the pound response away + * explicitly in case it gets stepped on. + */ + if (pound_arg == -1) + return(PS_ERROR); *countp = pound_arg; *newp = -1; @@ -125,7 +125,10 @@ int pop3_getauth(int sock, struct query *ctl, char *greeting) return(0); } -static int pop3_getrange(int sock, struct query *ctl, int*countp, int*newp) +static int pop3_getrange(int sock, + struct query *ctl, + const char *folder, + int *countp, int *newp) /* get range of messages to be fetched */ { int ok; @@ -279,7 +282,7 @@ const static struct method pop3 = int doPOP3 (struct query *ctl) /* retrieve messages using POP3 */ { - if (ctl->mailbox) { + if (ctl->mailboxes->id) { fprintf(stderr,"Option --remote is not supported with POP3\n"); return(PS_SYNTAX); } @@ -41,7 +41,7 @@ envelope { return ENVELOPE; } user(name)? { return USERNAME; } pass(word)? { return PASSWORD; } -remote(folder)? { return FOLDER; } +folder(s) { return FOLDER; } smtp(host)? { return SMTPHOST; } mda { return MDA; } pre(connect) { return PRECONNECT; } @@ -55,7 +55,7 @@ to { return TO; } = { return MAP; } "*" { return WILDCARD; } -no/[kfrsdu ] { return NO;} +no/[kfrsdu ].* { return NO;} keep { return KEEP; } flush { return FLUSH; } @@ -83,6 +83,11 @@ options {/* EMPTY */} (etrn)|(ETRN) { yylval.proto = P_ETRN; return PROTO; } (kpop)|(KPOP) { return KPOP; } +remote(folder)? { + fprintf(stderr, + "fetchmail: `remote' keyword is gone, use `folder'\n"); + } + (#.*)?\\?\n { prc_lineno++; } /* newline is ignored */ @@ -106,3 +111,5 @@ options {/* EMPTY */} [ \t\r]+ ; /* whitespace */ + + @@ -193,6 +193,10 @@ mapping : STRING {save_str_pair(¤t.localnames, $1, $3);} ; +folder_list : STRING {save_str(¤t.mailboxes,-1,$1);} + | folder_list STRING {save_str(¤t.mailboxes,-1,$2);} + ; + smtphunt : STRING {save_str(¤t.smtphunt, -1, $1);} | smtphunt STRING {save_str(¤t.smtphunt, -1, $2);} ; @@ -204,7 +208,7 @@ user_option : TO localnames HERE | IS STRING THERE {current.remotename = xstrdup($2);} | PASSWORD STRING {current.password = xstrdup($2);} - | FOLDER STRING {current.mailbox = xstrdup($2);} + | FOLDER folder_list | SMTPHOST smtphunt | MDA STRING {current.mda = xstrdup($2);} | PRECONNECT STRING {current.preconnect = xstrdup($2);} @@ -397,7 +401,8 @@ static void record_current(void) FLAG_FORCE(remotename); FLAG_FORCE(password); - FLAG_FORCE(mailbox); + if (cmd_opts.mailboxes) + save_str(¤t.mailboxes, -1, cmd_opts.mailboxes->id); if (cmd_opts.smtphunt) save_str(¤t.smtphunt, -1, cmd_opts.smtphunt->id); FLAG_FORCE(mda); @@ -423,6 +428,7 @@ void optmerge(struct query *h2, struct query *h1) { append_str_list(&h2->server.localdomains, &h1->server.localdomains); append_str_list(&h2->localnames, &h1->localnames); + append_str_list(&h2->mailboxes, &h1->mailboxes); append_str_list(&h2->smtphunt, &h1->smtphunt); #define FLAG_MERGE(fld) if (!h2->fld) h2->fld = h1->fld @@ -442,7 +448,6 @@ void optmerge(struct query *h2, struct query *h1) FLAG_MERGE(remotename); FLAG_MERGE(password); - FLAG_MERGE(mailbox); FLAG_MERGE(mda); FLAG_MERGE(preconnect); diff --git a/sample.rcfile b/sample.rcfile index 209242f6..e0edc8d7 100644 --- a/sample.rcfile +++ b/sample.rcfile @@ -34,9 +34,9 @@ # # username (or user) -- must be followed by a name # is -- must be followed by one or more names -# remotefolder (or remote) -- must be followed by a filename +# folder -- must be followed by remote folder names # password (or pass) -- must be followed by a password string -# smtphost (or smtp) -- must be followed by a host name +# smtphost (or smtp) -- must be followed by host names # mda -- must be followed by an MDA command string # preconnect (or pre) -- must be followed by an initialization command # @@ -112,7 +112,7 @@ struct idlist *save_str(struct idlist **idl, int num, const char *str) *end = (struct idlist *)xmalloc(sizeof(struct idlist)); (*end)->val.num = num; - (*end)->id = xstrdup(str); + (*end)->id = str ? xstrdup(str) : (char *)NULL; (*end)->next = NULL; return(*end); @@ -140,7 +140,7 @@ void save_str_pair(struct idlist **idl, const char *str1, const char *str2) continue; *end = (struct idlist *)xmalloc(sizeof(struct idlist)); - (*end)->id = xstrdup(str1); + (*end)->id = str1 ? xstrdup(str1) : (char *)NULL; if (str2) (*end)->val.id2 = xstrdup(str2); else |