GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/doas/parse.c Lines: 156 179 87.2 %
Date: 2017-11-13 Branches: 82 129 63.6 %

Line Branch Exec Source
1
#include <stdlib.h>
2
#include <string.h>
3
#define YYBYACC 1
4
#define YYMAJOR 1
5
#define YYMINOR 9
6
#define YYLEX yylex()
7
#define YYEMPTY -1
8
#define yyclearin (yychar=(YYEMPTY))
9
#define yyerrok (yyerrflag=0)
10
#define YYRECOVERING() (yyerrflag!=0)
11
#define YYPREFIX "yy"
12
#line 19 "parse.y"
13
#include <sys/types.h>
14
#include <ctype.h>
15
#include <unistd.h>
16
#include <stdint.h>
17
#include <stdarg.h>
18
#include <stdio.h>
19
#include <string.h>
20
#include <err.h>
21
22
#include "doas.h"
23
24
typedef struct {
25
	union {
26
		struct {
27
			int action;
28
			int options;
29
			const char *cmd;
30
			const char **cmdargs;
31
			const char **envlist;
32
		};
33
		const char **strlist;
34
		const char *str;
35
	};
36
	int lineno;
37
	int colno;
38
} yystype;
39
#define YYSTYPE yystype
40
41
FILE *yyfp;
42
43
struct rule **rules;
44
int nrules;
45
static int maxrules;
46
47
int parse_errors = 0;
48
49
static void yyerror(const char *, ...);
50
static int yylex(void);
51
52
static size_t
53
arraylen(const char **arr)
54
{
55
	size_t cnt = 0;
56
57
	while (*arr) {
58
		cnt++;
59
		arr++;
60
	}
61
	return cnt;
62
}
63
64
#line 65 "parse.c"
65
#define TPERMIT 257
66
#define TDENY 258
67
#define TAS 259
68
#define TCMD 260
69
#define TARGS 261
70
#define TNOPASS 262
71
#define TPERSIST 263
72
#define TKEEPENV 264
73
#define TSETENV 265
74
#define TSTRING 266
75
#define YYERRCODE 256
76
const short yylhs[] =
77
	{                                        -1,
78
    0,    0,    0,    0,    1,    2,    2,    6,    6,    7,
79
    7,    7,    7,    8,    8,    3,    4,    4,    5,    5,
80
    9,    9,
81
};
82
const short yylen[] =
83
	{                                         2,
84
    0,    2,    3,    2,    4,    2,    1,    0,    2,    1,
85
    1,    1,    4,    0,    2,    1,    0,    2,    0,    3,
86
75
    0,    2,
87
75
};
88
const short yydefred[] =
89
75
	{                                      0,
90
75
    0,    0,    4,    8,    7,    2,    0,    0,    0,    3,
91
75
   16,    0,   10,   11,   12,    0,    9,    0,    0,   14,
92
75
   18,    0,    5,    0,    0,   15,   13,   14,   20,    0,
93
75
};
94
75
const short yydgoto[] =
95
75
	{                                       2,
96
75
    7,    8,   12,   19,   23,    9,   17,   24,   29,
97
20
};
98
const short yysindex[] =
99
	{                                   -253,
100
10
   -1,   -6,    0,    0,    0,    0,    2, -256, -257,    0,
101
10
    0, -246,    0,    0,    0, -109,    0, -251, -244,    0,
102
    0, -249,    0, -123, -243,    0,    0,    0,    0, -247,};
103
const short yyrindex[] =
104
	{                                      1,
105
75
    0,    0,    0,    0,    0,    0,    0,    0, -245,    0,
106
    0,  -10,    0,    0,    0,    0,    0,    0,   10,    0,
107
75
    0,    0,    0,    0,   12,    0,    0,    0,    0,   13,};
