* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
"@(#) Copyright (c) 1980 Regents of the University of California.\n\
static char sccsid
[] = "@(#)tset.c 5.8 (Berkeley) %G%";
** TSET -- set terminal modes
** This program does sophisticated terminal initialization.
** I recommend that you include it in your .profile or .login
** file to initialize whatever terminal you are on.
** There are several features:
** A special file or sequence (as controlled by the termcap file)
** is sent to the terminal.
** Mode bits are set on a per-terminal_type basis (much better
** than UNIX itself). This allows special delays, automatic
** Erase and Kill characters can be set to whatever you want.
** Default is to change erase to control-H on a terminal which
** can overstrike, and leave it alone on anything else. Kill
** is always left alone unless specifically requested. These
** characters can be represented as "^X" meaning control-X;
** Terminals which are dialups or plugboard types can be aliased
** to whatever type you may have in your home or office. Thus,
** if you know that when you dial up you will always be on a
** TI 733, you can specify that fact to tset. You can represent
** a type as "?type". This will ask you what type you want it
** to be -- if you reply with just a newline, it will default
** The current terminal type can be queried.
** tset [-] [-EC] [-eC] [-kC] [-iC] [-s] [-h] [-u] [-r]
** [-m [ident] [test baudrate] :type]
** In systems with environments, use:
** Actually, this doesn't work in old csh's.
** tset -s ... > tset.tmp
** set term=(`tset -S ....`)
** setenv TERMCAP "$term[2]"
** Positional Parameters:
** type -- the terminal type to force. If this is
** specified, initialization is for this
** - -- report terminal type. Whatever type is
** decided on is reported. If no other flags
** are stated, the only affect is to write
** the terminal type on the standard output.
** -r -- report to user in addition to other flags.
** -EC -- set the erase character to C on all terminals
** except those which cannot backspace (e.g.,
** a TTY 33). C defaults to control-H.
** -eC -- set the erase character to C on all terminals.
** C defaults to control-H. If not specified,
** the erase character is untouched; however, if
** not specified and the erase character is NULL
** (zero byte), the erase character is set to delete.
** -kC -- set the kill character to C on all terminals.
** Default for C is control-X. If not specified,
** the kill character is untouched; however, if
** not specified and the kill character is NULL
** (zero byte), the kill character is set to control-U.
** -iC -- set the interrupt character to C on all terminals.
** Default for C is control-C. If not specified, the
** interrupt character is untouched; however, if
** not specified and the interrupt character is NULL
** (zero byte), the interrupt character is set to
** -qC -- reserved for setable quit character.
** -m -- map the system identified type to some user
** specified type. The mapping can be baud rate
** dependent. This replaces the old -d, -p flags.
** (-d type -> -m dialup:type)
** (-p type -> -m plug:type)
** Syntax: -m identifier [test baudrate] :type
** where: ``identifier'' is terminal type found in
** /etc/ttys for this port, (abscence of an identifier
** matches any identifier); ``test'' may be any combination
** of > = < ! @; ``baudrate'' is as with stty(1);
** ``type'' is the actual terminal type to use if the
** mapping condition is met. Multiple maps are scanned
** in order and the first match prevails.
** -n -- If the new tty driver from UCB is available, this flag
** will activate the new options for erase and kill
** processing. This will be different for printers
** and crt's. For crts, if the baud rate is < 1200 then
** erase and kill don't remove characters from the screen.
** -h -- don't read htmp file. Normally the terminal type
** is determined by reading the htmp file or the
** environment (unless some mapping is specified).
** This forces a read of the ttytype file -- useful
** when htmp is somehow wrong. (V6 only)
** -u -- don't update htmp. It seemed like this should
** be put in. Note that htmp is never actually
** written if there are no changes, so don't bother
** bother using this for efficiency reasons alone.
** -s -- output setenv commands for TERM. This can be
** and is to be prefered to:
** setenv TERM `tset - ...`
** because -s sets the TERMCAP variable also.
** -S -- Similar to -s but outputs 2 strings suitable for
** use in csh .login files as follows:
** set term=(`tset -S .....`)
** setenv TERMCAP "$term[2]"
** -Q -- be quiet. don't output 'Erase set to' etc.
** -I -- don't do terminal initialization (is & if
** -v -- On virtual terminal systems, don't set up a
** virtual terminal. Otherwise tset will tell
** the operating system what kind of terminal you
** are on (if it is a known terminal) and fix up
** the output of -s to use virtual terminal sequences.
** contains a terminal id -> terminal type
** mapping; used when any user mapping is specified,
** or the environment doesn't have TERM set.
** a terminal_type -> terminal_capabilities
** -1 -- couldn't open ttycap.
** 1 -- bad terminal type, or standard output not tty.
** DIALUP -- the type code for a dialup port.
** PLUGBOARD -- the type code for a plugboard port.
** ARPANET -- the type code for an arpanet port.
** BACKSPACE -- control-H, the default for -e.
** CNTL('X') -- control-X, the default for -k.
** OLDERASE -- the system default erase character.
** OLDKILL -- the system default kill character.
** FILEDES -- the file descriptor to do the operation
** STDOUT -- the standard output file descriptor.
** UIDMASK -- the bit pattern to mask with the getuid()
** call to get just the user id.
** GTTYN -- defines file containing generalized ttynames
** and compiles code to look there.
** Routines to handle htmp, ttys, and ttycap.
** OLDFLAGS -- must be defined to compile code for any of
** the -d, -p, or -a flags.
** OLDDIALUP -- accept the -d flag.
** OLDPLUGBOARD -- accept the -p flag.
** OLDARPANET -- accept the -a flag.
** V6 -- if clear, use environments, not htmp.
** also use TIOCSETN rather than stty to avoid flushing
** GTTYN -- if set, compiles code to look at /etc/ttys.
** UCB_NTTY -- set to handle new tty driver modes.
** An incorrect option was specified.
** more command line arguments are required.
** wrong type of argument was encountered.
** The specified file could not be openned.
** An unknown terminal type was specified.
** Cannot update htmp file when the standard
** output is not a terminal.
** Telling that the erase character has been
** set to the specified character.
** Erase is ... Kill is ...
** Tells that the erase/kill characters were
** wierd before, but they are being left as-is.
** Set if FILEDES is not a terminal.
** Compilation Instructions:
** cc -n -O tset.c -ltermlib
** where 'bin' should be whoever owns the 'htmp' file.
** If 'htmp' is 666, then tset need not be setuid.
** For version 6 the compile command should be:
** cc -n -O -I/usr/include/retrofit tset.c -ltermlib -lretro -lS
** Electronics Research Labs
** 1/81 -- Added alias checking for mapping identifiers.
** 9/80 -- Added UCB_NTTY mods to setup the new tty driver.
** Added the 'reset ...' invocation.
** 7/80 -- '-S' added. '-m' mapping added. TERMCAP string
** 3/80 -- Changed to use tputs. Prc & flush added.
** 10/79 -- '-s' option extended to handle TERMCAP
** variable, set noglob, quote the entry,
** and know about the Bourne shell. Terminal
** initialization moved to before any information
** output so screen clears would not screw you.
** 8/79 -- '-' option alone changed to only output
** type. '-s' option added. 'VERSION7'
** changed to 'V6' for compatibility.
** 12/78 -- modified for eventual migration to VAX/UNIX,
** so the '-' option is changed to output only
** the terminal type to STDOUT instead of
** 9/78 -- '-' and '-p' options added (now fully
** compatible with ttytype!), and spaces are
** permitted between the -d and the type.
** 8/78 -- The sense of -h and -u were reversed, and the
** -f flag is dropped -- same effect is available
** by just stating the terminal type.
# define curerase mode.c_cc[VERASE]
# define curkill mode.c_cc[VKILL]
# define curintr mode.c_cc[VINTR]
# define olderase oldmode.c_cc[VERASE]
# define oldkill oldmode.c_cc[VKILL]
# define oldintr oldmode.c_cc[VINTR]
# define curerase mode.sg_erase
# define curkill mode.sg_kill
# define curintr tchar.t_intrc
# define olderase oldmode.sg_erase
# define oldkill oldmode.sg_kill
# define oldintr oldtchar.t_intrc
# define CNTL(c) ((c)&037)
# define BACKSPACE (CNTL('H'))
# define CHK(val, dft) (val<=0 ? dft : val)
# define isdigit(c) (c >= '0' && c <= '9')
# define isalnum(c) (c > ' ' && (index("<@=>!:|\177", c) == NULL))
# define OLDINTR '\177' /* del */
/* default special characters */
#define CQUIT 034 /* FS, ^\ */
#define CWERASE CNTL('W')
# define FILEDES 2 /* do gtty/stty on this descriptor */
# define STDOUT 1 /* output of -s/-S to this descriptor */
# define USAGE "usage: tset [-] [-nrsIQS] [-eC] [-kC] [-iC] [-m [ident][test speed]:type] [type]\n"
# define USAGE "usage: tset [-] [-rsIQS] [-eC] [-kC] [-iC] [-m [ident][test speed]:type] [type]\n"
# define PLUGBOARD "plugboard"
# define OLDPLUGBOARD "sp"
# define ARPANET "arpanet"
# define DEFTYPE "unknown"
/* This should be available in an include file */
int HasAM
; /* True if terminal has automatic margins */
char Erase_char
; /* new erase character */
char Kill_char
; /* new kill character */
char Intr_char
; /* new interrupt character */
char Specialerase
; /* set => Erase_char only on terminals with backspace */
char *Ttyid
= NOTTY
; /* terminal identifier */
char Ttyid
= NOTTY
; /* terminal identifier */
char *TtyType
; /* type of terminal */
char *DefType
; /* default type if none other computed */
char *NewType
; /* mapping identifier based on old flags */
int Mapped
; /* mapping has been specified */
int Dash_u
; /* don't update htmp */
int Dash_h
; /* don't read htmp */
int DoSetenv
; /* output setenv commands */
int BeQuiet
; /* be quiet */
int NoInit
; /* don't output initialization string */
int IsReset
; /* invoked as reset */
int Report
; /* report current type */
int Ureport
; /* report to user */
int RepOnly
; /* report only */
int CmndLine
; /* output full command lines (-s option) */
int Ask
; /* ask user for termtype */
int DoVirtTerm
= YES
; /* Set up a virtual terminal */
int PadBaud
; /* Min rate of padding needed */
char Capbuf
[CAPBUFSIZ
]; /* line from /etc/termcap for this TtyType */
char *Ttycap
; /* termcap line from termcap or environ */
# include "tset.delays.h"
struct termcb block
= {0, 2, 0, 0, 0, 20};
extern char *hsgettype();
(void) ioctl(FILEDES
, TIOCLGET
, (char *)&lmode
);
(void) ioctl(FILEDES
, TIOCGETD
, (char *)&ldisc
);
if (gtty(FILEDES
, &mode
) < 0)
if (ioctl(FILEDES
, TCGETA
, (char *)&mode
) < 0)
bmove((char *)&mode
, (char *)&oldmode
, sizeof mode
);
(void) ioctl(FILEDES
, TIOCGETC
, (char *)&tchar
);
bmove((char *)&tchar
, (char *)&oldtchar
, sizeof tchar
);
ospeed
= mode
.sg_ospeed
& 017;
ospeed
= mode
.c_cflag
& CBAUD
;
(void) signal(SIGINT
, setmode
);
(void) signal(SIGQUIT
, setmode
);
(void) signal(SIGTERM
, setmode
);
if (command
= rindex(argv
[0], '/'))
if (sequal(command
, "reset") )
* reset the teletype mode bits to a sensible state.
* Copied from the program by Kurt Shoens & Mark Horton.
* Very useful after crapping out in raw.
(void) ioctl(FILEDES
, TIOCGLTC
, (char *)<c
);
ltc
.t_suspc
= CHK(ltc
.t_suspc
, CSUSP
);
ltc
.t_dsuspc
= CHK(ltc
.t_dsuspc
, CDSUSP
);
ltc
.t_rprntc
= CHK(ltc
.t_rprntc
, CRPRNT
);
ltc
.t_flushc
= CHK(ltc
.t_flushc
, CFLUSH
);
ltc
.t_werasc
= CHK(ltc
.t_werasc
, CWERASE
);
ltc
.t_lnextc
= CHK(ltc
.t_lnextc
, CLNEXT
);
(void) ioctl(FILEDES
, TIOCSLTC
, (char *)<c
);
tchar
.t_intrc
= CHK(tchar
.t_intrc
, CINTR
);
tchar
.t_quitc
= CHK(tchar
.t_quitc
, CQUIT
);
tchar
.t_startc
= CHK(tchar
.t_startc
, CSTART
);
tchar
.t_stopc
= CHK(tchar
.t_stopc
, CSTOP
);
tchar
.t_eofc
= CHK(tchar
.t_eofc
, CEOF
);
(void) ioctl(FILEDES
, TIOCSETC
, (char *)&tchar
);
mode
.sg_flags
|= XTABS
|ECHO
|CRMOD
|ANYP
;
curerase
= CHK(curerase
, CERASE
);
curkill
= CHK(curkill
, CKILL
);
curintr
= CHK(curintr
, CINTR
);
(void) ioctl(FILEDES
, TCGETA
, (char *)&mode
);
curerase
= CHK(curerase
, OLDERASE
);
curkill
= CHK(curkill
, OLDKILL
);
curintr
= CHK(curintr
, OLDINTR
);
mode
.c_cc
[VQUIT
] = CHK(mode
.c_cc
[VQUIT
], CQUIT
);
mode
.c_cc
[VEOF
] = CHK(mode
.c_cc
[VEOF
], CEOF
);
mode
.c_iflag
|= (BRKINT
|ISTRIP
|ICRNL
|IXON
);
mode
.c_iflag
&= ~(IGNBRK
|PARMRK
|INPCK
|INLCR
|IGNCR
|IUCLC
|IXOFF
);
mode
.c_oflag
|= (OPOST
|ONLCR
);
mode
.c_oflag
&= ~(OLCUC
|OCRNL
|ONOCR
|ONLRET
|OFILL
|OFDEL
|
NLDLY
|CRDLY
|TABDLY
|BSDLY
|VTDLY
|FFDLY
);
mode
.c_cflag
|= (CS7
|CREAD
);
mode
.c_cflag
&= ~(CSIZE
|PARODD
|CLOCAL
);
mode
.c_lflag
|= (ISIG
|ICANON
|ECHO
|ECHOK
);
mode
.c_lflag
&= ~(XCASE
|ECHONL
|NOFLSH
);
(void) ioctl(FILEDES
, TCSETAW
, (char *)&mode
);
else if (argc
== 2 && sequal(argv
[1], "-"))
/* scan argument list and collect flags */
Report
= YES
; /* report current terminal type */
else while (*p
) switch (*p
++)
if (ioctl(FILEDES
, TIOCSETD
, (char *)&ldisc
)<0)
case 'r': /* report to user */
case 'E': /* special erase: operate on all but TTY33 */
/* explicit fall-through to -e case */
case 'e': /* erase character */
if (*p
== '^' && p
[1] != NULL
)
# if defined(USG) || defined(TIOCGETC)
case 'i': /* interrupt character */
if (*p
== '^' && p
[1] != NULL
)
case 'k': /* kill character */
if (*p
== '^' && p
[1] != NULL
)
case 'd': /* dialup type */
case 'p': /* plugboard type */
case 'a': /* arpanet type */
mapold
: Map
->Ident
= NewType
;
p
= nextarg(argc
--, argv
++);
case 'm': /* map identifier to type */
/* This code is very loose. Almost no
** syntax checking is done!! However,
** illegal syntax will only produce
p
= nextarg(argc
--, argv
++);
Map
->Ident
= p
; /* identifier */
while (!Break
) switch (*p
)
p
= nextarg(argc
--, argv
++);
case ':': /* mapped type */
case '>': /* conditional */
case '<': /* conditional */
case '=': /* conditional */
case '!': /* invert conditions */
case 'B': /* Baud rate */
/* intentional fallthru */
if (isdigit(*p
) || *p
== 'e')
Map
->Speed
= baudrate(p
);
while (isalnum(*p
) || *p
== '.')
if (Not
) /* invert sense of test */
Map
->Test
= (~(Map
->Test
))&ALL
;
p
= nextarg(argc
--, argv
++);
case 'h': /* don't get type from htmp or env */
case 'u': /* don't update htmp */
case 's': /* output setenv commands */
case 'S': /* output setenv strings */
case 'I': /* no initialization */
case 'v': /* no virtual terminal */
Map
->Ident
= ""; /* means "map any type" */
Map
->Test
= ALL
; /* at all baud rates */
Map
->Type
= DefType
; /* to the default type */
* Get rid of $TERMCAP, if it's there, so we get a real
* entry from /etc/termcap. This prevents us from being
* fooled by out of date stuff in the environment, and
* makes tabs work right on CB/Unix.
bufp
= getenv("TERMCAP");
if (bufp
&& *bufp
!= '/')
(void) strcpy(bufp
-8, "NOTHING"); /* overwrite only "TERMCAP" */
/* get current idea of terminal type from environment */
if (!Dash_h
&& TtyType
== 0)
TtyType
= getenv("TERM");
/* determine terminal id if needed */
if (Ttyid
== NOTTY
&& (TtyType
== 0 || !Dash_h
|| !Dash_u
))
if (!RepOnly
&& Ttyid
== NOTTY
&& (TtyType
== 0 || !Dash_h
))
Ttyid
= ttyname(FILEDES
);
/* get htmp if ever used */
if (!Dash_u
|| (TtyType
== 0 && !Dash_h
))
/* get htmp entry -- if error or wrong user use ttytype */
if (Ttyid
== NOTTY
|| hget(Ttyid
) < 0 ||
hgettype() == 0 || hgetuid() != (getuid() & UIDMASK
))
/* find terminal type (if not already known) */
if (TtyType
== 0 && !Dash_h
)
/* get type from /etc/htmp */
/* If still undefined, look at /etc/ttytype */
TtyType
= stypeof(Ttyid
);
/* If still undefined, use DEFTYPE */
/* check for dialup or other mapping */
if (!(Alias
[0] && isalias(TtyType
)))
if (tgetent(Capbuf
, TtyType
) > 0)
TtyType
= mapped(TtyType
);
/* TtyType now contains a pointer to the type of the terminal */
/* If the first character is '?', ask the user */
/* read the terminal. If not empty, set type */
i
= read(2, termbuf
, sizeof termbuf
- 1);
if (termbuf
[i
- 1] == '\n')
/* get terminal capabilities */
if (!(Alias
[0] && isalias(TtyType
))) {
switch (tgetent(Capbuf
, TtyType
))
prs("Cannot find termcap\n");
/* determine erase and kill characters */
if (Specialerase
&& !tgetflag("bs"))
p
= tgetstr("kb", &bufp
);
if (p
== NULL
|| p
[1] != '\0')
p
= tgetstr("bc", &bufp
);
if (p
!= NULL
&& p
[1] == '\0')
if (Erase_char
== 0 && !tgetflag("os") && curerase
== OLDERASE
)
if (tgetflag("bs") || bs_char
!= 0)
Erase_char
= (bs_char
!= 0) ? bs_char
: BACKSPACE
;
PadBaud
= tgetnum("pb"); /* OK if fails */
for (i
=0; speeds
[i
].string
; i
++)
if (speeds
[i
].baudrate
== PadBaud
) {
PadBaud
= speeds
[i
].speed
;
setdelay("dC", CRdelay
, CRbits
, &mode
.sg_flags
);
setdelay("dN", NLdelay
, NLbits
, &mode
.sg_flags
);
setdelay("dB", BSdelay
, BSbits
, &mode
.sg_flags
);
setdelay("dF", FFdelay
, FFbits
, &mode
.sg_flags
);
setdelay("dT", TBdelay
, TBbits
, &mode
.sg_flags
);
if (tgetflag("UC") || (command
[0] & 0140) == 0100)
mode
.sg_flags
&= ~(EVENP
| ODDP
| RAW
);
mode
.sg_flags
&= ~CBREAK
;
if ((mode
.sg_flags
& (EVENP
| ODDP
)) == 0)
mode
.sg_flags
|= EVENP
| ODDP
;
mode
.sg_flags
|= CRMOD
| ECHO
| XTABS
;
if (tgetflag("NL")) /* new line, not line feed */
if (tgetflag("HD")) /* half duplex */
if (tgetflag("pt")) /* print tabs */
setdelay("dC", CRdelay
, CRbits
, &mode
.c_oflag
);
setdelay("dN", NLdelay
, NLbits
, &mode
.c_oflag
);
setdelay("dB", BSdelay
, BSbits
, &mode
.c_oflag
);
setdelay("dF", FFdelay
, FFbits
, &mode
.c_oflag
);
setdelay("dT", TBdelay
, TBbits
, &mode
.c_oflag
);
setdelay("dV", VTdelay
, VTbits
, &mode
.c_oflag
);
if (tgetflag("UC") || (command
[0] & 0140) == 0100) {
else if (tgetflag("LC")) {
mode
.c_iflag
&= ~(PARMRK
|INPCK
);
if (tgetflag("NL")) { /* new line, not line feed */
if (tgetflag("HD")) /* half duplex */
if (tgetflag("pt")) /* print tabs */
mode
.c_lflag
|= (ECHOE
|ECHOK
);
lmode
|= LCTLECH
; /* display ctrl chars */
{ /** set printer modes **/
lmode
&= ~(LCRTBS
|LCRTERA
|LCRTKIL
);
if (mode
.sg_ospeed
>= B1200
)
lmode
|= LCRTERA
|LCRTKIL
;
lmode
&= ~(LMDMBUF
|LLITOUT
|LPASS8
);
(void) ioctl(FILEDES
, TIOCLSET
, (char *)&lmode
);
if (tgetstr("pc", &bufp
) != 0)
(void) ioctl(FILEDES
, TIOCGWINSZ
, (char *)&win
);
if (win
.ws_row
== 0 && win
.ws_col
== 0 &&
lines
> 0 && columns
> 0) {
(void) ioctl(FILEDES
, TIOCSWINSZ
, (char *)&win
);
/* output startup string */
if (oldmode
.sg_flags
&(XTABS
|CRMOD
))
oldmode
.sg_flags
&= ~(XTABS
|CRMOD
);
if (oldmode
.c_oflag
&(TAB3
|ONLCR
|OCRNL
|ONLRET
))
oldmode
.c_oflag
&= (TAB3
|ONLCR
|OCRNL
|ONLRET
);
(void) ioctl(FILEDES
, LDSETT
, (char *)&block
);
if (IsReset
&& tgetstr("rs", &bufp
) != 0 ||
tgetstr("is", &bufp
) != 0)
if (IsReset
&& tgetstr("rf", &bufp
) != 0 ||
tgetstr("if", &bufp
) != 0)
sleep(1); /* let terminal settle down */
for (i
=0; vt_map
[i
].stdnum
; i
++)
if (vt_map
[i
].stdnum
== j
)
VirTermNo
= vt_map
[i
].localnum
;
setmode(0); /* set new modes, if they've changed */
/* set up environment for the shell we are using */
/* (this code is rather heuristic, checking for $SHELL */
/* ending in the 3 characters "csh") */
if ((sh
= getenv("SHELL")) && (i
= strlen(sh
)) >= 3)
if ((csh
= sequal(&sh
[i
-3], "csh")) && CmndLine
)
(void) write(STDOUT
, "set noglob;\n", 12);
/* running Bourne shell */
(void) write(STDOUT
, "export TERMCAP TERM;\n", 21);
/* report type if appropriate */
if (DoSetenv
|| Report
|| Ureport
)
/* if type is the short name, find first alias (if any) */
if (sequal(TtyType
, Alias
[0]) && Alias
[1]) {
(void) write(STDOUT
, "setenv TERM ", 12);
(void) write(STDOUT
, TtyType
, strlen(TtyType
));
(void) write(STDOUT
, " ", 1);
(void) write(STDOUT
, ";\n", 2);
(void) write(STDOUT
, "TERM=", 5);
(void) write(STDOUT
, TtyType
, strlen(TtyType
));
(void) write(STDOUT
, ";\n", 2);
(void) write(STDOUT
, TtyType
, strlen(TtyType
));
(void) write(STDOUT
, "\n", 1);
prs("Terminal type is ");
(void) write(STDOUT
, "setenv TERMCAP '", 16);
(void) write(STDOUT
, "TERMCAP='", 9);
(void) write(STDOUT
, "';\n", 3);
(void) write(STDOUT
, "unset noglob;\n", 14);
(void) write(STDOUT
, "';\n", 3);
/* tell about changing erase, kill and interrupt characters */
reportek("Erase", curerase
, olderase
, OLDERASE
);
reportek("Kill", curkill
, oldkill
, OLDKILL
);
reportek("Interrupt", curintr
, oldintr
, OLDINTR
);
prs("Cannot update htmp\n");
/* update htmp file only if changed */
if (!bequal(Capbuf
, hsgettype(), 2))
hsettype(Capbuf
[0] | (Capbuf
[1] << 8));
* Set the hardware tabs on the terminal, using the ct (clear all tabs),
* st (set one tab) and ch (horizontal cursor addressing) capabilities.
* This is done before if and is, so they can patch in case we blow this.
char *clear_tabs
, *set_tab
, *set_column
, *set_pos
;
clear_tabs
= tgetstr("ct", &capsp
);
set_tab
= tgetstr("st", &capsp
);
set_column
= tgetstr("ch", &capsp
);
set_pos
= tgetstr("cm", &capsp
);
if (clear_tabs
&& set_tab
) {
prc('\r'); /* force to be at left margin */
tputs(clear_tabs
, 0, prc
);
for (c
=8; c
<columns
; c
+= 8) {
/* get to that column. */
tg_out
= "OOPS"; /* also returned by tgoto */
tg_out
= tgoto(set_column
, 0, c
);
if (*tg_out
== 'O' && set_pos
)
tg_out
= tgoto(set_pos
, c
, lines
-1);
prc(' '); prc(' '); prc(' '); prc(' ');
prc(' '); prc(' '); prc(' '); prc(' ');
/* flag serves several purposes:
* if called as the result of a signal, flag will be > 0.
* if called from terminal init, flag == -1 means reset "oldmode".
* called with flag == 0 at end of normal mode processing.
struct tchars
*ttytchars
;
if (flag
< 0) { /* unconditionally reset oldmode (called from init) */
} else if (!bequal((char *)&mode
, (char *)&oldmode
, sizeof mode
)) {
} else { /* don't need it */
ttymode
= (struct sgttyb
*)0;
ttymode
= (struct termio
*)0;
ttytchars
= (struct tchars
*)0;
(void) ioctl(FILEDES
, TCSETAW
, (char *)ttymode
);
(void) ioctl(FILEDES
, TIOCSETN
, (char *)ttymode
);
(void) ioctl(FILEDES
, TIOCSETC
, (char *)ttytchars
);
r1
= ioctl(FILEDES
, LDGETT
, (char *)&block
);
block
.st_termt
= VirTermNo
;
block
.st_flgs
&= ~TM_ANL
;
r2
= ioctl(FILEDES
, LDSETT
, (char *)&block
);
if (flag
> 0) /* trapped signal */
reportek(name
, new, old
, def
)
if (tgetstr("kb", &bufp
) > 0 && n
== buf
[0] && buf
[1] == NULL
)
setdelay(cap
, dtab
, bits
, flags
)
register struct delay
*p
;
/* see if this capability exists at all */
/* No padding at speeds below PadBaud */
/* clear out the bits, replace with new ones */
/* scan dtab for first entry with adequate delay */
for (p
= dtab
; p
->d_delay
>= 0; p
++)
/* use last entry if none will do */
if (OutPtr
>= sizeof OutBuf
)
(void) write(2, OutBuf
, OutPtr
);
while ((i
= read(fd
, buf
, BUFSIZ
)) > 0)
(void) write(FILEDES
, buf
, i
);
bequal(a
, b
, len
) /* must be same thru len chars */
while ((*p
== *q
) && --i
> 0)
return ((*p
== *q
) && i
>= 0);
sequal(a
, b
) /* must be same thru NULL */
register char *p
= a
, *q
= b
;
while (*p
&& *q
&& (*p
== *q
))
while (*b
&& *b
!= ':') {
for(i
= 0; Alias
[i
]; printf("A:%s\n", Alias
[i
++]));
isalias(ident
) /* is ident same as one of the aliases? */
/* split off end of name */
if ((t
= getttynam(TtyId
)) != NULL
)
/* get aliases from termcap entry */
if (Mapped
&& tgetent(Capbuf
, PortType
) > 0) {
if (sequal(Alias
[0], PortType
) && Alias
[1])
* routine to output the string for the environment TERMCAP variable
#define WHITE(c) (c == ' ' || c == '\t')
/* discard names with blanks */
/** May not be desireable ? **/
while (*bp
&& *bp
!= ':') {
while (*tp
&& *tp
!= '|' && *tp
!= ':') {
space
= (space
|| WHITE(*tp
) );
p
= putbuf(p
, ":am"); /* All virt terms have auto margins */
case ':': /* discard empty, cancelled or dupl fields */
while (*tp
&& *tp
!= ':') {
empty
= (empty
&& WHITE(*tp
) );
* Virtual terminals use ic, not im or ei. Turn
* any of them into ic - duplicates will be cancelled
* below. I assume that terminals needing im+ic+ei
* are handled by the kernel.
if (VirTermNo
> 0 && !HasAM
&&
(bp
[1]=='i' && bp
[2]=='m' ||
bp
[1]=='e' && bp
[2]=='i')) {
if (VirTermNo
> 0 && !HasAM
&&
(bp
[1]=='c' && bp
[2]=='s')) {
/* Also need al, so kludge: */
p
= putbuf(p
, ":al=\033\120");
if (empty
|| cancelled(bp
+1)) {
if (VirTermNo
> 0 && !HasAM
)
for (i
= 0; vtab
[i
].value
; i
++) {
if (vtab
[i
].cap
[0] == bp
[1] &&
vtab
[i
].cap
[1] == bp
[2]) {
*p
++ = *bp
++; /* colon */
*p
++ = *bp
++; /* first char */
*p
++ = *bp
++; /* second " */
*p
++ = *bp
++; /* = sign */
p
= putbuf(p
, vtab
[i
].value
);
case ' ': /* no spaces in output */
case '!': /* the shell thinks this is history */
case ',': /* the shell thinks this is history */
case '"': /* no quotes in output */
case '\'': /* no quotes in output */
case '`': /* no back quotes in output */
case '^': /* anything following is OK */
if (*bp
== 'E' && VirTermNo
> 0 &&
(bp
[-3]!='\\'||bp
[-2]!='E') &&
(bp
[1]!='\\'||bp
[2]!='E'))
*p
++ = ':'; /* we skipped the last : with the : lookahead hack */
(void) write (STDOUT
, buf
, p
-buf
);
for (i
= 0; i
< ncap
; i
++)
if (cap
[0] == delcap
[i
][0] && cap
[1] == delcap
[i
][1])
/* delete a second occurrance of the same capability */
delcap
[ncap
][0] = cap
[0];
delcap
[ncap
][1] = cap
[1];
ptr
= putbuf(ptr
, "\\E");
(void) sprintf(buf
, "\\%03o", *str
);
while (i
< 7 && (isalnum(*p
) || *p
== '.'))
for (i
=0; speeds
[i
].string
; i
++)
if (sequal(speeds
[i
].string
, buf
))
return (speeds
[i
].speed
);
printf ("spd:%d\n", ospeed
);
if (*(Map
->Ident
) == NULL
|| sequal(Map
->Ident
, type
) || isalias(Map
->Ident
))
case ANY
: /* no test specified */
match
= (ospeed
> Map
->Speed
);
match
= (ospeed
>= Map
->Speed
);
match
= (ospeed
== Map
->Speed
);
match
= (ospeed
<= Map
->Speed
);
match
= (ospeed
< Map
->Speed
);
match
= (ospeed
!= Map
->Speed
);
/* no match found; return given type */
printf ("%s t:%d s:%d %s\n",
Map
->Ident
, Map
->Test
, Map
->Speed
, Map
->Type
);
fatal ("Too few args: ", *argv
);
fatal ("Unexpected arg: ", *argv
);