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