10e3d5408SPeter Wemm /**************************************************************************** 2*e1865124SBaptiste Daroussin * Copyright 2020 Thomas E. Dickey * 3*e1865124SBaptiste Daroussin * Copyright 1998-2016,2017 Free Software Foundation, Inc. * 40e3d5408SPeter Wemm * * 50e3d5408SPeter Wemm * Permission is hereby granted, free of charge, to any person obtaining a * 60e3d5408SPeter Wemm * copy of this software and associated documentation files (the * 70e3d5408SPeter Wemm * "Software"), to deal in the Software without restriction, including * 80e3d5408SPeter Wemm * without limitation the rights to use, copy, modify, merge, publish, * 90e3d5408SPeter Wemm * distribute, distribute with modifications, sublicense, and/or sell * 100e3d5408SPeter Wemm * copies of the Software, and to permit persons to whom the Software is * 110e3d5408SPeter Wemm * furnished to do so, subject to the following conditions: * 120e3d5408SPeter Wemm * * 130e3d5408SPeter Wemm * The above copyright notice and this permission notice shall be included * 140e3d5408SPeter Wemm * in all copies or substantial portions of the Software. * 150e3d5408SPeter Wemm * * 160e3d5408SPeter Wemm * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 170e3d5408SPeter Wemm * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 180e3d5408SPeter Wemm * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 190e3d5408SPeter Wemm * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 200e3d5408SPeter Wemm * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 210e3d5408SPeter Wemm * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 220e3d5408SPeter Wemm * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 230e3d5408SPeter Wemm * * 240e3d5408SPeter Wemm * Except as contained in this notice, the name(s) of the above copyright * 250e3d5408SPeter Wemm * holders shall not be used in advertising or otherwise to promote the * 260e3d5408SPeter Wemm * sale, use or other dealings in this Software without prior written * 270e3d5408SPeter Wemm * authorization. * 280e3d5408SPeter Wemm ****************************************************************************/ 290e3d5408SPeter Wemm 300e3d5408SPeter Wemm /**************************************************************************** 310e3d5408SPeter Wemm * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * 320e3d5408SPeter Wemm * and: Eric S. Raymond <esr@snark.thyrsus.com> * 334a1a9510SRong-En Fan * and: Thomas E. Dickey 1996-on * 340e3d5408SPeter Wemm ****************************************************************************/ 350e3d5408SPeter Wemm 360e3d5408SPeter Wemm /* 3706bfebdeSXin LI * Notes: 3806bfebdeSXin LI * The initial adaptation from 4.4BSD Lite sources in September 1995 used 686 3906bfebdeSXin LI * lines from that version, and made changes/additions for 150 lines. There 4006bfebdeSXin LI * was no reformatting, so with/without ignoring whitespace, the amount of 4106bfebdeSXin LI * change is the same. 4206bfebdeSXin LI * 4306bfebdeSXin LI * Comparing with current (2009) source, excluding this comment: 4406bfebdeSXin LI * a) 209 lines match identically to the 4.4BSD Lite sources, with 771 lines 4506bfebdeSXin LI * changed/added. 4606bfebdeSXin LI * a) Ignoring whitespace, the current version still uses 516 lines from the 4706bfebdeSXin LI * 4.4BSD Lite sources, with 402 lines changed/added. 4806bfebdeSXin LI * 4906bfebdeSXin LI * Raymond's original comment on this follows... 5006bfebdeSXin LI */ 5106bfebdeSXin LI 5206bfebdeSXin LI /* 530e3d5408SPeter Wemm * tset.c - terminal initialization utility 540e3d5408SPeter Wemm * 550e3d5408SPeter Wemm * This code was mostly swiped from 4.4BSD tset, with some obsolescent 560e3d5408SPeter Wemm * cruft removed and substantial portions rewritten. A Regents of the 570e3d5408SPeter Wemm * University of California copyright applies to some portions of the 580e3d5408SPeter Wemm * code, and is reproduced below: 590e3d5408SPeter Wemm */ 600e3d5408SPeter Wemm /*- 610e3d5408SPeter Wemm * Copyright (c) 1980, 1991, 1993 620e3d5408SPeter Wemm * The Regents of the University of California. All rights reserved. 630e3d5408SPeter Wemm * 640e3d5408SPeter Wemm * Redistribution and use in source and binary forms, with or without 650e3d5408SPeter Wemm * modification, are permitted provided that the following conditions 660e3d5408SPeter Wemm * are met: 670e3d5408SPeter Wemm * 1. Redistributions of source code must retain the above copyright 680e3d5408SPeter Wemm * notice, this list of conditions and the following disclaimer. 690e3d5408SPeter Wemm * 2. Redistributions in binary form must reproduce the above copyright 700e3d5408SPeter Wemm * notice, this list of conditions and the following disclaimer in the 710e3d5408SPeter Wemm * documentation and/or other materials provided with the distribution. 7206bfebdeSXin LI * 3. Neither the name of the University nor the names of its contributors 730e3d5408SPeter Wemm * may be used to endorse or promote products derived from this software 740e3d5408SPeter Wemm * without specific prior written permission. 750e3d5408SPeter Wemm * 760e3d5408SPeter Wemm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 770e3d5408SPeter Wemm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 780e3d5408SPeter Wemm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 790e3d5408SPeter Wemm * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 800e3d5408SPeter Wemm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 810e3d5408SPeter Wemm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 820e3d5408SPeter Wemm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 830e3d5408SPeter Wemm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 840e3d5408SPeter Wemm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 850e3d5408SPeter Wemm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 860e3d5408SPeter Wemm * SUCH DAMAGE. 870e3d5408SPeter Wemm */ 880e3d5408SPeter Wemm 89aae38d10SBaptiste Daroussin #include <reset_cmd.h> 900e3d5408SPeter Wemm #include <termcap.h> 91aae38d10SBaptiste Daroussin #include <transform.h> 92aae38d10SBaptiste Daroussin #include <tty_settings.h> 930e3d5408SPeter Wemm 940e3d5408SPeter Wemm #if HAVE_GETTTYNAM && HAVE_TTYENT_H 950e3d5408SPeter Wemm #include <ttyent.h> 960e3d5408SPeter Wemm #endif 970e3d5408SPeter Wemm #ifdef NeXT 980e3d5408SPeter Wemm char *ttyname(int fd); 990e3d5408SPeter Wemm #endif 1000e3d5408SPeter Wemm 101*e1865124SBaptiste Daroussin MODULE_ID("$Id: tset.c,v 1.121 2020/02/02 23:34:34 tom Exp $") 1020e3d5408SPeter Wemm 10306bfebdeSXin LI #ifndef environ 1040e3d5408SPeter Wemm extern char **environ; 10506bfebdeSXin LI #endif 1060e3d5408SPeter Wemm 1070e3d5408SPeter Wemm const char *_nc_progname = "tset"; 1080e3d5408SPeter Wemm 10939f2269fSPeter Wemm #define LOWERCASE(c) ((isalpha(UChar(c)) && isupper(UChar(c))) ? tolower(UChar(c)) : (c)) 1100e3d5408SPeter Wemm 111aae38d10SBaptiste Daroussin static void exit_error(void) GCC_NORETURN; 112aae38d10SBaptiste Daroussin 1130e3d5408SPeter Wemm static int 11415589c42SPeter Wemm CaselessCmp(const char *a, const char *b) 11515589c42SPeter Wemm { /* strcasecmp isn't portable */ 1160e3d5408SPeter Wemm while (*a && *b) { 1170e3d5408SPeter Wemm int cmp = LOWERCASE(*a) - LOWERCASE(*b); 1180e3d5408SPeter Wemm if (cmp != 0) 1190e3d5408SPeter Wemm break; 1200e3d5408SPeter Wemm a++, b++; 1210e3d5408SPeter Wemm } 1220e3d5408SPeter Wemm return LOWERCASE(*a) - LOWERCASE(*b); 1230e3d5408SPeter Wemm } 1240e3d5408SPeter Wemm 1250e3d5408SPeter Wemm static void 12639f2269fSPeter Wemm exit_error(void) 12739f2269fSPeter Wemm { 128aae38d10SBaptiste Daroussin restore_tty_settings(); 12939f2269fSPeter Wemm (void) fprintf(stderr, "\n"); 13039f2269fSPeter Wemm fflush(stderr); 1314a1a9510SRong-En Fan ExitProgram(EXIT_FAILURE); 13239f2269fSPeter Wemm /* NOTREACHED */ 13339f2269fSPeter Wemm } 13439f2269fSPeter Wemm 13539f2269fSPeter Wemm static void 1360e3d5408SPeter Wemm err(const char *fmt,...) 1370e3d5408SPeter Wemm { 1380e3d5408SPeter Wemm va_list ap; 1390e3d5408SPeter Wemm va_start(ap, fmt); 1404a1a9510SRong-En Fan (void) fprintf(stderr, "%s: ", _nc_progname); 1410e3d5408SPeter Wemm (void) vfprintf(stderr, fmt, ap); 1420e3d5408SPeter Wemm va_end(ap); 14339f2269fSPeter Wemm exit_error(); 1440e3d5408SPeter Wemm /* NOTREACHED */ 1450e3d5408SPeter Wemm } 1460e3d5408SPeter Wemm 1470e3d5408SPeter Wemm static void 1480e3d5408SPeter Wemm failed(const char *msg) 1490e3d5408SPeter Wemm { 1500e3d5408SPeter Wemm char temp[BUFSIZ]; 15173f0a83dSXin LI size_t len = strlen(_nc_progname) + 2; 1524a1a9510SRong-En Fan 1535d08fb1fSRong-En Fan if ((int) len < (int) sizeof(temp) - 12) { 15473f0a83dSXin LI _nc_STRCPY(temp, _nc_progname, sizeof(temp)); 15573f0a83dSXin LI _nc_STRCAT(temp, ": ", sizeof(temp)); 1564a1a9510SRong-En Fan } else { 15773f0a83dSXin LI _nc_STRCPY(temp, "tset: ", sizeof(temp)); 1584a1a9510SRong-En Fan } 159aae38d10SBaptiste Daroussin _nc_STRNCAT(temp, msg, sizeof(temp), sizeof(temp) - strlen(temp) - 2); 160aae38d10SBaptiste Daroussin perror(temp); 16139f2269fSPeter Wemm exit_error(); 1620e3d5408SPeter Wemm /* NOTREACHED */ 1630e3d5408SPeter Wemm } 1640e3d5408SPeter Wemm 1650e3d5408SPeter Wemm /* Prompt the user for a terminal type. */ 1660e3d5408SPeter Wemm static const char * 1670e3d5408SPeter Wemm askuser(const char *dflt) 1680e3d5408SPeter Wemm { 1690e3d5408SPeter Wemm static char answer[256]; 1700e3d5408SPeter Wemm char *p; 1710e3d5408SPeter Wemm 1720e3d5408SPeter Wemm /* We can get recalled; if so, don't continue uselessly. */ 1734a1a9510SRong-En Fan clearerr(stdin); 1740e3d5408SPeter Wemm if (feof(stdin) || ferror(stdin)) { 1750e3d5408SPeter Wemm (void) fprintf(stderr, "\n"); 17639f2269fSPeter Wemm exit_error(); 17739f2269fSPeter Wemm /* NOTREACHED */ 1780e3d5408SPeter Wemm } 1790e3d5408SPeter Wemm for (;;) { 1800e3d5408SPeter Wemm if (dflt) 1810e3d5408SPeter Wemm (void) fprintf(stderr, "Terminal type? [%s] ", dflt); 1820e3d5408SPeter Wemm else 1830e3d5408SPeter Wemm (void) fprintf(stderr, "Terminal type? "); 1840e3d5408SPeter Wemm (void) fflush(stderr); 1850e3d5408SPeter Wemm 1860e3d5408SPeter Wemm if (fgets(answer, sizeof(answer), stdin) == 0) { 1870e3d5408SPeter Wemm if (dflt == 0) { 18839f2269fSPeter Wemm exit_error(); 18939f2269fSPeter Wemm /* NOTREACHED */ 1900e3d5408SPeter Wemm } 1910e3d5408SPeter Wemm return (dflt); 1920e3d5408SPeter Wemm } 1930e3d5408SPeter Wemm 1940e3d5408SPeter Wemm if ((p = strchr(answer, '\n')) != 0) 1950e3d5408SPeter Wemm *p = '\0'; 1960e3d5408SPeter Wemm if (answer[0]) 1970e3d5408SPeter Wemm return (answer); 1980e3d5408SPeter Wemm if (dflt != 0) 1990e3d5408SPeter Wemm return (dflt); 2000e3d5408SPeter Wemm } 2010e3d5408SPeter Wemm } 2020e3d5408SPeter Wemm 2030e3d5408SPeter Wemm /************************************************************************** 2040e3d5408SPeter Wemm * 2050e3d5408SPeter Wemm * Mapping logic begins here 2060e3d5408SPeter Wemm * 2070e3d5408SPeter Wemm **************************************************************************/ 2080e3d5408SPeter Wemm 2090e3d5408SPeter Wemm /* Baud rate conditionals for mapping. */ 2100e3d5408SPeter Wemm #define GT 0x01 2110e3d5408SPeter Wemm #define EQ 0x02 2120e3d5408SPeter Wemm #define LT 0x04 2130e3d5408SPeter Wemm #define NOT 0x08 2140e3d5408SPeter Wemm #define GE (GT | EQ) 2150e3d5408SPeter Wemm #define LE (LT | EQ) 2160e3d5408SPeter Wemm 2170e3d5408SPeter Wemm typedef struct map { 2180e3d5408SPeter Wemm struct map *next; /* Linked list of maps. */ 2190e3d5408SPeter Wemm const char *porttype; /* Port type, or "" for any. */ 2200e3d5408SPeter Wemm const char *type; /* Terminal type to select. */ 2210e3d5408SPeter Wemm int conditional; /* Baud rate conditionals bitmask. */ 22218259542SPeter Wemm int speed; /* Baud rate to compare against. */ 2230e3d5408SPeter Wemm } MAP; 2240e3d5408SPeter Wemm 2250e3d5408SPeter Wemm static MAP *cur, *maplist; 2260e3d5408SPeter Wemm 227aae38d10SBaptiste Daroussin #define DATA(name,value) { { name }, value } 228aae38d10SBaptiste Daroussin 2290e3d5408SPeter Wemm typedef struct speeds { 230aae38d10SBaptiste Daroussin const char string[7]; 2310e3d5408SPeter Wemm int speed; 2320e3d5408SPeter Wemm } SPEEDS; 2330e3d5408SPeter Wemm 23415589c42SPeter Wemm static const SPEEDS speeds[] = 23515589c42SPeter Wemm { 236aae38d10SBaptiste Daroussin DATA("0", B0), 237aae38d10SBaptiste Daroussin DATA("50", B50), 238aae38d10SBaptiste Daroussin DATA("75", B75), 239aae38d10SBaptiste Daroussin DATA("110", B110), 240aae38d10SBaptiste Daroussin DATA("134", B134), 241aae38d10SBaptiste Daroussin DATA("134.5", B134), 242aae38d10SBaptiste Daroussin DATA("150", B150), 243aae38d10SBaptiste Daroussin DATA("200", B200), 244aae38d10SBaptiste Daroussin DATA("300", B300), 245aae38d10SBaptiste Daroussin DATA("600", B600), 246aae38d10SBaptiste Daroussin DATA("1200", B1200), 247aae38d10SBaptiste Daroussin DATA("1800", B1800), 248aae38d10SBaptiste Daroussin DATA("2400", B2400), 249aae38d10SBaptiste Daroussin DATA("4800", B4800), 250aae38d10SBaptiste Daroussin DATA("9600", B9600), 25118259542SPeter Wemm /* sgttyb may define up to this point */ 25218259542SPeter Wemm #ifdef B19200 253aae38d10SBaptiste Daroussin DATA("19200", B19200), 25418259542SPeter Wemm #endif 25518259542SPeter Wemm #ifdef B38400 256aae38d10SBaptiste Daroussin DATA("38400", B38400), 25718259542SPeter Wemm #endif 25818259542SPeter Wemm #ifdef B19200 259aae38d10SBaptiste Daroussin DATA("19200", B19200), 26018259542SPeter Wemm #endif 26118259542SPeter Wemm #ifdef B38400 262aae38d10SBaptiste Daroussin DATA("38400", B38400), 26318259542SPeter Wemm #endif 2640e3d5408SPeter Wemm #ifdef B19200 265aae38d10SBaptiste Daroussin DATA("19200", B19200), 2660e3d5408SPeter Wemm #else 2670e3d5408SPeter Wemm #ifdef EXTA 268aae38d10SBaptiste Daroussin DATA("19200", EXTA), 2690e3d5408SPeter Wemm #endif 2700e3d5408SPeter Wemm #endif 2710e3d5408SPeter Wemm #ifdef B38400 272aae38d10SBaptiste Daroussin DATA("38400", B38400), 2730e3d5408SPeter Wemm #else 2740e3d5408SPeter Wemm #ifdef EXTB 275aae38d10SBaptiste Daroussin DATA("38400", EXTB), 2760e3d5408SPeter Wemm #endif 2770e3d5408SPeter Wemm #endif 2780e3d5408SPeter Wemm #ifdef B57600 279aae38d10SBaptiste Daroussin DATA("57600", B57600), 280aae38d10SBaptiste Daroussin #endif 281aae38d10SBaptiste Daroussin #ifdef B76800 282aae38d10SBaptiste Daroussin DATA("76800", B57600), 2830e3d5408SPeter Wemm #endif 2840e3d5408SPeter Wemm #ifdef B115200 285aae38d10SBaptiste Daroussin DATA("115200", B115200), 286aae38d10SBaptiste Daroussin #endif 287aae38d10SBaptiste Daroussin #ifdef B153600 288aae38d10SBaptiste Daroussin DATA("153600", B153600), 2890e3d5408SPeter Wemm #endif 2900e3d5408SPeter Wemm #ifdef B230400 291aae38d10SBaptiste Daroussin DATA("230400", B230400), 292aae38d10SBaptiste Daroussin #endif 293aae38d10SBaptiste Daroussin #ifdef B307200 294aae38d10SBaptiste Daroussin DATA("307200", B307200), 2950e3d5408SPeter Wemm #endif 2960e3d5408SPeter Wemm #ifdef B460800 297aae38d10SBaptiste Daroussin DATA("460800", B460800), 2980e3d5408SPeter Wemm #endif 299aae38d10SBaptiste Daroussin #ifdef B500000 300aae38d10SBaptiste Daroussin DATA("500000", B500000), 301aae38d10SBaptiste Daroussin #endif 302aae38d10SBaptiste Daroussin #ifdef B576000 303aae38d10SBaptiste Daroussin DATA("576000", B576000), 304aae38d10SBaptiste Daroussin #endif 305aae38d10SBaptiste Daroussin #ifdef B921600 306aae38d10SBaptiste Daroussin DATA("921600", B921600), 307aae38d10SBaptiste Daroussin #endif 308aae38d10SBaptiste Daroussin #ifdef B1000000 309aae38d10SBaptiste Daroussin DATA("1000000", B1000000), 310aae38d10SBaptiste Daroussin #endif 311aae38d10SBaptiste Daroussin #ifdef B1152000 312aae38d10SBaptiste Daroussin DATA("1152000", B1152000), 313aae38d10SBaptiste Daroussin #endif 314aae38d10SBaptiste Daroussin #ifdef B1500000 315aae38d10SBaptiste Daroussin DATA("1500000", B1500000), 316aae38d10SBaptiste Daroussin #endif 317aae38d10SBaptiste Daroussin #ifdef B2000000 318aae38d10SBaptiste Daroussin DATA("2000000", B2000000), 319aae38d10SBaptiste Daroussin #endif 320aae38d10SBaptiste Daroussin #ifdef B2500000 321aae38d10SBaptiste Daroussin DATA("2500000", B2500000), 322aae38d10SBaptiste Daroussin #endif 323aae38d10SBaptiste Daroussin #ifdef B3000000 324aae38d10SBaptiste Daroussin DATA("3000000", B3000000), 325aae38d10SBaptiste Daroussin #endif 326aae38d10SBaptiste Daroussin #ifdef B3500000 327aae38d10SBaptiste Daroussin DATA("3500000", B3500000), 328aae38d10SBaptiste Daroussin #endif 329aae38d10SBaptiste Daroussin #ifdef B4000000 330aae38d10SBaptiste Daroussin DATA("4000000", B4000000), 331aae38d10SBaptiste Daroussin #endif 3320e3d5408SPeter Wemm }; 333aae38d10SBaptiste Daroussin #undef DATA 3340e3d5408SPeter Wemm 3350e3d5408SPeter Wemm static int 3360e3d5408SPeter Wemm tbaudrate(char *rate) 3370e3d5408SPeter Wemm { 338aae38d10SBaptiste Daroussin const SPEEDS *sp = 0; 339aae38d10SBaptiste Daroussin size_t n; 3400e3d5408SPeter Wemm 3410e3d5408SPeter Wemm /* The baudrate number can be preceded by a 'B', which is ignored. */ 3420e3d5408SPeter Wemm if (*rate == 'B') 3430e3d5408SPeter Wemm ++rate; 3440e3d5408SPeter Wemm 345aae38d10SBaptiste Daroussin for (n = 0; n < SIZEOF(speeds); ++n) { 346aae38d10SBaptiste Daroussin if (n > 0 && (speeds[n].speed <= speeds[n - 1].speed)) { 347aae38d10SBaptiste Daroussin /* if the speeds are not increasing, likely a numeric overflow */ 348aae38d10SBaptiste Daroussin break; 349aae38d10SBaptiste Daroussin } 350aae38d10SBaptiste Daroussin if (!CaselessCmp(rate, speeds[n].string)) { 351aae38d10SBaptiste Daroussin sp = speeds + n; 3520e3d5408SPeter Wemm break; 3530e3d5408SPeter Wemm } 3540e3d5408SPeter Wemm } 355aae38d10SBaptiste Daroussin if (sp == 0) 3560e3d5408SPeter Wemm err("unknown baud rate %s", rate); 3570e3d5408SPeter Wemm return (sp->speed); 3580e3d5408SPeter Wemm } 3590e3d5408SPeter Wemm 3600e3d5408SPeter Wemm /* 3610e3d5408SPeter Wemm * Syntax for -m: 3620e3d5408SPeter Wemm * [port-type][test baudrate]:terminal-type 3630e3d5408SPeter Wemm * The baud rate tests are: >, <, @, =, ! 3640e3d5408SPeter Wemm */ 3650e3d5408SPeter Wemm static void 3660e3d5408SPeter Wemm add_mapping(const char *port, char *arg) 3670e3d5408SPeter Wemm { 3680e3d5408SPeter Wemm MAP *mapp; 3690e3d5408SPeter Wemm char *copy, *p; 3700e3d5408SPeter Wemm const char *termp; 3710e3d5408SPeter Wemm char *base = 0; 3720e3d5408SPeter Wemm 3730e3d5408SPeter Wemm copy = strdup(arg); 37406bfebdeSXin LI mapp = typeMalloc(MAP, 1); 3750e3d5408SPeter Wemm if (copy == 0 || mapp == 0) 3760e3d5408SPeter Wemm failed("malloc"); 37706bfebdeSXin LI 37806bfebdeSXin LI assert(copy != 0); 37906bfebdeSXin LI assert(mapp != 0); 38006bfebdeSXin LI 3810e3d5408SPeter Wemm mapp->next = 0; 3820e3d5408SPeter Wemm if (maplist == 0) 3830e3d5408SPeter Wemm cur = maplist = mapp; 3840e3d5408SPeter Wemm else { 3850e3d5408SPeter Wemm cur->next = mapp; 3860e3d5408SPeter Wemm cur = mapp; 3870e3d5408SPeter Wemm } 3880e3d5408SPeter Wemm 3890e3d5408SPeter Wemm mapp->porttype = arg; 3900e3d5408SPeter Wemm mapp->conditional = 0; 3910e3d5408SPeter Wemm 3920e3d5408SPeter Wemm arg = strpbrk(arg, "><@=!:"); 3930e3d5408SPeter Wemm 3940e3d5408SPeter Wemm if (arg == 0) { /* [?]term */ 3950e3d5408SPeter Wemm mapp->type = mapp->porttype; 3960e3d5408SPeter Wemm mapp->porttype = 0; 3970e3d5408SPeter Wemm goto done; 3980e3d5408SPeter Wemm } 3990e3d5408SPeter Wemm 4000e3d5408SPeter Wemm if (arg == mapp->porttype) /* [><@=! baud]:term */ 4010e3d5408SPeter Wemm termp = mapp->porttype = 0; 4020e3d5408SPeter Wemm else 4030e3d5408SPeter Wemm termp = base = arg; 4040e3d5408SPeter Wemm 40515589c42SPeter Wemm for (;; ++arg) { /* Optional conditionals. */ 4060e3d5408SPeter Wemm switch (*arg) { 4070e3d5408SPeter Wemm case '<': 4080e3d5408SPeter Wemm if (mapp->conditional & GT) 4090e3d5408SPeter Wemm goto badmopt; 4100e3d5408SPeter Wemm mapp->conditional |= LT; 4110e3d5408SPeter Wemm break; 4120e3d5408SPeter Wemm case '>': 4130e3d5408SPeter Wemm if (mapp->conditional & LT) 4140e3d5408SPeter Wemm goto badmopt; 4150e3d5408SPeter Wemm mapp->conditional |= GT; 4160e3d5408SPeter Wemm break; 4170e3d5408SPeter Wemm case '@': 4180e3d5408SPeter Wemm case '=': /* Not documented. */ 4190e3d5408SPeter Wemm mapp->conditional |= EQ; 4200e3d5408SPeter Wemm break; 4210e3d5408SPeter Wemm case '!': 4220e3d5408SPeter Wemm mapp->conditional |= NOT; 4230e3d5408SPeter Wemm break; 4240e3d5408SPeter Wemm default: 4250e3d5408SPeter Wemm goto next; 4260e3d5408SPeter Wemm } 42715589c42SPeter Wemm } 4280e3d5408SPeter Wemm 42915589c42SPeter Wemm next: 43015589c42SPeter Wemm if (*arg == ':') { 4310e3d5408SPeter Wemm if (mapp->conditional) 4320e3d5408SPeter Wemm goto badmopt; 4330e3d5408SPeter Wemm ++arg; 4340e3d5408SPeter Wemm } else { /* Optional baudrate. */ 4350e3d5408SPeter Wemm arg = strchr(p = arg, ':'); 4360e3d5408SPeter Wemm if (arg == 0) 4370e3d5408SPeter Wemm goto badmopt; 4380e3d5408SPeter Wemm *arg++ = '\0'; 4390e3d5408SPeter Wemm mapp->speed = tbaudrate(p); 4400e3d5408SPeter Wemm } 4410e3d5408SPeter Wemm 4420e3d5408SPeter Wemm mapp->type = arg; 4430e3d5408SPeter Wemm 4440e3d5408SPeter Wemm /* Terminate porttype, if specified. */ 4450e3d5408SPeter Wemm if (termp != 0) 4460e3d5408SPeter Wemm *base = '\0'; 4470e3d5408SPeter Wemm 4480e3d5408SPeter Wemm /* If a NOT conditional, reverse the test. */ 4490e3d5408SPeter Wemm if (mapp->conditional & NOT) 4500e3d5408SPeter Wemm mapp->conditional = ~mapp->conditional & (EQ | GT | LT); 4510e3d5408SPeter Wemm 4520e3d5408SPeter Wemm /* If user specified a port with an option flag, set it. */ 4535d08fb1fSRong-En Fan done: 4545d08fb1fSRong-En Fan if (port) { 4555d08fb1fSRong-En Fan if (mapp->porttype) { 4565d08fb1fSRong-En Fan badmopt: 4575d08fb1fSRong-En Fan err("illegal -m option format: %s", copy); 4585d08fb1fSRong-En Fan } 4590e3d5408SPeter Wemm mapp->porttype = port; 4600e3d5408SPeter Wemm } 4615d08fb1fSRong-En Fan free(copy); 4620e3d5408SPeter Wemm #ifdef MAPDEBUG 4630e3d5408SPeter Wemm (void) printf("port: %s\n", mapp->porttype ? mapp->porttype : "ANY"); 4640e3d5408SPeter Wemm (void) printf("type: %s\n", mapp->type); 4650e3d5408SPeter Wemm (void) printf("conditional: "); 4660e3d5408SPeter Wemm p = ""; 4670e3d5408SPeter Wemm if (mapp->conditional & GT) { 4680e3d5408SPeter Wemm (void) printf("GT"); 4690e3d5408SPeter Wemm p = "/"; 4700e3d5408SPeter Wemm } 4710e3d5408SPeter Wemm if (mapp->conditional & EQ) { 4720e3d5408SPeter Wemm (void) printf("%sEQ", p); 4730e3d5408SPeter Wemm p = "/"; 4740e3d5408SPeter Wemm } 4750e3d5408SPeter Wemm if (mapp->conditional & LT) 4760e3d5408SPeter Wemm (void) printf("%sLT", p); 4770e3d5408SPeter Wemm (void) printf("\nspeed: %d\n", mapp->speed); 4780e3d5408SPeter Wemm #endif 4790e3d5408SPeter Wemm } 4800e3d5408SPeter Wemm 4810e3d5408SPeter Wemm /* 4820e3d5408SPeter Wemm * Return the type of terminal to use for a port of type 'type', as specified 4830e3d5408SPeter Wemm * by the first applicable mapping in 'map'. If no mappings apply, return 4840e3d5408SPeter Wemm * 'type'. 4850e3d5408SPeter Wemm */ 4860e3d5408SPeter Wemm static const char * 4870e3d5408SPeter Wemm mapped(const char *type) 4880e3d5408SPeter Wemm { 4890e3d5408SPeter Wemm MAP *mapp; 4900e3d5408SPeter Wemm int match; 4910e3d5408SPeter Wemm 4920e3d5408SPeter Wemm for (mapp = maplist; mapp; mapp = mapp->next) 4930e3d5408SPeter Wemm if (mapp->porttype == 0 || !strcmp(mapp->porttype, type)) { 4940e3d5408SPeter Wemm switch (mapp->conditional) { 4950e3d5408SPeter Wemm case 0: /* No test specified. */ 4960e3d5408SPeter Wemm match = TRUE; 4970e3d5408SPeter Wemm break; 4980e3d5408SPeter Wemm case EQ: 49973f0a83dSXin LI match = ((int) ospeed == mapp->speed); 5000e3d5408SPeter Wemm break; 5010e3d5408SPeter Wemm case GE: 50273f0a83dSXin LI match = ((int) ospeed >= mapp->speed); 5030e3d5408SPeter Wemm break; 5040e3d5408SPeter Wemm case GT: 50573f0a83dSXin LI match = ((int) ospeed > mapp->speed); 5060e3d5408SPeter Wemm break; 5070e3d5408SPeter Wemm case LE: 50873f0a83dSXin LI match = ((int) ospeed <= mapp->speed); 5090e3d5408SPeter Wemm break; 5100e3d5408SPeter Wemm case LT: 51173f0a83dSXin LI match = ((int) ospeed < mapp->speed); 5120e3d5408SPeter Wemm break; 5130e3d5408SPeter Wemm default: 5140e3d5408SPeter Wemm match = FALSE; 5150e3d5408SPeter Wemm } 5160e3d5408SPeter Wemm if (match) 5170e3d5408SPeter Wemm return (mapp->type); 5180e3d5408SPeter Wemm } 5190e3d5408SPeter Wemm /* No match found; return given type. */ 5200e3d5408SPeter Wemm return (type); 5210e3d5408SPeter Wemm } 5220e3d5408SPeter Wemm 5230e3d5408SPeter Wemm /************************************************************************** 5240e3d5408SPeter Wemm * 5250e3d5408SPeter Wemm * Entry fetching 5260e3d5408SPeter Wemm * 5270e3d5408SPeter Wemm **************************************************************************/ 5280e3d5408SPeter Wemm 5290e3d5408SPeter Wemm /* 5300e3d5408SPeter Wemm * Figure out what kind of terminal we're dealing with, and then read in 5310e3d5408SPeter Wemm * its termcap entry. 5320e3d5408SPeter Wemm */ 5330e3d5408SPeter Wemm static const char * 534aae38d10SBaptiste Daroussin get_termcap_entry(int fd, char *userarg) 5350e3d5408SPeter Wemm { 5367a69bbfbSPeter Wemm int errret; 5370e3d5408SPeter Wemm char *p; 5380e3d5408SPeter Wemm const char *ttype; 5390e3d5408SPeter Wemm #if HAVE_GETTTYNAM 5400e3d5408SPeter Wemm struct ttyent *t; 5410e3d5408SPeter Wemm #else 5420e3d5408SPeter Wemm FILE *fp; 5430e3d5408SPeter Wemm #endif 5440e3d5408SPeter Wemm char *ttypath; 5450e3d5408SPeter Wemm 546aae38d10SBaptiste Daroussin (void) fd; 547aae38d10SBaptiste Daroussin 5480e3d5408SPeter Wemm if (userarg) { 5490e3d5408SPeter Wemm ttype = userarg; 5500e3d5408SPeter Wemm goto found; 5510e3d5408SPeter Wemm } 5520e3d5408SPeter Wemm 5530e3d5408SPeter Wemm /* Try the environment. */ 5540e3d5408SPeter Wemm if ((ttype = getenv("TERM")) != 0) 5550e3d5408SPeter Wemm goto map; 5560e3d5408SPeter Wemm 557aae38d10SBaptiste Daroussin if ((ttypath = ttyname(fd)) != 0) { 55818259542SPeter Wemm p = _nc_basename(ttypath); 5590e3d5408SPeter Wemm #if HAVE_GETTTYNAM 5600e3d5408SPeter Wemm /* 5610e3d5408SPeter Wemm * We have the 4.3BSD library call getttynam(3); that means 5620e3d5408SPeter Wemm * there's an /etc/ttys to look up device-to-type mappings in. 5630e3d5408SPeter Wemm * Try ttyname(3); check for dialup or other mapping. 5640e3d5408SPeter Wemm */ 5650e3d5408SPeter Wemm if ((t = getttynam(p))) { 5660e3d5408SPeter Wemm ttype = t->ty_type; 5670e3d5408SPeter Wemm goto map; 5680e3d5408SPeter Wemm } 5690e3d5408SPeter Wemm #else 5700e3d5408SPeter Wemm if ((fp = fopen("/etc/ttytype", "r")) != 0 5710e3d5408SPeter Wemm || (fp = fopen("/etc/ttys", "r")) != 0) { 5720e3d5408SPeter Wemm char buffer[BUFSIZ]; 5730e3d5408SPeter Wemm char *s, *t, *d; 5740e3d5408SPeter Wemm 5750e3d5408SPeter Wemm while (fgets(buffer, sizeof(buffer) - 1, fp) != 0) { 5760e3d5408SPeter Wemm for (s = buffer, t = d = 0; *s; s++) { 57739f2269fSPeter Wemm if (isspace(UChar(*s))) 5780e3d5408SPeter Wemm *s = '\0'; 5790e3d5408SPeter Wemm else if (t == 0) 5800e3d5408SPeter Wemm t = s; 5810e3d5408SPeter Wemm else if (d == 0 && s != buffer && s[-1] == '\0') 5820e3d5408SPeter Wemm d = s; 5830e3d5408SPeter Wemm } 5840e3d5408SPeter Wemm if (t != 0 && d != 0 && !strcmp(d, p)) { 5850e3d5408SPeter Wemm ttype = strdup(t); 5860e3d5408SPeter Wemm fclose(fp); 5870e3d5408SPeter Wemm goto map; 5880e3d5408SPeter Wemm } 5890e3d5408SPeter Wemm } 5900e3d5408SPeter Wemm fclose(fp); 5910e3d5408SPeter Wemm } 5920e3d5408SPeter Wemm #endif /* HAVE_GETTTYNAM */ 5930e3d5408SPeter Wemm } 5940e3d5408SPeter Wemm 5950e3d5408SPeter Wemm /* If still undefined, use "unknown". */ 5960e3d5408SPeter Wemm ttype = "unknown"; 5970e3d5408SPeter Wemm 5980e3d5408SPeter Wemm map:ttype = mapped(ttype); 5990e3d5408SPeter Wemm 6000e3d5408SPeter Wemm /* 6010e3d5408SPeter Wemm * If not a path, remove TERMCAP from the environment so we get a 6020e3d5408SPeter Wemm * real entry from /etc/termcap. This prevents us from being fooled 6030e3d5408SPeter Wemm * by out of date stuff in the environment. 6040e3d5408SPeter Wemm */ 60573f0a83dSXin LI found: 60673f0a83dSXin LI if ((p = getenv("TERMCAP")) != 0 && !_nc_is_abs_path(p)) { 6070e3d5408SPeter Wemm /* 'unsetenv("TERMCAP")' is not portable. 6080e3d5408SPeter Wemm * The 'environ' array is better. 6090e3d5408SPeter Wemm */ 6100e3d5408SPeter Wemm int n; 6110e3d5408SPeter Wemm for (n = 0; environ[n] != 0; n++) { 61273f0a83dSXin LI if (!strncmp("TERMCAP=", environ[n], (size_t) 8)) { 6130e3d5408SPeter Wemm while ((environ[n] = environ[n + 1]) != 0) { 6140e3d5408SPeter Wemm n++; 6150e3d5408SPeter Wemm } 6160e3d5408SPeter Wemm break; 6170e3d5408SPeter Wemm } 6180e3d5408SPeter Wemm } 6190e3d5408SPeter Wemm } 6200e3d5408SPeter Wemm 6210e3d5408SPeter Wemm /* 6220e3d5408SPeter Wemm * ttype now contains a pointer to the type of the terminal. 6230e3d5408SPeter Wemm * If the first character is '?', ask the user. 6240e3d5408SPeter Wemm */ 6250e3d5408SPeter Wemm if (ttype[0] == '?') { 6260e3d5408SPeter Wemm if (ttype[1] != '\0') 6270e3d5408SPeter Wemm ttype = askuser(ttype + 1); 6280e3d5408SPeter Wemm else 6290e3d5408SPeter Wemm ttype = askuser(0); 6300e3d5408SPeter Wemm } 6310e3d5408SPeter Wemm /* Find the terminfo entry. If it doesn't exist, ask the user. */ 632aae38d10SBaptiste Daroussin while (setupterm((NCURSES_CONST char *) ttype, fd, &errret) 6337a69bbfbSPeter Wemm != OK) { 6340e3d5408SPeter Wemm if (errret == 0) { 6354a1a9510SRong-En Fan (void) fprintf(stderr, "%s: unknown terminal type %s\n", 6364a1a9510SRong-En Fan _nc_progname, ttype); 6370e3d5408SPeter Wemm ttype = 0; 63815589c42SPeter Wemm } else { 63915589c42SPeter Wemm (void) fprintf(stderr, 6404a1a9510SRong-En Fan "%s: can't initialize terminal type %s (error %d)\n", 6414a1a9510SRong-En Fan _nc_progname, ttype, errret); 6420e3d5408SPeter Wemm ttype = 0; 6430e3d5408SPeter Wemm } 6440e3d5408SPeter Wemm ttype = askuser(ttype); 6450e3d5408SPeter Wemm } 6460e3d5408SPeter Wemm #if BROKEN_LINKER 6470e3d5408SPeter Wemm tgetflag("am"); /* force lib_termcap.o to be linked for 'ospeed' */ 6480e3d5408SPeter Wemm #endif 6490e3d5408SPeter Wemm return (ttype); 6500e3d5408SPeter Wemm } 6510e3d5408SPeter Wemm 6520e3d5408SPeter Wemm /************************************************************************** 6530e3d5408SPeter Wemm * 6540e3d5408SPeter Wemm * Main sequence 6550e3d5408SPeter Wemm * 6560e3d5408SPeter Wemm **************************************************************************/ 6570e3d5408SPeter Wemm 6580e3d5408SPeter Wemm /* 6590e3d5408SPeter Wemm * Convert the obsolete argument forms into something that getopt can handle. 6600e3d5408SPeter Wemm * This means that -e, -i and -k get default arguments supplied for them. 6610e3d5408SPeter Wemm */ 6620e3d5408SPeter Wemm static void 6630e3d5408SPeter Wemm obsolete(char **argv) 6640e3d5408SPeter Wemm { 6650e3d5408SPeter Wemm for (; *argv; ++argv) { 6660e3d5408SPeter Wemm char *parm = argv[0]; 6670e3d5408SPeter Wemm 66815589c42SPeter Wemm if (parm[0] == '-' && parm[1] == '\0') { 6690e3d5408SPeter Wemm argv[0] = strdup("-q"); 6700e3d5408SPeter Wemm continue; 6710e3d5408SPeter Wemm } 6720e3d5408SPeter Wemm 6730e3d5408SPeter Wemm if ((parm[0] != '-') 6740e3d5408SPeter Wemm || (argv[1] && argv[1][0] != '-') 6750e3d5408SPeter Wemm || (parm[1] != 'e' && parm[1] != 'i' && parm[1] != 'k') 6760e3d5408SPeter Wemm || (parm[2] != '\0')) 6770e3d5408SPeter Wemm continue; 6780e3d5408SPeter Wemm switch (argv[0][1]) { 6790e3d5408SPeter Wemm case 'e': 6800e3d5408SPeter Wemm argv[0] = strdup("-e^H"); 6810e3d5408SPeter Wemm break; 6820e3d5408SPeter Wemm case 'i': 6830e3d5408SPeter Wemm argv[0] = strdup("-i^C"); 6840e3d5408SPeter Wemm break; 6850e3d5408SPeter Wemm case 'k': 6860e3d5408SPeter Wemm argv[0] = strdup("-k^U"); 6870e3d5408SPeter Wemm break; 6880e3d5408SPeter Wemm } 6890e3d5408SPeter Wemm } 6900e3d5408SPeter Wemm } 6910e3d5408SPeter Wemm 6920e3d5408SPeter Wemm static void 693aae38d10SBaptiste Daroussin print_shell_commands(const char *ttype) 694aae38d10SBaptiste Daroussin { 695aae38d10SBaptiste Daroussin const char *p; 696aae38d10SBaptiste Daroussin int len; 697aae38d10SBaptiste Daroussin char *var; 698aae38d10SBaptiste Daroussin char *leaf; 699aae38d10SBaptiste Daroussin /* 700aae38d10SBaptiste Daroussin * Figure out what shell we're using. A hack, we look for an 701aae38d10SBaptiste Daroussin * environmental variable SHELL ending in "csh". 702aae38d10SBaptiste Daroussin */ 703aae38d10SBaptiste Daroussin if ((var = getenv("SHELL")) != 0 704aae38d10SBaptiste Daroussin && ((len = (int) strlen(leaf = _nc_basename(var))) >= 3) 705aae38d10SBaptiste Daroussin && !strcmp(leaf + len - 3, "csh")) 706aae38d10SBaptiste Daroussin p = "set noglob;\nsetenv TERM %s;\nunset noglob;\n"; 707aae38d10SBaptiste Daroussin else 708aae38d10SBaptiste Daroussin p = "TERM=%s;\n"; 709aae38d10SBaptiste Daroussin (void) printf(p, ttype); 710aae38d10SBaptiste Daroussin } 711aae38d10SBaptiste Daroussin 712aae38d10SBaptiste Daroussin static void 7134a1a9510SRong-En Fan usage(void) 7140e3d5408SPeter Wemm { 715aae38d10SBaptiste Daroussin #define SKIP(s) /* nothing */ 716aae38d10SBaptiste Daroussin #define KEEP(s) s "\n" 717aae38d10SBaptiste Daroussin static const char msg[] = 7184a1a9510SRong-En Fan { 719aae38d10SBaptiste Daroussin KEEP("") 720aae38d10SBaptiste Daroussin KEEP("Options:") 721aae38d10SBaptiste Daroussin SKIP(" -a arpanet (obsolete)") 722aae38d10SBaptiste Daroussin KEEP(" -c set control characters") 723aae38d10SBaptiste Daroussin SKIP(" -d dialup (obsolete)") 724aae38d10SBaptiste Daroussin KEEP(" -e ch erase character") 725aae38d10SBaptiste Daroussin KEEP(" -I no initialization strings") 726aae38d10SBaptiste Daroussin KEEP(" -i ch interrupt character") 727aae38d10SBaptiste Daroussin KEEP(" -k ch kill character") 728aae38d10SBaptiste Daroussin KEEP(" -m mapping map identifier to type") 729aae38d10SBaptiste Daroussin SKIP(" -p plugboard (obsolete)") 730aae38d10SBaptiste Daroussin KEEP(" -Q do not output control key settings") 731aae38d10SBaptiste Daroussin KEEP(" -q display term only, do no changes") 732aae38d10SBaptiste Daroussin KEEP(" -r display term on stderr") 733aae38d10SBaptiste Daroussin SKIP(" -S (obsolete)") 734aae38d10SBaptiste Daroussin KEEP(" -s output TERM set command") 735aae38d10SBaptiste Daroussin KEEP(" -V print curses-version") 736aae38d10SBaptiste Daroussin KEEP(" -w set window-size") 737aae38d10SBaptiste Daroussin KEEP("") 738aae38d10SBaptiste Daroussin KEEP("If neither -c/-w are given, both are assumed.") 7394a1a9510SRong-En Fan }; 740aae38d10SBaptiste Daroussin #undef KEEP 741aae38d10SBaptiste Daroussin #undef SKIP 7424a1a9510SRong-En Fan (void) fprintf(stderr, "Usage: %s [options] [terminal]\n", _nc_progname); 743aae38d10SBaptiste Daroussin fputs(msg, stderr); 744aae38d10SBaptiste Daroussin ExitProgram(EXIT_FAILURE); 74539f2269fSPeter Wemm /* NOTREACHED */ 7460e3d5408SPeter Wemm } 7470e3d5408SPeter Wemm 74815589c42SPeter Wemm static char 74915589c42SPeter Wemm arg_to_char(void) 7500e3d5408SPeter Wemm { 7515d08fb1fSRong-En Fan return (char) ((optarg[0] == '^' && optarg[1] != '\0') 7520e3d5408SPeter Wemm ? ((optarg[1] == '?') ? '\177' : CTRL(optarg[1])) 7535d08fb1fSRong-En Fan : optarg[0]); 7540e3d5408SPeter Wemm } 7550e3d5408SPeter Wemm 7560e3d5408SPeter Wemm int 7570e3d5408SPeter Wemm main(int argc, char **argv) 7580e3d5408SPeter Wemm { 7590e3d5408SPeter Wemm int ch, noinit, noset, quiet, Sflag, sflag, showterm; 7600e3d5408SPeter Wemm const char *ttype; 761aae38d10SBaptiste Daroussin int terasechar = -1; /* new erase character */ 762aae38d10SBaptiste Daroussin int intrchar = -1; /* new interrupt character */ 763aae38d10SBaptiste Daroussin int tkillchar = -1; /* new kill character */ 764aae38d10SBaptiste Daroussin int my_fd; 765aae38d10SBaptiste Daroussin bool opt_c = FALSE; /* set control-chars */ 766aae38d10SBaptiste Daroussin bool opt_w = FALSE; /* set window-size */ 767aae38d10SBaptiste Daroussin TTY mode, oldmode; 7680e3d5408SPeter Wemm 769aae38d10SBaptiste Daroussin my_fd = STDERR_FILENO; 7700e3d5408SPeter Wemm obsolete(argv); 7710e3d5408SPeter Wemm noinit = noset = quiet = Sflag = sflag = showterm = 0; 772aae38d10SBaptiste Daroussin while ((ch = getopt(argc, argv, "a:cd:e:Ii:k:m:p:qQrSsVw")) != -1) { 7730e3d5408SPeter Wemm switch (ch) { 7744a1a9510SRong-En Fan case 'c': /* set control-chars */ 7754a1a9510SRong-En Fan opt_c = TRUE; 7760e3d5408SPeter Wemm break; 7770e3d5408SPeter Wemm case 'a': /* OBSOLETE: map identifier to type */ 7780e3d5408SPeter Wemm add_mapping("arpanet", optarg); 7790e3d5408SPeter Wemm break; 7800e3d5408SPeter Wemm case 'd': /* OBSOLETE: map identifier to type */ 7810e3d5408SPeter Wemm add_mapping("dialup", optarg); 7820e3d5408SPeter Wemm break; 7830e3d5408SPeter Wemm case 'e': /* erase character */ 7840e3d5408SPeter Wemm terasechar = arg_to_char(); 7850e3d5408SPeter Wemm break; 7860e3d5408SPeter Wemm case 'I': /* no initialization strings */ 7870e3d5408SPeter Wemm noinit = 1; 7880e3d5408SPeter Wemm break; 7890e3d5408SPeter Wemm case 'i': /* interrupt character */ 7900e3d5408SPeter Wemm intrchar = arg_to_char(); 7910e3d5408SPeter Wemm break; 7920e3d5408SPeter Wemm case 'k': /* kill character */ 7930e3d5408SPeter Wemm tkillchar = arg_to_char(); 7940e3d5408SPeter Wemm break; 7950e3d5408SPeter Wemm case 'm': /* map identifier to type */ 7960e3d5408SPeter Wemm add_mapping(0, optarg); 7970e3d5408SPeter Wemm break; 7980e3d5408SPeter Wemm case 'p': /* OBSOLETE: map identifier to type */ 7990e3d5408SPeter Wemm add_mapping("plugboard", optarg); 8000e3d5408SPeter Wemm break; 8010e3d5408SPeter Wemm case 'Q': /* don't output control key settings */ 8020e3d5408SPeter Wemm quiet = 1; 8030e3d5408SPeter Wemm break; 8044a1a9510SRong-En Fan case 'q': /* display term only */ 8054a1a9510SRong-En Fan noset = 1; 8060e3d5408SPeter Wemm break; 8070e3d5408SPeter Wemm case 'r': /* display term on stderr */ 8080e3d5408SPeter Wemm showterm = 1; 8090e3d5408SPeter Wemm break; 8104a1a9510SRong-En Fan case 'S': /* OBSOLETE: output TERM & TERMCAP */ 8114a1a9510SRong-En Fan Sflag = 1; 8124a1a9510SRong-En Fan break; 8130e3d5408SPeter Wemm case 's': /* output TERM set command */ 8140e3d5408SPeter Wemm sflag = 1; 8150e3d5408SPeter Wemm break; 8164a1a9510SRong-En Fan case 'V': /* print curses-version */ 81718259542SPeter Wemm puts(curses_version()); 8184a1a9510SRong-En Fan ExitProgram(EXIT_SUCCESS); 8194a1a9510SRong-En Fan case 'w': /* set window-size */ 8204a1a9510SRong-En Fan opt_w = TRUE; 8214a1a9510SRong-En Fan break; 8220e3d5408SPeter Wemm case '?': 8230e3d5408SPeter Wemm default: 8244a1a9510SRong-En Fan usage(); 8250e3d5408SPeter Wemm } 8260e3d5408SPeter Wemm } 8274a1a9510SRong-En Fan 8284a1a9510SRong-En Fan _nc_progname = _nc_rootname(*argv); 8290e3d5408SPeter Wemm argc -= optind; 8300e3d5408SPeter Wemm argv += optind; 8310e3d5408SPeter Wemm 8320e3d5408SPeter Wemm if (argc > 1) 8334a1a9510SRong-En Fan usage(); 8344a1a9510SRong-En Fan 8354a1a9510SRong-En Fan if (!opt_c && !opt_w) 8364a1a9510SRong-En Fan opt_c = opt_w = TRUE; 8374a1a9510SRong-En Fan 838aae38d10SBaptiste Daroussin my_fd = save_tty_settings(&mode, TRUE); 839aae38d10SBaptiste Daroussin oldmode = mode; 8404a1a9510SRong-En Fan #ifdef TERMIOS 8415d08fb1fSRong-En Fan ospeed = (NCURSES_OSPEED) cfgetospeed(&mode); 8424a1a9510SRong-En Fan #else 8435d08fb1fSRong-En Fan ospeed = (NCURSES_OSPEED) mode.sg_ospeed; 8444a1a9510SRong-En Fan #endif 8454a1a9510SRong-En Fan 84606bfebdeSXin LI if (same_program(_nc_progname, PROG_RESET)) { 847aae38d10SBaptiste Daroussin reset_start(stderr, TRUE, FALSE); 848aae38d10SBaptiste Daroussin reset_tty_settings(my_fd, &mode); 849aae38d10SBaptiste Daroussin } else { 850aae38d10SBaptiste Daroussin reset_start(stderr, FALSE, TRUE); 8514a1a9510SRong-En Fan } 8520e3d5408SPeter Wemm 853aae38d10SBaptiste Daroussin ttype = get_termcap_entry(my_fd, *argv); 8540e3d5408SPeter Wemm 8550e3d5408SPeter Wemm if (!noset) { 85673f0a83dSXin LI #if HAVE_SIZECHANGE 8574a1a9510SRong-En Fan if (opt_w) { 858aae38d10SBaptiste Daroussin set_window_size(my_fd, &lines, &columns); 8594a1a9510SRong-En Fan } 8600e3d5408SPeter Wemm #endif 8614a1a9510SRong-En Fan if (opt_c) { 862aae38d10SBaptiste Daroussin set_control_chars(&mode, terasechar, intrchar, tkillchar); 863aae38d10SBaptiste Daroussin set_conversions(&mode); 8640e3d5408SPeter Wemm 865aae38d10SBaptiste Daroussin if (!noinit) { 866aae38d10SBaptiste Daroussin if (send_init_strings(my_fd, &oldmode)) { 867aae38d10SBaptiste Daroussin (void) putc('\r', stderr); 868aae38d10SBaptiste Daroussin (void) fflush(stderr); 869aae38d10SBaptiste Daroussin (void) napms(1000); /* Settle the terminal. */ 8700e3d5408SPeter Wemm } 87115589c42SPeter Wemm } 872aae38d10SBaptiste Daroussin 873aae38d10SBaptiste Daroussin update_tty_settings(&oldmode, &mode); 874aae38d10SBaptiste Daroussin } 8754a1a9510SRong-En Fan } 8760e3d5408SPeter Wemm 877aae38d10SBaptiste Daroussin if (noset) { 8780e3d5408SPeter Wemm (void) printf("%s\n", ttype); 879aae38d10SBaptiste Daroussin } else { 8800e3d5408SPeter Wemm if (showterm) 8810e3d5408SPeter Wemm (void) fprintf(stderr, "Terminal type is %s.\n", ttype); 8820e3d5408SPeter Wemm /* 8830e3d5408SPeter Wemm * If erase, kill and interrupt characters could have been 8840e3d5408SPeter Wemm * modified and not -Q, display the changes. 8850e3d5408SPeter Wemm */ 8860e3d5408SPeter Wemm if (!quiet) { 887aae38d10SBaptiste Daroussin print_tty_chars(&oldmode, &mode); 8880e3d5408SPeter Wemm } 8890e3d5408SPeter Wemm } 8900e3d5408SPeter Wemm 8910e3d5408SPeter Wemm if (Sflag) 8920e3d5408SPeter Wemm err("The -S option is not supported under terminfo."); 8930e3d5408SPeter Wemm 8940e3d5408SPeter Wemm if (sflag) { 895aae38d10SBaptiste Daroussin print_shell_commands(ttype); 8960e3d5408SPeter Wemm } 8970e3d5408SPeter Wemm 8984a1a9510SRong-En Fan ExitProgram(EXIT_SUCCESS); 8990e3d5408SPeter Wemm } 900