3 * $Id: parser.y,v 1.1 1997/07/21 13:47:45 mdw Exp $
5 * Parser for `become.conf' files
10 /*----- Licencing 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
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 /*----- Revision history --------------------------------------------------*
32 * Revision 1.1 1997/07/21 13:47:45 mdw
37 /*----- Header files ------------------------------------------------------*/
40 /* --- ANSI headers --- */
46 /* --- Unix headers --- */
48 #include <sys/types.h>
53 /* --- Local headers --- */
66 /*----- Stack type --------------------------------------------------------*/
75 /*----- Token and rule declarations ---------------------------------------*/
98 %type <c> user_class command_class host_class
99 %type <c> user_class_opt command_class_opt host_class_opt
102 /*----- Error reporting ---------------------------------------------------*/
106 #define YYERROR_VERBOSE
108 /* --- @yyprint@ --- *
110 * Arguments: @FILE *fp@ = pointer to stream to write on
111 * @int type@ = pointer to token type
112 * @YYSTYPE v@ = token value
116 * Use: Displays the semantic value of a token.
119 #define YYPRINT(fp, type, value) yyprint(fp, type, value)
121 static void yyprint(FILE *fp, int type, YYSTYPE v)
125 fprintf(fp, " %li", v.i);
129 fprintf(fp, " `%s'", v.s);
134 /* --- @yyerror@ --- *
136 * Arguments: @const char *msg@ = pointer to error message
140 * Use: Reports parse errors.
143 static void yyerror(const char *msg)
145 moan("%s at line %i", msg, lex_line);
150 /*----- The actual grammar ------------------------------------------------*/
152 /* --- Simple driver things --- */
158 statement : user_spec
167 /* --- Main statement types --- */
169 user_spec : USER name '=' user_class ';' {
176 command_spec : COMMAND name '=' command_class ';' {
183 host_spec : HOST name '=' host_class ';' {
190 port_spec : PORT INT ';' { daemon_usePort($2); }
193 key_spec : KEYFILE STRING ';' { daemon_readKey($2); }
195 /* --- Parsing allow specifications --- */
197 allow_spec : ALLOW host_class_opt user_class ARROW
198 user_class_opt command_class_opt ';' {
199 rule_add($2, $3, $5, $6);
202 host_class_opt : /* empty */ { $$ = class_all; }
203 | '[' host_class ']' { $$ = $2; }
206 user_class_opt : /* empty */ { $$ = class_all; }
207 | user_class { $$ = $1; }
210 command_class_opt : /* empty */ { $$ = class_all; }
211 | ':' command_class { $$ = $2; }
214 /* --- Names get translated into symbols quickly --- */
218 name *n = name_find($1, 1, &f);
224 /*----- Various class expression types ------------------------------------*
226 * Unfortunately, all these need to handle token types slightly differently
227 * and I can't be bothered to remember the current state.
230 /* --- User class expressions --- */
232 user_class : user_class ',' user_class {
233 if ($1->type != $3->type) {
234 yyerror("type mismatch");
242 $$ = class_create($1->type,
243 set_union($1->t, $3->t));
248 | user_class '-' user_class {
249 if ($1->type != $3->type) {
250 yyerror("type mismatch");
255 $$ = class_create($1->type,
256 set_subtract($1->t, $3->t));
261 | user_class '&' user_class {
262 if ($1->type != $3->type) {
263 yyerror("type mismatch");
271 $$ = class_create($1->type,
272 set_intersect($1->t, $3->t));
277 | user_class '|' user_class {
278 if ($1->type != $3->type) {
279 yyerror("type mismatch");
287 $$ = class_create($1->type,
288 set_union($1->t, $3->t));
294 sym_table *t = xmalloc(sizeof(*t));
297 sym_find(t, (char *)&u, sizeof(u),
298 sizeof(sym_base), 0);
299 $$ = class_create(clType_user, t);
305 if ((pw = userdb_userByName($1)) == 0) {
306 moan("user `%s' not known at line %i",
310 t = xmalloc(sizeof(*t));
313 sym_find(t, (char *)&u, sizeof(u),
314 sizeof(sym_base), 0);
315 $$ = class_create(clType_user, t);
319 name *n = name_find($1, 0, 0);
321 moan("class `%s' not found at line %i",
324 } else if (~n->c->type & clType_user) {
325 yyerror("type mismatch");
332 | '(' user_class ')' { $$ = $2; }
335 /* --- Command class expressions --- */
337 command_class : command_class ',' command_class {
338 if ($1->type != $3->type) {
339 yyerror("type mismatch");
347 $$ = class_create($1->type,
348 set_union($1->t, $3->t));
353 | command_class '-' command_class {
354 if ($1->type != $3->type) {
355 yyerror("type mismatch");
360 $$ = class_create($1->type,
361 set_subtract($1->t, $3->t));
366 | command_class '&' command_class {
367 if ($1->type != $3->type) {
368 yyerror("type mismatch");
376 $$ = class_create($1->type,
377 set_intersect($1->t, $3->t));
382 | command_class '|' command_class {
383 if ($1->type != $3->type) {
384 yyerror("type mismatch");
392 $$ = class_create($1->type,
393 set_union($1->t, $3->t));
399 sym_table *t = xmalloc(sizeof(*t));
401 sym_find(t, $1, -1, sizeof(sym_base), 0);
402 $$ = class_create(clType_command, t);
405 name *n = name_find($1, 0, 0);
407 moan("class `%s' not found at line %i",
410 } else if (~n->c->type & clType_command) {
411 yyerror("type mismatch");
418 | '(' command_class ')' { $$ = $2; }
421 /* --- Host class expressions --- */
423 host_class : host_class ',' host_class {
424 if ($1->type != $3->type) {
425 yyerror("type mismatch");
433 $$ = class_create($1->type,
434 set_union($1->t, $3->t));
439 | host_class '-' host_class {
440 if ($1->type != $3->type) {
441 yyerror("type mismatch");
446 $$ = class_create($1->type,
447 set_subtract($1->t, $3->t));
452 | host_class '&' host_class {
453 if ($1->type != $3->type) {
454 yyerror("type mismatch");
462 $$ = class_create($1->type,
463 set_intersect($1->t, $3->t));
468 | host_class '|' host_class {
469 if ($1->type != $3->type) {
470 yyerror("type mismatch");
478 $$ = class_create($1->type,
479 set_union($1->t, $3->t));
485 sym_table *t = xmalloc(sizeof(*t));
487 sym_find(t, $1, -1, sizeof(sym_base), 0);
488 $$ = class_create(clType_host, t);
491 name *n = name_find($1, 0, 0);
493 moan("class `%s' not found at line %i",
496 } else if (~n->c->type & clType_host) {
497 yyerror("type mismatch");
504 | '(' host_class ')' { $$ = $2; }
507 /*----- That's all, folks -------------------------------------------------*/