1 /*
2  * configparser.y -- yacc grammar for unbound configuration files
3  *
4  * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
5  *
6  * Copyright (c) 2007, NLnet Labs. All rights reserved.
7  *
8  * This software is open source.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * Redistributions of source code must retain the above copyright notice,
15  * this list of conditions and the following disclaimer.
16  *
17  * Redistributions in binary form must reproduce the above copyright notice,
18  * this list of conditions and the following disclaimer in the documentation
19  * and/or other materials provided with the distribution.
20  *
21  * Neither the name of the NLNET LABS nor the names of its contributors may
22  * be used to endorse or promote products derived from this software without
23  * specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
31  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 %{
39 #include "config.h"
40 
41 #include <stdarg.h>
42 #include <stdio.h>
43 #include <string.h>
44 #include <stdlib.h>
45 #include <assert.h>
46 
47 #include "util/configyyrename.h"
48 #include "util/config_file.h"
49 #include "util/net_help.h"
50 
51 int ub_c_lex(void);
52 void ub_c_error(const char *message);
53 
54 /* these need to be global, otherwise they cannot be used inside yacc */
55 extern struct config_parser_state* cfg_parser;
56 
57 #if 0
58 #define OUTYY(s)  printf s /* used ONLY when debugging */
59 #else
60 #define OUTYY(s)
61 #endif
62 
63 %}
64 %union {
65 	char*	str;
66 };
67 
68 %token SPACE LETTER NEWLINE COMMENT COLON ANY ZONESTR
69 %token <str> STRING_ARG
70 %token VAR_SERVER VAR_VERBOSITY VAR_NUM_THREADS VAR_PORT
71 %token VAR_OUTGOING_RANGE VAR_INTERFACE
72 %token VAR_DO_IP4 VAR_DO_IP6 VAR_DO_UDP VAR_DO_TCP
73 %token VAR_CHROOT VAR_USERNAME VAR_DIRECTORY VAR_LOGFILE VAR_PIDFILE
74 %token VAR_MSG_CACHE_SIZE VAR_MSG_CACHE_SLABS VAR_NUM_QUERIES_PER_THREAD
75 %token VAR_RRSET_CACHE_SIZE VAR_RRSET_CACHE_SLABS VAR_OUTGOING_NUM_TCP
76 %token VAR_INFRA_HOST_TTL VAR_INFRA_LAME_TTL VAR_INFRA_CACHE_SLABS
77 %token VAR_INFRA_CACHE_NUMHOSTS VAR_INFRA_CACHE_LAME_SIZE VAR_NAME
78 %token VAR_STUB_ZONE VAR_STUB_HOST VAR_STUB_ADDR VAR_TARGET_FETCH_POLICY
79 %token VAR_HARDEN_SHORT_BUFSIZE VAR_HARDEN_LARGE_QUERIES
80 %token VAR_FORWARD_ZONE VAR_FORWARD_HOST VAR_FORWARD_ADDR
81 %token VAR_DO_NOT_QUERY_ADDRESS VAR_HIDE_IDENTITY VAR_HIDE_VERSION
82 %token VAR_IDENTITY VAR_VERSION VAR_HARDEN_GLUE VAR_MODULE_CONF
83 %token VAR_TRUST_ANCHOR_FILE VAR_TRUST_ANCHOR VAR_VAL_OVERRIDE_DATE
84 %token VAR_BOGUS_TTL VAR_VAL_CLEAN_ADDITIONAL VAR_VAL_PERMISSIVE_MODE
85 %token VAR_INCOMING_NUM_TCP VAR_MSG_BUFFER_SIZE VAR_KEY_CACHE_SIZE
86 %token VAR_KEY_CACHE_SLABS VAR_TRUSTED_KEYS_FILE
87 %token VAR_VAL_NSEC3_KEYSIZE_ITERATIONS VAR_USE_SYSLOG
88 %token VAR_OUTGOING_INTERFACE VAR_ROOT_HINTS VAR_DO_NOT_QUERY_LOCALHOST
89 %token VAR_CACHE_MAX_TTL VAR_HARDEN_DNSSEC_STRIPPED VAR_ACCESS_CONTROL
90 %token VAR_LOCAL_ZONE VAR_LOCAL_DATA VAR_INTERFACE_AUTOMATIC
91 %token VAR_STATISTICS_INTERVAL VAR_DO_DAEMONIZE VAR_USE_CAPS_FOR_ID
92 %token VAR_STATISTICS_CUMULATIVE VAR_OUTGOING_PORT_PERMIT
93 %token VAR_OUTGOING_PORT_AVOID VAR_DLV_ANCHOR_FILE VAR_DLV_ANCHOR
94 %token VAR_NEG_CACHE_SIZE VAR_HARDEN_REFERRAL_PATH VAR_PRIVATE_ADDRESS
95 %token VAR_PRIVATE_DOMAIN VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE
96 %token VAR_CONTROL_INTERFACE VAR_CONTROL_PORT VAR_SERVER_KEY_FILE
97 %token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE
98 %token VAR_EXTENDED_STATISTICS VAR_LOCAL_DATA_PTR VAR_JOSTLE_TIMEOUT
99 %token VAR_STUB_PRIME VAR_UNWANTED_REPLY_THRESHOLD VAR_LOG_TIME_ASCII
100 %token VAR_DOMAIN_INSECURE VAR_PYTHON VAR_PYTHON_SCRIPT VAR_VAL_SIG_SKEW_MIN
101 %token VAR_VAL_SIG_SKEW_MAX VAR_CACHE_MIN_TTL VAR_VAL_LOG_LEVEL
102 %token VAR_AUTO_TRUST_ANCHOR_FILE VAR_KEEP_MISSING VAR_ADD_HOLDDOWN
103 %token VAR_DEL_HOLDDOWN VAR_SO_RCVBUF VAR_EDNS_BUFFER_SIZE VAR_PREFETCH
104 %token VAR_PREFETCH_KEY VAR_SO_SNDBUF VAR_SO_REUSEPORT VAR_HARDEN_BELOW_NXDOMAIN
105 %token VAR_IGNORE_CD_FLAG VAR_LOG_QUERIES VAR_TCP_UPSTREAM VAR_SSL_UPSTREAM
106 %token VAR_SSL_SERVICE_KEY VAR_SSL_SERVICE_PEM VAR_SSL_PORT VAR_FORWARD_FIRST
107 %token VAR_STUB_FIRST VAR_MINIMAL_RESPONSES VAR_RRSET_ROUNDROBIN
108 %token VAR_MAX_UDP_SIZE VAR_DELAY_CLOSE
109 
110 %%
111 toplevelvars: /* empty */ | toplevelvars toplevelvar ;
112 toplevelvar: serverstart contents_server | stubstart contents_stub |
113 	forwardstart contents_forward | pythonstart contents_py |
114 	rcstart contents_rc
115 	;
116 
117 /* server: declaration */
118 serverstart: VAR_SERVER
119 	{
120 		OUTYY(("\nP(server:)\n"));
121 	}
122 	;
123 contents_server: contents_server content_server
124 	| ;
125 content_server: server_num_threads | server_verbosity | server_port |
126 	server_outgoing_range | server_do_ip4 |
127 	server_do_ip6 | server_do_udp | server_do_tcp |
128 	server_interface | server_chroot | server_username |
129 	server_directory | server_logfile | server_pidfile |
130 	server_msg_cache_size | server_msg_cache_slabs |
131 	server_num_queries_per_thread | server_rrset_cache_size |
132 	server_rrset_cache_slabs | server_outgoing_num_tcp |
133 	server_infra_host_ttl | server_infra_lame_ttl |
134 	server_infra_cache_slabs | server_infra_cache_numhosts |
135 	server_infra_cache_lame_size | server_target_fetch_policy |
136 	server_harden_short_bufsize | server_harden_large_queries |
137 	server_do_not_query_address | server_hide_identity |
138 	server_hide_version | server_identity | server_version |
139 	server_harden_glue | server_module_conf | server_trust_anchor_file |
140 	server_trust_anchor | server_val_override_date | server_bogus_ttl |
141 	server_val_clean_additional | server_val_permissive_mode |
142 	server_incoming_num_tcp | server_msg_buffer_size |
143 	server_key_cache_size | server_key_cache_slabs |
144 	server_trusted_keys_file | server_val_nsec3_keysize_iterations |
145 	server_use_syslog | server_outgoing_interface | server_root_hints |
146 	server_do_not_query_localhost | server_cache_max_ttl |
147 	server_harden_dnssec_stripped | server_access_control |
148 	server_local_zone | server_local_data | server_interface_automatic |
149 	server_statistics_interval | server_do_daemonize |
150 	server_use_caps_for_id | server_statistics_cumulative |
151 	server_outgoing_port_permit | server_outgoing_port_avoid |
152 	server_dlv_anchor_file | server_dlv_anchor | server_neg_cache_size |
153 	server_harden_referral_path | server_private_address |
154 	server_private_domain | server_extended_statistics |
155 	server_local_data_ptr | server_jostle_timeout |
156 	server_unwanted_reply_threshold | server_log_time_ascii |
157 	server_domain_insecure | server_val_sig_skew_min |
158 	server_val_sig_skew_max | server_cache_min_ttl | server_val_log_level |
159 	server_auto_trust_anchor_file | server_add_holddown |
160 	server_del_holddown | server_keep_missing | server_so_rcvbuf |
161 	server_edns_buffer_size | server_prefetch | server_prefetch_key |
162 	server_so_sndbuf | server_harden_below_nxdomain | server_ignore_cd_flag |
163 	server_log_queries | server_tcp_upstream | server_ssl_upstream |
164 	server_ssl_service_key | server_ssl_service_pem | server_ssl_port |
165 	server_minimal_responses | server_rrset_roundrobin | server_max_udp_size |
166     server_so_reuseport | server_delay_close
167 	;
168 stubstart: VAR_STUB_ZONE
169 	{
170 		struct config_stub* s;
171 		OUTYY(("\nP(stub_zone:)\n"));
172 		s = (struct config_stub*)calloc(1, sizeof(struct config_stub));
173 		if(s) {
174 			s->next = cfg_parser->cfg->stubs;
175 			cfg_parser->cfg->stubs = s;
176 		} else
177 			yyerror("out of memory");
178 	}
179 	;
180 contents_stub: contents_stub content_stub
181 	| ;
182 content_stub: stub_name | stub_host | stub_addr | stub_prime | stub_first
183 	;
184 forwardstart: VAR_FORWARD_ZONE
185 	{
186 		struct config_stub* s;
187 		OUTYY(("\nP(forward_zone:)\n"));
188 		s = (struct config_stub*)calloc(1, sizeof(struct config_stub));
189 		if(s) {
190 			s->next = cfg_parser->cfg->forwards;
191 			cfg_parser->cfg->forwards = s;
192 		} else
193 			yyerror("out of memory");
194 	}
195 	;
196 contents_forward: contents_forward content_forward
197 	| ;
198 content_forward: forward_name | forward_host | forward_addr | forward_first
199 	;
200 server_num_threads: VAR_NUM_THREADS STRING_ARG
201 	{
202 		OUTYY(("P(server_num_threads:%s)\n", $2));
203 		if(atoi($2) == 0 && strcmp($2, "0") != 0)
204 			yyerror("number expected");
205 		else cfg_parser->cfg->num_threads = atoi($2);
206 		free($2);
207 	}
208 	;
209 server_verbosity: VAR_VERBOSITY STRING_ARG
210 	{
211 		OUTYY(("P(server_verbosity:%s)\n", $2));
212 		if(atoi($2) == 0 && strcmp($2, "0") != 0)
213 			yyerror("number expected");
214 		else cfg_parser->cfg->verbosity = atoi($2);
215 		free($2);
216 	}
217 	;
218 server_statistics_interval: VAR_STATISTICS_INTERVAL STRING_ARG
219 	{
220 		OUTYY(("P(server_statistics_interval:%s)\n", $2));
221 		if(strcmp($2, "") == 0 || strcmp($2, "0") == 0)
222 			cfg_parser->cfg->stat_interval = 0;
223 		else if(atoi($2) == 0)
224 			yyerror("number expected");
225 		else cfg_parser->cfg->stat_interval = atoi($2);
226 		free($2);
227 	}
228 	;
229 server_statistics_cumulative: VAR_STATISTICS_CUMULATIVE STRING_ARG
230 	{
231 		OUTYY(("P(server_statistics_cumulative:%s)\n", $2));
232 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
233 			yyerror("expected yes or no.");
234 		else cfg_parser->cfg->stat_cumulative = (strcmp($2, "yes")==0);
235 		free($2);
236 	}
237 	;
238 server_extended_statistics: VAR_EXTENDED_STATISTICS STRING_ARG
239 	{
240 		OUTYY(("P(server_extended_statistics:%s)\n", $2));
241 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
242 			yyerror("expected yes or no.");
243 		else cfg_parser->cfg->stat_extended = (strcmp($2, "yes")==0);
244 		free($2);
245 	}
246 	;
247 server_port: VAR_PORT STRING_ARG
248 	{
249 		OUTYY(("P(server_port:%s)\n", $2));
250 		if(atoi($2) == 0)
251 			yyerror("port number expected");
252 		else cfg_parser->cfg->port = atoi($2);
253 		free($2);
254 	}
255 	;
256 server_interface: VAR_INTERFACE STRING_ARG
257 	{
258 		OUTYY(("P(server_interface:%s)\n", $2));
259 		if(cfg_parser->cfg->num_ifs == 0)
260 			cfg_parser->cfg->ifs = calloc(1, sizeof(char*));
261 		else 	cfg_parser->cfg->ifs = realloc(cfg_parser->cfg->ifs,
262 				(cfg_parser->cfg->num_ifs+1)*sizeof(char*));
263 		if(!cfg_parser->cfg->ifs)
264 			yyerror("out of memory");
265 		else
266 			cfg_parser->cfg->ifs[cfg_parser->cfg->num_ifs++] = $2;
267 	}
268 	;
269 server_outgoing_interface: VAR_OUTGOING_INTERFACE STRING_ARG
270 	{
271 		OUTYY(("P(server_outgoing_interface:%s)\n", $2));
272 		if(cfg_parser->cfg->num_out_ifs == 0)
273 			cfg_parser->cfg->out_ifs = calloc(1, sizeof(char*));
274 		else 	cfg_parser->cfg->out_ifs = realloc(
275 			cfg_parser->cfg->out_ifs,
276 			(cfg_parser->cfg->num_out_ifs+1)*sizeof(char*));
277 		if(!cfg_parser->cfg->out_ifs)
278 			yyerror("out of memory");
279 		else
280 			cfg_parser->cfg->out_ifs[
281 				cfg_parser->cfg->num_out_ifs++] = $2;
282 	}
283 	;
284 server_outgoing_range: VAR_OUTGOING_RANGE STRING_ARG
285 	{
286 		OUTYY(("P(server_outgoing_range:%s)\n", $2));
287 		if(atoi($2) == 0)
288 			yyerror("number expected");
289 		else cfg_parser->cfg->outgoing_num_ports = atoi($2);
290 		free($2);
291 	}
292 	;
293 server_outgoing_port_permit: VAR_OUTGOING_PORT_PERMIT STRING_ARG
294 	{
295 		OUTYY(("P(server_outgoing_port_permit:%s)\n", $2));
296 		if(!cfg_mark_ports($2, 1,
297 			cfg_parser->cfg->outgoing_avail_ports, 65536))
298 			yyerror("port number or range (\"low-high\") expected");
299 		free($2);
300 	}
301 	;
302 server_outgoing_port_avoid: VAR_OUTGOING_PORT_AVOID STRING_ARG
303 	{
304 		OUTYY(("P(server_outgoing_port_avoid:%s)\n", $2));
305 		if(!cfg_mark_ports($2, 0,
306 			cfg_parser->cfg->outgoing_avail_ports, 65536))
307 			yyerror("port number or range (\"low-high\") expected");
308 		free($2);
309 	}
310 	;
311 server_outgoing_num_tcp: VAR_OUTGOING_NUM_TCP STRING_ARG
312 	{
313 		OUTYY(("P(server_outgoing_num_tcp:%s)\n", $2));
314 		if(atoi($2) == 0 && strcmp($2, "0") != 0)
315 			yyerror("number expected");
316 		else cfg_parser->cfg->outgoing_num_tcp = atoi($2);
317 		free($2);
318 	}
319 	;
320 server_incoming_num_tcp: VAR_INCOMING_NUM_TCP STRING_ARG
321 	{
322 		OUTYY(("P(server_incoming_num_tcp:%s)\n", $2));
323 		if(atoi($2) == 0 && strcmp($2, "0") != 0)
324 			yyerror("number expected");
325 		else cfg_parser->cfg->incoming_num_tcp = atoi($2);
326 		free($2);
327 	}
328 	;
329 server_interface_automatic: VAR_INTERFACE_AUTOMATIC STRING_ARG
330 	{
331 		OUTYY(("P(server_interface_automatic:%s)\n", $2));
332 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
333 			yyerror("expected yes or no.");
334 		else cfg_parser->cfg->if_automatic = (strcmp($2, "yes")==0);
335 		free($2);
336 	}
337 	;
338 server_do_ip4: VAR_DO_IP4 STRING_ARG
339 	{
340 		OUTYY(("P(server_do_ip4:%s)\n", $2));
341 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
342 			yyerror("expected yes or no.");
343 		else cfg_parser->cfg->do_ip4 = (strcmp($2, "yes")==0);
344 		free($2);
345 	}
346 	;
347 server_do_ip6: VAR_DO_IP6 STRING_ARG
348 	{
349 		OUTYY(("P(server_do_ip6:%s)\n", $2));
350 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
351 			yyerror("expected yes or no.");
352 		else cfg_parser->cfg->do_ip6 = (strcmp($2, "yes")==0);
353 		free($2);
354 	}
355 	;
356 server_do_udp: VAR_DO_UDP STRING_ARG
357 	{
358 		OUTYY(("P(server_do_udp:%s)\n", $2));
359 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
360 			yyerror("expected yes or no.");
361 		else cfg_parser->cfg->do_udp = (strcmp($2, "yes")==0);
362 		free($2);
363 	}
364 	;
365 server_do_tcp: VAR_DO_TCP STRING_ARG
366 	{
367 		OUTYY(("P(server_do_tcp:%s)\n", $2));
368 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
369 			yyerror("expected yes or no.");
370 		else cfg_parser->cfg->do_tcp = (strcmp($2, "yes")==0);
371 		free($2);
372 	}
373 	;
374 server_tcp_upstream: VAR_TCP_UPSTREAM STRING_ARG
375 	{
376 		OUTYY(("P(server_tcp_upstream:%s)\n", $2));
377 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
378 			yyerror("expected yes or no.");
379 		else cfg_parser->cfg->tcp_upstream = (strcmp($2, "yes")==0);
380 		free($2);
381 	}
382 	;
383 server_ssl_upstream: VAR_SSL_UPSTREAM STRING_ARG
384 	{
385 		OUTYY(("P(server_ssl_upstream:%s)\n", $2));
386 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
387 			yyerror("expected yes or no.");
388 		else cfg_parser->cfg->ssl_upstream = (strcmp($2, "yes")==0);
389 		free($2);
390 	}
391 	;
392 server_ssl_service_key: VAR_SSL_SERVICE_KEY STRING_ARG
393 	{
394 		OUTYY(("P(server_ssl_service_key:%s)\n", $2));
395 		free(cfg_parser->cfg->ssl_service_key);
396 		cfg_parser->cfg->ssl_service_key = $2;
397 	}
398 	;
399 server_ssl_service_pem: VAR_SSL_SERVICE_PEM STRING_ARG
400 	{
401 		OUTYY(("P(server_ssl_service_pem:%s)\n", $2));
402 		free(cfg_parser->cfg->ssl_service_pem);
403 		cfg_parser->cfg->ssl_service_pem = $2;
404 	}
405 	;
406 server_ssl_port: VAR_SSL_PORT STRING_ARG
407 	{
408 		OUTYY(("P(server_ssl_port:%s)\n", $2));
409 		if(atoi($2) == 0)
410 			yyerror("port number expected");
411 		else cfg_parser->cfg->ssl_port = atoi($2);
412 		free($2);
413 	}
414 	;
415 server_do_daemonize: VAR_DO_DAEMONIZE STRING_ARG
416 	{
417 		OUTYY(("P(server_do_daemonize:%s)\n", $2));
418 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
419 			yyerror("expected yes or no.");
420 		else cfg_parser->cfg->do_daemonize = (strcmp($2, "yes")==0);
421 		free($2);
422 	}
423 	;
424 server_use_syslog: VAR_USE_SYSLOG STRING_ARG
425 	{
426 		OUTYY(("P(server_use_syslog:%s)\n", $2));
427 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
428 			yyerror("expected yes or no.");
429 		else cfg_parser->cfg->use_syslog = (strcmp($2, "yes")==0);
430 #if !defined(HAVE_SYSLOG_H) && !defined(UB_ON_WINDOWS)
431 		if(strcmp($2, "yes") == 0)
432 			yyerror("no syslog services are available. "
433 				"(reconfigure and compile to add)");
434 #endif
435 		free($2);
436 	}
437 	;
438 server_log_time_ascii: VAR_LOG_TIME_ASCII STRING_ARG
439 	{
440 		OUTYY(("P(server_log_time_ascii:%s)\n", $2));
441 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
442 			yyerror("expected yes or no.");
443 		else cfg_parser->cfg->log_time_ascii = (strcmp($2, "yes")==0);
444 		free($2);
445 	}
446 	;
447 server_log_queries: VAR_LOG_QUERIES STRING_ARG
448 	{
449 		OUTYY(("P(server_log_queries:%s)\n", $2));
450 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
451 			yyerror("expected yes or no.");
452 		else cfg_parser->cfg->log_queries = (strcmp($2, "yes")==0);
453 		free($2);
454 	}
455 	;
456 server_chroot: VAR_CHROOT STRING_ARG
457 	{
458 		OUTYY(("P(server_chroot:%s)\n", $2));
459 		free(cfg_parser->cfg->chrootdir);
460 		cfg_parser->cfg->chrootdir = $2;
461 	}
462 	;
463 server_username: VAR_USERNAME STRING_ARG
464 	{
465 		OUTYY(("P(server_username:%s)\n", $2));
466 		free(cfg_parser->cfg->username);
467 		cfg_parser->cfg->username = $2;
468 	}
469 	;
470 server_directory: VAR_DIRECTORY STRING_ARG
471 	{
472 		OUTYY(("P(server_directory:%s)\n", $2));
473 		free(cfg_parser->cfg->directory);
474 		cfg_parser->cfg->directory = $2;
475 	}
476 	;
477 server_logfile: VAR_LOGFILE STRING_ARG
478 	{
479 		OUTYY(("P(server_logfile:%s)\n", $2));
480 		free(cfg_parser->cfg->logfile);
481 		cfg_parser->cfg->logfile = $2;
482 		cfg_parser->cfg->use_syslog = 0;
483 	}
484 	;
485 server_pidfile: VAR_PIDFILE STRING_ARG
486 	{
487 		OUTYY(("P(server_pidfile:%s)\n", $2));
488 		free(cfg_parser->cfg->pidfile);
489 		cfg_parser->cfg->pidfile = $2;
490 	}
491 	;
492 server_root_hints: VAR_ROOT_HINTS STRING_ARG
493 	{
494 		OUTYY(("P(server_root_hints:%s)\n", $2));
495 		if(!cfg_strlist_insert(&cfg_parser->cfg->root_hints, $2))
496 			yyerror("out of memory");
497 	}
498 	;
499 server_dlv_anchor_file: VAR_DLV_ANCHOR_FILE STRING_ARG
500 	{
501 		OUTYY(("P(server_dlv_anchor_file:%s)\n", $2));
502 		free(cfg_parser->cfg->dlv_anchor_file);
503 		cfg_parser->cfg->dlv_anchor_file = $2;
504 	}
505 	;
506 server_dlv_anchor: VAR_DLV_ANCHOR STRING_ARG
507 	{
508 		OUTYY(("P(server_dlv_anchor:%s)\n", $2));
509 		if(!cfg_strlist_insert(&cfg_parser->cfg->dlv_anchor_list, $2))
510 			yyerror("out of memory");
511 	}
512 	;
513 server_auto_trust_anchor_file: VAR_AUTO_TRUST_ANCHOR_FILE STRING_ARG
514 	{
515 		OUTYY(("P(server_auto_trust_anchor_file:%s)\n", $2));
516 		if(!cfg_strlist_insert(&cfg_parser->cfg->
517 			auto_trust_anchor_file_list, $2))
518 			yyerror("out of memory");
519 	}
520 	;
521 server_trust_anchor_file: VAR_TRUST_ANCHOR_FILE STRING_ARG
522 	{
523 		OUTYY(("P(server_trust_anchor_file:%s)\n", $2));
524 		if(!cfg_strlist_insert(&cfg_parser->cfg->
525 			trust_anchor_file_list, $2))
526 			yyerror("out of memory");
527 	}
528 	;
529 server_trusted_keys_file: VAR_TRUSTED_KEYS_FILE STRING_ARG
530 	{
531 		OUTYY(("P(server_trusted_keys_file:%s)\n", $2));
532 		if(!cfg_strlist_insert(&cfg_parser->cfg->
533 			trusted_keys_file_list, $2))
534 			yyerror("out of memory");
535 	}
536 	;
537 server_trust_anchor: VAR_TRUST_ANCHOR STRING_ARG
538 	{
539 		OUTYY(("P(server_trust_anchor:%s)\n", $2));
540 		if(!cfg_strlist_insert(&cfg_parser->cfg->trust_anchor_list, $2))
541 			yyerror("out of memory");
542 	}
543 	;
544 server_domain_insecure: VAR_DOMAIN_INSECURE STRING_ARG
545 	{
546 		OUTYY(("P(server_domain_insecure:%s)\n", $2));
547 		if(!cfg_strlist_insert(&cfg_parser->cfg->domain_insecure, $2))
548 			yyerror("out of memory");
549 	}
550 	;
551 server_hide_identity: VAR_HIDE_IDENTITY STRING_ARG
552 	{
553 		OUTYY(("P(server_hide_identity:%s)\n", $2));
554 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
555 			yyerror("expected yes or no.");
556 		else cfg_parser->cfg->hide_identity = (strcmp($2, "yes")==0);
557 		free($2);
558 	}
559 	;
560 server_hide_version: VAR_HIDE_VERSION STRING_ARG
561 	{
562 		OUTYY(("P(server_hide_version:%s)\n", $2));
563 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
564 			yyerror("expected yes or no.");
565 		else cfg_parser->cfg->hide_version = (strcmp($2, "yes")==0);
566 		free($2);
567 	}
568 	;
569 server_identity: VAR_IDENTITY STRING_ARG
570 	{
571 		OUTYY(("P(server_identity:%s)\n", $2));
572 		free(cfg_parser->cfg->identity);
573 		cfg_parser->cfg->identity = $2;
574 	}
575 	;
576 server_version: VAR_VERSION STRING_ARG
577 	{
578 		OUTYY(("P(server_version:%s)\n", $2));
579 		free(cfg_parser->cfg->version);
580 		cfg_parser->cfg->version = $2;
581 	}
582 	;
583 server_so_rcvbuf: VAR_SO_RCVBUF STRING_ARG
584 	{
585 		OUTYY(("P(server_so_rcvbuf:%s)\n", $2));
586 		if(!cfg_parse_memsize($2, &cfg_parser->cfg->so_rcvbuf))
587 			yyerror("buffer size expected");
588 		free($2);
589 	}
590 	;
591 server_so_sndbuf: VAR_SO_SNDBUF STRING_ARG
592 	{
593 		OUTYY(("P(server_so_sndbuf:%s)\n", $2));
594 		if(!cfg_parse_memsize($2, &cfg_parser->cfg->so_sndbuf))
595 			yyerror("buffer size expected");
596 		free($2);
597 	}
598 	;
599 server_so_reuseport: VAR_SO_REUSEPORT STRING_ARG
600     {
601         OUTYY(("P(server_so_reuseport:%s)\n", $2));
602         if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
603             yyerror("expected yes or no.");
604         else cfg_parser->cfg->so_reuseport =
605             (strcmp($2, "yes")==0);
606         free($2);
607     }
608     ;
609 server_edns_buffer_size: VAR_EDNS_BUFFER_SIZE STRING_ARG
610 	{
611 		OUTYY(("P(server_edns_buffer_size:%s)\n", $2));
612 		if(atoi($2) == 0)
613 			yyerror("number expected");
614 		else if (atoi($2) < 12)
615 			yyerror("edns buffer size too small");
616 		else if (atoi($2) > 65535)
617 			cfg_parser->cfg->edns_buffer_size = 65535;
618 		else cfg_parser->cfg->edns_buffer_size = atoi($2);
619 		free($2);
620 	}
621 	;
622 server_msg_buffer_size: VAR_MSG_BUFFER_SIZE STRING_ARG
623 	{
624 		OUTYY(("P(server_msg_buffer_size:%s)\n", $2));
625 		if(atoi($2) == 0)
626 			yyerror("number expected");
627 		else if (atoi($2) < 4096)
628 			yyerror("message buffer size too small (use 4096)");
629 		else cfg_parser->cfg->msg_buffer_size = atoi($2);
630 		free($2);
631 	}
632 	;
633 server_msg_cache_size: VAR_MSG_CACHE_SIZE STRING_ARG
634 	{
635 		OUTYY(("P(server_msg_cache_size:%s)\n", $2));
636 		if(!cfg_parse_memsize($2, &cfg_parser->cfg->msg_cache_size))
637 			yyerror("memory size expected");
638 		free($2);
639 	}
640 	;
641 server_msg_cache_slabs: VAR_MSG_CACHE_SLABS STRING_ARG
642 	{
643 		OUTYY(("P(server_msg_cache_slabs:%s)\n", $2));
644 		if(atoi($2) == 0)
645 			yyerror("number expected");
646 		else {
647 			cfg_parser->cfg->msg_cache_slabs = atoi($2);
648 			if(!is_pow2(cfg_parser->cfg->msg_cache_slabs))
649 				yyerror("must be a power of 2");
650 		}
651 		free($2);
652 	}
653 	;
654 server_num_queries_per_thread: VAR_NUM_QUERIES_PER_THREAD STRING_ARG
655 	{
656 		OUTYY(("P(server_num_queries_per_thread:%s)\n", $2));
657 		if(atoi($2) == 0)
658 			yyerror("number expected");
659 		else cfg_parser->cfg->num_queries_per_thread = atoi($2);
660 		free($2);
661 	}
662 	;
663 server_jostle_timeout: VAR_JOSTLE_TIMEOUT STRING_ARG
664 	{
665 		OUTYY(("P(server_jostle_timeout:%s)\n", $2));
666 		if(atoi($2) == 0 && strcmp($2, "0") != 0)
667 			yyerror("number expected");
668 		else cfg_parser->cfg->jostle_time = atoi($2);
669 		free($2);
670 	}
671 	;
672 server_delay_close: VAR_DELAY_CLOSE STRING_ARG
673 	{
674 		OUTYY(("P(server_delay_close:%s)\n", $2));
675 		if(atoi($2) == 0 && strcmp($2, "0") != 0)
676 			yyerror("number expected");
677 		else cfg_parser->cfg->delay_close = atoi($2);
678 		free($2);
679 	}
680 	;
681 server_rrset_cache_size: VAR_RRSET_CACHE_SIZE STRING_ARG
682 	{
683 		OUTYY(("P(server_rrset_cache_size:%s)\n", $2));
684 		if(!cfg_parse_memsize($2, &cfg_parser->cfg->rrset_cache_size))
685 			yyerror("memory size expected");
686 		free($2);
687 	}
688 	;
689 server_rrset_cache_slabs: VAR_RRSET_CACHE_SLABS STRING_ARG
690 	{
691 		OUTYY(("P(server_rrset_cache_slabs:%s)\n", $2));
692 		if(atoi($2) == 0)
693 			yyerror("number expected");
694 		else {
695 			cfg_parser->cfg->rrset_cache_slabs = atoi($2);
696 			if(!is_pow2(cfg_parser->cfg->rrset_cache_slabs))
697 				yyerror("must be a power of 2");
698 		}
699 		free($2);
700 	}
701 	;
702 server_infra_host_ttl: VAR_INFRA_HOST_TTL STRING_ARG
703 	{
704 		OUTYY(("P(server_infra_host_ttl:%s)\n", $2));
705 		if(atoi($2) == 0 && strcmp($2, "0") != 0)
706 			yyerror("number expected");
707 		else cfg_parser->cfg->host_ttl = atoi($2);
708 		free($2);
709 	}
710 	;
711 server_infra_lame_ttl: VAR_INFRA_LAME_TTL STRING_ARG
712 	{
713 		OUTYY(("P(server_infra_lame_ttl:%s)\n", $2));
714 		verbose(VERB_DETAIL, "ignored infra-lame-ttl: %s (option "
715 			"removed, use infra-host-ttl)", $2);
716 		free($2);
717 	}
718 	;
719 server_infra_cache_numhosts: VAR_INFRA_CACHE_NUMHOSTS STRING_ARG
720 	{
721 		OUTYY(("P(server_infra_cache_numhosts:%s)\n", $2));
722 		if(atoi($2) == 0)
723 			yyerror("number expected");
724 		else cfg_parser->cfg->infra_cache_numhosts = atoi($2);
725 		free($2);
726 	}
727 	;
728 server_infra_cache_lame_size: VAR_INFRA_CACHE_LAME_SIZE STRING_ARG
729 	{
730 		OUTYY(("P(server_infra_cache_lame_size:%s)\n", $2));
731 		verbose(VERB_DETAIL, "ignored infra-cache-lame-size: %s "
732 			"(option removed, use infra-cache-numhosts)", $2);
733 		free($2);
734 	}
735 	;
736 server_infra_cache_slabs: VAR_INFRA_CACHE_SLABS STRING_ARG
737 	{
738 		OUTYY(("P(server_infra_cache_slabs:%s)\n", $2));
739 		if(atoi($2) == 0)
740 			yyerror("number expected");
741 		else {
742 			cfg_parser->cfg->infra_cache_slabs = atoi($2);
743 			if(!is_pow2(cfg_parser->cfg->infra_cache_slabs))
744 				yyerror("must be a power of 2");
745 		}
746 		free($2);
747 	}
748 	;
749 server_target_fetch_policy: VAR_TARGET_FETCH_POLICY STRING_ARG
750 	{
751 		OUTYY(("P(server_target_fetch_policy:%s)\n", $2));
752 		free(cfg_parser->cfg->target_fetch_policy);
753 		cfg_parser->cfg->target_fetch_policy = $2;
754 	}
755 	;
756 server_harden_short_bufsize: VAR_HARDEN_SHORT_BUFSIZE STRING_ARG
757 	{
758 		OUTYY(("P(server_harden_short_bufsize:%s)\n", $2));
759 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
760 			yyerror("expected yes or no.");
761 		else cfg_parser->cfg->harden_short_bufsize =
762 			(strcmp($2, "yes")==0);
763 		free($2);
764 	}
765 	;
766 server_harden_large_queries: VAR_HARDEN_LARGE_QUERIES STRING_ARG
767 	{
768 		OUTYY(("P(server_harden_large_queries:%s)\n", $2));
769 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
770 			yyerror("expected yes or no.");
771 		else cfg_parser->cfg->harden_large_queries =
772 			(strcmp($2, "yes")==0);
773 		free($2);
774 	}
775 	;
776 server_harden_glue: VAR_HARDEN_GLUE STRING_ARG
777 	{
778 		OUTYY(("P(server_harden_glue:%s)\n", $2));
779 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
780 			yyerror("expected yes or no.");
781 		else cfg_parser->cfg->harden_glue =
782 			(strcmp($2, "yes")==0);
783 		free($2);
784 	}
785 	;
786 server_harden_dnssec_stripped: VAR_HARDEN_DNSSEC_STRIPPED STRING_ARG
787 	{
788 		OUTYY(("P(server_harden_dnssec_stripped:%s)\n", $2));
789 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
790 			yyerror("expected yes or no.");
791 		else cfg_parser->cfg->harden_dnssec_stripped =
792 			(strcmp($2, "yes")==0);
793 		free($2);
794 	}
795 	;
796 server_harden_below_nxdomain: VAR_HARDEN_BELOW_NXDOMAIN STRING_ARG
797 	{
798 		OUTYY(("P(server_harden_below_nxdomain:%s)\n", $2));
799 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
800 			yyerror("expected yes or no.");
801 		else cfg_parser->cfg->harden_below_nxdomain =
802 			(strcmp($2, "yes")==0);
803 		free($2);
804 	}
805 	;
806 server_harden_referral_path: VAR_HARDEN_REFERRAL_PATH STRING_ARG
807 	{
808 		OUTYY(("P(server_harden_referral_path:%s)\n", $2));
809 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
810 			yyerror("expected yes or no.");
811 		else cfg_parser->cfg->harden_referral_path =
812 			(strcmp($2, "yes")==0);
813 		free($2);
814 	}
815 	;
816 server_use_caps_for_id: VAR_USE_CAPS_FOR_ID STRING_ARG
817 	{
818 		OUTYY(("P(server_use_caps_for_id:%s)\n", $2));
819 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
820 			yyerror("expected yes or no.");
821 		else cfg_parser->cfg->use_caps_bits_for_id =
822 			(strcmp($2, "yes")==0);
823 		free($2);
824 	}
825 	;
826 server_private_address: VAR_PRIVATE_ADDRESS STRING_ARG
827 	{
828 		OUTYY(("P(server_private_address:%s)\n", $2));
829 		if(!cfg_strlist_insert(&cfg_parser->cfg->private_address, $2))
830 			yyerror("out of memory");
831 	}
832 	;
833 server_private_domain: VAR_PRIVATE_DOMAIN STRING_ARG
834 	{
835 		OUTYY(("P(server_private_domain:%s)\n", $2));
836 		if(!cfg_strlist_insert(&cfg_parser->cfg->private_domain, $2))
837 			yyerror("out of memory");
838 	}
839 	;
840 server_prefetch: VAR_PREFETCH STRING_ARG
841 	{
842 		OUTYY(("P(server_prefetch:%s)\n", $2));
843 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
844 			yyerror("expected yes or no.");
845 		else cfg_parser->cfg->prefetch = (strcmp($2, "yes")==0);
846 		free($2);
847 	}
848 	;
849 server_prefetch_key: VAR_PREFETCH_KEY STRING_ARG
850 	{
851 		OUTYY(("P(server_prefetch_key:%s)\n", $2));
852 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
853 			yyerror("expected yes or no.");
854 		else cfg_parser->cfg->prefetch_key = (strcmp($2, "yes")==0);
855 		free($2);
856 	}
857 	;
858 server_unwanted_reply_threshold: VAR_UNWANTED_REPLY_THRESHOLD STRING_ARG
859 	{
860 		OUTYY(("P(server_unwanted_reply_threshold:%s)\n", $2));
861 		if(atoi($2) == 0 && strcmp($2, "0") != 0)
862 			yyerror("number expected");
863 		else cfg_parser->cfg->unwanted_threshold = atoi($2);
864 		free($2);
865 	}
866 	;
867 server_do_not_query_address: VAR_DO_NOT_QUERY_ADDRESS STRING_ARG
868 	{
869 		OUTYY(("P(server_do_not_query_address:%s)\n", $2));
870 		if(!cfg_strlist_insert(&cfg_parser->cfg->donotqueryaddrs, $2))
871 			yyerror("out of memory");
872 	}
873 	;
874 server_do_not_query_localhost: VAR_DO_NOT_QUERY_LOCALHOST STRING_ARG
875 	{
876 		OUTYY(("P(server_do_not_query_localhost:%s)\n", $2));
877 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
878 			yyerror("expected yes or no.");
879 		else cfg_parser->cfg->donotquery_localhost =
880 			(strcmp($2, "yes")==0);
881 		free($2);
882 	}
883 	;
884 server_access_control: VAR_ACCESS_CONTROL STRING_ARG STRING_ARG
885 	{
886 		OUTYY(("P(server_access_control:%s %s)\n", $2, $3));
887 		if(strcmp($3, "deny")!=0 && strcmp($3, "refuse")!=0 &&
888 			strcmp($3, "deny_non_local")!=0 &&
889 			strcmp($3, "refuse_non_local")!=0 &&
890 			strcmp($3, "allow")!=0 &&
891 			strcmp($3, "allow_snoop")!=0) {
892 			yyerror("expected deny, refuse, deny_non_local, "
893 				"refuse_non_local, allow or allow_snoop "
894 				"in access control action");
895 		} else {
896 			if(!cfg_str2list_insert(&cfg_parser->cfg->acls, $2, $3))
897 				fatal_exit("out of memory adding acl");
898 		}
899 	}
900 	;
901 server_module_conf: VAR_MODULE_CONF STRING_ARG
902 	{
903 		OUTYY(("P(server_module_conf:%s)\n", $2));
904 		free(cfg_parser->cfg->module_conf);
905 		cfg_parser->cfg->module_conf = $2;
906 	}
907 	;
908 server_val_override_date: VAR_VAL_OVERRIDE_DATE STRING_ARG
909 	{
910 		OUTYY(("P(server_val_override_date:%s)\n", $2));
911 		if(strlen($2) == 0 || strcmp($2, "0") == 0) {
912 			cfg_parser->cfg->val_date_override = 0;
913 		} else if(strlen($2) == 14) {
914 			cfg_parser->cfg->val_date_override =
915 				cfg_convert_timeval($2);
916 			if(!cfg_parser->cfg->val_date_override)
917 				yyerror("bad date/time specification");
918 		} else {
919 			if(atoi($2) == 0)
920 				yyerror("number expected");
921 			cfg_parser->cfg->val_date_override = atoi($2);
922 		}
923 		free($2);
924 	}
925 	;
926 server_val_sig_skew_min: VAR_VAL_SIG_SKEW_MIN STRING_ARG
927 	{
928 		OUTYY(("P(server_val_sig_skew_min:%s)\n", $2));
929 		if(strlen($2) == 0 || strcmp($2, "0") == 0) {
930 			cfg_parser->cfg->val_sig_skew_min = 0;
931 		} else {
932 			cfg_parser->cfg->val_sig_skew_min = atoi($2);
933 			if(!cfg_parser->cfg->val_sig_skew_min)
934 				yyerror("number expected");
935 		}
936 		free($2);
937 	}
938 	;
939 server_val_sig_skew_max: VAR_VAL_SIG_SKEW_MAX STRING_ARG
940 	{
941 		OUTYY(("P(server_val_sig_skew_max:%s)\n", $2));
942 		if(strlen($2) == 0 || strcmp($2, "0") == 0) {
943 			cfg_parser->cfg->val_sig_skew_max = 0;
944 		} else {
945 			cfg_parser->cfg->val_sig_skew_max = atoi($2);
946 			if(!cfg_parser->cfg->val_sig_skew_max)
947 				yyerror("number expected");
948 		}
949 		free($2);
950 	}
951 	;
952 server_cache_max_ttl: VAR_CACHE_MAX_TTL STRING_ARG
953 	{
954 		OUTYY(("P(server_cache_max_ttl:%s)\n", $2));
955 		if(atoi($2) == 0 && strcmp($2, "0") != 0)
956 			yyerror("number expected");
957 		else cfg_parser->cfg->max_ttl = atoi($2);
958 		free($2);
959 	}
960 	;
961 server_cache_min_ttl: VAR_CACHE_MIN_TTL STRING_ARG
962 	{
963 		OUTYY(("P(server_cache_min_ttl:%s)\n", $2));
964 		if(atoi($2) == 0 && strcmp($2, "0") != 0)
965 			yyerror("number expected");
966 		else cfg_parser->cfg->min_ttl = atoi($2);
967 		free($2);
968 	}
969 	;
970 server_bogus_ttl: VAR_BOGUS_TTL STRING_ARG
971 	{
972 		OUTYY(("P(server_bogus_ttl:%s)\n", $2));
973 		if(atoi($2) == 0 && strcmp($2, "0") != 0)
974 			yyerror("number expected");
975 		else cfg_parser->cfg->bogus_ttl = atoi($2);
976 		free($2);
977 	}
978 	;
979 server_val_clean_additional: VAR_VAL_CLEAN_ADDITIONAL STRING_ARG
980 	{
981 		OUTYY(("P(server_val_clean_additional:%s)\n", $2));
982 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
983 			yyerror("expected yes or no.");
984 		else cfg_parser->cfg->val_clean_additional =
985 			(strcmp($2, "yes")==0);
986 		free($2);
987 	}
988 	;
989 server_val_permissive_mode: VAR_VAL_PERMISSIVE_MODE STRING_ARG
990 	{
991 		OUTYY(("P(server_val_permissive_mode:%s)\n", $2));
992 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
993 			yyerror("expected yes or no.");
994 		else cfg_parser->cfg->val_permissive_mode =
995 			(strcmp($2, "yes")==0);
996 		free($2);
997 	}
998 	;
999 server_ignore_cd_flag: VAR_IGNORE_CD_FLAG STRING_ARG
1000 	{
1001 		OUTYY(("P(server_ignore_cd_flag:%s)\n", $2));
1002 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1003 			yyerror("expected yes or no.");
1004 		else cfg_parser->cfg->ignore_cd = (strcmp($2, "yes")==0);
1005 		free($2);
1006 	}
1007 	;
1008 server_val_log_level: VAR_VAL_LOG_LEVEL STRING_ARG
1009 	{
1010 		OUTYY(("P(server_val_log_level:%s)\n", $2));
1011 		if(atoi($2) == 0 && strcmp($2, "0") != 0)
1012 			yyerror("number expected");
1013 		else cfg_parser->cfg->val_log_level = atoi($2);
1014 		free($2);
1015 	}
1016 	;
1017 server_val_nsec3_keysize_iterations: VAR_VAL_NSEC3_KEYSIZE_ITERATIONS STRING_ARG
1018 	{
1019 		OUTYY(("P(server_val_nsec3_keysize_iterations:%s)\n", $2));
1020 		free(cfg_parser->cfg->val_nsec3_key_iterations);
1021 		cfg_parser->cfg->val_nsec3_key_iterations = $2;
1022 	}
1023 	;
1024 server_add_holddown: VAR_ADD_HOLDDOWN STRING_ARG
1025 	{
1026 		OUTYY(("P(server_add_holddown:%s)\n", $2));
1027 		if(atoi($2) == 0 && strcmp($2, "0") != 0)
1028 			yyerror("number expected");
1029 		else cfg_parser->cfg->add_holddown = atoi($2);
1030 		free($2);
1031 	}
1032 	;
1033 server_del_holddown: VAR_DEL_HOLDDOWN STRING_ARG
1034 	{
1035 		OUTYY(("P(server_del_holddown:%s)\n", $2));
1036 		if(atoi($2) == 0 && strcmp($2, "0") != 0)
1037 			yyerror("number expected");
1038 		else cfg_parser->cfg->del_holddown = atoi($2);
1039 		free($2);
1040 	}
1041 	;
1042 server_keep_missing: VAR_KEEP_MISSING STRING_ARG
1043 	{
1044 		OUTYY(("P(server_keep_missing:%s)\n", $2));
1045 		if(atoi($2) == 0 && strcmp($2, "0") != 0)
1046 			yyerror("number expected");
1047 		else cfg_parser->cfg->keep_missing = atoi($2);
1048 		free($2);
1049 	}
1050 	;
1051 server_key_cache_size: VAR_KEY_CACHE_SIZE STRING_ARG
1052 	{
1053 		OUTYY(("P(server_key_cache_size:%s)\n", $2));
1054 		if(!cfg_parse_memsize($2, &cfg_parser->cfg->key_cache_size))
1055 			yyerror("memory size expected");
1056 		free($2);
1057 	}
1058 	;
1059 server_key_cache_slabs: VAR_KEY_CACHE_SLABS STRING_ARG
1060 	{
1061 		OUTYY(("P(server_key_cache_slabs:%s)\n", $2));
1062 		if(atoi($2) == 0)
1063 			yyerror("number expected");
1064 		else {
1065 			cfg_parser->cfg->key_cache_slabs = atoi($2);
1066 			if(!is_pow2(cfg_parser->cfg->key_cache_slabs))
1067 				yyerror("must be a power of 2");
1068 		}
1069 		free($2);
1070 	}
1071 	;
1072 server_neg_cache_size: VAR_NEG_CACHE_SIZE STRING_ARG
1073 	{
1074 		OUTYY(("P(server_neg_cache_size:%s)\n", $2));
1075 		if(!cfg_parse_memsize($2, &cfg_parser->cfg->neg_cache_size))
1076 			yyerror("memory size expected");
1077 		free($2);
1078 	}
1079 	;
1080 server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG
1081 	{
1082 		OUTYY(("P(server_local_zone:%s %s)\n", $2, $3));
1083 		if(strcmp($3, "static")!=0 && strcmp($3, "deny")!=0 &&
1084 		   strcmp($3, "refuse")!=0 && strcmp($3, "redirect")!=0 &&
1085 		   strcmp($3, "transparent")!=0 && strcmp($3, "nodefault")!=0
1086 		   && strcmp($3, "typetransparent")!=0)
1087 			yyerror("local-zone type: expected static, deny, "
1088 				"refuse, redirect, transparent, "
1089 				"typetransparent or nodefault");
1090 		else if(strcmp($3, "nodefault")==0) {
1091 			if(!cfg_strlist_insert(&cfg_parser->cfg->
1092 				local_zones_nodefault, $2))
1093 				fatal_exit("out of memory adding local-zone");
1094 			free($3);
1095 		} else {
1096 			if(!cfg_str2list_insert(&cfg_parser->cfg->local_zones,
1097 				$2, $3))
1098 				fatal_exit("out of memory adding local-zone");
1099 		}
1100 	}
1101 	;
1102 server_local_data: VAR_LOCAL_DATA STRING_ARG
1103 	{
1104 		OUTYY(("P(server_local_data:%s)\n", $2));
1105 		if(!cfg_strlist_insert(&cfg_parser->cfg->local_data, $2))
1106 			fatal_exit("out of memory adding local-data");
1107 	}
1108 	;
1109 server_local_data_ptr: VAR_LOCAL_DATA_PTR STRING_ARG
1110 	{
1111 		char* ptr;
1112 		OUTYY(("P(server_local_data_ptr:%s)\n", $2));
1113 		ptr = cfg_ptr_reverse($2);
1114 		free($2);
1115 		if(ptr) {
1116 			if(!cfg_strlist_insert(&cfg_parser->cfg->
1117 				local_data, ptr))
1118 				fatal_exit("out of memory adding local-data");
1119 		} else {
1120 			yyerror("local-data-ptr could not be reversed");
1121 		}
1122 	}
1123 	;
1124 server_minimal_responses: VAR_MINIMAL_RESPONSES STRING_ARG
1125 	{
1126 		OUTYY(("P(server_minimal_responses:%s)\n", $2));
1127 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1128 			yyerror("expected yes or no.");
1129 		else cfg_parser->cfg->minimal_responses =
1130 			(strcmp($2, "yes")==0);
1131 		free($2);
1132 	}
1133 	;
1134 server_rrset_roundrobin: VAR_RRSET_ROUNDROBIN STRING_ARG
1135 	{
1136 		OUTYY(("P(server_rrset_roundrobin:%s)\n", $2));
1137 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1138 			yyerror("expected yes or no.");
1139 		else cfg_parser->cfg->rrset_roundrobin =
1140 			(strcmp($2, "yes")==0);
1141 		free($2);
1142 	}
1143 	;
1144 server_max_udp_size: VAR_MAX_UDP_SIZE STRING_ARG
1145 	{
1146 		OUTYY(("P(server_max_udp_size:%s)\n", $2));
1147 		cfg_parser->cfg->max_udp_size = atoi($2);
1148 		free($2);
1149 	}
1150 	;
1151 stub_name: VAR_NAME STRING_ARG
1152 	{
1153 		OUTYY(("P(name:%s)\n", $2));
1154 		if(cfg_parser->cfg->stubs->name)
1155 			yyerror("stub name override, there must be one name "
1156 				"for one stub-zone");
1157 		free(cfg_parser->cfg->stubs->name);
1158 		cfg_parser->cfg->stubs->name = $2;
1159 	}
1160 	;
1161 stub_host: VAR_STUB_HOST STRING_ARG
1162 	{
1163 		OUTYY(("P(stub-host:%s)\n", $2));
1164 		if(!cfg_strlist_insert(&cfg_parser->cfg->stubs->hosts, $2))
1165 			yyerror("out of memory");
1166 	}
1167 	;
1168 stub_addr: VAR_STUB_ADDR STRING_ARG
1169 	{
1170 		OUTYY(("P(stub-addr:%s)\n", $2));
1171 		if(!cfg_strlist_insert(&cfg_parser->cfg->stubs->addrs, $2))
1172 			yyerror("out of memory");
1173 	}
1174 	;
1175 stub_first: VAR_STUB_FIRST STRING_ARG
1176 	{
1177 		OUTYY(("P(stub-first:%s)\n", $2));
1178 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1179 			yyerror("expected yes or no.");
1180 		else cfg_parser->cfg->stubs->isfirst=(strcmp($2, "yes")==0);
1181 		free($2);
1182 	}
1183 	;
1184 stub_prime: VAR_STUB_PRIME STRING_ARG
1185 	{
1186 		OUTYY(("P(stub-prime:%s)\n", $2));
1187 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1188 			yyerror("expected yes or no.");
1189 		else cfg_parser->cfg->stubs->isprime =
1190 			(strcmp($2, "yes")==0);
1191 		free($2);
1192 	}
1193 	;
1194 forward_name: VAR_NAME STRING_ARG
1195 	{
1196 		OUTYY(("P(name:%s)\n", $2));
1197 		if(cfg_parser->cfg->forwards->name)
1198 			yyerror("forward name override, there must be one "
1199 				"name for one forward-zone");
1200 		free(cfg_parser->cfg->forwards->name);
1201 		cfg_parser->cfg->forwards->name = $2;
1202 	}
1203 	;
1204 forward_host: VAR_FORWARD_HOST STRING_ARG
1205 	{
1206 		OUTYY(("P(forward-host:%s)\n", $2));
1207 		if(!cfg_strlist_insert(&cfg_parser->cfg->forwards->hosts, $2))
1208 			yyerror("out of memory");
1209 	}
1210 	;
1211 forward_addr: VAR_FORWARD_ADDR STRING_ARG
1212 	{
1213 		OUTYY(("P(forward-addr:%s)\n", $2));
1214 		if(!cfg_strlist_insert(&cfg_parser->cfg->forwards->addrs, $2))
1215 			yyerror("out of memory");
1216 	}
1217 	;
1218 forward_first: VAR_FORWARD_FIRST STRING_ARG
1219 	{
1220 		OUTYY(("P(forward-first:%s)\n", $2));
1221 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1222 			yyerror("expected yes or no.");
1223 		else cfg_parser->cfg->forwards->isfirst=(strcmp($2, "yes")==0);
1224 		free($2);
1225 	}
1226 	;
1227 rcstart: VAR_REMOTE_CONTROL
1228 	{
1229 		OUTYY(("\nP(remote-control:)\n"));
1230 	}
1231 	;
1232 contents_rc: contents_rc content_rc
1233 	| ;
1234 content_rc: rc_control_enable | rc_control_interface | rc_control_port |
1235 	rc_server_key_file | rc_server_cert_file | rc_control_key_file |
1236 	rc_control_cert_file
1237 	;
1238 rc_control_enable: VAR_CONTROL_ENABLE STRING_ARG
1239 	{
1240 		OUTYY(("P(control_enable:%s)\n", $2));
1241 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1242 			yyerror("expected yes or no.");
1243 		else cfg_parser->cfg->remote_control_enable =
1244 			(strcmp($2, "yes")==0);
1245 		free($2);
1246 	}
1247 	;
1248 rc_control_port: VAR_CONTROL_PORT STRING_ARG
1249 	{
1250 		OUTYY(("P(control_port:%s)\n", $2));
1251 		if(atoi($2) == 0)
1252 			yyerror("control port number expected");
1253 		else cfg_parser->cfg->control_port = atoi($2);
1254 		free($2);
1255 	}
1256 	;
1257 rc_control_interface: VAR_CONTROL_INTERFACE STRING_ARG
1258 	{
1259 		OUTYY(("P(control_interface:%s)\n", $2));
1260 		if(!cfg_strlist_insert(&cfg_parser->cfg->control_ifs, $2))
1261 			yyerror("out of memory");
1262 	}
1263 	;
1264 rc_server_key_file: VAR_SERVER_KEY_FILE STRING_ARG
1265 	{
1266 		OUTYY(("P(rc_server_key_file:%s)\n", $2));
1267 		free(cfg_parser->cfg->server_key_file);
1268 		cfg_parser->cfg->server_key_file = $2;
1269 	}
1270 	;
1271 rc_server_cert_file: VAR_SERVER_CERT_FILE STRING_ARG
1272 	{
1273 		OUTYY(("P(rc_server_cert_file:%s)\n", $2));
1274 		free(cfg_parser->cfg->server_cert_file);
1275 		cfg_parser->cfg->server_cert_file = $2;
1276 	}
1277 	;
1278 rc_control_key_file: VAR_CONTROL_KEY_FILE STRING_ARG
1279 	{
1280 		OUTYY(("P(rc_control_key_file:%s)\n", $2));
1281 		free(cfg_parser->cfg->control_key_file);
1282 		cfg_parser->cfg->control_key_file = $2;
1283 	}
1284 	;
1285 rc_control_cert_file: VAR_CONTROL_CERT_FILE STRING_ARG
1286 	{
1287 		OUTYY(("P(rc_control_cert_file:%s)\n", $2));
1288 		free(cfg_parser->cfg->control_cert_file);
1289 		cfg_parser->cfg->control_cert_file = $2;
1290 	}
1291 	;
1292 pythonstart: VAR_PYTHON
1293 	{
1294 		OUTYY(("\nP(python:)\n"));
1295 	}
1296 	;
1297 contents_py: contents_py content_py
1298 	| ;
1299 content_py: py_script
1300 	;
1301 py_script: VAR_PYTHON_SCRIPT STRING_ARG
1302 	{
1303 		OUTYY(("P(python-script:%s)\n", $2));
1304 		free(cfg_parser->cfg->python_script);
1305 		cfg_parser->cfg->python_script = $2;
1306 	}
1307 %%
1308 
1309 /* parse helper routines could be here */
1310