xref: /openbsd/lib/libedit/readline.c (revision 5b133f3f)
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 
59 void rl_prep_terminal(int);
60 void 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 */
70 const char *rl_library_version = "EditLine wrapper";
71 int rl_readline_version = RL_READLINE_VERSION;
72 static char empty[] = { '\0' };
73 static char expand_chars[] = { ' ', '\t', '\n', '=', '(', '\0' };
74 static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$',
75     '>', '<', '=', ';', '|', '&', '{', '(', '\0' };
76 char *rl_readline_name = empty;
77 FILE *rl_instream = NULL;
78 FILE *rl_outstream = NULL;
79 int rl_point = 0;
80 int rl_end = 0;
81 char *rl_line_buffer = NULL;
82 VCPFunction *rl_linefunc = NULL;
83 int rl_done = 0;
84 VFunction *rl_event_hook = NULL;
85 KEYMAP_ENTRY_ARRAY emacs_standard_keymap,
86     emacs_meta_keymap,
87     emacs_ctlx_keymap;
88 
89 int history_base = 1;		/* probably never subject to change */
90 int history_length = 0;
91 int max_input_history = 0;
92 char history_expansion_char = '!';
93 char history_subst_char = '^';
94 char *history_no_expand_chars = expand_chars;
95 Function *history_inhibit_expansion_function = NULL;
96 char *history_arg_extract(int start, int end, const char *str);
97 
98 int rl_inhibit_completion = 0;
99 int rl_attempted_completion_over = 0;
100 char *rl_basic_word_break_characters = break_chars;
101 char *rl_completer_word_break_characters = NULL;
102 char *rl_completer_quote_characters = NULL;
103 Function *rl_completion_entry_function = NULL;
104 CPPFunction *rl_attempted_completion_function = NULL;
105 Function *rl_pre_input_hook = NULL;
106 Function *rl_startup1_hook = NULL;
107 int (*rl_getc_function)(FILE *) = NULL;
108 char *rl_terminal_name = NULL;
109 int rl_already_prompted = 0;
110 int rl_filename_completion_desired = 0;
111 int rl_ignore_completion_duplicates = 0;
112 int rl_catch_signals = 1;
113 int readline_echoing_p = 1;
114 int _rl_print_completions_horizontally = 0;
115 VFunction *rl_redisplay_function = NULL;
116 Function *rl_startup_hook = NULL;
117 VFunction *rl_completion_display_matches_hook = NULL;
118 VFunction *rl_prep_term_function = (VFunction *)rl_prep_terminal;
119 VFunction *rl_deprep_term_function = (VFunction *)rl_deprep_terminal;
120 KEYMAP_ENTRY_ARRAY emacs_meta_keymap;
121 
122 /*
123  * The current prompt string.
124  */
125 char *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  */
131 int 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  */
137 int 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  */
144 char *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  */
150 int 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  */
158 static int current_history_valid = 1;
159 
160 /* stuff below is used internally by libedit for readline emulation */
161 
162 static History *h = NULL;
163 static EditLine *e = NULL;
164 static Function *map[256];
165 static jmp_buf topbuf;
166 
167 /* internal functions */
168 static unsigned char	 _el_rl_complete(EditLine *, int);
169 static unsigned char	 _el_rl_tstp(EditLine *, int);
170 static char		*_get_prompt(EditLine *);
171 static int		 _getc_function(EditLine *, wchar_t *);
172 static HIST_ENTRY	*_move_history(int);
173 static int		 _history_expand_command(const char *, size_t, size_t,
174     char **);
175 static char		*_rl_compat_sub(const char *, const char *,
176     const char *, int);
177 static int		 _rl_event_read_char(EditLine *, wchar_t *);
178 static void		 _rl_update_pos(void);
179 
180 
181 static char *
_get_prompt(EditLine * el)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  */
192 static HIST_ENTRY *
_move_history(int op)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  */
211 static int
_getc_function(EditLine * el,wchar_t * c)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 
223 static void
_resize_fun(EditLine * el,void * a)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 
234 static const char _dothistory[] = "/.history";
235 
236 static const char *
_default_history_file(void)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  */
258 int
rl_set_prompt(const char * prompt)259 rl_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  */
282 int
rl_initialize(void)283 rl_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  */
383 char *
readline(const char * p)384 readline(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  */
448 void
using_history(void)449 using_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  */
461 static char *
_rl_compat_sub(const char * str,const char * what,const char * with,int globally)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 
504 static	char	*last_search_pat;	/* last !?pat[?] search pattern */
505 static	char	*last_search_match;	/* last !?pat[?] that matched */
506 
507 const char *
get_history_event(const char * cmd,int * cindex,int qchar)508 get_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  */
636 static int
_history_expand_command(const char * command,size_t offs,size_t cmdlen,char ** result)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  */
883 int
history_expand(char * str,char ** output)884 history_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;
943 loop:
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 */
1017 char *
history_arg_extract(int start,int end,const char * str)1018 history_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 
1062 out:
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  */
1074 char **
history_tokenize(const char * str)1075 history_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  */
1134 void
stifle_history(int max)1135 stifle_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  */
1162 int
unstifle_history(void)1163 unstifle_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 
1175 int
history_is_stifled(void)1176 history_is_stifled(void)
1177 {
1178 
1179 	/* cannot return true answer */
1180 	return max_input_history != INT_MAX;
1181 }
1182 
1183 static const char _history_tmp_template[] = "/tmp/.historyXXXXXX";
1184 
1185 int
history_truncate_file(const char * filename,int nlines)1186 history_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);
1309 out3:
1310 	fclose(tp);
1311 out2:
1312 	unlink(template);
1313 out1:
1314 	fclose(fp);
1315 
1316 	return ret;
1317 }
1318 
1319 
1320 /*
1321  * read history from a file given
1322  */
1323 int
read_history(const char * filename)1324 read_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  */
1340 int
write_history(const char * filename)1341 write_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  */
1359 HIST_ENTRY *
history_get(int num)1360 history_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 
1396 out:
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  */
1406 int
add_history(const char * line)1407 add_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  */
1426 HIST_ENTRY *
remove_history(int num)1427 remove_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  */
1454 HIST_ENTRY *
replace_history_entry(int num,const char * line,histdata_t data)1455 replace_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;
1492 out:
1493 	free(he);
1494 	return NULL;
1495 }
1496 
1497 /*
1498  * clear the history list - delete all entries
1499  */
1500 void
clear_history(void)1501 clear_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  */
1514 int
where_history(void)1515 where_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  */
1539 HIST_ENTRY *
current_history(void)1540 current_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  */
1550 int
history_total_bytes(void)1551 history_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  */
1577 int
history_set_pos(int pos)1578 history_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  */
1606 HIST_ENTRY *
previous_history(void)1607 previous_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  */
1621 HIST_ENTRY *
next_history(void)1622 next_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  */
1636 int
history_search(const char * str,int direction)1637 history_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  */
1661 int
history_search_prefix(const char * str,int direction)1662 history_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  */
1675 int
history_search_pos(const char * str,int direction,int pos)1676 history_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 
1710 char *
tilde_expand(char * name)1711 tilde_expand(char *name)
1712 {
1713 	return fn_tilde_expand(name);
1714 }
1715 
1716 char *
filename_completion_function(const char * name,int state)1717 filename_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  */
1729 char *
username_completion_function(const char * text,int state)1730 username_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  */
1757 static unsigned char
_el_rl_tstp(EditLine * el,int ch)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  */
1769 void
rl_display_match_list(char ** matches,int len,int max)1770 rl_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 
1776 static const char *
_rl_completion_append_character_function(const char * dummy)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  */
1790 int
rl_complete(int ignore,int invoking_key)1791 rl_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 
1821 static unsigned char
_el_rl_complete(EditLine * el,int ch)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  */
1834 int
rl_bind_key(int c,rl_command_func_t * func)1835 rl_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  */
1855 int
rl_read_key(void)1856 rl_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  */
1870 void
rl_reset_terminal(const char * p)1871 rl_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  */
1883 int
rl_insert(int count,int c)1884 rl_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 
1901 int
rl_insert_text(const char * text)1902 rl_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 
1915 int
rl_newline(int count,int c)1916 rl_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 
1924 static unsigned char
rl_bind_wrapper(EditLine * el,unsigned char c)1925 rl_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 
1941 int
rl_add_defun(const char * name,Function * fun,int c)1942 rl_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 
1954 void
rl_callback_read_char()1955 rl_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 
1980 void
rl_callback_handler_install(const char * prompt,VCPFunction * linefunc)1981 rl_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 
1991 void
rl_callback_handler_remove(void)1992 rl_callback_handler_remove(void)
1993 {
1994 	el_set(e, EL_UNBUFFERED, 0);
1995 	rl_linefunc = NULL;
1996 }
1997 
1998 void
rl_redisplay(void)1999 rl_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 
2007 int
rl_get_previous_history(int count,int key)2008 rl_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 
2018 void
rl_prep_terminal(int meta_flag)2019 rl_prep_terminal(int meta_flag)
2020 {
2021 	el_set(e, EL_PREP_TERM, 1);
2022 }
2023 
2024 void
rl_deprep_terminal(void)2025 rl_deprep_terminal(void)
2026 {
2027 	el_set(e, EL_PREP_TERM, 0);
2028 }
2029 
2030 int
rl_read_init_file(const char * s)2031 rl_read_init_file(const char *s)
2032 {
2033 	return el_source(e, s);
2034 }
2035 
2036 int
rl_parse_and_bind(const char * line)2037 rl_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 
2050 int
rl_variable_bind(const char * var,const char * value)2051 rl_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 
2060 void
rl_stuff_char(int c)2061 rl_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 
2070 static int
_rl_event_read_char(EditLine * el,wchar_t * wc)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 
2116 static void
_rl_update_pos(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 
2125 void
rl_get_screen_size(int * rows,int * cols)2126 rl_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 
2134 void
rl_set_screen_size(int rows,int cols)2135 rl_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 
2144 char **
rl_completion_matches(const char * str,rl_compentry_func_t * fun)2145 rl_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 
2194 out:
2195 	free(list);
2196 	return NULL;
2197 }
2198 
2199 char *
rl_filename_completion_function(const char * text,int state)2200 rl_filename_completion_function (const char *text, int state)
2201 {
2202 	return fn_filename_completion_function(text, state);
2203 }
2204 
2205 void
rl_forced_update_display(void)2206 rl_forced_update_display(void)
2207 {
2208 	el_set(e, EL_REFRESH);
2209 }
2210 
2211 int
_rl_abort_internal(void)2212 _rl_abort_internal(void)
2213 {
2214 	el_beep(e);
2215 	longjmp(topbuf, 1);
2216 	/*NOTREACHED*/
2217 }
2218 
2219 int
_rl_qsort_string_compare(char ** s1,char ** s2)2220 _rl_qsort_string_compare(char **s1, char **s2)
2221 {
2222 	return strcoll(*s1, *s2);
2223 }
2224 
2225 HISTORY_STATE *
history_get_history_state(void)2226 history_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 
2236 int
rl_kill_text(int from,int to)2237 rl_kill_text(int from, int to)
2238 {
2239 	return 0;
2240 }
2241 
2242 Keymap
rl_make_bare_keymap(void)2243 rl_make_bare_keymap(void)
2244 {
2245 	return NULL;
2246 }
2247 
2248 Keymap
rl_get_keymap(void)2249 rl_get_keymap(void)
2250 {
2251 	return NULL;
2252 }
2253 
2254 void
rl_set_keymap(Keymap k)2255 rl_set_keymap(Keymap k)
2256 {
2257 }
2258 
2259 int
rl_generic_bind(int type,const char * keyseq,const char * data,Keymap k)2260 rl_generic_bind(int type, const char * keyseq, const char * data, Keymap k)
2261 {
2262 	return 0;
2263 }
2264 
2265 int
rl_bind_key_in_map(int key,rl_command_func_t * fun,Keymap k)2266 rl_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 */
2272 void
rl_cleanup_after_signal(void)2273 rl_cleanup_after_signal(void)
2274 {
2275 }
2276 
2277 int
rl_on_new_line(void)2278 rl_on_new_line(void)
2279 {
2280 	return 0;
2281 }
2282 
2283 int
rl_set_keyboard_input_timeout(int u)2284 rl_set_keyboard_input_timeout(int u __attribute__((__unused__)))
2285 {
2286 	return 0;
2287 }
2288