xref: /netbsd-src/external/bsd/ntp/dist/ntpd/ntp_parser.y (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /*	$NetBSD: ntp_parser.y,v 1.17 2018/04/07 00:19:52 christos Exp $	*/
2 
3 /* ntp_parser.y
4  *
5  * The parser for the NTP configuration file.
6  *
7  * Written By:	Sachin Kamboj
8  *		University of Delaware
9  *		Newark, DE 19711
10  * Copyright (c) 2006
11  */
12 
13 %{
14   #ifdef HAVE_CONFIG_H
15   # include <config.h>
16   #endif
17 
18   #include "ntp.h"
19   #include "ntpd.h"
20   #include "ntp_machine.h"
21   #include "ntp_stdlib.h"
22   #include "ntp_filegen.h"
23   #include "ntp_scanner.h"
24   #include "ntp_config.h"
25   #include "ntp_crypto.h"
26 
27   #include "ntpsim.h"		/* HMS: Do we really want this all the time? */
28 				/* SK: It might be a good idea to always
29 				   include the simulator code. That way
30 				   someone can use the same configuration file
31 				   for both the simulator and the daemon
32 				*/
33 
34   #define YYMALLOC	emalloc
35   #define YYFREE	free
36   #define YYERROR_VERBOSE
37   #define YYMAXDEPTH	1000	/* stop the madness sooner */
38   void yyerror(const char *msg);
39 
40   #ifdef SIM
41   #  define ONLY_SIM(a)	(a)
42   #else
43   #  define ONLY_SIM(a)	NULL
44   #endif
45 %}
46 
47 /*
48  * Enable generation of token names array even without YYDEBUG.
49  * We access via token_name() defined below.
50  */
51 %token-table
52 
53 %union {
54 	char *			String;
55 	double			Double;
56 	int			Integer;
57 	unsigned		U_int;
58 	gen_fifo *		Generic_fifo;
59 	attr_val *		Attr_val;
60 	attr_val_fifo *		Attr_val_fifo;
61 	int_fifo *		Int_fifo;
62 	string_fifo *		String_fifo;
63 	address_node *		Address_node;
64 	address_fifo *		Address_fifo;
65 	setvar_node *		Set_var;
66 	server_info *		Sim_server;
67 	server_info_fifo *	Sim_server_fifo;
68 	script_info *		Sim_script;
69 	script_info_fifo *	Sim_script_fifo;
70 }
71 
72 /* TERMINALS (do not appear left of colon) */
73 %token	<Integer>	T_Abbrev
74 %token	<Integer>	T_Age
75 %token	<Integer>	T_All
76 %token	<Integer>	T_Allan
77 %token	<Integer>	T_Allpeers
78 %token	<Integer>	T_Auth
79 %token	<Integer>	T_Autokey
80 %token	<Integer>	T_Automax
81 %token	<Integer>	T_Average
82 %token	<Integer>	T_Basedate
83 %token	<Integer>	T_Bclient
84 %token	<Integer>	T_Bcpollbstep
85 %token	<Integer>	T_Beacon
86 %token	<Integer>	T_Broadcast
87 %token	<Integer>	T_Broadcastclient
88 %token	<Integer>	T_Broadcastdelay
89 %token	<Integer>	T_Burst
90 %token	<Integer>	T_Calibrate
91 %token	<Integer>	T_Ceiling
92 %token	<Integer>	T_Clockstats
93 %token	<Integer>	T_Cohort
94 %token	<Integer>	T_ControlKey
95 %token	<Integer>	T_Crypto
96 %token	<Integer>	T_Cryptostats
97 %token	<Integer>	T_Ctl
98 %token	<Integer>	T_Day
99 %token	<Integer>	T_Default
100 %token	<Integer>	T_Digest
101 %token	<Integer>	T_Disable
102 %token	<Integer>	T_Discard
103 %token	<Integer>	T_Dispersion
104 %token	<Double>	T_Double		/* not a token */
105 %token	<Integer>	T_Driftfile
106 %token	<Integer>	T_Drop
107 %token	<Integer>	T_Dscp
108 %token	<Integer>	T_Ellipsis	/* "..." not "ellipsis" */
109 %token	<Integer>	T_Enable
110 %token	<Integer>	T_End
111 %token	<Integer>	T_Epeer
112 %token	<Integer>	T_False
113 %token	<Integer>	T_File
114 %token	<Integer>	T_Filegen
115 %token	<Integer>	T_Filenum
116 %token	<Integer>	T_Flag1
117 %token	<Integer>	T_Flag2
118 %token	<Integer>	T_Flag3
119 %token	<Integer>	T_Flag4
120 %token	<Integer>	T_Flake
121 %token	<Integer>	T_Floor
122 %token	<Integer>	T_Freq
123 %token	<Integer>	T_Fudge
124 %token	<Integer>	T_Host
125 %token	<Integer>	T_Huffpuff
126 %token	<Integer>	T_Iburst
127 %token	<Integer>	T_Ident
128 %token	<Integer>	T_Ignore
129 %token	<Integer>	T_Incalloc
130 %token	<Integer>	T_Incmem
131 %token	<Integer>	T_Initalloc
132 %token	<Integer>	T_Initmem
133 %token	<Integer>	T_Includefile
134 %token	<Integer>	T_Integer		/* not a token */
135 %token	<Integer>	T_Interface
136 %token	<Integer>	T_Intrange		/* not a token */
137 %token	<Integer>	T_Io
138 %token	<Integer>	T_Ippeerlimit
139 %token	<Integer>	T_Ipv4
140 %token	<Integer>	T_Ipv4_flag
141 %token	<Integer>	T_Ipv6
142 %token	<Integer>	T_Ipv6_flag
143 %token	<Integer>	T_Kernel
144 %token	<Integer>	T_Key
145 %token	<Integer>	T_Keys
146 %token	<Integer>	T_Keysdir
147 %token	<Integer>	T_Kod
148 %token	<Integer>	T_Mssntp
149 %token	<Integer>	T_Leapfile
150 %token	<Integer>	T_Leapsmearinterval
151 %token	<Integer>	T_Limited
152 %token	<Integer>	T_Link
153 %token	<Integer>	T_Listen
154 %token	<Integer>	T_Logconfig
155 %token	<Integer>	T_Logfile
156 %token	<Integer>	T_Loopstats
157 %token	<Integer>	T_Lowpriotrap
158 %token	<Integer>	T_Manycastclient
159 %token	<Integer>	T_Manycastserver
160 %token	<Integer>	T_Mask
161 %token	<Integer>	T_Maxage
162 %token	<Integer>	T_Maxclock
163 %token	<Integer>	T_Maxdepth
164 %token	<Integer>	T_Maxdist
165 %token	<Integer>	T_Maxmem
166 %token	<Integer>	T_Maxpoll
167 %token	<Integer>	T_Mdnstries
168 %token	<Integer>	T_Mem
169 %token	<Integer>	T_Memlock
170 %token	<Integer>	T_Minclock
171 %token	<Integer>	T_Mindepth
172 %token	<Integer>	T_Mindist
173 %token	<Integer>	T_Minimum
174 %token	<Integer>	T_Minpoll
175 %token	<Integer>	T_Minsane
176 %token	<Integer>	T_Mode
177 %token	<Integer>	T_Mode7
178 %token	<Integer>	T_Monitor
179 %token	<Integer>	T_Month
180 %token	<Integer>	T_Mru
181 %token	<Integer>	T_Multicastclient
182 %token	<Integer>	T_Nic
183 %token	<Integer>	T_Nolink
184 %token	<Integer>	T_Nomodify
185 %token	<Integer>	T_Nomrulist
186 %token	<Integer>	T_None
187 %token	<Integer>	T_Nonvolatile
188 %token	<Integer>	T_Noepeer
189 %token	<Integer>	T_Nopeer
190 %token	<Integer>	T_Noquery
191 %token	<Integer>	T_Noselect
192 %token	<Integer>	T_Noserve
193 %token	<Integer>	T_Notrap
194 %token	<Integer>	T_Notrust
195 %token	<Integer>	T_Ntp
196 %token	<Integer>	T_Ntpport
197 %token	<Integer>	T_NtpSignDsocket
198 %token	<Integer>	T_Orphan
199 %token	<Integer>	T_Orphanwait
200 %token	<Integer>	T_PCEdigest
201 %token	<Integer>	T_Panic
202 %token	<Integer>	T_Peer
203 %token	<Integer>	T_Peerstats
204 %token	<Integer>	T_Phone
205 %token	<Integer>	T_Pid
206 %token	<Integer>	T_Pidfile
207 %token	<Integer>	T_Pool
208 %token	<Integer>	T_Port
209 %token	<Integer>	T_Preempt
210 %token	<Integer>	T_Prefer
211 %token	<Integer>	T_Protostats
212 %token	<Integer>	T_Pw
213 %token	<Integer>	T_Randfile
214 %token	<Integer>	T_Rawstats
215 %token	<Integer>	T_Refid
216 %token	<Integer>	T_Requestkey
217 %token	<Integer>	T_Reset
218 %token	<Integer>	T_Restrict
219 %token	<Integer>	T_Revoke
220 %token	<Integer>	T_Rlimit
221 %token	<Integer>	T_Saveconfigdir
222 %token	<Integer>	T_Server
223 %token	<Integer>	T_Setvar
224 %token	<Integer>	T_Source
225 %token	<Integer>	T_Stacksize
226 %token	<Integer>	T_Statistics
227 %token	<Integer>	T_Stats
228 %token	<Integer>	T_Statsdir
229 %token	<Integer>	T_Step
230 %token	<Integer>	T_Stepback
231 %token	<Integer>	T_Stepfwd
232 %token	<Integer>	T_Stepout
233 %token	<Integer>	T_Stratum
234 %token	<String>	T_String		/* not a token */
235 %token	<Integer>	T_Sys
236 %token	<Integer>	T_Sysstats
237 %token	<Integer>	T_Tick
238 %token	<Integer>	T_Time1
239 %token	<Integer>	T_Time2
240 %token	<Integer>	T_Timer
241 %token	<Integer>	T_Timingstats
242 %token	<Integer>	T_Tinker
243 %token	<Integer>	T_Tos
244 %token	<Integer>	T_Trap
245 %token	<Integer>	T_True
246 %token	<Integer>	T_Trustedkey
247 %token	<Integer>	T_Ttl
248 %token	<Integer>	T_Type
249 %token	<Integer>	T_U_int			/* Not a token */
250 %token	<Integer>	T_UEcrypto
251 %token	<Integer>	T_UEcryptonak
252 %token	<Integer>	T_UEdigest
253 %token	<Integer>	T_Unconfig
254 %token	<Integer>	T_Unpeer
255 %token	<Integer>	T_Version
256 %token	<Integer>	T_WanderThreshold	/* Not a token */
257 %token	<Integer>	T_Week
258 %token	<Integer>	T_Wildcard
259 %token	<Integer>	T_Xleave
260 %token	<Integer>	T_Year
261 %token	<Integer>	T_Flag			/* Not a token */
262 %token	<Integer>	T_EOC
263 
264 
265 /* NTP Simulator Tokens */
266 %token	<Integer>	T_Simulate
267 %token	<Integer>	T_Beep_Delay
268 %token	<Integer>	T_Sim_Duration
269 %token	<Integer>	T_Server_Offset
270 %token	<Integer>	T_Duration
271 %token	<Integer>	T_Freq_Offset
272 %token	<Integer>	T_Wander
273 %token	<Integer>	T_Jitter
274 %token	<Integer>	T_Prop_Delay
275 %token	<Integer>	T_Proc_Delay
276 
277 
278 
279 /*** NON-TERMINALS ***/
280 %type	<Integer>	access_control_flag
281 %type	<Int_fifo>	ac_flag_list
282 %type	<Address_node>	address
283 %type	<Integer>	address_fam
284 %type	<Address_fifo>	address_list
285 %type	<Integer>	basedate
286 %type	<Integer>	boolean
287 %type	<Integer>	client_type
288 %type	<Integer>	counter_set_keyword
289 %type	<Int_fifo>	counter_set_list
290 %type	<Attr_val>	crypto_command
291 %type	<Attr_val_fifo>	crypto_command_list
292 %type	<Integer>	crypto_str_keyword
293 %type	<Attr_val>	discard_option
294 %type	<Integer>	discard_option_keyword
295 %type	<Attr_val_fifo>	discard_option_list
296 %type	<Integer>	enable_disable
297 %type	<Attr_val>	filegen_option
298 %type	<Attr_val_fifo>	filegen_option_list
299 %type	<Integer>	filegen_type
300 %type	<Attr_val>	fudge_factor
301 %type	<Integer>	fudge_factor_bool_keyword
302 %type	<Integer>	fudge_factor_dbl_keyword
303 %type	<Attr_val_fifo>	fudge_factor_list
304 %type	<Attr_val_fifo>	integer_list
305 %type	<Attr_val_fifo>	integer_list_range
306 %type	<Attr_val>	integer_list_range_elt
307 %type	<Attr_val>	integer_range
308 %type	<Integer>	nic_rule_action
309 %type	<Integer>	interface_command
310 %type	<Integer>	interface_nic
311 %type	<Address_node>	ip_address
312 %type	<Integer>	res_ippeerlimit
313 %type	<Integer>	link_nolink
314 %type	<Attr_val>	log_config_command
315 %type	<Attr_val_fifo>	log_config_list
316 %type	<Integer>	misc_cmd_dbl_keyword
317 %type	<Integer>	misc_cmd_int_keyword
318 %type	<Integer>	misc_cmd_str_keyword
319 %type	<Integer>	misc_cmd_str_lcl_keyword
320 %type	<Attr_val>	mru_option
321 %type	<Integer>	mru_option_keyword
322 %type	<Attr_val_fifo>	mru_option_list
323 %type	<Integer>	nic_rule_class
324 %type	<Double>	number
325 %type	<Attr_val>	option
326 %type	<Attr_val>	option_flag
327 %type	<Integer>	option_flag_keyword
328 %type	<Attr_val_fifo>	option_list
329 %type	<Attr_val>	option_int
330 %type	<Integer>	option_int_keyword
331 %type	<Attr_val>	option_str
332 %type	<Integer>	option_str_keyword
333 %type	<Integer>	reset_command
334 %type	<Integer>	rlimit_option_keyword
335 %type	<Attr_val>	rlimit_option
336 %type	<Attr_val_fifo>	rlimit_option_list
337 %type	<Integer>	stat
338 %type	<Int_fifo>	stats_list
339 %type	<String_fifo>	string_list
340 %type	<Attr_val>	system_option
341 %type	<Integer>	system_option_flag_keyword
342 %type	<Integer>	system_option_local_flag_keyword
343 %type	<Attr_val_fifo>	system_option_list
344 %type	<Integer>	t_default_or_zero
345 %type	<Integer>	tinker_option_keyword
346 %type	<Attr_val>	tinker_option
347 %type	<Attr_val_fifo>	tinker_option_list
348 %type	<Attr_val>	tos_option
349 %type	<Integer>	tos_option_dbl_keyword
350 %type	<Integer>	tos_option_int_keyword
351 %type	<Attr_val_fifo>	tos_option_list
352 %type	<Attr_val>	trap_option
353 %type	<Attr_val_fifo>	trap_option_list
354 %type	<Integer>	unpeer_keyword
355 %type	<Set_var>	variable_assign
356 
357 /* NTP Simulator non-terminals */
358 %type	<Attr_val>		sim_init_statement
359 %type	<Attr_val_fifo>		sim_init_statement_list
360 %type	<Integer>		sim_init_keyword
361 %type	<Sim_server_fifo>	sim_server_list
362 %type	<Sim_server>		sim_server
363 %type	<Double>		sim_server_offset
364 %type	<Address_node>		sim_server_name
365 %type	<Sim_script>		sim_act
366 %type	<Sim_script_fifo>	sim_act_list
367 %type	<Integer>		sim_act_keyword
368 %type	<Attr_val_fifo>		sim_act_stmt_list
369 %type	<Attr_val>		sim_act_stmt
370 
371 %%
372 
373 /* ntp.conf
374  * Configuration File Grammar
375  * --------------------------
376  */
377 
378 configuration
379 	:	command_list
380 	;
381 
382 command_list
383 	:	command_list command T_EOC
384 	|	command T_EOC
385 	|	error T_EOC
386 		{
387 			/* I will need to incorporate much more fine grained
388 			 * error messages. The following should suffice for
389 			 * the time being.
390 			 */
391 			struct FILE_INFO * ip_ctx = lex_current();
392 			msyslog(LOG_ERR,
393 				"syntax error in %s line %d, column %d",
394 				ip_ctx->fname,
395 				ip_ctx->errpos.nline,
396 				ip_ctx->errpos.ncol);
397 		}
398 	;
399 
400 command :	/* NULL STATEMENT */
401 	|	server_command
402 	|	unpeer_command
403 	|	other_mode_command
404 	|	authentication_command
405 	|	monitoring_command
406 	|	access_control_command
407 	|	orphan_mode_command
408 	|	fudge_command
409 	|	rlimit_command
410 	|	system_option_command
411 	|	tinker_command
412 	|	miscellaneous_command
413 	|	simulate_command
414 	;
415 
416 /* Server Commands
417  * ---------------
418  */
419 
420 server_command
421 	:	client_type address option_list
422 		{
423 			peer_node *my_node;
424 
425 			my_node = create_peer_node($1, $2, $3);
426 			APPEND_G_FIFO(cfgt.peers, my_node);
427 		}
428 	;
429 
430 client_type
431 	:	T_Server
432 	|	T_Pool
433 	|	T_Peer
434 	|	T_Broadcast
435 	|	T_Manycastclient
436 	;
437 
438 address
439 	:	ip_address
440 	|	address_fam T_String
441 			{ $$ = create_address_node($2, $1); }
442 	;
443 
444 ip_address
445 	:	T_String
446 			{ $$ = create_address_node($1, AF_UNSPEC); }
447 	;
448 
449 address_fam
450 	:	T_Ipv4_flag
451 			{ $$ = AF_INET; }
452 	|	T_Ipv6_flag
453 			{ $$ = AF_INET6; }
454 	;
455 
456 option_list
457 	:	/* empty list */
458 			{ $$ = NULL; }
459 	|	option_list option
460 		{
461 			$$ = $1;
462 			APPEND_G_FIFO($$, $2);
463 		}
464 	;
465 
466 option
467 	:	option_flag
468 	|	option_int
469 	|	option_str
470 	;
471 
472 option_flag
473 	:	option_flag_keyword
474 			{ $$ = create_attr_ival(T_Flag, $1); }
475 	;
476 
477 option_flag_keyword
478 	:	T_Autokey
479 	|	T_Burst
480 	|	T_Iburst
481 	|	T_Noselect
482 	|	T_Preempt
483 	|	T_Prefer
484 	|	T_True
485 	|	T_Xleave
486 	;
487 
488 option_int
489 	:	option_int_keyword T_Integer
490 			{ $$ = create_attr_ival($1, $2); }
491 	|	option_int_keyword T_U_int
492 			{ $$ = create_attr_uval($1, $2); }
493 	;
494 
495 option_int_keyword
496 	:	T_Key
497 	|	T_Minpoll
498 	|	T_Maxpoll
499 	|	T_Ttl
500 	|	T_Mode
501 	|	T_Version
502 	;
503 
504 option_str
505 	:	option_str_keyword T_String
506 			{ $$ = create_attr_sval($1, $2); }
507 	;
508 
509 option_str_keyword
510 	:	T_Ident
511 	;
512 
513 
514 /* unpeer commands
515  * ---------------
516  */
517 
518 unpeer_command
519 	:	unpeer_keyword address
520 		{
521 			unpeer_node *my_node;
522 
523 			my_node = create_unpeer_node($2);
524 			if (my_node)
525 				APPEND_G_FIFO(cfgt.unpeers, my_node);
526 		}
527 	;
528 unpeer_keyword
529 	:	T_Unconfig
530 	|	T_Unpeer
531 	;
532 
533 
534 /* Other Modes
535  * (broadcastclient manycastserver multicastclient)
536  * ------------------------------------------------
537  */
538 
539 other_mode_command
540 	:	T_Broadcastclient
541 			{ cfgt.broadcastclient = 1; }
542 	|	T_Manycastserver address_list
543 			{ CONCAT_G_FIFOS(cfgt.manycastserver, $2); }
544 	|	T_Multicastclient address_list
545 			{ CONCAT_G_FIFOS(cfgt.multicastclient, $2); }
546 	|	T_Mdnstries T_Integer
547 			{ cfgt.mdnstries = $2; }
548 	;
549 
550 
551 
552 /* Authentication Commands
553  * -----------------------
554  */
555 
556 authentication_command
557 	:	T_Automax T_Integer
558 		{
559 			attr_val *atrv;
560 
561 			atrv = create_attr_ival($1, $2);
562 			APPEND_G_FIFO(cfgt.vars, atrv);
563 		}
564 	|	T_ControlKey T_Integer
565 			{ cfgt.auth.control_key = $2; }
566 	|	T_Crypto crypto_command_list
567 		{
568 			cfgt.auth.cryptosw++;
569 			CONCAT_G_FIFOS(cfgt.auth.crypto_cmd_list, $2);
570 		}
571 	|	T_Keys T_String
572 			{ cfgt.auth.keys = $2; }
573 	|	T_Keysdir T_String
574 			{ cfgt.auth.keysdir = $2; }
575 	|	T_Requestkey T_Integer
576 			{ cfgt.auth.request_key = $2; }
577 	|	T_Revoke T_Integer
578 			{ cfgt.auth.revoke = $2; }
579 	|	T_Trustedkey integer_list_range
580 		{
581 			/* [Bug 948] leaves it open if appending or
582 			 * replacing the trusted key list is the right
583 			 * way. In any case, either alternative should
584 			 * be coded correctly!
585 			 */
586 			DESTROY_G_FIFO(cfgt.auth.trusted_key_list, destroy_attr_val); /* remove for append */
587 			CONCAT_G_FIFOS(cfgt.auth.trusted_key_list, $2);
588 		}
589 	|	T_NtpSignDsocket T_String
590 			{ cfgt.auth.ntp_signd_socket = $2; }
591 	;
592 
593 crypto_command_list
594 	:	/* empty list */
595 			{ $$ = NULL; }
596 	|	crypto_command_list crypto_command
597 		{
598 			$$ = $1;
599 			APPEND_G_FIFO($$, $2);
600 		}
601 	;
602 
603 crypto_command
604 	:	crypto_str_keyword T_String
605 			{ $$ = create_attr_sval($1, $2); }
606 	|	T_Revoke T_Integer
607 		{
608 			$$ = NULL;
609 			cfgt.auth.revoke = $2;
610 			msyslog(LOG_WARNING,
611 				"'crypto revoke %d' is deprecated, "
612 				"please use 'revoke %d' instead.",
613 				cfgt.auth.revoke, cfgt.auth.revoke);
614 		}
615 	;
616 
617 crypto_str_keyword
618 	:	T_Host
619 	|	T_Ident
620 	|	T_Pw
621 	|	T_Randfile
622 	|	T_Digest
623 	;
624 
625 
626 /* Orphan Mode Commands
627  * --------------------
628  */
629 
630 orphan_mode_command
631 	:	T_Tos tos_option_list
632 			{ CONCAT_G_FIFOS(cfgt.orphan_cmds, $2); }
633 	;
634 
635 tos_option_list
636 	:	tos_option_list tos_option
637 		{
638 			$$ = $1;
639 			APPEND_G_FIFO($$, $2);
640 		}
641 	|	tos_option
642 		{
643 			$$ = NULL;
644 			APPEND_G_FIFO($$, $1);
645 		}
646 	;
647 
648 tos_option
649 	:	tos_option_int_keyword T_Integer
650 			{ $$ = create_attr_dval($1, (double)$2); }
651 	|	tos_option_dbl_keyword number
652 			{ $$ = create_attr_dval($1, $2); }
653 	|	T_Cohort boolean
654 			{ $$ = create_attr_dval($1, (double)$2); }
655 	|	basedate
656 			{ $$ = create_attr_ival(T_Basedate, $1); }
657 	;
658 
659 tos_option_int_keyword
660 	:	T_Bcpollbstep
661 	|	T_Beacon
662 	|	T_Ceiling
663 	|	T_Floor
664 	|	T_Maxclock
665 	|	T_Minclock
666 	|	T_Minsane
667 	|	T_Orphan
668 	|	T_Orphanwait
669 	;
670 
671 tos_option_dbl_keyword
672 	:	T_Mindist
673 	|	T_Maxdist
674 	;
675 
676 
677 /* Monitoring Commands
678  * -------------------
679  */
680 
681 monitoring_command
682 	:	T_Statistics stats_list
683 			{ CONCAT_G_FIFOS(cfgt.stats_list, $2); }
684 	|	T_Statsdir T_String
685 		{
686 			if (lex_from_file()) {
687 				cfgt.stats_dir = $2;
688 			} else {
689 				YYFREE($2);
690 				yyerror("statsdir remote configuration ignored");
691 			}
692 		}
693 	|	T_Filegen stat filegen_option_list
694 		{
695 			filegen_node *fgn;
696 
697 			fgn = create_filegen_node($2, $3);
698 			APPEND_G_FIFO(cfgt.filegen_opts, fgn);
699 		}
700 	;
701 
702 stats_list
703 	:	stats_list stat
704 		{
705 			$$ = $1;
706 			APPEND_G_FIFO($$, create_int_node($2));
707 		}
708 	|	stat
709 		{
710 			$$ = NULL;
711 			APPEND_G_FIFO($$, create_int_node($1));
712 		}
713 	;
714 
715 stat
716 	:	T_Clockstats
717 	|	T_Cryptostats
718 	|	T_Loopstats
719 	|	T_Peerstats
720 	|	T_Rawstats
721 	|	T_Sysstats
722 	|	T_Timingstats
723 	|	T_Protostats
724 	;
725 
726 filegen_option_list
727 	:	/* empty list */
728 			{ $$ = NULL; }
729 	|	filegen_option_list filegen_option
730 		{
731 			$$ = $1;
732 			APPEND_G_FIFO($$, $2);
733 		}
734 	;
735 
736 filegen_option
737 	:	T_File T_String
738 		{
739 			if (lex_from_file()) {
740 				$$ = create_attr_sval($1, $2);
741 			} else {
742 				$$ = NULL;
743 				YYFREE($2);
744 				yyerror("filegen file remote config ignored");
745 			}
746 		}
747 	|	T_Type filegen_type
748 		{
749 			if (lex_from_file()) {
750 				$$ = create_attr_ival($1, $2);
751 			} else {
752 				$$ = NULL;
753 				yyerror("filegen type remote config ignored");
754 			}
755 		}
756 	|	link_nolink
757 		{
758 			const char *err;
759 
760 			if (lex_from_file()) {
761 				$$ = create_attr_ival(T_Flag, $1);
762 			} else {
763 				$$ = NULL;
764 				if (T_Link == $1)
765 					err = "filegen link remote config ignored";
766 				else
767 					err = "filegen nolink remote config ignored";
768 				yyerror(err);
769 			}
770 		}
771 	|	enable_disable
772 			{ $$ = create_attr_ival(T_Flag, $1); }
773 	;
774 
775 link_nolink
776 	:	T_Link
777 	|	T_Nolink
778 	;
779 
780 enable_disable
781 	:	T_Enable
782 	|	T_Disable
783 	;
784 
785 filegen_type
786 	:	T_None
787 	|	T_Pid
788 	|	T_Day
789 	|	T_Week
790 	|	T_Month
791 	|	T_Year
792 	|	T_Age
793 	;
794 
795 
796 /* Access Control Commands
797  * -----------------------
798  */
799 
800 access_control_command
801 	:	T_Discard discard_option_list
802 		{
803 			CONCAT_G_FIFOS(cfgt.discard_opts, $2);
804 		}
805 	|	T_Mru mru_option_list
806 		{
807 			CONCAT_G_FIFOS(cfgt.mru_opts, $2);
808 		}
809 	|	T_Restrict address res_ippeerlimit ac_flag_list
810 		{
811 			restrict_node *rn;
812 
813 			rn = create_restrict_node($2, NULL, $3, $4,
814 						  lex_current()->curpos.nline);
815 			APPEND_G_FIFO(cfgt.restrict_opts, rn);
816 		}
817 	|	T_Restrict address T_Mask ip_address res_ippeerlimit ac_flag_list
818 		{
819 			restrict_node *rn;
820 
821 			rn = create_restrict_node($2, $4, $5, $6,
822 						  lex_current()->curpos.nline);
823 			APPEND_G_FIFO(cfgt.restrict_opts, rn);
824 		}
825 	|	T_Restrict T_Default res_ippeerlimit ac_flag_list
826 		{
827 			restrict_node *rn;
828 
829 			rn = create_restrict_node(NULL, NULL, $3, $4,
830 						  lex_current()->curpos.nline);
831 			APPEND_G_FIFO(cfgt.restrict_opts, rn);
832 		}
833 	|	T_Restrict T_Ipv4_flag T_Default res_ippeerlimit ac_flag_list
834 		{
835 			restrict_node *rn;
836 
837 			rn = create_restrict_node(
838 				create_address_node(
839 					estrdup("0.0.0.0"),
840 					AF_INET),
841 				create_address_node(
842 					estrdup("0.0.0.0"),
843 					AF_INET),
844 				$4, $5,
845 				lex_current()->curpos.nline);
846 			APPEND_G_FIFO(cfgt.restrict_opts, rn);
847 		}
848 	|	T_Restrict T_Ipv6_flag T_Default res_ippeerlimit ac_flag_list
849 		{
850 			restrict_node *rn;
851 
852 			rn = create_restrict_node(
853 				create_address_node(
854 					estrdup("::"),
855 					AF_INET6),
856 				create_address_node(
857 					estrdup("::"),
858 					AF_INET6),
859 				$4, $5,
860 				lex_current()->curpos.nline);
861 			APPEND_G_FIFO(cfgt.restrict_opts, rn);
862 		}
863 	|	T_Restrict T_Source res_ippeerlimit ac_flag_list
864 		{
865 			restrict_node *	rn;
866 
867 			APPEND_G_FIFO($4, create_int_node($2));
868 			rn = create_restrict_node(
869 				NULL, NULL, $3, $4, lex_current()->curpos.nline);
870 			APPEND_G_FIFO(cfgt.restrict_opts, rn);
871 		}
872 	;
873 
874 res_ippeerlimit
875 	:	/* empty ippeerlimit defaults to -1 (unlimited) */
876 			{ $$ = -1; }
877 	|	T_Ippeerlimit  T_Integer
878 		{
879 			if (($2 < -1) || ($2 > 100)) {
880 				struct FILE_INFO * ip_ctx;
881 
882 				ip_ctx = lex_current();
883 				msyslog(LOG_ERR,
884 					"Unreasonable ippeerlimit value (%d) in %s line %d, column %d.  Using 0.",
885 					$2,
886 					ip_ctx->fname,
887 					ip_ctx->errpos.nline,
888 					ip_ctx->errpos.ncol);
889 				$2 = 0;
890 			}
891 			$$ = $2;
892 		}
893 	;
894 
895 ac_flag_list
896 	:	/* empty list is allowed */
897 			{ $$ = NULL; }
898 	|	ac_flag_list access_control_flag
899 		{
900 			$$ = $1;
901 			APPEND_G_FIFO($$, create_int_node($2));
902 		}
903 	;
904 
905 access_control_flag
906 	:	T_Epeer
907 	|	T_Flake
908 	|	T_Ignore
909 	|	T_Kod
910 	|	T_Mssntp
911 	|	T_Limited
912 	|	T_Lowpriotrap
913 	|	T_Noepeer
914 	|	T_Nomodify
915 	|	T_Nomrulist
916 	|	T_Nopeer
917 	|	T_Noquery
918 	|	T_Noserve
919 	|	T_Notrap
920 	|	T_Notrust
921 	|	T_Ntpport
922 	|	T_Version
923 	;
924 
925 discard_option_list
926 	:	discard_option_list discard_option
927 		{
928 			$$ = $1;
929 			APPEND_G_FIFO($$, $2);
930 		}
931 	|	discard_option
932 		{
933 			$$ = NULL;
934 			APPEND_G_FIFO($$, $1);
935 		}
936 	;
937 
938 discard_option
939 	:	discard_option_keyword T_Integer
940 			{ $$ = create_attr_ival($1, $2); }
941 	;
942 
943 discard_option_keyword
944 	:	T_Average
945 	|	T_Minimum
946 	|	T_Monitor
947 	;
948 
949 mru_option_list
950 	:	mru_option_list mru_option
951 		{
952 			$$ = $1;
953 			APPEND_G_FIFO($$, $2);
954 		}
955 	|	mru_option
956 		{
957 			$$ = NULL;
958 			APPEND_G_FIFO($$, $1);
959 		}
960 	;
961 
962 mru_option
963 	:	mru_option_keyword T_Integer
964 			{ $$ = create_attr_ival($1, $2); }
965 	;
966 
967 mru_option_keyword
968 	:	T_Incalloc
969 	|	T_Incmem
970 	|	T_Initalloc
971 	|	T_Initmem
972 	|	T_Maxage
973 	|	T_Maxdepth
974 	|	T_Maxmem
975 	|	T_Mindepth
976 	;
977 
978 /* Fudge Commands
979  * --------------
980  */
981 
982 fudge_command
983 	:	T_Fudge address fudge_factor_list
984 		{
985 			addr_opts_node *aon;
986 
987 			aon = create_addr_opts_node($2, $3);
988 			APPEND_G_FIFO(cfgt.fudge, aon);
989 		}
990 	;
991 
992 fudge_factor_list
993 	:	fudge_factor_list fudge_factor
994 		{
995 			$$ = $1;
996 			APPEND_G_FIFO($$, $2);
997 		}
998 	|	fudge_factor
999 		{
1000 			$$ = NULL;
1001 			APPEND_G_FIFO($$, $1);
1002 		}
1003 	;
1004 
1005 fudge_factor
1006 	:	fudge_factor_dbl_keyword number
1007 			{ $$ = create_attr_dval($1, $2); }
1008 	|	fudge_factor_bool_keyword boolean
1009 			{ $$ = create_attr_ival($1, $2); }
1010 	|	T_Stratum T_Integer
1011 		{
1012 			if ($2 >= 0 && $2 <= 16) {
1013 				$$ = create_attr_ival($1, $2);
1014 			} else {
1015 				$$ = NULL;
1016 				yyerror("fudge factor: stratum value not in [0..16], ignored");
1017 			}
1018 		}
1019 	|	T_Abbrev T_String
1020 			{ $$ = create_attr_sval($1, $2); }
1021 	|	T_Refid T_String
1022 			{ $$ = create_attr_sval($1, $2); }
1023 	;
1024 
1025 fudge_factor_dbl_keyword
1026 	:	T_Time1
1027 	|	T_Time2
1028 	;
1029 
1030 fudge_factor_bool_keyword
1031 	:	T_Flag1
1032 	|	T_Flag2
1033 	|	T_Flag3
1034 	|	T_Flag4
1035 	;
1036 
1037 /* rlimit Commands
1038  * ---------------
1039  */
1040 
1041 rlimit_command
1042 	:	T_Rlimit rlimit_option_list
1043 			{ CONCAT_G_FIFOS(cfgt.rlimit, $2); }
1044 	;
1045 
1046 rlimit_option_list
1047 	:	rlimit_option_list rlimit_option
1048 		{
1049 			$$ = $1;
1050 			APPEND_G_FIFO($$, $2);
1051 		}
1052 	|	rlimit_option
1053 		{
1054 			$$ = NULL;
1055 			APPEND_G_FIFO($$, $1);
1056 		}
1057 	;
1058 
1059 rlimit_option
1060 	:	rlimit_option_keyword T_Integer
1061 			{ $$ = create_attr_ival($1, $2); }
1062 	;
1063 
1064 rlimit_option_keyword
1065 	:	T_Memlock
1066 	|	T_Stacksize
1067 	|	T_Filenum
1068 	;
1069 
1070 
1071 /* Command for System Options
1072  * --------------------------
1073  */
1074 
1075 system_option_command
1076 	:	T_Enable system_option_list
1077 			{ CONCAT_G_FIFOS(cfgt.enable_opts, $2); }
1078 	|	T_Disable system_option_list
1079 			{ CONCAT_G_FIFOS(cfgt.disable_opts, $2); }
1080 	;
1081 
1082 system_option_list
1083 	:	system_option_list system_option
1084 		{
1085 			$$ = $1;
1086 			APPEND_G_FIFO($$, $2);
1087 		}
1088 	|	system_option
1089 		{
1090 			$$ = NULL;
1091 			APPEND_G_FIFO($$, $1);
1092 		}
1093 	;
1094 
1095 system_option
1096 	:	system_option_flag_keyword
1097 			{ $$ = create_attr_ival(T_Flag, $1); }
1098 	|	system_option_local_flag_keyword
1099 		{
1100 			if (lex_from_file()) {
1101 				$$ = create_attr_ival(T_Flag, $1);
1102 			} else {
1103 				char err_str[128];
1104 
1105 				$$ = NULL;
1106 				snprintf(err_str, sizeof(err_str),
1107 					 "enable/disable %s remote configuration ignored",
1108 					 keyword($1));
1109 				yyerror(err_str);
1110 			}
1111 		}
1112 	;
1113 
1114 system_option_flag_keyword
1115 	:	T_Auth
1116 	|	T_Bclient
1117 	|	T_Calibrate
1118 	|	T_Kernel
1119 	|	T_Monitor
1120 	|	T_Ntp
1121 	;
1122 
1123 system_option_local_flag_keyword
1124 	:	T_Mode7
1125 	|	T_PCEdigest
1126 	|	T_Stats
1127 	|	T_UEcrypto
1128 	|	T_UEcryptonak
1129 	|	T_UEdigest
1130 	;
1131 
1132 /* Tinker Commands
1133  * ---------------
1134  */
1135 
1136 tinker_command
1137 	:	T_Tinker tinker_option_list
1138 			{ CONCAT_G_FIFOS(cfgt.tinker, $2); }
1139 	;
1140 
1141 tinker_option_list
1142 	:	tinker_option_list tinker_option
1143 		{
1144 			$$ = $1;
1145 			APPEND_G_FIFO($$, $2);
1146 		}
1147 	|	tinker_option
1148 		{
1149 			$$ = NULL;
1150 			APPEND_G_FIFO($$, $1);
1151 		}
1152 	;
1153 
1154 tinker_option
1155 	:	tinker_option_keyword number
1156 			{ $$ = create_attr_dval($1, $2); }
1157 	;
1158 
1159 tinker_option_keyword
1160 	:	T_Allan
1161 	|	T_Dispersion
1162 	|	T_Freq
1163 	|	T_Huffpuff
1164 	|	T_Panic
1165 	|	T_Step
1166 	|	T_Stepback
1167 	|	T_Stepfwd
1168 	|	T_Stepout
1169 	|	T_Tick
1170 	;
1171 
1172 
1173 /* Miscellaneous Commands
1174  * ----------------------
1175  */
1176 
1177 miscellaneous_command
1178 	:	interface_command
1179 	|	reset_command
1180 	|	misc_cmd_dbl_keyword number
1181 		{
1182 			attr_val *av;
1183 
1184 			av = create_attr_dval($1, $2);
1185 			APPEND_G_FIFO(cfgt.vars, av);
1186 		}
1187 	|	misc_cmd_int_keyword T_Integer
1188 		{
1189 			attr_val *av;
1190 
1191 			av = create_attr_ival($1, $2);
1192 			APPEND_G_FIFO(cfgt.vars, av);
1193 		}
1194 	|	misc_cmd_str_keyword T_String
1195 		{
1196 			attr_val *av;
1197 
1198 			av = create_attr_sval($1, $2);
1199 			APPEND_G_FIFO(cfgt.vars, av);
1200 		}
1201 	|	misc_cmd_str_lcl_keyword T_String
1202 		{
1203 			char error_text[64];
1204 			attr_val *av;
1205 
1206 			if (lex_from_file()) {
1207 				av = create_attr_sval($1, $2);
1208 				APPEND_G_FIFO(cfgt.vars, av);
1209 			} else {
1210 				YYFREE($2);
1211 				snprintf(error_text, sizeof(error_text),
1212 					 "%s remote config ignored",
1213 					 keyword($1));
1214 				yyerror(error_text);
1215 			}
1216 		}
1217 	|	T_Includefile T_String command
1218 		{
1219 			if (!lex_from_file()) {
1220 				YYFREE($2); /* avoid leak */
1221 				yyerror("remote includefile ignored");
1222 				break;
1223 			}
1224 			if (lex_level() > MAXINCLUDELEVEL) {
1225 				fprintf(stderr, "getconfig: Maximum include file level exceeded.\n");
1226 				msyslog(LOG_ERR, "getconfig: Maximum include file level exceeded.");
1227 			} else {
1228 				const char * path = FindConfig($2); /* might return $2! */
1229 				if (!lex_push_file(path, "r")) {
1230 					fprintf(stderr, "getconfig: Couldn't open <%s>\n", path);
1231 					msyslog(LOG_ERR, "getconfig: Couldn't open <%s>", path);
1232 				}
1233 			}
1234 			YYFREE($2); /* avoid leak */
1235 		}
1236 	|	T_End
1237 			{ lex_flush_stack(); }
1238 	|	T_Driftfile drift_parm
1239 			{ /* see drift_parm below for actions */ }
1240 	|	T_Logconfig log_config_list
1241 			{ CONCAT_G_FIFOS(cfgt.logconfig, $2); }
1242 	|	T_Phone string_list
1243 			{ CONCAT_G_FIFOS(cfgt.phone, $2); }
1244 	|	T_Setvar variable_assign
1245 			{ APPEND_G_FIFO(cfgt.setvar, $2); }
1246 	|	T_Trap ip_address trap_option_list
1247 		{
1248 			addr_opts_node *aon;
1249 
1250 			aon = create_addr_opts_node($2, $3);
1251 			APPEND_G_FIFO(cfgt.trap, aon);
1252 		}
1253 	|	T_Ttl integer_list
1254 			{ CONCAT_G_FIFOS(cfgt.ttl, $2); }
1255 	;
1256 
1257 misc_cmd_dbl_keyword
1258 	:	T_Broadcastdelay
1259 	|	T_Nonvolatile
1260 	|	T_Tick
1261 	;
1262 
1263 misc_cmd_int_keyword
1264 	:	T_Dscp
1265 	;
1266 
1267 misc_cmd_int_keyword
1268 	:	T_Leapsmearinterval
1269 		{
1270 #ifndef LEAP_SMEAR
1271 			yyerror("Built without LEAP_SMEAR support.");
1272 #endif
1273 		}
1274 	;
1275 
1276 misc_cmd_str_keyword
1277 	:	T_Ident
1278 	|	T_Leapfile
1279 	;
1280 
1281 misc_cmd_str_lcl_keyword
1282 	:	T_Logfile
1283 	|	T_Pidfile
1284 	|	T_Saveconfigdir
1285 	;
1286 
1287 drift_parm
1288 	:	T_String
1289 		{
1290 			if (lex_from_file()) {
1291 				attr_val *av;
1292 				av = create_attr_sval(T_Driftfile, $1);
1293 				APPEND_G_FIFO(cfgt.vars, av);
1294 			} else {
1295 				YYFREE($1);
1296 				yyerror("driftfile remote configuration ignored");
1297 			}
1298 		}
1299 	|	T_String T_Double
1300 		{
1301 			if (lex_from_file()) {
1302 				attr_val *av;
1303 				av = create_attr_sval(T_Driftfile, $1);
1304 				APPEND_G_FIFO(cfgt.vars, av);
1305 				av = create_attr_dval(T_WanderThreshold, $2);
1306 				APPEND_G_FIFO(cfgt.vars, av);
1307 			msyslog(LOG_WARNING,
1308 				"'driftfile FILENAME WanderValue' is deprecated, "
1309 				"please use separate 'driftfile FILENAME' and "
1310 				"'nonvolatile WanderValue' lines instead.");
1311 			} else {
1312 				YYFREE($1);
1313 				yyerror("driftfile remote configuration ignored");
1314 			}
1315 		}
1316 	|	/* Null driftfile,  indicated by empty string "" */
1317 		{
1318 			if (lex_from_file()) {
1319 				attr_val *av;
1320 				av = create_attr_sval(T_Driftfile, estrdup(""));
1321 				APPEND_G_FIFO(cfgt.vars, av);
1322 			} else {
1323 				yyerror("driftfile remote configuration ignored");
1324 			}
1325 		}
1326 	;
1327 
1328 variable_assign
1329 	:	T_String '=' T_String t_default_or_zero
1330 			{ $$ = create_setvar_node($1, $3, $4); }
1331 	;
1332 
1333 t_default_or_zero
1334 	:	T_Default
1335 	|	/* empty, no "default" modifier */
1336 			{ $$ = 0; }
1337 	;
1338 
1339 trap_option_list
1340 	:	/* empty list */
1341 			{ $$ = NULL; }
1342 	|	trap_option_list trap_option
1343 		{
1344 			$$ = $1;
1345 			APPEND_G_FIFO($$, $2);
1346 		}
1347 	;
1348 
1349 trap_option
1350 	:	T_Port T_Integer
1351 			{ $$ = create_attr_ival($1, $2); }
1352 	|	T_Interface ip_address
1353 		{
1354 			$$ = create_attr_sval($1, estrdup($2->address));
1355 			destroy_address_node($2);
1356 		}
1357 	;
1358 
1359 log_config_list
1360 	:	log_config_list log_config_command
1361 		{
1362 			$$ = $1;
1363 			APPEND_G_FIFO($$, $2);
1364 		}
1365 	|	log_config_command
1366 		{
1367 			$$ = NULL;
1368 			APPEND_G_FIFO($$, $1);
1369 		}
1370 	;
1371 
1372 log_config_command
1373 	:	T_String
1374 		{
1375 			char	prefix;
1376 			char *	type;
1377 
1378 			switch ($1[0]) {
1379 
1380 			case '+':
1381 			case '-':
1382 			case '=':
1383 				prefix = $1[0];
1384 				type = $1 + 1;
1385 				break;
1386 
1387 			default:
1388 				prefix = '=';
1389 				type = $1;
1390 			}
1391 
1392 			$$ = create_attr_sval(prefix, estrdup(type));
1393 			YYFREE($1);
1394 		}
1395 	;
1396 
1397 interface_command
1398 	:	interface_nic nic_rule_action nic_rule_class
1399 		{
1400 			nic_rule_node *nrn;
1401 
1402 			nrn = create_nic_rule_node($3, NULL, $2);
1403 			APPEND_G_FIFO(cfgt.nic_rules, nrn);
1404 		}
1405 	|	interface_nic nic_rule_action T_String
1406 		{
1407 			nic_rule_node *nrn;
1408 
1409 			nrn = create_nic_rule_node(0, $3, $2);
1410 			APPEND_G_FIFO(cfgt.nic_rules, nrn);
1411 		}
1412 	;
1413 
1414 interface_nic
1415 	:	T_Interface
1416 	|	T_Nic
1417 	;
1418 
1419 nic_rule_class
1420 	:	T_All
1421 	|	T_Ipv4
1422 	|	T_Ipv6
1423 	|	T_Wildcard
1424 	;
1425 
1426 nic_rule_action
1427 	:	T_Listen
1428 	|	T_Ignore
1429 	|	T_Drop
1430 	;
1431 
1432 reset_command
1433 	:	T_Reset counter_set_list
1434 			{ CONCAT_G_FIFOS(cfgt.reset_counters, $2); }
1435 	;
1436 
1437 counter_set_list
1438 	:	counter_set_list counter_set_keyword
1439 		{
1440 			$$ = $1;
1441 			APPEND_G_FIFO($$, create_int_node($2));
1442 		}
1443 	|	counter_set_keyword
1444 		{
1445 			$$ = NULL;
1446 			APPEND_G_FIFO($$, create_int_node($1));
1447 		}
1448 	;
1449 
1450 counter_set_keyword
1451 	:	T_Allpeers
1452 	|	T_Auth
1453 	|	T_Ctl
1454 	|	T_Io
1455 	|	T_Mem
1456 	|	T_Sys
1457 	|	T_Timer
1458 	;
1459 
1460 
1461 
1462 /* Miscellaneous Rules
1463  * -------------------
1464  */
1465 
1466 integer_list
1467 	:	integer_list T_Integer
1468 		{
1469 			$$ = $1;
1470 			APPEND_G_FIFO($$, create_int_node($2));
1471 		}
1472 	|	T_Integer
1473 		{
1474 			$$ = NULL;
1475 			APPEND_G_FIFO($$, create_int_node($1));
1476 		}
1477 	;
1478 
1479 integer_list_range
1480 	:	integer_list_range integer_list_range_elt
1481 		{
1482 			$$ = $1;
1483 			APPEND_G_FIFO($$, $2);
1484 		}
1485 	|	integer_list_range_elt
1486 		{
1487 			$$ = NULL;
1488 			APPEND_G_FIFO($$, $1);
1489 		}
1490 	;
1491 
1492 integer_list_range_elt
1493 	:	T_Integer
1494 			{ $$ = create_attr_ival('i', $1); }
1495 	|	integer_range
1496 	;
1497 
1498 integer_range
1499 	:	'(' T_Integer T_Ellipsis T_Integer ')'
1500 			{ $$ = create_attr_rangeval('-', $2, $4); }
1501 	;
1502 
1503 string_list
1504 	:	string_list T_String
1505 		{
1506 			$$ = $1;
1507 			APPEND_G_FIFO($$, create_string_node($2));
1508 		}
1509 	|	T_String
1510 		{
1511 			$$ = NULL;
1512 			APPEND_G_FIFO($$, create_string_node($1));
1513 		}
1514 	;
1515 
1516 address_list
1517 	:	address_list address
1518 		{
1519 			$$ = $1;
1520 			APPEND_G_FIFO($$, $2);
1521 		}
1522 	|	address
1523 		{
1524 			$$ = NULL;
1525 			APPEND_G_FIFO($$, $1);
1526 		}
1527 	;
1528 
1529 boolean
1530 	:	T_Integer
1531 		{
1532 			if ($1 != 0 && $1 != 1) {
1533 				yyerror("Integer value is not boolean (0 or 1). Assuming 1");
1534 				$$ = 1;
1535 			} else {
1536 				$$ = $1;
1537 			}
1538 		}
1539 	|	T_True	{ $$ = 1; }
1540 	|	T_False	{ $$ = 0; }
1541 	;
1542 
1543 number
1544 	:	T_Integer	{ $$ = (double)$1; }
1545 	|	T_Double
1546 	;
1547 
1548 basedate
1549 	:	T_Basedate T_String
1550 			{ $$ = basedate_eval_string($2); YYFREE($2); }
1551 
1552 /* Simulator Configuration Commands
1553  * --------------------------------
1554  */
1555 
1556 simulate_command
1557 	:	sim_conf_start '{' sim_init_statement_list sim_server_list '}'
1558 		{
1559 			sim_node *sn;
1560 
1561 			sn =  create_sim_node($3, $4);
1562 			APPEND_G_FIFO(cfgt.sim_details, sn);
1563 
1564 			/* Revert from ; to \n for end-of-command */
1565 			old_config_style = 1;
1566 		}
1567 	;
1568 
1569 /* The following is a terrible hack to get the configuration file to
1570  * treat newlines as whitespace characters within the simulation.
1571  * This is needed because newlines are significant in the rest of the
1572  * configuration file.
1573  */
1574 sim_conf_start
1575 	:	T_Simulate { old_config_style = 0; }
1576 	;
1577 
1578 sim_init_statement_list
1579 	:	sim_init_statement_list sim_init_statement T_EOC
1580 		{
1581 			$$ = $1;
1582 			APPEND_G_FIFO($$, $2);
1583 		}
1584 	|	sim_init_statement T_EOC
1585 		{
1586 			$$ = NULL;
1587 			APPEND_G_FIFO($$, $1);
1588 		}
1589 	;
1590 
1591 sim_init_statement
1592 	:	sim_init_keyword '=' number
1593 			{ $$ = create_attr_dval($1, $3); }
1594 	;
1595 
1596 sim_init_keyword
1597 	:	T_Beep_Delay
1598 	|	T_Sim_Duration
1599 	;
1600 
1601 sim_server_list
1602 	:	sim_server_list sim_server
1603 		{
1604 			$$ = $1;
1605 			APPEND_G_FIFO($$, $2);
1606 		}
1607 	|	sim_server
1608 		{
1609 			$$ = NULL;
1610 			APPEND_G_FIFO($$, $1);
1611 		}
1612 	;
1613 
1614 sim_server
1615 	:	sim_server_name '{' sim_server_offset sim_act_list '}'
1616 			{ $$ = ONLY_SIM(create_sim_server($1, $3, $4)); }
1617 	;
1618 
1619 sim_server_offset
1620 	:	T_Server_Offset '=' number T_EOC
1621 			{ $$ = $3; }
1622 	;
1623 
1624 sim_server_name
1625 	:	T_Server '=' address
1626 			{ $$ = $3; }
1627 	;
1628 
1629 sim_act_list
1630 	:	sim_act_list sim_act
1631 		{
1632 			$$ = $1;
1633 			APPEND_G_FIFO($$, $2);
1634 		}
1635 	|	sim_act
1636 		{
1637 			$$ = NULL;
1638 			APPEND_G_FIFO($$, $1);
1639 		}
1640 	;
1641 
1642 sim_act
1643 	:	T_Duration '=' number '{' sim_act_stmt_list '}'
1644 			{ $$ = ONLY_SIM(create_sim_script_info($3, $5)); }
1645 	;
1646 
1647 sim_act_stmt_list
1648 	:	sim_act_stmt_list sim_act_stmt T_EOC
1649 		{
1650 			$$ = $1;
1651 			APPEND_G_FIFO($$, $2);
1652 		}
1653 	|	sim_act_stmt T_EOC
1654 		{
1655 			$$ = NULL;
1656 			APPEND_G_FIFO($$, $1);
1657 		}
1658 	;
1659 
1660 sim_act_stmt
1661 	:	sim_act_keyword '=' number
1662 			{ $$ = create_attr_dval($1, $3); }
1663 	;
1664 
1665 sim_act_keyword
1666 	:	T_Freq_Offset
1667 	|	T_Wander
1668 	|	T_Jitter
1669 	|	T_Prop_Delay
1670 	|	T_Proc_Delay
1671 	;
1672 
1673 %%
1674 
1675 void
1676 yyerror(
1677 	const char *msg
1678 	)
1679 {
1680 	int retval;
1681 	struct FILE_INFO * ip_ctx;
1682 
1683 	ip_ctx = lex_current();
1684 	ip_ctx->errpos = ip_ctx->tokpos;
1685 
1686 	msyslog(LOG_ERR, "line %d column %d %s",
1687 		ip_ctx->errpos.nline, ip_ctx->errpos.ncol, msg);
1688 	if (!lex_from_file()) {
1689 		/* Save the error message in the correct buffer */
1690 		retval = snprintf(remote_config.err_msg + remote_config.err_pos,
1691 				  MAXLINE - remote_config.err_pos,
1692 				  "column %d %s",
1693 				  ip_ctx->errpos.ncol, msg);
1694 
1695 		/* Increment the value of err_pos */
1696 		if (retval > 0)
1697 			remote_config.err_pos += retval;
1698 
1699 		/* Increment the number of errors */
1700 		++remote_config.no_errors;
1701 	}
1702 }
1703 
1704 
1705 /*
1706  * token_name - convert T_ token integers to text
1707  *		example: token_name(T_Server) returns "T_Server"
1708  */
1709 const char *
1710 token_name(
1711 	int token
1712 	)
1713 {
1714 	return yytname[YYTRANSLATE(token)];
1715 }
1716 
1717 
1718 /* Initial Testing function -- ignore */
1719 #if 0
1720 int main(int argc, char *argv[])
1721 {
1722 	ip_file = FOPEN(argv[1], "r");
1723 	if (!ip_file)
1724 		fprintf(stderr, "ERROR!! Could not open file: %s\n", argv[1]);
1725 	yyparse();
1726 	return 0;
1727 }
1728 #endif
1729 
1730