108
const short yygindex[] =
109
70
	{                                      0,
110
70
    0,    0,    0,    0,    0,    0,    0,   -4,    0,
111
70
};
112
#define YYTABLESIZE 259
113
80
const short yytable[] =
114
10
	{                                      17,
115
10
    1,   27,    1,    6,   13,   14,   15,   16,    3,   11,
116
    1,   10,   18,   20,   21,   22,   25,   28,   26,   19,
117
10
    6,   21,   22,   30,    0,    0,    0,    0,    0,    0,
118
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
119
70
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
120
70
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
121
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
122
85
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
123
15
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
124
15
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
125
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
126
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
127
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
128
15
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
129
5
    0,    0,   26,    0,    0,    0,    0,    0,    0,    0,
130
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
131
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
132
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
133
5
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
134
5
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
135
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
136
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
137
10
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
138
10
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
139
    0,    0,    0,    0,    0,    0,    0,    0,    0,   17,
140
10
    4,    5,    0,    0,    0,    0,    0,    1,    1,
141
};
142
const short yycheck[] =
143
	{                                      10,
144
    0,  125,  256,   10,  262,  263,  264,  265,   10,  266,
145
   10,   10,  259,  123,  266,  260,  266,  261,  266,   10,
146
5
  266,   10,   10,   28,   -1,   -1,   -1,   -1,   -1,   -1,
147
5
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
148
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
149
5
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
150
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
151
30
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
152
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
153
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
154
150
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
155
150
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
156
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
157
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
158
150
   -1,   -1,  266,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
159
150
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
160
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
161
150
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
162
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
163
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
164
80
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
165
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
166
80
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
167
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
168
80
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  260,
169
  257,  258,   -1,   -1,   -1,   -1,   -1,  257,  258,
170
80
};
171
#define YYFINAL 2
172
#ifndef YYDEBUG
173
#define YYDEBUG 0
174
25
#endif
175
25
#define YYMAXTOKEN 266
176
#if YYDEBUG
177
75
const char * const yyname[] =
178
50
	{
179
"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
180
50
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
181
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
182
25
0,0,0,0,0,0,0,0,0,0,0,0,"'{'",0,"'}'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
183
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
184
50
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
185
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"TPERMIT","TDENY",
186
25
"TAS","TCMD","TARGS","TNOPASS","TPERSIST","TKEEPENV","TSETENV","TSTRING",
187
};
188
const char * const yyrule[] =
189
	{"$accept : grammar",
190
"grammar :",
191
"grammar : grammar '\\n'",
192
"grammar : grammar rule '\\n'",
193
"grammar : error '\\n'",
194
"rule : action ident target cmd",
195
"action : TPERMIT options",
196
"action : TDENY",
197
"options :",
198
"options : options option",
199
"option : TNOPASS",
200
"option : TPERSIST",
201
"option : TKEEPENV",
202
"option : TSETENV '{' strlist '}'",
203
"strlist :",
204
"strlist : strlist TSTRING",
205
"ident : TSTRING",
206
"target :",
207
"target : TAS TSTRING",
208
"cmd :",
209
"cmd : TCMD TSTRING args",
210
"args :",
211
"args : TARGS strlist",
212
};
213
#endif
214
#ifndef YYSTYPE
215
typedef int YYSTYPE;
216
#endif
217
#ifdef YYSTACKSIZE
218
#undef YYMAXDEPTH
219
#define YYMAXDEPTH YYSTACKSIZE
220
#else
221
#ifdef YYMAXDEPTH
222
#define YYSTACKSIZE YYMAXDEPTH
223
#else
224
#define YYSTACKSIZE 10000
225
#define YYMAXDEPTH 10000
226
#endif
227
#endif
228
#define YYINITSTACKSIZE 200
229
/* LINTUSED */
230
int yydebug;
231
int yynerrs;
232
int yyerrflag;
233
int yychar;
234
short *yyssp;
235
YYSTYPE *yyvsp;
236
YYSTYPE yyval;
237
YYSTYPE yylval;
238
short *yyss;
239
short *yysslim;
240
YYSTYPE *yyvs;
241
unsigned int yystacksize;
242
int yyparse(void);
243
#line 188 "parse.y"
244
245
void
246
yyerror(const char *fmt, ...)
247
{
248
	va_list va;
249
250
	fprintf(stderr, "doas: ");
251
	va_start(va, fmt);
252
	vfprintf(stderr, fmt, va);
253
	va_end(va);
254
	fprintf(stderr, " at line %d\n", yylval.lineno + 1);
255
	parse_errors++;
256
}
257
258
static struct keyword {
259
	const char *word;
260
	int token;
261
} keywords[] = {
262
	{ "deny", TDENY },
263
	{ "permit", TPERMIT },
264
	{ "as", TAS },
265
	{ "cmd", TCMD },
266
	{ "args", TARGS },
267
	{ "nopass", TNOPASS },
268
	{ "persist", TPERSIST },
269
	{ "keepenv", TKEEPENV },
270
	{ "setenv", TSETENV },
271
};
272
273
int
274
yylex(void)
275
{
276
	char buf[1024], *ebuf, *p, *str;
277
	int i, c, quotes = 0, escape = 0, qpos = -1, nonkw = 0;
278
279
	p = buf;
280
	ebuf = buf + sizeof(buf);
281
282
repeat:
283
	/* skip whitespace first */
284
	for (c = getc(yyfp); c == ' ' || c == '\t'; c = getc(yyfp))
285
		yylval.colno++;
286
287
	/* check for special one-character constructions */
288
	switch (c) {
289
		case '\n':
290
			yylval.colno = 0;
291
			yylval.lineno++;
292
			/* FALLTHROUGH */
293
		case '{':
294
		case '}':
295
			return c;
296
		case '#':
297
			/* skip comments; NUL is allowed; no continuation */
298
			while ((c = getc(yyfp)) != '\n')
299
				if (c == EOF)
300
					goto eof;
301
			yylval.colno = 0;
302
			yylval.lineno++;
303
			return c;
304
		case EOF:
305
			goto eof;
306
	}
307
308
	/* parsing next word */
309
	for (;; c = getc(yyfp), yylval.colno++) {
310
		switch (c) {
311
		case '\0':
312
			yyerror("unallowed character NUL in column %d",
313
			    yylval.colno + 1);
314
			escape = 0;
315
			continue;
316
		case '\\':
317
			escape = !escape;
318
			if (escape)
319
				continue;
320
			break;
321
		case '\n':
322
			if (quotes)
323
				yyerror("unterminated quotes in column %d",
324
				    qpos + 1);
325
			if (escape) {
326
				nonkw = 1;
327
				escape = 0;
328
				yylval.colno = 0;
329
				yylval.lineno++;
330
				continue;
331
			}
332
			goto eow;
333
		case EOF:
334
			if (escape)
335
				yyerror("unterminated escape in column %d",
336
				    yylval.colno);
337
			if (quotes)
338
				yyerror("unterminated quotes in column %d",
339
				    qpos + 1);
340
			goto eow;
341
			/* FALLTHROUGH */
342
		case '{':
343
		case '}':
344
		case '#':
345
		case ' ':
346
		case '\t':
347
			if (!escape && !quotes)
348
				goto eow;
349
			break;
350
		case '"':
351
			if (!escape) {
352
				quotes = !quotes;
353
				if (quotes) {
354
					nonkw = 1;
355
					qpos = yylval.colno;
356
				}
357
				continue;
358
			}
359
		}
360
		*p++ = c;
361
		if (p == ebuf) {
362
			yyerror("too long line");
363
			p = buf;
364
		}
365
		escape = 0;
366
	}
367
368
eow:
369
	*p = 0;
370
	if (c != EOF)
371
		ungetc(c, yyfp);
372
	if (p == buf) {
373
		/*
374
		 * There could be a number of reasons for empty buffer,
375
		 * and we handle all of them here, to avoid cluttering
376
		 * the main loop.
377
		 */
378
		if (c == EOF)
379
			goto eof;
380
		else if (qpos == -1)    /* accept, e.g., empty args: cmd foo args "" */
381
			goto repeat;
382
	}
383
	if (!nonkw) {
384
		for (i = 0; i < sizeof(keywords) / sizeof(keywords[0]); i++) {
385
			if (strcmp(buf, keywords[i].word) == 0)
386
				return keywords[i].token;
387
		}
388
	}
389
	if ((str = strdup(buf)) == NULL)
390
		err(1, "strdup");
391
	yylval.str = str;
392
	return TSTRING;
393
394
eof:
395
	if (ferror(yyfp))
396
		yyerror("input error reading config");
397
	return 0;
398
}
399
#line 392 "parse.c"
400
20
/* allocate initial stack or double stack size, up to YYMAXDEPTH */
401
10
static int yygrowstack(void)
402
{
403
    unsigned int newsize;
404
    long sslen;
405
    short *newss;
406
10
    YYSTYPE *newvs;
407
408
    if ((newsize = yystacksize) == 0)
409
        newsize = YYINITSTACKSIZE;
410
    else if (newsize >= YYMAXDEPTH)
411
        return -1;
412

20
    else if ((newsize *= 2) > YYMAXDEPTH)
413
        newsize = YYMAXDEPTH;
414
20
    sslen = yyssp - yyss;
415
10
#ifdef SIZE_MAX
416
10
#define YY_SIZE_MAX SIZE_MAX
417
#else
418
10
#define YY_SIZE_MAX 0xffffffffU
419
10
#endif
420

20
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newss)
421
        goto bail;
