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