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