Commit | Line | Data |
---|---|---|
965cadcc GW |
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 | * | |
3228baa0 | 31 | * $Id: imgact_shell.c,v 1.1 1993/12/20 16:16:46 wollman Exp $ |
965cadcc GW |
32 | */ |
33 | ||
34 | #include "param.h" | |
35 | #include "systm.h" | |
36 | #include "resourcevar.h" | |
37 | #include "imgact.h" | |
3228baa0 GW |
38 | #include "kernel.h" |
39 | #include "machine/endian.h" | |
965cadcc | 40 | |
3228baa0 | 41 | #if BYTE_ORDER == LITTLE_ENDIAN |
965cadcc | 42 | #define SHELLMAGIC 0x2123 /* #! */ |
3228baa0 GW |
43 | #else |
44 | #define SHELLMAGIC 0x2321 | |
45 | #endif | |
46 | ||
965cadcc GW |
47 | #define MAXSHELLCMDLEN 64 |
48 | ||
49 | /* | |
50 | * Shell interpreter image activator. A interpreter name beginning | |
51 | * at iparams->stringbase is the minimal successful exit requirement. | |
52 | */ | |
53 | int | |
54 | exec_shell_imgact(iparams) | |
55 | struct image_params *iparams; | |
56 | { | |
57 | const char *image_header = iparams->image_header; | |
58 | const char *ihp, *line_endp; | |
59 | int length; | |
60 | char *interp; | |
61 | char **argv; | |
62 | ||
63 | /* a shell script? */ | |
64 | if (((short *) image_header)[0] != SHELLMAGIC) | |
65 | return(-1); | |
66 | ||
67 | /* | |
68 | * Don't allow a shell script to be the shell for a shell | |
69 | * script. :-) | |
70 | */ | |
71 | if (iparams->interpreted) | |
72 | return(ENOEXEC); | |
73 | ||
74 | iparams->interpreted = 1; | |
75 | ||
76 | /* | |
77 | * Copy shell name and arguments from image_header into string | |
78 | * buffer. | |
79 | */ | |
80 | ||
81 | /* | |
82 | * Find end of line; return if the line > MAXSHELLCMDLEN long. | |
83 | */ | |
84 | for (ihp = &image_header[2]; *ihp != '\n'; ++ihp) { | |
85 | if (ihp >= &image_header[MAXSHELLCMDLEN]) | |
86 | return(ENOEXEC); | |
87 | } | |
88 | line_endp = ihp; | |
89 | ||
90 | /* reset for another pass */ | |
91 | ihp = &image_header[2]; | |
92 | ||
93 | /* Skip over leading spaces - until the interpreter name */ | |
94 | while ((*ihp == ' ') || (*ihp == '\t')) ihp++; | |
95 | ||
96 | /* copy the interpreter name */ | |
97 | interp = iparams->interpreter_name; | |
98 | while ((ihp < line_endp) && (*ihp != ' ') && (*ihp != '\t')) | |
99 | *interp++ = *ihp++; | |
100 | *interp = '\0'; | |
101 | ||
102 | /* Disallow a null interpreter filename */ | |
103 | if (*iparams->interpreter_name == '\0') | |
104 | return(ENOEXEC); | |
105 | ||
106 | /* reset for another pass */ | |
107 | ihp = &image_header[2]; | |
108 | ||
109 | /* copy the interpreter name and arguments */ | |
110 | while (ihp < line_endp) { | |
111 | /* Skip over leading spaces */ | |
112 | while ((*ihp == ' ') || (*ihp == '\t')) ihp++; | |
113 | ||
114 | if (ihp < line_endp) { | |
115 | /* | |
116 | * Copy to end of token. No need to watch stringspace | |
117 | * because this is at the front of the string buffer | |
118 | * and the maximum shell command length is tiny. | |
119 | */ | |
120 | while ((ihp < line_endp) && (*ihp != ' ') && (*ihp != '\t')) { | |
121 | *iparams->stringp++ = *ihp++; | |
122 | iparams->stringspace--; | |
123 | } | |
124 | ||
125 | *iparams->stringp++ = 0; | |
126 | iparams->stringspace--; | |
127 | ||
128 | iparams->argc++; | |
129 | } | |
130 | } | |
131 | ||
132 | /* set argv[0] to point to original file name */ | |
133 | suword(iparams->uap->argv, (int)iparams->uap->fname); | |
134 | ||
135 | return(0); | |
136 | } | |
3228baa0 GW |
137 | |
138 | /* | |
139 | * Tell kern_execve.c about it, with a little help from the linker. | |
140 | * Since `const' objects end up in the text segment, TEXT_SET is the | |
141 | * correct directive to use. | |
142 | */ | |
143 | static const struct execsw shell_execsw = { exec_shell_imgact }; | |
144 | TEXT_SET(execsw_set, shell_execsw); |