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