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