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