X-Git-Url: https://git.armaanb.net/?a=blobdiff_plain;f=parse.y;h=e4a041a374164133761a77c8f3f1e27f09c7556a;hb=38e072b353f5b1325bbf52dfb759fe49ff6ef0f7;hp=6166ceef908353e56ff965b7110dff68aa43f66e;hpb=7f11114f0f07c653e0ea3d4ae093d7dcdda4a4ef;p=opendoas.git diff --git a/parse.y b/parse.y index 6166cee..e4a041a 100644 --- a/parse.y +++ b/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.16 2016/06/05 00:46:34 djm Exp $ */ +/* $OpenBSD: parse.y,v 1.10 2015/07/24 06:36:42 zhuk Exp $ */ /* * Copyright (c) 2015 Ted Unangst * @@ -18,13 +18,13 @@ %{ #include #include -#include -#include +#include #include #include +#include #include #include -#include +#include #include "openbsd.h" @@ -38,8 +38,8 @@ typedef struct { const char *cmd; const char **cmdargs; const char **envlist; - const char **setenvlist; }; + const char **strlist; const char *str; }; int lineno; @@ -50,17 +50,30 @@ typedef struct { FILE *yyfp; struct rule **rules; -int nrules, maxrules; +int nrules; +static int maxrules; + int parse_errors = 0; -void yyerror(const char *, ...); -int yylex(void); -int yyparse(void); +static void yyerror(const char *, ...); +static int yylex(void); + +static size_t +arraylen(const char **arr) +{ + size_t cnt = 0; + + while (*arr) { + cnt++; + arr++; + } + return cnt; +} %} %token TPERMIT TDENY TAS TCMD TARGS -%token TNOPASS TKEEPENV TSETENV +%token TNOPASS TPERSIST TKEEPENV TSETENV %token TSTRING %% @@ -79,7 +92,6 @@ rule: action ident target cmd { r->action = $1.action; r->options = $1.options; r->envlist = $1.envlist; - r->setenvlist = $1.setenvlist; r->ident = $2.str; r->target = $3.str; r->cmd = $4.cmd; @@ -100,9 +112,10 @@ action: TPERMIT options { $$.action = PERMIT; $$.options = $2.options; $$.envlist = $2.envlist; - $$.setenvlist = $2.setenvlist; } | TDENY { $$.action = DENY; + $$.options = 0; + $$.envlist = NULL; } ; options: /* none */ { @@ -111,71 +124,43 @@ options: /* none */ { } | options option { $$.options = $1.options | $2.options; $$.envlist = $1.envlist; + if (($$.options & (NOPASS|PERSIST)) == (NOPASS|PERSIST)) { + yyerror("can't combine nopass and persist"); + YYERROR; + } if ($2.envlist) { if ($$.envlist) { - yyerror("can't have two keepenv sections"); - YYERROR; - } else - $$.envlist = $2.envlist; - } - $$.setenvlist = $1.setenvlist; - if ($2.setenvlist) { - if ($$.setenvlist) { yyerror("can't have two setenv sections"); YYERROR; } else - $$.setenvlist = $2.setenvlist; + $$.envlist = $2.envlist; } } ; option: TNOPASS { $$.options = NOPASS; $$.envlist = NULL; + } | TPERSIST { + $$.options = PERSIST; + $$.envlist = NULL; } | TKEEPENV { $$.options = KEEPENV; $$.envlist = NULL; - } | TKEEPENV '{' envlist '}' { - $$.options = KEEPENV; - $$.envlist = $3.envlist; - } | TSETENV '{' setenvlist '}' { - $$.options = SETENV; - $$.setenvlist = NULL; - $$.setenvlist = $3.setenvlist; + } | TSETENV '{' strlist '}' { + $$.options = 0; + $$.envlist = $3.strlist; } ; -envlist: /* empty */ { - $$.envlist = NULL; - if (!($$.envlist = calloc(1, sizeof(char *)))) - errx(1, "can't allocate envlist"); - } | envlist TSTRING { - int nenv = arraylen($1.envlist); - if (!($$.envlist = reallocarray($1.envlist, nenv + 2, +strlist: /* empty */ { + if (!($$.strlist = calloc(1, sizeof(char *)))) + errx(1, "can't allocate strlist"); + } | strlist TSTRING { + int nstr = arraylen($1.strlist); + if (!($$.strlist = reallocarray($1.strlist, nstr + 2, sizeof(char *)))) - errx(1, "can't allocate envlist"); - $$.envlist[nenv] = $2.str; - $$.envlist[nenv + 1] = NULL; - } - -setenvlist: /* empty */ { - if (!($$.setenvlist = calloc(1, sizeof(char *)))) - errx(1, "can't allocate setenvlist"); - } | setenvlist TSTRING '=' TSTRING { - int nenv = arraylen($1.setenvlist); - char *cp = NULL; - - if (*$2.str == '\0' || strchr($2.str, '=') != NULL) { - yyerror("invalid setenv expression"); - YYERROR; - } - if (!($$.setenvlist = reallocarray($1.setenvlist, - nenv + 2, sizeof(char *)))) - errx(1, "can't allocate envlist"); - $$.setenvlist[nenv] = NULL; - if (asprintf(&cp, "%s=%s", $2.str, $4.str) <= 0 || - cp == NULL) - errx(1,"asprintf failed"); - $$.setenvlist[nenv] = cp; - $$.setenvlist[nenv + 1] = NULL; - } + errx(1, "can't allocate strlist"); + $$.strlist[nstr] = $2.str; + $$.strlist[nstr + 1] = NULL; + } ; ident: TSTRING { @@ -198,21 +183,8 @@ cmd: /* optional */ { args: /* empty */ { $$.cmdargs = NULL; - } | TARGS argslist { - $$.cmdargs = $2.cmdargs; - } ; - -argslist: /* empty */ { - $$.cmdargs = NULL; - if (!($$.cmdargs = calloc(1, sizeof(char *)))) - errx(1, "can't allocate args"); - } | argslist TSTRING { - int nargs = arraylen($1.cmdargs); - if (!($$.cmdargs = reallocarray($1.cmdargs, nargs + 2, - sizeof(char *)))) - errx(1, "can't allocate args"); - $$.cmdargs[nargs] = $2.str; - $$.cmdargs[nargs + 1] = NULL; + } | TARGS strlist { + $$.cmdargs = $2.strlist; } ; %% @@ -230,7 +202,7 @@ yyerror(const char *fmt, ...) parse_errors++; } -struct keyword { +static struct keyword { const char *word; int token; } keywords[] = { @@ -240,6 +212,7 @@ struct keyword { { "cmd", TCMD }, { "args", TARGS }, { "nopass", TNOPASS }, + { "persist", TPERSIST }, { "keepenv", TKEEPENV }, { "setenv", TSETENV }, }; @@ -266,18 +239,17 @@ repeat: /* FALLTHROUGH */ case '{': case '}': - case '=': return c; case '#': /* skip comments; NUL is allowed; no continuation */ while ((c = getc(yyfp)) != '\n') if (c == EOF) - goto eof; + return 0; yylval.colno = 0; yylval.lineno++; return c; case EOF: - goto eof; + return 0; } /* parsing next word */ @@ -300,8 +272,6 @@ repeat: if (escape) { nonkw = 1; escape = 0; - yylval.colno = 0; - yylval.lineno++; continue; } goto eow; @@ -319,7 +289,6 @@ repeat: case '#': case ' ': case '\t': - case '=': if (!escape && !quotes) goto eow; break; @@ -334,10 +303,8 @@ repeat: } } *p++ = c; - if (p == ebuf) { + if (p == ebuf) yyerror("too long line"); - p = buf; - } escape = 0; } @@ -352,7 +319,7 @@ eow: * the main loop. */ if (c == EOF) - goto eof; + return 0; else if (qpos == -1) /* accept, e.g., empty args: cmd foo args "" */ goto repeat; } @@ -364,12 +331,7 @@ eow: } } if ((str = strdup(buf)) == NULL) - err(1, "strdup"); + err(1, "%s", __func__); yylval.str = str; return TSTRING; - -eof: - if (ferror(yyfp)) - yyerror("input error reading config"); - return 0; }