10e3d5408SPeter Wemm /**************************************************************************** 20e3d5408SPeter Wemm * Copyright (c) 1998 Free Software Foundation, Inc. * 30e3d5408SPeter Wemm * * 40e3d5408SPeter Wemm * Permission is hereby granted, free of charge, to any person obtaining a * 50e3d5408SPeter Wemm * copy of this software and associated documentation files (the * 60e3d5408SPeter Wemm * "Software"), to deal in the Software without restriction, including * 70e3d5408SPeter Wemm * without limitation the rights to use, copy, modify, merge, publish, * 80e3d5408SPeter Wemm * distribute, distribute with modifications, sublicense, and/or sell * 90e3d5408SPeter Wemm * copies of the Software, and to permit persons to whom the Software is * 100e3d5408SPeter Wemm * furnished to do so, subject to the following conditions: * 110e3d5408SPeter Wemm * * 120e3d5408SPeter Wemm * The above copyright notice and this permission notice shall be included * 130e3d5408SPeter Wemm * in all copies or substantial portions of the Software. * 140e3d5408SPeter Wemm * * 150e3d5408SPeter Wemm * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 160e3d5408SPeter Wemm * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 170e3d5408SPeter Wemm * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 180e3d5408SPeter Wemm * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 190e3d5408SPeter Wemm * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 200e3d5408SPeter Wemm * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 210e3d5408SPeter Wemm * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 220e3d5408SPeter Wemm * * 230e3d5408SPeter Wemm * Except as contained in this notice, the name(s) of the above copyright * 240e3d5408SPeter Wemm * holders shall not be used in advertising or otherwise to promote the * 250e3d5408SPeter Wemm * sale, use or other dealings in this Software without prior written * 260e3d5408SPeter Wemm * authorization. * 270e3d5408SPeter Wemm ****************************************************************************/ 280e3d5408SPeter Wemm 290e3d5408SPeter Wemm /**************************************************************************** 300e3d5408SPeter Wemm * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * 310e3d5408SPeter Wemm * and: Eric S. Raymond <esr@snark.thyrsus.com> * 320e3d5408SPeter Wemm ****************************************************************************/ 330e3d5408SPeter Wemm 340e3d5408SPeter Wemm 350e3d5408SPeter Wemm /* 360e3d5408SPeter Wemm * tset.c - terminal initialization utility 370e3d5408SPeter Wemm * 380e3d5408SPeter Wemm * This code was mostly swiped from 4.4BSD tset, with some obsolescent 390e3d5408SPeter Wemm * cruft removed and substantial portions rewritten. A Regents of the 400e3d5408SPeter Wemm * University of California copyright applies to some portions of the 410e3d5408SPeter Wemm * code, and is reproduced below: 420e3d5408SPeter Wemm */ 430e3d5408SPeter Wemm /*- 440e3d5408SPeter Wemm * Copyright (c) 1980, 1991, 1993 450e3d5408SPeter Wemm * The Regents of the University of California. All rights reserved. 460e3d5408SPeter Wemm * 470e3d5408SPeter Wemm * Redistribution and use in source and binary forms, with or without 480e3d5408SPeter Wemm * modification, are permitted provided that the following conditions 490e3d5408SPeter Wemm * are met: 500e3d5408SPeter Wemm * 1. Redistributions of source code must retain the above copyright 510e3d5408SPeter Wemm * notice, this list of conditions and the following disclaimer. 520e3d5408SPeter Wemm * 2. Redistributions in binary form must reproduce the above copyright 530e3d5408SPeter Wemm * notice, this list of conditions and the following disclaimer in the 540e3d5408SPeter Wemm * documentation and/or other materials provided with the distribution. 550e3d5408SPeter Wemm * 3. All advertising materials mentioning features or use of this software 560e3d5408SPeter Wemm * must display the following acknowledgement: 570e3d5408SPeter Wemm * This product includes software developed by the University of 580e3d5408SPeter Wemm * California, Berkeley and its contributors. 590e3d5408SPeter Wemm * 4. Neither the name of the University nor the names of its contributors 600e3d5408SPeter Wemm * may be used to endorse or promote products derived from this software 610e3d5408SPeter Wemm * without specific prior written permission. 620e3d5408SPeter Wemm * 630e3d5408SPeter Wemm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 640e3d5408SPeter Wemm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 650e3d5408SPeter Wemm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 660e3d5408SPeter Wemm * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 670e3d5408SPeter Wemm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 680e3d5408SPeter Wemm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 690e3d5408SPeter Wemm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 700e3d5408SPeter Wemm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 710e3d5408SPeter Wemm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 720e3d5408SPeter Wemm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 730e3d5408SPeter Wemm * SUCH DAMAGE. 740e3d5408SPeter Wemm */ 750e3d5408SPeter Wemm 760e3d5408SPeter Wemm #define __INTERNAL_CAPS_VISIBLE /* we need to see has_hardware_tabs */ 770e3d5408SPeter Wemm #include <progs.priv.h> 780e3d5408SPeter Wemm 790e3d5408SPeter Wemm #include <errno.h> 800e3d5408SPeter Wemm #include <stdio.h> 810e3d5408SPeter Wemm #include <termcap.h> 820e3d5408SPeter Wemm #include <fcntl.h> 830e3d5408SPeter Wemm 840e3d5408SPeter Wemm #if HAVE_GETTTYNAM && HAVE_TTYENT_H 850e3d5408SPeter Wemm #include <ttyent.h> 860e3d5408SPeter Wemm #endif 870e3d5408SPeter Wemm #ifdef NeXT 880e3d5408SPeter Wemm char *ttyname(int fd); 890e3d5408SPeter Wemm #endif 900e3d5408SPeter Wemm 910e3d5408SPeter Wemm /* this is just to stifle a missing-prototype warning */ 920e3d5408SPeter Wemm #ifdef linux 930e3d5408SPeter Wemm # include <sys/ioctl.h> 940e3d5408SPeter Wemm #endif 950e3d5408SPeter Wemm 960e3d5408SPeter Wemm #if NEED_PTEM_H 970e3d5408SPeter Wemm /* they neglected to define struct winsize in termios.h -- it's only 980e3d5408SPeter Wemm in termio.h */ 990e3d5408SPeter Wemm #include <sys/stream.h> 1000e3d5408SPeter Wemm #include <sys/ptem.h> 1010e3d5408SPeter Wemm #endif 1020e3d5408SPeter Wemm 1030e3d5408SPeter Wemm #include <curses.h> /* for bool typedef */ 1040e3d5408SPeter Wemm #include <dump_entry.h> 1050e3d5408SPeter Wemm 1060e3d5408SPeter Wemm MODULE_ID("$Id: tset.c,v 0.37 1999/03/14 12:30:02 tom Exp $") 1070e3d5408SPeter Wemm 1080e3d5408SPeter Wemm extern char **environ; 1090e3d5408SPeter Wemm 1100e3d5408SPeter Wemm #undef CTRL 1110e3d5408SPeter Wemm #define CTRL(x) ((x) & 0x1f) 1120e3d5408SPeter Wemm 1130e3d5408SPeter Wemm const char *_nc_progname = "tset"; 1140e3d5408SPeter Wemm 1150e3d5408SPeter Wemm static TTY mode, oldmode; 1160e3d5408SPeter Wemm 1170e3d5408SPeter Wemm static int terasechar = -1; /* new erase character */ 1180e3d5408SPeter Wemm static int intrchar = -1; /* new interrupt character */ 1190e3d5408SPeter Wemm static int isreset; /* invoked as reset */ 1200e3d5408SPeter Wemm static int tkillchar = -1; /* new kill character */ 1210e3d5408SPeter Wemm static int tlines, tcolumns; /* window size */ 1220e3d5408SPeter Wemm 1230e3d5408SPeter Wemm #define LOWERCASE(c) ((isalpha(c) && isupper(c)) ? tolower(c) : (c)) 1240e3d5408SPeter Wemm 1250e3d5408SPeter Wemm static int 1260e3d5408SPeter Wemm CaselessCmp(const char *a, const char *b) /* strcasecmp isn't portable */ 1270e3d5408SPeter Wemm { 1280e3d5408SPeter Wemm while (*a && *b) { 1290e3d5408SPeter Wemm int cmp = LOWERCASE(*a) - LOWERCASE(*b); 1300e3d5408SPeter Wemm if (cmp != 0) 1310e3d5408SPeter Wemm break; 1320e3d5408SPeter Wemm a++, b++; 1330e3d5408SPeter Wemm } 1340e3d5408SPeter Wemm return LOWERCASE(*a) - LOWERCASE(*b); 1350e3d5408SPeter Wemm } 1360e3d5408SPeter Wemm 1370e3d5408SPeter Wemm #if !HAVE_STRDUP 1380e3d5408SPeter Wemm #define strdup _nc_strdup 1390e3d5408SPeter Wemm extern char *_nc_strdup(const char *); 1400e3d5408SPeter Wemm #endif /* not HAVE_STRDUP */ 1410e3d5408SPeter Wemm 1420e3d5408SPeter Wemm static void 1430e3d5408SPeter Wemm err(const char *fmt, ...) 1440e3d5408SPeter Wemm { 1450e3d5408SPeter Wemm va_list ap; 1460e3d5408SPeter Wemm va_start(ap, fmt); 1470e3d5408SPeter Wemm (void)fprintf(stderr, "tset: "); 1480e3d5408SPeter Wemm (void)vfprintf(stderr, fmt, ap); 1490e3d5408SPeter Wemm va_end(ap); 1500e3d5408SPeter Wemm (void)fprintf(stderr, "\n"); 1510e3d5408SPeter Wemm exit(EXIT_FAILURE); 1520e3d5408SPeter Wemm /* NOTREACHED */ 1530e3d5408SPeter Wemm } 1540e3d5408SPeter Wemm 1550e3d5408SPeter Wemm static void 1560e3d5408SPeter Wemm failed(const char *msg) 1570e3d5408SPeter Wemm { 1580e3d5408SPeter Wemm char temp[BUFSIZ]; 1590e3d5408SPeter Wemm perror(strcat(strcpy(temp, "tset: "), msg)); 1600e3d5408SPeter Wemm exit(EXIT_FAILURE); 1610e3d5408SPeter Wemm /* NOTREACHED */ 1620e3d5408SPeter Wemm } 1630e3d5408SPeter Wemm 1640e3d5408SPeter Wemm static void 1650e3d5408SPeter Wemm cat(char *file) 1660e3d5408SPeter Wemm { 1670e3d5408SPeter Wemm register int fd, nr, nw; 1680e3d5408SPeter Wemm char buf[BUFSIZ]; 1690e3d5408SPeter Wemm 1700e3d5408SPeter Wemm if ((fd = open(file, O_RDONLY, 0)) < 0) 1710e3d5408SPeter Wemm failed(file); 1720e3d5408SPeter Wemm 1730e3d5408SPeter Wemm while ((nr = read(fd, buf, sizeof(buf))) > 0) 1740e3d5408SPeter Wemm if ((nw = write(STDERR_FILENO, buf, (size_t)nr)) == -1) 1750e3d5408SPeter Wemm failed("write to stderr"); 1760e3d5408SPeter Wemm if (nr != 0) 1770e3d5408SPeter Wemm failed(file); 1780e3d5408SPeter Wemm (void)close(fd); 1790e3d5408SPeter Wemm } 1800e3d5408SPeter Wemm 1810e3d5408SPeter Wemm static int 1820e3d5408SPeter Wemm outc(int c) 1830e3d5408SPeter Wemm { 1840e3d5408SPeter Wemm return putc(c, stderr); 1850e3d5408SPeter Wemm } 1860e3d5408SPeter Wemm 1870e3d5408SPeter Wemm /* Prompt the user for a terminal type. */ 1880e3d5408SPeter Wemm static const char * 1890e3d5408SPeter Wemm askuser(const char *dflt) 1900e3d5408SPeter Wemm { 1910e3d5408SPeter Wemm static char answer[256]; 1920e3d5408SPeter Wemm char *p; 1930e3d5408SPeter Wemm 1940e3d5408SPeter Wemm /* We can get recalled; if so, don't continue uselessly. */ 1950e3d5408SPeter Wemm if (feof(stdin) || ferror(stdin)) { 1960e3d5408SPeter Wemm (void)fprintf(stderr, "\n"); 1970e3d5408SPeter Wemm exit(EXIT_FAILURE); 1980e3d5408SPeter Wemm } 1990e3d5408SPeter Wemm for (;;) { 2000e3d5408SPeter Wemm if (dflt) 2010e3d5408SPeter Wemm (void)fprintf(stderr, "Terminal type? [%s] ", dflt); 2020e3d5408SPeter Wemm else 2030e3d5408SPeter Wemm (void)fprintf(stderr, "Terminal type? "); 2040e3d5408SPeter Wemm (void)fflush(stderr); 2050e3d5408SPeter Wemm 2060e3d5408SPeter Wemm if (fgets(answer, sizeof(answer), stdin) == 0) { 2070e3d5408SPeter Wemm if (dflt == 0) { 2080e3d5408SPeter Wemm (void)fprintf(stderr, "\n"); 2090e3d5408SPeter Wemm exit(EXIT_FAILURE); 2100e3d5408SPeter Wemm } 2110e3d5408SPeter Wemm return (dflt); 2120e3d5408SPeter Wemm } 2130e3d5408SPeter Wemm 2140e3d5408SPeter Wemm if ((p = strchr(answer, '\n')) != 0) 2150e3d5408SPeter Wemm *p = '\0'; 2160e3d5408SPeter Wemm if (answer[0]) 2170e3d5408SPeter Wemm return (answer); 2180e3d5408SPeter Wemm if (dflt != 0) 2190e3d5408SPeter Wemm return (dflt); 2200e3d5408SPeter Wemm } 2210e3d5408SPeter Wemm } 2220e3d5408SPeter Wemm 2230e3d5408SPeter Wemm /************************************************************************** 2240e3d5408SPeter Wemm * 2250e3d5408SPeter Wemm * Mapping logic begins here 2260e3d5408SPeter Wemm * 2270e3d5408SPeter Wemm **************************************************************************/ 2280e3d5408SPeter Wemm 2290e3d5408SPeter Wemm /* Baud rate conditionals for mapping. */ 2300e3d5408SPeter Wemm #define GT 0x01 2310e3d5408SPeter Wemm #define EQ 0x02 2320e3d5408SPeter Wemm #define LT 0x04 2330e3d5408SPeter Wemm #define NOT 0x08 2340e3d5408SPeter Wemm #define GE (GT | EQ) 2350e3d5408SPeter Wemm #define LE (LT | EQ) 2360e3d5408SPeter Wemm 2370e3d5408SPeter Wemm typedef struct map { 2380e3d5408SPeter Wemm struct map *next; /* Linked list of maps. */ 2390e3d5408SPeter Wemm const char *porttype; /* Port type, or "" for any. */ 2400e3d5408SPeter Wemm const char *type; /* Terminal type to select. */ 2410e3d5408SPeter Wemm int conditional; /* Baud rate conditionals bitmask. */ 2420e3d5408SPeter Wemm speed_t speed; /* Baud rate to compare against. */ 2430e3d5408SPeter Wemm } MAP; 2440e3d5408SPeter Wemm 2450e3d5408SPeter Wemm static MAP *cur, *maplist; 2460e3d5408SPeter Wemm 2470e3d5408SPeter Wemm typedef struct speeds { 2480e3d5408SPeter Wemm const char *string; 2490e3d5408SPeter Wemm int speed; 2500e3d5408SPeter Wemm } SPEEDS; 2510e3d5408SPeter Wemm 2520e3d5408SPeter Wemm static const SPEEDS speeds[] = { 2530e3d5408SPeter Wemm { "0", B0 }, 2540e3d5408SPeter Wemm { "50", B50 }, 2550e3d5408SPeter Wemm { "75", B75 }, 2560e3d5408SPeter Wemm { "110", B110 }, 2570e3d5408SPeter Wemm { "134", B134 }, 2580e3d5408SPeter Wemm { "134.5", B134 }, 2590e3d5408SPeter Wemm { "150", B150 }, 2600e3d5408SPeter Wemm { "200", B200 }, 2610e3d5408SPeter Wemm { "300", B300 }, 2620e3d5408SPeter Wemm { "600", B600 }, 2630e3d5408SPeter Wemm { "1200", B1200 }, 2640e3d5408SPeter Wemm { "1800", B1800 }, 2650e3d5408SPeter Wemm { "2400", B2400 }, 2660e3d5408SPeter Wemm { "4800", B4800 }, 2670e3d5408SPeter Wemm { "9600", B9600 }, 2680e3d5408SPeter Wemm { "19200", B19200 }, 2690e3d5408SPeter Wemm { "38400", B38400 }, 2700e3d5408SPeter Wemm { "19200", B19200 }, 2710e3d5408SPeter Wemm { "38400", B38400 }, 2720e3d5408SPeter Wemm #ifdef B19200 2730e3d5408SPeter Wemm { "19200", B19200 }, 2740e3d5408SPeter Wemm #else 2750e3d5408SPeter Wemm #ifdef EXTA 2760e3d5408SPeter Wemm { "19200", EXTA }, 2770e3d5408SPeter Wemm #endif 2780e3d5408SPeter Wemm #endif 2790e3d5408SPeter Wemm #ifdef B38400 2800e3d5408SPeter Wemm { "38400", B38400 }, 2810e3d5408SPeter Wemm #else 2820e3d5408SPeter Wemm #ifdef EXTB 2830e3d5408SPeter Wemm { "38400", EXTB }, 2840e3d5408SPeter Wemm #endif 2850e3d5408SPeter Wemm #endif 2860e3d5408SPeter Wemm #ifdef B57600 2870e3d5408SPeter Wemm { "57600", B57600 }, 2880e3d5408SPeter Wemm #endif 2890e3d5408SPeter Wemm #ifdef B115200 2900e3d5408SPeter Wemm { "115200", B115200 }, 2910e3d5408SPeter Wemm #endif 2920e3d5408SPeter Wemm #ifdef B230400 2930e3d5408SPeter Wemm { "230400", B230400 }, 2940e3d5408SPeter Wemm #endif 2950e3d5408SPeter Wemm #ifdef B460800 2960e3d5408SPeter Wemm { "460800", B460800 }, 2970e3d5408SPeter Wemm #endif 2980e3d5408SPeter Wemm { (char *)0, 0 } 2990e3d5408SPeter Wemm }; 3000e3d5408SPeter Wemm 3010e3d5408SPeter Wemm static int 3020e3d5408SPeter Wemm tbaudrate(char *rate) 3030e3d5408SPeter Wemm { 3040e3d5408SPeter Wemm const SPEEDS *sp; 3050e3d5408SPeter Wemm int found = FALSE; 3060e3d5408SPeter Wemm 3070e3d5408SPeter Wemm /* The baudrate number can be preceded by a 'B', which is ignored. */ 3080e3d5408SPeter Wemm if (*rate == 'B') 3090e3d5408SPeter Wemm ++rate; 3100e3d5408SPeter Wemm 3110e3d5408SPeter Wemm for (sp = speeds; sp->string; ++sp) { 3120e3d5408SPeter Wemm if (!CaselessCmp(rate, sp->string)) { 3130e3d5408SPeter Wemm found = TRUE; 3140e3d5408SPeter Wemm break; 3150e3d5408SPeter Wemm } 3160e3d5408SPeter Wemm } 3170e3d5408SPeter Wemm if (!found) 3180e3d5408SPeter Wemm err("unknown baud rate %s", rate); 3190e3d5408SPeter Wemm return (sp->speed); 3200e3d5408SPeter Wemm } 3210e3d5408SPeter Wemm 3220e3d5408SPeter Wemm /* 3230e3d5408SPeter Wemm * Syntax for -m: 3240e3d5408SPeter Wemm * [port-type][test baudrate]:terminal-type 3250e3d5408SPeter Wemm * The baud rate tests are: >, <, @, =, ! 3260e3d5408SPeter Wemm */ 3270e3d5408SPeter Wemm static void 3280e3d5408SPeter Wemm add_mapping(const char *port, char *arg) 3290e3d5408SPeter Wemm { 3300e3d5408SPeter Wemm MAP *mapp; 3310e3d5408SPeter Wemm char *copy, *p; 3320e3d5408SPeter Wemm const char *termp; 3330e3d5408SPeter Wemm char *base = 0; 3340e3d5408SPeter Wemm 3350e3d5408SPeter Wemm copy = strdup(arg); 3360e3d5408SPeter Wemm mapp = malloc(sizeof(MAP)); 3370e3d5408SPeter Wemm if (copy == 0 || mapp == 0) 3380e3d5408SPeter Wemm failed("malloc"); 3390e3d5408SPeter Wemm mapp->next = 0; 3400e3d5408SPeter Wemm if (maplist == 0) 3410e3d5408SPeter Wemm cur = maplist = mapp; 3420e3d5408SPeter Wemm else { 3430e3d5408SPeter Wemm cur->next = mapp; 3440e3d5408SPeter Wemm cur = mapp; 3450e3d5408SPeter Wemm } 3460e3d5408SPeter Wemm 3470e3d5408SPeter Wemm mapp->porttype = arg; 3480e3d5408SPeter Wemm mapp->conditional = 0; 3490e3d5408SPeter Wemm 3500e3d5408SPeter Wemm arg = strpbrk(arg, "><@=!:"); 3510e3d5408SPeter Wemm 3520e3d5408SPeter Wemm if (arg == 0) { /* [?]term */ 3530e3d5408SPeter Wemm mapp->type = mapp->porttype; 3540e3d5408SPeter Wemm mapp->porttype = 0; 3550e3d5408SPeter Wemm goto done; 3560e3d5408SPeter Wemm } 3570e3d5408SPeter Wemm 3580e3d5408SPeter Wemm if (arg == mapp->porttype) /* [><@=! baud]:term */ 3590e3d5408SPeter Wemm termp = mapp->porttype = 0; 3600e3d5408SPeter Wemm else 3610e3d5408SPeter Wemm termp = base = arg; 3620e3d5408SPeter Wemm 3630e3d5408SPeter Wemm for (;; ++arg) /* Optional conditionals. */ 3640e3d5408SPeter Wemm switch(*arg) { 3650e3d5408SPeter Wemm case '<': 3660e3d5408SPeter Wemm if (mapp->conditional & GT) 3670e3d5408SPeter Wemm goto badmopt; 3680e3d5408SPeter Wemm mapp->conditional |= LT; 3690e3d5408SPeter Wemm break; 3700e3d5408SPeter Wemm case '>': 3710e3d5408SPeter Wemm if (mapp->conditional & LT) 3720e3d5408SPeter Wemm goto badmopt; 3730e3d5408SPeter Wemm mapp->conditional |= GT; 3740e3d5408SPeter Wemm break; 3750e3d5408SPeter Wemm case '@': 3760e3d5408SPeter Wemm case '=': /* Not documented. */ 3770e3d5408SPeter Wemm mapp->conditional |= EQ; 3780e3d5408SPeter Wemm break; 3790e3d5408SPeter Wemm case '!': 3800e3d5408SPeter Wemm mapp->conditional |= NOT; 3810e3d5408SPeter Wemm break; 3820e3d5408SPeter Wemm default: 3830e3d5408SPeter Wemm goto next; 3840e3d5408SPeter Wemm } 3850e3d5408SPeter Wemm 3860e3d5408SPeter Wemm next: if (*arg == ':') { 3870e3d5408SPeter Wemm if (mapp->conditional) 3880e3d5408SPeter Wemm goto badmopt; 3890e3d5408SPeter Wemm ++arg; 3900e3d5408SPeter Wemm } else { /* Optional baudrate. */ 3910e3d5408SPeter Wemm arg = strchr(p = arg, ':'); 3920e3d5408SPeter Wemm if (arg == 0) 3930e3d5408SPeter Wemm goto badmopt; 3940e3d5408SPeter Wemm *arg++ = '\0'; 3950e3d5408SPeter Wemm mapp->speed = tbaudrate(p); 3960e3d5408SPeter Wemm } 3970e3d5408SPeter Wemm 3980e3d5408SPeter Wemm if (arg == (char *)0) /* Non-optional type. */ 3990e3d5408SPeter Wemm goto badmopt; 4000e3d5408SPeter Wemm 4010e3d5408SPeter Wemm mapp->type = arg; 4020e3d5408SPeter Wemm 4030e3d5408SPeter Wemm /* Terminate porttype, if specified. */ 4040e3d5408SPeter Wemm if (termp != 0) 4050e3d5408SPeter Wemm *base = '\0'; 4060e3d5408SPeter Wemm 4070e3d5408SPeter Wemm /* If a NOT conditional, reverse the test. */ 4080e3d5408SPeter Wemm if (mapp->conditional & NOT) 4090e3d5408SPeter Wemm mapp->conditional = ~mapp->conditional & (EQ | GT | LT); 4100e3d5408SPeter Wemm 4110e3d5408SPeter Wemm /* If user specified a port with an option flag, set it. */ 4120e3d5408SPeter Wemm done: if (port) { 4130e3d5408SPeter Wemm if (mapp->porttype) 4140e3d5408SPeter Wemm badmopt: err("illegal -m option format: %s", copy); 4150e3d5408SPeter Wemm mapp->porttype = port; 4160e3d5408SPeter Wemm } 4170e3d5408SPeter Wemm 4180e3d5408SPeter Wemm #ifdef MAPDEBUG 4190e3d5408SPeter Wemm (void)printf("port: %s\n", mapp->porttype ? mapp->porttype : "ANY"); 4200e3d5408SPeter Wemm (void)printf("type: %s\n", mapp->type); 4210e3d5408SPeter Wemm (void)printf("conditional: "); 4220e3d5408SPeter Wemm p = ""; 4230e3d5408SPeter Wemm if (mapp->conditional & GT) { 4240e3d5408SPeter Wemm (void)printf("GT"); 4250e3d5408SPeter Wemm p = "/"; 4260e3d5408SPeter Wemm } 4270e3d5408SPeter Wemm if (mapp->conditional & EQ) { 4280e3d5408SPeter Wemm (void)printf("%sEQ", p); 4290e3d5408SPeter Wemm p = "/"; 4300e3d5408SPeter Wemm } 4310e3d5408SPeter Wemm if (mapp->conditional & LT) 4320e3d5408SPeter Wemm (void)printf("%sLT", p); 4330e3d5408SPeter Wemm (void)printf("\nspeed: %d\n", mapp->speed); 4340e3d5408SPeter Wemm #endif 4350e3d5408SPeter Wemm } 4360e3d5408SPeter Wemm 4370e3d5408SPeter Wemm /* 4380e3d5408SPeter Wemm * Return the type of terminal to use for a port of type 'type', as specified 4390e3d5408SPeter Wemm * by the first applicable mapping in 'map'. If no mappings apply, return 4400e3d5408SPeter Wemm * 'type'. 4410e3d5408SPeter Wemm */ 4420e3d5408SPeter Wemm static const char * 4430e3d5408SPeter Wemm mapped(const char *type) 4440e3d5408SPeter Wemm { 4450e3d5408SPeter Wemm MAP *mapp; 4460e3d5408SPeter Wemm int match; 4470e3d5408SPeter Wemm 4480e3d5408SPeter Wemm for (mapp = maplist; mapp; mapp = mapp->next) 4490e3d5408SPeter Wemm if (mapp->porttype == 0 || !strcmp(mapp->porttype, type)) { 4500e3d5408SPeter Wemm switch (mapp->conditional) { 4510e3d5408SPeter Wemm case 0: /* No test specified. */ 4520e3d5408SPeter Wemm match = TRUE; 4530e3d5408SPeter Wemm break; 4540e3d5408SPeter Wemm case EQ: 4550e3d5408SPeter Wemm match = (ospeed == mapp->speed); 4560e3d5408SPeter Wemm break; 4570e3d5408SPeter Wemm case GE: 4580e3d5408SPeter Wemm match = (ospeed >= mapp->speed); 4590e3d5408SPeter Wemm break; 4600e3d5408SPeter Wemm case GT: 4610e3d5408SPeter Wemm match = (ospeed > mapp->speed); 4620e3d5408SPeter Wemm break; 4630e3d5408SPeter Wemm case LE: 4640e3d5408SPeter Wemm match = (ospeed <= mapp->speed); 4650e3d5408SPeter Wemm break; 4660e3d5408SPeter Wemm case LT: 4670e3d5408SPeter Wemm match = (ospeed < mapp->speed); 4680e3d5408SPeter Wemm break; 4690e3d5408SPeter Wemm default: 4700e3d5408SPeter Wemm match = FALSE; 4710e3d5408SPeter Wemm } 4720e3d5408SPeter Wemm if (match) 4730e3d5408SPeter Wemm return (mapp->type); 4740e3d5408SPeter Wemm } 4750e3d5408SPeter Wemm /* No match found; return given type. */ 4760e3d5408SPeter Wemm return (type); 4770e3d5408SPeter Wemm } 4780e3d5408SPeter Wemm 4790e3d5408SPeter Wemm /************************************************************************** 4800e3d5408SPeter Wemm * 4810e3d5408SPeter Wemm * Entry fetching 4820e3d5408SPeter Wemm * 4830e3d5408SPeter Wemm **************************************************************************/ 4840e3d5408SPeter Wemm 4850e3d5408SPeter Wemm /* 4860e3d5408SPeter Wemm * Figure out what kind of terminal we're dealing with, and then read in 4870e3d5408SPeter Wemm * its termcap entry. 4880e3d5408SPeter Wemm */ 4890e3d5408SPeter Wemm static const char * 4900e3d5408SPeter Wemm get_termcap_entry(char *userarg) 4910e3d5408SPeter Wemm { 4920e3d5408SPeter Wemm int rval, errret; 4930e3d5408SPeter Wemm char *p; 4940e3d5408SPeter Wemm const char *ttype; 4950e3d5408SPeter Wemm #if HAVE_GETTTYNAM 4960e3d5408SPeter Wemm struct ttyent *t; 4970e3d5408SPeter Wemm #else 4980e3d5408SPeter Wemm FILE *fp; 4990e3d5408SPeter Wemm #endif 5000e3d5408SPeter Wemm char *ttypath; 5010e3d5408SPeter Wemm 5020e3d5408SPeter Wemm if (userarg) { 5030e3d5408SPeter Wemm ttype = userarg; 5040e3d5408SPeter Wemm goto found; 5050e3d5408SPeter Wemm } 5060e3d5408SPeter Wemm 5070e3d5408SPeter Wemm /* Try the environment. */ 5080e3d5408SPeter Wemm if ((ttype = getenv("TERM")) != 0) 5090e3d5408SPeter Wemm goto map; 5100e3d5408SPeter Wemm 5110e3d5408SPeter Wemm if ((ttypath = ttyname(STDERR_FILENO)) != 0) { 5120e3d5408SPeter Wemm if ((p = strrchr(ttypath, '/')) != 0) 5130e3d5408SPeter Wemm ++p; 5140e3d5408SPeter Wemm else 5150e3d5408SPeter Wemm p = ttypath; 5160e3d5408SPeter Wemm #if HAVE_GETTTYNAM 5170e3d5408SPeter Wemm /* 5180e3d5408SPeter Wemm * We have the 4.3BSD library call getttynam(3); that means 5190e3d5408SPeter Wemm * there's an /etc/ttys to look up device-to-type mappings in. 5200e3d5408SPeter Wemm * Try ttyname(3); check for dialup or other mapping. 5210e3d5408SPeter Wemm */ 5220e3d5408SPeter Wemm if ((t = getttynam(p))) { 5230e3d5408SPeter Wemm ttype = t->ty_type; 5240e3d5408SPeter Wemm goto map; 5250e3d5408SPeter Wemm } 5260e3d5408SPeter Wemm #else 5270e3d5408SPeter Wemm if ((fp = fopen("/etc/ttytype", "r")) != 0 5280e3d5408SPeter Wemm || (fp = fopen("/etc/ttys", "r")) != 0) { 5290e3d5408SPeter Wemm char buffer[BUFSIZ]; 5300e3d5408SPeter Wemm char *s, *t, *d; 5310e3d5408SPeter Wemm 5320e3d5408SPeter Wemm while (fgets(buffer, sizeof(buffer)-1, fp) != 0) { 5330e3d5408SPeter Wemm for (s = buffer, t = d = 0; *s; s++) { 5340e3d5408SPeter Wemm if (isspace(*s)) 5350e3d5408SPeter Wemm *s = '\0'; 5360e3d5408SPeter Wemm else if (t == 0) 5370e3d5408SPeter Wemm t = s; 5380e3d5408SPeter Wemm else if (d == 0 && s != buffer && s[-1] == '\0') 5390e3d5408SPeter Wemm d = s; 5400e3d5408SPeter Wemm } 5410e3d5408SPeter Wemm if (t != 0 && d != 0 && !strcmp(d,p)) { 5420e3d5408SPeter Wemm ttype = strdup(t); 5430e3d5408SPeter Wemm fclose(fp); 5440e3d5408SPeter Wemm goto map; 5450e3d5408SPeter Wemm } 5460e3d5408SPeter Wemm } 5470e3d5408SPeter Wemm fclose(fp); 5480e3d5408SPeter Wemm } 5490e3d5408SPeter Wemm #endif /* HAVE_GETTTYNAM */ 5500e3d5408SPeter Wemm } 5510e3d5408SPeter Wemm 5520e3d5408SPeter Wemm /* If still undefined, use "unknown". */ 5530e3d5408SPeter Wemm ttype = "unknown"; 5540e3d5408SPeter Wemm 5550e3d5408SPeter Wemm map: ttype = mapped(ttype); 5560e3d5408SPeter Wemm 5570e3d5408SPeter Wemm /* 5580e3d5408SPeter Wemm * If not a path, remove TERMCAP from the environment so we get a 5590e3d5408SPeter Wemm * real entry from /etc/termcap. This prevents us from being fooled 5600e3d5408SPeter Wemm * by out of date stuff in the environment. 5610e3d5408SPeter Wemm */ 5620e3d5408SPeter Wemm found: if ((p = getenv("TERMCAP")) != 0 && *p != '/') { 5630e3d5408SPeter Wemm /* 'unsetenv("TERMCAP")' is not portable. 5640e3d5408SPeter Wemm * The 'environ' array is better. 5650e3d5408SPeter Wemm */ 5660e3d5408SPeter Wemm int n; 5670e3d5408SPeter Wemm for (n = 0; environ[n] != 0; n++) { 5680e3d5408SPeter Wemm if (!strncmp("TERMCAP=", environ[n], 8)) { 5690e3d5408SPeter Wemm while ((environ[n] = environ[n+1]) != 0) { 5700e3d5408SPeter Wemm n++; 5710e3d5408SPeter Wemm } 5720e3d5408SPeter Wemm break; 5730e3d5408SPeter Wemm } 5740e3d5408SPeter Wemm } 5750e3d5408SPeter Wemm } 5760e3d5408SPeter Wemm 5770e3d5408SPeter Wemm /* 5780e3d5408SPeter Wemm * ttype now contains a pointer to the type of the terminal. 5790e3d5408SPeter Wemm * If the first character is '?', ask the user. 5800e3d5408SPeter Wemm */ 5810e3d5408SPeter Wemm if (ttype[0] == '?') { 5820e3d5408SPeter Wemm if (ttype[1] != '\0') 5830e3d5408SPeter Wemm ttype = askuser(ttype + 1); 5840e3d5408SPeter Wemm else 5850e3d5408SPeter Wemm ttype = askuser(0); 5860e3d5408SPeter Wemm } 5870e3d5408SPeter Wemm /* Find the terminfo entry. If it doesn't exist, ask the user. */ 5880e3d5408SPeter Wemm while ((rval = setupterm((NCURSES_CONST char *)ttype, STDOUT_FILENO, &errret)) != OK) { 5890e3d5408SPeter Wemm if (errret == 0) { 5900e3d5408SPeter Wemm (void)fprintf(stderr, "tset: unknown terminal type %s\n", 5910e3d5408SPeter Wemm ttype); 5920e3d5408SPeter Wemm ttype = 0; 5930e3d5408SPeter Wemm } 5940e3d5408SPeter Wemm else { 5950e3d5408SPeter Wemm (void)fprintf(stderr, "tset: can't initialize terminal type %s (error %d)\n", ttype, errret); 5960e3d5408SPeter Wemm ttype = 0; 5970e3d5408SPeter Wemm } 5980e3d5408SPeter Wemm ttype = askuser(ttype); 5990e3d5408SPeter Wemm } 6000e3d5408SPeter Wemm #if BROKEN_LINKER 6010e3d5408SPeter Wemm tgetflag("am"); /* force lib_termcap.o to be linked for 'ospeed' */ 6020e3d5408SPeter Wemm #endif 6030e3d5408SPeter Wemm return (ttype); 6040e3d5408SPeter Wemm } 6050e3d5408SPeter Wemm 6060e3d5408SPeter Wemm /************************************************************************** 6070e3d5408SPeter Wemm * 6080e3d5408SPeter Wemm * Mode-setting logic 6090e3d5408SPeter Wemm * 6100e3d5408SPeter Wemm **************************************************************************/ 6110e3d5408SPeter Wemm 6120e3d5408SPeter Wemm /* some BSD systems have these built in, some systems are missing 6130e3d5408SPeter Wemm * one or more definitions. The safest solution is to override. 6140e3d5408SPeter Wemm */ 6150e3d5408SPeter Wemm #undef CEOF 6160e3d5408SPeter Wemm #undef CERASE 6170e3d5408SPeter Wemm #undef CINTR 6180e3d5408SPeter Wemm #undef CKILL 6190e3d5408SPeter Wemm #undef CLNEXT 6200e3d5408SPeter Wemm #undef CRPRNT 6210e3d5408SPeter Wemm #undef CQUIT 6220e3d5408SPeter Wemm #undef CSTART 6230e3d5408SPeter Wemm #undef CSTOP 6240e3d5408SPeter Wemm #undef CSUSP 6250e3d5408SPeter Wemm 6260e3d5408SPeter Wemm /* control-character defaults */ 6270e3d5408SPeter Wemm #define CEOF CTRL('D') 6280e3d5408SPeter Wemm #define CERASE CTRL('H') 6290e3d5408SPeter Wemm #define CINTR 127 /* ^? */ 6300e3d5408SPeter Wemm #define CKILL CTRL('U') 6310e3d5408SPeter Wemm #define CLNEXT CTRL('v') 6320e3d5408SPeter Wemm #define CRPRNT CTRL('r') 6330e3d5408SPeter Wemm #define CQUIT CTRL('\\') 6340e3d5408SPeter Wemm #define CSTART CTRL('Q') 6350e3d5408SPeter Wemm #define CSTOP CTRL('S') 6360e3d5408SPeter Wemm #define CSUSP CTRL('Z') 6370e3d5408SPeter Wemm 6380e3d5408SPeter Wemm #define CHK(val, dft) ((int)val <= 0 ? dft : val) 6390e3d5408SPeter Wemm 6400e3d5408SPeter Wemm static bool set_tabs (void); 6410e3d5408SPeter Wemm 6420e3d5408SPeter Wemm /* 6430e3d5408SPeter Wemm * Reset the terminal mode bits to a sensible state. Very useful after 6440e3d5408SPeter Wemm * a child program dies in raw mode. 6450e3d5408SPeter Wemm */ 6460e3d5408SPeter Wemm static void 6470e3d5408SPeter Wemm reset_mode(void) 6480e3d5408SPeter Wemm { 6490e3d5408SPeter Wemm #ifdef TERMIOS 6500e3d5408SPeter Wemm tcgetattr(STDERR_FILENO, &mode); 6510e3d5408SPeter Wemm #else 6520e3d5408SPeter Wemm stty(STDERR_FILENO,&mode); 6530e3d5408SPeter Wemm #endif 6540e3d5408SPeter Wemm 6550e3d5408SPeter Wemm #ifdef TERMIOS 6560e3d5408SPeter Wemm #if defined(VDISCARD) && defined(CDISCARD) 6570e3d5408SPeter Wemm mode.c_cc[VDISCARD] = CHK(mode.c_cc[VDISCARD], CDISCARD); 6580e3d5408SPeter Wemm #endif 6590e3d5408SPeter Wemm mode.c_cc[VEOF] = CHK(mode.c_cc[VEOF], CEOF); 6600e3d5408SPeter Wemm mode.c_cc[VERASE] = CHK(mode.c_cc[VERASE], CERASE); 6610e3d5408SPeter Wemm #if defined(VFLUSH) && defined(CFLUSH) 6620e3d5408SPeter Wemm mode.c_cc[VFLUSH] = CHK(mode.c_cc[VFLUSH], CFLUSH); 6630e3d5408SPeter Wemm #endif 6640e3d5408SPeter Wemm mode.c_cc[VINTR] = CHK(mode.c_cc[VINTR], CINTR); 6650e3d5408SPeter Wemm mode.c_cc[VKILL] = CHK(mode.c_cc[VKILL], CKILL); 6660e3d5408SPeter Wemm #if defined(VLNEXT) && defined(CLNEXT) 6670e3d5408SPeter Wemm mode.c_cc[VLNEXT] = CHK(mode.c_cc[VLNEXT], CLNEXT); 6680e3d5408SPeter Wemm #endif 6690e3d5408SPeter Wemm mode.c_cc[VQUIT] = CHK(mode.c_cc[VQUIT], CQUIT); 6700e3d5408SPeter Wemm #if defined(VREPRINT) && defined(CRPRNT) 6710e3d5408SPeter Wemm mode.c_cc[VREPRINT] = CHK(mode.c_cc[VREPRINT], CRPRNT); 6720e3d5408SPeter Wemm #endif 6730e3d5408SPeter Wemm #if defined(VSTART) && defined(CSTART) 6740e3d5408SPeter Wemm mode.c_cc[VSTART] = CHK(mode.c_cc[VSTART], CSTART); 6750e3d5408SPeter Wemm #endif 6760e3d5408SPeter Wemm #if defined(VSTOP) && defined(CSTOP) 6770e3d5408SPeter Wemm mode.c_cc[VSTOP] = CHK(mode.c_cc[VSTOP], CSTOP); 6780e3d5408SPeter Wemm #endif 6790e3d5408SPeter Wemm #if defined(VSUSP) && defined(CSUSP) 6800e3d5408SPeter Wemm mode.c_cc[VSUSP] = CHK(mode.c_cc[VSUSP], CSUSP); 6810e3d5408SPeter Wemm #endif 6820e3d5408SPeter Wemm #if defined(VWERASE) && defined(CWERASE) 6830e3d5408SPeter Wemm mode.c_cc[VWERASE] = CHK(mode.c_cc[VWERASE], CWERASE); 6840e3d5408SPeter Wemm #endif 6850e3d5408SPeter Wemm 6860e3d5408SPeter Wemm mode.c_iflag &= ~(IGNBRK | PARMRK | INPCK | ISTRIP | INLCR | IGNCR 6870e3d5408SPeter Wemm #ifdef IUCLC 6880e3d5408SPeter Wemm | IUCLC 6890e3d5408SPeter Wemm #endif 6900e3d5408SPeter Wemm #ifdef IXANY 6910e3d5408SPeter Wemm | IXANY 6920e3d5408SPeter Wemm #endif 6930e3d5408SPeter Wemm | IXOFF); 6940e3d5408SPeter Wemm 6950e3d5408SPeter Wemm mode.c_iflag |= (BRKINT | IGNPAR | ICRNL | IXON 6960e3d5408SPeter Wemm #ifdef IMAXBEL 6970e3d5408SPeter Wemm | IMAXBEL 6980e3d5408SPeter Wemm #endif 6990e3d5408SPeter Wemm ); 7000e3d5408SPeter Wemm 7010e3d5408SPeter Wemm mode.c_oflag &= ~(0 7020e3d5408SPeter Wemm #ifdef OLCUC 7030e3d5408SPeter Wemm | OLCUC 7040e3d5408SPeter Wemm #endif 7050e3d5408SPeter Wemm #ifdef OCRNL 7060e3d5408SPeter Wemm | OCRNL 7070e3d5408SPeter Wemm #endif 7080e3d5408SPeter Wemm #ifdef ONOCR 7090e3d5408SPeter Wemm | ONOCR 7100e3d5408SPeter Wemm #endif 7110e3d5408SPeter Wemm #ifdef ONLRET 7120e3d5408SPeter Wemm | ONLRET 7130e3d5408SPeter Wemm #endif 7140e3d5408SPeter Wemm #ifdef OFILL 7150e3d5408SPeter Wemm | OFILL 7160e3d5408SPeter Wemm #endif 7170e3d5408SPeter Wemm #ifdef OFDEL 7180e3d5408SPeter Wemm | OFDEL 7190e3d5408SPeter Wemm #endif 7200e3d5408SPeter Wemm #ifdef NLDLY 7210e3d5408SPeter Wemm | NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY 7220e3d5408SPeter Wemm #endif 7230e3d5408SPeter Wemm ); 7240e3d5408SPeter Wemm 7250e3d5408SPeter Wemm mode.c_oflag |= (OPOST 7260e3d5408SPeter Wemm #ifdef ONLCR 7270e3d5408SPeter Wemm | ONLCR 7280e3d5408SPeter Wemm #endif 7290e3d5408SPeter Wemm ); 7300e3d5408SPeter Wemm 7310e3d5408SPeter Wemm mode.c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD | CLOCAL); 7320e3d5408SPeter Wemm mode.c_cflag |= (CS8 | CREAD); 7330e3d5408SPeter Wemm mode.c_lflag &= ~(ECHONL | NOFLSH 7340e3d5408SPeter Wemm #ifdef TOSTOP 7350e3d5408SPeter Wemm | TOSTOP 7360e3d5408SPeter Wemm #endif 7370e3d5408SPeter Wemm #ifdef ECHOPTR 7380e3d5408SPeter Wemm | ECHOPRT 7390e3d5408SPeter Wemm #endif 7400e3d5408SPeter Wemm #ifdef XCASE 7410e3d5408SPeter Wemm | XCASE 7420e3d5408SPeter Wemm #endif 7430e3d5408SPeter Wemm ); 7440e3d5408SPeter Wemm 7450e3d5408SPeter Wemm mode.c_lflag |= (ISIG | ICANON | ECHO | ECHOE | ECHOK 7460e3d5408SPeter Wemm #ifdef ECHOCTL 7470e3d5408SPeter Wemm | ECHOCTL 7480e3d5408SPeter Wemm #endif 7490e3d5408SPeter Wemm #ifdef ECHOKE 7500e3d5408SPeter Wemm | ECHOKE 7510e3d5408SPeter Wemm #endif 7520e3d5408SPeter Wemm ); 7530e3d5408SPeter Wemm #endif 7540e3d5408SPeter Wemm 7550e3d5408SPeter Wemm #ifdef TERMIOS 7560e3d5408SPeter Wemm tcsetattr(STDERR_FILENO, TCSADRAIN, &mode); 7570e3d5408SPeter Wemm #else 7580e3d5408SPeter Wemm stty(STDERR_FILENO, &mode); 7590e3d5408SPeter Wemm #endif 7600e3d5408SPeter Wemm } 7610e3d5408SPeter Wemm 7620e3d5408SPeter Wemm /* 7630e3d5408SPeter Wemm * Returns a "good" value for the erase character. This is loosely based on 7640e3d5408SPeter Wemm * the BSD4.4 logic. 7650e3d5408SPeter Wemm */ 7660e3d5408SPeter Wemm static int 7670e3d5408SPeter Wemm default_erase(void) 7680e3d5408SPeter Wemm { 7690e3d5408SPeter Wemm int result; 7700e3d5408SPeter Wemm 7710e3d5408SPeter Wemm if (over_strike 7720e3d5408SPeter Wemm && key_backspace != 0 7730e3d5408SPeter Wemm && strlen(key_backspace) == 1) 7740e3d5408SPeter Wemm result = key_backspace[0]; 7750e3d5408SPeter Wemm else 7760e3d5408SPeter Wemm result = CERASE; 7770e3d5408SPeter Wemm 7780e3d5408SPeter Wemm return result; 7790e3d5408SPeter Wemm } 7800e3d5408SPeter Wemm 7810e3d5408SPeter Wemm /* 7820e3d5408SPeter Wemm * Update the values of the erase, interrupt, and kill characters in 'mode'. 7830e3d5408SPeter Wemm * 7840e3d5408SPeter Wemm * SVr4 tset (e.g., Solaris 2.5) only modifies the intr, quit or erase 7850e3d5408SPeter Wemm * characters if they're unset, or if we specify them as options. This differs 7860e3d5408SPeter Wemm * from BSD 4.4 tset, which always sets erase. 7870e3d5408SPeter Wemm */ 7880e3d5408SPeter Wemm static void 7890e3d5408SPeter Wemm set_control_chars(void) 7900e3d5408SPeter Wemm { 7910e3d5408SPeter Wemm #ifdef TERMIOS 7920e3d5408SPeter Wemm if (mode.c_cc[VERASE] == 0 || terasechar >= 0) 7930e3d5408SPeter Wemm mode.c_cc[VERASE] = terasechar >= 0 ? terasechar : default_erase(); 7940e3d5408SPeter Wemm 7950e3d5408SPeter Wemm if (mode.c_cc[VINTR] == 0 || intrchar >= 0) 7960e3d5408SPeter Wemm mode.c_cc[VINTR] = intrchar >= 0 ? intrchar : CINTR; 7970e3d5408SPeter Wemm 7980e3d5408SPeter Wemm if (mode.c_cc[VKILL] == 0 || tkillchar >= 0) 7990e3d5408SPeter Wemm mode.c_cc[VKILL] = tkillchar >= 0 ? tkillchar : CKILL; 8000e3d5408SPeter Wemm #endif 8010e3d5408SPeter Wemm } 8020e3d5408SPeter Wemm 8030e3d5408SPeter Wemm /* 8040e3d5408SPeter Wemm * Set up various conversions in 'mode', including parity, tabs, returns, 8050e3d5408SPeter Wemm * echo, and case, according to the termcap entry. If the program we're 8060e3d5408SPeter Wemm * running was named with a leading upper-case character, map external 8070e3d5408SPeter Wemm * uppercase to internal lowercase. 8080e3d5408SPeter Wemm */ 8090e3d5408SPeter Wemm static void 8100e3d5408SPeter Wemm set_conversions(void) 8110e3d5408SPeter Wemm { 8120e3d5408SPeter Wemm #ifdef __OBSOLETE__ 8130e3d5408SPeter Wemm /* 8140e3d5408SPeter Wemm * Conversion logic for some *really* ancient terminal glitches, 8150e3d5408SPeter Wemm * not supported in terminfo. Left here for succeeding generations 8160e3d5408SPeter Wemm * to marvel at. 8170e3d5408SPeter Wemm */ 8180e3d5408SPeter Wemm if (tgetflag("UC")) { 8190e3d5408SPeter Wemm #ifdef IUCLC 8200e3d5408SPeter Wemm mode.c_iflag |= IUCLC; 8210e3d5408SPeter Wemm mode.c_oflag |= OLCUC; 8220e3d5408SPeter Wemm #endif 8230e3d5408SPeter Wemm } else if (tgetflag("LC")) { 8240e3d5408SPeter Wemm #ifdef IUCLC 8250e3d5408SPeter Wemm mode.c_iflag &= ~IUCLC; 8260e3d5408SPeter Wemm mode.c_oflag &= ~OLCUC; 8270e3d5408SPeter Wemm #endif 8280e3d5408SPeter Wemm } 8290e3d5408SPeter Wemm mode.c_iflag &= ~(PARMRK | INPCK); 8300e3d5408SPeter Wemm mode.c_lflag |= ICANON; 8310e3d5408SPeter Wemm if (tgetflag("EP")) { 8320e3d5408SPeter Wemm mode.c_cflag |= PARENB; 8330e3d5408SPeter Wemm mode.c_cflag &= ~PARODD; 8340e3d5408SPeter Wemm } 8350e3d5408SPeter Wemm if (tgetflag("OP")) { 8360e3d5408SPeter Wemm mode.c_cflag |= PARENB; 8370e3d5408SPeter Wemm mode.c_cflag |= PARODD; 8380e3d5408SPeter Wemm } 8390e3d5408SPeter Wemm #endif /* __OBSOLETE__ */ 8400e3d5408SPeter Wemm 8410e3d5408SPeter Wemm #ifdef TERMIOS 8420e3d5408SPeter Wemm #ifdef ONLCR 8430e3d5408SPeter Wemm mode.c_oflag |= ONLCR; 8440e3d5408SPeter Wemm #endif 8450e3d5408SPeter Wemm mode.c_iflag |= ICRNL; 8460e3d5408SPeter Wemm mode.c_lflag |= ECHO; 8470e3d5408SPeter Wemm #ifdef OXTABS 8480e3d5408SPeter Wemm mode.c_oflag |= OXTABS; 8490e3d5408SPeter Wemm #endif /* OXTABS */ 8500e3d5408SPeter Wemm 8510e3d5408SPeter Wemm /* test used to be tgetflag("NL") */ 8520e3d5408SPeter Wemm if (newline != (char *)0 && newline[0] == '\n' && !newline[1]) { 8530e3d5408SPeter Wemm /* Newline, not linefeed. */ 8540e3d5408SPeter Wemm #ifdef ONLCR 8550e3d5408SPeter Wemm mode.c_oflag &= ~ONLCR; 8560e3d5408SPeter Wemm #endif 8570e3d5408SPeter Wemm mode.c_iflag &= ~ICRNL; 8580e3d5408SPeter Wemm } 8590e3d5408SPeter Wemm #ifdef __OBSOLETE__ 8600e3d5408SPeter Wemm if (tgetflag("HD")) /* Half duplex. */ 8610e3d5408SPeter Wemm mode.c_lflag &= ~ECHO; 8620e3d5408SPeter Wemm #endif /* __OBSOLETE__ */ 8630e3d5408SPeter Wemm #ifdef OXTABS 8640e3d5408SPeter Wemm /* test used to be tgetflag("pt") */ 8650e3d5408SPeter Wemm if (has_hardware_tabs) /* Print tabs. */ 8660e3d5408SPeter Wemm mode.c_oflag &= ~OXTABS; 8670e3d5408SPeter Wemm #endif /* OXTABS */ 8680e3d5408SPeter Wemm mode.c_lflag |= (ECHOE | ECHOK); 8690e3d5408SPeter Wemm #endif 8700e3d5408SPeter Wemm } 8710e3d5408SPeter Wemm 8720e3d5408SPeter Wemm /* Output startup string. */ 8730e3d5408SPeter Wemm static void 8740e3d5408SPeter Wemm set_init(void) 8750e3d5408SPeter Wemm { 8760e3d5408SPeter Wemm char *p; 8770e3d5408SPeter Wemm bool settle; 8780e3d5408SPeter Wemm 8790e3d5408SPeter Wemm #ifdef __OBSOLETE__ 8800e3d5408SPeter Wemm if (pad_char != (char *)0) /* Get/set pad character. */ 8810e3d5408SPeter Wemm PC = pad_char[0]; 8820e3d5408SPeter Wemm #endif /* OBSOLETE */ 8830e3d5408SPeter Wemm 8840e3d5408SPeter Wemm #ifdef TAB3 8850e3d5408SPeter Wemm if (oldmode.c_oflag & (TAB3 | ONLCR | OCRNL | ONLRET)) { 8860e3d5408SPeter Wemm oldmode.c_oflag &= (TAB3 | ONLCR | OCRNL | ONLRET); 8870e3d5408SPeter Wemm tcsetattr(STDERR_FILENO, TCSADRAIN, &oldmode); 8880e3d5408SPeter Wemm } 8890e3d5408SPeter Wemm #endif 8900e3d5408SPeter Wemm settle = set_tabs(); 8910e3d5408SPeter Wemm 8920e3d5408SPeter Wemm if (isreset) { 8930e3d5408SPeter Wemm if ((p = reset_1string) != 0) { 8940e3d5408SPeter Wemm tputs(p, 0, outc); 8950e3d5408SPeter Wemm settle = TRUE; 8960e3d5408SPeter Wemm } 8970e3d5408SPeter Wemm if ((p = reset_2string) != 0) { 8980e3d5408SPeter Wemm tputs(p, 0, outc); 8990e3d5408SPeter Wemm settle = TRUE; 9000e3d5408SPeter Wemm } 9010e3d5408SPeter Wemm /* What about rf, rs3, as per terminfo man page? */ 9020e3d5408SPeter Wemm /* also might be nice to send rmacs, rmul, rmm */ 9030e3d5408SPeter Wemm if ((p = reset_file) != 0 9040e3d5408SPeter Wemm || (p = init_file) != 0) { 9050e3d5408SPeter Wemm cat(p); 9060e3d5408SPeter Wemm settle = TRUE; 9070e3d5408SPeter Wemm } 9080e3d5408SPeter Wemm } 9090e3d5408SPeter Wemm 9100e3d5408SPeter Wemm if (settle) { 9110e3d5408SPeter Wemm (void)putc('\r', stderr); 9120e3d5408SPeter Wemm (void)fflush(stderr); 9130e3d5408SPeter Wemm (void)napms(1000); /* Settle the terminal. */ 9140e3d5408SPeter Wemm } 9150e3d5408SPeter Wemm } 9160e3d5408SPeter Wemm 9170e3d5408SPeter Wemm /* 9180e3d5408SPeter Wemm * Set the hardware tabs on the terminal, using the ct (clear all tabs), 9190e3d5408SPeter Wemm * st (set one tab) and ch (horizontal cursor addressing) capabilities. 9200e3d5408SPeter Wemm * This is done before if and is, so they can patch in case we blow this. 9210e3d5408SPeter Wemm * Return TRUE if we set any tab stops, FALSE if not. 9220e3d5408SPeter Wemm */ 9230e3d5408SPeter Wemm static bool 9240e3d5408SPeter Wemm set_tabs() 9250e3d5408SPeter Wemm { 9260e3d5408SPeter Wemm if (set_tab && clear_all_tabs) { 9270e3d5408SPeter Wemm int c; 9280e3d5408SPeter Wemm 9290e3d5408SPeter Wemm (void)putc('\r', stderr); /* Force to left margin. */ 9300e3d5408SPeter Wemm tputs(clear_all_tabs, 0, outc); 9310e3d5408SPeter Wemm 9320e3d5408SPeter Wemm for (c = 8; c < tcolumns; c += 8) { 9330e3d5408SPeter Wemm /* Get to the right column. In BSD tset, this 9340e3d5408SPeter Wemm * used to try a bunch of half-clever things 9350e3d5408SPeter Wemm * with cup and hpa, for an average saving of 9360e3d5408SPeter Wemm * somewhat less than two character times per 9370e3d5408SPeter Wemm * tab stop, less that .01 sec at 2400cps. We 9380e3d5408SPeter Wemm * lost all this cruft because it seemed to be 9390e3d5408SPeter Wemm * introducing some odd bugs. 9400e3d5408SPeter Wemm * ----------12345678----------- */ 9410e3d5408SPeter Wemm (void)fputs(" ", stderr); 9420e3d5408SPeter Wemm tputs(set_tab, 0, outc); 9430e3d5408SPeter Wemm } 9440e3d5408SPeter Wemm putc('\r', stderr); 9450e3d5408SPeter Wemm return (TRUE); 9460e3d5408SPeter Wemm } 9470e3d5408SPeter Wemm return (FALSE); 9480e3d5408SPeter Wemm } 9490e3d5408SPeter Wemm 9500e3d5408SPeter Wemm /************************************************************************** 9510e3d5408SPeter Wemm * 9520e3d5408SPeter Wemm * Main sequence 9530e3d5408SPeter Wemm * 9540e3d5408SPeter Wemm **************************************************************************/ 9550e3d5408SPeter Wemm 9560e3d5408SPeter Wemm /* 9570e3d5408SPeter Wemm * Tell the user if a control key has been changed from the default value. 9580e3d5408SPeter Wemm */ 9590e3d5408SPeter Wemm static void 9600e3d5408SPeter Wemm report(const char *name, int which, unsigned def) 9610e3d5408SPeter Wemm { 9620e3d5408SPeter Wemm #ifdef TERMIOS 9630e3d5408SPeter Wemm unsigned older, newer; 9640e3d5408SPeter Wemm char *p; 9650e3d5408SPeter Wemm 9660e3d5408SPeter Wemm newer = mode.c_cc[which]; 9670e3d5408SPeter Wemm older = oldmode.c_cc[which]; 9680e3d5408SPeter Wemm 9690e3d5408SPeter Wemm if (older == newer && older == def) 9700e3d5408SPeter Wemm return; 9710e3d5408SPeter Wemm 9720e3d5408SPeter Wemm (void)fprintf(stderr, "%s %s ", name, older == newer ? "is" : "set to"); 9730e3d5408SPeter Wemm 9740e3d5408SPeter Wemm /* 9750e3d5408SPeter Wemm * Check 'delete' before 'backspace', since the key_backspace value 9760e3d5408SPeter Wemm * is ambiguous. 9770e3d5408SPeter Wemm */ 9780e3d5408SPeter Wemm if (newer == 0177) 9790e3d5408SPeter Wemm (void)fprintf(stderr, "delete.\n"); 9800e3d5408SPeter Wemm else if ((p = key_backspace) != 0 9810e3d5408SPeter Wemm && newer == (unsigned char)p[0] 9820e3d5408SPeter Wemm && p[1] == '\0') 9830e3d5408SPeter Wemm (void)fprintf(stderr, "backspace.\n"); 9840e3d5408SPeter Wemm else if (newer < 040) { 9850e3d5408SPeter Wemm newer ^= 0100; 9860e3d5408SPeter Wemm (void)fprintf(stderr, "control-%c (^%c).\n", newer, newer); 9870e3d5408SPeter Wemm } else 9880e3d5408SPeter Wemm (void)fprintf(stderr, "%c.\n", newer); 9890e3d5408SPeter Wemm #endif 9900e3d5408SPeter Wemm } 9910e3d5408SPeter Wemm 9920e3d5408SPeter Wemm /* 9930e3d5408SPeter Wemm * Convert the obsolete argument forms into something that getopt can handle. 9940e3d5408SPeter Wemm * This means that -e, -i and -k get default arguments supplied for them. 9950e3d5408SPeter Wemm */ 9960e3d5408SPeter Wemm static void 9970e3d5408SPeter Wemm obsolete(char **argv) 9980e3d5408SPeter Wemm { 9990e3d5408SPeter Wemm for (; *argv; ++argv) { 10000e3d5408SPeter Wemm char *parm = argv[0]; 10010e3d5408SPeter Wemm 10020e3d5408SPeter Wemm if (parm[0] == '-' && parm[1] == '\0') 10030e3d5408SPeter Wemm { 10040e3d5408SPeter Wemm argv[0] = strdup("-q"); 10050e3d5408SPeter Wemm continue; 10060e3d5408SPeter Wemm } 10070e3d5408SPeter Wemm 10080e3d5408SPeter Wemm if ((parm[0] != '-') 10090e3d5408SPeter Wemm || (argv[1] && argv[1][0] != '-') 10100e3d5408SPeter Wemm || (parm[1] != 'e' && parm[1] != 'i' && parm[1] != 'k') 10110e3d5408SPeter Wemm || (parm[2] != '\0')) 10120e3d5408SPeter Wemm continue; 10130e3d5408SPeter Wemm switch(argv[0][1]) { 10140e3d5408SPeter Wemm case 'e': 10150e3d5408SPeter Wemm argv[0] = strdup("-e^H"); 10160e3d5408SPeter Wemm break; 10170e3d5408SPeter Wemm case 'i': 10180e3d5408SPeter Wemm argv[0] = strdup("-i^C"); 10190e3d5408SPeter Wemm break; 10200e3d5408SPeter Wemm case 'k': 10210e3d5408SPeter Wemm argv[0] = strdup("-k^U"); 10220e3d5408SPeter Wemm break; 10230e3d5408SPeter Wemm } 10240e3d5408SPeter Wemm } 10250e3d5408SPeter Wemm } 10260e3d5408SPeter Wemm 10270e3d5408SPeter Wemm static void 10280e3d5408SPeter Wemm usage(const char* pname) 10290e3d5408SPeter Wemm { 10300e3d5408SPeter Wemm (void)fprintf(stderr, 10310e3d5408SPeter Wemm "usage: %s [-IQrs] [-] [-e ch] [-i ch] [-k ch] [-m mapping] [terminal]\n", pname); 10320e3d5408SPeter Wemm exit(EXIT_FAILURE); 10330e3d5408SPeter Wemm } 10340e3d5408SPeter Wemm 10350e3d5408SPeter Wemm static char arg_to_char(void) 10360e3d5408SPeter Wemm { 10370e3d5408SPeter Wemm return (optarg[0] == '^' && optarg[1] != '\0') 10380e3d5408SPeter Wemm ? ((optarg[1] == '?') ? '\177' : CTRL(optarg[1])) 10390e3d5408SPeter Wemm : optarg[0]; 10400e3d5408SPeter Wemm } 10410e3d5408SPeter Wemm 10420e3d5408SPeter Wemm int 10430e3d5408SPeter Wemm main(int argc, char **argv) 10440e3d5408SPeter Wemm { 10450e3d5408SPeter Wemm #if defined(TIOCGWINSZ) && defined(TIOCSWINSZ) 10460e3d5408SPeter Wemm struct winsize win; 10470e3d5408SPeter Wemm #endif 10480e3d5408SPeter Wemm int ch, noinit, noset, quiet, Sflag, sflag, showterm; 10490e3d5408SPeter Wemm const char *p; 10500e3d5408SPeter Wemm const char *ttype; 10510e3d5408SPeter Wemm 10520e3d5408SPeter Wemm #ifdef TERMIOS 10530e3d5408SPeter Wemm if (tcgetattr(STDERR_FILENO, &mode) < 0) 10540e3d5408SPeter Wemm failed("standard error"); 10550e3d5408SPeter Wemm 10560e3d5408SPeter Wemm oldmode = mode; 10570e3d5408SPeter Wemm ospeed = cfgetospeed(&mode); 10580e3d5408SPeter Wemm #else 10590e3d5408SPeter Wemm if (gtty(STDERR_FILENO, &mode) < 0) 10600e3d5408SPeter Wemm failed("standard error"); 10610e3d5408SPeter Wemm 10620e3d5408SPeter Wemm oldmode = mode; 10630e3d5408SPeter Wemm ospeed = mode.sg_ospeed; 10640e3d5408SPeter Wemm #endif 10650e3d5408SPeter Wemm 10660e3d5408SPeter Wemm if ((p = strrchr(*argv, '/')) != 0) 10670e3d5408SPeter Wemm ++p; 10680e3d5408SPeter Wemm else 10690e3d5408SPeter Wemm p = *argv; 10700e3d5408SPeter Wemm if (!CaselessCmp(p, "reset")) { 10710e3d5408SPeter Wemm isreset = 1; 10720e3d5408SPeter Wemm reset_mode(); 10730e3d5408SPeter Wemm } 10740e3d5408SPeter Wemm 10750e3d5408SPeter Wemm obsolete(argv); 10760e3d5408SPeter Wemm noinit = noset = quiet = Sflag = sflag = showterm = 0; 10770e3d5408SPeter Wemm while ((ch = getopt(argc, argv, "a:d:e:Ii:k:m:np:qQSrs")) != EOF) { 10780e3d5408SPeter Wemm switch (ch) { 10790e3d5408SPeter Wemm case 'q': /* display term only */ 10800e3d5408SPeter Wemm noset = 1; 10810e3d5408SPeter Wemm break; 10820e3d5408SPeter Wemm case 'a': /* OBSOLETE: map identifier to type */ 10830e3d5408SPeter Wemm add_mapping("arpanet", optarg); 10840e3d5408SPeter Wemm break; 10850e3d5408SPeter Wemm case 'd': /* OBSOLETE: map identifier to type */ 10860e3d5408SPeter Wemm add_mapping("dialup", optarg); 10870e3d5408SPeter Wemm break; 10880e3d5408SPeter Wemm case 'e': /* erase character */ 10890e3d5408SPeter Wemm terasechar = arg_to_char(); 10900e3d5408SPeter Wemm break; 10910e3d5408SPeter Wemm case 'I': /* no initialization strings */ 10920e3d5408SPeter Wemm noinit = 1; 10930e3d5408SPeter Wemm break; 10940e3d5408SPeter Wemm case 'i': /* interrupt character */ 10950e3d5408SPeter Wemm intrchar = arg_to_char(); 10960e3d5408SPeter Wemm break; 10970e3d5408SPeter Wemm case 'k': /* kill character */ 10980e3d5408SPeter Wemm tkillchar = arg_to_char(); 10990e3d5408SPeter Wemm break; 11000e3d5408SPeter Wemm case 'm': /* map identifier to type */ 11010e3d5408SPeter Wemm add_mapping(0, optarg); 11020e3d5408SPeter Wemm break; 11030e3d5408SPeter Wemm case 'n': /* OBSOLETE: set new tty driver */ 11040e3d5408SPeter Wemm break; 11050e3d5408SPeter Wemm case 'p': /* OBSOLETE: map identifier to type */ 11060e3d5408SPeter Wemm add_mapping("plugboard", optarg); 11070e3d5408SPeter Wemm break; 11080e3d5408SPeter Wemm case 'Q': /* don't output control key settings */ 11090e3d5408SPeter Wemm quiet = 1; 11100e3d5408SPeter Wemm break; 11110e3d5408SPeter Wemm case 'S': /* OBSOLETE: output TERM & TERMCAP */ 11120e3d5408SPeter Wemm Sflag = 1; 11130e3d5408SPeter Wemm break; 11140e3d5408SPeter Wemm case 'r': /* display term on stderr */ 11150e3d5408SPeter Wemm showterm = 1; 11160e3d5408SPeter Wemm break; 11170e3d5408SPeter Wemm case 's': /* output TERM set command */ 11180e3d5408SPeter Wemm sflag = 1; 11190e3d5408SPeter Wemm break; 11200e3d5408SPeter Wemm case '?': 11210e3d5408SPeter Wemm default: 11220e3d5408SPeter Wemm usage(*argv); 11230e3d5408SPeter Wemm } 11240e3d5408SPeter Wemm } 11250e3d5408SPeter Wemm argc -= optind; 11260e3d5408SPeter Wemm argv += optind; 11270e3d5408SPeter Wemm 11280e3d5408SPeter Wemm if (argc > 1) 11290e3d5408SPeter Wemm usage(*argv); 11300e3d5408SPeter Wemm 11310e3d5408SPeter Wemm ttype = get_termcap_entry(*argv); 11320e3d5408SPeter Wemm 11330e3d5408SPeter Wemm if (!noset) { 11340e3d5408SPeter Wemm tcolumns = columns; 11350e3d5408SPeter Wemm tlines = lines; 11360e3d5408SPeter Wemm 11370e3d5408SPeter Wemm #if defined(TIOCGWINSZ) && defined(TIOCSWINSZ) 11380e3d5408SPeter Wemm /* Set window size */ 11390e3d5408SPeter Wemm (void)ioctl(STDERR_FILENO, TIOCGWINSZ, &win); 11400e3d5408SPeter Wemm if (win.ws_row == 0 && win.ws_col == 0 && 11410e3d5408SPeter Wemm tlines > 0 && tcolumns > 0) { 11420e3d5408SPeter Wemm win.ws_row = tlines; 11430e3d5408SPeter Wemm win.ws_col = tcolumns; 11440e3d5408SPeter Wemm (void)ioctl(STDERR_FILENO, TIOCSWINSZ, &win); 11450e3d5408SPeter Wemm } 11460e3d5408SPeter Wemm #endif 11470e3d5408SPeter Wemm set_control_chars(); 11480e3d5408SPeter Wemm set_conversions(); 11490e3d5408SPeter Wemm 11500e3d5408SPeter Wemm if (!noinit) 11510e3d5408SPeter Wemm set_init(); 11520e3d5408SPeter Wemm 11530e3d5408SPeter Wemm /* Set the modes if they've changed. */ 11540e3d5408SPeter Wemm if (memcmp(&mode, &oldmode, sizeof(mode))) 11550e3d5408SPeter Wemm #ifdef TERMIOS 11560e3d5408SPeter Wemm tcsetattr(STDERR_FILENO, TCSADRAIN, &mode); 11570e3d5408SPeter Wemm #else 11580e3d5408SPeter Wemm stty(STDERR_FILENO, &mode); 11590e3d5408SPeter Wemm #endif 11600e3d5408SPeter Wemm } 11610e3d5408SPeter Wemm 11620e3d5408SPeter Wemm /* Get the terminal name from the entry. */ 11630e3d5408SPeter Wemm ttype = _nc_first_name(cur_term->type.term_names); 11640e3d5408SPeter Wemm 11650e3d5408SPeter Wemm if (noset) 11660e3d5408SPeter Wemm (void)printf("%s\n", ttype); 11670e3d5408SPeter Wemm else { 11680e3d5408SPeter Wemm if (showterm) 11690e3d5408SPeter Wemm (void)fprintf(stderr, "Terminal type is %s.\n", ttype); 11700e3d5408SPeter Wemm /* 11710e3d5408SPeter Wemm * If erase, kill and interrupt characters could have been 11720e3d5408SPeter Wemm * modified and not -Q, display the changes. 11730e3d5408SPeter Wemm */ 11740e3d5408SPeter Wemm if (!quiet) { 11750e3d5408SPeter Wemm report("Erase", VERASE, CERASE); 11760e3d5408SPeter Wemm report("Kill", VKILL, CINTR); 11770e3d5408SPeter Wemm report("Interrupt", VINTR, CKILL); 11780e3d5408SPeter Wemm } 11790e3d5408SPeter Wemm } 11800e3d5408SPeter Wemm 11810e3d5408SPeter Wemm if (Sflag) 11820e3d5408SPeter Wemm err("The -S option is not supported under terminfo."); 11830e3d5408SPeter Wemm 11840e3d5408SPeter Wemm if (sflag) { 11850e3d5408SPeter Wemm /* 11860e3d5408SPeter Wemm * Figure out what shell we're using. A hack, we look for an 11870e3d5408SPeter Wemm * environmental variable SHELL ending in "csh". 11880e3d5408SPeter Wemm */ 11890e3d5408SPeter Wemm if ((p = getenv("SHELL")) != 0 11900e3d5408SPeter Wemm && !strcmp(p + strlen(p) - 3, "csh")) 11910e3d5408SPeter Wemm p = "set noglob;\nsetenv TERM %s;\nunset noglob;\n"; 11920e3d5408SPeter Wemm else 11930e3d5408SPeter Wemm p = "TERM=%s;\n"; 11940e3d5408SPeter Wemm (void) printf(p, ttype); 11950e3d5408SPeter Wemm } 11960e3d5408SPeter Wemm 11970e3d5408SPeter Wemm return EXIT_SUCCESS; 11980e3d5408SPeter Wemm } 11990e3d5408SPeter Wemm 12000e3d5408SPeter Wemm /* tset.c ends here */ 1201