xref: /illumos-gate/usr/src/cmd/svc/svccfg/svccfg.y (revision f6f4cb8ada400367a1921f6b93fb9e02f53ac5e6)
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 
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_ADDPROPVALUE SCC_DELPROPVALUE SCC_SETENV SCC_UNSETENV
51 %token SCC_LISTSNAP SCC_SELECTSNAP SCC_REVERT SCC_REFRESH
52 %token SCS_REDIRECT SCS_NEWLINE SCS_EQUALS SCS_LPAREN SCS_RPAREN
53 %token SCV_WORD SCV_STRING
54 
55 %type <tok> command_token
56 %type <str> SCV_WORD SCV_STRING
57 %type <str> string opt_word
58 %type <uul> string_list multiline_string_list
59 
60 %%
61 
62 /*
63  * We could hoist the command terminator for all the rules up here, but then
64  * the parser would reduce before shifting the terminator, which would require
65  * an additional error rule (per command) to catch extra arguments.
66  * This way requires all input to be terminated, which is done by input() in
67  * svccfg.l.
68  */
69 
70 commands : command
71 	| commands command
72 
73 command : terminator
74 	| validate_cmd
75 	| import_cmd
76 	| export_cmd
77 	| archive_cmd
78 	| restore_cmd
79 	| apply_cmd
80 	| extract_cmd
81 	| repository_cmd
82 	| inventory_cmd
83 	| set_cmd
84 	| end_cmd
85 	| help_cmd
86 	| list_cmd
87 	| add_cmd
88 	| delete_cmd
89 	| select_cmd
90 	| unselect_cmd
91 	| listpg_cmd
92 	| addpg_cmd
93 	| delpg_cmd
94 	| delhash_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 delhash_cmd : SCC_DELHASH SCV_WORD terminator
350 	{
351 		lscf_delhash($2, 0); free($2);
352 	}
353 	| SCC_DELHASH SCV_WORD SCV_WORD terminator
354 	{
355 		if (strcmp($2, "-d") == 0) {
356 			lscf_delhash($3, 1);
357 			free($2);
358 			free($3);
359 		} else {
360 			synerr(SCC_DELHASH);
361 			free($2);
362 			free($3);
363 			return(0);
364 		}
365 	}
366 	| SCC_DELHASH error terminator	{ synerr(SCC_DELHASH); return(0); }
367 
368 listprop_cmd : SCC_LISTPROP opt_word terminator
369 					{ lscf_listprop($2); free($2); }
370 	| SCC_LISTPROP error terminator	{ synerr(SCC_LISTPROP); return(0); }
371 
372 setprop_cmd : SCC_SETPROP SCV_WORD SCS_EQUALS string terminator
373 	{
374 		lscf_setprop($2, NULL, $4, NULL);
375 		free($2);
376 		free($4);
377 	}
378 	| SCC_SETPROP SCV_WORD SCS_EQUALS SCV_WORD string terminator
379 	{
380 		(void) lscf_setprop($2, $4, $5, NULL);
381 		free($2);
382 		free($4);
383 		free($5);
384 	}
385 	| SCC_SETPROP SCV_WORD SCS_EQUALS opt_word SCS_LPAREN
386 	      multiline_string_list SCS_RPAREN terminator
387 	{
388 		string_list_t *slp;
389 		void *cookie = NULL;
390 
391 		(void) lscf_setprop($2, $4, NULL, $6);
392 
393 		free($2);
394 		free($4);
395 
396 		while ((slp = uu_list_teardown($6, &cookie)) != NULL) {
397 			free(slp->str);
398 			free(slp);
399 		}
400 
401 		uu_list_destroy($6);
402 	}
403 	| SCC_SETPROP error terminator	{ synerr(SCC_SETPROP); return(0); }
404 	| SCC_SETPROP error		{ synerr(SCC_SETPROP); return(0); }
405 
406 delprop_cmd : SCC_DELPROP SCV_WORD terminator
407 					{ lscf_delprop($2); free($2); }
408 	| SCC_DELPROP error terminator	{ synerr(SCC_DELPROP); return(0); }
409 
410 editprop_cmd : SCC_EDITPROP terminator	{ lscf_editprop(); }
411 	| SCC_EDITPROP error terminator	{ synerr(SCC_EDITPROP); return(0); }
412 
413 addpropvalue_cmd : SCC_ADDPROPVALUE SCV_WORD string terminator
414 	{
415 		lscf_addpropvalue($2, NULL, $3);
416 		free($2);
417 		free($3);
418 	}
419 	| SCC_ADDPROPVALUE SCV_WORD string string terminator
420 	{
421 		(void) lscf_addpropvalue($2, $3, $4);
422 		free($2);
423 		free($3);
424 		free($4);
425 	}
426 	| SCC_ADDPROPVALUE error terminator { synerr(SCC_ADDPROPVALUE); return(0); }
427 
428 delpropvalue_cmd : SCC_DELPROPVALUE SCV_WORD string terminator
429 	{
430 		lscf_delpropvalue($2, $3, 0);
431 		free($2);
432 		free($3);
433 	}
434 	| SCC_DELPROPVALUE error terminator { synerr(SCC_DELPROPVALUE); return(0); }
435 
436 setenv_cmd : SCC_SETENV string_list terminator
437 	{
438 		string_list_t *slp;
439 		void *cookie = NULL;
440 
441 		if (lscf_setenv($2, 0) == -2) {
442 			synerr(SCC_SETENV);
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_SETENV error terminator		{ synerr(SCC_SETENV); return(0); }
454 
455 unsetenv_cmd : SCC_UNSETENV string_list terminator
456 	{
457 		string_list_t *slp;
458 		void *cookie = NULL;
459 
460 		if (lscf_setenv($2, 1) == -2) {
461 			synerr(SCC_UNSETENV);
462 			return(0);
463 		}
464 
465 		while ((slp = uu_list_teardown($2, &cookie)) != NULL) {
466 			free(slp->str);
467 			free(slp);
468 		}
469 
470 		uu_list_destroy($2);
471 	}
472 	| SCC_UNSETENV error terminator	{ synerr(SCC_UNSETENV); return(0); }
473 
474 listsnap_cmd : SCC_LISTSNAP terminator	{ lscf_listsnap(); }
475 	| SCC_LISTSNAP error terminator	{ synerr(SCC_LISTSNAP); return(0); }
476 
477 selectsnap_cmd : SCC_SELECTSNAP opt_word terminator
478 					{ lscf_selectsnap($2); free($2); }
479 	| SCC_SELECTSNAP error terminator
480 					{ synerr(SCC_SELECTSNAP); return(0); }
481 
482 revert_cmd: SCC_REVERT opt_word terminator	{ lscf_revert($2); free ($2); }
483 	| SCC_REVERT error terminator		{ synerr(SCC_REVERT); return(0); }
484 
485 refresh_cmd: SCC_REFRESH terminator	{ lscf_refresh(); }
486 	| SCC_REFRESH error terminator	{ synerr(SCC_REFRESH); return(0); }
487 
488 terminator : SCS_NEWLINE
489 
490 string_list :
491 	{
492 		$$ = uu_list_create(string_pool, NULL, 0);
493 		if ($$ == NULL)
494 			uu_die(gettext("Out of memory\n"));
495 	}
496 	| string_list string
497 	{
498 		string_list_t *slp;
499 
500 		slp = safe_malloc(sizeof (*slp));
501 
502 		slp->str = $2;
503 		uu_list_node_init(slp, &slp->node, string_pool);
504 		uu_list_append($1, slp);
505 		$$ = $1;
506 	}
507 
508 multiline_string_list : string_list
509 	{
510 		$$ = $1;
511 	}
512 	| multiline_string_list SCS_NEWLINE string_list
513 	{
514 		void *cookie = NULL;
515 		string_list_t *slp;
516 
517 		/* Append $3 to $1. */
518 		while ((slp = uu_list_teardown($3, &cookie)) != NULL)
519 			uu_list_append($1, slp);
520 
521 		uu_list_destroy($3);
522 	}
523 
524 string : SCV_WORD	{ $$ = $1; }
525 	| SCV_STRING	{ $$ = $1; }
526 
527 opt_word :		{ $$ = NULL; }
528 	| SCV_WORD	{ $$ = $1; }
529 
530 command_token : SCC_VALIDATE	{ $$ = SCC_VALIDATE; }
531 	| SCC_IMPORT		{ $$ = SCC_IMPORT; }
532 	| SCC_EXPORT		{ $$ = SCC_EXPORT; }
533 	| SCC_APPLY		{ $$ = SCC_APPLY; }
534 	| SCC_EXTRACT		{ $$ = SCC_EXTRACT; }
535 	| SCC_REPOSITORY	{ $$ = SCC_REPOSITORY; }
536 	| SCC_ARCHIVE		{ $$ = SCC_ARCHIVE; }
537 	| SCC_INVENTORY		{ $$ = SCC_INVENTORY; }
538 	| SCC_SET		{ $$ = SCC_SET; }
539 	| SCC_END		{ $$ = SCC_END; }
540 	| SCC_HELP		{ $$ = SCC_HELP; }
541 	| SCC_LIST		{ $$ = SCC_LIST; }
542 	| SCC_ADD		{ $$ = SCC_ADD; }
543 	| SCC_DELETE		{ $$ = SCC_DELETE; }
544 	| SCC_SELECT		{ $$ = SCC_SELECT; }
545 	| SCC_UNSELECT		{ $$ = SCC_UNSELECT; }
546 	| SCC_LISTPG		{ $$ = SCC_LISTPG; }
547 	| SCC_ADDPG		{ $$ = SCC_ADDPG; }
548 	| SCC_DELPG		{ $$ = SCC_DELPG; }
549 	| SCC_DELHASH		{ $$ = SCC_DELHASH; }
550 	| SCC_LISTPROP		{ $$ = SCC_LISTPROP; }
551 	| SCC_SETPROP		{ $$ = SCC_SETPROP; }
552 	| SCC_DELPROP		{ $$ = SCC_DELPROP; }
553 	| SCC_EDITPROP		{ $$ = SCC_EDITPROP; }
554 	| SCC_ADDPROPVALUE	{ $$ = SCC_ADDPROPVALUE; }
555 	| SCC_DELPROPVALUE	{ $$ = SCC_DELPROPVALUE; }
556 	| SCC_SETENV		{ $$ = SCC_SETENV; }
557 	| SCC_UNSETENV		{ $$ = SCC_UNSETENV; }
558 	| SCC_LISTSNAP		{ $$ = SCC_LISTSNAP; }
559 	| SCC_SELECTSNAP	{ $$ = SCC_SELECTSNAP; }
560 	| SCC_REVERT		{ $$ = SCC_REVERT; }
561 	| SCC_REFRESH		{ $$ = SCC_REFRESH; }
562