]> Pileus Git - ~andy/fetchmail/blobdiff - options.c
Complete Dominik's name.
[~andy/fetchmail] / options.c
index fc8056ba25b84bb9b6064820cbd340aa2c70da52..d53044fc72c4215ee3e975092acde6fb7819a142 100644 (file)
--- a/options.c
+++ b/options.c
 #include "fetchmail.h"
 #include "i18n.h"
 
-#define LA_HELP                1
-#define LA_VERSION     2 
-#define LA_CHECK       3
-#define LA_SILENT      4 
-#define LA_VERBOSE     5 
-#define LA_DAEMON      6
-#define LA_NODETACH    7
-#define LA_QUIT                8
-#define LA_LOGFILE     9
-#define LA_INVISIBLE   10
-#define LA_SYSLOG      11
-#define LA_NOSYSLOG    12
-#define LA_RCFILE      13
-#define LA_IDFILE      14
-#define LA_POSTMASTER  15
-#define LA_NOBOUNCE    16
-#define LA_PROTOCOL    17
-#define LA_UIDL                18
-#define LA_PORT                19
-#define LA_PREAUTH     20
-#define LA_TIMEOUT     21
-#define LA_ENVELOPE    22
-#define LA_QVIRTUAL     23
-#define LA_USERNAME    24
-#define LA_ALL          25
-#define LA_NOKEEP      26
-#define        LA_KEEP         27
-#define LA_FLUSH        28
-#define LA_NOREWRITE   29
-#define LA_LIMIT       30
-#define LA_WARNINGS    31
-#define LA_FOLDER      32
-#define LA_SMTPHOST    33
-#define LA_SMTPADDR     34
-#define LA_ANTISPAM    35
-#define LA_BATCHLIMIT  36
-#define LA_FETCHLIMIT  37
-#define LA_EXPUNGE     38
-#define LA_MDA         39
-#define LA_BSMTP       40
-#define LA_LMTP                41
-#define LA_PLUGIN      42
-#define LA_PLUGOUT     43
-#define LA_NETSEC      44
-#define LA_INTERFACE    45
-#define LA_MONITOR      46
-#define LA_CONFIGDUMP  47
-#define LA_YYDEBUG     48
-
-#ifdef SSL_ENABLE
-#define LA_SSL         49
-#define LA_SSLKEY      50
-#define LA_SSLCERT     51
-#endif
+enum {
+    LA_INVISIBLE = 256,
+    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: CDgGhHjJoORwWxXYz */
+/* options still left: CgGhHjJoORTWxXYz */
 static const char *shortoptions = 
-       "?Vcsvd:NqL:f:i:p:UP:A:t:E:Q:u:akKFnl:r:S:Z:b:B:e:m:T:I:M:yw:";
+       "?Vcsvd:NqL:f:i:p:UP:A:t:E:Q:u:akKFnl:r:S:Z:b:B:e:m:I:M:yw:D:";
 
 static const struct option longoptions[] = {
 /* this can be const because all flag fields are 0 and will never get set */
-  {"help",     no_argument,       (int *) 0, LA_HELP        },
-  {"version",  no_argument,       (int *) 0, LA_VERSION     },
-  {"check",    no_argument,       (int *) 0, LA_CHECK       },
-  {"silent",   no_argument,       (int *) 0, LA_SILENT      },
-  {"verbose",  no_argument,       (int *) 0, LA_VERBOSE     },
-  {"daemon",   required_argument, (int *) 0, LA_DAEMON      },
-  {"nodetach", no_argument,       (int *) 0, LA_NODETACH    },
-  {"quit",     no_argument,       (int *) 0, LA_QUIT        },
-  {"logfile",  required_argument, (int *) 0, LA_LOGFILE     },
-  {"invisible",        no_argument,       (int *) 0, LA_INVISIBLE   },
-  {"syslog",   no_argument,       (int *) 0, LA_SYSLOG      },
-  {"nosyslog", no_argument,       (int *) 0, LA_NOSYSLOG    },
-  {"fetchmailrc",required_argument,(int *) 0, LA_RCFILE      },
-  {"idfile",   required_argument, (int *) 0, LA_IDFILE      },
-  {"postmaster",required_argument, (int *) 0, LA_POSTMASTER  },
-  {"nobounce",  no_argument,       (int *) 0, LA_NOBOUNCE    },
-
-  {"protocol", required_argument, (int *) 0, LA_PROTOCOL    },
-  {"proto",    required_argument, (int *) 0, LA_PROTOCOL    },
-  {"uidl",     no_argument,       (int *) 0, LA_UIDL        },
-  {"port",     required_argument, (int *) 0, LA_PORT        },
-  {"preauth",  required_argument, (int *) 0, LA_PREAUTH},
-  {"timeout",  required_argument, (int *) 0, LA_TIMEOUT     },
-  {"envelope", required_argument, (int *) 0, LA_ENVELOPE    },
-  {"qvirtual", required_argument, (int *) 0, LA_QVIRTUAL    },
-
-  {"user",     required_argument, (int *) 0, LA_USERNAME    },
-  {"username", required_argument, (int *) 0, LA_USERNAME    },
-
-  {"all",      no_argument,       (int *) 0, LA_ALL         },
-  {"nokeep",   no_argument,       (int *) 0, LA_NOKEEP      },
-  {"keep",     no_argument,       (int *) 0, LA_KEEP        },
-  {"flush",    no_argument,       (int *) 0, LA_FLUSH       },
-  {"norewrite",        no_argument,       (int *) 0, LA_NOREWRITE   },
-  {"limit",    required_argument, (int *) 0, LA_LIMIT       },
-  {"warnings", required_argument, (int *) 0, LA_WARNINGS    },
-
-  {"folder",   required_argument, (int *) 0, LA_FOLDER      },
-  {"smtphost", required_argument, (int *) 0, LA_SMTPHOST    },
-  {"smtpaddress", required_argument, (int *) 0, LA_SMTPADDR  },
-  {"antispam", required_argument, (int *) 0, LA_ANTISPAM    },
-  
-  {"batchlimit",required_argument, (int *) 0, LA_BATCHLIMIT  },
-  {"fetchlimit",required_argument, (int *) 0, LA_FETCHLIMIT  },
-  {"expunge",  required_argument, (int *) 0, LA_EXPUNGE     },
-  {"mda",      required_argument, (int *) 0, LA_MDA         },
-  {"bsmtp",    required_argument, (int *) 0, LA_BSMTP       },
-  {"lmtp",     no_argument,       (int *) 0, LA_LMTP        },
-
-#ifdef INET6
-  {"netsec",   required_argument, (int *) 0, LA_NETSEC      },
-#endif /* INET6 */
+  {"help",     no_argument,       (int *) 0, '?' },
+  {"version",  no_argument,       (int *) 0, 'V' },
+  {"check",    no_argument,       (int *) 0, 'c' },
+  {"silent",   no_argument,       (int *) 0, 's' },
+  {"verbose",  no_argument,       (int *) 0, 'v' },
+  {"daemon",   required_argument, (int *) 0, 'd' },
+  {"nodetach", no_argument,       (int *) 0, 'N' },
+  {"quit",     no_argument,       (int *) 0, 'q' },
+  {"logfile",  required_argument, (int *) 0, 'L' },
+  {"invisible",        no_argument,       (int *) 0, LA_INVISIBLE },
+  {"showdots", no_argument,       (int *) 0, LA_SHOWDOTS },
+  {"syslog",   no_argument,       (int *) 0, LA_SYSLOG },
+  {"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' },
+  {"limitflush",       no_argument, (int *) 0, LA_LIMITFLUSH },
+  {"norewrite",        no_argument,       (int *) 0, 'n' },
+  {"limit",    required_argument, (int *) 0, 'l' },
+  {"warnings", required_argument, (int *) 0, 'w' },
+
+  {"folder",   required_argument, (int *) 0, 'r' },
+  {"smtphost", required_argument, (int *) 0, 'S' },
+  {"fetchdomains",     required_argument, (int *) 0, LA_FETCHDOMAINS },
+  {"smtpaddress", required_argument, (int *) 0, 'D' },
+  {"smtpname", required_argument, (int *) 0, LA_SMTPNAME },
+  {"antispam", required_argument, (int *) 0, 'Z' },
+
+  {"batchlimit",required_argument, (int *) 0, 'b' },
+  {"fetchlimit",required_argument, (int *) 0, 'B' },
+  {"fetchsizelimit",required_argument, (int *) 0, LA_FETCHSIZELIMIT },
+  {"fastuidl", required_argument, (int *) 0, LA_FASTUIDL },
+  {"expunge",  required_argument, (int *) 0, 'e' },
+  {"mda",      required_argument, (int *) 0, 'm' },
+  {"bsmtp",    required_argument, (int *) 0, LA_BSMTP },
+  {"lmtp",     no_argument,       (int *) 0, LA_LMTP },
 
 #ifdef SSL_ENABLE
-  {"ssl",       no_argument,       (int *) 0, LA_SSL        },
-  {"sslkey",    required_argument, (int *) 0, LA_SSLKEY     },
-  {"sslcert",   required_argument, (int *) 0, LA_SSLCERT    },
+  {"ssl",      no_argument,       (int *) 0, LA_SSL },
+  {"sslkey",   required_argument, (int *) 0, LA_SSLKEY },
+  {"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
 
-#if (defined(linux) && !INET6) || defined(__FreeBSD__)
-  {"interface",        required_argument, (int *) 0, LA_INTERFACE   },
-  {"monitor",  required_argument, (int *) 0, LA_MONITOR     },
-#endif /* (defined(linux) && !INET6) || defined(__FreeBSD__) */
-  {"plugin",   required_argument, (int *) 0, LA_PLUGIN      },
-  {"plugout",  required_argument, (int *) 0, LA_PLUGOUT     },
+  {"principal", required_argument, (int *) 0, LA_PRINCIPAL },
+
+#ifdef CAN_MONITOR
+  {"interface",        required_argument, (int *) 0, 'I' },
+  {"monitor",  required_argument, (int *) 0, 'M' },
+#endif /* CAN_MONITOR */
+  {"plugin",   required_argument, (int *) 0, LA_PLUGIN },
+  {"plugout",  required_argument, (int *) 0, LA_PLUGOUT },
+
+  {"configdump",no_argument,      (int *) 0, LA_CONFIGDUMP },
 
-  {"configdump",no_argument,      (int *) 0, LA_CONFIGDUMP  },
+  {"yydebug",  no_argument,       (int *) 0, 'y' },
 
-  {"yydebug",  no_argument,       (int *) 0, LA_YYDEBUG     },
+  {"tracepolls",no_argument,      (int *) 0, LA_TRACEPOLLS },
 
-  {(char *) 0,  no_argument,       (int *) 0, 0              }
+  {(char *) 0, no_argument,       (int *) 0, 0 }
 };
 
 static int xatoi(char *s, int *errflagptr)
@@ -173,7 +173,7 @@ static int xatoi(char *s, int *errflagptr)
 
     /* any invalid chars in string? */
     if ( (endptr == s) || (*endptr != '\0') ) {
-       (void) fprintf(stderr, _("String '%s' is not a valid number string.\n"), s);
+       (void) fprintf(stderr, GT_("String '%s' is not a valid number string.\n"), s);
        (*errflagptr)++;
        return 0;
     }
@@ -182,8 +182,8 @@ static int xatoi(char *s, int *errflagptr)
     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"),
+       (void) fprintf(stderr, GT_("Value of string '%s' is %s than %d.\n"), s,
+                                       (value < 0) ? GT_("smaller"): GT_("larger"),
                                        (value < 0) ? INT_MIN : INT_MAX);
        (*errflagptr)++;
        return 0;
@@ -203,7 +203,7 @@ static int xatoi(char *s, int *errflagptr)
 
     len = strlen(s);
     /* check for leading white spaces */
-    for (i = 0; (i < len) && isspace(s[i]); i++)
+    for (i = 0; (i < len) && isspace((unsigned char)s[i]); i++)
        ;
 
     dp = &s[i];
@@ -212,12 +212,12 @@ static int xatoi(char *s, int *errflagptr)
     if (i < len && (s[i] == '+' || s[i] == '-'))       i++;
 
     /* skip over digits */
-    for ( /* no init */ ; (i < len) && isdigit(s[i]); i++)
+    for ( /* no init */ ; (i < len) && isdigit((unsigned char)s[i]); i++)
        ;
 
     /* check for trailing garbage */
     if (i != len) {
-       (void) fprintf(stderr, _("String '%s' is not a valid number string.\n"), s);
+       (void) fprintf(stderr, GT_("String '%s' is not a valid number string.\n"), s);
        (*errflagptr)++;
        return 0;
     }
@@ -227,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
@@ -256,66 +255,77 @@ struct query *ctl;        /* option record to be initialized */
 
     while (!errflag && 
           (c = getopt_long(argc,argv,shortoptions,
-                           longoptions,&option_index)) != -1) {
-
+                           longoptions, &option_index)) != -1)
+    {
        switch (c) {
        case 'V':
-       case LA_VERSION:
            versioninfo = TRUE;
            break;
        case 'c':
-       case LA_CHECK:
            check_only = TRUE;
            break;
        case 's':
-       case LA_SILENT:
            outlevel = O_SILENT;
            break;
        case 'v':
-       case LA_VERBOSE:
-           if (outlevel == O_VERBOSE)
+           if (outlevel >= O_VERBOSE)
                outlevel = O_DEBUG;
            else
                outlevel = O_VERBOSE;
            break;
        case 'd':
-       case LA_DAEMON:
            rctl->poll_interval = xatoi(optarg, &errflag);
            break;
        case 'N':
-       case LA_NODETACH:
            nodetach = TRUE;
            break;
        case 'q':
-       case LA_QUIT:
            quitmode = TRUE;
+           quitind = optind;
            break;
        case 'L':
-       case LA_LOGFILE:
-           rctl->logfile = optarg;
+           rctl->logfile = prependdir (optarg, currentwd);
            break;
        case LA_INVISIBLE:
-           rctl->invisible = TRUE;
+           rctl->invisible = FLAG_TRUE;
+           break;
+       case LA_SHOWDOTS:
+           rctl->showdots = FLAG_TRUE;
            break;
        case 'f':
-       case LA_RCFILE:
-           rcfile = (char *) xmalloc(strlen(optarg)+1);
-           strcpy(rcfile,optarg);
+           xfree(rcfile);
+           rcfile = prependdir (optarg, currentwd);
            break;
        case 'i':
-       case LA_IDFILE:
-           rctl->idfile = (char *) xmalloc(strlen(optarg)+1);
-           strcpy(rctl->idfile,optarg);
+           rctl->idfile = prependdir (optarg, currentwd);
+           break;
+       case LA_PIDFILE:
+           rctl->pidfile = prependdir (optarg, currentwd);
            break;
        case LA_POSTMASTER:
-           rctl->postmaster = (char *) xmalloc(strlen(optarg)+1);
-           strcpy(rctl->postmaster,optarg);
+           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':
-       case LA_PROTOCOL:
            /* XXX -- should probably use a table lookup here */
            if (strcasecmp(optarg,"auto") == 0)
                ctl->server.protocol = P_AUTO;
@@ -324,8 +334,8 @@ struct query *ctl;  /* option record to be initialized */
 #ifdef SDPS_ENABLE
            else if (strcasecmp(optarg,"sdps") == 0)
            {
-               ctl->server.protocol = P_POP3; 
-                ctl->server.sdps = TRUE;
+               ctl->server.protocol = P_POP3; 
+               ctl->server.sdps = TRUE;
            }
 #endif /* SDPS_ENABLE */
            else if (strcasecmp(optarg,"pop3") == 0)
@@ -337,197 +347,193 @@ struct query *ctl;      /* option record to be initialized */
            else if (strcasecmp(optarg,"kpop") == 0)
            {
                ctl->server.protocol = P_POP3;
-#if INET6
-               ctl->server.service = KPOP_PORT;
-#else /* INET6 */
-               ctl->server.port = KPOP_PORT;
-#endif /* INET6 */
+               ctl->server.service = xstrdup(KPOP_PORT);
 #ifdef KERBEROS_V5
-               ctl->server.preauthenticate =  A_KERBEROS_V5;
+               ctl->server.authenticate =  A_KERBEROS_V5;
 #else
-               ctl->server.preauthenticate =  A_KERBEROS_V4;
+               ctl->server.authenticate =  A_KERBEROS_V4;
 #endif /* KERBEROS_V5 */
            }
            else if (strcasecmp(optarg,"imap") == 0)
                ctl->server.protocol = P_IMAP;
-#ifdef KERBEROS_V4
-           else if (strcasecmp(optarg,"imap-k4") == 0)
-               ctl->server.protocol = P_IMAP_K4;
-#endif /* KERBEROS_V4 */
-#ifdef GSSAPI
-           else if (strcasecmp(optarg, "imap-gss") == 0)
-                ctl->server.protocol = P_IMAP_GSS;
-#endif /* GSSAPI */
-           else if (strcasecmp(optarg, "imap-crammd5") == 0)
-                ctl->server.protocol = P_IMAP_CRAM_MD5;
-           else if (strcasecmp(optarg, "imap-login") == 0)
-                ctl->server.protocol = P_IMAP_LOGIN;
            else if (strcasecmp(optarg,"etrn") == 0)
                ctl->server.protocol = P_ETRN;
+           else if (strcasecmp(optarg,"odmr") == 0)
+               ctl->server.protocol = P_ODMR;
            else {
-               fprintf(stderr,_("Invalid protocol `%s' specified.\n"), optarg);
+               fprintf(stderr,GT_("Invalid protocol `%s' specified.\n"), optarg);
                errflag++;
            }
            break;
        case 'U':
-       case LA_UIDL:
            ctl->server.uidl = FLAG_TRUE;
            break;
+       case LA_IDLE:
+           ctl->idle = FLAG_TRUE;
+           break;
        case 'P':
-       case LA_PORT:
-#if INET6
            ctl->server.service = optarg;
-#else /* INET6 */
-           ctl->server.port = xatoi(optarg, &errflag);
-#endif /* INET6 */
            break;
-       case LA_PREAUTH:
+       case LA_AUTH:
            if (strcmp(optarg, "password") == 0)
-               ctl->server.preauthenticate = A_PASSWORD;
+               ctl->server.authenticate = A_PASSWORD;
            else if (strcmp(optarg, "kerberos") == 0)
 #ifdef KERBEROS_V5
-               ctl->server.preauthenticate = A_KERBEROS_V5;
+               ctl->server.authenticate = A_KERBEROS_V5;
 #else
-               ctl->server.preauthenticate = A_KERBEROS_V4;
+               ctl->server.authenticate = A_KERBEROS_V4;
 #endif /* KERBEROS_V5 */
            else if (strcmp(optarg, "kerberos_v5") == 0)
-               ctl->server.preauthenticate = A_KERBEROS_V5;
+               ctl->server.authenticate = A_KERBEROS_V5;
            else if (strcmp(optarg, "kerberos_v4") == 0)
-               ctl->server.preauthenticate = A_KERBEROS_V4;
+               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)
+               ctl->server.authenticate = A_OTP;
+           else if (strcmp(optarg, "ntlm") == 0)
+               ctl->server.authenticate = A_NTLM;
+           else if (strcmp(optarg, "cram") == 0)
+               ctl->server.authenticate = A_CRAM_MD5;
+           else if (strcmp(optarg, "cram-md5") == 0)
+               ctl->server.authenticate = A_CRAM_MD5;
+           else if (strcmp(optarg, "gssapi") == 0)
+               ctl->server.authenticate = A_GSSAPI;
+           else if (strcmp(optarg, "any") == 0)
+               ctl->server.authenticate = A_ANY;
+           else if (strcmp(optarg, "msn") == 0)
+               ctl->server.authenticate = A_MSN;
            else {
-               fprintf(stderr,_("Invalid preauthentication `%s' specified.\n"), optarg);
+               fprintf(stderr,GT_("Invalid authentication `%s' specified.\n"), optarg);
                errflag++;
            }
            break;
        case 't':
-       case LA_TIMEOUT:
            ctl->server.timeout = xatoi(optarg, &errflag);
            if (ctl->server.timeout == 0)
                ctl->server.timeout = -1;
            break;
        case 'E':
-       case LA_ENVELOPE:
            ctl->server.envelope = xstrdup(optarg);
            break;
        case 'Q':    
-       case LA_QVIRTUAL:
            ctl->server.qvirtual = xstrdup(optarg);
            break;
 
        case 'u':
-       case LA_USERNAME:
            ctl->remotename = xstrdup(optarg);
            break;
        case 'a':
-       case LA_ALL:
            ctl->fetchall = FLAG_TRUE;
            break;
        case 'K':
-       case LA_NOKEEP:
            ctl->keep = FLAG_FALSE;
            break;
        case 'k':
-       case LA_KEEP:
            ctl->keep = FLAG_TRUE;
            break;
        case 'F':
-       case LA_FLUSH:
            ctl->flush = FLAG_TRUE;
            break;
+       case LA_LIMITFLUSH:
+           ctl->limitflush = FLAG_TRUE;
+           break;
        case 'n':
-       case LA_NOREWRITE:
            ctl->rewrite = FLAG_FALSE;
            break;
        case 'l':
-       case LA_LIMIT:
            c = xatoi(optarg, &errflag);
            ctl->limit = NUM_VALUE_IN(c);
            break;
        case 'r':
-       case LA_FOLDER:
-           xalloca(buf, char *, strlen(optarg) + 1);
-           strcpy(buf, optarg);
+           buf = xstrdup(optarg);
            cp = strtok(buf, ",");
            do {
                save_str(&ctl->mailboxes, cp, 0);
            } while
                ((cp = strtok((char *)NULL, ",")));
+           free(buf);
            break;
        case 'S':
-       case LA_SMTPHOST:
-           xalloca(buf, char *, strlen(optarg) + 1);
-           strcpy(buf, optarg);
+           buf = xstrdup(optarg);
            cp = strtok(buf, ",");
            do {
                save_str(&ctl->smtphunt, cp, TRUE);
            } while
                ((cp = strtok((char *)NULL, ",")));
+           free(buf);
            ocount++;
            break;
+       case LA_FETCHDOMAINS:
+           buf = xstrdup(optarg);
+           cp = strtok(buf, ",");
+           do {
+               save_str(&ctl->domainlist, cp, TRUE);
+           } while
+               ((cp = strtok((char *)NULL, ",")));
+           free(buf);
+           break;
        case 'D':
-       case LA_SMTPADDR:
            ctl->smtpaddress = xstrdup(optarg);
            break;
+       case LA_SMTPNAME:
+         ctl->smtpname = xstrdup(optarg);
+         break;
        case 'Z':
-       case LA_ANTISPAM:
-           xalloca(buf, char *, strlen(optarg) + 1);
-           strcpy(buf, optarg);
+           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 = atoi(cp);
+               idp->val.status.num = xatoi(cp, &errflag);
            } while
                ((cp = strtok((char *)NULL, ",")));
+           free(buf);
            break;
        case 'b':
-       case LA_BATCHLIMIT:
            c = xatoi(optarg, &errflag);
            ctl->batchlimit = NUM_VALUE_IN(c);
            break;
        case 'B':
-       case LA_FETCHLIMIT:
            c = xatoi(optarg, &errflag);
            ctl->fetchlimit = NUM_VALUE_IN(c);
            break;
+       case LA_FETCHSIZELIMIT:
+           c = xatoi(optarg, &errflag);
+           ctl->fetchsizelimit = NUM_VALUE_IN(c);
+           break;
+       case LA_FASTUIDL:
+           c = xatoi(optarg, &errflag);
+           ctl->fastuidl = NUM_VALUE_IN(c);
+           break;
        case 'e':
-       case LA_EXPUNGE:
            c = xatoi(optarg, &errflag);
            ctl->expunge = NUM_VALUE_IN(c);
            break;
        case 'm':
-       case LA_MDA:
            ctl->mda = xstrdup(optarg);
            ocount++;
            break;
        case LA_BSMTP:
-           ctl->bsmtp = xstrdup(optarg);
+           ctl->bsmtp = prependdir (optarg, currentwd);
            ocount++;
            break;
        case LA_LMTP:
            ctl->listener = LMTP_MODE;
            break;
 
-       case 'T':
-       case LA_NETSEC:
-#if NET_SECURITY
-           ctl->server.netsec = (void *)optarg;
-#else
-           fprintf(stderr, _("fetchmail: network security support is disabled\n"));
-           errflag++;
-#endif /* NET_SECURITY */
-           break;
-
-#if (defined(linux) && !INET6) || defined(__FreeBSD__)
+#ifdef CAN_MONITOR
        case 'I':
-       case LA_INTERFACE:
            interface_parse(optarg, &ctl->server);
            break;
        case 'M':
-       case LA_MONITOR:
            ctl->server.monitor = xstrdup(optarg);
            break;
-#endif /* (defined(linux) && !INET6) || defined(__FreeBSD__) */
+#endif /* CAN_MONITOR */
        case LA_PLUGIN:
            ctl->server.plugin = xstrdup(optarg);
            break;
@@ -541,21 +547,47 @@ struct query *ctl;        /* option record to be initialized */
            break;
 
        case LA_SSLKEY:
-           ctl->sslkey = xstrdup(optarg);
+           ctl->sslkey = prependdir (optarg, currentwd);
            break;
 
        case LA_SSLCERT:
-           ctl->sslcert = xstrdup(optarg);
+           ctl->sslcert = prependdir (optarg, currentwd);
+           break;
+
+       case LA_SSLPROTO:
+           ctl->sslproto = xstrdup(optarg);
+           break;
+
+       case LA_SSLCERTCK:
+           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;
 #endif
 
+       case LA_PRINCIPAL:
+           ctl->server.principal = xstrdup(optarg);
+           break;
+
        case 'y':
-       case LA_YYDEBUG:
            yydebug = TRUE;
            break;
 
        case 'w':
-       case LA_WARNINGS:
            c = xatoi(optarg, &errflag);
            ctl->warnings = NUM_VALUE_IN(c);
            break;
@@ -572,8 +604,11 @@ struct query *ctl; /* option record to be initialized */
            rctl->use_syslog = FLAG_FALSE;
            break;
 
+       case LA_TRACEPOLLS:
+           ctl->server.tracepolls = FLAG_TRUE;
+           break;
+
        case '?':
-       case LA_HELP:
        default:
            helpflag++;
        }
