xref: /illumos-gate/usr/src/cmd/svc/svccfg/svccfg.y (revision aff4bce51ecc47df7e5a6351b7cee6bc20408c63)
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 2009 Sun Microsystems, Inc.  All rights reserved.
25  * Use is subject to license terms.
26  */
27 
28 
29 #include <libintl.h>
30 
31 #include "svccfg.h"
32 
33 uu_list_pool_t *string_pool;
34 
35 %}
36 
37 %union {
38 	int tok;
39 	char *str;
40 	uu_list_t *uul;
41 }
42 
43 %start commands
44 
45 %token SCC_VALIDATE SCC_IMPORT SCC_EXPORT SCC_ARCHIVE SCC_APPLY SCC_EXTRACT
46 %token SCC_REPOSITORY SCC_INVENTORY SCC_SET SCC_END SCC_HELP SCC_RESTORE
47 %token SCC_LIST SCC_ADD SCC_DELETE SCC_SELECT SCC_UNSELECT
48 %token SCC_LISTPG SCC_ADDPG SCC_DELPG SCC_DELHASH
49 %token SCC_LISTPROP SCC_SETPROP SCC_DELPROP SCC_EDITPROP
50 %token SCC_DESCRIBE
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 	| delhash_cmd
96 	| listprop_cmd
97 	| setprop_cmd
98 	| delprop_cmd
99 	| editprop_cmd
100 	| describe_cmd
101 	| addpropvalue_cmd
102 	| delpropvalue_cmd
103 	| setenv_cmd
104 	| unsetenv_cmd
105 	| listsnap_cmd
106 	| selectsnap_cmd
107 	| revert_cmd
108 	| refresh_cmd
109 	| unknown_cmd
110 	| error terminator	{ semerr(gettext("Syntax error.\n")); }
111 
112 unknown_cmd : SCV_WORD terminator
113 	{
114 		semerr(gettext("Unknown command \"%s\".\n"), $1);
115 		free($1);
116 	}
117 	| SCV_WORD string_list terminator
118 	{
119 		string_list_t *slp;
120 		void *cookie = NULL;
121 
122 		semerr(gettext("Unknown command \"%s\".\n"), $1);
123 
124 		while ((slp = uu_list_teardown($2, &cookie)) != NULL) {
125 			free(slp->str);
126 			free(slp);
127 		}
128 
129 		uu_list_destroy($2);
130 		free($1);
131 	}
132 
133 validate_cmd : SCC_VALIDATE SCV_WORD terminator
134 	{
135 		lscf_validate($2);
136 		free($2);
137 	}
138 	| SCC_VALIDATE terminator { lscf_validate_fmri(NULL); }
139 	| SCC_VALIDATE error terminator	{ synerr(SCC_VALIDATE); return(0); }
140 
141 import_cmd : SCC_IMPORT string_list terminator
142 	{
143 		string_list_t *slp;
144 		void *cookie = NULL;
145 
146 		if (engine_import($2) == -2) {
147 			synerr(SCC_IMPORT);
148 			return(0);
149 		}
150 
151 		while ((slp = uu_list_teardown($2, &cookie)) != NULL) {
152 			free(slp->str);
153 			free(slp);
154 		}
155 
156 		uu_list_destroy($2);
157 	}
158 	| SCC_IMPORT error terminator	{ synerr(SCC_IMPORT); return(0); }
159 
160 export_cmd : SCC_EXPORT SCV_WORD terminator
161 	{
162 		lscf_service_export($2, NULL, 0);
163 		free($2);
164 	}
165 	| SCC_EXPORT SCV_WORD SCS_REDIRECT SCV_WORD terminator
166 	{
167 		lscf_service_export($2, $4, 0);
168 		free($2);
169 		free($4);
170 	}
171 	| SCC_EXPORT SCV_WORD SCV_WORD terminator
172 	{
173 		if (strcmp($2, "-a") == 0) {
174 			lscf_service_export($3, NULL, SCE_ALL_VALUES);
175 			free($2);
176 			free($3);
177 		} else {
178 			synerr(SCC_EXPORT);
179 			free($2);
180 			free($3);
181 			return (0);
182 		}
183 	}
184 	| SCC_EXPORT SCV_WORD SCV_WORD SCS_REDIRECT SCV_WORD terminator
185 	{
186 		if (strcmp($2, "-a") == 0) {
187 			lscf_service_export($3, $5, SCE_ALL_VALUES);
188 			free($2);
189 			free($3);
190 			free($5);
191 		} else {
192 			synerr(SCC_EXPORT);
193 			free($2);
194 			free($3);
195 			free($5);
196 			return (0);
197 		}
198 	}
199 	| SCC_EXPORT error terminator	{ synerr(SCC_EXPORT); return(0); }
200 
201 archive_cmd : SCC_ARCHIVE terminator
202 	{
203 		lscf_archive(NULL, 0);
204 	}
205 	| SCC_ARCHIVE SCV_WORD terminator
206 	{
207 		if (strcmp($2, "-a") == 0) {
208 			lscf_archive(NULL, SCE_ALL_VALUES);
209 			free($2);
210 		} else {
211 			synerr(SCC_ARCHIVE);
212 			free($2);
213 			return (0);
214 		}
215 	}
216 	| SCC_ARCHIVE SCS_REDIRECT SCV_WORD terminator
217 	{
218 		lscf_archive($3, 0);
219 		free($3);
220 	}
221 	| SCC_ARCHIVE SCV_WORD SCS_REDIRECT SCV_WORD terminator
222 	{
223 		if (strcmp($2, "-a") == 0) {
224 			lscf_archive($4, SCE_ALL_VALUES);
225 			free($2);
226 			free($4);
227 		} else {
228 			synerr(SCC_ARCHIVE);
229 			free($2);
230 			free($4);
231 			return (0);
232 		}
233 	}
234 	| SCC_ARCHIVE error terminator	{ synerr(SCC_ARCHIVE); return(0); }
235 
236 restore_cmd : SCC_RESTORE SCV_WORD terminator
237 	{
238 		(void) engine_restore($2);
239 		free($2);
240 	}
241 	| SCC_RESTORE error terminator	{ synerr(SCC_RESTORE); return(0); }
242 
243 apply_cmd : SCC_APPLY SCV_WORD terminator
244 	{
245 		(void) engine_apply($2, 1);
246 		free($2);
247 	}
248 	| SCC_APPLY SCV_WORD SCV_WORD terminator
249 	{
250 		if (strcmp($2, "-n") == 0) {
251 			(void) engine_apply($3, 0);
252 			free($2);
253 			free($3);
254 		} else {
255 			synerr(SCC_APPLY);
256 			free($2);
257 			free($3);
258 			return (0);
259 		}
260 	}
261 	| SCC_APPLY error terminator	{ synerr(SCC_APPLY); return(0); }
262 
263 extract_cmd: SCC_EXTRACT terminator	{ lscf_profile_extract(NULL); }
264 	| SCC_EXTRACT SCS_REDIRECT SCV_WORD terminator
265 	{
266 		lscf_profile_extract($3);
267 		free($3);
268 	}
269 	| SCC_EXTRACT error terminator	{ synerr(SCC_EXTRACT); return(0); }
270 
271 repository_cmd: SCC_REPOSITORY SCV_WORD terminator
272 	{
273 		if (strcmp($2, "-f") == 0) {
274 			synerr(SCC_REPOSITORY);
275 			return(0);
276 		}
277 		lscf_set_repository($2, 0);
278 		free($2);
279 	}
280 	| SCC_REPOSITORY SCV_WORD SCV_WORD terminator
281 	{
282 		if (strcmp($2, "-f") == 0) {
283 			lscf_set_repository($3, 1);
284 			free($2);
285 			free($3);
286 		} else {
287 			synerr(SCC_REPOSITORY);
288 			return(0);
289 		}
290 	}
291 	| SCC_REPOSITORY error terminator   { synerr(SCC_REPOSITORY); return(0); }
292 
293 inventory_cmd : SCC_INVENTORY SCV_WORD terminator
294 					{ lxml_inventory($2); free($2); }
295 	| SCC_INVENTORY error terminator	{ synerr(SCC_INVENTORY); return(0); }
296 
297 set_cmd : SCC_SET string_list terminator
298 	{
299 		string_list_t *slp;
300 		void *cookie = NULL;
301 
302 		(void) engine_set($2);
303 
304 		while ((slp = uu_list_teardown($2, &cookie)) != NULL) {
305 			free(slp->str);
306 			free(slp);
307 		}
308 
309 		uu_list_destroy($2);
310 	}
311 	| SCC_SET error terminator		{ synerr(SCC_SET); return(0); }
312 
313 end_cmd : SCC_END terminator			{ exit(0); }
314 	| SCC_END error terminator		{ synerr (SCC_END); return(0); }
315 
316 help_cmd : SCC_HELP terminator			{ help(0); }
317 	| SCC_HELP command_token terminator	{ help($2); }
318 	| SCC_HELP error terminator		{ synerr(SCC_HELP); return(0); }
319 
320 list_cmd : SCC_LIST opt_word terminator	{ lscf_list($2); free($2); }
321 	| SCC_LIST error terminator	{ synerr(SCC_LIST); return(0); }
322 
323 add_cmd : SCC_ADD SCV_WORD terminator	{ lscf_add($2); free($2); }
324 	| SCC_ADD error terminator	{ synerr(SCC_ADD); return(0); }
325 
326 delete_cmd : SCC_DELETE SCV_WORD terminator
327 					{ lscf_delete($2, 0); free($2); }
328 	| SCC_DELETE SCV_WORD SCV_WORD terminator
329 	{
330 		if (strcmp($2, "-f") == 0) {
331 			lscf_delete($3, 1);
332 			free($2);
333 			free($3);
334 		} else {
335 			synerr(SCC_DELETE);
336 			free($2);
337 			free($3);
338 			return(0);
339 		}
340 	}
341 	| SCC_DELETE error terminator	{ synerr(SCC_DELETE); return(0); }
342 
343 select_cmd : SCC_SELECT SCV_WORD terminator	{ lscf_select($2); free($2); }
344 	| SCC_SELECT error terminator	{ synerr(SCC_SELECT); return(0) ;}
345 
346 unselect_cmd : SCC_UNSELECT terminator	{ lscf_unselect(); }
347 	| SCC_UNSELECT error terminator	{ synerr(SCC_UNSELECT); return(0); }
348 
349 listpg_cmd : SCC_LISTPG opt_word terminator
350 					{ lscf_listpg($2); free($2); }
351 	| SCC_LISTPG error terminator	{ synerr(SCC_LISTPG); return(0); }
352 
353 addpg_cmd : SCC_ADDPG SCV_WORD SCV_WORD opt_word terminator
354 	{
355 		(void) lscf_addpg($2, $3, $4);
356 		free($2);
357 		free($3);
358 		free($4);
359 	}
360 	| SCC_ADDPG error terminator	{ synerr(SCC_ADDPG); return(0); }
361 
362 delpg_cmd : SCC_DELPG SCV_WORD terminator
363 					{ lscf_delpg($2); free($2); }
364 	| SCC_DELPG error terminator	{ synerr(SCC_DELPG); return(0); }
365 
366 delhash_cmd : SCC_DELHASH SCV_WORD terminator
367 	{
368 		lscf_delhash($2, 0); free($2);
369 	}
370 	| SCC_DELHASH SCV_WORD SCV_WORD terminator
371 	{
372 		if (strcmp($2, "-d") == 0) {
373 			lscf_delhash($3, 1);
374 			free($2);
375 			free($3);
376 		} else {
377 			synerr(SCC_DELHASH);
378 			free($2);
379 			free($3);
380 			return(0);
381 		}
382 	}
383 	| SCC_DELHASH error terminator	{ synerr(SCC_DELHASH); return(0); }
384 
385 listprop_cmd : SCC_LISTPROP opt_word terminator
386 					{ lscf_listprop($2); free($2); }
387 	| SCC_LISTPROP error terminator	{ synerr(SCC_LISTPROP); return(0); }
388 
389 setprop_cmd : SCC_SETPROP SCV_WORD SCS_EQUALS string terminator
390 	{
391 		lscf_setprop($2, NULL, $4, NULL);
392 		free($2);
393 		free($4);
394 	}
395 	| SCC_SETPROP SCV_WORD SCS_EQUALS SCV_WORD string terminator
396 	{
397 		(void) lscf_setprop($2, $4, $5, NULL);
398 		free($2);
399 		free($4);
400 		free($5);
401 	}
402 	| SCC_SETPROP SCV_WORD SCS_EQUALS opt_word SCS_LPAREN
403 	      multiline_string_list SCS_RPAREN terminator
404 	{
405 		string_list_t *slp;
406 		void *cookie = NULL;
407 
408 		(void) lscf_setprop($2, $4, NULL, $6);
409 
410 		free($2);
411 		free($4);
412 
413 		while ((slp = uu_list_teardown($6, &cookie)) != NULL) {
414 			free(slp->str);
415 			free(slp);
416 		}
417 
418 		uu_list_destroy($6);
419 	}
420 	| SCC_SETPROP error terminator	{ synerr(SCC_SETPROP); return(0); }
421 	| SCC_SETPROP error		{ synerr(SCC_SETPROP); return(0); }
422 
423 delprop_cmd : SCC_DELPROP SCV_WORD terminator
424 					{ lscf_delprop($2); free($2); }
425 	| SCC_DELPROP error terminator	{ synerr(SCC_DELPROP); return(0); }
426 
427 editprop_cmd : SCC_EDITPROP terminator	{ lscf_editprop(); }
428 	| SCC_EDITPROP error terminator	{ synerr(SCC_EDITPROP); return(0); }
429 
430 describe_cmd : SCC_DESCRIBE string_list terminator
431 	{
432 		string_list_t *slp;
433 		void *cookie = NULL;
434 
435 		if (lscf_describe($2, 1) == -2) {
436 			synerr(SCC_DESCRIBE);
437 			return(0);
438 		}
439 
440 		while ((slp = uu_list_teardown($2, &cookie)) != NULL) {
441 			free(slp->str);
442 			free(slp);
443 		}
444 
445 		uu_list_destroy($2);
446 	}
447 	| SCC_DESCRIBE terminator { lscf_describe(NULL, 0); }
448 	| SCC_DESCRIBE error terminator	 { synerr(SCC_DESCRIBE); return(0); }
449 
450 addpropvalue_cmd : SCC_ADDPROPVALUE SCV_WORD string terminator
451 	{
452 		lscf_addpropvalue($2, NULL, $3);
453 		free($2);
454 		free($3);
455 	}
456 	| SCC_ADDPROPVALUE SCV_WORD string string terminator
457 	{
458 		(void) lscf_addpropvalue($2, $3, $4);
459 		free($2);
460 		free($3);
461 		free($4);
462 	}
463 	| SCC_ADDPROPVALUE error terminator { synerr(SCC_ADDPROPVALUE); return(0); }
464 
465 delpropvalue_cmd : SCC_DELPROPVALUE SCV_WORD string terminator
466 	{
467 		lscf_delpropvalue($2, $3, 0);
468 		free($2);
469 		free($3);
470 	}
471 	| SCC_DELPROPVALUE error terminator { synerr(SCC_DELPROPVALUE); return(0); }
472 
473 setenv_cmd : SCC_SETENV string_list terminator
474 	{
475 		string_list_t *slp;
476 		void *cookie = NULL;
477 
478 		if (lscf_setenv($2, 0) == -2) {
479 			synerr(SCC_SETENV);
480 			return(0);
481 		}
482 
483 		while ((slp = uu_list_teardown($2, &cookie)) != NULL) {
484 			free(slp->str);
485 			free(slp);
486 		}
487 
488 		uu_list_destroy($2);
489 	}
490 	| SCC_SETENV error terminator		{ synerr(SCC_SETENV); return(0); }
491 
492 unsetenv_cmd : SCC_UNSETENV string_list terminator
493 	{
494 		string_list_t *slp;
495 		void *cookie = NULL;
496 
497 		if (lscf_setenv($2, 1) == -2) {
498 			synerr(SCC_UNSETENV);
499 			return(0);
500 		}
501 
502 		while ((slp = uu_list_teardown($2, &cookie)) != NULL) {
503 			free(slp->str);
504 			free(slp);
505 		}
506 
507 		uu_list_destroy($2);
508 	}
509 	| SCC_UNSETENV error terminator	{ synerr(SCC_UNSETENV); return(0); }
510 
511 listsnap_cmd : SCC_LISTSNAP terminator	{ lscf_listsnap(); }
512 	| SCC_LISTSNAP error terminator	{ synerr(SCC_LISTSNAP); return(0); }
513 
514 selectsnap_cmd : SCC_SELECTSNAP opt_word terminator
515 					{ lscf_selectsnap($2); free($2); }
516 	| SCC_SELECTSNAP error terminator
517 					{ synerr(SCC_SELECTSNAP); return(0); }
518 
519 revert_cmd: SCC_REVERT opt_word terminator	{ lscf_revert($2); free ($2); }
520 	| SCC_REVERT error terminator		{ synerr(SCC_REVERT); return(0); }
521 
522 refresh_cmd: SCC_REFRESH terminator	{ lscf_refresh(); }
523 	| SCC_REFRESH error terminator	{ synerr(SCC_REFRESH); return(0); }
524 
525 terminator : SCS_NEWLINE
526 
527 string_list :
528 	{
529 		$$ = uu_list_create(string_pool, NULL, 0);
530 		if ($$ == NULL)
531 			uu_die(gettext("Out of memory\n"));
532 	}
533 	| string_list string
534 	{
535 		string_list_t *slp;
536 
537 		slp = safe_malloc(sizeof (*slp));
538 
539 		slp->str = $2;
540 		uu_list_node_init(slp, &slp->node, string_pool);
541 		uu_list_append($1, slp);
542 		$$ = $1;
543 	}
544 
545 multiline_string_list : string_list
546 	{
547 		$$ = $1;
548 	}
549 	| multiline_string_list SCS_NEWLINE string_list
550 	{
551 		void *cookie = NULL;
552 		string_list_t *slp;
553 
554 		/* Append $3 to $1. */
555 		while ((slp = uu_list_teardown($3, &cookie)) != NULL)
556 			uu_list_append($1, slp);
557 
558 		uu_list_destroy($3);
559 	}
560 
561 string : SCV_WORD	{ $$ = $1; }
562 	| SCV_STRING	{ $$ = $1; }
563 
564 opt_word :		{ $$ = NULL; }
565 	| SCV_WORD	{ $$ = $1; }
566 
567 command_token : SCC_VALIDATE	{ $$ = SCC_VALIDATE; }
568 	| SCC_IMPORT		{ $$ = SCC_IMPORT; }
569 	| SCC_EXPORT		{ $$ = SCC_EXPORT; }
570 	| SCC_APPLY		{ $$ = SCC_APPLY; }
571 	| SCC_EXTRACT		{ $$ = SCC_EXTRACT; }
572 	| SCC_REPOSITORY	{ $$ = SCC_REPOSITORY; }
573 	| SCC_ARCHIVE		{ $$ = SCC_ARCHIVE; }
574 	| SCC_INVENTORY		{ $$ = SCC_INVENTORY; }
575 	| SCC_SET		{ $$ = SCC_SET; }
576 	| SCC_END		{ $$ = SCC_END; }
577 	| SCC_HELP		{ $$ = SCC_HELP; }
578 	| SCC_LIST		{ $$ = SCC_LIST; }
579 	| SCC_ADD		{ $$ = SCC_ADD; }
580 	| SCC_DELETE		{ $$ = SCC_DELETE; }
581 	| SCC_SELECT		{ $$ = SCC_SELECT; }
582 	| SCC_UNSELECT		{ $$ = SCC_UNSELECT; }
583 	| SCC_LISTPG		{ $$ = SCC_LISTPG; }
584 	| SCC_ADDPG		{ $$ = SCC_ADDPG; }
585 	| SCC_DELPG		{ $$ = SCC_DELPG; }
586 	| SCC_DELHASH		{ $$ = SCC_DELHASH; }
587 	| SCC_LISTPROP		{ $$ = SCC_LISTPROP; }
588 	| SCC_SETPROP		{ $$ = SCC_SETPROP; }
589 	| SCC_DELPROP		{ $$ = SCC_DELPROP; }
590 	| SCC_EDITPROP		{ $$ = SCC_EDITPROP; }
591 	| SCC_ADDPROPVALUE	{ $$ = SCC_ADDPROPVALUE; }
592 	| SCC_DELPROPVALUE	{ $$ = SCC_DELPROPVALUE; }
593 	| SCC_SETENV		{ $$ = SCC_SETENV; }
594 	| SCC_UNSETENV		{ $$ = SCC_UNSETENV; }
595 	| SCC_LISTSNAP		{ $$ = SCC_LISTSNAP; }
596 	| SCC_SELECTSNAP	{ $$ = SCC_SELECTSNAP; }
597 	| SCC_REVERT		{ $$ = SCC_REVERT; }
598 	| SCC_REFRESH		{ $$ = SCC_REFRESH; }
599 	| SCC_DESCRIBE		{ $$ = SCC_DESCRIBE; }
600