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