imgact_shell.c revision 886
1284990Scy/*
2284990Scy * Copyright (c) 1993, David Greenman
3284990Scy * All rights reserved.
4289997Sglebius *
5284990Scy * Redistribution and use in source and binary forms, with or without
6284990Scy * modification, are permitted provided that the following conditions
7284990Scy * are met:
8284990Scy * 1. Redistributions of source code must retain the above copyright
9289997Sglebius *    notice, this list of conditions and the following disclaimer.
10289997Sglebius * 2. Redistributions in binary form must reproduce the above copyright
11289997Sglebius *    notice, this list of conditions and the following disclaimer in the
12289997Sglebius *    documentation and/or other materials provided with the distribution.
13289997Sglebius * 3. All advertising materials mentioning features or use of this software
14289997Sglebius *    must display the following acknowledgement:
15289997Sglebius *	This product includes software developed by David Greenman
16289997Sglebius * 4. The name of the developer may be used to endorse or promote products
17289997Sglebius *    derived from this software without specific prior written permission.
18284990Scy *
19289997Sglebius * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20289997Sglebius * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21284990Scy * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22289997Sglebius * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23289997Sglebius * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24284990Scy * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25284990Scy * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26284990Scy * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27289997Sglebius * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28289997Sglebius * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29284990Scy * SUCH DAMAGE.
30289997Sglebius *
31289997Sglebius *	$Id: imgact_shell.c,v 1.1 1993/12/20 16:16:46 wollman Exp $
32284990Scy */
33284990Scy
34284990Scy#include "param.h"
35284990Scy#include "systm.h"
36284990Scy#include "resourcevar.h"
37284990Scy#include "imgact.h"
38289997Sglebius#include "kernel.h"
39289997Sglebius#include "machine/endian.h"
40284990Scy
41284990Scy#if BYTE_ORDER == LITTLE_ENDIAN
42284990Scy#define SHELLMAGIC	0x2123 /* #! */
43284990Scy#else
44284990Scy#define SHELLMAGIC	0x2321
45284990Scy#endif
46284990Scy
47284990Scy#define MAXSHELLCMDLEN	64
48284990Scy
49284990Scy/*
50284990Scy * Shell interpreter image activator. A interpreter name beginning
51284990Scy *	at iparams->stringbase is the minimal successful exit requirement.
52284990Scy */
53289997Sglebiusint
54289997Sglebiusexec_shell_imgact(iparams)
55289997Sglebius	struct image_params *iparams;
56284990Scy{
57284990Scy	const char *image_header = iparams->image_header;
58284990Scy	const char *ihp, *line_endp;
59284990Scy	int length;
60284990Scy	char *interp;
61284990Scy	char **argv;
62284990Scy
63284990Scy	/* a shell script? */
64284990Scy	if (((short *) image_header)[0] != SHELLMAGIC)
65284990Scy		return(-1);
66284990Scy
67284990Scy	/*
68289997Sglebius	 * Don't allow a shell script to be the shell for a shell
69289997Sglebius	 *	script. :-)
70284990Scy	 */
71284990Scy	if (iparams->interpreted)
72284990Scy		return(ENOEXEC);
73284990Scy
74284990Scy	iparams->interpreted = 1;
75284990Scy
76284990Scy	/*
77284990Scy	 * Copy shell name and arguments from image_header into string
78284990Scy	 *	buffer.
79284990Scy	 */
80284990Scy
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}
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 */
143static const struct execsw shell_execsw = { exec_shell_imgact };
144TEXT_SET(execsw_set, shell_execsw);
145