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