xref: /illumos-gate/usr/src/ucbcmd/tset/tset.c (revision 566b4223c74de6cad48ddbedf35a12d6a511c8c5)
1cc6c5292Schin /*
2de81e71eSTim 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 /*
17de81e71eSTim Marsland  *  TSET -- set terminal modes
18de81e71eSTim Marsland  *
19de81e71eSTim Marsland  *	This program does sophisticated terminal initialization.
20de81e71eSTim Marsland  *	I recommend that you include it in your .profile or .login
21de81e71eSTim Marsland  *	file to initialize whatever terminal you are on.
22de81e71eSTim Marsland  *
23de81e71eSTim Marsland  *	There are several features:
24de81e71eSTim Marsland  *
25de81e71eSTim Marsland  *	A special file or sequence (as controlled by the termcap file)
26de81e71eSTim Marsland  *	is sent to the terminal.
27de81e71eSTim Marsland  *
28de81e71eSTim Marsland  *	Mode bits are set on a per-terminal_type basis (much better
29de81e71eSTim Marsland  *	than UNIX itself).  This allows special delays, automatic
30de81e71eSTim Marsland  *	tabs, etc.
31de81e71eSTim Marsland  *
32de81e71eSTim Marsland  *	Erase and Kill characters can be set to whatever you want.
33de81e71eSTim Marsland  *	Default is to change erase to control-H on a terminal which
34de81e71eSTim Marsland  *	can overstrike, and leave it alone on anything else.  Kill
35de81e71eSTim Marsland  *	is always left alone unless specifically requested.  These
36de81e71eSTim Marsland  *	characters can be represented as "^X" meaning control-X;
37de81e71eSTim Marsland  *	X is any character.
38de81e71eSTim Marsland  *
39de81e71eSTim Marsland  *	Terminals which are dialups or plugboard types can be aliased
40de81e71eSTim Marsland  *	to whatever type you may have in your home or office.  Thus,
41de81e71eSTim Marsland  *	if you know that when you dial up you will always be on a
42de81e71eSTim Marsland  *	TI 733, you can specify that fact to tset.  You can represent
43de81e71eSTim Marsland  *	a type as "?type".  This will ask you what type you want it
44de81e71eSTim Marsland  *	to be -- if you reply with just a newline, it will default
45de81e71eSTim Marsland  *	to the type given.
46de81e71eSTim Marsland  *
47de81e71eSTim Marsland  *	The current terminal type can be queried.
48de81e71eSTim Marsland  *
49de81e71eSTim Marsland  *	Usage:
50de81e71eSTim Marsland  *		tset [-] [-EC] [-eC] [-kC] [-iC] [-s] [-h] [-u] [-r]
51de81e71eSTim Marsland  *			[-m [ident] [test baudrate] :type]
52de81e71eSTim Marsland  *			[-Q] [-I] [-S] [type]
53de81e71eSTim Marsland  *
54de81e71eSTim Marsland  *		In systems with environments, use:
55de81e71eSTim Marsland  *			eval `tset -s ...`
56de81e71eSTim Marsland  *		Actually, this doesn't work in old csh's.
57de81e71eSTim Marsland  *		Instead, use:
58de81e71eSTim Marsland  *			tset -s ... > tset.tmp
59de81e71eSTim Marsland  *			source tset.tmp
60de81e71eSTim Marsland  *			rm tset.tmp
61de81e71eSTim Marsland  *		or:
62de81e71eSTim Marsland  *			set noglob
63de81e71eSTim Marsland  *			set term=(`tset -S ....`)
64de81e71eSTim Marsland  *			setenv TERM $term[1]
65de81e71eSTim Marsland  *			setenv TERMCAP "$term[2]"
66de81e71eSTim Marsland  *			unset term
67de81e71eSTim Marsland  *			unset noglob
68de81e71eSTim Marsland  *
69de81e71eSTim Marsland  *	Positional Parameters:
70de81e71eSTim Marsland  *		type -- the terminal type to force.  If this is
71de81e71eSTim Marsland  *			specified, initialization is for this
72de81e71eSTim Marsland  *			terminal type.
73de81e71eSTim Marsland  *
74de81e71eSTim Marsland  *	Flags:
75de81e71eSTim Marsland  *		- -- report terminal type.  Whatever type is
76de81e71eSTim Marsland  *			decided on is reported.  If no other flags
77de81e71eSTim Marsland  *			are stated, the only affect is to write
78de81e71eSTim Marsland  *			the terminal type on the standard output.
79de81e71eSTim Marsland  *		-r -- report to user in addition to other flags.
80de81e71eSTim Marsland  *		-EC -- set the erase character to C on all terminals
81de81e71eSTim Marsland  *			except those which cannot backspace (e.g.,
82de81e71eSTim Marsland  *			a TTY 33).  C defaults to control-H.
83de81e71eSTim Marsland  *		-eC -- set the erase character to C on all terminals.
84de81e71eSTim Marsland  *			C defaults to control-H.  If not specified,
85de81e71eSTim Marsland  *			the erase character is untouched; however, if
86de81e71eSTim Marsland  *			not specified and the erase character is NULL
87de81e71eSTim Marsland  *			(zero byte), the erase character is set to CERASE.
88de81e71eSTim Marsland  *		-kC -- set the kill character to C on all terminals.
89de81e71eSTim Marsland  *			Default for C is control-U.  If not specified,
90de81e71eSTim Marsland  *			the kill character is untouched; however, if
91de81e71eSTim Marsland  *			not specified and the kill character is NULL
92de81e71eSTim Marsland  *			(zero byte), the kill character is set to CKILL.
93de81e71eSTim Marsland  *		-iC -- set the interrupt character to C on all terminals.
94de81e71eSTim Marsland  *			Default for C is control-C.  If not specified, the
95de81e71eSTim Marsland  *			interrupt character is untouched; however, if
96de81e71eSTim Marsland  *			not specified and the interrupt character is NULL
97de81e71eSTim Marsland  *			(zero byte), the interrupt character is set to
98de81e71eSTim Marsland  *			control-C.
99de81e71eSTim Marsland  *		-qC -- reserved for setable quit character.
100de81e71eSTim Marsland  *		-m -- map the system identified type to some user
101de81e71eSTim Marsland  *			specified type. The mapping can be baud rate
102de81e71eSTim Marsland  *			dependent. This replaces the old -d, -p flags.
103de81e71eSTim Marsland  *			(-d type  ->  -m dialup:type)
104de81e71eSTim Marsland  *			(-p type  ->  -m plug:type)
105de81e71eSTim Marsland  *			Syntax:	-m identifier [test baudrate] :type
106de81e71eSTim Marsland  *			where: ``identifier'' is terminal type found in
107de81e71eSTim Marsland  *			/etc/ttys for this port, (abscence of an identifier
108de81e71eSTim Marsland  *			matches any identifier); ``test'' may be any combination
109de81e71eSTim Marsland  *			of  >  =  <  !  @; ``baudrate'' is as with stty(1);
110de81e71eSTim Marsland  *			``type'' is the actual terminal type to use if the
111de81e71eSTim Marsland  *			mapping condition is met. Multiple maps are scanned
112de81e71eSTim Marsland  *			in order and the first match prevails.
113de81e71eSTim Marsland  *		-n -- If the new tty driver from UCB is available, this flag
114de81e71eSTim Marsland  *			will activate the new options for erase and kill
115de81e71eSTim Marsland  *			processing. This will be different for printers
116de81e71eSTim Marsland  *			and crt's. For crts, if the baud rate is < 1200 then
117de81e71eSTim Marsland  *			erase and kill don't remove characters from the screen.
118de81e71eSTim Marsland  *		-h -- don't read htmp file.  Normally the terminal type
119de81e71eSTim Marsland  *			is determined by reading the htmp file or the
120de81e71eSTim Marsland  *			environment (unless some mapping is specified).
121de81e71eSTim Marsland  *			This forces a read of the ttytype file -- useful
122de81e71eSTim Marsland  *			when htmp is somehow wrong. (V6 only)
123de81e71eSTim Marsland  *		-u -- don't update htmp.  It seemed like this should
124de81e71eSTim Marsland  *			be put in.  Note that htmp is never actually
125de81e71eSTim Marsland  *			written if there are no changes, so don't bother
126de81e71eSTim Marsland  *			bother using this for efficiency reasons alone.
127de81e71eSTim Marsland  *		-s -- output setenv commands for TERM.  This can be
128de81e71eSTim Marsland  *			used with
129de81e71eSTim Marsland  *				`tset -s ...`
130de81e71eSTim Marsland  *			and is to be prefered to:
131de81e71eSTim Marsland  *				setenv TERM `tset - ...`
132de81e71eSTim Marsland  *			because -s sets the TERMCAP variable also.
133de81e71eSTim Marsland  *		-S -- Similar to -s but outputs 2 strings suitable for
134de81e71eSTim Marsland  *			use in csh .login files as follows:
135de81e71eSTim Marsland  *				set noglob
136de81e71eSTim Marsland  *				set term=(`tset -S .....`)
137de81e71eSTim Marsland  *				setenv TERM $term[1]
138de81e71eSTim Marsland  *				setenv TERMCAP "$term[2]"
139de81e71eSTim Marsland  *				unset term
140de81e71eSTim Marsland  *				unset noglob
141de81e71eSTim Marsland  *		-Q -- be quiet.  don't output 'Erase set to' etc.
142de81e71eSTim Marsland  *		-I -- don't do terminal initialization (is & if
143de81e71eSTim Marsland  *			strings).
144de81e71eSTim Marsland  *		-v -- On virtual terminal systems, don't set up a
145de81e71eSTim Marsland  *			virtual terminal.  Otherwise tset will tell
146de81e71eSTim Marsland  *			the operating system what kind of terminal you
147de81e71eSTim Marsland  *			are on (if it is a known terminal) and fix up
148de81e71eSTim Marsland  *			the output of -s to use virtual terminal sequences.
149de81e71eSTim Marsland  *
150de81e71eSTim Marsland  *	Files:
151de81e71eSTim Marsland  *		/etc/ttys
152de81e71eSTim Marsland  *			contains a terminal id -> terminal type
153de81e71eSTim Marsland  *			mapping; used when any user mapping is specified,
154de81e71eSTim Marsland  *			or the environment doesn't have TERM set.
155de81e71eSTim Marsland  *		/etc/termcap
156de81e71eSTim Marsland  *			a terminal_type -> terminal_capabilities
157de81e71eSTim Marsland  *			mapping.
158de81e71eSTim Marsland  *
159de81e71eSTim Marsland  *	Return Codes:
160de81e71eSTim Marsland  *		-1 -- couldn't open termcap.
161de81e71eSTim Marsland  *		1 -- bad terminal type, or standard output not tty.
162de81e71eSTim Marsland  *		0 -- ok.
163de81e71eSTim Marsland  *
164de81e71eSTim Marsland  *	Defined Constants:
165de81e71eSTim Marsland  *		DIALUP -- the type code for a dialup port.
166de81e71eSTim Marsland  *		PLUGBOARD -- the type code for a plugboard port.
167de81e71eSTim Marsland  *		ARPANET -- the type code for an arpanet port.
168de81e71eSTim Marsland  *		BACKSPACE -- control-H, the default for -e.
169de81e71eSTim Marsland  *		CNTL('U') -- control-U, the default for -k.
170de81e71eSTim Marsland  *		OLDERASE -- the ancient default erase character.
171de81e71eSTim Marsland  *		FILEDES -- the file descriptor to do the operation
172de81e71eSTim Marsland  *			on, nominally 1 or 2.
173de81e71eSTim Marsland  *		STDOUT -- the standard output file descriptor.
174de81e71eSTim Marsland  *		UIDMASK -- the bit pattern to mask with the getuid()
175de81e71eSTim Marsland  *			call to get just the user id.
176de81e71eSTim Marsland  *		GTTYN -- defines file containing generalized ttynames
177de81e71eSTim Marsland  *			and compiles code to look there.
178de81e71eSTim Marsland  *
179de81e71eSTim Marsland  *	Requires:
180de81e71eSTim Marsland  *		Routines to handle htmp, ttys, and termcap.
181de81e71eSTim Marsland  *
182de81e71eSTim Marsland  *	Compilation Flags:
183de81e71eSTim Marsland  *		OLDFLAGS -- must be defined to compile code for any of
184de81e71eSTim Marsland  *			the -d, -p, or -a flags.
185de81e71eSTim Marsland  *		OLDDIALUP -- accept the -d flag.
186de81e71eSTim Marsland  *		OLDPLUGBOARD -- accept the -p flag.
187de81e71eSTim Marsland  *		OLDARPANET -- accept the -a flag.
188de81e71eSTim Marsland  *		V6 -- if clear, use environments, not htmp.
189de81e71eSTim Marsland  *			also use TIOCSETN rather than stty to avoid flushing
190de81e71eSTim Marsland  *		GTTYN -- if set, compiles code to look at /etc/ttys.
191de81e71eSTim Marsland  *
192de81e71eSTim Marsland  *	Trace Flags:
193de81e71eSTim Marsland  *		none
194de81e71eSTim Marsland  *
195de81e71eSTim Marsland  *	Diagnostics:
196de81e71eSTim Marsland  *		Bad flag
197de81e71eSTim Marsland  *			An incorrect option was specified.
198de81e71eSTim Marsland  *		Too few args
199de81e71eSTim Marsland  *			more command line arguments are required.
200de81e71eSTim Marsland  *		Unexpected arg
201de81e71eSTim Marsland  *			wrong type of argument was encountered.
202de81e71eSTim Marsland  *		Cannot open ...
203de81e71eSTim Marsland  *			The specified file could not be openned.
204de81e71eSTim Marsland  *		Type ... unknown
205de81e71eSTim Marsland  *			An unknown terminal type was specified.
206de81e71eSTim Marsland  *		Cannot update htmp
207de81e71eSTim Marsland  *			Cannot update htmp file when the standard
208de81e71eSTim Marsland  *			output is not a terminal.
209de81e71eSTim Marsland  *		Erase set to ...
210de81e71eSTim Marsland  *			Telling that the erase character has been
211de81e71eSTim Marsland  *			set to the specified character.
212de81e71eSTim Marsland  *		Kill set to ...
213de81e71eSTim Marsland  *			Ditto for kill
214de81e71eSTim Marsland  *		Erase is ...    Kill is ...
215de81e71eSTim Marsland  *			Tells that the erase/kill characters were
216de81e71eSTim Marsland  *			wierd before, but they are being left as-is.
217de81e71eSTim Marsland  *		Not a terminal
218de81e71eSTim Marsland  *			Set if FILEDES is not a terminal.
219de81e71eSTim Marsland  *
220de81e71eSTim Marsland  *	Compilation Instructions:
221de81e71eSTim Marsland  *		cc -n -O tset.c -ltermlib
222de81e71eSTim Marsland  *		mv a.out tset
223de81e71eSTim Marsland  *		chown bin tset
224de81e71eSTim Marsland  *		chmod 4755 tset
225de81e71eSTim Marsland  *
226de81e71eSTim Marsland  *		where 'bin' should be whoever owns the 'htmp' file.
227de81e71eSTim Marsland  *		If 'htmp' is 666, then tset need not be setuid.
228de81e71eSTim Marsland  *
229de81e71eSTim Marsland  *		For version 6 the compile command should be:
230de81e71eSTim Marsland  *		cc -n -O -I/usr/include/retrofit tset.c -ltermlib -lretro -lS
231de81e71eSTim Marsland  *
232de81e71eSTim Marsland  *
233de81e71eSTim Marsland  *	History:
234de81e71eSTim Marsland  *		1/81 -- Added alias checking for mapping identifiers.
235de81e71eSTim Marsland  *		7/80 -- '-S' added. '-m' mapping added. TERMCAP string
236de81e71eSTim Marsland  *			cleaned up.
237de81e71eSTim Marsland  *		3/80 -- Changed to use tputs.  Prc & flush added.
238de81e71eSTim Marsland  *		10/79 -- '-s' option extended to handle TERMCAP
239de81e71eSTim Marsland  *			variable, set noglob, quote the entry,
240de81e71eSTim Marsland  *			and know about the Bourne shell.  Terminal
241de81e71eSTim Marsland  *			initialization moved to before any information
242de81e71eSTim Marsland  *			output so screen clears would not screw you.
243de81e71eSTim Marsland  *			'-Q' option added.
244de81e71eSTim Marsland  *		8/79 -- '-' option alone changed to only output
245de81e71eSTim Marsland  *			type.  '-s' option added.  'VERSION7'
246de81e71eSTim Marsland  *			changed to 'V6' for compatibility.
247de81e71eSTim Marsland  *		12/78 -- modified for eventual migration to VAX/UNIX,
248de81e71eSTim Marsland  *			so the '-' option is changed to output only
249de81e71eSTim Marsland  *			the terminal type to STDOUT instead of
250de81e71eSTim Marsland  *			FILEDES.
251de81e71eSTim Marsland  *		9/78 -- '-' and '-p' options added (now fully
252de81e71eSTim Marsland  *			compatible with ttytype!), and spaces are
253de81e71eSTim Marsland  *			permitted between the -d and the type.
254de81e71eSTim Marsland  *		8/78 -- The sense of -h and -u were reversed, and the
255de81e71eSTim Marsland  *			-f flag is dropped -- same effect is available
256de81e71eSTim Marsland  *			by just stating the terminal type.
257de81e71eSTim Marsland  *		10/77 -- Written.
258de81e71eSTim Marsland  */
259de81e71eSTim Marsland 
260de81e71eSTim Marsland 
261de81e71eSTim Marsland #define	index strchr
262de81e71eSTim Marsland #define	rindex strrchr
263de81e71eSTim Marsland #define	curerase modes.c_cc[VERASE]
264de81e71eSTim Marsland #define	curkill modes.c_cc[VKILL]
265de81e71eSTim Marsland #define	curintr modes.c_cc[VINTR]
266de81e71eSTim Marsland #define	olderase oldmodes.c_cc[VERASE]
267de81e71eSTim Marsland #define	oldkill oldmodes.c_cc[VKILL]
268de81e71eSTim Marsland #define	oldintr oldmodes.c_cc[VINTR]
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate #include	<stdio.h>
271*566b4223SToomas Soome #include	<stdlib.h>
2727c478bd9Sstevel@tonic-gate #include	<termio.h>
2737c478bd9Sstevel@tonic-gate #include	<signal.h>
2747c478bd9Sstevel@tonic-gate 
2757c478bd9Sstevel@tonic-gate 
2767c478bd9Sstevel@tonic-gate #define	YES		1
2777c478bd9Sstevel@tonic-gate #define	NO		0
2787c478bd9Sstevel@tonic-gate #undef CNTL
2797c478bd9Sstevel@tonic-gate #define	CNTL(c)		((c)&037)
2807c478bd9Sstevel@tonic-gate #define	BACKSPACE	(CNTL('H'))
2817c478bd9Sstevel@tonic-gate #define	isdigit(c)	(c >= '0' && c <= '9')
2827c478bd9Sstevel@tonic-gate #define	isalnum(c)	(c > ' ' && (index("<@=>!:|\177", c) == NULL))
2837c478bd9Sstevel@tonic-gate #define	OLDERASE	'#'
2847c478bd9Sstevel@tonic-gate 
2857c478bd9Sstevel@tonic-gate /* default special characters */
2867c478bd9Sstevel@tonic-gate #ifndef CERASE
2877c478bd9Sstevel@tonic-gate #define	CERASE	'\177'
2887c478bd9Sstevel@tonic-gate #endif
2897c478bd9Sstevel@tonic-gate #ifndef CKILL
2907c478bd9Sstevel@tonic-gate #define	CKILL	CNTL('U')
2917c478bd9Sstevel@tonic-gate #endif
2927c478bd9Sstevel@tonic-gate #ifndef CINTR
2937c478bd9Sstevel@tonic-gate #define	CINTR	CNTL('C')
2947c478bd9Sstevel@tonic-gate #endif
2957c478bd9Sstevel@tonic-gate #ifndef CDSUSP
2967c478bd9Sstevel@tonic-gate #define	CQUIT	034		/* FS, ^\ */
2977c478bd9Sstevel@tonic-gate #define	CSTART	CNTL('Q')
2987c478bd9Sstevel@tonic-gate #define	CSTOP	CNTL('S')
2997c478bd9Sstevel@tonic-gate #define	CEOF	CNTL('D')
3007c478bd9Sstevel@tonic-gate #define	CEOT	CEOF
3017c478bd9Sstevel@tonic-gate #define	CBRK	0377
3027c478bd9Sstevel@tonic-gate #define	CSUSP	CNTL('Z')
3037c478bd9Sstevel@tonic-gate #define	CDSUSP	CNTL('Y')
3047c478bd9Sstevel@tonic-gate #define	CRPRNT	CNTL('R')
3057c478bd9Sstevel@tonic-gate #define	CFLUSH	CNTL('O')
3067c478bd9Sstevel@tonic-gate #define	CWERASE	CNTL('W')
3077c478bd9Sstevel@tonic-gate #define	CLNEXT	CNTL('V')
3087c478bd9Sstevel@tonic-gate #endif
3097c478bd9Sstevel@tonic-gate 
3107c478bd9Sstevel@tonic-gate #define	FILEDES		2	/* do gtty/stty on this descriptor */
3117c478bd9Sstevel@tonic-gate #define	STDOUT		1	/* output of -s/-S to this descriptor */
3127c478bd9Sstevel@tonic-gate 
3137c478bd9Sstevel@tonic-gate #define	UIDMASK		-1
3147c478bd9Sstevel@tonic-gate 
315de81e71eSTim Marsland #define	USAGE	"usage: tset [-] [-rsIQS] [-eC] [-kC] "	\
316de81e71eSTim Marsland 		"[-iC] [-m [ident][test speed]:type] [type]\n"
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate #define	OLDFLAGS
3197c478bd9Sstevel@tonic-gate #define	DIALUP		"dialup"
3207c478bd9Sstevel@tonic-gate #define	OLDDIALUP	"sd"
3217c478bd9Sstevel@tonic-gate #define	PLUGBOARD	"plugboard"
3227c478bd9Sstevel@tonic-gate #define	OLDPLUGBOARD	"sp"
3237c478bd9Sstevel@tonic-gate 
3247c478bd9Sstevel@tonic-gate #define	DEFTYPE		"unknown"
3257c478bd9Sstevel@tonic-gate 
3267c478bd9Sstevel@tonic-gate /*
3277c478bd9Sstevel@tonic-gate  * Baud Rate Conditionals
3287c478bd9Sstevel@tonic-gate  */
3297c478bd9Sstevel@tonic-gate #define	ANY		0
3307c478bd9Sstevel@tonic-gate #define	GT		1
3317c478bd9Sstevel@tonic-gate #define	EQ		2
3327c478bd9Sstevel@tonic-gate #define	LT		4
3337c478bd9Sstevel@tonic-gate #define	GE		(GT|EQ)
3347c478bd9Sstevel@tonic-gate #define	LE		(LT|EQ)
3357c478bd9Sstevel@tonic-gate #define	NE		(GT|LT)
3367c478bd9Sstevel@tonic-gate #define	ALL		(GT|EQ|LT)
3377c478bd9Sstevel@tonic-gate 
3387c478bd9Sstevel@tonic-gate 
3397c478bd9Sstevel@tonic-gate 
3407c478bd9Sstevel@tonic-gate #define	NMAP		10
3417c478bd9Sstevel@tonic-gate 
3427c478bd9Sstevel@tonic-gate struct	map {
3437c478bd9Sstevel@tonic-gate 	char *Ident;
3447c478bd9Sstevel@tonic-gate 	char Test;
3457c478bd9Sstevel@tonic-gate 	char Speed;
3467c478bd9Sstevel@tonic-gate 	char *Type;
3477c478bd9Sstevel@tonic-gate } map[NMAP];
3487c478bd9Sstevel@tonic-gate 
3497c478bd9Sstevel@tonic-gate struct map *Map = map;
3507c478bd9Sstevel@tonic-gate 
3517c478bd9Sstevel@tonic-gate /* This should be available in an include file */
3527c478bd9Sstevel@tonic-gate struct
3537c478bd9Sstevel@tonic-gate {
3547c478bd9Sstevel@tonic-gate 	char	*string;
3557c478bd9Sstevel@tonic-gate 	int	speed;
3567c478bd9Sstevel@tonic-gate 	int	baudrate;
3577c478bd9Sstevel@tonic-gate } speeds[] = {
3587c478bd9Sstevel@tonic-gate 	"0",	B0,	0,
3597c478bd9Sstevel@tonic-gate 	"50",	B50,	50,
3607c478bd9Sstevel@tonic-gate 	"75",	B75,	75,
3617c478bd9Sstevel@tonic-gate 	"110",	B110,	110,
3627c478bd9Sstevel@tonic-gate 	"134",	B134,	134,
363de81e71eSTim Marsland 	"134.5", B134,	134,
3647c478bd9Sstevel@tonic-gate 	"150",	B150,	150,
3657c478bd9Sstevel@tonic-gate 	"200",	B200,	200,
3667c478bd9Sstevel@tonic-gate 	"300",	B300,	300,
3677c478bd9Sstevel@tonic-gate 	"600",	B600,	600,
3687c478bd9Sstevel@tonic-gate 	"1200",	B1200,	1200,
3697c478bd9Sstevel@tonic-gate 	"1800",	B1800,	1800,
3707c478bd9Sstevel@tonic-gate 	"2400",	B2400,	2400,
3717c478bd9Sstevel@tonic-gate 	"4800",	B4800,	4800,
3727c478bd9Sstevel@tonic-gate 	"9600",	B9600,	9600,
373de81e71eSTim Marsland 	"19200", EXTA,	19200,
3747c478bd9Sstevel@tonic-gate 	"exta",	EXTA,	19200,
3757c478bd9Sstevel@tonic-gate 	"extb",	EXTB,	38400,
376de81e71eSTim Marsland 	"57600", B57600,	57600,
377de81e71eSTim Marsland 	"76800", B76800,	76800,
378de81e71eSTim Marsland 	"115200", B115200, 115200,
379de81e71eSTim Marsland 	"153600", B153600, 153600,
380de81e71eSTim Marsland 	"230400", B230400, 230400,
381de81e71eSTim Marsland 	"307200", B307200, 307200,
382de81e71eSTim Marsland 	"460800", B460800, 460800,
383de81e71eSTim Marsland 	"921600", B921600, 921600,
3847c478bd9Sstevel@tonic-gate 	0,
3857c478bd9Sstevel@tonic-gate };
3867c478bd9Sstevel@tonic-gate 
3877c478bd9Sstevel@tonic-gate signed char Erase_char;		/* new erase character */
3887c478bd9Sstevel@tonic-gate char	Kill_char;		/* new kill character */
3897c478bd9Sstevel@tonic-gate char	Intr_char;		/* new interrupt character */
390de81e71eSTim Marsland char	Specialerase;	/* set => Erase_char only on terminals with backspace */
3917c478bd9Sstevel@tonic-gate 
3927c478bd9Sstevel@tonic-gate char	*TtyType;		/* type of terminal */
3937c478bd9Sstevel@tonic-gate char	*DefType;		/* default type if none other computed */
3947c478bd9Sstevel@tonic-gate char	*NewType;		/* mapping identifier based on old flags */
3957c478bd9Sstevel@tonic-gate int	Mapped;			/* mapping has been specified */
3967c478bd9Sstevel@tonic-gate int	Dash_u;			/* don't update htmp */
3977c478bd9Sstevel@tonic-gate int	Dash_h;			/* don't read htmp */
3987c478bd9Sstevel@tonic-gate int	DoSetenv;		/* output setenv commands */
3997c478bd9Sstevel@tonic-gate int	BeQuiet;		/* be quiet */
4007c478bd9Sstevel@tonic-gate int	NoInit;			/* don't output initialization string */
4017c478bd9Sstevel@tonic-gate int	IsReset;		/* invoked as reset */
4027c478bd9Sstevel@tonic-gate int	Report;			/* report current type */
4037c478bd9Sstevel@tonic-gate int	Ureport;		/* report to user */
4047c478bd9Sstevel@tonic-gate int	RepOnly;		/* report only */
4057c478bd9Sstevel@tonic-gate int	CmndLine;		/* output full command lines (-s option) */
4067c478bd9Sstevel@tonic-gate int	Ask;			/* ask user for termtype */
4077c478bd9Sstevel@tonic-gate int	DoVirtTerm = YES;	/* Set up a virtual terminal */
4087c478bd9Sstevel@tonic-gate int	PadBaud;		/* Min rate of padding needed */
4097c478bd9Sstevel@tonic-gate 
410de81e71eSTim Marsland #define	CAPBUFSIZ	1024
4117c478bd9Sstevel@tonic-gate char	Capbuf[CAPBUFSIZ];	/* line from /etc/termcap for this TtyType */
4127c478bd9Sstevel@tonic-gate char	*Ttycap;		/* termcap line from termcap or environ */
4137c478bd9Sstevel@tonic-gate 
4147c478bd9Sstevel@tonic-gate char	Aliasbuf[128];
4157c478bd9Sstevel@tonic-gate char	*Alias[16];
4167c478bd9Sstevel@tonic-gate 
4177c478bd9Sstevel@tonic-gate extern char *strcpy();
4187c478bd9Sstevel@tonic-gate extern char *index();
4197c478bd9Sstevel@tonic-gate 
4207c478bd9Sstevel@tonic-gate struct delay
4217c478bd9Sstevel@tonic-gate {
4227c478bd9Sstevel@tonic-gate 	int	d_delay;
4237c478bd9Sstevel@tonic-gate 	int	d_bits;
4247c478bd9Sstevel@tonic-gate };
4257c478bd9Sstevel@tonic-gate 
4267c478bd9Sstevel@tonic-gate #include	"tset.delays.h"
4277c478bd9Sstevel@tonic-gate 
4287c478bd9Sstevel@tonic-gate struct termio	mode;
4297c478bd9Sstevel@tonic-gate struct termio	oldmode;
4307c478bd9Sstevel@tonic-gate struct termios	modes;
4317c478bd9Sstevel@tonic-gate struct termios	oldmodes;
4327c478bd9Sstevel@tonic-gate int		istermios;
4337c478bd9Sstevel@tonic-gate 
434cc6c5292Schin void reportek(char *, char, char, char);
435cc6c5292Schin void setdelay(char *, struct delay [], tcflag_t, tcflag_t *);
436cc6c5292Schin void prs(char *);
437cc6c5292Schin void prc(char);
438cc6c5292Schin void flush(void);
439cc6c5292Schin void cat(char *);
440cc6c5292Schin void bmove(char *, char *, int);
441cc6c5292Schin void makealias(char *);
442cc6c5292Schin void wrtermcap(char *);
443de81e71eSTim Marsland void fatal(char *, char *);
4447c478bd9Sstevel@tonic-gate char reset();			/* Routine for checking&resetting chars */
4457c478bd9Sstevel@tonic-gate 
446cc6c5292Schin int
447cc6c5292Schin main(int argc, char *argv[])
4487c478bd9Sstevel@tonic-gate {
4497c478bd9Sstevel@tonic-gate 	char		buf[CAPBUFSIZ];
4507c478bd9Sstevel@tonic-gate 	char		termbuf[32];
4517c478bd9Sstevel@tonic-gate 	auto char	*bufp;
452cc6c5292Schin 	char		*p;
4537c478bd9Sstevel@tonic-gate 	char		*command;
454cc6c5292Schin 	int		i;
4557c478bd9Sstevel@tonic-gate 	int		Break;
4567c478bd9Sstevel@tonic-gate 	int		Not;
4577c478bd9Sstevel@tonic-gate 	char		*nextarg();
4587c478bd9Sstevel@tonic-gate 	char		*mapped();
4597c478bd9Sstevel@tonic-gate 	extern char	*rindex();
4607c478bd9Sstevel@tonic-gate 	struct winsize	win;
4617c478bd9Sstevel@tonic-gate 	extern char	*getenv();
4627c478bd9Sstevel@tonic-gate 	extern char	*tgetstr();
4637c478bd9Sstevel@tonic-gate 	char		bs_char;
4647c478bd9Sstevel@tonic-gate 	int		csh;
4657c478bd9Sstevel@tonic-gate 	int		settle = NO;
4667c478bd9Sstevel@tonic-gate 	void		setmode();
4677c478bd9Sstevel@tonic-gate 	extern char	PC;
4687c478bd9Sstevel@tonic-gate 	extern short	ospeed;
4697c478bd9Sstevel@tonic-gate 
4707c478bd9Sstevel@tonic-gate 	if ((istermios = ioctl(FILEDES, TCGETS, (char *)&modes)) < 0) {
471de81e71eSTim Marsland 		if (ioctl(FILEDES, TCGETA, (char *)&mode) < 0) {
4727c478bd9Sstevel@tonic-gate 			prs("Not a terminal\n");
4737c478bd9Sstevel@tonic-gate 			exit(1);
4747c478bd9Sstevel@tonic-gate 		}
475de81e71eSTim Marsland 		bmove((char *)&mode, (char *)&oldmode, sizeof (mode));
4767c478bd9Sstevel@tonic-gate 		modes.c_lflag = oldmodes.c_lflag = mode.c_lflag;
4777c478bd9Sstevel@tonic-gate 		modes.c_oflag = oldmodes.c_oflag = mode.c_oflag;
4787c478bd9Sstevel@tonic-gate 		modes.c_iflag = oldmodes.c_iflag = mode.c_iflag;
4797c478bd9Sstevel@tonic-gate 		modes.c_cflag = oldmodes.c_cflag = mode.c_cflag;
480de81e71eSTim Marsland 		for (i = 0; i < NCC; i++)
4817c478bd9Sstevel@tonic-gate 			modes.c_cc[i] = oldmodes.c_cc[i] = mode.c_cc[i];
4827c478bd9Sstevel@tonic-gate 	} else
483de81e71eSTim Marsland 		bmove((char *)&modes, (char *)&oldmodes, sizeof (modes));
4847c478bd9Sstevel@tonic-gate 	ospeed = cfgetospeed(&modes);
4857c478bd9Sstevel@tonic-gate 	(void) signal(SIGINT, setmode);
4867c478bd9Sstevel@tonic-gate 	(void) signal(SIGQUIT, setmode);
4877c478bd9Sstevel@tonic-gate 	(void) signal(SIGTERM, setmode);
4887c478bd9Sstevel@tonic-gate 
4897c478bd9Sstevel@tonic-gate 	if (command = rindex(argv[0], '/'))
4907c478bd9Sstevel@tonic-gate 		command++;
4917c478bd9Sstevel@tonic-gate 	else
4927c478bd9Sstevel@tonic-gate 		command = argv[0];
493de81e71eSTim Marsland 	if (sequal(command, "reset")) {
4947c478bd9Sstevel@tonic-gate 		/*
4957c478bd9Sstevel@tonic-gate 		 * Reset the teletype mode bits to a sensible state.
4967c478bd9Sstevel@tonic-gate 		 * Copied from the program by Kurt Shoens & Mark Horton.
4977c478bd9Sstevel@tonic-gate 		 * Very useful after crapping out in raw.
4987c478bd9Sstevel@tonic-gate 		 */
4997c478bd9Sstevel@tonic-gate 		if ((istermios = ioctl(FILEDES, TCGETS, (char *)&modes)) < 0) {
5007c478bd9Sstevel@tonic-gate 			(void) ioctl(FILEDES, TCGETA, (char *)&mode);
5017c478bd9Sstevel@tonic-gate 			modes.c_lflag = mode.c_lflag;
5027c478bd9Sstevel@tonic-gate 			modes.c_oflag = mode.c_oflag;
5037c478bd9Sstevel@tonic-gate 			modes.c_iflag = mode.c_iflag;
5047c478bd9Sstevel@tonic-gate 			modes.c_cflag = mode.c_cflag;
505de81e71eSTim Marsland 			for (i = 0; i < NCC; i++)
5067c478bd9Sstevel@tonic-gate 				modes.c_cc[i] = mode.c_cc[i];
5077c478bd9Sstevel@tonic-gate 		}
5087c478bd9Sstevel@tonic-gate 		curerase = reset(curerase, CERASE);
5097c478bd9Sstevel@tonic-gate 		curkill = reset(curkill, CKILL);
5107c478bd9Sstevel@tonic-gate 		curintr = reset(curintr, CINTR);
5117c478bd9Sstevel@tonic-gate 		modes.c_cc[VQUIT] = reset(modes.c_cc[VQUIT], CQUIT);
5127c478bd9Sstevel@tonic-gate 		modes.c_cc[VEOF] = reset(modes.c_cc[VEOF], CEOF);
5137c478bd9Sstevel@tonic-gate 
5147c478bd9Sstevel@tonic-gate 		modes.c_iflag |= (BRKINT|ISTRIP|ICRNL|IXON);
5157c478bd9Sstevel@tonic-gate 		modes.c_iflag &= ~(IGNBRK|PARMRK|INPCK|INLCR|IGNCR|IUCLC|IXOFF);
5167c478bd9Sstevel@tonic-gate 		modes.c_oflag |= (OPOST|ONLCR);
5177c478bd9Sstevel@tonic-gate 		modes.c_oflag &= ~(OLCUC|OCRNL|ONOCR|ONLRET|OFILL|OFDEL|
518de81e71eSTim Marsland 		    NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
5197c478bd9Sstevel@tonic-gate 		modes.c_cflag |= (CS7|CREAD);
5207c478bd9Sstevel@tonic-gate 		modes.c_cflag &= ~(PARODD|CLOCAL);
5217c478bd9Sstevel@tonic-gate 		modes.c_lflag |= (ISIG|ICANON|ECHO|ECHOK);
5227c478bd9Sstevel@tonic-gate 		modes.c_lflag &= ~(XCASE|ECHONL|NOFLSH);
523de81e71eSTim Marsland 		if (istermios < 0) {
5247c478bd9Sstevel@tonic-gate 			mode.c_lflag = modes.c_lflag;
5257c478bd9Sstevel@tonic-gate 			mode.c_oflag = modes.c_oflag;
5267c478bd9Sstevel@tonic-gate 			mode.c_iflag = modes.c_iflag;
5277c478bd9Sstevel@tonic-gate 			mode.c_cflag = modes.c_cflag;
528de81e71eSTim Marsland 			for (i = 0; i < NCC; i++)
5297c478bd9Sstevel@tonic-gate 				mode.c_cc[i] = modes.c_cc[i];
5307c478bd9Sstevel@tonic-gate 			(void) ioctl(FILEDES, TCSETAW, (char *)&mode);
5317c478bd9Sstevel@tonic-gate 		} else
5327c478bd9Sstevel@tonic-gate 			(void) ioctl(FILEDES, TCSETSW, (char *)&modes);
5337c478bd9Sstevel@tonic-gate 		Dash_u = YES;
5347c478bd9Sstevel@tonic-gate 		BeQuiet = YES;
5357c478bd9Sstevel@tonic-gate 		IsReset = YES;
536de81e71eSTim Marsland 	} else if (argc == 2 && sequal(argv[1], "-")) {
5377c478bd9Sstevel@tonic-gate 		RepOnly = YES;
5387c478bd9Sstevel@tonic-gate 		Dash_u = YES;
5397c478bd9Sstevel@tonic-gate 	}
5407c478bd9Sstevel@tonic-gate 	argc--;
5417c478bd9Sstevel@tonic-gate 
5427c478bd9Sstevel@tonic-gate 	/* scan argument list and collect flags */
543de81e71eSTim Marsland 	while (--argc >= 0) {
5447c478bd9Sstevel@tonic-gate 		p = *++argv;
545de81e71eSTim Marsland 		if (*p == '-') {
5467c478bd9Sstevel@tonic-gate 			if (*++p == NULL)
5477c478bd9Sstevel@tonic-gate 				Report = YES; /* report current terminal type */
548de81e71eSTim Marsland 			else
549de81e71eSTim Marsland 				while (*p)
550de81e71eSTim Marsland 					switch (*p++) {
5517c478bd9Sstevel@tonic-gate 
552de81e71eSTim Marsland 			case 'r':	/* report to user */
5537c478bd9Sstevel@tonic-gate 				Ureport = YES;
5547c478bd9Sstevel@tonic-gate 				continue;
5557c478bd9Sstevel@tonic-gate 
556de81e71eSTim Marsland 			case 'E':
557de81e71eSTim Marsland 				/* special erase: operate on all but TTY33 */
5587c478bd9Sstevel@tonic-gate 				Specialerase = YES;
5597c478bd9Sstevel@tonic-gate 				/* explicit fall-through to -e case */
560*566b4223SToomas Soome 				/* FALLTHROUGH */
5617c478bd9Sstevel@tonic-gate 
562de81e71eSTim Marsland 			case 'e':	/* erase character */
5637c478bd9Sstevel@tonic-gate 				if (*p == NULL)
5647c478bd9Sstevel@tonic-gate 					Erase_char = -1;
565de81e71eSTim Marsland 				else {
5667c478bd9Sstevel@tonic-gate 					if (*p == '^' && p[1] != NULL)
5677c478bd9Sstevel@tonic-gate 						if (*++p == '?')
5687c478bd9Sstevel@tonic-gate 							Erase_char = '\177';
5697c478bd9Sstevel@tonic-gate 						else
5707c478bd9Sstevel@tonic-gate 							Erase_char = CNTL(*p);
5717c478bd9Sstevel@tonic-gate 					else
5727c478bd9Sstevel@tonic-gate 						Erase_char = *p;
5737c478bd9Sstevel@tonic-gate 					p++;
5747c478bd9Sstevel@tonic-gate 				}
5757c478bd9Sstevel@tonic-gate 				continue;
5767c478bd9Sstevel@tonic-gate 
577de81e71eSTim Marsland 			case 'i':	/* interrupt character */
5787c478bd9Sstevel@tonic-gate 				if (*p == NULL)
5797c478bd9Sstevel@tonic-gate 					Intr_char = CNTL('C');
580de81e71eSTim Marsland 				else {
5817c478bd9Sstevel@tonic-gate 					if (*p == '^' && p[1] != NULL)
5827c478bd9Sstevel@tonic-gate 						if (*++p == '?')
5837c478bd9Sstevel@tonic-gate 							Intr_char = '\177';
5847c478bd9Sstevel@tonic-gate 						else
5857c478bd9Sstevel@tonic-gate 							Intr_char = CNTL(*p);
5867c478bd9Sstevel@tonic-gate 					else
5877c478bd9Sstevel@tonic-gate 						Intr_char = *p;
5887c478bd9Sstevel@tonic-gate 					p++;
5897c478bd9Sstevel@tonic-gate 				}
5907c478bd9Sstevel@tonic-gate 				continue;
5917c478bd9Sstevel@tonic-gate 
592de81e71eSTim Marsland 			case 'k':	/* kill character */
5937c478bd9Sstevel@tonic-gate 				if (*p == NULL)
5947c478bd9Sstevel@tonic-gate 					Kill_char = CNTL('U');
595de81e71eSTim Marsland 				else {
5967c478bd9Sstevel@tonic-gate 					if (*p == '^' && p[1] != NULL)
5977c478bd9Sstevel@tonic-gate 						if (*++p == '?')
5987c478bd9Sstevel@tonic-gate 							Kill_char = '\177';
5997c478bd9Sstevel@tonic-gate 						else
6007c478bd9Sstevel@tonic-gate 							Kill_char = CNTL(*p);
6017c478bd9Sstevel@tonic-gate 					else
6027c478bd9Sstevel@tonic-gate 						Kill_char = *p;
6037c478bd9Sstevel@tonic-gate 					p++;
6047c478bd9Sstevel@tonic-gate 				}
6057c478bd9Sstevel@tonic-gate 				continue;
6067c478bd9Sstevel@tonic-gate 
607de81e71eSTim Marsland #ifdef OLDFLAGS
608de81e71eSTim Marsland #ifdef	OLDDIALUP
609de81e71eSTim Marsland 			case 'd':	/* dialup type */
6107c478bd9Sstevel@tonic-gate 				NewType = DIALUP;
6117c478bd9Sstevel@tonic-gate 				goto mapold;
612de81e71eSTim Marsland #endif
6137c478bd9Sstevel@tonic-gate 
614de81e71eSTim Marsland #ifdef OLDPLUGBOARD
615de81e71eSTim Marsland 			case 'p':	/* plugboard type */
6167c478bd9Sstevel@tonic-gate 				NewType = PLUGBOARD;
6177c478bd9Sstevel@tonic-gate 				goto mapold;
618de81e71eSTim Marsland #endif
6197c478bd9Sstevel@tonic-gate 
620de81e71eSTim Marsland #ifdef OLDARPANET
621de81e71eSTim Marsland 			case 'a':	/* arpanet type */
6227c478bd9Sstevel@tonic-gate 				Newtype = ARPANET;
6237c478bd9Sstevel@tonic-gate 				goto mapold;
624de81e71eSTim Marsland #endif
6257c478bd9Sstevel@tonic-gate 
6267c478bd9Sstevel@tonic-gate mapold:				Map->Ident = NewType;
6277c478bd9Sstevel@tonic-gate 				Map->Test = ALL;
628de81e71eSTim Marsland 				if (*p == NULL) {
6297c478bd9Sstevel@tonic-gate 					p = nextarg(argc--, argv++);
6307c478bd9Sstevel@tonic-gate 				}
6317c478bd9Sstevel@tonic-gate 				Map->Type = p;
6327c478bd9Sstevel@tonic-gate 				Map++;
6337c478bd9Sstevel@tonic-gate 				Mapped = YES;
6347c478bd9Sstevel@tonic-gate 				p = "";
6357c478bd9Sstevel@tonic-gate 				continue;
636de81e71eSTim Marsland #endif
637de81e71eSTim Marsland 
638de81e71eSTim Marsland 			case 'm':	/* map identifier to type */
639de81e71eSTim Marsland 				/*
640de81e71eSTim Marsland 				 * This code is very loose. Almost no
641de81e71eSTim Marsland 				 * syntax checking is done!! However,
642de81e71eSTim Marsland 				 * illegal syntax will only produce
643de81e71eSTim Marsland 				 * weird results.
644de81e71eSTim Marsland 				 */
645de81e71eSTim Marsland 				if (*p == NULL) {
6467c478bd9Sstevel@tonic-gate 					p = nextarg(argc--, argv++);
6477c478bd9Sstevel@tonic-gate 				}
648de81e71eSTim Marsland 				if (isalnum(*p)) {
6497c478bd9Sstevel@tonic-gate 					Map->Ident = p;	/* identifier */
6507c478bd9Sstevel@tonic-gate 					while (isalnum(*p)) p++;
6517c478bd9Sstevel@tonic-gate 				}
6527c478bd9Sstevel@tonic-gate 				else
6537c478bd9Sstevel@tonic-gate 					Map->Ident = "";
6547c478bd9Sstevel@tonic-gate 				Break = NO;
6557c478bd9Sstevel@tonic-gate 				Not = NO;
656de81e71eSTim Marsland 				while (!Break)
657de81e71eSTim Marsland 					switch (*p) {
6587c478bd9Sstevel@tonic-gate 					case NULL:
6597c478bd9Sstevel@tonic-gate 						p = nextarg(argc--, argv++);
6607c478bd9Sstevel@tonic-gate 						continue;
6617c478bd9Sstevel@tonic-gate 
6627c478bd9Sstevel@tonic-gate 					case ':':	/* mapped type */
6637c478bd9Sstevel@tonic-gate 						*p++ = NULL;
6647c478bd9Sstevel@tonic-gate 						Break = YES;
6657c478bd9Sstevel@tonic-gate 						continue;
6667c478bd9Sstevel@tonic-gate 
6677c478bd9Sstevel@tonic-gate 					case '>':	/* conditional */
6687c478bd9Sstevel@tonic-gate 						Map->Test |= GT;
6697c478bd9Sstevel@tonic-gate 						*p++ = NULL;
6707c478bd9Sstevel@tonic-gate 						continue;
6717c478bd9Sstevel@tonic-gate 
6727c478bd9Sstevel@tonic-gate 					case '<':	/* conditional */
6737c478bd9Sstevel@tonic-gate 						Map->Test |= LT;
6747c478bd9Sstevel@tonic-gate 						*p++ = NULL;
6757c478bd9Sstevel@tonic-gate 						continue;
6767c478bd9Sstevel@tonic-gate 
6777c478bd9Sstevel@tonic-gate 					case '=':	/* conditional */
6787c478bd9Sstevel@tonic-gate 					case '@':
6797c478bd9Sstevel@tonic-gate 						Map->Test |= EQ;
6807c478bd9Sstevel@tonic-gate 						*p++ = NULL;
6817c478bd9Sstevel@tonic-gate 						continue;
682de81e71eSTim Marsland 
6837c478bd9Sstevel@tonic-gate 					case '!':	/* invert conditions */
6847c478bd9Sstevel@tonic-gate 						Not = ~Not;
6857c478bd9Sstevel@tonic-gate 						*p++ = NULL;
6867c478bd9Sstevel@tonic-gate 						continue;
6877c478bd9Sstevel@tonic-gate 
6887c478bd9Sstevel@tonic-gate 					case 'B':	/* Baud rate */
6897c478bd9Sstevel@tonic-gate 						p++;
6907c478bd9Sstevel@tonic-gate 						/* intentional fallthru */
6917c478bd9Sstevel@tonic-gate 					default:
692de81e71eSTim Marsland 						if (isdigit(*p) || *p == 'e') {
693de81e71eSTim Marsland 							Map->Speed =
694de81e71eSTim Marsland 							    baudrate(p);
695de81e71eSTim Marsland 							while (isalnum(*p) ||
696de81e71eSTim Marsland 							    *p == '.')
6977c478bd9Sstevel@tonic-gate 								p++;
698de81e71eSTim Marsland 						} else
6997c478bd9Sstevel@tonic-gate 							Break = YES;
7007c478bd9Sstevel@tonic-gate 						continue;
7017c478bd9Sstevel@tonic-gate 				}
702de81e71eSTim Marsland 				if (Not) {	/* invert sense of test */
7037c478bd9Sstevel@tonic-gate 					Map->Test = (~(Map->Test))&ALL;
7047c478bd9Sstevel@tonic-gate 				}
705de81e71eSTim Marsland 				if (*p == NULL) {
7067c478bd9Sstevel@tonic-gate 					p = nextarg(argc--, argv++);
7077c478bd9Sstevel@tonic-gate 				}
7087c478bd9Sstevel@tonic-gate 				Map->Type = p;
7097c478bd9Sstevel@tonic-gate 				p = "";
7107c478bd9Sstevel@tonic-gate 				Map++;
7117c478bd9Sstevel@tonic-gate 				Mapped = YES;
7127c478bd9Sstevel@tonic-gate 				continue;
7137c478bd9Sstevel@tonic-gate 
714de81e71eSTim Marsland 			case 'h':	/* don't get type from htmp or env */
7157c478bd9Sstevel@tonic-gate 				Dash_h = YES;
7167c478bd9Sstevel@tonic-gate 				continue;
7177c478bd9Sstevel@tonic-gate 
718de81e71eSTim Marsland 			case 'u':	/* don't update htmp */
7197c478bd9Sstevel@tonic-gate 				Dash_u = YES;
7207c478bd9Sstevel@tonic-gate 				continue;
7217c478bd9Sstevel@tonic-gate 
722de81e71eSTim Marsland 			case 's':	/* output setenv commands */
7237c478bd9Sstevel@tonic-gate 				DoSetenv = YES;
7247c478bd9Sstevel@tonic-gate 				CmndLine = YES;
7257c478bd9Sstevel@tonic-gate 				continue;
7267c478bd9Sstevel@tonic-gate 
727de81e71eSTim Marsland 			case 'S':	/* output setenv strings */
7287c478bd9Sstevel@tonic-gate 				DoSetenv = YES;
7297c478bd9Sstevel@tonic-gate 				CmndLine = NO;
7307c478bd9Sstevel@tonic-gate 				continue;
7317c478bd9Sstevel@tonic-gate 
732de81e71eSTim Marsland 			case 'Q':	/* be quiet */
7337c478bd9Sstevel@tonic-gate 				BeQuiet = YES;
7347c478bd9Sstevel@tonic-gate 				continue;
7357c478bd9Sstevel@tonic-gate 
736de81e71eSTim Marsland 			case 'I':	/* no initialization */
7377c478bd9Sstevel@tonic-gate 				NoInit = YES;
7387c478bd9Sstevel@tonic-gate 				continue;
7397c478bd9Sstevel@tonic-gate 
740de81e71eSTim Marsland 			case 'A':	/* Ask user */
7417c478bd9Sstevel@tonic-gate 				Ask = YES;
7427c478bd9Sstevel@tonic-gate 				continue;
743de81e71eSTim Marsland 
744de81e71eSTim Marsland 			case 'v':	/* no virtual terminal */
7457c478bd9Sstevel@tonic-gate 				DoVirtTerm = NO;
7467c478bd9Sstevel@tonic-gate 				continue;
7477c478bd9Sstevel@tonic-gate 
748de81e71eSTim Marsland 			default:
7497c478bd9Sstevel@tonic-gate 				*p-- = NULL;
7507c478bd9Sstevel@tonic-gate 				fatal("Bad flag -", p);
7517c478bd9Sstevel@tonic-gate 			}
752de81e71eSTim Marsland 		} else {
7537c478bd9Sstevel@tonic-gate 			/* terminal type */
7547c478bd9Sstevel@tonic-gate 			DefType = p;
7557c478bd9Sstevel@tonic-gate 		}
7567c478bd9Sstevel@tonic-gate 	}
7577c478bd9Sstevel@tonic-gate 
758de81e71eSTim Marsland 	if (DefType) {
759de81e71eSTim Marsland 		if (Mapped) {
7607c478bd9Sstevel@tonic-gate 			Map->Ident = "";	/* means "map any type" */
7617c478bd9Sstevel@tonic-gate 			Map->Test = ALL;	/* at all baud rates */
7627c478bd9Sstevel@tonic-gate 			Map->Type = DefType;	/* to the default type */
763de81e71eSTim Marsland 		} else
7647c478bd9Sstevel@tonic-gate 			TtyType = DefType;
7657c478bd9Sstevel@tonic-gate 	}
7667c478bd9Sstevel@tonic-gate 
7677c478bd9Sstevel@tonic-gate 	/*
7687c478bd9Sstevel@tonic-gate 	 * Get rid of $TERMCAP, if it's there, so we get a real
7697c478bd9Sstevel@tonic-gate 	 * entry from /etc/termcap.  This prevents us from being
7707c478bd9Sstevel@tonic-gate 	 * fooled by out of date stuff in the environment, and
7717c478bd9Sstevel@tonic-gate 	 * makes tabs work right on CB/Unix.
7727c478bd9Sstevel@tonic-gate 	 */
7737c478bd9Sstevel@tonic-gate 	bufp = getenv("TERMCAP");
7747c478bd9Sstevel@tonic-gate 	if (bufp && *bufp != '/')
7757c478bd9Sstevel@tonic-gate 		(void) strcpy(bufp-8, "NOTHING"); /* overwrite only "TERMCAP" */
7767c478bd9Sstevel@tonic-gate 	/* get current idea of terminal type from environment */
777*566b4223SToomas Soome 	if (!Dash_h && TtyType == NULL)
7787c478bd9Sstevel@tonic-gate 		TtyType = getenv("TERM");
7797c478bd9Sstevel@tonic-gate 
7807c478bd9Sstevel@tonic-gate 	/* If still undefined, use DEFTYPE */
781*566b4223SToomas Soome 	if (TtyType == NULL) {
7827c478bd9Sstevel@tonic-gate 		TtyType = DEFTYPE;
7837c478bd9Sstevel@tonic-gate 	}
7847c478bd9Sstevel@tonic-gate 
7857c478bd9Sstevel@tonic-gate 	/* check for dialup or other mapping */
786de81e71eSTim Marsland 	if (Mapped) {
7877c478bd9Sstevel@tonic-gate 		if (!(Alias[0] && isalias(TtyType)))
7887c478bd9Sstevel@tonic-gate 			if (tgetent(Capbuf, TtyType) > 0)
7897c478bd9Sstevel@tonic-gate 				makealias(Capbuf);
7907c478bd9Sstevel@tonic-gate 		TtyType = mapped(TtyType);
7917c478bd9Sstevel@tonic-gate 	}
7927c478bd9Sstevel@tonic-gate 
7937c478bd9Sstevel@tonic-gate 	/* TtyType now contains a pointer to the type of the terminal */
7947c478bd9Sstevel@tonic-gate 	/* If the first character is '?', ask the user */
795de81e71eSTim Marsland 	if (TtyType[0] == '?') {
7967c478bd9Sstevel@tonic-gate 		Ask = YES;
7977c478bd9Sstevel@tonic-gate 		TtyType++;
7987c478bd9Sstevel@tonic-gate 		if (TtyType[0] == '\0')
7997c478bd9Sstevel@tonic-gate 			TtyType = DEFTYPE;
8007c478bd9Sstevel@tonic-gate 	}
801de81e71eSTim Marsland 	if (Ask) {
8027c478bd9Sstevel@tonic-gate ask:
8037c478bd9Sstevel@tonic-gate 		prs("TERM = (");
8047c478bd9Sstevel@tonic-gate 		prs(TtyType);
8057c478bd9Sstevel@tonic-gate 		prs(") ");
8067c478bd9Sstevel@tonic-gate 		flush();
8077c478bd9Sstevel@tonic-gate 
8087c478bd9Sstevel@tonic-gate 		/* read the terminal.  If not empty, set type */
809de81e71eSTim Marsland 		i = read(2, termbuf, sizeof (termbuf) - 1);
810de81e71eSTim Marsland 		if (i > 0) {
8117c478bd9Sstevel@tonic-gate 			if (termbuf[i - 1] == '\n')
8127c478bd9Sstevel@tonic-gate 				i--;
8137c478bd9Sstevel@tonic-gate 			termbuf[i] = '\0';
8147c478bd9Sstevel@tonic-gate 			if (termbuf[0] != '\0')
8157c478bd9Sstevel@tonic-gate 				TtyType = termbuf;
8167c478bd9Sstevel@tonic-gate 		}
8177c478bd9Sstevel@tonic-gate 	}
8187c478bd9Sstevel@tonic-gate 
8197c478bd9Sstevel@tonic-gate 	/* get terminal capabilities */
8207c478bd9Sstevel@tonic-gate 	if (!(Alias[0] && isalias(TtyType))) {
821de81e71eSTim Marsland 		switch (tgetent(Capbuf, TtyType)) {
822de81e71eSTim Marsland 		case -1:
8237c478bd9Sstevel@tonic-gate 			prs("Cannot find termcap\n");
8247c478bd9Sstevel@tonic-gate 			flush();
8257c478bd9Sstevel@tonic-gate 			exit(-1);
8267c478bd9Sstevel@tonic-gate 
827de81e71eSTim Marsland 		case 0:
8287c478bd9Sstevel@tonic-gate 			prs("Type ");
8297c478bd9Sstevel@tonic-gate 			prs(TtyType);
8307c478bd9Sstevel@tonic-gate 			prs(" unknown\n");
8317c478bd9Sstevel@tonic-gate 			flush();
832de81e71eSTim Marsland 			if (DoSetenv) {
8337c478bd9Sstevel@tonic-gate 				TtyType = DEFTYPE;
8347c478bd9Sstevel@tonic-gate 				Alias[0] = '\0';
8357c478bd9Sstevel@tonic-gate 				goto ask;
836de81e71eSTim Marsland 			} else
8377c478bd9Sstevel@tonic-gate 				exit(1);
8387c478bd9Sstevel@tonic-gate 		}
8397c478bd9Sstevel@tonic-gate 	}
8407c478bd9Sstevel@tonic-gate 	Ttycap = Capbuf;
8417c478bd9Sstevel@tonic-gate 
842de81e71eSTim Marsland 	if (!RepOnly) {
8437c478bd9Sstevel@tonic-gate 		/* determine erase and kill characters */
8447c478bd9Sstevel@tonic-gate 		if (Specialerase && !tgetflag("bs"))
8457c478bd9Sstevel@tonic-gate 			Erase_char = 0;
8467c478bd9Sstevel@tonic-gate 		bufp = buf;
8477c478bd9Sstevel@tonic-gate 		p = tgetstr("kb", &bufp);
8487c478bd9Sstevel@tonic-gate 		if (p == NULL || p[1] != '\0')
8497c478bd9Sstevel@tonic-gate 			p = tgetstr("bc", &bufp);
8507c478bd9Sstevel@tonic-gate 		if (p != NULL && p[1] == '\0')
8517c478bd9Sstevel@tonic-gate 			bs_char = p[0];
8527c478bd9Sstevel@tonic-gate 		else if (tgetflag("bs"))
8537c478bd9Sstevel@tonic-gate 			bs_char = BACKSPACE;
8547c478bd9Sstevel@tonic-gate 		else
8557c478bd9Sstevel@tonic-gate 			bs_char = 0;
8567c478bd9Sstevel@tonic-gate 		/*
8577c478bd9Sstevel@tonic-gate 		 * The next statement can't be fixed, because now users
8587c478bd9Sstevel@tonic-gate 		 * depend on keeping their erase character as DEL if the
8597c478bd9Sstevel@tonic-gate 		 * system set it there.  People who want backspace have
8607c478bd9Sstevel@tonic-gate 		 * to say tset -e.
8617c478bd9Sstevel@tonic-gate 		 */
862de81e71eSTim Marsland 		if (Erase_char == 0 && !tgetflag("os") &&
863de81e71eSTim Marsland 		    curerase == OLDERASE) {
8647c478bd9Sstevel@tonic-gate 			if (tgetflag("bs") || bs_char != 0)
8657c478bd9Sstevel@tonic-gate 				Erase_char = -1;
8667c478bd9Sstevel@tonic-gate 		}
8677c478bd9Sstevel@tonic-gate 		if (Erase_char < 0)
8687c478bd9Sstevel@tonic-gate 			Erase_char = (bs_char != 0) ? bs_char : BACKSPACE;
8697c478bd9Sstevel@tonic-gate 
8707c478bd9Sstevel@tonic-gate 		if (curerase == 0)
8717c478bd9Sstevel@tonic-gate 			curerase = CERASE;
8727c478bd9Sstevel@tonic-gate 		if (Erase_char != 0)
8737c478bd9Sstevel@tonic-gate 			curerase = Erase_char;
8747c478bd9Sstevel@tonic-gate 
8757c478bd9Sstevel@tonic-gate 		if (curintr == 0)
8767c478bd9Sstevel@tonic-gate 			curintr = CINTR;
8777c478bd9Sstevel@tonic-gate 		if (Intr_char != 0)
8787c478bd9Sstevel@tonic-gate 			curintr = Intr_char;
8797c478bd9Sstevel@tonic-gate 
8807c478bd9Sstevel@tonic-gate 		if (curkill == 0)
8817c478bd9Sstevel@tonic-gate 			curkill = CKILL;
8827c478bd9Sstevel@tonic-gate 		if (Kill_char != 0)
8837c478bd9Sstevel@tonic-gate 			curkill = Kill_char;
8847c478bd9Sstevel@tonic-gate 
8857c478bd9Sstevel@tonic-gate 		/* set modes */
8867c478bd9Sstevel@tonic-gate 		PadBaud = tgetnum("pb");	/* OK if fails */
887de81e71eSTim Marsland 		for (i = 0; speeds[i].string; i++)
8887c478bd9Sstevel@tonic-gate 			if (speeds[i].baudrate == PadBaud) {
8897c478bd9Sstevel@tonic-gate 				PadBaud = speeds[i].speed;
8907c478bd9Sstevel@tonic-gate 				break;
8917c478bd9Sstevel@tonic-gate 			}
8927c478bd9Sstevel@tonic-gate 		setdelay("dC", CRdelay, CRbits, &modes.c_oflag);
8937c478bd9Sstevel@tonic-gate 		setdelay("dN", NLdelay, NLbits, &modes.c_oflag);
8947c478bd9Sstevel@tonic-gate 		setdelay("dB", BSdelay, BSbits, &modes.c_oflag);
8957c478bd9Sstevel@tonic-gate 		setdelay("dF", FFdelay, FFbits, &modes.c_oflag);
8967c478bd9Sstevel@tonic-gate 		setdelay("dT", TBdelay, TBbits, &modes.c_oflag);
8977c478bd9Sstevel@tonic-gate 		setdelay("dV", VTdelay, VTbits, &modes.c_oflag);
8987c478bd9Sstevel@tonic-gate 
8997c478bd9Sstevel@tonic-gate 		if (tgetflag("UC") || (command[0] & 0140) == 0100) {
9007c478bd9Sstevel@tonic-gate 			modes.c_iflag |= IUCLC;
9017c478bd9Sstevel@tonic-gate 			modes.c_oflag |= OLCUC;
9027c478bd9Sstevel@tonic-gate 			modes.c_cflag |= XCASE;
903de81e71eSTim Marsland 		} else if (tgetflag("LC")) {
9047c478bd9Sstevel@tonic-gate 			modes.c_iflag &= ~IUCLC;
9057c478bd9Sstevel@tonic-gate 			modes.c_oflag &= ~OLCUC;
9067c478bd9Sstevel@tonic-gate 			modes.c_cflag &= ~XCASE;
9077c478bd9Sstevel@tonic-gate 		}
9087c478bd9Sstevel@tonic-gate 		modes.c_iflag &= ~(PARMRK|INPCK);
9097c478bd9Sstevel@tonic-gate 		modes.c_lflag |= ICANON;
9107c478bd9Sstevel@tonic-gate 		if (tgetflag("EP")) {
9117c478bd9Sstevel@tonic-gate 			modes.c_iflag |= INPCK;
9127c478bd9Sstevel@tonic-gate 			modes.c_cflag |= PARENB;
9137c478bd9Sstevel@tonic-gate 			modes.c_cflag &= ~PARODD;
9147c478bd9Sstevel@tonic-gate 		}
9157c478bd9Sstevel@tonic-gate 		if (tgetflag("OP")) {
9167c478bd9Sstevel@tonic-gate 			modes.c_iflag |= INPCK;
9177c478bd9Sstevel@tonic-gate 			modes.c_cflag |= PARENB;
9187c478bd9Sstevel@tonic-gate 			modes.c_cflag |= PARODD;
9197c478bd9Sstevel@tonic-gate 		}
9207c478bd9Sstevel@tonic-gate 
9217c478bd9Sstevel@tonic-gate 		modes.c_oflag |= ONLCR;
9227c478bd9Sstevel@tonic-gate 		modes.c_iflag |= ICRNL;
9237c478bd9Sstevel@tonic-gate 		modes.c_lflag |= ECHO;
9247c478bd9Sstevel@tonic-gate 		modes.c_oflag |= TAB3;
9257c478bd9Sstevel@tonic-gate 		if (tgetflag("NL")) {	/* new line, not line feed */
9267c478bd9Sstevel@tonic-gate 			modes.c_oflag &= ~ONLCR;
9277c478bd9Sstevel@tonic-gate 			modes.c_iflag &= ~ICRNL;
9287c478bd9Sstevel@tonic-gate 		}
9297c478bd9Sstevel@tonic-gate 		if (tgetflag("HD"))	/* half duplex */
9307c478bd9Sstevel@tonic-gate 			modes.c_lflag &= ~ECHO;
9317c478bd9Sstevel@tonic-gate 		if (tgetflag("pt"))	/* print tabs */
9327c478bd9Sstevel@tonic-gate 			modes.c_oflag &= ~TAB3;
933de81e71eSTim Marsland 
9347c478bd9Sstevel@tonic-gate 		modes.c_lflag |= (ECHOE|ECHOK);
935de81e71eSTim Marsland 		if (tgetflag("hc")) {	/* set printer modes */
9367c478bd9Sstevel@tonic-gate 			modes.c_lflag &= ~ECHOE;
9377c478bd9Sstevel@tonic-gate 		}
9387c478bd9Sstevel@tonic-gate 
9397c478bd9Sstevel@tonic-gate 		/* get pad character */
9407c478bd9Sstevel@tonic-gate 		bufp = buf;
9417c478bd9Sstevel@tonic-gate 		if (tgetstr("pc", &bufp) != 0)
9427c478bd9Sstevel@tonic-gate 			PC = buf[0];
9437c478bd9Sstevel@tonic-gate 
9447c478bd9Sstevel@tonic-gate 		/* output startup string */
945de81e71eSTim Marsland 		if (!NoInit) {
946de81e71eSTim Marsland 			if (oldmodes.c_oflag&(TAB3|ONLCR|OCRNL|ONLRET)) {
9477c478bd9Sstevel@tonic-gate 				oldmodes.c_oflag &= (TAB3|ONLCR|OCRNL|ONLRET);
9487c478bd9Sstevel@tonic-gate 				setmode(-1);
9497c478bd9Sstevel@tonic-gate 			}
9507c478bd9Sstevel@tonic-gate 			if (settabs()) {
9517c478bd9Sstevel@tonic-gate 				settle = YES;
9527c478bd9Sstevel@tonic-gate 				flush();
9537c478bd9Sstevel@tonic-gate 			}
9547c478bd9Sstevel@tonic-gate 			bufp = buf;
955de81e71eSTim Marsland 			if (IsReset && tgetstr("rs", &bufp) != 0 ||
956de81e71eSTim Marsland 			    tgetstr("is", &bufp) != 0) {
9577c478bd9Sstevel@tonic-gate 				tputs(buf, 0, prc);
9587c478bd9Sstevel@tonic-gate 				settle = YES;
9597c478bd9Sstevel@tonic-gate 				flush();
9607c478bd9Sstevel@tonic-gate 			}
9617c478bd9Sstevel@tonic-gate 			bufp = buf;
9627c478bd9Sstevel@tonic-gate 			if (IsReset && tgetstr("rf", &bufp) != 0 ||
963de81e71eSTim Marsland 			    tgetstr("if", &bufp) != 0) {
9647c478bd9Sstevel@tonic-gate 				cat(buf);
9657c478bd9Sstevel@tonic-gate 				settle = YES;
9667c478bd9Sstevel@tonic-gate 			}
967de81e71eSTim Marsland 			if (settle) {
9687c478bd9Sstevel@tonic-gate 				prc('\r');
9697c478bd9Sstevel@tonic-gate 				if (IsReset)
9707c478bd9Sstevel@tonic-gate 					prc('\n');  /* newline too */
9717c478bd9Sstevel@tonic-gate 				flush();
9727c478bd9Sstevel@tonic-gate 				sleep(1);	/* let terminal settle down */
9737c478bd9Sstevel@tonic-gate 			}
9747c478bd9Sstevel@tonic-gate 		}
9757c478bd9Sstevel@tonic-gate 
9767c478bd9Sstevel@tonic-gate 		setmode(0);	/* set new modes, if they've changed */
9777c478bd9Sstevel@tonic-gate 
9787c478bd9Sstevel@tonic-gate 		/* set up environment for the shell we are using */
9797c478bd9Sstevel@tonic-gate 		/* (this code is rather heuristic, checking for $SHELL */
9807c478bd9Sstevel@tonic-gate 		/* ending in the 3 characters "csh") */
9817c478bd9Sstevel@tonic-gate 		csh = NO;
982de81e71eSTim Marsland 		if (DoSetenv) {
9837c478bd9Sstevel@tonic-gate 			char *sh;
9847c478bd9Sstevel@tonic-gate 
985de81e71eSTim Marsland 			if ((sh = getenv("SHELL")) && (i = strlen(sh)) >= 3) {
986de81e71eSTim Marsland 				if ((csh = sequal(&sh[i-3], "csh")) && CmndLine)
987de81e71eSTim Marsland 					(void) write(STDOUT,
988de81e71eSTim Marsland 					    "set noglob;\n", 12);
989de81e71eSTim Marsland 			}
990de81e71eSTim Marsland 			if (!csh) {	/* running Bourne shell */
991de81e71eSTim Marsland 				(void) write(STDOUT,
992de81e71eSTim Marsland 				    "export TERMCAP TERM;\n", 21);
9937c478bd9Sstevel@tonic-gate 			}
9947c478bd9Sstevel@tonic-gate 		}
9957c478bd9Sstevel@tonic-gate 	}
9967c478bd9Sstevel@tonic-gate 
9977c478bd9Sstevel@tonic-gate 	/* report type if appropriate */
998de81e71eSTim Marsland 	if (DoSetenv || Report || Ureport) {
9997c478bd9Sstevel@tonic-gate 		/* if type is the short name, find first alias (if any) */
10007c478bd9Sstevel@tonic-gate 		makealias(Ttycap);
10017c478bd9Sstevel@tonic-gate 		if (sequal(TtyType, Alias[0]) && Alias[1]) {
10027c478bd9Sstevel@tonic-gate 			TtyType = Alias[1];
10037c478bd9Sstevel@tonic-gate 		}
10047c478bd9Sstevel@tonic-gate 
1005de81e71eSTim Marsland 		if (DoSetenv) {
1006de81e71eSTim Marsland 			if (csh) {
10077c478bd9Sstevel@tonic-gate 				if (CmndLine)
1008de81e71eSTim Marsland 					(void) write(STDOUT,
1009de81e71eSTim Marsland 					    "setenv TERM ", 12);
10107c478bd9Sstevel@tonic-gate 				(void) write(STDOUT, TtyType, strlen(TtyType));
10117c478bd9Sstevel@tonic-gate 				(void) write(STDOUT, " ", 1);
10127c478bd9Sstevel@tonic-gate 				if (CmndLine)
1013de81e71eSTim Marsland 					(void) write(STDOUT, ";\n", 2);
1014de81e71eSTim Marsland 			} else {
10157c478bd9Sstevel@tonic-gate 				(void) write(STDOUT, "TERM=", 5);
10167c478bd9Sstevel@tonic-gate 				(void) write(STDOUT, TtyType, strlen(TtyType));
10177c478bd9Sstevel@tonic-gate 				(void) write(STDOUT, ";\n", 2);
10187c478bd9Sstevel@tonic-gate 			}
1019de81e71eSTim Marsland 		} else if (Report) {
10207c478bd9Sstevel@tonic-gate 			(void) write(STDOUT, TtyType, strlen(TtyType));
10217c478bd9Sstevel@tonic-gate 			(void) write(STDOUT, "\n", 1);
10227c478bd9Sstevel@tonic-gate 		}
1023de81e71eSTim Marsland 		if (Ureport) {
10247c478bd9Sstevel@tonic-gate 			prs("Terminal type is ");
10257c478bd9Sstevel@tonic-gate 			prs(TtyType);
10267c478bd9Sstevel@tonic-gate 			prs("\n");
10277c478bd9Sstevel@tonic-gate 			flush();
10287c478bd9Sstevel@tonic-gate 		}
10297c478bd9Sstevel@tonic-gate 
1030de81e71eSTim Marsland 		if (DoSetenv) {
1031de81e71eSTim Marsland 			if (csh) {
10327c478bd9Sstevel@tonic-gate 				if (CmndLine)
1033de81e71eSTim Marsland 					(void) write(STDOUT,
1034de81e71eSTim Marsland 					    "setenv TERMCAP '", 16);
1035de81e71eSTim Marsland 			} else
1036de81e71eSTim Marsland 				(void) write(STDOUT, "TERMCAP='", 9);
1037de81e71eSTim Marsland 			wrtermcap(Ttycap);
1038de81e71eSTim Marsland 			if (csh) {
1039de81e71eSTim Marsland 				if (CmndLine) {
1040de81e71eSTim Marsland 					(void) write(STDOUT, "';\n", 3);
1041de81e71eSTim Marsland 					(void) write(STDOUT,
1042de81e71eSTim Marsland 					    "unset noglob;\n", 14);
10437c478bd9Sstevel@tonic-gate 				}
1044de81e71eSTim Marsland 			} else
10457c478bd9Sstevel@tonic-gate 				(void) write(STDOUT, "';\n", 3);
10467c478bd9Sstevel@tonic-gate 		}
10477c478bd9Sstevel@tonic-gate 	}
10487c478bd9Sstevel@tonic-gate 
10497c478bd9Sstevel@tonic-gate 	if (RepOnly)
10507c478bd9Sstevel@tonic-gate 		exit(0);
10517c478bd9Sstevel@tonic-gate 
10527c478bd9Sstevel@tonic-gate 	/* tell about changing erase, kill and interrupt characters */
10537c478bd9Sstevel@tonic-gate 	reportek("Erase", curerase, olderase, CERASE);
10547c478bd9Sstevel@tonic-gate 	reportek("Kill", curkill, oldkill, CKILL);
10557c478bd9Sstevel@tonic-gate 	reportek("Interrupt", curintr, oldintr, CINTR);
10567c478bd9Sstevel@tonic-gate 
1057cc6c5292Schin 	return (0);
10587c478bd9Sstevel@tonic-gate }
10597c478bd9Sstevel@tonic-gate 
10607c478bd9Sstevel@tonic-gate /*
10617c478bd9Sstevel@tonic-gate  * Set the hardware tabs on the terminal, using the ct (clear all tabs),
10627c478bd9Sstevel@tonic-gate  * st (set one tab) and ch (horizontal cursor addressing) capabilities.
10637c478bd9Sstevel@tonic-gate  * This is done before if and is, so they can patch in case we blow this.
10647c478bd9Sstevel@tonic-gate  */
1065cc6c5292Schin int
1066cc6c5292Schin settabs(void)
10677c478bd9Sstevel@tonic-gate {
10687c478bd9Sstevel@tonic-gate 	char caps[100];
10697c478bd9Sstevel@tonic-gate 	char *capsp = caps;
10707c478bd9Sstevel@tonic-gate 	char *clear_tabs, *set_tab, *set_column, *set_pos;
10717c478bd9Sstevel@tonic-gate 	char *tg_out, *tgoto();
10727c478bd9Sstevel@tonic-gate 	int c;
10737c478bd9Sstevel@tonic-gate 	extern char *tgetstr();
10747c478bd9Sstevel@tonic-gate 	int lines, columns;
10757c478bd9Sstevel@tonic-gate 
10767c478bd9Sstevel@tonic-gate 	clear_tabs = tgetstr("ct", &capsp);
10777c478bd9Sstevel@tonic-gate 	set_tab = tgetstr("st", &capsp);
10787c478bd9Sstevel@tonic-gate 	set_column = tgetstr("ch", &capsp);
10797c478bd9Sstevel@tonic-gate 	if (set_column == 0)
10807c478bd9Sstevel@tonic-gate 		set_pos = tgetstr("cm", &capsp);
10817c478bd9Sstevel@tonic-gate 
10827c478bd9Sstevel@tonic-gate 	if (clear_tabs && set_tab) {
10837c478bd9Sstevel@tonic-gate 		prc('\r');	/* force to be at left margin */
10847c478bd9Sstevel@tonic-gate 		tputs(clear_tabs, 0, prc);
10857c478bd9Sstevel@tonic-gate 	}
10867c478bd9Sstevel@tonic-gate 	if (set_tab) {
10877c478bd9Sstevel@tonic-gate 		columns = tgetnum("co");
10887c478bd9Sstevel@tonic-gate 		lines = tgetnum("li");
1089de81e71eSTim Marsland 		for (c = 0; c < columns; c += 8) {
10907c478bd9Sstevel@tonic-gate 			/* get to that column. */
10917c478bd9Sstevel@tonic-gate 			tg_out = "OOPS";	/* also returned by tgoto */
10927c478bd9Sstevel@tonic-gate 			if (set_column)
10937c478bd9Sstevel@tonic-gate 				tg_out = tgoto(set_column, 0, c);
10947c478bd9Sstevel@tonic-gate 			if (*tg_out == 'O' && set_pos)
10957c478bd9Sstevel@tonic-gate 				tg_out = tgoto(set_pos, c, lines-1);
10967c478bd9Sstevel@tonic-gate 			if (*tg_out != 'O')
10977c478bd9Sstevel@tonic-gate 				tputs(tg_out, 1, prc);
10987c478bd9Sstevel@tonic-gate 			else if (c != 0) {
10997c478bd9Sstevel@tonic-gate 				prc(' '); prc(' '); prc(' '); prc(' ');
11007c478bd9Sstevel@tonic-gate 				prc(' '); prc(' '); prc(' '); prc(' ');
11017c478bd9Sstevel@tonic-gate 			}
11027c478bd9Sstevel@tonic-gate 			/* set the tab */
11037c478bd9Sstevel@tonic-gate 			tputs(set_tab, 0, prc);
11047c478bd9Sstevel@tonic-gate 		}
11057c478bd9Sstevel@tonic-gate 		prc('\r');
1106cc6c5292Schin 		return (1);
11077c478bd9Sstevel@tonic-gate 	}
1108cc6c5292Schin 	return (0);
11097c478bd9Sstevel@tonic-gate }
11107c478bd9Sstevel@tonic-gate 
1111de81e71eSTim Marsland /*
1112de81e71eSTim Marsland  * flag serves several purposes:
11137c478bd9Sstevel@tonic-gate  *	if called as the result of a signal, flag will be > 0.
11147c478bd9Sstevel@tonic-gate  *	if called from terminal init, flag == -1 means reset "oldmode".
11157c478bd9Sstevel@tonic-gate  *	called with flag == 0 at end of normal mode processing.
11167c478bd9Sstevel@tonic-gate  */
1117de81e71eSTim Marsland void
1118de81e71eSTim Marsland setmode(int flag)
11197c478bd9Sstevel@tonic-gate {
11207c478bd9Sstevel@tonic-gate 	struct termio *ttymode;
11217c478bd9Sstevel@tonic-gate 	struct termios *ttymodes;
1122cc6c5292Schin 	int i;
11237c478bd9Sstevel@tonic-gate 
11247c478bd9Sstevel@tonic-gate 	ttymode = (struct termio *)0;
11257c478bd9Sstevel@tonic-gate 	ttymodes = (struct termios *)0;
11267c478bd9Sstevel@tonic-gate 
11277c478bd9Sstevel@tonic-gate 	if (flag < 0) { /* unconditionally reset oldmode (called from init) */
11287c478bd9Sstevel@tonic-gate 		if (istermios < 0) {
1129de81e71eSTim Marsland 			oldmode.c_lflag = oldmodes.c_lflag;
1130de81e71eSTim Marsland 			oldmode.c_oflag = oldmodes.c_oflag;
1131de81e71eSTim Marsland 			oldmode.c_iflag = oldmodes.c_iflag;
1132de81e71eSTim Marsland 			oldmode.c_cflag = oldmodes.c_cflag;
1133de81e71eSTim Marsland 			for (i = 0; i < NCC; i++)
1134de81e71eSTim Marsland 				oldmode.c_cc[i] = oldmodes.c_cc[i];
1135de81e71eSTim Marsland 			ttymode = &oldmode;
11367c478bd9Sstevel@tonic-gate 		} else
1137de81e71eSTim Marsland 			ttymodes = &oldmodes;
11387c478bd9Sstevel@tonic-gate 	} else {
11397c478bd9Sstevel@tonic-gate 		if (istermios < 0) {
1140de81e71eSTim Marsland 			oldmode.c_lflag = oldmodes.c_lflag;
1141de81e71eSTim Marsland 			oldmode.c_oflag = oldmodes.c_oflag;
1142de81e71eSTim Marsland 			oldmode.c_iflag = oldmodes.c_iflag;
1143de81e71eSTim Marsland 			oldmode.c_cflag = oldmodes.c_cflag;
1144de81e71eSTim Marsland 			for (i = 0; i < NCC; i++)
1145de81e71eSTim Marsland 				oldmode.c_cc[i] = oldmodes.c_cc[i];
1146de81e71eSTim Marsland 			mode.c_lflag = modes.c_lflag;
1147de81e71eSTim Marsland 			mode.c_oflag = modes.c_oflag;
1148de81e71eSTim Marsland 			mode.c_iflag = modes.c_iflag;
1149de81e71eSTim Marsland 			mode.c_cflag = modes.c_cflag;
1150de81e71eSTim Marsland 			for (i = 0; i < NCC; i++)
1151de81e71eSTim Marsland 				mode.c_cc[i] = modes.c_cc[i];
1152de81e71eSTim Marsland 			if (!bequal((char *)&mode, (char *)&oldmode,
1153de81e71eSTim Marsland 			    sizeof (mode)))
11547c478bd9Sstevel@tonic-gate 				ttymode = &mode;
11557c478bd9Sstevel@tonic-gate 		} else if (!bequal((char *)&modes, (char *)&oldmodes,
1156de81e71eSTim Marsland 		    sizeof (modes)))
1157de81e71eSTim Marsland 			ttymodes = &modes;
11587c478bd9Sstevel@tonic-gate 	}
1159de81e71eSTim Marsland 
1160de81e71eSTim Marsland 	if (ttymode) {
11617c478bd9Sstevel@tonic-gate 		(void) ioctl(FILEDES, TCSETAW, (char *)ttymode);
11627c478bd9Sstevel@tonic-gate 	} else if (ttymodes) {
11637c478bd9Sstevel@tonic-gate 		(void) ioctl(FILEDES, TCSETSW, (char *)ttymodes);
11647c478bd9Sstevel@tonic-gate 	}
11657c478bd9Sstevel@tonic-gate 	if (flag > 0)	/* trapped signal */
11667c478bd9Sstevel@tonic-gate 		exit(1);
11677c478bd9Sstevel@tonic-gate }
11687c478bd9Sstevel@tonic-gate 
1169cc6c5292Schin void
1170cc6c5292Schin reportek(char *name, char new, char old, char def)
11717c478bd9Sstevel@tonic-gate {
1172cc6c5292Schin 	char	o;
1173cc6c5292Schin 	char	n;
1174cc6c5292Schin 	char	*p;
11757c478bd9Sstevel@tonic-gate 	char		buf[32];
11767c478bd9Sstevel@tonic-gate 	char		*bufp;
11777c478bd9Sstevel@tonic-gate 	extern char *tgetstr();
11787c478bd9Sstevel@tonic-gate 
11797c478bd9Sstevel@tonic-gate 	if (BeQuiet)
11807c478bd9Sstevel@tonic-gate 		return;
11817c478bd9Sstevel@tonic-gate 	o = old;
11827c478bd9Sstevel@tonic-gate 	n = new;
11837c478bd9Sstevel@tonic-gate 
11847c478bd9Sstevel@tonic-gate 	if (o == n && n == def)
11857c478bd9Sstevel@tonic-gate 		return;
11867c478bd9Sstevel@tonic-gate 	prs(name);
11877c478bd9Sstevel@tonic-gate 	if (o == n)
11887c478bd9Sstevel@tonic-gate 		prs(" is ");
11897c478bd9Sstevel@tonic-gate 	else
11907c478bd9Sstevel@tonic-gate 		prs(" set to ");
11917c478bd9Sstevel@tonic-gate 	bufp = buf;
11927c478bd9Sstevel@tonic-gate 	if (tgetstr("kb", &bufp) > (char *)0 && n == buf[0] && buf[1] == NULL)
11937c478bd9Sstevel@tonic-gate 		prs("Backspace\n");
11947c478bd9Sstevel@tonic-gate 	else if (n == 0177)
11957c478bd9Sstevel@tonic-gate 		prs("Delete\n");
1196de81e71eSTim Marsland 	else {
1197de81e71eSTim Marsland 		if (n < 040) {
11987c478bd9Sstevel@tonic-gate 			prs("Ctrl-");
11997c478bd9Sstevel@tonic-gate 			n ^= 0100;
12007c478bd9Sstevel@tonic-gate 		}
12017c478bd9Sstevel@tonic-gate 		p = "x\n";
12027c478bd9Sstevel@tonic-gate 		p[0] = n;
12037c478bd9Sstevel@tonic-gate 		prs(p);
12047c478bd9Sstevel@tonic-gate 	}
12057c478bd9Sstevel@tonic-gate 	flush();
12067c478bd9Sstevel@tonic-gate }
12077c478bd9Sstevel@tonic-gate 
12087c478bd9Sstevel@tonic-gate 
12097c478bd9Sstevel@tonic-gate 
1210cc6c5292Schin void
1211cc6c5292Schin setdelay(char *cap, struct delay dtab[], tcflag_t bits, tcflag_t *flags)
12127c478bd9Sstevel@tonic-gate {
1213cc6c5292Schin 	int		i;
1214cc6c5292Schin 	struct delay	*p;
12157c478bd9Sstevel@tonic-gate 	extern short	ospeed;
12167c478bd9Sstevel@tonic-gate 
12177c478bd9Sstevel@tonic-gate 	/* see if this capability exists at all */
12187c478bd9Sstevel@tonic-gate 	i = tgetnum(cap);
12197c478bd9Sstevel@tonic-gate 	if (i < 0)
12207c478bd9Sstevel@tonic-gate 		i = 0;
12217c478bd9Sstevel@tonic-gate 	/* No padding at speeds below PadBaud */
12227c478bd9Sstevel@tonic-gate 	if (PadBaud > ospeed)
12237c478bd9Sstevel@tonic-gate 		i = 0;
12247c478bd9Sstevel@tonic-gate 
12257c478bd9Sstevel@tonic-gate 	/* clear out the bits, replace with new ones */
12267c478bd9Sstevel@tonic-gate 	*flags &= ~bits;
12277c478bd9Sstevel@tonic-gate 
12287c478bd9Sstevel@tonic-gate 	/* scan dtab for first entry with adequate delay */
1229de81e71eSTim Marsland 	for (p = dtab; p->d_delay >= 0; p++) {
1230de81e71eSTim Marsland 		if (p->d_delay >= i) {
12317c478bd9Sstevel@tonic-gate 			p++;
12327c478bd9Sstevel@tonic-gate 			break;
12337c478bd9Sstevel@tonic-gate 		}
12347c478bd9Sstevel@tonic-gate 	}
12357c478bd9Sstevel@tonic-gate 
12367c478bd9Sstevel@tonic-gate 	/* use last entry if none will do */
1237cc6c5292Schin 	*flags |= (tcflag_t)((--p)->d_bits);
12387c478bd9Sstevel@tonic-gate }
12397c478bd9Sstevel@tonic-gate 
1240cc6c5292Schin void
1241cc6c5292Schin prs(char *s)
12427c478bd9Sstevel@tonic-gate {
12437c478bd9Sstevel@tonic-gate 	while (*s != '\0')
12447c478bd9Sstevel@tonic-gate 		prc(*s++);
12457c478bd9Sstevel@tonic-gate }
12467c478bd9Sstevel@tonic-gate 
12477c478bd9Sstevel@tonic-gate 
12487c478bd9Sstevel@tonic-gate char	OutBuf[256];
12497c478bd9Sstevel@tonic-gate int	OutPtr;
12507c478bd9Sstevel@tonic-gate 
1251cc6c5292Schin void
1252cc6c5292Schin prc(char c)
12537c478bd9Sstevel@tonic-gate {
12547c478bd9Sstevel@tonic-gate 	OutBuf[OutPtr++] = c;
1255de81e71eSTim Marsland 	if (OutPtr >= sizeof (OutBuf))
12567c478bd9Sstevel@tonic-gate 		flush();
12577c478bd9Sstevel@tonic-gate }
12587c478bd9Sstevel@tonic-gate 
1259cc6c5292Schin void
1260cc6c5292Schin flush(void)
12617c478bd9Sstevel@tonic-gate {
12627c478bd9Sstevel@tonic-gate 	if (OutPtr > 0)
12637c478bd9Sstevel@tonic-gate 		(void) write(2, OutBuf, OutPtr);
12647c478bd9Sstevel@tonic-gate 	OutPtr = 0;
12657c478bd9Sstevel@tonic-gate }
12667c478bd9Sstevel@tonic-gate 
1267cc6c5292Schin void
1268cc6c5292Schin cat(char *file)
12697c478bd9Sstevel@tonic-gate {
1270cc6c5292Schin 	int	fd;
1271cc6c5292Schin 	int	i;
12727c478bd9Sstevel@tonic-gate 	char		buf[BUFSIZ];
12737c478bd9Sstevel@tonic-gate 
12747c478bd9Sstevel@tonic-gate 	fd = open(file, 0);
1275de81e71eSTim Marsland 	if (fd < 0) {
12767c478bd9Sstevel@tonic-gate 		prs("Cannot open ");
12777c478bd9Sstevel@tonic-gate 		prs(file);
12787c478bd9Sstevel@tonic-gate 		prs("\n");
12797c478bd9Sstevel@tonic-gate 		flush();
12807c478bd9Sstevel@tonic-gate 		return;
12817c478bd9Sstevel@tonic-gate 	}
12827c478bd9Sstevel@tonic-gate 
12837c478bd9Sstevel@tonic-gate 	while ((i = read(fd, buf, BUFSIZ)) > 0)
12847c478bd9Sstevel@tonic-gate 		(void) write(FILEDES, buf, i);
12857c478bd9Sstevel@tonic-gate 
12867c478bd9Sstevel@tonic-gate 	(void) close(fd);
12877c478bd9Sstevel@tonic-gate }
12887c478bd9Sstevel@tonic-gate 
12897c478bd9Sstevel@tonic-gate 
1290cc6c5292Schin void
1291cc6c5292Schin bmove(char *from, char *to, int length)
12927c478bd9Sstevel@tonic-gate {
1293cc6c5292Schin 	char	*p, *q;
1294cc6c5292Schin 	int	i;
12957c478bd9Sstevel@tonic-gate 
12967c478bd9Sstevel@tonic-gate 	i = length;
12977c478bd9Sstevel@tonic-gate 	p = from;
12987c478bd9Sstevel@tonic-gate 	q = to;
12997c478bd9Sstevel@tonic-gate 
13007c478bd9Sstevel@tonic-gate 	while (i-- > 0)
13017c478bd9Sstevel@tonic-gate 		*q++ = *p++;
13027c478bd9Sstevel@tonic-gate }
13037c478bd9Sstevel@tonic-gate 
13047c478bd9Sstevel@tonic-gate 
1305cc6c5292Schin int
1306cc6c5292Schin bequal(char *a, char *b, int len)	/* must be same thru len chars */
13077c478bd9Sstevel@tonic-gate {
1308cc6c5292Schin 	char	*p, *q;
1309cc6c5292Schin 	int	i;
13107c478bd9Sstevel@tonic-gate 
13117c478bd9Sstevel@tonic-gate 	i = len;
13127c478bd9Sstevel@tonic-gate 	p = a;
13137c478bd9Sstevel@tonic-gate 	q = b;
13147c478bd9Sstevel@tonic-gate 
1315de81e71eSTim Marsland 	while ((*p == *q) && --i > 0) {
13167c478bd9Sstevel@tonic-gate 		p++; q++;
13177c478bd9Sstevel@tonic-gate 	}
13187c478bd9Sstevel@tonic-gate 	return ((*p == *q) && i >= 0);
13197c478bd9Sstevel@tonic-gate }
13207c478bd9Sstevel@tonic-gate 
1321cc6c5292Schin int
1322cc6c5292Schin sequal(char *a, char *b)	/* must be same thru NULL */
13237c478bd9Sstevel@tonic-gate {
1324cc6c5292Schin 	char *p = a, *q = b;
13257c478bd9Sstevel@tonic-gate 
1326de81e71eSTim Marsland 	while (*p && *q && (*p == *q)) {
13277c478bd9Sstevel@tonic-gate 		p++; q++;
13287c478bd9Sstevel@tonic-gate 	}
13297c478bd9Sstevel@tonic-gate 	return (*p == *q);
13307c478bd9Sstevel@tonic-gate }
13317c478bd9Sstevel@tonic-gate 
1332cc6c5292Schin void
1333cc6c5292Schin makealias(char *buf)
13347c478bd9Sstevel@tonic-gate {
1335cc6c5292Schin 	int i;
1336cc6c5292Schin 	char *a;
1337cc6c5292Schin 	char *b;
13387c478bd9Sstevel@tonic-gate 
13397c478bd9Sstevel@tonic-gate 	Alias[0] = a = Aliasbuf;
13407c478bd9Sstevel@tonic-gate 	b = buf;
13417c478bd9Sstevel@tonic-gate 	i = 1;
13427c478bd9Sstevel@tonic-gate 	while (*b && *b != ':') {
13437c478bd9Sstevel@tonic-gate 		if (*b == '|') {
13447c478bd9Sstevel@tonic-gate 			*a++ = NULL;
13457c478bd9Sstevel@tonic-gate 			Alias[i++] = a;
13467c478bd9Sstevel@tonic-gate 			b++;
1347de81e71eSTim Marsland 		} else
13487c478bd9Sstevel@tonic-gate 			*a++ = *b++;
13497c478bd9Sstevel@tonic-gate 	}
13507c478bd9Sstevel@tonic-gate 	*a = NULL;
13517c478bd9Sstevel@tonic-gate 	Alias[i] = NULL;
1352de81e71eSTim Marsland #ifdef	DEB
1353de81e71eSTim Marsland 	for (i = 0; Alias[i]; printf("A:%s\n", Alias[i++]))
1354de81e71eSTim Marsland 		;
1355de81e71eSTim Marsland #endif
13567c478bd9Sstevel@tonic-gate }
13577c478bd9Sstevel@tonic-gate 
1358cc6c5292Schin int
1359cc6c5292Schin isalias(char *ident)	/* is ident same as one of the aliases? */
13607c478bd9Sstevel@tonic-gate {
13617c478bd9Sstevel@tonic-gate 	char **a = Alias;
13627c478bd9Sstevel@tonic-gate 
13637c478bd9Sstevel@tonic-gate 	if (*a)
13647c478bd9Sstevel@tonic-gate 		while (*a)
13657c478bd9Sstevel@tonic-gate 			if (sequal(ident, *a))
1366de81e71eSTim Marsland 				return (YES);
13677c478bd9Sstevel@tonic-gate 			else
13687c478bd9Sstevel@tonic-gate 				a++;
1369de81e71eSTim Marsland 	return (NO);
13707c478bd9Sstevel@tonic-gate }
13717c478bd9Sstevel@tonic-gate 
13727c478bd9Sstevel@tonic-gate 
13737c478bd9Sstevel@tonic-gate /*
13747c478bd9Sstevel@tonic-gate  * routine to output the string for the environment TERMCAP variable
13757c478bd9Sstevel@tonic-gate  */
13767c478bd9Sstevel@tonic-gate #define	WHITE(c)	(c == ' ' || c == '\t')
13777c478bd9Sstevel@tonic-gate char delcap[128][2];
13787c478bd9Sstevel@tonic-gate int ncap = 0;
13797c478bd9Sstevel@tonic-gate 
1380cc6c5292Schin void
1381cc6c5292Schin wrtermcap(char *bp)
13827c478bd9Sstevel@tonic-gate {
13837c478bd9Sstevel@tonic-gate 	char buf[CAPBUFSIZ];
13847c478bd9Sstevel@tonic-gate 	char *p = buf;
13857c478bd9Sstevel@tonic-gate 	char *tp;
13867c478bd9Sstevel@tonic-gate 	char *putbuf();
13877c478bd9Sstevel@tonic-gate 	int space, empty;
13887c478bd9Sstevel@tonic-gate 
13897c478bd9Sstevel@tonic-gate 	/* discard names with blanks */
1390de81e71eSTim Marsland /* May not be desireable ? */
13917c478bd9Sstevel@tonic-gate 	while (*bp && *bp != ':') {
13927c478bd9Sstevel@tonic-gate 		if (*bp == '|') {
13937c478bd9Sstevel@tonic-gate 			tp = bp+1;
13947c478bd9Sstevel@tonic-gate 			space = NO;
13957c478bd9Sstevel@tonic-gate 			while (*tp && *tp != '|' && *tp != ':') {
1396de81e71eSTim Marsland 				space = (space || WHITE(*tp));
13977c478bd9Sstevel@tonic-gate 				tp++;
13987c478bd9Sstevel@tonic-gate 			}
13997c478bd9Sstevel@tonic-gate 			if (space) {
14007c478bd9Sstevel@tonic-gate 				bp = tp;
14017c478bd9Sstevel@tonic-gate 				continue;
14027c478bd9Sstevel@tonic-gate 			}
14037c478bd9Sstevel@tonic-gate 		}
14047c478bd9Sstevel@tonic-gate 		*p++ = *bp++;
14057c478bd9Sstevel@tonic-gate 	}
1406de81e71eSTim Marsland /* */
14077c478bd9Sstevel@tonic-gate 
14087c478bd9Sstevel@tonic-gate 	while (*bp) {
14097c478bd9Sstevel@tonic-gate 		switch (*bp) {
14107c478bd9Sstevel@tonic-gate 		case ':':	/* discard empty, cancelled  or dupl fields */
1411de81e71eSTim Marsland 			tp = bp + 1;
14127c478bd9Sstevel@tonic-gate 			empty = YES;
14137c478bd9Sstevel@tonic-gate 			while (*tp && *tp != ':') {
1414de81e71eSTim Marsland 				empty = (empty && WHITE(*tp));
14157c478bd9Sstevel@tonic-gate 				tp++;
14167c478bd9Sstevel@tonic-gate 			}
14177c478bd9Sstevel@tonic-gate 			if (empty || cancelled(bp+1)) {
14187c478bd9Sstevel@tonic-gate 				bp = tp;
14197c478bd9Sstevel@tonic-gate 				continue;
14207c478bd9Sstevel@tonic-gate 			}
14217c478bd9Sstevel@tonic-gate 			break;
14227c478bd9Sstevel@tonic-gate 
14237c478bd9Sstevel@tonic-gate 		case ' ':	/* no spaces in output */
14247c478bd9Sstevel@tonic-gate 			p = putbuf(p, "\\040");
14257c478bd9Sstevel@tonic-gate 			bp++;
14267c478bd9Sstevel@tonic-gate 			continue;
14277c478bd9Sstevel@tonic-gate 
14287c478bd9Sstevel@tonic-gate 		case '!':	/* the shell thinks this is history */
14297c478bd9Sstevel@tonic-gate 			p = putbuf(p, "\\041");
14307c478bd9Sstevel@tonic-gate 			bp++;
14317c478bd9Sstevel@tonic-gate 			continue;
14327c478bd9Sstevel@tonic-gate 
14337c478bd9Sstevel@tonic-gate 		case ',':	/* the shell thinks this is history */
14347c478bd9Sstevel@tonic-gate 			p = putbuf(p, "\\054");
14357c478bd9Sstevel@tonic-gate 			bp++;
14367c478bd9Sstevel@tonic-gate 			continue;
14377c478bd9Sstevel@tonic-gate 
14387c478bd9Sstevel@tonic-gate 		case '"':	/* no quotes in output */
14397c478bd9Sstevel@tonic-gate 			p = putbuf(p, "\\042");
14407c478bd9Sstevel@tonic-gate 			bp++;
14417c478bd9Sstevel@tonic-gate 			continue;
14427c478bd9Sstevel@tonic-gate 
14437c478bd9Sstevel@tonic-gate 		case '\'':	/* no quotes in output */
14447c478bd9Sstevel@tonic-gate 			p = putbuf(p, "\\047");
14457c478bd9Sstevel@tonic-gate 			bp++;
14467c478bd9Sstevel@tonic-gate 			continue;
14477c478bd9Sstevel@tonic-gate 
14487c478bd9Sstevel@tonic-gate 		case '`':	/* no back quotes in output */
14497c478bd9Sstevel@tonic-gate 			p = putbuf(p, "\\140");
14507c478bd9Sstevel@tonic-gate 			bp++;
14517c478bd9Sstevel@tonic-gate 			continue;
14527c478bd9Sstevel@tonic-gate 
14537c478bd9Sstevel@tonic-gate 		case '\\':
14547c478bd9Sstevel@tonic-gate 		case '^':	/* anything following is OK */
14557c478bd9Sstevel@tonic-gate 			*p++ = *bp++;
14567c478bd9Sstevel@tonic-gate 		}
14577c478bd9Sstevel@tonic-gate 		*p++ = *bp++;
14587c478bd9Sstevel@tonic-gate 	}
14597c478bd9Sstevel@tonic-gate 	*p++ = ':';	/* we skipped the last : with the : lookahead hack */
1460de81e71eSTim Marsland 	(void) write(STDOUT, buf, p-buf);
14617c478bd9Sstevel@tonic-gate }
14627c478bd9Sstevel@tonic-gate 
1463cc6c5292Schin int
1464cc6c5292Schin cancelled(char *cap)
14657c478bd9Sstevel@tonic-gate {
1466cc6c5292Schin 	int i;
14677c478bd9Sstevel@tonic-gate 
1468de81e71eSTim Marsland 	for (i = 0; i < ncap; i++) {
14697c478bd9Sstevel@tonic-gate 		if (cap[0] == delcap[i][0] && cap[1] == delcap[i][1])
14707c478bd9Sstevel@tonic-gate 			return (YES);
14717c478bd9Sstevel@tonic-gate 	}
14727c478bd9Sstevel@tonic-gate 	/* delete a second occurrance of the same capability */
14737c478bd9Sstevel@tonic-gate 	delcap[ncap][0] = cap[0];
14747c478bd9Sstevel@tonic-gate 	delcap[ncap][1] = cap[1];
14757c478bd9Sstevel@tonic-gate 	ncap++;
14767c478bd9Sstevel@tonic-gate 	return (cap[2] == '@');
14777c478bd9Sstevel@tonic-gate }
14787c478bd9Sstevel@tonic-gate 
14797c478bd9Sstevel@tonic-gate char *
14807c478bd9Sstevel@tonic-gate putbuf(ptr, str)
14817c478bd9Sstevel@tonic-gate char	*ptr;
14827c478bd9Sstevel@tonic-gate char	*str;
14837c478bd9Sstevel@tonic-gate {
14847c478bd9Sstevel@tonic-gate 	char buf[20];
14857c478bd9Sstevel@tonic-gate 
14867c478bd9Sstevel@tonic-gate 	while (*str) {
14877c478bd9Sstevel@tonic-gate 		switch (*str) {
14887c478bd9Sstevel@tonic-gate 		case '\033':
14897c478bd9Sstevel@tonic-gate 			ptr = putbuf(ptr, "\\E");
14907c478bd9Sstevel@tonic-gate 			str++;
14917c478bd9Sstevel@tonic-gate 			break;
14927c478bd9Sstevel@tonic-gate 		default:
14937c478bd9Sstevel@tonic-gate 			if (*str <= ' ') {
14947c478bd9Sstevel@tonic-gate 				(void) sprintf(buf, "\\%03o", *str);
14957c478bd9Sstevel@tonic-gate 				ptr = putbuf(ptr, buf);
14967c478bd9Sstevel@tonic-gate 				str++;
14977c478bd9Sstevel@tonic-gate 			} else
14987c478bd9Sstevel@tonic-gate 				*ptr++ = *str++;
14997c478bd9Sstevel@tonic-gate 		}
15007c478bd9Sstevel@tonic-gate 	}
15017c478bd9Sstevel@tonic-gate 	return (ptr);
15027c478bd9Sstevel@tonic-gate }
15037c478bd9Sstevel@tonic-gate 
1504cc6c5292Schin int
1505cc6c5292Schin baudrate(char *p)
15067c478bd9Sstevel@tonic-gate {
15077c478bd9Sstevel@tonic-gate 	char buf[8];
15087c478bd9Sstevel@tonic-gate 	int i = 0;
15097c478bd9Sstevel@tonic-gate 
15107c478bd9Sstevel@tonic-gate 	while (i < 7 && (isalnum(*p) || *p == '.'))
15117c478bd9Sstevel@tonic-gate 		buf[i++] = *p++;
15127c478bd9Sstevel@tonic-gate 	buf[i] = NULL;
1513de81e71eSTim Marsland 	for (i = 0; speeds[i].string; i++)
15147c478bd9Sstevel@tonic-gate 		if (sequal(speeds[i].string, buf))
15157c478bd9Sstevel@tonic-gate 			return (speeds[i].speed);
15167c478bd9Sstevel@tonic-gate 	return (-1);
15177c478bd9Sstevel@tonic-gate }
15187c478bd9Sstevel@tonic-gate 
15197c478bd9Sstevel@tonic-gate char *
15207c478bd9Sstevel@tonic-gate mapped(type)
15217c478bd9Sstevel@tonic-gate char	*type;
15227c478bd9Sstevel@tonic-gate {
15237c478bd9Sstevel@tonic-gate 	extern short	ospeed;
15247c478bd9Sstevel@tonic-gate 	int	match;
15257c478bd9Sstevel@tonic-gate 
1526de81e71eSTim Marsland #ifdef DEB
1527de81e71eSTim Marsland 	printf("spd:%d\n", ospeed);
15287c478bd9Sstevel@tonic-gate 	prmap();
1529de81e71eSTim Marsland #endif
15307c478bd9Sstevel@tonic-gate 	Map = map;
1531de81e71eSTim Marsland 	while (Map->Ident) {
1532de81e71eSTim Marsland 		if (*(Map->Ident) == NULL ||
1533de81e71eSTim Marsland 		    sequal(Map->Ident, type) || isalias(Map->Ident)) {
15347c478bd9Sstevel@tonic-gate 			match = NO;
1535de81e71eSTim Marsland 			switch (Map->Test) {
1536de81e71eSTim Marsland 			case ANY:	/* no test specified */
1537de81e71eSTim Marsland 			case ALL:
1538de81e71eSTim Marsland 				match = YES;
1539de81e71eSTim Marsland 				break;
1540de81e71eSTim Marsland 
1541de81e71eSTim Marsland 			case GT:
1542de81e71eSTim Marsland 				match = (ospeed > Map->Speed);
1543de81e71eSTim Marsland 				break;
1544de81e71eSTim Marsland 
1545de81e71eSTim Marsland 			case GE:
1546de81e71eSTim Marsland 				match = (ospeed >= Map->Speed);
1547de81e71eSTim Marsland 				break;
1548de81e71eSTim Marsland 
1549de81e71eSTim Marsland 			case EQ:
1550de81e71eSTim Marsland 				match = (ospeed == Map->Speed);
1551de81e71eSTim Marsland 				break;
1552de81e71eSTim Marsland 
1553de81e71eSTim Marsland 			case LE:
1554de81e71eSTim Marsland 				match = (ospeed <= Map->Speed);
1555de81e71eSTim Marsland 				break;
1556de81e71eSTim Marsland 
1557de81e71eSTim Marsland 			case LT:
1558de81e71eSTim Marsland 				match = (ospeed < Map->Speed);
1559de81e71eSTim Marsland 				break;
1560de81e71eSTim Marsland 
1561de81e71eSTim Marsland 			case NE:
1562de81e71eSTim Marsland 				match = (ospeed != Map->Speed);
1563de81e71eSTim Marsland 				break;
15647c478bd9Sstevel@tonic-gate 			}
15657c478bd9Sstevel@tonic-gate 			if (match)
15667c478bd9Sstevel@tonic-gate 				return (Map->Type);
15677c478bd9Sstevel@tonic-gate 		}
15687c478bd9Sstevel@tonic-gate 		Map++;
15697c478bd9Sstevel@tonic-gate 	}
15707c478bd9Sstevel@tonic-gate 	/* no match found; return given type */
15717c478bd9Sstevel@tonic-gate 	return (type);
15727c478bd9Sstevel@tonic-gate }
15737c478bd9Sstevel@tonic-gate 
1574de81e71eSTim Marsland #ifdef DEB
15757c478bd9Sstevel@tonic-gate prmap()
15767c478bd9Sstevel@tonic-gate {
15777c478bd9Sstevel@tonic-gate 	Map = map;
1578de81e71eSTim Marsland 	while (Map->Ident) {
1579de81e71eSTim Marsland 		printf("%s t:%d s:%d %s\n",
1580de81e71eSTim Marsland 		    Map->Ident, Map->Test, Map->Speed, Map->Type);
1581de81e71eSTim Marsland 		Map++;
15827c478bd9Sstevel@tonic-gate 	}
15837c478bd9Sstevel@tonic-gate }
1584de81e71eSTim Marsland #endif
15857c478bd9Sstevel@tonic-gate 
15867c478bd9Sstevel@tonic-gate char *
15877c478bd9Sstevel@tonic-gate nextarg(argc, argv)
15887c478bd9Sstevel@tonic-gate int	argc;
15897c478bd9Sstevel@tonic-gate char	*argv[];
15907c478bd9Sstevel@tonic-gate {
15917c478bd9Sstevel@tonic-gate 	if (argc <= 0)
1592de81e71eSTim Marsland 		fatal("Too few args: ", *argv);
15937c478bd9Sstevel@tonic-gate 	if (*(*++argv) == '-')
1594de81e71eSTim Marsland 		fatal("Unexpected arg: ", *argv);
15957c478bd9Sstevel@tonic-gate 	return (*argv);
15967c478bd9Sstevel@tonic-gate }
15977c478bd9Sstevel@tonic-gate 
1598cc6c5292Schin void
1599de81e71eSTim Marsland fatal(char *mesg, char *obj)
16007c478bd9Sstevel@tonic-gate {
1601de81e71eSTim Marsland 	prs(mesg);
1602de81e71eSTim Marsland 	prs(obj);
1603de81e71eSTim Marsland 	prc('\n');
1604de81e71eSTim Marsland 	prs(USAGE);
16057c478bd9Sstevel@tonic-gate 	flush();
16067c478bd9Sstevel@tonic-gate 	exit(1);
16077c478bd9Sstevel@tonic-gate }
16087c478bd9Sstevel@tonic-gate 
16097c478bd9Sstevel@tonic-gate 
16107c478bd9Sstevel@tonic-gate /*
16117c478bd9Sstevel@tonic-gate  * Stolen from /usr/src/ucb/reset.c, which this mod obsoletes.
16127c478bd9Sstevel@tonic-gate  */
16137c478bd9Sstevel@tonic-gate char
16147c478bd9Sstevel@tonic-gate reset(ch, def)
16157c478bd9Sstevel@tonic-gate 	char ch;
16167c478bd9Sstevel@tonic-gate 	int def;
16177c478bd9Sstevel@tonic-gate {
16187c478bd9Sstevel@tonic-gate 	if (ch == 0 || (ch&0377) == 0377)
1619de81e71eSTim Marsland 		return (def);
1620de81e71eSTim Marsland 	return (ch);
16217c478bd9Sstevel@tonic-gate }
1622