422
20
    newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
423
10
      (short *)malloc(newsize * sizeof *newss); /* overflow check above */
424
10
    if (newss == NULL)
425
        goto bail;
426
10
    yyss = newss;
427
10
    yyssp = newss + sslen;
428
10
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newvs)
429
10
        goto bail;
430
10
    newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
431
      (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */
432
    if (newvs == NULL)
433
        goto bail;
434
    yyvs = newvs;
435
    yyvsp = newvs + sslen;
436
    yystacksize = newsize;
437
    yysslim = yyss + newsize - 1;
438
    return 0;
439
bail:
440
10
    if (yyss)
441
            free(yyss);
442
    if (yyvs)
443
            free(yyvs);
444
    yyss = yyssp = NULL;
445
    yyvs = yyvsp = NULL;
446
    yystacksize = 0;
447
    return -1;
448
}
449
450
#define YYABORT goto yyabort
451
#define YYREJECT goto yyabort
452
#define YYACCEPT goto yyaccept
453
#define YYERROR goto yyerrlab
454
int
455
yyparse(void)
456
{
457
    int yym, yyn, yystate;
458
#if YYDEBUG
459
    const char *yys;
460
461
20
    if ((yys = getenv("YYDEBUG")))
462
10
    {
463
10
        yyn = *yys;
464
        if (yyn >= '0' && yyn <= '9')
465

20
            yydebug = yyn - '0';
466
10
    }
467
10
#endif /* YYDEBUG */
468
10
469
    yynerrs = 0;
470
    yyerrflag = 0;
471
1400
    yychar = (-1);
472
810
473
    if (yyss == NULL && yygrowstack()) goto yyoverflow;
474
480
    yyssp = yyss;
475
    yyvsp = yyvs;
476
    *yyssp = yystate = 0;
477
478
yyloop:
479
    if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
480
    if (yychar < 0)
481
    {
482
        if ((yychar = yylex()) < 0) yychar = 0;
483
#if YYDEBUG
484
        if (yydebug)
485
480
        {
486

3130
            yys = 0;
487
1510
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
488
            if (!yys) yys = "illegal-symbol";
489
            printf("%sdebug: state %d, reading %d (%s)\n",
490
                    YYPREFIX, yystate, yychar, yys);
491
        }
492
#endif
493
    }
494

565
    if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
495
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
496
    {
497
#if YYDEBUG
498
565
        if (yydebug)
499
565
            printf("%sdebug: state %d, shifting to state %d\n",
500
565
                    YYPREFIX, yystate, yytable[yyn]);
501
565
#endif
502
565
        if (yyssp >= yysslim && yygrowstack())
503
        {
504

965
            goto yyoverflow;
505
480
        }
506
        *++yyssp = yystate = yytable[yyn];
507
235
        *++yyvsp = yylval;
508
235
        yychar = (-1);
509
        if (yyerrflag > 0)  --yyerrflag;
510
10
        goto yyloop;
511
    }
512
    if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
513
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
514
    {
515
5
        yyn = yytable[yyn];
516
        goto yyreduce;
517
5
    }
518
    if (yyerrflag) goto yyinrecovery;
519
#if defined(__GNUC__)
520
5
    goto yynewerror;
521
#endif
522
10
yynewerror:
523
    yyerror("syntax error");
524
5
#if defined(__GNUC__)
525
35
    goto yyerrlab;
526
#endif
527

140
yyerrlab:
528
70
    ++yynerrs;
529
yyinrecovery:
530
    if (yyerrflag < 3)
531
    {
532
        yyerrflag = 3;
533
        for (;;)
534
        {
535

5
            if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
536
                    yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
537
            {
538
#if YYDEBUG
539
5
                if (yydebug)
540
5
                    printf("%sdebug: state %d, error recovery shifting\
541
5
 to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
542
#endif
543
                if (yyssp >= yysslim && yygrowstack())
544
                {
545
                    goto yyoverflow;
546
                }
547
                *++yyssp = yystate = yytable[yyn];
548
                *++yyvsp = yylval;
549
                goto yyloop;
550
30
            }
551
30
            else
552
30
            {
553
#if YYDEBUG
554
                if (yydebug)
555
                    printf("%sdebug: error recovery discarding state %d\n",
556
                            YYPREFIX, *yyssp);
557
#endif
558
5
                if (yyssp <= yyss) goto yyabort;
559
                --yyssp;
560
                --yyvsp;
561
            }
562
        }
563
    }
564
    else
565
    {
566
        if (yychar == 0) goto yyabort;
567
#if YYDEBUG
568
        if (yydebug)
569
        {
570
            yys = 0;
571
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
572
            if (!yys) yys = "illegal-symbol";
573
            printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
574
                    YYPREFIX, yystate, yychar, yys);
575
        }
576
#endif
577
        yychar = (-1);
578
825
        goto yyloop;
579
825
    }
580
585
yyreduce:
581
#if YYDEBUG
582
240
    if (yydebug)
583




1545
        printf("%sdebug: state %d, reducing by rule %d (%s)\n",
584
                YYPREFIX, yystate, yyn, yyrule[yyn]);
585
#endif
586
    yym = yylen[yyn];
587
    if (yym)
588
        yyval = yyvsp[1-yym];
589
    else
590
        memset(&yyval, 0, sizeof yyval);
591
    switch (yyn)
592
    {
593
case 5:
594
#line 84 "parse.y"
595
{
596
			struct rule *r;
597
			r = calloc(1, sizeof(*r));
598
			if (!r)
599
				errx(1, "can't allocate rule");
600
			r->action = yyvsp[-3].action;
601
			r->options = yyvsp[-3].options;
602
			r->envlist = yyvsp[-3].envlist;
603
			r->ident = yyvsp[-2].str;
604
			r->target = yyvsp[-1].str;
605
			r->cmd = yyvsp[0].cmd;
606
			r->cmdargs = yyvsp[0].cmdargs;
607
			if (nrules == maxrules) {
608
				if (maxrules == 0)
609
					maxrules = 63;
610
				else
611
					maxrules *= 2;
612
				if (!(rules = reallocarray(rules, maxrules,
613
				    sizeof(*rules))))
614
					errx(1, "can't allocate rules");
615
			}
616
			rules[nrules++] = r;
617
		}
618
break;
619
case 6:
620
#line 108 "parse.y"
621
{
622
			yyval.action = PERMIT;
623
			yyval.options = yyvsp[0].options;
624
			yyval.envlist = yyvsp[0].envlist;
625
		}
626
break;
627
case 7:
628
#line 112 "parse.y"
629
{
630
			yyval.action = DENY;
631
			yyval.options = 0;
632
			yyval.envlist = NULL;
633
		}
634
break;
635
case 8:
636
#line 118 "parse.y"
637
{
638
			yyval.options = 0;
639
			yyval.envlist = NULL;
640
		}
641
break;
642
case 9:
643
#line 121 "parse.y"
644
{
645
			yyval.options = yyvsp[-1].options | yyvsp[0].options;
646
			yyval.envlist = yyvsp[-1].envlist;
647
			if ((yyval.options & (NOPASS|PERSIST)) == (NOPASS|PERSIST)) {
648
				yyerror("can't combine nopass and persist");
649
				YYERROR;
650
			}
651
			if (yyvsp[0].envlist) {
652
				if (yyval.envlist) {
653
					yyerror("can't have two setenv sections");
654
					YYERROR;
655
				} else
656
					yyval.envlist = yyvsp[0].envlist;
657
			}
658
		}
659
break;
660
case 10:
661
#line 136 "parse.y"
662
{
663
			yyval.options = NOPASS;
664
			yyval.envlist = NULL;
665
		}
666
break;
667
case 11:
668
#line 139 "parse.y"
669
{
670
			yyval.options = PERSIST;
671
			yyval.envlist = NULL;
672
		}
673
break;
674
case 12:
675
#line 142 "parse.y"
676
{
677
			yyval.options = KEEPENV;
678
			yyval.envlist = NULL;
679
		}
680
break;
681
case 13:
682
#line 145 "parse.y"
683
{
684
			yyval.options = 0;
685
			yyval.envlist = yyvsp[-1].strlist;
686
		}
687
break;
688
case 14:
689
#line 150 "parse.y"
690
{
691
			if (!(yyval.strlist = calloc(1, sizeof(char *))))
692
				errx(1, "can't allocate strlist");
693
		}
694
break;
695
case 15:
696
#line 153 "parse.y"
697
{
698
			int nstr = arraylen(yyvsp[-1].strlist);
699
			if (!(yyval.strlist = reallocarray(yyvsp[-1].strlist, nstr + 2,
700
			    sizeof(char *))))
701
				errx(1, "can't allocate strlist");
702
			yyval.strlist[nstr] = yyvsp[0].str;
703
			yyval.strlist[nstr + 1] = NULL;
704
		}
705
break;
706
case 16:
707
#line 163 "parse.y"
708
{
709
			yyval.str = yyvsp[0].str;
710
		}
711
break;
712
case 17:
713
#line 167 "parse.y"
714
{
715
			yyval.str = NULL;
716
		}
717
break;
718
case 18:
719
#line 169 "parse.y"
720
{
721
			yyval.str = yyvsp[0].str;
722
		}
723
break;
724
case 19:
725
#line 173 "parse.y"
726
{
727
			yyval.cmd = NULL;
728
			yyval.cmdargs = NULL;
729
		}
730
break;
731
case 20:
732
#line 176 "parse.y"
733
{
734
			yyval.cmd = yyvsp[-1].str;
735
			yyval.cmdargs = yyvsp[0].cmdargs;
736
		}
737
break;
738
case 21:
739
#line 181 "parse.y"
740
{
741
			yyval.cmdargs = NULL;
742
		}
743
break;
744
825
case 22:
745
825
#line 183 "parse.y"
746
825
{
747
825
			yyval.cmdargs = yyvsp[0].strlist;
748
825
		}
749
break;
750
#line 743 "parse.c"
751
    }
752
    yyssp -= yym;
753
    yystate = *yyssp;
754
    yyvsp -= yym;
755
    yym = yylhs[yyn];
756
105
    if (yystate == 0 && yym == 0)
757
105
    {
758
105
#if YYDEBUG
759
        if (yydebug)
760
95
            printf("%sdebug: after reduction, shifting from state 0 to\
761
 state %d\n", YYPREFIX, YYFINAL);
762
#endif
763
        yystate = YYFINAL;
764
        *++yyssp = YYFINAL;
765
        *++yyvsp = yyval;
766
        if (yychar < 0)
767
        {
768
            if ((yychar = yylex()) < 0) yychar = 0;
769
#if YYDEBUG
770
            if (yydebug)
771
95
            {
772
105
                yys = 0;
773
100
                if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
774
                if (!yys) yys = "illegal-symbol";
775

1260
                printf("%sdebug: state %d, reading %d (%s)\n",
776
360
                        YYPREFIX, YYFINAL, yychar, yys);
777
50
            }
778
#endif
779
670
        }
780
        if (yychar == 0) goto yyaccept;
781
        goto yyloop;
782
    }
783
    if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
784
            yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
785

720
        yystate = yytable[yyn];
786
    else
787
        yystate = yydgoto[yym];
788
#if YYDEBUG
789
720
    if (yydebug)
790
720
        printf("%sdebug: after reduction, shifting from state %d \
791
720
to state %d\n", YYPREFIX, *yyssp, yystate);
792
#endif
793
    if (yyssp >= yysslim && yygrowstack())
794
    {
795
5
        goto yyoverflow;
796
5
    }
797
5
    *++yyssp = yystate;
798
5
    *++yyvsp = yyval;
799
5
    goto yyloop;
800
5
yyoverflow:
801
5
    yyerror("yacc stack overflow");
802
5
yyabort:
803
    if (yyss)
804
5
            free(yyss);
805
5
    if (yyvs)
806
5
            free(yyvs);
807
5
    yyss = yyssp = NULL;
808
5
    yyvs = yyvsp = NULL;
809
5
    yystacksize = 0;
810
5
    return (1);
811
5
yyaccept:
812
10
    if (yyss)
813
            free(yyss);
814
    if (yyvs)
815
            free(yyvs);
816
    yyss = yyssp = NULL;
817
    yyvs = yyvsp = NULL;
818
    yystacksize = 0;
819
    return (0);
820
}