]> Pileus Git - ~andy/fetchmail/blobdiff - options.c
Minor bug fixes for socket.c
[~andy/fetchmail] / options.c
index 8a674a67f9aa9784a26a85821c3a872085f12749..d53044fc72c4215ee3e975092acde6fb7819a142 100644 (file)
--- a/options.c
+++ b/options.c
 
 enum {
     LA_INVISIBLE = 256,
-                LA_SYSLOG,
-                LA_NOSYSLOG,
-                LA_POSTMASTER,
-                LA_NOBOUNCE,
-                LA_AUTH,
-                LA_FETCHDOMAINS,
-                LA_BSMTP,
-                LA_LMTP,
-                LA_PLUGIN,
-                LA_PLUGOUT,
-                LA_CONFIGDUMP,
-                LA_SMTPNAME,
-                LA_SHOWDOTS,
-                LA_PRINCIPAL,
-                LA_TRACEPOLLS,
-                LA_SSL,
-                LA_SSLKEY,
-                LA_SSLCERT,
-                LA_SSLPROTO,
-                LA_SSLCERTCK,
-                LA_SSLCERTPATH,
-                LA_SSLFINGERPRINT,
-                LA_FETCHSIZELIMIT,
-                LA_FASTUIDL,
-                LA_LIMITFLUSH,
+    LA_PIDFILE,
+    LA_SYSLOG,
+    LA_NOSYSLOG,
+    LA_POSTMASTER,
+    LA_NOBOUNCE,
+    LA_AUTH,
+    LA_FETCHDOMAINS,
+    LA_BSMTP,
+    LA_LMTP,
+    LA_PLUGIN,
+    LA_PLUGOUT,
+    LA_CONFIGDUMP,
+    LA_SMTPNAME,
+    LA_SHOWDOTS,
+    LA_PRINCIPAL,
+    LA_TRACEPOLLS,
+    LA_SSL,
+    LA_SSLKEY,
+    LA_SSLCERT,
+    LA_SSLPROTO,
+    LA_SSLCERTCK,
+    LA_SSLCERTFILE,
+    LA_SSLCERTPATH,
+    LA_SSLCOMMONNAME,
+    LA_SSLFINGERPRINT,
+    LA_FETCHSIZELIMIT,
+    LA_FASTUIDL,
+    LA_LIMITFLUSH,
+    LA_IDLE,
+    LA_NOSOFTBOUNCE,
+    LA_SOFTBOUNCE,
+    LA_BADHEADER
 };
 
 /* options still left: CgGhHjJoORTWxXYz */
