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