Commit | Line | Data |
---|---|---|
317350b1 DG |
1 | /* |
2 | * Copyright (c) 1993, David Greenman | |
3 | * All rights reserved. | |
4 | * | |
5 | * Redistribution and use in source and binary forms, with or without | |
6 | * modification, are permitted provided that the following conditions | |
7 | * are met: | |
8 | * 1. Redistributions of source code must retain the above copyright | |
9 | * notice, this list of conditions and the following disclaimer. | |
10 | * 2. Redistributions in binary form must reproduce the above copyright | |
11 | * notice, this list of conditions and the following disclaimer in the | |
12 | * documentation and/or other materials provided with the distribution. | |
13 | * 3. All advertising materials mentioning features or use of this software | |
14 | * must display the following acknowledgement: | |
15 | * This product includes software developed by David Greenman | |
16 | * 4. The name of the developer may be used to endorse or promote products | |
17 | * derived from this software without specific prior written permission. | |
18 | * | |
19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |
20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
29 | * SUCH DAMAGE. | |
30 | * | |
31 | * $Id: shell_imgact.c,v 1.3 1993/12/11 06:55:33 davidg Exp davidg $ | |
32 | */ | |
33 | ||
34 | #include "param.h" | |
35 | #include "systm.h" | |
36 | #include "resourcevar.h" | |
37 | #include "imgact.h" | |
38 | ||
39 | #define SHELLMAGIC 0x2123 /* #! */ | |
40 | #define MAXSHELLCMDLEN 64 | |
41 | ||
42 | /* | |
43 | * Shell interpreter image activator. A interpreter name beginning | |
44 | * at iparams->stringbase is the minimal successful exit requirement. | |
45 | */ | |
46 | int | |
47 | exec_shell_imgact(iparams) | |
48 | struct image_params *iparams; | |
49 | { | |
50 | const char *image_header = iparams->image_header; | |
51 | const char *ihp, *line_endp; | |
52 | int length; | |
53 | char *interp; | |
54 | char **argv; | |
55 | ||
56 | /* a shell script? */ | |
57 | if (((short *) image_header)[0] != SHELLMAGIC) | |
58 | return(-1); | |
59 | ||
60 | /* | |
61 | * Don't allow a shell script to be the shell for a shell | |
62 | * script. :-) | |
63 | */ | |
64 | if (iparams->interpreted) | |
65 | return(ENOEXEC); | |
66 | ||
67 | iparams->interpreted = 1; | |
68 | ||
69 | /* | |
70 | * Copy shell name and arguments from image_header into string | |
71 | * buffer. | |
72 | */ | |
73 | ||
74 | /* | |
75 | * Find end of line; return if the line > MAXSHELLCMDLEN long. | |
76 | */ | |
77 | for (ihp = &image_header[2]; *ihp != '\n'; ++ihp) { | |
78 | if (ihp >= &image_header[MAXSHELLCMDLEN]) | |
79 | return(ENOEXEC); | |
80 | } | |
81 | line_endp = ihp; | |
82 | ||
83 | /* reset for another pass */ | |
84 | ihp = &image_header[2]; | |
85 | ||
86 | /* Skip over leading spaces - until the interpreter name */ | |
87 | while ((*ihp == ' ') || (*ihp == '\t')) ihp++; | |
88 | ||
89 | /* copy the interpreter name */ | |
90 | interp = iparams->interpreter_name; | |
91 | while ((ihp < line_endp) && (*ihp != ' ') && (*ihp != '\t')) | |
92 | *interp++ = *ihp++; | |
93 | *interp = '\0'; | |
94 | ||
95 | /* Disallow a null interpreter filename */ | |
96 | if (*iparams->interpreter_name == '\0') | |
97 | return(ENOEXEC); | |
98 | ||
99 | /* reset for another pass */ | |
100 | ihp = &image_header[2]; | |
101 | ||
102 | /* copy the interpreter name and arguments */ | |
103 | while (ihp < line_endp) { | |
104 | /* Skip over leading spaces */ | |
105 | while ((*ihp == ' ') || (*ihp == '\t')) ihp++; | |
106 | ||
107 | if (ihp < line_endp) { | |
108 | /* | |
109 | * Copy to end of token. No need to watch stringspace | |
110 | * because this is at the front of the string buffer | |
111 | * and the maximum shell command length is tiny. | |
112 | */ | |
113 | while ((ihp < line_endp) && (*ihp != ' ') && (*ihp != '\t')) { | |
114 | *iparams->stringp++ = *ihp++; | |
115 | iparams->stringspace--; | |
116 | } | |
117 | ||
118 | *iparams->stringp++ = 0; | |
119 | iparams->stringspace--; | |
120 | ||
121 | iparams->argc++; | |
122 | } | |
123 | } | |
124 | ||
125 | /* set argv[0] to point to original file name */ | |
126 | suword(iparams->uap->argv, (int)iparams->uap->fname); | |
127 | ||
128 | return(0); | |
129 | } |