@@ -72,23 +79,29 @@ static const struct option longoptions[] = {
   {"nosyslog", no_argument,       (int *) 0, LA_NOSYSLOG },
   {"fetchmailrc",required_argument,(int *) 0, 'f' },
   {"idfile",   required_argument, (int *) 0, 'i' },
+  {"pidfile",  required_argument, (int *) 0, LA_PIDFILE },
   {"postmaster",required_argument, (int *) 0, LA_POSTMASTER },
   {"nobounce", no_argument,       (int *) 0, LA_NOBOUNCE },
+  {"nosoftbounce", no_argument,           (int *) 0, LA_NOSOFTBOUNCE },
+  {"softbounce", no_argument,     (int *) 0, LA_SOFTBOUNCE },
 
   {"protocol", required_argument, (int *) 0, 'p' },
   {"proto",    required_argument, (int *) 0, 'p' },
   {"uidl",     no_argument,       (int *) 0, 'U' },
+  {"idle",     no_argument,       (int *) 0, LA_IDLE},
   {"port",     required_argument, (int *) 0, 'P' },
   {"service",  required_argument, (int *) 0, 'P' },
   {"auth",     required_argument, (int *) 0, LA_AUTH},
   {"timeout",  required_argument, (int *) 0, 't' },
   {"envelope", required_argument, (int *) 0, 'E' },
   {"qvirtual", required_argument, (int *) 0, 'Q' },
+  {"bad-header",required_argument, (int *) 0, LA_BADHEADER},
 
   {"user",     required_argument, (int *) 0, 'u' },
   {"username", required_argument, (int *) 0, 'u' },
 
   {"all",      no_argument,       (int *) 0, 'a' },
+  {"fetchall", no_argument,       (int *) 0, 'a' },
   {"nokeep",   no_argument,       (int *) 0, 'K' },
   {"keep",     no_argument,       (int *) 0, 'k' },
   {"flush",    no_argument,       (int *) 0, 'F' },
@@ -119,7 +132,9 @@ static const struct option longoptions[] = {
   {"sslcert",  required_argument, (int *) 0, LA_SSLCERT },
   {"sslproto",  required_argument, (int *) 0, LA_SSLPROTO },
   {"sslcertck", no_argument,      (int *) 0, LA_SSLCERTCK },
+  {"sslcertfile",   required_argument, (int *) 0, LA_SSLCERTFILE },
   {"sslcertpath",   required_argument, (int *) 0, LA_SSLCERTPATH },
+  {"sslcommonname",    required_argument, (int *) 0, LA_SSLCOMMONNAME },
   {"sslfingerprint",   required_argument, (int *) 0, LA_SSLFINGERPRINT },
 #endif
 
@@ -212,12 +227,11 @@ static int xatoi(char *s, int *errflagptr)
 #endif
 }
 
-int parsecmdline (argc, argv, rctl, ctl)
-/* parse and validate the command line options */
-int argc;              /* argument count */
-char **argv;           /* argument strings */
-struct runctl *rctl;   /* global run controls to modify */
-struct query *ctl;     /* option record to be initialized */
+/** parse and validate the command line options */
+int parsecmdline (int argc /** argument count */,
+                 char **argv /** argument strings */,
+                 struct runctl *rctl /** global run controls to modify */,
+                 struct query *ctl /** option record to initialize */)
 {
     /*
      * return value: if positive, argv index of last parsed option + 1
@@ -254,7 +268,7 @@ struct query *ctl;  /* option record to be initialized */
            outlevel = O_SILENT;
            break;
        case 'v':
-           if (outlevel == O_VERBOSE)
+           if (outlevel >= O_VERBOSE)
                outlevel = O_DEBUG;
            else
                outlevel = O_VERBOSE;
@@ -267,12 +281,13 @@ struct query *ctl;        /* option record to be initialized */
            break;
        case 'q':
            quitmode = TRUE;
+           quitind = optind;
            break;
        case 'L':
            rctl->logfile = prependdir (optarg, currentwd);
            break;
        case LA_INVISIBLE:
-           rctl->invisible = TRUE;
+           rctl->invisible = FLAG_TRUE;
            break;
        case LA_SHOWDOTS:
            rctl->showdots = FLAG_TRUE;
@@ -284,12 +299,32 @@ struct query *ctl;        /* option record to be initialized */
        case 'i':
            rctl->idfile = prependdir (optarg, currentwd);
            break;
+       case LA_PIDFILE:
+           rctl->pidfile = prependdir (optarg, currentwd);
+           break;
        case LA_POSTMASTER:
            rctl->postmaster = (char *) xstrdup(optarg);
            break;
        case LA_NOBOUNCE:
-           run.bouncemail = FALSE;
+           rctl->bouncemail = FLAG_FALSE;
+           break;
+       case LA_NOSOFTBOUNCE:
+           rctl->softbounce = FLAG_FALSE;
+           break;
+       case LA_SOFTBOUNCE:
+           rctl->softbounce = FLAG_TRUE;
+           break;
+       case LA_BADHEADER:
+           if (strcasecmp(optarg,"accept") == 0) {
+               ctl->server.badheader = BHACCEPT;
+           } else if (strcasecmp(optarg,"reject") == 0) {
+               ctl->server.badheader = BHREJECT;
+           } else {
+               fprintf(stderr,GT_("Invalid bad-header policy `%s' specified.\n"), optarg);
+               errflag++;
+           }
            break;
+
        case 'p':
            /* XXX -- should probably use a table lookup here */
            if (strcasecmp(optarg,"auto") == 0)
@@ -312,7 +347,7 @@ struct query *ctl;  /* option record to be initialized */
            else if (strcasecmp(optarg,"kpop") == 0)
            {
                ctl->server.protocol = P_POP3;
-               ctl->server.service = KPOP_PORT;
+               ctl->server.service = xstrdup(KPOP_PORT);
 #ifdef KERBEROS_V5
                ctl->server.authenticate =  A_KERBEROS_V5;
 #else
@@ -333,6 +368,9 @@ struct query *ctl;  /* option record to be initialized */
        case 'U':
            ctl->server.uidl = FLAG_TRUE;
            break;
+       case LA_IDLE:
+           ctl->idle = FLAG_TRUE;
+           break;
        case 'P':
            ctl->server.service = optarg;
            break;
@@ -351,6 +389,8 @@ struct query *ctl;  /* option record to be initialized */
                ctl->server.authenticate = A_KERBEROS_V4;
            else if (strcmp(optarg, "ssh") == 0)
                ctl->server.authenticate = A_SSH;
+           else if (strcasecmp(optarg, "external") == 0)
+               ctl->server.authenticate = A_EXTERNAL;
            else if (strcmp(optarg, "otp") == 0)
                ctl->server.authenticate = A_OTP;
            else if (strcmp(optarg, "opie") == 0)
@@ -447,7 +487,7 @@ struct query *ctl;  /* option record to be initialized */
            buf = xstrdup(optarg);
            cp = strtok(buf, ",");
            do {
-               struct idlist   *idp = save_str(&ctl->antispam, NULL, 0);;
+               struct idlist   *idp = save_str(&ctl->antispam, STRING_DUMMY, 0);
 
                idp->val.status.num = xatoi(cp, &errflag);
            } while
@@ -522,10 +562,18 @@ struct query *ctl;        /* option record to be initialized */
            ctl->sslcertck = FLAG_TRUE;
            break;
 
+       case LA_SSLCERTFILE:
+           ctl->sslcertfile = prependdir(optarg, currentwd);
+           break;
+
        case LA_SSLCERTPATH:
            ctl->sslcertpath = prependdir(optarg, currentwd);
            break;
 
+       case LA_SSLCOMMONNAME:
+           ctl->sslcommonname = xstrdup(optarg);
+           break;
+
        case LA_SSLFINGERPRINT:
            ctl->sslfingerprint = xstrdup(optarg);
            break;
@@ -568,59 +616,67 @@ struct query *ctl;        /* option record to be initialized */
 
     if (errflag || ocount > 1 || helpflag) {
        /* squawk if syntax errors were detected */
-#define P(s)   fputs(s, helpflag ? stdout : stderr)
+#define P(s)    fputs(s, helpflag ? stdout : stderr)
        P(GT_("usage:  fetchmail [options] [server ...]\n"));
        P(GT_("  Options are as follows:\n"));
-       P(GT_("  -?, --help        display this option help\n"));
-       P(GT_("  -V, --version     display version info\n"));
+       P(GT_("  -?, --help        display this option help\n"));
+       P(GT_("  -V, --version     display version info\n"));
 
-       P(GT_("  -c, --check       check for messages without fetching\n"));
-       P(GT_("  -s, --silent      work silently\n"));
-       P(GT_("  -v, --verbose     work noisily (diagnostic output)\n"));
-       P(GT_("  -d, --daemon      run as a daemon once per n seconds\n"));
+       P(GT_("  -c, --check       check for messages without fetching\n"));
+       P(GT_("  -s, --silent      work silently\n"));
+       P(GT_("  -v, --verbose     work noisily (diagnostic output)\n"));
+       P(GT_("  -d, --daemon      run as a daemon once per n seconds\n"));
        P(GT_("  -N, --nodetach    don't detach daemon process\n"));
-       P(GT_("  -q, --quit        kill daemon process\n"));
-       P(GT_("  -L, --logfile     specify logfile name\n"));
-       P(GT_("      --syslog      use syslog(3) for most messages when running as a daemon\n"));
+       P(GT_("  -q, --quit        kill daemon process\n"));
+       P(GT_("  -L, --logfile     specify logfile name\n"));
+       P(GT_("      --syslog      use syslog(3) for most messages when running as a daemon\n"));
        P(GT_("      --invisible   don't write Received & enable host spoofing\n"));
        P(GT_("  -f, --fetchmailrc specify alternate run control file\n"));
-       P(GT_("  -i, --idfile      specify alternate UIDs file\n"));
+       P(GT_("  -i, --idfile      specify alternate UIDs file\n"));
+       P(GT_("      --pidfile     specify alternate PID (lock) file\n"));
        P(GT_("      --postmaster  specify recipient of last resort\n"));
        P(GT_("      --nobounce    redirect bounces from user to postmaster.\n"));
+       P(GT_("      --nosoftbounce fetchmail deletes permanently undeliverable messages.\n"));
+       P(GT_("      --softbounce  keep permanently undeliverable messages on server (default).\n"));
 #ifdef CAN_MONITOR
        P(GT_("  -I, --interface   interface required specification\n"));
-       P(GT_("  -M, --monitor     monitor interface for activity\n"));
+       P(GT_("  -M, --monitor     monitor interface for activity\n"));
 #endif
 #if defined( SSL_ENABLE )
-       P(GT_("      --ssl         enable ssl encrypted session\n"));
-       P(GT_("      --sslkey      ssl private key file\n"));
-       P(GT_("      --sslcert     ssl client certificate\n"));
-       P(GT_("      --sslcertpath path to ssl certificates\n"));
+       P(GT_("      --ssl         enable ssl encrypted session\n"));
+       P(GT_("      --sslkey      ssl private key file\n"));
+       P(GT_("      --sslcert     ssl client certificate\n"));
+       P(GT_("      --sslcertck   do strict server certificate check (recommended)\n"));
+       P(GT_("      --sslcertfile path to trusted-CA ssl certificate file\n"));
+       P(GT_("      --sslcertpath path to trusted-CA ssl certificate directory\n"));
+       P(GT_("      --sslcommonname  expect this CommonName from server (discouraged)\n"));
        P(GT_("      --sslfingerprint fingerprint that must match that of the server's cert.\n"));
-       P(GT_("      --sslproto    force ssl protocol (ssl2/ssl3/tls1)\n"));
+       P(GT_("      --sslproto    force ssl protocol (SSL2/SSL3/TLS1)\n"));
 #endif
-       P(GT_("      --plugin      specify external command to open connection\n"));
-       P(GT_("      --plugout     specify external command to open smtp connection\n"));
+       P(GT_("      --plugin      specify external command to open connection\n"));
+       P(GT_("      --plugout     specify external command to open smtp connection\n"));
+       P(GT_("      --bad-header {reject|accept}\n"
+             "                    specify policy for handling messages with bad headers\n"));
 
        P(GT_("  -p, --protocol    specify retrieval protocol (see man page)\n"));
-       P(GT_("  -U, --uidl        force the use of UIDLs (pop3 only)\n"));
-       P(GT_("  -P, --port        TCP port to connect to (obsolete, use --service)\n"));
-       P(GT_("      --service     TCP service to connect to (can be numeric TCP port)\n"));
-       P(GT_("      --auth        authentication type (password/kerberos/ssh/otp)\n"));
-       P(GT_("  -t, --timeout     server nonresponse timeout\n"));
+       P(GT_("  -U, --uidl        force the use of UIDLs (pop3 only)\n"));
+       P(GT_("      --port        TCP port to connect to (obsolete, use --service)\n"));
+       P(GT_("  -P, --service     TCP service to connect to (can be numeric TCP port)\n"));
+       P(GT_("      --auth        authentication type (password/kerberos/ssh/otp)\n"));
+       P(GT_("  -t, --timeout     server nonresponse timeout\n"));
        P(GT_("  -E, --envelope    envelope address header\n"));
        P(GT_("  -Q, --qvirtual    prefix to remove from local user id\n"));
        P(GT_("      --principal   mail service principal\n"));
        P(GT_("      --tracepolls  add poll-tracing information to Received header\n"));
 
        P(GT_("  -u, --username    specify users's login on server\n"));
-       P(GT_("  -a, --all         retrieve old and new messages\n"));
-       P(GT_("  -K, --nokeep      delete new messages after retrieval\n"));
-       P(GT_("  -k, --keep        save new messages after retrieval\n"));
-       P(GT_("  -F, --flush       delete old messages from server\n"));
+       P(GT_("  -a, --[fetch]all  retrieve old and new messages\n"));
+       P(GT_("  -K, --nokeep      delete new messages after retrieval\n"));
+       P(GT_("  -k, --keep        save new messages after retrieval\n"));
+       P(GT_("  -F, --flush       delete old messages from server\n"));
        P(GT_("      --limitflush  delete oversized messages\n"));
        P(GT_("  -n, --norewrite   don't rewrite header addresses\n"));
-       P(GT_("  -l, --limit       don't fetch messages over given size\n"));
+       P(GT_("  -l, --limit       don't fetch messages over given size\n"));
        P(GT_("  -w, --warnings    interval between warning mail notification\n"));
 
        P(GT_("  -S, --smtphost    set SMTP forwarding host\n"));
@@ -632,13 +688,17 @@ struct query *ctl;        /* option record to be initialized */
        P(GT_("  -B, --fetchlimit  set fetch limit for server connections\n"));
        P(GT_("      --fetchsizelimit set fetch message size limit\n"));
        P(GT_("      --fastuidl    do a binary search for UIDLs\n"));
-       P(GT_("  -e, --expunge     set max deletions between expunges\n"));
-       P(GT_("  -m, --mda         set MDA to use for forwarding\n"));
-       P(GT_("      --bsmtp       set output BSMTP file\n"));
-       P(GT_("      --lmtp        use LMTP (RFC2033) for delivery\n"));
-       P(GT_("  -r, --folder      specify remote folder name\n"));
+       P(GT_("  -e, --expunge     set max deletions between expunges\n"));
+       P(GT_("  -m, --mda         set MDA to use for forwarding\n"));
+       P(GT_("      --bsmtp       set output BSMTP file\n"));
+       P(GT_("      --lmtp        use LMTP (RFC2033) for delivery\n"));
+       P(GT_("  -r, --folder      specify remote folder name\n"));
        P(GT_("      --showdots    show progress dots even in logfiles\n"));
 #undef P
+       /* undocumented:
+        * --configdump (internal use by fetchmailconf, dumps
+        *               configuration as Python source code)
+        * --yydebug    (developer use, enables parser debugging) */
 
        if (helpflag)
            exit(PS_SUCCESS);