@@ -581,68 +616,89 @@ 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)
-       P(_("usage:  fetchmail [options] [server ...]\n"));
-       P(_("  Options are as follows:\n"));
-       P(_("  -?, --help        display this option help\n"));
-       P(_("  -V, --version     display version info\n"));
-
-       P(_("  -c, --check       check for messages without fetching\n"));
-       P(_("  -s, --silent      work silently\n"));
-       P(_("  -v, --verbose     work noisily (diagnostic output)\n"));
-       P(_("  -d, --daemon      run as a daemon once per n seconds\n"));
-       P(_("  -N, --nodetach    don't detach daemon process\n"));
-       P(_("  -q, --quit        kill daemon process\n"));
-       P(_("  -L, --logfile     specify logfile name\n"));
-       P(_("      --syslog      use syslog(3) for most messages when running as a daemon\n"));
-       P(_("      --invisible   don't write Received & enable host spoofing\n"));
-       P(_("  -f, --fetchmailrc specify alternate run control file\n"));
-       P(_("  -i, --idfile      specify alternate UIDs file\n"));
-       P(_("      --postmaster  specify recipient of last resort\n"));
-       P(_("      --nobounce    redirect bounces from user to postmaster.\n"));
-#if (defined(linux) && !INET6) || defined(__FreeBSD__)
-       P(_("  -I, --interface   interface required specification\n"));
-       P(_("  -M, --monitor     monitor interface for activity\n"));
+#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_("  -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_("      --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_("      --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"));
 #endif
 #if defined( SSL_ENABLE )
