From 37be61c23fb9a84e57c7603051199874d9678247 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Mon, 16 Nov 1998 03:08:42 +0000 Subject: ncurses tset plus hacks to make $TERMCAP still get set --- usr.bin/tset/Makefile | 18 +- usr.bin/tset/extern.h | 62 --- usr.bin/tset/map.c | 237 --------- usr.bin/tset/misc.c | 76 --- usr.bin/tset/set.c | 327 ------------- usr.bin/tset/term.c | 158 ------ usr.bin/tset/termcap.c | 218 +++++++++ usr.bin/tset/tset.1 | 58 ++- usr.bin/tset/tset.c | 1256 ++++++++++++++++++++++++++++++++++++++++++------ usr.bin/tset/wrterm.c | 118 ----- 10 files changed, 1376 insertions(+), 1152 deletions(-) delete mode 100644 usr.bin/tset/extern.h delete mode 100644 usr.bin/tset/map.c delete mode 100644 usr.bin/tset/misc.c delete mode 100644 usr.bin/tset/set.c delete mode 100644 usr.bin/tset/term.c create mode 100644 usr.bin/tset/termcap.c delete mode 100644 usr.bin/tset/wrterm.c (limited to 'usr.bin') diff --git a/usr.bin/tset/Makefile b/usr.bin/tset/Makefile index 4529cd029e3..e8264bb66af 100644 --- a/usr.bin/tset/Makefile +++ b/usr.bin/tset/Makefile @@ -1,11 +1,19 @@ -# $OpenBSD: Makefile,v 1.5 1998/07/25 19:27:37 millert Exp $ +# $OpenBSD: Makefile,v 1.6 1998/11/16 03:08:40 millert Exp $ PROG= tset -SRCS= map.c misc.c set.c term.c tset.c wrterm.c - -DPADD= ${LIBOLDCURSES} -LDADD= -locurses +SRCS= tset.c dump_entry.c termcap.c +DPADD= ${LIBCURSES} +LDADD= -lcurses +CURSES= ${.CURDIR}/../../lib/libcurses +TIC= ${.CURDIR}/../tic +CFLAGS+= -I${CURSES} -I${TIC} -I${.CURDIR} -I. +.PATH: ${TIC} LINKS= ${BINDIR}/tset ${BINDIR}/reset MLINKS= tset.1 reset.1 +beforedepend: termsort.c + +termsort.c: ${TIC}/MKtermsort.sh + sh ${TIC}/MKtermsort.sh awk ${CURSES}/Caps > ${.TARGET} + .include diff --git a/usr.bin/tset/extern.h b/usr.bin/tset/extern.h deleted file mode 100644 index d3509a11465..00000000000 --- a/usr.bin/tset/extern.h +++ /dev/null @@ -1,62 +0,0 @@ -/* $OpenBSD: extern.h,v 1.3 1997/07/25 22:13:23 mickey Exp $ */ -/* $NetBSD: extern.h,v 1.3 1994/12/07 05:08:06 jtc Exp $ */ - -/*- - * 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 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 *)); -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 deleted file mode 100644 index 9e7c6b3d1f4..00000000000 --- a/usr.bin/tset/map.c +++ /dev/null @@ -1,237 +0,0 @@ -/* $OpenBSD: map.c,v 1.4 1997/07/25 22:13:23 mickey Exp $ */ -/* $NetBSD: map.c,v 1.4 1994/12/07 05:08:07 jtc Exp $ */ - -/*- - * 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 -#if 0 -static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/9/93"; -#endif -static char rcsid[] = "$OpenBSD: map.c,v 1.4 1997/07/25 22:13:23 mickey Exp $"; -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include -#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(1, "malloc"); - 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 = strchr(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: errx(1, "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); -} - -int -baudrate(rate) - char *rate; -{ - - /* The baudrate number can be preceded by a 'B', which is ignored. */ - if (*rate == 'B') - ++rate; - - return (atoi(rate)); -} diff --git a/usr.bin/tset/misc.c b/usr.bin/tset/misc.c deleted file mode 100644 index 64c936531c1..00000000000 --- a/usr.bin/tset/misc.c +++ /dev/null @@ -1,76 +0,0 @@ -/* $OpenBSD: misc.c,v 1.4 1997/07/25 22:13:24 mickey Exp $ */ -/* $NetBSD: misc.c,v 1.3 1994/12/07 05:08:09 jtc Exp $ */ - -/*- - * 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 -#if 0 -static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 6/9/93"; -#endif -static char rcsid[] = "$OpenBSD: misc.c,v 1.4 1997/07/25 22:13:24 mickey Exp $"; -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include -#include -#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(1, file); - - while ((nr = read(fd, buf, sizeof(buf))) > 0) - if ((nw = write(STDERR_FILENO, buf, nr)) == -1) - err(1, "write to stderr"); - if (nr != 0) - err(1, file); - (void)close(fd); -} - -void -outc(c) - int c; -{ - (void)putc(c, stderr); -} diff --git a/usr.bin/tset/set.c b/usr.bin/tset/set.c deleted file mode 100644 index ffad7e96fb4..00000000000 --- a/usr.bin/tset/set.c +++ /dev/null @@ -1,327 +0,0 @@ -/* $OpenBSD: set.c,v 1.3 1998/04/25 04:30:37 millert Exp $ */ -/* $NetBSD: set.c,v 1.6 1994/12/07 05:08:10 jtc Exp $ */ - -/*- - * 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 -#if 0 -static char sccsid[] = "@(#)set.c 8.2 (Berkeley) 2/28/94"; -#endif -static char rcsid[] = "$OpenBSD: set.c,v 1.3 1998/04/25 04:30:37 millert Exp $"; -#endif /* not lint */ - -#include -#include -#include -#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); - 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)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); - } - (void)putc('\r', stderr); - return (1); - } - return (0); -} diff --git a/usr.bin/tset/term.c b/usr.bin/tset/term.c deleted file mode 100644 index 4b500a91594..00000000000 --- a/usr.bin/tset/term.c +++ /dev/null @@ -1,158 +0,0 @@ -/* $OpenBSD: term.c,v 1.6 1998/10/16 18:51:21 millert Exp $ */ -/* $NetBSD: term.c,v 1.6 1994/12/07 05:08:12 jtc Exp $ */ - -/*- - * 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 -#if 0 -static char sccsid[] = "@(#)term.c 8.1 (Berkeley) 6/9/93"; -#endif -static char rcsid[] = "$OpenBSD: term.c,v 1.6 1998/10/16 18:51:21 millert Exp $"; -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include -#include -#include -#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 = strrchr(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) { - warnx("terminal type %s is unknown", ttype); - ttype = askuser(NULL); - } - if (rval == -1) - warnx("termcap: %s", strerror(errno ? errno : ENOENT)); - *tcapbufp = *tbuf ? tbuf : NULL; - 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)) - exit(1); - for (;;) { - if (dflt) - (void)fprintf(stderr, "Terminal type? [%s] ", dflt); - else - (void)fprintf(stderr, "Terminal type? "); - - if (fgets(answer, sizeof(answer), stdin) == NULL) { - if (dflt == NULL) { - (void)putc('\n', stderr); - exit(1); - } - return (dflt); - } - - if (p = strchr(answer, '\n')) - *p = '\0'; - if (answer[0]) - return (answer); - if (dflt != NULL) - return (dflt); - } -} diff --git a/usr.bin/tset/termcap.c b/usr.bin/tset/termcap.c new file mode 100644 index 00000000000..e75ec91afd7 --- /dev/null +++ b/usr.bin/tset/termcap.c @@ -0,0 +1,218 @@ +/* $OpenBSD: termcap.c,v 1.1 1998/11/16 03:08:41 millert Exp $ */ +/* $NetBSD: termcap.c,v 1.7 1995/06/05 19:45:52 pk Exp $ */ + +/* + * 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 rcsid[] = "$OpenBSD: termcap.c,v 1.1 1998/11/16 03:08:41 millert Exp $"; +#endif /* not lint */ + +#define PVECSIZ 32 /* max number of names in path */ +#define _PATH_DEF ".termcap /usr/share/misc/termcap" + +#include +#include +#include +#include +#include +#include +#include + +/* + * Get an entry for terminal name in buffer bp from the termcap file. + */ +int +tcgetent(bp, name) + char *bp; + const char *name; +{ + char *p; + char *cp; + char *dummy; + char **fname; + char *home; + int i; + char pathbuf[MAXPATHLEN]; /* holds raw path of filenames */ + char *pathvec[PVECSIZ]; /* to point to names in pathbuf */ + char **pvec; /* holds usable tail of path vector */ + char *termpath; + char *ttype; + + fname = pathvec; + pvec = pathvec; + + if (!issetugid()) { + cp = getenv("TERMCAP"); + /* + * TERMCAP can have one of two things in it. It can be the name + * of a file to use instead of /usr/share/misc/termcap. In this + * case it better start with a "/". Or it can be an entry to + * use so we don't have to read the file. In this case it + * has to already have the newlines crunched out. If TERMCAP + * does not hold a file name then a path of names is searched + * instead. The path is found in the TERMPATH variable, or + * becomes "$HOME/.termcap /usr/share/misc/termcap" if no + * TERMPATH exists. + */ + if (!cp || *cp != '/') { /* no TERMCAP or it holds an entry */ + if ((termpath = getenv("TERMPATH")) != NULL) + strlcpy(pathbuf, termpath, sizeof(pathbuf)); + else { + if ((home = getenv("HOME")) != NULL && + strlen(home) + sizeof(_PATH_DEF) < + sizeof(pathbuf)) { + sprintf(pathbuf, "%s/%s", home, + _PATH_DEF); + } else { + strlcpy(pathbuf, _PATH_DEF, + sizeof(pathbuf)); + } + } + } else { /* user-defined path in TERMCAP */ + /* still can be tokenized */ + strlcpy(pathbuf, cp, sizeof(pathbuf)); + } + *fname++ = pathbuf; /* tokenize path into vector of names */ + } + + /* split pathbuf into a vector of paths */ + p = pathbuf; + while (*++p) + if (*p == ' ' || *p == ':') { + *p = '\0'; + while (*++p) + if (*p != ' ' && *p != ':') + break; + if (*p == '\0') + break; + *fname++ = p; + if (fname >= pathvec + PVECSIZ) { + fname--; + break; + } + } + *fname = (char *) 0; /* mark end of vector */ + if (cp && *cp && *cp != '/') + if (cgetset(cp) < 0) + return (-2); + + dummy = NULL; + i = cgetent(&dummy, pathvec, (char *)name); + + if (i == 0 && bp != NULL) { + strlcpy(bp, dummy, 1024); + if ((cp = strrchr(bp, ':')) != NULL) + if (cp[1] != '\0') + cp[1] = '\0'; + } + else if (i == 0 && bp == NULL) + bp = dummy; + else if (dummy != NULL) + free(dummy); + + /* no tc reference loop return code in libterm XXX */ + if (i == -3) + return (-1); + return (i + 1); +} + +/* + * Output termcap entry to stdout, quoting characters that would give the + * shell problems and omitting empty fields. + */ +void +wrtermcap(bp) + char *bp; +{ + int ch; + char *p; + char *t, *sep; + + /* Find the end of the terminal names. */ + if ((t = strchr(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(':'); + } +} diff --git a/usr.bin/tset/tset.1 b/usr.bin/tset/tset.1 index d00e293a5bd..555f20980c4 100644 --- a/usr.bin/tset/tset.1 +++ b/usr.bin/tset/tset.1 @@ -1,5 +1,4 @@ -.\" $OpenBSD: tset.1,v 1.5 1998/10/30 00:24:40 aaron Exp $ -.\" $NetBSD: tset.1,v 1.4.2.1 1995/12/05 02:53:34 jtc Exp $ +.\" $OpenBSD: tset.1,v 1.6 1998/11/16 03:08:41 millert Exp $ .\" .\" Copyright (c) 1985, 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -34,15 +33,15 @@ .\" .\" @(#)tset.1 8.1 (Berkeley) 6/9/93 .\" -.Dd June 9, 1993 +.Dd November 15, 1998 .Dt TSET 1 -.Os BSD 4 +.Os .Sh NAME .Nm tset .Nd terminal initialization .Sh SYNOPSIS .Nm tset -.Op Fl IQrSs +.Op Fl IQqrSs .Op Fl .Op Fl e Ar ch .Op Fl i Ar ch @@ -51,7 +50,7 @@ .Op Ar terminal .br .Nm reset -.Op Fl IQrSs +.Op Fl IQqrSs .Op Fl .Op Fl e Ar ch .Op Fl i Ar ch @@ -64,8 +63,7 @@ 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 +.Bl -enum -offset indent .It The .Ar terminal @@ -79,7 +77,8 @@ The terminal type associated with the standard error output device in the .Pa /etc/ttys file. .It -The default terminal type, ``unknown''. +The default terminal type, +.Dq unknown . .El .Pp If the terminal type was not specified on the command-line, the @@ -118,7 +117,10 @@ 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. +not initialized in any way. This option has been deprecated in favor of +the +.Fl q +flag. .It Fl e Ar ch Set the erase character to .Ar ch . @@ -135,6 +137,9 @@ 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 q +The terminal type is displayed to the standard output, and the terminal is +not initialized in any way. .It Fl r Print the terminal type to the standard error output. .It Fl S @@ -186,7 +191,9 @@ option is specified, the commands to enter the information into the shell's environment are written to the standard output. If the .Ev SHELL -environment variable ends in ``csh'', the commands are for +environment variable ends in +.Dq csh , +the commands are for .Xr csh 1 , otherwise, they are for .Xr sh 1 . @@ -240,6 +247,7 @@ for .Xr csh 1 users) it is often desirable to provide information about the type of terminal used on such ports. +.Pp The purpose of the .Fl m option is to @@ -351,6 +359,34 @@ command appeared in .Bx 3.0 . .Sh COMPATIBILITY The +.Nm tset +command now uses the +.Xr terminfo 5 +database where previous versions used +.Xr termcap 5 . +To make the +.Fl s +and +.Fl S +options still work, +.Nm tset +also reads in the terminal entry from +.Xr termcap 5 . +However, this info is used for setting +.Ev TERMCAP +only. If the terminal type appears in +.Xr terminfo 5 +but not in +.Xr termcap 5 , +the +.Fl q +option will not set +.Ev TERMCAP +and the +.Fl Q +option will not work at all. +.Pp +The .Fl A , .Fl E , .Fl h , diff --git a/usr.bin/tset/tset.c b/usr.bin/tset/tset.c index 672c437f50f..7381d6223ec 100644 --- a/usr.bin/tset/tset.c +++ b/usr.bin/tset/tset.c @@ -1,6 +1,45 @@ -/* $OpenBSD: tset.c,v 1.6 1998/10/16 18:51:21 millert Exp $ */ -/* $NetBSD: tset.c,v 1.4 1994/12/07 05:08:15 jtc Exp $ */ +/**************************************************************************** + * Copyright (c) 1998 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ +/**************************************************************************** + * Author: Zeyd M. Ben-Halim 1992,1995 * + * and: Eric S. Raymond * + ****************************************************************************/ + + +/* + * tset.c - terminal initialization utility + * + * This code was mostly swiped from 4.4BSD tset, with some obsolescent + * cruft removed and substantial portions rewritten. A Regents of the + * University of California copyright applies to some portions of the + * code, and is reproduced below: + */ /*- * Copyright (c) 1980, 1991, 1993 * The Regents of the University of California. All rights reserved. @@ -34,75 +73,1023 @@ * 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 */ +#define __INTERNAL_CAPS_VISIBLE /* we need to see has_hardware_tabs */ +#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)tset.c 8.1 (Berkeley) 6/9/93"; -#endif -static char rcsid[] = "$OpenBSD: tset.c,v 1.6 1998/10/16 18:51:21 millert Exp $"; -#endif /* not lint */ - -#include -#include -#include #include -#include -#include #include -#include -#include -#include -#include "extern.h" +#include +#include + +#if HAVE_GETTTYNAM && HAVE_TTYENT_H +#include +#endif +#ifdef NeXT +char *ttyname(int fd); +#endif + +/* this is just to stifle a missing-prototype warning */ +#ifdef linux +# include +#endif + +#if NEED_PTEM_H +/* they neglected to define struct winsize in termios.h -- it's only + in termio.h */ +#include +#include +#endif + +#include /* for bool typedef */ +#include + +MODULE_ID("$Id: tset.c,v 1.7 1998/11/16 03:08:41 millert Exp $") + +extern char **environ; + +#undef CTRL +#define CTRL(x) ((x) & 0x1f) + +const char *_nc_progname = "tset"; + +static TTY mode, oldmode; + +static int terasechar = -1; /* new erase character */ +static int intrchar = -1; /* new interrupt character */ +static int isreset; /* invoked as reset */ +static int tkillchar = -1; /* new kill character */ +static int tlines, tcolumns; /* window size */ + +#define LOWERCASE(c) ((isalpha(c) && isupper(c)) ? tolower(c) : (c)) + +static int +CaselessCmp(const char *a, const char *b) /* strcasecmp isn't portable */ +{ + while (*a && *b) { + int cmp = LOWERCASE(*a) - LOWERCASE(*b); + if (cmp != 0) + break; + a++, b++; + } + return LOWERCASE(*a) - LOWERCASE(*b); +} + +#if !HAVE_STRDUP +static char *strdup (char *s) +{ + char *p; + + p = malloc(strlen(s)+1); + if (p) + strcpy(p,s); + return(p); +} +#endif /* not HAVE_STRDUP */ + +static void +err(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + (void)fprintf(stderr, "tset: "); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + (void)fprintf(stderr, "\n"); + exit(EXIT_FAILURE); + /* NOTREACHED */ +} + +static void +failed(const char *msg) +{ + char temp[BUFSIZ]; + perror(strcat(strcpy(temp, "tset: "), msg)); + exit(EXIT_FAILURE); + /* NOTREACHED */ +} + +static void +cat(char *file) +{ + register int fd, nr, nw; + char buf[BUFSIZ]; + + if ((fd = open(file, O_RDONLY, 0)) < 0) + failed(file); + + while ((nr = read(fd, buf, sizeof(buf))) > 0) + if ((nw = write(STDERR_FILENO, buf, (size_t)nr)) == -1) + failed("write to stderr"); + if (nr != 0) + failed(file); + (void)close(fd); +} + +static int +outc(int c) +{ + return putc(c, stderr); +} + +/* Prompt the user for a terminal type. */ +static const char * +askuser(const 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(EXIT_FAILURE); + } + 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) == 0) { + if (dflt == 0) { + (void)fprintf(stderr, "\n"); + exit(EXIT_FAILURE); + } + return (dflt); + } + + if ((p = strchr(answer, '\n')) != 0) + *p = '\0'; + if (answer[0]) + return (answer); + if (dflt != 0) + return (dflt); + } +} + +/************************************************************************** + * + * Mapping logic begins here + * + **************************************************************************/ + +/* 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. */ + const char *porttype; /* Port type, or "" for any. */ + const char *type; /* Terminal type to select. */ + int conditional; /* Baud rate conditionals bitmask. */ + speed_t speed; /* Baud rate to compare against. */ +} MAP; + +static MAP *cur, *maplist; + +typedef struct speeds { + const char *string; + int speed; +} SPEEDS; + +static const 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 }, + { "19200", B19200 }, + { "38400", B38400 }, +#ifdef B19200 + { "19200", B19200 }, +#else +#ifdef EXTA + { "19200", EXTA }, +#endif +#endif +#ifdef B38400 + { "38400", B38400 }, +#else +#ifdef EXTB + { "38400", EXTB }, +#endif +#endif +#ifdef B57600 + { "57600", B57600 }, +#endif +#ifdef B115200 + { "115200", B115200 }, +#endif +#ifdef B230400 + { "230400", B230400 }, +#endif +#ifdef B460800 + { "460800", B460800 }, +#endif + { (char *)0, 0 } +}; + +static int +tbaudrate(char *rate) +{ + const SPEEDS *sp; + int found = FALSE; + + /* The baudrate number can be preceded by a 'B', which is ignored. */ + if (*rate == 'B') + ++rate; + + for (sp = speeds; sp->string; ++sp) { + if (!CaselessCmp(rate, sp->string)) { + found = TRUE; + break; + } + } + if (!found) + err("unknown baud rate %s", rate); + return (sp->speed); +} + +/* + * Syntax for -m: + * [port-type][test baudrate]:terminal-type + * The baud rate tests are: >, <, @, =, ! + */ +static void +add_mapping(const char *port, char *arg) +{ + MAP *mapp; + char *copy, *p; + const char *termp; + char *base = 0; + + copy = strdup(arg); + mapp = malloc((u_int)sizeof(MAP)); + if (copy == 0 || mapp == 0) + failed("malloc"); + mapp->next = 0; + if (maplist == 0) + cur = maplist = mapp; + else { + cur->next = mapp; + cur = mapp; + } + + mapp->porttype = arg; + mapp->conditional = 0; -void obsolete __P((char *[])); -void report __P((char *, int, u_int)); -void usage __P((void)); + arg = strpbrk(arg, "><@=!:"); -struct termios mode, oldmode; + if (arg == 0) { /* [?]term */ + mapp->type = mapp->porttype; + mapp->porttype = 0; + goto done; + } + + if (arg == mapp->porttype) /* [><@=! baud]:term */ + termp = mapp->porttype = 0; + else + termp = base = 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 = strchr(p = arg, ':'); + if (arg == 0) + goto badmopt; + *arg++ = '\0'; + mapp->speed = tbaudrate(p); + } + + if (arg == (char *)0) /* Non-optional type. */ + goto badmopt; + + mapp->type = arg; + + /* Terminate porttype, if specified. */ + if (termp != 0) + *base = '\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'. + */ +static const char * +mapped(const char *type) +{ + MAP *mapp; + int match; + + for (mapp = maplist; mapp; mapp = mapp->next) + if (mapp->porttype == 0 || !strcmp(mapp->porttype, type)) { + switch (mapp->conditional) { + case 0: /* No test specified. */ + match = TRUE; + 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; + default: + match = FALSE; + } + if (match) + return (mapp->type); + } + /* No match found; return given type. */ + return (type); +} + +/************************************************************************** + * + * Entry fetching + * + **************************************************************************/ + +/* + * Figure out what kind of terminal we're dealing with, and then read in + * its termcap entry. + */ +static const char * +get_termcap_entry(char *userarg) +{ + int rval, errret; + char *p; + const char *ttype; +#if HAVE_GETTTYNAM + struct ttyent *t; +#else + FILE *fp; +#endif + char *ttypath; + + if (userarg) { + ttype = userarg; + goto found; + } + + /* Try the environment. */ + if ((ttype = getenv("TERM")) != 0) + goto map; + + if ((ttypath = ttyname(STDERR_FILENO)) != 0) { + if ((p = strrchr(ttypath, '/')) != 0) + ++p; + else + p = ttypath; +#if HAVE_GETTTYNAM + /* + * We have the 4.3BSD library call getttynam(3); that means + * there's an /etc/ttys to look up device-to-type mappings in. + * Try ttyname(3); check for dialup or other mapping. + */ + if ((t = getttynam(p))) { + ttype = t->ty_type; + goto map; + } +#else + if ((fp = fopen("/etc/ttytype", "r")) != 0 + || (fp = fopen("/etc/ttys", "r")) != 0) { + char buffer[BUFSIZ]; + char *s, *t, *d; + + while (fgets(buffer, sizeof(buffer)-1, fp) != 0) { + for (s = buffer, t = d = 0; *s; s++) { + if (isspace(*s)) + *s = '\0'; + else if (t == 0) + t = s; + else if (d == 0 && s != buffer && s[-1] == '\0') + d = s; + } + if (t != 0 && d != 0 && !strcmp(d,p)) { + ttype = strdup(t); + fclose(fp); + goto map; + } + } + fclose(fp); + } +#endif /* HAVE_GETTTYNAM */ + } + + /* 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")) != 0 && *p != '/') { + /* 'unsetenv("TERMCAP")' is not portable. + * The 'environ' array is better. + */ + int n; + for (n = 0; environ[n] != 0; n++) { + if (!strncmp("TERMCAP=", environ[n], 8)) { + while ((environ[n] = environ[n+1]) != 0) { + n++; + } + break; + } + } + } + + /* + * 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(0); + } + /* Find the terminfo entry. If it doesn't exist, ask the user. */ + while ((rval = setupterm(ttype, STDOUT_FILENO, &errret)) != OK) { + if (errret == 0) { + (void)fprintf(stderr, "tset: unknown terminal type %s\n", + ttype); + ttype = 0; + } + else { + (void)fprintf(stderr, "tset: can't initialize terminal\ + type %s (error %d)\n", ttype, errret); + ttype = 0; + } + ttype = askuser(ttype); + } +#if BROKEN_LINKER + tgetflag("am"); /* force lib_termcap.o to be linked for 'ospeed' */ +#endif + return (ttype); +} + +/************************************************************************** + * + * Mode-setting logic + * + **************************************************************************/ + +/* some BSD systems have these built in, some systems are missing + * one or more definitions. The safest solution is to override. + */ +#undef CEOF +#undef CERASE +#undef CINTR +#undef CKILL +#undef CLNEXT +#undef CRPRNT +#undef CQUIT +#undef CSTART +#undef CSTOP +#undef CSUSP + +/* control-character defaults */ +#define CEOF CTRL('D') +#define CERASE CTRL('H') +#define CINTR 127 /* ^? */ +#define CKILL CTRL('U') +#define CLNEXT CTRL('v') +#define CRPRNT CTRL('r') +#define CQUIT CTRL('\\') +#define CSTART CTRL('Q') +#define CSTOP CTRL('S') +#define CSUSP CTRL('Z') + +#define CHK(val, dft) ((int)val <= 0 ? dft : val) + +static bool set_tabs (void); + +/* + * Reset the terminal mode bits to a sensible state. Very useful after + * a child program dies in raw mode. + */ +static void +reset_mode(void) +{ +#ifdef TERMIOS + tcgetattr(STDERR_FILENO, &mode); +#else + stty(STDERR_FILENO,&mode); +#endif -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 */ +#ifdef TERMIOS +#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 +#if defined(VSTART) && defined(CSTART) + mode.c_cc[VSTART] = CHK(mode.c_cc[VSTART], CSTART); +#endif +#if defined(VSTOP) && defined(CSTOP) + mode.c_cc[VSTOP] = CHK(mode.c_cc[VSTOP], CSTOP); +#endif +#if defined(VSUSP) && defined(CSUSP) + mode.c_cc[VSUSP] = CHK(mode.c_cc[VSUSP], CSUSP); +#endif +#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 +#ifdef TOSTOP + | TOSTOP +#endif +#ifdef ECHOPTR + | ECHOPRT +#endif +#ifdef XCASE + | XCASE +#endif + ); + + mode.c_lflag |= (ISIG | ICANON | ECHO | ECHOE | ECHOK +#ifdef ECHOCTL + | ECHOCTL +#endif +#ifdef ECHOKE + | ECHOKE +#endif + ); +#endif + +#ifdef TERMIOS + tcsetattr(STDERR_FILENO, TCSADRAIN, &mode); +#else + stty(STDERR_FILENO, &mode); +#endif +} + +/* + * Returns a "good" value for the erase character. This is loosely based on + * the BSD4.4 logic. + */ +static int +default_erase(void) +{ + int result; + + if (over_strike + && key_backspace != 0 + && strlen(key_backspace) == 1) + result = key_backspace[0]; + else + result = CERASE; + + return result; +} + +/* + * Update the values of the erase, interrupt, and kill characters in 'mode'. + * + * SVr4 tset (e.g., Solaris 2.5) only modifies the intr, quit or erase + * characters if they're unset, or if we specify them as options. This differs + * from BSD 4.4 tset, which always sets erase. + */ +static void +set_control_chars(void) +{ +#ifdef TERMIOS + if (mode.c_cc[VERASE] == 0 || terasechar >= 0) + mode.c_cc[VERASE] = terasechar >= 0 ? terasechar : default_erase(); + + if (mode.c_cc[VINTR] == 0 || intrchar >= 0) + mode.c_cc[VINTR] = intrchar >= 0 ? intrchar : CINTR; + + if (mode.c_cc[VKILL] == 0 || tkillchar >= 0) + mode.c_cc[VKILL] = tkillchar >= 0 ? tkillchar : CKILL; +#endif +} + +/* + * 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. + */ +static void +set_conversions(void) +{ +#ifdef __OBSOLETE__ + /* + * Conversion logic for some *really* ancient terminal glitches, + * not supported in terminfo. Left here for succeeding generations + * to marvel at. + */ + if (tgetflag("UC")) { +#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; + } +#endif /* __OBSOLETE__ */ + +#ifdef TERMIOS +#ifdef ONLCR + mode.c_oflag |= ONLCR; +#endif + mode.c_iflag |= ICRNL; + mode.c_lflag |= ECHO; +#ifdef OXTABS + mode.c_oflag |= OXTABS; +#endif /* OXTABS */ + + /* test used to be tgetflag("NL") */ + if (newline != (char *)0 && newline[0] == '\n' && !newline[1]) { + /* Newline, not linefeed. */ +#ifdef ONLCR + mode.c_oflag &= ~ONLCR; +#endif + mode.c_iflag &= ~ICRNL; + } +#ifdef __OBSOLETE__ + if (tgetflag("HD")) /* Half duplex. */ + mode.c_lflag &= ~ECHO; +#endif /* __OBSOLETE__ */ +#ifdef OXTABS + /* test used to be tgetflag("pt") */ + if (has_hardware_tabs) /* Print tabs. */ + mode.c_oflag &= ~OXTABS; +#endif /* OXTABS */ + mode.c_lflag |= (ECHOE | ECHOK); +#endif +} + +/* Output startup string. */ +static void +set_init(void) +{ + char *p; + bool settle; + +#ifdef __OBSOLETE__ + if (pad_char != (char *)0) /* Get/set pad character. */ + PC = pad_char[0]; +#endif /* OBSOLETE */ + +#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) { + if ((p = reset_1string) != 0) { + tputs(p, 0, outc); + settle = TRUE; + } + if ((p = reset_2string) != 0) { + tputs(p, 0, outc); + settle = TRUE; + } + /* What about rf, rs3, as per terminfo man page? */ + /* also might be nice to send rmacs, rmul, rmm */ + if ((p = reset_file) != 0 + || (p = init_file) != 0) { + cat(p); + settle = TRUE; + } + } + + if (settle) { + (void)putc('\r', stderr); + (void)fflush(stderr); + (void)napms(1000); /* 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 TRUE if we set any tab stops, FALSE if not. + */ +static bool +set_tabs() +{ + if (set_tab && clear_all_tabs) { + int c; + + (void)putc('\r', stderr); /* Force to left margin. */ + tputs(clear_all_tabs, 0, outc); + + for (c = 8; c < tcolumns; c += 8) { + /* Get to the right column. In BSD tset, this + * used to try a bunch of half-clever things + * with cup and hpa, for an average saving of + * somewhat less than two character times per + * tab stop, less that .01 sec at 2400cps. We + * lost all this cruft because it seemed to be + * introducing some odd bugs. + * ----------12345678----------- */ + (void)fputs(" ", stderr); + tputs(set_tab, 0, outc); + } + putc('\r', stderr); + return (TRUE); + } + return (FALSE); +} + +/************************************************************************** + * + * Main sequence + * + **************************************************************************/ + +/* + * Tell the user if a control key has been changed from the default value. + */ +static void +report(const char *name, int which, u_int def) +{ +#ifdef TERMIOS + u_int older, newer; + char *p; + + newer = mode.c_cc[which]; + older = oldmode.c_cc[which]; + + if (older == newer && older == def) + return; + + (void)fprintf(stderr, "%s %s ", name, older == newer ? "is" : "set to"); + + /* + * Check 'delete' before 'backspace', since the key_backspace value + * is ambiguous. + */ + if (newer == 0177) + (void)fprintf(stderr, "delete.\n"); + else if ((p = key_backspace) != 0 + && newer == (u_int)p[0] + && p[1] == '\0') + (void)fprintf(stderr, "backspace.\n"); + else if (newer < 040) { + newer ^= 0100; + (void)fprintf(stderr, "control-%c (^%c).\n", newer, newer); + } else + (void)fprintf(stderr, "%c.\n", newer); +#endif +} + +/* + * Convert the obsolete argument forms into something that getopt can handle. + * This means that -e, -i and -k get default arguments supplied for them. + */ +static void +obsolete(char **argv) +{ + for (; *argv; ++argv) { + char *parm = argv[0]; + + if (parm[0] == '-' && parm[1] == '\0') + { + argv[0] = strdup("-q"); + continue; + } + + if ((parm[0] != '-') + || (argv[1] && argv[1][0] != '-') + || (parm[1] != 'e' && parm[1] != 'i' && parm[1] != 'k') + || (parm[2] != '\0')) + continue; + switch(argv[0][1]) { + case 'e': + argv[0] = strdup("-e^H"); + break; + case 'i': + argv[0] = strdup("-i^C"); + break; + case 'k': + argv[0] = strdup("-k^U"); + break; + } + } +} + +static void +usage(const char* pname) +{ + (void)fprintf(stderr, +"usage: %s [-IQrs] [-] [-e ch] [-i ch] [-k ch] [-m mapping] [terminal]\n", pname); + exit(EXIT_FAILURE); +} + +static char arg_to_char(void) +{ + return (optarg[0] == '^' && optarg[1] != '\0') + ? ((optarg[1] == '?') ? '\177' : CTRL(optarg[1])) + : optarg[0]; +} int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char **argv) { -#ifdef TIOCGWINSZ +#if defined(TIOCGWINSZ) && defined(TIOCSWINSZ) struct winsize win; #endif - int ch, noinit, noset, quiet, Sflag, sflag, showterm, usingupper; - char savech, *p, *t, *tcapbuf, *ttype; + int ch, noinit, noset, quiet, Sflag, sflag, showterm; + const char *p, *t; + const char *ttype; +#ifdef __OpenBSD__ + char tcapbuf[1024]; + int tcgetent(char *, const char *); + void wrtermcap (char *); +#endif +#ifdef TERMIOS if (tcgetattr(STDERR_FILENO, &mode) < 0) - err(1, "standard error"); + failed("standard error"); oldmode = mode; ospeed = cfgetospeed(&mode); +#else + if (gtty(STDERR_FILENO, &mode) < 0) + failed("standard error"); - if (p = strrchr(*argv, '/')) + oldmode = mode; + ospeed = mode.sg_ospeed; +#endif + + if ((p = strrchr(*argv, '/')) != 0) ++p; else p = *argv; - usingupper = isupper(*p); - if (!strcasecmp(p, "reset")) { + if (!CaselessCmp(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")) != -1) { + while ((ch = getopt(argc, argv, "a:d:e:Ii:k:m:np:qQSrs")) != EOF) { switch (ch) { - case '-': /* display term only */ + case 'q': /* display term only */ noset = 1; break; case 'a': /* OBSOLETE: map identifier to type */ @@ -112,25 +1099,19 @@ main(argc, argv) add_mapping("dialup", optarg); break; case 'e': /* erase character */ - erasechar = optarg[0] == '^' && optarg[1] != '\0' ? - optarg[1] == '?' ? '\177' : CTRL(optarg[1]) : - optarg[0]; + terasechar = arg_to_char(); 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]; + intrchar = arg_to_char(); break; case 'k': /* kill character */ - killchar = optarg[0] == '^' && optarg[1] != '\0' ? - optarg[1] == '?' ? '\177' : CTRL(optarg[1]) : - optarg[0]; + tkillchar = arg_to_char(); break; case 'm': /* map identifier to type */ - add_mapping(NULL, optarg); + add_mapping(0, optarg); break; case 'n': /* OBSOLETE: set new tty driver */ break; @@ -138,67 +1119,65 @@ main(argc, argv) add_mapping("plugboard", optarg); break; case 'Q': /* don't output control key settings */ - quiet = 1; break; - case 'S': /* output TERM/TERMCAP strings */ + quiet = 1; + case 'S': /* OBSOLETE: output TERM & TERMCAP */ Sflag = 1; break; case 'r': /* display term on stderr */ showterm = 1; break; - case 's': /* output TERM/TERMCAP strings */ + case 's': /* output TERM set command */ sflag = 1; break; case '?': default: - usage(); + usage(*argv); } } argc -= optind; argv += optind; if (argc > 1) - usage(); + usage(*argv); - ttype = get_termcap_entry(*argv, &tcapbuf); + ttype = get_termcap_entry(*argv); +#ifdef __OpenBSD__ + if (tcgetent(tcapbuf, ttype) < 0) + tcapbuf[0] = '\0'; +#endif if (!noset) { - columns = tgetnum("co"); - lines = tgetnum("li"); + tcolumns = columns; + tlines = lines; -#ifdef TIOCGWINSZ +#if defined(TIOCGWINSZ) && defined(TIOCSWINSZ) /* 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; + tlines > 0 && tcolumns > 0) { + win.ws_row = tlines; + win.ws_col = tcolumns; (void)ioctl(STDERR_FILENO, TIOCSWINSZ, &win); } #endif set_control_chars(); - set_conversions(usingupper); + set_conversions(); if (!noinit) set_init(); /* Set the modes if they've changed. */ if (memcmp(&mode, &oldmode, sizeof(mode))) +#ifdef TERMIOS tcsetattr(STDERR_FILENO, TCSADRAIN, &mode); +#else + stty(STDERR_FILENO, &mode); +#endif } /* 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(1, "strdup"); - *p = savech; - } - } + ttype = _nc_first_name(cur_term->type.term_names); if (noset) (void)printf("%s\n", ttype); @@ -211,113 +1190,74 @@ main(argc, argv) */ if (!quiet) { report("Erase", VERASE, CERASE); - report("Kill", VKILL, CKILL); - report("Interrupt", VINTR, CINTR); + report("Kill", VKILL, CINTR); + report("Interrupt", VINTR, CKILL); } } +#ifdef __OpenBSD__ if (Sflag) { - (void)printf("%s ", ttype); - if (tcapbuf) + if (tcapbuf[0]) { + (void) printf("%s ", ttype); wrtermcap(tcapbuf); + } else + err("No termcap entry for %s, only terminfo.", ttype); } +#else + if (Sflag) + err("The -S option is not supported under terminfo."); +#endif /* __OpenBSD__ */ +#ifdef __OpenBSD__ 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")) { - if (tcapbuf) + if ((p = getenv("SHELL")) != 0 + && !strcmp(p + strlen(p) - 3, "csh")) { + if (tcapbuf[0]) p = "set noglob histchars="";\nsetenv TERM %s;\nsetenv TERMCAP "; else p = "set noglob histchars="";\nsetenv TERM %s;\n"; - t = "unset noglob histchars;\n"; + t = "unset noglob histchars;\n"; } else { if (tcapbuf) { p = "TERM=%s;\nTERMCAP="; t = "export TERMCAP TERM;\n"; } else { - p = "TERM=%s;\n"; - t = "export TERMCAP;\n"; + if (tcapbuf) { + p = "TERM=%s;\nTERMCAP="; + t = "export TERMCAP TERM;\n"; + } else { + p = "TERM=%s;\n"; + t = "export TERMCAP;\n"; + } } } - (void)printf(p, ttype); - if (tcapbuf) { + (void) printf(p, ttype); + if (tcapbuf[0]) { putchar('\''); wrtermcap(tcapbuf); fputs("';\n", stdout); } - (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; - } +#else + 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")) != 0 + && !strcmp(p + strlen(p) - 3, "csh")) + p = "set noglob;\nsetenv TERM %s;\nunset noglob;\n"; + else + p = "TERM=%s;\n"; + (void) printf(p, ttype); } -} +#endif /* __OpenBSD__ */ -void -usage() -{ - (void)fprintf(stderr, -"usage: tset [-IQrSs] [-] [-e ch] [-i ch] [-k ch] [-m mapping] [terminal]\n"); - exit(1); + return EXIT_SUCCESS; } + +/* tset.c ends here */ diff --git a/usr.bin/tset/wrterm.c b/usr.bin/tset/wrterm.c deleted file mode 100644 index be06c172545..00000000000 --- a/usr.bin/tset/wrterm.c +++ /dev/null @@ -1,118 +0,0 @@ -/* $OpenBSD: wrterm.c,v 1.3 1997/01/17 07:13:45 millert Exp $ */ -/* $NetBSD: wrterm.c,v 1.3 1994/12/07 05:08:16 jtc Exp $ */ - -/*- - * 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 -#if 0 -static char sccsid[] = "@(#)wrterm.c 8.1 (Berkeley) 6/9/93"; -#endif -static char rcsid[] = "$OpenBSD: wrterm.c,v 1.3 1997/01/17 07:13:45 millert Exp $"; -#endif /* not lint */ - -#include -#include -#include -#include -#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 = strchr(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(':'); - } -} -- cgit v1.2.3