3 * $Id: parser.y,v 1.7 1999/03/26 15:25:22 mdw Exp $
5 * Parser for `become.conf' files
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of `become'
14 * `Become' is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * `Become' is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with `become'; if not, write to the Free Software Foundation,
26 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 /*----- Revision history --------------------------------------------------*
32 * Revision 1.7 1999/03/26 15:25:22 mdw
33 * Insert some missing semicolons. Bison didn't seem to care, but other
34 * programs like `yyextract' do, so it's worth fixing.
36 * Revision 1.6 1998/04/23 13:26:49 mdw
37 * New `parse' interface to configuration file parser; informs caller
38 * whether parsing encountered any errors. Also support no-network
41 * Revision 1.5 1998/01/12 16:46:22 mdw
44 * Revision 1.4 1997/09/17 10:26:52 mdw
45 * Use rewritten class handler. Makes the expression parsers considerably
48 * Revision 1.3 1997/09/09 18:17:06 mdw
49 * Allow default port to be given as a service name or port number.
51 * Revision 1.2 1997/08/04 10:24:24 mdw
52 * Sources placed under CVS control.
54 * Revision 1.1 1997/07/21 13:47:45 mdw
59 /*----- Header files ------------------------------------------------------*/
62 /* --- ANSI headers --- */
68 /* --- Unix headers --- */
70 #include <sys/types.h>
71 #include <sys/socket.h>
73 #include <netinet/in.h>
75 #include <arpa/inet.h>
81 /* --- Local headers --- */
93 /*----- Stack type --------------------------------------------------------*/
102 /*----- Token and rule declarations ---------------------------------------*/
125 %type <c> user_class command_class host_class
126 %type <c> user_class_opt command_class_opt host_class_opt
129 /*----- Error reporting ---------------------------------------------------*/
133 #define YYERROR_VERBOSE
135 /* --- @yyprint@ --- *
137 * Arguments: @FILE *fp@ = pointer to stream to write on
138 * @int type@ = pointer to token type
139 * @YYSTYPE v@ = token value
143 * Use: Displays the semantic value of a token.
146 #define YYPRINT(fp, type, value) yyprint(fp, type, value)
148 static void yyprint(FILE *fp, int type, YYSTYPE v)
152 fprintf(fp, " %li", v.i);
156 fprintf(fp, " `%s'", v.s);
161 /* --- @yyerror@ --- *
163 * Arguments: @const char *msg@ = pointer to error message
167 * Use: Reports parse errors.
170 static void yyerror(const char *msg)
172 moan("%s at line %i", msg, lex_line);
177 /*----- The actual grammar ------------------------------------------------*/
179 /* --- Simple driver things --- */
185 statement : user_spec
194 /* --- Main statement types --- */
196 user_spec : USER name '=' user_class ';' {
203 command_spec : COMMAND name '=' command_class ';' {
210 host_spec : HOST name '=' host_class ';' {
217 port_spec : PORT STRING ';' {
219 struct servent *s = getservbyname($2, "udp");
221 moan("unknown service `%s' at line %i",
225 daemon_usePort(s->s_port);
227 yyerror("`port' command unsupported");
233 daemon_usePort(htons($2));
235 yyerror("`port' command unsupported");
241 key_spec : KEYFILE STRING ';' {
245 yyerror("`keyfile' command unsupported");
251 /* --- Parsing allow specifications --- */
253 allow_spec : ALLOW host_class_opt user_class ARROW
254 user_class_opt command_class_opt ';' {
255 rule_add($2, $3, $5, $6);
259 host_class_opt : /* empty */ { $$ = class_all; }
260 | '[' host_class ']' { $$ = $2; }
263 user_class_opt : /* empty */ { $$ = class_all; }
264 | user_class { $$ = $1; }
267 command_class_opt : /* empty */ { $$ = class_all; }
268 | ':' command_class { $$ = $2; }
271 /* --- Names get translated into symbols quickly --- */
275 name *n = name_find($1, 1, &f);
282 /*----- Various class expression types ------------------------------------*
284 * Unfortunately, all these need to handle token types slightly differently
285 * and I can't be bothered to remember the current state.
288 /* --- User class expressions --- */
290 user_class : user_class ',' user_class {
291 if (($$ = class_union($1, $3)) == 0) {
292 yyerror("type mismatch");
296 | user_class '-' user_class {
297 if (($$ = class_diff($1, $3)) == 0) {
298 yyerror("type mismatch");
302 | user_class '&' user_class {
303 if (($$ = class_isect($1, $3)) == 0) {
304 yyerror("type mismatch");
308 | user_class '|' user_class {
309 if (($$ = class_union($1, $3)) == 0) {
310 yyerror("type mismatch");
314 | INT { $$ = class_fromUser(clType_user, $1); }
317 if ((pw = userdb_userByName($1)) == 0) {
318 moan("user `%s' not known at line %i",
322 $$ = class_fromUser(clType_user, pw->pw_uid);
325 name *n = name_find($1, 0, 0);
327 moan("class `%s' not found at line %i",
330 } else if (~n->c->type & clType_user) {
331 yynerrs++; yyerror("type mismatch");
338 | '(' user_class ')' { $$ = $2; }
341 /* --- Command class expressions --- */
343 command_class : command_class ',' command_class {
344 if (($$ = class_union($1, $3)) == 0) {
345 yyerror("type mismatch");
349 | command_class '-' command_class {
350 if (($$ = class_diff($1, $3)) == 0) {
351 yyerror("type mismatch");
355 | command_class '&' command_class {
356 if (($$ = class_isect($1, $3)) == 0) {
357 yyerror("type mismatch");
361 | command_class '|' command_class {
362 if (($$ = class_union($1, $3)) == 0) {
363 yyerror("type mismatch");
367 | STRING { $$ = class_fromString(clType_command, $1); }
369 name *n = name_find($1, 0, 0);
371 moan("class `%s' not found at line %i",
374 } else if (~n->c->type & clType_command) {
375 yyerror("type mismatch");
382 | '(' command_class ')' { $$ = $2; }
385 /* --- Host class expressions --- */
387 host_class : host_class ',' host_class {
388 if (($$ = class_union($1, $3)) == 0) {
389 yyerror("type mismatch");
393 | host_class '-' host_class {
394 if (($$ = class_diff($1, $3)) == 0) {
395 yyerror("type mismatch");
399 | host_class '&' host_class {
400 if (($$ = class_isect($1, $3)) == 0) {
401 yyerror("type mismatch");
405 | host_class '|' host_class {
406 if (($$ = class_union($1, $3)) == 0) {
407 yyerror("type mismatch");
411 | STRING { $$ = class_fromString(clType_host, $1); }
413 name *n = name_find($1, 0, 0);
415 moan("class `%s' not found at line %i",
418 } else if (~n->c->type & clType_host) {
419 yyerror("type mismatch");
426 | '(' host_class ')' { $$ = $2; }
429 /*----- Helper functions --------------------------------------------------*/
435 * Returns: Zero if it worked, nonzero if it didn't.
437 * Use: Parses configuration files.
443 return (yyparse() || yynerrs);
446 /*----- That's all, folks -------------------------------------------------*/