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