1/*	$NetBSD: readline.c,v 1.126 2016/02/24 17:13:22 christos Exp $	*/
2
3/*-
4 * Copyright (c) 1997 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jaromir Dolecek.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include "config.h"
33#if !defined(lint) && !defined(SCCSID)
34__RCSID("$NetBSD: readline.c,v 1.126 2016/02/24 17:13:22 christos Exp $");
35#endif /* not lint && not SCCSID */
36#include <sys/cdefs.h>
37__FBSDID("$FreeBSD: stable/11/lib/libedit/readline.c 313981 2017-02-20 03:33:59Z pfg $");
38
39#include <sys/types.h>
40#include <sys/stat.h>
41#include <ctype.h>
42#include <dirent.h>
43#include <errno.h>
44#include <fcntl.h>
45#include <limits.h>
46#include <pwd.h>
47#include <setjmp.h>
48#include <stdint.h>
49#include <stdio.h>
50#include <stdlib.h>
51#include <string.h>
52#include <unistd.h>
53#include <vis.h>
54
55#include "readline/readline.h"
56#include "el.h"
57#include "filecomplete.h"
58
59void rl_prep_terminal(int);
60void rl_deprep_terminal(void);
61
62/* for rl_complete() */
63#define TAB		'\r'
64
65/* see comment at the #ifdef for sense of this */
66/* #define GDB_411_HACK */
67
68/* readline compatibility stuff - look at readline sources/documentation */
69/* to see what these variables mean */
70const char *rl_library_version = "EditLine wrapper";
71int rl_readline_version = RL_READLINE_VERSION;
72static char empty[] = { '\0' };
73static char expand_chars[] = { ' ', '\t', '\n', '=', '(', '\0' };
74static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$',
75    '>', '<', '=', ';', '|', '&', '{', '(', '\0' };
76char *rl_readline_name = empty;
77FILE *rl_instream = NULL;
78FILE *rl_outstream = NULL;
79int rl_point = 0;
80int rl_end = 0;
81char *rl_line_buffer = NULL;
82rl_vcpfunc_t *rl_linefunc = NULL;
83int rl_done = 0;
84VFunction *rl_event_hook = NULL;
85KEYMAP_ENTRY_ARRAY emacs_standard_keymap,
86    emacs_meta_keymap,
87    emacs_ctlx_keymap;
88/*
89 * The following is not implemented; we always catch signals in the
90 * libedit fashion: set handlers on entry to el_gets() and clear them
91 * on the way out. This simplistic approach works for most cases; if
92 * it does not work for your application, please let us know.
93 */
94int rl_catch_signals = 1;
95int rl_catch_sigwinch = 1;
96
97int history_base = 1;		/* probably never subject to change */
98int history_length = 0;
99int max_input_history = 0;
100char history_expansion_char = '!';
101char history_subst_char = '^';
102char *history_no_expand_chars = expand_chars;
103Function *history_inhibit_expansion_function = NULL;
104char *history_arg_extract(int start, int end, const char *str);
105
106int rl_inhibit_completion = 0;
107int rl_attempted_completion_over = 0;
108char *rl_basic_word_break_characters = break_chars;
109char *rl_completer_word_break_characters = NULL;
110char *rl_completer_quote_characters = NULL;
111rl_compentry_func_t *rl_completion_entry_function = NULL;
112char *(*rl_completion_word_break_hook)(void) = NULL;
113rl_completion_func_t *rl_attempted_completion_function = NULL;
114Function *rl_pre_input_hook = NULL;
115Function *rl_startup1_hook = NULL;
116int (*rl_getc_function)(FILE *) = NULL;
117char *rl_terminal_name = NULL;
118int rl_already_prompted = 0;
119int rl_filename_completion_desired = 0;
120int rl_ignore_completion_duplicates = 0;
121int readline_echoing_p = 1;
122int _rl_print_completions_horizontally = 0;
123VFunction *rl_redisplay_function = NULL;
124Function *rl_startup_hook = NULL;
125VFunction *rl_completion_display_matches_hook = NULL;
126VFunction *rl_prep_term_function = (VFunction *)rl_prep_terminal;
127VFunction *rl_deprep_term_function = (VFunction *)rl_deprep_terminal;
128KEYMAP_ENTRY_ARRAY emacs_meta_keymap;
129
130/*
131 * The current prompt string.
132 */
133char *rl_prompt = NULL;
134/*
135 * This is set to character indicating type of completion being done by
136 * rl_complete_internal(); this is available for application completion
137 * functions.
138 */
139int rl_completion_type = 0;
140
141/*
142 * If more than this number of items results from query for possible
143 * completions, we ask user if they are sure to really display the list.
144 */
145int rl_completion_query_items = 100;
146
147/*
148 * List of characters which are word break characters, but should be left
149 * in the parsed text when it is passed to the completion function.
150 * Shell uses this to help determine what kind of completing to do.
151 */
152char *rl_special_prefixes = NULL;
153
154/*
155 * This is the character appended to the completed words if at the end of
156 * the line. Default is ' ' (a space).
157 */
158int rl_completion_append_character = ' ';
159
160/* stuff below is used internally by libedit for readline emulation */
161
162static History *h = NULL;
163static EditLine *e = NULL;
164static rl_command_func_t *map[256];
165static jmp_buf topbuf;
166
167/* internal functions */
168static unsigned char	 _el_rl_complete(EditLine *, int);
169static unsigned char	 _el_rl_tstp(EditLine *, int);
170static char		*_get_prompt(EditLine *);
171static int		 _getc_function(EditLine *, wchar_t *);
172static HIST_ENTRY	*_move_history(int);
173static int		 _history_expand_command(const char *, size_t, size_t,
174    char **);
175static char		*_rl_compat_sub(const char *, const char *,
176    const char *, int);
177static int		 _rl_event_read_char(EditLine *, wchar_t *);
178static void		 _rl_update_pos(void);
179
180
181/* ARGSUSED */
182static char *
183_get_prompt(EditLine *el __attribute__((__unused__)))
184{
185	rl_already_prompted = 1;
186	return rl_prompt;
187}
188
189
190/*
191 * generic function for moving around history
192 */
193static HIST_ENTRY *
194_move_history(int op)
195{
196	HistEvent ev;
197	static HIST_ENTRY rl_he;
198
199	if (history(h, &ev, op) != 0)
200		return NULL;
201
202	rl_he.line = ev.str;
203	rl_he.data = NULL;
204
205	return &rl_he;
206}
207
208
209/*
210 * read one key from user defined input function
211 */
212static int
213/*ARGSUSED*/
214_getc_function(EditLine *el __attribute__((__unused__)), wchar_t *c)
215{
216	int i;
217
218	i = (*rl_getc_function)(NULL);
219	if (i == -1)
220		return 0;
221	*c = (wchar_t)i;
222	return 1;
223}
224
225static void
226_resize_fun(EditLine *el, void *a)
227{
228	const LineInfo *li;
229	char **ap = a;
230
231	li = el_line(el);
232	/* a cheesy way to get rid of const cast. */
233	*ap = memchr(li->buffer, *li->buffer, (size_t)1);
234}
235
236static const char *
237_default_history_file(void)
238{
239	struct passwd *p;
240	static char *path;
241	size_t len;
242
243	if (path)
244		return path;
245
246	if ((p = getpwuid(getuid())) == NULL)
247		return NULL;
248
249	len = strlen(p->pw_dir) + sizeof("/.history");
250	if ((path = malloc(len)) == NULL)
251		return NULL;
252
253	(void)snprintf(path, len, "%s/.history", p->pw_dir);
254	return path;
255}
256
257/*
258 * READLINE compatibility stuff
259 */
260
261/*
262 * Set the prompt
263 */
264int
265rl_set_prompt(const char *prompt)
266{
267	char *p;
268
269	if (!prompt)
270		prompt = "";
271	if (rl_prompt != NULL && strcmp(rl_prompt, prompt) == 0)
272		return 0;
273	if (rl_prompt)
274		el_free(rl_prompt);
275	rl_prompt = strdup(prompt);
276	if (rl_prompt == NULL)
277		return -1;
278
279	while ((p = strchr(rl_prompt, RL_PROMPT_END_IGNORE)) != NULL)
280		*p = RL_PROMPT_START_IGNORE;
281
282	return 0;
283}
284
285/*
286 * initialize rl compat stuff
287 */
288int
289rl_initialize(void)
290{
291	HistEvent ev;
292	int editmode = 1;
293	struct termios t;
294
295	if (e != NULL)
296		el_end(e);
297	if (h != NULL)
298		history_end(h);
299
300	if (!rl_instream)
301		rl_instream = stdin;
302	if (!rl_outstream)
303		rl_outstream = stdout;
304
305	/*
306	 * See if we don't really want to run the editor
307	 */
308	if (tcgetattr(fileno(rl_instream), &t) != -1 && (t.c_lflag & ECHO) == 0)
309		editmode = 0;
310
311	e = el_init(rl_readline_name, rl_instream, rl_outstream, stderr);
312
313	if (!editmode)
314		el_set(e, EL_EDITMODE, 0);
315
316	h = history_init();
317	if (!e || !h)
318		return -1;
319
320	history(h, &ev, H_SETSIZE, INT_MAX);	/* unlimited */
321	history_length = 0;
322	max_input_history = INT_MAX;
323	el_set(e, EL_HIST, history, h);
324
325	/* Setup resize function */
326	el_set(e, EL_RESIZE, _resize_fun, &rl_line_buffer);
327
328	/* setup getc function if valid */
329	if (rl_getc_function)
330		el_set(e, EL_GETCFN, _getc_function);
331
332	/* for proper prompt printing in readline() */
333	if (rl_set_prompt("") == -1) {
334		history_end(h);
335		el_end(e);
336		return -1;
337	}
338	el_set(e, EL_PROMPT, _get_prompt, RL_PROMPT_START_IGNORE);
339	el_set(e, EL_SIGNAL, rl_catch_signals);
340
341	/* set default mode to "emacs"-style and read setting afterwards */
342	/* so this can be overridden */
343	el_set(e, EL_EDITOR, "emacs");
344	if (rl_terminal_name != NULL)
345		el_set(e, EL_TERMINAL, rl_terminal_name);
346	else
347		el_get(e, EL_TERMINAL, &rl_terminal_name);
348
349	/*
350	 * Word completion - this has to go AFTER rebinding keys
351	 * to emacs-style.
352	 */
353	el_set(e, EL_ADDFN, "rl_complete",
354	    "ReadLine compatible completion function",
355	    _el_rl_complete);
356	el_set(e, EL_BIND, "^I", "rl_complete", NULL);
357
358	/*
359	 * Send TSTP when ^Z is pressed.
360	 */
361	el_set(e, EL_ADDFN, "rl_tstp",
362	    "ReadLine compatible suspend function",
363	    _el_rl_tstp);
364	el_set(e, EL_BIND, "^Z", "rl_tstp", NULL);
365
366	/*
367	 * Set some readline compatible key-bindings.
368	 */
369	el_set(e, EL_BIND, "^R", "em-inc-search-prev", NULL);
370
371	/*
372	 * Allow the use of Home/End keys.
373	 */
374	el_set(e, EL_BIND, "\\e[1~", "ed-move-to-beg", NULL);
375	el_set(e, EL_BIND, "\\e[4~", "ed-move-to-end", NULL);
376	el_set(e, EL_BIND, "\\e[7~", "ed-move-to-beg", NULL);
377	el_set(e, EL_BIND, "\\e[8~", "ed-move-to-end", NULL);
378	el_set(e, EL_BIND, "\\e[H", "ed-move-to-beg", NULL);
379	el_set(e, EL_BIND, "\\e[F", "ed-move-to-end", NULL);
380
381	/*
382	 * Allow the use of the Delete/Insert keys.
383	 */
384	el_set(e, EL_BIND, "\\e[3~", "ed-delete-next-char", NULL);
385	el_set(e, EL_BIND, "\\e[2~", "ed-quoted-insert", NULL);
386
387	/*
388	 * Ctrl-left-arrow and Ctrl-right-arrow for word moving.
389	 */
390	el_set(e, EL_BIND, "\\e[1;5C", "em-next-word", NULL);
391	el_set(e, EL_BIND, "\\e[1;5D", "ed-prev-word", NULL);
392	el_set(e, EL_BIND, "\\e[5C", "em-next-word", NULL);
393	el_set(e, EL_BIND, "\\e[5D", "ed-prev-word", NULL);
394	el_set(e, EL_BIND, "\\e\\e[C", "em-next-word", NULL);
395	el_set(e, EL_BIND, "\\e\\e[D", "ed-prev-word", NULL);
396
397	/* read settings from configuration file */
398	el_source(e, NULL);
399
400	/*
401	 * Unfortunately, some applications really do use rl_point
402	 * and rl_line_buffer directly.
403	 */
404	_resize_fun(e, &rl_line_buffer);
405	_rl_update_pos();
406
407	if (rl_startup_hook)
408		(*rl_startup_hook)(NULL, 0);
409
410	return 0;
411}
412
413
414/*
415 * read one line from input stream and return it, chomping
416 * trailing newline (if there is any)
417 */
418char *
419readline(const char *p)
420{
421	HistEvent ev;
422	const char * volatile prompt = p;
423	int count;
424	const char *ret;
425	char *buf;
426	static int used_event_hook;
427
428	if (e == NULL || h == NULL)
429		rl_initialize();
430
431	rl_done = 0;
432
433	(void)setjmp(topbuf);
434
435	/* update prompt accordingly to what has been passed */
436	if (rl_set_prompt(prompt) == -1)
437		return NULL;
438
439	if (rl_pre_input_hook)
440		(*rl_pre_input_hook)(NULL, 0);
441
442	if (rl_event_hook && !(e->el_flags&NO_TTY)) {
443		el_set(e, EL_GETCFN, _rl_event_read_char);
444		used_event_hook = 1;
445	}
446
447	if (!rl_event_hook && used_event_hook) {
448		el_set(e, EL_GETCFN, EL_BUILTIN_GETCFN);
449		used_event_hook = 0;
450	}
451
452	rl_already_prompted = 0;
453
454	/* get one line from input stream */
455	ret = el_gets(e, &count);
456
457	if (ret && count > 0) {
458		int lastidx;
459
460		buf = strdup(ret);
461		if (buf == NULL)
462			return NULL;
463		lastidx = count - 1;
464		if (buf[lastidx] == '\n')
465			buf[lastidx] = '\0';
466	} else
467		buf = NULL;
468
469	history(h, &ev, H_GETSIZE);
470	history_length = ev.num;
471
472	return buf;
473}
474
475/*
476 * history functions
477 */
478
479/*
480 * is normally called before application starts to use
481 * history expansion functions
482 */
483void
484using_history(void)
485{
486	if (h == NULL || e == NULL)
487		rl_initialize();
488}
489
490
491/*
492 * substitute ``what'' with ``with'', returning resulting string; if
493 * globally == 1, substitutes all occurrences of what, otherwise only the
494 * first one
495 */
496static char *
497_rl_compat_sub(const char *str, const char *what, const char *with,
498    int globally)
499{
500	const	char	*s;
501	char	*r, *result;
502	size_t	len, with_len, what_len;
503
504	len = strlen(str);
505	with_len = strlen(with);
506	what_len = strlen(what);
507
508	/* calculate length we need for result */
509	s = str;
510	while (*s) {
511		if (*s == *what && !strncmp(s, what, what_len)) {
512			len += with_len - what_len;
513			if (!globally)
514				break;
515			s += what_len;
516		} else
517			s++;
518	}
519	r = result = el_malloc((len + 1) * sizeof(*r));
520	if (result == NULL)
521		return NULL;
522	s = str;
523	while (*s) {
524		if (*s == *what && !strncmp(s, what, what_len)) {
525			(void)strncpy(r, with, with_len);
526			r += with_len;
527			s += what_len;
528			if (!globally) {
529				(void)strcpy(r, s);
530				return result;
531			}
532		} else
533			*r++ = *s++;
534	}
535	*r = '\0';
536	return result;
537}
538
539static	char	*last_search_pat;	/* last !?pat[?] search pattern */
540static	char	*last_search_match;	/* last !?pat[?] that matched */
541
542const char *
543get_history_event(const char *cmd, int *cindex, int qchar)
544{
545	int idx, sign, sub, num, begin, ret;
546	size_t len;
547	char	*pat;
548	const char *rptr;
549	HistEvent ev;
550
551	idx = *cindex;
552	if (cmd[idx++] != history_expansion_char)
553		return NULL;
554
555	/* find out which event to take */
556	if (cmd[idx] == history_expansion_char || cmd[idx] == '\0') {
557		if (history(h, &ev, H_FIRST) != 0)
558			return NULL;
559		*cindex = cmd[idx]? (idx + 1):idx;
560		return ev.str;
561	}
562	sign = 0;
563	if (cmd[idx] == '-') {
564		sign = 1;
565		idx++;
566	}
567
568	if ('0' <= cmd[idx] && cmd[idx] <= '9') {
569		HIST_ENTRY *rl_he;
570
571		num = 0;
572		while (cmd[idx] && '0' <= cmd[idx] && cmd[idx] <= '9') {
573			num = num * 10 + cmd[idx] - '0';
574			idx++;
575		}
576		if (sign)
577			num = history_length - num + 1;
578
579		if (!(rl_he = history_get(num)))
580			return NULL;
581
582		*cindex = idx;
583		return rl_he->line;
584	}
585	sub = 0;
586	if (cmd[idx] == '?') {
587		sub = 1;
588		idx++;
589	}
590	begin = idx;
591	while (cmd[idx]) {
592		if (cmd[idx] == '\n')
593			break;
594		if (sub && cmd[idx] == '?')
595			break;
596		if (!sub && (cmd[idx] == ':' || cmd[idx] == ' '
597				    || cmd[idx] == '\t' || cmd[idx] == qchar))
598			break;
599		idx++;
600	}
601	len = (size_t)idx - (size_t)begin;
602	if (sub && cmd[idx] == '?')
603		idx++;
604	if (sub && len == 0 && last_search_pat && *last_search_pat)
605		pat = last_search_pat;
606	else if (len == 0)
607		return NULL;
608	else {
609		if ((pat = el_malloc((len + 1) * sizeof(*pat))) == NULL)
610			return NULL;
611		(void)strncpy(pat, cmd + begin, len);
612		pat[len] = '\0';
613	}
614
615	if (history(h, &ev, H_CURR) != 0) {
616		if (pat != last_search_pat)
617			el_free(pat);
618		return NULL;
619	}
620	num = ev.num;
621
622	if (sub) {
623		if (pat != last_search_pat) {
624			if (last_search_pat)
625				el_free(last_search_pat);
626			last_search_pat = pat;
627		}
628		ret = history_search(pat, -1);
629	} else
630		ret = history_search_prefix(pat, -1);
631
632	if (ret == -1) {
633		/* restore to end of list on failed search */
634		history(h, &ev, H_FIRST);
635		(void)fprintf(rl_outstream, "%s: Event not found\n", pat);
636		if (pat != last_search_pat)
637			el_free(pat);
638		return NULL;
639	}
640
641	if (sub && len) {
642		if (last_search_match && last_search_match != pat)
643			el_free(last_search_match);
644		last_search_match = pat;
645	}
646
647	if (pat != last_search_pat)
648		el_free(pat);
649
650	if (history(h, &ev, H_CURR) != 0)
651		return NULL;
652	*cindex = idx;
653	rptr = ev.str;
654
655	/* roll back to original position */
656	(void)history(h, &ev, H_SET, num);
657
658	return rptr;
659}
660
661/*
662 * the real function doing history expansion - takes as argument command
663 * to do and data upon which the command should be executed
664 * does expansion the way I've understood readline documentation
665 *
666 * returns 0 if data was not modified, 1 if it was and 2 if the string
667 * should be only printed and not executed; in case of error,
668 * returns -1 and *result points to NULL
669 * it's the caller's responsibility to free() the string returned in *result
670 */
671static int
672_history_expand_command(const char *command, size_t offs, size_t cmdlen,
673    char **result)
674{
675	char *tmp, *search = NULL, *aptr;
676	const char *ptr, *cmd;
677	static char *from = NULL, *to = NULL;
678	int start, end, idx, has_mods = 0;
679	int p_on = 0, g_on = 0;
680
681	*result = NULL;
682	aptr = NULL;
683	ptr = NULL;
684
685	/* First get event specifier */
686	idx = 0;
687
688	if (strchr(":^*$", command[offs + 1])) {
689		char str[4];
690		/*
691		* "!:" is shorthand for "!!:".
692		* "!^", "!*" and "!$" are shorthand for
693		* "!!:^", "!!:*" and "!!:$" respectively.
694		*/
695		str[0] = str[1] = '!';
696		str[2] = '0';
697		ptr = get_history_event(str, &idx, 0);
698		idx = (command[offs + 1] == ':')? 1:0;
699		has_mods = 1;
700	} else {
701		if (command[offs + 1] == '#') {
702			/* use command so far */
703			if ((aptr = el_malloc((offs + 1) * sizeof(*aptr)))
704			    == NULL)
705				return -1;
706			(void)strncpy(aptr, command, offs);
707			aptr[offs] = '\0';
708			idx = 1;
709		} else {
710			int	qchar;
711
712			qchar = (offs > 0 && command[offs - 1] == '"')? '"':0;
713			ptr = get_history_event(command + offs, &idx, qchar);
714		}
715		has_mods = command[offs + (size_t)idx] == ':';
716	}
717
718	if (ptr == NULL && aptr == NULL)
719		return -1;
720
721	if (!has_mods) {
722		*result = strdup(aptr ? aptr : ptr);
723		if (aptr)
724			el_free(aptr);
725		if (*result == NULL)
726			return -1;
727		return 1;
728	}
729
730	cmd = command + offs + idx + 1;
731
732	/* Now parse any word designators */
733
734	if (*cmd == '%')	/* last word matched by ?pat? */
735		tmp = strdup(last_search_match? last_search_match:"");
736	else if (strchr("^*$-0123456789", *cmd)) {
737		start = end = -1;
738		if (*cmd == '^')
739			start = end = 1, cmd++;
740		else if (*cmd == '$')
741			start = -1, cmd++;
742		else if (*cmd == '*')
743			start = 1, cmd++;
744	       else if (*cmd == '-' || isdigit((unsigned char) *cmd)) {
745			start = 0;
746			while (*cmd && '0' <= *cmd && *cmd <= '9')
747				start = start * 10 + *cmd++ - '0';
748
749			if (*cmd == '-') {
750				if (isdigit((unsigned char) cmd[1])) {
751					cmd++;
752					end = 0;
753					while (*cmd && '0' <= *cmd && *cmd <= '9')
754						end = end * 10 + *cmd++ - '0';
755				} else if (cmd[1] == '$') {
756					cmd += 2;
757					end = -1;
758				} else {
759					cmd++;
760					end = -2;
761				}
762			} else if (*cmd == '*')
763				end = -1, cmd++;
764			else
765				end = start;
766		}
767		tmp = history_arg_extract(start, end, aptr? aptr:ptr);
768		if (tmp == NULL) {
769			(void)fprintf(rl_outstream, "%s: Bad word specifier",
770			    command + offs + idx);
771			if (aptr)
772				el_free(aptr);
773			return -1;
774		}
775	} else
776		tmp = strdup(aptr? aptr:ptr);
777
778	if (aptr)
779		el_free(aptr);
780
781	if (*cmd == '\0' || ((size_t)(cmd - (command + offs)) >= cmdlen)) {
782		*result = tmp;
783		return 1;
784	}
785
786	for (; *cmd; cmd++) {
787		if (*cmd == ':')
788			continue;
789		else if (*cmd == 'h') {		/* remove trailing path */
790			if ((aptr = strrchr(tmp, '/')) != NULL)
791				*aptr = '\0';
792		} else if (*cmd == 't') {	/* remove leading path */
793			if ((aptr = strrchr(tmp, '/')) != NULL) {
794				aptr = strdup(aptr + 1);
795				el_free(tmp);
796				tmp = aptr;
797			}
798		} else if (*cmd == 'r') {	/* remove trailing suffix */
799			if ((aptr = strrchr(tmp, '.')) != NULL)
800				*aptr = '\0';
801		} else if (*cmd == 'e') {	/* remove all but suffix */
802			if ((aptr = strrchr(tmp, '.')) != NULL) {
803				aptr = strdup(aptr);
804				el_free(tmp);
805				tmp = aptr;
806			}
807		} else if (*cmd == 'p')		/* print only */
808			p_on = 1;
809		else if (*cmd == 'g')
810			g_on = 2;
811		else if (*cmd == 's' || *cmd == '&') {
812			char *what, *with, delim;
813			size_t len, from_len;
814			size_t size;
815
816			if (*cmd == '&' && (from == NULL || to == NULL))
817				continue;
818			else if (*cmd == 's') {
819				delim = *(++cmd), cmd++;
820				size = 16;
821				what = el_realloc(from, size * sizeof(*what));
822				if (what == NULL) {
823					el_free(from);
824					el_free(tmp);
825					return 0;
826				}
827				len = 0;
828				for (; *cmd && *cmd != delim; cmd++) {
829					if (*cmd == '\\' && cmd[1] == delim)
830						cmd++;
831					if (len >= size) {
832						char *nwhat;
833						nwhat = el_realloc(what,
834						    (size <<= 1) *
835						    sizeof(*nwhat));
836						if (nwhat == NULL) {
837							el_free(what);
838							el_free(tmp);
839							return 0;
840						}
841						what = nwhat;
842					}
843					what[len++] = *cmd;
844				}
845				what[len] = '\0';
846				from = what;
847				if (*what == '\0') {
848					el_free(what);
849					if (search) {
850						from = strdup(search);
851						if (from == NULL) {
852							el_free(tmp);
853							return 0;
854						}
855					} else {
856						from = NULL;
857						el_free(tmp);
858						return -1;
859					}
860				}
861				cmd++;	/* shift after delim */
862				if (!*cmd)
863					continue;
864
865				size = 16;
866				with = el_realloc(to, size * sizeof(*with));
867				if (with == NULL) {
868					el_free(to);
869					el_free(tmp);
870					return -1;
871				}
872				len = 0;
873				from_len = strlen(from);
874				for (; *cmd && *cmd != delim; cmd++) {
875					if (len + from_len + 1 >= size) {
876						char *nwith;
877						size += from_len + 1;
878						nwith = el_realloc(with,
879						    size * sizeof(*nwith));
880						if (nwith == NULL) {
881							el_free(with);
882							el_free(tmp);
883							return -1;
884						}
885						with = nwith;
886					}
887					if (*cmd == '&') {
888						/* safe */
889						(void)strcpy(&with[len], from);
890						len += from_len;
891						continue;
892					}
893					if (*cmd == '\\'
894					    && (*(cmd + 1) == delim
895						|| *(cmd + 1) == '&'))
896						cmd++;
897					with[len++] = *cmd;
898				}
899				with[len] = '\0';
900				to = with;
901			}
902
903			aptr = _rl_compat_sub(tmp, from, to, g_on);
904			if (aptr) {
905				el_free(tmp);
906				tmp = aptr;
907			}
908			g_on = 0;
909		}
910	}
911	*result = tmp;
912	return p_on? 2:1;
913}
914
915
916/*
917 * csh-style history expansion
918 */
919int
920history_expand(char *str, char **output)
921{
922	int ret = 0;
923	size_t idx, i, size;
924	char *tmp, *result;
925
926	if (h == NULL || e == NULL)
927		rl_initialize();
928
929	if (history_expansion_char == 0) {
930		*output = strdup(str);
931		return 0;
932	}
933
934	*output = NULL;
935	if (str[0] == history_subst_char) {
936		/* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */
937		*output = el_malloc((strlen(str) + 4 + 1) * sizeof(**output));
938		if (*output == NULL)
939			return 0;
940		(*output)[0] = (*output)[1] = history_expansion_char;
941		(*output)[2] = ':';
942		(*output)[3] = 's';
943		(void)strcpy((*output) + 4, str);
944		str = *output;
945	} else {
946		*output = strdup(str);
947		if (*output == NULL)
948			return 0;
949	}
950
951#define ADD_STRING(what, len, fr)					\
952	{								\
953		if (idx + len + 1 > size) {				\
954			char *nresult = el_realloc(result,		\
955			    (size += len + 1) * sizeof(*nresult));	\
956			if (nresult == NULL) {				\
957				el_free(*output);			\
958				if (/*CONSTCOND*/fr)			\
959					el_free(tmp);			\
960				return 0;				\
961			}						\
962			result = nresult;				\
963		}							\
964		(void)strncpy(&result[idx], what, len);			\
965		idx += len;						\
966		result[idx] = '\0';					\
967	}
968
969	result = NULL;
970	size = idx = 0;
971	tmp = NULL;
972	for (i = 0; str[i];) {
973		int qchar, loop_again;
974		size_t len, start, j;
975
976		qchar = 0;
977		loop_again = 1;
978		start = j = i;
979loop:
980		for (; str[j]; j++) {
981			if (str[j] == '\\' &&
982			    str[j + 1] == history_expansion_char) {
983				len = strlen(&str[j + 1]) + 1;
984				memmove(&str[j], &str[j + 1], len);
985				continue;
986			}
987			if (!loop_again) {
988				if (isspace((unsigned char) str[j])
989				    || str[j] == qchar)
990					break;
991			}
992			if (str[j] == history_expansion_char
993			    && !strchr(history_no_expand_chars, str[j + 1])
994			    && (!history_inhibit_expansion_function ||
995			    (*history_inhibit_expansion_function)(str,
996			    (int)j) == 0))
997				break;
998		}
999
1000		if (str[j] && loop_again) {
1001			i = j;
1002			qchar = (j > 0 && str[j - 1] == '"' )? '"':0;
1003			j++;
1004			if (str[j] == history_expansion_char)
1005				j++;
1006			loop_again = 0;
1007			goto loop;
1008		}
1009		len = i - start;
1010		ADD_STRING(&str[start], len, 0);
1011
1012		if (str[i] == '\0' || str[i] != history_expansion_char) {
1013			len = j - i;
1014			ADD_STRING(&str[i], len, 0);
1015			if (start == 0)
1016				ret = 0;
1017			else
1018				ret = 1;
1019			break;
1020		}
1021		ret = _history_expand_command (str, i, (j - i), &tmp);
1022		if (ret > 0 && tmp) {
1023			len = strlen(tmp);
1024			ADD_STRING(tmp, len, 1);
1025		}
1026		if (tmp) {
1027			el_free(tmp);
1028			tmp = NULL;
1029		}
1030		i = j;
1031	}
1032
1033	/* ret is 2 for "print only" option */
1034	if (ret == 2) {
1035		add_history(result);
1036#ifdef GDB_411_HACK
1037		/* gdb 4.11 has been shipped with readline, where */
1038		/* history_expand() returned -1 when the line	  */
1039		/* should not be executed; in readline 2.1+	  */
1040		/* it should return 2 in such a case		  */
1041		ret = -1;
1042#endif
1043	}
1044	el_free(*output);
1045	*output = result;
1046
1047	return ret;
1048}
1049
1050/*
1051* Return a string consisting of arguments of "str" from "start" to "end".
1052*/
1053char *
1054history_arg_extract(int start, int end, const char *str)
1055{
1056	size_t  i, len, max;
1057	char	**arr, *result = NULL;
1058
1059	arr = history_tokenize(str);
1060	if (!arr)
1061		return NULL;
1062	if (arr && *arr == NULL)
1063		goto out;
1064
1065	for (max = 0; arr[max]; max++)
1066		continue;
1067	max--;
1068
1069	if (start == '$')
1070		start = (int)max;
1071	if (end == '$')
1072		end = (int)max;
1073	if (end < 0)
1074		end = (int)max + end + 1;
1075	if (start < 0)
1076		start = end;
1077
1078	if (start < 0 || end < 0 || (size_t)start > max ||
1079	    (size_t)end > max || start > end)
1080		goto out;
1081
1082	for (i = (size_t)start, len = 0; i <= (size_t)end; i++)
1083		len += strlen(arr[i]) + 1;
1084	len++;
1085	result = el_malloc(len * sizeof(*result));
1086	if (result == NULL)
1087		goto out;
1088
1089	for (i = (size_t)start, len = 0; i <= (size_t)end; i++) {
1090		(void)strcpy(result + len, arr[i]);
1091		len += strlen(arr[i]);
1092		if (i < (size_t)end)
1093			result[len++] = ' ';
1094	}
1095	result[len] = '\0';
1096
1097out:
1098	for (i = 0; arr[i]; i++)
1099		el_free(arr[i]);
1100	el_free(arr);
1101
1102	return result;
1103}
1104
1105/*
1106 * Parse the string into individual tokens,
1107 * similar to how shell would do it.
1108 */
1109char **
1110history_tokenize(const char *str)
1111{
1112	int size = 1, idx = 0, i, start;
1113	size_t len;
1114	char **result = NULL, *temp, delim = '\0';
1115
1116	for (i = 0; str[i];) {
1117		while (isspace((unsigned char) str[i]))
1118			i++;
1119		start = i;
1120		for (; str[i];) {
1121			if (str[i] == '\\') {
1122				if (str[i+1] != '\0')
1123					i++;
1124			} else if (str[i] == delim)
1125				delim = '\0';
1126			else if (!delim &&
1127				    (isspace((unsigned char) str[i]) ||
1128				strchr("()<>;&|$", str[i])))
1129				break;
1130			else if (!delim && strchr("'`\"", str[i]))
1131				delim = str[i];
1132			if (str[i])
1133				i++;
1134		}
1135
1136		if (idx + 2 >= size) {
1137			char **nresult;
1138			size <<= 1;
1139			nresult = el_realloc(result, (size_t)size * sizeof(*nresult));
1140			if (nresult == NULL) {
1141				el_free(result);
1142				return NULL;
1143			}
1144			result = nresult;
1145		}
1146		len = (size_t)i - (size_t)start;
1147		temp = el_malloc((size_t)(len + 1) * sizeof(*temp));
1148		if (temp == NULL) {
1149			for (i = 0; i < idx; i++)
1150				el_free(result[i]);
1151			el_free(result);
1152			return NULL;
1153		}
1154		(void)strncpy(temp, &str[start], len);
1155		temp[len] = '\0';
1156		result[idx++] = temp;
1157		result[idx] = NULL;
1158		if (str[i])
1159			i++;
1160	}
1161	return result;
1162}
1163
1164
1165/*
1166 * limit size of history record to ``max'' events
1167 */
1168void
1169stifle_history(int max)
1170{
1171	HistEvent ev;
1172
1173	if (h == NULL || e == NULL)
1174		rl_initialize();
1175
1176	if (history(h, &ev, H_SETSIZE, max) == 0)
1177		max_input_history = max;
1178}
1179
1180
1181/*
1182 * "unlimit" size of history - set the limit to maximum allowed int value
1183 */
1184int
1185unstifle_history(void)
1186{
1187	HistEvent ev;
1188	int omax;
1189
1190	history(h, &ev, H_SETSIZE, INT_MAX);
1191	omax = max_input_history;
1192	max_input_history = INT_MAX;
1193	return omax;		/* some value _must_ be returned */
1194}
1195
1196
1197int
1198history_is_stifled(void)
1199{
1200
1201	/* cannot return true answer */
1202	return max_input_history != INT_MAX;
1203}
1204
1205static const char _history_tmp_template[] = "/tmp/.historyXXXXXX";
1206
1207int
1208history_truncate_file (const char *filename, int nlines)
1209{
1210	int ret = 0;
1211	FILE *fp, *tp;
1212	char template[sizeof(_history_tmp_template)];
1213	char buf[4096];
1214	int fd;
1215	char *cp;
1216	off_t off;
1217	int count = 0;
1218	ssize_t left = 0;
1219
1220	if (filename == NULL && (filename = _default_history_file()) == NULL)
1221		return errno;
1222	if ((fp = fopen(filename, "r+")) == NULL)
1223		return errno;
1224	strcpy(template, _history_tmp_template);
1225	if ((fd = mkstemp(template)) == -1) {
1226		ret = errno;
1227		goto out1;
1228	}
1229
1230	if ((tp = fdopen(fd, "r+")) == NULL) {
1231		close(fd);
1232		ret = errno;
1233		goto out2;
1234	}
1235
1236	for(;;) {
1237		if (fread(buf, sizeof(buf), (size_t)1, fp) != 1) {
1238			if (ferror(fp)) {
1239				ret = errno;
1240				break;
1241			}
1242			if (fseeko(fp, (off_t)sizeof(buf) * count, SEEK_SET) ==
1243			    (off_t)-1) {
1244				ret = errno;
1245				break;
1246			}
1247			left = (ssize_t)fread(buf, (size_t)1, sizeof(buf), fp);
1248			if (ferror(fp)) {
1249				ret = errno;
1250				break;
1251			}
1252			if (left == 0) {
1253				count--;
1254				left = sizeof(buf);
1255			} else if (fwrite(buf, (size_t)left, (size_t)1, tp)
1256			    != 1) {
1257				ret = errno;
1258				break;
1259			}
1260			fflush(tp);
1261			break;
1262		}
1263		if (fwrite(buf, sizeof(buf), (size_t)1, tp) != 1) {
1264			ret = errno;
1265			break;
1266		}
1267		count++;
1268	}
1269	if (ret)
1270		goto out3;
1271	cp = buf + left - 1;
1272	if(*cp != '\n')
1273		cp++;
1274	for(;;) {
1275		while (--cp >= buf) {
1276			if (*cp == '\n') {
1277				if (--nlines == 0) {
1278					if (++cp >= buf + sizeof(buf)) {
1279						count++;
1280						cp = buf;
1281					}
1282					break;
1283				}
1284			}
1285		}
1286		if (nlines <= 0 || count == 0)
1287			break;
1288		count--;
1289		if (fseeko(tp, (off_t)sizeof(buf) * count, SEEK_SET) < 0) {
1290			ret = errno;
1291			break;
1292		}
1293		if (fread(buf, sizeof(buf), (size_t)1, tp) != 1) {
1294			if (ferror(tp)) {
1295				ret = errno;
1296				break;
1297			}
1298			ret = EAGAIN;
1299			break;
1300		}
1301		cp = buf + sizeof(buf);
1302	}
1303
1304	if (ret || nlines > 0)
1305		goto out3;
1306
1307	if (fseeko(fp, (off_t)0, SEEK_SET) == (off_t)-1) {
1308		ret = errno;
1309		goto out3;
1310	}
1311
1312	if (fseeko(tp, (off_t)sizeof(buf) * count + (cp - buf), SEEK_SET) ==
1313	    (off_t)-1) {
1314		ret = errno;
1315		goto out3;
1316	}
1317
1318	for(;;) {
1319		if ((left = (ssize_t)fread(buf, (size_t)1, sizeof(buf), tp)) == 0) {
1320			if (ferror(fp))
1321				ret = errno;
1322			break;
1323		}
1324		if (fwrite(buf, (size_t)left, (size_t)1, fp) != 1) {
1325			ret = errno;
1326			break;
1327		}
1328	}
1329	fflush(fp);
1330	if((off = ftello(fp)) > 0)
1331		(void)ftruncate(fileno(fp), off);
1332out3:
1333	fclose(tp);
1334out2:
1335	unlink(template);
1336out1:
1337	fclose(fp);
1338
1339	return ret;
1340}
1341
1342
1343/*
1344 * read history from a file given
1345 */
1346int
1347read_history(const char *filename)
1348{
1349	HistEvent ev;
1350
1351	if (h == NULL || e == NULL)
1352		rl_initialize();
1353	if (filename == NULL && (filename = _default_history_file()) == NULL)
1354		return errno;
1355	return history(h, &ev, H_LOAD, filename) == -1 ?
1356	    (errno ? errno : EINVAL) : 0;
1357}
1358
1359
1360/*
1361 * write history to a file given
1362 */
1363int
1364write_history(const char *filename)
1365{
1366	HistEvent ev;
1367
1368	if (h == NULL || e == NULL)
1369		rl_initialize();
1370	if (filename == NULL && (filename = _default_history_file()) == NULL)
1371		return errno;
1372	return history(h, &ev, H_SAVE, filename) == -1 ?
1373	    (errno ? errno : EINVAL) : 0;
1374}
1375
1376
1377/*
1378 * returns history ``num''th event
1379 *
1380 * returned pointer points to static variable
1381 */
1382HIST_ENTRY *
1383history_get(int num)
1384{
1385	static HIST_ENTRY she;
1386	HistEvent ev;
1387	int curr_num;
1388
1389	if (h == NULL || e == NULL)
1390		rl_initialize();
1391
1392	/* save current position */
1393	if (history(h, &ev, H_CURR) != 0)
1394		return NULL;
1395	curr_num = ev.num;
1396
1397	/* start from the oldest */
1398	if (history(h, &ev, H_LAST) != 0)
1399		return NULL;	/* error */
1400
1401	/* look forwards for event matching specified offset */
1402	if (history(h, &ev, H_NEXT_EVDATA, num, &she.data))
1403		return NULL;
1404
1405	she.line = ev.str;
1406
1407	/* restore pointer to where it was */
1408	(void)history(h, &ev, H_SET, curr_num);
1409
1410	return &she;
1411}
1412
1413
1414/*
1415 * add the line to history table
1416 */
1417int
1418add_history(const char *line)
1419{
1420	HistEvent ev;
1421
1422	if (line == NULL)
1423		return 0;
1424
1425	if (h == NULL || e == NULL)
1426		rl_initialize();
1427
1428	(void)history(h, &ev, H_ENTER, line);
1429	if (history(h, &ev, H_GETSIZE) == 0)
1430		history_length = ev.num;
1431
1432	return !(history_length > 0); /* return 0 if all is okay */
1433}
1434
1435
1436/*
1437 * remove the specified entry from the history list and return it.
1438 */
1439HIST_ENTRY *
1440remove_history(int num)
1441{
1442	HIST_ENTRY *he;
1443	HistEvent ev;
1444
1445	if (h == NULL || e == NULL)
1446		rl_initialize();
1447
1448	if ((he = el_malloc(sizeof(*he))) == NULL)
1449		return NULL;
1450
1451	if (history(h, &ev, H_DELDATA, num, &he->data) != 0) {
1452		el_free(he);
1453		return NULL;
1454	}
1455
1456	he->line = ev.str;
1457	if (history(h, &ev, H_GETSIZE) == 0)
1458		history_length = ev.num;
1459
1460	return he;
1461}
1462
1463
1464/*
1465 * replace the line and data of the num-th entry
1466 */
1467HIST_ENTRY *
1468replace_history_entry(int num, const char *line, histdata_t data)
1469{
1470	HIST_ENTRY *he;
1471	HistEvent ev;
1472	int curr_num;
1473
1474	if (h == NULL || e == NULL)
1475		rl_initialize();
1476
1477	/* save current position */
1478	if (history(h, &ev, H_CURR) != 0)
1479		return NULL;
1480	curr_num = ev.num;
1481
1482	/* start from the oldest */
1483	if (history(h, &ev, H_LAST) != 0)
1484		return NULL;	/* error */
1485
1486	if ((he = el_malloc(sizeof(*he))) == NULL)
1487		return NULL;
1488
1489	/* look forwards for event matching specified offset */
1490	if (history(h, &ev, H_NEXT_EVDATA, num, &he->data))
1491		goto out;
1492
1493	he->line = strdup(ev.str);
1494	if (he->line == NULL)
1495		goto out;
1496
1497	if (history(h, &ev, H_REPLACE, line, data))
1498		goto out;
1499
1500	/* restore pointer to where it was */
1501	if (history(h, &ev, H_SET, curr_num))
1502		goto out;
1503
1504	return he;
1505out:
1506	el_free(he);
1507	return NULL;
1508}
1509
1510/*
1511 * clear the history list - delete all entries
1512 */
1513void
1514clear_history(void)
1515{
1516	HistEvent ev;
1517
1518	if (h == NULL || e == NULL)
1519		rl_initialize();
1520
1521	(void)history(h, &ev, H_CLEAR);
1522	history_length = 0;
1523}
1524
1525
1526/*
1527 * returns offset of the current history event
1528 */
1529int
1530where_history(void)
1531{
1532	HistEvent ev;
1533	int curr_num, off;
1534
1535	if (history(h, &ev, H_CURR) != 0)
1536		return 0;
1537	curr_num = ev.num;
1538
1539	(void)history(h, &ev, H_FIRST);
1540	off = 1;
1541	while (ev.num != curr_num && history(h, &ev, H_NEXT) == 0)
1542		off++;
1543
1544	return off;
1545}
1546
1547
1548/*
1549 * returns current history event or NULL if there is no such event
1550 */
1551HIST_ENTRY *
1552current_history(void)
1553{
1554
1555	return _move_history(H_CURR);
1556}
1557
1558
1559/*
1560 * returns total number of bytes history events' data are using
1561 */
1562int
1563history_total_bytes(void)
1564{
1565	HistEvent ev;
1566	int curr_num;
1567	size_t size;
1568
1569	if (history(h, &ev, H_CURR) != 0)
1570		return -1;
1571	curr_num = ev.num;
1572
1573	(void)history(h, &ev, H_FIRST);
1574	size = 0;
1575	do
1576		size += strlen(ev.str) * sizeof(*ev.str);
1577	while (history(h, &ev, H_NEXT) == 0);
1578
1579	/* get to the same position as before */
1580	history(h, &ev, H_PREV_EVENT, curr_num);
1581
1582	return (int)size;
1583}
1584
1585
1586/*
1587 * sets the position in the history list to ``pos''
1588 */
1589int
1590history_set_pos(int pos)
1591{
1592	HistEvent ev;
1593	int curr_num;
1594
1595	if (pos >= history_length || pos < 0)
1596		return -1;
1597
1598	(void)history(h, &ev, H_CURR);
1599	curr_num = ev.num;
1600
1601	/*
1602	 * use H_DELDATA to set to nth history (without delete) by passing
1603	 * (void **)-1
1604	 */
1605	if (history(h, &ev, H_DELDATA, pos, (void **)-1)) {
1606		(void)history(h, &ev, H_SET, curr_num);
1607		return -1;
1608	}
1609	return 0;
1610}
1611
1612
1613/*
1614 * returns previous event in history and shifts pointer accordingly
1615 */
1616HIST_ENTRY *
1617previous_history(void)
1618{
1619
1620	return _move_history(H_PREV);
1621}
1622
1623
1624/*
1625 * returns next event in history and shifts pointer accordingly
1626 */
1627HIST_ENTRY *
1628next_history(void)
1629{
1630
1631	return _move_history(H_NEXT);
1632}
1633
1634
1635/*
1636 * searches for first history event containing the str
1637 */
1638int
1639history_search(const char *str, int direction)
1640{
1641	HistEvent ev;
1642	const char *strp;
1643	int curr_num;
1644
1645	if (history(h, &ev, H_CURR) != 0)
1646		return -1;
1647	curr_num = ev.num;
1648
1649	for (;;) {
1650		if ((strp = strstr(ev.str, str)) != NULL)
1651			return (int)(strp - ev.str);
1652		if (history(h, &ev, direction < 0 ? H_NEXT:H_PREV) != 0)
1653			break;
1654	}
1655	(void)history(h, &ev, H_SET, curr_num);
1656	return -1;
1657}
1658
1659
1660/*
1661 * searches for first history event beginning with str
1662 */
1663int
1664history_search_prefix(const char *str, int direction)
1665{
1666	HistEvent ev;
1667
1668	return (history(h, &ev, direction < 0 ?
1669	    H_PREV_STR : H_NEXT_STR, str));
1670}
1671
1672
1673/*
1674 * search for event in history containing str, starting at offset
1675 * abs(pos); continue backward, if pos<0, forward otherwise
1676 */
1677/* ARGSUSED */
1678int
1679history_search_pos(const char *str,
1680		   int direction __attribute__((__unused__)), int pos)
1681{
1682	HistEvent ev;
1683	int curr_num, off;
1684
1685	off = (pos > 0) ? pos : -pos;
1686	pos = (pos > 0) ? 1 : -1;
1687
1688	if (history(h, &ev, H_CURR) != 0)
1689		return -1;
1690	curr_num = ev.num;
1691
1692	if (history_set_pos(off) != 0 || history(h, &ev, H_CURR) != 0)
1693		return -1;
1694
1695	for (;;) {
1696		if (strstr(ev.str, str))
1697			return off;
1698		if (history(h, &ev, (pos < 0) ? H_PREV : H_NEXT) != 0)
1699			break;
1700	}
1701
1702	/* set "current" pointer back to previous state */
1703	(void)history(h, &ev,
1704	    pos < 0 ? H_NEXT_EVENT : H_PREV_EVENT, curr_num);
1705
1706	return -1;
1707}
1708
1709
1710/********************************/
1711/* completion functions */
1712
1713char *
1714tilde_expand(char *name)
1715{
1716	return fn_tilde_expand(name);
1717}
1718
1719char *
1720filename_completion_function(const char *name, int state)
1721{
1722	return fn_filename_completion_function(name, state);
1723}
1724
1725/*
1726 * a completion generator for usernames; returns _first_ username
1727 * which starts with supplied text
1728 * text contains a partial username preceded by random character
1729 * (usually '~'); state resets search from start (??? should we do that anyway)
1730 * it's the caller's responsibility to free the returned value
1731 */
1732char *
1733username_completion_function(const char *text, int state)
1734{
1735#if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT)
1736	struct passwd pwres;
1737	char pwbuf[1024];
1738#endif
1739	struct passwd *pass = NULL;
1740
1741	if (text[0] == '\0')
1742		return NULL;
1743
1744	if (*text == '~')
1745		text++;
1746
1747	if (state == 0)
1748		setpwent();
1749
1750	while (
1751#if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT)
1752	    getpwent_r(&pwres, pwbuf, sizeof(pwbuf), &pass) == 0 && pass != NULL
1753#else
1754	    (pass = getpwent()) != NULL
1755#endif
1756	    && text[0] == pass->pw_name[0]
1757	    && strcmp(text, pass->pw_name) == 0)
1758		continue;
1759
1760	if (pass == NULL) {
1761		endpwent();
1762		return NULL;
1763	}
1764	return strdup(pass->pw_name);
1765}
1766
1767
1768/*
1769 * el-compatible wrapper to send TSTP on ^Z
1770 */
1771/* ARGSUSED */
1772static unsigned char
1773_el_rl_tstp(EditLine *el __attribute__((__unused__)), int ch __attribute__((__unused__)))
1774{
1775	(void)kill(0, SIGTSTP);
1776	return CC_NORM;
1777}
1778
1779/*
1780 * Display list of strings in columnar format on readline's output stream.
1781 * 'matches' is list of strings, 'len' is number of strings in 'matches',
1782 * 'max' is maximum length of string in 'matches'.
1783 */
1784void
1785rl_display_match_list(char **matches, int len, int max)
1786{
1787
1788	fn_display_match_list(e, matches, (size_t)len, (size_t)max);
1789}
1790
1791static const char *
1792/*ARGSUSED*/
1793_rl_completion_append_character_function(const char *dummy
1794    __attribute__((__unused__)))
1795{
1796	static char buf[2];
1797	buf[0] = (char)rl_completion_append_character;
1798	buf[1] = '\0';
1799	return buf;
1800}
1801
1802
1803/*
1804 * complete word at current point
1805 */
1806/* ARGSUSED */
1807int
1808rl_complete(int ignore __attribute__((__unused__)), int invoking_key)
1809{
1810#ifdef WIDECHAR
1811	static ct_buffer_t wbreak_conv, sprefix_conv;
1812#endif
1813	char *breakchars;
1814
1815	if (h == NULL || e == NULL)
1816		rl_initialize();
1817
1818	if (rl_inhibit_completion) {
1819		char arr[2];
1820		arr[0] = (char)invoking_key;
1821		arr[1] = '\0';
1822		el_insertstr(e, arr);
1823		return CC_REFRESH;
1824	}
1825
1826	if (rl_completion_word_break_hook != NULL)
1827		breakchars = (*rl_completion_word_break_hook)();
1828	else
1829		breakchars = rl_basic_word_break_characters;
1830
1831	_rl_update_pos();
1832
1833	/* Just look at how many global variables modify this operation! */
1834	return fn_complete(e,
1835	    (rl_compentry_func_t *)rl_completion_entry_function,
1836	    rl_attempted_completion_function,
1837	    ct_decode_string(rl_basic_word_break_characters, &wbreak_conv),
1838	    ct_decode_string(breakchars, &sprefix_conv),
1839	    _rl_completion_append_character_function,
1840	    (size_t)rl_completion_query_items,
1841	    &rl_completion_type, &rl_attempted_completion_over,
1842	    &rl_point, &rl_end, NULL, NULL, NULL);
1843
1844
1845}
1846
1847
1848/* ARGSUSED */
1849static unsigned char
1850_el_rl_complete(EditLine *el __attribute__((__unused__)), int ch)
1851{
1852	return (unsigned char)rl_complete(0, ch);
1853}
1854
1855/*
1856 * misc other functions
1857 */
1858
1859/*
1860 * bind key c to readline-type function func
1861 */
1862int
1863rl_bind_key(int c, rl_command_func_t *func)
1864{
1865	int retval = -1;
1866
1867	if (h == NULL || e == NULL)
1868		rl_initialize();
1869
1870	if (func == rl_insert) {
1871		/* XXX notice there is no range checking of ``c'' */
1872		e->el_map.key[c] = ED_INSERT;
1873		retval = 0;
1874	}
1875	return retval;
1876}
1877
1878
1879/*
1880 * read one key from input - handles chars pushed back
1881 * to input stream also
1882 */
1883int
1884rl_read_key(void)
1885{
1886	char fooarr[2 * sizeof(int)];
1887
1888	if (e == NULL || h == NULL)
1889		rl_initialize();
1890
1891	return el_getc(e, fooarr);
1892}
1893
1894
1895/*
1896 * reset the terminal
1897 */
1898/* ARGSUSED */
1899void
1900rl_reset_terminal(const char *p __attribute__((__unused__)))
1901{
1902
1903	if (h == NULL || e == NULL)
1904		rl_initialize();
1905	el_reset(e);
1906}
1907
1908
1909/*
1910 * insert character ``c'' back into input stream, ``count'' times
1911 */
1912int
1913rl_insert(int count, int c)
1914{
1915	char arr[2];
1916
1917	if (h == NULL || e == NULL)
1918		rl_initialize();
1919
1920	/* XXX - int -> char conversion can lose on multichars */
1921	arr[0] = (char)c;
1922	arr[1] = '\0';
1923
1924	for (; count > 0; count--)
1925		el_push(e, arr);
1926
1927	return 0;
1928}
1929
1930int
1931rl_insert_text(const char *text)
1932{
1933	if (!text || *text == 0)
1934		return 0;
1935
1936	if (h == NULL || e == NULL)
1937		rl_initialize();
1938
1939	if (el_insertstr(e, text) < 0)
1940		return 0;
1941	return (int)strlen(text);
1942}
1943
1944/*ARGSUSED*/
1945int
1946rl_newline(int count __attribute__((__unused__)),
1947    int c __attribute__((__unused__)))
1948{
1949	/*
1950	 * Readline-4.0 appears to ignore the args.
1951	 */
1952	return rl_insert(1, '\n');
1953}
1954
1955/*ARGSUSED*/
1956static unsigned char
1957rl_bind_wrapper(EditLine *el __attribute__((__unused__)), unsigned char c)
1958{
1959	if (map[c] == NULL)
1960	    return CC_ERROR;
1961
1962	_rl_update_pos();
1963
1964	(*map[c])(1, c);
1965
1966	/* If rl_done was set by the above call, deal with it here */
1967	if (rl_done)
1968		return CC_EOF;
1969
1970	return CC_NORM;
1971}
1972
1973int
1974rl_add_defun(const char *name, rl_command_func_t *fun, int c)
1975{
1976	char dest[8];
1977	if ((size_t)c >= sizeof(map) / sizeof(map[0]) || c < 0)
1978		return -1;
1979	map[(unsigned char)c] = fun;
1980	el_set(e, EL_ADDFN, name, name, rl_bind_wrapper);
1981	vis(dest, c, VIS_WHITE|VIS_NOSLASH, 0);
1982	el_set(e, EL_BIND, dest, name, NULL);
1983	return 0;
1984}
1985
1986void
1987rl_callback_read_char(void)
1988{
1989	int count = 0, done = 0;
1990	const char *buf = el_gets(e, &count);
1991	char *wbuf;
1992
1993	if (buf == NULL || count-- <= 0)
1994		return;
1995	if (count == 0 && buf[0] == e->el_tty.t_c[TS_IO][C_EOF])
1996		done = 1;
1997	if (buf[count] == '\n' || buf[count] == '\r')
1998		done = 2;
1999
2000	if (done && rl_linefunc != NULL) {
2001		el_set(e, EL_UNBUFFERED, 0);
2002		if (done == 2) {
2003		    if ((wbuf = strdup(buf)) != NULL)
2004			wbuf[count] = '\0';
2005		} else
2006			wbuf = NULL;
2007		(*(void (*)(const char *))rl_linefunc)(wbuf);
2008		el_set(e, EL_UNBUFFERED, 1);
2009	}
2010}
2011
2012void
2013rl_callback_handler_install(const char *prompt, rl_vcpfunc_t *linefunc)
2014{
2015	if (e == NULL) {
2016		rl_initialize();
2017	}
2018	(void)rl_set_prompt(prompt);
2019	rl_linefunc = linefunc;
2020	el_set(e, EL_UNBUFFERED, 1);
2021}
2022
2023void
2024rl_callback_handler_remove(void)
2025{
2026	el_set(e, EL_UNBUFFERED, 0);
2027	rl_linefunc = NULL;
2028}
2029
2030void
2031rl_redisplay(void)
2032{
2033	char a[2];
2034	a[0] = (char)e->el_tty.t_c[TS_IO][C_REPRINT];
2035	a[1] = '\0';
2036	el_push(e, a);
2037}
2038
2039int
2040rl_get_previous_history(int count, int key)
2041{
2042	char a[2];
2043	a[0] = (char)key;
2044	a[1] = '\0';
2045	while (count--)
2046		el_push(e, a);
2047	return 0;
2048}
2049
2050void
2051/*ARGSUSED*/
2052rl_prep_terminal(int meta_flag __attribute__((__unused__)))
2053{
2054	el_set(e, EL_PREP_TERM, 1);
2055}
2056
2057void
2058rl_deprep_terminal(void)
2059{
2060	el_set(e, EL_PREP_TERM, 0);
2061}
2062
2063int
2064rl_read_init_file(const char *s)
2065{
2066	return el_source(e, s);
2067}
2068
2069int
2070rl_parse_and_bind(const char *line)
2071{
2072	const char **argv;
2073	int argc;
2074	Tokenizer *tok;
2075
2076	tok = tok_init(NULL);
2077	tok_str(tok, line, &argc, &argv);
2078	argc = el_parse(e, argc, argv);
2079	tok_end(tok);
2080	return argc ? 1 : 0;
2081}
2082
2083int
2084rl_variable_bind(const char *var, const char *value)
2085{
2086	/*
2087	 * The proper return value is undocument, but this is what the
2088	 * readline source seems to do.
2089	 */
2090	return el_set(e, EL_BIND, "", var, value, NULL) == -1 ? 1 : 0;
2091}
2092
2093void
2094rl_stuff_char(int c)
2095{
2096	char buf[2];
2097
2098	buf[0] = (char)c;
2099	buf[1] = '\0';
2100	el_insertstr(e, buf);
2101}
2102
2103static int
2104_rl_event_read_char(EditLine *el, wchar_t *wc)
2105{
2106	char	ch;
2107	int	n;
2108	ssize_t num_read = 0;
2109
2110	ch = '\0';
2111	*wc = L'\0';
2112	while (rl_event_hook) {
2113
2114		(*rl_event_hook)();
2115
2116#if defined(FIONREAD)
2117		if (ioctl(el->el_infd, FIONREAD, &n) < 0)
2118			return -1;
2119		if (n)
2120			num_read = read(el->el_infd, &ch, (size_t)1);
2121		else
2122			num_read = 0;
2123#elif defined(F_SETFL) && defined(O_NDELAY)
2124		if ((n = fcntl(el->el_infd, F_GETFL, 0)) < 0)
2125			return -1;
2126		if (fcntl(el->el_infd, F_SETFL, n|O_NDELAY) < 0)
2127			return -1;
2128		num_read = read(el->el_infd, &ch, 1);
2129		if (fcntl(el->el_infd, F_SETFL, n))
2130			return -1;
2131#else
2132		/* not non-blocking, but what you gonna do? */
2133		num_read = read(el->el_infd, &ch, 1);
2134		return -1;
2135#endif
2136
2137		if (num_read < 0 && errno == EAGAIN)
2138			continue;
2139		if (num_read == 0)
2140			continue;
2141		break;
2142	}
2143	if (!rl_event_hook)
2144		el_set(el, EL_GETCFN, EL_BUILTIN_GETCFN);
2145	*wc = (wchar_t)ch;
2146	return (int)num_read;
2147}
2148
2149static void
2150_rl_update_pos(void)
2151{
2152	const LineInfo *li = el_line(e);
2153
2154	rl_point = (int)(li->cursor - li->buffer);
2155	rl_end = (int)(li->lastchar - li->buffer);
2156}
2157
2158void
2159rl_get_screen_size(int *rows, int *cols)
2160{
2161	if (rows)
2162		el_get(e, EL_GETTC, "li", rows, (void *)0);
2163	if (cols)
2164		el_get(e, EL_GETTC, "co", cols, (void *)0);
2165}
2166
2167void
2168rl_set_screen_size(int rows, int cols)
2169{
2170	char buf[64];
2171	(void)snprintf(buf, sizeof(buf), "%d", rows);
2172	el_set(e, EL_SETTC, "li", buf, NULL);
2173	(void)snprintf(buf, sizeof(buf), "%d", cols);
2174	el_set(e, EL_SETTC, "co", buf, NULL);
2175}
2176
2177char **
2178rl_completion_matches(const char *str, rl_compentry_func_t *fun)
2179{
2180	size_t len, max, i, j, min;
2181	char **list, *match, *a, *b;
2182
2183	len = 1;
2184	max = 10;
2185	if ((list = el_malloc(max * sizeof(*list))) == NULL)
2186		return NULL;
2187
2188	while ((match = (*fun)(str, (int)(len - 1))) != NULL) {
2189		list[len++] = match;
2190		if (len == max) {
2191			char **nl;
2192			max += 10;
2193			if ((nl = el_realloc(list, max * sizeof(*nl))) == NULL)
2194				goto out;
2195			list = nl;
2196		}
2197	}
2198	if (len == 1)
2199		goto out;
2200	list[len] = NULL;
2201	if (len == 2) {
2202		if ((list[0] = strdup(list[1])) == NULL)
2203			goto out;
2204		return list;
2205	}
2206	qsort(&list[1], len - 1, sizeof(*list),
2207	    (int (*)(const void *, const void *)) strcmp);
2208	min = SIZE_MAX;
2209	for (i = 1, a = list[i]; i < len - 1; i++, a = b) {
2210		b = list[i + 1];
2211		for (j = 0; a[j] && a[j] == b[j]; j++)
2212			continue;
2213		if (min > j)
2214			min = j;
2215	}
2216	if (min == 0 && *str) {
2217		if ((list[0] = strdup(str)) == NULL)
2218			goto out;
2219	} else {
2220		if ((list[0] = el_malloc((min + 1) * sizeof(*list[0]))) == NULL)
2221			goto out;
2222		(void)memcpy(list[0], list[1], min);
2223		list[0][min] = '\0';
2224	}
2225	return list;
2226
2227out:
2228	el_free(list);
2229	return NULL;
2230}
2231
2232char *
2233rl_filename_completion_function (const char *text, int state)
2234{
2235	return fn_filename_completion_function(text, state);
2236}
2237
2238void
2239rl_forced_update_display(void)
2240{
2241	el_set(e, EL_REFRESH);
2242}
2243
2244int
2245_rl_abort_internal(void)
2246{
2247	el_beep(e);
2248	longjmp(topbuf, 1);
2249	/*NOTREACHED*/
2250}
2251
2252int
2253_rl_qsort_string_compare(char **s1, char **s2)
2254{
2255	return strcoll(*s1, *s2);
2256}
2257
2258HISTORY_STATE *
2259history_get_history_state(void)
2260{
2261	HISTORY_STATE *hs;
2262
2263	if ((hs = el_malloc(sizeof(*hs))) == NULL)
2264		return NULL;
2265	hs->length = history_length;
2266	return hs;
2267}
2268
2269int
2270/*ARGSUSED*/
2271rl_kill_text(int from __attribute__((__unused__)),
2272    int to __attribute__((__unused__)))
2273{
2274	return 0;
2275}
2276
2277Keymap
2278rl_make_bare_keymap(void)
2279{
2280	return NULL;
2281}
2282
2283Keymap
2284rl_get_keymap(void)
2285{
2286	return NULL;
2287}
2288
2289void
2290/*ARGSUSED*/
2291rl_set_keymap(Keymap k __attribute__((__unused__)))
2292{
2293}
2294
2295int
2296/*ARGSUSED*/
2297rl_generic_bind(int type __attribute__((__unused__)),
2298    const char * keyseq __attribute__((__unused__)),
2299    const char * data __attribute__((__unused__)),
2300    Keymap k __attribute__((__unused__)))
2301{
2302	return 0;
2303}
2304
2305int
2306/*ARGSUSED*/
2307rl_bind_key_in_map(int key __attribute__((__unused__)),
2308    rl_command_func_t *fun __attribute__((__unused__)),
2309    Keymap k __attribute__((__unused__)))
2310{
2311	return 0;
2312}
2313
2314/* unsupported, but needed by python */
2315void
2316rl_cleanup_after_signal(void)
2317{
2318}
2319
2320int
2321rl_on_new_line(void)
2322{
2323	return 0;
2324}
2325
2326void
2327rl_free_line_state(void)
2328{
2329}
2330
2331int
2332/*ARGSUSED*/
2333rl_set_keyboard_input_timeout(int u __attribute__((__unused__)))
2334{
2335	return 0;
2336}
2337