1 %{ 2 /*- 3 * SPDX-License-Identifier: BSD-2-Clause 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 */ 67 conf : 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 84 jail : STR '{' param_l '}' 85 { 86 $$ = add_jail(); 87 $$->name = $1; 88 TAILQ_CONCAT(&$$->params, $3, tq); 89 free($3); 90 } 91 ; 92 93 param_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 */ 110 param : 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 */ 142 name : 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 158 value : 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 */ 175 string : 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