Blame


1 15902770 2021-01-15 op %{
2 15902770 2021-01-15 op
3 15902770 2021-01-15 op /*
4 f862d389 2024-01-30 op * Copyright (c) 2021-2024 Omar Polo <op@omarpolo.com>
5 c39be742 2021-07-09 op * Copyright (c) 2018 Florian Obser <florian@openbsd.org>
6 c39be742 2021-07-09 op * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
7 c39be742 2021-07-09 op * Copyright (c) 2004 Ryan McBride <mcbride@openbsd.org>
8 c39be742 2021-07-09 op * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
9 c39be742 2021-07-09 op * Copyright (c) 2001 Markus Friedl. All rights reserved.
10 c39be742 2021-07-09 op * Copyright (c) 2001 Daniel Hartmeier. All rights reserved.
11 c39be742 2021-07-09 op * Copyright (c) 2001 Theo de Raadt. All rights reserved.
12 15902770 2021-01-15 op *
13 15902770 2021-01-15 op * Permission to use, copy, modify, and distribute this software for any
14 15902770 2021-01-15 op * purpose with or without fee is hereby granted, provided that the above
15 15902770 2021-01-15 op * copyright notice and this permission notice appear in all copies.
16 15902770 2021-01-15 op *
17 15902770 2021-01-15 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
18 15902770 2021-01-15 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
19 15902770 2021-01-15 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
20 15902770 2021-01-15 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21 15902770 2021-01-15 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
22 15902770 2021-01-15 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
23 15902770 2021-01-15 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 15902770 2021-01-15 op */
25 1f1f3810 2022-02-03 op
26 1f1f3810 2022-02-03 op #include "gmid.h"
27 15902770 2021-01-15 op
28 74f0778b 2021-06-16 op #include <ctype.h>
29 002a84a1 2021-02-10 op #include <errno.h>
30 534afd0d 2022-10-05 op #include <netdb.h>
31 6abda252 2021-02-06 op #include <stdarg.h>
32 15902770 2021-01-15 op #include <stdio.h>
33 74f0778b 2021-06-16 op #include <stdlib.h>
34 32693ee6 2021-01-28 op #include <string.h>
35 9abba172 2023-08-07 op #include <syslog.h>
36 df5058c9 2023-06-05 op
37 df5058c9 2023-06-05 op #include "log.h"
38 15902770 2021-01-15 op
39 af1dab18 2023-06-09 op struct conf *conf;
40 af1dab18 2023-06-09 op
41 c2c051f2 2023-08-25 op static const char *default_host = NULL;
42 509d0509 2023-06-23 op static uint16_t default_port = 1965;
43 509d0509 2023-06-23 op
44 c39be742 2021-07-09 op TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
45 c39be742 2021-07-09 op static struct file {
46 c39be742 2021-07-09 op TAILQ_ENTRY(file) entry;
47 c39be742 2021-07-09 op FILE *stream;
48 c39be742 2021-07-09 op char *name;
49 574f71f7 2024-01-30 op size_t ungetpos;
50 c39be742 2021-07-09 op size_t ungetsize;
51 c39be742 2021-07-09 op u_char *ungetbuf;
52 c39be742 2021-07-09 op int eof_reached;
53 c39be742 2021-07-09 op int lineno;
54 c39be742 2021-07-09 op int errors;
55 c39be742 2021-07-09 op } *file, *topfile;
56 74f0778b 2021-06-16 op
57 c39be742 2021-07-09 op struct file *pushfile(const char *, int);
58 c39be742 2021-07-09 op int popfile(void);
59 c39be742 2021-07-09 op int yyparse(void);
60 c39be742 2021-07-09 op int yylex(void);
61 c39be742 2021-07-09 op void yyerror(const char *, ...)
62 c39be742 2021-07-09 op __attribute__((__format__ (printf, 1, 2)))
63 c39be742 2021-07-09 op __attribute__((__nonnull__ (1)));
64 f3966209 2021-07-13 op void yywarn(const char *, ...)
65 f3966209 2021-07-13 op __attribute__((__format__ (printf, 1, 2)))
66 f3966209 2021-07-13 op __attribute__((__nonnull__ (1)));
67 c39be742 2021-07-09 op int kw_cmp(const void *, const void *);
68 c39be742 2021-07-09 op int lookup(char *);
69 c39be742 2021-07-09 op int igetc(void);
70 c39be742 2021-07-09 op int lgetc(int);
71 c39be742 2021-07-09 op void lungetc(int);
72 c39be742 2021-07-09 op int findeol(void);
73 ef129b08 2021-06-16 op
74 15902770 2021-01-15 op /*
75 15902770 2021-01-15 op * #define YYDEBUG 1
76 15902770 2021-01-15 op * int yydebug = 1;
77 15902770 2021-01-15 op */
78 15902770 2021-01-15 op
79 3b21cca3 2021-06-29 op TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
80 3b21cca3 2021-06-29 op struct sym {
81 3b21cca3 2021-06-29 op TAILQ_ENTRY(sym) entry;
82 3b21cca3 2021-06-29 op int used;
83 3b21cca3 2021-06-29 op int persist;
84 3b21cca3 2021-06-29 op char *name;
85 3b21cca3 2021-06-29 op char *val;
86 3b21cca3 2021-06-29 op };
87 3b21cca3 2021-06-29 op
88 c39be742 2021-07-09 op int symset(const char *, const char *, int);
89 c39be742 2021-07-09 op char *symget(const char *);
90 15902770 2021-01-15 op
91 e17642a7 2021-02-01 op char *ensure_absolute_path(char*);
92 6abda252 2021-02-06 op int check_block_code(int);
93 6abda252 2021-02-06 op char *check_block_fmt(char*);
94 6abda252 2021-02-06 op int check_strip_no(int);
95 a709ddf5 2021-02-07 op int check_prefork_num(int);
96 49b73ba1 2021-02-10 op void advance_loc(void);
97 b7967bc1 2022-01-02 op void advance_proxy(void);
98 7b00c890 2022-10-05 op int fastcgi_conf(const char *, const char *);
99 2025e96d 2022-09-10 op void add_param(char *, char *);
100 534afd0d 2022-10-05 op int getservice(const char *);
101 94f14377 2024-06-17 op void listen_on(const char *, const char *, int);
102 13ed2fb6 2021-01-27 op
103 c39be742 2021-07-09 op static struct vhost *host;
104 c39be742 2021-07-09 op static struct location *loc;
105 b7967bc1 2022-01-02 op static struct proxy *proxy;
106 ee219d70 2022-02-26 op static char *current_media;
107 c39be742 2021-07-09 op static int errors;
108 c39be742 2021-07-09 op
109 c39be742 2021-07-09 op typedef struct {
110 c39be742 2021-07-09 op union {
111 c39be742 2021-07-09 op char *string;
112 c39be742 2021-07-09 op int number;
113 c39be742 2021-07-09 op } v;
114 c39be742 2021-07-09 op int lineno;
115 c39be742 2021-07-09 op } YYSTYPE;
116 8af9da98 2023-06-13 op
117 8af9da98 2023-06-13 op #define YYSTYPE YYSTYPE
118 c39be742 2021-07-09 op
119 15902770 2021-01-15 op %}
120 15902770 2021-01-15 op
121 15902770 2021-01-15 op /* for bison: */
122 15902770 2021-01-15 op /* %define parse.error verbose */
123 15902770 2021-01-15 op
124 226f13ec 2023-07-24 op %token ACCESS ALIAS AUTO
125 c74c7030 2021-07-19 op %token BLOCK
126 6174e65d 2024-06-05 op %token CA CERT CGI CHROOT CLIENT
127 c74c7030 2021-07-19 op %token DEFAULT
128 9abba172 2023-08-07 op %token FACILITY FASTCGI FOR_HOST
129 c74c7030 2021-07-19 op %token INCLUDE INDEX IPV6
130 c74c7030 2021-07-19 op %token KEY
131 f862d389 2024-01-30 op %token LANG LISTEN LOCATION LOG
132 ff05125e 2021-10-15 op %token OCSP OFF ON
133 94f14377 2024-06-17 op %token PARAM PORT PREFORK PROTO PROTOCOLS PROXY PROXYV1
134 72b033ef 2021-12-29 op %token RELAY_TO REQUIRE RETURN ROOT
135 abd261d2 2023-07-25 op %token SERVER SNI SOCKET STRIP STYLE SYSLOG
136 ee219d70 2022-02-26 op %token TCP TOEXT TYPE TYPES
137 593e412b 2022-01-01 op %token USE_TLS USER
138 5128c0b0 2022-01-01 op %token VERIFYNAME
139 d06d6f4b 2021-04-29 op
140 c39be742 2021-07-09 op %token ERROR
141 7252049d 2021-06-29 op
142 c39be742 2021-07-09 op %token <v.string> STRING
143 c39be742 2021-07-09 op %token <v.number> NUM
144 15902770 2021-01-15 op
145 534afd0d 2022-10-05 op %type <v.number> bool proxy_port
146 a7a998ac 2023-06-23 op %type <v.string> string numberstring listen_addr
147 98f52178 2021-06-29 op
148 15902770 2021-01-15 op %%
149 15902770 2021-01-15 op
150 3b2ee15a 2024-06-06 op /*
151 fcf3f1fa 2024-06-06 op * Allow empty lines at the start of the configuration.
152 3b2ee15a 2024-06-06 op */
153 3b2ee15a 2024-06-06 op grammar : nl conf | conf
154 3b2ee15a 2024-06-06 op ;
155 3b2ee15a 2024-06-06 op
156 6b86655a 2021-06-29 op conf : /* empty */
157 ddb089c1 2024-01-26 op | conf include nl
158 ddb089c1 2024-01-26 op | conf varset nl
159 ddb089c1 2024-01-26 op | conf option nl
160 ddb089c1 2024-01-26 op | conf vhost nl
161 ddb089c1 2024-01-26 op | conf types nl
162 ddb089c1 2024-01-26 op | conf error nl { file->errors++; }
163 3b21cca3 2021-06-29 op ;
164 3b21cca3 2021-06-29 op
165 c39be742 2021-07-09 op include : INCLUDE STRING {
166 c39be742 2021-07-09 op struct file *nfile;
167 c39be742 2021-07-09 op
168 c39be742 2021-07-09 op if ((nfile = pushfile($2, 0)) == NULL) {
169 c39be742 2021-07-09 op yyerror("failed to include file %s", $2);
170 c39be742 2021-07-09 op free($2);
171 c39be742 2021-07-09 op YYERROR;
172 c39be742 2021-07-09 op }
173 c39be742 2021-07-09 op free($2);
174 c39be742 2021-07-09 op
175 c39be742 2021-07-09 op file = nfile;
176 c39be742 2021-07-09 op lungetc('\n');
177 c39be742 2021-07-09 op }
178 c39be742 2021-07-09 op ;
179 c39be742 2021-07-09 op
180 c74c7030 2021-07-19 op bool : ON { $$ = 1; }
181 c74c7030 2021-07-19 op | OFF { $$ = 0; }
182 c39be742 2021-07-09 op ;
183 c39be742 2021-07-09 op
184 c39be742 2021-07-09 op string : string STRING {
185 98f52178 2021-06-29 op if (asprintf(&$$, "%s%s", $1, $2) == -1) {
186 98f52178 2021-06-29 op free($1);
187 98f52178 2021-06-29 op free($2);
188 98f52178 2021-06-29 op yyerror("string: asprintf: %s", strerror(errno));
189 98f52178 2021-06-29 op YYERROR;
190 98f52178 2021-06-29 op }
191 98f52178 2021-06-29 op free($1);
192 98f52178 2021-06-29 op free($2);
193 98f52178 2021-06-29 op }
194 c39be742 2021-07-09 op | STRING
195 98f52178 2021-06-29 op ;
196 98f52178 2021-06-29 op
197 ee219d70 2022-02-26 op numberstring : NUM {
198 ee219d70 2022-02-26 op char *s;
199 ee219d70 2022-02-26 op if (asprintf(&s, "%d", $1) == -1) {
200 ee219d70 2022-02-26 op yyerror("asprintf: number");
201 ee219d70 2022-02-26 op YYERROR;
202 ee219d70 2022-02-26 op }
203 ee219d70 2022-02-26 op $$ = s;
204 ee219d70 2022-02-26 op }
205 ee219d70 2022-02-26 op | STRING
206 ee219d70 2022-02-26 op ;
207 ee219d70 2022-02-26 op
208 c39be742 2021-07-09 op varset : STRING '=' string {
209 3b21cca3 2021-06-29 op char *s = $1;
210 3b21cca3 2021-06-29 op while (*s++) {
211 c39be742 2021-07-09 op if (isspace((unsigned char)*s)) {
212 3b21cca3 2021-06-29 op yyerror("macro name cannot contain "
213 3b21cca3 2021-06-29 op "whitespaces");
214 3b21cca3 2021-06-29 op free($1);
215 3b21cca3 2021-06-29 op free($3);
216 3b21cca3 2021-06-29 op YYERROR;
217 3b21cca3 2021-06-29 op }
218 3b21cca3 2021-06-29 op }
219 3b21cca3 2021-06-29 op symset($1, $3, 0);
220 3b21cca3 2021-06-29 op free($1);
221 3b21cca3 2021-06-29 op free($3);
222 3b21cca3 2021-06-29 op }
223 15902770 2021-01-15 op ;
224 15902770 2021-01-15 op
225 7277bb7d 2022-09-10 op option : CHROOT string {
226 af1dab18 2023-06-09 op if (strlcpy(conf->chroot, $2, sizeof(conf->chroot)) >=
227 af1dab18 2023-06-09 op sizeof(conf->chroot))
228 7277bb7d 2022-09-10 op yyerror("chroot path too long");
229 7277bb7d 2022-09-10 op free($2);
230 7277bb7d 2022-09-10 op }
231 509d0509 2023-06-23 op | IPV6 bool {
232 509d0509 2023-06-23 op yywarn("option `ipv6' is deprecated,"
233 509d0509 2023-06-23 op " please use `listen on'");
234 509d0509 2023-06-23 op if ($2)
235 c2c051f2 2023-08-25 op default_host = NULL;
236 509d0509 2023-06-23 op else
237 509d0509 2023-06-23 op default_host = "0.0.0.0";
238 509d0509 2023-06-23 op }
239 226f13ec 2023-07-24 op | log
240 509d0509 2023-06-23 op | PORT NUM {
241 509d0509 2023-06-23 op yywarn("option `port' is deprecated,"
242 509d0509 2023-06-23 op " please use `listen on'");
243 509d0509 2023-06-23 op default_port = $2;
244 509d0509 2023-06-23 op }
245 af1dab18 2023-06-09 op | PREFORK NUM { conf->prefork = check_prefork_num($2); }
246 c74c7030 2021-07-19 op | PROTOCOLS string {
247 af1dab18 2023-06-09 op if (tls_config_parse_protocols(&conf->protos, $2) == -1)
248 002a84a1 2021-02-10 op yyerror("invalid protocols string \"%s\"", $2);
249 3c4b712b 2022-01-01 op free($2);
250 5bc3c98e 2021-01-15 op }
251 7277bb7d 2022-09-10 op | USER string {
252 af1dab18 2023-06-09 op if (strlcpy(conf->user, $2, sizeof(conf->user)) >=
253 af1dab18 2023-06-09 op sizeof(conf->user))
254 7277bb7d 2022-09-10 op yyerror("user name too long");
255 7277bb7d 2022-09-10 op free($2);
256 7277bb7d 2022-09-10 op }
257 226f13ec 2023-07-24 op ;
258 226f13ec 2023-07-24 op
259 226f13ec 2023-07-24 op log : LOG '{' optnl logopts '}'
260 226f13ec 2023-07-24 op | LOG logopt
261 15902770 2021-01-15 op ;
262 15902770 2021-01-15 op
263 226f13ec 2023-07-24 op logopts : /* empty */
264 226f13ec 2023-07-24 op | logopts logopt optnl
265 226f13ec 2023-07-24 op ;
266 226f13ec 2023-07-24 op
267 3a93c904 2023-08-07 op logopt : ACCESS string {
268 226f13ec 2023-07-24 op free(conf->log_access);
269 226f13ec 2023-07-24 op conf->log_access = $2;
270 abd261d2 2023-07-25 op }
271 f862d389 2024-01-30 op | STYLE string {
272 f862d389 2024-01-30 op if (!strcmp("combined", $2))
273 f862d389 2024-01-30 op conf->log_format = LOG_FORMAT_COMBINED;
274 f862d389 2024-01-30 op else if (!strcmp("common", $2))
275 f862d389 2024-01-30 op conf->log_format = LOG_FORMAT_COMMON;
276 f862d389 2024-01-30 op else if (!strcmp("condensed", $2))
277 f862d389 2024-01-30 op conf->log_format = LOG_FORMAT_CONDENSED;
278 f862d389 2024-01-30 op else if (!strcmp("legacy", $2))
279 f862d389 2024-01-30 op conf->log_format = LOG_FORMAT_LEGACY;
280 f862d389 2024-01-30 op else
281 f862d389 2024-01-30 op yyerror("unknown log style: %s", $2);
282 f862d389 2024-01-30 op free($2);
283 9abba172 2023-08-07 op }
284 9abba172 2023-08-07 op | SYSLOG FACILITY string {
285 9abba172 2023-08-07 op const char *str = $3;
286 9abba172 2023-08-07 op
287 9abba172 2023-08-07 op conf->log_syslog = 1;
288 9abba172 2023-08-07 op
289 9abba172 2023-08-07 op if (!strncasecmp(str, "LOG_", 4))
290 9abba172 2023-08-07 op str += 4;
291 9abba172 2023-08-07 op
292 9abba172 2023-08-07 op if (!strcasecmp(str, "daemon"))
293 9abba172 2023-08-07 op conf->log_facility = LOG_DAEMON;
294 9abba172 2023-08-07 op #ifdef LOG_FTP
295 9abba172 2023-08-07 op else if (!strcasecmp(str, "ftp"))
296 9abba172 2023-08-07 op conf->log_facility = LOG_FTP;
297 9abba172 2023-08-07 op #endif
298 9abba172 2023-08-07 op else if (!strcasecmp(str, "local1"))
299 9abba172 2023-08-07 op conf->log_facility = LOG_LOCAL1;
300 9abba172 2023-08-07 op else if (!strcasecmp(str, "local2"))
301 9abba172 2023-08-07 op conf->log_facility = LOG_LOCAL2;
302 9abba172 2023-08-07 op else if (!strcasecmp(str, "local3"))
303 9abba172 2023-08-07 op conf->log_facility = LOG_LOCAL3;
304 9abba172 2023-08-07 op else if (!strcasecmp(str, "local4"))
305 9abba172 2023-08-07 op conf->log_facility = LOG_LOCAL4;
306 9abba172 2023-08-07 op else if (!strcasecmp(str, "local5"))
307 9abba172 2023-08-07 op conf->log_facility = LOG_LOCAL5;
308 9abba172 2023-08-07 op else if (!strcasecmp(str, "local6"))
309 9abba172 2023-08-07 op conf->log_facility = LOG_LOCAL6;
310 9abba172 2023-08-07 op else if (!strcasecmp(str, "local7"))
311 9abba172 2023-08-07 op conf->log_facility = LOG_LOCAL7;
312 9abba172 2023-08-07 op else if (!strcasecmp(str, "user"))
313 9abba172 2023-08-07 op conf->log_facility = LOG_USER;
314 9abba172 2023-08-07 op else
315 9abba172 2023-08-07 op yywarn("unknown syslog facility `%s'",
316 9abba172 2023-08-07 op $3);
317 9abba172 2023-08-07 op
318 9abba172 2023-08-07 op free($3);
319 3a93c904 2023-08-07 op }
320 3a93c904 2023-08-07 op | SYSLOG OFF {
321 3a93c904 2023-08-07 op conf->log_syslog = 0;
322 3a93c904 2023-08-07 op }
323 3a93c904 2023-08-07 op | SYSLOG {
324 3a93c904 2023-08-07 op conf->log_syslog = 1;
325 abd261d2 2023-07-25 op }
326 226f13ec 2023-07-24 op ;
327 226f13ec 2023-07-24 op
328 c74c7030 2021-07-19 op vhost : SERVER string {
329 b8e64ccd 2021-03-31 op host = new_vhost();
330 af1dab18 2023-06-09 op TAILQ_INSERT_HEAD(&conf->hosts, host, vhosts);
331 b8e64ccd 2021-03-31 op
332 b8e64ccd 2021-03-31 op loc = new_location();
333 b8e64ccd 2021-03-31 op TAILQ_INSERT_HEAD(&host->locations, loc, locations);
334 b8e64ccd 2021-03-31 op
335 b7967bc1 2022-01-02 op TAILQ_INIT(&host->proxies);
336 b7967bc1 2022-01-02 op
337 534afd0d 2022-10-05 op (void) strlcpy(loc->match, "*", sizeof(loc->match));
338 15902770 2021-01-15 op
339 68d36b20 2024-06-09 op if (strlcpy(host->domain, $2, sizeof(host->domain))
340 68d36b20 2024-06-09 op >= sizeof(host->domain))
341 68d36b20 2024-06-09 op yyerror("server name too long: %s", $2);
342 68d36b20 2024-06-09 op
343 cbeee4ca 2021-01-28 op if (strstr($2, "xn--") != NULL) {
344 f3966209 2021-07-13 op yywarn("\"%s\" looks like punycode: you "
345 f3966209 2021-07-13 op "should use the decoded hostname", $2);
346 cbeee4ca 2021-01-28 op }
347 534afd0d 2022-10-05 op
348 534afd0d 2022-10-05 op free($2);
349 b7967bc1 2022-01-02 op } '{' optnl servbody '}' {
350 1c6967b3 2023-06-08 op if (host->cert_path == NULL ||
351 1c6967b3 2023-06-08 op host->key_path == NULL)
352 fc2d207c 2023-06-23 op yyerror("invalid vhost definition: %s",
353 fc2d207c 2023-06-23 op host->domain);
354 509d0509 2023-06-23 op if (TAILQ_EMPTY(&host->addrs)) {
355 509d0509 2023-06-23 op char portno[32];
356 509d0509 2023-06-23 op int r;
357 509d0509 2023-06-23 op
358 509d0509 2023-06-23 op r = snprintf(portno, sizeof(portno), "%d",
359 509d0509 2023-06-23 op default_port);
360 509d0509 2023-06-23 op if (r < 0 || (size_t)r >= sizeof(portno))
361 509d0509 2023-06-23 op fatal("snprintf");
362 509d0509 2023-06-23 op
363 509d0509 2023-06-23 op yywarn("missing `listen on' in server %s,"
364 d8df6756 2024-01-11 op " assuming %s port %d", host->domain,
365 c2c051f2 2023-08-25 op default_host ? default_host : "*",
366 509d0509 2023-06-23 op default_port);
367 94f14377 2024-06-17 op listen_on(default_host, portno, 0);
368 509d0509 2023-06-23 op }
369 15902770 2021-01-15 op }
370 f3966209 2021-07-13 op | error '}' { yyerror("bad server directive"); }
371 15902770 2021-01-15 op ;
372 15902770 2021-01-15 op
373 b7967bc1 2022-01-02 op servbody : /* empty */
374 b7967bc1 2022-01-02 op | servbody servopt optnl
375 b7967bc1 2022-01-02 op | servbody location optnl
376 b7967bc1 2022-01-02 op | servbody proxy optnl
377 a7a998ac 2023-06-23 op ;
378 a7a998ac 2023-06-23 op
379 a7a998ac 2023-06-23 op listen_addr : '*' { $$ = NULL; }
380 a7a998ac 2023-06-23 op | STRING
381 15902770 2021-01-15 op ;
382 15902770 2021-01-15 op
383 c74c7030 2021-07-19 op servopt : ALIAS string {
384 cc8c2901 2021-04-29 op struct alist *a;
385 cc8c2901 2021-04-29 op
386 cc8c2901 2021-04-29 op a = xcalloc(1, sizeof(*a));
387 68d36b20 2024-06-09 op if (strlcpy(a->alias, $2, sizeof(a->alias))
388 68d36b20 2024-06-09 op >= sizeof(a->alias))
389 68d36b20 2024-06-09 op yyerror("alias too long: %s", $2);
390 534afd0d 2022-10-05 op free($2);
391 edc5ca66 2022-09-10 op TAILQ_INSERT_TAIL(&host->aliases, a, aliases);
392 cc8c2901 2021-04-29 op }
393 c74c7030 2021-07-19 op | CERT string {
394 534afd0d 2022-10-05 op ensure_absolute_path($2);
395 1c6967b3 2023-06-08 op free(host->cert_path);
396 1c6967b3 2023-06-08 op host->cert_path = $2;
397 6174e65d 2024-06-05 op }
398 6174e65d 2024-06-05 op | CGI string {
399 6174e65d 2024-06-05 op free($2);
400 6174e65d 2024-06-05 op yyerror("`cgi' was removed in gmid 2.0."
401 6174e65d 2024-06-05 op " Please use fastcgi or proxy instead.");
402 9cc630aa 2021-04-28 op }
403 c74c7030 2021-07-19 op | KEY string {
404 534afd0d 2022-10-05 op ensure_absolute_path($2);
405 1c6967b3 2023-06-08 op free(host->key_path);
406 1c6967b3 2023-06-08 op host->key_path = $2;
407 c92b802b 2021-06-11 op }
408 ff05125e 2021-10-15 op | OCSP string {
409 534afd0d 2022-10-05 op ensure_absolute_path($2);
410 1c6967b3 2023-06-08 op free(host->ocsp_path);
411 1c6967b3 2023-06-08 op host->ocsp_path = $2;
412 ff05125e 2021-10-15 op }
413 c74c7030 2021-07-19 op | PARAM string '=' string {
414 a1ba9650 2023-07-23 op yywarn("the top-level `param' directive is deprecated."
415 a1ba9650 2023-07-23 op " Please use `fastcgi { param ... }`");
416 2025e96d 2022-09-10 op add_param($2, $4);
417 509d0509 2023-06-23 op }
418 911156fb 2023-06-29 op | LISTEN ON listen_addr {
419 94f14377 2024-06-17 op listen_on($3, "1965", 0);
420 7bbf17a8 2023-08-25 op free($3);
421 911156fb 2023-06-29 op }
422 a7a998ac 2023-06-23 op | LISTEN ON listen_addr PORT STRING {
423 94f14377 2024-06-17 op listen_on($3, $5, 0);
424 509d0509 2023-06-23 op free($3);
425 509d0509 2023-06-23 op free($5);
426 509d0509 2023-06-23 op }
427 a7a998ac 2023-06-23 op | LISTEN ON listen_addr PORT NUM {
428 509d0509 2023-06-23 op char portno[32];
429 509d0509 2023-06-23 op int r;
430 509d0509 2023-06-23 op
431 509d0509 2023-06-23 op r = snprintf(portno, sizeof(portno), "%d", $5);
432 509d0509 2023-06-23 op if (r < 0 || (size_t)r >= sizeof(portno))
433 509d0509 2023-06-23 op fatal("snprintf");
434 509d0509 2023-06-23 op
435 94f14377 2024-06-17 op listen_on($3, portno, 0);
436 94f14377 2024-06-17 op free($3);
437 94f14377 2024-06-17 op }
438 94f14377 2024-06-17 op | LISTEN ON listen_addr PROXYV1 {
439 94f14377 2024-06-17 op listen_on($3, "1965", 1);
440 94f14377 2024-06-17 op free($3);
441 94f14377 2024-06-17 op }
442 94f14377 2024-06-17 op | LISTEN ON listen_addr PORT STRING PROXYV1 {
443 94f14377 2024-06-17 op listen_on($3, $5, 1);
444 94f14377 2024-06-17 op free($3);
445 94f14377 2024-06-17 op free($5);
446 94f14377 2024-06-17 op }
447 94f14377 2024-06-17 op | LISTEN ON listen_addr PORT NUM PROXYV1 {
448 94f14377 2024-06-17 op char portno[32];
449 94f14377 2024-06-17 op int r;
450 94f14377 2024-06-17 op
451 94f14377 2024-06-17 op r = snprintf(portno, sizeof(portno), "%d", $5);
452 94f14377 2024-06-17 op if (r < 0 || (size_t)r >= sizeof(portno))
453 94f14377 2024-06-17 op fatal("snprintf");
454 94f14377 2024-06-17 op
455 94f14377 2024-06-17 op listen_on($3, portno, 1);
456 509d0509 2023-06-23 op free($3);
457 c705ecb1 2021-05-03 op }
458 c8b74339 2021-01-24 op | locopt
459 c8b74339 2021-01-24 op ;
460 7bdcc91e 2022-01-01 op
461 b7967bc1 2022-01-02 op proxy : PROXY { advance_proxy(); }
462 b7967bc1 2022-01-02 op proxy_matches '{' optnl proxy_opts '}' {
463 534afd0d 2022-10-05 op if (*proxy->host == '\0')
464 b7967bc1 2022-01-02 op yyerror("invalid proxy block: missing `relay-to' option");
465 b7967bc1 2022-01-02 op
466 deadd9e1 2023-06-09 op if ((proxy->cert_path == NULL && proxy->key_path != NULL) ||
467 deadd9e1 2023-06-09 op (proxy->cert_path != NULL && proxy->key_path == NULL))
468 b7967bc1 2022-01-02 op yyerror("invalid proxy block: missing cert or key");
469 b7967bc1 2022-01-02 op }
470 b7967bc1 2022-01-02 op ;
471 b7967bc1 2022-01-02 op
472 b7967bc1 2022-01-02 op proxy_matches : /* empty */
473 b7967bc1 2022-01-02 op | proxy_matches proxy_match
474 b7967bc1 2022-01-02 op ;
475 b7967bc1 2022-01-02 op
476 534afd0d 2022-10-05 op proxy_port : /* empty */ { $$ = 1965; }
477 534afd0d 2022-10-05 op | PORT STRING {
478 534afd0d 2022-10-05 op if (($$ = getservice($2)) == -1)
479 534afd0d 2022-10-05 op yyerror("invalid port number %s", $2);
480 534afd0d 2022-10-05 op free($2);
481 534afd0d 2022-10-05 op }
482 534afd0d 2022-10-05 op | PORT NUM { $$ = $2; }
483 534afd0d 2022-10-05 op ;
484 534afd0d 2022-10-05 op
485 b7967bc1 2022-01-02 op proxy_match : PROTO string {
486 68d36b20 2024-06-09 op if (strlcpy(proxy->match_proto, $2,
487 68d36b20 2024-06-09 op sizeof(proxy->match_proto))
488 68d36b20 2024-06-09 op >= sizeof(proxy->match_proto))
489 68d36b20 2024-06-09 op yyerror("proto too long: %s", $2);
490 534afd0d 2022-10-05 op free($2);
491 b7967bc1 2022-01-02 op }
492 534afd0d 2022-10-05 op | FOR_HOST string proxy_port {
493 68d36b20 2024-06-09 op if (strlcpy(proxy->match_host, $2,
494 68d36b20 2024-06-09 op sizeof(proxy->match_host))
495 68d36b20 2024-06-09 op >= sizeof(proxy->match_host))
496 68d36b20 2024-06-09 op yyerror("for-host too long: %s", $2);
497 534afd0d 2022-10-05 op (void) snprintf(proxy->match_port, sizeof(proxy->match_port),
498 534afd0d 2022-10-05 op "%d", $3);
499 534afd0d 2022-10-05 op free($2);
500 b7967bc1 2022-01-02 op }
501 7bdcc91e 2022-01-01 op ;
502 7bdcc91e 2022-01-01 op
503 7bdcc91e 2022-01-01 op proxy_opts : /* empty */
504 7bdcc91e 2022-01-01 op | proxy_opts proxy_opt optnl
505 7bdcc91e 2022-01-01 op ;
506 7bdcc91e 2022-01-01 op
507 7bdcc91e 2022-01-01 op proxy_opt : CERT string {
508 deadd9e1 2023-06-09 op free(proxy->cert);
509 7bdcc91e 2022-01-01 op ensure_absolute_path($2);
510 deadd9e1 2023-06-09 op proxy->cert_path = $2;
511 7bdcc91e 2022-01-01 op }
512 7bdcc91e 2022-01-01 op | KEY string {
513 deadd9e1 2023-06-09 op free(proxy->key);
514 7bdcc91e 2022-01-01 op ensure_absolute_path($2);
515 deadd9e1 2023-06-09 op proxy->key_path = $2;
516 c7c8ef44 2022-01-01 op }
517 c7c8ef44 2022-01-01 op | PROTOCOLS string {
518 b7967bc1 2022-01-02 op if (tls_config_parse_protocols(&proxy->protocols, $2) == -1)
519 c7c8ef44 2022-01-01 op yyerror("invalid protocols string \"%s\"", $2);
520 3c4b712b 2022-01-01 op free($2);
521 7bdcc91e 2022-01-01 op }
522 534afd0d 2022-10-05 op | RELAY_TO string proxy_port {
523 68d36b20 2024-06-09 op if (strlcpy(proxy->host, $2, sizeof(proxy->host))
524 68d36b20 2024-06-09 op >= sizeof(proxy->host))
525 68d36b20 2024-06-09 op yyerror("relay-to host too long: %s", $2);
526 534afd0d 2022-10-05 op (void) snprintf(proxy->port, sizeof(proxy->port),
527 534afd0d 2022-10-05 op "%d", $3);
528 534afd0d 2022-10-05 op free($2);
529 593e412b 2022-01-01 op }
530 ba94a608 2022-01-04 op | REQUIRE CLIENT CA string {
531 ba94a608 2022-01-04 op ensure_absolute_path($4);
532 deadd9e1 2023-06-09 op proxy->reqca_path = $4;
533 1cdea97b 2022-01-30 op }
534 1cdea97b 2022-01-30 op | SNI string {
535 68d36b20 2024-06-09 op if (strlcpy(proxy->sni, $2, sizeof(proxy->sni))
536 68d36b20 2024-06-09 op >= sizeof(proxy->sni))
537 68d36b20 2024-06-09 op yyerror("sni hostname too long: %s", $2);
538 534afd0d 2022-10-05 op free($2);
539 ba94a608 2022-01-04 op }
540 593e412b 2022-01-01 op | USE_TLS bool {
541 b7967bc1 2022-01-02 op proxy->notls = !$2;
542 7bdcc91e 2022-01-01 op }
543 5128c0b0 2022-01-01 op | VERIFYNAME bool {
544 b7967bc1 2022-01-02 op proxy->noverifyname = !$2;
545 5128c0b0 2022-01-01 op }
546 7bdcc91e 2022-01-01 op ;
547 7bdcc91e 2022-01-01 op
548 c74c7030 2021-07-19 op location : LOCATION { advance_loc(); } string '{' optnl locopts '}' {
549 49b73ba1 2021-02-10 op /* drop the starting '/' if any */
550 49b73ba1 2021-02-10 op if (*$3 == '/')
551 49b73ba1 2021-02-10 op memmove($3, $3+1, strlen($3));
552 68d36b20 2024-06-09 op if (strlcpy(loc->match, $3, sizeof(loc->match))
553 68d36b20 2024-06-09 op >= sizeof(loc->match))
554 68d36b20 2024-06-09 op yyerror("location path too long: %s", $3);
555 534afd0d 2022-10-05 op free($3);
556 6119e13e 2021-01-19 op }
557 c8b74339 2021-01-24 op | error '}'
558 c8b74339 2021-01-24 op ;
559 c8b74339 2021-01-24 op
560 c8b74339 2021-01-24 op locopts : /* empty */
561 c39be742 2021-07-09 op | locopts locopt optnl
562 c8b74339 2021-01-24 op ;
563 c8b74339 2021-01-24 op
564 c74c7030 2021-07-19 op locopt : AUTO INDEX bool { loc->auto_index = $3 ? 1 : -1; }
565 c74c7030 2021-07-19 op | BLOCK RETURN NUM string {
566 534afd0d 2022-10-05 op check_block_fmt($4);
567 68d36b20 2024-06-09 op if (strlcpy(loc->block_fmt, $4, sizeof(loc->block_fmt))
568 68d36b20 2024-06-09 op >= sizeof(loc->block_fmt))
569 68d36b20 2024-06-09 op yyerror("block return meta too long: %s", $4);
570 6abda252 2021-02-06 op loc->block_code = check_block_code($3);
571 534afd0d 2022-10-05 op free($4);
572 6abda252 2021-02-06 op }
573 c74c7030 2021-07-19 op | BLOCK RETURN NUM {
574 534afd0d 2022-10-05 op (void) strlcpy(loc->block_fmt, "temporary failure",
575 534afd0d 2022-10-05 op sizeof(loc->block_fmt));
576 6abda252 2021-02-06 op loc->block_code = check_block_code($3);
577 6abda252 2021-02-06 op if ($3 >= 30 && $3 < 40)
578 6abda252 2021-02-06 op yyerror("missing `meta' for block return %d", $3);
579 6abda252 2021-02-06 op }
580 c74c7030 2021-07-19 op | BLOCK {
581 534afd0d 2022-10-05 op (void) strlcpy(loc->block_fmt, "temporary failure",
582 534afd0d 2022-10-05 op sizeof(loc->block_fmt));
583 6abda252 2021-02-06 op loc->block_code = 40;
584 6abda252 2021-02-06 op }
585 c74c7030 2021-07-19 op | DEFAULT TYPE string {
586 68d36b20 2024-06-09 op if (strlcpy(loc->default_mime, $3,
587 68d36b20 2024-06-09 op sizeof(loc->default_mime))
588 68d36b20 2024-06-09 op >= sizeof(loc->default_mime))
589 68d36b20 2024-06-09 op yyerror("default type too long: %s", $3);
590 534afd0d 2022-10-05 op free($3);
591 eb59f87e 2021-02-09 op }
592 a1ba9650 2023-07-23 op | fastcgi
593 c74c7030 2021-07-19 op | INDEX string {
594 68d36b20 2024-06-09 op if (strlcpy(loc->index, $2, sizeof(loc->index))
595 68d36b20 2024-06-09 op >= sizeof(loc->index))
596 68d36b20 2024-06-09 op yyerror("index string too long: %s", $2);
597 534afd0d 2022-10-05 op free($2);
598 eb59f87e 2021-02-09 op }
599 c74c7030 2021-07-19 op | LANG string {
600 68d36b20 2024-06-09 op if (strlcpy(loc->lang, $2, sizeof(loc->lang))
601 68d36b20 2024-06-09 op >= sizeof(loc->lang))
602 68d36b20 2024-06-09 op yyerror("lang too long: %s", $2);
603 534afd0d 2022-10-05 op free($2);
604 eb59f87e 2021-02-09 op }
605 c74c7030 2021-07-19 op | LOG bool { loc->disable_log = !$2; }
606 da2185f3 2022-01-01 op | REQUIRE CLIENT CA string {
607 da2185f3 2022-01-01 op ensure_absolute_path($4);
608 deadd9e1 2023-06-09 op loc->reqca_path = $4;
609 da2185f3 2022-01-01 op }
610 da2185f3 2022-01-01 op | ROOT string {
611 68d36b20 2024-06-09 op if (strlcpy(loc->dir, $2, sizeof(loc->dir))
612 68d36b20 2024-06-09 op >= sizeof(loc->dir))
613 68d36b20 2024-06-09 op yyerror("root path too long: %s", $2);
614 534afd0d 2022-10-05 op free($2);
615 da2185f3 2022-01-01 op }
616 da2185f3 2022-01-01 op | STRIP NUM { loc->strip = check_strip_no($2); }
617 da2185f3 2022-01-01 op ;
618 da2185f3 2022-01-01 op
619 a1ba9650 2023-07-23 op fastcgi : FASTCGI '{' optnl fastcgiopts '}'
620 a1ba9650 2023-07-23 op | FASTCGI fastcgiopt
621 6a8387e5 2023-07-23 op | FASTCGI OFF {
622 6a8387e5 2023-07-23 op loc->fcgi = -1;
623 6a8387e5 2023-07-23 op loc->nofcgi = 1;
624 6a8387e5 2023-07-23 op }
625 a1ba9650 2023-07-23 op | FASTCGI string {
626 a1ba9650 2023-07-23 op yywarn("`fastcgi path' is deprecated. "
627 a1ba9650 2023-07-23 op "Please use `fastcgi socket path' instead.");
628 a1ba9650 2023-07-23 op loc->fcgi = fastcgi_conf($2, NULL);
629 534afd0d 2022-10-05 op free($2);
630 0d047efc 2021-05-24 op }
631 a1ba9650 2023-07-23 op ;
632 a1ba9650 2023-07-23 op
633 a1ba9650 2023-07-23 op fastcgiopts : /* empty */
634 a1ba9650 2023-07-23 op | fastcgiopts fastcgiopt optnl
635 a1ba9650 2023-07-23 op ;
636 a1ba9650 2023-07-23 op
637 a1ba9650 2023-07-23 op fastcgiopt : PARAM string '=' string {
638 a1ba9650 2023-07-23 op add_param($2, $4);
639 0d047efc 2021-05-24 op }
640 a1ba9650 2023-07-23 op | SOCKET string {
641 a1ba9650 2023-07-23 op loc->fcgi = fastcgi_conf($2, NULL);
642 534afd0d 2022-10-05 op free($2);
643 0d047efc 2021-05-24 op }
644 a1ba9650 2023-07-23 op | SOCKET TCP string PORT NUM {
645 a1ba9650 2023-07-23 op char *c;
646 a1ba9650 2023-07-23 op
647 a1ba9650 2023-07-23 op if (asprintf(&c, "%d", $5) == -1)
648 a1ba9650 2023-07-23 op fatal("asprintf");
649 a1ba9650 2023-07-23 op loc->fcgi = fastcgi_conf($3, c);
650 a1ba9650 2023-07-23 op free($3);
651 a1ba9650 2023-07-23 op free(c);
652 a1ba9650 2023-07-23 op }
653 a1ba9650 2023-07-23 op | SOCKET TCP string {
654 a1ba9650 2023-07-23 op loc->fcgi = fastcgi_conf($3, "9000");
655 a1ba9650 2023-07-23 op }
656 a1ba9650 2023-07-23 op | SOCKET TCP string PORT string {
657 a1ba9650 2023-07-23 op loc->fcgi = fastcgi_conf($3, $5);
658 a1ba9650 2023-07-23 op free($3);
659 a1ba9650 2023-07-23 op free($5);
660 a1ba9650 2023-07-23 op }
661 03d671e2 2023-08-08 op | STRIP NUM {
662 03d671e2 2023-08-08 op loc->fcgi_strip = $2;
663 03d671e2 2023-08-08 op }
664 ee219d70 2022-02-26 op ;
665 ee219d70 2022-02-26 op
666 cd5826b8 2022-09-10 op types : TYPES '{' optnl mediaopts_l '}' ;
667 0d047efc 2021-05-24 op
668 ee219d70 2022-02-26 op mediaopts_l : mediaopts_l mediaoptsl nl
669 ee219d70 2022-02-26 op | mediaoptsl nl
670 ee219d70 2022-02-26 op ;
671 ee219d70 2022-02-26 op
672 aa9543b9 2022-09-10 op mediaoptsl : STRING {
673 aa9543b9 2022-09-10 op free(current_media);
674 aa9543b9 2022-09-10 op current_media = $1;
675 ddb089c1 2024-01-26 op } medianames_l
676 ee219d70 2022-02-26 op | include
677 ee219d70 2022-02-26 op ;
678 ee219d70 2022-02-26 op
679 ee219d70 2022-02-26 op medianames_l : medianames_l medianamesl
680 ee219d70 2022-02-26 op | medianamesl
681 ee219d70 2022-02-26 op ;
682 ee219d70 2022-02-26 op
683 d8d170aa 2022-04-08 op medianamesl : numberstring {
684 af1dab18 2023-06-09 op if (add_mime(&conf->mime, current_media, $1) == -1)
685 792f302a 2023-06-09 op fatal("add_mime");
686 aa9543b9 2022-09-10 op free($1);
687 d8d170aa 2022-04-08 op }
688 ee219d70 2022-02-26 op ;
689 ee219d70 2022-02-26 op
690 ee219d70 2022-02-26 op nl : '\n' optnl
691 ddb089c1 2024-01-26 op | ';' optnl
692 ee219d70 2022-02-26 op ;
693 ee219d70 2022-02-26 op
694 ddb089c1 2024-01-26 op optnl : nl
695 c39be742 2021-07-09 op | /*empty*/
696 c39be742 2021-07-09 op ;
697 fdea6aa0 2021-04-30 op
698 c39be742 2021-07-09 op %%
699 b8e64ccd 2021-03-31 op
700 e5d82d94 2022-03-19 op static const struct keyword {
701 74f0778b 2021-06-16 op const char *word;
702 74f0778b 2021-06-16 op int token;
703 74f0778b 2021-06-16 op } keywords[] = {
704 d93c8191 2021-07-09 op /* these MUST be sorted */
705 226f13ec 2023-07-24 op {"access", ACCESS},
706 c74c7030 2021-07-19 op {"alias", ALIAS},
707 c74c7030 2021-07-19 op {"auto", AUTO},
708 c74c7030 2021-07-19 op {"block", BLOCK},
709 c74c7030 2021-07-19 op {"ca", CA},
710 c74c7030 2021-07-19 op {"cert", CERT},
711 6174e65d 2024-06-05 op {"cgi", CGI},
712 c74c7030 2021-07-19 op {"chroot", CHROOT},
713 c74c7030 2021-07-19 op {"client", CLIENT},
714 c74c7030 2021-07-19 op {"default", DEFAULT},
715 9abba172 2023-08-07 op {"facility", FACILITY},
716 abc8801d 2021-07-19 op {"fastcgi", FASTCGI},
717 b7967bc1 2022-01-02 op {"for-host", FOR_HOST},
718 88971f9a 2022-02-26 op {"include", INCLUDE},
719 c74c7030 2021-07-19 op {"index", INDEX},
720 c74c7030 2021-07-19 op {"ipv6", IPV6},
721 c74c7030 2021-07-19 op {"key", KEY},
722 c74c7030 2021-07-19 op {"lang", LANG},
723 509d0509 2023-06-23 op {"listen", LISTEN},
724 c74c7030 2021-07-19 op {"location", LOCATION},
725 c74c7030 2021-07-19 op {"log", LOG},
726 ff05125e 2021-10-15 op {"ocsp", OCSP},
727 c74c7030 2021-07-19 op {"off", OFF},
728 c74c7030 2021-07-19 op {"on", ON},
729 c74c7030 2021-07-19 op {"param", PARAM},
730 c74c7030 2021-07-19 op {"port", PORT},
731 c74c7030 2021-07-19 op {"prefork", PREFORK},
732 b7967bc1 2022-01-02 op {"proto", PROTO},
733 c74c7030 2021-07-19 op {"protocols", PROTOCOLS},
734 72b033ef 2021-12-29 op {"proxy", PROXY},
735 94f14377 2024-06-17 op {"proxy-v1", PROXYV1},
736 72b033ef 2021-12-29 op {"relay-to", RELAY_TO},
737 c74c7030 2021-07-19 op {"require", REQUIRE},
738 c74c7030 2021-07-19 op {"return", RETURN},
739 c74c7030 2021-07-19 op {"root", ROOT},
740 c74c7030 2021-07-19 op {"server", SERVER},
741 1cdea97b 2022-01-30 op {"sni", SNI},
742 a1ba9650 2023-07-23 op {"socket", SOCKET},
743 c74c7030 2021-07-19 op {"strip", STRIP},
744 abd261d2 2023-07-25 op {"style", STYLE},
745 226f13ec 2023-07-24 op {"syslog", SYSLOG},
746 c74c7030 2021-07-19 op {"tcp", TCP},
747 c74c7030 2021-07-19 op {"to-ext", TOEXT},
748 c74c7030 2021-07-19 op {"type", TYPE},
749 ee219d70 2022-02-26 op {"types", TYPES},
750 593e412b 2022-01-01 op {"use-tls", USE_TLS},
751 c74c7030 2021-07-19 op {"user", USER},
752 5128c0b0 2022-01-01 op {"verifyname", VERIFYNAME},
753 74f0778b 2021-06-16 op };
754 74f0778b 2021-06-16 op
755 c39be742 2021-07-09 op void
756 c39be742 2021-07-09 op yyerror(const char *msg, ...)
757 c39be742 2021-07-09 op {
758 c39be742 2021-07-09 op va_list ap;
759 c39be742 2021-07-09 op
760 c39be742 2021-07-09 op file->errors++;
761 c39be742 2021-07-09 op
762 c39be742 2021-07-09 op va_start(ap, msg);
763 f3966209 2021-07-13 op fprintf(stderr, "%s:%d error: ", config_path, yylval.lineno);
764 f3966209 2021-07-13 op vfprintf(stderr, msg, ap);
765 f3966209 2021-07-13 op fprintf(stderr, "\n");
766 f3966209 2021-07-13 op va_end(ap);
767 f3966209 2021-07-13 op }
768 f3966209 2021-07-13 op
769 f3966209 2021-07-13 op void
770 f3966209 2021-07-13 op yywarn(const char *msg, ...)
771 f3966209 2021-07-13 op {
772 f3966209 2021-07-13 op va_list ap;
773 f3966209 2021-07-13 op
774 f3966209 2021-07-13 op va_start(ap, msg);
775 f3966209 2021-07-13 op fprintf(stderr, "%s:%d warning: ", config_path, yylval.lineno);
776 c39be742 2021-07-09 op vfprintf(stderr, msg, ap);
777 c39be742 2021-07-09 op fprintf(stderr, "\n");
778 c39be742 2021-07-09 op va_end(ap);
779 c39be742 2021-07-09 op }
780 c39be742 2021-07-09 op
781 d93c8191 2021-07-09 op int
782 d93c8191 2021-07-09 op kw_cmp(const void *k, const void *e)
783 d93c8191 2021-07-09 op {
784 d93c8191 2021-07-09 op return strcmp(k, ((struct keyword *)e)->word);
785 d93c8191 2021-07-09 op }
786 d93c8191 2021-07-09 op
787 c39be742 2021-07-09 op int
788 c39be742 2021-07-09 op lookup(char *s)
789 74f0778b 2021-06-16 op {
790 c39be742 2021-07-09 op const struct keyword *p;
791 74f0778b 2021-06-16 op
792 c39be742 2021-07-09 op p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
793 c39be742 2021-07-09 op sizeof(keywords[0]), kw_cmp);
794 74f0778b 2021-06-16 op
795 c39be742 2021-07-09 op if (p)
796 c39be742 2021-07-09 op return p->token;
797 c39be742 2021-07-09 op else
798 c39be742 2021-07-09 op return STRING;
799 c39be742 2021-07-09 op }
800 c39be742 2021-07-09 op
801 c39be742 2021-07-09 op #define START_EXPAND 1
802 c39be742 2021-07-09 op #define DONE_EXPAND 2
803 c39be742 2021-07-09 op
804 c39be742 2021-07-09 op static int expanding;
805 c39be742 2021-07-09 op
806 c39be742 2021-07-09 op int
807 c39be742 2021-07-09 op igetc(void)
808 c39be742 2021-07-09 op {
809 c39be742 2021-07-09 op int c;
810 c39be742 2021-07-09 op
811 c39be742 2021-07-09 op while (1) {
812 c39be742 2021-07-09 op if (file->ungetpos > 0)
813 c39be742 2021-07-09 op c = file->ungetbuf[--file->ungetpos];
814 c39be742 2021-07-09 op else
815 c39be742 2021-07-09 op c = getc(file->stream);
816 c39be742 2021-07-09 op
817 c39be742 2021-07-09 op if (c == START_EXPAND)
818 c39be742 2021-07-09 op expanding = 1;
819 c39be742 2021-07-09 op else if (c == DONE_EXPAND)
820 c39be742 2021-07-09 op expanding = 0;
821 c39be742 2021-07-09 op else
822 c39be742 2021-07-09 op break;
823 74f0778b 2021-06-16 op }
824 c39be742 2021-07-09 op return c;
825 c39be742 2021-07-09 op }
826 74f0778b 2021-06-16 op
827 c39be742 2021-07-09 op int
828 c39be742 2021-07-09 op lgetc(int quotec)
829 c39be742 2021-07-09 op {
830 c39be742 2021-07-09 op int c, next;
831 c39be742 2021-07-09 op
832 c39be742 2021-07-09 op if (quotec) {
833 c39be742 2021-07-09 op if ((c = igetc()) == EOF) {
834 c39be742 2021-07-09 op yyerror("reached end of file while parsing "
835 c39be742 2021-07-09 op "quoted string");
836 c39be742 2021-07-09 op if (file == topfile || popfile() == EOF)
837 c39be742 2021-07-09 op return EOF;
838 c39be742 2021-07-09 op return quotec;
839 c39be742 2021-07-09 op }
840 74f0778b 2021-06-16 op return c;
841 74f0778b 2021-06-16 op }
842 74f0778b 2021-06-16 op
843 c39be742 2021-07-09 op while ((c = igetc()) == '\\') {
844 c39be742 2021-07-09 op next = igetc();
845 c39be742 2021-07-09 op if (next != '\n') {
846 c39be742 2021-07-09 op c = next;
847 74f0778b 2021-06-16 op break;
848 c39be742 2021-07-09 op }
849 c39be742 2021-07-09 op yylval.lineno = file->lineno;
850 c39be742 2021-07-09 op file->lineno++;
851 c39be742 2021-07-09 op }
852 3b21cca3 2021-06-29 op
853 c39be742 2021-07-09 op if (c == EOF) {
854 c39be742 2021-07-09 op /*
855 c39be742 2021-07-09 op * Fake EOL when hit EOF for the first time. This gets line
856 c39be742 2021-07-09 op * count right if last line in included file is syntactically
857 c39be742 2021-07-09 op * invalid and has no newline.
858 c39be742 2021-07-09 op */
859 c39be742 2021-07-09 op if (file->eof_reached == 0) {
860 c39be742 2021-07-09 op file->eof_reached = 1;
861 c39be742 2021-07-09 op return '\n';
862 c39be742 2021-07-09 op }
863 c39be742 2021-07-09 op while (c == EOF) {
864 c39be742 2021-07-09 op if (file == topfile || popfile() == EOF)
865 c39be742 2021-07-09 op return EOF;
866 c39be742 2021-07-09 op c = igetc();
867 c39be742 2021-07-09 op }
868 c39be742 2021-07-09 op }
869 c39be742 2021-07-09 op return c;
870 c39be742 2021-07-09 op }
871 c39be742 2021-07-09 op
872 c39be742 2021-07-09 op void
873 c39be742 2021-07-09 op lungetc(int c)
874 c39be742 2021-07-09 op {
875 c39be742 2021-07-09 op if (c == EOF)
876 c39be742 2021-07-09 op return;
877 c39be742 2021-07-09 op
878 c39be742 2021-07-09 op if (file->ungetpos >= file->ungetsize) {
879 c39be742 2021-07-09 op void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
880 c39be742 2021-07-09 op if (p == NULL)
881 2dd5994a 2023-06-06 op fatal("lungetc");
882 c39be742 2021-07-09 op file->ungetbuf = p;
883 c39be742 2021-07-09 op file->ungetsize *= 2;
884 c39be742 2021-07-09 op }
885 c39be742 2021-07-09 op file->ungetbuf[file->ungetpos++] = c;
886 c39be742 2021-07-09 op }
887 c39be742 2021-07-09 op
888 c39be742 2021-07-09 op int
889 c39be742 2021-07-09 op findeol(void)
890 c39be742 2021-07-09 op {
891 c39be742 2021-07-09 op int c;
892 c39be742 2021-07-09 op
893 c39be742 2021-07-09 op /* Skip to either EOF or the first real EOL. */
894 c39be742 2021-07-09 op while (1) {
895 c39be742 2021-07-09 op c = lgetc(0);
896 c39be742 2021-07-09 op if (c == '\n') {
897 c39be742 2021-07-09 op file->lineno++;
898 3b21cca3 2021-06-29 op break;
899 c39be742 2021-07-09 op }
900 c39be742 2021-07-09 op if (c == EOF)
901 74f0778b 2021-06-16 op break;
902 c39be742 2021-07-09 op }
903 c39be742 2021-07-09 op return ERROR;
904 c39be742 2021-07-09 op }
905 c39be742 2021-07-09 op
906 c39be742 2021-07-09 op int
907 c39be742 2021-07-09 op yylex(void)
908 c39be742 2021-07-09 op {
909 1bd706dc 2021-07-09 op char buf[8096];
910 1bd706dc 2021-07-09 op char *p, *val;
911 1bd706dc 2021-07-09 op int quotec, next, c;
912 1bd706dc 2021-07-09 op int token;
913 c39be742 2021-07-09 op
914 c39be742 2021-07-09 op top:
915 c39be742 2021-07-09 op p = buf;
916 c39be742 2021-07-09 op while ((c = lgetc(0)) == ' ' || c == '\t')
917 c39be742 2021-07-09 op ; /* nothing */
918 c39be742 2021-07-09 op
919 c39be742 2021-07-09 op yylval.lineno = file->lineno;
920 c39be742 2021-07-09 op if (c == '#')
921 c39be742 2021-07-09 op while ((c = lgetc(0)) != '\n' && c != EOF)
922 c39be742 2021-07-09 op ; /* nothing */
923 c39be742 2021-07-09 op if (c == '$' && !expanding) {
924 c39be742 2021-07-09 op while (1) {
925 c39be742 2021-07-09 op if ((c = lgetc(0)) == EOF)
926 c39be742 2021-07-09 op return 0;
927 67f49405 2021-07-09 op if (p + 1 >= buf + sizeof(buf) -1) {
928 67f49405 2021-07-09 op yyerror("string too long");
929 67f49405 2021-07-09 op return findeol();
930 67f49405 2021-07-09 op }
931 67f49405 2021-07-09 op if (isalnum(c) || c == '_') {
932 67f49405 2021-07-09 op *p++ = c;
933 67f49405 2021-07-09 op continue;
934 67f49405 2021-07-09 op }
935 67f49405 2021-07-09 op *p = '\0';
936 67f49405 2021-07-09 op lungetc(c);
937 67f49405 2021-07-09 op break;
938 67f49405 2021-07-09 op }
939 67f49405 2021-07-09 op val = symget(buf);
940 67f49405 2021-07-09 op if (val == NULL) {
941 67f49405 2021-07-09 op yyerror("macro `%s' not defined", buf);
942 67f49405 2021-07-09 op return findeol();
943 67f49405 2021-07-09 op }
944 67f49405 2021-07-09 op yylval.v.string = xstrdup(val);
945 67f49405 2021-07-09 op return STRING;
946 67f49405 2021-07-09 op }
947 67f49405 2021-07-09 op if (c == '@' && !expanding) {
948 67f49405 2021-07-09 op while (1) {
949 67f49405 2021-07-09 op if ((c = lgetc(0)) == EOF)
950 67f49405 2021-07-09 op return 0;
951 c39be742 2021-07-09 op
952 c39be742 2021-07-09 op if (p + 1 >= buf + sizeof(buf) - 1) {
953 c39be742 2021-07-09 op yyerror("string too long");
954 c39be742 2021-07-09 op return findeol();
955 c39be742 2021-07-09 op }
956 c39be742 2021-07-09 op if (isalnum(c) || c == '_') {
957 c39be742 2021-07-09 op *p++ = c;
958 74f0778b 2021-06-16 op continue;
959 74f0778b 2021-06-16 op }
960 c39be742 2021-07-09 op *p = '\0';
961 c39be742 2021-07-09 op lungetc(c);
962 c39be742 2021-07-09 op break;
963 74f0778b 2021-06-16 op }
964 c39be742 2021-07-09 op val = symget(buf);
965 c39be742 2021-07-09 op if (val == NULL) {
966 c39be742 2021-07-09 op yyerror("macro '%s' not defined", buf);
967 c39be742 2021-07-09 op return findeol();
968 74f0778b 2021-06-16 op }
969 c39be742 2021-07-09 op p = val + strlen(val) - 1;
970 c39be742 2021-07-09 op lungetc(DONE_EXPAND);
971 c39be742 2021-07-09 op while (p >= val) {
972 c39be742 2021-07-09 op lungetc(*p);
973 c39be742 2021-07-09 op p--;
974 c39be742 2021-07-09 op }
975 c39be742 2021-07-09 op lungetc(START_EXPAND);
976 c39be742 2021-07-09 op goto top;
977 74f0778b 2021-06-16 op }
978 74f0778b 2021-06-16 op
979 c39be742 2021-07-09 op switch (c) {
980 c39be742 2021-07-09 op case '\'':
981 c39be742 2021-07-09 op case '"':
982 c39be742 2021-07-09 op quotec = c;
983 c39be742 2021-07-09 op while (1) {
984 c39be742 2021-07-09 op if ((c = lgetc(quotec)) == EOF)
985 c39be742 2021-07-09 op return 0;
986 c39be742 2021-07-09 op if (c == '\n') {
987 c39be742 2021-07-09 op file->lineno++;
988 c39be742 2021-07-09 op continue;
989 c39be742 2021-07-09 op } else if (c == '\\') {
990 c39be742 2021-07-09 op if ((next = lgetc(quotec)) == EOF)
991 c39be742 2021-07-09 op return (0);
992 c39be742 2021-07-09 op if (next == quotec || next == ' ' ||
993 c39be742 2021-07-09 op next == '\t')
994 c39be742 2021-07-09 op c = next;
995 c39be742 2021-07-09 op else if (next == '\n') {
996 c39be742 2021-07-09 op file->lineno++;
997 c39be742 2021-07-09 op continue;
998 c39be742 2021-07-09 op } else
999 c39be742 2021-07-09 op lungetc(next);
1000 c39be742 2021-07-09 op } else if (c == quotec) {
1001 c39be742 2021-07-09 op *p = '\0';
1002 c39be742 2021-07-09 op break;
1003 c39be742 2021-07-09 op } else if (c == '\0') {
1004 f3966209 2021-07-13 op yyerror("invalid syntax");
1005 c39be742 2021-07-09 op return findeol();
1006 c39be742 2021-07-09 op }
1007 c39be742 2021-07-09 op if (p + 1 >= buf + sizeof(buf) - 1) {
1008 c39be742 2021-07-09 op yyerror("string too long");
1009 c39be742 2021-07-09 op return findeol();
1010 c39be742 2021-07-09 op }
1011 c39be742 2021-07-09 op *p++ = c;
1012 c39be742 2021-07-09 op }
1013 c39be742 2021-07-09 op yylval.v.string = strdup(buf);
1014 c39be742 2021-07-09 op if (yylval.v.string == NULL)
1015 2dd5994a 2023-06-06 op fatal("yylex: strdup");
1016 c39be742 2021-07-09 op return STRING;
1017 74f0778b 2021-06-16 op }
1018 c39be742 2021-07-09 op
1019 c39be742 2021-07-09 op #define allowed_to_end_number(x) \
1020 c39be742 2021-07-09 op (isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
1021 c39be742 2021-07-09 op
1022 c39be742 2021-07-09 op if (c == '-' || isdigit(c)) {
1023 c39be742 2021-07-09 op do {
1024 c39be742 2021-07-09 op *p++ = c;
1025 c39be742 2021-07-09 op if ((size_t)(p-buf) >= sizeof(buf)) {
1026 c39be742 2021-07-09 op yyerror("string too long");
1027 c39be742 2021-07-09 op return findeol();
1028 c39be742 2021-07-09 op }
1029 c39be742 2021-07-09 op } while ((c = lgetc(0)) != EOF && isdigit(c));
1030 c39be742 2021-07-09 op lungetc(c);
1031 c39be742 2021-07-09 op if (p == buf + 1 && buf[0] == '-')
1032 c39be742 2021-07-09 op goto nodigits;
1033 c39be742 2021-07-09 op if (c == EOF || allowed_to_end_number(c)) {
1034 c39be742 2021-07-09 op const char *errstr = NULL;
1035 c39be742 2021-07-09 op
1036 c39be742 2021-07-09 op *p = '\0';
1037 c39be742 2021-07-09 op yylval.v.number = strtonum(buf, LLONG_MIN,
1038 c39be742 2021-07-09 op LLONG_MAX, &errstr);
1039 c39be742 2021-07-09 op if (errstr) {
1040 c39be742 2021-07-09 op yyerror("\"%s\" invalid number: %s",
1041 c39be742 2021-07-09 op buf, errstr);
1042 c39be742 2021-07-09 op return findeol();
1043 c39be742 2021-07-09 op }
1044 c39be742 2021-07-09 op return NUM;
1045 c39be742 2021-07-09 op } else {
1046 c39be742 2021-07-09 op nodigits:
1047 c39be742 2021-07-09 op while (p > buf + 1)
1048 c39be742 2021-07-09 op lungetc(*--p);
1049 c39be742 2021-07-09 op c = *--p;
1050 c39be742 2021-07-09 op if (c == '-')
1051 c39be742 2021-07-09 op return c;
1052 c39be742 2021-07-09 op }
1053 74f0778b 2021-06-16 op }
1054 c39be742 2021-07-09 op
1055 c39be742 2021-07-09 op #define allowed_in_string(x) \
1056 c39be742 2021-07-09 op (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
1057 c39be742 2021-07-09 op x != '{' && x != '}' && \
1058 c39be742 2021-07-09 op x != '!' && x != '=' && x != '#' && \
1059 67f49405 2021-07-09 op x != ',' && x != ';'))
1060 c39be742 2021-07-09 op
1061 67f49405 2021-07-09 op if (isalnum(c) || c == ':' || c == '_') {
1062 c39be742 2021-07-09 op do {
1063 c39be742 2021-07-09 op *p++ = c;
1064 c39be742 2021-07-09 op if ((size_t)(p-buf) >= sizeof(buf)) {
1065 c39be742 2021-07-09 op yyerror("string too long");
1066 c39be742 2021-07-09 op return findeol();
1067 c39be742 2021-07-09 op }
1068 c39be742 2021-07-09 op } while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
1069 c39be742 2021-07-09 op lungetc(c);
1070 c39be742 2021-07-09 op *p = '\0';
1071 c39be742 2021-07-09 op if ((token = lookup(buf)) == STRING)
1072 c39be742 2021-07-09 op yylval.v.string = xstrdup(buf);
1073 c39be742 2021-07-09 op return token;
1074 74f0778b 2021-06-16 op }
1075 c39be742 2021-07-09 op if (c == '\n') {
1076 c39be742 2021-07-09 op yylval.lineno = file->lineno;
1077 c39be742 2021-07-09 op file->lineno++;
1078 74f0778b 2021-06-16 op }
1079 c39be742 2021-07-09 op if (c == EOF)
1080 c39be742 2021-07-09 op return 0;
1081 c39be742 2021-07-09 op return c;
1082 c39be742 2021-07-09 op }
1083 c39be742 2021-07-09 op
1084 c39be742 2021-07-09 op struct file *
1085 c39be742 2021-07-09 op pushfile(const char *name, int secret)
1086 c39be742 2021-07-09 op {
1087 c39be742 2021-07-09 op struct file *nfile;
1088 c39be742 2021-07-09 op
1089 c39be742 2021-07-09 op nfile = xcalloc(1, sizeof(*nfile));
1090 c39be742 2021-07-09 op nfile->name = xstrdup(name);
1091 c39be742 2021-07-09 op if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
1092 eae52ad4 2023-06-06 op log_warn("can't open %s", nfile->name);
1093 c39be742 2021-07-09 op free(nfile->name);
1094 c39be742 2021-07-09 op free(nfile);
1095 c39be742 2021-07-09 op return NULL;
1096 74f0778b 2021-06-16 op }
1097 c39be742 2021-07-09 op nfile->lineno = TAILQ_EMPTY(&files) ? 1 : 0;
1098 c39be742 2021-07-09 op nfile->ungetsize = 16;
1099 c39be742 2021-07-09 op nfile->ungetbuf = xcalloc(1, nfile->ungetsize);
1100 c39be742 2021-07-09 op TAILQ_INSERT_TAIL(&files, nfile, entry);
1101 c39be742 2021-07-09 op return nfile;
1102 c39be742 2021-07-09 op }
1103 74f0778b 2021-06-16 op
1104 c39be742 2021-07-09 op int
1105 c39be742 2021-07-09 op popfile(void)
1106 c39be742 2021-07-09 op {
1107 c39be742 2021-07-09 op struct file *prev;
1108 13ed2fb6 2021-01-27 op
1109 c39be742 2021-07-09 op if ((prev = TAILQ_PREV(file, files, entry)) != NULL)
1110 c39be742 2021-07-09 op prev->errors += file->errors;
1111 13ed2fb6 2021-01-27 op
1112 c39be742 2021-07-09 op TAILQ_REMOVE(&files, file, entry);
1113 c39be742 2021-07-09 op fclose(file->stream);
1114 c39be742 2021-07-09 op free(file->name);
1115 c39be742 2021-07-09 op free(file->ungetbuf);
1116 c39be742 2021-07-09 op free(file);
1117 c39be742 2021-07-09 op file = prev;
1118 c39be742 2021-07-09 op return file ? 0 : EOF;
1119 13ed2fb6 2021-01-27 op }
1120 13ed2fb6 2021-01-27 op
1121 68368f4c 2023-06-09 op int
1122 af1dab18 2023-06-09 op parse_conf(struct conf *c, const char *filename)
1123 13ed2fb6 2021-01-27 op {
1124 c39be742 2021-07-09 op struct sym *sym, *next;
1125 af1dab18 2023-06-09 op
1126 c2c051f2 2023-08-25 op default_host = NULL;
1127 509d0509 2023-06-23 op default_port = 1965;
1128 509d0509 2023-06-23 op
1129 af1dab18 2023-06-09 op conf = c;
1130 3b21cca3 2021-06-29 op
1131 c39be742 2021-07-09 op file = pushfile(filename, 0);
1132 c39be742 2021-07-09 op if (file == NULL)
1133 68368f4c 2023-06-09 op return -1;
1134 c39be742 2021-07-09 op topfile = file;
1135 c39be742 2021-07-09 op
1136 13ed2fb6 2021-01-27 op yyparse();
1137 c39be742 2021-07-09 op errors = file->errors;
1138 c39be742 2021-07-09 op popfile();
1139 13ed2fb6 2021-01-27 op
1140 c39be742 2021-07-09 op /* Free macros and check which have not been used. */
1141 3b21cca3 2021-06-29 op TAILQ_FOREACH_SAFE(sym, &symhead, entry, next) {
1142 3b21cca3 2021-06-29 op /* TODO: warn if !sym->used */
1143 3b21cca3 2021-06-29 op if (!sym->persist) {
1144 3b21cca3 2021-06-29 op free(sym->name);
1145 3b21cca3 2021-06-29 op free(sym->val);
1146 3b21cca3 2021-06-29 op TAILQ_REMOVE(&symhead, sym, entry);
1147 3b21cca3 2021-06-29 op free(sym);
1148 3b21cca3 2021-06-29 op }
1149 3b21cca3 2021-06-29 op }
1150 c39be742 2021-07-09 op
1151 c39be742 2021-07-09 op if (errors)
1152 68368f4c 2023-06-09 op return -1;
1153 68368f4c 2023-06-09 op return 0;
1154 13ed2fb6 2021-01-27 op }
1155 e17642a7 2021-02-01 op
1156 c39be742 2021-07-09 op int
1157 c39be742 2021-07-09 op symset(const char *name, const char *val, int persist)
1158 c39be742 2021-07-09 op {
1159 c39be742 2021-07-09 op struct sym *sym;
1160 c39be742 2021-07-09 op
1161 c39be742 2021-07-09 op TAILQ_FOREACH(sym, &symhead, entry) {
1162 c39be742 2021-07-09 op if (!strcmp(name, sym->name))
1163 c39be742 2021-07-09 op break;
1164 c39be742 2021-07-09 op }
1165 c39be742 2021-07-09 op
1166 c39be742 2021-07-09 op if (sym != NULL) {
1167 c39be742 2021-07-09 op if (sym->persist)
1168 c39be742 2021-07-09 op return 0;
1169 c39be742 2021-07-09 op else {
1170 c39be742 2021-07-09 op free(sym->name);
1171 c39be742 2021-07-09 op free(sym->val);
1172 c39be742 2021-07-09 op TAILQ_REMOVE(&symhead, sym, entry);
1173 c39be742 2021-07-09 op free(sym);
1174 c39be742 2021-07-09 op }
1175 c39be742 2021-07-09 op }
1176 c39be742 2021-07-09 op
1177 c39be742 2021-07-09 op sym = xcalloc(1, sizeof(*sym));
1178 c39be742 2021-07-09 op sym->name = xstrdup(name);
1179 c39be742 2021-07-09 op sym->val = xstrdup(val);
1180 c39be742 2021-07-09 op sym->used = 0;
1181 c39be742 2021-07-09 op sym->persist = persist;
1182 c39be742 2021-07-09 op
1183 c39be742 2021-07-09 op TAILQ_INSERT_TAIL(&symhead, sym, entry);
1184 c39be742 2021-07-09 op return 0;
1185 c39be742 2021-07-09 op }
1186 c39be742 2021-07-09 op
1187 c39be742 2021-07-09 op int
1188 c39be742 2021-07-09 op cmdline_symset(char *s)
1189 c39be742 2021-07-09 op {
1190 c39be742 2021-07-09 op char *sym, *val;
1191 c39be742 2021-07-09 op int ret;
1192 c39be742 2021-07-09 op
1193 c39be742 2021-07-09 op if ((val = strrchr(s, '=')) == NULL)
1194 c39be742 2021-07-09 op return -1;
1195 c39be742 2021-07-09 op sym = xcalloc(1, val - s + 1);
1196 c39be742 2021-07-09 op memcpy(sym, s, val - s);
1197 c39be742 2021-07-09 op ret = symset(sym, val + 1, 1);
1198 c39be742 2021-07-09 op free(sym);
1199 c39be742 2021-07-09 op return ret;
1200 c39be742 2021-07-09 op }
1201 c39be742 2021-07-09 op
1202 e17642a7 2021-02-01 op char *
1203 c39be742 2021-07-09 op symget(const char *nam)
1204 c39be742 2021-07-09 op {
1205 c39be742 2021-07-09 op struct sym *sym;
1206 c39be742 2021-07-09 op
1207 c39be742 2021-07-09 op TAILQ_FOREACH(sym, &symhead, entry) {
1208 c39be742 2021-07-09 op if (strcmp(nam, sym->name) == 0) {
1209 c39be742 2021-07-09 op sym->used = 1;
1210 c39be742 2021-07-09 op return sym->val;
1211 c39be742 2021-07-09 op }
1212 c39be742 2021-07-09 op }
1213 c39be742 2021-07-09 op return NULL;
1214 c39be742 2021-07-09 op }
1215 c39be742 2021-07-09 op
1216 c39be742 2021-07-09 op char *
1217 e17642a7 2021-02-01 op ensure_absolute_path(char *path)
1218 e17642a7 2021-02-01 op {
1219 e17642a7 2021-02-01 op if (path == NULL || *path != '/')
1220 adbe6a64 2021-04-30 op yyerror("not an absolute path: %s", path);
1221 e17642a7 2021-02-01 op return path;
1222 e17642a7 2021-02-01 op }
1223 6abda252 2021-02-06 op
1224 6abda252 2021-02-06 op int
1225 6abda252 2021-02-06 op check_block_code(int n)
1226 6abda252 2021-02-06 op {
1227 6abda252 2021-02-06 op if (n < 10 || n >= 70 || (n >= 20 && n <= 29))
1228 6abda252 2021-02-06 op yyerror("invalid block code %d", n);
1229 6abda252 2021-02-06 op return n;
1230 6abda252 2021-02-06 op }
1231 6abda252 2021-02-06 op
1232 6abda252 2021-02-06 op char *
1233 6abda252 2021-02-06 op check_block_fmt(char *fmt)
1234 6abda252 2021-02-06 op {
1235 6abda252 2021-02-06 op char *s;
1236 6abda252 2021-02-06 op
1237 6abda252 2021-02-06 op for (s = fmt; *s; ++s) {
1238 6abda252 2021-02-06 op if (*s != '%')
1239 6abda252 2021-02-06 op continue;
1240 6abda252 2021-02-06 op switch (*++s) {
1241 6abda252 2021-02-06 op case '%':
1242 6abda252 2021-02-06 op case 'p':
1243 6abda252 2021-02-06 op case 'q':
1244 6abda252 2021-02-06 op case 'P':
1245 6abda252 2021-02-06 op case 'N':
1246 6abda252 2021-02-06 op break;
1247 6abda252 2021-02-06 op default:
1248 6abda252 2021-02-06 op yyerror("invalid format specifier %%%c", *s);
1249 6abda252 2021-02-06 op }
1250 6abda252 2021-02-06 op }
1251 6abda252 2021-02-06 op
1252 6abda252 2021-02-06 op return fmt;
1253 6abda252 2021-02-06 op }
1254 6abda252 2021-02-06 op
1255 6abda252 2021-02-06 op int
1256 6abda252 2021-02-06 op check_strip_no(int n)
1257 6abda252 2021-02-06 op {
1258 6abda252 2021-02-06 op if (n <= 0)
1259 6abda252 2021-02-06 op yyerror("invalid strip number %d", n);
1260 a709ddf5 2021-02-07 op return n;
1261 a709ddf5 2021-02-07 op }
1262 a709ddf5 2021-02-07 op
1263 a709ddf5 2021-02-07 op int
1264 a709ddf5 2021-02-07 op check_prefork_num(int n)
1265 a709ddf5 2021-02-07 op {
1266 c26f2460 2023-06-08 op if (n <= 0 || n >= PROC_MAX_INSTANCES)
1267 a709ddf5 2021-02-07 op yyerror("invalid prefork number %d", n);
1268 6abda252 2021-02-06 op return n;
1269 6abda252 2021-02-06 op }
1270 49b73ba1 2021-02-10 op
1271 49b73ba1 2021-02-10 op void
1272 49b73ba1 2021-02-10 op advance_loc(void)
1273 49b73ba1 2021-02-10 op {
1274 b8e64ccd 2021-03-31 op loc = new_location();
1275 b8e64ccd 2021-03-31 op TAILQ_INSERT_TAIL(&host->locations, loc, locations);
1276 49b73ba1 2021-02-10 op }
1277 c705ecb1 2021-05-03 op
1278 c705ecb1 2021-05-03 op void
1279 b7967bc1 2022-01-02 op advance_proxy(void)
1280 b7967bc1 2022-01-02 op {
1281 b7967bc1 2022-01-02 op proxy = new_proxy();
1282 b7967bc1 2022-01-02 op TAILQ_INSERT_TAIL(&host->proxies, proxy, proxies);
1283 b7967bc1 2022-01-02 op }
1284 b7967bc1 2022-01-02 op
1285 8ad1c570 2021-05-09 op int
1286 7b00c890 2022-10-05 op fastcgi_conf(const char *path, const char *port)
1287 8ad1c570 2021-05-09 op {
1288 8ad1c570 2021-05-09 op struct fcgi *f;
1289 5d22294a 2023-06-09 op int i = 0;
1290 fafc6849 2021-06-29 op
1291 af1dab18 2023-06-09 op TAILQ_FOREACH(f, &conf->fcgi, fcgi) {
1292 8ad1c570 2021-05-09 op if (!strcmp(f->path, path) &&
1293 534afd0d 2022-10-05 op ((port == NULL && *f->port == '\0') ||
1294 534afd0d 2022-10-05 op !strcmp(f->port, port)))
1295 8ad1c570 2021-05-09 op return i;
1296 5d22294a 2023-06-09 op ++i;
1297 8ad1c570 2021-05-09 op }
1298 8ad1c570 2021-05-09 op
1299 5d22294a 2023-06-09 op f = xcalloc(1, sizeof(*f));
1300 5d22294a 2023-06-09 op f->id = i;
1301 68d36b20 2024-06-09 op if (strlcpy(f->path, path, sizeof(f->path)) >= sizeof(f->path))
1302 68d36b20 2024-06-09 op yyerror("fastcgi path is too long: %s", path);
1303 68d36b20 2024-06-09 op if (port != NULL &&
1304 68d36b20 2024-06-09 op strlcpy(f->port, port, sizeof(f->port)) >= sizeof(f->port))
1305 68d36b20 2024-06-09 op yyerror("port too long: %s", port);
1306 af1dab18 2023-06-09 op TAILQ_INSERT_TAIL(&conf->fcgi, f, fcgi);
1307 5d22294a 2023-06-09 op
1308 5d22294a 2023-06-09 op return f->id;
1309 c92b802b 2021-06-11 op }
1310 c92b802b 2021-06-11 op
1311 c92b802b 2021-06-11 op void
1312 2025e96d 2022-09-10 op add_param(char *name, char *val)
1313 c92b802b 2021-06-11 op {
1314 c92b802b 2021-06-11 op struct envlist *e;
1315 a1ba9650 2023-07-23 op struct envhead *h = &loc->params;
1316 c92b802b 2021-06-11 op
1317 c92b802b 2021-06-11 op e = xcalloc(1, sizeof(*e));
1318 68d36b20 2024-06-09 op if (strlcpy(e->name, name, sizeof(e->name)) >= sizeof(e->name))
1319 68d36b20 2024-06-09 op yyerror("parameter name too long: %s", name);
1320 68d36b20 2024-06-09 op if (strlcpy(e->value, val, sizeof(e->value)) >= sizeof(e->value))
1321 68d36b20 2024-06-09 op yyerror("param value too long: %s", val);
1322 edc5ca66 2022-09-10 op TAILQ_INSERT_TAIL(h, e, envs);
1323 3b21cca3 2021-06-29 op }
1324 534afd0d 2022-10-05 op
1325 534afd0d 2022-10-05 op int
1326 534afd0d 2022-10-05 op getservice(const char *n)
1327 534afd0d 2022-10-05 op {
1328 534afd0d 2022-10-05 op struct servent *s;
1329 534afd0d 2022-10-05 op const char *errstr;
1330 534afd0d 2022-10-05 op long long llval;
1331 534afd0d 2022-10-05 op
1332 534afd0d 2022-10-05 op llval = strtonum(n, 0, UINT16_MAX, &errstr);
1333 534afd0d 2022-10-05 op if (errstr) {
1334 534afd0d 2022-10-05 op s = getservbyname(n, "tcp");
1335 534afd0d 2022-10-05 op if (s == NULL)
1336 534afd0d 2022-10-05 op s = getservbyname(n, "udp");
1337 534afd0d 2022-10-05 op if (s == NULL)
1338 534afd0d 2022-10-05 op return (-1);
1339 534afd0d 2022-10-05 op return (ntohs(s->s_port));
1340 534afd0d 2022-10-05 op }
1341 534afd0d 2022-10-05 op
1342 534afd0d 2022-10-05 op return ((unsigned short)llval);
1343 509d0509 2023-06-23 op }
1344 509d0509 2023-06-23 op
1345 509d0509 2023-06-23 op static void
1346 94f14377 2024-06-17 op add_to_addr_queue(struct addrhead *a, struct addrinfo *ai, const char *pp,
1347 94f14377 2024-06-17 op int proxy)
1348 509d0509 2023-06-23 op {
1349 509d0509 2023-06-23 op struct address *addr;
1350 509d0509 2023-06-23 op struct sockaddr_in *sin;
1351 509d0509 2023-06-23 op struct sockaddr_in6 *sin6;
1352 509d0509 2023-06-23 op
1353 509d0509 2023-06-23 op if (ai->ai_addrlen > sizeof(addr->ss))
1354 509d0509 2023-06-23 op fatalx("ai_addrlen larger than a sockaddr_storage");
1355 509d0509 2023-06-23 op
1356 509d0509 2023-06-23 op TAILQ_FOREACH(addr, a, addrs) {
1357 509d0509 2023-06-23 op if (addr->ai_flags == ai->ai_flags &&
1358 509d0509 2023-06-23 op addr->ai_family == ai->ai_family &&
1359 509d0509 2023-06-23 op addr->ai_socktype == ai->ai_socktype &&
1360 509d0509 2023-06-23 op addr->ai_protocol == ai->ai_protocol &&
1361 509d0509 2023-06-23 op addr->slen == ai->ai_addrlen &&
1362 94f14377 2024-06-17 op !memcmp(&addr->ss, ai->ai_addr, addr->slen)) {
1363 94f14377 2024-06-17 op if (addr->proxy != proxy)
1364 94f14377 2024-06-17 op yyerror("can't specify the same listen"
1365 94f14377 2024-06-17 op " address both with and without"
1366 94f14377 2024-06-17 op " `proxy-v1'.");
1367 509d0509 2023-06-23 op return;
1368 94f14377 2024-06-17 op }
1369 509d0509 2023-06-23 op }
1370 509d0509 2023-06-23 op
1371 509d0509 2023-06-23 op addr = xcalloc(1, sizeof(*addr));
1372 509d0509 2023-06-23 op addr->ai_flags = ai->ai_flags;
1373 509d0509 2023-06-23 op addr->ai_family = ai->ai_family;
1374 509d0509 2023-06-23 op addr->ai_socktype = ai->ai_socktype;
1375 509d0509 2023-06-23 op addr->ai_protocol = ai->ai_protocol;
1376 509d0509 2023-06-23 op addr->slen = ai->ai_addrlen;
1377 509d0509 2023-06-23 op memcpy(&addr->ss, ai->ai_addr, ai->ai_addrlen);
1378 cd12ad11 2024-05-29 op strlcpy(addr->pp, pp, sizeof(addr->pp));
1379 94f14377 2024-06-17 op addr->proxy = proxy;
1380 509d0509 2023-06-23 op
1381 509d0509 2023-06-23 op /* for commodity */
1382 509d0509 2023-06-23 op switch (addr->ai_family) {
1383 509d0509 2023-06-23 op case AF_INET:
1384 509d0509 2023-06-23 op sin = (struct sockaddr_in *)&addr->ss;
1385 509d0509 2023-06-23 op addr->port = ntohs(sin->sin_port);
1386 509d0509 2023-06-23 op break;
1387 509d0509 2023-06-23 op case AF_INET6:
1388 509d0509 2023-06-23 op sin6 = (struct sockaddr_in6 *)&addr->ss;
1389 509d0509 2023-06-23 op addr->port = ntohs(sin6->sin6_port);
1390 509d0509 2023-06-23 op break;
1391 509d0509 2023-06-23 op default:
1392 509d0509 2023-06-23 op fatalx("unknown socket family %d", addr->ai_family);
1393 509d0509 2023-06-23 op }
1394 509d0509 2023-06-23 op
1395 509d0509 2023-06-23 op addr->sock = -1;
1396 509d0509 2023-06-23 op
1397 509d0509 2023-06-23 op TAILQ_INSERT_HEAD(a, addr, addrs);
1398 534afd0d 2022-10-05 op }
1399 509d0509 2023-06-23 op
1400 509d0509 2023-06-23 op void
1401 94f14377 2024-06-17 op listen_on(const char *hostname, const char *servname, int proxy)
1402 509d0509 2023-06-23 op {
1403 509d0509 2023-06-23 op struct addrinfo hints, *res, *res0;
1404 cd12ad11 2024-05-29 op char pp[NI_MAXHOST];
1405 509d0509 2023-06-23 op int error;
1406 509d0509 2023-06-23 op
1407 509d0509 2023-06-23 op memset(&hints, 0, sizeof(hints));
1408 509d0509 2023-06-23 op hints.ai_family = AF_UNSPEC;
1409 509d0509 2023-06-23 op hints.ai_socktype = SOCK_STREAM;
1410 509d0509 2023-06-23 op hints.ai_flags = AI_PASSIVE;
1411 509d0509 2023-06-23 op error = getaddrinfo(hostname, servname, &hints, &res0);
1412 509d0509 2023-06-23 op if (error) {
1413 509d0509 2023-06-23 op yyerror("listen on \"%s\" port %s: %s", hostname, servname,
1414 509d0509 2023-06-23 op gai_strerror(errno));
1415 509d0509 2023-06-23 op return;
1416 509d0509 2023-06-23 op }
1417 509d0509 2023-06-23 op
1418 509d0509 2023-06-23 op for (res = res0; res; res = res->ai_next) {
1419 cd12ad11 2024-05-29 op if (getnameinfo(res->ai_addr, res->ai_addrlen, pp, sizeof(pp),
1420 cd12ad11 2024-05-29 op NULL, 0, NI_NUMERICHOST) == -1) {
1421 cd12ad11 2024-05-29 op yyerror("getnameinfo failed: %s", strerror(errno));
1422 cd12ad11 2024-05-29 op break;
1423 cd12ad11 2024-05-29 op }
1424 cd12ad11 2024-05-29 op
1425 94f14377 2024-06-17 op add_to_addr_queue(&host->addrs, res, pp, proxy);
1426 94f14377 2024-06-17 op add_to_addr_queue(&conf->addrs, res, pp, proxy);
1427 509d0509 2023-06-23 op }
1428 509d0509 2023-06-23 op
1429 509d0509 2023-06-23 op freeaddrinfo(res0);
1430 509d0509 2023-06-23 op }