histedit.c revision dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*	$NetBSD: histedit.c,v 1.34 2003/10/27 06:19:29 lukem Exp $	*/
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*-
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (c) 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[] = "@(#)histedit.c	8.2 (Berkeley) 5/4/95";
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project__RCSID("$NetBSD: histedit.c,v 1.34 2003/10/27 06:19:29 lukem 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/param.h>
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <paths.h>
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h>
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h>
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Editline and history functions (and glue).
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "shell.h"
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "parser.h"
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "var.h"
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "options.h"
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "main.h"
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "output.h"
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "mystring.h"
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "myhistedit.h"
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "error.h"
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef SMALL
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "eval.h"
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "memalloc.h"
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define MAXHISTLOOPS	4	/* max recursions through fc */
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define DEFEDITOR	"ed"	/* default editor *should* be $EDITOR */
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectHistory *hist;	/* history cookie */
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectEditLine *el;	/* editline cookie */
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint displayhist;
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic FILE *el_in, *el_out;
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC const char *fc_replace(const char *, char *, char *);
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef DEBUG
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern FILE *tracefile;
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Set history and editing status.  Called whenever the status may
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * have changed (figures out what to do).
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecthistedit(void)
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	FILE *el_err;
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define editing (Eflag || Vflag)
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (iflag) {
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (!hist) {
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/*
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			 * turn history on
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			 */
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			INTOFF;
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			hist = history_init();
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			INTON;
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (hist != NULL)
100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				sethistsize(histsizeval());
101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			else
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				out2str("sh: can't initialize history\n");
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (editing && !el && isatty(0)) { /* && isatty(2) ??? */
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/*
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			 * turn editing on
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			 */
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			char *term, *shname;
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			INTOFF;
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (el_in == NULL)
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				el_in = fdopen(0, "r");
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (el_out == NULL)
114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				el_out = fdopen(2, "w");
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (el_in == NULL || el_out == NULL)
116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				goto bad;
117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			el_err = el_out;
118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if DEBUG
119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (tracefile)
120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				el_err = tracefile;
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			term = lookupvar("TERM");
123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (term)
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				setenv("TERM", term, 1);
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			else
126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				unsetenv("TERM");
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			shname = arg0;
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (shname[0] == '-')
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				shname++;
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			el = el_init(shname, el_in, el_out, el_err);
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (el != NULL) {
132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (hist)
133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					el_set(el, EL_HIST, history, hist);
134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				el_set(el, EL_PROMPT, getprompt);
135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				el_set(el, EL_SIGNAL, 1);
136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			} else {
137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbad:
138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				out2str("sh: can't initialize editing\n");
139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			INTON;
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		} else if (!editing && el) {
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			INTOFF;
143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			el_end(el);
144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			el = NULL;
145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			INTON;
146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (el) {
148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (Vflag)
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				el_set(el, EL_EDITOR, "vi");
150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			else if (Eflag)
151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				el_set(el, EL_EDITOR, "emacs");
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			el_source(el, NULL);
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} else {
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		INTOFF;
156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (el) {	/* no editing if not interactive */
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			el_end(el);
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			el = NULL;
159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (hist) {
161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			history_end(hist);
162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			hist = NULL;
163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		INTON;
165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectsethistsize(const char *hs)
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int histsize;
173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	HistEvent he;
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (hist != NULL) {
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (hs == NULL || *hs == '\0' ||
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		   (histsize = atoi(hs)) < 0)
178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			histsize = 100;
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		history(hist, &he, H_SETSIZE, histsize);
180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectsetterm(const char *term)
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (el != NULL && term != NULL)
187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (el_set(el, EL_TERMINAL, term) != 0) {
188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			outfmt(out2, "sh: Can't set terminal type %s\n", term);
189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			outfmt(out2, "sh: Using dumb terminal settings.\n");
190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinputrc(argc, argv)
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int argc;
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	char **argv;
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (argc != 2) {
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		out2str("usage: inputrc file\n");
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return 1;
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (el != NULL) {
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (el_source(el, argv[1])) {
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			out2str("inputrc: failed\n");
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return 1;
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		} else
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return 0;
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} else {
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		out2str("sh: inputrc ignored, not editing\n");
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return 1;
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *  This command is provided since POSIX decided to standardize
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *  the Korn shell fc command.  Oh well...
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecthistcmd(int argc, char **argv)
220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int ch;
222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	const char *editor = NULL;
223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	HistEvent he;
224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int lflg = 0, nflg = 0, rflg = 0, sflg = 0;
225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int i, retval;
226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	const char *firststr, *laststr;
227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int first, last, direction;
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	char *pat = NULL, *repl;	/* ksh "fc old=new" crap */
229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	static int active = 0;
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct jmploc jmploc;
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct jmploc *volatile savehandler;
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	char editfile[MAXPATHLEN + 1];
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	FILE *efp;
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef __GNUC__
235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* Avoid longjmp clobbering */
236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void) &editor;
237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void) &lflg;
238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void) &nflg;
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void) &rflg;
240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void) &sflg;
241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void) &firststr;
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void) &laststr;
243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void) &pat;
244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void) &repl;
245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void) &efp;
246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void) &argc;
247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void) &argv;
248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (hist == NULL)
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		error("history not active");
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (argc == 1)
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		error("missing history argument");
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	optreset = 1; optind = 1; /* initialize getopt */
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while (not_fcnumber(argv[optind]) &&
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	      (ch = getopt(argc, argv, ":e:lnrs")) != -1)
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		switch ((char)ch) {
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		case 'e':
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			editor = optionarg;
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			break;
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		case 'l':
264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			lflg = 1;
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			break;
266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		case 'n':
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			nflg = 1;
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			break;
269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		case 'r':
270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			rflg = 1;
271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			break;
272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		case 's':
273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sflg = 1;
274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			break;
275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		case ':':
276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			error("option -%c expects argument", optopt);
277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/* NOTREACHED */
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		case '?':
279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		default:
280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			error("unknown option: -%c", optopt);
281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/* NOTREACHED */
282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	argc -= optind, argv += optind;
284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * If executing...
287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 */
288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (lflg == 0 || editor || sflg) {
289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		lflg = 0;	/* ignore */
290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		editfile[0] = '\0';
291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * Catch interrupts to reset active counter and
293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * cleanup temp files.
294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 */
295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (setjmp(jmploc.loc)) {
296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			active = 0;
297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (*editfile)
298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				unlink(editfile);
299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			handler = savehandler;
300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			longjmp(handler->loc, 1);
301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		savehandler = handler;
303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		handler = &jmploc;
304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (++active > MAXHISTLOOPS) {
305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			active = 0;
306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			displayhist = 0;
307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			error("called recursively too many times");
308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * Set editor.
311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 */
312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (sflg == 0) {
313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (editor == NULL &&
314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			    (editor = bltinlookup("FCEDIT", 1)) == NULL &&
315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			    (editor = bltinlookup("EDITOR", 1)) == NULL)
316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				editor = DEFEDITOR;
317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (editor[0] == '-' && editor[1] == '\0') {
318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				sflg = 1;	/* no edit */
319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				editor = NULL;
320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * If executing, parse [old=new] now
326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 */
327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (lflg == 0 && argc > 0 &&
328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	     ((repl = strchr(argv[0], '=')) != NULL)) {
329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		pat = argv[0];
330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*repl++ = '\0';
331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		argc--, argv++;
332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * determine [first] and [last]
335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 */
336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	switch (argc) {
337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	case 0:
338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		firststr = lflg ? "-16" : "-1";
339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		laststr = "-1";
340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		break;
341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	case 1:
342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		firststr = argv[0];
343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		laststr = lflg ? "-1" : argv[0];
344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		break;
345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	case 2:
346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		firststr = argv[0];
347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		laststr = argv[1];
348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		break;
349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	default:
350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		error("too many args");
351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/* NOTREACHED */
352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * Turn into event numbers.
355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 */
356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	first = str_to_event(firststr, 0);
357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	last = str_to_event(laststr, 1);
358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (rflg) {
360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		i = last;
361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		last = first;
362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		first = i;
363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * XXX - this should not depend on the event numbers
366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * always increasing.  Add sequence numbers or offset
367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * to the history element in next (diskbased) release.
368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 */
369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	direction = first < last ? H_PREV : H_NEXT;
370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * If editing, grab a temp file.
373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 */
374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (editor) {
375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		int fd;
376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		INTOFF;		/* easier */
377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		snprintf(editfile, sizeof(editfile), "%s_shXXXXXX", _PATH_TMP);
378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if ((fd = mkstemp(editfile)) < 0)
379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			error("can't create temporary file %s", editfile);
380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if ((efp = fdopen(fd, "w")) == NULL) {
381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			close(fd);
382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			error("can't allocate stdio buffer for temp");
383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * Loop through selected history events.  If listing or executing,
388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * do it now.  Otherwise, put into temp file and call the editor
389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * after.
390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 *
391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * The history interface needs rethinking, as the following
392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * convolutions will demonstrate.
393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 */
394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	history(hist, &he, H_FIRST);
395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	retval = history(hist, &he, H_NEXT_EVENT, first);
396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (;retval != -1; retval = history(hist, &he, direction)) {
397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (lflg) {
398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (!nflg)
399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				out1fmt("%5d ", he.num);
400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			out1str(he.str);
401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		} else {
402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			const char *s = pat ?
403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			   fc_replace(he.str, pat, repl) : he.str;
404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (sflg) {
406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (displayhist) {
407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					out2str(s);
408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				}
409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				evalstring(strcpy(stalloc(strlen(s) + 1), s), 0);
411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (displayhist && hist) {
412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					/*
413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					 *  XXX what about recursive and
414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					 *  relative histnums.
415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					 */
416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					history(hist, &he, H_ENTER, s);
417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				}
418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			} else
419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				fputs(s, efp);
420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * At end?  (if we were to lose last, we'd sure be
423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * messed up).
424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 */
425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (he.num == last)
426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			break;
427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (editor) {
429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		char *editcmd;
430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		fclose(efp);
432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		editcmd = stalloc(strlen(editor) + strlen(editfile) + 2);
433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		sprintf(editcmd, "%s %s", editor, editfile);
434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		evalstring(editcmd, 0);	/* XXX - should use no JC command */
435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		INTON;
436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		readcmdfile(editfile);	/* XXX - should read back - quick tst */
437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		unlink(editfile);
438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (lflg == 0 && active > 0)
441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		--active;
442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (displayhist)
443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		displayhist = 0;
444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return 0;
445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC const char *
448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfc_replace(const char *s, char *p, char *r)
449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	char *dest;
451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int plen = strlen(p);
452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	STARTSTACKSTR(dest);
454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while (*s) {
455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (*s == *p && strncmp(s, p, plen) == 0) {
456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			while (*r)
457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				STPUTC(*r++, dest);
458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			s += plen;
459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			*p = '\0';	/* so no more matches */
460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		} else
461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			STPUTC(*s++, dest);
462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	STACKSTRNUL(dest);
464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	dest = grabstackstr(dest);
465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return (dest);
467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint
470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectnot_fcnumber(char *s)
471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (s == NULL)
473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return 0;
474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (*s == '-')
475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                s++;
476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return (!is_number(s));
477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint
480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstr_to_event(const char *str, int last)
481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	HistEvent he;
483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	const char *s = str;
484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int relative = 0;
485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int i, retval;
486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	retval = history(hist, &he, H_FIRST);
488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	switch (*s) {
489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	case '-':
490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		relative = 1;
491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*FALLTHROUGH*/
492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	case '+':
493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		s++;
494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (is_number(s)) {
496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		i = atoi(s);
497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (relative) {
498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			while (retval != -1 && i--) {
499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				retval = history(hist, &he, H_NEXT);
500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (retval == -1)
502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				retval = history(hist, &he, H_LAST);
503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		} else {
504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			retval = history(hist, &he, H_NEXT_EVENT, i);
505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (retval == -1) {
506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				/*
507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				 * the notion of first and last is
508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				 * backwards to that of the history package
509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				 */
510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				retval = history(hist, &he,
511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						last ? H_FIRST : H_LAST);
512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (retval == -1)
515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			error("history number %s not found (internal error)",
516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			       str);
517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} else {
518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * pattern
520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 */
521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		retval = history(hist, &he, H_PREV_STR, str);
522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (retval == -1)
523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			error("history pattern not found: %s", str);
524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return (he.num);
526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint
529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecthistcmd(int argc, char **argv)
530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	error("not compiled with history support");
532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* NOTREACHED */
533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint
535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinputrc(int argc, char **argv)
536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	error("not compiled with history support");
538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* NOTREACHED */
539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
541