3 * $Id: parser.y,v 1.9 2004/04/08 01:36:20 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 /*----- Header files ------------------------------------------------------*/
32 /* --- ANSI headers --- */
38 /* --- Unix headers --- */
40 #include <sys/types.h>
41 #include <sys/socket.h>
43 #include <netinet/in.h>
45 #include <arpa/inet.h>
51 /* --- mLib headers --- */
53 #include <mLib/report.h>
56 /* --- 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 STRING ';' {
192 struct servent *s = getservbyname($2, "udp");
194 moan("unknown service `%s' at line %i",
198 daemon_usePort(s->s_port);
200 yyerror("`port' command unsupported");
206 daemon_usePort(htons($2));
208 yyerror("`port' command unsupported");
214 key_spec : KEYFILE STRING ';' {
218 yyerror("`keyfile' command unsupported");
224 /* --- Parsing allow specifications --- */
226 allow_spec : ALLOW host_class_opt user_class ARROW
227 user_class_opt command_class_opt ';' {
228 rule_add($2, $3, $5, $6);
232 host_class_opt : /* empty */ { $$ = class_all; }
233 | '[' host_class ']' { $$ = $2; }
236 user_class_opt : /* empty */ { $$ = class_all; }
237 | user_class { $$ = $1; }
240 command_class_opt : /* empty */ { $$ = class_all; }
241 | ':' command_class { $$ = $2; }
244 /* --- Names get translated into symbols quickly --- */
248 name *n = name_find($1, 1, &f);
255 /*----- Various class expression types ------------------------------------*
257 * Unfortunately, all these need to handle token types slightly differently
258 * and I can't be bothered to remember the current state.
261 /* --- User class expressions --- */
263 user_class : user_class ',' user_class {
264 if (($$ = class_union($1, $3)) == 0) {
265 yyerror("type mismatch");
269 | user_class '-' user_class {
270 if (($$ = class_diff($1, $3)) == 0) {
271 yyerror("type mismatch");
275 | user_class '&' user_class {
276 if (($$ = class_isect($1, $3)) == 0) {
277 yyerror("type mismatch");
281 | user_class '|' user_class {
282 if (($$ = class_union($1, $3)) == 0) {
283 yyerror("type mismatch");
287 | INT { $$ = class_fromUser(clType_user, $1); }
290 if ((pw = userdb_userByName($1)) == 0) {
291 moan("user `%s' not known at line %i",
295 $$ = class_fromUser(clType_user, pw->pw_uid);
298 name *n = name_find($1, 0, 0);
300 moan("class `%s' not found at line %i",
303 } else if (~n->c->type & clType_user) {
304 yynerrs++; yyerror("type mismatch");
311 | '(' user_class ')' { $$ = $2; }
314 /* --- Command class expressions --- */
316 command_class : command_class ',' command_class {
317 if (($$ = class_union($1, $3)) == 0) {
318 yyerror("type mismatch");
322 | command_class '-' command_class {
323 if (($$ = class_diff($1, $3)) == 0) {
324 yyerror("type mismatch");
328 | command_class '&' command_class {
329 if (($$ = class_isect($1, $3)) == 0) {
330 yyerror("type mismatch");
334 | command_class '|' command_class {
335 if (($$ = class_union($1, $3)) == 0) {
336 yyerror("type mismatch");
340 | STRING { $$ = class_fromString(clType_command, $1); }
342 name *n = name_find($1, 0, 0);
344 moan("class `%s' not found at line %i",
347 } else if (~n->c->type & clType_command) {
348 yyerror("type mismatch");
355 | '(' command_class ')' { $$ = $2; }
358 /* --- Host class expressions --- */
360 host_class : host_class ',' host_class {
361 if (($$ = class_union($1, $3)) == 0) {
362 yyerror("type mismatch");
366 | host_class '-' host_class {
367 if (($$ = class_diff($1, $3)) == 0) {
368 yyerror("type mismatch");
372 | host_class '&' host_class {
373 if (($$ = class_isect($1, $3)) == 0) {
374 yyerror("type mismatch");
378 | host_class '|' host_class {
379 if (($$ = class_union($1, $3)) == 0) {
380 yyerror("type mismatch");
384 | STRING { $$ = class_fromString(clType_host, $1); }
386 name *n = name_find($1, 0, 0);
388 moan("class `%s' not found at line %i",
391 } else if (~n->c->type & clType_host) {
392 yyerror("type mismatch");
399 | '(' host_class ')' { $$ = $2; }
402 /*----- Helper functions --------------------------------------------------*/
408 * Returns: Zero if it worked, nonzero if it didn't.
410 * Use: Parses configuration files.
416 return (yyparse() || yynerrs);
419 /*----- That's all, folks -------------------------------------------------*/