]> Pileus Git - ~andy/fetchmail/blob - options.c
Add settable server-nonresponse timeout
[~andy/fetchmail] / options.c
1 /*
2  * For license terms, see the file COPYING in this directory.
3  */
4
5 /***********************************************************************
6   module:       options.c
7   project:      fetchmail
8   programmer:   Eric S. Raymond, <esr@thyrsus.com>
9   description:  command-line option processing
10
11  ***********************************************************************/
12
13 #include <config.h>
14 #include <stdio.h>
15 #include <pwd.h>
16
17 #include "getopt.h"
18 #include "fetchmail.h"
19
20 #define LA_HELP         1
21 #define LA_VERSION      2 
22 #define LA_CHECK        3
23 #define LA_SILENT       4 
24 #define LA_VERBOSE      5 
25 #define LA_DAEMON       6
26 #define LA_QUIT         7
27 #define LA_LOGFILE      8
28 #define LA_RCFILE       9
29 #define LA_IDFILE       10
30 #define LA_PROTOCOL     11
31 #define LA_PORT         12
32 #define LA_AUTHENTICATE 13
33 #define LA_TIMEOUT      14
34 #define LA_USERNAME     15
35 #define LA_ALL          16
36 #define LA_KILL         17
37 #define LA_KEEP         18
38 #define LA_FLUSH        19
39 #define LA_NOREWRITE    20
40 #define LA_REMOTEFILE   21
41 #define LA_SMTPHOST     22
42 #define LA_MDA          23
43 #define LA_YYDEBUG      24
44
45 static char *shortoptions = "?Vcsvd:qL:f:i:p:P:A:t:u:akKFnr:S:m:y";
46 static struct option longoptions[] = {
47   {"help",      no_argument,       (int *) 0, LA_HELP        },
48   {"version",   no_argument,       (int *) 0, LA_VERSION     },
49   {"check",     no_argument,       (int *) 0, LA_CHECK       },
50   {"silent",    no_argument,       (int *) 0, LA_SILENT      },
51   {"verbose",   no_argument,       (int *) 0, LA_VERBOSE     },
52   {"daemon",    required_argument, (int *) 0, LA_DAEMON      },
53   {"quit",      no_argument,       (int *) 0, LA_QUIT        },
54   {"logfile",   required_argument, (int *) 0, LA_LOGFILE     },
55   {"fetchmailrc",required_argument,(int *) 0, LA_RCFILE      },
56   {"idfile",    required_argument, (int *) 0, LA_IDFILE      },
57
58   {"protocol",  required_argument, (int *) 0, LA_PROTOCOL    },
59   {"proto",     required_argument, (int *) 0, LA_PROTOCOL    },
60   {"port",      required_argument, (int *) 0, LA_PORT        },
61   {"auth",      required_argument, (int *) 0, LA_AUTHENTICATE},
62   {"timeout",   required_argument, (int *) 0, LA_TIMEOUT     },
63
64   {"user",      required_argument, (int *) 0, LA_USERNAME    },
65   {"username",  required_argument, (int *) 0, LA_USERNAME    },
66
67   {"all",       no_argument,       (int *) 0, LA_ALL         },
68   {"kill",      no_argument,       (int *) 0, LA_KILL        },
69   {"keep",      no_argument,       (int *) 0, LA_KEEP        },
70   {"flush",     no_argument,       (int *) 0, LA_FLUSH       },
71   {"norewrite", no_argument,       (int *) 0, LA_NOREWRITE   },
72
73   {"remote",    required_argument, (int *) 0, LA_REMOTEFILE  },
74   {"smtphost",  required_argument, (int *) 0, LA_SMTPHOST    },
75   {"mda",       required_argument, (int *) 0, LA_MDA         },
76
77   {"yydebug",   no_argument,       (int *) 0, LA_YYDEBUG     },
78
79   {(char *) 0,  no_argument,       (int *) 0, 0              }
80 };
81
82
83 /*********************************************************************
84   function:      parsecmdline
85   description:   parse/validate the command line options.
86   arguments:
87     argc         argument count.
88     argv         argument strings.
89     queryctl     pointer to a struct hostrec to receive the parsed 
90                  options.
91
92   return value:  if positive, argv index of last parsed option + 1
93                  (presumes one or more server names follows).
94                  if zero, the command line switches are such that
95                  no server names are required (e.g. --version).
96                  if negative, the command line is has one or more
97                  syntax errors.
98   calls:         none.  
99   globals:       writes outlevel, versioninfo, yydebug, logfile, 
100                  poll_interval, quitmode, rcfile
101  *********************************************************************/
102
103 int parsecmdline (argc,argv,queryctl)
104 int argc;
105 char **argv;
106 struct hostrec *queryctl;
107 {
108     int c;
109     int ocount = 0;     /* count of destinations specified */
110     int errflag = 0;   /* TRUE when a syntax error is detected */
111     int option_index;
112
113     memset(queryctl, '\0', sizeof(struct hostrec));    /* start clean */
114
115     while (!errflag && 
116            (c = getopt_long(argc,argv,shortoptions,
117                             longoptions,&option_index)) != -1) {
118
119         switch (c) {
120         case 'V':
121         case LA_VERSION:
122             versioninfo = TRUE;
123             break;
124         case 'c':
125         case LA_CHECK:
126             check_only = TRUE;
127             break;
128         case 's':
129         case LA_SILENT:
130             outlevel = O_SILENT;
131             break;
132         case 'v':
133         case LA_VERBOSE:
134             outlevel = O_VERBOSE;
135             break;
136         case 'd':
137         case LA_DAEMON:
138             poll_interval = atoi(optarg);
139             break;
140         case 'q':
141         case LA_QUIT:
142             quitmode = TRUE;
143             break;
144         case 'L':
145         case LA_LOGFILE:
146             logfile = optarg;
147             break;
148         case 'f':
149         case LA_RCFILE:
150             rcfile = (char *) xmalloc(strlen(optarg)+1);
151             strcpy(rcfile,optarg);
152             break;
153         case 'i':
154         case LA_IDFILE:
155             idfile = (char *) xmalloc(strlen(optarg)+1);
156             strcpy(idfile,optarg);
157             break;
158         case 'p':
159         case LA_PROTOCOL:
160             /* XXX -- should probably use a table lookup here */
161             if (strcasecmp(optarg,"pop2") == 0)
162                 queryctl->protocol = P_POP2;
163             else if (strcasecmp(optarg,"pop3") == 0)
164                 queryctl->protocol = P_POP3;
165             else if (strcasecmp(optarg,"imap") == 0)
166                 queryctl->protocol = P_IMAP;
167             else if (strcasecmp(optarg,"apop") == 0)
168                 queryctl->protocol = P_APOP;
169             else if (strcasecmp(optarg,"kpop") == 0)
170             {
171                 queryctl->protocol = P_POP3;
172                 queryctl->port = KPOP_PORT;
173                 queryctl->authenticate =  A_KERBEROS;
174             }
175             else {
176                 fprintf(stderr,"Invalid protocol `%s' specified.\n", optarg);
177                 errflag++;
178             }
179             break;
180         case 'P':
181         case LA_PORT:
182             queryctl->port = atoi(optarg);
183             break;
184         case 'A':
185         case LA_AUTHENTICATE:
186             if (strcmp(optarg, "password") == 0)
187                 queryctl->authenticate = A_PASSWORD;
188             else if (strcmp(optarg, "kerberos") == 0)
189                 queryctl->authenticate = A_KERBEROS;
190             else {
191                 fprintf(stderr,"Invalid authentication `%s' specified.\n", optarg);
192                 errflag++;
193             }
194             break;
195         case 't':
196             queryctl->timeout = atoi(optarg);
197             break;
198         case 'u':
199         case LA_USERNAME:
200             strncpy(queryctl->remotename,optarg,sizeof(queryctl->remotename)-1);
201             break;
202
203         case 'a':
204         case LA_ALL:
205             queryctl->fetchall = TRUE;
206             break;
207         case 'K':
208         case LA_KILL:
209             queryctl->keep = FALSE;
210             break;
211         case 'k':
212         case LA_KEEP:
213             queryctl->keep = TRUE;
214             break;
215         case 'F':
216         case LA_FLUSH:
217             queryctl->flush = TRUE;
218             break;
219         case 'n':
220         case LA_NOREWRITE:
221             queryctl->norewrite = TRUE;
222             break;
223         case 'r':
224         case LA_REMOTEFILE:
225             strncpy(queryctl->mailbox,optarg,sizeof(queryctl->mailbox)-1);
226             break;
227         case 'S':
228         case LA_SMTPHOST:
229             strncpy(queryctl->smtphost,optarg,sizeof(queryctl->smtphost)-1);
230             ocount++;
231             break;
232         case 'm':
233         case LA_MDA:
234             strncpy(queryctl->mda,optarg,sizeof(queryctl->mda));
235             ocount++;
236             break;
237         case 'y':
238         case LA_YYDEBUG:
239             yydebug = TRUE;
240             break;
241
242         case '?':
243         case LA_HELP:
244         default:
245             errflag++;
246         }
247     }
248
249     if (errflag || ocount > 1) {
250         /* squawk if syntax errors were detected */
251         fputs("usage:  fetchmail [options] [server ...]\n", stderr);
252         fputs("  Options are as follows:\n",stderr);
253         fputs("  -?, --help        display this option help\n", stderr);
254         fputs("  -V, --version     display version info\n", stderr);
255
256         fputs("  -c, --check       check for messages without fetching\n", stderr);
257         fputs("  -s, --silent      work silently\n", stderr);
258         fputs("  -v, --verbose     work noisily (diagnostic output)\n", stderr);
259         fputs("  -d, --daemon      run as a daemon once per n seconds\n", stderr);
260         fputs("  -q, --quit        kill daemon process\n", stderr);
261         fputs("  -L, --logfile     specify logfile name\n", stderr);
262         fputs("  -f, --fetchmailrc specify alternate run control file\n", stderr);
263         fputs("  -i, --idfile      specify alternate UIDs file\n", stderr);
264
265         fputs("  -p, --protocol    specify pop2, pop3, imap, apop, rpop, kpop\n", stderr);
266         fputs("  -P, --port        TCP/IP service port to connect to\n",stderr);
267         fputs("  -A, --auth        authentication type (password or kerberos)\n",stderr);
268         fputs("  -t, --timeout     server nonresponse timeout\n",stderr);
269
270         fputs("  -u, --username    specify users's login on server\n", stderr);
271         fputs("  -a, --all         retrieve old and new messages\n", stderr);
272         fputs("  -K, --kill        delete new messages after retrieval\n", stderr);
273         fputs("  -k, --keep        save new messages after retrieval\n", stderr);
274         fputs("  -F, --flush       delete old messages from server\n", stderr);
275         fputs("  -n, --norewrite    don't rewrite header addresses\n", stderr);
276
277         fputs("  -S, --smtphost    set SMTP forwarding host\n", stderr);
278         fputs("  -r, --remote      specify remote folder name\n", stderr);
279         return(-1);
280     }
281
282     return(optind);
283 }
284