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