1*cc6c5292Schin /* 2*cc6c5292Schin * Copyright 1999 Sun Microsystems, Inc. All rights reserved. 3*cc6c5292Schin * Use is subject to license terms. 4*cc6c5292Schin */ 5*cc6c5292Schin 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 16*cc6c5292Schin #pragma ident "%Z%%M% %I% %E% SMI" 177c478bd9Sstevel@tonic-gate 187c478bd9Sstevel@tonic-gate /* 197c478bd9Sstevel@tonic-gate ** TSET -- set terminal modes 207c478bd9Sstevel@tonic-gate ** 217c478bd9Sstevel@tonic-gate ** This program does sophisticated terminal initialization. 227c478bd9Sstevel@tonic-gate ** I recommend that you include it in your .profile or .login 237c478bd9Sstevel@tonic-gate ** file to initialize whatever terminal you are on. 247c478bd9Sstevel@tonic-gate ** 257c478bd9Sstevel@tonic-gate ** There are several features: 267c478bd9Sstevel@tonic-gate ** 277c478bd9Sstevel@tonic-gate ** A special file or sequence (as controlled by the termcap file) 287c478bd9Sstevel@tonic-gate ** is sent to the terminal. 297c478bd9Sstevel@tonic-gate ** 307c478bd9Sstevel@tonic-gate ** Mode bits are set on a per-terminal_type basis (much better 317c478bd9Sstevel@tonic-gate ** than UNIX itself). This allows special delays, automatic 327c478bd9Sstevel@tonic-gate ** tabs, etc. 337c478bd9Sstevel@tonic-gate ** 347c478bd9Sstevel@tonic-gate ** Erase and Kill characters can be set to whatever you want. 357c478bd9Sstevel@tonic-gate ** Default is to change erase to control-H on a terminal which 367c478bd9Sstevel@tonic-gate ** can overstrike, and leave it alone on anything else. Kill 377c478bd9Sstevel@tonic-gate ** is always left alone unless specifically requested. These 387c478bd9Sstevel@tonic-gate ** characters can be represented as "^X" meaning control-X; 397c478bd9Sstevel@tonic-gate ** X is any character. 407c478bd9Sstevel@tonic-gate ** 417c478bd9Sstevel@tonic-gate ** Terminals which are dialups or plugboard types can be aliased 427c478bd9Sstevel@tonic-gate ** to whatever type you may have in your home or office. Thus, 437c478bd9Sstevel@tonic-gate ** if you know that when you dial up you will always be on a 447c478bd9Sstevel@tonic-gate ** TI 733, you can specify that fact to tset. You can represent 457c478bd9Sstevel@tonic-gate ** a type as "?type". This will ask you what type you want it 467c478bd9Sstevel@tonic-gate ** to be -- if you reply with just a newline, it will default 477c478bd9Sstevel@tonic-gate ** to the type given. 487c478bd9Sstevel@tonic-gate ** 497c478bd9Sstevel@tonic-gate ** The current terminal type can be queried. 507c478bd9Sstevel@tonic-gate ** 517c478bd9Sstevel@tonic-gate ** Usage: 527c478bd9Sstevel@tonic-gate ** tset [-] [-EC] [-eC] [-kC] [-iC] [-s] [-h] [-u] [-r] 537c478bd9Sstevel@tonic-gate ** [-m [ident] [test baudrate] :type] 547c478bd9Sstevel@tonic-gate ** [-Q] [-I] [-S] [type] 557c478bd9Sstevel@tonic-gate ** 567c478bd9Sstevel@tonic-gate ** In systems with environments, use: 577c478bd9Sstevel@tonic-gate ** eval `tset -s ...` 587c478bd9Sstevel@tonic-gate ** Actually, this doesn't work in old csh's. 597c478bd9Sstevel@tonic-gate ** Instead, use: 607c478bd9Sstevel@tonic-gate ** tset -s ... > tset.tmp 617c478bd9Sstevel@tonic-gate ** source tset.tmp 627c478bd9Sstevel@tonic-gate ** rm tset.tmp 637c478bd9Sstevel@tonic-gate ** or: 647c478bd9Sstevel@tonic-gate ** set noglob 657c478bd9Sstevel@tonic-gate ** set term=(`tset -S ....`) 667c478bd9Sstevel@tonic-gate ** setenv TERM $term[1] 677c478bd9Sstevel@tonic-gate ** setenv TERMCAP "$term[2]" 687c478bd9Sstevel@tonic-gate ** unset term 697c478bd9Sstevel@tonic-gate ** unset noglob 707c478bd9Sstevel@tonic-gate ** 717c478bd9Sstevel@tonic-gate ** Positional Parameters: 727c478bd9Sstevel@tonic-gate ** type -- the terminal type to force. If this is 737c478bd9Sstevel@tonic-gate ** specified, initialization is for this 747c478bd9Sstevel@tonic-gate ** terminal type. 757c478bd9Sstevel@tonic-gate ** 767c478bd9Sstevel@tonic-gate ** Flags: 777c478bd9Sstevel@tonic-gate ** - -- report terminal type. Whatever type is 787c478bd9Sstevel@tonic-gate ** decided on is reported. If no other flags 797c478bd9Sstevel@tonic-gate ** are stated, the only affect is to write 807c478bd9Sstevel@tonic-gate ** the terminal type on the standard output. 817c478bd9Sstevel@tonic-gate ** -r -- report to user in addition to other flags. 827c478bd9Sstevel@tonic-gate ** -EC -- set the erase character to C on all terminals 837c478bd9Sstevel@tonic-gate ** except those which cannot backspace (e.g., 847c478bd9Sstevel@tonic-gate ** a TTY 33). C defaults to control-H. 857c478bd9Sstevel@tonic-gate ** -eC -- set the erase character to C on all terminals. 867c478bd9Sstevel@tonic-gate ** C defaults to control-H. If not specified, 877c478bd9Sstevel@tonic-gate ** the erase character is untouched; however, if 887c478bd9Sstevel@tonic-gate ** not specified and the erase character is NULL 897c478bd9Sstevel@tonic-gate ** (zero byte), the erase character is set to CERASE. 907c478bd9Sstevel@tonic-gate ** -kC -- set the kill character to C on all terminals. 917c478bd9Sstevel@tonic-gate ** Default for C is control-U. If not specified, 927c478bd9Sstevel@tonic-gate ** the kill character is untouched; however, if 937c478bd9Sstevel@tonic-gate ** not specified and the kill character is NULL 947c478bd9Sstevel@tonic-gate ** (zero byte), the kill character is set to CKILL. 957c478bd9Sstevel@tonic-gate ** -iC -- set the interrupt character to C on all terminals. 967c478bd9Sstevel@tonic-gate ** Default for C is control-C. If not specified, the 977c478bd9Sstevel@tonic-gate ** interrupt character is untouched; however, if 987c478bd9Sstevel@tonic-gate ** not specified and the interrupt character is NULL 997c478bd9Sstevel@tonic-gate ** (zero byte), the interrupt character is set to 1007c478bd9Sstevel@tonic-gate ** control-C. 1017c478bd9Sstevel@tonic-gate ** -qC -- reserved for setable quit character. 1027c478bd9Sstevel@tonic-gate ** -m -- map the system identified type to some user 1037c478bd9Sstevel@tonic-gate ** specified type. The mapping can be baud rate 1047c478bd9Sstevel@tonic-gate ** dependent. This replaces the old -d, -p flags. 1057c478bd9Sstevel@tonic-gate ** (-d type -> -m dialup:type) 1067c478bd9Sstevel@tonic-gate ** (-p type -> -m plug:type) 1077c478bd9Sstevel@tonic-gate ** Syntax: -m identifier [test baudrate] :type 1087c478bd9Sstevel@tonic-gate ** where: ``identifier'' is terminal type found in 1097c478bd9Sstevel@tonic-gate ** /etc/ttys for this port, (abscence of an identifier 1107c478bd9Sstevel@tonic-gate ** matches any identifier); ``test'' may be any combination 1117c478bd9Sstevel@tonic-gate ** of > = < ! @; ``baudrate'' is as with stty(1); 1127c478bd9Sstevel@tonic-gate ** ``type'' is the actual terminal type to use if the 1137c478bd9Sstevel@tonic-gate ** mapping condition is met. Multiple maps are scanned 1147c478bd9Sstevel@tonic-gate ** in order and the first match prevails. 1157c478bd9Sstevel@tonic-gate ** -n -- If the new tty driver from UCB is available, this flag 1167c478bd9Sstevel@tonic-gate ** will activate the new options for erase and kill 1177c478bd9Sstevel@tonic-gate ** processing. This will be different for printers 1187c478bd9Sstevel@tonic-gate ** and crt's. For crts, if the baud rate is < 1200 then 1197c478bd9Sstevel@tonic-gate ** erase and kill don't remove characters from the screen. 1207c478bd9Sstevel@tonic-gate ** -h -- don't read htmp file. Normally the terminal type 1217c478bd9Sstevel@tonic-gate ** is determined by reading the htmp file or the 1227c478bd9Sstevel@tonic-gate ** environment (unless some mapping is specified). 1237c478bd9Sstevel@tonic-gate ** This forces a read of the ttytype file -- useful 1247c478bd9Sstevel@tonic-gate ** when htmp is somehow wrong. (V6 only) 1257c478bd9Sstevel@tonic-gate ** -u -- don't update htmp. It seemed like this should 1267c478bd9Sstevel@tonic-gate ** be put in. Note that htmp is never actually 1277c478bd9Sstevel@tonic-gate ** written if there are no changes, so don't bother 1287c478bd9Sstevel@tonic-gate ** bother using this for efficiency reasons alone. 1297c478bd9Sstevel@tonic-gate ** -s -- output setenv commands for TERM. This can be 1307c478bd9Sstevel@tonic-gate ** used with 1317c478bd9Sstevel@tonic-gate ** `tset -s ...` 1327c478bd9Sstevel@tonic-gate ** and is to be prefered to: 1337c478bd9Sstevel@tonic-gate ** setenv TERM `tset - ...` 1347c478bd9Sstevel@tonic-gate ** because -s sets the TERMCAP variable also. 1357c478bd9Sstevel@tonic-gate ** -S -- Similar to -s but outputs 2 strings suitable for 1367c478bd9Sstevel@tonic-gate ** use in csh .login files as follows: 1377c478bd9Sstevel@tonic-gate ** set noglob 1387c478bd9Sstevel@tonic-gate ** set term=(`tset -S .....`) 1397c478bd9Sstevel@tonic-gate ** setenv TERM $term[1] 1407c478bd9Sstevel@tonic-gate ** setenv TERMCAP "$term[2]" 1417c478bd9Sstevel@tonic-gate ** unset term 1427c478bd9Sstevel@tonic-gate ** unset noglob 1437c478bd9Sstevel@tonic-gate ** -Q -- be quiet. don't output 'Erase set to' etc. 1447c478bd9Sstevel@tonic-gate ** -I -- don't do terminal initialization (is & if 1457c478bd9Sstevel@tonic-gate ** strings). 1467c478bd9Sstevel@tonic-gate ** -v -- On virtual terminal systems, don't set up a 1477c478bd9Sstevel@tonic-gate ** virtual terminal. Otherwise tset will tell 1487c478bd9Sstevel@tonic-gate ** the operating system what kind of terminal you 1497c478bd9Sstevel@tonic-gate ** are on (if it is a known terminal) and fix up 1507c478bd9Sstevel@tonic-gate ** the output of -s to use virtual terminal sequences. 1517c478bd9Sstevel@tonic-gate ** 1527c478bd9Sstevel@tonic-gate ** Files: 1537c478bd9Sstevel@tonic-gate ** /etc/ttys 1547c478bd9Sstevel@tonic-gate ** contains a terminal id -> terminal type 1557c478bd9Sstevel@tonic-gate ** mapping; used when any user mapping is specified, 1567c478bd9Sstevel@tonic-gate ** or the environment doesn't have TERM set. 1577c478bd9Sstevel@tonic-gate ** /etc/termcap 1587c478bd9Sstevel@tonic-gate ** a terminal_type -> terminal_capabilities 1597c478bd9Sstevel@tonic-gate ** mapping. 1607c478bd9Sstevel@tonic-gate ** 1617c478bd9Sstevel@tonic-gate ** Return Codes: 1627c478bd9Sstevel@tonic-gate ** -1 -- couldn't open termcap. 1637c478bd9Sstevel@tonic-gate ** 1 -- bad terminal type, or standard output not tty. 1647c478bd9Sstevel@tonic-gate ** 0 -- ok. 1657c478bd9Sstevel@tonic-gate ** 1667c478bd9Sstevel@tonic-gate ** Defined Constants: 1677c478bd9Sstevel@tonic-gate ** DIALUP -- the type code for a dialup port. 1687c478bd9Sstevel@tonic-gate ** PLUGBOARD -- the type code for a plugboard port. 1697c478bd9Sstevel@tonic-gate ** ARPANET -- the type code for an arpanet port. 1707c478bd9Sstevel@tonic-gate ** BACKSPACE -- control-H, the default for -e. 1717c478bd9Sstevel@tonic-gate ** CNTL('U') -- control-U, the default for -k. 1727c478bd9Sstevel@tonic-gate ** OLDERASE -- the ancient default erase character. 1737c478bd9Sstevel@tonic-gate ** FILEDES -- the file descriptor to do the operation 1747c478bd9Sstevel@tonic-gate ** on, nominally 1 or 2. 1757c478bd9Sstevel@tonic-gate ** STDOUT -- the standard output file descriptor. 1767c478bd9Sstevel@tonic-gate ** UIDMASK -- the bit pattern to mask with the getuid() 1777c478bd9Sstevel@tonic-gate ** call to get just the user id. 1787c478bd9Sstevel@tonic-gate ** GTTYN -- defines file containing generalized ttynames 1797c478bd9Sstevel@tonic-gate ** and compiles code to look there. 1807c478bd9Sstevel@tonic-gate ** 1817c478bd9Sstevel@tonic-gate ** Requires: 1827c478bd9Sstevel@tonic-gate ** Routines to handle htmp, ttys, and termcap. 1837c478bd9Sstevel@tonic-gate ** 1847c478bd9Sstevel@tonic-gate ** Compilation Flags: 1857c478bd9Sstevel@tonic-gate ** OLDFLAGS -- must be defined to compile code for any of 1867c478bd9Sstevel@tonic-gate ** the -d, -p, or -a flags. 1877c478bd9Sstevel@tonic-gate ** OLDDIALUP -- accept the -d flag. 1887c478bd9Sstevel@tonic-gate ** OLDPLUGBOARD -- accept the -p flag. 1897c478bd9Sstevel@tonic-gate ** OLDARPANET -- accept the -a flag. 1907c478bd9Sstevel@tonic-gate ** V6 -- if clear, use environments, not htmp. 1917c478bd9Sstevel@tonic-gate ** also use TIOCSETN rather than stty to avoid flushing 1927c478bd9Sstevel@tonic-gate ** GTTYN -- if set, compiles code to look at /etc/ttys. 1937c478bd9Sstevel@tonic-gate ** 1947c478bd9Sstevel@tonic-gate ** Trace Flags: 1957c478bd9Sstevel@tonic-gate ** none 1967c478bd9Sstevel@tonic-gate ** 1977c478bd9Sstevel@tonic-gate ** Diagnostics: 1987c478bd9Sstevel@tonic-gate ** Bad flag 1997c478bd9Sstevel@tonic-gate ** An incorrect option was specified. 2007c478bd9Sstevel@tonic-gate ** Too few args 2017c478bd9Sstevel@tonic-gate ** more command line arguments are required. 2027c478bd9Sstevel@tonic-gate ** Unexpected arg 2037c478bd9Sstevel@tonic-gate ** wrong type of argument was encountered. 2047c478bd9Sstevel@tonic-gate ** Cannot open ... 2057c478bd9Sstevel@tonic-gate ** The specified file could not be openned. 2067c478bd9Sstevel@tonic-gate ** Type ... unknown 2077c478bd9Sstevel@tonic-gate ** An unknown terminal type was specified. 2087c478bd9Sstevel@tonic-gate ** Cannot update htmp 2097c478bd9Sstevel@tonic-gate ** Cannot update htmp file when the standard 2107c478bd9Sstevel@tonic-gate ** output is not a terminal. 2117c478bd9Sstevel@tonic-gate ** Erase set to ... 2127c478bd9Sstevel@tonic-gate ** Telling that the erase character has been 2137c478bd9Sstevel@tonic-gate ** set to the specified character. 2147c478bd9Sstevel@tonic-gate ** Kill set to ... 2157c478bd9Sstevel@tonic-gate ** Ditto for kill 2167c478bd9Sstevel@tonic-gate ** Erase is ... Kill is ... 2177c478bd9Sstevel@tonic-gate ** Tells that the erase/kill characters were 2187c478bd9Sstevel@tonic-gate ** wierd before, but they are being left as-is. 2197c478bd9Sstevel@tonic-gate ** Not a terminal 2207c478bd9Sstevel@tonic-gate ** Set if FILEDES is not a terminal. 2217c478bd9Sstevel@tonic-gate ** 2227c478bd9Sstevel@tonic-gate ** Compilation Instructions: 2237c478bd9Sstevel@tonic-gate ** cc -n -O tset.c -ltermlib 2247c478bd9Sstevel@tonic-gate ** mv a.out tset 2257c478bd9Sstevel@tonic-gate ** chown bin tset 2267c478bd9Sstevel@tonic-gate ** chmod 4755 tset 2277c478bd9Sstevel@tonic-gate ** 2287c478bd9Sstevel@tonic-gate ** where 'bin' should be whoever owns the 'htmp' file. 2297c478bd9Sstevel@tonic-gate ** If 'htmp' is 666, then tset need not be setuid. 2307c478bd9Sstevel@tonic-gate ** 2317c478bd9Sstevel@tonic-gate ** For version 6 the compile command should be: 2327c478bd9Sstevel@tonic-gate ** cc -n -O -I/usr/include/retrofit tset.c -ltermlib -lretro -lS 2337c478bd9Sstevel@tonic-gate ** 2347c478bd9Sstevel@tonic-gate ** 2357c478bd9Sstevel@tonic-gate ** History: 2367c478bd9Sstevel@tonic-gate ** 1/81 -- Added alias checking for mapping identifiers. 2377c478bd9Sstevel@tonic-gate ** 7/80 -- '-S' added. '-m' mapping added. TERMCAP string 2387c478bd9Sstevel@tonic-gate ** cleaned up. 2397c478bd9Sstevel@tonic-gate ** 3/80 -- Changed to use tputs. Prc & flush added. 2407c478bd9Sstevel@tonic-gate ** 10/79 -- '-s' option extended to handle TERMCAP 2417c478bd9Sstevel@tonic-gate ** variable, set noglob, quote the entry, 2427c478bd9Sstevel@tonic-gate ** and know about the Bourne shell. Terminal 2437c478bd9Sstevel@tonic-gate ** initialization moved to before any information 2447c478bd9Sstevel@tonic-gate ** output so screen clears would not screw you. 2457c478bd9Sstevel@tonic-gate ** '-Q' option added. 2467c478bd9Sstevel@tonic-gate ** 8/79 -- '-' option alone changed to only output 2477c478bd9Sstevel@tonic-gate ** type. '-s' option added. 'VERSION7' 2487c478bd9Sstevel@tonic-gate ** changed to 'V6' for compatibility. 2497c478bd9Sstevel@tonic-gate ** 12/78 -- modified for eventual migration to VAX/UNIX, 2507c478bd9Sstevel@tonic-gate ** so the '-' option is changed to output only 2517c478bd9Sstevel@tonic-gate ** the terminal type to STDOUT instead of 2527c478bd9Sstevel@tonic-gate ** FILEDES. 2537c478bd9Sstevel@tonic-gate ** 9/78 -- '-' and '-p' options added (now fully 2547c478bd9Sstevel@tonic-gate ** compatible with ttytype!), and spaces are 2557c478bd9Sstevel@tonic-gate ** permitted between the -d and the type. 2567c478bd9Sstevel@tonic-gate ** 8/78 -- The sense of -h and -u were reversed, and the 2577c478bd9Sstevel@tonic-gate ** -f flag is dropped -- same effect is available 2587c478bd9Sstevel@tonic-gate ** by just stating the terminal type. 2597c478bd9Sstevel@tonic-gate ** 10/77 -- Written. 2607c478bd9Sstevel@tonic-gate */ 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate 2637c478bd9Sstevel@tonic-gate #define index strchr 2647c478bd9Sstevel@tonic-gate #define rindex strrchr 2657c478bd9Sstevel@tonic-gate #define curerase modes.c_cc[VERASE] 2667c478bd9Sstevel@tonic-gate #define curkill modes.c_cc[VKILL] 2677c478bd9Sstevel@tonic-gate #define curintr modes.c_cc[VINTR] 2687c478bd9Sstevel@tonic-gate #define olderase oldmodes.c_cc[VERASE] 2697c478bd9Sstevel@tonic-gate #define oldkill oldmodes.c_cc[VKILL] 2707c478bd9Sstevel@tonic-gate #define oldintr oldmodes.c_cc[VINTR] 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate #include <stdio.h> 2737c478bd9Sstevel@tonic-gate #include <termio.h> 2747c478bd9Sstevel@tonic-gate #include <signal.h> 2757c478bd9Sstevel@tonic-gate 2767c478bd9Sstevel@tonic-gate 2777c478bd9Sstevel@tonic-gate #define YES 1 2787c478bd9Sstevel@tonic-gate #define NO 0 2797c478bd9Sstevel@tonic-gate #undef CNTL 2807c478bd9Sstevel@tonic-gate #define CNTL(c) ((c)&037) 2817c478bd9Sstevel@tonic-gate #define BACKSPACE (CNTL('H')) 2827c478bd9Sstevel@tonic-gate #define isdigit(c) (c >= '0' && c <= '9') 2837c478bd9Sstevel@tonic-gate #define isalnum(c) (c > ' ' && (index("<@=>!:|\177", c) == NULL)) 2847c478bd9Sstevel@tonic-gate #define OLDERASE '#' 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate /* default special characters */ 2877c478bd9Sstevel@tonic-gate #ifndef CERASE 2887c478bd9Sstevel@tonic-gate #define CERASE '\177' 2897c478bd9Sstevel@tonic-gate #endif 2907c478bd9Sstevel@tonic-gate #ifndef CKILL 2917c478bd9Sstevel@tonic-gate #define CKILL CNTL('U') 2927c478bd9Sstevel@tonic-gate #endif 2937c478bd9Sstevel@tonic-gate #ifndef CINTR 2947c478bd9Sstevel@tonic-gate #define CINTR CNTL('C') 2957c478bd9Sstevel@tonic-gate #endif 2967c478bd9Sstevel@tonic-gate #ifndef CDSUSP 2977c478bd9Sstevel@tonic-gate #define CQUIT 034 /* FS, ^\ */ 2987c478bd9Sstevel@tonic-gate #define CSTART CNTL('Q') 2997c478bd9Sstevel@tonic-gate #define CSTOP CNTL('S') 3007c478bd9Sstevel@tonic-gate #define CEOF CNTL('D') 3017c478bd9Sstevel@tonic-gate #define CEOT CEOF 3027c478bd9Sstevel@tonic-gate #define CBRK 0377 3037c478bd9Sstevel@tonic-gate #define CSUSP CNTL('Z') 3047c478bd9Sstevel@tonic-gate #define CDSUSP CNTL('Y') 3057c478bd9Sstevel@tonic-gate #define CRPRNT CNTL('R') 3067c478bd9Sstevel@tonic-gate #define CFLUSH CNTL('O') 3077c478bd9Sstevel@tonic-gate #define CWERASE CNTL('W') 3087c478bd9Sstevel@tonic-gate #define CLNEXT CNTL('V') 3097c478bd9Sstevel@tonic-gate #endif 3107c478bd9Sstevel@tonic-gate 3117c478bd9Sstevel@tonic-gate #define FILEDES 2 /* do gtty/stty on this descriptor */ 3127c478bd9Sstevel@tonic-gate #define STDOUT 1 /* output of -s/-S to this descriptor */ 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate #define UIDMASK -1 3157c478bd9Sstevel@tonic-gate 3167c478bd9Sstevel@tonic-gate #define USAGE "usage: tset [-] [-rsIQS] [-eC] [-kC] [-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" 323*cc6c5292Schin /* 3247c478bd9Sstevel@tonic-gate #define ARPANET "arpanet" 3257c478bd9Sstevel@tonic-gate #define OLDARPANET "sa" 326*cc6c5292Schin */ 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate #define DEFTYPE "unknown" 3297c478bd9Sstevel@tonic-gate 3307c478bd9Sstevel@tonic-gate #define NOTTY 'x' 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate /* 3337c478bd9Sstevel@tonic-gate * Baud Rate Conditionals 3347c478bd9Sstevel@tonic-gate */ 3357c478bd9Sstevel@tonic-gate #define ANY 0 3367c478bd9Sstevel@tonic-gate #define GT 1 3377c478bd9Sstevel@tonic-gate #define EQ 2 3387c478bd9Sstevel@tonic-gate #define LT 4 3397c478bd9Sstevel@tonic-gate #define GE (GT|EQ) 3407c478bd9Sstevel@tonic-gate #define LE (LT|EQ) 3417c478bd9Sstevel@tonic-gate #define NE (GT|LT) 3427c478bd9Sstevel@tonic-gate #define ALL (GT|EQ|LT) 3437c478bd9Sstevel@tonic-gate 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate 3467c478bd9Sstevel@tonic-gate #define NMAP 10 3477c478bd9Sstevel@tonic-gate 3487c478bd9Sstevel@tonic-gate struct map { 3497c478bd9Sstevel@tonic-gate char *Ident; 3507c478bd9Sstevel@tonic-gate char Test; 3517c478bd9Sstevel@tonic-gate char Speed; 3527c478bd9Sstevel@tonic-gate char *Type; 3537c478bd9Sstevel@tonic-gate } map[NMAP]; 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate struct map *Map = map; 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate /* This should be available in an include file */ 3587c478bd9Sstevel@tonic-gate struct 3597c478bd9Sstevel@tonic-gate { 3607c478bd9Sstevel@tonic-gate char *string; 3617c478bd9Sstevel@tonic-gate int speed; 3627c478bd9Sstevel@tonic-gate int baudrate; 3637c478bd9Sstevel@tonic-gate } speeds[] = { 3647c478bd9Sstevel@tonic-gate "0", B0, 0, 3657c478bd9Sstevel@tonic-gate "50", B50, 50, 3667c478bd9Sstevel@tonic-gate "75", B75, 75, 3677c478bd9Sstevel@tonic-gate "110", B110, 110, 3687c478bd9Sstevel@tonic-gate "134", B134, 134, 3697c478bd9Sstevel@tonic-gate "134.5",B134, 134, 3707c478bd9Sstevel@tonic-gate "150", B150, 150, 3717c478bd9Sstevel@tonic-gate "200", B200, 200, 3727c478bd9Sstevel@tonic-gate "300", B300, 300, 3737c478bd9Sstevel@tonic-gate "600", B600, 600, 3747c478bd9Sstevel@tonic-gate "1200", B1200, 1200, 3757c478bd9Sstevel@tonic-gate "1800", B1800, 1800, 3767c478bd9Sstevel@tonic-gate "2400", B2400, 2400, 3777c478bd9Sstevel@tonic-gate "4800", B4800, 4800, 3787c478bd9Sstevel@tonic-gate "9600", B9600, 9600, 3797c478bd9Sstevel@tonic-gate "19200",EXTA, 19200, 3807c478bd9Sstevel@tonic-gate "exta", EXTA, 19200, 3817c478bd9Sstevel@tonic-gate "extb", EXTB, 38400, 3827c478bd9Sstevel@tonic-gate "57600",B57600, 57600, 3837c478bd9Sstevel@tonic-gate "76800",B76800, 76800, 3847c478bd9Sstevel@tonic-gate "115200",B115200,115200, 3857c478bd9Sstevel@tonic-gate "153600",B153600,153600, 3867c478bd9Sstevel@tonic-gate "230400",B230400,230400, 3877c478bd9Sstevel@tonic-gate "307200",B307200,307200, 3887c478bd9Sstevel@tonic-gate "460800",B460800,460800, 3897c478bd9Sstevel@tonic-gate 0, 3907c478bd9Sstevel@tonic-gate }; 3917c478bd9Sstevel@tonic-gate 3927c478bd9Sstevel@tonic-gate signed char Erase_char; /* new erase character */ 3937c478bd9Sstevel@tonic-gate char Kill_char; /* new kill character */ 3947c478bd9Sstevel@tonic-gate char Intr_char; /* new interrupt character */ 3957c478bd9Sstevel@tonic-gate char Specialerase; /* set => Erase_char only on terminals with backspace */ 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate char Ttyid = NOTTY; /* terminal identifier */ 3987c478bd9Sstevel@tonic-gate char *TtyType; /* type of terminal */ 3997c478bd9Sstevel@tonic-gate char *DefType; /* default type if none other computed */ 4007c478bd9Sstevel@tonic-gate char *NewType; /* mapping identifier based on old flags */ 4017c478bd9Sstevel@tonic-gate int Mapped; /* mapping has been specified */ 4027c478bd9Sstevel@tonic-gate int Dash_u; /* don't update htmp */ 4037c478bd9Sstevel@tonic-gate int Dash_h; /* don't read htmp */ 4047c478bd9Sstevel@tonic-gate int DoSetenv; /* output setenv commands */ 4057c478bd9Sstevel@tonic-gate int BeQuiet; /* be quiet */ 4067c478bd9Sstevel@tonic-gate int NoInit; /* don't output initialization string */ 4077c478bd9Sstevel@tonic-gate int IsReset; /* invoked as reset */ 4087c478bd9Sstevel@tonic-gate int Report; /* report current type */ 4097c478bd9Sstevel@tonic-gate int Ureport; /* report to user */ 4107c478bd9Sstevel@tonic-gate int RepOnly; /* report only */ 4117c478bd9Sstevel@tonic-gate int CmndLine; /* output full command lines (-s option) */ 4127c478bd9Sstevel@tonic-gate int Ask; /* ask user for termtype */ 4137c478bd9Sstevel@tonic-gate int DoVirtTerm = YES; /* Set up a virtual terminal */ 4147c478bd9Sstevel@tonic-gate int PadBaud; /* Min rate of padding needed */ 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate #define CAPBUFSIZ 1024 4177c478bd9Sstevel@tonic-gate char Capbuf[CAPBUFSIZ]; /* line from /etc/termcap for this TtyType */ 4187c478bd9Sstevel@tonic-gate char *Ttycap; /* termcap line from termcap or environ */ 4197c478bd9Sstevel@tonic-gate 4207c478bd9Sstevel@tonic-gate char Aliasbuf[128]; 4217c478bd9Sstevel@tonic-gate char *Alias[16]; 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate extern char *strcpy(); 4247c478bd9Sstevel@tonic-gate extern char *index(); 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate struct delay 4277c478bd9Sstevel@tonic-gate { 4287c478bd9Sstevel@tonic-gate int d_delay; 4297c478bd9Sstevel@tonic-gate int d_bits; 4307c478bd9Sstevel@tonic-gate }; 4317c478bd9Sstevel@tonic-gate 4327c478bd9Sstevel@tonic-gate #include "tset.delays.h" 4337c478bd9Sstevel@tonic-gate 4347c478bd9Sstevel@tonic-gate struct termio mode; 4357c478bd9Sstevel@tonic-gate struct termio oldmode; 4367c478bd9Sstevel@tonic-gate struct termios modes; 4377c478bd9Sstevel@tonic-gate struct termios oldmodes; 4387c478bd9Sstevel@tonic-gate int istermios; 4397c478bd9Sstevel@tonic-gate 440*cc6c5292Schin void reportek(char *, char, char, char); 441*cc6c5292Schin void setdelay(char *, struct delay [], tcflag_t, tcflag_t *); 442*cc6c5292Schin void prs(char *); 443*cc6c5292Schin void prc(char); 444*cc6c5292Schin void flush(void); 445*cc6c5292Schin void cat(char *); 446*cc6c5292Schin void bmove(char *, char *, int); 447*cc6c5292Schin void makealias(char *); 448*cc6c5292Schin void wrtermcap(char *); 449*cc6c5292Schin void fatal (char *, char *); 4507c478bd9Sstevel@tonic-gate char reset(); /* Routine for checking&resetting chars */ 4517c478bd9Sstevel@tonic-gate 452*cc6c5292Schin int 453*cc6c5292Schin main(int argc, char *argv[]) 4547c478bd9Sstevel@tonic-gate { 4557c478bd9Sstevel@tonic-gate char buf[CAPBUFSIZ]; 4567c478bd9Sstevel@tonic-gate char termbuf[32]; 4577c478bd9Sstevel@tonic-gate auto char *bufp; 458*cc6c5292Schin char *p; 4597c478bd9Sstevel@tonic-gate char *command; 460*cc6c5292Schin int i; 4617c478bd9Sstevel@tonic-gate int Break; 4627c478bd9Sstevel@tonic-gate int Not; 4637c478bd9Sstevel@tonic-gate char *nextarg(); 4647c478bd9Sstevel@tonic-gate char *mapped(); 4657c478bd9Sstevel@tonic-gate extern char *rindex(); 4667c478bd9Sstevel@tonic-gate struct winsize win; 4677c478bd9Sstevel@tonic-gate extern char *getenv(); 4687c478bd9Sstevel@tonic-gate extern char *tgetstr(); 4697c478bd9Sstevel@tonic-gate char bs_char; 4707c478bd9Sstevel@tonic-gate int csh; 4717c478bd9Sstevel@tonic-gate int settle = NO; 4727c478bd9Sstevel@tonic-gate void setmode(); 4737c478bd9Sstevel@tonic-gate extern char PC; 4747c478bd9Sstevel@tonic-gate extern short ospeed; 4757c478bd9Sstevel@tonic-gate 4767c478bd9Sstevel@tonic-gate if ((istermios = ioctl(FILEDES, TCGETS, (char *)&modes)) < 0) { 4777c478bd9Sstevel@tonic-gate if (ioctl(FILEDES, TCGETA, (char *)&mode) < 0) 4787c478bd9Sstevel@tonic-gate { 4797c478bd9Sstevel@tonic-gate prs("Not a terminal\n"); 4807c478bd9Sstevel@tonic-gate exit(1); 4817c478bd9Sstevel@tonic-gate } 4827c478bd9Sstevel@tonic-gate bmove((char *)&mode, (char *)&oldmode, sizeof mode); 4837c478bd9Sstevel@tonic-gate modes.c_lflag = oldmodes.c_lflag = mode.c_lflag; 4847c478bd9Sstevel@tonic-gate modes.c_oflag = oldmodes.c_oflag = mode.c_oflag; 4857c478bd9Sstevel@tonic-gate modes.c_iflag = oldmodes.c_iflag = mode.c_iflag; 4867c478bd9Sstevel@tonic-gate modes.c_cflag = oldmodes.c_cflag = mode.c_cflag; 4877c478bd9Sstevel@tonic-gate for(i = 0; i < NCC; i++) 4887c478bd9Sstevel@tonic-gate modes.c_cc[i] = oldmodes.c_cc[i] = mode.c_cc[i]; 4897c478bd9Sstevel@tonic-gate } else 4907c478bd9Sstevel@tonic-gate bmove((char *)&modes, (char *)&oldmodes, sizeof modes); 4917c478bd9Sstevel@tonic-gate ospeed = cfgetospeed(&modes); 4927c478bd9Sstevel@tonic-gate (void) signal(SIGINT, setmode); 4937c478bd9Sstevel@tonic-gate (void) signal(SIGQUIT, setmode); 4947c478bd9Sstevel@tonic-gate (void) signal(SIGTERM, setmode); 4957c478bd9Sstevel@tonic-gate 4967c478bd9Sstevel@tonic-gate if (command = rindex(argv[0], '/')) 4977c478bd9Sstevel@tonic-gate command++; 4987c478bd9Sstevel@tonic-gate else 4997c478bd9Sstevel@tonic-gate command = argv[0]; 5007c478bd9Sstevel@tonic-gate if (sequal(command, "reset") ) 5017c478bd9Sstevel@tonic-gate { 5027c478bd9Sstevel@tonic-gate /* 5037c478bd9Sstevel@tonic-gate * Reset the teletype mode bits to a sensible state. 5047c478bd9Sstevel@tonic-gate * Copied from the program by Kurt Shoens & Mark Horton. 5057c478bd9Sstevel@tonic-gate * Very useful after crapping out in raw. 5067c478bd9Sstevel@tonic-gate */ 5077c478bd9Sstevel@tonic-gate if ((istermios = ioctl(FILEDES, TCGETS, (char *)&modes)) < 0) { 5087c478bd9Sstevel@tonic-gate (void) ioctl(FILEDES, TCGETA, (char *)&mode); 5097c478bd9Sstevel@tonic-gate modes.c_lflag = mode.c_lflag; 5107c478bd9Sstevel@tonic-gate modes.c_oflag = mode.c_oflag; 5117c478bd9Sstevel@tonic-gate modes.c_iflag = mode.c_iflag; 5127c478bd9Sstevel@tonic-gate modes.c_cflag = mode.c_cflag; 5137c478bd9Sstevel@tonic-gate for(i = 0; i < NCC; i++) 5147c478bd9Sstevel@tonic-gate modes.c_cc[i] = mode.c_cc[i]; 5157c478bd9Sstevel@tonic-gate } 5167c478bd9Sstevel@tonic-gate curerase = reset(curerase, CERASE); 5177c478bd9Sstevel@tonic-gate curkill = reset(curkill, CKILL); 5187c478bd9Sstevel@tonic-gate curintr = reset(curintr, CINTR); 5197c478bd9Sstevel@tonic-gate modes.c_cc[VQUIT] = reset(modes.c_cc[VQUIT], CQUIT); 5207c478bd9Sstevel@tonic-gate modes.c_cc[VEOF] = reset(modes.c_cc[VEOF], CEOF); 5217c478bd9Sstevel@tonic-gate 5227c478bd9Sstevel@tonic-gate modes.c_iflag |= (BRKINT|ISTRIP|ICRNL|IXON); 5237c478bd9Sstevel@tonic-gate modes.c_iflag &= ~(IGNBRK|PARMRK|INPCK|INLCR|IGNCR|IUCLC|IXOFF); 5247c478bd9Sstevel@tonic-gate modes.c_oflag |= (OPOST|ONLCR); 5257c478bd9Sstevel@tonic-gate modes.c_oflag &= ~(OLCUC|OCRNL|ONOCR|ONLRET|OFILL|OFDEL| 5267c478bd9Sstevel@tonic-gate NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY); 5277c478bd9Sstevel@tonic-gate modes.c_cflag |= (CS7|CREAD); 5287c478bd9Sstevel@tonic-gate modes.c_cflag &= ~(PARODD|CLOCAL); 5297c478bd9Sstevel@tonic-gate modes.c_lflag |= (ISIG|ICANON|ECHO|ECHOK); 5307c478bd9Sstevel@tonic-gate modes.c_lflag &= ~(XCASE|ECHONL|NOFLSH); 5317c478bd9Sstevel@tonic-gate if (istermios < 0) { 5327c478bd9Sstevel@tonic-gate mode.c_lflag = modes.c_lflag; 5337c478bd9Sstevel@tonic-gate mode.c_oflag = modes.c_oflag; 5347c478bd9Sstevel@tonic-gate mode.c_iflag = modes.c_iflag; 5357c478bd9Sstevel@tonic-gate mode.c_cflag = modes.c_cflag; 5367c478bd9Sstevel@tonic-gate for(i = 0; i < NCC; i++) 5377c478bd9Sstevel@tonic-gate mode.c_cc[i] = modes.c_cc[i]; 5387c478bd9Sstevel@tonic-gate (void) ioctl(FILEDES, TCSETAW, (char *)&mode); 5397c478bd9Sstevel@tonic-gate } else 5407c478bd9Sstevel@tonic-gate (void) ioctl(FILEDES, TCSETSW, (char *)&modes); 5417c478bd9Sstevel@tonic-gate Dash_u = YES; 5427c478bd9Sstevel@tonic-gate BeQuiet = YES; 5437c478bd9Sstevel@tonic-gate IsReset = YES; 5447c478bd9Sstevel@tonic-gate } 5457c478bd9Sstevel@tonic-gate else if (argc == 2 && sequal(argv[1], "-")) 5467c478bd9Sstevel@tonic-gate { 5477c478bd9Sstevel@tonic-gate RepOnly = YES; 5487c478bd9Sstevel@tonic-gate Dash_u = YES; 5497c478bd9Sstevel@tonic-gate } 5507c478bd9Sstevel@tonic-gate argc--; 5517c478bd9Sstevel@tonic-gate 5527c478bd9Sstevel@tonic-gate /* scan argument list and collect flags */ 5537c478bd9Sstevel@tonic-gate while (--argc >= 0) 5547c478bd9Sstevel@tonic-gate { 5557c478bd9Sstevel@tonic-gate p = *++argv; 5567c478bd9Sstevel@tonic-gate if (*p == '-') 5577c478bd9Sstevel@tonic-gate { 5587c478bd9Sstevel@tonic-gate if (*++p == NULL) 5597c478bd9Sstevel@tonic-gate Report = YES; /* report current terminal type */ 5607c478bd9Sstevel@tonic-gate else while (*p) switch (*p++) 5617c478bd9Sstevel@tonic-gate { 5627c478bd9Sstevel@tonic-gate 5637c478bd9Sstevel@tonic-gate case 'r': /* report to user */ 5647c478bd9Sstevel@tonic-gate Ureport = YES; 5657c478bd9Sstevel@tonic-gate continue; 5667c478bd9Sstevel@tonic-gate 5677c478bd9Sstevel@tonic-gate case 'E': /* special erase: operate on all but TTY33 */ 5687c478bd9Sstevel@tonic-gate Specialerase = YES; 5697c478bd9Sstevel@tonic-gate /* explicit fall-through to -e case */ 5707c478bd9Sstevel@tonic-gate 5717c478bd9Sstevel@tonic-gate case 'e': /* erase character */ 5727c478bd9Sstevel@tonic-gate if (*p == NULL) 5737c478bd9Sstevel@tonic-gate Erase_char = -1; 5747c478bd9Sstevel@tonic-gate else 5757c478bd9Sstevel@tonic-gate { 5767c478bd9Sstevel@tonic-gate if (*p == '^' && p[1] != NULL) 5777c478bd9Sstevel@tonic-gate if (*++p == '?') 5787c478bd9Sstevel@tonic-gate Erase_char = '\177'; 5797c478bd9Sstevel@tonic-gate else 5807c478bd9Sstevel@tonic-gate Erase_char = CNTL(*p); 5817c478bd9Sstevel@tonic-gate else 5827c478bd9Sstevel@tonic-gate Erase_char = *p; 5837c478bd9Sstevel@tonic-gate p++; 5847c478bd9Sstevel@tonic-gate } 5857c478bd9Sstevel@tonic-gate continue; 5867c478bd9Sstevel@tonic-gate 5877c478bd9Sstevel@tonic-gate case 'i': /* interrupt character */ 5887c478bd9Sstevel@tonic-gate if (*p == NULL) 5897c478bd9Sstevel@tonic-gate Intr_char = CNTL('C'); 5907c478bd9Sstevel@tonic-gate else 5917c478bd9Sstevel@tonic-gate { 5927c478bd9Sstevel@tonic-gate if (*p == '^' && p[1] != NULL) 5937c478bd9Sstevel@tonic-gate if (*++p == '?') 5947c478bd9Sstevel@tonic-gate Intr_char = '\177'; 5957c478bd9Sstevel@tonic-gate else 5967c478bd9Sstevel@tonic-gate Intr_char = CNTL(*p); 5977c478bd9Sstevel@tonic-gate else 5987c478bd9Sstevel@tonic-gate Intr_char = *p; 5997c478bd9Sstevel@tonic-gate p++; 6007c478bd9Sstevel@tonic-gate } 6017c478bd9Sstevel@tonic-gate continue; 6027c478bd9Sstevel@tonic-gate 6037c478bd9Sstevel@tonic-gate case 'k': /* kill character */ 6047c478bd9Sstevel@tonic-gate if (*p == NULL) 6057c478bd9Sstevel@tonic-gate Kill_char = CNTL('U'); 6067c478bd9Sstevel@tonic-gate else 6077c478bd9Sstevel@tonic-gate { 6087c478bd9Sstevel@tonic-gate if (*p == '^' && p[1] != NULL) 6097c478bd9Sstevel@tonic-gate if (*++p == '?') 6107c478bd9Sstevel@tonic-gate Kill_char = '\177'; 6117c478bd9Sstevel@tonic-gate else 6127c478bd9Sstevel@tonic-gate Kill_char = CNTL(*p); 6137c478bd9Sstevel@tonic-gate else 6147c478bd9Sstevel@tonic-gate Kill_char = *p; 6157c478bd9Sstevel@tonic-gate p++; 6167c478bd9Sstevel@tonic-gate } 6177c478bd9Sstevel@tonic-gate continue; 6187c478bd9Sstevel@tonic-gate 6197c478bd9Sstevel@tonic-gate # ifdef OLDFLAGS 6207c478bd9Sstevel@tonic-gate # ifdef OLDDIALUP 6217c478bd9Sstevel@tonic-gate case 'd': /* dialup type */ 6227c478bd9Sstevel@tonic-gate NewType = DIALUP; 6237c478bd9Sstevel@tonic-gate goto mapold; 6247c478bd9Sstevel@tonic-gate # endif 6257c478bd9Sstevel@tonic-gate 6267c478bd9Sstevel@tonic-gate # ifdef OLDPLUGBOARD 6277c478bd9Sstevel@tonic-gate case 'p': /* plugboard type */ 6287c478bd9Sstevel@tonic-gate NewType = PLUGBOARD; 6297c478bd9Sstevel@tonic-gate goto mapold; 6307c478bd9Sstevel@tonic-gate # endif 6317c478bd9Sstevel@tonic-gate 6327c478bd9Sstevel@tonic-gate # ifdef OLDARPANET 6337c478bd9Sstevel@tonic-gate case 'a': /* arpanet type */ 6347c478bd9Sstevel@tonic-gate Newtype = ARPANET; 6357c478bd9Sstevel@tonic-gate goto mapold; 6367c478bd9Sstevel@tonic-gate # endif 6377c478bd9Sstevel@tonic-gate 6387c478bd9Sstevel@tonic-gate mapold: Map->Ident = NewType; 6397c478bd9Sstevel@tonic-gate Map->Test = ALL; 6407c478bd9Sstevel@tonic-gate if (*p == NULL) 6417c478bd9Sstevel@tonic-gate { 6427c478bd9Sstevel@tonic-gate p = nextarg(argc--, argv++); 6437c478bd9Sstevel@tonic-gate } 6447c478bd9Sstevel@tonic-gate Map->Type = p; 6457c478bd9Sstevel@tonic-gate Map++; 6467c478bd9Sstevel@tonic-gate Mapped = YES; 6477c478bd9Sstevel@tonic-gate p = ""; 6487c478bd9Sstevel@tonic-gate continue; 6497c478bd9Sstevel@tonic-gate # endif 6507c478bd9Sstevel@tonic-gate 6517c478bd9Sstevel@tonic-gate case 'm': /* map identifier to type */ 6527c478bd9Sstevel@tonic-gate /* This code is very loose. Almost no 6537c478bd9Sstevel@tonic-gate ** syntax checking is done!! However, 6547c478bd9Sstevel@tonic-gate ** illegal syntax will only produce 6557c478bd9Sstevel@tonic-gate ** weird results. 6567c478bd9Sstevel@tonic-gate */ 6577c478bd9Sstevel@tonic-gate if (*p == NULL) 6587c478bd9Sstevel@tonic-gate { 6597c478bd9Sstevel@tonic-gate p = nextarg(argc--, argv++); 6607c478bd9Sstevel@tonic-gate } 6617c478bd9Sstevel@tonic-gate if (isalnum(*p)) 6627c478bd9Sstevel@tonic-gate { 6637c478bd9Sstevel@tonic-gate Map->Ident = p; /* identifier */ 6647c478bd9Sstevel@tonic-gate while (isalnum(*p)) p++; 6657c478bd9Sstevel@tonic-gate } 6667c478bd9Sstevel@tonic-gate else 6677c478bd9Sstevel@tonic-gate Map->Ident = ""; 6687c478bd9Sstevel@tonic-gate Break = NO; 6697c478bd9Sstevel@tonic-gate Not = NO; 6707c478bd9Sstevel@tonic-gate while (!Break) switch (*p) 6717c478bd9Sstevel@tonic-gate { 6727c478bd9Sstevel@tonic-gate case NULL: 6737c478bd9Sstevel@tonic-gate p = nextarg(argc--, argv++); 6747c478bd9Sstevel@tonic-gate continue; 6757c478bd9Sstevel@tonic-gate 6767c478bd9Sstevel@tonic-gate case ':': /* mapped type */ 6777c478bd9Sstevel@tonic-gate *p++ = NULL; 6787c478bd9Sstevel@tonic-gate Break = YES; 6797c478bd9Sstevel@tonic-gate continue; 6807c478bd9Sstevel@tonic-gate 6817c478bd9Sstevel@tonic-gate case '>': /* conditional */ 6827c478bd9Sstevel@tonic-gate Map->Test |= GT; 6837c478bd9Sstevel@tonic-gate *p++ = NULL; 6847c478bd9Sstevel@tonic-gate continue; 6857c478bd9Sstevel@tonic-gate 6867c478bd9Sstevel@tonic-gate case '<': /* conditional */ 6877c478bd9Sstevel@tonic-gate Map->Test |= LT; 6887c478bd9Sstevel@tonic-gate *p++ = NULL; 6897c478bd9Sstevel@tonic-gate continue; 6907c478bd9Sstevel@tonic-gate 6917c478bd9Sstevel@tonic-gate case '=': /* conditional */ 6927c478bd9Sstevel@tonic-gate case '@': 6937c478bd9Sstevel@tonic-gate Map->Test |= EQ; 6947c478bd9Sstevel@tonic-gate *p++ = NULL; 6957c478bd9Sstevel@tonic-gate continue; 6967c478bd9Sstevel@tonic-gate 6977c478bd9Sstevel@tonic-gate case '!': /* invert conditions */ 6987c478bd9Sstevel@tonic-gate Not = ~Not; 6997c478bd9Sstevel@tonic-gate *p++ = NULL; 7007c478bd9Sstevel@tonic-gate continue; 7017c478bd9Sstevel@tonic-gate 7027c478bd9Sstevel@tonic-gate case 'B': /* Baud rate */ 7037c478bd9Sstevel@tonic-gate p++; 7047c478bd9Sstevel@tonic-gate /* intentional fallthru */ 7057c478bd9Sstevel@tonic-gate default: 7067c478bd9Sstevel@tonic-gate if (isdigit(*p) || *p == 'e') 7077c478bd9Sstevel@tonic-gate { 7087c478bd9Sstevel@tonic-gate Map->Speed = baudrate(p); 7097c478bd9Sstevel@tonic-gate while (isalnum(*p) || *p == '.') 7107c478bd9Sstevel@tonic-gate p++; 7117c478bd9Sstevel@tonic-gate } 7127c478bd9Sstevel@tonic-gate else 7137c478bd9Sstevel@tonic-gate Break = YES; 7147c478bd9Sstevel@tonic-gate continue; 7157c478bd9Sstevel@tonic-gate } 7167c478bd9Sstevel@tonic-gate if (Not) /* invert sense of test */ 7177c478bd9Sstevel@tonic-gate { 7187c478bd9Sstevel@tonic-gate Map->Test = (~(Map->Test))&ALL; 7197c478bd9Sstevel@tonic-gate } 7207c478bd9Sstevel@tonic-gate if (*p == NULL) 7217c478bd9Sstevel@tonic-gate { 7227c478bd9Sstevel@tonic-gate p = nextarg(argc--, argv++); 7237c478bd9Sstevel@tonic-gate } 7247c478bd9Sstevel@tonic-gate Map->Type = p; 7257c478bd9Sstevel@tonic-gate p = ""; 7267c478bd9Sstevel@tonic-gate Map++; 7277c478bd9Sstevel@tonic-gate Mapped = YES; 7287c478bd9Sstevel@tonic-gate continue; 7297c478bd9Sstevel@tonic-gate 7307c478bd9Sstevel@tonic-gate case 'h': /* don't get type from htmp or env */ 7317c478bd9Sstevel@tonic-gate Dash_h = YES; 7327c478bd9Sstevel@tonic-gate continue; 7337c478bd9Sstevel@tonic-gate 7347c478bd9Sstevel@tonic-gate case 'u': /* don't update htmp */ 7357c478bd9Sstevel@tonic-gate Dash_u = YES; 7367c478bd9Sstevel@tonic-gate continue; 7377c478bd9Sstevel@tonic-gate 7387c478bd9Sstevel@tonic-gate case 's': /* output setenv commands */ 7397c478bd9Sstevel@tonic-gate DoSetenv = YES; 7407c478bd9Sstevel@tonic-gate CmndLine = YES; 7417c478bd9Sstevel@tonic-gate continue; 7427c478bd9Sstevel@tonic-gate 7437c478bd9Sstevel@tonic-gate case 'S': /* output setenv strings */ 7447c478bd9Sstevel@tonic-gate DoSetenv = YES; 7457c478bd9Sstevel@tonic-gate CmndLine = NO; 7467c478bd9Sstevel@tonic-gate continue; 7477c478bd9Sstevel@tonic-gate 7487c478bd9Sstevel@tonic-gate case 'Q': /* be quiet */ 7497c478bd9Sstevel@tonic-gate BeQuiet = YES; 7507c478bd9Sstevel@tonic-gate continue; 7517c478bd9Sstevel@tonic-gate 7527c478bd9Sstevel@tonic-gate case 'I': /* no initialization */ 7537c478bd9Sstevel@tonic-gate NoInit = YES; 7547c478bd9Sstevel@tonic-gate continue; 7557c478bd9Sstevel@tonic-gate 7567c478bd9Sstevel@tonic-gate case 'A': /* Ask user */ 7577c478bd9Sstevel@tonic-gate Ask = YES; 7587c478bd9Sstevel@tonic-gate continue; 7597c478bd9Sstevel@tonic-gate 7607c478bd9Sstevel@tonic-gate case 'v': /* no virtual terminal */ 7617c478bd9Sstevel@tonic-gate DoVirtTerm = NO; 7627c478bd9Sstevel@tonic-gate continue; 7637c478bd9Sstevel@tonic-gate 7647c478bd9Sstevel@tonic-gate default: 7657c478bd9Sstevel@tonic-gate *p-- = NULL; 7667c478bd9Sstevel@tonic-gate fatal("Bad flag -", p); 7677c478bd9Sstevel@tonic-gate } 7687c478bd9Sstevel@tonic-gate } 7697c478bd9Sstevel@tonic-gate else 7707c478bd9Sstevel@tonic-gate { 7717c478bd9Sstevel@tonic-gate /* terminal type */ 7727c478bd9Sstevel@tonic-gate DefType = p; 7737c478bd9Sstevel@tonic-gate } 7747c478bd9Sstevel@tonic-gate } 7757c478bd9Sstevel@tonic-gate 7767c478bd9Sstevel@tonic-gate if (DefType) 7777c478bd9Sstevel@tonic-gate { 7787c478bd9Sstevel@tonic-gate if (Mapped) 7797c478bd9Sstevel@tonic-gate { 7807c478bd9Sstevel@tonic-gate Map->Ident = ""; /* means "map any type" */ 7817c478bd9Sstevel@tonic-gate Map->Test = ALL; /* at all baud rates */ 7827c478bd9Sstevel@tonic-gate Map->Type = DefType; /* to the default type */ 7837c478bd9Sstevel@tonic-gate } 7847c478bd9Sstevel@tonic-gate else 7857c478bd9Sstevel@tonic-gate TtyType = DefType; 7867c478bd9Sstevel@tonic-gate } 7877c478bd9Sstevel@tonic-gate 7887c478bd9Sstevel@tonic-gate /* 7897c478bd9Sstevel@tonic-gate * Get rid of $TERMCAP, if it's there, so we get a real 7907c478bd9Sstevel@tonic-gate * entry from /etc/termcap. This prevents us from being 7917c478bd9Sstevel@tonic-gate * fooled by out of date stuff in the environment, and 7927c478bd9Sstevel@tonic-gate * makes tabs work right on CB/Unix. 7937c478bd9Sstevel@tonic-gate */ 7947c478bd9Sstevel@tonic-gate bufp = getenv("TERMCAP"); 7957c478bd9Sstevel@tonic-gate if (bufp && *bufp != '/') 7967c478bd9Sstevel@tonic-gate (void) strcpy(bufp-8, "NOTHING"); /* overwrite only "TERMCAP" */ 7977c478bd9Sstevel@tonic-gate /* get current idea of terminal type from environment */ 7987c478bd9Sstevel@tonic-gate if (!Dash_h && TtyType == 0) 7997c478bd9Sstevel@tonic-gate TtyType = getenv("TERM"); 8007c478bd9Sstevel@tonic-gate 8017c478bd9Sstevel@tonic-gate if (!RepOnly && Ttyid == NOTTY && (TtyType == 0 || !Dash_h)) 8027c478bd9Sstevel@tonic-gate Ttyid = ttyname(FILEDES); 8037c478bd9Sstevel@tonic-gate 8047c478bd9Sstevel@tonic-gate /* If still undefined, use DEFTYPE */ 8057c478bd9Sstevel@tonic-gate if (TtyType == 0) 8067c478bd9Sstevel@tonic-gate { 8077c478bd9Sstevel@tonic-gate TtyType = DEFTYPE; 8087c478bd9Sstevel@tonic-gate } 8097c478bd9Sstevel@tonic-gate 8107c478bd9Sstevel@tonic-gate /* check for dialup or other mapping */ 8117c478bd9Sstevel@tonic-gate if (Mapped) 8127c478bd9Sstevel@tonic-gate { 8137c478bd9Sstevel@tonic-gate if (!(Alias[0] && isalias(TtyType))) 8147c478bd9Sstevel@tonic-gate if (tgetent(Capbuf, TtyType) > 0) 8157c478bd9Sstevel@tonic-gate makealias(Capbuf); 8167c478bd9Sstevel@tonic-gate TtyType = mapped(TtyType); 8177c478bd9Sstevel@tonic-gate } 8187c478bd9Sstevel@tonic-gate 8197c478bd9Sstevel@tonic-gate /* TtyType now contains a pointer to the type of the terminal */ 8207c478bd9Sstevel@tonic-gate /* If the first character is '?', ask the user */ 8217c478bd9Sstevel@tonic-gate if (TtyType[0] == '?') 8227c478bd9Sstevel@tonic-gate { 8237c478bd9Sstevel@tonic-gate Ask = YES; 8247c478bd9Sstevel@tonic-gate TtyType++; 8257c478bd9Sstevel@tonic-gate if (TtyType[0] == '\0') 8267c478bd9Sstevel@tonic-gate TtyType = DEFTYPE; 8277c478bd9Sstevel@tonic-gate } 8287c478bd9Sstevel@tonic-gate if (Ask) 8297c478bd9Sstevel@tonic-gate { 8307c478bd9Sstevel@tonic-gate ask: 8317c478bd9Sstevel@tonic-gate prs("TERM = ("); 8327c478bd9Sstevel@tonic-gate prs(TtyType); 8337c478bd9Sstevel@tonic-gate prs(") "); 8347c478bd9Sstevel@tonic-gate flush(); 8357c478bd9Sstevel@tonic-gate 8367c478bd9Sstevel@tonic-gate /* read the terminal. If not empty, set type */ 8377c478bd9Sstevel@tonic-gate i = read(2, termbuf, sizeof termbuf - 1); 8387c478bd9Sstevel@tonic-gate if (i > 0) 8397c478bd9Sstevel@tonic-gate { 8407c478bd9Sstevel@tonic-gate if (termbuf[i - 1] == '\n') 8417c478bd9Sstevel@tonic-gate i--; 8427c478bd9Sstevel@tonic-gate termbuf[i] = '\0'; 8437c478bd9Sstevel@tonic-gate if (termbuf[0] != '\0') 8447c478bd9Sstevel@tonic-gate TtyType = termbuf; 8457c478bd9Sstevel@tonic-gate } 8467c478bd9Sstevel@tonic-gate } 8477c478bd9Sstevel@tonic-gate 8487c478bd9Sstevel@tonic-gate /* get terminal capabilities */ 8497c478bd9Sstevel@tonic-gate if (!(Alias[0] && isalias(TtyType))) { 8507c478bd9Sstevel@tonic-gate switch (tgetent(Capbuf, TtyType)) 8517c478bd9Sstevel@tonic-gate { 8527c478bd9Sstevel@tonic-gate case -1: 8537c478bd9Sstevel@tonic-gate prs("Cannot find termcap\n"); 8547c478bd9Sstevel@tonic-gate flush(); 8557c478bd9Sstevel@tonic-gate exit(-1); 8567c478bd9Sstevel@tonic-gate 8577c478bd9Sstevel@tonic-gate case 0: 8587c478bd9Sstevel@tonic-gate prs("Type "); 8597c478bd9Sstevel@tonic-gate prs(TtyType); 8607c478bd9Sstevel@tonic-gate prs(" unknown\n"); 8617c478bd9Sstevel@tonic-gate flush(); 8627c478bd9Sstevel@tonic-gate if (DoSetenv) 8637c478bd9Sstevel@tonic-gate { 8647c478bd9Sstevel@tonic-gate TtyType = DEFTYPE; 8657c478bd9Sstevel@tonic-gate Alias[0] = '\0'; 8667c478bd9Sstevel@tonic-gate goto ask; 8677c478bd9Sstevel@tonic-gate } 8687c478bd9Sstevel@tonic-gate else 8697c478bd9Sstevel@tonic-gate exit(1); 8707c478bd9Sstevel@tonic-gate } 8717c478bd9Sstevel@tonic-gate } 8727c478bd9Sstevel@tonic-gate Ttycap = Capbuf; 8737c478bd9Sstevel@tonic-gate 8747c478bd9Sstevel@tonic-gate if (!RepOnly) 8757c478bd9Sstevel@tonic-gate { 8767c478bd9Sstevel@tonic-gate /* determine erase and kill characters */ 8777c478bd9Sstevel@tonic-gate if (Specialerase && !tgetflag("bs")) 8787c478bd9Sstevel@tonic-gate Erase_char = 0; 8797c478bd9Sstevel@tonic-gate bufp = buf; 8807c478bd9Sstevel@tonic-gate p = tgetstr("kb", &bufp); 8817c478bd9Sstevel@tonic-gate if (p == NULL || p[1] != '\0') 8827c478bd9Sstevel@tonic-gate p = tgetstr("bc", &bufp); 8837c478bd9Sstevel@tonic-gate if (p != NULL && p[1] == '\0') 8847c478bd9Sstevel@tonic-gate bs_char = p[0]; 8857c478bd9Sstevel@tonic-gate else if (tgetflag("bs")) 8867c478bd9Sstevel@tonic-gate bs_char = BACKSPACE; 8877c478bd9Sstevel@tonic-gate else 8887c478bd9Sstevel@tonic-gate bs_char = 0; 8897c478bd9Sstevel@tonic-gate /* 8907c478bd9Sstevel@tonic-gate * The next statement can't be fixed, because now users 8917c478bd9Sstevel@tonic-gate * depend on keeping their erase character as DEL if the 8927c478bd9Sstevel@tonic-gate * system set it there. People who want backspace have 8937c478bd9Sstevel@tonic-gate * to say tset -e. 8947c478bd9Sstevel@tonic-gate */ 8957c478bd9Sstevel@tonic-gate if (Erase_char == 0 && !tgetflag("os") && curerase == OLDERASE) 8967c478bd9Sstevel@tonic-gate { 8977c478bd9Sstevel@tonic-gate if (tgetflag("bs") || bs_char != 0) 8987c478bd9Sstevel@tonic-gate Erase_char = -1; 8997c478bd9Sstevel@tonic-gate } 9007c478bd9Sstevel@tonic-gate if (Erase_char < 0) 9017c478bd9Sstevel@tonic-gate Erase_char = (bs_char != 0) ? bs_char : BACKSPACE; 9027c478bd9Sstevel@tonic-gate 9037c478bd9Sstevel@tonic-gate if (curerase == 0) 9047c478bd9Sstevel@tonic-gate curerase = CERASE; 9057c478bd9Sstevel@tonic-gate if (Erase_char != 0) 9067c478bd9Sstevel@tonic-gate curerase = Erase_char; 9077c478bd9Sstevel@tonic-gate 9087c478bd9Sstevel@tonic-gate if (curintr == 0) 9097c478bd9Sstevel@tonic-gate curintr = CINTR; 9107c478bd9Sstevel@tonic-gate if (Intr_char != 0) 9117c478bd9Sstevel@tonic-gate curintr = Intr_char; 9127c478bd9Sstevel@tonic-gate 9137c478bd9Sstevel@tonic-gate if (curkill == 0) 9147c478bd9Sstevel@tonic-gate curkill = CKILL; 9157c478bd9Sstevel@tonic-gate if (Kill_char != 0) 9167c478bd9Sstevel@tonic-gate curkill = Kill_char; 9177c478bd9Sstevel@tonic-gate 9187c478bd9Sstevel@tonic-gate /* set modes */ 9197c478bd9Sstevel@tonic-gate PadBaud = tgetnum("pb"); /* OK if fails */ 9207c478bd9Sstevel@tonic-gate for (i=0; speeds[i].string; i++) 9217c478bd9Sstevel@tonic-gate if (speeds[i].baudrate == PadBaud) { 9227c478bd9Sstevel@tonic-gate PadBaud = speeds[i].speed; 9237c478bd9Sstevel@tonic-gate break; 9247c478bd9Sstevel@tonic-gate } 9257c478bd9Sstevel@tonic-gate setdelay("dC", CRdelay, CRbits, &modes.c_oflag); 9267c478bd9Sstevel@tonic-gate setdelay("dN", NLdelay, NLbits, &modes.c_oflag); 9277c478bd9Sstevel@tonic-gate setdelay("dB", BSdelay, BSbits, &modes.c_oflag); 9287c478bd9Sstevel@tonic-gate setdelay("dF", FFdelay, FFbits, &modes.c_oflag); 9297c478bd9Sstevel@tonic-gate setdelay("dT", TBdelay, TBbits, &modes.c_oflag); 9307c478bd9Sstevel@tonic-gate setdelay("dV", VTdelay, VTbits, &modes.c_oflag); 9317c478bd9Sstevel@tonic-gate 9327c478bd9Sstevel@tonic-gate if (tgetflag("UC") || (command[0] & 0140) == 0100) { 9337c478bd9Sstevel@tonic-gate modes.c_iflag |= IUCLC; 9347c478bd9Sstevel@tonic-gate modes.c_oflag |= OLCUC; 9357c478bd9Sstevel@tonic-gate modes.c_cflag |= XCASE; 9367c478bd9Sstevel@tonic-gate } 9377c478bd9Sstevel@tonic-gate else if (tgetflag("LC")) { 9387c478bd9Sstevel@tonic-gate modes.c_iflag &= ~IUCLC; 9397c478bd9Sstevel@tonic-gate modes.c_oflag &= ~OLCUC; 9407c478bd9Sstevel@tonic-gate modes.c_cflag &= ~XCASE; 9417c478bd9Sstevel@tonic-gate } 9427c478bd9Sstevel@tonic-gate modes.c_iflag &= ~(PARMRK|INPCK); 9437c478bd9Sstevel@tonic-gate modes.c_lflag |= ICANON; 9447c478bd9Sstevel@tonic-gate if (tgetflag("EP")) { 9457c478bd9Sstevel@tonic-gate modes.c_iflag |= INPCK; 9467c478bd9Sstevel@tonic-gate modes.c_cflag |= PARENB; 9477c478bd9Sstevel@tonic-gate modes.c_cflag &= ~PARODD; 9487c478bd9Sstevel@tonic-gate } 9497c478bd9Sstevel@tonic-gate if (tgetflag("OP")) { 9507c478bd9Sstevel@tonic-gate modes.c_iflag |= INPCK; 9517c478bd9Sstevel@tonic-gate modes.c_cflag |= PARENB; 9527c478bd9Sstevel@tonic-gate modes.c_cflag |= PARODD; 9537c478bd9Sstevel@tonic-gate } 9547c478bd9Sstevel@tonic-gate 9557c478bd9Sstevel@tonic-gate modes.c_oflag |= ONLCR; 9567c478bd9Sstevel@tonic-gate modes.c_iflag |= ICRNL; 9577c478bd9Sstevel@tonic-gate modes.c_lflag |= ECHO; 9587c478bd9Sstevel@tonic-gate modes.c_oflag |= TAB3; 9597c478bd9Sstevel@tonic-gate if (tgetflag("NL")) { /* new line, not line feed */ 9607c478bd9Sstevel@tonic-gate modes.c_oflag &= ~ONLCR; 9617c478bd9Sstevel@tonic-gate modes.c_iflag &= ~ICRNL; 9627c478bd9Sstevel@tonic-gate } 9637c478bd9Sstevel@tonic-gate if (tgetflag("HD")) /* half duplex */ 9647c478bd9Sstevel@tonic-gate modes.c_lflag &= ~ECHO; 9657c478bd9Sstevel@tonic-gate if (tgetflag("pt")) /* print tabs */ 9667c478bd9Sstevel@tonic-gate modes.c_oflag &= ~TAB3; 9677c478bd9Sstevel@tonic-gate 9687c478bd9Sstevel@tonic-gate modes.c_lflag |= (ECHOE|ECHOK); 9697c478bd9Sstevel@tonic-gate if (tgetflag("hc")) 9707c478bd9Sstevel@tonic-gate { /** set printer modes **/ 9717c478bd9Sstevel@tonic-gate modes.c_lflag &= ~ECHOE; 9727c478bd9Sstevel@tonic-gate } 9737c478bd9Sstevel@tonic-gate 9747c478bd9Sstevel@tonic-gate /* get pad character */ 9757c478bd9Sstevel@tonic-gate bufp = buf; 9767c478bd9Sstevel@tonic-gate if (tgetstr("pc", &bufp) != 0) 9777c478bd9Sstevel@tonic-gate PC = buf[0]; 9787c478bd9Sstevel@tonic-gate 9797c478bd9Sstevel@tonic-gate /* output startup string */ 9807c478bd9Sstevel@tonic-gate if (!NoInit) 9817c478bd9Sstevel@tonic-gate { 9827c478bd9Sstevel@tonic-gate if (oldmodes.c_oflag&(TAB3|ONLCR|OCRNL|ONLRET)) 9837c478bd9Sstevel@tonic-gate { 9847c478bd9Sstevel@tonic-gate oldmodes.c_oflag &= (TAB3|ONLCR|OCRNL|ONLRET); 9857c478bd9Sstevel@tonic-gate setmode(-1); 9867c478bd9Sstevel@tonic-gate } 9877c478bd9Sstevel@tonic-gate if (settabs()) { 9887c478bd9Sstevel@tonic-gate settle = YES; 9897c478bd9Sstevel@tonic-gate flush(); 9907c478bd9Sstevel@tonic-gate } 9917c478bd9Sstevel@tonic-gate bufp = buf; 9927c478bd9Sstevel@tonic-gate if (IsReset && tgetstr("rs", &bufp) != 0 || 9937c478bd9Sstevel@tonic-gate tgetstr("is", &bufp) != 0) 9947c478bd9Sstevel@tonic-gate { 9957c478bd9Sstevel@tonic-gate tputs(buf, 0, prc); 9967c478bd9Sstevel@tonic-gate settle = YES; 9977c478bd9Sstevel@tonic-gate flush(); 9987c478bd9Sstevel@tonic-gate } 9997c478bd9Sstevel@tonic-gate bufp = buf; 10007c478bd9Sstevel@tonic-gate if (IsReset && tgetstr("rf", &bufp) != 0 || 10017c478bd9Sstevel@tonic-gate tgetstr("if", &bufp) != 0) 10027c478bd9Sstevel@tonic-gate { 10037c478bd9Sstevel@tonic-gate cat(buf); 10047c478bd9Sstevel@tonic-gate settle = YES; 10057c478bd9Sstevel@tonic-gate } 10067c478bd9Sstevel@tonic-gate if (settle) 10077c478bd9Sstevel@tonic-gate { 10087c478bd9Sstevel@tonic-gate prc('\r'); 10097c478bd9Sstevel@tonic-gate if (IsReset) 10107c478bd9Sstevel@tonic-gate prc('\n'); /* newline too */ 10117c478bd9Sstevel@tonic-gate flush(); 10127c478bd9Sstevel@tonic-gate sleep(1); /* let terminal settle down */ 10137c478bd9Sstevel@tonic-gate } 10147c478bd9Sstevel@tonic-gate } 10157c478bd9Sstevel@tonic-gate 10167c478bd9Sstevel@tonic-gate setmode(0); /* set new modes, if they've changed */ 10177c478bd9Sstevel@tonic-gate 10187c478bd9Sstevel@tonic-gate /* set up environment for the shell we are using */ 10197c478bd9Sstevel@tonic-gate /* (this code is rather heuristic, checking for $SHELL */ 10207c478bd9Sstevel@tonic-gate /* ending in the 3 characters "csh") */ 10217c478bd9Sstevel@tonic-gate csh = NO; 10227c478bd9Sstevel@tonic-gate if (DoSetenv) 10237c478bd9Sstevel@tonic-gate { 10247c478bd9Sstevel@tonic-gate char *sh; 10257c478bd9Sstevel@tonic-gate 10267c478bd9Sstevel@tonic-gate if ((sh = getenv("SHELL")) && (i = strlen(sh)) >= 3) 10277c478bd9Sstevel@tonic-gate { 10287c478bd9Sstevel@tonic-gate if ((csh = sequal(&sh[i-3], "csh")) && CmndLine) 10297c478bd9Sstevel@tonic-gate (void) write(STDOUT, "set noglob;\n", 12); 10307c478bd9Sstevel@tonic-gate } 10317c478bd9Sstevel@tonic-gate if (!csh) 10327c478bd9Sstevel@tonic-gate /* running Bourne shell */ 10337c478bd9Sstevel@tonic-gate (void) write(STDOUT, "export TERMCAP TERM;\n", 21); 10347c478bd9Sstevel@tonic-gate } 10357c478bd9Sstevel@tonic-gate } 10367c478bd9Sstevel@tonic-gate 10377c478bd9Sstevel@tonic-gate /* report type if appropriate */ 10387c478bd9Sstevel@tonic-gate if (DoSetenv || Report || Ureport) 10397c478bd9Sstevel@tonic-gate { 10407c478bd9Sstevel@tonic-gate /* if type is the short name, find first alias (if any) */ 10417c478bd9Sstevel@tonic-gate makealias(Ttycap); 10427c478bd9Sstevel@tonic-gate if (sequal(TtyType, Alias[0]) && Alias[1]) { 10437c478bd9Sstevel@tonic-gate TtyType = Alias[1]; 10447c478bd9Sstevel@tonic-gate } 10457c478bd9Sstevel@tonic-gate 10467c478bd9Sstevel@tonic-gate if (DoSetenv) 10477c478bd9Sstevel@tonic-gate { 10487c478bd9Sstevel@tonic-gate if (csh) 10497c478bd9Sstevel@tonic-gate { 10507c478bd9Sstevel@tonic-gate if (CmndLine) 10517c478bd9Sstevel@tonic-gate (void) write(STDOUT, "setenv TERM ", 12); 10527c478bd9Sstevel@tonic-gate (void) write(STDOUT, TtyType, strlen(TtyType)); 10537c478bd9Sstevel@tonic-gate (void) write(STDOUT, " ", 1); 10547c478bd9Sstevel@tonic-gate if (CmndLine) 10557c478bd9Sstevel@tonic-gate (void) write(STDOUT, ";\n", 2); 10567c478bd9Sstevel@tonic-gate } 10577c478bd9Sstevel@tonic-gate else 10587c478bd9Sstevel@tonic-gate { 10597c478bd9Sstevel@tonic-gate (void) write(STDOUT, "TERM=", 5); 10607c478bd9Sstevel@tonic-gate (void) write(STDOUT, TtyType, strlen(TtyType)); 10617c478bd9Sstevel@tonic-gate (void) write(STDOUT, ";\n", 2); 10627c478bd9Sstevel@tonic-gate } 10637c478bd9Sstevel@tonic-gate } 10647c478bd9Sstevel@tonic-gate else if (Report) 10657c478bd9Sstevel@tonic-gate { 10667c478bd9Sstevel@tonic-gate (void) write(STDOUT, TtyType, strlen(TtyType)); 10677c478bd9Sstevel@tonic-gate (void) write(STDOUT, "\n", 1); 10687c478bd9Sstevel@tonic-gate } 10697c478bd9Sstevel@tonic-gate if (Ureport) 10707c478bd9Sstevel@tonic-gate { 10717c478bd9Sstevel@tonic-gate prs("Terminal type is "); 10727c478bd9Sstevel@tonic-gate prs(TtyType); 10737c478bd9Sstevel@tonic-gate prs("\n"); 10747c478bd9Sstevel@tonic-gate flush(); 10757c478bd9Sstevel@tonic-gate } 10767c478bd9Sstevel@tonic-gate 10777c478bd9Sstevel@tonic-gate if (DoSetenv) 10787c478bd9Sstevel@tonic-gate { 10797c478bd9Sstevel@tonic-gate if (csh) 10807c478bd9Sstevel@tonic-gate { 10817c478bd9Sstevel@tonic-gate if (CmndLine) 10827c478bd9Sstevel@tonic-gate (void) write(STDOUT, "setenv TERMCAP '", 16); 10837c478bd9Sstevel@tonic-gate } 10847c478bd9Sstevel@tonic-gate else 10857c478bd9Sstevel@tonic-gate (void) write(STDOUT, "TERMCAP='", 9); 10867c478bd9Sstevel@tonic-gate wrtermcap(Ttycap); 10877c478bd9Sstevel@tonic-gate if (csh) 10887c478bd9Sstevel@tonic-gate { 10897c478bd9Sstevel@tonic-gate if (CmndLine) 10907c478bd9Sstevel@tonic-gate { 10917c478bd9Sstevel@tonic-gate (void) write(STDOUT, "';\n", 3); 10927c478bd9Sstevel@tonic-gate (void) write(STDOUT, "unset noglob;\n", 14); 10937c478bd9Sstevel@tonic-gate } 10947c478bd9Sstevel@tonic-gate } 10957c478bd9Sstevel@tonic-gate else 10967c478bd9Sstevel@tonic-gate (void) write(STDOUT, "';\n", 3); 10977c478bd9Sstevel@tonic-gate } 10987c478bd9Sstevel@tonic-gate } 10997c478bd9Sstevel@tonic-gate 11007c478bd9Sstevel@tonic-gate if (RepOnly) 11017c478bd9Sstevel@tonic-gate exit(0); 11027c478bd9Sstevel@tonic-gate 11037c478bd9Sstevel@tonic-gate /* tell about changing erase, kill and interrupt characters */ 11047c478bd9Sstevel@tonic-gate reportek("Erase", curerase, olderase, CERASE); 11057c478bd9Sstevel@tonic-gate reportek("Kill", curkill, oldkill, CKILL); 11067c478bd9Sstevel@tonic-gate reportek("Interrupt", curintr, oldintr, CINTR); 11077c478bd9Sstevel@tonic-gate 1108*cc6c5292Schin return (0); 11097c478bd9Sstevel@tonic-gate } 11107c478bd9Sstevel@tonic-gate 11117c478bd9Sstevel@tonic-gate /* 11127c478bd9Sstevel@tonic-gate * Set the hardware tabs on the terminal, using the ct (clear all tabs), 11137c478bd9Sstevel@tonic-gate * st (set one tab) and ch (horizontal cursor addressing) capabilities. 11147c478bd9Sstevel@tonic-gate * This is done before if and is, so they can patch in case we blow this. 11157c478bd9Sstevel@tonic-gate */ 1116*cc6c5292Schin int 1117*cc6c5292Schin settabs(void) 11187c478bd9Sstevel@tonic-gate { 11197c478bd9Sstevel@tonic-gate char caps[100]; 11207c478bd9Sstevel@tonic-gate char *capsp = caps; 11217c478bd9Sstevel@tonic-gate char *clear_tabs, *set_tab, *set_column, *set_pos; 11227c478bd9Sstevel@tonic-gate char *tg_out, *tgoto(); 11237c478bd9Sstevel@tonic-gate int c; 11247c478bd9Sstevel@tonic-gate extern char *tgetstr(); 11257c478bd9Sstevel@tonic-gate int lines, columns; 11267c478bd9Sstevel@tonic-gate 11277c478bd9Sstevel@tonic-gate clear_tabs = tgetstr("ct", &capsp); 11287c478bd9Sstevel@tonic-gate set_tab = tgetstr("st", &capsp); 11297c478bd9Sstevel@tonic-gate set_column = tgetstr("ch", &capsp); 11307c478bd9Sstevel@tonic-gate if (set_column == 0) 11317c478bd9Sstevel@tonic-gate set_pos = tgetstr("cm", &capsp); 11327c478bd9Sstevel@tonic-gate 11337c478bd9Sstevel@tonic-gate if (clear_tabs && set_tab) { 11347c478bd9Sstevel@tonic-gate prc('\r'); /* force to be at left margin */ 11357c478bd9Sstevel@tonic-gate tputs(clear_tabs, 0, prc); 11367c478bd9Sstevel@tonic-gate } 11377c478bd9Sstevel@tonic-gate if (set_tab) { 11387c478bd9Sstevel@tonic-gate columns = tgetnum("co"); 11397c478bd9Sstevel@tonic-gate lines = tgetnum("li"); 11407c478bd9Sstevel@tonic-gate for (c=0; c<columns; c += 8) { 11417c478bd9Sstevel@tonic-gate /* get to that column. */ 11427c478bd9Sstevel@tonic-gate tg_out = "OOPS"; /* also returned by tgoto */ 11437c478bd9Sstevel@tonic-gate if (set_column) 11447c478bd9Sstevel@tonic-gate tg_out = tgoto(set_column, 0, c); 11457c478bd9Sstevel@tonic-gate if (*tg_out == 'O' && set_pos) 11467c478bd9Sstevel@tonic-gate tg_out = tgoto(set_pos, c, lines-1); 11477c478bd9Sstevel@tonic-gate if (*tg_out != 'O') 11487c478bd9Sstevel@tonic-gate tputs(tg_out, 1, prc); 11497c478bd9Sstevel@tonic-gate else if (c != 0) { 11507c478bd9Sstevel@tonic-gate prc(' '); prc(' '); prc(' '); prc(' '); 11517c478bd9Sstevel@tonic-gate prc(' '); prc(' '); prc(' '); prc(' '); 11527c478bd9Sstevel@tonic-gate } 11537c478bd9Sstevel@tonic-gate /* set the tab */ 11547c478bd9Sstevel@tonic-gate tputs(set_tab, 0, prc); 11557c478bd9Sstevel@tonic-gate } 11567c478bd9Sstevel@tonic-gate prc('\r'); 1157*cc6c5292Schin return (1); 11587c478bd9Sstevel@tonic-gate } 1159*cc6c5292Schin return (0); 11607c478bd9Sstevel@tonic-gate } 11617c478bd9Sstevel@tonic-gate 11627c478bd9Sstevel@tonic-gate void setmode(flag) 11637c478bd9Sstevel@tonic-gate int flag; 11647c478bd9Sstevel@tonic-gate /* flag serves several purposes: 11657c478bd9Sstevel@tonic-gate * if called as the result of a signal, flag will be > 0. 11667c478bd9Sstevel@tonic-gate * if called from terminal init, flag == -1 means reset "oldmode". 11677c478bd9Sstevel@tonic-gate * called with flag == 0 at end of normal mode processing. 11687c478bd9Sstevel@tonic-gate */ 11697c478bd9Sstevel@tonic-gate { 11707c478bd9Sstevel@tonic-gate struct termio *ttymode; 11717c478bd9Sstevel@tonic-gate struct termios *ttymodes; 1172*cc6c5292Schin int i; 11737c478bd9Sstevel@tonic-gate 11747c478bd9Sstevel@tonic-gate ttymode = (struct termio *)0; 11757c478bd9Sstevel@tonic-gate ttymodes = (struct termios *)0; 11767c478bd9Sstevel@tonic-gate 11777c478bd9Sstevel@tonic-gate if (flag < 0) { /* unconditionally reset oldmode (called from init) */ 11787c478bd9Sstevel@tonic-gate if (istermios < 0) { 11797c478bd9Sstevel@tonic-gate oldmode.c_lflag = oldmodes.c_lflag; 11807c478bd9Sstevel@tonic-gate oldmode.c_oflag = oldmodes.c_oflag; 11817c478bd9Sstevel@tonic-gate oldmode.c_iflag = oldmodes.c_iflag; 11827c478bd9Sstevel@tonic-gate oldmode.c_cflag = oldmodes.c_cflag; 11837c478bd9Sstevel@tonic-gate for(i = 0; i < NCC; i++) 11847c478bd9Sstevel@tonic-gate oldmode.c_cc[i] = oldmodes.c_cc[i]; 11857c478bd9Sstevel@tonic-gate ttymode = &oldmode; 11867c478bd9Sstevel@tonic-gate } else 11877c478bd9Sstevel@tonic-gate ttymodes = &oldmodes; 11887c478bd9Sstevel@tonic-gate } else { 11897c478bd9Sstevel@tonic-gate if (istermios < 0) { 11907c478bd9Sstevel@tonic-gate oldmode.c_lflag = oldmodes.c_lflag; 11917c478bd9Sstevel@tonic-gate oldmode.c_oflag = oldmodes.c_oflag; 11927c478bd9Sstevel@tonic-gate oldmode.c_iflag = oldmodes.c_iflag; 11937c478bd9Sstevel@tonic-gate oldmode.c_cflag = oldmodes.c_cflag; 11947c478bd9Sstevel@tonic-gate for(i = 0; i < NCC; i++) 11957c478bd9Sstevel@tonic-gate oldmode.c_cc[i] = oldmodes.c_cc[i]; 11967c478bd9Sstevel@tonic-gate mode.c_lflag = modes.c_lflag; 11977c478bd9Sstevel@tonic-gate mode.c_oflag = modes.c_oflag; 11987c478bd9Sstevel@tonic-gate mode.c_iflag = modes.c_iflag; 11997c478bd9Sstevel@tonic-gate mode.c_cflag = modes.c_cflag; 12007c478bd9Sstevel@tonic-gate for(i = 0; i < NCC; i++) 12017c478bd9Sstevel@tonic-gate mode.c_cc[i] = modes.c_cc[i]; 12027c478bd9Sstevel@tonic-gate if (!bequal((char *)&mode, (char *)&oldmode, sizeof mode)) 12037c478bd9Sstevel@tonic-gate ttymode = &mode; 12047c478bd9Sstevel@tonic-gate } else if (!bequal((char *)&modes, (char *)&oldmodes, 12057c478bd9Sstevel@tonic-gate sizeof modes)) 12067c478bd9Sstevel@tonic-gate ttymodes = &modes; 12077c478bd9Sstevel@tonic-gate } 12087c478bd9Sstevel@tonic-gate 12097c478bd9Sstevel@tonic-gate if (ttymode) 12107c478bd9Sstevel@tonic-gate { 12117c478bd9Sstevel@tonic-gate (void) ioctl(FILEDES, TCSETAW, (char *)ttymode); 12127c478bd9Sstevel@tonic-gate } else if (ttymodes) { 12137c478bd9Sstevel@tonic-gate (void) ioctl(FILEDES, TCSETSW, (char *)ttymodes); 12147c478bd9Sstevel@tonic-gate } 12157c478bd9Sstevel@tonic-gate if (flag > 0) /* trapped signal */ 12167c478bd9Sstevel@tonic-gate exit(1); 12177c478bd9Sstevel@tonic-gate } 12187c478bd9Sstevel@tonic-gate 1219*cc6c5292Schin void 1220*cc6c5292Schin reportek(char *name, char new, char old, char def) 12217c478bd9Sstevel@tonic-gate { 1222*cc6c5292Schin char o; 1223*cc6c5292Schin char n; 1224*cc6c5292Schin char *p; 12257c478bd9Sstevel@tonic-gate char buf[32]; 12267c478bd9Sstevel@tonic-gate char *bufp; 12277c478bd9Sstevel@tonic-gate extern char *tgetstr(); 12287c478bd9Sstevel@tonic-gate 12297c478bd9Sstevel@tonic-gate if (BeQuiet) 12307c478bd9Sstevel@tonic-gate return; 12317c478bd9Sstevel@tonic-gate o = old; 12327c478bd9Sstevel@tonic-gate n = new; 12337c478bd9Sstevel@tonic-gate 12347c478bd9Sstevel@tonic-gate if (o == n && n == def) 12357c478bd9Sstevel@tonic-gate return; 12367c478bd9Sstevel@tonic-gate prs(name); 12377c478bd9Sstevel@tonic-gate if (o == n) 12387c478bd9Sstevel@tonic-gate prs(" is "); 12397c478bd9Sstevel@tonic-gate else 12407c478bd9Sstevel@tonic-gate prs(" set to "); 12417c478bd9Sstevel@tonic-gate bufp = buf; 12427c478bd9Sstevel@tonic-gate if (tgetstr("kb", &bufp) > (char *)0 && n == buf[0] && buf[1] == NULL) 12437c478bd9Sstevel@tonic-gate prs("Backspace\n"); 12447c478bd9Sstevel@tonic-gate else if (n == 0177) 12457c478bd9Sstevel@tonic-gate prs("Delete\n"); 12467c478bd9Sstevel@tonic-gate else 12477c478bd9Sstevel@tonic-gate { 12487c478bd9Sstevel@tonic-gate if (n < 040) 12497c478bd9Sstevel@tonic-gate { 12507c478bd9Sstevel@tonic-gate prs("Ctrl-"); 12517c478bd9Sstevel@tonic-gate n ^= 0100; 12527c478bd9Sstevel@tonic-gate } 12537c478bd9Sstevel@tonic-gate p = "x\n"; 12547c478bd9Sstevel@tonic-gate p[0] = n; 12557c478bd9Sstevel@tonic-gate prs(p); 12567c478bd9Sstevel@tonic-gate } 12577c478bd9Sstevel@tonic-gate flush(); 12587c478bd9Sstevel@tonic-gate } 12597c478bd9Sstevel@tonic-gate 12607c478bd9Sstevel@tonic-gate 12617c478bd9Sstevel@tonic-gate 1262*cc6c5292Schin void 1263*cc6c5292Schin setdelay(char *cap, struct delay dtab[], tcflag_t bits, tcflag_t *flags) 12647c478bd9Sstevel@tonic-gate { 1265*cc6c5292Schin int i; 1266*cc6c5292Schin struct delay *p; 12677c478bd9Sstevel@tonic-gate extern short ospeed; 12687c478bd9Sstevel@tonic-gate 12697c478bd9Sstevel@tonic-gate /* see if this capability exists at all */ 12707c478bd9Sstevel@tonic-gate i = tgetnum(cap); 12717c478bd9Sstevel@tonic-gate if (i < 0) 12727c478bd9Sstevel@tonic-gate i = 0; 12737c478bd9Sstevel@tonic-gate /* No padding at speeds below PadBaud */ 12747c478bd9Sstevel@tonic-gate if (PadBaud > ospeed) 12757c478bd9Sstevel@tonic-gate i = 0; 12767c478bd9Sstevel@tonic-gate 12777c478bd9Sstevel@tonic-gate /* clear out the bits, replace with new ones */ 12787c478bd9Sstevel@tonic-gate *flags &= ~bits; 12797c478bd9Sstevel@tonic-gate 12807c478bd9Sstevel@tonic-gate /* scan dtab for first entry with adequate delay */ 12817c478bd9Sstevel@tonic-gate for (p = dtab; p->d_delay >= 0; p++) 12827c478bd9Sstevel@tonic-gate { 12837c478bd9Sstevel@tonic-gate if (p->d_delay >= i) 12847c478bd9Sstevel@tonic-gate { 12857c478bd9Sstevel@tonic-gate p++; 12867c478bd9Sstevel@tonic-gate break; 12877c478bd9Sstevel@tonic-gate } 12887c478bd9Sstevel@tonic-gate } 12897c478bd9Sstevel@tonic-gate 12907c478bd9Sstevel@tonic-gate /* use last entry if none will do */ 1291*cc6c5292Schin *flags |= (tcflag_t)((--p)->d_bits); 12927c478bd9Sstevel@tonic-gate } 12937c478bd9Sstevel@tonic-gate 1294*cc6c5292Schin void 1295*cc6c5292Schin prs(char *s) 12967c478bd9Sstevel@tonic-gate { 12977c478bd9Sstevel@tonic-gate while (*s != '\0') 12987c478bd9Sstevel@tonic-gate prc(*s++); 12997c478bd9Sstevel@tonic-gate } 13007c478bd9Sstevel@tonic-gate 13017c478bd9Sstevel@tonic-gate 13027c478bd9Sstevel@tonic-gate char OutBuf[256]; 13037c478bd9Sstevel@tonic-gate int OutPtr; 13047c478bd9Sstevel@tonic-gate 1305*cc6c5292Schin void 1306*cc6c5292Schin prc(char c) 13077c478bd9Sstevel@tonic-gate { 13087c478bd9Sstevel@tonic-gate OutBuf[OutPtr++] = c; 13097c478bd9Sstevel@tonic-gate if (OutPtr >= sizeof OutBuf) 13107c478bd9Sstevel@tonic-gate flush(); 13117c478bd9Sstevel@tonic-gate } 13127c478bd9Sstevel@tonic-gate 1313*cc6c5292Schin void 1314*cc6c5292Schin flush(void) 13157c478bd9Sstevel@tonic-gate { 13167c478bd9Sstevel@tonic-gate if (OutPtr > 0) 13177c478bd9Sstevel@tonic-gate (void) write(2, OutBuf, OutPtr); 13187c478bd9Sstevel@tonic-gate OutPtr = 0; 13197c478bd9Sstevel@tonic-gate } 13207c478bd9Sstevel@tonic-gate 1321*cc6c5292Schin void 1322*cc6c5292Schin cat(char *file) 13237c478bd9Sstevel@tonic-gate { 1324*cc6c5292Schin int fd; 1325*cc6c5292Schin int i; 13267c478bd9Sstevel@tonic-gate char buf[BUFSIZ]; 13277c478bd9Sstevel@tonic-gate 13287c478bd9Sstevel@tonic-gate fd = open(file, 0); 13297c478bd9Sstevel@tonic-gate if (fd < 0) 13307c478bd9Sstevel@tonic-gate { 13317c478bd9Sstevel@tonic-gate prs("Cannot open "); 13327c478bd9Sstevel@tonic-gate prs(file); 13337c478bd9Sstevel@tonic-gate prs("\n"); 13347c478bd9Sstevel@tonic-gate flush(); 13357c478bd9Sstevel@tonic-gate return; 13367c478bd9Sstevel@tonic-gate } 13377c478bd9Sstevel@tonic-gate 13387c478bd9Sstevel@tonic-gate while ((i = read(fd, buf, BUFSIZ)) > 0) 13397c478bd9Sstevel@tonic-gate (void) write(FILEDES, buf, i); 13407c478bd9Sstevel@tonic-gate 13417c478bd9Sstevel@tonic-gate (void) close(fd); 13427c478bd9Sstevel@tonic-gate } 13437c478bd9Sstevel@tonic-gate 13447c478bd9Sstevel@tonic-gate 1345*cc6c5292Schin void 1346*cc6c5292Schin bmove(char *from, char *to, int length) 13477c478bd9Sstevel@tonic-gate { 1348*cc6c5292Schin char *p, *q; 1349*cc6c5292Schin int i; 13507c478bd9Sstevel@tonic-gate 13517c478bd9Sstevel@tonic-gate i = length; 13527c478bd9Sstevel@tonic-gate p = from; 13537c478bd9Sstevel@tonic-gate q = to; 13547c478bd9Sstevel@tonic-gate 13557c478bd9Sstevel@tonic-gate while (i-- > 0) 13567c478bd9Sstevel@tonic-gate *q++ = *p++; 13577c478bd9Sstevel@tonic-gate } 13587c478bd9Sstevel@tonic-gate 13597c478bd9Sstevel@tonic-gate 1360*cc6c5292Schin int 1361*cc6c5292Schin bequal(char *a, char *b, int len) /* must be same thru len chars */ 13627c478bd9Sstevel@tonic-gate { 1363*cc6c5292Schin char *p, *q; 1364*cc6c5292Schin int i; 13657c478bd9Sstevel@tonic-gate 13667c478bd9Sstevel@tonic-gate i = len; 13677c478bd9Sstevel@tonic-gate p = a; 13687c478bd9Sstevel@tonic-gate q = b; 13697c478bd9Sstevel@tonic-gate 13707c478bd9Sstevel@tonic-gate while ((*p == *q) && --i > 0) 13717c478bd9Sstevel@tonic-gate { 13727c478bd9Sstevel@tonic-gate p++; q++; 13737c478bd9Sstevel@tonic-gate } 13747c478bd9Sstevel@tonic-gate return ((*p == *q) && i >= 0); 13757c478bd9Sstevel@tonic-gate } 13767c478bd9Sstevel@tonic-gate 1377*cc6c5292Schin int 1378*cc6c5292Schin sequal(char *a, char *b) /* must be same thru NULL */ 13797c478bd9Sstevel@tonic-gate { 1380*cc6c5292Schin char *p = a, *q = b; 13817c478bd9Sstevel@tonic-gate 13827c478bd9Sstevel@tonic-gate while (*p && *q && (*p == *q)) 13837c478bd9Sstevel@tonic-gate { 13847c478bd9Sstevel@tonic-gate p++; q++; 13857c478bd9Sstevel@tonic-gate } 13867c478bd9Sstevel@tonic-gate return (*p == *q); 13877c478bd9Sstevel@tonic-gate } 13887c478bd9Sstevel@tonic-gate 1389*cc6c5292Schin void 1390*cc6c5292Schin makealias(char *buf) 13917c478bd9Sstevel@tonic-gate { 1392*cc6c5292Schin int i; 1393*cc6c5292Schin char *a; 1394*cc6c5292Schin char *b; 13957c478bd9Sstevel@tonic-gate 13967c478bd9Sstevel@tonic-gate Alias[0] = a = Aliasbuf; 13977c478bd9Sstevel@tonic-gate b = buf; 13987c478bd9Sstevel@tonic-gate i = 1; 13997c478bd9Sstevel@tonic-gate while (*b && *b != ':') { 14007c478bd9Sstevel@tonic-gate if (*b == '|') { 14017c478bd9Sstevel@tonic-gate *a++ = NULL; 14027c478bd9Sstevel@tonic-gate Alias[i++] = a; 14037c478bd9Sstevel@tonic-gate b++; 14047c478bd9Sstevel@tonic-gate } 14057c478bd9Sstevel@tonic-gate else 14067c478bd9Sstevel@tonic-gate *a++ = *b++; 14077c478bd9Sstevel@tonic-gate } 14087c478bd9Sstevel@tonic-gate *a = NULL; 14097c478bd9Sstevel@tonic-gate Alias[i] = NULL; 14107c478bd9Sstevel@tonic-gate # ifdef DEB 14117c478bd9Sstevel@tonic-gate for(i = 0; Alias[i]; printf("A:%s\n", Alias[i++])); 14127c478bd9Sstevel@tonic-gate # endif 14137c478bd9Sstevel@tonic-gate } 14147c478bd9Sstevel@tonic-gate 1415*cc6c5292Schin int 1416*cc6c5292Schin isalias(char *ident) /* is ident same as one of the aliases? */ 14177c478bd9Sstevel@tonic-gate { 14187c478bd9Sstevel@tonic-gate char **a = Alias; 14197c478bd9Sstevel@tonic-gate 14207c478bd9Sstevel@tonic-gate if (*a) 14217c478bd9Sstevel@tonic-gate while (*a) 14227c478bd9Sstevel@tonic-gate if (sequal(ident, *a)) 14237c478bd9Sstevel@tonic-gate return(YES); 14247c478bd9Sstevel@tonic-gate else 14257c478bd9Sstevel@tonic-gate a++; 14267c478bd9Sstevel@tonic-gate return(NO); 14277c478bd9Sstevel@tonic-gate } 14287c478bd9Sstevel@tonic-gate 14297c478bd9Sstevel@tonic-gate 14307c478bd9Sstevel@tonic-gate /* 14317c478bd9Sstevel@tonic-gate * routine to output the string for the environment TERMCAP variable 14327c478bd9Sstevel@tonic-gate */ 14337c478bd9Sstevel@tonic-gate #define WHITE(c) (c == ' ' || c == '\t') 14347c478bd9Sstevel@tonic-gate char delcap[128][2]; 14357c478bd9Sstevel@tonic-gate int ncap = 0; 14367c478bd9Sstevel@tonic-gate 1437*cc6c5292Schin void 1438*cc6c5292Schin wrtermcap(char *bp) 14397c478bd9Sstevel@tonic-gate { 14407c478bd9Sstevel@tonic-gate char buf[CAPBUFSIZ]; 14417c478bd9Sstevel@tonic-gate char *p = buf; 14427c478bd9Sstevel@tonic-gate char *tp; 14437c478bd9Sstevel@tonic-gate char *putbuf(); 14447c478bd9Sstevel@tonic-gate int space, empty; 14457c478bd9Sstevel@tonic-gate 14467c478bd9Sstevel@tonic-gate /* discard names with blanks */ 14477c478bd9Sstevel@tonic-gate /** May not be desireable ? **/ 14487c478bd9Sstevel@tonic-gate while (*bp && *bp != ':') { 14497c478bd9Sstevel@tonic-gate if (*bp == '|') { 14507c478bd9Sstevel@tonic-gate tp = bp+1; 14517c478bd9Sstevel@tonic-gate space = NO; 14527c478bd9Sstevel@tonic-gate while (*tp && *tp != '|' && *tp != ':') { 14537c478bd9Sstevel@tonic-gate space = (space || WHITE(*tp) ); 14547c478bd9Sstevel@tonic-gate tp++; 14557c478bd9Sstevel@tonic-gate } 14567c478bd9Sstevel@tonic-gate if (space) { 14577c478bd9Sstevel@tonic-gate bp = tp; 14587c478bd9Sstevel@tonic-gate continue; 14597c478bd9Sstevel@tonic-gate } 14607c478bd9Sstevel@tonic-gate } 14617c478bd9Sstevel@tonic-gate *p++ = *bp++; 14627c478bd9Sstevel@tonic-gate } 14637c478bd9Sstevel@tonic-gate /**/ 14647c478bd9Sstevel@tonic-gate 14657c478bd9Sstevel@tonic-gate while (*bp) { 14667c478bd9Sstevel@tonic-gate switch (*bp) { 14677c478bd9Sstevel@tonic-gate case ':': /* discard empty, cancelled or dupl fields */ 14687c478bd9Sstevel@tonic-gate tp = bp+1; 14697c478bd9Sstevel@tonic-gate empty = YES; 14707c478bd9Sstevel@tonic-gate while (*tp && *tp != ':') { 14717c478bd9Sstevel@tonic-gate empty = (empty && WHITE(*tp) ); 14727c478bd9Sstevel@tonic-gate tp++; 14737c478bd9Sstevel@tonic-gate } 14747c478bd9Sstevel@tonic-gate if (empty || cancelled(bp+1)) { 14757c478bd9Sstevel@tonic-gate bp = tp; 14767c478bd9Sstevel@tonic-gate continue; 14777c478bd9Sstevel@tonic-gate } 14787c478bd9Sstevel@tonic-gate break; 14797c478bd9Sstevel@tonic-gate 14807c478bd9Sstevel@tonic-gate case ' ': /* no spaces in output */ 14817c478bd9Sstevel@tonic-gate p = putbuf(p, "\\040"); 14827c478bd9Sstevel@tonic-gate bp++; 14837c478bd9Sstevel@tonic-gate continue; 14847c478bd9Sstevel@tonic-gate 14857c478bd9Sstevel@tonic-gate case '!': /* the shell thinks this is history */ 14867c478bd9Sstevel@tonic-gate p = putbuf(p, "\\041"); 14877c478bd9Sstevel@tonic-gate bp++; 14887c478bd9Sstevel@tonic-gate continue; 14897c478bd9Sstevel@tonic-gate 14907c478bd9Sstevel@tonic-gate case ',': /* the shell thinks this is history */ 14917c478bd9Sstevel@tonic-gate p = putbuf(p, "\\054"); 14927c478bd9Sstevel@tonic-gate bp++; 14937c478bd9Sstevel@tonic-gate continue; 14947c478bd9Sstevel@tonic-gate 14957c478bd9Sstevel@tonic-gate case '"': /* no quotes in output */ 14967c478bd9Sstevel@tonic-gate p = putbuf(p, "\\042"); 14977c478bd9Sstevel@tonic-gate bp++; 14987c478bd9Sstevel@tonic-gate continue; 14997c478bd9Sstevel@tonic-gate 15007c478bd9Sstevel@tonic-gate case '\'': /* no quotes in output */ 15017c478bd9Sstevel@tonic-gate p = putbuf(p, "\\047"); 15027c478bd9Sstevel@tonic-gate bp++; 15037c478bd9Sstevel@tonic-gate continue; 15047c478bd9Sstevel@tonic-gate 15057c478bd9Sstevel@tonic-gate case '`': /* no back quotes in output */ 15067c478bd9Sstevel@tonic-gate p = putbuf(p, "\\140"); 15077c478bd9Sstevel@tonic-gate bp++; 15087c478bd9Sstevel@tonic-gate continue; 15097c478bd9Sstevel@tonic-gate 15107c478bd9Sstevel@tonic-gate case '\\': 15117c478bd9Sstevel@tonic-gate case '^': /* anything following is OK */ 15127c478bd9Sstevel@tonic-gate *p++ = *bp++; 15137c478bd9Sstevel@tonic-gate } 15147c478bd9Sstevel@tonic-gate *p++ = *bp++; 15157c478bd9Sstevel@tonic-gate } 15167c478bd9Sstevel@tonic-gate *p++ = ':'; /* we skipped the last : with the : lookahead hack */ 15177c478bd9Sstevel@tonic-gate (void) write (STDOUT, buf, p-buf); 15187c478bd9Sstevel@tonic-gate } 15197c478bd9Sstevel@tonic-gate 1520*cc6c5292Schin int 1521*cc6c5292Schin cancelled(char *cap) 15227c478bd9Sstevel@tonic-gate { 1523*cc6c5292Schin int i; 15247c478bd9Sstevel@tonic-gate 15257c478bd9Sstevel@tonic-gate for (i = 0; i < ncap; i++) 15267c478bd9Sstevel@tonic-gate { 15277c478bd9Sstevel@tonic-gate if (cap[0] == delcap[i][0] && cap[1] == delcap[i][1]) 15287c478bd9Sstevel@tonic-gate return (YES); 15297c478bd9Sstevel@tonic-gate } 15307c478bd9Sstevel@tonic-gate /* delete a second occurrance of the same capability */ 15317c478bd9Sstevel@tonic-gate delcap[ncap][0] = cap[0]; 15327c478bd9Sstevel@tonic-gate delcap[ncap][1] = cap[1]; 15337c478bd9Sstevel@tonic-gate ncap++; 15347c478bd9Sstevel@tonic-gate return (cap[2] == '@'); 15357c478bd9Sstevel@tonic-gate } 15367c478bd9Sstevel@tonic-gate 15377c478bd9Sstevel@tonic-gate char * 15387c478bd9Sstevel@tonic-gate putbuf(ptr, str) 15397c478bd9Sstevel@tonic-gate char *ptr; 15407c478bd9Sstevel@tonic-gate char *str; 15417c478bd9Sstevel@tonic-gate { 15427c478bd9Sstevel@tonic-gate char buf[20]; 15437c478bd9Sstevel@tonic-gate 15447c478bd9Sstevel@tonic-gate while (*str) { 15457c478bd9Sstevel@tonic-gate switch (*str) { 15467c478bd9Sstevel@tonic-gate case '\033': 15477c478bd9Sstevel@tonic-gate ptr = putbuf(ptr, "\\E"); 15487c478bd9Sstevel@tonic-gate str++; 15497c478bd9Sstevel@tonic-gate break; 15507c478bd9Sstevel@tonic-gate default: 15517c478bd9Sstevel@tonic-gate if (*str <= ' ') { 15527c478bd9Sstevel@tonic-gate (void) sprintf(buf, "\\%03o", *str); 15537c478bd9Sstevel@tonic-gate ptr = putbuf(ptr, buf); 15547c478bd9Sstevel@tonic-gate str++; 15557c478bd9Sstevel@tonic-gate } else 15567c478bd9Sstevel@tonic-gate *ptr++ = *str++; 15577c478bd9Sstevel@tonic-gate } 15587c478bd9Sstevel@tonic-gate } 15597c478bd9Sstevel@tonic-gate return (ptr); 15607c478bd9Sstevel@tonic-gate } 15617c478bd9Sstevel@tonic-gate 1562*cc6c5292Schin int 1563*cc6c5292Schin baudrate(char *p) 15647c478bd9Sstevel@tonic-gate { 15657c478bd9Sstevel@tonic-gate char buf[8]; 15667c478bd9Sstevel@tonic-gate int i = 0; 15677c478bd9Sstevel@tonic-gate 15687c478bd9Sstevel@tonic-gate while (i < 7 && (isalnum(*p) || *p == '.')) 15697c478bd9Sstevel@tonic-gate buf[i++] = *p++; 15707c478bd9Sstevel@tonic-gate buf[i] = NULL; 15717c478bd9Sstevel@tonic-gate for (i=0; speeds[i].string; i++) 15727c478bd9Sstevel@tonic-gate if (sequal(speeds[i].string, buf)) 15737c478bd9Sstevel@tonic-gate return (speeds[i].speed); 15747c478bd9Sstevel@tonic-gate return (-1); 15757c478bd9Sstevel@tonic-gate } 15767c478bd9Sstevel@tonic-gate 15777c478bd9Sstevel@tonic-gate char * 15787c478bd9Sstevel@tonic-gate mapped(type) 15797c478bd9Sstevel@tonic-gate char *type; 15807c478bd9Sstevel@tonic-gate { 15817c478bd9Sstevel@tonic-gate extern short ospeed; 15827c478bd9Sstevel@tonic-gate int match; 15837c478bd9Sstevel@tonic-gate 15847c478bd9Sstevel@tonic-gate # ifdef DEB 15857c478bd9Sstevel@tonic-gate printf ("spd:%d\n", ospeed); 15867c478bd9Sstevel@tonic-gate prmap(); 15877c478bd9Sstevel@tonic-gate # endif 15887c478bd9Sstevel@tonic-gate Map = map; 15897c478bd9Sstevel@tonic-gate while (Map->Ident) 15907c478bd9Sstevel@tonic-gate { 15917c478bd9Sstevel@tonic-gate if (*(Map->Ident) == NULL || sequal(Map->Ident, type) || isalias(Map->Ident)) 15927c478bd9Sstevel@tonic-gate { 15937c478bd9Sstevel@tonic-gate match = NO; 15947c478bd9Sstevel@tonic-gate switch (Map->Test) 15957c478bd9Sstevel@tonic-gate { 15967c478bd9Sstevel@tonic-gate case ANY: /* no test specified */ 15977c478bd9Sstevel@tonic-gate case ALL: 15987c478bd9Sstevel@tonic-gate match = YES; 15997c478bd9Sstevel@tonic-gate break; 16007c478bd9Sstevel@tonic-gate 16017c478bd9Sstevel@tonic-gate case GT: 16027c478bd9Sstevel@tonic-gate match = (ospeed > Map->Speed); 16037c478bd9Sstevel@tonic-gate break; 16047c478bd9Sstevel@tonic-gate 16057c478bd9Sstevel@tonic-gate case GE: 16067c478bd9Sstevel@tonic-gate match = (ospeed >= Map->Speed); 16077c478bd9Sstevel@tonic-gate break; 16087c478bd9Sstevel@tonic-gate 16097c478bd9Sstevel@tonic-gate case EQ: 16107c478bd9Sstevel@tonic-gate match = (ospeed == Map->Speed); 16117c478bd9Sstevel@tonic-gate break; 16127c478bd9Sstevel@tonic-gate 16137c478bd9Sstevel@tonic-gate case LE: 16147c478bd9Sstevel@tonic-gate match = (ospeed <= Map->Speed); 16157c478bd9Sstevel@tonic-gate break; 16167c478bd9Sstevel@tonic-gate 16177c478bd9Sstevel@tonic-gate case LT: 16187c478bd9Sstevel@tonic-gate match = (ospeed < Map->Speed); 16197c478bd9Sstevel@tonic-gate break; 16207c478bd9Sstevel@tonic-gate 16217c478bd9Sstevel@tonic-gate case NE: 16227c478bd9Sstevel@tonic-gate match = (ospeed != Map->Speed); 16237c478bd9Sstevel@tonic-gate break; 16247c478bd9Sstevel@tonic-gate } 16257c478bd9Sstevel@tonic-gate if (match) 16267c478bd9Sstevel@tonic-gate return (Map->Type); 16277c478bd9Sstevel@tonic-gate } 16287c478bd9Sstevel@tonic-gate Map++; 16297c478bd9Sstevel@tonic-gate } 16307c478bd9Sstevel@tonic-gate /* no match found; return given type */ 16317c478bd9Sstevel@tonic-gate return (type); 16327c478bd9Sstevel@tonic-gate } 16337c478bd9Sstevel@tonic-gate 16347c478bd9Sstevel@tonic-gate # ifdef DEB 16357c478bd9Sstevel@tonic-gate prmap() 16367c478bd9Sstevel@tonic-gate { 16377c478bd9Sstevel@tonic-gate Map = map; 16387c478bd9Sstevel@tonic-gate while (Map->Ident) 16397c478bd9Sstevel@tonic-gate { 16407c478bd9Sstevel@tonic-gate printf ("%s t:%d s:%d %s\n", 16417c478bd9Sstevel@tonic-gate Map->Ident, Map->Test, Map->Speed, Map->Type); 16427c478bd9Sstevel@tonic-gate Map++; 16437c478bd9Sstevel@tonic-gate } 16447c478bd9Sstevel@tonic-gate } 16457c478bd9Sstevel@tonic-gate # endif 16467c478bd9Sstevel@tonic-gate 16477c478bd9Sstevel@tonic-gate char * 16487c478bd9Sstevel@tonic-gate nextarg(argc, argv) 16497c478bd9Sstevel@tonic-gate int argc; 16507c478bd9Sstevel@tonic-gate char *argv[]; 16517c478bd9Sstevel@tonic-gate { 16527c478bd9Sstevel@tonic-gate if (argc <= 0) 16537c478bd9Sstevel@tonic-gate fatal ("Too few args: ", *argv); 16547c478bd9Sstevel@tonic-gate if (*(*++argv) == '-') 16557c478bd9Sstevel@tonic-gate fatal ("Unexpected arg: ", *argv); 16567c478bd9Sstevel@tonic-gate return (*argv); 16577c478bd9Sstevel@tonic-gate } 16587c478bd9Sstevel@tonic-gate 1659*cc6c5292Schin void 1660*cc6c5292Schin fatal (char *mesg, char *obj) 16617c478bd9Sstevel@tonic-gate { 16627c478bd9Sstevel@tonic-gate prs (mesg); 16637c478bd9Sstevel@tonic-gate prs (obj); 16647c478bd9Sstevel@tonic-gate prc ('\n'); 16657c478bd9Sstevel@tonic-gate prs (USAGE); 16667c478bd9Sstevel@tonic-gate flush(); 16677c478bd9Sstevel@tonic-gate exit(1); 16687c478bd9Sstevel@tonic-gate } 16697c478bd9Sstevel@tonic-gate 16707c478bd9Sstevel@tonic-gate 16717c478bd9Sstevel@tonic-gate /* 16727c478bd9Sstevel@tonic-gate * Stolen from /usr/src/ucb/reset.c, which this mod obsoletes. 16737c478bd9Sstevel@tonic-gate */ 16747c478bd9Sstevel@tonic-gate char 16757c478bd9Sstevel@tonic-gate reset(ch, def) 16767c478bd9Sstevel@tonic-gate char ch; 16777c478bd9Sstevel@tonic-gate int def; 16787c478bd9Sstevel@tonic-gate { 16797c478bd9Sstevel@tonic-gate 16807c478bd9Sstevel@tonic-gate if (ch == 0 || (ch&0377) == 0377) 16817c478bd9Sstevel@tonic-gate return def; 16827c478bd9Sstevel@tonic-gate return ch; 16837c478bd9Sstevel@tonic-gate } 1684