xref: /illumos-gate/usr/src/cmd/svc/svccfg/svccfg.y (revision f998c95e3b7029fe5f7542e115f7474ddb8024d7)
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 <libintl.h>
31 
32 #include "svccfg.h"
33 
34 uu_list_pool_t *string_pool;
35 
36 %}
37 
38 %union {
39 	int tok;
40 	char *str;
41 	uu_list_t *uul;
42 }
43 
44 %start commands
45 
46 %token SCC_VALIDATE SCC_IMPORT SCC_EXPORT SCC_ARCHIVE SCC_APPLY SCC_EXTRACT
47 %token SCC_REPOSITORY SCC_INVENTORY SCC_SET SCC_END SCC_HELP SCC_RESTORE
48 %token SCC_LIST SCC_ADD SCC_DELETE SCC_SELECT SCC_UNSELECT
49 %token SCC_LISTPG SCC_ADDPG SCC_DELPG
50 %token SCC_LISTPROP SCC_SETPROP SCC_DELPROP SCC_EDITPROP
51 %token SCC_ADDPROPVALUE SCC_DELPROPVALUE SCC_SETENV SCC_UNSETENV
52 %token SCC_LISTSNAP SCC_SELECTSNAP SCC_REVERT SCC_REFRESH
53 %token SCS_REDIRECT SCS_NEWLINE SCS_EQUALS SCS_LPAREN SCS_RPAREN
54 %token SCV_WORD SCV_STRING
55 
56 %type <tok> command_token
57 %type <str> SCV_WORD SCV_STRING
58 %type <str> string opt_word
59 %type <uul> string_list multiline_string_list
60 
61 %%
62 
63 /*
64  * We could hoist the command terminator for all the rules up here, but then
65  * the parser would reduce before shifting the terminator, which would require
66  * an additional error rule (per command) to catch extra arguments.
67  * This way requires all input to be terminated, which is done by input() in
68  * svccfg.l.
69  */
70 
71 commands : command
72 	| commands command
73 
74 command : terminator
75 	| validate_cmd
76 	| import_cmd
77 	| export_cmd
78 	| archive_cmd
79 	| restore_cmd
80 	| apply_cmd
81 	| extract_cmd
82 	| repository_cmd
83 	| inventory_cmd
84 	| set_cmd
85 	| end_cmd
86 	| help_cmd
87 	| list_cmd
88 	| add_cmd
89 	| delete_cmd
90 	| select_cmd
91 	| unselect_cmd
92 	| listpg_cmd
93 	| addpg_cmd
94 	| delpg_cmd
95 	| listprop_cmd
96 	| setprop_cmd
97 	| delprop_cmd
98 	| editprop_cmd
99 	| addpropvalue_cmd
100 	| delpropvalue_cmd
101 	| setenv_cmd
102 	| unsetenv_cmd
103 	| listsnap_cmd
104 	| selectsnap_cmd
105 	| revert_cmd
106 	| refresh_cmd
107 	| unknown_cmd
108 	| error terminator	{ semerr(gettext("Syntax error.\n")); }
109 
110 unknown_cmd : SCV_WORD terminator
111 	{
112 		semerr(gettext("Unknown command \"%s\".\n"), $1);
113 		free($1);
114 	}
115 	| SCV_WORD string_list terminator
116 	{
117 		string_list_t *slp;
118 		void *cookie = NULL;
119 
120 		semerr(gettext("Unknown command \"%s\".\n"), $1);
121 
122 		while ((slp = uu_list_teardown($2, &cookie)) != NULL) {
123 			free(slp->str);
124 			free(slp);
125 		}
126 
127 		uu_list_destroy($2);
128 		free($1);
129 	}
130 
131 validate_cmd : SCC_VALIDATE SCV_WORD terminator
132 	{
133 		bundle_t *b = internal_bundle_new();
134 		lxml_get_bundle_file(b, $2, SVCCFG_OP_IMPORT);
135 		(void) internal_bundle_free(b);
136 		free($2);
137 	}
138 	| SCC_VALIDATE error terminator	{ synerr(SCC_VALIDATE); return(0); }
139 
140 import_cmd : SCC_IMPORT string_list terminator
141 	{
142 		string_list_t *slp;
143 		void *cookie = NULL;
144 
145 		if (engine_import($2) == -2) {
146 			synerr(SCC_IMPORT);
147 			return(0);
148 		}
149 
150 		while ((slp = uu_list_teardown($2, &cookie)) != NULL) {
151 			free(slp->str);
152 			free(slp);
153 		}
154 
155 		uu_list_destroy($2);
156 	}
157 	| SCC_IMPORT error terminator	{ synerr(SCC_IMPORT); return(0); }
158 
159 export_cmd : SCC_EXPORT SCV_WORD terminator
160 	{
161 		lscf_service_export($2, NULL, 0);
162 		free($2);
163 	}
164 	| SCC_EXPORT SCV_WORD SCS_REDIRECT SCV_WORD terminator
165 	{
166 		lscf_service_export($2, $4, 0);
167 		free($2);
168 		free($4);
169 	}
170 	| SCC_EXPORT SCV_WORD SCV_WORD terminator
171 	{
172 		if (strcmp($2, "-a") == 0) {
173 			lscf_service_export($3, NULL, SCE_ALL_VALUES);
174 			free($2);
175 			free($3);
176 		} else {
177 			synerr(SCC_EXPORT);
178 			free($2);
179 			free($3);
180 			return (0);
181 		}
182 	}
183 	| SCC_EXPORT SCV_WORD SCV_WORD SCS_REDIRECT SCV_WORD terminator
184 	{
185 		if (strcmp($2, "-a") == 0) {
186 			lscf_service_export($3, $5, SCE_ALL_VALUES);
187 			free($2);
188 			free($3);
189 			free($5);
190 		} else {
191 			synerr(SCC_EXPORT);
192 			free($2);
193 			free($3);
194 			free($5);
195 			return (0);
196 		}
197 	}
198 	| SCC_EXPORT error terminator	{ synerr(SCC_EXPORT); return(0); }
199 
200 archive_cmd : SCC_ARCHIVE terminator
201 	{
202 		lscf_archive(NULL, 0);
203 	}
204 	| SCC_ARCHIVE SCV_WORD terminator
205 	{
206 		if (strcmp($2, "-a") == 0) {
207 			lscf_archive(NULL, SCE_ALL_VALUES);
208 			free($2);
209 		} else {
210 			synerr(SCC_ARCHIVE);
211 			free($2);
212 			return (0);
213 		}
214 	}
215 	| SCC_ARCHIVE SCS_REDIRECT SCV_WORD terminator
216 	{
217 		lscf_archive($3, 0);
218 		free($3);
219 	}
220 	| SCC_ARCHIVE SCV_WORD SCS_REDIRECT SCV_WORD terminator
221 	{
222 		if (strcmp($2, "-a") == 0) {
223 			lscf_archive($4, SCE_ALL_VALUES);
224 			free($2);
225 			free($4);
226 		} else {
227 			synerr(SCC_ARCHIVE);
228 			free($2);
229 			free($4);
230 			return (0);
231 		}
232 	}
233 	| SCC_ARCHIVE error terminator	{ synerr(SCC_ARCHIVE); return(0); }
234 
235 restore_cmd : SCC_RESTORE SCV_WORD terminator
236 	{
237 		(void) engine_restore($2);
238 		free($2);
239 	}
240 	| SCC_RESTORE error terminator	{ synerr(SCC_RESTORE); return(0); }
241 
242 apply_cmd : SCC_APPLY SCV_WORD terminator
243 					{ (void) engine_apply($2); free($2); }
244 	| SCC_APPLY error terminator	{ synerr(SCC_APPLY); return(0); }
245 
246 extract_cmd: SCC_EXTRACT terminator	{ lscf_profile_extract(NULL); }
247 	| SCC_EXTRACT SCS_REDIRECT SCV_WORD terminator
248 	{
249 		lscf_profile_extract($3);
250 		free($3);
251 	}
252 	| SCC_EXTRACT error terminator	{ synerr(SCC_EXTRACT); return(0); }
253 
254 repository_cmd: SCC_REPOSITORY SCV_WORD terminator
255 	{
256 		if (strcmp($2, "-f") == 0) {
257 			synerr(SCC_REPOSITORY);
258 			return(0);
259 		}
260 		lscf_set_repository($2, 0);
261 		free($2);
262 	}
263 	| SCC_REPOSITORY SCV_WORD SCV_WORD terminator
264 	{
265 		if (strcmp($2, "-f") == 0) {
266 			lscf_set_repository($3, 1);
267 			free($2);
268 			free($3);
269 		} else {
270 			synerr(SCC_REPOSITORY);
271 			return(0);
272 		}
273 	}
274 	| SCC_REPOSITORY error terminator   { synerr(SCC_REPOSITORY); return(0); }
275 
276 inventory_cmd : SCC_INVENTORY SCV_WORD terminator
277 					{ lxml_inventory($2); free($2); }
278 	| SCC_INVENTORY error terminator	{ synerr(SCC_INVENTORY); return(0); }
279 
280 set_cmd : SCC_SET string_list terminator
281 	{
282 		string_list_t *slp;
283 		void *cookie = NULL;
284 
285 		(void) engine_set($2);
286 
287 		while ((slp = uu_list_teardown($2, &cookie)) != NULL) {
288 			free(slp->str);
289 			free(slp);
290 		}
291 
292 		uu_list_destroy($2);
293 	}
294 	| SCC_SET error terminator		{ synerr(SCC_SET); return(0); }
295 
296 end_cmd : SCC_END terminator			{ exit(0); }
297 	| SCC_END error terminator		{ synerr (SCC_END); return(0); }
298 
299 help_cmd : SCC_HELP terminator			{ help(0); }
300 	| SCC_HELP command_token terminator	{ help($2); }
301 	| SCC_HELP error terminator		{ synerr(SCC_HELP); return(0); }
302 
303 list_cmd : SCC_LIST opt_word terminator	{ lscf_list($2); free($2); }
304 	| SCC_LIST error terminator	{ synerr(SCC_LIST); return(0); }
305 
306 add_cmd : SCC_ADD SCV_WORD terminator	{ lscf_add($2); free($2); }
307 	| SCC_ADD error terminator	{ synerr(SCC_ADD); return(0); }
308 
309 delete_cmd : SCC_DELETE SCV_WORD terminator
310 					{ lscf_delete($2, 0); free($2); }
311 	| SCC_DELETE SCV_WORD SCV_WORD terminator
312 	{
313 		if (strcmp($2, "-f") == 0) {
314 			lscf_delete($3, 1);
315 			free($2);
316 			free($3);
317 		} else {
318 			synerr(SCC_DELETE);
319 			free($2);
320 			free($3);
321 			return(0);
322 		}
323 	}
324 	| SCC_DELETE error terminator	{ synerr(SCC_DELETE); return(0); }
325 
326 select_cmd : SCC_SELECT SCV_WORD terminator	{ lscf_select($2); free($2); }
327 	| SCC_SELECT error terminator	{ synerr(SCC_SELECT); return(0) ;}
328 
329 unselect_cmd : SCC_UNSELECT terminator	{ lscf_unselect(); }
330 	| SCC_UNSELECT error terminator	{ synerr(SCC_UNSELECT); return(0); }
331 
332 listpg_cmd : SCC_LISTPG opt_word terminator
333 					{ lscf_listpg($2); free($2); }
334 	| SCC_LISTPG error terminator	{ synerr(SCC_LISTPG); return(0); }
335 
336 addpg_cmd : SCC_ADDPG SCV_WORD SCV_WORD opt_word terminator
337 	{
338 		(void) lscf_addpg($2, $3, $4);
339 		free($2);
340 		free($3);
341 		free($4);
342 	}
343 	| SCC_ADDPG error terminator	{ synerr(SCC_ADDPG); return(0); }
344 
345 delpg_cmd : SCC_DELPG SCV_WORD terminator
346 					{ lscf_delpg($2); free($2); }
347 	| SCC_DELPG error terminator	{ synerr(SCC_DELPG); return(0); }
348 
349 listprop_cmd : SCC_LISTPROP opt_word terminator
350 					{ lscf_listprop($2); free($2); }
351 	| SCC_LISTPROP error terminator	{ synerr(SCC_LISTPROP); return(0); }
352 
353 setprop_cmd : SCC_SETPROP SCV_WORD SCS_EQUALS string terminator
354 	{
355 		lscf_setprop($2, NULL, $4, NULL);
356 		free($2);
357 		free($4);
358 	}
359 	| SCC_SETPROP SCV_WORD SCS_EQUALS SCV_WORD string terminator
360 	{
361 		(void) lscf_setprop($2, $4, $5, NULL);
362 		free($2);
363 		free($4);
364 		free($5);
365 	}
366 	| SCC_SETPROP SCV_WORD SCS_EQUALS opt_word SCS_LPAREN
367 	      multiline_string_list SCS_RPAREN terminator
368 	{
369 		string_list_t *slp;
370 		void *cookie = NULL;
371 
372 		(void) lscf_setprop($2, $4, NULL, $6);
373 
374 		free($2);
375 		free($4);
376 
377 		while ((slp = uu_list_teardown($6, &cookie)) != NULL) {
378 			free(slp->str);
379 			free(slp);
380 		}
381 
382 		uu_list_destroy($6);
383 	}
384 	| SCC_SETPROP error terminator	{ synerr(SCC_SETPROP); return(0); }
385 	| SCC_SETPROP error		{ synerr(SCC_SETPROP); return(0); }
386 
387 delprop_cmd : SCC_DELPROP SCV_WORD terminator
388 					{ lscf_delprop($2); free($2); }
389 	| SCC_DELPROP error terminator	{ synerr(SCC_DELPROP); return(0); }
390 
391 editprop_cmd : SCC_EDITPROP terminator	{ lscf_editprop(); }
392 	| SCC_EDITPROP error terminator	{ synerr(SCC_EDITPROP); return(0); }
393 
394 addpropvalue_cmd : SCC_ADDPROPVALUE SCV_WORD string terminator
395 	{
396 		lscf_addpropvalue($2, NULL, $3);
397 		free($2);
398 		free($3);
399 	}
400 	| SCC_ADDPROPVALUE SCV_WORD string string terminator
401 	{
402 		(void) lscf_addpropvalue($2, $3, $4);
403 		free($2);
404 		free($3);
405 		free($4);
406 	}
407 	| SCC_ADDPROPVALUE error terminator { synerr(SCC_ADDPROPVALUE); return(0); }
408 
409 delpropvalue_cmd : SCC_DELPROPVALUE SCV_WORD string terminator
410 	{
411 		lscf_delpropvalue($2, $3, 0);
412 		free($2);
413 		free($3);
414 	}
415 	| SCC_DELPROPVALUE error terminator { synerr(SCC_DELPROPVALUE); return(0); }
416 
417 setenv_cmd : SCC_SETENV string_list terminator
418 	{
419 		string_list_t *slp;
420 		void *cookie = NULL;
421 
422 		if (lscf_setenv($2, 0) == -2) {
423 			synerr(SCC_SETENV);
424 			return(0);
425 		}
426 
427 		while ((slp = uu_list_teardown($2, &cookie)) != NULL) {
428 			free(slp->str);
429 			free(slp);
430 		}
431 
432 		uu_list_destroy($2);
433 	}
434 	| SCC_SETENV error terminator		{ synerr(SCC_SETENV); return(0); }
435 
436 unsetenv_cmd : SCC_UNSETENV string_list terminator
437 	{
438 		string_list_t *slp;
439 		void *cookie = NULL;
440 
441 		if (lscf_setenv($2, 1) == -2) {
442 			synerr(SCC_UNSETENV);
443 			return(0);
444 		}
445 
446 		while ((slp = uu_list_teardown($2, &cookie)) != NULL) {
447 			free(slp->str);
448 			free(slp);
449 		}
450 
451 		uu_list_destroy($2);
452 	}
453 	| SCC_UNSETENV error terminator	{ synerr(SCC_UNSETENV); return(0); }
454 
455 listsnap_cmd : SCC_LISTSNAP terminator	{ lscf_listsnap(); }
456 	| SCC_LISTSNAP error terminator	{ synerr(SCC_LISTSNAP); return(0); }
457 
458 selectsnap_cmd : SCC_SELECTSNAP opt_word terminator
459 					{ lscf_selectsnap($2); free($2); }
460 	| SCC_SELECTSNAP error terminator
461 					{ synerr(SCC_SELECTSNAP); return(0); }
462 
463 revert_cmd: SCC_REVERT opt_word terminator	{ lscf_revert($2); free ($2); }
464 	| SCC_REVERT error terminator		{ synerr(SCC_REVERT); return(0); }
465 
466 refresh_cmd: SCC_REFRESH terminator	{ lscf_refresh(); }
467 	| SCC_REFRESH error terminator	{ synerr(SCC_REFRESH); return(0); }
468 
469 terminator : SCS_NEWLINE
470 
471 string_list :
472 	{
473 		$$ = uu_list_create(string_pool, NULL, 0);
474 		if ($$ == NULL)
475 			uu_die(gettext("Out of memory\n"));
476 	}
477 	| string_list string
478 	{
479 		string_list_t *slp;
480 
481 		slp = safe_malloc(sizeof (*slp));
482 
483 		slp->str = $2;
484 		uu_list_node_init(slp, &slp->node, string_pool);
485 		uu_list_append($1, slp);
486 		$$ = $1;
487 	}
488 
489 multiline_string_list : string_list
490 	{
491 		$$ = $1;
492 	}
493 	| multiline_string_list SCS_NEWLINE string_list
494 	{
495 		void *cookie = NULL;
496 		string_list_t *slp;
497 
498 		/* Append $3 to $1. */
499 		while ((slp = uu_list_teardown($3, &cookie)) != NULL)
500 			uu_list_append($1, slp);
501 
502 		uu_list_destroy($3);
503 	}
504 
505 string : SCV_WORD	{ $$ = $1; }
506 	| SCV_STRING	{ $$ = $1; }
507 
508 opt_word :		{ $$ = NULL; }
509 	| SCV_WORD	{ $$ = $1; }
510 
511 command_token : SCC_VALIDATE	{ $$ = SCC_VALIDATE; }
512 	| SCC_IMPORT		{ $$ = SCC_IMPORT; }
513 	| SCC_EXPORT		{ $$ = SCC_EXPORT; }
514 	| SCC_APPLY		{ $$ = SCC_APPLY; }
515 	| SCC_EXTRACT		{ $$ = SCC_EXTRACT; }
516 	| SCC_REPOSITORY	{ $$ = SCC_REPOSITORY; }
517 	| SCC_ARCHIVE		{ $$ = SCC_ARCHIVE; }
518 	| SCC_INVENTORY		{ $$ = SCC_INVENTORY; }
519 	| SCC_SET		{ $$ = SCC_SET; }
520 	| SCC_END		{ $$ = SCC_END; }
521 	| SCC_HELP		{ $$ = SCC_HELP; }
522 	| SCC_LIST		{ $$ = SCC_LIST; }
523 	| SCC_ADD		{ $$ = SCC_ADD; }
524 	| SCC_DELETE		{ $$ = SCC_DELETE; }
525 	| SCC_SELECT		{ $$ = SCC_SELECT; }
526 	| SCC_UNSELECT		{ $$ = SCC_UNSELECT; }
527 	| SCC_LISTPG		{ $$ = SCC_LISTPG; }
528 	| SCC_ADDPG		{ $$ = SCC_ADDPG; }
529 	| SCC_DELPG		{ $$ = SCC_DELPG; }
530 	| SCC_LISTPROP		{ $$ = SCC_LISTPROP; }
531 	| SCC_SETPROP		{ $$ = SCC_SETPROP; }
532 	| SCC_DELPROP		{ $$ = SCC_DELPROP; }
533 	| SCC_EDITPROP		{ $$ = SCC_EDITPROP; }
534 	| SCC_ADDPROPVALUE	{ $$ = SCC_ADDPROPVALUE; }
535 	| SCC_DELPROPVALUE	{ $$ = SCC_DELPROPVALUE; }
536 	| SCC_SETENV		{ $$ = SCC_SETENV; }
537 	| SCC_UNSETENV		{ $$ = SCC_UNSETENV; }
538 	| SCC_LISTSNAP		{ $$ = SCC_LISTSNAP; }
539 	| SCC_SELECTSNAP	{ $$ = SCC_SELECTSNAP; }
540 	| SCC_REVERT		{ $$ = SCC_REVERT; }
541 	| SCC_REFRESH		{ $$ = SCC_REFRESH; }
542