xref: /illumos-gate/usr/src/cmd/zonecfg/zonecfg_grammar.y (revision 150d2c5288c645a1c1a7d2bee61199a3729406c7)
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 2007 Sun Microsystems, Inc.  All rights reserved.
25  * Use is subject to license terms.
26  */
27 
28 #pragma ident	"%Z%%M%	%I%	%E% SMI"
29 
30 #include <stdio.h>
31 
32 #include "zonecfg.h"
33 
34 static cmd_t *cmd = NULL;		/* Command being processed */
35 static complex_property_ptr_t complex = NULL;
36 static list_property_ptr_t new_list = NULL, tmp_list, last,
37     list[MAX_EQ_PROP_PAIRS];
38 static property_value_t property[MAX_EQ_PROP_PAIRS];
39 
40 extern bool newline_terminated;
41 extern int num_prop_vals;		/* # of property values */
42 
43 /* yacc externals */
44 extern int yydebug;
45 extern void yyerror(char *s);
46 
47 %}
48 
49 %union {
50 	int ival;
51 	char *strval;
52 	cmd_t *cmd;
53 	complex_property_ptr_t complex;
54 	list_property_ptr_t list;
55 }
56 
57 %start commands
58 
59 %token HELP CREATE EXPORT ADD DELETE REMOVE SELECT SET INFO CANCEL END VERIFY
60 %token COMMIT REVERT EXIT SEMICOLON TOKEN ZONENAME ZONEPATH AUTOBOOT POOL NET
61 %token FS IPD ATTR DEVICE RCTL SPECIAL RAW DIR OPTIONS TYPE ADDRESS PHYSICAL
62 %token 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
65 %token MCAP NCPUS IMPORTANCE SHARES MAXLWPS MAXSHMMEM MAXSHMIDS MAXMSGIDS
66 %token MAXSEMIDS LOCKED SWAP SCHED CLEAR
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 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
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 = TRUE; }
149 	|	';'	{ newline_terminated = FALSE; }
150 
151 add_command: ADD
152 	{
153 		short_usage(CMD_ADD);
154 		(void) fputs("\n", stderr);
155 		usage(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(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(FALSE, HELP_RES_PROPS);
590 		YYERROR;
591 	}
592 	| REMOVE TOKEN
593 	{
594 		short_usage(CMD_REMOVE);
595 		(void) fputs("\n", stderr);
596 		usage(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(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 MCAP
704 	{
705 		if (($$ = alloc_cmd()) == NULL)
706 			YYERROR;
707 		cmd = $$;
708 		$$->cmd_handler = &select_func;
709 		$$->cmd_res_type = RT_MCAP;
710 	}
711 	| SELECT resource_type
712 	{
713 		short_usage(CMD_SELECT);
714 		YYERROR;
715 	}
716 	| SELECT resource_type property_name EQUAL property_value
717 	{
718 		if (($$ = alloc_cmd()) == NULL)
719 			YYERROR;
720 		cmd = $$;
721 		$$->cmd_handler = &select_func;
722 		$$->cmd_res_type = $2;
723 		$$->cmd_prop_nv_pairs = 1;
724 		$$->cmd_prop_name[0] = $3;
725 		$$->cmd_property_ptr[0] = &property[0];
726 	}
727 	| SELECT resource_type property_name EQUAL property_value property_name EQUAL property_value
728 	{
729 		if (($$ = alloc_cmd()) == NULL)
730 			YYERROR;
731 		cmd = $$;
732 		$$->cmd_handler = &select_func;
733 		$$->cmd_res_type = $2;
734 		$$->cmd_prop_nv_pairs = 2;
735 		$$->cmd_prop_name[0] = $3;
736 		$$->cmd_property_ptr[0] = &property[0];
737 		$$->cmd_prop_name[1] = $6;
738 		$$->cmd_property_ptr[1] = &property[1];
739 	}
740 	| SELECT resource_type property_name EQUAL property_value property_name EQUAL property_value property_name EQUAL property_value
741 	{
742 		if (($$ = alloc_cmd()) == NULL)
743 			YYERROR;
744 		cmd = $$;
745 		$$->cmd_handler = &select_func;
746 		$$->cmd_res_type = $2;
747 		$$->cmd_prop_nv_pairs = 3;
748 		$$->cmd_prop_name[0] = $3;
749 		$$->cmd_property_ptr[0] = &property[0];
750 		$$->cmd_prop_name[1] = $6;
751 		$$->cmd_property_ptr[1] = &property[1];
752 		$$->cmd_prop_name[2] = $9;
753 		$$->cmd_property_ptr[2] = &property[2];
754 	}
755 
756 set_command: SET
757 	{
758 		short_usage(CMD_SET);
759 		(void) fputs("\n", stderr);
760 		usage(FALSE, HELP_PROPS);
761 		YYERROR;
762 	}
763 	| SET property_name EQUAL OPEN_SQ_BRACKET CLOSE_SQ_BRACKET
764 	{
765 		if (($$ = alloc_cmd()) == NULL)
766 			YYERROR;
767 		cmd = $$;
768 		$$->cmd_handler = &set_func;
769 		$$->cmd_prop_nv_pairs = 0;
770 		$$->cmd_prop_name[0] = $2;
771 		property[0].pv_type = PROP_VAL_LIST;
772 		property[0].pv_list = NULL;
773 		$$->cmd_property_ptr[0] = &property[0];
774 	}
775 	| SET property_name EQUAL property_value
776 	{
777 		if (($$ = alloc_cmd()) == NULL)
778 			YYERROR;
779 		cmd = $$;
780 		$$->cmd_handler = &set_func;
781 		$$->cmd_prop_nv_pairs = 1;
782 		$$->cmd_prop_name[0] = $2;
783 		$$->cmd_property_ptr[0] = &property[0];
784 	}
785 	| SET TOKEN ZONEPATH EQUAL property_value
786 	{
787 		if (($$ = alloc_cmd()) == NULL)
788 			YYERROR;
789 		cmd = $$;
790 		$$->cmd_argc = 1;
791 		$$->cmd_argv[0] = $2;
792 		$$->cmd_argv[1] = NULL;
793 		$$->cmd_handler = &set_func;
794 		$$->cmd_prop_nv_pairs = 1;
795 		$$->cmd_prop_name[0] = PT_ZONEPATH;
796 		$$->cmd_property_ptr[0] = &property[0];
797 	}
798 
799 clear_command: CLEAR
800 	{
801 		short_usage(CMD_CLEAR);
802 		(void) fputs("\n", stderr);
803 		usage(FALSE, HELP_PROPS);
804 		YYERROR;
805 	}
806 	| CLEAR property_name
807 	{
808 		if (($$ = alloc_cmd()) == NULL)
809 			YYERROR;
810 		cmd = $$;
811 		$$->cmd_handler = &clear_func;
812 		$$->cmd_res_type = $2;
813 	}
814 
815 verify_command: VERIFY
816 	{
817 		if (($$ = alloc_cmd()) == NULL)
818 			YYERROR;
819 		cmd = $$;
820 		$$->cmd_handler = &verify_func;
821 		$$->cmd_argc = 0;
822 		$$->cmd_argv[0] = NULL;
823 	}
824 	| VERIFY TOKEN
825 	{
826 		if (($$ = alloc_cmd()) == NULL)
827 			YYERROR;
828 		cmd = $$;
829 		$$->cmd_handler = &verify_func;
830 		$$->cmd_argc = 1;
831 		$$->cmd_argv[0] = $2;
832 		$$->cmd_argv[1] = NULL;
833 	}
834 
835 resource_type: NET	{ $$ = RT_NET; }
836 	| FS		{ $$ = RT_FS; }
837 	| IPD		{ $$ = RT_IPD; }
838 	| DEVICE	{ $$ = RT_DEVICE; }
839 	| RCTL		{ $$ = RT_RCTL; }
840 	| ATTR		{ $$ = RT_ATTR; }
841 	| DATASET	{ $$ = RT_DATASET; }
842 	| PSET		{ $$ = RT_DCPU; }
843 	| MCAP		{ $$ = RT_MCAP; }
844 
845 property_name: SPECIAL	{ $$ = PT_SPECIAL; }
846 	| RAW		{ $$ = PT_RAW; }
847 	| DIR		{ $$ = PT_DIR; }
848 	| TYPE		{ $$ = PT_TYPE; }
849 	| OPTIONS	{ $$ = PT_OPTIONS; }
850 	| ZONENAME	{ $$ = PT_ZONENAME; }
851 	| ZONEPATH	{ $$ = PT_ZONEPATH; }
852 	| AUTOBOOT	{ $$ = PT_AUTOBOOT; }
853 	| IPTYPE	{ $$ = PT_IPTYPE; }
854 	| POOL		{ $$ = PT_POOL; }
855 	| LIMITPRIV	{ $$ = PT_LIMITPRIV; }
856 	| BOOTARGS	{ $$ = PT_BOOTARGS; }
857 	| ADDRESS	{ $$ = PT_ADDRESS; }
858 	| PHYSICAL	{ $$ = PT_PHYSICAL; }
859 	| NAME		{ $$ = PT_NAME; }
860 	| VALUE		{ $$ = PT_VALUE; }
861 	| MATCH		{ $$ = PT_MATCH; }
862 	| PRIV		{ $$ = PT_PRIV; }
863 	| LIMIT		{ $$ = PT_LIMIT; }
864 	| ACTION	{ $$ = PT_ACTION; }
865 	| BRAND		{ $$ = PT_BRAND; }
866 	| NCPUS		{ $$ = PT_NCPUS; }
867 	| LOCKED	{ $$ = PT_LOCKED; }
868 	| SWAP		{ $$ = PT_SWAP; }
869 	| IMPORTANCE	{ $$ = PT_IMPORTANCE; }
870 	| SHARES	{ $$ = PT_SHARES; }
871 	| MAXLWPS	{ $$ = PT_MAXLWPS; }
872 	| MAXSHMMEM	{ $$ = PT_MAXSHMMEM; }
873 	| MAXSHMIDS	{ $$ = PT_MAXSHMIDS; }
874 	| MAXMSGIDS	{ $$ = PT_MAXMSGIDS; }
875 	| MAXSEMIDS	{ $$ = PT_MAXSEMIDS; }
876 	| SCHED		{ $$ = PT_SCHED; }
877 
878 /*
879  * The grammar builds data structures from the bottom up.  Thus various
880  * strings are lexed into TOKENs or commands or resource or property values.
881  * Below is where the resource and property values are built up into more
882  * complex data structures.
883  *
884  * There are three kinds of properties: simple (single valued), complex
885  * (one or more name=value pairs) and list (concatenation of one or more
886  * simple or complex properties).
887  *
888  * So the property structure has a type which is one of these, and the
889  * corresponding _simple, _complex or _list is set to the corresponding
890  * lower-level data structure.
891  */
892 
893 property_value: simple_prop_val
894 	{
895 		property[num_prop_vals].pv_type = PROP_VAL_SIMPLE;
896 		property[num_prop_vals].pv_simple = $1;
897 		if (list[num_prop_vals] != NULL) {
898 			free_outer_list(list[num_prop_vals]);
899 			list[num_prop_vals] = NULL;
900 		}
901 		num_prop_vals++;
902 	}
903 	| complex_prop_val
904 	{
905 		property[num_prop_vals].pv_type = PROP_VAL_COMPLEX;
906 		property[num_prop_vals].pv_complex = complex;
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 	| list_prop_val
914 	{
915 		property[num_prop_vals].pv_type = PROP_VAL_LIST;
916 		property[num_prop_vals].pv_list = list[num_prop_vals];
917 		num_prop_vals++;
918 	}
919 
920 /*
921  * One level lower, lists are made up of simple or complex values, so
922  * simple_prop_val and complex_prop_val fill in a list structure and
923  * insert it into the linked list which is built up.  And because
924  * complex properties can have multiple name=value pairs, we keep
925  * track of them in another linked list.
926  *
927  * The complex and list structures for the linked lists are allocated
928  * below, and freed by recursive functions which are ultimately called
929  * by free_cmd(), which is called from the top-most "commands" part of
930  * the grammar.
931  */
932 
933 simple_prop_val: TOKEN
934 	{
935 		if ((new_list = alloc_list()) == NULL)
936 			YYERROR;
937 		new_list->lp_simple = $1;
938 		new_list->lp_complex = NULL;
939 		new_list->lp_next = NULL;
940 		if (list[num_prop_vals] == NULL) {
941 			list[num_prop_vals] = new_list;
942 		} else {
943 			for (tmp_list = list[num_prop_vals]; tmp_list != NULL;
944 			    tmp_list = tmp_list->lp_next)
945 				last = tmp_list;
946 			last->lp_next = new_list;
947 		}
948 	}
949 
950 complex_prop_val: OPEN_PAREN complex_piece CLOSE_PAREN
951 	{
952 		if ((new_list = alloc_list()) == NULL)
953 			YYERROR;
954 		new_list->lp_simple = NULL;
955 		new_list->lp_complex = complex;
956 		new_list->lp_next = NULL;
957 		if (list[num_prop_vals] == NULL) {
958 			list[num_prop_vals] = new_list;
959 		} else {
960 			for (tmp_list = list[num_prop_vals]; tmp_list != NULL;
961 			    tmp_list = tmp_list->lp_next)
962 				last = tmp_list;
963 			last->lp_next = new_list;
964 		}
965 	}
966 
967 complex_piece: property_name EQUAL TOKEN
968 	{
969 		if (($$ = alloc_complex()) == NULL)
970 			YYERROR;
971 		$$->cp_type = $1;
972 		$$->cp_value = $3;
973 		$$->cp_next = NULL;
974 		complex = $$;
975 	}
976 	| property_name EQUAL TOKEN COMMA complex_piece
977 	{
978 		if (($$ = alloc_complex()) == NULL)
979 			YYERROR;
980 		$$->cp_type = $1;
981 		$$->cp_value = $3;
982 		$$->cp_next = complex;
983 		complex = $$;
984 	}
985 
986 list_piece: simple_prop_val
987 	| complex_prop_val
988 	| simple_prop_val COMMA list_piece
989 	| complex_prop_val COMMA list_piece
990 
991 list_prop_val: OPEN_SQ_BRACKET list_piece CLOSE_SQ_BRACKET
992 %%
993