1 %{ 2 /* 3 * CDDL HEADER START 4 * 5 * The contents of this file are subject to the terms of the 6 * Common Development and Distribution License (the "License"). 7 * You may not use this file except in compliance with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 23 /* 24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 #pragma ident "%Z%%M% %I% %E% SMI" 29 30 #include <stdio.h> 31 32 #include "zonecfg.h" 33 34 static cmd_t *cmd = NULL; /* Command being processed */ 35 static complex_property_ptr_t complex = NULL; 36 static list_property_ptr_t new_list = NULL, tmp_list, last, 37 list[MAX_EQ_PROP_PAIRS]; 38 static property_value_t property[MAX_EQ_PROP_PAIRS]; 39 40 extern bool newline_terminated; 41 extern int num_prop_vals; /* # of property values */ 42 43 /* yacc externals */ 44 extern int yydebug; 45 extern void yyerror(char *s); 46 47 %} 48 49 %union { 50 int ival; 51 char *strval; 52 cmd_t *cmd; 53 complex_property_ptr_t complex; 54 list_property_ptr_t list; 55 } 56 57 %start commands 58 59 %token HELP CREATE EXPORT ADD DELETE REMOVE SELECT SET INFO CANCEL END VERIFY 60 %token COMMIT REVERT EXIT SEMICOLON TOKEN ZONENAME ZONEPATH AUTOBOOT POOL NET 61 %token FS IPD ATTR DEVICE RCTL SPECIAL RAW DIR OPTIONS TYPE ADDRESS PHYSICAL 62 %token NAME MATCH PRIV LIMIT ACTION VALUE EQUAL OPEN_SQ_BRACKET CLOSE_SQ_BRACKET 63 %token OPEN_PAREN CLOSE_PAREN COMMA DATASET LIMITPRIV BOOTARGS 64 65 %type <strval> TOKEN EQUAL OPEN_SQ_BRACKET CLOSE_SQ_BRACKET 66 property_value OPEN_PAREN CLOSE_PAREN COMMA simple_prop_val 67 %type <complex> complex_piece complex_prop_val 68 %type <ival> resource_type NET FS IPD DEVICE RCTL ATTR 69 %type <ival> property_name SPECIAL RAW DIR OPTIONS TYPE ADDRESS PHYSICAL NAME 70 MATCH ZONENAME ZONEPATH AUTOBOOT POOL LIMITPRIV BOOTARGS VALUE PRIV LIMIT 71 ACTION 72 %type <cmd> command 73 %type <cmd> add_command ADD 74 %type <cmd> cancel_command CANCEL 75 %type <cmd> commit_command COMMIT 76 %type <cmd> create_command CREATE 77 %type <cmd> delete_command DELETE 78 %type <cmd> end_command END 79 %type <cmd> exit_command EXIT 80 %type <cmd> export_command EXPORT 81 %type <cmd> help_command HELP 82 %type <cmd> info_command INFO 83 %type <cmd> remove_command REMOVE 84 %type <cmd> revert_command REVERT 85 %type <cmd> select_command SELECT 86 %type <cmd> set_command SET 87 %type <cmd> verify_command VERIFY 88 %type <cmd> terminator 89 90 %% 91 92 commands: command terminator 93 { 94 if ($1 != NULL) { 95 if ($1->cmd_handler != NULL) 96 $1->cmd_handler($1); 97 free_cmd($1); 98 bzero(list, sizeof (list_property_t)); 99 num_prop_vals = 0; 100 } 101 return (0); 102 } 103 | command error terminator 104 { 105 if ($1 != NULL) { 106 free_cmd($1); 107 bzero(list, sizeof (list_property_t)); 108 num_prop_vals = 0; 109 } 110 if (YYRECOVERING()) 111 YYABORT; 112 yyclearin; 113 yyerrok; 114 } 115 | error terminator 116 { 117 if (YYRECOVERING()) 118 YYABORT; 119 yyclearin; 120 yyerrok; 121 } 122 | terminator 123 { 124 return (0); 125 } 126 127 command: add_command 128 | cancel_command 129 | create_command 130 | commit_command 131 | delete_command 132 | end_command 133 | exit_command 134 | export_command 135 | help_command 136 | info_command 137 | remove_command 138 | revert_command 139 | select_command 140 | set_command 141 | verify_command 142 143 terminator: '\n' { newline_terminated = TRUE; } 144 | ';' { newline_terminated = FALSE; } 145 146 add_command: ADD 147 { 148 short_usage(CMD_ADD); 149 (void) fputs("\n", stderr); 150 usage(FALSE, HELP_RES_PROPS); 151 YYERROR; 152 } 153 | ADD TOKEN 154 { 155 if (($$ = alloc_cmd()) == NULL) 156 YYERROR; 157 cmd = $$; 158 $$->cmd_handler = &add_func; 159 $$->cmd_argc = 1; 160 $$->cmd_argv[0] = $2; 161 $$->cmd_argv[1] = NULL; 162 } 163 | ADD resource_type 164 { 165 if (($$ = alloc_cmd()) == NULL) 166 YYERROR; 167 cmd = $$; 168 $$->cmd_handler = &add_func; 169 $$->cmd_argc = 0; 170 $$->cmd_res_type = $2; 171 $$->cmd_prop_nv_pairs = 0; 172 } 173 | ADD property_name property_value 174 { 175 if (($$ = alloc_cmd()) == NULL) 176 YYERROR; 177 cmd = $$; 178 $$->cmd_handler = &add_func; 179 $$->cmd_argc = 0; 180 $$->cmd_prop_nv_pairs = 1; 181 $$->cmd_prop_name[0] = $2; 182 $$->cmd_property_ptr[0] = &property[0]; 183 } 184 185 cancel_command: CANCEL 186 { 187 if (($$ = alloc_cmd()) == NULL) 188 YYERROR; 189 cmd = $$; 190 $$->cmd_handler = &cancel_func; 191 $$->cmd_argc = 0; 192 $$->cmd_argv[0] = NULL; 193 } 194 | CANCEL TOKEN 195 { 196 if (($$ = alloc_cmd()) == NULL) 197 YYERROR; 198 cmd = $$; 199 $$->cmd_handler = &cancel_func; 200 $$->cmd_argc = 1; 201 $$->cmd_argv[0] = $2; 202 $$->cmd_argv[1] = NULL; 203 } 204 205 create_command: CREATE 206 { 207 if (($$ = alloc_cmd()) == NULL) 208 YYERROR; 209 cmd = $$; 210 $$->cmd_handler = &create_func; 211 $$->cmd_argc = 0; 212 $$->cmd_argv[0] = NULL; 213 } 214 | CREATE TOKEN 215 { 216 if (($$ = alloc_cmd()) == NULL) 217 YYERROR; 218 cmd = $$; 219 $$->cmd_handler = &create_func; 220 $$->cmd_argc = 1; 221 $$->cmd_argv[0] = $2; 222 $$->cmd_argv[1] = NULL; 223 } 224 | CREATE TOKEN TOKEN 225 { 226 if (($$ = alloc_cmd()) == NULL) 227 YYERROR; 228 cmd = $$; 229 $$->cmd_handler = &create_func; 230 $$->cmd_argc = 2; 231 $$->cmd_argv[0] = $2; 232 $$->cmd_argv[1] = $3; 233 $$->cmd_argv[2] = NULL; 234 } 235 | CREATE TOKEN TOKEN TOKEN 236 { 237 if (($$ = alloc_cmd()) == NULL) 238 YYERROR; 239 cmd = $$; 240 $$->cmd_handler = &create_func; 241 $$->cmd_argc = 3; 242 $$->cmd_argv[0] = $2; 243 $$->cmd_argv[1] = $3; 244 $$->cmd_argv[2] = $4; 245 $$->cmd_argv[3] = NULL; 246 } 247 248 commit_command: COMMIT 249 { 250 if (($$ = alloc_cmd()) == NULL) 251 YYERROR; 252 cmd = $$; 253 $$->cmd_handler = &commit_func; 254 $$->cmd_argc = 0; 255 $$->cmd_argv[0] = NULL; 256 } 257 | COMMIT TOKEN 258 { 259 if (($$ = alloc_cmd()) == NULL) 260 YYERROR; 261 cmd = $$; 262 $$->cmd_handler = &commit_func; 263 $$->cmd_argc = 1; 264 $$->cmd_argv[0] = $2; 265 $$->cmd_argv[1] = NULL; 266 } 267 268 delete_command: DELETE 269 { 270 if (($$ = alloc_cmd()) == NULL) 271 YYERROR; 272 cmd = $$; 273 $$->cmd_handler = &delete_func; 274 $$->cmd_argc = 0; 275 $$->cmd_argv[0] = NULL; 276 } 277 | DELETE TOKEN 278 { 279 if (($$ = alloc_cmd()) == NULL) 280 YYERROR; 281 cmd = $$; 282 $$->cmd_handler = &delete_func; 283 $$->cmd_argc = 1; 284 $$->cmd_argv[0] = $2; 285 $$->cmd_argv[1] = NULL; 286 } 287 288 end_command: END 289 { 290 if (($$ = alloc_cmd()) == NULL) 291 YYERROR; 292 cmd = $$; 293 $$->cmd_handler = &end_func; 294 $$->cmd_argc = 0; 295 $$->cmd_argv[0] = NULL; 296 } 297 | END TOKEN 298 { 299 if (($$ = alloc_cmd()) == NULL) 300 YYERROR; 301 cmd = $$; 302 $$->cmd_handler = &end_func; 303 $$->cmd_argc = 1; 304 $$->cmd_argv[0] = $2; 305 $$->cmd_argv[1] = NULL; 306 } 307 308 exit_command: EXIT 309 { 310 if (($$ = alloc_cmd()) == NULL) 311 YYERROR; 312 cmd = $$; 313 $$->cmd_handler = &exit_func; 314 $$->cmd_argc = 0; 315 $$->cmd_argv[0] = NULL; 316 } 317 | EXIT TOKEN 318 { 319 if (($$ = alloc_cmd()) == NULL) 320 YYERROR; 321 cmd = $$; 322 $$->cmd_handler = &exit_func; 323 $$->cmd_argc = 1; 324 $$->cmd_argv[0] = $2; 325 $$->cmd_argv[1] = NULL; 326 } 327 328 export_command: EXPORT 329 { 330 if (($$ = alloc_cmd()) == NULL) 331 YYERROR; 332 cmd = $$; 333 $$->cmd_handler = &export_func; 334 $$->cmd_argc = 0; 335 $$->cmd_argv[0] = NULL; 336 } 337 | EXPORT TOKEN 338 { 339 if (($$ = alloc_cmd()) == NULL) 340 YYERROR; 341 cmd = $$; 342 $$->cmd_handler = &export_func; 343 $$->cmd_argc = 1; 344 $$->cmd_argv[0] = $2; 345 $$->cmd_argv[1] = NULL; 346 } 347 | EXPORT TOKEN TOKEN 348 { 349 if (($$ = alloc_cmd()) == NULL) 350 YYERROR; 351 cmd = $$; 352 $$->cmd_handler = &export_func; 353 $$->cmd_argc = 2; 354 $$->cmd_argv[0] = $2; 355 $$->cmd_argv[1] = $3; 356 $$->cmd_argv[2] = NULL; 357 } 358 359 help_command: HELP 360 { 361 if (($$ = alloc_cmd()) == NULL) 362 YYERROR; 363 cmd = $$; 364 $$->cmd_handler = &help_func; 365 $$->cmd_argc = 0; 366 $$->cmd_argv[0] = NULL; 367 } 368 | HELP TOKEN 369 { 370 if (($$ = alloc_cmd()) == NULL) 371 YYERROR; 372 cmd = $$; 373 $$->cmd_handler = &help_func; 374 $$->cmd_argc = 1; 375 $$->cmd_argv[0] = $2; 376 $$->cmd_argv[1] = NULL; 377 } 378 379 info_command: INFO 380 { 381 if (($$ = alloc_cmd()) == NULL) 382 YYERROR; 383 cmd = $$; 384 $$->cmd_handler = &info_func; 385 $$->cmd_res_type = RT_UNKNOWN; 386 $$->cmd_prop_nv_pairs = 0; 387 } 388 | INFO TOKEN 389 { 390 short_usage(CMD_INFO); 391 (void) fputs("\n", stderr); 392 usage(FALSE, HELP_RES_PROPS); 393 free($2); 394 YYERROR; 395 } 396 | INFO resource_type 397 { 398 if (($$ = alloc_cmd()) == NULL) 399 YYERROR; 400 cmd = $$; 401 $$->cmd_handler = &info_func; 402 $$->cmd_res_type = $2; 403 $$->cmd_prop_nv_pairs = 0; 404 } 405 | INFO ZONENAME 406 { 407 if (($$ = alloc_cmd()) == NULL) 408 YYERROR; 409 cmd = $$; 410 $$->cmd_handler = &info_func; 411 $$->cmd_res_type = RT_ZONENAME; 412 $$->cmd_prop_nv_pairs = 0; 413 } 414 | INFO ZONEPATH 415 { 416 if (($$ = alloc_cmd()) == NULL) 417 YYERROR; 418 cmd = $$; 419 $$->cmd_handler = &info_func; 420 $$->cmd_res_type = RT_ZONEPATH; 421 $$->cmd_prop_nv_pairs = 0; 422 } 423 | INFO AUTOBOOT 424 { 425 if (($$ = alloc_cmd()) == NULL) 426 YYERROR; 427 cmd = $$; 428 $$->cmd_handler = &info_func; 429 $$->cmd_res_type = RT_AUTOBOOT; 430 $$->cmd_prop_nv_pairs = 0; 431 } 432 | INFO POOL 433 { 434 if (($$ = alloc_cmd()) == NULL) 435 YYERROR; 436 cmd = $$; 437 $$->cmd_handler = &info_func; 438 $$->cmd_res_type = RT_POOL; 439 $$->cmd_prop_nv_pairs = 0; 440 } 441 | INFO LIMITPRIV 442 { 443 if (($$ = alloc_cmd()) == NULL) 444 YYERROR; 445 cmd = $$; 446 $$->cmd_handler = &info_func; 447 $$->cmd_res_type = RT_LIMITPRIV; 448 $$->cmd_prop_nv_pairs = 0; 449 } 450 | INFO BOOTARGS 451 { 452 if (($$ = alloc_cmd()) == NULL) 453 YYERROR; 454 cmd = $$; 455 $$->cmd_handler = &info_func; 456 $$->cmd_res_type = RT_BOOTARGS; 457 $$->cmd_prop_nv_pairs = 0; 458 } 459 | INFO resource_type property_name EQUAL property_value 460 { 461 if (($$ = alloc_cmd()) == NULL) 462 YYERROR; 463 cmd = $$; 464 $$->cmd_handler = &info_func; 465 $$->cmd_res_type = $2; 466 $$->cmd_prop_nv_pairs = 1; 467 $$->cmd_prop_name[0] = $3; 468 $$->cmd_property_ptr[0] = &property[0]; 469 } 470 | INFO resource_type property_name EQUAL property_value property_name EQUAL property_value 471 { 472 if (($$ = alloc_cmd()) == NULL) 473 YYERROR; 474 cmd = $$; 475 $$->cmd_handler = &info_func; 476 $$->cmd_res_type = $2; 477 $$->cmd_prop_nv_pairs = 2; 478 $$->cmd_prop_name[0] = $3; 479 $$->cmd_property_ptr[0] = &property[0]; 480 $$->cmd_prop_name[1] = $6; 481 $$->cmd_property_ptr[1] = &property[1]; 482 } 483 | INFO resource_type property_name EQUAL property_value property_name EQUAL property_value property_name EQUAL property_value 484 { 485 if (($$ = alloc_cmd()) == NULL) 486 YYERROR; 487 cmd = $$; 488 $$->cmd_handler = &info_func; 489 $$->cmd_res_type = $2; 490 $$->cmd_prop_nv_pairs = 3; 491 $$->cmd_prop_name[0] = $3; 492 $$->cmd_property_ptr[0] = &property[0]; 493 $$->cmd_prop_name[1] = $6; 494 $$->cmd_property_ptr[1] = &property[1]; 495 $$->cmd_prop_name[2] = $9; 496 $$->cmd_property_ptr[2] = &property[2]; 497 } 498 499 remove_command: REMOVE 500 { 501 short_usage(CMD_REMOVE); 502 (void) fputs("\n", stderr); 503 usage(FALSE, HELP_RES_PROPS); 504 YYERROR; 505 } 506 | REMOVE resource_type 507 { 508 short_usage(CMD_REMOVE); 509 YYERROR; 510 } 511 | REMOVE property_name property_value 512 { 513 if (($$ = alloc_cmd()) == NULL) 514 YYERROR; 515 cmd = $$; 516 $$->cmd_handler = &remove_func; 517 $$->cmd_prop_nv_pairs = 1; 518 $$->cmd_prop_name[0] = $2; 519 $$->cmd_property_ptr[0] = &property[0]; 520 } 521 | REMOVE resource_type property_name EQUAL property_value 522 { 523 if (($$ = alloc_cmd()) == NULL) 524 YYERROR; 525 cmd = $$; 526 $$->cmd_handler = &remove_func; 527 $$->cmd_res_type = $2; 528 $$->cmd_prop_nv_pairs = 1; 529 $$->cmd_prop_name[0] = $3; 530 $$->cmd_property_ptr[0] = &property[0]; 531 } 532 | REMOVE resource_type property_name EQUAL property_value property_name EQUAL property_value 533 { 534 if (($$ = alloc_cmd()) == NULL) 535 YYERROR; 536 cmd = $$; 537 $$->cmd_handler = &remove_func; 538 $$->cmd_res_type = $2; 539 $$->cmd_prop_nv_pairs = 2; 540 $$->cmd_prop_name[0] = $3; 541 $$->cmd_property_ptr[0] = &property[0]; 542 $$->cmd_prop_name[1] = $6; 543 $$->cmd_property_ptr[1] = &property[1]; 544 } 545 | REMOVE resource_type property_name EQUAL property_value property_name EQUAL property_value property_name EQUAL property_value 546 { 547 if (($$ = alloc_cmd()) == NULL) 548 YYERROR; 549 cmd = $$; 550 $$->cmd_handler = &remove_func; 551 $$->cmd_res_type = $2; 552 $$->cmd_prop_nv_pairs = 3; 553 $$->cmd_prop_name[0] = $3; 554 $$->cmd_property_ptr[0] = &property[0]; 555 $$->cmd_prop_name[1] = $6; 556 $$->cmd_property_ptr[1] = &property[1]; 557 $$->cmd_prop_name[2] = $9; 558 $$->cmd_property_ptr[2] = &property[2]; 559 } 560 561 revert_command: REVERT 562 { 563 if (($$ = alloc_cmd()) == NULL) 564 YYERROR; 565 cmd = $$; 566 $$->cmd_handler = &revert_func; 567 $$->cmd_argc = 0; 568 $$->cmd_argv[0] = NULL; 569 } 570 | REVERT TOKEN 571 { 572 if (($$ = alloc_cmd()) == NULL) 573 YYERROR; 574 cmd = $$; 575 $$->cmd_handler = &revert_func; 576 $$->cmd_argc = 1; 577 $$->cmd_argv[0] = $2; 578 $$->cmd_argv[1] = NULL; 579 } 580 581 select_command: SELECT 582 { 583 short_usage(CMD_SELECT); 584 (void) fputs("\n", stderr); 585 usage(FALSE, HELP_RES_PROPS); 586 YYERROR; 587 } 588 | SELECT resource_type 589 { 590 short_usage(CMD_SELECT); 591 YYERROR; 592 } 593 | SELECT resource_type property_name EQUAL property_value 594 { 595 if (($$ = alloc_cmd()) == NULL) 596 YYERROR; 597 cmd = $$; 598 $$->cmd_handler = &select_func; 599 $$->cmd_res_type = $2; 600 $$->cmd_prop_nv_pairs = 1; 601 $$->cmd_prop_name[0] = $3; 602 $$->cmd_property_ptr[0] = &property[0]; 603 } 604 | SELECT resource_type property_name EQUAL property_value property_name EQUAL property_value 605 { 606 if (($$ = alloc_cmd()) == NULL) 607 YYERROR; 608 cmd = $$; 609 $$->cmd_handler = &select_func; 610 $$->cmd_res_type = $2; 611 $$->cmd_prop_nv_pairs = 2; 612 $$->cmd_prop_name[0] = $3; 613 $$->cmd_property_ptr[0] = &property[0]; 614 $$->cmd_prop_name[1] = $6; 615 $$->cmd_property_ptr[1] = &property[1]; 616 } 617 | SELECT resource_type property_name EQUAL property_value property_name EQUAL property_value property_name EQUAL property_value 618 { 619 if (($$ = alloc_cmd()) == NULL) 620 YYERROR; 621 cmd = $$; 622 $$->cmd_handler = &select_func; 623 $$->cmd_res_type = $2; 624 $$->cmd_prop_nv_pairs = 3; 625 $$->cmd_prop_name[0] = $3; 626 $$->cmd_property_ptr[0] = &property[0]; 627 $$->cmd_prop_name[1] = $6; 628 $$->cmd_property_ptr[1] = &property[1]; 629 $$->cmd_prop_name[2] = $9; 630 $$->cmd_property_ptr[2] = &property[2]; 631 } 632 633 set_command: SET 634 { 635 short_usage(CMD_SET); 636 (void) fputs("\n", stderr); 637 usage(FALSE, HELP_PROPS); 638 YYERROR; 639 } 640 | SET property_name EQUAL OPEN_SQ_BRACKET CLOSE_SQ_BRACKET 641 { 642 if (($$ = alloc_cmd()) == NULL) 643 YYERROR; 644 cmd = $$; 645 $$->cmd_handler = &set_func; 646 $$->cmd_prop_nv_pairs = 0; 647 $$->cmd_prop_name[0] = $2; 648 property[0].pv_type = PROP_VAL_LIST; 649 property[0].pv_list = NULL; 650 $$->cmd_property_ptr[0] = &property[0]; 651 } 652 | SET property_name EQUAL property_value 653 { 654 if (($$ = alloc_cmd()) == NULL) 655 YYERROR; 656 cmd = $$; 657 $$->cmd_handler = &set_func; 658 $$->cmd_prop_nv_pairs = 1; 659 $$->cmd_prop_name[0] = $2; 660 $$->cmd_property_ptr[0] = &property[0]; 661 } 662 | SET TOKEN ZONEPATH EQUAL property_value 663 { 664 if (($$ = alloc_cmd()) == NULL) 665 YYERROR; 666 cmd = $$; 667 $$->cmd_argc = 1; 668 $$->cmd_argv[0] = $2; 669 $$->cmd_argv[1] = NULL; 670 $$->cmd_handler = &set_func; 671 $$->cmd_prop_nv_pairs = 1; 672 $$->cmd_prop_name[0] = PT_ZONEPATH; 673 $$->cmd_property_ptr[0] = &property[0]; 674 } 675 676 verify_command: VERIFY 677 { 678 if (($$ = alloc_cmd()) == NULL) 679 YYERROR; 680 cmd = $$; 681 $$->cmd_handler = &verify_func; 682 $$->cmd_argc = 0; 683 $$->cmd_argv[0] = NULL; 684 } 685 | VERIFY TOKEN 686 { 687 if (($$ = alloc_cmd()) == NULL) 688 YYERROR; 689 cmd = $$; 690 $$->cmd_handler = &verify_func; 691 $$->cmd_argc = 1; 692 $$->cmd_argv[0] = $2; 693 $$->cmd_argv[1] = NULL; 694 } 695 696 resource_type: NET { $$ = RT_NET; } 697 | FS { $$ = RT_FS; } 698 | IPD { $$ = RT_IPD; } 699 | DEVICE { $$ = RT_DEVICE; } 700 | RCTL { $$ = RT_RCTL; } 701 | ATTR { $$ = RT_ATTR; } 702 | DATASET { $$ = RT_DATASET; } 703 704 property_name: SPECIAL { $$ = PT_SPECIAL; } 705 | RAW { $$ = PT_RAW; } 706 | DIR { $$ = PT_DIR; } 707 | TYPE { $$ = PT_TYPE; } 708 | OPTIONS { $$ = PT_OPTIONS; } 709 | ZONENAME { $$ = PT_ZONENAME; } 710 | ZONEPATH { $$ = PT_ZONEPATH; } 711 | AUTOBOOT { $$ = PT_AUTOBOOT; } 712 | POOL { $$ = PT_POOL; } 713 | LIMITPRIV { $$ = PT_LIMITPRIV; } 714 | BOOTARGS { $$ = PT_BOOTARGS; } 715 | ADDRESS { $$ = PT_ADDRESS; } 716 | PHYSICAL { $$ = PT_PHYSICAL; } 717 | NAME { $$ = PT_NAME; } 718 | VALUE { $$ = PT_VALUE; } 719 | MATCH { $$ = PT_MATCH; } 720 | PRIV { $$ = PT_PRIV; } 721 | LIMIT { $$ = PT_LIMIT; } 722 | ACTION { $$ = PT_ACTION; } 723 724 /* 725 * The grammar builds data structures from the bottom up. Thus various 726 * strings are lexed into TOKENs or commands or resource or property values. 727 * Below is where the resource and property values are built up into more 728 * complex data structures. 729 * 730 * There are three kinds of properties: simple (single valued), complex 731 * (one or more name=value pairs) and list (concatenation of one or more 732 * simple or complex properties). 733 * 734 * So the property structure has a type which is one of these, and the 735 * corresponding _simple, _complex or _list is set to the corresponding 736 * lower-level data structure. 737 */ 738 739 property_value: simple_prop_val 740 { 741 property[num_prop_vals].pv_type = PROP_VAL_SIMPLE; 742 property[num_prop_vals].pv_simple = $1; 743 if (list[num_prop_vals] != NULL) { 744 free_outer_list(list[num_prop_vals]); 745 list[num_prop_vals] = NULL; 746 } 747 num_prop_vals++; 748 } 749 | complex_prop_val 750 { 751 property[num_prop_vals].pv_type = PROP_VAL_COMPLEX; 752 property[num_prop_vals].pv_complex = complex; 753 if (list[num_prop_vals] != NULL) { 754 free_outer_list(list[num_prop_vals]); 755 list[num_prop_vals] = NULL; 756 } 757 num_prop_vals++; 758 } 759 | list_prop_val 760 { 761 property[num_prop_vals].pv_type = PROP_VAL_LIST; 762 property[num_prop_vals].pv_list = list[num_prop_vals]; 763 num_prop_vals++; 764 } 765 766 /* 767 * One level lower, lists are made up of simple or complex values, so 768 * simple_prop_val and complex_prop_val fill in a list structure and 769 * insert it into the linked list which is built up. And because 770 * complex properties can have multiple name=value pairs, we keep 771 * track of them in another linked list. 772 * 773 * The complex and list structures for the linked lists are allocated 774 * below, and freed by recursive functions which are ultimately called 775 * by free_cmd(), which is called from the top-most "commands" part of 776 * the grammar. 777 */ 778 779 simple_prop_val: TOKEN 780 { 781 if ((new_list = alloc_list()) == NULL) 782 YYERROR; 783 new_list->lp_simple = $1; 784 new_list->lp_complex = NULL; 785 new_list->lp_next = NULL; 786 if (list[num_prop_vals] == NULL) { 787 list[num_prop_vals] = new_list; 788 } else { 789 for (tmp_list = list[num_prop_vals]; tmp_list != NULL; 790 tmp_list = tmp_list->lp_next) 791 last = tmp_list; 792 last->lp_next = new_list; 793 } 794 } 795 796 complex_prop_val: OPEN_PAREN complex_piece CLOSE_PAREN 797 { 798 if ((new_list = alloc_list()) == NULL) 799 YYERROR; 800 new_list->lp_simple = NULL; 801 new_list->lp_complex = complex; 802 new_list->lp_next = NULL; 803 if (list[num_prop_vals] == NULL) { 804 list[num_prop_vals] = new_list; 805 } else { 806 for (tmp_list = list[num_prop_vals]; tmp_list != NULL; 807 tmp_list = tmp_list->lp_next) 808 last = tmp_list; 809 last->lp_next = new_list; 810 } 811 } 812 813 complex_piece: property_name EQUAL TOKEN 814 { 815 if (($$ = alloc_complex()) == NULL) 816 YYERROR; 817 $$->cp_type = $1; 818 $$->cp_value = $3; 819 $$->cp_next = NULL; 820 complex = $$; 821 } 822 | property_name EQUAL TOKEN COMMA complex_piece 823 { 824 if (($$ = alloc_complex()) == NULL) 825 YYERROR; 826 $$->cp_type = $1; 827 $$->cp_value = $3; 828 $$->cp_next = complex; 829 complex = $$; 830 } 831 832 list_piece: simple_prop_val 833 | complex_prop_val 834 | simple_prop_val COMMA list_piece 835 | complex_prop_val COMMA list_piece 836 837 list_prop_val: OPEN_SQ_BRACKET list_piece CLOSE_SQ_BRACKET 838 %% 839