xref: /titanic_44/usr/src/ucbcmd/tset/tset.c (revision de81e71e031139a0a7f13b7bf64152c3faa76698)
1cc6c5292Schin /*
2*de81e71eSTim Marsland  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
3cc6c5292Schin  * Use is subject to license terms.
4cc6c5292Schin  */
5cc6c5292Schin 
67c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
77c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
87c478bd9Sstevel@tonic-gate 
97c478bd9Sstevel@tonic-gate 
107c478bd9Sstevel@tonic-gate /*
117c478bd9Sstevel@tonic-gate  * Copyright (c) 1980 Regents of the University of California.
127c478bd9Sstevel@tonic-gate  * All rights reserved. The Berkeley software License Agreement
137c478bd9Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
147c478bd9Sstevel@tonic-gate  */
157c478bd9Sstevel@tonic-gate 
167c478bd9Sstevel@tonic-gate /*
17*de81e71eSTim Marsland  *  TSET -- set terminal modes
18*de81e71eSTim Marsland  *
19*de81e71eSTim Marsland  *	This program does sophisticated terminal initialization.
20*de81e71eSTim Marsland  *	I recommend that you include it in your .profile or .login
21*de81e71eSTim Marsland  *	file to initialize whatever terminal you are on.
22*de81e71eSTim Marsland  *
23*de81e71eSTim Marsland  *	There are several features:
24*de81e71eSTim Marsland  *
25*de81e71eSTim Marsland  *	A special file or sequence (as controlled by the termcap file)
26*de81e71eSTim Marsland  *	is sent to the terminal.
27*de81e71eSTim Marsland  *
28*de81e71eSTim Marsland  *	Mode bits are set on a per-terminal_type basis (much better
29*de81e71eSTim Marsland  *	than UNIX itself).  This allows special delays, automatic
30*de81e71eSTim Marsland  *	tabs, etc.
31*de81e71eSTim Marsland  *
32*de81e71eSTim Marsland  *	Erase and Kill characters can be set to whatever you want.
33*de81e71eSTim Marsland  *	Default is to change erase to control-H on a terminal which
34*de81e71eSTim Marsland  *	can overstrike, and leave it alone on anything else.  Kill
35*de81e71eSTim Marsland  *	is always left alone unless specifically requested.  These
36*de81e71eSTim Marsland  *	characters can be represented as "^X" meaning control-X;
37*de81e71eSTim Marsland  *	X is any character.
38*de81e71eSTim Marsland  *
39*de81e71eSTim Marsland  *	Terminals which are dialups or plugboard types can be aliased
40*de81e71eSTim Marsland  *	to whatever type you may have in your home or office.  Thus,
41*de81e71eSTim Marsland  *	if you know that when you dial up you will always be on a
42*de81e71eSTim Marsland  *	TI 733, you can specify that fact to tset.  You can represent
43*de81e71eSTim Marsland  *	a type as "?type".  This will ask you what type you want it
44*de81e71eSTim Marsland  *	to be -- if you reply with just a newline, it will default
45*de81e71eSTim Marsland  *	to the type given.
46*de81e71eSTim Marsland  *
47*de81e71eSTim Marsland  *	The current terminal type can be queried.
48*de81e71eSTim Marsland  *
49*de81e71eSTim Marsland  *	Usage:
50*de81e71eSTim Marsland  *		tset [-] [-EC] [-eC] [-kC] [-iC] [-s] [-h] [-u] [-r]
51*de81e71eSTim Marsland  *			[-m [ident] [test baudrate] :type]
52*de81e71eSTim Marsland  *			[-Q] [-I] [-S] [type]
53*de81e71eSTim Marsland  *
54*de81e71eSTim Marsland  *		In systems with environments, use:
55*de81e71eSTim Marsland  *			eval `tset -s ...`
56*de81e71eSTim Marsland  *		Actually, this doesn't work in old csh's.
57*de81e71eSTim Marsland  *		Instead, use:
58*de81e71eSTim Marsland  *			tset -s ... > tset.tmp
59*de81e71eSTim Marsland  *			source tset.tmp
60*de81e71eSTim Marsland  *			rm tset.tmp
61*de81e71eSTim Marsland  *		or:
62*de81e71eSTim Marsland  *			set noglob
63*de81e71eSTim Marsland  *			set term=(`tset -S ....`)
64*de81e71eSTim Marsland  *			setenv TERM $term[1]
65*de81e71eSTim Marsland  *			setenv TERMCAP "$term[2]"
66*de81e71eSTim Marsland  *			unset term
67*de81e71eSTim Marsland  *			unset noglob
68*de81e71eSTim Marsland  *
69*de81e71eSTim Marsland  *	Positional Parameters:
70*de81e71eSTim Marsland  *		type -- the terminal type to force.  If this is
71*de81e71eSTim Marsland  *			specified, initialization is for this
72*de81e71eSTim Marsland  *			terminal type.
73*de81e71eSTim Marsland  *
74*de81e71eSTim Marsland  *	Flags:
75*de81e71eSTim Marsland  *		- -- report terminal type.  Whatever type is
76*de81e71eSTim Marsland  *			decided on is reported.  If no other flags
77*de81e71eSTim Marsland  *			are stated, the only affect is to write
78*de81e71eSTim Marsland  *			the terminal type on the standard output.
79*de81e71eSTim Marsland  *		-r -- report to user in addition to other flags.
80*de81e71eSTim Marsland  *		-EC -- set the erase character to C on all terminals
81*de81e71eSTim Marsland  *			except those which cannot backspace (e.g.,
82*de81e71eSTim Marsland  *			a TTY 33).  C defaults to control-H.
83*de81e71eSTim Marsland  *		-eC -- set the erase character to C on all terminals.
84*de81e71eSTim Marsland  *			C defaults to control-H.  If not specified,
85*de81e71eSTim Marsland  *			the erase character is untouched; however, if
86*de81e71eSTim Marsland  *			not specified and the erase character is NULL
87*de81e71eSTim Marsland  *			(zero byte), the erase character is set to CERASE.
88*de81e71eSTim Marsland  *		-kC -- set the kill character to C on all terminals.
89*de81e71eSTim Marsland  *			Default for C is control-U.  If not specified,
90*de81e71eSTim Marsland  *			the kill character is untouched; however, if
91*de81e71eSTim Marsland  *			not specified and the kill character is NULL
92*de81e71eSTim Marsland  *			(zero byte), the kill character is set to CKILL.
93*de81e71eSTim Marsland  *		-iC -- set the interrupt character to C on all terminals.
94*de81e71eSTim Marsland  *			Default for C is control-C.  If not specified, the
95*de81e71eSTim Marsland  *			interrupt character is untouched; however, if
96*de81e71eSTim Marsland  *			not specified and the interrupt character is NULL
97*de81e71eSTim Marsland  *			(zero byte), the interrupt character is set to
98*de81e71eSTim Marsland  *			control-C.
99*de81e71eSTim Marsland  *		-qC -- reserved for setable quit character.
100*de81e71eSTim Marsland  *		-m -- map the system identified type to some user
101*de81e71eSTim Marsland  *			specified type. The mapping can be baud rate
102*de81e71eSTim Marsland  *			dependent. This replaces the old -d, -p flags.
103*de81e71eSTim Marsland  *			(-d type  ->  -m dialup:type)
104*de81e71eSTim Marsland  *			(-p type  ->  -m plug:type)
105*de81e71eSTim Marsland  *			Syntax:	-m identifier [test baudrate] :type
106*de81e71eSTim Marsland  *			where: ``identifier'' is terminal type found in
107*de81e71eSTim Marsland  *			/etc/ttys for this port, (abscence of an identifier
108*de81e71eSTim Marsland  *			matches any identifier); ``test'' may be any combination
109*de81e71eSTim Marsland  *			of  >  =  <  !  @; ``baudrate'' is as with stty(1);
110*de81e71eSTim Marsland  *			``type'' is the actual terminal type to use if the
111*de81e71eSTim Marsland  *			mapping condition is met. Multiple maps are scanned
112*de81e71eSTim Marsland  *			in order and the first match prevails.
113*de81e71eSTim Marsland  *		-n -- If the new tty driver from UCB is available, this flag
114*de81e71eSTim Marsland  *			will activate the new options for erase and kill
115*de81e71eSTim Marsland  *			processing. This will be different for printers
116*de81e71eSTim Marsland  *			and crt's. For crts, if the baud rate is < 1200 then
117*de81e71eSTim Marsland  *			erase and kill don't remove characters from the screen.
118*de81e71eSTim Marsland  *		-h -- don't read htmp file.  Normally the terminal type
119*de81e71eSTim Marsland  *			is determined by reading the htmp file or the
120*de81e71eSTim Marsland  *			environment (unless some mapping is specified).
121*de81e71eSTim Marsland  *			This forces a read of the ttytype file -- useful
122*de81e71eSTim Marsland  *			when htmp is somehow wrong. (V6 only)
123*de81e71eSTim Marsland  *		-u -- don't update htmp.  It seemed like this should
124*de81e71eSTim Marsland  *			be put in.  Note that htmp is never actually
125*de81e71eSTim Marsland  *			written if there are no changes, so don't bother
126*de81e71eSTim Marsland  *			bother using this for efficiency reasons alone.
127*de81e71eSTim Marsland  *		-s -- output setenv commands for TERM.  This can be
128*de81e71eSTim Marsland  *			used with
129*de81e71eSTim Marsland  *				`tset -s ...`
130*de81e71eSTim Marsland  *			and is to be prefered to:
131*de81e71eSTim Marsland  *				setenv TERM `tset - ...`
132*de81e71eSTim Marsland  *			because -s sets the TERMCAP variable also.
133*de81e71eSTim Marsland  *		-S -- Similar to -s but outputs 2 strings suitable for
134*de81e71eSTim Marsland  *			use in csh .login files as follows:
135*de81e71eSTim Marsland  *				set noglob
136*de81e71eSTim Marsland  *				set term=(`tset -S .....`)
137*de81e71eSTim Marsland  *				setenv TERM $term[1]
138*de81e71eSTim Marsland  *				setenv TERMCAP "$term[2]"
139*de81e71eSTim Marsland  *				unset term
140*de81e71eSTim Marsland  *				unset noglob
141*de81e71eSTim Marsland  *		-Q -- be quiet.  don't output 'Erase set to' etc.
142*de81e71eSTim Marsland  *		-I -- don't do terminal initialization (is & if
143*de81e71eSTim Marsland  *			strings).
144*de81e71eSTim Marsland  *		-v -- On virtual terminal systems, don't set up a
145*de81e71eSTim Marsland  *			virtual terminal.  Otherwise tset will tell
146*de81e71eSTim Marsland  *			the operating system what kind of terminal you
147*de81e71eSTim Marsland  *			are on (if it is a known terminal) and fix up
148*de81e71eSTim Marsland  *			the output of -s to use virtual terminal sequences.
149*de81e71eSTim Marsland  *
150*de81e71eSTim Marsland  *	Files:
151*de81e71eSTim Marsland  *		/etc/ttys
152*de81e71eSTim Marsland  *			contains a terminal id -> terminal type
153*de81e71eSTim Marsland  *			mapping; used when any user mapping is specified,
154*de81e71eSTim Marsland  *			or the environment doesn't have TERM set.
155*de81e71eSTim Marsland  *		/etc/termcap
156*de81e71eSTim Marsland  *			a terminal_type -> terminal_capabilities
157*de81e71eSTim Marsland  *			mapping.
158*de81e71eSTim Marsland  *
159*de81e71eSTim Marsland  *	Return Codes:
160*de81e71eSTim Marsland  *		-1 -- couldn't open termcap.
161*de81e71eSTim Marsland  *		1 -- bad terminal type, or standard output not tty.
162*de81e71eSTim Marsland  *		0 -- ok.
163*de81e71eSTim Marsland  *
164*de81e71eSTim Marsland  *	Defined Constants:
165*de81e71eSTim Marsland  *		DIALUP -- the type code for a dialup port.
166*de81e71eSTim Marsland  *		PLUGBOARD -- the type code for a plugboard port.
167*de81e71eSTim Marsland  *		ARPANET -- the type code for an arpanet port.
168*de81e71eSTim Marsland  *		BACKSPACE -- control-H, the default for -e.
169*de81e71eSTim Marsland  *		CNTL('U') -- control-U, the default for -k.
170*de81e71eSTim Marsland  *		OLDERASE -- the ancient default erase character.
171*de81e71eSTim Marsland  *		FILEDES -- the file descriptor to do the operation
172*de81e71eSTim Marsland  *			on, nominally 1 or 2.
173*de81e71eSTim Marsland  *		STDOUT -- the standard output file descriptor.
174*de81e71eSTim Marsland  *		UIDMASK -- the bit pattern to mask with the getuid()
175*de81e71eSTim Marsland  *			call to get just the user id.
176*de81e71eSTim Marsland  *		GTTYN -- defines file containing generalized ttynames
177*de81e71eSTim Marsland  *			and compiles code to look there.
178*de81e71eSTim Marsland  *
179*de81e71eSTim Marsland  *	Requires:
180*de81e71eSTim Marsland  *		Routines to handle htmp, ttys, and termcap.
181*de81e71eSTim Marsland  *
182*de81e71eSTim Marsland  *	Compilation Flags:
183*de81e71eSTim Marsland  *		OLDFLAGS -- must be defined to compile code for any of
184*de81e71eSTim Marsland  *			the -d, -p, or -a flags.
185*de81e71eSTim Marsland  *		OLDDIALUP -- accept the -d flag.
186*de81e71eSTim Marsland  *		OLDPLUGBOARD -- accept the -p flag.
187*de81e71eSTim Marsland  *		OLDARPANET -- accept the -a flag.
188*de81e71eSTim Marsland  *		V6 -- if clear, use environments, not htmp.
189*de81e71eSTim Marsland  *			also use TIOCSETN rather than stty to avoid flushing
190*de81e71eSTim Marsland  *		GTTYN -- if set, compiles code to look at /etc/ttys.
191*de81e71eSTim Marsland  *
192*de81e71eSTim Marsland  *	Trace Flags:
193*de81e71eSTim Marsland  *		none
194*de81e71eSTim Marsland  *
195*de81e71eSTim Marsland  *	Diagnostics:
196*de81e71eSTim Marsland  *		Bad flag
197*de81e71eSTim Marsland  *			An incorrect option was specified.
198*de81e71eSTim Marsland  *		Too few args
199*de81e71eSTim Marsland  *			more command line arguments are required.
200*de81e71eSTim Marsland  *		Unexpected arg
201*de81e71eSTim Marsland  *			wrong type of argument was encountered.
202*de81e71eSTim Marsland  *		Cannot open ...
203*de81e71eSTim Marsland  *			The specified file could not be openned.
204*de81e71eSTim Marsland  *		Type ... unknown
205*de81e71eSTim Marsland  *			An unknown terminal type was specified.
206*de81e71eSTim Marsland  *		Cannot update htmp
207*de81e71eSTim Marsland  *			Cannot update htmp file when the standard
208*de81e71eSTim Marsland  *			output is not a terminal.
209*de81e71eSTim Marsland  *		Erase set to ...
210*de81e71eSTim Marsland  *			Telling that the erase character has been
211*de81e71eSTim Marsland  *			set to the specified character.
212*de81e71eSTim Marsland  *		Kill set to ...
213*de81e71eSTim Marsland  *			Ditto for kill
214*de81e71eSTim Marsland  *		Erase is ...    Kill is ...
215*de81e71eSTim Marsland  *			Tells that the erase/kill characters were
216*de81e71eSTim Marsland  *			wierd before, but they are being left as-is.
217*de81e71eSTim Marsland  *		Not a terminal
218*de81e71eSTim Marsland  *			Set if FILEDES is not a terminal.
219*de81e71eSTim Marsland  *
220*de81e71eSTim Marsland  *	Compilation Instructions:
221*de81e71eSTim Marsland  *		cc -n -O tset.c -ltermlib
222*de81e71eSTim Marsland  *		mv a.out tset
223*de81e71eSTim Marsland  *		chown bin tset
224*de81e71eSTim Marsland  *		chmod 4755 tset
225*de81e71eSTim Marsland  *
226*de81e71eSTim Marsland  *		where 'bin' should be whoever owns the 'htmp' file.
227*de81e71eSTim Marsland  *		If 'htmp' is 666, then tset need not be setuid.
228*de81e71eSTim Marsland  *
229*de81e71eSTim Marsland  *		For version 6 the compile command should be:
230*de81e71eSTim Marsland  *		cc -n -O -I/usr/include/retrofit tset.c -ltermlib -lretro -lS
231*de81e71eSTim Marsland  *
232*de81e71eSTim Marsland  *
233*de81e71eSTim Marsland  *	History:
234*de81e71eSTim Marsland  *		1/81 -- Added alias checking for mapping identifiers.
235*de81e71eSTim Marsland  *		7/80 -- '-S' added. '-m' mapping added. TERMCAP string
236*de81e71eSTim Marsland  *			cleaned up.
237*de81e71eSTim Marsland  *		3/80 -- Changed to use tputs.  Prc & flush added.
238*de81e71eSTim Marsland  *		10/79 -- '-s' option extended to handle TERMCAP
239*de81e71eSTim Marsland  *			variable, set noglob, quote the entry,
240*de81e71eSTim Marsland  *			and know about the Bourne shell.  Terminal
241*de81e71eSTim Marsland  *			initialization moved to before any information
242*de81e71eSTim Marsland  *			output so screen clears would not screw you.
243*de81e71eSTim Marsland  *			'-Q' option added.
244*de81e71eSTim Marsland  *		8/79 -- '-' option alone changed to only output
245*de81e71eSTim Marsland  *			type.  '-s' option added.  'VERSION7'
246*de81e71eSTim Marsland  *			changed to 'V6' for compatibility.
247*de81e71eSTim Marsland  *		12/78 -- modified for eventual migration to VAX/UNIX,
248*de81e71eSTim Marsland  *			so the '-' option is changed to output only
249*de81e71eSTim Marsland  *			the terminal type to STDOUT instead of
250*de81e71eSTim Marsland  *			FILEDES.
251*de81e71eSTim Marsland  *		9/78 -- '-' and '-p' options added (now fully
252*de81e71eSTim Marsland  *			compatible with ttytype!), and spaces are
253*de81e71eSTim Marsland  *			permitted between the -d and the type.
254*de81e71eSTim Marsland  *		8/78 -- The sense of -h and -u were reversed, and the
255*de81e71eSTim Marsland  *			-f flag is dropped -- same effect is available
256*de81e71eSTim Marsland  *			by just stating the terminal type.
257*de81e71eSTim Marsland  *		10/77 -- Written.
2587c478bd9Sstevel@tonic-gate  */
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate #define	index strchr
2627c478bd9Sstevel@tonic-gate #define	rindex strrchr
2637c478bd9Sstevel@tonic-gate #define	curerase modes.c_cc[VERASE]
2647c478bd9Sstevel@tonic-gate #define	curkill modes.c_cc[VKILL]
2657c478bd9Sstevel@tonic-gate #define	curintr modes.c_cc[VINTR]
2667c478bd9Sstevel@tonic-gate #define	olderase oldmodes.c_cc[VERASE]
2677c478bd9Sstevel@tonic-gate #define	oldkill oldmodes.c_cc[VKILL]
2687c478bd9Sstevel@tonic-gate #define	oldintr oldmodes.c_cc[VINTR]
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate #include	<stdio.h>
2717c478bd9Sstevel@tonic-gate #include	<termio.h>
2727c478bd9Sstevel@tonic-gate #include	<signal.h>
2737c478bd9Sstevel@tonic-gate 
2747c478bd9Sstevel@tonic-gate 
2757c478bd9Sstevel@tonic-gate #define	YES		1
2767c478bd9Sstevel@tonic-gate #define	NO		0
2777c478bd9Sstevel@tonic-gate #undef CNTL
2787c478bd9Sstevel@tonic-gate #define	CNTL(c)		((c)&037)
2797c478bd9Sstevel@tonic-gate #define	BACKSPACE	(CNTL('H'))
2807c478bd9Sstevel@tonic-gate #define	isdigit(c)	(c >= '0' && c <= '9')
2817c478bd9Sstevel@tonic-gate #define	isalnum(c)	(c > ' ' && (index("<@=>!:|\177", c) == NULL))
2827c478bd9Sstevel@tonic-gate #define	OLDERASE	'#'
2837c478bd9Sstevel@tonic-gate 
2847c478bd9Sstevel@tonic-gate /* default special characters */
2857c478bd9Sstevel@tonic-gate #ifndef CERASE
2867c478bd9Sstevel@tonic-gate #define	CERASE	'\177'
2877c478bd9Sstevel@tonic-gate #endif
2887c478bd9Sstevel@tonic-gate #ifndef CKILL
2897c478bd9Sstevel@tonic-gate #define	CKILL	CNTL('U')
2907c478bd9Sstevel@tonic-gate #endif
2917c478bd9Sstevel@tonic-gate #ifndef CINTR
2927c478bd9Sstevel@tonic-gate #define	CINTR	CNTL('C')
2937c478bd9Sstevel@tonic-gate #endif
2947c478bd9Sstevel@tonic-gate #ifndef CDSUSP
2957c478bd9Sstevel@tonic-gate #define	CQUIT	034		/* FS, ^\ */
2967c478bd9Sstevel@tonic-gate #define	CSTART	CNTL('Q')
2977c478bd9Sstevel@tonic-gate #define	CSTOP	CNTL('S')
2987c478bd9Sstevel@tonic-gate #define	CEOF	CNTL('D')
2997c478bd9Sstevel@tonic-gate #define	CEOT	CEOF
3007c478bd9Sstevel@tonic-gate #define	CBRK	0377
3017c478bd9Sstevel@tonic-gate #define	CSUSP	CNTL('Z')
3027c478bd9Sstevel@tonic-gate #define	CDSUSP	CNTL('Y')
3037c478bd9Sstevel@tonic-gate #define	CRPRNT	CNTL('R')
3047c478bd9Sstevel@tonic-gate #define	CFLUSH	CNTL('O')
3057c478bd9Sstevel@tonic-gate #define	CWERASE	CNTL('W')
3067c478bd9Sstevel@tonic-gate #define	CLNEXT	CNTL('V')
3077c478bd9Sstevel@tonic-gate #endif
3087c478bd9Sstevel@tonic-gate 
3097c478bd9Sstevel@tonic-gate #define	FILEDES		2	/* do gtty/stty on this descriptor */
3107c478bd9Sstevel@tonic-gate #define	STDOUT		1	/* output of -s/-S to this descriptor */
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate #define	UIDMASK		-1
3137c478bd9Sstevel@tonic-gate 
314*de81e71eSTim Marsland #define	USAGE	"usage: tset [-] [-rsIQS] [-eC] [-kC] "	\
315*de81e71eSTim Marsland 		"[-iC] [-m [ident][test speed]:type] [type]\n"
3167c478bd9Sstevel@tonic-gate 
3177c478bd9Sstevel@tonic-gate #define	OLDFLAGS
3187c478bd9Sstevel@tonic-gate #define	DIALUP		"dialup"
3197c478bd9Sstevel@tonic-gate #define	OLDDIALUP	"sd"
3207c478bd9Sstevel@tonic-gate #define	PLUGBOARD	"plugboard"
3217c478bd9Sstevel@tonic-gate #define	OLDPLUGBOARD	"sp"
3227c478bd9Sstevel@tonic-gate 
3237c478bd9Sstevel@tonic-gate #define	DEFTYPE		"unknown"
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate #define	NOTTY		'x'
3267c478bd9Sstevel@tonic-gate 
3277c478bd9Sstevel@tonic-gate /*
3287c478bd9Sstevel@tonic-gate  * Baud Rate Conditionals
3297c478bd9Sstevel@tonic-gate  */
3307c478bd9Sstevel@tonic-gate #define	ANY		0
3317c478bd9Sstevel@tonic-gate #define	GT		1
3327c478bd9Sstevel@tonic-gate #define	EQ		2
3337c478bd9Sstevel@tonic-gate #define	LT		4
3347c478bd9Sstevel@tonic-gate #define	GE		(GT|EQ)
3357c478bd9Sstevel@tonic-gate #define	LE		(LT|EQ)
3367c478bd9Sstevel@tonic-gate #define	NE		(GT|LT)
3377c478bd9Sstevel@tonic-gate #define	ALL		(GT|EQ|LT)
3387c478bd9Sstevel@tonic-gate 
3397c478bd9Sstevel@tonic-gate 
3407c478bd9Sstevel@tonic-gate 
3417c478bd9Sstevel@tonic-gate #define	NMAP		10
3427c478bd9Sstevel@tonic-gate 
3437c478bd9Sstevel@tonic-gate struct	map {
3447c478bd9Sstevel@tonic-gate 	char *Ident;
3457c478bd9Sstevel@tonic-gate 	char Test;
3467c478bd9Sstevel@tonic-gate 	char Speed;
3477c478bd9Sstevel@tonic-gate 	char *Type;
3487c478bd9Sstevel@tonic-gate } map[NMAP];
3497c478bd9Sstevel@tonic-gate 
3507c478bd9Sstevel@tonic-gate struct map *Map = map;
3517c478bd9Sstevel@tonic-gate 
3527c478bd9Sstevel@tonic-gate /* This should be available in an include file */
3537c478bd9Sstevel@tonic-gate struct
3547c478bd9Sstevel@tonic-gate {
3557c478bd9Sstevel@tonic-gate 	char	*string;
3567c478bd9Sstevel@tonic-gate 	int	speed;
3577c478bd9Sstevel@tonic-gate 	int	baudrate;
3587c478bd9Sstevel@tonic-gate } speeds[] = {
3597c478bd9Sstevel@tonic-gate 	"0",	B0,	0,
3607c478bd9Sstevel@tonic-gate 	"50",	B50,	50,
3617c478bd9Sstevel@tonic-gate 	"75",	B75,	75,
3627c478bd9Sstevel@tonic-gate 	"110",	B110,	110,
3637c478bd9Sstevel@tonic-gate 	"134",	B134,	134,
3647c478bd9Sstevel@tonic-gate 	"134.5", B134,	134,
3657c478bd9Sstevel@tonic-gate 	"150",	B150,	150,
3667c478bd9Sstevel@tonic-gate 	"200",	B200,	200,
3677c478bd9Sstevel@tonic-gate 	"300",	B300,	300,
3687c478bd9Sstevel@tonic-gate 	"600",	B600,	600,
3697c478bd9Sstevel@tonic-gate 	"1200",	B1200,	1200,
3707c478bd9Sstevel@tonic-gate 	"1800",	B1800,	1800,
3717c478bd9Sstevel@tonic-gate 	"2400",	B2400,	2400,
3727c478bd9Sstevel@tonic-gate 	"4800",	B4800,	4800,
3737c478bd9Sstevel@tonic-gate 	"9600",	B9600,	9600,
3747c478bd9Sstevel@tonic-gate 	"19200", EXTA,	19200,
3757c478bd9Sstevel@tonic-gate 	"exta",	EXTA,	19200,
3767c478bd9Sstevel@tonic-gate 	"extb",	EXTB,	38400,
3777c478bd9Sstevel@tonic-gate 	"57600", B57600,	57600,
3787c478bd9Sstevel@tonic-gate 	"76800", B76800,	76800,
3797c478bd9Sstevel@tonic-gate 	"115200", B115200, 115200,
3807c478bd9Sstevel@tonic-gate 	"153600", B153600, 153600,
3817c478bd9Sstevel@tonic-gate 	"230400", B230400, 230400,
3827c478bd9Sstevel@tonic-gate 	"307200", B307200, 307200,
3837c478bd9Sstevel@tonic-gate 	"460800", B460800, 460800,
384*de81e71eSTim Marsland 	"921600", B921600, 921600,
3857c478bd9Sstevel@tonic-gate 	0,
3867c478bd9Sstevel@tonic-gate };
3877c478bd9Sstevel@tonic-gate 
3887c478bd9Sstevel@tonic-gate signed char Erase_char;		/* new erase character */
3897c478bd9Sstevel@tonic-gate char	Kill_char;		/* new kill character */
3907c478bd9Sstevel@tonic-gate char	Intr_char;		/* new interrupt character */
3917c478bd9Sstevel@tonic-gate char	Specialerase;	/* set => Erase_char only on terminals with backspace */
3927c478bd9Sstevel@tonic-gate 
3937c478bd9Sstevel@tonic-gate char	Ttyid = NOTTY;		/* terminal identifier */
3947c478bd9Sstevel@tonic-gate char	*TtyType;		/* type of terminal */
3957c478bd9Sstevel@tonic-gate char	*DefType;		/* default type if none other computed */
3967c478bd9Sstevel@tonic-gate char	*NewType;		/* mapping identifier based on old flags */
3977c478bd9Sstevel@tonic-gate int	Mapped;			/* mapping has been specified */
3987c478bd9Sstevel@tonic-gate int	Dash_u;			/* don't update htmp */
3997c478bd9Sstevel@tonic-gate int	Dash_h;			/* don't read htmp */
4007c478bd9Sstevel@tonic-gate int	DoSetenv;		/* output setenv commands */
4017c478bd9Sstevel@tonic-gate int	BeQuiet;		/* be quiet */
4027c478bd9Sstevel@tonic-gate int	NoInit;			/* don't output initialization string */
4037c478bd9Sstevel@tonic-gate int	IsReset;		/* invoked as reset */
4047c478bd9Sstevel@tonic-gate int	Report;			/* report current type */
4057c478bd9Sstevel@tonic-gate int	Ureport;		/* report to user */
4067c478bd9Sstevel@tonic-gate int	RepOnly;		/* report only */
4077c478bd9Sstevel@tonic-gate int	CmndLine;		/* output full command lines (-s option) */
4087c478bd9Sstevel@tonic-gate int	Ask;			/* ask user for termtype */
4097c478bd9Sstevel@tonic-gate int	DoVirtTerm = YES;	/* Set up a virtual terminal */
4107c478bd9Sstevel@tonic-gate int	PadBaud;		/* Min rate of padding needed */
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate #define	CAPBUFSIZ	1024
4137c478bd9Sstevel@tonic-gate char	Capbuf[CAPBUFSIZ];	/* line from /etc/termcap for this TtyType */
4147c478bd9Sstevel@tonic-gate char	*Ttycap;		/* termcap line from termcap or environ */
4157c478bd9Sstevel@tonic-gate 
4167c478bd9Sstevel@tonic-gate char	Aliasbuf[128];
4177c478bd9Sstevel@tonic-gate char	*Alias[16];
4187c478bd9Sstevel@tonic-gate 
4197c478bd9Sstevel@tonic-gate extern char *strcpy();
4207c478bd9Sstevel@tonic-gate extern char *index();
4217c478bd9Sstevel@tonic-gate 
4227c478bd9Sstevel@tonic-gate struct delay
4237c478bd9Sstevel@tonic-gate {
4247c478bd9Sstevel@tonic-gate 	int	d_delay;
4257c478bd9Sstevel@tonic-gate 	int	d_bits;
4267c478bd9Sstevel@tonic-gate };
4277c478bd9Sstevel@tonic-gate 
4287c478bd9Sstevel@tonic-gate #include	"tset.delays.h"
4297c478bd9Sstevel@tonic-gate 
4307c478bd9Sstevel@tonic-gate struct termio	mode;
4317c478bd9Sstevel@tonic-gate struct termio	oldmode;
4327c478bd9Sstevel@tonic-gate struct termios	modes;
4337c478bd9Sstevel@tonic-gate struct termios	oldmodes;
4347c478bd9Sstevel@tonic-gate int		istermios;
4357c478bd9Sstevel@tonic-gate 
436cc6c5292Schin void reportek(char *, char, char, char);
437cc6c5292Schin void setdelay(char *, struct delay [], tcflag_t, tcflag_t *);
438cc6c5292Schin void prs(char *);
439cc6c5292Schin void prc(char);
440cc6c5292Schin void flush(void);
441cc6c5292Schin void cat(char *);
442cc6c5292Schin void bmove(char *, char *, int);
443cc6c5292Schin void makealias(char *);
444cc6c5292Schin void wrtermcap(char *);
445cc6c5292Schin void fatal(char *, char *);
4467c478bd9Sstevel@tonic-gate char reset();			/* Routine for checking&resetting chars */
4477c478bd9Sstevel@tonic-gate 
448cc6c5292Schin int
main(int argc,char * argv[])449cc6c5292Schin main(int argc, char *argv[])
4507c478bd9Sstevel@tonic-gate {
4517c478bd9Sstevel@tonic-gate 	char		buf[CAPBUFSIZ];
4527c478bd9Sstevel@tonic-gate 	char		termbuf[32];
4537c478bd9Sstevel@tonic-gate 	auto char	*bufp;
454cc6c5292Schin 	char		*p;
4557c478bd9Sstevel@tonic-gate 	char		*command;
456cc6c5292Schin 	int		i;
4577c478bd9Sstevel@tonic-gate 	int		Break;
4587c478bd9Sstevel@tonic-gate 	int		Not;
4597c478bd9Sstevel@tonic-gate 	char		*nextarg();
4607c478bd9Sstevel@tonic-gate 	char		*mapped();
4617c478bd9Sstevel@tonic-gate 	extern char	*rindex();
4627c478bd9Sstevel@tonic-gate 	struct winsize	win;
4637c478bd9Sstevel@tonic-gate 	extern char	*getenv();
4647c478bd9Sstevel@tonic-gate 	extern char	*tgetstr();
4657c478bd9Sstevel@tonic-gate 	char		bs_char;
4667c478bd9Sstevel@tonic-gate 	int		csh;
4677c478bd9Sstevel@tonic-gate 	int		settle = NO;
4687c478bd9Sstevel@tonic-gate 	void		setmode();
4697c478bd9Sstevel@tonic-gate 	extern char	PC;
4707c478bd9Sstevel@tonic-gate 	extern short	ospeed;
4717c478bd9Sstevel@tonic-gate 
4727c478bd9Sstevel@tonic-gate 	if ((istermios = ioctl(FILEDES, TCGETS, (char *)&modes)) < 0) {
473*de81e71eSTim Marsland 		if (ioctl(FILEDES, TCGETA, (char *)&mode) < 0) {
4747c478bd9Sstevel@tonic-gate 			prs("Not a terminal\n");
4757c478bd9Sstevel@tonic-gate 			exit(1);
4767c478bd9Sstevel@tonic-gate 		}
477*de81e71eSTim Marsland 		bmove((char *)&mode, (char *)&oldmode, sizeof (mode));
4787c478bd9Sstevel@tonic-gate 		modes.c_lflag = oldmodes.c_lflag = mode.c_lflag;
4797c478bd9Sstevel@tonic-gate 		modes.c_oflag = oldmodes.c_oflag = mode.c_oflag;
4807c478bd9Sstevel@tonic-gate 		modes.c_iflag = oldmodes.c_iflag = mode.c_iflag;
4817c478bd9Sstevel@tonic-gate 		modes.c_cflag = oldmodes.c_cflag = mode.c_cflag;
4827c478bd9Sstevel@tonic-gate 		for (i = 0; i < NCC; i++)
4837c478bd9Sstevel@tonic-gate 			modes.c_cc[i] = oldmodes.c_cc[i] = mode.c_cc[i];
4847c478bd9Sstevel@tonic-gate 	} else
485*de81e71eSTim Marsland 		bmove((char *)&modes, (char *)&oldmodes, sizeof (modes));
4867c478bd9Sstevel@tonic-gate 	ospeed = cfgetospeed(&modes);
4877c478bd9Sstevel@tonic-gate 	(void) signal(SIGINT, setmode);
4887c478bd9Sstevel@tonic-gate 	(void) signal(SIGQUIT, setmode);
4897c478bd9Sstevel@tonic-gate 	(void) signal(SIGTERM, setmode);
4907c478bd9Sstevel@tonic-gate 
4917c478bd9Sstevel@tonic-gate 	if (command = rindex(argv[0], '/'))
4927c478bd9Sstevel@tonic-gate 		command++;
4937c478bd9Sstevel@tonic-gate 	else
4947c478bd9Sstevel@tonic-gate 		command = argv[0];
495*de81e71eSTim Marsland 	if (sequal(command, "reset")) {
4967c478bd9Sstevel@tonic-gate 		/*
4977c478bd9Sstevel@tonic-gate 		 * Reset the teletype mode bits to a sensible state.
4987c478bd9Sstevel@tonic-gate 		 * Copied from the program by Kurt Shoens & Mark Horton.
4997c478bd9Sstevel@tonic-gate 		 * Very useful after crapping out in raw.
5007c478bd9Sstevel@tonic-gate 		 */
5017c478bd9Sstevel@tonic-gate 		if ((istermios = ioctl(FILEDES, TCGETS, (char *)&modes)) < 0) {
5027c478bd9Sstevel@tonic-gate 			(void) ioctl(FILEDES, TCGETA, (char *)&mode);
5037c478bd9Sstevel@tonic-gate 			modes.c_lflag = mode.c_lflag;
5047c478bd9Sstevel@tonic-gate 			modes.c_oflag = mode.c_oflag;
5057c478bd9Sstevel@tonic-gate 			modes.c_iflag = mode.c_iflag;
5067c478bd9Sstevel@tonic-gate 			modes.c_cflag = mode.c_cflag;
5077c478bd9Sstevel@tonic-gate 			for (i = 0; i < NCC; i++)
5087c478bd9Sstevel@tonic-gate 				modes.c_cc[i] = mode.c_cc[i];
5097c478bd9Sstevel@tonic-gate 		}
5107c478bd9Sstevel@tonic-gate 		curerase = reset(curerase, CERASE);
5117c478bd9Sstevel@tonic-gate 		curkill = reset(curkill, CKILL);
5127c478bd9Sstevel@tonic-gate 		curintr = reset(curintr, CINTR);
5137c478bd9Sstevel@tonic-gate 		modes.c_cc[VQUIT] = reset(modes.c_cc[VQUIT], CQUIT);
5147c478bd9Sstevel@tonic-gate 		modes.c_cc[VEOF] = reset(modes.c_cc[VEOF], CEOF);
5157c478bd9Sstevel@tonic-gate 
5167c478bd9Sstevel@tonic-gate 		modes.c_iflag |= (BRKINT|ISTRIP|ICRNL|IXON);
5177c478bd9Sstevel@tonic-gate 		modes.c_iflag &= ~(IGNBRK|PARMRK|INPCK|INLCR|IGNCR|IUCLC|IXOFF);
5187c478bd9Sstevel@tonic-gate 		modes.c_oflag |= (OPOST|ONLCR);
5197c478bd9Sstevel@tonic-gate 		modes.c_oflag &= ~(OLCUC|OCRNL|ONOCR|ONLRET|OFILL|OFDEL|
5207c478bd9Sstevel@tonic-gate 		    NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
5217c478bd9Sstevel@tonic-gate 		modes.c_cflag |= (CS7|CREAD);
5227c478bd9Sstevel@tonic-gate 		modes.c_cflag &= ~(PARODD|CLOCAL);
5237c478bd9Sstevel@tonic-gate 		modes.c_lflag |= (ISIG|ICANON|ECHO|ECHOK);
5247c478bd9Sstevel@tonic-gate 		modes.c_lflag &= ~(XCASE|ECHONL|NOFLSH);
5257c478bd9Sstevel@tonic-gate 		if (istermios < 0) {
5267c478bd9Sstevel@tonic-gate 			mode.c_lflag = modes.c_lflag;
5277c478bd9Sstevel@tonic-gate 			mode.c_oflag = modes.c_oflag;
5287c478bd9Sstevel@tonic-gate 			mode.c_iflag = modes.c_iflag;
5297c478bd9Sstevel@tonic-gate 			mode.c_cflag = modes.c_cflag;
5307c478bd9Sstevel@tonic-gate 			for (i = 0; i < NCC; i++)
5317c478bd9Sstevel@tonic-gate 				mode.c_cc[i] = modes.c_cc[i];
5327c478bd9Sstevel@tonic-gate 			(void) ioctl(FILEDES, TCSETAW, (char *)&mode);
5337c478bd9Sstevel@tonic-gate 		} else
5347c478bd9Sstevel@tonic-gate 			(void) ioctl(FILEDES, TCSETSW, (char *)&modes);
5357c478bd9Sstevel@tonic-gate 		Dash_u = YES;
5367c478bd9Sstevel@tonic-gate 		BeQuiet = YES;
5377c478bd9Sstevel@tonic-gate 		IsReset = YES;
538*de81e71eSTim Marsland 	} else if (argc == 2 && sequal(argv[1], "-")) {
5397c478bd9Sstevel@tonic-gate 		RepOnly = YES;
5407c478bd9Sstevel@tonic-gate 		Dash_u = YES;
5417c478bd9Sstevel@tonic-gate 	}
5427c478bd9Sstevel@tonic-gate 	argc--;
5437c478bd9Sstevel@tonic-gate 
5447c478bd9Sstevel@tonic-gate 	/* scan argument list and collect flags */
545*de81e71eSTim Marsland 	while (--argc >= 0) {
5467c478bd9Sstevel@tonic-gate 		p = *++argv;
547*de81e71eSTim Marsland 		if (*p == '-') {
5487c478bd9Sstevel@tonic-gate 			if (*++p == NULL)
5497c478bd9Sstevel@tonic-gate 				Report = YES; /* report current terminal type */
550*de81e71eSTim Marsland 			else
551*de81e71eSTim Marsland 				while (*p)
552*de81e71eSTim Marsland 					switch (*p++) {
5537c478bd9Sstevel@tonic-gate 
5547c478bd9Sstevel@tonic-gate 			case 'r':	/* report to user */
5557c478bd9Sstevel@tonic-gate 				Ureport = YES;
5567c478bd9Sstevel@tonic-gate 				continue;
5577c478bd9Sstevel@tonic-gate 
558*de81e71eSTim Marsland 			case 'E':
559*de81e71eSTim Marsland 				/* special erase: operate on all but TTY33 */
5607c478bd9Sstevel@tonic-gate 				Specialerase = YES;
5617c478bd9Sstevel@tonic-gate 				/* explicit fall-through to -e case */
5627c478bd9Sstevel@tonic-gate 
5637c478bd9Sstevel@tonic-gate 			case 'e':	/* erase character */
5647c478bd9Sstevel@tonic-gate 				if (*p == NULL)
5657c478bd9Sstevel@tonic-gate 					Erase_char = -1;
566*de81e71eSTim Marsland 				else {
5677c478bd9Sstevel@tonic-gate 					if (*p == '^' && p[1] != NULL)
5687c478bd9Sstevel@tonic-gate 						if (*++p == '?')
5697c478bd9Sstevel@tonic-gate 							Erase_char = '\177';
5707c478bd9Sstevel@tonic-gate 						else
5717c478bd9Sstevel@tonic-gate 							Erase_char = CNTL(*p);
5727c478bd9Sstevel@tonic-gate 					else
5737c478bd9Sstevel@tonic-gate 						Erase_char = *p;
5747c478bd9Sstevel@tonic-gate 					p++;
5757c478bd9Sstevel@tonic-gate 				}
5767c478bd9Sstevel@tonic-gate 				continue;
5777c478bd9Sstevel@tonic-gate 
5787c478bd9Sstevel@tonic-gate 			case 'i':	/* interrupt character */
5797c478bd9Sstevel@tonic-gate 				if (*p == NULL)
5807c478bd9Sstevel@tonic-gate 					Intr_char = CNTL('C');
581*de81e71eSTim Marsland 				else {
5827c478bd9Sstevel@tonic-gate 					if (*p == '^' && p[1] != NULL)
5837c478bd9Sstevel@tonic-gate 						if (*++p == '?')
5847c478bd9Sstevel@tonic-gate 							Intr_char = '\177';
5857c478bd9Sstevel@tonic-gate 						else
5867c478bd9Sstevel@tonic-gate 							Intr_char = CNTL(*p);
5877c478bd9Sstevel@tonic-gate 					else
5887c478bd9Sstevel@tonic-gate 						Intr_char = *p;
5897c478bd9Sstevel@tonic-gate 					p++;
5907c478bd9Sstevel@tonic-gate 				}
5917c478bd9Sstevel@tonic-gate 				continue;
5927c478bd9Sstevel@tonic-gate 
5937c478bd9Sstevel@tonic-gate 			case 'k':	/* kill character */
5947c478bd9Sstevel@tonic-gate 				if (*p == NULL)
5957c478bd9Sstevel@tonic-gate 					Kill_char = CNTL('U');
596*de81e71eSTim Marsland 				else {
5977c478bd9Sstevel@tonic-gate 					if (*p == '^' && p[1] != NULL)
5987c478bd9Sstevel@tonic-gate 						if (*++p == '?')
5997c478bd9Sstevel@tonic-gate 							Kill_char = '\177';
6007c478bd9Sstevel@tonic-gate 						else
6017c478bd9Sstevel@tonic-gate 							Kill_char = CNTL(*p);
6027c478bd9Sstevel@tonic-gate 					else
6037c478bd9Sstevel@tonic-gate 						Kill_char = *p;
6047c478bd9Sstevel@tonic-gate 					p++;
6057c478bd9Sstevel@tonic-gate 				}
6067c478bd9Sstevel@tonic-gate 				continue;
6077c478bd9Sstevel@tonic-gate 
6087c478bd9Sstevel@tonic-gate #ifdef OLDFLAGS
6097c478bd9Sstevel@tonic-gate #ifdef	OLDDIALUP
6107c478bd9Sstevel@tonic-gate 			case 'd':	/* dialup type */
6117c478bd9Sstevel@tonic-gate 				NewType = DIALUP;
6127c478bd9Sstevel@tonic-gate 				goto mapold;
6137c478bd9Sstevel@tonic-gate #endif
6147c478bd9Sstevel@tonic-gate 
6157c478bd9Sstevel@tonic-gate #ifdef OLDPLUGBOARD
6167c478bd9Sstevel@tonic-gate 			case 'p':	/* plugboard type */
6177c478bd9Sstevel@tonic-gate 				NewType = PLUGBOARD;
6187c478bd9Sstevel@tonic-gate 				goto mapold;
6197c478bd9Sstevel@tonic-gate #endif
6207c478bd9Sstevel@tonic-gate 
6217c478bd9Sstevel@tonic-gate #ifdef OLDARPANET
6227c478bd9Sstevel@tonic-gate 			case 'a':	/* arpanet type */
6237c478bd9Sstevel@tonic-gate 				Newtype = ARPANET;
6247c478bd9Sstevel@tonic-gate 				goto mapold;
6257c478bd9Sstevel@tonic-gate #endif
6267c478bd9Sstevel@tonic-gate 
6277c478bd9Sstevel@tonic-gate mapold:				Map->Ident = NewType;
6287c478bd9Sstevel@tonic-gate 				Map->Test = ALL;
629*de81e71eSTim Marsland 				if (*p == NULL) {
6307c478bd9Sstevel@tonic-gate 					p = nextarg(argc--, argv++);
6317c478bd9Sstevel@tonic-gate 				}
6327c478bd9Sstevel@tonic-gate 				Map->Type = p;
6337c478bd9Sstevel@tonic-gate 				Map++;
6347c478bd9Sstevel@tonic-gate 				Mapped = YES;
6357c478bd9Sstevel@tonic-gate 				p = "";
6367c478bd9Sstevel@tonic-gate 				continue;
6377c478bd9Sstevel@tonic-gate #endif
6387c478bd9Sstevel@tonic-gate 
6397c478bd9Sstevel@tonic-gate 			case 'm':	/* map identifier to type */
640*de81e71eSTim Marsland 				/*
641*de81e71eSTim Marsland 				 * This code is very loose. Almost no
642*de81e71eSTim Marsland 				 * syntax checking is done!! However,
643*de81e71eSTim Marsland 				 * illegal syntax will only produce
644*de81e71eSTim Marsland 				 * weird results.
6457c478bd9Sstevel@tonic-gate 				 */
646*de81e71eSTim Marsland 				if (*p == NULL) {
6477c478bd9Sstevel@tonic-gate 					p = nextarg(argc--, argv++);
6487c478bd9Sstevel@tonic-gate 				}
649*de81e71eSTim Marsland 				if (isalnum(*p)) {
6507c478bd9Sstevel@tonic-gate 					Map->Ident = p;	/* identifier */
6517c478bd9Sstevel@tonic-gate 					while (isalnum(*p)) p++;
6527c478bd9Sstevel@tonic-gate 				}
6537c478bd9Sstevel@tonic-gate 				else
6547c478bd9Sstevel@tonic-gate 					Map->Ident = "";
6557c478bd9Sstevel@tonic-gate 				Break = NO;
6567c478bd9Sstevel@tonic-gate 				Not = NO;
657*de81e71eSTim Marsland 				while (!Break)
658*de81e71eSTim Marsland 					switch (*p) {
6597c478bd9Sstevel@tonic-gate 					case NULL:
6607c478bd9Sstevel@tonic-gate 						p = nextarg(argc--, argv++);
6617c478bd9Sstevel@tonic-gate 						continue;
6627c478bd9Sstevel@tonic-gate 
6637c478bd9Sstevel@tonic-gate 					case ':':	/* mapped type */
6647c478bd9Sstevel@tonic-gate 						*p++ = NULL;
6657c478bd9Sstevel@tonic-gate 						Break = YES;
6667c478bd9Sstevel@tonic-gate 						continue;
6677c478bd9Sstevel@tonic-gate 
6687c478bd9Sstevel@tonic-gate 					case '>':	/* conditional */
6697c478bd9Sstevel@tonic-gate 						Map->Test |= GT;
6707c478bd9Sstevel@tonic-gate 						*p++ = NULL;
6717c478bd9Sstevel@tonic-gate 						continue;
6727c478bd9Sstevel@tonic-gate 
6737c478bd9Sstevel@tonic-gate 					case '<':	/* conditional */
6747c478bd9Sstevel@tonic-gate 						Map->Test |= LT;
6757c478bd9Sstevel@tonic-gate 						*p++ = NULL;
6767c478bd9Sstevel@tonic-gate 						continue;
6777c478bd9Sstevel@tonic-gate 
6787c478bd9Sstevel@tonic-gate 					case '=':	/* conditional */
6797c478bd9Sstevel@tonic-gate 					case '@':
6807c478bd9Sstevel@tonic-gate 						Map->Test |= EQ;
6817c478bd9Sstevel@tonic-gate 						*p++ = NULL;
6827c478bd9Sstevel@tonic-gate 						continue;
6837c478bd9Sstevel@tonic-gate 
6847c478bd9Sstevel@tonic-gate 					case '!':	/* invert conditions */
6857c478bd9Sstevel@tonic-gate 						Not = ~Not;
6867c478bd9Sstevel@tonic-gate 						*p++ = NULL;
6877c478bd9Sstevel@tonic-gate 						continue;
6887c478bd9Sstevel@tonic-gate 
6897c478bd9Sstevel@tonic-gate 					case 'B':	/* Baud rate */
6907c478bd9Sstevel@tonic-gate 						p++;
6917c478bd9Sstevel@tonic-gate 						/* intentional fallthru */
6927c478bd9Sstevel@tonic-gate 					default:
693*de81e71eSTim Marsland 						if (isdigit(*p) || *p == 'e') {
694*de81e71eSTim Marsland 							Map->Speed =
695*de81e71eSTim Marsland 							    baudrate(p);
696*de81e71eSTim Marsland 							while (isalnum(*p) ||
697*de81e71eSTim Marsland 							    *p == '.')
6987c478bd9Sstevel@tonic-gate 								p++;
699*de81e71eSTim Marsland 						} else
7007c478bd9Sstevel@tonic-gate 							Break = YES;
7017c478bd9Sstevel@tonic-gate 						continue;
7027c478bd9Sstevel@tonic-gate 				}
703*de81e71eSTim Marsland 				if (Not) {	/* invert sense of test */
7047c478bd9Sstevel@tonic-gate 					Map->Test = (~(Map->Test))&ALL;
7057c478bd9Sstevel@tonic-gate 				}
706*de81e71eSTim Marsland 				if (*p == NULL) {
7077c478bd9Sstevel@tonic-gate 					p = nextarg(argc--, argv++);
7087c478bd9Sstevel@tonic-gate 				}
7097c478bd9Sstevel@tonic-gate 				Map->Type = p;
7107c478bd9Sstevel@tonic-gate 				p = "";
7117c478bd9Sstevel@tonic-gate 				Map++;
7127c478bd9Sstevel@tonic-gate 				Mapped = YES;
7137c478bd9Sstevel@tonic-gate 				continue;
7147c478bd9Sstevel@tonic-gate 
7157c478bd9Sstevel@tonic-gate 			case 'h':	/* don't get type from htmp or env */
7167c478bd9Sstevel@tonic-gate 				Dash_h = YES;
7177c478bd9Sstevel@tonic-gate 				continue;
7187c478bd9Sstevel@tonic-gate 
7197c478bd9Sstevel@tonic-gate 			case 'u':	/* don't update htmp */
7207c478bd9Sstevel@tonic-gate 				Dash_u = YES;
7217c478bd9Sstevel@tonic-gate 				continue;
7227c478bd9Sstevel@tonic-gate 
7237c478bd9Sstevel@tonic-gate 			case 's':	/* output setenv commands */
7247c478bd9Sstevel@tonic-gate 				DoSetenv = YES;
7257c478bd9Sstevel@tonic-gate 				CmndLine = YES;
7267c478bd9Sstevel@tonic-gate 				continue;
7277c478bd9Sstevel@tonic-gate 
7287c478bd9Sstevel@tonic-gate 			case 'S':	/* output setenv strings */
7297c478bd9Sstevel@tonic-gate 				DoSetenv = YES;
7307c478bd9Sstevel@tonic-gate 				CmndLine = NO;
7317c478bd9Sstevel@tonic-gate 				continue;
7327c478bd9Sstevel@tonic-gate 
7337c478bd9Sstevel@tonic-gate 			case 'Q':	/* be quiet */
7347c478bd9Sstevel@tonic-gate 				BeQuiet = YES;
7357c478bd9Sstevel@tonic-gate 				continue;
7367c478bd9Sstevel@tonic-gate 
7377c478bd9Sstevel@tonic-gate 			case 'I':	/* no initialization */
7387c478bd9Sstevel@tonic-gate 				NoInit = YES;
7397c478bd9Sstevel@tonic-gate 				continue;
7407c478bd9Sstevel@tonic-gate 
7417c478bd9Sstevel@tonic-gate 			case 'A':	/* Ask user */
7427c478bd9Sstevel@tonic-gate 				Ask = YES;
7437c478bd9Sstevel@tonic-gate 				continue;
7447c478bd9Sstevel@tonic-gate 
7457c478bd9Sstevel@tonic-gate 			case 'v':	/* no virtual terminal */
7467c478bd9Sstevel@tonic-gate 				DoVirtTerm = NO;
7477c478bd9Sstevel@tonic-gate 				continue;
7487c478bd9Sstevel@tonic-gate 
7497c478bd9Sstevel@tonic-gate 			default:
7507c478bd9Sstevel@tonic-gate 				*p-- = NULL;
7517c478bd9Sstevel@tonic-gate 				fatal("Bad flag -", p);
7527c478bd9Sstevel@tonic-gate 			}
753*de81e71eSTim Marsland 		} else {
7547c478bd9Sstevel@tonic-gate 			/* terminal type */
7557c478bd9Sstevel@tonic-gate 			DefType = p;
7567c478bd9Sstevel@tonic-gate 		}
7577c478bd9Sstevel@tonic-gate 	}
7587c478bd9Sstevel@tonic-gate 
759*de81e71eSTim Marsland 	if (DefType) {
760*de81e71eSTim Marsland 		if (Mapped) {
7617c478bd9Sstevel@tonic-gate 			Map->Ident = "";	/* means "map any type" */
7627c478bd9Sstevel@tonic-gate 			Map->Test = ALL;	/* at all baud rates */
7637c478bd9Sstevel@tonic-gate 			Map->Type = DefType;	/* to the default type */
764*de81e71eSTim Marsland 		} else
7657c478bd9Sstevel@tonic-gate 			TtyType = DefType;
7667c478bd9Sstevel@tonic-gate 	}
7677c478bd9Sstevel@tonic-gate 
7687c478bd9Sstevel@tonic-gate 	/*
7697c478bd9Sstevel@tonic-gate 	 * Get rid of $TERMCAP, if it's there, so we get a real
7707c478bd9Sstevel@tonic-gate 	 * entry from /etc/termcap.  This prevents us from being
7717c478bd9Sstevel@tonic-gate 	 * fooled by out of date stuff in the environment, and
7727c478bd9Sstevel@tonic-gate 	 * makes tabs work right on CB/Unix.
7737c478bd9Sstevel@tonic-gate 	 */
7747c478bd9Sstevel@tonic-gate 	bufp = getenv("TERMCAP");
7757c478bd9Sstevel@tonic-gate 	if (bufp && *bufp != '/')
7767c478bd9Sstevel@tonic-gate 		(void) strcpy(bufp-8, "NOTHING"); /* overwrite only "TERMCAP" */
7777c478bd9Sstevel@tonic-gate 	/* get current idea of terminal type from environment */
7787c478bd9Sstevel@tonic-gate 	if (!Dash_h && TtyType == 0)
7797c478bd9Sstevel@tonic-gate 		TtyType = getenv("TERM");
7807c478bd9Sstevel@tonic-gate 
7817c478bd9Sstevel@tonic-gate 	if (!RepOnly && Ttyid == NOTTY && (TtyType == 0 || !Dash_h))
7827c478bd9Sstevel@tonic-gate 		Ttyid = ttyname(FILEDES);
7837c478bd9Sstevel@tonic-gate 
7847c478bd9Sstevel@tonic-gate 	/* If still undefined, use DEFTYPE */
785*de81e71eSTim Marsland 	if (TtyType == 0) {
7867c478bd9Sstevel@tonic-gate 		TtyType = DEFTYPE;
7877c478bd9Sstevel@tonic-gate 	}
7887c478bd9Sstevel@tonic-gate 
7897c478bd9Sstevel@tonic-gate 	/* check for dialup or other mapping */
790*de81e71eSTim Marsland 	if (Mapped) {
7917c478bd9Sstevel@tonic-gate 		if (!(Alias[0] && isalias(TtyType)))
7927c478bd9Sstevel@tonic-gate 			if (tgetent(Capbuf, TtyType) > 0)
7937c478bd9Sstevel@tonic-gate 				makealias(Capbuf);
7947c478bd9Sstevel@tonic-gate 		TtyType = mapped(TtyType);
7957c478bd9Sstevel@tonic-gate 	}
7967c478bd9Sstevel@tonic-gate 
7977c478bd9Sstevel@tonic-gate 	/* TtyType now contains a pointer to the type of the terminal */
7987c478bd9Sstevel@tonic-gate 	/* If the first character is '?', ask the user */
799*de81e71eSTim Marsland 	if (TtyType[0] == '?') {
8007c478bd9Sstevel@tonic-gate 		Ask = YES;
8017c478bd9Sstevel@tonic-gate 		TtyType++;
8027c478bd9Sstevel@tonic-gate 		if (TtyType[0] == '\0')
8037c478bd9Sstevel@tonic-gate 			TtyType = DEFTYPE;
8047c478bd9Sstevel@tonic-gate 	}
805*de81e71eSTim Marsland 	if (Ask) {
8067c478bd9Sstevel@tonic-gate ask:
8077c478bd9Sstevel@tonic-gate 		prs("TERM = (");
8087c478bd9Sstevel@tonic-gate 		prs(TtyType);
8097c478bd9Sstevel@tonic-gate 		prs(") ");
8107c478bd9Sstevel@tonic-gate 		flush();
8117c478bd9Sstevel@tonic-gate 
8127c478bd9Sstevel@tonic-gate 		/* read the terminal.  If not empty, set type */
813*de81e71eSTim Marsland 		i = read(2, termbuf, sizeof (termbuf) - 1);
814*de81e71eSTim Marsland 		if (i > 0) {
8157c478bd9Sstevel@tonic-gate 			if (termbuf[i - 1] == '\n')
8167c478bd9Sstevel@tonic-gate 				i--;
8177c478bd9Sstevel@tonic-gate 			termbuf[i] = '\0';
8187c478bd9Sstevel@tonic-gate 			if (termbuf[0] != '\0')
8197c478bd9Sstevel@tonic-gate 				TtyType = termbuf;
8207c478bd9Sstevel@tonic-gate 		}
8217c478bd9Sstevel@tonic-gate 	}
8227c478bd9Sstevel@tonic-gate 
8237c478bd9Sstevel@tonic-gate 	/* get terminal capabilities */
8247c478bd9Sstevel@tonic-gate 	if (!(Alias[0] && isalias(TtyType))) {
825*de81e71eSTim Marsland 		switch (tgetent(Capbuf, TtyType)) {
8267c478bd9Sstevel@tonic-gate 		case -1:
8277c478bd9Sstevel@tonic-gate 			prs("Cannot find termcap\n");
8287c478bd9Sstevel@tonic-gate 			flush();
8297c478bd9Sstevel@tonic-gate 			exit(-1);
8307c478bd9Sstevel@tonic-gate 
8317c478bd9Sstevel@tonic-gate 		case 0:
8327c478bd9Sstevel@tonic-gate 			prs("Type ");
8337c478bd9Sstevel@tonic-gate 			prs(TtyType);
8347c478bd9Sstevel@tonic-gate 			prs(" unknown\n");
8357c478bd9Sstevel@tonic-gate 			flush();
836*de81e71eSTim Marsland 			if (DoSetenv) {
8377c478bd9Sstevel@tonic-gate 				TtyType = DEFTYPE;
8387c478bd9Sstevel@tonic-gate 				Alias[0] = '\0';
8397c478bd9Sstevel@tonic-gate 				goto ask;
840*de81e71eSTim Marsland 			} else
8417c478bd9Sstevel@tonic-gate 				exit(1);
8427c478bd9Sstevel@tonic-gate 		}
8437c478bd9Sstevel@tonic-gate 	}
8447c478bd9Sstevel@tonic-gate 	Ttycap = Capbuf;
8457c478bd9Sstevel@tonic-gate 
846*de81e71eSTim Marsland 	if (!RepOnly) {
8477c478bd9Sstevel@tonic-gate 		/* determine erase and kill characters */
8487c478bd9Sstevel@tonic-gate 		if (Specialerase && !tgetflag("bs"))
8497c478bd9Sstevel@tonic-gate 			Erase_char = 0;
8507c478bd9Sstevel@tonic-gate 		bufp = buf;
8517c478bd9Sstevel@tonic-gate 		p = tgetstr("kb", &bufp);
8527c478bd9Sstevel@tonic-gate 		if (p == NULL || p[1] != '\0')
8537c478bd9Sstevel@tonic-gate 			p = tgetstr("bc", &bufp);
8547c478bd9Sstevel@tonic-gate 		if (p != NULL && p[1] == '\0')
8557c478bd9Sstevel@tonic-gate 			bs_char = p[0];
8567c478bd9Sstevel@tonic-gate 		else if (tgetflag("bs"))
8577c478bd9Sstevel@tonic-gate 			bs_char = BACKSPACE;
8587c478bd9Sstevel@tonic-gate 		else
8597c478bd9Sstevel@tonic-gate 			bs_char = 0;
8607c478bd9Sstevel@tonic-gate 		/*
8617c478bd9Sstevel@tonic-gate 		 * The next statement can't be fixed, because now users
8627c478bd9Sstevel@tonic-gate 		 * depend on keeping their erase character as DEL if the
8637c478bd9Sstevel@tonic-gate 		 * system set it there.  People who want backspace have
8647c478bd9Sstevel@tonic-gate 		 * to say tset -e.
8657c478bd9Sstevel@tonic-gate 		 */
866*de81e71eSTim Marsland 		if (Erase_char == 0 && !tgetflag("os") &&
867*de81e71eSTim Marsland 		    curerase == OLDERASE) {
8687c478bd9Sstevel@tonic-gate 			if (tgetflag("bs") || bs_char != 0)
8697c478bd9Sstevel@tonic-gate 				Erase_char = -1;
8707c478bd9Sstevel@tonic-gate 		}
8717c478bd9Sstevel@tonic-gate 		if (Erase_char < 0)
8727c478bd9Sstevel@tonic-gate 			Erase_char = (bs_char != 0) ? bs_char : BACKSPACE;
8737c478bd9Sstevel@tonic-gate 
8747c478bd9Sstevel@tonic-gate 		if (curerase == 0)
8757c478bd9Sstevel@tonic-gate 			curerase = CERASE;
8767c478bd9Sstevel@tonic-gate 		if (Erase_char != 0)
8777c478bd9Sstevel@tonic-gate 			curerase = Erase_char;
8787c478bd9Sstevel@tonic-gate 
8797c478bd9Sstevel@tonic-gate 		if (curintr == 0)
8807c478bd9Sstevel@tonic-gate 			curintr = CINTR;
8817c478bd9Sstevel@tonic-gate 		if (Intr_char != 0)
8827c478bd9Sstevel@tonic-gate 			curintr = Intr_char;
8837c478bd9Sstevel@tonic-gate 
8847c478bd9Sstevel@tonic-gate 		if (curkill == 0)
8857c478bd9Sstevel@tonic-gate 			curkill = CKILL;
8867c478bd9Sstevel@tonic-gate 		if (Kill_char != 0)
8877c478bd9Sstevel@tonic-gate 			curkill = Kill_char;
8887c478bd9Sstevel@tonic-gate 
8897c478bd9Sstevel@tonic-gate 		/* set modes */
8907c478bd9Sstevel@tonic-gate 		PadBaud = tgetnum("pb");	/* OK if fails */
8917c478bd9Sstevel@tonic-gate 		for (i = 0; speeds[i].string; i++)
8927c478bd9Sstevel@tonic-gate 			if (speeds[i].baudrate == PadBaud) {
8937c478bd9Sstevel@tonic-gate 				PadBaud = speeds[i].speed;
8947c478bd9Sstevel@tonic-gate 				break;
8957c478bd9Sstevel@tonic-gate 			}
8967c478bd9Sstevel@tonic-gate 		setdelay("dC", CRdelay, CRbits, &modes.c_oflag);
8977c478bd9Sstevel@tonic-gate 		setdelay("dN", NLdelay, NLbits, &modes.c_oflag);
8987c478bd9Sstevel@tonic-gate 		setdelay("dB", BSdelay, BSbits, &modes.c_oflag);
8997c478bd9Sstevel@tonic-gate 		setdelay("dF", FFdelay, FFbits, &modes.c_oflag);
9007c478bd9Sstevel@tonic-gate 		setdelay("dT", TBdelay, TBbits, &modes.c_oflag);
9017c478bd9Sstevel@tonic-gate 		setdelay("dV", VTdelay, VTbits, &modes.c_oflag);
9027c478bd9Sstevel@tonic-gate 
9037c478bd9Sstevel@tonic-gate 		if (tgetflag("UC") || (command[0] & 0140) == 0100) {
9047c478bd9Sstevel@tonic-gate 			modes.c_iflag |= IUCLC;
9057c478bd9Sstevel@tonic-gate 			modes.c_oflag |= OLCUC;
9067c478bd9Sstevel@tonic-gate 			modes.c_cflag |= XCASE;
907*de81e71eSTim Marsland 		} else if (tgetflag("LC")) {
9087c478bd9Sstevel@tonic-gate 			modes.c_iflag &= ~IUCLC;
9097c478bd9Sstevel@tonic-gate 			modes.c_oflag &= ~OLCUC;
9107c478bd9Sstevel@tonic-gate 			modes.c_cflag &= ~XCASE;
9117c478bd9Sstevel@tonic-gate 		}
9127c478bd9Sstevel@tonic-gate 		modes.c_iflag &= ~(PARMRK|INPCK);
9137c478bd9Sstevel@tonic-gate 		modes.c_lflag |= ICANON;
9147c478bd9Sstevel@tonic-gate 		if (tgetflag("EP")) {
9157c478bd9Sstevel@tonic-gate 			modes.c_iflag |= INPCK;
9167c478bd9Sstevel@tonic-gate 			modes.c_cflag |= PARENB;
9177c478bd9Sstevel@tonic-gate 			modes.c_cflag &= ~PARODD;
9187c478bd9Sstevel@tonic-gate 		}
9197c478bd9Sstevel@tonic-gate 		if (tgetflag("OP")) {
9207c478bd9Sstevel@tonic-gate 			modes.c_iflag |= INPCK;
9217c478bd9Sstevel@tonic-gate 			modes.c_cflag |= PARENB;
9227c478bd9Sstevel@tonic-gate 			modes.c_cflag |= PARODD;
9237c478bd9Sstevel@tonic-gate 		}
9247c478bd9Sstevel@tonic-gate 
9257c478bd9Sstevel@tonic-gate 		modes.c_oflag |= ONLCR;
9267c478bd9Sstevel@tonic-gate 		modes.c_iflag |= ICRNL;
9277c478bd9Sstevel@tonic-gate 		modes.c_lflag |= ECHO;
9287c478bd9Sstevel@tonic-gate 		modes.c_oflag |= TAB3;
9297c478bd9Sstevel@tonic-gate 		if (tgetflag("NL")) {	/* new line, not line feed */
9307c478bd9Sstevel@tonic-gate 			modes.c_oflag &= ~ONLCR;
9317c478bd9Sstevel@tonic-gate 			modes.c_iflag &= ~ICRNL;
9327c478bd9Sstevel@tonic-gate 		}
9337c478bd9Sstevel@tonic-gate 		if (tgetflag("HD"))	/* half duplex */
9347c478bd9Sstevel@tonic-gate 			modes.c_lflag &= ~ECHO;
9357c478bd9Sstevel@tonic-gate 		if (tgetflag("pt"))	/* print tabs */
9367c478bd9Sstevel@tonic-gate 			modes.c_oflag &= ~TAB3;
9377c478bd9Sstevel@tonic-gate 
9387c478bd9Sstevel@tonic-gate 		modes.c_lflag |= (ECHOE|ECHOK);
939*de81e71eSTim Marsland 		if (tgetflag("hc")) {	/* set printer modes */
9407c478bd9Sstevel@tonic-gate 			modes.c_lflag &= ~ECHOE;
9417c478bd9Sstevel@tonic-gate 		}
9427c478bd9Sstevel@tonic-gate 
9437c478bd9Sstevel@tonic-gate 		/* get pad character */
9447c478bd9Sstevel@tonic-gate 		bufp = buf;
9457c478bd9Sstevel@tonic-gate 		if (tgetstr("pc", &bufp) != 0)
9467c478bd9Sstevel@tonic-gate 			PC = buf[0];
9477c478bd9Sstevel@tonic-gate 
9487c478bd9Sstevel@tonic-gate 		/* output startup string */
949*de81e71eSTim Marsland 		if (!NoInit) {
950*de81e71eSTim Marsland 			if (oldmodes.c_oflag&(TAB3|ONLCR|OCRNL|ONLRET)) {
9517c478bd9Sstevel@tonic-gate 				oldmodes.c_oflag &= (TAB3|ONLCR|OCRNL|ONLRET);
9527c478bd9Sstevel@tonic-gate 				setmode(-1);
9537c478bd9Sstevel@tonic-gate 			}
9547c478bd9Sstevel@tonic-gate 			if (settabs()) {
9557c478bd9Sstevel@tonic-gate 				settle = YES;
9567c478bd9Sstevel@tonic-gate 				flush();
9577c478bd9Sstevel@tonic-gate 			}
9587c478bd9Sstevel@tonic-gate 			bufp = buf;
9597c478bd9Sstevel@tonic-gate 			if (IsReset && tgetstr("rs", &bufp) != 0 ||
960*de81e71eSTim Marsland 			    tgetstr("is", &bufp) != 0) {
9617c478bd9Sstevel@tonic-gate 				tputs(buf, 0, prc);
9627c478bd9Sstevel@tonic-gate 				settle = YES;
9637c478bd9Sstevel@tonic-gate 				flush();
9647c478bd9Sstevel@tonic-gate 			}
9657c478bd9Sstevel@tonic-gate 			bufp = buf;
9667c478bd9Sstevel@tonic-gate 			if (IsReset && tgetstr("rf", &bufp) != 0 ||
967*de81e71eSTim Marsland 			    tgetstr("if", &bufp) != 0) {
9687c478bd9Sstevel@tonic-gate 				cat(buf);
9697c478bd9Sstevel@tonic-gate 				settle = YES;
9707c478bd9Sstevel@tonic-gate 			}
971*de81e71eSTim Marsland 			if (settle) {
9727c478bd9Sstevel@tonic-gate 				prc('\r');
9737c478bd9Sstevel@tonic-gate 				if (IsReset)
9747c478bd9Sstevel@tonic-gate 					prc('\n');  /* newline too */
9757c478bd9Sstevel@tonic-gate 				flush();
9767c478bd9Sstevel@tonic-gate 				sleep(1);	/* let terminal settle down */
9777c478bd9Sstevel@tonic-gate 			}
9787c478bd9Sstevel@tonic-gate 		}
9797c478bd9Sstevel@tonic-gate 
9807c478bd9Sstevel@tonic-gate 		setmode(0);	/* set new modes, if they've changed */
9817c478bd9Sstevel@tonic-gate 
9827c478bd9Sstevel@tonic-gate 		/* set up environment for the shell we are using */
9837c478bd9Sstevel@tonic-gate 		/* (this code is rather heuristic, checking for $SHELL */
9847c478bd9Sstevel@tonic-gate 		/* ending in the 3 characters "csh") */
9857c478bd9Sstevel@tonic-gate 		csh = NO;
986*de81e71eSTim Marsland 		if (DoSetenv) {
9877c478bd9Sstevel@tonic-gate 			char *sh;
9887c478bd9Sstevel@tonic-gate 
989*de81e71eSTim Marsland 			if ((sh = getenv("SHELL")) && (i = strlen(sh)) >= 3) {
9907c478bd9Sstevel@tonic-gate 				if ((csh = sequal(&sh[i-3], "csh")) && CmndLine)
991*de81e71eSTim Marsland 					(void) write(STDOUT,
992*de81e71eSTim Marsland 					    "set noglob;\n", 12);
9937c478bd9Sstevel@tonic-gate 			}
994*de81e71eSTim Marsland 			if (!csh) {	/* running Bourne shell */
995*de81e71eSTim Marsland 				(void) write(STDOUT,
996*de81e71eSTim Marsland 				    "export TERMCAP TERM;\n", 21);
997*de81e71eSTim Marsland 			}
9987c478bd9Sstevel@tonic-gate 		}
9997c478bd9Sstevel@tonic-gate 	}
10007c478bd9Sstevel@tonic-gate 
10017c478bd9Sstevel@tonic-gate 	/* report type if appropriate */
1002*de81e71eSTim Marsland 	if (DoSetenv || Report || Ureport) {
10037c478bd9Sstevel@tonic-gate 		/* if type is the short name, find first alias (if any) */
10047c478bd9Sstevel@tonic-gate 		makealias(Ttycap);
10057c478bd9Sstevel@tonic-gate 		if (sequal(TtyType, Alias[0]) && Alias[1]) {
10067c478bd9Sstevel@tonic-gate 			TtyType = Alias[1];
10077c478bd9Sstevel@tonic-gate 		}
10087c478bd9Sstevel@tonic-gate 
1009*de81e71eSTim Marsland 		if (DoSetenv) {
1010*de81e71eSTim Marsland 			if (csh) {
10117c478bd9Sstevel@tonic-gate 				if (CmndLine)
1012*de81e71eSTim Marsland 					(void) write(STDOUT,
1013*de81e71eSTim Marsland 					    "setenv TERM ", 12);
10147c478bd9Sstevel@tonic-gate 				(void) write(STDOUT, TtyType, strlen(TtyType));
10157c478bd9Sstevel@tonic-gate 				(void) write(STDOUT, " ", 1);
10167c478bd9Sstevel@tonic-gate 				if (CmndLine)
10177c478bd9Sstevel@tonic-gate 					(void) write(STDOUT, ";\n", 2);
1018*de81e71eSTim Marsland 			} else {
10197c478bd9Sstevel@tonic-gate 				(void) write(STDOUT, "TERM=", 5);
10207c478bd9Sstevel@tonic-gate 				(void) write(STDOUT, TtyType, strlen(TtyType));
10217c478bd9Sstevel@tonic-gate 				(void) write(STDOUT, ";\n", 2);
10227c478bd9Sstevel@tonic-gate 			}
1023*de81e71eSTim Marsland 		} else if (Report) {
10247c478bd9Sstevel@tonic-gate 			(void) write(STDOUT, TtyType, strlen(TtyType));
10257c478bd9Sstevel@tonic-gate 			(void) write(STDOUT, "\n", 1);
10267c478bd9Sstevel@tonic-gate 		}
1027*de81e71eSTim Marsland 		if (Ureport) {
10287c478bd9Sstevel@tonic-gate 			prs("Terminal type is ");
10297c478bd9Sstevel@tonic-gate 			prs(TtyType);
10307c478bd9Sstevel@tonic-gate 			prs("\n");
10317c478bd9Sstevel@tonic-gate 			flush();
10327c478bd9Sstevel@tonic-gate 		}
10337c478bd9Sstevel@tonic-gate 
1034*de81e71eSTim Marsland 		if (DoSetenv) {
1035*de81e71eSTim Marsland 			if (csh) {
10367c478bd9Sstevel@tonic-gate 				if (CmndLine)
1037*de81e71eSTim Marsland 					(void) write(STDOUT,
1038*de81e71eSTim Marsland 					    "setenv TERMCAP '", 16);
1039*de81e71eSTim Marsland 			} else
10407c478bd9Sstevel@tonic-gate 				(void) write(STDOUT, "TERMCAP='", 9);
10417c478bd9Sstevel@tonic-gate 			wrtermcap(Ttycap);
1042*de81e71eSTim Marsland 			if (csh) {
1043*de81e71eSTim Marsland 				if (CmndLine) {
10447c478bd9Sstevel@tonic-gate 					(void) write(STDOUT, "';\n", 3);
1045*de81e71eSTim Marsland 					(void) write(STDOUT,
1046*de81e71eSTim Marsland 					    "unset noglob;\n", 14);
10477c478bd9Sstevel@tonic-gate 				}
1048*de81e71eSTim Marsland 			} else
10497c478bd9Sstevel@tonic-gate 				(void) write(STDOUT, "';\n", 3);
10507c478bd9Sstevel@tonic-gate 		}
10517c478bd9Sstevel@tonic-gate 	}
10527c478bd9Sstevel@tonic-gate 
10537c478bd9Sstevel@tonic-gate 	if (RepOnly)
10547c478bd9Sstevel@tonic-gate 		exit(0);
10557c478bd9Sstevel@tonic-gate 
10567c478bd9Sstevel@tonic-gate 	/* tell about changing erase, kill and interrupt characters */
10577c478bd9Sstevel@tonic-gate 	reportek("Erase", curerase, olderase, CERASE);
10587c478bd9Sstevel@tonic-gate 	reportek("Kill", curkill, oldkill, CKILL);
10597c478bd9Sstevel@tonic-gate 	reportek("Interrupt", curintr, oldintr, CINTR);
10607c478bd9Sstevel@tonic-gate 
1061cc6c5292Schin 	return (0);
10627c478bd9Sstevel@tonic-gate }
10637c478bd9Sstevel@tonic-gate 
10647c478bd9Sstevel@tonic-gate /*
10657c478bd9Sstevel@tonic-gate  * Set the hardware tabs on the terminal, using the ct (clear all tabs),
10667c478bd9Sstevel@tonic-gate  * st (set one tab) and ch (horizontal cursor addressing) capabilities.
10677c478bd9Sstevel@tonic-gate  * This is done before if and is, so they can patch in case we blow this.
10687c478bd9Sstevel@tonic-gate  */
1069cc6c5292Schin int
settabs(void)1070cc6c5292Schin settabs(void)
10717c478bd9Sstevel@tonic-gate {
10727c478bd9Sstevel@tonic-gate 	char caps[100];
10737c478bd9Sstevel@tonic-gate 	char *capsp = caps;
10747c478bd9Sstevel@tonic-gate 	char *clear_tabs, *set_tab, *set_column, *set_pos;
10757c478bd9Sstevel@tonic-gate 	char *tg_out, *tgoto();
10767c478bd9Sstevel@tonic-gate 	int c;
10777c478bd9Sstevel@tonic-gate 	extern char *tgetstr();
10787c478bd9Sstevel@tonic-gate 	int lines, columns;
10797c478bd9Sstevel@tonic-gate 
10807c478bd9Sstevel@tonic-gate 	clear_tabs = tgetstr("ct", &capsp);
10817c478bd9Sstevel@tonic-gate 	set_tab = tgetstr("st", &capsp);
10827c478bd9Sstevel@tonic-gate 	set_column = tgetstr("ch", &capsp);
10837c478bd9Sstevel@tonic-gate 	if (set_column == 0)
10847c478bd9Sstevel@tonic-gate 		set_pos = tgetstr("cm", &capsp);
10857c478bd9Sstevel@tonic-gate 
10867c478bd9Sstevel@tonic-gate 	if (clear_tabs && set_tab) {
10877c478bd9Sstevel@tonic-gate 		prc('\r');	/* force to be at left margin */
10887c478bd9Sstevel@tonic-gate 		tputs(clear_tabs, 0, prc);
10897c478bd9Sstevel@tonic-gate 	}
10907c478bd9Sstevel@tonic-gate 	if (set_tab) {
10917c478bd9Sstevel@tonic-gate 		columns = tgetnum("co");
10927c478bd9Sstevel@tonic-gate 		lines = tgetnum("li");
10937c478bd9Sstevel@tonic-gate 		for (c = 0; c < columns; c += 8) {
10947c478bd9Sstevel@tonic-gate 			/* get to that column. */
10957c478bd9Sstevel@tonic-gate 			tg_out = "OOPS";	/* also returned by tgoto */
10967c478bd9Sstevel@tonic-gate 			if (set_column)
10977c478bd9Sstevel@tonic-gate 				tg_out = tgoto(set_column, 0, c);
10987c478bd9Sstevel@tonic-gate 			if (*tg_out == 'O' && set_pos)
10997c478bd9Sstevel@tonic-gate 				tg_out = tgoto(set_pos, c, lines-1);
11007c478bd9Sstevel@tonic-gate 			if (*tg_out != 'O')
11017c478bd9Sstevel@tonic-gate 				tputs(tg_out, 1, prc);
11027c478bd9Sstevel@tonic-gate 			else if (c != 0) {
11037c478bd9Sstevel@tonic-gate 				prc(' '); prc(' '); prc(' '); prc(' ');
11047c478bd9Sstevel@tonic-gate 				prc(' '); prc(' '); prc(' '); prc(' ');
11057c478bd9Sstevel@tonic-gate 			}
11067c478bd9Sstevel@tonic-gate 			/* set the tab */
11077c478bd9Sstevel@tonic-gate 			tputs(set_tab, 0, prc);
11087c478bd9Sstevel@tonic-gate 		}
11097c478bd9Sstevel@tonic-gate 		prc('\r');
1110cc6c5292Schin 		return (1);
11117c478bd9Sstevel@tonic-gate 	}
1112cc6c5292Schin 	return (0);
11137c478bd9Sstevel@tonic-gate }
11147c478bd9Sstevel@tonic-gate 
1115*de81e71eSTim Marsland /*
1116*de81e71eSTim Marsland  * flag serves several purposes:
11177c478bd9Sstevel@tonic-gate  *	if called as the result of a signal, flag will be > 0.
11187c478bd9Sstevel@tonic-gate  *	if called from terminal init, flag == -1 means reset "oldmode".
11197c478bd9Sstevel@tonic-gate  *	called with flag == 0 at end of normal mode processing.
11207c478bd9Sstevel@tonic-gate  */
1121*de81e71eSTim Marsland void
setmode(int flag)1122*de81e71eSTim Marsland setmode(int flag)
11237c478bd9Sstevel@tonic-gate {
11247c478bd9Sstevel@tonic-gate 	struct termio *ttymode;
11257c478bd9Sstevel@tonic-gate 	struct termios *ttymodes;
1126cc6c5292Schin 	int i;
11277c478bd9Sstevel@tonic-gate 
11287c478bd9Sstevel@tonic-gate 	ttymode = (struct termio *)0;
11297c478bd9Sstevel@tonic-gate 	ttymodes = (struct termios *)0;
11307c478bd9Sstevel@tonic-gate 
11317c478bd9Sstevel@tonic-gate 	if (flag < 0) { /* unconditionally reset oldmode (called from init) */
11327c478bd9Sstevel@tonic-gate 		if (istermios < 0) {
11337c478bd9Sstevel@tonic-gate 			oldmode.c_lflag = oldmodes.c_lflag;
11347c478bd9Sstevel@tonic-gate 			oldmode.c_oflag = oldmodes.c_oflag;
11357c478bd9Sstevel@tonic-gate 			oldmode.c_iflag = oldmodes.c_iflag;
11367c478bd9Sstevel@tonic-gate 			oldmode.c_cflag = oldmodes.c_cflag;
11377c478bd9Sstevel@tonic-gate 			for (i = 0; i < NCC; i++)
11387c478bd9Sstevel@tonic-gate 				oldmode.c_cc[i] = oldmodes.c_cc[i];
11397c478bd9Sstevel@tonic-gate 			ttymode = &oldmode;
11407c478bd9Sstevel@tonic-gate 		} else
11417c478bd9Sstevel@tonic-gate 			ttymodes = &oldmodes;
11427c478bd9Sstevel@tonic-gate 	} else {
11437c478bd9Sstevel@tonic-gate 		if (istermios < 0) {
11447c478bd9Sstevel@tonic-gate 			oldmode.c_lflag = oldmodes.c_lflag;
11457c478bd9Sstevel@tonic-gate 			oldmode.c_oflag = oldmodes.c_oflag;
11467c478bd9Sstevel@tonic-gate 			oldmode.c_iflag = oldmodes.c_iflag;
11477c478bd9Sstevel@tonic-gate 			oldmode.c_cflag = oldmodes.c_cflag;
11487c478bd9Sstevel@tonic-gate 			for (i = 0; i < NCC; i++)
11497c478bd9Sstevel@tonic-gate 				oldmode.c_cc[i] = oldmodes.c_cc[i];
11507c478bd9Sstevel@tonic-gate 			mode.c_lflag = modes.c_lflag;
11517c478bd9Sstevel@tonic-gate 			mode.c_oflag = modes.c_oflag;
11527c478bd9Sstevel@tonic-gate 			mode.c_iflag = modes.c_iflag;
11537c478bd9Sstevel@tonic-gate 			mode.c_cflag = modes.c_cflag;
11547c478bd9Sstevel@tonic-gate 			for (i = 0; i < NCC; i++)
11557c478bd9Sstevel@tonic-gate 				mode.c_cc[i] = modes.c_cc[i];
1156*de81e71eSTim Marsland 			if (!bequal((char *)&mode, (char *)&oldmode,
1157*de81e71eSTim Marsland 			    sizeof (mode)))
11587c478bd9Sstevel@tonic-gate 				ttymode = &mode;
11597c478bd9Sstevel@tonic-gate 		} else if (!bequal((char *)&modes, (char *)&oldmodes,
1160*de81e71eSTim Marsland 		    sizeof (modes)))
11617c478bd9Sstevel@tonic-gate 			ttymodes = &modes;
11627c478bd9Sstevel@tonic-gate 	}
11637c478bd9Sstevel@tonic-gate 
1164*de81e71eSTim Marsland 	if (ttymode) {
11657c478bd9Sstevel@tonic-gate 		(void) ioctl(FILEDES, TCSETAW, (char *)ttymode);
11667c478bd9Sstevel@tonic-gate 	} else if (ttymodes) {
11677c478bd9Sstevel@tonic-gate 		(void) ioctl(FILEDES, TCSETSW, (char *)ttymodes);
11687c478bd9Sstevel@tonic-gate 	}
11697c478bd9Sstevel@tonic-gate 	if (flag > 0)	/* trapped signal */
11707c478bd9Sstevel@tonic-gate 		exit(1);
11717c478bd9Sstevel@tonic-gate }
11727c478bd9Sstevel@tonic-gate 
1173cc6c5292Schin void
reportek(char * name,char new,char old,char def)1174cc6c5292Schin reportek(char *name, char new, char old, char def)
11757c478bd9Sstevel@tonic-gate {
1176cc6c5292Schin 	char	o;
1177cc6c5292Schin 	char	n;
1178cc6c5292Schin 	char	*p;
11797c478bd9Sstevel@tonic-gate 	char		buf[32];
11807c478bd9Sstevel@tonic-gate 	char		*bufp;
11817c478bd9Sstevel@tonic-gate 	extern char *tgetstr();
11827c478bd9Sstevel@tonic-gate 
11837c478bd9Sstevel@tonic-gate 	if (BeQuiet)
11847c478bd9Sstevel@tonic-gate 		return;
11857c478bd9Sstevel@tonic-gate 	o = old;
11867c478bd9Sstevel@tonic-gate 	n = new;
11877c478bd9Sstevel@tonic-gate 
11887c478bd9Sstevel@tonic-gate 	if (o == n && n == def)
11897c478bd9Sstevel@tonic-gate 		return;
11907c478bd9Sstevel@tonic-gate 	prs(name);
11917c478bd9Sstevel@tonic-gate 	if (o == n)
11927c478bd9Sstevel@tonic-gate 		prs(" is ");
11937c478bd9Sstevel@tonic-gate 	else
11947c478bd9Sstevel@tonic-gate 		prs(" set to ");
11957c478bd9Sstevel@tonic-gate 	bufp = buf;
11967c478bd9Sstevel@tonic-gate 	if (tgetstr("kb", &bufp) > (char *)0 && n == buf[0] && buf[1] == NULL)
11977c478bd9Sstevel@tonic-gate 		prs("Backspace\n");
11987c478bd9Sstevel@tonic-gate 	else if (n == 0177)
11997c478bd9Sstevel@tonic-gate 		prs("Delete\n");
1200*de81e71eSTim Marsland 	else {
1201*de81e71eSTim Marsland 		if (n < 040) {
12027c478bd9Sstevel@tonic-gate 			prs("Ctrl-");
12037c478bd9Sstevel@tonic-gate 			n ^= 0100;
12047c478bd9Sstevel@tonic-gate 		}
12057c478bd9Sstevel@tonic-gate 		p = "x\n";
12067c478bd9Sstevel@tonic-gate 		p[0] = n;
12077c478bd9Sstevel@tonic-gate 		prs(p);
12087c478bd9Sstevel@tonic-gate 	}
12097c478bd9Sstevel@tonic-gate 	flush();
12107c478bd9Sstevel@tonic-gate }
12117c478bd9Sstevel@tonic-gate 
12127c478bd9Sstevel@tonic-gate 
12137c478bd9Sstevel@tonic-gate 
1214cc6c5292Schin void
setdelay(char * cap,struct delay dtab[],tcflag_t bits,tcflag_t * flags)1215cc6c5292Schin setdelay(char *cap, struct delay dtab[], tcflag_t bits, tcflag_t *flags)
12167c478bd9Sstevel@tonic-gate {
1217cc6c5292Schin 	int		i;
1218cc6c5292Schin 	struct delay	*p;
12197c478bd9Sstevel@tonic-gate 	extern short	ospeed;
12207c478bd9Sstevel@tonic-gate 
12217c478bd9Sstevel@tonic-gate 	/* see if this capability exists at all */
12227c478bd9Sstevel@tonic-gate 	i = tgetnum(cap);
12237c478bd9Sstevel@tonic-gate 	if (i < 0)
12247c478bd9Sstevel@tonic-gate 		i = 0;
12257c478bd9Sstevel@tonic-gate 	/* No padding at speeds below PadBaud */
12267c478bd9Sstevel@tonic-gate 	if (PadBaud > ospeed)
12277c478bd9Sstevel@tonic-gate 		i = 0;
12287c478bd9Sstevel@tonic-gate 
12297c478bd9Sstevel@tonic-gate 	/* clear out the bits, replace with new ones */
12307c478bd9Sstevel@tonic-gate 	*flags &= ~bits;
12317c478bd9Sstevel@tonic-gate 
12327c478bd9Sstevel@tonic-gate 	/* scan dtab for first entry with adequate delay */
1233*de81e71eSTim Marsland 	for (p = dtab; p->d_delay >= 0; p++) {
1234*de81e71eSTim Marsland 		if (p->d_delay >= i) {
12357c478bd9Sstevel@tonic-gate 			p++;
12367c478bd9Sstevel@tonic-gate 			break;
12377c478bd9Sstevel@tonic-gate 		}
12387c478bd9Sstevel@tonic-gate 	}
12397c478bd9Sstevel@tonic-gate 
12407c478bd9Sstevel@tonic-gate 	/* use last entry if none will do */
1241cc6c5292Schin 	*flags |= (tcflag_t)((--p)->d_bits);
12427c478bd9Sstevel@tonic-gate }
12437c478bd9Sstevel@tonic-gate 
1244cc6c5292Schin void
prs(char * s)1245cc6c5292Schin prs(char *s)
12467c478bd9Sstevel@tonic-gate {
12477c478bd9Sstevel@tonic-gate 	while (*s != '\0')
12487c478bd9Sstevel@tonic-gate 		prc(*s++);
12497c478bd9Sstevel@tonic-gate }
12507c478bd9Sstevel@tonic-gate 
12517c478bd9Sstevel@tonic-gate 
12527c478bd9Sstevel@tonic-gate char	OutBuf[256];
12537c478bd9Sstevel@tonic-gate int	OutPtr;
12547c478bd9Sstevel@tonic-gate 
1255cc6c5292Schin void
prc(char c)1256cc6c5292Schin prc(char c)
12577c478bd9Sstevel@tonic-gate {
12587c478bd9Sstevel@tonic-gate 	OutBuf[OutPtr++] = c;
1259*de81e71eSTim Marsland 	if (OutPtr >= sizeof (OutBuf))
12607c478bd9Sstevel@tonic-gate 		flush();
12617c478bd9Sstevel@tonic-gate }
12627c478bd9Sstevel@tonic-gate 
1263cc6c5292Schin void
flush(void)1264cc6c5292Schin flush(void)
12657c478bd9Sstevel@tonic-gate {
12667c478bd9Sstevel@tonic-gate 	if (OutPtr > 0)
12677c478bd9Sstevel@tonic-gate 		(void) write(2, OutBuf, OutPtr);
12687c478bd9Sstevel@tonic-gate 	OutPtr = 0;
12697c478bd9Sstevel@tonic-gate }
12707c478bd9Sstevel@tonic-gate 
1271cc6c5292Schin void
cat(char * file)1272cc6c5292Schin cat(char *file)
12737c478bd9Sstevel@tonic-gate {
1274cc6c5292Schin 	int	fd;
1275cc6c5292Schin 	int	i;
12767c478bd9Sstevel@tonic-gate 	char		buf[BUFSIZ];
12777c478bd9Sstevel@tonic-gate 
12787c478bd9Sstevel@tonic-gate 	fd = open(file, 0);
1279*de81e71eSTim Marsland 	if (fd < 0) {
12807c478bd9Sstevel@tonic-gate 		prs("Cannot open ");
12817c478bd9Sstevel@tonic-gate 		prs(file);
12827c478bd9Sstevel@tonic-gate 		prs("\n");
12837c478bd9Sstevel@tonic-gate 		flush();
12847c478bd9Sstevel@tonic-gate 		return;
12857c478bd9Sstevel@tonic-gate 	}
12867c478bd9Sstevel@tonic-gate 
12877c478bd9Sstevel@tonic-gate 	while ((i = read(fd, buf, BUFSIZ)) > 0)
12887c478bd9Sstevel@tonic-gate 		(void) write(FILEDES, buf, i);
12897c478bd9Sstevel@tonic-gate 
12907c478bd9Sstevel@tonic-gate 	(void) close(fd);
12917c478bd9Sstevel@tonic-gate }
12927c478bd9Sstevel@tonic-gate 
12937c478bd9Sstevel@tonic-gate 
1294cc6c5292Schin void
bmove(char * from,char * to,int length)1295cc6c5292Schin bmove(char *from, char *to, int length)
12967c478bd9Sstevel@tonic-gate {
1297cc6c5292Schin 	char	*p, *q;
1298cc6c5292Schin 	int	i;
12997c478bd9Sstevel@tonic-gate 
13007c478bd9Sstevel@tonic-gate 	i = length;
13017c478bd9Sstevel@tonic-gate 	p = from;
13027c478bd9Sstevel@tonic-gate 	q = to;
13037c478bd9Sstevel@tonic-gate 
13047c478bd9Sstevel@tonic-gate 	while (i-- > 0)
13057c478bd9Sstevel@tonic-gate 		*q++ = *p++;
13067c478bd9Sstevel@tonic-gate }
13077c478bd9Sstevel@tonic-gate 
13087c478bd9Sstevel@tonic-gate 
1309cc6c5292Schin int
bequal(char * a,char * b,int len)1310cc6c5292Schin bequal(char *a, char *b, int len)	/* must be same thru len chars */
13117c478bd9Sstevel@tonic-gate {
1312cc6c5292Schin 	char	*p, *q;
1313cc6c5292Schin 	int	i;
13147c478bd9Sstevel@tonic-gate 
13157c478bd9Sstevel@tonic-gate 	i = len;
13167c478bd9Sstevel@tonic-gate 	p = a;
13177c478bd9Sstevel@tonic-gate 	q = b;
13187c478bd9Sstevel@tonic-gate 
1319*de81e71eSTim Marsland 	while ((*p == *q) && --i > 0) {
13207c478bd9Sstevel@tonic-gate 		p++; q++;
13217c478bd9Sstevel@tonic-gate 	}
13227c478bd9Sstevel@tonic-gate 	return ((*p == *q) && i >= 0);
13237c478bd9Sstevel@tonic-gate }
13247c478bd9Sstevel@tonic-gate 
1325cc6c5292Schin int
sequal(char * a,char * b)1326cc6c5292Schin sequal(char *a, char *b)	/* must be same thru NULL */
13277c478bd9Sstevel@tonic-gate {
1328cc6c5292Schin 	char *p = a, *q = b;
13297c478bd9Sstevel@tonic-gate 
1330*de81e71eSTim Marsland 	while (*p && *q && (*p == *q)) {
13317c478bd9Sstevel@tonic-gate 		p++; q++;
13327c478bd9Sstevel@tonic-gate 	}
13337c478bd9Sstevel@tonic-gate 	return (*p == *q);
13347c478bd9Sstevel@tonic-gate }
13357c478bd9Sstevel@tonic-gate 
1336cc6c5292Schin void
makealias(char * buf)1337cc6c5292Schin makealias(char *buf)
13387c478bd9Sstevel@tonic-gate {
1339cc6c5292Schin 	int i;
1340cc6c5292Schin 	char *a;
1341cc6c5292Schin 	char *b;
13427c478bd9Sstevel@tonic-gate 
13437c478bd9Sstevel@tonic-gate 	Alias[0] = a = Aliasbuf;
13447c478bd9Sstevel@tonic-gate 	b = buf;
13457c478bd9Sstevel@tonic-gate 	i = 1;
13467c478bd9Sstevel@tonic-gate 	while (*b && *b != ':') {
13477c478bd9Sstevel@tonic-gate 		if (*b == '|') {
13487c478bd9Sstevel@tonic-gate 			*a++ = NULL;
13497c478bd9Sstevel@tonic-gate 			Alias[i++] = a;
13507c478bd9Sstevel@tonic-gate 			b++;
1351*de81e71eSTim Marsland 		} else
13527c478bd9Sstevel@tonic-gate 			*a++ = *b++;
13537c478bd9Sstevel@tonic-gate 	}
13547c478bd9Sstevel@tonic-gate 	*a = NULL;
13557c478bd9Sstevel@tonic-gate 	Alias[i] = NULL;
13567c478bd9Sstevel@tonic-gate #ifdef	DEB
1357*de81e71eSTim Marsland 	for (i = 0; Alias[i]; printf("A:%s\n", Alias[i++]))
1358*de81e71eSTim Marsland 		;
13597c478bd9Sstevel@tonic-gate #endif
13607c478bd9Sstevel@tonic-gate }
13617c478bd9Sstevel@tonic-gate 
1362cc6c5292Schin int
isalias(char * ident)1363cc6c5292Schin isalias(char *ident)	/* is ident same as one of the aliases? */
13647c478bd9Sstevel@tonic-gate {
13657c478bd9Sstevel@tonic-gate 	char **a = Alias;
13667c478bd9Sstevel@tonic-gate 
13677c478bd9Sstevel@tonic-gate 	if (*a)
13687c478bd9Sstevel@tonic-gate 		while (*a)
13697c478bd9Sstevel@tonic-gate 			if (sequal(ident, *a))
13707c478bd9Sstevel@tonic-gate 				return (YES);
13717c478bd9Sstevel@tonic-gate 			else
13727c478bd9Sstevel@tonic-gate 				a++;
13737c478bd9Sstevel@tonic-gate 	return (NO);
13747c478bd9Sstevel@tonic-gate }
13757c478bd9Sstevel@tonic-gate 
13767c478bd9Sstevel@tonic-gate 
13777c478bd9Sstevel@tonic-gate /*
13787c478bd9Sstevel@tonic-gate  * routine to output the string for the environment TERMCAP variable
13797c478bd9Sstevel@tonic-gate  */
13807c478bd9Sstevel@tonic-gate #define	WHITE(c)	(c == ' ' || c == '\t')
13817c478bd9Sstevel@tonic-gate char delcap[128][2];
13827c478bd9Sstevel@tonic-gate int ncap = 0;
13837c478bd9Sstevel@tonic-gate 
1384cc6c5292Schin void
wrtermcap(char * bp)1385cc6c5292Schin wrtermcap(char *bp)
13867c478bd9Sstevel@tonic-gate {
13877c478bd9Sstevel@tonic-gate 	char buf[CAPBUFSIZ];
13887c478bd9Sstevel@tonic-gate 	char *p = buf;
13897c478bd9Sstevel@tonic-gate 	char *tp;
13907c478bd9Sstevel@tonic-gate 	char *putbuf();
13917c478bd9Sstevel@tonic-gate 	int space, empty;
13927c478bd9Sstevel@tonic-gate 
13937c478bd9Sstevel@tonic-gate 	/* discard names with blanks */
1394*de81e71eSTim Marsland /* May not be desireable ? */
13957c478bd9Sstevel@tonic-gate 	while (*bp && *bp != ':') {
13967c478bd9Sstevel@tonic-gate 		if (*bp == '|') {
13977c478bd9Sstevel@tonic-gate 			tp = bp+1;
13987c478bd9Sstevel@tonic-gate 			space = NO;
13997c478bd9Sstevel@tonic-gate 			while (*tp && *tp != '|' && *tp != ':') {
14007c478bd9Sstevel@tonic-gate 				space = (space || WHITE(*tp));
14017c478bd9Sstevel@tonic-gate 				tp++;
14027c478bd9Sstevel@tonic-gate 			}
14037c478bd9Sstevel@tonic-gate 			if (space) {
14047c478bd9Sstevel@tonic-gate 				bp = tp;
14057c478bd9Sstevel@tonic-gate 				continue;
14067c478bd9Sstevel@tonic-gate 			}
14077c478bd9Sstevel@tonic-gate 		}
14087c478bd9Sstevel@tonic-gate 		*p++ = *bp++;
14097c478bd9Sstevel@tonic-gate 	}
14107c478bd9Sstevel@tonic-gate /* */
14117c478bd9Sstevel@tonic-gate 
14127c478bd9Sstevel@tonic-gate 	while (*bp) {
14137c478bd9Sstevel@tonic-gate 		switch (*bp) {
14147c478bd9Sstevel@tonic-gate 		case ':':	/* discard empty, cancelled  or dupl fields */
14157c478bd9Sstevel@tonic-gate 			tp = bp + 1;
14167c478bd9Sstevel@tonic-gate 			empty = YES;
14177c478bd9Sstevel@tonic-gate 			while (*tp && *tp != ':') {
14187c478bd9Sstevel@tonic-gate 				empty = (empty && WHITE(*tp));
14197c478bd9Sstevel@tonic-gate 				tp++;
14207c478bd9Sstevel@tonic-gate 			}
14217c478bd9Sstevel@tonic-gate 			if (empty || cancelled(bp+1)) {
14227c478bd9Sstevel@tonic-gate 				bp = tp;
14237c478bd9Sstevel@tonic-gate 				continue;
14247c478bd9Sstevel@tonic-gate 			}
14257c478bd9Sstevel@tonic-gate 			break;
14267c478bd9Sstevel@tonic-gate 
14277c478bd9Sstevel@tonic-gate 		case ' ':	/* no spaces in output */
14287c478bd9Sstevel@tonic-gate 			p = putbuf(p, "\\040");
14297c478bd9Sstevel@tonic-gate 			bp++;
14307c478bd9Sstevel@tonic-gate 			continue;
14317c478bd9Sstevel@tonic-gate 
14327c478bd9Sstevel@tonic-gate 		case '!':	/* the shell thinks this is history */
14337c478bd9Sstevel@tonic-gate 			p = putbuf(p, "\\041");
14347c478bd9Sstevel@tonic-gate 			bp++;
14357c478bd9Sstevel@tonic-gate 			continue;
14367c478bd9Sstevel@tonic-gate 
14377c478bd9Sstevel@tonic-gate 		case ',':	/* the shell thinks this is history */
14387c478bd9Sstevel@tonic-gate 			p = putbuf(p, "\\054");
14397c478bd9Sstevel@tonic-gate 			bp++;
14407c478bd9Sstevel@tonic-gate 			continue;
14417c478bd9Sstevel@tonic-gate 
14427c478bd9Sstevel@tonic-gate 		case '"':	/* no quotes in output */
14437c478bd9Sstevel@tonic-gate 			p = putbuf(p, "\\042");
14447c478bd9Sstevel@tonic-gate 			bp++;
14457c478bd9Sstevel@tonic-gate 			continue;
14467c478bd9Sstevel@tonic-gate 
14477c478bd9Sstevel@tonic-gate 		case '\'':	/* no quotes in output */
14487c478bd9Sstevel@tonic-gate 			p = putbuf(p, "\\047");
14497c478bd9Sstevel@tonic-gate 			bp++;
14507c478bd9Sstevel@tonic-gate 			continue;
14517c478bd9Sstevel@tonic-gate 
14527c478bd9Sstevel@tonic-gate 		case '`':	/* no back quotes in output */
14537c478bd9Sstevel@tonic-gate 			p = putbuf(p, "\\140");
14547c478bd9Sstevel@tonic-gate 			bp++;
14557c478bd9Sstevel@tonic-gate 			continue;
14567c478bd9Sstevel@tonic-gate 
14577c478bd9Sstevel@tonic-gate 		case '\\':
14587c478bd9Sstevel@tonic-gate 		case '^':	/* anything following is OK */
14597c478bd9Sstevel@tonic-gate 			*p++ = *bp++;
14607c478bd9Sstevel@tonic-gate 		}
14617c478bd9Sstevel@tonic-gate 		*p++ = *bp++;
14627c478bd9Sstevel@tonic-gate 	}
14637c478bd9Sstevel@tonic-gate 	*p++ = ':';	/* we skipped the last : with the : lookahead hack */
14647c478bd9Sstevel@tonic-gate 	(void) write(STDOUT, buf, p-buf);
14657c478bd9Sstevel@tonic-gate }
14667c478bd9Sstevel@tonic-gate 
1467cc6c5292Schin int
cancelled(char * cap)1468cc6c5292Schin cancelled(char *cap)
14697c478bd9Sstevel@tonic-gate {
1470cc6c5292Schin 	int i;
14717c478bd9Sstevel@tonic-gate 
1472*de81e71eSTim Marsland 	for (i = 0; i < ncap; i++) {
14737c478bd9Sstevel@tonic-gate 		if (cap[0] == delcap[i][0] && cap[1] == delcap[i][1])
14747c478bd9Sstevel@tonic-gate 			return (YES);
14757c478bd9Sstevel@tonic-gate 	}
14767c478bd9Sstevel@tonic-gate 	/* delete a second occurrance of the same capability */
14777c478bd9Sstevel@tonic-gate 	delcap[ncap][0] = cap[0];
14787c478bd9Sstevel@tonic-gate 	delcap[ncap][1] = cap[1];
14797c478bd9Sstevel@tonic-gate 	ncap++;
14807c478bd9Sstevel@tonic-gate 	return (cap[2] == '@');
14817c478bd9Sstevel@tonic-gate }
14827c478bd9Sstevel@tonic-gate 
14837c478bd9Sstevel@tonic-gate char *
putbuf(ptr,str)14847c478bd9Sstevel@tonic-gate putbuf(ptr, str)
14857c478bd9Sstevel@tonic-gate char	*ptr;
14867c478bd9Sstevel@tonic-gate char	*str;
14877c478bd9Sstevel@tonic-gate {
14887c478bd9Sstevel@tonic-gate 	char buf[20];
14897c478bd9Sstevel@tonic-gate 
14907c478bd9Sstevel@tonic-gate 	while (*str) {
14917c478bd9Sstevel@tonic-gate 		switch (*str) {
14927c478bd9Sstevel@tonic-gate 		case '\033':
14937c478bd9Sstevel@tonic-gate 			ptr = putbuf(ptr, "\\E");
14947c478bd9Sstevel@tonic-gate 			str++;
14957c478bd9Sstevel@tonic-gate 			break;
14967c478bd9Sstevel@tonic-gate 		default:
14977c478bd9Sstevel@tonic-gate 			if (*str <= ' ') {
14987c478bd9Sstevel@tonic-gate 				(void) sprintf(buf, "\\%03o", *str);
14997c478bd9Sstevel@tonic-gate 				ptr = putbuf(ptr, buf);
15007c478bd9Sstevel@tonic-gate 				str++;
15017c478bd9Sstevel@tonic-gate 			} else
15027c478bd9Sstevel@tonic-gate 				*ptr++ = *str++;
15037c478bd9Sstevel@tonic-gate 		}
15047c478bd9Sstevel@tonic-gate 	}
15057c478bd9Sstevel@tonic-gate 	return (ptr);
15067c478bd9Sstevel@tonic-gate }
15077c478bd9Sstevel@tonic-gate 
1508cc6c5292Schin int
baudrate(char * p)1509cc6c5292Schin baudrate(char *p)
15107c478bd9Sstevel@tonic-gate {
15117c478bd9Sstevel@tonic-gate 	char buf[8];
15127c478bd9Sstevel@tonic-gate 	int i = 0;
15137c478bd9Sstevel@tonic-gate 
15147c478bd9Sstevel@tonic-gate 	while (i < 7 && (isalnum(*p) || *p == '.'))
15157c478bd9Sstevel@tonic-gate 		buf[i++] = *p++;
15167c478bd9Sstevel@tonic-gate 	buf[i] = NULL;
15177c478bd9Sstevel@tonic-gate 	for (i = 0; speeds[i].string; i++)
15187c478bd9Sstevel@tonic-gate 		if (sequal(speeds[i].string, buf))
15197c478bd9Sstevel@tonic-gate 			return (speeds[i].speed);
15207c478bd9Sstevel@tonic-gate 	return (-1);
15217c478bd9Sstevel@tonic-gate }
15227c478bd9Sstevel@tonic-gate 
15237c478bd9Sstevel@tonic-gate char *
mapped(type)15247c478bd9Sstevel@tonic-gate mapped(type)
15257c478bd9Sstevel@tonic-gate char	*type;
15267c478bd9Sstevel@tonic-gate {
15277c478bd9Sstevel@tonic-gate 	extern short	ospeed;
15287c478bd9Sstevel@tonic-gate 	int	match;
15297c478bd9Sstevel@tonic-gate 
15307c478bd9Sstevel@tonic-gate #ifdef DEB
15317c478bd9Sstevel@tonic-gate 	printf("spd:%d\n", ospeed);
15327c478bd9Sstevel@tonic-gate 	prmap();
15337c478bd9Sstevel@tonic-gate #endif
15347c478bd9Sstevel@tonic-gate 	Map = map;
1535*de81e71eSTim Marsland 	while (Map->Ident) {
1536*de81e71eSTim Marsland 		if (*(Map->Ident) == NULL ||
1537*de81e71eSTim Marsland 		    sequal(Map->Ident, type) || isalias(Map->Ident)) {
15387c478bd9Sstevel@tonic-gate 			match = NO;
1539*de81e71eSTim Marsland 			switch (Map->Test) {
15407c478bd9Sstevel@tonic-gate 			case ANY:	/* no test specified */
15417c478bd9Sstevel@tonic-gate 			case ALL:
15427c478bd9Sstevel@tonic-gate 				match = YES;
15437c478bd9Sstevel@tonic-gate 				break;
15447c478bd9Sstevel@tonic-gate 
15457c478bd9Sstevel@tonic-gate 			case GT:
15467c478bd9Sstevel@tonic-gate 				match = (ospeed > Map->Speed);
15477c478bd9Sstevel@tonic-gate 				break;
15487c478bd9Sstevel@tonic-gate 
15497c478bd9Sstevel@tonic-gate 			case GE:
15507c478bd9Sstevel@tonic-gate 				match = (ospeed >= Map->Speed);
15517c478bd9Sstevel@tonic-gate 				break;
15527c478bd9Sstevel@tonic-gate 
15537c478bd9Sstevel@tonic-gate 			case EQ:
15547c478bd9Sstevel@tonic-gate 				match = (ospeed == Map->Speed);
15557c478bd9Sstevel@tonic-gate 				break;
15567c478bd9Sstevel@tonic-gate 
15577c478bd9Sstevel@tonic-gate 			case LE:
15587c478bd9Sstevel@tonic-gate 				match = (ospeed <= Map->Speed);
15597c478bd9Sstevel@tonic-gate 				break;
15607c478bd9Sstevel@tonic-gate 
15617c478bd9Sstevel@tonic-gate 			case LT:
15627c478bd9Sstevel@tonic-gate 				match = (ospeed < Map->Speed);
15637c478bd9Sstevel@tonic-gate 				break;
15647c478bd9Sstevel@tonic-gate 
15657c478bd9Sstevel@tonic-gate 			case NE:
15667c478bd9Sstevel@tonic-gate 				match = (ospeed != Map->Speed);
15677c478bd9Sstevel@tonic-gate 				break;
15687c478bd9Sstevel@tonic-gate 			}
15697c478bd9Sstevel@tonic-gate 			if (match)
15707c478bd9Sstevel@tonic-gate 				return (Map->Type);
15717c478bd9Sstevel@tonic-gate 		}
15727c478bd9Sstevel@tonic-gate 		Map++;
15737c478bd9Sstevel@tonic-gate 	}
15747c478bd9Sstevel@tonic-gate 	/* no match found; return given type */
15757c478bd9Sstevel@tonic-gate 	return (type);
15767c478bd9Sstevel@tonic-gate }
15777c478bd9Sstevel@tonic-gate 
15787c478bd9Sstevel@tonic-gate #ifdef DEB
prmap()15797c478bd9Sstevel@tonic-gate prmap()
15807c478bd9Sstevel@tonic-gate {
15817c478bd9Sstevel@tonic-gate 	Map = map;
1582*de81e71eSTim Marsland 	while (Map->Ident) {
15837c478bd9Sstevel@tonic-gate 		printf("%s t:%d s:%d %s\n",
15847c478bd9Sstevel@tonic-gate 		    Map->Ident, Map->Test, Map->Speed, Map->Type);
15857c478bd9Sstevel@tonic-gate 		Map++;
15867c478bd9Sstevel@tonic-gate 	}
15877c478bd9Sstevel@tonic-gate }
15887c478bd9Sstevel@tonic-gate #endif
15897c478bd9Sstevel@tonic-gate 
15907c478bd9Sstevel@tonic-gate char *
nextarg(argc,argv)15917c478bd9Sstevel@tonic-gate nextarg(argc, argv)
15927c478bd9Sstevel@tonic-gate int	argc;
15937c478bd9Sstevel@tonic-gate char	*argv[];
15947c478bd9Sstevel@tonic-gate {
15957c478bd9Sstevel@tonic-gate 	if (argc <= 0)
15967c478bd9Sstevel@tonic-gate 		fatal("Too few args: ", *argv);
15977c478bd9Sstevel@tonic-gate 	if (*(*++argv) == '-')
15987c478bd9Sstevel@tonic-gate 		fatal("Unexpected arg: ", *argv);
15997c478bd9Sstevel@tonic-gate 	return (*argv);
16007c478bd9Sstevel@tonic-gate }
16017c478bd9Sstevel@tonic-gate 
1602cc6c5292Schin void
fatal(char * mesg,char * obj)1603cc6c5292Schin fatal(char *mesg, char *obj)
16047c478bd9Sstevel@tonic-gate {
16057c478bd9Sstevel@tonic-gate 	prs(mesg);
16067c478bd9Sstevel@tonic-gate 	prs(obj);
16077c478bd9Sstevel@tonic-gate 	prc('\n');
16087c478bd9Sstevel@tonic-gate 	prs(USAGE);
16097c478bd9Sstevel@tonic-gate 	flush();
16107c478bd9Sstevel@tonic-gate 	exit(1);
16117c478bd9Sstevel@tonic-gate }
16127c478bd9Sstevel@tonic-gate 
16137c478bd9Sstevel@tonic-gate 
16147c478bd9Sstevel@tonic-gate /*
16157c478bd9Sstevel@tonic-gate  * Stolen from /usr/src/ucb/reset.c, which this mod obsoletes.
16167c478bd9Sstevel@tonic-gate  */
16177c478bd9Sstevel@tonic-gate char
reset(ch,def)16187c478bd9Sstevel@tonic-gate reset(ch, def)
16197c478bd9Sstevel@tonic-gate 	char ch;
16207c478bd9Sstevel@tonic-gate 	int def;
16217c478bd9Sstevel@tonic-gate {
16227c478bd9Sstevel@tonic-gate 	if (ch == 0 || (ch&0377) == 0377)
1623*de81e71eSTim Marsland 		return (def);
1624*de81e71eSTim Marsland 	return (ch);
16257c478bd9Sstevel@tonic-gate }
1626