2 * Copyright (c) 2016 Martijn van Duren <martijn@openbsd.org>
3 * Copyright (c) 2015 Ted Unangst <tedu@openbsd.org>
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #include <sys/types.h>
46 #define YYSTYPE yystype
53 int obsolete_warned = 0;
55 void yyerror(const char *, ...);
61 %token TPERMIT TDENY TAS TEDIT
62 %token TNOPASS TPERSIST
73 rule: action ident target edit {
75 if ((r = calloc(1, sizeof(*r))) == NULL)
77 r->action = $1.action;
78 r->options = $1.options;
82 if (nrules == maxrules) {
87 if ((rules = reallocarray(rules, maxrules,
88 sizeof(*rules))) == NULL)
94 action: TPERMIT options {
96 $$.options = $2.options;
102 options: /* none */ {
105 $$.options = $1.options | $2.options;
106 if (($$.options & (NOPASS|PERSIST)) == (NOPASS|PERSIST)) {
107 yyerror("can't combine nopass and persist");
114 $$.options = PERSIST;
121 target: /* optional */ {
130 if (arraylen($2.files))
139 if (($$.files = calloc(1, sizeof(char *))) == NULL)
142 int nargs = arraylen($1.files);
145 if ($2.str[0] != '/') {
146 warnx("File %s can't be relative", $2.str);
149 if ((str = realpath($2.str, NULL)) == NULL &&
151 warn("Problem verifying %s", $2.str);
154 if (str != NULL && strcmp($2.str, str)) {
156 if ((str = reallocarray(str, strl + 2,
157 sizeof(*str))) == NULL)
161 if (strcmp($2.str, str)) {
162 warnx("file %s needs to be a resolved "
169 if (($$.files = reallocarray($1.files, nargs + 2,
170 sizeof(char *))) == NULL)
172 $$.files[nargs] = $2.str;
173 $$.files[nargs + 1] = NULL;
180 yyerror(const char *fmt, ...)
184 fprintf(stderr, "vias: ");
186 vfprintf(stderr, fmt, va);
188 fprintf(stderr, " at line %d\n", yylval.lineno + 1);
197 { "permit", TPERMIT },
199 { "nopass", TNOPASS },
200 { "persist", TPERSIST },
207 char buf[1024], *ebuf, *p, *str;
208 int c, quotes = 0, escape = 0, qpos = -1, nonkw = 0;
212 ebuf = buf + sizeof(buf);
215 /* skip whitespace first */
216 for (c = getc(yyfp); c == ' ' || c == '\t'; c = getc(yyfp))
219 /* check for special one-character constructions */
229 /* skip comments; NUL is allowed; no continuation */
230 while ((c = getc(yyfp)) != '\n')
240 /* parsing next word */
241 for (;; c = getc(yyfp), yylval.colno++) {
244 yyerror("unallowed character NUL in column %d",
255 yyerror("unterminated quotes in column %d",
267 yyerror("unterminated escape in column %d",
270 yyerror("unterminated quotes in column %d",
279 if (!escape && !quotes)
294 yyerror("too long line");
306 * There could be a number of reasons for empty buffer,
307 * and we handle all of them here, to avoid cluttering
312 else if (qpos == -1) /* accept, e.g., empty args: cmd foo args "" */
316 for (i = 0; i < sizeof(keywords) / sizeof(keywords[0]); i++) {
317 if (strcmp(buf, keywords[i].word) == 0)
318 return keywords[i].token;
321 if ((str = strdup(buf)) == NULL)
328 yyerror("input error reading config");