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