1%{
2/*-
3 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 *
5 * Copyright (c) 2011 James Gritton
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD$");
32
33#include <stdlib.h>
34#include <string.h>
35
36#include "jailp.h"
37
38#ifdef DEBUG
39#define YYDEBUG 1
40#endif
41%}
42
43%union {
44	struct cfjail		*j;
45	struct cfparams		*pp;
46	struct cfparam		*p;
47	struct cfstrings	*ss;
48	struct cfstring		*s;
49	char			*cs;
50}
51
52%token      PLEQ
53%token <cs> STR STR1 VAR VAR1
54
55%type <j>  jail
56%type <pp> param_l
57%type <p>  param name
58%type <ss> value
59%type <s>  string
60
61%%
62
63/*
64 * A config file is a series of jails (containing parameters) and jail-less
65 * parameters which really belong to a global pseudo-jail.
66 */
67conf	:
68	;
69	| conf jail
70	;
71	| conf param ';'
72	{
73		struct cfjail *j;
74
75		j = TAILQ_LAST(&cfjails, cfjails);
76		if (!j || strcmp(j->name, "*")) {
77			j = add_jail();
78			j->name = estrdup("*");
79		}
80		TAILQ_INSERT_TAIL(&j->params, $2, tq);
81	}
82	| conf ';'
83
84jail	: STR '{' param_l '}'
85	{
86		$$ = add_jail();
87		$$->name = $1;
88		TAILQ_CONCAT(&$$->params, $3, tq);
89		free($3);
90	}
91	;
92
93param_l	:
94	{
95		$$ = emalloc(sizeof(struct cfparams));
96		TAILQ_INIT($$);
97	}
98	| param_l param ';'
99	{
100		$$ = $1;
101		TAILQ_INSERT_TAIL($$, $2, tq);
102	}
103	| param_l ';'
104	;
105
106/*
107 * Parameters have a name and an optional list of value strings,
108 * which may have "+=" or "=" preceding them.
109 */
110param	: name
111	{
112		$$ = $1;
113	}
114	| name '=' value
115	{
116		$$ = $1;
117		TAILQ_CONCAT(&$$->val, $3, tq);
118		free($3);
119	}
120	| name PLEQ value
121	{
122		$$ = $1;
123		TAILQ_CONCAT(&$$->val, $3, tq);
124		$$->flags |= PF_APPEND;
125		free($3);
126	}
127	| name value
128	{
129		$$ = $1;
130		TAILQ_CONCAT(&$$->val, $2, tq);
131		free($2);
132	}
133	| error
134	{
135	}
136	;
137
138/*
139 * A parameter has a fixed name.  A variable definition looks just like a
140 * parameter except that the name is a variable.
141 */
142name	: STR
143	{
144		$$ = emalloc(sizeof(struct cfparam));
145		$$->name = $1;
146		TAILQ_INIT(&$$->val);
147		$$->flags = 0;
148	}
149	| VAR
150	{
151		$$ = emalloc(sizeof(struct cfparam));
152		$$->name = $1;
153		TAILQ_INIT(&$$->val);
154		$$->flags = PF_VAR;
155	}
156	;
157
158value	: string
159	{
160		$$ = emalloc(sizeof(struct cfstrings));
161		TAILQ_INIT($$);
162		TAILQ_INSERT_TAIL($$, $1, tq);
163	}
164	| value ',' string
165	{
166		$$ = $1;
167		TAILQ_INSERT_TAIL($$, $3, tq);
168	}
169	;
170
171/*
172 * Strings may be passed in pieces, because of quoting and/or variable
173 * interpolation.  Reassemble them into a single string.
174 */
175string	: STR
176	{
177		$$ = emalloc(sizeof(struct cfstring));
178		$$->s = $1;
179		$$->len = strlen($1);
180		STAILQ_INIT(&$$->vars);
181	}
182	| VAR
183	{
184		struct cfvar *v;
185
186		$$ = emalloc(sizeof(struct cfstring));
187		$$->s = estrdup("");
188		$$->len = 0;
189		STAILQ_INIT(&$$->vars);
190		v = emalloc(sizeof(struct cfvar));
191		v->name = $1;
192		v->pos = 0;
193		STAILQ_INSERT_TAIL(&$$->vars, v, tq);
194	}
195	| string STR1
196	{
197		size_t len1;
198
199		$$ = $1;
200		len1 = strlen($2);
201		$$->s = erealloc($$->s, $$->len + len1 + 1);
202		strcpy($$->s + $$->len, $2);
203		free($2);
204		$$->len += len1;
205	}
206	| string VAR1
207	{
208		struct cfvar *v;
209
210		$$ = $1;
211		v = emalloc(sizeof(struct cfvar));
212		v->name = $2;
213		v->pos = $$->len;
214		STAILQ_INSERT_TAIL(&$$->vars, v, tq);
215	}
216	;
217
218%%
219