xref: /dragonfly/contrib/libedit/src/el.c (revision cdf8408c)
1*cdf8408cSAntonio Huete Jimenez /*	$NetBSD: el.c,v 1.100 2021/08/15 10:08:41 christos Exp $	*/
232fe07f8SJohn Marino 
332fe07f8SJohn Marino /*-
432fe07f8SJohn Marino  * Copyright (c) 1992, 1993
532fe07f8SJohn Marino  *	The Regents of the University of California.  All rights reserved.
632fe07f8SJohn Marino  *
732fe07f8SJohn Marino  * This code is derived from software contributed to Berkeley by
832fe07f8SJohn Marino  * Christos Zoulas of Cornell University.
932fe07f8SJohn Marino  *
1032fe07f8SJohn Marino  * Redistribution and use in source and binary forms, with or without
1132fe07f8SJohn Marino  * modification, are permitted provided that the following conditions
1232fe07f8SJohn Marino  * are met:
1332fe07f8SJohn Marino  * 1. Redistributions of source code must retain the above copyright
1432fe07f8SJohn Marino  *    notice, this list of conditions and the following disclaimer.
1532fe07f8SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
1632fe07f8SJohn Marino  *    notice, this list of conditions and the following disclaimer in the
1732fe07f8SJohn Marino  *    documentation and/or other materials provided with the distribution.
1832fe07f8SJohn Marino  * 3. Neither the name of the University nor the names of its contributors
1932fe07f8SJohn Marino  *    may be used to endorse or promote products derived from this software
2032fe07f8SJohn Marino  *    without specific prior written permission.
2132fe07f8SJohn Marino  *
2232fe07f8SJohn Marino  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2332fe07f8SJohn Marino  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2432fe07f8SJohn Marino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2532fe07f8SJohn Marino  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2632fe07f8SJohn Marino  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2732fe07f8SJohn Marino  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2832fe07f8SJohn Marino  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2932fe07f8SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3032fe07f8SJohn Marino  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3132fe07f8SJohn Marino  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3232fe07f8SJohn Marino  * SUCH DAMAGE.
3332fe07f8SJohn Marino  */
3432fe07f8SJohn Marino 
3532fe07f8SJohn Marino #include "config.h"
3632fe07f8SJohn Marino #if !defined(lint) && !defined(SCCSID)
3732fe07f8SJohn Marino #if 0
3832fe07f8SJohn Marino static char sccsid[] = "@(#)el.c	8.2 (Berkeley) 1/3/94";
3932fe07f8SJohn Marino #else
40*cdf8408cSAntonio Huete Jimenez __RCSID("$NetBSD: el.c,v 1.100 2021/08/15 10:08:41 christos Exp $");
4132fe07f8SJohn Marino #endif
4232fe07f8SJohn Marino #endif /* not lint && not SCCSID */
4332fe07f8SJohn Marino 
4432fe07f8SJohn Marino /*
4532fe07f8SJohn Marino  * el.c: EditLine interface functions
4632fe07f8SJohn Marino  */
4732fe07f8SJohn Marino #include <sys/types.h>
4832fe07f8SJohn Marino #include <sys/param.h>
4932fe07f8SJohn Marino #include <ctype.h>
5032fe07f8SJohn Marino #include <langinfo.h>
5132fe07f8SJohn Marino #include <locale.h>
5232fe07f8SJohn Marino #include <stdarg.h>
5332fe07f8SJohn Marino #include <stdlib.h>
5432fe07f8SJohn Marino #include <string.h>
5512db70c8Szrj 
5612db70c8Szrj #include "el.h"
5712db70c8Szrj #include "parse.h"
5812db70c8Szrj #include "read.h"
5912db70c8Szrj 
6032fe07f8SJohn Marino #ifndef HAVE_SECURE_GETENV
6112db70c8Szrj #	ifdef HAVE___SECURE_GETENV
6212db70c8Szrj #		define secure_getenv __secure_getenv
6332fe07f8SJohn Marino #		define HAVE_SECURE_GETENV 1
6484b940c1SJohn Marino #	else
6584b940c1SJohn Marino #		ifdef HAVE_ISSETUGID
6684b940c1SJohn Marino #			include <unistd.h>
6784b940c1SJohn Marino #		else
6884b940c1SJohn Marino #			undef issetugid
6984b940c1SJohn Marino #			define issetugid() 1
7084b940c1SJohn Marino #		endif
7184b940c1SJohn Marino #	endif
7284b940c1SJohn Marino #endif
7384b940c1SJohn Marino 
7484b940c1SJohn Marino #ifndef HAVE_SECURE_GETENV
secure_getenv(char const * name)7584b940c1SJohn Marino char *secure_getenv(char const *name)
7684b940c1SJohn Marino {
7784b940c1SJohn Marino 	if (issetugid())
7884b940c1SJohn Marino 		return 0;
7984b940c1SJohn Marino 	return getenv(name);
8084b940c1SJohn Marino }
8184b940c1SJohn Marino #endif
8284b940c1SJohn Marino 
8384b940c1SJohn Marino /* el_init():
8484b940c1SJohn Marino  *	Initialize editline and set default parameters.
8584b940c1SJohn Marino  */
8684b940c1SJohn Marino EditLine *
el_init(const char * prog,FILE * fin,FILE * fout,FILE * ferr)8732fe07f8SJohn Marino el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
8832fe07f8SJohn Marino {
8932fe07f8SJohn Marino     return el_init_fd(prog, fin, fout, ferr, fileno(fin), fileno(fout),
9012db70c8Szrj 	fileno(ferr));
9132fe07f8SJohn Marino }
9232fe07f8SJohn Marino 
9384b940c1SJohn Marino libedit_private EditLine *
el_init_internal(const char * prog,FILE * fin,FILE * fout,FILE * ferr,int fdin,int fdout,int fderr,int flags)9484b940c1SJohn Marino el_init_internal(const char *prog, FILE *fin, FILE *fout, FILE *ferr,
9584b940c1SJohn Marino     int fdin, int fdout, int fderr, int flags)
9684b940c1SJohn Marino {
97ae19eda8Szrj 	EditLine *el = el_calloc(1, sizeof(*el));
98ae19eda8Szrj 
99ae19eda8Szrj 	if (el == NULL)
10084b940c1SJohn Marino 		return NULL;
10160ecde0cSDaniel Fojt 
10232fe07f8SJohn Marino 	el->el_infile = fin;
10332fe07f8SJohn Marino 	el->el_outfile = fout;
10432fe07f8SJohn Marino 	el->el_errfile = ferr;
10532fe07f8SJohn Marino 
10632fe07f8SJohn Marino 	el->el_infd = fdin;
10732fe07f8SJohn Marino 	el->el_outfd = fdout;
10832fe07f8SJohn Marino 	el->el_errfd = fderr;
10932fe07f8SJohn Marino 
11084b940c1SJohn Marino 	el->el_prog = wcsdup(ct_decode_string(prog, &el->el_scratch));
11184b940c1SJohn Marino 	if (el->el_prog == NULL) {
11284b940c1SJohn Marino 		el_free(el);
11332fe07f8SJohn Marino 		return NULL;
11412db70c8Szrj 	}
11532fe07f8SJohn Marino 
11632fe07f8SJohn Marino 	/*
11732fe07f8SJohn Marino          * Initialize all the modules. Order is important!!!
11832fe07f8SJohn Marino          */
11932fe07f8SJohn Marino 	el->el_flags = flags;
12032fe07f8SJohn Marino 
12132fe07f8SJohn Marino 	if (terminal_init(el) == -1) {
12232fe07f8SJohn Marino 		el_free(el->el_prog);
123ae19eda8Szrj 		el_free(el);
12432fe07f8SJohn Marino 		return NULL;
12532fe07f8SJohn Marino 	}
12632fe07f8SJohn Marino 	(void) keymacro_init(el);
12732fe07f8SJohn Marino 	(void) map_init(el);
12832fe07f8SJohn Marino 	if (tty_init(el) == -1)
12932fe07f8SJohn Marino 		el->el_flags |= NO_TTY;
13032fe07f8SJohn Marino 	(void) ch_init(el);
13132fe07f8SJohn Marino 	(void) search_init(el);
13232fe07f8SJohn Marino 	(void) hist_init(el);
13332fe07f8SJohn Marino 	(void) prompt_init(el);
13432fe07f8SJohn Marino 	(void) sig_init(el);
13532fe07f8SJohn Marino 	(void) literal_init(el);
13632fe07f8SJohn Marino 	if (read_init(el) == -1) {
13732fe07f8SJohn Marino 		el_end(el);
13832fe07f8SJohn Marino 		return NULL;
139ae19eda8Szrj 	}
14012db70c8Szrj 	return el;
14112db70c8Szrj }
14212db70c8Szrj 
14312db70c8Szrj EditLine *
el_init_fd(const char * prog,FILE * fin,FILE * fout,FILE * ferr,int fdin,int fdout,int fderr)14432fe07f8SJohn Marino el_init_fd(const char *prog, FILE *fin, FILE *fout, FILE *ferr,
14532fe07f8SJohn Marino     int fdin, int fdout, int fderr)
14632fe07f8SJohn Marino {
147ae19eda8Szrj 	return el_init_internal(prog, fin, fout, ferr, fdin, fdout, fderr, 0);
148ae19eda8Szrj }
149ae19eda8Szrj 
150ae19eda8Szrj /* el_end():
151ae19eda8Szrj  *	Clean up.
152ae19eda8Szrj  */
15332fe07f8SJohn Marino void
el_end(EditLine * el)15432fe07f8SJohn Marino el_end(EditLine *el)
15532fe07f8SJohn Marino {
15632fe07f8SJohn Marino 
15712db70c8Szrj 	if (el == NULL)
15832fe07f8SJohn Marino 		return;
15932fe07f8SJohn Marino 
16032fe07f8SJohn Marino 	el_reset(el);
16132fe07f8SJohn Marino 
16232fe07f8SJohn Marino 	terminal_end(el);
16332fe07f8SJohn Marino 	keymacro_end(el);
16432fe07f8SJohn Marino 	map_end(el);
16532fe07f8SJohn Marino 	if (!(el->el_flags & NO_TTY))
16632fe07f8SJohn Marino 		tty_end(el, TCSAFLUSH);
16732fe07f8SJohn Marino 	ch_end(el);
16832fe07f8SJohn Marino 	read_end(el->el_read);
16912db70c8Szrj 	search_end(el);
170ae19eda8Szrj 	hist_end(el);
17132fe07f8SJohn Marino 	prompt_end(el);
17212db70c8Szrj 	sig_end(el);
17332fe07f8SJohn Marino 	literal_end(el);
17432fe07f8SJohn Marino 
17532fe07f8SJohn Marino 	el_free(el->el_prog);
17632fe07f8SJohn Marino 	el_free(el->el_visual.cbuff);
177ae19eda8Szrj 	el_free(el->el_visual.wbuff);
17832fe07f8SJohn Marino 	el_free(el->el_scratch.cbuff);
17932fe07f8SJohn Marino 	el_free(el->el_scratch.wbuff);
18012db70c8Szrj 	el_free(el->el_lgcyconv.cbuff);
18112db70c8Szrj 	el_free(el->el_lgcyconv.wbuff);
18232fe07f8SJohn Marino 	el_free(el);
18332fe07f8SJohn Marino }
18432fe07f8SJohn Marino 
18532fe07f8SJohn Marino 
18632fe07f8SJohn Marino /* el_reset():
18732fe07f8SJohn Marino  *	Reset the tty and the parser
18832fe07f8SJohn Marino  */
18932fe07f8SJohn Marino void
el_reset(EditLine * el)19032fe07f8SJohn Marino el_reset(EditLine *el)
19132fe07f8SJohn Marino {
19232fe07f8SJohn Marino 
19312db70c8Szrj 	tty_cookedmode(el);
19432fe07f8SJohn Marino 	ch_reset(el);		/* XXX: Do we want that? */
19532fe07f8SJohn Marino }
19632fe07f8SJohn Marino 
19732fe07f8SJohn Marino 
19812db70c8Szrj /* el_set():
19932fe07f8SJohn Marino  *	set the editline parameters
20032fe07f8SJohn Marino  */
20132fe07f8SJohn Marino int
el_wset(EditLine * el,int op,...)20232fe07f8SJohn Marino el_wset(EditLine *el, int op, ...)
20332fe07f8SJohn Marino {
20432fe07f8SJohn Marino 	va_list ap;
20512db70c8Szrj 	int rv = 0;
20612db70c8Szrj 
20732fe07f8SJohn Marino 	if (el == NULL)
20832fe07f8SJohn Marino 		return -1;
20932fe07f8SJohn Marino 	va_start(ap, op);
21032fe07f8SJohn Marino 
21132fe07f8SJohn Marino 	switch (op) {
21232fe07f8SJohn Marino 	case EL_PROMPT:
21332fe07f8SJohn Marino 	case EL_RPROMPT: {
21432fe07f8SJohn Marino 		el_pfunc_t p = va_arg(ap, el_pfunc_t);
21532fe07f8SJohn Marino 
21632fe07f8SJohn Marino 		rv = prompt_set(el, p, 0, op, 1);
21732fe07f8SJohn Marino 		break;
21832fe07f8SJohn Marino 	}
21932fe07f8SJohn Marino 
22032fe07f8SJohn Marino 	case EL_RESIZE: {
22132fe07f8SJohn Marino 		el_zfunc_t p = va_arg(ap, el_zfunc_t);
22232fe07f8SJohn Marino 		void *arg = va_arg(ap, void *);
22332fe07f8SJohn Marino 		rv = ch_resizefun(el, p, arg);
22432fe07f8SJohn Marino 		break;
22532fe07f8SJohn Marino 	}
22632fe07f8SJohn Marino 
22732fe07f8SJohn Marino 	case EL_ALIAS_TEXT: {
22832fe07f8SJohn Marino 		el_afunc_t p = va_arg(ap, el_afunc_t);
22932fe07f8SJohn Marino 		void *arg = va_arg(ap, void *);
23032fe07f8SJohn Marino 		rv = ch_aliasfun(el, p, arg);
23184b940c1SJohn Marino 		break;
23284b940c1SJohn Marino 	}
23384b940c1SJohn Marino 
23484b940c1SJohn Marino 	case EL_PROMPT_ESC:
23584b940c1SJohn Marino 	case EL_RPROMPT_ESC: {
23684b940c1SJohn Marino 		el_pfunc_t p = va_arg(ap, el_pfunc_t);
23784b940c1SJohn Marino 		int c = va_arg(ap, int);
23832fe07f8SJohn Marino 
23932fe07f8SJohn Marino 		rv = prompt_set(el, p, (wchar_t)c, op, 1);
24032fe07f8SJohn Marino 		break;
24132fe07f8SJohn Marino 	}
24232fe07f8SJohn Marino 
24312db70c8Szrj 	case EL_TERMINAL:
24432fe07f8SJohn Marino 		rv = terminal_set(el, va_arg(ap, char *));
24532fe07f8SJohn Marino 		break;
24632fe07f8SJohn Marino 
24732fe07f8SJohn Marino 	case EL_EDITOR:
24832fe07f8SJohn Marino 		rv = map_set_editor(el, va_arg(ap, wchar_t *));
24932fe07f8SJohn Marino 		break;
25032fe07f8SJohn Marino 
25132fe07f8SJohn Marino 	case EL_SIGNAL:
25212db70c8Szrj 		if (va_arg(ap, int))
25332fe07f8SJohn Marino 			el->el_flags |= HANDLE_SIGNALS;
25432fe07f8SJohn Marino 		else
25532fe07f8SJohn Marino 			el->el_flags &= ~HANDLE_SIGNALS;
25632fe07f8SJohn Marino 		break;
25732fe07f8SJohn Marino 
25832fe07f8SJohn Marino 	case EL_BIND:
25932fe07f8SJohn Marino 	case EL_TELLTC:
26032fe07f8SJohn Marino 	case EL_SETTC:
26132fe07f8SJohn Marino 	case EL_ECHOTC:
26232fe07f8SJohn Marino 	case EL_SETTY:
26332fe07f8SJohn Marino 	{
26432fe07f8SJohn Marino 		const wchar_t *argv[20];
26532fe07f8SJohn Marino 		int i;
26632fe07f8SJohn Marino 
26732fe07f8SJohn Marino 		for (i = 1; i < (int)__arraycount(argv); i++)
26812db70c8Szrj 			if ((argv[i] = va_arg(ap, wchar_t *)) == NULL)
26932fe07f8SJohn Marino 				break;
27032fe07f8SJohn Marino 
27132fe07f8SJohn Marino 		switch (op) {
27212db70c8Szrj 		case EL_BIND:
27332fe07f8SJohn Marino 			argv[0] = L"bind";
27432fe07f8SJohn Marino 			rv = map_bind(el, i, argv);
27532fe07f8SJohn Marino 			break;
27632fe07f8SJohn Marino 
27712db70c8Szrj 		case EL_TELLTC:
27832fe07f8SJohn Marino 			argv[0] = L"telltc";
27932fe07f8SJohn Marino 			rv = terminal_telltc(el, i, argv);
28032fe07f8SJohn Marino 			break;
28132fe07f8SJohn Marino 
28212db70c8Szrj 		case EL_SETTC:
28332fe07f8SJohn Marino 			argv[0] = L"settc";
28432fe07f8SJohn Marino 			rv = terminal_settc(el, i, argv);
28532fe07f8SJohn Marino 			break;
28632fe07f8SJohn Marino 
28712db70c8Szrj 		case EL_ECHOTC:
28832fe07f8SJohn Marino 			argv[0] = L"echotc";
28932fe07f8SJohn Marino 			rv = terminal_echotc(el, i, argv);
29032fe07f8SJohn Marino 			break;
29132fe07f8SJohn Marino 
29212db70c8Szrj 		case EL_SETTY:
29332fe07f8SJohn Marino 			argv[0] = L"setty";
29432fe07f8SJohn Marino 			rv = tty_stty(el, i, argv);
29532fe07f8SJohn Marino 			break;
29632fe07f8SJohn Marino 
29712db70c8Szrj 		default:
29832fe07f8SJohn Marino 			rv = -1;
29932fe07f8SJohn Marino 			EL_ABORT((el->el_errfile, "Bad op %d\n", op));
30032fe07f8SJohn Marino 			break;
30132fe07f8SJohn Marino 		}
30232fe07f8SJohn Marino 		break;
30332fe07f8SJohn Marino 	}
30432fe07f8SJohn Marino 
30532fe07f8SJohn Marino 	case EL_ADDFN:
30632fe07f8SJohn Marino 	{
30732fe07f8SJohn Marino 		wchar_t *name = va_arg(ap, wchar_t *);
30832fe07f8SJohn Marino 		wchar_t *help = va_arg(ap, wchar_t *);
30932fe07f8SJohn Marino 		el_func_t func = va_arg(ap, el_func_t);
31032fe07f8SJohn Marino 
31112db70c8Szrj 		rv = map_addfunc(el, name, help, func);
31212db70c8Szrj 		break;
31332fe07f8SJohn Marino 	}
31432fe07f8SJohn Marino 
31532fe07f8SJohn Marino 	case EL_HIST:
31632fe07f8SJohn Marino 	{
31732fe07f8SJohn Marino 		hist_fun_t func = va_arg(ap, hist_fun_t);
31832fe07f8SJohn Marino 		void *ptr = va_arg(ap, void *);
31932fe07f8SJohn Marino 
32032fe07f8SJohn Marino 		rv = hist_set(el, func, ptr);
32132fe07f8SJohn Marino 		if (MB_CUR_MAX == 1)
32232fe07f8SJohn Marino 			el->el_flags &= ~NARROW_HISTORY;
32332fe07f8SJohn Marino 		break;
32432fe07f8SJohn Marino 	}
325ae19eda8Szrj 
32632fe07f8SJohn Marino 	case EL_SAFEREAD:
32732fe07f8SJohn Marino 		if (va_arg(ap, int))
32832fe07f8SJohn Marino 			el->el_flags |= FIXIO;
32932fe07f8SJohn Marino 		else
330*cdf8408cSAntonio Huete Jimenez 			el->el_flags &= ~FIXIO;
331*cdf8408cSAntonio Huete Jimenez 		rv = 0;
332*cdf8408cSAntonio Huete Jimenez 		break;
333*cdf8408cSAntonio Huete Jimenez 
334*cdf8408cSAntonio Huete Jimenez 	case EL_EDITMODE:
335*cdf8408cSAntonio Huete Jimenez 		if (va_arg(ap, int))
336*cdf8408cSAntonio Huete Jimenez 			el->el_flags &= ~EDIT_DISABLED;
337*cdf8408cSAntonio Huete Jimenez 		else
33832fe07f8SJohn Marino 			el->el_flags |= EDIT_DISABLED;
33932fe07f8SJohn Marino 		rv = 0;
34032fe07f8SJohn Marino 		break;
34132fe07f8SJohn Marino 
34232fe07f8SJohn Marino 	case EL_GETCFN:
34332fe07f8SJohn Marino 	{
34432fe07f8SJohn Marino 		el_rfunc_t rc = va_arg(ap, el_rfunc_t);
34532fe07f8SJohn Marino 		rv = el_read_setfn(el->el_read, rc);
34632fe07f8SJohn Marino 		break;
34732fe07f8SJohn Marino 	}
34832fe07f8SJohn Marino 
34912db70c8Szrj 	case EL_CLIENTDATA:
35032fe07f8SJohn Marino 		el->el_data = va_arg(ap, void *);
35132fe07f8SJohn Marino 		break;
35232fe07f8SJohn Marino 
35332fe07f8SJohn Marino 	case EL_UNBUFFERED:
35432fe07f8SJohn Marino 		rv = va_arg(ap, int);
35532fe07f8SJohn Marino 		if (rv && !(el->el_flags & UNBUFFERED)) {
35632fe07f8SJohn Marino 			el->el_flags |= UNBUFFERED;
35732fe07f8SJohn Marino 			read_prepare(el);
35832fe07f8SJohn Marino 		} else if (!rv && (el->el_flags & UNBUFFERED)) {
35932fe07f8SJohn Marino 			el->el_flags &= ~UNBUFFERED;
36032fe07f8SJohn Marino 			read_finish(el);
36132fe07f8SJohn Marino 		}
36232fe07f8SJohn Marino 		rv = 0;
36332fe07f8SJohn Marino 		break;
36432fe07f8SJohn Marino 
36532fe07f8SJohn Marino 	case EL_PREP_TERM:
36632fe07f8SJohn Marino 		rv = va_arg(ap, int);
36732fe07f8SJohn Marino 		if (rv)
36832fe07f8SJohn Marino 			(void) tty_rawmode(el);
36932fe07f8SJohn Marino 		else
37032fe07f8SJohn Marino 			(void) tty_cookedmode(el);
37132fe07f8SJohn Marino 		rv = 0;
37232fe07f8SJohn Marino 		break;
37332fe07f8SJohn Marino 
37432fe07f8SJohn Marino 	case EL_SETFP:
37532fe07f8SJohn Marino 	{
37632fe07f8SJohn Marino 		FILE *fp;
37732fe07f8SJohn Marino 		int what;
37832fe07f8SJohn Marino 
37932fe07f8SJohn Marino 		what = va_arg(ap, int);
38032fe07f8SJohn Marino 		fp = va_arg(ap, FILE *);
38132fe07f8SJohn Marino 
38232fe07f8SJohn Marino 		rv = 0;
38332fe07f8SJohn Marino 		switch (what) {
38432fe07f8SJohn Marino 		case 0:
38532fe07f8SJohn Marino 			el->el_infile = fp;
38632fe07f8SJohn Marino 			el->el_infd = fileno(fp);
38732fe07f8SJohn Marino 			break;
38832fe07f8SJohn Marino 		case 1:
38932fe07f8SJohn Marino 			el->el_outfile = fp;
39032fe07f8SJohn Marino 			el->el_outfd = fileno(fp);
39132fe07f8SJohn Marino 			break;
39232fe07f8SJohn Marino 		case 2:
39332fe07f8SJohn Marino 			el->el_errfile = fp;
39432fe07f8SJohn Marino 			el->el_errfd = fileno(fp);
39532fe07f8SJohn Marino 			break;
39632fe07f8SJohn Marino 		default:
39732fe07f8SJohn Marino 			rv = -1;
39832fe07f8SJohn Marino 			break;
39932fe07f8SJohn Marino 		}
40032fe07f8SJohn Marino 		break;
40132fe07f8SJohn Marino 	}
40232fe07f8SJohn Marino 
40332fe07f8SJohn Marino 	case EL_REFRESH:
40432fe07f8SJohn Marino 		re_clear_display(el);
40532fe07f8SJohn Marino 		re_refresh(el);
40632fe07f8SJohn Marino 		terminal__flush(el);
40732fe07f8SJohn Marino 		break;
40832fe07f8SJohn Marino 
40932fe07f8SJohn Marino 	default:
41032fe07f8SJohn Marino 		rv = -1;
41132fe07f8SJohn Marino 		break;
41232fe07f8SJohn Marino 	}
41332fe07f8SJohn Marino 
41432fe07f8SJohn Marino 	va_end(ap);
41532fe07f8SJohn Marino 	return rv;
41632fe07f8SJohn Marino }
41732fe07f8SJohn Marino 
41832fe07f8SJohn Marino 
41932fe07f8SJohn Marino /* el_get():
42032fe07f8SJohn Marino  *	retrieve the editline parameters
42132fe07f8SJohn Marino  */
42232fe07f8SJohn Marino int
el_wget(EditLine * el,int op,...)42332fe07f8SJohn Marino el_wget(EditLine *el, int op, ...)
42432fe07f8SJohn Marino {
42532fe07f8SJohn Marino 	va_list ap;
42612db70c8Szrj 	int rv;
42712db70c8Szrj 
42832fe07f8SJohn Marino 	if (el == NULL)
42932fe07f8SJohn Marino 		return -1;
43032fe07f8SJohn Marino 
43132fe07f8SJohn Marino 	va_start(ap, op);
43232fe07f8SJohn Marino 
43332fe07f8SJohn Marino 	switch (op) {
43432fe07f8SJohn Marino 	case EL_PROMPT:
43532fe07f8SJohn Marino 	case EL_RPROMPT: {
43632fe07f8SJohn Marino 		el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
43732fe07f8SJohn Marino 		rv = prompt_get(el, p, 0, op);
43832fe07f8SJohn Marino 		break;
43932fe07f8SJohn Marino 	}
44032fe07f8SJohn Marino 	case EL_PROMPT_ESC:
44132fe07f8SJohn Marino 	case EL_RPROMPT_ESC: {
44232fe07f8SJohn Marino 		el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
44332fe07f8SJohn Marino 		wchar_t *c = va_arg(ap, wchar_t *);
44432fe07f8SJohn Marino 
44532fe07f8SJohn Marino 		rv = prompt_get(el, p, c, op);
44632fe07f8SJohn Marino 		break;
44712db70c8Szrj 	}
44832fe07f8SJohn Marino 
44932fe07f8SJohn Marino 	case EL_EDITOR:
45032fe07f8SJohn Marino 		rv = map_get_editor(el, va_arg(ap, const wchar_t **));
45132fe07f8SJohn Marino 		break;
45232fe07f8SJohn Marino 
45332fe07f8SJohn Marino 	case EL_SIGNAL:
45412db70c8Szrj 		*va_arg(ap, int *) = (el->el_flags & HANDLE_SIGNALS);
45532fe07f8SJohn Marino 		rv = 0;
45632fe07f8SJohn Marino 		break;
45732fe07f8SJohn Marino 
45832fe07f8SJohn Marino 	case EL_EDITMODE:
45932fe07f8SJohn Marino 		*va_arg(ap, int *) = !(el->el_flags & EDIT_DISABLED);
46032fe07f8SJohn Marino 		rv = 0;
46132fe07f8SJohn Marino 		break;
46232fe07f8SJohn Marino 
46332fe07f8SJohn Marino 	case EL_SAFEREAD:
46432fe07f8SJohn Marino 		*va_arg(ap, int *) = (el->el_flags & FIXIO);
46532fe07f8SJohn Marino 		rv = 0;
46632fe07f8SJohn Marino 		break;
467*cdf8408cSAntonio Huete Jimenez 
468*cdf8408cSAntonio Huete Jimenez 	case EL_TERMINAL:
469*cdf8408cSAntonio Huete Jimenez 		terminal_get(el, va_arg(ap, const char **));
470*cdf8408cSAntonio Huete Jimenez 		rv = 0;
471*cdf8408cSAntonio Huete Jimenez 		break;
47232fe07f8SJohn Marino 
47332fe07f8SJohn Marino 	case EL_GETTC:
47432fe07f8SJohn Marino 	{
47532fe07f8SJohn Marino 		static char name[] = "gettc";
47632fe07f8SJohn Marino 		char *argv[3];
47732fe07f8SJohn Marino 		argv[0] = name;
47832fe07f8SJohn Marino 		argv[1] = va_arg(ap, char *);
47932fe07f8SJohn Marino 		argv[2] = va_arg(ap, void *);
48060ecde0cSDaniel Fojt 		rv = terminal_gettc(el, 3, argv);
48132fe07f8SJohn Marino 		break;
48260ecde0cSDaniel Fojt 	}
48360ecde0cSDaniel Fojt 
48460ecde0cSDaniel Fojt 	case EL_GETCFN:
48532fe07f8SJohn Marino 		*va_arg(ap, el_rfunc_t *) = el_read_getfn(el->el_read);
48632fe07f8SJohn Marino 		rv = 0;
48732fe07f8SJohn Marino 		break;
48832fe07f8SJohn Marino 
48912db70c8Szrj 	case EL_CLIENTDATA:
49032fe07f8SJohn Marino 		*va_arg(ap, void **) = el->el_data;
49132fe07f8SJohn Marino 		rv = 0;
49232fe07f8SJohn Marino 		break;
49332fe07f8SJohn Marino 
49432fe07f8SJohn Marino 	case EL_UNBUFFERED:
49532fe07f8SJohn Marino 		*va_arg(ap, int *) = (el->el_flags & UNBUFFERED) != 0;
49632fe07f8SJohn Marino 		rv = 0;
49732fe07f8SJohn Marino 		break;
49832fe07f8SJohn Marino 
499c8e4d2bfSJohn Marino 	case EL_GETFP:
50032fe07f8SJohn Marino 	{
50132fe07f8SJohn Marino 		int what;
50232fe07f8SJohn Marino 		FILE **fpp;
50332fe07f8SJohn Marino 
50432fe07f8SJohn Marino 		what = va_arg(ap, int);
50532fe07f8SJohn Marino 		fpp = va_arg(ap, FILE **);
50632fe07f8SJohn Marino 		rv = 0;
50732fe07f8SJohn Marino 		switch (what) {
50832fe07f8SJohn Marino 		case 0:
50932fe07f8SJohn Marino 			*fpp = el->el_infile;
51032fe07f8SJohn Marino 			break;
51132fe07f8SJohn Marino 		case 1:
51232fe07f8SJohn Marino 			*fpp = el->el_outfile;
51332fe07f8SJohn Marino 			break;
51432fe07f8SJohn Marino 		case 2:
51532fe07f8SJohn Marino 			*fpp = el->el_errfile;
51632fe07f8SJohn Marino 			break;
51732fe07f8SJohn Marino 		default:
51832fe07f8SJohn Marino 			rv = -1;
51932fe07f8SJohn Marino 			break;
52032fe07f8SJohn Marino 		}
52132fe07f8SJohn Marino 		break;
52232fe07f8SJohn Marino 	}
52332fe07f8SJohn Marino 	default:
52432fe07f8SJohn Marino 		rv = -1;
52532fe07f8SJohn Marino 		break;
52632fe07f8SJohn Marino 	}
52732fe07f8SJohn Marino 	va_end(ap);
52832fe07f8SJohn Marino 
52932fe07f8SJohn Marino 	return rv;
53032fe07f8SJohn Marino }
53132fe07f8SJohn Marino 
53232fe07f8SJohn Marino 
53332fe07f8SJohn Marino /* el_line():
53432fe07f8SJohn Marino  *	Return editing info
53532fe07f8SJohn Marino  */
53632fe07f8SJohn Marino const LineInfoW *
el_wline(EditLine * el)53732fe07f8SJohn Marino el_wline(EditLine *el)
53832fe07f8SJohn Marino {
53932fe07f8SJohn Marino 
54012db70c8Szrj 	return (const LineInfoW *)(void *)&el->el_line;
54112db70c8Szrj }
54232fe07f8SJohn Marino 
54332fe07f8SJohn Marino 
54412db70c8Szrj /* el_source():
54532fe07f8SJohn Marino  *	Source a file
54632fe07f8SJohn Marino  */
54732fe07f8SJohn Marino int
el_source(EditLine * el,const char * fname)54832fe07f8SJohn Marino el_source(EditLine *el, const char *fname)
54932fe07f8SJohn Marino {
55032fe07f8SJohn Marino 	FILE *fp;
55112db70c8Szrj 	size_t len;
55232fe07f8SJohn Marino 	ssize_t slen;
55332fe07f8SJohn Marino 	char *ptr;
55432fe07f8SJohn Marino 	char *path = NULL;
55532fe07f8SJohn Marino 	const wchar_t *dptr;
55612db70c8Szrj 	int error = 0;
55732fe07f8SJohn Marino 
55832fe07f8SJohn Marino 	fp = NULL;
55912db70c8Szrj 	if (fname == NULL) {
56032fe07f8SJohn Marino 
56132fe07f8SJohn Marino 		/* secure_getenv is guaranteed to be defined and do the right thing here */
56232fe07f8SJohn Marino 		/* because of the defines above which take into account issetugid, */
56332fe07f8SJohn Marino 		/* secure_getenv and __secure_getenv availability. */
564ae19eda8Szrj 		if ((fname = secure_getenv("EDITRC")) == NULL) {
565*cdf8408cSAntonio Huete Jimenez 			static const char elpath[] = "/.editrc";
566*cdf8408cSAntonio Huete Jimenez 			size_t plen = sizeof(elpath);
567*cdf8408cSAntonio Huete Jimenez 
568*cdf8408cSAntonio Huete Jimenez 			if ((ptr = secure_getenv("HOME")) == NULL)
56932fe07f8SJohn Marino 				return -1;
57032fe07f8SJohn Marino 			plen += strlen(ptr);
57132fe07f8SJohn Marino 			if ((path = el_calloc(plen, sizeof(*path))) == NULL)
572*cdf8408cSAntonio Huete Jimenez 				return -1;
57332fe07f8SJohn Marino 			(void)snprintf(path, plen, "%s%s", ptr,
57432fe07f8SJohn Marino 				elpath + (*ptr == '\0'));
57560ecde0cSDaniel Fojt 			fname = path;
57632fe07f8SJohn Marino 		}
577ae19eda8Szrj 
578ae19eda8Szrj 	}
57932fe07f8SJohn Marino 	if (fname[0] == '\0')
58032fe07f8SJohn Marino 		return -1;
581*cdf8408cSAntonio Huete Jimenez 
582ae19eda8Szrj 	if (fp == NULL)
583ae19eda8Szrj 		fp = fopen(fname, "r");
584ae19eda8Szrj 	if (fp == NULL) {
585ae19eda8Szrj 		el_free(path);
58632fe07f8SJohn Marino 		return -1;
58732fe07f8SJohn Marino 	}
58832fe07f8SJohn Marino 
58932fe07f8SJohn Marino 	ptr = NULL;
59032fe07f8SJohn Marino 	len = 0;
59132fe07f8SJohn Marino 	while ((slen = getline(&ptr, &len, fp)) != -1) {
59232fe07f8SJohn Marino 		if (*ptr == '\n')
59312db70c8Szrj 			continue;	/* Empty line. */
59412db70c8Szrj 		if (slen > 0 && ptr[--slen] == '\n')
59512db70c8Szrj 			ptr[slen] = '\0';
59632fe07f8SJohn Marino 
59732fe07f8SJohn Marino 		dptr = ct_decode_string(ptr, &el->el_scratch);
59812db70c8Szrj 		if (!dptr)
59912db70c8Szrj 			continue;
60012db70c8Szrj 		/* loop until first non-space char or EOL */
60132fe07f8SJohn Marino 		while (*dptr != '\0' && iswspace(*dptr))
60232fe07f8SJohn Marino 			dptr++;
60332fe07f8SJohn Marino 		if (*dptr == '#')
60432fe07f8SJohn Marino 			continue;   /* ignore, this is a comment line */
60512db70c8Szrj 		if ((error = parse_line(el, dptr)) == -1)
60632fe07f8SJohn Marino 			break;
60732fe07f8SJohn Marino 	}
60832fe07f8SJohn Marino 	free(ptr);
60932fe07f8SJohn Marino 
61032fe07f8SJohn Marino 	el_free(path);
61132fe07f8SJohn Marino 	(void) fclose(fp);
61212db70c8Szrj 	return error;
61332fe07f8SJohn Marino }
61432fe07f8SJohn Marino 
61532fe07f8SJohn Marino 
61632fe07f8SJohn Marino /* el_resize():
61732fe07f8SJohn Marino  *	Called from program when terminal is resized
61832fe07f8SJohn Marino  */
61932fe07f8SJohn Marino void
el_resize(EditLine * el)62032fe07f8SJohn Marino el_resize(EditLine *el)
62132fe07f8SJohn Marino {
62232fe07f8SJohn Marino 	int lins, cols;
62312db70c8Szrj 	sigset_t oset, nset;
62432fe07f8SJohn Marino 
62532fe07f8SJohn Marino 	(void) sigemptyset(&nset);
62632fe07f8SJohn Marino 	(void) sigaddset(&nset, SIGWINCH);
62732fe07f8SJohn Marino 	(void) sigprocmask(SIG_BLOCK, &nset, &oset);
62832fe07f8SJohn Marino 
62932fe07f8SJohn Marino 	/* get the correct window size */
63032fe07f8SJohn Marino 	if (terminal_get_size(el, &lins, &cols))
63132fe07f8SJohn Marino 		terminal_change_size(el, lins, cols);
63232fe07f8SJohn Marino 
63332fe07f8SJohn Marino 	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
63432fe07f8SJohn Marino }
63532fe07f8SJohn Marino 
63632fe07f8SJohn Marino 
63732fe07f8SJohn Marino /* el_beep():
63832fe07f8SJohn Marino  *	Called from the program to beep
63932fe07f8SJohn Marino  */
64032fe07f8SJohn Marino void
el_beep(EditLine * el)64132fe07f8SJohn Marino el_beep(EditLine *el)
64232fe07f8SJohn Marino {
64332fe07f8SJohn Marino 
64412db70c8Szrj 	terminal_beep(el);
64532fe07f8SJohn Marino }
64632fe07f8SJohn Marino 
64732fe07f8SJohn Marino 
64832fe07f8SJohn Marino /* el_editmode()
64932fe07f8SJohn Marino  *	Set the state of EDIT_DISABLED from the `edit' command.
65032fe07f8SJohn Marino  */
65132fe07f8SJohn Marino libedit_private int
65232fe07f8SJohn Marino /*ARGSUSED*/
el_editmode(EditLine * el,int argc,const wchar_t ** argv)65332fe07f8SJohn Marino el_editmode(EditLine *el, int argc, const wchar_t **argv)
65432fe07f8SJohn Marino {
65512db70c8Szrj 	const wchar_t *how;
65632fe07f8SJohn Marino 
65712db70c8Szrj 	if (argv == NULL || argc != 2 || argv[1] == NULL)
65832fe07f8SJohn Marino 		return -1;
65912db70c8Szrj 
66032fe07f8SJohn Marino 	how = argv[1];
66132fe07f8SJohn Marino 	if (wcscmp(how, L"on") == 0) {
66232fe07f8SJohn Marino 		el->el_flags &= ~EDIT_DISABLED;
66332fe07f8SJohn Marino 		tty_rawmode(el);
66432fe07f8SJohn Marino 	} else if (wcscmp(how, L"off") == 0) {
66512db70c8Szrj 		tty_cookedmode(el);
66632fe07f8SJohn Marino 		el->el_flags |= EDIT_DISABLED;
66732fe07f8SJohn Marino 	}
66812db70c8Szrj 	else {
66932fe07f8SJohn Marino 		(void) fprintf(el->el_errfile, "edit: Bad value `%ls'.\n",
67032fe07f8SJohn Marino 		    how);
67132fe07f8SJohn Marino 		return -1;
67232fe07f8SJohn Marino 	}
67312db70c8Szrj 	return 0;
67432fe07f8SJohn Marino }
67532fe07f8SJohn Marino