]> Pileus Git - ~andy/fetchmail/blob - options.c
Allow --idle on the command line.
[~andy/fetchmail] / options.c
1 /*
2  * options.c -- command-line option processing
3  *
4  * Copyright 1998 by Eric S. Raymond.
5  * For license terms, see the file COPYING in this directory.
6  */
7
8 #include "config.h"
9
10 #include <stdio.h>
11 #include <pwd.h>
12 #include <string.h>
13 #include <errno.h>
14 #if defined(STDC_HEADERS)
15 #include  <stdlib.h>
16 #include  <limits.h>
17 #else
18 #include  <ctype.h>
19 #endif
20
21 #include "getopt.h"
22 #include "fetchmail.h"
23 #include "i18n.h"
24
25 enum {
26     LA_INVISIBLE = 256,
27     LA_SYSLOG,
28     LA_NOSYSLOG,
29     LA_POSTMASTER,
30     LA_NOBOUNCE,
31     LA_AUTH,
32     LA_FETCHDOMAINS,
33     LA_BSMTP,
34     LA_LMTP,
35     LA_PLUGIN,
36     LA_PLUGOUT,
37     LA_CONFIGDUMP,
38     LA_SMTPNAME,
39     LA_SHOWDOTS,
40     LA_PRINCIPAL,
41     LA_TRACEPOLLS,
42     LA_SSL,
43     LA_SSLKEY,
44     LA_SSLCERT,
45     LA_SSLPROTO,
46     LA_SSLCERTCK,
47     LA_SSLCERTPATH,
48     LA_SSLFINGERPRINT,
49     LA_FETCHSIZELIMIT,
50     LA_FASTUIDL,
51     LA_LIMITFLUSH,
52     LA_IDLE,
53 };
54
55 /* options still left: CgGhHjJoORTWxXYz */
56 static const char *shortoptions = 
57         "?Vcsvd:NqL:f:i:p:UP:A:t:E:Q:u:akKFnl:r:S:Z:b:B:e:m:I:M:yw:D:";
58
59 static const struct option longoptions[] = {
60 /* this can be const because all flag fields are 0 and will never get set */
61   {"help",      no_argument,       (int *) 0, '?' },
62   {"version",   no_argument,       (int *) 0, 'V' },
63   {"check",     no_argument,       (int *) 0, 'c' },
64   {"silent",    no_argument,       (int *) 0, 's' },
65   {"verbose",   no_argument,       (int *) 0, 'v' },
66   {"daemon",    required_argument, (int *) 0, 'd' },
67   {"nodetach",  no_argument,       (int *) 0, 'N' },
68   {"quit",      no_argument,       (int *) 0, 'q' },
69   {"logfile",   required_argument, (int *) 0, 'L' },
70   {"invisible", no_argument,       (int *) 0, LA_INVISIBLE },
71   {"showdots",  no_argument,       (int *) 0, LA_SHOWDOTS },
72   {"syslog",    no_argument,       (int *) 0, LA_SYSLOG },
73   {"nosyslog",  no_argument,       (int *) 0, LA_NOSYSLOG },
74   {"fetchmailrc",required_argument,(int *) 0, 'f' },
75   {"idfile",    required_argument, (int *) 0, 'i' },
76   {"postmaster",required_argument, (int *) 0, LA_POSTMASTER },
77   {"nobounce",  no_argument,       (int *) 0, LA_NOBOUNCE },
78
79   {"protocol",  required_argument, (int *) 0, 'p' },
80   {"proto",     required_argument, (int *) 0, 'p' },
81   {"uidl",      no_argument,       (int *) 0, 'U' },
82   {"idle",      no_argument,       (int *) 0, LA_IDLE},
83   {"port",      required_argument, (int *) 0, 'P' },
84   {"service",   required_argument, (int *) 0, 'P' },
85   {"auth",      required_argument, (int *) 0, LA_AUTH},
86   {"timeout",   required_argument, (int *) 0, 't' },
87   {"envelope",  required_argument, (int *) 0, 'E' },
88   {"qvirtual",  required_argument, (int *) 0, 'Q' },
89
90   {"user",      required_argument, (int *) 0, 'u' },
91   {"username",  required_argument, (int *) 0, 'u' },
92
93   {"all",       no_argument,       (int *) 0, 'a' },
94   {"nokeep",    no_argument,       (int *) 0, 'K' },
95   {"keep",      no_argument,       (int *) 0, 'k' },
96   {"flush",     no_argument,       (int *) 0, 'F' },
97   {"limitflush",        no_argument, (int *) 0, LA_LIMITFLUSH },
98   {"norewrite", no_argument,       (int *) 0, 'n' },
99   {"limit",     required_argument, (int *) 0, 'l' },
100   {"warnings",  required_argument, (int *) 0, 'w' },
101
102   {"folder",    required_argument, (int *) 0, 'r' },
103   {"smtphost",  required_argument, (int *) 0, 'S' },
104   {"fetchdomains",      required_argument, (int *) 0, LA_FETCHDOMAINS },
105   {"smtpaddress", required_argument, (int *) 0, 'D' },
106   {"smtpname",  required_argument, (int *) 0, LA_SMTPNAME },
107   {"antispam",  required_argument, (int *) 0, 'Z' },
108
109   {"batchlimit",required_argument, (int *) 0, 'b' },
110   {"fetchlimit",required_argument, (int *) 0, 'B' },
111   {"fetchsizelimit",required_argument, (int *) 0, LA_FETCHSIZELIMIT },
112   {"fastuidl",  required_argument, (int *) 0, LA_FASTUIDL },
113   {"expunge",   required_argument, (int *) 0, 'e' },
114   {"mda",       required_argument, (int *) 0, 'm' },
115   {"bsmtp",     required_argument, (int *) 0, LA_BSMTP },
116   {"lmtp",      no_argument,       (int *) 0, LA_LMTP },
117
118 #ifdef SSL_ENABLE
119   {"ssl",       no_argument,       (int *) 0, LA_SSL },
120   {"sslkey",    required_argument, (int *) 0, LA_SSLKEY },
121   {"sslcert",   required_argument, (int *) 0, LA_SSLCERT },
122   {"sslproto",   required_argument, (int *) 0, LA_SSLPROTO },
123   {"sslcertck", no_argument,       (int *) 0, LA_SSLCERTCK },
124   {"sslcertpath",   required_argument, (int *) 0, LA_SSLCERTPATH },
125   {"sslfingerprint",   required_argument, (int *) 0, LA_SSLFINGERPRINT },
126 #endif
127
128   {"principal", required_argument, (int *) 0, LA_PRINCIPAL },
129
130 #ifdef CAN_MONITOR
131   {"interface", required_argument, (int *) 0, 'I' },
132   {"monitor",   required_argument, (int *) 0, 'M' },
133 #endif /* CAN_MONITOR */
134   {"plugin",    required_argument, (int *) 0, LA_PLUGIN },
135   {"plugout",   required_argument, (int *) 0, LA_PLUGOUT },
136
137   {"configdump",no_argument,       (int *) 0, LA_CONFIGDUMP },
138
139   {"yydebug",   no_argument,       (int *) 0, 'y' },
140
141   {"tracepolls",no_argument,       (int *) 0, LA_TRACEPOLLS },
142
143   {(char *) 0,  no_argument,       (int *) 0, 0 }
144 };
145
146 static int xatoi(char *s, int *errflagptr)
147 /* do safe conversion from string to number */
148 {
149 #if defined (STDC_HEADERS) && defined (LONG_MAX) && defined (INT_MAX)
150     /* parse and convert numbers, but also check for invalid characters in
151      * numbers
152      */
153
154     char *endptr;
155     long value;
156
157     errno = 0;
158
159     value = strtol(s, &endptr, 0);
160
161     /* any invalid chars in string? */
162     if ( (endptr == s) || (*endptr != '\0') ) {
163         (void) fprintf(stderr, GT_("String '%s' is not a valid number string.\n"), s);
164         (*errflagptr)++;
165         return 0;
166     }
167
168     /* is the range valid? */
169     if ( (((value == LONG_MAX) || (value == LONG_MIN)) && (errno == ERANGE)) ||
170                                 (value > INT_MAX) || (value < INT_MIN)) {
171
172         (void) fprintf(stderr, GT_("Value of string '%s' is %s than %d.\n"), s,
173                                         (value < 0) ? GT_("smaller"): GT_("larger"),
174                                         (value < 0) ? INT_MIN : INT_MAX);
175         (*errflagptr)++;
176         return 0;
177     }
178
179     return (int) value;  /* shut up, I know what I'm doing */
180 #else
181     int i;
182     char *dp;
183 # if defined (STDC_HEADERS)
184     size_t      len;
185 # else
186     int         len;
187 # endif
188
189     /* We do only base 10 conversions here (atoi)! */
190
191     len = strlen(s);
192     /* check for leading white spaces */
193     for (i = 0; (i < len) && isspace((unsigned char)s[i]); i++)
194         ;
195
196     dp = &s[i];
197
198     /* check for +/- */
199     if (i < len && (s[i] == '+' || s[i] == '-'))        i++;
200
201     /* skip over digits */
202     for ( /* no init */ ; (i < len) && isdigit((unsigned char)s[i]); i++)
203         ;
204
205     /* check for trailing garbage */
206     if (i != len) {
207         (void) fprintf(stderr, GT_("String '%s' is not a valid number string.\n"), s);
208         (*errflagptr)++;
209         return 0;
210     }
211
212     /* atoi should be safe by now, except for number range over/underflow */
213     return atoi(dp);
214 #endif
215 }
216
217 int parsecmdline (argc, argv, rctl, ctl)
218 /* parse and validate the command line options */
219 int argc;               /* argument count */
220 char **argv;            /* argument strings */
221 struct runctl *rctl;    /* global run controls to modify */
222 struct query *ctl;      /* option record to be initialized */
223 {
224     /*
225      * return value: if positive, argv index of last parsed option + 1
226      * (presumes one or more server names follows).  if zero, the
227      * command line switches are such that no server names are
228      * required (e.g. --version).  if negative, the command line is
229      * has one or more syntax errors.
230      */
231
232     int c;
233     int ocount = 0;     /* count of destinations specified */
234     int errflag = 0;    /* TRUE when a syntax error is detected */
235     int helpflag = 0;   /* TRUE when option help was explicitly requested */
236     int option_index;
237     char *buf, *cp;
238
239     rctl->poll_interval = -1;
240
241     memset(ctl, '\0', sizeof(struct query));    /* start clean */
242     ctl->smtp_socket = -1;
243
244     while (!errflag && 
245            (c = getopt_long(argc,argv,shortoptions,
246                             longoptions, &option_index)) != -1)
247     {
248         switch (c) {
249         case 'V':
250             versioninfo = TRUE;
251             break;
252         case 'c':
253             check_only = TRUE;
254             break;
255         case 's':
256             outlevel = O_SILENT;
257             break;
258         case 'v':
259             if (outlevel >= O_VERBOSE)
260                 outlevel = O_DEBUG;
261             else
262                 outlevel = O_VERBOSE;
263             break;
264         case 'd':
265             rctl->poll_interval = xatoi(optarg, &errflag);
266             break;
267         case 'N':
268             nodetach = TRUE;
269             break;
270         case 'q':
271             quitmode = TRUE;
272             quitind = optind;
273             break;
274         case 'L':
275             rctl->logfile = prependdir (optarg, currentwd);
276             break;
277         case LA_INVISIBLE:
278             rctl->invisible = TRUE;
279             break;
280         case LA_SHOWDOTS:
281             rctl->showdots = FLAG_TRUE;
282             break;
283         case 'f':
284             xfree(rcfile);
285             rcfile = prependdir (optarg, currentwd);
286             break;
287         case 'i':
288             rctl->idfile = prependdir (optarg, currentwd);
289             break;
290         case LA_POSTMASTER:
291             rctl->postmaster = (char *) xstrdup(optarg);
292             break;
293         case LA_NOBOUNCE:
294             run.bouncemail = FALSE;
295             break;
296         case 'p':
297             /* XXX -- should probably use a table lookup here */
298             if (strcasecmp(optarg,"auto") == 0)
299                 ctl->server.protocol = P_AUTO;
300             else if (strcasecmp(optarg,"pop2") == 0)
301                 ctl->server.protocol = P_POP2;
302 #ifdef SDPS_ENABLE
303             else if (strcasecmp(optarg,"sdps") == 0)
304             {
305                 ctl->server.protocol = P_POP3; 
306                 ctl->server.sdps = TRUE;
307             }
308 #endif /* SDPS_ENABLE */
309             else if (strcasecmp(optarg,"pop3") == 0)
310                 ctl->server.protocol = P_POP3;
311             else if (strcasecmp(optarg,"apop") == 0)
312                 ctl->server.protocol = P_APOP;
313             else if (strcasecmp(optarg,"rpop") == 0)
314                 ctl->server.protocol = P_RPOP;
315             else if (strcasecmp(optarg,"kpop") == 0)
316             {
317                 ctl->server.protocol = P_POP3;
318                 ctl->server.service = KPOP_PORT;
319 #ifdef KERBEROS_V5
320                 ctl->server.authenticate =  A_KERBEROS_V5;
321 #else
322                 ctl->server.authenticate =  A_KERBEROS_V4;
323 #endif /* KERBEROS_V5 */
324             }
325             else if (strcasecmp(optarg,"imap") == 0)
326                 ctl->server.protocol = P_IMAP;
327             else if (strcasecmp(optarg,"etrn") == 0)
328                 ctl->server.protocol = P_ETRN;
329             else if (strcasecmp(optarg,"odmr") == 0)
330                 ctl->server.protocol = P_ODMR;
331             else {
332                 fprintf(stderr,GT_("Invalid protocol `%s' specified.\n"), optarg);
333                 errflag++;
334             }
335             break;
336         case 'U':
337             ctl->server.uidl = FLAG_TRUE;
338             break;
339         case LA_IDLE:
340             ctl->idle = FLAG_TRUE;
341             break;
342         case 'P':
343             ctl->server.service = optarg;
344             break;
345         case LA_AUTH:
346             if (strcmp(optarg, "password") == 0)
347                 ctl->server.authenticate = A_PASSWORD;
348             else if (strcmp(optarg, "kerberos") == 0)
349 #ifdef KERBEROS_V5
350                 ctl->server.authenticate = A_KERBEROS_V5;
351 #else
352                 ctl->server.authenticate = A_KERBEROS_V4;
353 #endif /* KERBEROS_V5 */
354             else if (strcmp(optarg, "kerberos_v5") == 0)
355                 ctl->server.authenticate = A_KERBEROS_V5;
356             else if (strcmp(optarg, "kerberos_v4") == 0)
357                 ctl->server.authenticate = A_KERBEROS_V4;
358             else if (strcmp(optarg, "ssh") == 0)
359                 ctl->server.authenticate = A_SSH;
360             else if (strcmp(optarg, "otp") == 0)
361                 ctl->server.authenticate = A_OTP;
362             else if (strcmp(optarg, "opie") == 0)
363                 ctl->server.authenticate = A_OTP;
364             else if (strcmp(optarg, "ntlm") == 0)
365                 ctl->server.authenticate = A_NTLM;
366             else if (strcmp(optarg, "cram") == 0)
367                 ctl->server.authenticate = A_CRAM_MD5;
368             else if (strcmp(optarg, "cram-md5") == 0)
369                 ctl->server.authenticate = A_CRAM_MD5;
370             else if (strcmp(optarg, "gssapi") == 0)
371                 ctl->server.authenticate = A_GSSAPI;
372             else if (strcmp(optarg, "any") == 0)
373                 ctl->server.authenticate = A_ANY;
374             else if (strcmp(optarg, "msn") == 0)
375                 ctl->server.authenticate = A_MSN;
376             else {
377                 fprintf(stderr,GT_("Invalid authentication `%s' specified.\n"), optarg);
378                 errflag++;
379             }
380             break;
381         case 't':
382             ctl->server.timeout = xatoi(optarg, &errflag);
383             if (ctl->server.timeout == 0)
384                 ctl->server.timeout = -1;
385             break;
386         case 'E':
387             ctl->server.envelope = xstrdup(optarg);
388             break;
389         case 'Q':    
390             ctl->server.qvirtual = xstrdup(optarg);
391             break;
392
393         case 'u':
394             ctl->remotename = xstrdup(optarg);
395             break;
396         case 'a':
397             ctl->fetchall = FLAG_TRUE;
398             break;
399         case 'K':
400             ctl->keep = FLAG_FALSE;
401             break;
402         case 'k':
403             ctl->keep = FLAG_TRUE;
404             break;
405         case 'F':
406             ctl->flush = FLAG_TRUE;
407             break;
408         case LA_LIMITFLUSH:
409             ctl->limitflush = FLAG_TRUE;
410             break;
411         case 'n':
412             ctl->rewrite = FLAG_FALSE;
413             break;
414         case 'l':
415             c = xatoi(optarg, &errflag);
416             ctl->limit = NUM_VALUE_IN(c);
417             break;
418         case 'r':
419             buf = xstrdup(optarg);
420             cp = strtok(buf, ",");
421             do {
422                 save_str(&ctl->mailboxes, cp, 0);
423             } while
424                 ((cp = strtok((char *)NULL, ",")));
425             free(buf);
426             break;
427         case 'S':
428             buf = xstrdup(optarg);
429             cp = strtok(buf, ",");
430             do {
431                 save_str(&ctl->smtphunt, cp, TRUE);
432             } while
433                 ((cp = strtok((char *)NULL, ",")));
434             free(buf);
435             ocount++;
436             break;
437         case LA_FETCHDOMAINS:
438             buf = xstrdup(optarg);
439             cp = strtok(buf, ",");
440             do {
441                 save_str(&ctl->domainlist, cp, TRUE);
442             } while
443                 ((cp = strtok((char *)NULL, ",")));
444             free(buf);
445             break;
446         case 'D':
447             ctl->smtpaddress = xstrdup(optarg);
448             break;
449         case LA_SMTPNAME:
450           ctl->smtpname = xstrdup(optarg);
451           break;
452         case 'Z':
453             buf = xstrdup(optarg);
454             cp = strtok(buf, ",");
455             do {
456                 struct idlist   *idp = save_str(&ctl->antispam, NULL, 0);;
457
458                 idp->val.status.num = xatoi(cp, &errflag);
459             } while
460                 ((cp = strtok((char *)NULL, ",")));
461             free(buf);
462             break;
463         case 'b':
464             c = xatoi(optarg, &errflag);
465             ctl->batchlimit = NUM_VALUE_IN(c);
466             break;
467         case 'B':
468             c = xatoi(optarg, &errflag);
469             ctl->fetchlimit = NUM_VALUE_IN(c);
470             break;
471         case LA_FETCHSIZELIMIT:
472             c = xatoi(optarg, &errflag);
473             ctl->fetchsizelimit = NUM_VALUE_IN(c);
474             break;
475         case LA_FASTUIDL:
476             c = xatoi(optarg, &errflag);
477             ctl->fastuidl = NUM_VALUE_IN(c);
478             break;
479         case 'e':
480             c = xatoi(optarg, &errflag);
481             ctl->expunge = NUM_VALUE_IN(c);
482             break;
483         case 'm':
484             ctl->mda = xstrdup(optarg);
485             ocount++;
486             break;
487         case LA_BSMTP:
488             ctl->bsmtp = prependdir (optarg, currentwd);
489             ocount++;
490             break;
491         case LA_LMTP:
492             ctl->listener = LMTP_MODE;
493             break;
494
495 #ifdef CAN_MONITOR
496         case 'I':
497             interface_parse(optarg, &ctl->server);
498             break;
499         case 'M':
500             ctl->server.monitor = xstrdup(optarg);
501             break;
502 #endif /* CAN_MONITOR */
503         case LA_PLUGIN:
504             ctl->server.plugin = xstrdup(optarg);
505             break;
506         case LA_PLUGOUT:
507             ctl->server.plugout = xstrdup(optarg);
508             break;
509
510 #ifdef SSL_ENABLE
511         case LA_SSL:
512             ctl->use_ssl = FLAG_TRUE;
513             break;
514
515         case LA_SSLKEY:
516             ctl->sslkey = prependdir (optarg, currentwd);
517             break;
518
519         case LA_SSLCERT:
520             ctl->sslcert = prependdir (optarg, currentwd);
521             break;
522
523         case LA_SSLPROTO:
524             ctl->sslproto = xstrdup(optarg);
525             break;
526
527         case LA_SSLCERTCK:
528             ctl->sslcertck = FLAG_TRUE;
529             break;
530
531         case LA_SSLCERTPATH:
532             ctl->sslcertpath = prependdir(optarg, currentwd);
533             break;
534
535         case LA_SSLFINGERPRINT:
536             ctl->sslfingerprint = xstrdup(optarg);
537             break;
538 #endif
539
540         case LA_PRINCIPAL:
541             ctl->server.principal = xstrdup(optarg);
542             break;
543
544         case 'y':
545             yydebug = TRUE;
546             break;
547
548         case 'w':
549             c = xatoi(optarg, &errflag);
550             ctl->warnings = NUM_VALUE_IN(c);
551             break;
552
553         case LA_CONFIGDUMP:
554             configdump = TRUE;
555             break;
556
557         case LA_SYSLOG:
558             rctl->use_syslog = FLAG_TRUE;
559             break;
560
561         case LA_NOSYSLOG:
562             rctl->use_syslog = FLAG_FALSE;
563             break;
564
565         case LA_TRACEPOLLS:
566             ctl->server.tracepolls = FLAG_TRUE;
567             break;
568
569         case '?':
570         default:
571             helpflag++;
572         }
573     }
574
575     if (errflag || ocount > 1 || helpflag) {
576         /* squawk if syntax errors were detected */
577 #define P(s)    fputs(s, helpflag ? stdout : stderr)
578         P(GT_("usage:  fetchmail [options] [server ...]\n"));
579         P(GT_("  Options are as follows:\n"));
580         P(GT_("  -?, --help        display this option help\n"));
581         P(GT_("  -V, --version     display version info\n"));
582
583         P(GT_("  -c, --check       check for messages without fetching\n"));
584         P(GT_("  -s, --silent      work silently\n"));
585         P(GT_("  -v, --verbose     work noisily (diagnostic output)\n"));
586         P(GT_("  -d, --daemon      run as a daemon once per n seconds\n"));
587         P(GT_("  -N, --nodetach    don't detach daemon process\n"));
588         P(GT_("  -q, --quit        kill daemon process\n"));
589         P(GT_("  -L, --logfile     specify logfile name\n"));
590         P(GT_("      --syslog      use syslog(3) for most messages when running as a daemon\n"));
591         P(GT_("      --invisible   don't write Received & enable host spoofing\n"));
592         P(GT_("  -f, --fetchmailrc specify alternate run control file\n"));
593         P(GT_("  -i, --idfile      specify alternate UIDs file\n"));
594         P(GT_("      --postmaster  specify recipient of last resort\n"));
595         P(GT_("      --nobounce    redirect bounces from user to postmaster.\n"));
596 #ifdef CAN_MONITOR
597         P(GT_("  -I, --interface   interface required specification\n"));
598         P(GT_("  -M, --monitor     monitor interface for activity\n"));
599 #endif
600 #if defined( SSL_ENABLE )
601         P(GT_("      --ssl         enable ssl encrypted session\n"));
602         P(GT_("      --sslkey      ssl private key file\n"));
603         P(GT_("      --sslcert     ssl client certificate\n"));
604         P(GT_("      --sslcertck   do strict server certificate check (recommended)\n"));
605         P(GT_("      --sslcertpath path to ssl certificates\n"));
606         P(GT_("      --sslfingerprint fingerprint that must match that of the server's cert.\n"));
607         P(GT_("      --sslproto    force ssl protocol (ssl2/ssl3/tls1)\n"));
608 #endif
609         P(GT_("      --plugin      specify external command to open connection\n"));
610         P(GT_("      --plugout     specify external command to open smtp connection\n"));
611
612         P(GT_("  -p, --protocol    specify retrieval protocol (see man page)\n"));
613         P(GT_("  -U, --uidl        force the use of UIDLs (pop3 only)\n"));
614         P(GT_("      --port        TCP port to connect to (obsolete, use --service)\n"));
615         P(GT_("  -P, --service     TCP service to connect to (can be numeric TCP port)\n"));
616         P(GT_("      --auth        authentication type (password/kerberos/ssh/otp)\n"));
617         P(GT_("  -t, --timeout     server nonresponse timeout\n"));
618         P(GT_("  -E, --envelope    envelope address header\n"));
619         P(GT_("  -Q, --qvirtual    prefix to remove from local user id\n"));
620         P(GT_("      --principal   mail service principal\n"));
621         P(GT_("      --tracepolls  add poll-tracing information to Received header\n"));
622
623         P(GT_("  -u, --username    specify users's login on server\n"));
624         P(GT_("  -a, --all         retrieve old and new messages\n"));
625         P(GT_("  -K, --nokeep      delete new messages after retrieval\n"));
626         P(GT_("  -k, --keep        save new messages after retrieval\n"));
627         P(GT_("  -F, --flush       delete old messages from server\n"));
628         P(GT_("      --limitflush  delete oversized messages\n"));
629         P(GT_("  -n, --norewrite   don't rewrite header addresses\n"));
630         P(GT_("  -l, --limit       don't fetch messages over given size\n"));
631         P(GT_("  -w, --warnings    interval between warning mail notification\n"));
632
633         P(GT_("  -S, --smtphost    set SMTP forwarding host\n"));
634         P(GT_("      --fetchdomains fetch mail for specified domains\n"));
635         P(GT_("  -D, --smtpaddress set SMTP delivery domain to use\n"));
636         P(GT_("      --smtpname    set SMTP full name username@domain\n"));
637         P(GT_("  -Z, --antispam,   set antispam response values\n"));
638         P(GT_("  -b, --batchlimit  set batch limit for SMTP connections\n"));
639         P(GT_("  -B, --fetchlimit  set fetch limit for server connections\n"));
640         P(GT_("      --fetchsizelimit set fetch message size limit\n"));
641         P(GT_("      --fastuidl    do a binary search for UIDLs\n"));
642         P(GT_("  -e, --expunge     set max deletions between expunges\n"));
643         P(GT_("  -m, --mda         set MDA to use for forwarding\n"));
644         P(GT_("      --bsmtp       set output BSMTP file\n"));
645         P(GT_("      --lmtp        use LMTP (RFC2033) for delivery\n"));
646         P(GT_("  -r, --folder      specify remote folder name\n"));
647         P(GT_("      --showdots    show progress dots even in logfiles\n"));
648 #undef P
649         /* undocumented:
650          * --configdump (internal use by fetchmailconf, dumps
651          *               configuration as Python source code)
652          * --yydebug    (developer use, enables parser debugging) */
653
654         if (helpflag)
655             exit(PS_SUCCESS);
656         else
657             exit(PS_SYNTAX);
658     }
659
660     return(optind);
661 }
662
663 /* options.c ends here */