1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*	$NetBSD: var.c,v 1.36 2004/10/06 10:23:43 enami 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[] = "@(#)var.c	8.3 (Berkeley) 5/4/95";
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project__RCSID("$NetBSD: var.c,v 1.36 2004/10/06 10:23:43 enami 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 <unistd.h>
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h>
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <paths.h>
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Shell variables.
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "shell.h"
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "output.h"
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "expand.h"
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "nodes.h"	/* for other headers */
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "eval.h"	/* defines cmdenviron */
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "exec.h"
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "syntax.h"
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "options.h"
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "var.h"
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "memalloc.h"
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "error.h"
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "mystring.h"
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "parser.h"
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "show.h"
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef SMALL
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "myhistedit.h"
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef SMALL
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define VTABSIZE 39
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define VTABSIZE 517
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct varinit {
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct var *var;
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int flags;
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	const char *text;
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	void (*func)(const char *);
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ATTY
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct var vatty;
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef WITH_HISTORY
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct var vhistsize;
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct var vterm;
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct var vifs;
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct var vmpath;
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct var vpath;
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct var vps1;
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct var vps2;
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct var vps4;
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct var vvers;
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct var voptind;
100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst struct varinit varinit[] = {
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ATTY
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ &vatty,	VSTRFIXED|VTEXTFIXED|VUNSET,	"ATTY=",
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	  NULL },
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef WITH_HISTORY
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ &vhistsize,	VSTRFIXED|VTEXTFIXED|VUNSET,	"HISTSIZE=",
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	  sethistsize },
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ &vifs,	VSTRFIXED|VTEXTFIXED,		"IFS= \t\n",
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	  NULL },
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ &vmpath,	VSTRFIXED|VTEXTFIXED|VUNSET,	"MAILPATH=",
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	  NULL },
114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ &vpath,	VSTRFIXED|VTEXTFIXED,		"PATH=" _PATH_DEFPATH,
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	  changepath },
116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * vps1 depends on uid
118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 */
119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ &vps2,	VSTRFIXED|VTEXTFIXED,		"PS2=> ",
120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	  NULL },
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ &vps4,	VSTRFIXED|VTEXTFIXED,		"PS4=+ ",
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	  NULL },
123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef WITH_HISTORY
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ &vterm,	VSTRFIXED|VTEXTFIXED|VUNSET,	"TERM=",
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	  setterm },
126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ &voptind,	VSTRFIXED|VTEXTFIXED|VNOFUNC,	"OPTIND=1",
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	  getoptsreset },
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ NULL,	0,				NULL,
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	  NULL }
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct var *vartab[VTABSIZE];
134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC int strequal(const char *, const char *);
136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC struct var *find_var(const char *, struct var ***, int *);
137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Initialize the varable symbol tables and import the environment
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef mkinit
143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectINCLUDE "var.h"
144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectMKINIT char **environ;
145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectINIT {
146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	char **envp;
147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	initvar();
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (envp = environ ; *envp ; envp++) {
150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (strchr(*envp, '=')) {
151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			setvareq(*envp, VEXPORT|VTEXTFIXED);
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * This routine initializes the builtin variables.  It is called when the
160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * shell is initialized and again when a shell procedure is spawned.
161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinitvar(void)
165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	const struct varinit *ip;
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct var *vp;
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct var **vpp;
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (ip = varinit ; (vp = ip->var) != NULL ; ip++) {
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (find_var(ip->text, &vpp, &vp->name_len) != NULL)
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			continue;
173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		vp->next = *vpp;
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*vpp = vp;
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		vp->text = strdup(ip->text);
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		vp->flags = ip->flags;
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		vp->func = ip->func;
178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * PS1 depends on uid
181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 */
182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (find_var("PS1", &vpp, &vps1.name_len) == NULL) {
183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		vps1.next = *vpp;
184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*vpp = &vps1;
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		vps1.text = strdup(geteuid() ? "PS1=$ " : "PS1=# ");
186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		vps1.flags = VSTRFIXED|VTEXTFIXED;
187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Safe version of setvar, returns 1 on success 0 on failure.
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectsetvarsafe(const char *name, const char *val, int flags)
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct jmploc jmploc;
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct jmploc *volatile savehandler = handler;
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int err = 0;
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef __GNUC__
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void) &err;
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (setjmp(jmploc.loc))
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		err = 1;
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	else {
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		handler = &jmploc;
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		setvar(name, val, flags);
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	handler = savehandler;
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return err;
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Set the value of a variable.  The flags argument is ored with the
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * flags of the variable.  If val is NULL, the variable is unset.
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectsetvar(const char *name, const char *val, int flags)
221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	const char *p;
223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	const char *q;
224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	char *d;
225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int len;
226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int namelen;
227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	char *nameeq;
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int isbad;
229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	isbad = 0;
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	p = name;
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (! is_name(*p))
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		isbad = 1;
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	p++;
235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (;;) {
236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (! is_in_name(*p)) {
237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (*p == '\0' || *p == '=')
238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				break;
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			isbad = 1;
240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		p++;
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	namelen = p - name;
244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (isbad)
245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		error("%.*s: bad variable name", namelen, name);
246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	len = namelen + 2;		/* 2 is space for '=' and '\0' */
247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (val == NULL) {
248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		flags |= VUNSET;
249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} else {
250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		len += strlen(val);
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	d = nameeq = ckmalloc(len);
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	q = name;
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while (--namelen >= 0)
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*d++ = *q++;
256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*d++ = '=';
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*d = '\0';
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (val)
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		scopy(val, d);
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	setvareq(nameeq, flags);
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Same as setvar except that the variable and value are passed in
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * the first argument as name=value.  Since the first argument will
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * be actually stored in the table, it should not be a string that
269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * will go away.
270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectsetvareq(char *s, int flags)
274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct var *vp, **vpp;
276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int nlen;
277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (aflag)
279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		flags |= VEXPORT;
280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	vp = find_var(s, &vpp, &nlen);
281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (vp != NULL) {
282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (vp->flags & VREADONLY)
283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			error("%.*s: is read only", vp->name_len, s);
284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (flags & VNOSET)
285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return;
286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		INTOFF;
287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (vp->func && (flags & VNOFUNC) == 0)
289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			(*vp->func)(s + vp->name_len + 1);
290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			ckfree(vp->text);
293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		vp->flags &= ~(VTEXTFIXED|VSTACK|VUNSET);
295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		vp->flags |= flags & ~VNOFUNC;
296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		vp->text = s;
297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		INTON;
299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return;
300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* not found */
302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (flags & VNOSET)
303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return;
304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	vp = ckmalloc(sizeof (*vp));
305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	vp->flags = flags & ~VNOFUNC;
306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	vp->text = s;
307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	vp->name_len = nlen;
308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	vp->next = *vpp;
309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	vp->func = NULL;
310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*vpp = vp;
311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Process a linked list of variable assignments.
317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectlistsetvar(struct strlist *list, int flags)
321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct strlist *lp;
323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	INTOFF;
325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (lp = list ; lp ; lp = lp->next) {
326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		setvareq(savestr(lp->text), flags);
327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	INTON;
329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectlistmklocal(struct strlist *list, int flags)
333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct strlist *lp;
335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (lp = list ; lp ; lp = lp->next)
337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		mklocal(lp->text, flags);
338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Find the value of a variable.  Returns NULL if not set.
343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectchar *
346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectlookupvar(const char *name)
347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct var *v;
349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	v = find_var(name, NULL, NULL);
351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (v == NULL || v->flags & VUNSET)
352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return NULL;
353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return v->text + v->name_len + 1;
354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Search the environment of a builtin command.  If the second argument
360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * is nonzero, return the value of a variable even if it hasn't been
361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * exported.
362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectchar *
365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbltinlookup(const char *name, int doall)
366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct strlist *sp;
368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct var *v;
369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (sp = cmdenviron ; sp ; sp = sp->next) {
371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (strequal(sp->text, name))
372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return strchr(sp->text, '=') + 1;
373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	v = find_var(name, NULL, NULL);
376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (v == NULL || v->flags & VUNSET || (!doall && !(v->flags & VEXPORT)))
378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return NULL;
379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return v->text + v->name_len + 1;
380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Generate a list of exported variables.  This routine is used to construct
386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * the third argument to execve when executing a program.
387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectchar **
390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectenvironment(void)
391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int nenv;
393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct var **vpp;
394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct var *vp;
395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	char **env;
396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	char **ep;
397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	nenv = 0;
399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (vp = *vpp ; vp ; vp = vp->next)
401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (vp->flags & VEXPORT)
402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				nenv++;
403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	ep = env = stalloc((nenv + 1) * sizeof *env);
405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (vp = *vpp ; vp ; vp = vp->next)
407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (vp->flags & VEXPORT)
408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				*ep++ = vp->text;
409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*ep = NULL;
411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return env;
412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Called when a shell procedure is invoked to clear out nonexported
417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * variables.  It is also necessary to reallocate variables of with
418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * VSTACK set since these are currently allocated on the stack.
419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef mkinit
422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid shprocvar(void);
423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSHELLPROC {
425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	shprocvar();
426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectshprocvar(void)
431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct var **vpp;
433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct var *vp, **prev;
434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (prev = vpp ; (vp = *prev) != NULL ; ) {
437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if ((vp->flags & VEXPORT) == 0) {
438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				*prev = vp->next;
439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if ((vp->flags & VTEXTFIXED) == 0)
440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					ckfree(vp->text);
441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if ((vp->flags & VSTRFIXED) == 0)
442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					ckfree(vp);
443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			} else {
444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (vp->flags & VSTACK) {
445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					vp->text = savestr(vp->text);
446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					vp->flags &=~ VSTACK;
447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				}
448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				prev = &vp->next;
449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	initvar();
453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Command to list all variables which are set.  Currently this command
459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * is invoked from the set command when the set command is called without
460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * any variables.
461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectprint_quoted(const char *p)
465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	const char *q;
467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (strcspn(p, "|&;<>()$`\\\"' \t\n*?[]#~=%") == strlen(p)) {
469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		out1fmt("%s", p);
470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return;
471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while (*p) {
473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (*p == '\'') {
474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			out1fmt("\\'");
475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			p++;
476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			continue;
477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		q = index(p, '\'');
479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (!q) {
480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			out1fmt("'%s'", p );
481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return;
482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		out1fmt("'%.*s'", (int)(q - p), p );
484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		p = q;
485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectsort_var(const void *v_v1, const void *v_v2)
490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	const struct var * const *v1 = v_v1;
492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	const struct var * const *v2 = v_v2;
493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* XXX Will anyone notice we include the '=' of the shorter name? */
495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return strcmp((*v1)->text, (*v2)->text);
496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * POSIX requires that 'set' (but not export or readonly) output the
500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * variables in lexicographic order - by the locale's collating order (sigh).
501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Maybe we could keep them in an ordered balanced binary tree
502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * instead of hashed lists.
503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * For now just roll 'em through qsort for printing...
504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint
507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectshowvars(const char *name, int flag, int show_value)
508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct var **vpp;
510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct var *vp;
511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	const char *p;
512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	static struct var **list;	/* static in case we are interrupted */
514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	static int list_len;
515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int count = 0;
516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (!list) {
518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		list_len = 32;
519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		list = ckmalloc(list_len * sizeof *list);
520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (vp = *vpp ; vp ; vp = vp->next) {
524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (flag && !(vp->flags & flag))
525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				continue;
526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (vp->flags & VUNSET && !(show_value & 2))
527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				continue;
528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (count >= list_len) {
529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				list = ckrealloc(list,
530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					(list_len << 1) * sizeof *list);
531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				list_len <<= 1;
532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			list[count++] = vp;
534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	qsort(list, count, sizeof *list, sort_var);
538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (vpp = list; count--; vpp++) {
540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		vp = *vpp;
541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (name)
542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			out1fmt("%s ", name);
543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (p = vp->text ; *p != '=' ; p++)
544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			out1c(*p);
545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (!(vp->flags & VUNSET) && show_value) {
546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			out1fmt("=");
547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			print_quoted(++p);
548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		out1c('\n');
550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return 0;
552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * The export and readonly commands.
558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint
561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectexportcmd(int argc, char **argv)
562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct var *vp;
564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	char *name;
565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	const char *p;
566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT;
567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int pflag;
568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	pflag = nextopt("p") == 'p' ? 3 : 0;
570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (argc <= 1 || pflag) {
571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		showvars( pflag ? argv[0] : 0, flag, pflag );
572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return 0;
573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while ((name = *argptr++) != NULL) {
576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if ((p = strchr(name, '=')) != NULL) {
577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			p++;
578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		} else {
579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			vp = find_var(name, NULL, NULL);
580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (vp != NULL) {
581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				vp->flags |= flag;
582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				continue;
583dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
584dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
585dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		setvar(name, p, flag);
586dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
587dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return 0;
588dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
589dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
590dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
591dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * The "local" command.
593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint
596dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectlocalcmd(int argc, char **argv)
597dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
598dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	char *name;
599dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
600dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (! in_function())
601dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		error("Not in a function");
602dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while ((name = *argptr++) != NULL) {
603dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		mklocal(name, 0);
604dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
605dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return 0;
606dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
607dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
608dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
610dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Make a variable a local variable.  When a variable is made local, it's
611dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * value and flags are saved in a localvar structure.  The saved values
612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * will be restored when the shell function returns.  We handle the name
613dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * "-" as a special case.
614dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
615dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
616dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
617dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectmklocal(const char *name, int flags)
618dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
619dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct localvar *lvp;
620dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct var **vpp;
621dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct var *vp;
622dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
623dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	INTOFF;
624dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	lvp = ckmalloc(sizeof (struct localvar));
625dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (name[0] == '-' && name[1] == '\0') {
626dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		char *p;
627dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		p = ckmalloc(sizeof_optlist);
628dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		lvp->text = memcpy(p, optlist, sizeof_optlist);
629dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		vp = NULL;
630dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} else {
631dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		vp = find_var(name, &vpp, NULL);
632dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (vp == NULL) {
633dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (strchr(name, '='))
634dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				setvareq(savestr(name), VSTRFIXED|flags);
635dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			else
636dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				setvar(name, NULL, VSTRFIXED|flags);
637dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			vp = *vpp;	/* the new variable */
638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			lvp->text = NULL;
639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			lvp->flags = VUNSET;
640dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		} else {
641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			lvp->text = vp->text;
642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			lvp->flags = vp->flags;
643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			vp->flags |= VSTRFIXED|VTEXTFIXED;
644dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (name[vp->name_len] == '=')
645dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				setvareq(savestr(name), flags);
646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	lvp->vp = vp;
649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	lvp->next = localvars;
650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	localvars = lvp;
651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	INTON;
652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
655dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Called after a function returns.
657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
658dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
659dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
660dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectpoplocalvars(void)
661dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct localvar *lvp;
663dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct var *vp;
664dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
665dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while ((lvp = localvars) != NULL) {
666dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		localvars = lvp->next;
667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		vp = lvp->vp;
668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		TRACE(("poplocalvar %s", vp ? vp->text : "-"));
669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (vp == NULL) {	/* $- saved */
670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			memcpy(optlist, lvp->text, sizeof_optlist);
671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			ckfree(lvp->text);
672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		} else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) {
673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			(void)unsetvar(vp->text, 0);
674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		} else {
675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (vp->func && (vp->flags & VNOFUNC) == 0)
676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				(*vp->func)(lvp->text + vp->name_len + 1);
677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if ((vp->flags & VTEXTFIXED) == 0)
678dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				ckfree(vp->text);
679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			vp->flags = lvp->flags;
680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			vp->text = lvp->text;
681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		ckfree(lvp);
683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint
688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectsetvarcmd(int argc, char **argv)
689dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (argc <= 2)
691dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return unsetcmd(argc, argv);
692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	else if (argc == 3)
693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		setvar(argv[1], argv[2], 0);
694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	else
695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		error("List assignment not implemented");
696dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return 0;
697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
701dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * The unset builtin command.  We unset the function before we unset the
702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * variable to allow a function to be unset when there is a readonly variable
703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * with the same name.
704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
705dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
706dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint
707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectunsetcmd(int argc, char **argv)
708dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	char **ap;
710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int i;
711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int flg_func = 0;
712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int flg_var = 0;
713dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int ret = 0;
714dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while ((i = nextopt("evf")) != '\0') {
716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (i == 'f')
717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			flg_func = 1;
718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		else
719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			flg_var = i;
720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (flg_func == 0 && flg_var == 0)
722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		flg_var = 1;
723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (ap = argptr; *ap ; ap++) {
725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (flg_func)
726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			ret |= unsetfunc(*ap);
727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (flg_var)
728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			ret |= unsetvar(*ap, flg_var == 'e');
729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return ret;
731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
732dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
733dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
734dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
735dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unset the specified variable.
736dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint
739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectunsetvar(const char *s, int unexport)
740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
741dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct var **vpp;
742dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct var *vp;
743dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
744dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	vp = find_var(s, &vpp, NULL);
745dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (vp == NULL)
746dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return 1;
747dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
748dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (vp->flags & VREADONLY)
749dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return (1);
750dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
751dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	INTOFF;
752dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (unexport) {
753dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		vp->flags &= ~VEXPORT;
754dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} else {
755dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (vp->text[vp->name_len + 1] != '\0')
756dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			setvar(s, nullstr, 0);
757dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		vp->flags &= ~VEXPORT;
758dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		vp->flags |= VUNSET;
759dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if ((vp->flags & VSTRFIXED) == 0) {
760dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if ((vp->flags & VTEXTFIXED) == 0)
761dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				ckfree(vp->text);
762dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			*vpp = vp->next;
763dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			ckfree(vp);
764dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
765dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
766dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	INTON;
767dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return 0;
768dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
769dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
770dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
771dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Returns true if the two strings specify the same varable.  The first
773dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * variable name is terminated by '='; the second may be terminated by
774dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * either '=' or '\0'.
775dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
776dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
777dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC int
778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstrequal(const char *p, const char *q)
779dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while (*p == *q++) {
781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (*p++ == '=')
782dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return 1;
783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
784dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (*p == '=' && *(q - 1) == '\0')
785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return 1;
786dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return 0;
787dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
788dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
789dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
790dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Search for a variable.
791dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 'name' may be terminated by '=' or a NUL.
792dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * vppp is set to the pointer to vp, or the list head if vp isn't found
793dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * lenp is set to the number of charactets in 'name'
794dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
795dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
796dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC struct var *
797dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfind_var(const char *name, struct var ***vppp, int *lenp)
798dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
799dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	unsigned int hashval;
800dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int len;
801dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct var *vp, **vpp;
802dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	const char *p = name;
803dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
804dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	hashval = 0;
805dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while (*p && *p != '=')
806dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		hashval = 2 * hashval + (unsigned char)*p++;
807dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	len = p - name;
808dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
809dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (lenp)
810dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*lenp = len;
811dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	vpp = &vartab[hashval % VTABSIZE];
812dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (vppp)
813dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*vppp = vpp;
814dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
815dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (vp = *vpp ; vp ; vpp = &vp->next, vp = *vpp) {
816dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (vp->name_len != len)
817dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			continue;
818dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (memcmp(vp->text, name, len) != 0)
819dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			continue;
820dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (vppp)
821dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			*vppp = vpp;
822dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return vp;
823dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
824dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return NULL;
825dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
826