| 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 */ |