3 * rcfile_y.y -- Run control file parser for fetchmail
5 * For license terms, see the file COPYING in this directory.
10 #include <sys/types.h>
15 #if defined(STDC_HEADERS)
18 #if defined(HAVE_UNISTD_H)
23 #include "fetchmail.h"
25 struct query cmd_opts; /* where to put command-line info */
26 struct query *querylist; /* head of server list (globally visible) */
28 int yydebug; /* in case we didn't generate with -- debug */
30 static struct query current; /* current server record */
31 static int prc_errflag;
33 static void prc_register();
34 static void prc_reset();
44 %token DEFAULTS POLL SKIP AKA LOCALDOMAINS PROTOCOL
45 %token AUTHENTICATE TIMEOUT KPOP KERBEROS
46 %token ENVELOPE USERNAME PASSWORD FOLDER SMTPHOST MDA PRECONNECT LIMIT
47 %token IS HERE THERE TO MAP WILDCARD
48 %token SET BATCHLIMIT FETCHLIMIT LOGFILE INTERFACE MONITOR
51 %token <number> NUMBER
52 %token <flag> KEEP FLUSH FETCHALL REWRITE STRIPCR DNS PORT
54 /* these are actually used by the lexer */
64 statement_list : statement
65 | statement_list statement
68 /* future global options should also have the form SET <name> <value> */
69 statement : SET LOGFILE MAP STRING {logfile = xstrdup($4);}
72 * The way the next two productions are written depends on the fact that
73 * userspecs cannot be empty. It's a kluge to deal with files that set
74 * up a load of defaults and then have poll statements following with no
75 * user options at all.
77 | define_server serverspecs {prc_register(); prc_reset();}
78 | define_server serverspecs userspecs
80 memset(¤t,'\0',sizeof(current));
85 define_server : POLL STRING {current.server.names = (struct idlist *)NULL;
86 save_str(¤t.server.names, -1,$2);
87 current.server.skip = FALSE;}
88 | SKIP STRING {current.server.names = (struct idlist *)NULL;
89 save_str(¤t.server.names, -1,$2);
90 current.server.skip = TRUE;}
91 | DEFAULTS {current.server.names = (struct idlist *)NULL;
92 save_str(¤t.server.names, -1,"defaults");}
95 serverspecs : /* EMPTY */
96 | serverspecs serv_option
99 alias_list : STRING {save_str(¤t.server.names,-1,$1);}
100 | alias_list STRING {save_str(¤t.server.names,-1,$2);}
103 domain_list : STRING {save_str(¤t.server.localdomains,-1,$1);}
104 | domain_list STRING {save_str(¤t.server.localdomains,-1,$2);}
107 serv_option : AKA alias_list
108 | LOCALDOMAINS domain_list
109 | PROTOCOL PROTO {current.server.protocol = $2;}
111 current.server.protocol = P_POP3;
112 current.server.authenticate = A_KERBEROS;
113 current.server.port = KPOP_PORT;
115 | PORT NUMBER {current.server.port = $2;}
116 | AUTHENTICATE PASSWORD {current.server.authenticate = A_PASSWORD;}
117 | AUTHENTICATE KERBEROS {current.server.authenticate = A_KERBEROS;}
118 | TIMEOUT NUMBER {current.server.timeout = $2;}
119 | ENVELOPE STRING {current.server.envelope = xstrdup($2);}
122 interface_parse($2, ¤t.server);
124 fprintf(stderr, "fetchmail: interface option is only supported under Linux\n");
129 current.server.monitor = xstrdup($2);
131 fprintf(stderr, "fetchmail: monitor option is only supported under Linux\n");
134 | DNS {current.server.no_dns = ($1==FLAG_FALSE);}
138 * The first and only the first user spec may omit the USERNAME part.
139 * This is a backward-compatibility kluge to allow old popclient files
142 userspecs : user1opts {prc_register(); prc_reset();}
143 | user1opts explicits {prc_register(); prc_reset();}
147 explicits : explicitdef {prc_register(); prc_reset();}
148 | explicits explicitdef {prc_register(); prc_reset();}
151 explicitdef : userdef user0opts
154 userdef : USERNAME STRING {current.remotename = xstrdup($2);}
155 | USERNAME mapping_list HERE
156 | USERNAME STRING THERE {current.remotename = xstrdup($2);}
159 user0opts : /* EMPTY */
160 | user0opts user_option
163 user1opts : user_option
164 | user1opts user_option
167 localnames : WILDCARD {current.wildcard = TRUE;}
168 | mapping_list {current.wildcard = FALSE;}
169 | mapping_list WILDCARD {current.wildcard = TRUE;}
172 mapping_list : mapping
173 | mapping_list mapping
177 {save_str_pair(¤t.localnames, $1, NULL);}
179 {save_str_pair(¤t.localnames, $1, $3);}
182 user_option : TO localnames HERE
187 | IS STRING THERE {current.remotename = xstrdup($2);}
188 | PASSWORD STRING {current.password = xstrdup($2);}
189 | FOLDER STRING {current.mailbox = xstrdup($2);}
190 | SMTPHOST STRING {current.smtphost = xstrdup($2);}
191 | MDA STRING {current.mda = xstrdup($2);}
192 | PRECONNECT STRING {current.preconnect = xstrdup($2);}
194 | KEEP {current.keep = ($1==FLAG_TRUE);}
195 | FLUSH {current.flush = ($1==FLAG_TRUE);}
196 | FETCHALL {current.fetchall = ($1==FLAG_TRUE);}
197 | REWRITE {current.no_rewrite =($1==FLAG_FALSE);}
198 | STRIPCR {current.stripcr = ($1==FLAG_TRUE);}
199 | LIMIT NUMBER {current.limit = $2;}
200 | FETCHLIMIT NUMBER {current.fetchlimit = $2;}
201 | BATCHLIMIT NUMBER {current.batchlimit = $2;}
205 /* lexer interface */
207 extern int prc_lineno;
211 static struct query *hosttail; /* where to add new elements */
213 void yyerror (const char *s)
214 /* report a syntax error */
216 fprintf(stderr,"%s line %d: %s at %s\n", rcfile, prc_lineno, s, yytext);
220 int prc_filecheck(pathname)
221 /* check that a configuration file is secure */
222 const char *pathname; /* pathname for the configuration file */
226 /* the run control file must have the same uid as the REAL uid of this
227 process, it must have permissions no greater than 600, and it must not
228 be a symbolic link. We check these conditions here. */
231 if (lstat(pathname, &statbuf) < 0) {
235 error(0, errno, "lstat: %s", pathname);
240 if ((statbuf.st_mode & S_IFLNK) == S_IFLNK) {
241 fprintf(stderr, "File %s must not be a symbolic link.\n", pathname);
245 if (statbuf.st_mode & ~(S_IFREG | S_IREAD | S_IWRITE)) {
246 fprintf(stderr, "File %s must have no more than -rw------ permissions.\n",
251 if (statbuf.st_uid != getuid()) {
252 fprintf(stderr, "File %s must be owned by you.\n", pathname);
259 int prc_parse_file (pathname)
260 /* digest the configuration into a linked list of host records */
261 const char *pathname; /* pathname for the configuration file */
264 querylist = hosttail = (struct query *)NULL;
267 /* Check that the file is secure */
268 if ((prc_errflag = prc_filecheck(pathname)) != 0)
274 /* Open the configuration and feed it to the lexer. */
275 if ((yyin = fopen(pathname,"r")) == (FILE *)NULL) {
276 error(0, errno, "open: %s", pathname);
280 yyparse(); /* parse entire file */
290 static void prc_reset(void)
291 /* clear the global current record (server parameters) used by the parser */
293 struct hostdata save;
296 * Purpose of this code is to initialize the new server block, but
297 * preserve whatever server name was previously set. Also
298 * preserve server options unless the command-line explicitly
301 save = current.server;
303 memset(¤t, '\0', sizeof(current));
305 current.server = save;
308 struct query *hostalloc(init)
309 /* append a host record to the host list */
310 struct query *init; /* pointer to block containing initial values */
314 /* allocate new node */
315 node = (struct query *) xmalloc(sizeof(struct query));
318 memcpy(node, init, sizeof(struct query));
320 /* append to end of list */
321 if (hosttail != (struct query *) 0)
322 hosttail->next = node; /* list contains at least one element */
324 querylist = node; /* list is empty */
329 static void prc_register(void)
330 /* register current parameters and append to the host list */
332 #define FLAG_FORCE(fld) if (cmd_opts.fld) current.fld = cmd_opts.fld
333 FLAG_FORCE(server.protocol);
334 FLAG_FORCE(server.port);
335 FLAG_FORCE(server.authenticate);
336 FLAG_FORCE(server.timeout);
337 FLAG_FORCE(server.envelope);
338 FLAG_FORCE(server.skip);
339 FLAG_FORCE(server.no_dns);
342 FLAG_FORCE(server.interface);
343 FLAG_FORCE(server.monitor);
344 FLAG_FORCE(server.interface_pair);
347 FLAG_FORCE(remotename);
348 FLAG_FORCE(password);
350 FLAG_FORCE(smtphost);
352 FLAG_FORCE(preconnect);
356 FLAG_FORCE(fetchall);
357 FLAG_FORCE(no_rewrite);
360 FLAG_FORCE(fetchlimit);
361 FLAG_FORCE(batchlimit);
365 (void) hostalloc(¤t);
368 void optmerge(struct query *h2, struct query *h1)
369 /* merge two options records; empty fields in h2 are filled in from h1 */
371 append_str_list(&h2->server.localdomains, &h1->server.localdomains);
372 append_str_list(&h2->localnames, &h1->localnames);
374 #define FLAG_MERGE(fld) if (!h2->fld) h2->fld = h1->fld
375 FLAG_MERGE(server.protocol);
376 FLAG_MERGE(server.port);
377 FLAG_MERGE(server.authenticate);
378 FLAG_MERGE(server.timeout);
379 FLAG_MERGE(server.envelope);
380 FLAG_MERGE(server.skip);
381 FLAG_MERGE(server.no_dns);
384 FLAG_MERGE(server.interface);
385 FLAG_MERGE(server.monitor);
386 FLAG_MERGE(server.interface_pair);
389 FLAG_MERGE(remotename);
390 FLAG_MERGE(password);
392 FLAG_MERGE(smtphost);
394 FLAG_MERGE(preconnect);
398 FLAG_MERGE(fetchall);
399 FLAG_MERGE(no_rewrite);
402 FLAG_MERGE(fetchlimit);
403 FLAG_MERGE(batchlimit);
407 /* easier to do this than cope with variations in where the library lives */
408 int yywrap(void) {return 1;}
410 /* rcfile_y.y ends here */