]> Pileus Git - ~andy/fetchmail/commitdiff
Gunter's command-line fixes.
authorEric S. Raymond <esr@thyrsus.com>
Mon, 25 May 1998 14:48:26 +0000 (14:48 -0000)
committerEric S. Raymond <esr@thyrsus.com>
Mon, 25 May 1998 14:48:26 +0000 (14:48 -0000)
svn path=/trunk/; revision=1823

NEWS
fetchmail.c
fetchmail.man
options.c

diff --git a/NEWS b/NEWS
index c8225328e553da895958e19415c0e951b07269f8..5bbe62b4a97c8f3c36f8fd03d560c592c4aedde8 100644 (file)
--- a/NEWS
+++ b/NEWS
 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.
index ddfdb3093decf4a5e62b5b768be9d21b7878ce59..5e3e28acb172fce6f36066a955b00fe2d22d96c2 100644 (file)
@@ -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",
index 7c10341c0f6cb996bbae212f459450190538a5fd..383ecc89489efd49e5f3c3d58411d7f2ae38cc41 100644 (file)
@@ -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) 
index 3a7465c96e5e653db63cacd1c2d6a0cd9a151505..92d24b2460c38bd7ceef7a2c60e1164c49b7b901 100644 (file)
--- a/options.c
+++ b/options.c
@@ -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':