diff options
-rw-r--r-- | NEWS | 26 | ||||
-rw-r--r-- | fetchmail.c | 24 | ||||
-rw-r--r-- | fetchmail.man | 7 | ||||
-rw-r--r-- | options.c | 63 |
4 files changed, 92 insertions, 28 deletions
@@ -10,6 +10,24 @@ fetchmail-4.4.8 (): * Removed fetchall side-effect kluge, now that we knowe how to make TOP work with qpopper 2.3+. +* Several fixes for command-line processing from Gunther Leber: + - in fetchmail.c + * set tmpbuf to NULL after freeing the buffer (so this will hopefully + cause a coredump, when tmpbuf is used somewhere else) + * when makeing sure we have a nonempty host list to forward to, I + added "localhost" for non ETRN protocols. This should relieve the + situation for people, who do neither have a static ip-address + (hostname) assigned and neither bother to set up a dummy-interface + for their hostname. I think this feature was already in fetchmail + in an older version. We lost this, when we changed the code that it + would work with ETRN. My fix here works for both ETRN and non ETRN. + - fixed reversed dumping of mimedecode option + - in options.c + * changed char buf[...] to *buf + xmalloc to avoid buffer overuns and + possible resulting (and annoying) coredumps + * in parsecmdline(): replaced atoi by xatoi which uses strtol and + better validity checks for input numbers. This fix only works on + ANSI-C systems; old systems still use atoi. fetchmail-4.4.7 (Sat May 23 08:26:58 EDT 1998): * FEATURE FREEZE IS NOW IN EFFECT! No new features until after 4.5.0. @@ -116,29 +134,21 @@ There are 269 people on fetchmail-friends and 144 on fetchmail-announce. fetchmail-4.3.7 (Tue Feb 17 21:30:26 EST 1998) * Fixed a minor bug in the IMAP re-polling logic. * Nicholas Pitre's extensive changes to multidrop: - - Seek for the true sender of a mail which is not necessarily in the From: header. (see comments in the code for more explicit details). This one is particularly important with list distributions... - - Respect the Resent-To/-Cc/-Bcc precedence over the To/Cc/Bcc headers for recipient delivery. So avoid resending a message to a person who just resent a mail to some other addresses. - - Fix a bug in find_server_names() wich caused recipient addresses to figure twice in the recipient address list. - - Modified parse_received() to let full adress from the Received header to pass through so local domains can be used (now has same policy as in the find_server_names() function). - - Fixed memory leaks from readheaders(). - - Made some strcmp() be strcasecmp() as it should be because it didn't work correctly in some cases. - - Modified reply_hack() to meet the needs of above modifications. - Thomas says these changes have been tested for two weeks in a production multidrop environment. I tested them for another week in mine. * Doug Muth's runfetchmail version 1.1. diff --git a/fetchmail.c b/fetchmail.c index ddfdb309..5e3e28ac 100644 --- a/fetchmail.c +++ b/fetchmail.c @@ -373,6 +373,7 @@ int main (int argc, char **argv) /* we don't need tmpbuf anymore */ free(tmpbuf); + tmpbuf = NULL; /* firewall code */ /* * Maybe time to go to demon mode... @@ -755,7 +756,15 @@ static int load_params(int argc, char **argv, int optind) /* make sure we have a nonempty host list to forward to */ if (!ctl->smtphunt) + { save_str(&ctl->smtphunt, fetchmailhost, FALSE); + /* for non ETRN try to deliver mails to localhost if + * fetchmailhost fails + */ + if (ctl->server.protocol != P_ETRN) { + save_str(&ctl->smtphunt, "localhost", FALSE); + } + } /* keep lusers from shooting themselves in the foot :-) */ if (run.poll_interval && ctl->limit) @@ -1131,10 +1140,10 @@ void dump_params (struct runctl *runp, struct query *querylist, flag implicit) ctl->forcecr ? "en" : "dis", ctl->forcecr ? "on" : "off"); printf(" Interpretation of Content-Transfer-Encoding is %sabled (pass8bits %s).\n", - ctl->pass8bits ? "dis" : "en", + ctl->pass8bits ? "en" : "dis", ctl->pass8bits ? "on" : "off"); printf(" MIME decoding is %sabled (mimedecode %s).\n", - ctl->mimedecode ? "dis" : "en", + ctl->mimedecode ? "en" : "dis", ctl->mimedecode ? "on" : "off"); printf(" Nonempty Status lines will be %s (dropstatus %s)\n", ctl->dropstatus ? "discarded" : "kept", @@ -1166,12 +1175,11 @@ void dump_params (struct runctl *runp, struct query *querylist, flag implicit) printf(" Messages will be SMTP-forwarded to:"); for (idp = ctl->smtphunt; idp; idp = idp->next) - if (ctl->server.protocol != P_ETRN || idp->val.status.mark) - { - printf(" %s", idp->id); - if (!idp->val.status.mark) - printf(" (default)"); - } + { + printf(" %s", idp->id); + if (!idp->val.status.mark) + printf(" (default)"); + } printf("\n"); if (ctl->smtpaddress) printf(" Host part of MAIL FROM line will be %s\n", diff --git a/fetchmail.man b/fetchmail.man index 7c10341c..383ecc89 100644 --- a/fetchmail.man +++ b/fetchmail.man @@ -207,9 +207,10 @@ 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. Each hostname may have a '/'-delimited suffix specifying -a port or service to forward to; the default is 25 (or "smtp" under -IPv6). +current run. In all modes except ETRN, `localhost' is added to the +end of the list as an invisible default. Each hostname may have a +'/'-delimited suffix specifying a port or service to forward to; the +default is 25 (or "smtp" under IPv6). .TP .B \-D domain, --smtpaddress domain (Keyword: smtpaddress) @@ -9,8 +9,10 @@ #include <stdio.h> #include <pwd.h> #include <string.h> +#include <errno.h> #if defined(STDC_HEADERS) #include <stdlib.h> +#include <limits.h> #endif #include "getopt.h" @@ -122,6 +124,45 @@ static const struct option longoptions[] = { {(char *) 0, no_argument, (int *) 0, 0 } }; +static int xatoi(char *s, int *errflagptr) +/* do safe conversion from string to number */ +{ +#if defined (__STDC__) + /* parse and convert numbers, but also check for invalid characters in + * numbers + */ + + char *endptr; + long value; + + errno = 0; + + value = strtol(s, &endptr, 0); + + /* any invalid chars in string? */ + if ( (endptr == s) || (*endptr != '\0') ) { + (void) fprintf(stderr, "String '%s' is not a valid number string.\n", s); + (*errflagptr)++; + return 0; + } + + /* is the range valid? */ + if ( (((value == LONG_MAX) || (value == LONG_MIN)) && (errno == ERANGE)) || + (value > INT_MAX) || (value < INT_MIN)) { + + (void) fprintf(stderr, "Value of string '%s' is %s than %d.\n", s, + (value < 0) ? "smaller": "larger", + (value < 0) ? INT_MIN : INT_MAX); + (*errflagptr)++; + return 0; + } + + return (int) value; /* shut up, I know what I'm doing */ +#else + return atoi(s); +#endif +} + int parsecmdline (argc, argv, rctl, ctl) /* parse and validate the command line options */ int argc; /* argument count */ @@ -141,7 +182,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; + char *buf, *cp; rctl->poll_interval = -1; @@ -171,7 +212,7 @@ struct query *ctl; /* option record to be initialized */ break; case 'd': case LA_DAEMON: - rctl->poll_interval = atoi(optarg); + rctl->poll_interval = xatoi(optarg, &errflag); break; case 'N': case LA_NODETACH: @@ -245,7 +286,7 @@ struct query *ctl; /* option record to be initialized */ #if INET6 ctl->server.service = optarg; #else /* INET6 */ - ctl->server.port = atoi(optarg); + ctl->server.port = xatoi(optarg, &errflag); #endif /* INET6 */ break; case 'A': @@ -269,7 +310,7 @@ struct query *ctl; /* option record to be initialized */ break; case 't': case LA_TIMEOUT: - ctl->server.timeout = atoi(optarg); + ctl->server.timeout = xatoi(optarg, &errflag); if (ctl->server.timeout == 0) ctl->server.timeout = -1; break; @@ -308,20 +349,23 @@ struct query *ctl; /* option record to be initialized */ break; case 'l': case LA_LIMIT: - c = atoi(optarg); + c = xatoi(optarg, &errflag); ctl->limit = NUM_VALUE(c); break; case 'r': case LA_FOLDER: + buf = xmalloc(strlen(optarg)); strcpy(buf, optarg); cp = strtok(buf, ","); do { save_str(&ctl->mailboxes, cp, 0); } while ((cp = strtok((char *)NULL, ","))); + free(buf); break; case 'S': case LA_SMTPHOST: + buf = xmalloc(strlen(optarg)); strcpy(buf, optarg); cp = strtok(buf, ","); do { @@ -329,6 +373,7 @@ struct query *ctl; /* option record to be initialized */ } while ((cp = strtok((char *)NULL, ","))); ocount++; + free(buf); break; case 'D': case LA_SMTPADDR: @@ -336,21 +381,21 @@ struct query *ctl; /* option record to be initialized */ break; case 'Z': case LA_ANTISPAM: - c = atoi(optarg); + c = xatoi(optarg, &errflag); ctl->antispam = NUM_VALUE(c); case 'b': case LA_BATCHLIMIT: - c = atoi(optarg); + c = xatoi(optarg, &errflag); ctl->batchlimit = NUM_VALUE(c); break; case 'B': case LA_FETCHLIMIT: - c = atoi(optarg); + c = xatoi(optarg, &errflag); ctl->fetchlimit = NUM_VALUE(c); break; case 'e': case LA_EXPUNGE: - c = atoi(optarg); + c = xatoi(optarg, &errflag); ctl->expunge = NUM_VALUE(c); break; case 'm': |