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