1 /*-
2 * Copyright (c) 1988, 1989, 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 1988, 1989 by Adam de Boor
5 * Copyright (c) 1989 by Berkeley Softworks
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Adam de Boor.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the University of
22 * California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 */
39
40 #include <sys/cdefs.h>
41 __FBSDID("$FreeBSD$");
42
43 #include <sys/queue.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47
48 #include "parse.h"
49 #include "pathnames.h"
50 #include "shell.h"
51 #include "util.h"
52
53 /*
54 * Descriptions for various shells. What the list of builtins should contain
55 * is debatable: either all builtins or only those which may specified on
56 * a single line without use of meta-characters. For correct makefiles that
57 * contain only correct command lines there is no difference. But if a command
58 * line, for example, is: 'if -foo bar' and there is an executable named 'if'
59 * in the path, the first possibility would execute that 'if' while in the
60 * second case the shell would give an error. Histerically only a small
61 * subset of the builtins and no reserved words where given in the list which
62 * corresponds roughly to the first variant. So go with this but add missing
63 * words.
64 */
65 #define CSH_BUILTINS \
66 "alias cd eval exec exit read set ulimit unalias " \
67 "umask unset wait"
68
69 #define SH_BUILTINS \
70 "alias cd eval exec exit read set ulimit unalias " \
71 "umask unset wait"
72
73 #define CSH_META "#=|^(){};&<>*?[]:$`\\@\n"
74 #define SH_META "#=|^(){};&<>*?[]:$`\\\n"
75
76 static const char *const shells_init[] = {
77 /*
78 * CSH description. The csh can do echo control by playing
79 * with the setting of the 'echo' shell variable. Sadly,
80 * however, it is unable to do error control nicely.
81 */
82 "name=csh path='" PATH_DEFSHELLDIR "/csh' "
83 "quiet='unset verbose' echo='set verbose' filter='unset verbose' "
84 "hasErrCtl=N check='echo \"%s\"\n' ignore='csh -c \"%s || exit 0\"' "
85 "echoFlag=v errFlag=e "
86 "meta='" CSH_META "' builtins='" CSH_BUILTINS "'",
87
88 /*
89 * SH description. Echo control is also possible and, under
90 * sun UNIX anyway, one can even control error checking.
91 */
92 "name=sh path='" PATH_DEFSHELLDIR "/sh' "
93 "quiet='set -' echo='set -v' filter='set -' "
94 "hasErrCtl=Y check='set -e' ignore='set +e' "
95 "echoFlag=v errFlag=e "
96 "meta='" SH_META "' builtins='" SH_BUILTINS "'",
97
98 /*
99 * KSH description. The Korn shell has a superset of
100 * the Bourne shell's functionality. There are probably builtins
101 * missing here.
102 */
103 "name=ksh path='" PATH_DEFSHELLDIR "/ksh' "
104 "quiet='set -' echo='set -v' filter='set -' "
105 "hasErrCtl=Y check='set -e' ignore='set +e' "
106 "echoFlag=v errFlag=e "
107 "meta='" SH_META "' builtins='" SH_BUILTINS "' unsetenv=T",
108
109 NULL
110 };
111
112 /*
113 * This is the shell to which we pass all commands in the Makefile.
114 * It is set by the Job_ParseShell function.
115 */
116 struct Shell *commandShell;
117
118 /*
119 * This is the list of all known shells.
120 */
121 static struct Shells shells = TAILQ_HEAD_INITIALIZER(shells);
122
123 void ShellDump(const struct Shell *) __unused;
124
125 /**
126 * Helper function for sorting the builtin list alphabetically.
127 */
128 static int
sort_builtins(const void * p1,const void * p2)129 sort_builtins(const void *p1, const void *p2)
130 {
131
132 return (strcmp(*(const char* const*)p1, *(const char* const*)p2));
133 }
134
135 /**
136 * Free a shell structure and all associated strings.
137 */
138 static void
ShellFree(struct Shell * sh)139 ShellFree(struct Shell *sh)
140 {
141
142 if (sh != NULL) {
143 free(sh->name);
144 free(sh->path);
145 free(sh->echoOff);
146 free(sh->echoOn);
147 free(sh->noPrint);
148 free(sh->errCheck);
149 free(sh->ignErr);
150 free(sh->echo);
151 free(sh->exit);
152 ArgArray_Done(&sh->builtins);
153 free(sh->meta);
154 free(sh);
155 }
156 }
157
158 /**
159 * Dump a shell specification to stderr.
160 */
161 void
ShellDump(const struct Shell * sh)162 ShellDump(const struct Shell *sh)
163 {
164 int i;
165
166 fprintf(stderr, "Shell %p:\n", sh);
167 fprintf(stderr, " name='%s' path='%s'\n", sh->name, sh->path);
168 fprintf(stderr, " hasEchoCtl=%d echoOff='%s' echoOn='%s'\n",
169 sh->hasEchoCtl, sh->echoOff, sh->echoOn);
170 fprintf(stderr, " noPrint='%s'\n", sh->noPrint);
171 fprintf(stderr, " hasErrCtl=%d errCheck='%s' ignErr='%s'\n",
172 sh->hasErrCtl, sh->errCheck, sh->ignErr);
173 fprintf(stderr, " echo='%s' exit='%s'\n", sh->echo, sh->exit);
174 fprintf(stderr, " builtins=%d\n", sh->builtins.argc - 1);
175 for (i = 1; i < sh->builtins.argc; i++)
176 fprintf(stderr, " '%s'", sh->builtins.argv[i]);
177 fprintf(stderr, "\n meta='%s'\n", sh->meta);
178 fprintf(stderr, " unsetenv=%d\n", sh->unsetenv);
179 }
180
181 /**
182 * Parse a shell specification line and return the new Shell structure.
183 * In case of an error a message is printed and NULL is returned.
184 */
185 static struct Shell *
ShellParseSpec(const char * spec,Boolean * fullSpec)186 ShellParseSpec(const char *spec, Boolean *fullSpec)
187 {
188 ArgArray aa;
189 struct Shell *sh;
190 char *eq;
191 char *keyw;
192 int arg;
193
194 *fullSpec = FALSE;
195
196 sh = emalloc(sizeof(*sh));
197 memset(sh, 0, sizeof(*sh));
198 ArgArray_Init(&sh->builtins);
199
200 /*
201 * Parse the specification by keyword but skip the first word
202 */
203 brk_string(&aa, spec, TRUE);
204
205 for (arg = 1; arg < aa.argc; arg++) {
206 /*
207 * Split keyword and value
208 */
209 keyw = aa.argv[arg];
210 if ((eq = strchr(keyw, '=')) == NULL) {
211 Parse_Error(PARSE_FATAL, "missing '=' in shell "
212 "specification keyword '%s'", keyw);
213 ArgArray_Done(&aa);
214 ShellFree(sh);
215 return (NULL);
216 }
217 *eq++ = '\0';
218
219 if (strcmp(keyw, "path") == 0) {
220 free(sh->path);
221 sh->path = estrdup(eq);
222 } else if (strcmp(keyw, "name") == 0) {
223 free(sh->name);
224 sh->name = estrdup(eq);
225 } else if (strcmp(keyw, "quiet") == 0) {
226 free(sh->echoOff);
227 sh->echoOff = estrdup(eq);
228 *fullSpec = TRUE;
229 } else if (strcmp(keyw, "echo") == 0) {
230 free(sh->echoOn);
231 sh->echoOn = estrdup(eq);
232 *fullSpec = TRUE;
233 } else if (strcmp(keyw, "filter") == 0) {
234 free(sh->noPrint);
235 sh->noPrint = estrdup(eq);
236 *fullSpec = TRUE;
237 } else if (strcmp(keyw, "echoFlag") == 0) {
238 free(sh->echo);
239 sh->echo = estrdup(eq);
240 *fullSpec = TRUE;
241 } else if (strcmp(keyw, "errFlag") == 0) {
242 free(sh->exit);
243 sh->exit = estrdup(eq);
244 *fullSpec = TRUE;
245 } else if (strcmp(keyw, "hasErrCtl") == 0) {
246 sh->hasErrCtl = (*eq == 'Y' || *eq == 'y' ||
247 *eq == 'T' || *eq == 't');
248 *fullSpec = TRUE;
249 } else if (strcmp(keyw, "check") == 0) {
250 free(sh->errCheck);
251 sh->errCheck = estrdup(eq);
252 *fullSpec = TRUE;
253 } else if (strcmp(keyw, "ignore") == 0) {
254 free(sh->ignErr);
255 sh->ignErr = estrdup(eq);
256 *fullSpec = TRUE;
257 } else if (strcmp(keyw, "builtins") == 0) {
258 ArgArray_Done(&sh->builtins);
259 brk_string(&sh->builtins, eq, TRUE);
260 qsort(sh->builtins.argv + 1, sh->builtins.argc - 1,
261 sizeof(char *), sort_builtins);
262 *fullSpec = TRUE;
263 } else if (strcmp(keyw, "meta") == 0) {
264 free(sh->meta);
265 sh->meta = estrdup(eq);
266 *fullSpec = TRUE;
267 } else if (strcmp(keyw, "unsetenv") == 0) {
268 sh->unsetenv = (*eq == 'Y' || *eq == 'y' ||
269 *eq == 'T' || *eq == 't');
270 *fullSpec = TRUE;
271 } else {
272 Parse_Error(PARSE_FATAL, "unknown keyword in shell "
273 "specification '%s'", keyw);
274 ArgArray_Done(&aa);
275 ShellFree(sh);
276 return (NULL);
277 }
278 }
279 ArgArray_Done(&aa);
280
281 /*
282 * Some checks (could be more)
283 */
284 if (*fullSpec) {
285 if ((sh->echoOn != NULL) ^ (sh->echoOff != NULL)) {
286 Parse_Error(PARSE_FATAL, "Shell must have either both "
287 "echoOff and echoOn or none of them");
288 ShellFree(sh);
289 return (NULL);
290 }
291
292 if (sh->echoOn != NULL && sh->echoOff != NULL)
293 sh->hasEchoCtl = TRUE;
294 }
295
296 return (sh);
297 }
298
299 /**
300 * Parse the builtin shell specifications and put them into the shell
301 * list. Then select the default shell to be the current shell. This
302 * is called from main() before any parsing (including MAKEFLAGS and
303 * command line) is done.
304 */
305 void
Shell_Init(void)306 Shell_Init(void)
307 {
308 int i;
309 struct Shell *sh;
310 Boolean fullSpec;
311
312 for (i = 0; shells_init[i] != NULL; i++) {
313 sh = ShellParseSpec(shells_init[i], &fullSpec);
314 TAILQ_INSERT_TAIL(&shells, sh, link);
315 if (strcmp(sh->name, DEFSHELLNAME) == 0)
316 commandShell = sh;
317 }
318 }
319
320 /**
321 * Find a matching shell in 'shells' given its final component.
322 *
323 * Results:
324 * A pointer to a freshly allocated Shell structure with the contents
325 * from static description or NULL if no shell with the given name
326 * is found.
327 */
328 static struct Shell *
ShellMatch(const char * name)329 ShellMatch(const char *name)
330 {
331 struct Shell *sh;
332
333 TAILQ_FOREACH(sh, &shells, link)
334 if (strcmp(sh->name, name) == 0)
335 return (sh);
336
337 return (NULL);
338 }
339
340 /**
341 * Parse a shell specification and set up commandShell appropriately.
342 *
343 * Results:
344 * TRUE if the specification was correct. FALSE otherwise.
345 *
346 * Side Effects:
347 * commandShell points to a Shell structure.
348 * created from the shell spec).
349 *
350 * Notes:
351 * A shell specification consists of a .SHELL target, with dependency
352 * operator, followed by a series of blank-separated words. Double
353 * quotes can be used to use blanks in words. A backslash escapes
354 * anything (most notably a double-quote and a space) and
355 * provides the functionality it does in C. Each word consists of
356 * keyword and value separated by an equal sign. There should be no
357 * unnecessary spaces in the word. The keywords are as follows:
358 * name Name of shell.
359 * path Location of shell. Overrides "name" if given
360 * quiet Command to turn off echoing.
361 * echo Command to turn echoing on
362 * filter Result of turning off echoing that shouldn't be
363 * printed.
364 * echoFlag Flag to turn echoing on at the start
365 * errFlag Flag to turn error checking on at the start
366 * hasErrCtl True if shell has error checking control
367 * check Command to turn on error checking if hasErrCtl
368 * is TRUE or template of command to echo a command
369 * for which error checking is off if hasErrCtl is
370 * FALSE.
371 * ignore Command to turn off error checking if hasErrCtl
372 * is TRUE or template of command to execute a
373 * command so as to ignore any errors it returns if
374 * hasErrCtl is FALSE.
375 * builtins A space separated list of builtins. If one
376 * of these builtins is detected when make wants
377 * to execute a command line, the command line is
378 * handed to the shell. Otherwise make may try to
379 * execute the command directly. If this list is empty
380 * it is assumed, that the command must always be
381 * handed over to the shell.
382 * meta The shell meta characters. If this is not specified
383 * or empty, commands are alway passed to the shell.
384 * Otherwise they are not passed when they contain
385 * neither a meta character nor a builtin command.
386 * unsetenv Unsetenv("ENV") before executing anything.
387 */
388 Boolean
Shell_Parse(const char line[])389 Shell_Parse(const char line[])
390 {
391 Boolean fullSpec;
392 struct Shell *sh;
393 struct Shell *match;
394
395 /* parse the specification */
396 if ((sh = ShellParseSpec(line, &fullSpec)) == NULL)
397 return (FALSE);
398
399 if (sh->path == NULL) {
400 /*
401 * If no path was given, the user wants one of the pre-defined
402 * shells, yes? So we find the one s/he wants with the help of
403 * JobMatchShell and set things up the right way.
404 */
405 if (sh->name == NULL) {
406 Parse_Error(PARSE_FATAL,
407 "Neither path nor name specified");
408 ShellFree(sh);
409 return (FALSE);
410 }
411 if (fullSpec) {
412 /*
413 * XXX May want to merge sh into match. But this
414 * require ShellParseSpec to return information
415 * which attributes actuall have been specified.
416 */
417 Parse_Error(PARSE_FATAL, "No path specified");
418 ShellFree(sh);
419 return (FALSE);
420 }
421 if ((match = ShellMatch(sh->name)) == NULL) {
422 Parse_Error(PARSE_FATAL, "%s: no matching shell",
423 sh->name);
424 ShellFree(sh);
425 return (FALSE);
426 }
427 ShellFree(sh);
428 commandShell = match;
429
430 return (TRUE);
431 }
432
433 /*
434 * The user provided a path. If s/he gave nothing else
435 * (fullSpec is FALSE), try and find a matching shell in the
436 * ones we know of. Else we just take the specification at its
437 * word and copy it to a new location. In either case, we need
438 * to record the path the user gave for the shell.
439 */
440 if (sh->name == NULL) {
441 /* get the base name as the name */
442 if ((sh->name = strrchr(sh->path, '/')) == NULL) {
443 sh->name = estrdup(sh->path);
444 } else {
445 sh->name = estrdup(sh->name + 1);
446 }
447 }
448
449 if (!fullSpec) {
450 if ((match = ShellMatch(sh->name)) == NULL) {
451 Parse_Error(PARSE_FATAL,
452 "%s: no matching shell", sh->name);
453 ShellFree(sh);
454 return (FALSE);
455 }
456
457 /* set the patch on the matching shell */
458 free(match->path);
459 match->path = sh->path;
460 sh->path = NULL;
461
462 ShellFree(sh);
463 commandShell = match;
464 return (TRUE);
465 }
466
467 TAILQ_INSERT_HEAD(&shells, sh, link);
468
469 /* set the new shell */
470 commandShell = sh;
471 return (TRUE);
472 }
473