diff options
author | rgrimes <rgrimes@FreeBSD.org> | 1994-05-27 12:33:43 +0000 |
---|---|---|
committer | rgrimes <rgrimes@FreeBSD.org> | 1994-05-27 12:33:43 +0000 |
commit | f9ab90d9d6d02989a075d0f0074496d5b1045e4b (patch) | |
tree | add7e996bac5289cdc55e6935750c352505560a9 /usr.bin/tset | |
parent | be22b15ae2ff8d7fe06b6e14fddf0c5b444a95da (diff) | |
download | FreeBSD-src-f9ab90d9d6d02989a075d0f0074496d5b1045e4b.zip FreeBSD-src-f9ab90d9d6d02989a075d0f0074496d5b1045e4b.tar.gz |
BSD 4.4 Lite Usr.bin Sources
Diffstat (limited to 'usr.bin/tset')
-rw-r--r-- | usr.bin/tset/Makefile | 11 | ||||
-rw-r--r-- | usr.bin/tset/extern.h | 60 | ||||
-rw-r--r-- | usr.bin/tset/map.c | 263 | ||||
-rw-r--r-- | usr.bin/tset/misc.c | 98 | ||||
-rw-r--r-- | usr.bin/tset/set.c | 322 | ||||
-rw-r--r-- | usr.bin/tset/term.c | 155 | ||||
-rw-r--r-- | usr.bin/tset/tset.1 | 405 | ||||
-rw-r--r-- | usr.bin/tset/tset.c | 303 | ||||
-rw-r--r-- | usr.bin/tset/wrterm.c | 112 |
9 files changed, 1729 insertions, 0 deletions
diff --git a/usr.bin/tset/Makefile b/usr.bin/tset/Makefile new file mode 100644 index 0000000..126cf321 --- /dev/null +++ b/usr.bin/tset/Makefile @@ -0,0 +1,11 @@ +# @(#)Makefile 8.1 (Berkeley) 6/9/93 + +PROG= tset +SRCS= map.c misc.c set.c term.c tset.c wrterm.c + +DPADD= ${LIBTERMCAP} +LDADD= -ltermcap +LINKS= ${BINDIR}/tset ${BINDIR}/reset +MLINKS= tset.1 reset.1 + +.include <bsd.prog.mk> diff --git a/usr.bin/tset/extern.h b/usr.bin/tset/extern.h new file mode 100644 index 0000000..0465a66 --- /dev/null +++ b/usr.bin/tset/extern.h @@ -0,0 +1,60 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)extern.h 8.1 (Berkeley) 6/9/93 + */ + +/* This should be in <termcap.h> instead. */ +extern char PC; +extern short ospeed; +int tgetent __P((char *, char *)); +int tgetflag __P((char *)); +int tgetnum __P((char *)); +char *tgetstr __P((char *, char **)); +char *tgoto __P((char *, int, int)); +int tputs __P((char *, int, void (*) __P((int)))); + +extern struct termios mode, oldmode; +extern int columns, isreset, lines; +extern int erasechar, intrchar, killchar; + +void add_mapping __P((char *, char *)); +void cat __P((char *)); +void err __P((const char *, ...)); +char *get_termcap_entry __P((char *, char **)); +char *mapped __P((char *)); +void outc __P((int)); +void reset_mode __P((void)); +void set_control_chars __P((void)); +void set_conversions __P((int)); +void set_init __P((void)); +void wrtermcap __P((char *)); diff --git a/usr.bin/tset/map.c b/usr.bin/tset/map.c new file mode 100644 index 0000000..56cb725 --- /dev/null +++ b/usr.bin/tset/map.c @@ -0,0 +1,263 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/9/93"; +#endif /* not lint */ + +#include <sys/types.h> +#include <termios.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include "extern.h" + +int baudrate __P((char *)); + +/* Baud rate conditionals for mapping. */ +#define GT 0x01 +#define EQ 0x02 +#define LT 0x04 +#define NOT 0x08 +#define GE (GT | EQ) +#define LE (LT | EQ) + +typedef struct map { + struct map *next; /* Linked list of maps. */ + char *porttype; /* Port type, or "" for any. */ + char *type; /* Terminal type to select. */ + int conditional; /* Baud rate conditionals bitmask. */ + int speed; /* Baud rate to compare against. */ +} MAP; + +MAP *cur, *maplist; + +/* + * Syntax for -m: + * [port-type][test baudrate]:terminal-type + * The baud rate tests are: >, <, @, =, ! + */ +void +add_mapping(port, arg) + char *port, *arg; +{ + MAP *mapp; + char *copy, *p, *termp; + + copy = strdup(arg); + mapp = malloc((u_int)sizeof(MAP)); + if (copy == NULL || mapp == NULL) + err("%s", strerror(errno)); + mapp->next = NULL; + if (maplist == NULL) + cur = maplist = mapp; + else { + cur->next = mapp; + cur = mapp; + } + + mapp->porttype = arg; + mapp->conditional = 0; + + arg = strpbrk(arg, "><@=!:"); + + if (arg == NULL) { /* [?]term */ + mapp->type = mapp->porttype; + mapp->porttype = NULL; + goto done; + } + + if (arg == mapp->porttype) /* [><@=! baud]:term */ + termp = mapp->porttype = NULL; + else + termp = arg; + + for (;; ++arg) /* Optional conditionals. */ + switch(*arg) { + case '<': + if (mapp->conditional & GT) + goto badmopt; + mapp->conditional |= LT; + break; + case '>': + if (mapp->conditional & LT) + goto badmopt; + mapp->conditional |= GT; + break; + case '@': + case '=': /* Not documented. */ + mapp->conditional |= EQ; + break; + case '!': + mapp->conditional |= NOT; + break; + default: + goto next; + } + +next: if (*arg == ':') { + if (mapp->conditional) + goto badmopt; + ++arg; + } else { /* Optional baudrate. */ + arg = index(p = arg, ':'); + if (arg == NULL) + goto badmopt; + *arg++ = '\0'; + mapp->speed = baudrate(p); + } + + if (*arg == NULL) /* Non-optional type. */ + goto badmopt; + + mapp->type = arg; + + /* Terminate porttype, if specified. */ + if (termp != NULL) + *termp = '\0'; + + /* If a NOT conditional, reverse the test. */ + if (mapp->conditional & NOT) + mapp->conditional = ~mapp->conditional & (EQ | GT | LT); + + /* If user specified a port with an option flag, set it. */ +done: if (port) { + if (mapp->porttype) +badmopt: err("illegal -m option format: %s", copy); + mapp->porttype = port; + } + +#ifdef MAPDEBUG + (void)printf("port: %s\n", mapp->porttype ? mapp->porttype : "ANY"); + (void)printf("type: %s\n", mapp->type); + (void)printf("conditional: "); + p = ""; + if (mapp->conditional & GT) { + (void)printf("GT"); + p = "/"; + } + if (mapp->conditional & EQ) { + (void)printf("%sEQ", p); + p = "/"; + } + if (mapp->conditional & LT) + (void)printf("%sLT", p); + (void)printf("\nspeed: %d\n", mapp->speed); +#endif +} + +/* + * Return the type of terminal to use for a port of type 'type', as specified + * by the first applicable mapping in 'map'. If no mappings apply, return + * 'type'. + */ +char * +mapped(type) + char *type; +{ + MAP *mapp; + int match; + + for (mapp = maplist; mapp; mapp = mapp->next) + if (mapp->porttype == NULL || !strcmp(mapp->porttype, type)) { + switch (mapp->conditional) { + case 0: /* No test specified. */ + match = 1; + break; + case EQ: + match = (ospeed == mapp->speed); + break; + case GE: + match = (ospeed >= mapp->speed); + break; + case GT: + match = (ospeed > mapp->speed); + break; + case LE: + match = (ospeed <= mapp->speed); + break; + case LT: + match = (ospeed < mapp->speed); + break; + } + if (match) + return (mapp->type); + } + /* No match found; return given type. */ + return (type); +} + +typedef struct speeds { + char *string; + int speed; +} SPEEDS; + +SPEEDS speeds[] = { + "0", B0, + "50", B50, + "75", B75, + "110", B110, + "134", B134, + "134.5", B134, + "150", B150, + "200", B200, + "300", B300, + "600", B600, + "1200", B1200, + "1800", B1800, + "2400", B2400, + "4800", B4800, + "9600", B9600, + "19200", B19200, + "38400", B38400, + "exta", B19200, + "extb", B38400, + NULL +}; + +int +baudrate(rate) + char *rate; +{ + SPEEDS *sp; + + /* The baudrate number can be preceded by a 'B', which is ignored. */ + if (*rate == 'B') + ++rate; + + for (sp = speeds; sp->string; ++sp) + if (!strcasecmp(rate, sp->string)) + return (sp->speed); + err("unknown baud rate %s", rate); + /* NOTREACHED */ +} diff --git a/usr.bin/tset/misc.c b/usr.bin/tset/misc.c new file mode 100644 index 0000000..c96c48c --- /dev/null +++ b/usr.bin/tset/misc.c @@ -0,0 +1,98 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 6/9/93"; +#endif /* not lint */ + +#include <fcntl.h> +#include <errno.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "extern.h" + +void +cat(file) + char *file; +{ + register int fd, nr, nw; + char buf[1024]; + + if ((fd = open(file, O_RDONLY, 0)) < 0) + err("%s: %s", file, strerror(errno)); + + while ((nr = read(fd, buf, sizeof(buf))) > 0) + if ((nw = write(STDERR_FILENO, buf, nr)) == -1) + err("write to stderr: %s", strerror(errno)); + if (nr != 0) + err("%s: %s", file, strerror(errno)); + (void)close(fd); +} + +void +outc(c) + int c; +{ + (void)putc(c, stderr); +} + +#if __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif + +void +#if __STDC__ +err(const char *fmt, ...) +#else +err(fmt, va_alist) + char *fmt; + va_dcl +#endif +{ + va_list ap; +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + (void)fprintf(stderr, "tset: "); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + (void)fprintf(stderr, "\n"); + exit(1); + /* NOTREACHED */ +} diff --git a/usr.bin/tset/set.c b/usr.bin/tset/set.c new file mode 100644 index 0000000..b279a1c --- /dev/null +++ b/usr.bin/tset/set.c @@ -0,0 +1,322 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)set.c 8.2 (Berkeley) 2/28/94"; +#endif /* not lint */ + +#include <termios.h> +#include <unistd.h> +#include <stdio.h> +#include "extern.h" + +#define CHK(val, dft) (val <= 0 ? dft : val) + +int set_tabs __P((void)); + +/* + * Reset the terminal mode bits to a sensible state. Very useful after + * a child program dies in raw mode. + */ +void +reset_mode() +{ + tcgetattr(STDERR_FILENO, &mode); + +#if defined(VDISCARD) && defined(CDISCARD) + mode.c_cc[VDISCARD] = CHK(mode.c_cc[VDISCARD], CDISCARD); +#endif + mode.c_cc[VEOF] = CHK(mode.c_cc[VEOF], CEOF); + mode.c_cc[VERASE] = CHK(mode.c_cc[VERASE], CERASE); +#if defined(VFLUSH) && defined(CFLUSH) + mode.c_cc[VFLUSH] = CHK(mode.c_cc[VFLUSH], CFLUSH); +#endif + mode.c_cc[VINTR] = CHK(mode.c_cc[VINTR], CINTR); + mode.c_cc[VKILL] = CHK(mode.c_cc[VKILL], CKILL); +#if defined(VLNEXT) && defined(CLNEXT) + mode.c_cc[VLNEXT] = CHK(mode.c_cc[VLNEXT], CLNEXT); +#endif + mode.c_cc[VQUIT] = CHK(mode.c_cc[VQUIT], CQUIT); +#if defined(VREPRINT) && defined(CRPRNT) + mode.c_cc[VREPRINT] = CHK(mode.c_cc[VREPRINT], CRPRNT); +#endif + mode.c_cc[VSTART] = CHK(mode.c_cc[VSTART], CSTART); + mode.c_cc[VSTOP] = CHK(mode.c_cc[VSTOP], CSTOP); + mode.c_cc[VSUSP] = CHK(mode.c_cc[VSUSP], CSUSP); +#if defined(VWERASE) && defined(CWERASE) + mode.c_cc[VWERASE] = CHK(mode.c_cc[VWERASE], CWERASE); +#endif + + mode.c_iflag &= ~(IGNBRK | PARMRK | INPCK | ISTRIP | INLCR | IGNCR +#ifdef IUCLC + | IUCLC +#endif +#ifdef IXANY + | IXANY +#endif + | IXOFF); + + mode.c_iflag |= (BRKINT | IGNPAR | ICRNL | IXON +#ifdef IMAXBEL + | IMAXBEL +#endif + ); + + mode.c_oflag &= ~(0 +#ifdef OLCUC + | OLCUC +#endif +#ifdef OCRNL + | OCRNL +#endif +#ifdef ONOCR + | ONOCR +#endif +#ifdef ONLRET + | ONLRET +#endif +#ifdef OFILL + | OFILL +#endif +#ifdef OFDEL + | OFDEL +#endif +#ifdef NLDLY + | NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY +#endif + ); + + mode.c_oflag |= (OPOST +#ifdef ONLCR + | ONLCR +#endif + ); + + mode.c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD | CLOCAL); + mode.c_cflag |= (CS8 | CREAD); + mode.c_lflag &= ~(ECHONL | NOFLSH | TOSTOP +#ifdef ECHOPTR + | ECHOPRT +#endif +#ifdef XCASE + | XCASE +#endif + ); + + mode.c_lflag |= (ISIG | ICANON | ECHO | ECHOE | ECHOK +#ifdef ECHOCTL + | ECHOCTL +#endif +#ifdef ECHOKE + | ECHOKE +#endif + ); + + tcsetattr(STDERR_FILENO, TCSADRAIN, &mode); +} + +/* + * Determine the erase, interrupt, and kill characters from the termcap + * entry and command line and update their values in 'mode'. + */ +void +set_control_chars() +{ + char *bp, *p, bs_char, buf[1024]; + + bp = buf; + p = tgetstr("kb", &bp); + if (p == NULL || p[1] != '\0') + p = tgetstr("bc", &bp); + if (p != NULL && p[1] == '\0') + bs_char = p[0]; + else if (tgetflag("bs")) + bs_char = CTRL('h'); + else + bs_char = 0; + + if (erasechar == 0 && !tgetflag("os") && mode.c_cc[VERASE] != CERASE) { + if (tgetflag("bs") || bs_char != 0) + erasechar = -1; + } + if (erasechar < 0) + erasechar = (bs_char != 0) ? bs_char : CTRL('h'); + + if (mode.c_cc[VERASE] == 0 || erasechar != 0) + mode.c_cc[VERASE] = erasechar ? erasechar : CERASE; + + if (mode.c_cc[VINTR] == 0 || intrchar != 0) + mode.c_cc[VINTR] = intrchar ? intrchar : CINTR; + + if (mode.c_cc[VKILL] == 0 || killchar != 0) + mode.c_cc[VKILL] = killchar ? killchar : CKILL; +} + +/* + * Set up various conversions in 'mode', including parity, tabs, returns, + * echo, and case, according to the termcap entry. If the program we're + * running was named with a leading upper-case character, map external + * uppercase to internal lowercase. + */ +void +set_conversions(usingupper) + int usingupper; +{ + if (tgetflag("UC") || usingupper) { +#ifdef IUCLC + mode.c_iflag |= IUCLC; + mode.c_oflag |= OLCUC; +#endif + } else if (tgetflag("LC")) { +#ifdef IUCLC + mode.c_iflag &= ~IUCLC; + mode.c_oflag &= ~OLCUC; +#endif + } + mode.c_iflag &= ~(PARMRK | INPCK); + mode.c_lflag |= ICANON; + if (tgetflag("EP")) { + mode.c_cflag |= PARENB; + mode.c_cflag &= ~PARODD; + } + if (tgetflag("OP")) { + mode.c_cflag |= PARENB; + mode.c_cflag |= PARODD; + } + +#ifdef ONLCR + mode.c_oflag |= ONLCR; +#endif + mode.c_iflag |= ICRNL; + mode.c_lflag |= ECHO; + mode.c_oflag |= OXTABS; + if (tgetflag("NL")) { /* Newline, not linefeed. */ +#ifdef ONLCR + mode.c_oflag &= ~ONLCR; +#endif + mode.c_iflag &= ~ICRNL; + } + if (tgetflag("HD")) /* Half duplex. */ + mode.c_lflag &= ~ECHO; + if (tgetflag("pt")) /* Print tabs. */ + mode.c_oflag &= ~OXTABS; + mode.c_lflag |= (ECHOE | ECHOK); +} + +/* Output startup string. */ +void +set_init() +{ + char *bp, buf[1024]; + int settle; + + bp = buf; + if (tgetstr("pc", &bp) != 0) /* Get/set pad character. */ + PC = buf[0]; + +#ifdef TAB3 + if (oldmode.c_oflag & (TAB3 | ONLCR | OCRNL | ONLRET)) { + oldmode.c_oflag &= (TAB3 | ONLCR | OCRNL | ONLRET); + tcsetattr(STDERR_FILENO, TCSADRAIN, &oldmode); + } +#endif + settle = set_tabs(); + + if (isreset) { + bp = buf; + if (tgetstr("rs", &bp) != 0 || tgetstr("is", &bp) != 0) { + tputs(buf, 0, outc); + settle = 1; + } + bp = buf; + if (tgetstr("rf", &bp) != 0 || tgetstr("if", &bp) != 0) { + cat(buf); + settle = 1; + } + } + + if (settle) { + (void)putc('\r', stderr); + (void)fflush(stderr); + (void)sleep(1); /* Settle the terminal. */ + } +} + +/* + * 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. + * Return nonzero if we set any tab stops, zero if not. + */ +int +set_tabs() +{ + int c; + char *capsp, *clear_tabs; + char *set_column, *set_pos, *set_tab, *tg_out; + char caps[1024]; + + capsp = caps; + set_tab = tgetstr("st", &capsp); + + if (set_tab && (clear_tabs = tgetstr("ct", &capsp))) { + (void)putc('\r', stderr); /* Force to left margin. */ + tputs(clear_tabs, 0, outc); + } + + set_column = tgetstr("ch", &capsp); + set_pos = set_column ? NULL : tgetstr("cm", &capsp); + + if (set_tab) { + for (c = 8; c < columns; c += 8) { + /* + * Get to the right column. "OOPS" is returned by + * tgoto() if it can't do the job. (*snarl*) + */ + tg_out = "OOPS"; + if (set_column) + tg_out = tgoto(set_column, 0, c); + if (*tg_out == 'O' && set_pos) + tg_out = tgoto(set_pos, c, lines - 1); + if (*tg_out != 'O') + tputs(tg_out, 1, outc); + else + (void)fprintf(stderr, "%s", " "); + /* Set the tab. */ + tputs(set_tab, 0, outc); + } + putc('\r', stderr); + return (1); + } + return (0); +} diff --git a/usr.bin/tset/term.c b/usr.bin/tset/term.c new file mode 100644 index 0000000..dc652e3 --- /dev/null +++ b/usr.bin/tset/term.c @@ -0,0 +1,155 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)term.c 8.1 (Berkeley) 6/9/93"; +#endif /* not lint */ + +#include <sys/types.h> +#include <errno.h> +#include <ttyent.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "extern.h" + +char tbuf[1024]; /* Termcap entry. */ + +char *askuser __P((char *)); +char *ttys __P((char *)); + +/* + * Figure out what kind of terminal we're dealing with, and then read in + * its termcap entry. + */ +char * +get_termcap_entry(userarg, tcapbufp) + char *userarg, **tcapbufp; +{ + struct ttyent *t; + int rval; + char *p, *ttype, *ttypath; + + if (userarg) { + ttype = userarg; + goto found; + } + + /* Try the environment. */ + if (ttype = getenv("TERM")) + goto map; + + /* Try ttyname(3); check for dialup or other mapping. */ + if (ttypath = ttyname(STDERR_FILENO)) { + if (p = rindex(ttypath, '/')) + ++p; + else + p = ttypath; + if ((t = getttynam(p))) { + ttype = t->ty_type; + goto map; + } + } + + /* If still undefined, use "unknown". */ + ttype = "unknown"; + +map: ttype = mapped(ttype); + + /* + * If not a path, remove TERMCAP from the environment so we get a + * real entry from /etc/termcap. This prevents us from being fooled + * by out of date stuff in the environment. + */ +found: if ((p = getenv("TERMCAP")) != NULL && *p != '/') + unsetenv("TERMCAP"); + + /* + * ttype now contains a pointer to the type of the terminal. + * If the first character is '?', ask the user. + */ + if (ttype[0] == '?') + if (ttype[1] != '\0') + ttype = askuser(ttype + 1); + else + ttype = askuser(NULL); + + /* Find the termcap entry. If it doesn't exist, ask the user. */ + while ((rval = tgetent(tbuf, ttype)) == 0) { + (void)fprintf(stderr, + "tset: terminal type %s is unknown\n", ttype); + ttype = askuser(NULL); + } + if (rval == -1) + err("termcap: %s", strerror(errno ? errno : ENOENT)); + *tcapbufp = tbuf; + return (ttype); +} + +/* Prompt the user for a terminal type. */ +char * +askuser(dflt) + char *dflt; +{ + static char answer[256]; + char *p; + + /* We can get recalled; if so, don't continue uselessly. */ + if (feof(stdin) || ferror(stdin)) { + (void)fprintf(stderr, "\n"); + exit(1); + } + for (;;) { + if (dflt) + (void)fprintf(stderr, "Terminal type? [%s] ", dflt); + else + (void)fprintf(stderr, "Terminal type? "); + (void)fflush(stderr); + + if (fgets(answer, sizeof(answer), stdin) == NULL) { + if (dflt == NULL) { + (void)fprintf(stderr, "\n"); + exit(1); + } + return (dflt); + } + + if (p = index(answer, '\n')) + *p = '\0'; + if (answer[0]) + return (answer); + if (dflt != NULL) + return (dflt); + } +} diff --git a/usr.bin/tset/tset.1 b/usr.bin/tset/tset.1 new file mode 100644 index 0000000..16b7344 --- /dev/null +++ b/usr.bin/tset/tset.1 @@ -0,0 +1,405 @@ +.\" Copyright (c) 1985, 1990, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)tset.1 8.1 (Berkeley) 6/9/93 +.\" +.Dd June 9, 1993 +.Dt TSET 1 +.Os BSD 4 +.Sh NAME +.Nm tset +.Nd terminal initialization +.Sh SYNOPSIS +.Nm tset +.Op Fl IQrSs +.Op Fl +.Op Fl e Ar ch +.Op Fl i Ar ch +.Op Fl k Ar ch +.Op Fl m Ar mapping +.Op Ar terminal +.br +.Nm reset +.Op Fl IQrSs +.Op Fl +.Op Fl e Ar ch +.Op Fl i Ar ch +.Op Fl k Ar ch +.Op Fl m Ar mapping +.Op Ar terminal +.Sh DESCRIPTION +.Nm Tset +initializes terminals. +.Nm Tset +first determines the type of terminal that you are using. +This determination is done as follows, using the first terminal type found. +.sp +.Bl -bullet -compact -offset indent +.It +The +.Ar terminal +argument specified on the command line. +.It +The value of the +.Ev TERM +environmental variable. +.It +The terminal type associated with the standard error output device in the +.Pa /etc/ttys +file. +.It +The default terminal type, ``unknown''. +.El +.Pp +If the terminal type was not specified on the command-line, the +.Fl m +option mappings are then applied (see below for more information). +Then, if the terminal type begins with a question mark (``?''), the user is +prompted for confirmation of the terminal type. +An empty response confirms the type, or, another type can be entered to +specify a new type. +Once the terminal type has been determined, the termcap entry for the terminal +is retrieved. +If no termcap entry is found for the type, the user is prompted for another +terminal type. +.Pp +Once the termcap entry is retrieved, the window size, backspace, interrupt +and line kill characters (among many other things) are set and the terminal +and tab initialization strings are sent to the standard error output. +Finally, if the erase, interrupt and line kill characters have changed, +or are not set to their default values, their values are displayed to the +standard error output. +.Pp +When invoked as +.Nm reset , +.Nm tset +sets cooked and echo modes, turns off cbreak and raw modes, turns on +newline translation and resets any unset special characters to their +default values before doing the terminal initialization described above. +This is useful after a program dies leaving a terminal in a abnormal state. +Note, you may have to type +.Dq Li <LF>reset<LF> +(the line-feed character is normally control-J) to get the terminal +to work, as carriage-return may no longer work in the abnormal state. +Also, the terminal will often not echo the command. +.Pp +The options are as follows: +.Bl -tag -width flag +.It Fl +The terminal type is displayed to the standard output, and the terminal is +not initialized in any way. +.It Fl e +Set the erase character to +.Ar ch . +.It Fl I +Do not send the terminal or tab initialization strings to the terminal. +.It Fl i +Set the interrupt character to +.Ar ch . +.It Fl k +Set the line kill character to +.Ar ch . +.It Fl m +Specify a mapping from a port type to a terminal. +See below for more information. +.It Fl Q +Don't display any values for the erase, interrupt and line kill characters. +.It Fl r +Print the terminal type to the standard error output. +.It Fl S +Print the terminal type and the termcap entry to the standard output. +See the section below on setting the environment for details. +.It Fl s +Print the sequence of shell commands to initialize the environment variables +.Ev TERM +and +.Ev TERMCAP +to the standard output. +See the section below on setting the environment for details. +.El +.Pp +The arguments for the +.Fl e , +.Fl i +and +.Fl k +options may either be entered as actual characters or by using the +.Dq hat +notation, i.e. control-h may be specified as +.Dq Li ^H +or +.Dq Li ^h . +.Sh SETTING THE ENVIRONMENT +It is often desirable to enter the terminal type and information about +the terminal's capabilities into the shell's environment. +This is done using the +.Fl S +and +.Fl s +options. +.Pp +When the +.Fl S +option is specified, the terminal type and the termcap entry are written +to the standard output, separated by a space and without a terminating +newline. +This can be assigned to an array by +.Nm csh +and +.Nm ksh +users and then used like any other shell array. +.Pp +When the +.Fl s +option is specified, the commands to enter the information into the +shell's environment are written to the standard output. +If the +.Ev SHELL +environmental variable ends in ``csh'', the commands are for the +.Nm csh , +otherwise, they are for +.Xr sh . +Note, the +.Nm csh +commands set and unset the shell variable +.Dq noglob , +leaving it unset. +The following line in the +.Pa .login +or +.Pa .profile +files will initialize the environment correctly: +.Bd -literal -offset indent +eval \`tset -s options ... \` +.Ed +.Pp +To demonstrate a simple use of the +.Fl S +option, the following lines in the +.Pa .login +file have an equivalent effect: +.Bd -literal -offset indent +set noglob +set term=(`tset -S options ...`) +setenv TERM $term[1] +setenv TERMCAP "$term[2]" +unset term +unset noglob +.Ed +.Sh TERMINAL TYPE MAPPING +When the terminal is not hardwired into the system (or the current system +information is incorrect) the terminal type derived from the +.Pa /etc/ttys +file or the +.Ev TERM +environmental variable is often something generic like +.Dq network , +.Dq dialup , +or +.Dq unknown . +When +.Nm tset +is used in a startup script +.Pf ( Pa .profile +for +.Xr sh 1 +users or +.Pa .login +for +.Xr csh 1 +users) it is often desirable to provide information about the type of +terminal used on such ports. +The purpose of the +.Fl m +option is to +.Dq map +from some set of conditions to a terminal type, that is, to +tell +.Nm tset +``If I'm on this port at a particular speed, guess that I'm on that +kind of terminal''. +.Pp +The argument to the +.Fl m +option consists of an optional port type, an optional operator, an optional +baud rate specification, an optional colon (``:'') character and a terminal +type. +The port type is a string (delimited by either the operator or the colon +character). +The operator may be any combination of: +.Dq Li \&> , +.Dq Li \&< , +.Dq Li \&@ , +and +.Dq Li \&! ; +.Dq Li \&> +means greater than, +.Dq Li \&< +means less than, +.Dq Li \&@ +means equal to +and +.Dq Li \&! +inverts the sense of the test. +The baud rate is specified as a number and is compared with the speed +of the standard error output (which should be the control terminal). +The terminal type is a string. +.Pp +If the terminal type is not specified on the command line, the +.Fl m +mappings are applied to the terminal type. +If the port type and baud rate match the mapping, the terminal type specified +in the mapping replaces the current type. +If more than one mapping is specified, the first applicable mapping is used. +.Pp +For example, consider the following mapping: +.Dq Li dialup>9600:vt100 . +The port type is +.Dq Li dialup , +the operator is +.Dq Li > , +the baud rate specification is +.Dq Li 9600 , +and the terminal type is +.Dq Li vt100 . +The result of this mapping is to specify that if the terminal type is +.Dq Li dialup , +and the baud rate is greater than 9600 baud, a terminal type of +.Dq Li vt100 +will be used. +.Pp +If no port type is specified, the terminal type will match any port type, +for example, +.Dq Li -m dialup:vt100 -m :?xterm +will cause any dialup port, regardless of baud rate, to match the terminal +type +.Dq Li vt100 , +and any non-dialup port type to match the terminal type +.Dq Li ?xterm . +Note, because of the leading question mark, the user will be +queried on a default port as to whether they are actually using an +.Ar xterm +terminal. +.Pp +No whitespace characters are permitted in the +.Fl m +option argument. +Also, to avoid problems with metacharacters, it is suggested that the entire +.Fl m +option argument be placed within single quote characters, and that +.Nm csh +users insert a backslash character (``\e'') before any exclamation +marks (``!''). +.Sh ENVIRONMENT +The +.Nm tset +command utilizes the +.Ev SHELL +and +.Ev TERM +environment variables. +.Sh FILES +.Bl -tag -width /usr/share/misc/termcap -compact +.It Pa /etc/ttys +system port name to terminal type mapping database +.It Pa /usr/share/misc/termcap +terminal capability database +.El +.Sh SEE ALSO +.Xr csh 1 , +.Xr sh 1 , +.Xr stty 1 , +.Xr tty 4 , +.Xr termcap 5 , +.Xr ttys 5 , +.Xr environ 7 +.Sh HISTORY +The +.Nm tset +command appeared in +.Bx 3.0 . +.Sh COMPATIBILITY +The +.Fl A , +.Fl E , +.Fl h , +.Fl u +and +.Fl v +options have been deleted from the +.Nm tset +utility. +None of them were documented in 4.3BSD and all are of limited utility at +best. +The +.Fl a , +.Fl d +and +.Fl p +options are similarly not documented or useful, but were retained as they +appear to be in widespread use. +It is strongly recommended that any usage of these three options be +changed to use the +.Fl m +option instead. +The +.Fl n +option remains, but has no effect. +It is still permissible to specify the +.Fl e , +.Fl i +and +.Fl k +options without arguments, although it is strongly recommended that such +usage be fixed to explicitly specify the character. +.Pp +Executing +.Nm tset +as +.Nm reset +no longer implies the +.Fl Q +option. +Also, the interaction between the +.Fl +option and the +.Ar terminal +argument in some historic implementations of +.Nm tset +has been removed. +.Pp +Finally, the +.Nm tset +implementation has been completely redone (as part of the addition to the +system of a +.St -p1003.1-88 +compliant terminal interface) and will no longer compile on systems with +older terminal interfaces. diff --git a/usr.bin/tset/tset.c b/usr.bin/tset/tset.c new file mode 100644 index 0000000..7198e96 --- /dev/null +++ b/usr.bin/tset/tset.c @@ -0,0 +1,303 @@ +/*- + * Copyright (c) 1980, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1980, 1991, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)tset.c 8.1 (Berkeley) 6/9/93"; +#endif /* not lint */ + +#include <sys/types.h> +#include <sys/ioctl.h> +#include <termios.h> +#include <errno.h> +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include "extern.h" + +void obsolete __P((char *[])); +void report __P((char *, int, u_int)); +void usage __P((void)); + +struct termios mode, oldmode; + +int erasechar; /* new erase character */ +int intrchar; /* new interrupt character */ +int isreset; /* invoked as reset */ +int killchar; /* new kill character */ +int lines, columns; /* window size */ + +int +main(argc, argv) + int argc; + char *argv[]; +{ +#ifdef TIOCGWINSZ + struct winsize win; +#endif + int ch, noinit, noset, quiet, Sflag, sflag, showterm, usingupper; + char savech, *p, *t, *tcapbuf, *ttype; + + if (tcgetattr(STDERR_FILENO, &mode) < 0) + err("standard error: %s", strerror(errno)); + + oldmode = mode; + ospeed = cfgetospeed(&mode); + + if (p = strrchr(*argv, '/')) + ++p; + else + p = *argv; + usingupper = isupper(*p); + if (!strcasecmp(p, "reset")) { + isreset = 1; + reset_mode(); + } + + obsolete(argv); + noinit = noset = quiet = Sflag = sflag = showterm = 0; + while ((ch = getopt(argc, argv, "-a:d:e:Ii:k:m:np:QSrs")) != EOF) { + switch (ch) { + case '-': /* display term only */ + noset = 1; + break; + case 'a': /* OBSOLETE: map identifier to type */ + add_mapping("arpanet", optarg); + break; + case 'd': /* OBSOLETE: map identifier to type */ + add_mapping("dialup", optarg); + break; + case 'e': /* erase character */ + erasechar = optarg[0] == '^' && optarg[1] != '\0' ? + optarg[1] == '?' ? '\177' : CTRL(optarg[1]) : + optarg[0]; + break; + case 'I': /* no initialization strings */ + noinit = 1; + break; + case 'i': /* interrupt character */ + intrchar = optarg[0] == '^' && optarg[1] != '\0' ? + optarg[1] == '?' ? '\177' : CTRL(optarg[1]) : + optarg[0]; + break; + case 'k': /* kill character */ + killchar = optarg[0] == '^' && optarg[1] != '\0' ? + optarg[1] == '?' ? '\177' : CTRL(optarg[1]) : + optarg[0]; + break; + case 'm': /* map identifier to type */ + add_mapping(NULL, optarg); + break; + case 'n': /* OBSOLETE: set new tty driver */ + break; + case 'p': /* OBSOLETE: map identifier to type */ + add_mapping("plugboard", optarg); + break; + case 'Q': /* don't output control key settings */ + quiet = 1; + break; + case 'S': /* output TERM/TERMCAP strings */ + Sflag = 1; + break; + case 'r': /* display term on stderr */ + showterm = 1; + break; + case 's': /* output TERM/TERMCAP strings */ + sflag = 1; + break; + case '?': + default: + usage(); + } + } + argc -= optind; + argv += optind; + + if (argc > 1) + usage(); + + ttype = get_termcap_entry(*argv, &tcapbuf); + + if (!noset) { + columns = tgetnum("co"); + lines = tgetnum("li"); + +#ifdef TIOCGWINSZ + /* Set window size */ + (void)ioctl(STDERR_FILENO, TIOCGWINSZ, &win); + if (win.ws_row == 0 && win.ws_col == 0 && + lines > 0 && columns > 0) { + win.ws_row = lines; + win.ws_col = columns; + (void)ioctl(STDERR_FILENO, TIOCSWINSZ, &win); + } +#endif + set_control_chars(); + set_conversions(usingupper); + + if (!noinit) + set_init(); + + /* Set the modes if they've changed. */ + if (memcmp(&mode, &oldmode, sizeof(mode))) + tcsetattr(STDERR_FILENO, TCSADRAIN, &mode); + } + + /* Get the terminal name from the entry. */ + p = tcapbuf; + if (p != NULL && *p != ':') { + t = p; + if (p = strpbrk(p, "|:")) { + savech = *p; + *p = '\0'; + if ((ttype = strdup(t)) == NULL) + err("%s", strerror(errno)); + *p = savech; + } + } + + if (noset) + (void)printf("%s\n", ttype); + else { + if (showterm) + (void)fprintf(stderr, "Terminal type is %s.\n", ttype); + /* + * If erase, kill and interrupt characters could have been + * modified and not -Q, display the changes. + */ + if (!quiet) { + report("Erase", VERASE, CERASE); + report("Kill", VKILL, CKILL); + report("Interrupt", VINTR, CINTR); + } + } + + if (Sflag) { + (void)printf("%s ", ttype); + wrtermcap(tcapbuf); + } + + if (sflag) { + /* + * Figure out what shell we're using. A hack, we look for an + * environmental variable SHELL ending in "csh". + */ + if ((p = getenv("SHELL")) && + !strcmp(p + strlen(p) - 3, "csh")) { + p = "set noglob;\nsetenv TERM %s;\nsetenv TERMCAP '"; + t = "';\nunset noglob;\n"; + } else { + p = "TERM=%s;\nTERMCAP='"; + t = "';\nexport TERMCAP TERM;\n"; + } + (void)printf(p, ttype); + wrtermcap(tcapbuf); + (void)printf(t); + } + + exit(0); +} + +/* + * Tell the user if a control key has been changed from the default value. + */ +void +report(name, which, def) + char *name; + int which; + u_int def; +{ + u_int old, new; + char *bp, buf[1024]; + + new = mode.c_cc[which]; + old = oldmode.c_cc[which]; + + if (old == new && old == def) + return; + + (void)fprintf(stderr, "%s %s ", name, old == new ? "is" : "set to"); + + bp = buf; + if (tgetstr("kb", &bp) && new == buf[0] && buf[1] == '\0') + (void)fprintf(stderr, "backspace.\n"); + else if (new == 0177) + (void)fprintf(stderr, "delete.\n"); + else if (new < 040) { + new ^= 0100; + (void)fprintf(stderr, "control-%c (^%c).\n", new, new); + } else + (void)fprintf(stderr, "%c.\n", new); +} + +/* + * Convert the obsolete argument form into something that getopt can handle. + * This means that -e, -i and -k get default arguments supplied for them. + */ +void +obsolete(argv) + char *argv[]; +{ + for (; *argv; ++argv) { + if (argv[0][0] != '-' || argv[1] && argv[1][0] != '-' || + argv[0][1] != 'e' && argv[0][1] != 'i' && + argv[0][1] != 'k' || argv[0][2] != '\0') + continue; + switch(argv[0][1]) { + case 'e': + argv[0] = "-e^H"; + break; + case 'i': + argv[0] = "-i^C"; + break; + case 'k': + argv[0] = "-k^U"; + break; + } + } +} + +void +usage() +{ + (void)fprintf(stderr, +"usage: tset [-IQrSs] [-] [-e ch] [-i ch] [-k ch] [-m mapping] [terminal]\n"); + exit(1); +} diff --git a/usr.bin/tset/wrterm.c b/usr.bin/tset/wrterm.c new file mode 100644 index 0000000..5c33b49 --- /dev/null +++ b/usr.bin/tset/wrterm.c @@ -0,0 +1,112 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)wrterm.c 8.1 (Berkeley) 6/9/93"; +#endif /* not lint */ + +#include <sys/types.h> +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include "extern.h" + +/* + * Output termcap entry to stdout, quoting characters that would give the + * shell problems and omitting empty fields. + */ +void +wrtermcap(bp) + char *bp; +{ + register int ch; + register char *p; + char *t, *sep; + + /* Find the end of the terminal names. */ + if ((t = index(bp, ':')) == NULL) + err("termcap names not colon terminated"); + *t++ = '\0'; + + /* Output terminal names that don't have whitespace. */ + sep = ""; + while ((p = strsep(&bp, "|")) != NULL) + if (*p != '\0' && strpbrk(p, " \t") == NULL) { + (void)printf("%s%s", sep, p); + sep = "|"; + } + (void)putchar(':'); + + /* + * Output fields, transforming any dangerous characters. Skip + * empty fields or fields containing only whitespace. + */ + while ((p = strsep(&t, ":")) != NULL) { + while ((ch = *p) != '\0' && isspace(ch)) + ++p; + if (ch == '\0') + continue; + while ((ch = *p++) != '\0') + switch(ch) { + case '\033': + (void)printf("\\E"); + case ' ': /* No spaces. */ + (void)printf("\\040"); + break; + case '!': /* No csh history chars. */ + (void)printf("\\041"); + break; + case ',': /* No csh history chars. */ + (void)printf("\\054"); + break; + case '"': /* No quotes. */ + (void)printf("\\042"); + break; + case '\'': /* No quotes. */ + (void)printf("\\047"); + break; + case '`': /* No quotes. */ + (void)printf("\\140"); + break; + case '\\': /* Anything following is OK. */ + case '^': + (void)putchar(ch); + if ((ch = *p++) == '\0') + break; + /* FALLTHROUGH */ + default: + (void)putchar(ch); + } + (void)putchar(':'); + } +} |