1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* $NetBSD: exec.c,v 1.37 2003/08/07 09:05:31 agc Exp $ */ 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*- 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (c) 1991, 1993 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * The Regents of the University of California. All rights reserved. 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * This code is derived from software contributed to Berkeley by 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Kenneth Almquist. 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Redistribution and use in source and binary forms, with or without 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * modification, are permitted provided that the following conditions 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * are met: 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * notice, this list of conditions and the following disclaimer. 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * documentation and/or other materials provided with the distribution. 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 3. Neither the name of the University nor the names of its contributors 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * may be used to endorse or promote products derived from this software 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * without specific prior written permission. 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * SUCH DAMAGE. 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/cdefs.h> 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef lint 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char sccsid[] = "@(#)exec.c 8.4 (Berkeley) 6/8/95"; 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project__RCSID("$NetBSD: exec.c,v 1.37 2003/08/07 09:05:31 agc Exp $"); 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* not lint */ 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/types.h> 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/stat.h> 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/wait.h> 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h> 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * When commands are first encountered, they are entered in a hash table. 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * This ensures that a full path search will not have to be done for them 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * on each invocation. 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * We should investigate converting to a linear search, even though that 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * would make the command name "hash" a misnomer. 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "shell.h" 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "main.h" 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "nodes.h" 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "parser.h" 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "redir.h" 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "eval.h" 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "exec.h" 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "builtins.h" 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "var.h" 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "options.h" 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "input.h" 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "output.h" 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "syntax.h" 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "memalloc.h" 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "error.h" 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "init.h" 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "mystring.h" 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "show.h" 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "jobs.h" 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "alias.h" 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define CMDTABLESIZE 31 /* should be prime */ 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define ARB 1 /* actual size determined at run time */ 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct tblentry { 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct tblentry *next; /* next entry in hash chain */ 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project union param param; /* definition of builtin function */ 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project short cmdtype; /* index identifying command */ 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char rehash; /* if set, cd done since entry created */ 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char cmdname[ARB]; /* name of command */ 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC struct tblentry *cmdtable[CMDTABLESIZE]; 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC int builtinloc = -1; /* index in path of %builtin, or -1 */ 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint exerrno = 0; /* Last exec error */ 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void tryexec(char *, char **, char **, int); 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void execinterp(char **, char **); 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void printentry(struct tblentry *, int); 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void clearcmdentry(int); 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC struct tblentry *cmdlookup(const char *, int); 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void delete_cmd_entry(void); 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern char *const parsekwd[]; 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Exec a program. Never returns. If you change this routine, you may 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * have to change the find_command routine as well. 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectshellexec(char **argv, char **envp, const char *path, int idx, int vforked) 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *cmdname; 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int e; 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (strchr(argv[0], '/') != NULL) { 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tryexec(argv[0], argv, envp, vforked); 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project e = errno; 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project e = ENOENT; 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while ((cmdname = padvance(&path, argv[0])) != NULL) { 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (--idx < 0 && pathopt == NULL) { 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tryexec(cmdname, argv, envp, vforked); 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (errno != ENOENT && errno != ENOTDIR) 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project e = errno; 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project stunalloc(cmdname); 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Map to POSIX errors */ 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch (e) { 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case EACCES: 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exerrno = 126; 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case ENOENT: 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exerrno = 127; 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exerrno = 2; 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project TRACE(("shellexec failed for %s, errno %d, vforked %d, suppressint %d\n", 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argv[0], e, vforked, suppressint )); 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exerror(EXEXEC, "%s: %s", argv[0], errmsg(e, E_EXEC)); 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* NOTREACHED */ 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttryexec(char *cmd, char **argv, char **envp, int vforked) 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int e; 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef BSD 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p; 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef SYSV 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do { 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project execve(cmd, argv, envp); 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } while (errno == EINTR); 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project execve(cmd, argv, envp); 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project e = errno; 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (e == ENOEXEC) { 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (vforked) { 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* We are currently vfork(2)ed, so raise an 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * exception, and evalcommand will try again 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * with a normal fork(2). 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exraise(EXSHELLPROC); 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project initshellproc(); 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setinputfile(cmd, 0); 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project commandname = arg0 = savestr(argv[0]); 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if !defined(BSD) && !defined(__linux__) 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pgetc(); pungetc(); /* fill up input buffer */ 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = parsenextc; 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (parsenleft > 2 && p[0] == '#' && p[1] == '!') { 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argv[0] = cmd; 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project execinterp(argv, envp); 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setparam(argv + 1); 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exraise(EXSHELLPROC); 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project errno = e; 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if !defined(BSD) && !defined(__linux__) 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Execute an interpreter introduced by "#!", for systems where this 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * feature has not been built into the kernel. If the interpreter is 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * the shell, return (effectively ignoring the "#!"). If the execution 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * of the interpreter fails, exit. 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * This code peeks inside the input buffer in order to avoid actually 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * reading any input. It would benefit from a rewrite. 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define NEWARGS 5 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectexecinterp(char **argv, char **envp) 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int n; 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *inp; 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *outp; 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char c; 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p; 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char **ap; 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *newargs[NEWARGS]; 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i; 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char **ap2; 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char **new; 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project n = parsenleft - 2; 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project inp = parsenextc + 2; 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ap = newargs; 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (;;) { 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (--n >= 0 && (*inp == ' ' || *inp == '\t')) 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project inp++; 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (n < 0) 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto bad; 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((c = *inp++) == '\n') 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ap == &newargs[NEWARGS]) 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbad: error("Bad #! line"); 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project STARTSTACKSTR(outp); 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do { 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project STPUTC(c, outp); 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } while (--n >= 0 && (c = *inp++) != ' ' && c != '\t' && c != '\n'); 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project STPUTC('\0', outp); 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project n++, inp--; 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *ap++ = grabstackstr(outp); 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ap == newargs + 1) { /* if no args, maybe no exec is needed */ 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = newargs[0]; 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (;;) { 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (equal(p, "sh") || equal(p, "ash")) { 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (*p != '/') { 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*p == '\0') 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto break2; 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p++; 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p++; 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbreak2:; 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project i = (char *)ap - (char *)newargs; /* size in bytes */ 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (i == 0) 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("Bad #! line"); 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (ap2 = argv ; *ap2++ != NULL ; ); 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project new = ckmalloc(i + ((char *)ap2 - (char *)argv)); 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ap = newargs, ap2 = new; 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while ((i -= sizeof (char **)) >= 0) 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *ap2++ = *ap++; 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ap = argv; 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (*ap2++ = *ap++); 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project shellexec(new, envp, pathval(), 0); 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* NOTREACHED */ 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Do a path search. The variable path (passed by reference) should be 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * set to the start of the path before the first call; padvance will update 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * this value as it proceeds. Successive calls to padvance will return 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * the possible path expansions in sequence. If an option (indicated by 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * a percent sign) appears in the path entry then the global variable 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * pathopt will be set to point to it; otherwise pathopt will be set to 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * NULL. 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst char *pathopt; 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectchar * 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectpadvance(const char **path, const char *name) 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *p; 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *q; 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *start; 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*path == NULL) 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return NULL; 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project start = *path; 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (p = start ; *p && *p != ':' && *p != '%' ; p++); 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = p - start + strlen(name) + 2; /* "2" is for '/' and '\0' */ 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (stackblocksize() < len) 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project growstackblock(); 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project q = stackblock(); 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (p != start) { 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(q, start, p - start); 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project q += p - start; 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *q++ = '/'; 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy(q, name); 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pathopt = NULL; 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*p == '%') { 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pathopt = ++p; 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (*p && *p != ':') p++; 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*p == ':') 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *path = p + 1; 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *path = NULL; 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return stalloc(len); 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*** Command hashing code ***/ 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecthashcmd(int argc, char **argv) 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct tblentry **pp; 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct tblentry *cmdp; 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int c; 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int verbose; 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct cmdentry entry; 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *name; 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project verbose = 0; 341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while ((c = nextopt("rv")) != '\0') { 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (c == 'r') { 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project clearcmdentry(0); 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (c == 'v') { 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project verbose++; 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*argptr == NULL) { 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) { 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) { 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (verbose || cmdp->cmdtype == CMDNORMAL) 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printentry(cmdp, verbose); 353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while ((name = *argptr) != NULL) { 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((cmdp = cmdlookup(name, 0)) != NULL 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project && (cmdp->cmdtype == CMDNORMAL 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0))) 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project delete_cmd_entry(); 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project find_command(name, &entry, DO_ERR, pathval()); 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (verbose) { 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (entry.cmdtype != CMDUNKNOWN) { /* if no error msg */ 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp = cmdlookup(name, 0); 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printentry(cmdp, verbose); 367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project flushall(); 369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argptr++; 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void 377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectprintentry(struct tblentry *cmdp, int verbose) 378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int idx; 380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *path; 381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *name; 382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch (cmdp->cmdtype) { 384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CMDNORMAL: 385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project idx = cmdp->param.index; 386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project path = pathval(); 387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do { 388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name = padvance(&path, cmdp->cmdname); 389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project stunalloc(name); 390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } while (--idx >= 0); 391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1str(name); 392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CMDSPLBLTIN: 394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1fmt("special builtin %s", cmdp->cmdname); 395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CMDBUILTIN: 397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1fmt("builtin %s", cmdp->cmdname); 398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CMDFUNCTION: 400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1fmt("function %s", cmdp->cmdname); 401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (verbose) { 402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct procstat ps; 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project commandtext(&ps, cmdp->param.func); 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1str("() { "); 407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1str(ps.cmd); 408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1str("; }"); 409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("internal error: %s cmdtype %d", cmdp->cmdname, cmdp->cmdtype); 413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (cmdp->rehash) 415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1c('*'); 416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1c('\n'); 417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Resolve a command name. If you change this routine, you may have to 423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * change the shellexec routine as well. 424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfind_command(char *name, struct cmdentry *entry, int act, const char *path) 428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct tblentry *cmdp, loc_cmd; 430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int idx; 431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int prev; 432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *fullname; 433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct stat statb; 434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int e; 435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int (*bltin)(int,char **); 436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* If name contains a slash, don't use PATH or hash table */ 438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (strchr(name, '/') != NULL) { 439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (act & DO_ABS) { 440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (stat(name, &statb) < 0) { 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef SYSV 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (errno == EINTR) 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (errno != ENOENT && errno != ENOTDIR) 446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project e = errno; 447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project entry->cmdtype = CMDUNKNOWN; 448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project entry->u.index = -1; 449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project entry->cmdtype = CMDNORMAL; 452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project entry->u.index = -1; 453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project entry->cmdtype = CMDNORMAL; 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project entry->u.index = 0; 457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (path != pathval()) 461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project act |= DO_ALTPATH; 462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (act & DO_ALTPATH && strstr(path, "%builtin") != NULL) 464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project act |= DO_ALTBLTIN; 465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* If name is in the table, check answer will be ok */ 467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((cmdp = cmdlookup(name, 0)) != NULL) { 468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do { 469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch (cmdp->cmdtype) { 470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CMDNORMAL: 471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (act & DO_ALTPATH) { 472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp = NULL; 473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CMDFUNCTION: 477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (act & DO_NOFUNC) { 478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp = NULL; 479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CMDBUILTIN: 483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((act & DO_ALTBLTIN) || builtinloc >= 0) { 484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp = NULL; 485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* if not invalidated by cd, we're done */ 490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (cmdp->rehash == 0) 491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto success; 492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } while (0); 493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* If %builtin not in path, check for builtin next */ 496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((act & DO_ALTPATH ? !(act & DO_ALTBLTIN) : builtinloc < 0) && 497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (bltin = find_builtin(name)) != 0) 498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto builtin_success; 499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* We have to search path. */ 501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project prev = -1; /* where to start */ 502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (cmdp) { /* doing a rehash */ 503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (cmdp->cmdtype == CMDBUILTIN) 504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project prev = builtinloc; 505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project prev = cmdp->param.index; 507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project e = ENOENT; 510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project idx = -1; 511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectloop: 512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while ((fullname = padvance(&path, name)) != NULL) { 513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project stunalloc(fullname); 514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project idx++; 515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (pathopt) { 516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (prefix("builtin", pathopt)) { 517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((bltin = find_builtin(name)) == 0) 518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto loop; 519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto builtin_success; 520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (prefix("func", pathopt)) { 521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* handled below */ 522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* ignore unimplemented options */ 524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto loop; 525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* if rehash, don't redo absolute path names */ 528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fullname[0] == '/' && idx <= prev) { 529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (idx < prev) 530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto loop; 531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project TRACE(("searchexec \"%s\": no change\n", name)); 532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto success; 533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (stat(fullname, &statb) < 0) { 535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef SYSV 536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (errno == EINTR) 537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (errno != ENOENT && errno != ENOTDIR) 540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project e = errno; 541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto loop; 542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project e = EACCES; /* if we fail, this will be the error */ 544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!S_ISREG(statb.st_mode)) 545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto loop; 546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (pathopt) { /* this is a %func directory */ 547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (act & DO_NOFUNC) 548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto loop; 549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project stalloc(strlen(fullname) + 1); 550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project readcmdfile(fullname); 551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((cmdp = cmdlookup(name, 0)) == NULL || 552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp->cmdtype != CMDFUNCTION) 553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("%s not defined in %s", name, fullname); 554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project stunalloc(fullname); 555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto success; 556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef notdef 558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* XXX this code stops root executing stuff, and is buggy 559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if you need a group from the group list. */ 560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (statb.st_uid == geteuid()) { 561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((statb.st_mode & 0100) == 0) 562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto loop; 563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (statb.st_gid == getegid()) { 564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((statb.st_mode & 010) == 0) 565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto loop; 566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((statb.st_mode & 01) == 0) 568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto loop; 569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname)); 572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (act & DO_ALTPATH) { 574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project stalloc(strlen(fullname) + 1); 575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp = &loc_cmd; 576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else 577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp = cmdlookup(name, 1); 578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp->cmdtype = CMDNORMAL; 579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp->param.index = idx; 580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto success; 582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 583dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 584dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* We failed. If there was an entry for this command, delete it */ 585dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (cmdp) 586dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project delete_cmd_entry(); 587dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (act & DO_ERR) 588dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project outfmt(out2, "%s: %s\n", name, errmsg(e, E_EXEC)); 589dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project entry->cmdtype = CMDUNKNOWN; 590dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 591dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbuiltin_success: 593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (act & DO_ALTPATH) 595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp = &loc_cmd; 596dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 597dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp = cmdlookup(name, 1); 598dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (cmdp->cmdtype == CMDFUNCTION) 599dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* DO_NOFUNC must have been set */ 600dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp = &loc_cmd; 601dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp->cmdtype = CMDBUILTIN; 602dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp->param.bltin = bltin; 603dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 604dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectsuccess: 605dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp->rehash = 0; 606dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project entry->cmdtype = cmdp->cmdtype; 607dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project entry->u = cmdp->param; 608dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 610dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 611dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 613dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Search the table of builtin commands. 614dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 615dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 616dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 617dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project(*find_builtin(name))(int, char **) 618dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *name; 619dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 620dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const struct builtincmd *bp; 621dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 622dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (bp = builtincmd ; bp->name ; bp++) { 623dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*bp->name == *name && equal(bp->name, name)) 624dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return bp->builtin; 625dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 626dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 627dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 628dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 629dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 630dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project(*find_splbltin(name))(int, char **) 631dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *name; 632dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 633dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const struct builtincmd *bp; 634dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 635dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (bp = splbltincmd ; bp->name ; bp++) { 636dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*bp->name == *name && equal(bp->name, name)) 637dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return bp->builtin; 638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 640dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * At shell startup put special builtins into hash table. 644dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * ensures they are executed first (see posix). 645dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * We stop functions being added with the same name 646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * (as they are impossible to call) 647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecthash_special_builtins(void) 651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const struct builtincmd *bp; 653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct tblentry *cmdp; 654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 655dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (bp = splbltincmd ; bp->name ; bp++) { 656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp = cmdlookup(bp->name, 1); 657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp->cmdtype = CMDSPLBLTIN; 658dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp->param.bltin = bp->builtin; 659dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 660dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 661dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 663dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 664dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 665dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Called when a cd is done. Marks all commands so the next time they 666dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * are executed they will be rehashed. 667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecthashcd(void) 671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct tblentry **pp; 673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct tblentry *cmdp; 674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) { 676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) { 677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (cmdp->cmdtype == CMDNORMAL 678dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)) 679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp->rehash = 1; 680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Fix command hash table when PATH changed. 688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Called before PATH is changed. The argument is the new value of PATH; 689dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * pathval() still returns the old value at this point. 690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Called with interrupts off. 691dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectchangepath(const char *newval) 695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 696dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *old, *new; 697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int idx; 698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int firstchange; 699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int bltin; 700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 701dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project old = pathval(); 702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project new = newval; 703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project firstchange = 9999; /* assume no change */ 704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project idx = 0; 705dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project bltin = -1; 706dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (;;) { 707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*old != *new) { 708dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project firstchange = idx; 709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((*old == '\0' && *new == ':') 710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project || (*old == ':' && *new == '\0')) 711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project firstchange++; 712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project old = new; /* ignore subsequent differences */ 713dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 714dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*new == '\0') 715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*new == '%' && bltin < 0 && prefix("builtin", new + 1)) 717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project bltin = idx; 718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*new == ':') { 719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project idx++; 720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project new++, old++; 722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (builtinloc < 0 && bltin >= 0) 724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project builtinloc = bltin; /* zap builtins */ 725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (builtinloc >= 0 && bltin < 0) 726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project firstchange = 0; 727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project clearcmdentry(firstchange); 728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project builtinloc = bltin; 729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 732dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 733dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Clear out command entries. The argument specifies the first entry in 734dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * PATH which has changed. 735dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 736dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void 738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectclearcmdentry(int firstchange) 739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct tblentry **tblp; 741dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct tblentry **pp; 742dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct tblentry *cmdp; 743dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 744dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 745dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) { 746dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pp = tblp; 747dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while ((cmdp = *pp) != NULL) { 748dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((cmdp->cmdtype == CMDNORMAL && 749dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp->param.index >= firstchange) 750dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project || (cmdp->cmdtype == CMDBUILTIN && 751dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project builtinloc >= firstchange)) { 752dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *pp = cmdp->next; 753dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ckfree(cmdp); 754dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 755dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pp = &cmdp->next; 756dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 757dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 758dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 759dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 760dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 761dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 762dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 763dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 764dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Delete all functions. 765dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 766dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 767dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef mkinit 768dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectMKINIT void deletefuncs(void); 769dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectMKINIT void hash_special_builtins(void); 770dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 771dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectINIT { 772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project hash_special_builtins(); 773dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 774dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 775dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSHELLPROC { 776dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project deletefuncs(); 777dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 779dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdeletefuncs(void) 782dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct tblentry **tblp; 784dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct tblentry **pp; 785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct tblentry *cmdp; 786dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 787dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 788dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) { 789dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pp = tblp; 790dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while ((cmdp = *pp) != NULL) { 791dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (cmdp->cmdtype == CMDFUNCTION) { 792dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *pp = cmdp->next; 793dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project freefunc(cmdp->param.func); 794dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ckfree(cmdp); 795dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 796dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pp = &cmdp->next; 797dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 798dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 799dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 800dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 801dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 802dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 803dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 804dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 805dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 806dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Locate a command in the command hash table. If "add" is nonzero, 807dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * add the command to the table if it is not already present. The 808dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * variable "lastcmdentry" is set to point to the address of the link 809dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * pointing to the entry, so that delete_cmd_entry can delete the 810dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * entry. 811dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 812dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 813dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct tblentry **lastcmdentry; 814dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 815dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 816dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC struct tblentry * 817dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectcmdlookup(const char *name, int add) 818dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 819dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int hashval; 820dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *p; 821dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct tblentry *cmdp; 822dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct tblentry **pp; 823dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 824dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = name; 825dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project hashval = *p << 4; 826dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (*p) 827dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project hashval += *p++; 828dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project hashval &= 0x7FFF; 829dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pp = &cmdtable[hashval % CMDTABLESIZE]; 830dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) { 831dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (equal(cmdp->cmdname, name)) 832dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 833dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pp = &cmdp->next; 834dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 835dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (add && cmdp == NULL) { 836dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 837dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp = *pp = ckmalloc(sizeof (struct tblentry) - ARB 838dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project + strlen(name) + 1); 839dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp->next = NULL; 840dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp->cmdtype = CMDUNKNOWN; 841dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp->rehash = 0; 842dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy(cmdp->cmdname, name); 843dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 844dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 845dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project lastcmdentry = pp; 846dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return cmdp; 847dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 848dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 849dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 850dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Delete the command entry returned on the last lookup. 851dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 852dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 853dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void 854dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdelete_cmd_entry(void) 855dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 856dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct tblentry *cmdp; 857dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 858dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 859dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp = *lastcmdentry; 860dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *lastcmdentry = cmdp->next; 861dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ckfree(cmdp); 862dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 863dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 864dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 865dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 866dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 867dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef notdef 868dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 869dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectgetcmdentry(char *name, struct cmdentry *entry) 870dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 871dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct tblentry *cmdp = cmdlookup(name, 0); 872dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 873dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (cmdp) { 874dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project entry->u = cmdp->param; 875dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project entry->cmdtype = cmdp->cmdtype; 876dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 877dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project entry->cmdtype = CMDUNKNOWN; 878dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project entry->u.index = 0; 879dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 880dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 881dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 882dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 883dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 884dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 885dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Add a new command entry, replacing any existing command entry for 886dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * the same name - except special builtins. 887dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 888dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 889dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void 890dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectaddcmdentry(char *name, struct cmdentry *entry) 891dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 892dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct tblentry *cmdp; 893dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 894dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 895dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp = cmdlookup(name, 1); 896dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (cmdp->cmdtype != CMDSPLBLTIN) { 897dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (cmdp->cmdtype == CMDFUNCTION) { 898dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project freefunc(cmdp->param.func); 899dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 900dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp->cmdtype = entry->cmdtype; 901dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp->param = entry->u; 902dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 903dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 904dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 905dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 906dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 907dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 908dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Define a shell function. 909dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 910dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 911dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 912dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdefun(char *name, union node *func) 913dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 914dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct cmdentry entry; 915dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 916dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 917dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project entry.cmdtype = CMDFUNCTION; 918dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project entry.u.func = copyfunc(func); 919dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project addcmdentry(name, &entry); 920dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 921dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 922dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 923dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 924dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 925dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Delete a function if it exists. 926dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 927dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 928dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 929dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectunsetfunc(char *name) 930dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 931dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct tblentry *cmdp; 932dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 933dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((cmdp = cmdlookup(name, 0)) != NULL && 934dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp->cmdtype == CMDFUNCTION) { 935dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project freefunc(cmdp->param.func); 936dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project delete_cmd_entry(); 937dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (0); 938dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 939dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (1); 940dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 941dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 942dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 943dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Locate and print what a word is... 944dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * also used for 'command -[v|V]' 945dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 946dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 947dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 948dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypecmd(int argc, char **argv) 949dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 950dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct cmdentry entry; 951dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct tblentry *cmdp; 952dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char * const *pp; 953dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct alias *ap; 954dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int err = 0; 955dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *arg; 956dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int c; 957dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int V_flag = 0; 958dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int v_flag = 0; 959dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int p_flag = 0; 960dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 961dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while ((c = nextopt("vVp")) != 0) { 962dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch (c) { 963dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'v': v_flag = 1; break; 964dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'V': V_flag = 1; break; 965dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'p': p_flag = 1; break; 966dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 967dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 968dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 969dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (p_flag && (v_flag || V_flag)) 970dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("cannot specify -p with -v or -V"); 971dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 972dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while ((arg = *argptr++)) { 973dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!v_flag) 974dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1str(arg); 975dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* First look at the keywords */ 976dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (pp = parsekwd; *pp; pp++) 977dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (**pp == *arg && equal(*pp, arg)) 978dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 979dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 980dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*pp) { 981dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (v_flag) 982dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = 1; 983dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 984dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1str(" is a shell keyword\n"); 985dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 986dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 987dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 988dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Then look at the aliases */ 989dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((ap = lookupalias(arg, 1)) != NULL) { 990dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!v_flag) 991dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1fmt(" is an alias for \n"); 992dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1fmt("%s\n", ap->val); 993dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 994dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 995dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 996dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Then check if it is a tracked alias */ 997dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((cmdp = cmdlookup(arg, 0)) != NULL) { 998dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project entry.cmdtype = cmdp->cmdtype; 999dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project entry.u = cmdp->param; 1000dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 1001dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Finally use brute force */ 1002dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project find_command(arg, &entry, DO_ABS, pathval()); 1003dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1004dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1005dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch (entry.cmdtype) { 1006dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CMDNORMAL: { 1007dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (strchr(arg, '/') == NULL) { 1008dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *path = pathval(); 1009dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *name; 1010dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int j = entry.u.index; 1011dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do { 1012dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name = padvance(&path, arg); 1013dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project stunalloc(name); 1014dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } while (--j >= 0); 1015dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!v_flag) 1016dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1fmt(" is%s ", 1017dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdp ? " a tracked alias for" : ""); 1018dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1fmt("%s\n", name); 1019dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 1020dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (access(arg, X_OK) == 0) { 1021dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!v_flag) 1022dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1fmt(" is "); 1023dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1fmt("%s\n", arg); 1024dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 1025dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!v_flag) 1026dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1fmt(": %s\n", 1027dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strerror(errno)); 1028dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 1029dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = 126; 1030dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1031dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1032dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1033dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1034dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CMDFUNCTION: 1035dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!v_flag) 1036dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1str(" is a shell function\n"); 1037dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 1038dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1fmt("%s\n", arg); 1039dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1040dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1041dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CMDBUILTIN: 1042dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!v_flag) 1043dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1str(" is a shell builtin\n"); 1044dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 1045dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1fmt("%s\n", arg); 1046dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1047dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1048dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CMDSPLBLTIN: 1049dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!v_flag) 1050dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1str(" is a special shell builtin\n"); 1051dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 1052dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1fmt("%s\n", arg); 1053dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1054dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1055dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 1056dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!v_flag) 1057dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1str(": not found\n"); 1058dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = 127; 1059dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1060dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1061dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1062dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return err; 1063dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1064