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