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 (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 25 */ 26 27 /* 28 * This file defines zonecfg(8)'s grammar. 29 * 30 * Reduction rules that consume TOKENs must invoke claim_token() immediately 31 * before freeing the TOKENs or adding them to data structures (e.g., cmd) that 32 * will be cleaned up when the parser finishes or encounters errors. 33 */ 34 35 #include <stdio.h> 36 #include <strings.h> 37 38 #include "zonecfg.h" 39 40 static cmd_t *cmd = NULL; /* Command being processed */ 41 static complex_property_ptr_t complex = NULL; 42 static list_property_ptr_t new_list = NULL, tmp_list, last, 43 list[MAX_EQ_PROP_PAIRS]; 44 static property_value_t property[MAX_EQ_PROP_PAIRS]; 45 46 extern boolean_t newline_terminated; 47 extern int num_prop_vals; /* # of property values */ 48 49 /* yacc externals */ 50 extern int yydebug; 51 extern void yyerror(char *s); 52 53 /* 54 * This function is used by the simple_prop_val reduction rules to set up 55 * a list_property_ptr_t and adjust the above global variables appropriately. 56 * Note that this function duplicates the specified string and makes 57 * the new list's lp_simple field point to the duplicate. This function does 58 * not free the original string. 59 * 60 * This function returns a pointer to the duplicated string or NULL if an error 61 * occurred. The simple_prop_val reduction rules that invoke this function 62 * should set $$ to the returned pointer. 63 */ 64 static char * 65 simple_prop_val_func(const char *str) 66 { 67 char *retstr; 68 69 if ((new_list = alloc_list()) == NULL) 70 return (NULL); 71 if ((retstr = strdup(str)) == NULL) { 72 free_list(new_list); 73 return (NULL); 74 } 75 new_list->lp_simple = retstr; 76 new_list->lp_complex = NULL; 77 new_list->lp_next = NULL; 78 if (list[num_prop_vals] == NULL) { 79 list[num_prop_vals] = new_list; 80 } else { 81 for (tmp_list = list[num_prop_vals]; tmp_list != NULL; 82 tmp_list = tmp_list->lp_next) 83 last = tmp_list; 84 last->lp_next = new_list; 85 } 86 return (retstr); 87 } 88 89 /* 90 * This function is used by the complex_piece reduction rules to set up a 91 * complex_property_prt_t and adjust the above global variables appropriately. 92 * Note that this function duplicates the specified string and makes the new 93 * complex_property_ptr_t's cp_value field point to the duplicate. It also sets 94 * the complex_property_ptr_t's cp_type field to cp_type and its cp_next field 95 * to cp_next. This function does not free the original string. 96 * 97 * This function returns a pointer to the complex_property_t created for the 98 * complex_piece or NULL if an error occurred. The complex_piece reduction 99 * rules that invoke this function should set $$ to the returned pointer. 100 */ 101 static complex_property_ptr_t 102 complex_piece_func(int cp_type, const char *str, complex_property_ptr_t cp_next) 103 { 104 complex_property_ptr_t retval; 105 106 if ((retval = alloc_complex()) == NULL) 107 return (NULL); 108 if ((retval->cp_value = strdup(str)) == NULL) { 109 free_complex(retval); 110 return (NULL); 111 } 112 retval->cp_type = cp_type; 113 retval->cp_next = cp_next; 114 complex = retval; 115 return (retval); 116 } 117 118 119 %} 120 121 %union { 122 int ival; 123 char *strval; 124 cmd_t *cmd; 125 complex_property_ptr_t complex; 126 list_property_ptr_t list; 127 } 128 129 %start commands 130 131 %token HELP CREATE EXPORT ADD DELETE REMOVE SELECT SET INFO CANCEL END VERIFY 132 %token COMMIT REVERT EXIT SEMICOLON TOKEN ZONENAME ZONEPATH AUTOBOOT POOL NET 133 %token FS ATTR DEVICE RCTL SPECIAL RAW DIR OPTIONS TYPE ADDRESS PHYSICAL 134 %token IPTYPE HOSTID FS_ALLOWED ALLOWED_ADDRESS 135 %token NAME MATCH PRIV LIMIT ACTION VALUE EQUAL OPEN_SQ_BRACKET CLOSE_SQ_BRACKET 136 %token OPEN_PAREN CLOSE_PAREN COMMA DATASET LIMITPRIV BOOTARGS BRAND PSET PCAP 137 %token MCAP NCPUS IMPORTANCE SHARES MAXLWPS MAXSHMMEM MAXSHMIDS MAXMSGIDS 138 %token MAXSEMIDS LOCKED SWAP SCHED CLEAR DEFROUTER ADMIN SECFLAGS USER AUTHS MAXPROCS 139 %token DEFAULT UPPER LOWER 140 141 %type <strval> TOKEN EQUAL OPEN_SQ_BRACKET CLOSE_SQ_BRACKET 142 property_value OPEN_PAREN CLOSE_PAREN COMMA simple_prop_val 143 %type <complex> complex_piece complex_prop_val 144 %type <ival> resource_type NET FS DEVICE RCTL ATTR DATASET PSET PCAP MCAP 145 ADMIN SECFLAGS 146 %type <ival> property_name SPECIAL RAW DIR OPTIONS TYPE ADDRESS PHYSICAL NAME 147 MATCH ZONENAME ZONEPATH AUTOBOOT POOL LIMITPRIV BOOTARGS VALUE PRIV LIMIT 148 ACTION BRAND SCHED IPTYPE DEFROUTER HOSTID USER AUTHS FS_ALLOWED 149 ALLOWED_ADDRESS DEFAULT UPPER LOWER 150 %type <cmd> command 151 %type <cmd> add_command ADD 152 %type <cmd> cancel_command CANCEL 153 %type <cmd> commit_command COMMIT 154 %type <cmd> create_command CREATE 155 %type <cmd> delete_command DELETE 156 %type <cmd> end_command END 157 %type <cmd> exit_command EXIT 158 %type <cmd> export_command EXPORT 159 %type <cmd> help_command HELP 160 %type <cmd> info_command INFO 161 %type <cmd> remove_command REMOVE 162 %type <cmd> revert_command REVERT 163 %type <cmd> select_command SELECT 164 %type <cmd> set_command SET 165 %type <cmd> clear_command CLEAR 166 %type <cmd> verify_command VERIFY 167 %type <cmd> terminator 168 169 %% 170 171 /* 172 * NOTE: Each commands reduction rule must invoke assert_no_unclaimed_tokens() 173 * before it completes if it isn't processing an error. This ensures that 174 * reduction rules properly consume TOKENs. 175 */ 176 commands: command terminator 177 { 178 if ($1 != NULL) { 179 if ($1->cmd_handler != NULL) 180 $1->cmd_handler($1); 181 free_cmd($1); 182 bzero(list, sizeof (list_property_t)); 183 num_prop_vals = 0; 184 } 185 assert_no_unclaimed_tokens(); 186 return (0); 187 } 188 | command error terminator 189 { 190 if ($1 != NULL) { 191 free_cmd($1); 192 bzero(list, sizeof (list_property_t)); 193 num_prop_vals = 0; 194 } 195 if (YYRECOVERING()) 196 YYABORT; 197 yyclearin; 198 yyerrok; 199 } 200 | error terminator 201 { 202 if (YYRECOVERING()) 203 YYABORT; 204 yyclearin; 205 yyerrok; 206 } 207 | terminator 208 { 209 assert_no_unclaimed_tokens(); 210 return (0); 211 } 212 213 command: add_command 214 | cancel_command 215 | clear_command 216 | create_command 217 | commit_command 218 | delete_command 219 | end_command 220 | exit_command 221 | export_command 222 | help_command 223 | info_command 224 | remove_command 225 | revert_command 226 | select_command 227 | set_command 228 | verify_command 229 230 terminator: '\n' { newline_terminated = B_TRUE; } 231 | ';' { newline_terminated = B_FALSE; } 232 233 add_command: ADD 234 { 235 short_usage(CMD_ADD); 236 (void) fputs("\n", stderr); 237 usage(B_FALSE, HELP_RES_PROPS); 238 YYERROR; 239 } 240 | ADD TOKEN 241 { 242 if (($$ = alloc_cmd()) == NULL) 243 YYERROR; 244 cmd = $$; 245 $$->cmd_handler = &add_func; 246 $$->cmd_argc = 1; 247 $$->cmd_argv[0] = claim_token($2); 248 $$->cmd_argv[1] = NULL; 249 } 250 | ADD resource_type 251 { 252 if (($$ = alloc_cmd()) == NULL) 253 YYERROR; 254 cmd = $$; 255 $$->cmd_handler = &add_func; 256 $$->cmd_argc = 0; 257 $$->cmd_res_type = $2; 258 $$->cmd_prop_nv_pairs = 0; 259 } 260 | ADD property_name property_value 261 { 262 if (($$ = alloc_cmd()) == NULL) 263 YYERROR; 264 cmd = $$; 265 $$->cmd_handler = &add_func; 266 $$->cmd_argc = 0; 267 $$->cmd_prop_nv_pairs = 1; 268 $$->cmd_prop_name[0] = $2; 269 $$->cmd_property_ptr[0] = &property[0]; 270 } 271 272 cancel_command: CANCEL 273 { 274 if (($$ = alloc_cmd()) == NULL) 275 YYERROR; 276 cmd = $$; 277 $$->cmd_handler = &cancel_func; 278 $$->cmd_argc = 0; 279 $$->cmd_argv[0] = NULL; 280 } 281 | CANCEL TOKEN 282 { 283 if (($$ = alloc_cmd()) == NULL) 284 YYERROR; 285 cmd = $$; 286 $$->cmd_handler = &cancel_func; 287 $$->cmd_argc = 1; 288 $$->cmd_argv[0] = claim_token($2); 289 $$->cmd_argv[1] = NULL; 290 } 291 292 create_command: CREATE 293 { 294 if (($$ = alloc_cmd()) == NULL) 295 YYERROR; 296 cmd = $$; 297 $$->cmd_handler = &create_func; 298 $$->cmd_argc = 0; 299 $$->cmd_argv[0] = NULL; 300 } 301 | CREATE TOKEN 302 { 303 if (($$ = alloc_cmd()) == NULL) 304 YYERROR; 305 cmd = $$; 306 $$->cmd_handler = &create_func; 307 $$->cmd_argc = 1; 308 $$->cmd_argv[0] = claim_token($2); 309 $$->cmd_argv[1] = NULL; 310 } 311 | CREATE TOKEN TOKEN 312 { 313 if (($$ = alloc_cmd()) == NULL) 314 YYERROR; 315 cmd = $$; 316 $$->cmd_handler = &create_func; 317 $$->cmd_argc = 2; 318 $$->cmd_argv[0] = claim_token($2); 319 $$->cmd_argv[1] = claim_token($3); 320 $$->cmd_argv[2] = NULL; 321 } 322 | CREATE TOKEN TOKEN TOKEN 323 { 324 if (($$ = alloc_cmd()) == NULL) 325 YYERROR; 326 cmd = $$; 327 $$->cmd_handler = &create_func; 328 $$->cmd_argc = 3; 329 $$->cmd_argv[0] = claim_token($2); 330 $$->cmd_argv[1] = claim_token($3); 331 $$->cmd_argv[2] = claim_token($4); 332 $$->cmd_argv[3] = NULL; 333 } 334 335 commit_command: COMMIT 336 { 337 if (($$ = alloc_cmd()) == NULL) 338 YYERROR; 339 cmd = $$; 340 $$->cmd_handler = &commit_func; 341 $$->cmd_argc = 0; 342 $$->cmd_argv[0] = NULL; 343 } 344 | COMMIT TOKEN 345 { 346 if (($$ = alloc_cmd()) == NULL) 347 YYERROR; 348 cmd = $$; 349 $$->cmd_handler = &commit_func; 350 $$->cmd_argc = 1; 351 $$->cmd_argv[0] = claim_token($2); 352 $$->cmd_argv[1] = NULL; 353 } 354 355 delete_command: DELETE 356 { 357 if (($$ = alloc_cmd()) == NULL) 358 YYERROR; 359 cmd = $$; 360 $$->cmd_handler = &delete_func; 361 $$->cmd_argc = 0; 362 $$->cmd_argv[0] = NULL; 363 } 364 | DELETE TOKEN 365 { 366 if (($$ = alloc_cmd()) == NULL) 367 YYERROR; 368 cmd = $$; 369 $$->cmd_handler = &delete_func; 370 $$->cmd_argc = 1; 371 $$->cmd_argv[0] = claim_token($2); 372 $$->cmd_argv[1] = NULL; 373 } 374 375 end_command: END 376 { 377 if (($$ = alloc_cmd()) == NULL) 378 YYERROR; 379 cmd = $$; 380 $$->cmd_handler = &end_func; 381 $$->cmd_argc = 0; 382 $$->cmd_argv[0] = NULL; 383 } 384 | END TOKEN 385 { 386 if (($$ = alloc_cmd()) == NULL) 387 YYERROR; 388 cmd = $$; 389 $$->cmd_handler = &end_func; 390 $$->cmd_argc = 1; 391 $$->cmd_argv[0] = claim_token($2); 392 $$->cmd_argv[1] = NULL; 393 } 394 395 exit_command: EXIT 396 { 397 if (($$ = alloc_cmd()) == NULL) 398 YYERROR; 399 cmd = $$; 400 $$->cmd_handler = &exit_func; 401 $$->cmd_argc = 0; 402 $$->cmd_argv[0] = NULL; 403 } 404 | EXIT TOKEN 405 { 406 if (($$ = alloc_cmd()) == NULL) 407 YYERROR; 408 cmd = $$; 409 $$->cmd_handler = &exit_func; 410 $$->cmd_argc = 1; 411 $$->cmd_argv[0] = claim_token($2); 412 $$->cmd_argv[1] = NULL; 413 } 414 415 export_command: EXPORT 416 { 417 if (($$ = alloc_cmd()) == NULL) 418 YYERROR; 419 cmd = $$; 420 $$->cmd_handler = &export_func; 421 $$->cmd_argc = 0; 422 $$->cmd_argv[0] = NULL; 423 } 424 | EXPORT TOKEN 425 { 426 if (($$ = alloc_cmd()) == NULL) 427 YYERROR; 428 cmd = $$; 429 $$->cmd_handler = &export_func; 430 $$->cmd_argc = 1; 431 $$->cmd_argv[0] = claim_token($2); 432 $$->cmd_argv[1] = NULL; 433 } 434 | EXPORT TOKEN TOKEN 435 { 436 if (($$ = alloc_cmd()) == NULL) 437 YYERROR; 438 cmd = $$; 439 $$->cmd_handler = &export_func; 440 $$->cmd_argc = 2; 441 $$->cmd_argv[0] = claim_token($2); 442 $$->cmd_argv[1] = claim_token($3); 443 $$->cmd_argv[2] = NULL; 444 } 445 446 help_command: HELP 447 { 448 if (($$ = alloc_cmd()) == NULL) 449 YYERROR; 450 cmd = $$; 451 $$->cmd_handler = &help_func; 452 $$->cmd_argc = 0; 453 $$->cmd_argv[0] = NULL; 454 } 455 | HELP TOKEN 456 { 457 if (($$ = alloc_cmd()) == NULL) 458 YYERROR; 459 cmd = $$; 460 $$->cmd_handler = &help_func; 461 $$->cmd_argc = 1; 462 $$->cmd_argv[0] = claim_token($2); 463 $$->cmd_argv[1] = NULL; 464 } 465 466 info_command: INFO 467 { 468 if (($$ = alloc_cmd()) == NULL) 469 YYERROR; 470 cmd = $$; 471 $$->cmd_handler = &info_func; 472 $$->cmd_res_type = RT_UNKNOWN; 473 $$->cmd_prop_nv_pairs = 0; 474 } 475 | INFO TOKEN 476 { 477 short_usage(CMD_INFO); 478 (void) fputs("\n", stderr); 479 usage(B_FALSE, HELP_RES_PROPS); 480 free(claim_token($2)); 481 YYERROR; 482 } 483 | INFO resource_type 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 = 0; 491 } 492 | INFO ZONENAME 493 { 494 if (($$ = alloc_cmd()) == NULL) 495 YYERROR; 496 cmd = $$; 497 $$->cmd_handler = &info_func; 498 $$->cmd_res_type = RT_ZONENAME; 499 $$->cmd_prop_nv_pairs = 0; 500 } 501 | INFO ZONEPATH 502 { 503 if (($$ = alloc_cmd()) == NULL) 504 YYERROR; 505 cmd = $$; 506 $$->cmd_handler = &info_func; 507 $$->cmd_res_type = RT_ZONEPATH; 508 $$->cmd_prop_nv_pairs = 0; 509 } 510 | INFO BRAND 511 { 512 if (($$ = alloc_cmd()) == NULL) 513 YYERROR; 514 cmd = $$; 515 $$->cmd_handler = &info_func; 516 $$->cmd_res_type = RT_BRAND; 517 $$->cmd_prop_nv_pairs = 0; 518 } 519 | INFO AUTOBOOT 520 { 521 if (($$ = alloc_cmd()) == NULL) 522 YYERROR; 523 cmd = $$; 524 $$->cmd_handler = &info_func; 525 $$->cmd_res_type = RT_AUTOBOOT; 526 $$->cmd_prop_nv_pairs = 0; 527 } 528 | INFO IPTYPE 529 { 530 if (($$ = alloc_cmd()) == NULL) 531 YYERROR; 532 cmd = $$; 533 $$->cmd_handler = &info_func; 534 $$->cmd_res_type = RT_IPTYPE; 535 $$->cmd_prop_nv_pairs = 0; 536 } 537 | INFO POOL 538 { 539 if (($$ = alloc_cmd()) == NULL) 540 YYERROR; 541 cmd = $$; 542 $$->cmd_handler = &info_func; 543 $$->cmd_res_type = RT_POOL; 544 $$->cmd_prop_nv_pairs = 0; 545 } 546 | INFO LIMITPRIV 547 { 548 if (($$ = alloc_cmd()) == NULL) 549 YYERROR; 550 cmd = $$; 551 $$->cmd_handler = &info_func; 552 $$->cmd_res_type = RT_LIMITPRIV; 553 $$->cmd_prop_nv_pairs = 0; 554 } 555 | INFO BOOTARGS 556 { 557 if (($$ = alloc_cmd()) == NULL) 558 YYERROR; 559 cmd = $$; 560 $$->cmd_handler = &info_func; 561 $$->cmd_res_type = RT_BOOTARGS; 562 $$->cmd_prop_nv_pairs = 0; 563 } 564 | INFO SCHED 565 { 566 if (($$ = alloc_cmd()) == NULL) 567 YYERROR; 568 cmd = $$; 569 $$->cmd_handler = &info_func; 570 $$->cmd_res_type = RT_SCHED; 571 $$->cmd_prop_nv_pairs = 0; 572 } 573 | INFO SHARES 574 { 575 if (($$ = alloc_cmd()) == NULL) 576 YYERROR; 577 cmd = $$; 578 $$->cmd_handler = &info_func; 579 $$->cmd_res_type = RT_SHARES; 580 $$->cmd_prop_nv_pairs = 0; 581 } 582 | INFO MAXLWPS 583 { 584 if (($$ = alloc_cmd()) == NULL) 585 YYERROR; 586 cmd = $$; 587 $$->cmd_handler = &info_func; 588 $$->cmd_res_type = RT_MAXLWPS; 589 $$->cmd_prop_nv_pairs = 0; 590 } 591 | INFO MAXPROCS 592 { 593 if (($$ = alloc_cmd()) == NULL) 594 YYERROR; 595 cmd = $$; 596 $$->cmd_handler = &info_func; 597 $$->cmd_res_type = RT_MAXPROCS; 598 $$->cmd_prop_nv_pairs = 0; 599 } 600 | INFO MAXSHMMEM 601 { 602 if (($$ = alloc_cmd()) == NULL) 603 YYERROR; 604 cmd = $$; 605 $$->cmd_handler = &info_func; 606 $$->cmd_res_type = RT_MAXSHMMEM; 607 $$->cmd_prop_nv_pairs = 0; 608 } 609 | INFO MAXSHMIDS 610 { 611 if (($$ = alloc_cmd()) == NULL) 612 YYERROR; 613 cmd = $$; 614 $$->cmd_handler = &info_func; 615 $$->cmd_res_type = RT_MAXSHMIDS; 616 $$->cmd_prop_nv_pairs = 0; 617 } 618 | INFO MAXMSGIDS 619 { 620 if (($$ = alloc_cmd()) == NULL) 621 YYERROR; 622 cmd = $$; 623 $$->cmd_handler = &info_func; 624 $$->cmd_res_type = RT_MAXMSGIDS; 625 $$->cmd_prop_nv_pairs = 0; 626 } 627 | INFO MAXSEMIDS 628 { 629 if (($$ = alloc_cmd()) == NULL) 630 YYERROR; 631 cmd = $$; 632 $$->cmd_handler = &info_func; 633 $$->cmd_res_type = RT_MAXSEMIDS; 634 $$->cmd_prop_nv_pairs = 0; 635 } 636 | INFO HOSTID 637 { 638 if (($$ = alloc_cmd()) == NULL) 639 YYERROR; 640 cmd = $$; 641 $$->cmd_handler = &info_func; 642 $$->cmd_res_type = RT_HOSTID; 643 $$->cmd_prop_nv_pairs = 0; 644 } 645 | INFO FS_ALLOWED 646 { 647 if (($$ = alloc_cmd()) == NULL) 648 YYERROR; 649 cmd = $$; 650 $$->cmd_handler = &info_func; 651 $$->cmd_res_type = RT_FS_ALLOWED; 652 $$->cmd_prop_nv_pairs = 0; 653 } 654 | INFO resource_type property_name EQUAL property_value 655 { 656 if (($$ = alloc_cmd()) == NULL) 657 YYERROR; 658 cmd = $$; 659 $$->cmd_handler = &info_func; 660 $$->cmd_res_type = $2; 661 $$->cmd_prop_nv_pairs = 1; 662 $$->cmd_prop_name[0] = $3; 663 $$->cmd_property_ptr[0] = &property[0]; 664 } 665 | INFO resource_type property_name EQUAL property_value property_name EQUAL property_value 666 { 667 if (($$ = alloc_cmd()) == NULL) 668 YYERROR; 669 cmd = $$; 670 $$->cmd_handler = &info_func; 671 $$->cmd_res_type = $2; 672 $$->cmd_prop_nv_pairs = 2; 673 $$->cmd_prop_name[0] = $3; 674 $$->cmd_property_ptr[0] = &property[0]; 675 $$->cmd_prop_name[1] = $6; 676 $$->cmd_property_ptr[1] = &property[1]; 677 } 678 | INFO resource_type property_name EQUAL property_value property_name EQUAL property_value property_name EQUAL property_value 679 { 680 if (($$ = alloc_cmd()) == NULL) 681 YYERROR; 682 cmd = $$; 683 $$->cmd_handler = &info_func; 684 $$->cmd_res_type = $2; 685 $$->cmd_prop_nv_pairs = 3; 686 $$->cmd_prop_name[0] = $3; 687 $$->cmd_property_ptr[0] = &property[0]; 688 $$->cmd_prop_name[1] = $6; 689 $$->cmd_property_ptr[1] = &property[1]; 690 $$->cmd_prop_name[2] = $9; 691 $$->cmd_property_ptr[2] = &property[2]; 692 } 693 694 remove_command: REMOVE 695 { 696 short_usage(CMD_REMOVE); 697 (void) fputs("\n", stderr); 698 usage(B_FALSE, HELP_RES_PROPS); 699 YYERROR; 700 } 701 | REMOVE TOKEN 702 { 703 short_usage(CMD_REMOVE); 704 (void) fputs("\n", stderr); 705 usage(B_FALSE, HELP_RES_PROPS); 706 free(claim_token($2)); 707 YYERROR; 708 } 709 | REMOVE resource_type 710 { 711 if (($$ = alloc_cmd()) == NULL) 712 YYERROR; 713 cmd = $$; 714 $$->cmd_handler = &remove_func; 715 $$->cmd_res_type = $2; 716 } 717 | REMOVE TOKEN resource_type 718 { 719 if (($$ = alloc_cmd()) == NULL) 720 YYERROR; 721 cmd = $$; 722 $$->cmd_handler = &remove_func; 723 $$->cmd_res_type = $3; 724 $$->cmd_argc = 1; 725 $$->cmd_argv[0] = claim_token($2); 726 $$->cmd_argv[1] = NULL; 727 } 728 | REMOVE property_name property_value 729 { 730 if (($$ = alloc_cmd()) == NULL) 731 YYERROR; 732 cmd = $$; 733 $$->cmd_handler = &remove_func; 734 $$->cmd_prop_nv_pairs = 1; 735 $$->cmd_prop_name[0] = $2; 736 $$->cmd_property_ptr[0] = &property[0]; 737 } 738 | REMOVE resource_type property_name EQUAL property_value 739 { 740 if (($$ = alloc_cmd()) == NULL) 741 YYERROR; 742 cmd = $$; 743 $$->cmd_handler = &remove_func; 744 $$->cmd_res_type = $2; 745 $$->cmd_prop_nv_pairs = 1; 746 $$->cmd_prop_name[0] = $3; 747 $$->cmd_property_ptr[0] = &property[0]; 748 } 749 | REMOVE resource_type property_name EQUAL property_value property_name EQUAL property_value 750 { 751 if (($$ = alloc_cmd()) == NULL) 752 YYERROR; 753 cmd = $$; 754 $$->cmd_handler = &remove_func; 755 $$->cmd_res_type = $2; 756 $$->cmd_prop_nv_pairs = 2; 757 $$->cmd_prop_name[0] = $3; 758 $$->cmd_property_ptr[0] = &property[0]; 759 $$->cmd_prop_name[1] = $6; 760 $$->cmd_property_ptr[1] = &property[1]; 761 } 762 | REMOVE resource_type property_name EQUAL property_value property_name EQUAL property_value property_name EQUAL property_value 763 { 764 if (($$ = alloc_cmd()) == NULL) 765 YYERROR; 766 cmd = $$; 767 $$->cmd_handler = &remove_func; 768 $$->cmd_res_type = $2; 769 $$->cmd_prop_nv_pairs = 3; 770 $$->cmd_prop_name[0] = $3; 771 $$->cmd_property_ptr[0] = &property[0]; 772 $$->cmd_prop_name[1] = $6; 773 $$->cmd_property_ptr[1] = &property[1]; 774 $$->cmd_prop_name[2] = $9; 775 $$->cmd_property_ptr[2] = &property[2]; 776 } 777 778 revert_command: REVERT 779 { 780 if (($$ = alloc_cmd()) == NULL) 781 YYERROR; 782 cmd = $$; 783 $$->cmd_handler = &revert_func; 784 $$->cmd_argc = 0; 785 $$->cmd_argv[0] = NULL; 786 } 787 | REVERT TOKEN 788 { 789 if (($$ = alloc_cmd()) == NULL) 790 YYERROR; 791 cmd = $$; 792 $$->cmd_handler = &revert_func; 793 $$->cmd_argc = 1; 794 $$->cmd_argv[0] = claim_token($2); 795 $$->cmd_argv[1] = NULL; 796 } 797 798 select_command: SELECT 799 { 800 short_usage(CMD_SELECT); 801 (void) fputs("\n", stderr); 802 usage(B_FALSE, HELP_RES_PROPS); 803 YYERROR; 804 } 805 | SELECT PSET 806 { 807 if (($$ = alloc_cmd()) == NULL) 808 YYERROR; 809 cmd = $$; 810 $$->cmd_handler = &select_func; 811 $$->cmd_res_type = RT_DCPU; 812 } 813 | SELECT PCAP 814 { 815 if (($$ = alloc_cmd()) == NULL) 816 YYERROR; 817 cmd = $$; 818 $$->cmd_handler = &select_func; 819 $$->cmd_res_type = RT_PCAP; 820 } 821 | SELECT MCAP 822 { 823 if (($$ = alloc_cmd()) == NULL) 824 YYERROR; 825 cmd = $$; 826 $$->cmd_handler = &select_func; 827 $$->cmd_res_type = RT_MCAP; 828 } 829 | SELECT resource_type 830 { 831 short_usage(CMD_SELECT); 832 YYERROR; 833 } 834 | SELECT resource_type property_name EQUAL property_value 835 { 836 if (($$ = alloc_cmd()) == NULL) 837 YYERROR; 838 cmd = $$; 839 $$->cmd_handler = &select_func; 840 $$->cmd_res_type = $2; 841 $$->cmd_prop_nv_pairs = 1; 842 $$->cmd_prop_name[0] = $3; 843 $$->cmd_property_ptr[0] = &property[0]; 844 } 845 | SELECT resource_type property_name EQUAL property_value property_name EQUAL property_value 846 { 847 if (($$ = alloc_cmd()) == NULL) 848 YYERROR; 849 cmd = $$; 850 $$->cmd_handler = &select_func; 851 $$->cmd_res_type = $2; 852 $$->cmd_prop_nv_pairs = 2; 853 $$->cmd_prop_name[0] = $3; 854 $$->cmd_property_ptr[0] = &property[0]; 855 $$->cmd_prop_name[1] = $6; 856 $$->cmd_property_ptr[1] = &property[1]; 857 } 858 | SELECT resource_type property_name EQUAL property_value property_name EQUAL property_value property_name EQUAL property_value 859 { 860 if (($$ = alloc_cmd()) == NULL) 861 YYERROR; 862 cmd = $$; 863 $$->cmd_handler = &select_func; 864 $$->cmd_res_type = $2; 865 $$->cmd_prop_nv_pairs = 3; 866 $$->cmd_prop_name[0] = $3; 867 $$->cmd_property_ptr[0] = &property[0]; 868 $$->cmd_prop_name[1] = $6; 869 $$->cmd_property_ptr[1] = &property[1]; 870 $$->cmd_prop_name[2] = $9; 871 $$->cmd_property_ptr[2] = &property[2]; 872 } 873 874 set_command: SET 875 { 876 short_usage(CMD_SET); 877 (void) fputs("\n", stderr); 878 usage(B_FALSE, HELP_PROPS); 879 YYERROR; 880 } 881 | SET property_name EQUAL OPEN_SQ_BRACKET CLOSE_SQ_BRACKET 882 { 883 if (($$ = alloc_cmd()) == NULL) 884 YYERROR; 885 cmd = $$; 886 $$->cmd_handler = &set_func; 887 $$->cmd_prop_nv_pairs = 0; 888 $$->cmd_prop_name[0] = $2; 889 property[0].pv_type = PROP_VAL_LIST; 890 property[0].pv_list = NULL; 891 $$->cmd_property_ptr[0] = &property[0]; 892 } 893 | SET property_name EQUAL property_value 894 { 895 if (($$ = alloc_cmd()) == NULL) 896 YYERROR; 897 cmd = $$; 898 $$->cmd_handler = &set_func; 899 $$->cmd_prop_nv_pairs = 1; 900 $$->cmd_prop_name[0] = $2; 901 $$->cmd_property_ptr[0] = &property[0]; 902 } 903 | SET TOKEN ZONEPATH EQUAL property_value 904 { 905 if (($$ = alloc_cmd()) == NULL) 906 YYERROR; 907 cmd = $$; 908 $$->cmd_argc = 1; 909 $$->cmd_argv[0] = claim_token($2); 910 $$->cmd_argv[1] = NULL; 911 $$->cmd_handler = &set_func; 912 $$->cmd_prop_nv_pairs = 1; 913 $$->cmd_prop_name[0] = PT_ZONEPATH; 914 $$->cmd_property_ptr[0] = &property[0]; 915 } 916 917 clear_command: CLEAR 918 { 919 short_usage(CMD_CLEAR); 920 (void) fputs("\n", stderr); 921 usage(B_FALSE, HELP_PROPS); 922 YYERROR; 923 } 924 | CLEAR property_name 925 { 926 if (($$ = alloc_cmd()) == NULL) 927 YYERROR; 928 cmd = $$; 929 $$->cmd_handler = &clear_func; 930 $$->cmd_res_type = $2; 931 } 932 933 verify_command: VERIFY 934 { 935 if (($$ = alloc_cmd()) == NULL) 936 YYERROR; 937 cmd = $$; 938 $$->cmd_handler = &verify_func; 939 $$->cmd_argc = 0; 940 $$->cmd_argv[0] = NULL; 941 } 942 | VERIFY TOKEN 943 { 944 if (($$ = alloc_cmd()) == NULL) 945 YYERROR; 946 cmd = $$; 947 $$->cmd_handler = &verify_func; 948 $$->cmd_argc = 1; 949 $$->cmd_argv[0] = claim_token($2); 950 $$->cmd_argv[1] = NULL; 951 } 952 953 resource_type: NET { $$ = RT_NET; } 954 | FS { $$ = RT_FS; } 955 | DEVICE { $$ = RT_DEVICE; } 956 | RCTL { $$ = RT_RCTL; } 957 | ATTR { $$ = RT_ATTR; } 958 | DATASET { $$ = RT_DATASET; } 959 | PSET { $$ = RT_DCPU; } 960 | PCAP { $$ = RT_PCAP; } 961 | MCAP { $$ = RT_MCAP; } 962 | ADMIN { $$ = RT_ADMIN; } 963 | SECFLAGS { $$ = RT_SECFLAGS; } 964 965 property_name: SPECIAL { $$ = PT_SPECIAL; } 966 | RAW { $$ = PT_RAW; } 967 | DIR { $$ = PT_DIR; } 968 | TYPE { $$ = PT_TYPE; } 969 | OPTIONS { $$ = PT_OPTIONS; } 970 | ZONENAME { $$ = PT_ZONENAME; } 971 | ZONEPATH { $$ = PT_ZONEPATH; } 972 | AUTOBOOT { $$ = PT_AUTOBOOT; } 973 | IPTYPE { $$ = PT_IPTYPE; } 974 | POOL { $$ = PT_POOL; } 975 | LIMITPRIV { $$ = PT_LIMITPRIV; } 976 | BOOTARGS { $$ = PT_BOOTARGS; } 977 | ADDRESS { $$ = PT_ADDRESS; } 978 | ALLOWED_ADDRESS { $$ = PT_ALLOWED_ADDRESS; } 979 | PHYSICAL { $$ = PT_PHYSICAL; } 980 | DEFROUTER { $$ = PT_DEFROUTER; } 981 | NAME { $$ = PT_NAME; } 982 | VALUE { $$ = PT_VALUE; } 983 | MATCH { $$ = PT_MATCH; } 984 | PRIV { $$ = PT_PRIV; } 985 | LIMIT { $$ = PT_LIMIT; } 986 | ACTION { $$ = PT_ACTION; } 987 | BRAND { $$ = PT_BRAND; } 988 | NCPUS { $$ = PT_NCPUS; } 989 | LOCKED { $$ = PT_LOCKED; } 990 | SWAP { $$ = PT_SWAP; } 991 | IMPORTANCE { $$ = PT_IMPORTANCE; } 992 | SHARES { $$ = PT_SHARES; } 993 | MAXLWPS { $$ = PT_MAXLWPS; } 994 | MAXPROCS { $$ = PT_MAXPROCS; } 995 | MAXSHMMEM { $$ = PT_MAXSHMMEM; } 996 | MAXSHMIDS { $$ = PT_MAXSHMIDS; } 997 | MAXMSGIDS { $$ = PT_MAXMSGIDS; } 998 | MAXSEMIDS { $$ = PT_MAXSEMIDS; } 999 | SCHED { $$ = PT_SCHED; } 1000 | HOSTID { $$ = PT_HOSTID; } 1001 | USER { $$ = PT_USER; } 1002 | AUTHS { $$ = PT_AUTHS; } 1003 | FS_ALLOWED { $$ = PT_FS_ALLOWED; } 1004 | DEFAULT { $$ = PT_DEFAULT; } 1005 | UPPER { $$ = PT_UPPER; } 1006 | LOWER { $$ = PT_LOWER; } 1007 1008 /* 1009 * The grammar builds data structures from the bottom up. Thus various 1010 * strings are lexed into TOKENs or commands or resource or property values. 1011 * Below is where the resource and property values are built up into more 1012 * complex data structures. 1013 * 1014 * There are three kinds of properties: simple (single valued), complex 1015 * (one or more name=value pairs) and list (concatenation of one or more 1016 * simple or complex properties). 1017 * 1018 * So the property structure has a type which is one of these, and the 1019 * corresponding _simple, _complex or _list is set to the corresponding 1020 * lower-level data structure. 1021 */ 1022 1023 property_value: simple_prop_val 1024 { 1025 property[num_prop_vals].pv_type = PROP_VAL_SIMPLE; 1026 property[num_prop_vals].pv_simple = $1; 1027 if (list[num_prop_vals] != NULL) { 1028 free_outer_list(list[num_prop_vals]); 1029 list[num_prop_vals] = NULL; 1030 } 1031 num_prop_vals++; 1032 } 1033 | complex_prop_val 1034 { 1035 property[num_prop_vals].pv_type = PROP_VAL_COMPLEX; 1036 property[num_prop_vals].pv_complex = complex; 1037 if (list[num_prop_vals] != NULL) { 1038 free_outer_list(list[num_prop_vals]); 1039 list[num_prop_vals] = NULL; 1040 } 1041 num_prop_vals++; 1042 } 1043 | list_prop_val 1044 { 1045 property[num_prop_vals].pv_type = PROP_VAL_LIST; 1046 property[num_prop_vals].pv_list = list[num_prop_vals]; 1047 num_prop_vals++; 1048 } 1049 1050 /* 1051 * One level lower, lists are made up of simple or complex values, so 1052 * simple_prop_val and complex_prop_val fill in a list structure and 1053 * insert it into the linked list which is built up. And because 1054 * complex properties can have multiple name=value pairs, we keep 1055 * track of them in another linked list. 1056 * 1057 * The complex and list structures for the linked lists are allocated 1058 * below, and freed by recursive functions which are ultimately called 1059 * by free_cmd(), which is called from the top-most "commands" part of 1060 * the grammar. 1061 * 1062 * NOTE: simple_prop_val and complex_piece need reduction rules for 1063 * property_name and resource_type so that the parser will accept property names 1064 * and resource type names as property values. 1065 */ 1066 1067 simple_prop_val: TOKEN 1068 { 1069 $$ = simple_prop_val_func($1); 1070 free(claim_token($1)); 1071 if ($$ == NULL) 1072 YYERROR; 1073 } 1074 | resource_type 1075 { 1076 if (($$ = simple_prop_val_func(res_types[$1])) == NULL) 1077 YYERROR; 1078 } 1079 | property_name 1080 { 1081 if (($$ = simple_prop_val_func(prop_types[$1])) == NULL) 1082 YYERROR; 1083 } 1084 1085 complex_prop_val: OPEN_PAREN complex_piece CLOSE_PAREN 1086 { 1087 if ((new_list = alloc_list()) == NULL) 1088 YYERROR; 1089 new_list->lp_simple = NULL; 1090 new_list->lp_complex = complex; 1091 new_list->lp_next = NULL; 1092 if (list[num_prop_vals] == NULL) { 1093 list[num_prop_vals] = new_list; 1094 } else { 1095 for (tmp_list = list[num_prop_vals]; tmp_list != NULL; 1096 tmp_list = tmp_list->lp_next) 1097 last = tmp_list; 1098 last->lp_next = new_list; 1099 } 1100 } 1101 1102 complex_piece: property_name EQUAL TOKEN 1103 { 1104 $$ = complex_piece_func($1, $3, NULL); 1105 free(claim_token($3)); 1106 if ($$ == NULL) 1107 YYERROR; 1108 } 1109 | property_name EQUAL resource_type 1110 { 1111 if (($$ = complex_piece_func($1, res_types[$3], NULL)) == NULL) 1112 YYERROR; 1113 } 1114 | property_name EQUAL property_name 1115 { 1116 if (($$ = complex_piece_func($1, prop_types[$3], NULL)) == NULL) 1117 YYERROR; 1118 } 1119 | property_name EQUAL TOKEN COMMA complex_piece 1120 { 1121 $$ = complex_piece_func($1, $3, complex); 1122 free(claim_token($3)); 1123 if ($$ == NULL) 1124 YYERROR; 1125 } 1126 | property_name EQUAL resource_type COMMA complex_piece 1127 { 1128 if (($$ = complex_piece_func($1, res_types[$3], complex)) == 1129 NULL) 1130 YYERROR; 1131 } 1132 | property_name EQUAL property_name COMMA complex_piece 1133 { 1134 if (($$ = complex_piece_func($1, prop_types[$3], complex)) == 1135 NULL) 1136 YYERROR; 1137 } 1138 1139 list_piece: simple_prop_val 1140 | complex_prop_val 1141 | simple_prop_val COMMA list_piece 1142 | complex_prop_val COMMA list_piece 1143 1144 list_prop_val: OPEN_SQ_BRACKET list_piece CLOSE_SQ_BRACKET 1145 %% 1146