xref: /onnv-gate/usr/src/lib/libcurses/screen/setupterm.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate /*	Copyright (c) 1988 AT&T	*/
28*0Sstevel@tonic-gate /*	  All Rights Reserved	*/
29*0Sstevel@tonic-gate 
30*0Sstevel@tonic-gate /*
31*0Sstevel@tonic-gate  * University Copyright- Copyright (c) 1982, 1986, 1988
32*0Sstevel@tonic-gate  * The Regents of the University of California
33*0Sstevel@tonic-gate  * All Rights Reserved
34*0Sstevel@tonic-gate  *
35*0Sstevel@tonic-gate  * University Acknowledgment- Portions of this document are derived from
36*0Sstevel@tonic-gate  * software developed by the University of California, Berkeley, and its
37*0Sstevel@tonic-gate  * contributors.
38*0Sstevel@tonic-gate  */
39*0Sstevel@tonic-gate 
40*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
41*0Sstevel@tonic-gate 
42*0Sstevel@tonic-gate /*LINTLIBRARY*/
43*0Sstevel@tonic-gate 
44*0Sstevel@tonic-gate #include	<stdio.h>
45*0Sstevel@tonic-gate #include	<sys/types.h>
46*0Sstevel@tonic-gate #include	<fcntl.h>
47*0Sstevel@tonic-gate #include	<stdlib.h>
48*0Sstevel@tonic-gate #include	<string.h>
49*0Sstevel@tonic-gate #include	<unistd.h>
50*0Sstevel@tonic-gate #include	<errno.h>
51*0Sstevel@tonic-gate #include	"curses_inc.h"
52*0Sstevel@tonic-gate 
53*0Sstevel@tonic-gate #define	TERMPATH	"/usr/share/lib/terminfo/"
54*0Sstevel@tonic-gate #define	TERMPATHLEN	512
55*0Sstevel@tonic-gate 
56*0Sstevel@tonic-gate extern	bool	_use_env;	/* in curses.c */
57*0Sstevel@tonic-gate 
58*0Sstevel@tonic-gate chtype	bit_attributes[NUM_ATTRIBUTES] = {
59*0Sstevel@tonic-gate 	    A_STANDOUT,
60*0Sstevel@tonic-gate 	    A_UNDERLINE,
61*0Sstevel@tonic-gate 	    A_ALTCHARSET,
62*0Sstevel@tonic-gate 	    A_REVERSE,
63*0Sstevel@tonic-gate 	    A_BLINK,
64*0Sstevel@tonic-gate 	    A_DIM,
65*0Sstevel@tonic-gate 	    A_BOLD,
66*0Sstevel@tonic-gate 	    A_INVIS,
67*0Sstevel@tonic-gate 	    A_PROTECT
68*0Sstevel@tonic-gate 	};
69*0Sstevel@tonic-gate 
70*0Sstevel@tonic-gate char	*Def_term = "unknown",	/* default terminal type */
71*0Sstevel@tonic-gate 	term_parm_err[32], ttytype[BUFSIZ], _frst_tblstr[1400];
72*0Sstevel@tonic-gate 
73*0Sstevel@tonic-gate TERMINAL		_first_term, *cur_term = &_first_term;
74*0Sstevel@tonic-gate struct	_bool_struct	_frst_bools, *cur_bools = &_frst_bools;
75*0Sstevel@tonic-gate struct	_num_struct	_frst_nums, *cur_nums = &_frst_nums;
76*0Sstevel@tonic-gate struct	_str_struct	_frst_strs, *cur_strs = &_frst_strs;
77*0Sstevel@tonic-gate 
78*0Sstevel@tonic-gate /* _called_before is used/cleared by delterm.c and restart.c */
79*0Sstevel@tonic-gate char	_called_before = 0;
80*0Sstevel@tonic-gate short	term_errno = -1;
81*0Sstevel@tonic-gate 
82*0Sstevel@tonic-gate #ifdef SYSV
83*0Sstevel@tonic-gate int	prog_istermios = -1;
84*0Sstevel@tonic-gate int	shell_istermios = -1;
85*0Sstevel@tonic-gate #endif
86*0Sstevel@tonic-gate 
87*0Sstevel@tonic-gate #ifdef	DUMPTI
88*0Sstevel@tonic-gate extern	char	*boolfnames[], *boolnames[], *boolcodes[],
89*0Sstevel@tonic-gate 		*numfnames[], *numnames[], *numcodes[],
90*0Sstevel@tonic-gate 		*strfnames[], *strnames[], *strcodes[];
91*0Sstevel@tonic-gate 
main(int argc,char ** argv)92*0Sstevel@tonic-gate main(int argc, char **argv)	/* FOR DEBUG ONLY */
93*0Sstevel@tonic-gate {
94*0Sstevel@tonic-gate 	if (argc > 1)
95*0Sstevel@tonic-gate 		setupterm(argv[1], 1, (int *)0);
96*0Sstevel@tonic-gate 	else
97*0Sstevel@tonic-gate 		setupterm((char *)0, 1, (int *)0);
98*0Sstevel@tonic-gate 	return (0);
99*0Sstevel@tonic-gate }
100*0Sstevel@tonic-gate 
_Pr(int ch)101*0Sstevel@tonic-gate _Pr(int ch)	/* FOR DEBUG ONLY */
102*0Sstevel@tonic-gate {
103*0Sstevel@tonic-gate 	if (ch >= 0200) {
104*0Sstevel@tonic-gate 		printf("M-");
105*0Sstevel@tonic-gate 		ch -= 0200;
106*0Sstevel@tonic-gate 	}
107*0Sstevel@tonic-gate 	if ((ch < ' ') || (ch == 0177))
108*0Sstevel@tonic-gate 		printf("^%c", ch ^ 0100);
109*0Sstevel@tonic-gate 	else
110*0Sstevel@tonic-gate 		printf("%c", ch);
111*0Sstevel@tonic-gate }
112*0Sstevel@tonic-gate 
_Sprint(int n,char * string)113*0Sstevel@tonic-gate _Sprint(int n, char *string)	/* FOR DEBUG ONLY */
114*0Sstevel@tonic-gate {
115*0Sstevel@tonic-gate 	int	ch;
116*0Sstevel@tonic-gate 
117*0Sstevel@tonic-gate 	if (n == -1) {
118*0Sstevel@tonic-gate 		printf(".\n");
119*0Sstevel@tonic-gate 		return;
120*0Sstevel@tonic-gate 	}
121*0Sstevel@tonic-gate 	printf(", string = '");
122*0Sstevel@tonic-gate 	while (ch = *string++)
123*0Sstevel@tonic-gate 		_Pr(ch&0377);
124*0Sstevel@tonic-gate 
125*0Sstevel@tonic-gate 	printf("'.\n");
126*0Sstevel@tonic-gate }
127*0Sstevel@tonic-gate 
_Mprint(int n,char * memory)128*0Sstevel@tonic-gate _Mprint(int n, char *memory)	/* FOR DEBUG ONLY */
129*0Sstevel@tonic-gate {
130*0Sstevel@tonic-gate 	unsigned	char	ch;
131*0Sstevel@tonic-gate 
132*0Sstevel@tonic-gate 	while (ch = *memory++, n-- > 0)
133*0Sstevel@tonic-gate 		_Pr(ch&0377);
134*0Sstevel@tonic-gate }
135*0Sstevel@tonic-gate 
136*0Sstevel@tonic-gate #define	_Vr2getshi()	_Vr2getsh(ip-2)
137*0Sstevel@tonic-gate 
138*0Sstevel@tonic-gate #if	vax || pdp11
139*0Sstevel@tonic-gate #define	_Vr2getsh(ip)	(* (short *)(ip))
140*0Sstevel@tonic-gate #endif	/* vax || pdp11 */
141*0Sstevel@tonic-gate 
142*0Sstevel@tonic-gate #ifndef	_Vr2getsh
143*0Sstevel@tonic-gate /*
144*0Sstevel@tonic-gate  * Here is a more portable version, which does not assume byte ordering
145*0Sstevel@tonic-gate  * in shorts, sign extension, etc.
146*0Sstevel@tonic-gate  */
_Vr2getsh(char * p)147*0Sstevel@tonic-gate _Vr2getsh(char *p)
148*0Sstevel@tonic-gate {
149*0Sstevel@tonic-gate 	int	rv;
150*0Sstevel@tonic-gate 
151*0Sstevel@tonic-gate 	if (*p == (char)0377)
152*0Sstevel@tonic-gate 		return (-1);
153*0Sstevel@tonic-gate 	rv = (unsigned char) *p++;
154*0Sstevel@tonic-gate 	rv += (unsigned char) *p * 256;
155*0Sstevel@tonic-gate 	return (rv);
156*0Sstevel@tonic-gate }
157*0Sstevel@tonic-gate #endif	/* _Vr2getsh */
158*0Sstevel@tonic-gate 
159*0Sstevel@tonic-gate #endif	/* DUMPTI */
160*0Sstevel@tonic-gate 
161*0Sstevel@tonic-gate #define	_Getshi()	_Getsh(ip); ip += 2
162*0Sstevel@tonic-gate 
163*0Sstevel@tonic-gate /*
164*0Sstevel@tonic-gate  * "function" to get a short from a pointer.  The short is in a standard
165*0Sstevel@tonic-gate  * format: two bytes, the first is the low order byte, the second is
166*0Sstevel@tonic-gate  * the high order byte (base 256).  The only negative numbers allowed are
167*0Sstevel@tonic-gate  * -1 and -2, which are represented as 255,255 and 255,254  This format
168*0Sstevel@tonic-gate  * happens to be the same as the hardware on the pdp-11, vax, and 386,
169*0Sstevel@tonic-gate  * making it fast and convenient and small to do this on a pdp-11.
170*0Sstevel@tonic-gate  */
171*0Sstevel@tonic-gate 
172*0Sstevel@tonic-gate #if	vax || pdp11 || i386
173*0Sstevel@tonic-gate #define	_Getsh(ip)	(* (short *)ip)
174*0Sstevel@tonic-gate #endif	/* vax || pdp11 */
175*0Sstevel@tonic-gate /*
176*0Sstevel@tonic-gate  * The following macro is partly due to Mike Laman, laman@sdcsvax
177*0Sstevel@tonic-gate  *	NCR @ Torrey Pines.		- Tony Hansen
178*0Sstevel@tonic-gate  */
179*0Sstevel@tonic-gate #if	u3b || u3b15 || u3b2 || m68000
180*0Sstevel@tonic-gate #define	_Getsh(ip)	((short)(*((unsigned char *)ip) | (*(ip+1) << 8)))
181*0Sstevel@tonic-gate #endif	/* u3b || u3b15 || u3b2 || m68000 */
182*0Sstevel@tonic-gate 
183*0Sstevel@tonic-gate #ifndef	_Getsh
184*0Sstevel@tonic-gate /*
185*0Sstevel@tonic-gate  * Here is a more portable version, which does not assume byte ordering
186*0Sstevel@tonic-gate  * in shorts, sign extension, etc.  For the sake of the porters,
187*0Sstevel@tonic-gate  * two alternative implementations, for the machines that don't have
188*0Sstevel@tonic-gate  * casting to "unsigned char", are also given, but commented out.
189*0Sstevel@tonic-gate  * Not ANSI C implementation assumes that the * C preprocessor does
190*0Sstevel@tonic-gate  * sign-extension the same as on the machine being compiled for.
191*0Sstevel@tonic-gate  */
192*0Sstevel@tonic-gate static int
_Getsh(char * p)193*0Sstevel@tonic-gate _Getsh(char *p)
194*0Sstevel@tonic-gate {
195*0Sstevel@tonic-gate 	int	rv, rv2;
196*0Sstevel@tonic-gate 
197*0Sstevel@tonic-gate 	rv  = (unsigned char) p[0];
198*0Sstevel@tonic-gate 	rv2 = (unsigned char) p[1];
199*0Sstevel@tonic-gate 
200*0Sstevel@tonic-gate 	/* the following stuff is only for porting.  See the comment above */
201*0Sstevel@tonic-gate 
202*0Sstevel@tonic-gate #ifdef FOR_PORTING
203*0Sstevel@tonic-gate #if    CHAR_MIN < 0
204*0Sstevel@tonic-gate 	rv = (*p++) & 0377;
205*0Sstevel@tonic-gate 	rv2 = (*p) & 0377;
206*0Sstevel@tonic-gate #else   /* CHAR_MIN < 0 */
207*0Sstevel@tonic-gate 	rv = *p++;
208*0Sstevel@tonic-gate 	rv2 = *p;
209*0Sstevel@tonic-gate #endif  /* CHAR_MIN < 0 */
210*0Sstevel@tonic-gate 
211*0Sstevel@tonic-gate #endif  /* FOR_PORTING  */
212*0Sstevel@tonic-gate 
213*0Sstevel@tonic-gate 	if ((rv2 == 0377) && ((rv == 0377) || (rv == 0376)))
214*0Sstevel@tonic-gate 		return (-1);
215*0Sstevel@tonic-gate 	return (rv + (rv2 * 256));
216*0Sstevel@tonic-gate }
217*0Sstevel@tonic-gate #endif	/* _Getsh */
218*0Sstevel@tonic-gate 
219*0Sstevel@tonic-gate /*
220*0Sstevel@tonic-gate  * setupterm: low level routine to dig up terminfo from database
221*0Sstevel@tonic-gate  * and read it in.  Parms are terminal type (0 means use getenv("TERM"),
222*0Sstevel@tonic-gate  * file descriptor all output will go to (for ioctls), and a pointer
223*0Sstevel@tonic-gate  * to an int into which the error return code goes (0 means to bomb
224*0Sstevel@tonic-gate  * out with an error message if there's an error).  Thus,
225*0Sstevel@tonic-gate  * setupterm((char *)0, 1, (int *)0) is a reasonable way for a simple
226*0Sstevel@tonic-gate  * program to set up.
227*0Sstevel@tonic-gate  */
228*0Sstevel@tonic-gate int
setupterm(char * term,int filenum,int * errret)229*0Sstevel@tonic-gate setupterm(char *term, int filenum, int *errret)
230*0Sstevel@tonic-gate 	/* filenum - This is a UNIX file descriptor, not a stdio ptr. */
231*0Sstevel@tonic-gate {
232*0Sstevel@tonic-gate 	char	tiebuf[4096];
233*0Sstevel@tonic-gate 	char	fname[TERMPATHLEN];
234*0Sstevel@tonic-gate 	char	*ip;
235*0Sstevel@tonic-gate 	char	*cp;
236*0Sstevel@tonic-gate 	int	n, tfd;
237*0Sstevel@tonic-gate 	char	*lcp, *ccp, **on_sequences, **str_array;
238*0Sstevel@tonic-gate 	int	snames, nbools, nints, nstrs, sstrtab;
239*0Sstevel@tonic-gate 	char	*strtab;
240*0Sstevel@tonic-gate #ifdef	DUMPTI
241*0Sstevel@tonic-gate 	int		Vr2val;
242*0Sstevel@tonic-gate #endif	/* DUMPTI */
243*0Sstevel@tonic-gate 
244*0Sstevel@tonic-gate 	(void) mbgetwidth();
245*0Sstevel@tonic-gate 
246*0Sstevel@tonic-gate 	if (term == NULL)
247*0Sstevel@tonic-gate 		term = getenv("TERM");
248*0Sstevel@tonic-gate 
249*0Sstevel@tonic-gate 	if (term == NULL || *term == '\0')
250*0Sstevel@tonic-gate 		term = Def_term;
251*0Sstevel@tonic-gate 
252*0Sstevel@tonic-gate 	tfd = -1;
253*0Sstevel@tonic-gate 	errno = 0; 	/* ehr3 */
254*0Sstevel@tonic-gate 
255*0Sstevel@tonic-gate 	if (errret != 0)
256*0Sstevel@tonic-gate 		*errret = -1;
257*0Sstevel@tonic-gate 
258*0Sstevel@tonic-gate 	if (((cp = getenv("TERMINFO")) != 0) && *cp) {
259*0Sstevel@tonic-gate 		/* $TERMINFO/?/$TERM */
260*0Sstevel@tonic-gate 		if (snprintf(fname, sizeof (fname),
261*0Sstevel@tonic-gate 			"%s/%c/%s", cp, *term, term) >= sizeof (fname)) {
262*0Sstevel@tonic-gate 			term_errno = TERMINFO_TOO_LONG;
263*0Sstevel@tonic-gate 			goto out_err;
264*0Sstevel@tonic-gate 		}
265*0Sstevel@tonic-gate 
266*0Sstevel@tonic-gate 		tfd = open(fname, 0);
267*0Sstevel@tonic-gate #ifdef	DUMPTI
268*0Sstevel@tonic-gate 		printf("looking in file %s\n", fname);
269*0Sstevel@tonic-gate #endif	/* DUMPTI */
270*0Sstevel@tonic-gate 		if ((tfd < 0) && (errno == EACCES))
271*0Sstevel@tonic-gate 			goto cant_read;
272*0Sstevel@tonic-gate 	}
273*0Sstevel@tonic-gate 
274*0Sstevel@tonic-gate 	if (tfd < 0) {
275*0Sstevel@tonic-gate 		/* /usr/share/lib/terminfo/?/$TERM */
276*0Sstevel@tonic-gate 		if (snprintf(fname, sizeof (fname),
277*0Sstevel@tonic-gate 			"%s/%c/%s", TERMPATH, *term, term) >= sizeof (fname)) {
278*0Sstevel@tonic-gate 			term_errno = TERMINFO_TOO_LONG;
279*0Sstevel@tonic-gate 			goto out_err;
280*0Sstevel@tonic-gate 		}
281*0Sstevel@tonic-gate 
282*0Sstevel@tonic-gate 		tfd = open(fname, 0);
283*0Sstevel@tonic-gate #ifdef	DUMPTI
284*0Sstevel@tonic-gate 		printf("looking in file %s\n", fname);
285*0Sstevel@tonic-gate #endif	/* DUMPTI */
286*0Sstevel@tonic-gate 
287*0Sstevel@tonic-gate 	}
288*0Sstevel@tonic-gate 
289*0Sstevel@tonic-gate 	if (tfd < 0) {
290*0Sstevel@tonic-gate 		if (errno == EACCES) {
291*0Sstevel@tonic-gate cant_read:
292*0Sstevel@tonic-gate 			term_errno = NOT_READABLE;
293*0Sstevel@tonic-gate 		} else {
294*0Sstevel@tonic-gate 			if (access(TERMPATH, 0) == -1)
295*0Sstevel@tonic-gate 				term_errno = UNACCESSIBLE;
296*0Sstevel@tonic-gate 			else {
297*0Sstevel@tonic-gate 				term_errno = NO_TERMINAL;
298*0Sstevel@tonic-gate 				if (errret != 0)
299*0Sstevel@tonic-gate 					*errret = 0;
300*0Sstevel@tonic-gate 			}
301*0Sstevel@tonic-gate 		}
302*0Sstevel@tonic-gate 		/*
303*0Sstevel@tonic-gate 		 * if the length of the specified terminal name is longer
304*0Sstevel@tonic-gate 		 * than 31, it will be chopped after the 31st byte.
305*0Sstevel@tonic-gate 		 * This should be a rare case.
306*0Sstevel@tonic-gate 		 */
307*0Sstevel@tonic-gate 		(void) strncpy(term_parm_err, term, 31);
308*0Sstevel@tonic-gate 		term_parm_err[31] = '\0';
309*0Sstevel@tonic-gate 		goto out_err;
310*0Sstevel@tonic-gate 	}
311*0Sstevel@tonic-gate 
312*0Sstevel@tonic-gate 	/* LINTED */
313*0Sstevel@tonic-gate 	n = (int)read(tfd, tiebuf, sizeof (tiebuf));
314*0Sstevel@tonic-gate 	(void) close(tfd);
315*0Sstevel@tonic-gate 
316*0Sstevel@tonic-gate 	if (n <= 0) {
317*0Sstevel@tonic-gate corrupt:
318*0Sstevel@tonic-gate 		term_errno = CORRUPTED;
319*0Sstevel@tonic-gate 		goto out_err;
320*0Sstevel@tonic-gate 	} else
321*0Sstevel@tonic-gate 		if (n == sizeof (tiebuf)) {
322*0Sstevel@tonic-gate 			term_errno = ENTRY_TOO_LONG;
323*0Sstevel@tonic-gate 			goto out_err;
324*0Sstevel@tonic-gate 		}
325*0Sstevel@tonic-gate 	cp = ttytype;
326*0Sstevel@tonic-gate 	ip = tiebuf;
327*0Sstevel@tonic-gate 
328*0Sstevel@tonic-gate 	/* Pick up header */
329*0Sstevel@tonic-gate 	snames = _Getshi();
330*0Sstevel@tonic-gate #ifdef	DUMPTI
331*0Sstevel@tonic-gate 	Vr2val = _Vr2getshi();
332*0Sstevel@tonic-gate 	printf("Magic number = %d, %#o [%d, %#o].\n", snames,
333*0Sstevel@tonic-gate 	    snames, Vr2val, Vr2val);
334*0Sstevel@tonic-gate #endif	/* DUMPTI */
335*0Sstevel@tonic-gate 	if (snames != MAGNUM)
336*0Sstevel@tonic-gate 		goto corrupt;
337*0Sstevel@tonic-gate 	snames = _Getshi();
338*0Sstevel@tonic-gate #ifdef	DUMPTI
339*0Sstevel@tonic-gate 	Vr2val = _Vr2getshi();
340*0Sstevel@tonic-gate 	printf("Size of names = %d, %#o [%d, %#o].\n", snames,
341*0Sstevel@tonic-gate 	    snames, Vr2val, Vr2val);
342*0Sstevel@tonic-gate #endif	/* DUMPTI */
343*0Sstevel@tonic-gate 
344*0Sstevel@tonic-gate 	nbools = _Getshi();
345*0Sstevel@tonic-gate #ifdef	DUMPTI
346*0Sstevel@tonic-gate 	Vr2val = _Vr2getshi();
347*0Sstevel@tonic-gate 	printf("Number of bools = %d, %#o [%d, %#o].\n", nbools,
348*0Sstevel@tonic-gate 	    nbools, Vr2val, Vr2val);
349*0Sstevel@tonic-gate #endif	/* DUMPTI */
350*0Sstevel@tonic-gate 
351*0Sstevel@tonic-gate 	nints = _Getshi();
352*0Sstevel@tonic-gate #ifdef	DUMPTI
353*0Sstevel@tonic-gate 	Vr2val = _Vr2getshi();
354*0Sstevel@tonic-gate 	printf("Number of ints = %d, %#o [%d, %#o].\n", nints, nints,
355*0Sstevel@tonic-gate 	    Vr2val, Vr2val);
356*0Sstevel@tonic-gate #endif	/* DUMPTI */
357*0Sstevel@tonic-gate 
358*0Sstevel@tonic-gate 	nstrs = _Getshi();
359*0Sstevel@tonic-gate #ifdef	DUMPTI
360*0Sstevel@tonic-gate 	Vr2val = _Vr2getshi();
361*0Sstevel@tonic-gate 	printf("Number of strings = %d, %#o [%d, %#o].\n", nstrs, nstrs,
362*0Sstevel@tonic-gate 	    Vr2val, Vr2val);
363*0Sstevel@tonic-gate #endif	/* DUMPTI */
364*0Sstevel@tonic-gate 
365*0Sstevel@tonic-gate 	sstrtab = _Getshi();
366*0Sstevel@tonic-gate #ifdef	DUMPTI
367*0Sstevel@tonic-gate 	Vr2val = _Vr2getshi();
368*0Sstevel@tonic-gate 	printf("Size of string table = %d, %#o [%d, %#o].\n", sstrtab,
369*0Sstevel@tonic-gate 	    sstrtab, Vr2val, Vr2val);
370*0Sstevel@tonic-gate 	printf("Names are: %.*s.\n", snames, ip);
371*0Sstevel@tonic-gate #endif	/* DUMPTI */
372*0Sstevel@tonic-gate 
373*0Sstevel@tonic-gate 	/* allocate all of the space */
374*0Sstevel@tonic-gate 	strtab = NULL;
375*0Sstevel@tonic-gate 	if (_called_before) {
376*0Sstevel@tonic-gate 		/* 2nd or more times through */
377*0Sstevel@tonic-gate 		if ((cur_term = (TERMINAL *)
378*0Sstevel@tonic-gate 		    calloc(sizeof (TERMINAL), 1)) == NULL)
379*0Sstevel@tonic-gate 			goto badmalloc;
380*0Sstevel@tonic-gate 		if ((cur_bools = (struct _bool_struct *)
381*0Sstevel@tonic-gate 		    calloc(sizeof (struct _bool_struct), 1)) == NULL)
382*0Sstevel@tonic-gate 			goto freeterminal;
383*0Sstevel@tonic-gate 		if ((cur_nums = (struct _num_struct *)
384*0Sstevel@tonic-gate 		    calloc(sizeof (struct _num_struct), 1)) == NULL)
385*0Sstevel@tonic-gate 			goto freebools;
386*0Sstevel@tonic-gate 		if ((cur_strs = (struct _str_struct *)
387*0Sstevel@tonic-gate 		    calloc(sizeof (struct _str_struct), 1)) == NULL) {
388*0Sstevel@tonic-gate freenums:
389*0Sstevel@tonic-gate 			free((char *)cur_nums);
390*0Sstevel@tonic-gate freebools:
391*0Sstevel@tonic-gate 			free((char *)cur_bools);
392*0Sstevel@tonic-gate freeterminal:
393*0Sstevel@tonic-gate 			free((char *)cur_term);
394*0Sstevel@tonic-gate badmalloc:
395*0Sstevel@tonic-gate 			term_errno = TERM_BAD_MALLOC;
396*0Sstevel@tonic-gate #ifdef	DEBUG
397*0Sstevel@tonic-gate 			strcpy(term_parm_err, "setupterm");
398*0Sstevel@tonic-gate #endif	/* DEBUG */
399*0Sstevel@tonic-gate out_err:
400*0Sstevel@tonic-gate 			if (errret == 0) {
401*0Sstevel@tonic-gate 				termerr();
402*0Sstevel@tonic-gate 				exit(-term_errno);
403*0Sstevel@tonic-gate 			} else
404*0Sstevel@tonic-gate 				return (ERR);
405*0Sstevel@tonic-gate 		}
406*0Sstevel@tonic-gate 	} else {
407*0Sstevel@tonic-gate 		/* First time through */
408*0Sstevel@tonic-gate 		_called_before = TRUE;
409*0Sstevel@tonic-gate 		cur_term = &_first_term;
410*0Sstevel@tonic-gate 		cur_bools = &_frst_bools;
411*0Sstevel@tonic-gate 		cur_nums = &_frst_nums;
412*0Sstevel@tonic-gate 		cur_strs = &_frst_strs;
413*0Sstevel@tonic-gate 		if (sstrtab < sizeof (_frst_tblstr))
414*0Sstevel@tonic-gate 			strtab = _frst_tblstr;
415*0Sstevel@tonic-gate 	}
416*0Sstevel@tonic-gate 
417*0Sstevel@tonic-gate 	if (strtab == NULL) {
418*0Sstevel@tonic-gate 		if ((strtab = (char *)malloc((unsigned)sstrtab)) == NULL) {
419*0Sstevel@tonic-gate 			if (cur_strs != &_frst_strs)
420*0Sstevel@tonic-gate 				free((char *)cur_strs);
421*0Sstevel@tonic-gate 			goto freenums;
422*0Sstevel@tonic-gate 		}
423*0Sstevel@tonic-gate 	}
424*0Sstevel@tonic-gate 
425*0Sstevel@tonic-gate 	/* no more catchable errors */
426*0Sstevel@tonic-gate 	if (errret)
427*0Sstevel@tonic-gate 		*errret = 1;
428*0Sstevel@tonic-gate 
429*0Sstevel@tonic-gate 	(void) strncpy(cur_term->_termname, term, 14);
430*0Sstevel@tonic-gate 	/* In case the name is exactly 15 characters */
431*0Sstevel@tonic-gate 	cur_term->_termname[14] = '\0';
432*0Sstevel@tonic-gate 	cur_term->_bools = cur_bools;
433*0Sstevel@tonic-gate 	cur_term->_nums = cur_nums;
434*0Sstevel@tonic-gate 	cur_term->_strs = cur_strs;
435*0Sstevel@tonic-gate 	cur_term->_strtab = strtab;
436*0Sstevel@tonic-gate 	cur_term->sgr_mode = cur_term->sgr_faked = A_NORMAL;
437*0Sstevel@tonic-gate 
438*0Sstevel@tonic-gate 	if (filenum == 1 && !isatty(filenum))
439*0Sstevel@tonic-gate 		filenum = 2;	/* Allow output redirect */
440*0Sstevel@tonic-gate 	/* LINTED */
441*0Sstevel@tonic-gate 	cur_term->Filedes = (short)filenum;
442*0Sstevel@tonic-gate 	_blast_keys(cur_term);
443*0Sstevel@tonic-gate 	cur_term->_iwait = cur_term->fl_typeahdok = cur_term->_chars_on_queue =
444*0Sstevel@tonic-gate 		cur_term->_fl_rawmode = cur_term->_ungotten = 0;
445*0Sstevel@tonic-gate 	cur_term->_cursorstate = 1;
446*0Sstevel@tonic-gate 	cur_term->_delay = cur_term->_inputfd = cur_term->_check_fd = -1;
447*0Sstevel@tonic-gate 	(void) memset((char *)cur_term->_regs, 0, 26 * sizeof (short));
448*0Sstevel@tonic-gate 
449*0Sstevel@tonic-gate #ifndef	DUMPTI
450*0Sstevel@tonic-gate 	(void) def_shell_mode();
451*0Sstevel@tonic-gate 	/* This is a useful default for PROGTTY, too */
452*0Sstevel@tonic-gate #ifdef SYSV
453*0Sstevel@tonic-gate 	if (shell_istermios < 0) {
454*0Sstevel@tonic-gate 		int i;
455*0Sstevel@tonic-gate 
456*0Sstevel@tonic-gate 		SHELLTTY.c_lflag = SHELLTTYS.c_lflag;
457*0Sstevel@tonic-gate 		SHELLTTY.c_oflag = SHELLTTYS.c_oflag;
458*0Sstevel@tonic-gate 		SHELLTTY.c_iflag = SHELLTTYS.c_iflag;
459*0Sstevel@tonic-gate 		SHELLTTY.c_cflag = SHELLTTYS.c_cflag;
460*0Sstevel@tonic-gate 		for (i = 0; i < NCC; i++)
461*0Sstevel@tonic-gate 			SHELLTTY.c_cc[i] = SHELLTTYS.c_cc[i];
462*0Sstevel@tonic-gate 		PROGTTY = SHELLTTY;
463*0Sstevel@tonic-gate 		prog_istermios = -1;
464*0Sstevel@tonic-gate 
465*0Sstevel@tonic-gate 		PROGTTYS.c_lflag = PROGTTY.c_lflag;
466*0Sstevel@tonic-gate 		PROGTTYS.c_oflag = PROGTTY.c_oflag;
467*0Sstevel@tonic-gate 		PROGTTYS.c_iflag = PROGTTY.c_iflag;
468*0Sstevel@tonic-gate 		PROGTTYS.c_cflag = PROGTTY.c_cflag;
469*0Sstevel@tonic-gate 		for (i = 0; i < NCC; i++)
470*0Sstevel@tonic-gate 			PROGTTYS.c_cc[i] = PROGTTY.c_cc[i];
471*0Sstevel@tonic-gate 	} else {
472*0Sstevel@tonic-gate 		PROGTTYS = SHELLTTYS;
473*0Sstevel@tonic-gate 		prog_istermios = 0;
474*0Sstevel@tonic-gate 	}
475*0Sstevel@tonic-gate #else	/* SYSV */
476*0Sstevel@tonic-gate 	PROGTTY = SHELLTTY;
477*0Sstevel@tonic-gate #endif	/* SYSV */
478*0Sstevel@tonic-gate #endif	/* DUMPTI */
479*0Sstevel@tonic-gate 
480*0Sstevel@tonic-gate 	/* Skip names of terminals */
481*0Sstevel@tonic-gate 	(void) memcpy((char *)cp, (char *)ip, (snames * sizeof (*cp)));
482*0Sstevel@tonic-gate 	ip += snames;
483*0Sstevel@tonic-gate 
484*0Sstevel@tonic-gate 	/*
485*0Sstevel@tonic-gate 	 * Pull out the booleans.
486*0Sstevel@tonic-gate 	 * The for loop below takes care of a new curses with an old tic
487*0Sstevel@tonic-gate 	 * file and visa-versa.  nbools says how many bools the tic file has.
488*0Sstevel@tonic-gate 	 * So, we only loop for as long as there are bools to read.
489*0Sstevel@tonic-gate 	 * However, if this is an old curses that doesn't have all the
490*0Sstevel@tonic-gate 	 * bools that this new tic has dumped, then the extra if
491*0Sstevel@tonic-gate 	 * "if (cp < fp)" says that if we are going to read into our structure
492*0Sstevel@tonic-gate 	 * passed its size don't do it but we still need to keep bumping
493*0Sstevel@tonic-gate 	 * up the pointer of what we read in from the terminfo file.
494*0Sstevel@tonic-gate 	 */
495*0Sstevel@tonic-gate 	{
496*0Sstevel@tonic-gate 		char	*fp = &cur_bools->Sentinel;
497*0Sstevel@tonic-gate 		char	s;
498*0Sstevel@tonic-gate #ifdef	DUMPTI
499*0Sstevel@tonic-gate 		int	tempindex = 0;
500*0Sstevel@tonic-gate #endif	/* DUMPTI */
501*0Sstevel@tonic-gate 		cp = &cur_bools->_auto_left_margin;
502*0Sstevel@tonic-gate 		while (nbools--) {
503*0Sstevel@tonic-gate 			s = *ip++;
504*0Sstevel@tonic-gate #ifdef	DUMPTI
505*0Sstevel@tonic-gate 			printf("Bool %s [%s] (%s) = %d.\n",
506*0Sstevel@tonic-gate 			    boolfnames[tempindex], boolnames[tempindex],
507*0Sstevel@tonic-gate 			    boolcodes[tempindex], s);
508*0Sstevel@tonic-gate 			tempindex++;
509*0Sstevel@tonic-gate #endif	/* DUMPTI */
510*0Sstevel@tonic-gate 			if (cp < fp)
511*0Sstevel@tonic-gate 				*cp++ = s & 01;
512*0Sstevel@tonic-gate 		}
513*0Sstevel@tonic-gate 		if (cp < fp)
514*0Sstevel@tonic-gate 			(void) memset(cp, 0, ((fp - cp) * sizeof (bool)));
515*0Sstevel@tonic-gate 	}
516*0Sstevel@tonic-gate 
517*0Sstevel@tonic-gate 	/* Force proper alignment */
518*0Sstevel@tonic-gate 	if (((unsigned long) ip) & 1)
519*0Sstevel@tonic-gate 		ip++;
520*0Sstevel@tonic-gate 
521*0Sstevel@tonic-gate 	/*
522*0Sstevel@tonic-gate 	 * Pull out the numbers.
523*0Sstevel@tonic-gate 	 */
524*0Sstevel@tonic-gate 	{
525*0Sstevel@tonic-gate 		short	*sp = &cur_nums->_columns;
526*0Sstevel@tonic-gate 		short	*fp = &cur_nums->Sentinel;
527*0Sstevel@tonic-gate 		int	s;
528*0Sstevel@tonic-gate #ifdef	DUMPTI
529*0Sstevel@tonic-gate 		int	tempindex = 0;
530*0Sstevel@tonic-gate #endif	/* DUMPTI */
531*0Sstevel@tonic-gate 
532*0Sstevel@tonic-gate 		while (nints--) {
533*0Sstevel@tonic-gate 			s = _Getshi();
534*0Sstevel@tonic-gate #ifdef	DUMPTI
535*0Sstevel@tonic-gate 			Vr2val = _Vr2getshi();
536*0Sstevel@tonic-gate 			printf("Num %s [%s] (%s) = %d [%d].\n",
537*0Sstevel@tonic-gate 			    numfnames[tempindex], numnames[tempindex],
538*0Sstevel@tonic-gate 			    numcodes[tempindex], s, Vr2val);
539*0Sstevel@tonic-gate 			tempindex++;
540*0Sstevel@tonic-gate #endif	/* DUMPTI */
541*0Sstevel@tonic-gate 			if (sp < fp)
542*0Sstevel@tonic-gate 				if (s < 0)
543*0Sstevel@tonic-gate 					*sp++ = -1;
544*0Sstevel@tonic-gate 				else
545*0Sstevel@tonic-gate 					/* LINTED */
546*0Sstevel@tonic-gate 					*sp++ = (short)s;
547*0Sstevel@tonic-gate 		}
548*0Sstevel@tonic-gate 		if (sp < fp)
549*0Sstevel@tonic-gate 			(void) memset((char *)sp, '\377',
550*0Sstevel@tonic-gate 			    ((fp - sp) * sizeof (short)));
551*0Sstevel@tonic-gate 	}
552*0Sstevel@tonic-gate 
553*0Sstevel@tonic-gate 	if (_use_env) {
554*0Sstevel@tonic-gate 		/*
555*0Sstevel@tonic-gate 		 * This ioctl defines the window size and overrides what
556*0Sstevel@tonic-gate 		 * it says in terminfo.
557*0Sstevel@tonic-gate 		 */
558*0Sstevel@tonic-gate 		{
559*0Sstevel@tonic-gate 			struct	winsize	w;
560*0Sstevel@tonic-gate 
561*0Sstevel@tonic-gate 			if (ioctl(filenum, TIOCGWINSZ, &w) != -1) {
562*0Sstevel@tonic-gate 				if (w.ws_row != 0)
563*0Sstevel@tonic-gate 					cur_nums->_lines = w.ws_row;
564*0Sstevel@tonic-gate 				if (w.ws_col != 0)
565*0Sstevel@tonic-gate 					cur_nums->_columns = w.ws_col;
566*0Sstevel@tonic-gate #ifdef	DUMPTI
567*0Sstevel@tonic-gate 				printf("ioctl TIOCGWINSZ override: "
568*0Sstevel@tonic-gate 				    "(lines, columns) = (%d, %d)\n",
569*0Sstevel@tonic-gate 				    w.ws_row, w.ws_col);
570*0Sstevel@tonic-gate #endif	/* DUMPTI */
571*0Sstevel@tonic-gate 			}
572*0Sstevel@tonic-gate 		}
573*0Sstevel@tonic-gate 
574*0Sstevel@tonic-gate 		/*
575*0Sstevel@tonic-gate 		 * Check $LINES and $COLUMNS.
576*0Sstevel@tonic-gate 		 */
577*0Sstevel@tonic-gate 		{
578*0Sstevel@tonic-gate 			int	ilines, icolumns;
579*0Sstevel@tonic-gate 
580*0Sstevel@tonic-gate 			lcp = getenv("LINES");
581*0Sstevel@tonic-gate 			ccp = getenv("COLUMNS");
582*0Sstevel@tonic-gate 			if (lcp)
583*0Sstevel@tonic-gate 				if ((ilines = atoi(lcp)) > 0) {
584*0Sstevel@tonic-gate 					/* LINTED */
585*0Sstevel@tonic-gate 					cur_nums->_lines = (short)ilines;
586*0Sstevel@tonic-gate #ifdef	DUMPTI
587*0Sstevel@tonic-gate 					printf("$LINES override: lines = %d\n",
588*0Sstevel@tonic-gate 					    ilines);
589*0Sstevel@tonic-gate #endif	/* DUMPTI */
590*0Sstevel@tonic-gate 				}
591*0Sstevel@tonic-gate 			if (ccp)
592*0Sstevel@tonic-gate 				if ((icolumns = atoi(ccp)) > 0) {
593*0Sstevel@tonic-gate 					/* LINTED */
594*0Sstevel@tonic-gate 					cur_nums->_columns = (short)icolumns;
595*0Sstevel@tonic-gate #ifdef	DUMPTI
596*0Sstevel@tonic-gate 					printf("$COLUMNS override: columns = "
597*0Sstevel@tonic-gate 					    "%d\n", icolumns);
598*0Sstevel@tonic-gate #endif	/* DUMPTI */
599*0Sstevel@tonic-gate 				}
600*0Sstevel@tonic-gate 		}
601*0Sstevel@tonic-gate 	}
602*0Sstevel@tonic-gate 
603*0Sstevel@tonic-gate 	/* Pull out the strings. */
604*0Sstevel@tonic-gate 	{
605*0Sstevel@tonic-gate 		char	**pp = &cur_strs->strs._back_tab;
606*0Sstevel@tonic-gate 		char	**fp = &cur_strs->strs4.Sentinel;
607*0Sstevel@tonic-gate #ifdef	DUMPTI
608*0Sstevel@tonic-gate 		int	tempindex = 0;
609*0Sstevel@tonic-gate 		char	*startstr = ip + sizeof (short) *
610*0Sstevel@tonic-gate 					    nstrs;
611*0Sstevel@tonic-gate 
612*0Sstevel@tonic-gate 		printf("string table = '");
613*0Sstevel@tonic-gate 		_Mprint(sstrtab, startstr);
614*0Sstevel@tonic-gate 		printf("'\n");
615*0Sstevel@tonic-gate #endif	/* DUMPTI */
616*0Sstevel@tonic-gate 
617*0Sstevel@tonic-gate 		while (nstrs--) {
618*0Sstevel@tonic-gate 			n = _Getshi();
619*0Sstevel@tonic-gate #ifdef	DUMPTI
620*0Sstevel@tonic-gate 			Vr2val = _Vr2getshi();
621*0Sstevel@tonic-gate 			printf("String %s [%s] (%s) offset = %d [%d]",
622*0Sstevel@tonic-gate 			    strfnames[tempindex], strnames[tempindex],
623*0Sstevel@tonic-gate 			    strcodes[tempindex], n, Vr2val);
624*0Sstevel@tonic-gate 			tempindex++;
625*0Sstevel@tonic-gate #endif	/* DUMPTI */
626*0Sstevel@tonic-gate 			if (pp < fp) {
627*0Sstevel@tonic-gate #ifdef	DUMPTI
628*0Sstevel@tonic-gate 				_Sprint(n, startstr+n);
629*0Sstevel@tonic-gate #endif	/* DUMPTI */
630*0Sstevel@tonic-gate 				if (n < 0)
631*0Sstevel@tonic-gate 					*pp++ = NULL;
632*0Sstevel@tonic-gate 				else
633*0Sstevel@tonic-gate 					*pp++ = strtab + n;
634*0Sstevel@tonic-gate 			}
635*0Sstevel@tonic-gate #ifdef	DUMPTI
636*0Sstevel@tonic-gate 			else
637*0Sstevel@tonic-gate 				_Sprint(-1, (char *)0);
638*0Sstevel@tonic-gate #endif	/* DUMPTI */
639*0Sstevel@tonic-gate 		}
640*0Sstevel@tonic-gate 		if (pp < fp)
641*0Sstevel@tonic-gate 		(void) memset((char *)pp, 0, ((fp - pp) * sizeof (charptr)));
642*0Sstevel@tonic-gate 	}
643*0Sstevel@tonic-gate 
644*0Sstevel@tonic-gate 	(void) memcpy(strtab, ip, sstrtab);
645*0Sstevel@tonic-gate 
646*0Sstevel@tonic-gate #ifndef	DUMPTI
647*0Sstevel@tonic-gate 
648*0Sstevel@tonic-gate 	/*
649*0Sstevel@tonic-gate 	 * If tabs are being expanded in software, turn this off
650*0Sstevel@tonic-gate 	 * so output won't get messed up.  Also, don't use tab
651*0Sstevel@tonic-gate 	 * or backtab, even if the terminal has them, since the
652*0Sstevel@tonic-gate 	 * user might not have hardware tabs set right.
653*0Sstevel@tonic-gate 	 */
654*0Sstevel@tonic-gate #ifdef	SYSV
655*0Sstevel@tonic-gate 	if ((PROGTTYS.c_oflag & TABDLY) == TAB3) {
656*0Sstevel@tonic-gate 		PROGTTYS.c_oflag &= ~TABDLY;
657*0Sstevel@tonic-gate 		(void) reset_prog_mode();
658*0Sstevel@tonic-gate 		goto next;
659*0Sstevel@tonic-gate 	}
660*0Sstevel@tonic-gate #else	/* SYSV */
661*0Sstevel@tonic-gate 	if ((PROGTTY.sg_flags & XTABS) == XTABS) {
662*0Sstevel@tonic-gate 		PROGTTY.sg_flags &= ~XTABS;
663*0Sstevel@tonic-gate 		(void) reset_prog_mode();
664*0Sstevel@tonic-gate 		goto next;
665*0Sstevel@tonic-gate 	}
666*0Sstevel@tonic-gate #endif	/* SYSV */
667*0Sstevel@tonic-gate 	if (dest_tabs_magic_smso) {
668*0Sstevel@tonic-gate next:
669*0Sstevel@tonic-gate 		cur_strs->strs2._tab = cur_strs->strs._back_tab = NULL;
670*0Sstevel@tonic-gate 	}
671*0Sstevel@tonic-gate 
672*0Sstevel@tonic-gate #ifdef	LTILDE
673*0Sstevel@tonic-gate 	ioctl(cur_term -> Filedes, TIOCLGET, &n);
674*0Sstevel@tonic-gate #endif	/* LTILDE */
675*0Sstevel@tonic-gate #endif	/* DUMPTI */
676*0Sstevel@tonic-gate 
677*0Sstevel@tonic-gate #ifdef	_VR2_COMPAT_CODE
678*0Sstevel@tonic-gate 	(void) memcpy(&cur_term->_b1, &cur_bools->_auto_left_margin,
679*0Sstevel@tonic-gate 	    (char *)&cur_term->_c1 - (char *)&cur_term->_b1);
680*0Sstevel@tonic-gate 	(void) memcpy((char *)&cur_term->_c1, (char *)&cur_nums->_columns,
681*0Sstevel@tonic-gate 	    (char *)&cur_term->_Vr2_Astrs._s1 - (char *)&cur_term->_c1);
682*0Sstevel@tonic-gate 	(void) memcpy((char *)&cur_term->_Vr2_Astrs._s1,
683*0Sstevel@tonic-gate 	    (char *)&cur_strs->strs._back_tab,
684*0Sstevel@tonic-gate 	    (char *)&cur_term->Filedes - (char *)&cur_term->_Vr2_Astrs._s1);
685*0Sstevel@tonic-gate #endif	/* _VR2_COMPAT_CODE */
686*0Sstevel@tonic-gate 
687*0Sstevel@tonic-gate 	on_sequences = cur_term->turn_on_seq;
688*0Sstevel@tonic-gate 	str_array = (char **)cur_strs;
689*0Sstevel@tonic-gate 	{
690*0Sstevel@tonic-gate 		static	char	offsets[] = {
691*0Sstevel@tonic-gate 			    35,	/* enter_standout_mode, */
692*0Sstevel@tonic-gate 			    36,	/* enter_underline_mode, */
693*0Sstevel@tonic-gate 			    25,	/* enter_alt_charset_mode, */
694*0Sstevel@tonic-gate 			    34,	/* enter_reverse_mode, */
695*0Sstevel@tonic-gate 			    26,	/* enter_blink_mode, */
696*0Sstevel@tonic-gate 			    30,	/* enter_dim_mode, */
697*0Sstevel@tonic-gate 			    27,	/* enter_bold_mode, */
698*0Sstevel@tonic-gate 			    32,	/* enter_secure_mode, */
699*0Sstevel@tonic-gate 			    33,	/* enter_protected_mode, */
700*0Sstevel@tonic-gate 			};
701*0Sstevel@tonic-gate 
702*0Sstevel@tonic-gate 		for (n = 0; n < NUM_ATTRIBUTES; n++) {
703*0Sstevel@tonic-gate 			if ((on_sequences[n] = str_array[offsets[n]]) != 0)
704*0Sstevel@tonic-gate 				cur_term->bit_vector |= bit_attributes[n];
705*0Sstevel@tonic-gate 		}
706*0Sstevel@tonic-gate 	}
707*0Sstevel@tonic-gate 
708*0Sstevel@tonic-gate 	if (!(set_attributes)) {
709*0Sstevel@tonic-gate 		static	char	faked_attrs[] = { 1, 3, 4, 6 },
710*0Sstevel@tonic-gate 			offsets[] = {
711*0Sstevel@tonic-gate 			    43,	/* exit_standout_mode, */
712*0Sstevel@tonic-gate 			    44,	/* exit_underline_mode, */
713*0Sstevel@tonic-gate 			    38,	/* exit_alt_charset_mode, */
714*0Sstevel@tonic-gate 			};
715*0Sstevel@tonic-gate 		char		**off_sequences = cur_term->turn_off_seq;
716*0Sstevel@tonic-gate 		int		i;
717*0Sstevel@tonic-gate 
718*0Sstevel@tonic-gate 		if ((max_attributes == -1) && (ceol_standout_glitch ||
719*0Sstevel@tonic-gate 		    (magic_cookie_glitch >= 0)))
720*0Sstevel@tonic-gate 			max_attributes = 1;
721*0Sstevel@tonic-gate 
722*0Sstevel@tonic-gate 		/* Figure out what attributes need to be faked. */
723*0Sstevel@tonic-gate 		/* See vidupdate.c */
724*0Sstevel@tonic-gate 
725*0Sstevel@tonic-gate 		for (n = 0; n < sizeof (faked_attrs); n++) {
726*0Sstevel@tonic-gate 			if (on_sequences[0] != NULL) {
727*0Sstevel@tonic-gate 				if ((!on_sequences[i = faked_attrs[n]]) ||
728*0Sstevel@tonic-gate 				    (strcmp(on_sequences[i],
729*0Sstevel@tonic-gate 				    on_sequences[0]) == 0)) {
730*0Sstevel@tonic-gate 					cur_term->sgr_faked |=
731*0Sstevel@tonic-gate 					    bit_attributes[i];
732*0Sstevel@tonic-gate 				}
733*0Sstevel@tonic-gate 			} else {
734*0Sstevel@tonic-gate 				if (!on_sequences[i = faked_attrs[n]]) {
735*0Sstevel@tonic-gate 					cur_term->sgr_faked |=
736*0Sstevel@tonic-gate 					    bit_attributes[i];
737*0Sstevel@tonic-gate 				}
738*0Sstevel@tonic-gate 			}
739*0Sstevel@tonic-gate 		}
740*0Sstevel@tonic-gate 
741*0Sstevel@tonic-gate 		cur_term->check_turn_off = A_STANDOUT | A_UNDERLINE |
742*0Sstevel@tonic-gate 		    A_ALTCHARSET;
743*0Sstevel@tonic-gate 
744*0Sstevel@tonic-gate 		for (n = 0; n < sizeof (offsets); n++) {
745*0Sstevel@tonic-gate 			if ((!(off_sequences[n] = str_array[offsets[n]])) ||
746*0Sstevel@tonic-gate 			    ((n > 0) && off_sequences[0] &&
747*0Sstevel@tonic-gate 			    (strcmp(off_sequences[n], off_sequences[0]) ==
748*0Sstevel@tonic-gate 			    0)) || ((n == 2) && (exit_attribute_mode) &&
749*0Sstevel@tonic-gate 			    (strcmp(exit_attribute_mode, off_sequences[n]) ==
750*0Sstevel@tonic-gate 			    0))) {
751*0Sstevel@tonic-gate 				cur_term->check_turn_off &= ~bit_attributes[n];
752*0Sstevel@tonic-gate 			}
753*0Sstevel@tonic-gate 		}
754*0Sstevel@tonic-gate 	}
755*0Sstevel@tonic-gate 	cur_term->cursor_seq[0] = cursor_invisible;
756*0Sstevel@tonic-gate 	cur_term->cursor_seq[1] = cursor_normal;
757*0Sstevel@tonic-gate 	cur_term->cursor_seq[2] = cursor_visible;
758*0Sstevel@tonic-gate 	cur_term->_pairs_tbl = (_Color_pair *) NULL;
759*0Sstevel@tonic-gate 	cur_term->_color_tbl = (_Color *) NULL;
760*0Sstevel@tonic-gate 
761*0Sstevel@tonic-gate 	return (OK);
762*0Sstevel@tonic-gate }
763*0Sstevel@tonic-gate 
764*0Sstevel@tonic-gate void
_blast_keys(TERMINAL * terminal)765*0Sstevel@tonic-gate _blast_keys(TERMINAL *terminal)
766*0Sstevel@tonic-gate {
767*0Sstevel@tonic-gate 	terminal->_keys = NULL;
768*0Sstevel@tonic-gate 	terminal->internal_keys = NULL;
769*0Sstevel@tonic-gate 	terminal->_ksz = terminal->_first_macro = 0;
770*0Sstevel@tonic-gate 	terminal->_lastkey_ordered = terminal->_lastmacro_ordered = -1;
771*0Sstevel@tonic-gate 	(void) memset((char *)terminal->funckeystarter, 0, 0400 *
772*0Sstevel@tonic-gate 	    sizeof (bool));
773*0Sstevel@tonic-gate }
774*0Sstevel@tonic-gate 
775*0Sstevel@tonic-gate #ifndef	DUMPTI
776*0Sstevel@tonic-gate 
777*0Sstevel@tonic-gate int
reset_prog_mode(void)778*0Sstevel@tonic-gate reset_prog_mode(void)
779*0Sstevel@tonic-gate {
780*0Sstevel@tonic-gate #ifdef	SYSV
781*0Sstevel@tonic-gate 	if (_BRS(PROGTTYS)) {
782*0Sstevel@tonic-gate 		if (prog_istermios < 0) {
783*0Sstevel@tonic-gate 			int i;
784*0Sstevel@tonic-gate 
785*0Sstevel@tonic-gate 			PROGTTY.c_lflag = PROGTTYS.c_lflag;
786*0Sstevel@tonic-gate 			PROGTTY.c_oflag = PROGTTYS.c_oflag;
787*0Sstevel@tonic-gate 			PROGTTY.c_iflag = PROGTTYS.c_iflag;
788*0Sstevel@tonic-gate 			PROGTTY.c_cflag = PROGTTYS.c_cflag;
789*0Sstevel@tonic-gate 			for (i = 0; i < NCC; i++)
790*0Sstevel@tonic-gate 				PROGTTY.c_cc[i] = PROGTTYS.c_cc[i];
791*0Sstevel@tonic-gate 			(void) ioctl(cur_term -> Filedes, TCSETAW, &PROGTTY);
792*0Sstevel@tonic-gate 		} else
793*0Sstevel@tonic-gate 			(void) ioctl(cur_term -> Filedes, TCSETSW, &PROGTTYS);
794*0Sstevel@tonic-gate 	}
795*0Sstevel@tonic-gate #else	/* SYSV */
796*0Sstevel@tonic-gate 	if (_BR(PROGTTY))
797*0Sstevel@tonic-gate 		(void) ioctl(cur_term -> Filedes, TIOCSETN, &PROGTTY);
798*0Sstevel@tonic-gate #endif	/* SYSV */
799*0Sstevel@tonic-gate 
800*0Sstevel@tonic-gate #ifdef	LTILDE
801*0Sstevel@tonic-gate 	ioctl(cur_term -> Filedes, TIOCLGET, &cur_term -> oldlmode);
802*0Sstevel@tonic-gate 	cur_term -> newlmode = cur_term -> oldlmode & ~LTILDE;
803*0Sstevel@tonic-gate 	if (cur_term -> newlmode != cur_term -> oldlmode)
804*0Sstevel@tonic-gate 		ioctl(cur_term -> Filedes, TIOCLSET, &cur_term -> newlmode);
805*0Sstevel@tonic-gate #endif	/* LTILDE */
806*0Sstevel@tonic-gate #ifdef	DIOCSETT
807*0Sstevel@tonic-gate 	if (cur_term -> old.st_termt == 0)
808*0Sstevel@tonic-gate 		ioctl(cur_term->Filedes, DIOCGETT, &cur_term -> old);
809*0Sstevel@tonic-gate 	cur_term -> new = cur_term -> old;
810*0Sstevel@tonic-gate 	cur_term -> new.st_termt = 0;
811*0Sstevel@tonic-gate 	cur_term -> new.st_flgs |= TM_SET;
812*0Sstevel@tonic-gate 	ioctl(cur_term->Filedes, DIOCSETT, &cur_term -> new);
813*0Sstevel@tonic-gate #endif	/* DIOCSETT */
814*0Sstevel@tonic-gate 	return (OK);
815*0Sstevel@tonic-gate }
816*0Sstevel@tonic-gate 
817*0Sstevel@tonic-gate int
def_shell_mode(void)818*0Sstevel@tonic-gate def_shell_mode(void)
819*0Sstevel@tonic-gate {
820*0Sstevel@tonic-gate #ifdef	SYSV
821*0Sstevel@tonic-gate 	if ((shell_istermios =
822*0Sstevel@tonic-gate 	    ioctl(cur_term -> Filedes, TCGETS, &SHELLTTYS)) < 0) {
823*0Sstevel@tonic-gate 		int i;
824*0Sstevel@tonic-gate 
825*0Sstevel@tonic-gate 		(void) ioctl(cur_term -> Filedes, TCGETA, &SHELLTTY);
826*0Sstevel@tonic-gate 		SHELLTTYS.c_lflag = SHELLTTY.c_lflag;
827*0Sstevel@tonic-gate 		SHELLTTYS.c_oflag = SHELLTTY.c_oflag;
828*0Sstevel@tonic-gate 		SHELLTTYS.c_iflag = SHELLTTY.c_iflag;
829*0Sstevel@tonic-gate 		SHELLTTYS.c_cflag = SHELLTTY.c_cflag;
830*0Sstevel@tonic-gate 		for (i = 0; i < NCC; i++)
831*0Sstevel@tonic-gate 			SHELLTTYS.c_cc[i] = SHELLTTY.c_cc[i];
832*0Sstevel@tonic-gate 	}
833*0Sstevel@tonic-gate #else	/* SYSV */
834*0Sstevel@tonic-gate 	(void) ioctl(cur_term -> Filedes, TIOCGETP, &SHELLTTY);
835*0Sstevel@tonic-gate #endif	/* SYSV */
836*0Sstevel@tonic-gate 	return (OK);
837*0Sstevel@tonic-gate }
838*0Sstevel@tonic-gate 
839*0Sstevel@tonic-gate #endif	/* DUMPTI */
840