-       P(_("      --ssl         enable ssl encrypted session\n"));
-       P(_("      --sslkey      ssl private key file\n"));
-       P(_("      --sslcert     ssl client certificate\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"));
 #endif
-       P(_("      --plugin      specify external command to open connection\n"));
-       P(_("      --plugout     specify external command to open smtp connection\n"));
-
-       P(_("  -p, --protocol    specify retrieval protocol (see man page)\n"));
-       P(_("  -U, --uidl        force the use of UIDLs (pop3 only)\n"));
-       P(_("  -P, --port        TCP/IP service port to connect to\n"));
-       P(_("      --preauth     preauthentication type (password or kerberos)\n"));
-       P(_("  -t, --timeout     server nonresponse timeout\n"));
-       P(_("  -E, --envelope    envelope address header\n"));
-       P(_("  -Q, --qvirtual    prefix to remove from local user id\n"));
-
-       P(_("  -u, --username    specify users's login on server\n"));
-       P(_("  -a, --all         retrieve old and new messages\n"));
-       P(_("  -K, --nokeep      delete new messages after retrieval\n"));
-       P(_("  -k, --keep        save new messages after retrieval\n"));
-       P(_("  -F, --flush       delete old messages from server\n"));
-       P(_("  -n, --norewrite   don't rewrite header addresses\n"));
-       P(_("  -l, --limit       don't fetch messages over given size\n"));
-       P(_("  -w, --warnings    interval between warning mail notification\n"));
-
-#if NET_SECURITY
-       P(_("  -T, --netsec      set IP security request\n"));
-#endif /* NET_SECURITY */
-       P(_("  -S, --smtphost    set SMTP forwarding host\n"));
-       P(_("  -D, --smtpaddress set SMTP delivery domain to use\n"));
-       P(_("  -Z, --antispam,   set antispam response values\n"));
-       P(_("  -b, --batchlimit  set batch limit for SMTP connections\n"));
-       P(_("  -B, --fetchlimit  set fetch limit for server connections\n"));
-       P(_("  -e, --expunge     set max deletions between expunges\n"));
-        P(_("  -m, --mda         set MDA to use for forwarding\n"));
-        P(_("      --bsmtp       set output BSMTP file\n"));
-        P(_("      --lmtp        use LMTP (RFC2033) for delivery\n"));
-       P(_("  -r, --folder      specify remote folder name\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_("      --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, --[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_("  -w, --warnings    interval between warning mail notification\n"));
+
+       P(GT_("  -S, --smtphost    set SMTP forwarding host\n"));
+       P(GT_("      --fetchdomains fetch mail for specified domains\n"));
+       P(GT_("  -D, --smtpaddress set SMTP delivery domain to use\n"));
+       P(GT_("      --smtpname    set SMTP full name username@domain\n"));
+       P(GT_("  -Z, --antispam,   set antispam response values\n"));
+       P(GT_("  -b, --batchlimit  set batch limit for SMTP connections\n"));
+       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_("      --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);