=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/doas/parse.y,v retrieving revision 1.15 retrieving revision 1.16 diff -c -r1.15 -r1.16 *** src/usr.bin/doas/parse.y 2016/04/27 02:35:55 1.15 --- src/usr.bin/doas/parse.y 2016/06/05 00:46:34 1.16 *************** *** 1,4 **** ! /* $OpenBSD: parse.y,v 1.15 2016/04/27 02:35:55 gsoares Exp $ */ /* * Copyright (c) 2015 Ted Unangst * --- 1,4 ---- ! /* $OpenBSD: parse.y,v 1.16 2016/06/05 00:46:34 djm Exp $ */ /* * Copyright (c) 2015 Ted Unangst * *************** *** 35,40 **** --- 35,41 ---- const char *cmd; const char **cmdargs; const char **envlist; + const char **setenvlist; }; const char *str; }; *************** *** 56,62 **** %} %token TPERMIT TDENY TAS TCMD TARGS ! %token TNOPASS TKEEPENV %token TSTRING %% --- 57,63 ---- %} %token TPERMIT TDENY TAS TCMD TARGS ! %token TNOPASS TKEEPENV TSETENV %token TSTRING %% *************** *** 75,80 **** --- 76,82 ---- 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; *************** *** 95,100 **** --- 97,103 ---- $$.action = PERMIT; $$.options = $2.options; $$.envlist = $2.envlist; + $$.setenvlist = $2.setenvlist; } | TDENY { $$.action = DENY; } ; *************** *** 110,116 **** --- 113,128 ---- } else $$.envlist = $2.envlist; } + $$.setenvlist = $1.setenvlist; + if ($2.setenvlist) { + if ($$.setenvlist) { + yyerror("can't have two setenv sections"); + YYERROR; + } else + $$.setenvlist = $2.setenvlist; + } } ; + option: TNOPASS { $$.options = NOPASS; } | TKEEPENV { *************** *** 118,123 **** --- 130,138 ---- } | TKEEPENV '{' envlist '}' { $$.options = KEEPENV; $$.envlist = $3.envlist; + } | TSETENV '{' setenvlist '}' { + $$.options = SETENV; + $$.setenvlist = $3.setenvlist; } ; envlist: /* empty */ { *************** *** 132,138 **** --- 147,175 ---- $$.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; + } + + ident: TSTRING { $$.str = $1.str; } ; *************** *** 195,200 **** --- 232,238 ---- { "args", TARGS }, { "nopass", TNOPASS }, { "keepenv", TKEEPENV }, + { "setenv", TSETENV }, }; int *************** *** 219,224 **** --- 257,263 ---- /* FALLTHROUGH */ case '{': case '}': + case '=': return c; case '#': /* skip comments; NUL is allowed; no continuation */ *************** *** 271,276 **** --- 310,316 ---- case '#': case ' ': case '\t': + case '=': if (!escape && !quotes) goto eow; break;