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