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 PROTOCOL AUTHENTICATE TIMEOUT KPOP KERBEROS
45 %token USERNAME PASSWORD FOLDER SMTPHOST MDA IS HERE THERE TO MAP LIMIT
49 %token <number> NUMBER
50 %token <flag> KEEP FLUSH FETCHALL REWRITE PORT SKIP
52 /* these are actually used by the lexer */
62 statement_list : statement
63 | statement_list statement
66 /* future global options should also have the form SET <name> <value> */
67 statement : define_server serverspecs userspecs
68 | SET BATCHLIMIT MAP NUMBER {batchlimit = $4;}
71 define_server : POLL STRING {strcpy(current.servername, $2);}
72 | SKIP STRING {strcpy(current.servername, $2);
73 current.skip=($1==FLAG_TRUE);}
74 | DEFAULTS {strcpy(current.servername,"defaults");}
77 serverspecs : /* EMPTY */
78 | serverspecs serv_option
81 serv_option : PROTOCOL PROTO {current.protocol = $2;}
83 current.protocol = P_POP3;
84 current.authenticate = A_KERBEROS;
85 current.port = KPOP_PORT;
87 | PORT NUMBER {current.port = $2;}
88 | AUTHENTICATE PASSWORD {current.authenticate = A_PASSWORD;}
89 | AUTHENTICATE KERBEROS {current.authenticate = A_KERBEROS;}
90 | TIMEOUT NUMBER {current.timeout = $2;}
93 /* the first and only the first user spec may omit the USERNAME part */
94 userspecs : /* EMPTY */
95 | user1opts {prc_register(); prc_reset();}
96 | user1opts explicits {prc_register(); prc_reset();}
100 explicits : explicitdef {prc_register(); prc_reset();}
101 | explicits explicitdef {prc_register(); prc_reset();}
104 explicitdef : userdef user0opts
107 userdef : USERNAME STRING {strcpy(current.remotename, $2);}
108 | USERNAME mapping_list HERE
109 | USERNAME STRING THERE {strcpy(current.remotename, $2);}
112 user0opts : /* EMPTY */
113 | user0opts user_option
116 user1opts : user_option
117 | user1opts user_option
120 mapping_list : mapping
121 | mapping_list mapping
125 {save_id_pair(¤t.localnames, $1, NULL);}
127 {save_id_pair(¤t.localnames, $1, $3);}
130 user_option : TO mapping_list HERE
132 | IS mapping_list HERE
134 | IS STRING THERE {strcpy(current.remotename, $2);}
135 | PASSWORD STRING {strcpy(current.password, $2);}
136 | FOLDER STRING {strcpy(current.mailbox, $2);}
137 | SMTPHOST STRING {strcpy(current.smtphost, $2);}
138 | MDA STRING {strcpy(current.mda, $2);}
140 | KEEP {current.keep = ($1==FLAG_TRUE);}
141 | FLUSH {current.flush = ($1==FLAG_TRUE);}
142 | FETCHALL {current.fetchall = ($1==FLAG_TRUE);}
143 | REWRITE {current.norewrite = ($1==FLAG_TRUE);}
144 | LIMIT NUMBER {current.limit = $2;}
148 /* lexer interface */
150 extern int prc_lineno;
154 static struct query *hosttail; /* where to add new elements */
157 /* report a syntax error */
158 char *s; /* error string */
160 fprintf(stderr,"%s line %d: %s at %s\n", rcfile, prc_lineno, s, yytext);
164 int prc_filecheck(pathname)
165 /* check that a configuration file is secure */
166 const char *pathname; /* pathname for the configuration file */
170 /* the run control file must have the same uid as the REAL uid of this
171 process, it must have permissions no greater than 600, and it must not
172 be a symbolic link. We check these conditions here. */
175 if (lstat(pathname, &statbuf) < 0) {
184 if ((statbuf.st_mode & S_IFLNK) == S_IFLNK) {
185 fprintf(stderr, "File %s must not be a symbolic link.\n", pathname);
189 if (statbuf.st_mode & ~(S_IFREG | S_IREAD | S_IWRITE)) {
190 fprintf(stderr, "File %s must have no more than -rw------ permissions.\n",
195 if (statbuf.st_uid != getuid()) {
196 fprintf(stderr, "File %s must be owned by you.\n", pathname);
203 int prc_parse_file (pathname)
204 /* digest the configuration into a linked list of host records */
205 const char *pathname; /* pathname for the configuration file */
208 querylist = hosttail = (struct query *)NULL;
211 /* Check that the file is secure */
212 if ((prc_errflag = prc_filecheck(pathname)) != 0)
218 /* Open the configuration and feed it to the lexer. */
219 if ((yyin = fopen(pathname,"r")) == (FILE *)NULL) {
224 yyparse(); /* parse entire file */
234 static void prc_reset()
235 /* clear the global current record (server parameters) used by the parser */
237 char savename[HOSTLEN+1];
238 int saveport, saveproto, saveauth, saveskip;
241 * Purpose of this code is to initialize the new server block, but
242 * preserve whatever server name was previously set. Also
243 * preserve server options unless the command-line explicitly
246 (void) strcpy(savename, current.servername);
247 saveport = current.port;
248 saveproto = current.protocol;
249 saveauth = current.authenticate;
250 saveskip = current.skip;
252 memset(¤t, '\0', sizeof(current));
254 (void) strcpy(current.servername, savename);
255 current.protocol = saveproto;
256 current.authenticate = saveauth;
257 current.skip = saveskip;
260 struct query *hostalloc(init)
261 /* append a host record to the host list */
262 struct query *init; /* pointer to block containing initial values */
266 /* allocate new node */
267 node = (struct query *) xmalloc(sizeof(struct query));
270 memcpy(node, init, sizeof(struct query));
272 /* append to end of list */
273 if (hosttail != (struct query *) 0)
274 hosttail->next = node; /* list contains at least one element */
276 querylist = node; /* list is empty */
281 static void prc_register()
282 /* register current parameters and append to the host list */
284 #define STR_FORCE(fld, len) if (cmd_opts.fld[0]) \
285 strcpy(current.fld, cmd_opts.fld)
286 STR_FORCE(remotename, USERNAMELEN);
287 STR_FORCE(password, PASSWORDLEN);
288 STR_FORCE(mailbox, FOLDERLEN);
289 STR_FORCE(smtphost, HOSTLEN);
290 STR_FORCE(mda, MDALEN);
293 #define FLAG_FORCE(fld) if (cmd_opts.fld) current.fld = cmd_opts.fld
294 FLAG_FORCE(protocol);
297 FLAG_FORCE(fetchall);
298 FLAG_FORCE(norewrite);
301 FLAG_FORCE(authenticate);
306 (void) hostalloc(¤t);
309 void optmerge(h2, h1)
310 /* merge two options records; empty fields in h2 are filled in from h1 */
314 append_uid_list(&h2->localnames, &h1->localnames);
316 #define STR_MERGE(fld, len) if (*(h2->fld) == '\0') strcpy(h2->fld, h1->fld)
317 STR_MERGE(remotename, USERNAMELEN);
318 STR_MERGE(password, PASSWORDLEN);
319 STR_MERGE(mailbox, FOLDERLEN);
320 STR_MERGE(smtphost, HOSTLEN);
321 STR_MERGE(mda, MDALEN);
324 #define FLAG_MERGE(fld) if (!h2->fld) h2->fld = h1->fld
325 FLAG_MERGE(protocol);
328 FLAG_MERGE(fetchall);
329 FLAG_MERGE(norewrite);
332 FLAG_MERGE(authenticate);
339 /* easier to do this than cope with variations in where the library lives */
340 int yywrap() {return 1;}
342 /* rcfile_y.y ends here */