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