diff options
Diffstat (limited to 'contrib/ncurses/progs/tset.c')
-rw-r--r-- | contrib/ncurses/progs/tset.c | 1305 |
1 files changed, 0 insertions, 1305 deletions
diff --git a/contrib/ncurses/progs/tset.c b/contrib/ncurses/progs/tset.c deleted file mode 100644 index 3d60912..0000000 --- a/contrib/ncurses/progs/tset.c +++ /dev/null @@ -1,1305 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998-2006,2007 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 <zmbenhal@netcom.com> 1992,1995 * - * and: Eric S. Raymond <esr@snark.thyrsus.com> * - * and: Thomas E. Dickey 1996-on * - ****************************************************************************/ - -/* - * 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. - * - * 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. - */ - -#define USE_LIBTINFO -#define __INTERNAL_CAPS_VISIBLE /* we need to see has_hardware_tabs */ -#include <progs.priv.h> - -#include <errno.h> -#include <stdio.h> -#include <termcap.h> -#include <fcntl.h> - -#if HAVE_GETTTYNAM && HAVE_TTYENT_H -#include <ttyent.h> -#endif -#ifdef NeXT -char *ttyname(int fd); -#endif - -/* this is just to stifle a missing-prototype warning */ -#ifdef linux -# include <sys/ioctl.h> -#endif - -#if NEED_PTEM_H -/* they neglected to define struct winsize in termios.h -- it's only - in termio.h */ -#include <sys/stream.h> -#include <sys/ptem.h> -#endif - -#include <dump_entry.h> -#include <transform.h> - -MODULE_ID("$Id: tset.c,v 1.70 2007/10/13 22:22:04 tom Exp $") - -extern char **environ; - -#undef CTRL -#define CTRL(x) ((x) & 0x1f) - -const char *_nc_progname = "tset"; - -static TTY mode, oldmode, original; - -static bool opt_c; /* set control-chars */ -static bool opt_w; /* set window-size */ - -static bool can_restore = FALSE; -static bool isreset = FALSE; /* invoked as reset */ -static int terasechar = -1; /* new erase character */ -static int intrchar = -1; /* new interrupt character */ -static int tkillchar = -1; /* new kill character */ -static int tlines, tcolumns; /* window size */ - -#define LOWERCASE(c) ((isalpha(UChar(c)) && isupper(UChar(c))) ? tolower(UChar(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); -} - -static void -exit_error(void) -{ - if (can_restore) - SET_TTY(STDERR_FILENO, &original); - (void) fprintf(stderr, "\n"); - fflush(stderr); - ExitProgram(EXIT_FAILURE); - /* NOTREACHED */ -} - -static void -err(const char *fmt,...) -{ - va_list ap; - va_start(ap, fmt); - (void) fprintf(stderr, "%s: ", _nc_progname); - (void) vfprintf(stderr, fmt, ap); - va_end(ap); - exit_error(); - /* NOTREACHED */ -} - -static void -failed(const char *msg) -{ - char temp[BUFSIZ]; - unsigned len = strlen(_nc_progname) + 2; - - if (len < sizeof(temp) - 12) { - strcpy(temp, _nc_progname); - strcat(temp, ": "); - } else { - strcpy(temp, "tset: "); - } - perror(strncat(temp, msg, sizeof(temp) - strlen(temp) - 2)); - exit_error(); - /* NOTREACHED */ -} - -static void -cat(char *file) -{ - FILE *fp; - size_t nr; - char buf[BUFSIZ]; - - if ((fp = fopen(file, "r")) == 0) - failed(file); - - while ((nr = fread(buf, sizeof(char), sizeof(buf), fp)) != 0) - if (fwrite(buf, sizeof(char), nr, stderr) != nr) - failed("write to stderr"); - fclose(fp); -} - -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. */ - clearerr(stdin); - if (feof(stdin) || ferror(stdin)) { - (void) fprintf(stderr, "\n"); - exit_error(); - /* NOTREACHED */ - } - 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) { - exit_error(); - /* NOTREACHED */ - } - 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. */ - int 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}, - /* sgttyb may define up to this point */ -#ifdef B19200 - {"19200", B19200}, -#endif -#ifdef B38400 - {"38400", B38400}, -#endif -#ifdef B19200 - {"19200", B19200}, -#endif -#ifdef B38400 - {"38400", B38400}, -#endif -#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 = (MAP *) malloc(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; - - arg = strpbrk(arg, "><@=!:"); - - 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 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) { - p = _nc_basename(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(UChar(*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 && !_nc_is_abs_path(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 (setupterm((NCURSES_CONST char *) ttype, STDOUT_FILENO, &errret) - != OK) { - if (errret == 0) { - (void) fprintf(stderr, "%s: unknown terminal type %s\n", - _nc_progname, ttype); - ttype = 0; - } else { - (void) fprintf(stderr, - "%s: can't initialize terminal type %s (error %d)\n", - _nc_progname, 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 unless the - * commonly-altered ones are defined. - */ -#if !(defined(CERASE) && defined(CINTR) && defined(CKILL) && defined(CQUIT)) -#undef CEOF -#undef CERASE -#undef CINTR -#undef CKILL -#undef CLNEXT -#undef CRPRNT -#undef CQUIT -#undef CSTART -#undef CSTOP -#undef CSUSP -#endif - -/* control-character defaults */ -#ifndef CEOF -#define CEOF CTRL('D') -#endif -#ifndef CERASE -#define CERASE CTRL('H') -#endif -#ifndef CINTR -#define CINTR 127 /* ^? */ -#endif -#ifndef CKILL -#define CKILL CTRL('U') -#endif -#ifndef CLNEXT -#define CLNEXT CTRL('v') -#endif -#ifndef CRPRNT -#define CRPRNT CTRL('r') -#endif -#ifndef CQUIT -#define CQUIT CTRL('\\') -#endif -#ifndef CSTART -#define CSTART CTRL('Q') -#endif -#ifndef CSTOP -#define CSTOP CTRL('S') -#endif -#ifndef CSUSP -#define CSUSP CTRL('Z') -#endif - -#if defined(_POSIX_VDISABLE) -#define DISABLED(val) (((_POSIX_VDISABLE != -1) \ - && ((val) == _POSIX_VDISABLE)) \ - || ((val) <= 0)) -#else -#define DISABLED(val) ((int)(val) <= 0) -#endif - -#define CHK(val, dft) (DISABLED(val) ? 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 - -#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 -#endif -#ifdef CRDLY - | CRDLY -#endif -#ifdef TABDLY - | TABDLY -#endif -#ifdef BSDLY - | BSDLY -#endif -#ifdef VTDLY - | VTDLY -#endif -#ifdef FFDLY - | 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 - - SET_TTY(STDERR_FILENO, &mode); -} - -/* - * Returns a "good" value for the erase character. This is loosely based on - * the BSD4.4 logic. - */ -#ifdef TERMIOS -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; -} -#endif - -/* - * 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 (DISABLED(mode.c_cc[VERASE]) || terasechar >= 0) - mode.c_cc[VERASE] = terasechar >= 0 ? terasechar : default_erase(); - - if (DISABLED(mode.c_cc[VINTR]) || intrchar >= 0) - mode.c_cc[VINTR] = intrchar >= 0 ? intrchar : CINTR; - - if (DISABLED(mode.c_cc[VKILL]) || 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); - SET_TTY(STDERR_FILENO, &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(void) -{ - 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 than .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. - */ -#ifdef TERMIOS -static void -report(const char *name, int which, unsigned def) -{ - unsigned 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"); - - if (DISABLED(newer)) - (void) fprintf(stderr, "undef.\n"); - /* - * Check 'delete' before 'backspace', since the key_backspace value - * is ambiguous. - */ - else if (newer == 0177) - (void) fprintf(stderr, "delete.\n"); - else if ((p = key_backspace) != 0 - && newer == (unsigned char) p[0] - && p[1] == '\0') - (void) fprintf(stderr, "backspace.\n"); - else if (newer < 040) { - newer ^= 0100; - (void) fprintf(stderr, "control-%c (^%c).\n", UChar(newer), UChar(newer)); - } else - (void) fprintf(stderr, "%c.\n", UChar(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(void) -{ - static const char *tbl[] = - { - "" - ,"Options:" - ," -c set control characters" - ," -e ch erase character" - ," -I no initialization strings" - ," -i ch interrupt character" - ," -k ch kill character" - ," -m mapping map identifier to type" - ," -Q do not output control key settings" - ," -r display term on stderr" - ," -s output TERM set command" - ," -V print curses-version" - ," -w set window-size" - }; - unsigned n; - (void) fprintf(stderr, "Usage: %s [options] [terminal]\n", _nc_progname); - for (n = 0; n < sizeof(tbl) / sizeof(tbl[0]); ++n) - fprintf(stderr, "%s\n", tbl[n]); - exit_error(); - /* NOTREACHED */ -} - -static char -arg_to_char(void) -{ - return (optarg[0] == '^' && optarg[1] != '\0') - ? ((optarg[1] == '?') ? '\177' : CTRL(optarg[1])) - : optarg[0]; -} - -int -main(int argc, char **argv) -{ -#if defined(TIOCGWINSZ) && defined(TIOCSWINSZ) - struct winsize win; -#endif - int ch, noinit, noset, quiet, Sflag, sflag, showterm; - const char *p; - const char *ttype; - - obsolete(argv); - noinit = noset = quiet = Sflag = sflag = showterm = 0; - while ((ch = getopt(argc, argv, "a:cd:e:Ii:k:m:np:qQSrsVw")) != -1) { - switch (ch) { - case 'c': /* set control-chars */ - opt_c = TRUE; - 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 */ - terasechar = arg_to_char(); - break; - case 'I': /* no initialization strings */ - noinit = 1; - break; - case 'i': /* interrupt character */ - intrchar = arg_to_char(); - break; - case 'k': /* kill character */ - tkillchar = arg_to_char(); - break; - case 'm': /* map identifier to type */ - add_mapping(0, 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 'q': /* display term only */ - noset = 1; - break; - case 'r': /* display term on stderr */ - showterm = 1; - break; - case 'S': /* OBSOLETE: output TERM & TERMCAP */ - Sflag = 1; - break; - case 's': /* output TERM set command */ - sflag = 1; - break; - case 'V': /* print curses-version */ - puts(curses_version()); - ExitProgram(EXIT_SUCCESS); - case 'w': /* set window-size */ - opt_w = TRUE; - break; - case '?': - default: - usage(); - } - } - - _nc_progname = _nc_rootname(*argv); - argc -= optind; - argv += optind; - - if (argc > 1) - usage(); - - if (!opt_c && !opt_w) - opt_c = opt_w = TRUE; - - if (GET_TTY(STDERR_FILENO, &mode) < 0) - failed("standard error"); - can_restore = TRUE; - original = oldmode = mode; -#ifdef TERMIOS - ospeed = cfgetospeed(&mode); -#else - ospeed = mode.sg_ospeed; -#endif - - if (!strcmp(_nc_progname, PROG_RESET)) { - isreset = TRUE; - reset_mode(); - } - - ttype = get_termcap_entry(*argv); - - if (!noset) { - tcolumns = columns; - tlines = lines; - -#if defined(TIOCGWINSZ) && defined(TIOCSWINSZ) - if (opt_w) { - /* Set window size */ - (void) ioctl(STDERR_FILENO, TIOCGWINSZ, &win); - if (win.ws_row == 0 && win.ws_col == 0 && - tlines > 0 && tcolumns > 0) { - win.ws_row = tlines; - win.ws_col = tcolumns; - (void) ioctl(STDERR_FILENO, TIOCSWINSZ, &win); - } - } -#endif - if (opt_c) { - set_control_chars(); - set_conversions(); - - if (!noinit) - set_init(); - - /* Set the modes if they've changed. */ - if (memcmp(&mode, &oldmode, sizeof(mode))) { - SET_TTY(STDERR_FILENO, &mode); - } - } - } - - /* Get the terminal name from the entry. */ - ttype = _nc_first_name(cur_term->type.term_names); - - 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. - */ -#ifdef TERMIOS - if (!quiet) { - report("Erase", VERASE, CERASE); - report("Kill", VKILL, CKILL); - report("Interrupt", VINTR, CINTR); - } -#endif - } - - if (Sflag) - err("The -S option is not supported under terminfo."); - - if (sflag) { - int len; - char *var; - char *leaf; - /* - * Figure out what shell we're using. A hack, we look for an - * environmental variable SHELL ending in "csh". - */ - if ((var = getenv("SHELL")) != 0 - && ((len = strlen(leaf = _nc_basename(var))) >= 3) - && !strcmp(leaf + len - 3, "csh")) - p = "set noglob;\nsetenv TERM %s;\nunset noglob;\n"; - else - p = "TERM=%s;\n"; - (void) printf(p, ttype); - } - - ExitProgram(EXIT_SUCCESS); -} |