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