3 * $Id: parser.y,v 1.3 1997/09/09 18:17:06 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.3 1997/09/09 18:17:06 mdw
33 * Allow default port to be given as a service name or port number.
35 * Revision 1.2 1997/08/04 10:24:24 mdw
36 * Sources placed under CVS control.
38 * Revision 1.1 1997/07/21 13:47:45 mdw
43 /*----- Header files ------------------------------------------------------*/
46 /* --- ANSI headers --- */
52 /* --- Unix headers --- */
54 #include <sys/types.h>
55 #include <sys/socket.h>
57 #include <netinet/in.h>
59 #include <arpa/inet.h>
65 /* --- Local headers --- */
78 /*----- Stack type --------------------------------------------------------*/
87 /*----- Token and rule declarations ---------------------------------------*/
110 %type <c> user_class command_class host_class
111 %type <c> user_class_opt command_class_opt host_class_opt
114 /*----- Error reporting ---------------------------------------------------*/
118 #define YYERROR_VERBOSE
120 /* --- @yyprint@ --- *
122 * Arguments: @FILE *fp@ = pointer to stream to write on
123 * @int type@ = pointer to token type
124 * @YYSTYPE v@ = token value
128 * Use: Displays the semantic value of a token.
131 #define YYPRINT(fp, type, value) yyprint(fp, type, value)
133 static void yyprint(FILE *fp, int type, YYSTYPE v)
137 fprintf(fp, " %li", v.i);
141 fprintf(fp, " `%s'", v.s);
146 /* --- @yyerror@ --- *
148 * Arguments: @const char *msg@ = pointer to error message
152 * Use: Reports parse errors.
155 static void yyerror(const char *msg)
157 moan("%s at line %i", msg, lex_line);
162 /*----- The actual grammar ------------------------------------------------*/
164 /* --- Simple driver things --- */
170 statement : user_spec
179 /* --- Main statement types --- */
181 user_spec : USER name '=' user_class ';' {
188 command_spec : COMMAND name '=' command_class ';' {
195 host_spec : HOST name '=' host_class ';' {
202 port_spec : PORT STRING ';' {
203 struct servent *s = getservbyname($2, "udp");
205 moan("unknown service `%s' at line %i",
209 daemon_usePort(s->s_port);
211 | PORT INT ';' { daemon_usePort(htons($2)); }
214 key_spec : KEYFILE STRING ';' { daemon_readKey($2); }
216 /* --- Parsing allow specifications --- */
218 allow_spec : ALLOW host_class_opt user_class ARROW
219 user_class_opt command_class_opt ';' {
220 rule_add($2, $3, $5, $6);
223 host_class_opt : /* empty */ { $$ = class_all; }
224 | '[' host_class ']' { $$ = $2; }
227 user_class_opt : /* empty */ { $$ = class_all; }
228 | user_class { $$ = $1; }
231 command_class_opt : /* empty */ { $$ = class_all; }
232 | ':' command_class { $$ = $2; }
235 /* --- Names get translated into symbols quickly --- */
239 name *n = name_find($1, 1, &f);
245 /*----- Various class expression types ------------------------------------*
247 * Unfortunately, all these need to handle token types slightly differently
248 * and I can't be bothered to remember the current state.
251 /* --- User class expressions --- */
253 user_class : user_class ',' user_class {
254 if ($1->type != $3->type) {
255 yyerror("type mismatch");
263 $$ = class_create($1->type,
264 set_union($1->t, $3->t));
269 | user_class '-' user_class {
270 if ($1->type != $3->type) {
271 yyerror("type mismatch");
276 $$ = class_create($1->type,
277 set_subtract($1->t, $3->t));
282 | user_class '&' user_class {
283 if ($1->type != $3->type) {
284 yyerror("type mismatch");
292 $$ = class_create($1->type,
293 set_intersect($1->t, $3->t));
298 | user_class '|' user_class {
299 if ($1->type != $3->type) {
300 yyerror("type mismatch");
308 $$ = class_create($1->type,
309 set_union($1->t, $3->t));
315 sym_table *t = xmalloc(sizeof(*t));
318 sym_find(t, (char *)&u, sizeof(u),
319 sizeof(sym_base), 0);
320 $$ = class_create(clType_user, t);
326 if ((pw = userdb_userByName($1)) == 0) {
327 moan("user `%s' not known at line %i",
331 t = xmalloc(sizeof(*t));
334 sym_find(t, (char *)&u, sizeof(u),
335 sizeof(sym_base), 0);
336 $$ = class_create(clType_user, t);
340 name *n = name_find($1, 0, 0);
342 moan("class `%s' not found at line %i",
345 } else if (~n->c->type & clType_user) {
346 yyerror("type mismatch");
353 | '(' user_class ')' { $$ = $2; }
356 /* --- Command class expressions --- */
358 command_class : command_class ',' command_class {
359 if ($1->type != $3->type) {
360 yyerror("type mismatch");
368 $$ = class_create($1->type,
369 set_union($1->t, $3->t));
374 | command_class '-' command_class {
375 if ($1->type != $3->type) {
376 yyerror("type mismatch");
381 $$ = class_create($1->type,
382 set_subtract($1->t, $3->t));
387 | command_class '&' command_class {
388 if ($1->type != $3->type) {
389 yyerror("type mismatch");
397 $$ = class_create($1->type,
398 set_intersect($1->t, $3->t));
403 | command_class '|' command_class {
404 if ($1->type != $3->type) {
405 yyerror("type mismatch");
413 $$ = class_create($1->type,
414 set_union($1->t, $3->t));
420 sym_table *t = xmalloc(sizeof(*t));
422 sym_find(t, $1, -1, sizeof(sym_base), 0);
423 $$ = class_create(clType_command, t);
426 name *n = name_find($1, 0, 0);
428 moan("class `%s' not found at line %i",
431 } else if (~n->c->type & clType_command) {
432 yyerror("type mismatch");
439 | '(' command_class ')' { $$ = $2; }
442 /* --- Host class expressions --- */
444 host_class : host_class ',' host_class {
445 if ($1->type != $3->type) {
446 yyerror("type mismatch");
454 $$ = class_create($1->type,
455 set_union($1->t, $3->t));
460 | host_class '-' host_class {
461 if ($1->type != $3->type) {
462 yyerror("type mismatch");
467 $$ = class_create($1->type,
468 set_subtract($1->t, $3->t));
473 | host_class '&' host_class {
474 if ($1->type != $3->type) {
475 yyerror("type mismatch");
483 $$ = class_create($1->type,
484 set_intersect($1->t, $3->t));
489 | host_class '|' host_class {
490 if ($1->type != $3->type) {
491 yyerror("type mismatch");
499 $$ = class_create($1->type,
500 set_union($1->t, $3->t));
506 sym_table *t = xmalloc(sizeof(*t));
508 sym_find(t, $1, -1, sizeof(sym_base), 0);
509 $$ = class_create(clType_host, t);
512 name *n = name_find($1, 0, 0);
514 moan("class `%s' not found at line %i",
517 } else if (~n->c->type & clType_host) {
518 yyerror("type mismatch");
525 | '(' host_class ')' { $$ = $2; }
528 /*----- That's all, folks -------------------------------------------------*/