xref: /illumos-gate/usr/src/cmd/svc/svccfg/svccfg.l (revision fcdb3229a31dd4ff700c69238814e326aad49098)
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 #include <libintl.h>
28 #include <string.h>
29 
30 #include "svccfg.h"
31 #include "svccfg_grammar.h"
32 
33 /*
34  * We need to undefine lex's input, unput, and output macros so that references
35  * to these call the functions we provide at the end of this source file,
36  * instead of the default versions based on libc's stdio.
37  */
38 #ifdef input
39 #undef input
40 #endif
41 
42 #ifdef unput
43 #undef unput
44 #endif
45 
46 #ifdef output
47 #undef output
48 #endif
49 
50 static int input(void);
51 static void unput(int);
52 static void output(int);
53 
54 int parens = 0;
55 
56 extern int yyerror(const char *);
57 
58 %}
59 
60 /*
61  * Since command tokens are only valid at the beginning of the command (or
62  * after help), we'll only return them in the INITIAL state, and report them
63  * as SCV_WORDs afterwards.
64  */
65 %Start	WORD
66 
67 /*
68  * The default value of lex for transitions is 2000 and it seems we reached it.
69  * So we are bumping it up!
70  */
71 %a 3000
72 
73 %%
74 
75 #.*$			;	/* comments */
76 
77 <INITIAL>validate	{ BEGIN WORD; return (SCC_VALIDATE); }
78 <INITIAL>import		{ BEGIN WORD; return (SCC_IMPORT); }
79 <INITIAL>cleanup	{ BEGIN WORD; return (SCC_CLEANUP); }
80 <INITIAL>export		{ BEGIN WORD; return (SCC_EXPORT); }
81 <INITIAL>archive	{ BEGIN WORD; return (SCC_ARCHIVE); }
82 <INITIAL>restore	{ BEGIN WORD; return (SCC_RESTORE); }
83 <INITIAL>apply		{ BEGIN WORD; return (SCC_APPLY); }
84 <INITIAL>extract	{ BEGIN WORD; return (SCC_EXTRACT); }
85 <INITIAL>repository	{ BEGIN WORD; return (SCC_REPOSITORY); }
86 <INITIAL>inventory	{ BEGIN WORD; return (SCC_INVENTORY); }
87 <INITIAL>set		{ BEGIN WORD; return (SCC_SET); }
88 <INITIAL>end		{ BEGIN WORD; return (SCC_END); }
89 <INITIAL>exit		{ BEGIN WORD; return (SCC_END); }
90 <INITIAL>quit		{ BEGIN WORD; return (SCC_END); }
91 <INITIAL>help		{ return (SCC_HELP); }
92 
93 <INITIAL>list		{ BEGIN WORD; return (SCC_LIST); }
94 <INITIAL>add		{ BEGIN WORD; return (SCC_ADD); }
95 <INITIAL>delete		{ BEGIN WORD; return (SCC_DELETE); }
96 <INITIAL>select		{ BEGIN WORD; return (SCC_SELECT); }
97 <INITIAL>unselect	{ BEGIN WORD; return (SCC_UNSELECT); }
98 
99 <INITIAL>listpg		{ BEGIN WORD; return (SCC_LISTPG); }
100 <INITIAL>addpg		{ BEGIN WORD; return (SCC_ADDPG); }
101 <INITIAL>delpg		{ BEGIN WORD; return (SCC_DELPG); }
102 <INITIAL>delhash	{ BEGIN WORD; return (SCC_DELHASH); }
103 <INITIAL>listprop	{ BEGIN WORD; return (SCC_LISTPROP); }
104 <INITIAL>setprop	{ BEGIN WORD; return (SCC_SETPROP); }
105 <INITIAL>delprop	{ BEGIN WORD; return (SCC_DELPROP); }
106 <INITIAL>editprop	{ BEGIN WORD; return (SCC_EDITPROP); }
107 <INITIAL>describe	{ BEGIN WORD; return (SCC_DESCRIBE); }
108 <INITIAL>addpropvalue	{ BEGIN WORD; return (SCC_ADDPROPVALUE); }
109 <INITIAL>delpropvalue	{ BEGIN WORD; return (SCC_DELPROPVALUE); }
110 <INITIAL>setenv		{ BEGIN WORD; return (SCC_SETENV); }
111 <INITIAL>unsetenv	{ BEGIN WORD; return (SCC_UNSETENV); }
112 
113 <INITIAL>listsnap	{ BEGIN WORD; return (SCC_LISTSNAP); }
114 <INITIAL>selectsnap	{ BEGIN WORD; return (SCC_SELECTSNAP); }
115 <INITIAL>revert		{ BEGIN WORD; return (SCC_REVERT); }
116 <INITIAL>refresh	{ BEGIN WORD; return (SCC_REFRESH); }
117 
118 <INITIAL>delnotify	{ BEGIN WORD; return (SCC_DELNOTIFY); }
119 <INITIAL>listnotify	{ BEGIN WORD; return (SCC_LISTNOTIFY); }
120 <INITIAL>setnotify	{ BEGIN WORD; return (SCC_SETNOTIFY); }
121 
122 [^ \t\n">=()]+		{
123 				if ((yylval.str = strdup(yytext)) == NULL) {
124 					yyerror(gettext("Out of memory"));
125 					exit(UU_EXIT_FATAL);
126 				}
127 
128 				return SCV_WORD;
129 			}
130 
131 \"([^"\\]|\\.)*\"	{
132 				/*
133 				 * double-quoted strings start at a
134 				 * double-quote, include characters other than
135 				 * double-quote and backslash, and
136 				 * backslashed-characters, and end with a
137 				 * double-quote.
138 				 */
139 
140 				char *str, *cp;
141 				int shift;
142 
143 				if ((str = strdup(yytext)) == NULL) {
144 					yyerror(gettext("Out of memory"));
145 					exit(UU_EXIT_FATAL);
146 				}
147 
148 				/* Strip out the backslashes. */
149 				for (cp = str, shift = 0; *cp != '\0'; ++cp) {
150 					if (*cp == '\\') {
151 						++cp;
152 
153 						/*
154 						 * This can't be null because
155 						 * the string always ends with
156 						 * a double-quote.
157 						 */
158 
159 						++shift;
160 						*(cp - shift) = *cp;
161 					} else if (shift != 0)
162 						*(cp - shift) = *cp;
163 				}
164 
165 				/* Nullify everything after trailing quote */
166 				*(cp - shift) = '\0';
167 
168 				yylval.str = str;
169 				return SCV_STRING;
170 			}
171 
172 \n			{
173 				est->sc_cmd_lineno++;
174 				BEGIN INITIAL;
175 				return (SCS_NEWLINE);
176 			}
177 
178 [ \t]+			;
179 
180 ">"			{ return SCS_REDIRECT; }
181 "="			{ return SCS_EQUALS; }
182 "("			{ ++parens; return SCS_LPAREN; }
183 ")"			{ --parens; return SCS_RPAREN; }
184 
185 .			{
186 				uu_die(gettext("unrecognized character %s\n"),
187 				    yytext);
188 			}
189 
190 %%
191 
192 int
193 yyerror(const char *s)
194 {
195 	return (0);
196 }
197 
198 static int
199 input(void)
200 {
201 	static int saw_eof = 0;
202 
203 	int c = engine_cmd_getc(est);
204 
205 	/*
206 	 * To ensure input is terminated, slip in a newline on EOF.
207 	 */
208 	if (c == EOF) {
209 		if (saw_eof)
210 			return (0);
211 
212 		saw_eof = 1;
213 		return ('\n');
214 	} else
215 		saw_eof = 0;
216 
217 	if (c == '\n')
218 		yylineno++;
219 
220 	return (c);
221 }
222 
223 static void
224 unput(int c)
225 {
226 	if (c == '\n')
227 		yylineno--;
228 
229 	(void) engine_cmd_ungetc(est, c == 0 ? EOF : c);
230 }
231 
232 static void
233 output(int c)
234 {
235 	char ch = c;
236 	engine_cmd_nputs(est, &ch, sizeof (ch));
237 }
238