10e3d5408SPeter Wemm /**************************************************************************** 2*aae38d10SBaptiste Daroussin * Copyright (c) 1998-2016,2017 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> * 324a1a9510SRong-En Fan * and: Thomas E. Dickey 1996-on * 330e3d5408SPeter Wemm ****************************************************************************/ 340e3d5408SPeter Wemm 350e3d5408SPeter Wemm /* 3606bfebdeSXin LI * Notes: 3706bfebdeSXin LI * The initial adaptation from 4.4BSD Lite sources in September 1995 used 686 3806bfebdeSXin LI * lines from that version, and made changes/additions for 150 lines. There 3906bfebdeSXin LI * was no reformatting, so with/without ignoring whitespace, the amount of 4006bfebdeSXin LI * change is the same. 4106bfebdeSXin LI * 4206bfebdeSXin LI * Comparing with current (2009) source, excluding this comment: 4306bfebdeSXin LI * a) 209 lines match identically to the 4.4BSD Lite sources, with 771 lines 4406bfebdeSXin LI * changed/added. 4506bfebdeSXin LI * a) Ignoring whitespace, the current version still uses 516 lines from the 4606bfebdeSXin LI * 4.4BSD Lite sources, with 402 lines changed/added. 4706bfebdeSXin LI * 4806bfebdeSXin LI * Raymond's original comment on this follows... 4906bfebdeSXin LI */ 5006bfebdeSXin LI 5106bfebdeSXin LI /* 520e3d5408SPeter Wemm * tset.c - terminal initialization utility 530e3d5408SPeter Wemm * 540e3d5408SPeter Wemm * This code was mostly swiped from 4.4BSD tset, with some obsolescent 550e3d5408SPeter Wemm * cruft removed and substantial portions rewritten. A Regents of the 560e3d5408SPeter Wemm * University of California copyright applies to some portions of the 570e3d5408SPeter Wemm * code, and is reproduced below: 580e3d5408SPeter Wemm */ 590e3d5408SPeter Wemm /*- 600e3d5408SPeter Wemm * Copyright (c) 1980, 1991, 1993 610e3d5408SPeter Wemm * The Regents of the University of California. All rights reserved. 620e3d5408SPeter Wemm * 630e3d5408SPeter Wemm * Redistribution and use in source and binary forms, with or without 640e3d5408SPeter Wemm * modification, are permitted provided that the following conditions 650e3d5408SPeter Wemm * are met: 660e3d5408SPeter Wemm * 1. Redistributions of source code must retain the above copyright 670e3d5408SPeter Wemm * notice, this list of conditions and the following disclaimer. 680e3d5408SPeter Wemm * 2. Redistributions in binary form must reproduce the above copyright 690e3d5408SPeter Wemm * notice, this list of conditions and the following disclaimer in the 700e3d5408SPeter Wemm * documentation and/or other materials provided with the distribution. 7106bfebdeSXin LI * 3. Neither the name of the University nor the names of its contributors 720e3d5408SPeter Wemm * may be used to endorse or promote products derived from this software 730e3d5408SPeter Wemm * without specific prior written permission. 740e3d5408SPeter Wemm * 750e3d5408SPeter Wemm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 760e3d5408SPeter Wemm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 770e3d5408SPeter Wemm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 780e3d5408SPeter Wemm * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 790e3d5408SPeter Wemm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 800e3d5408SPeter Wemm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 810e3d5408SPeter Wemm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 820e3d5408SPeter Wemm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 830e3d5408SPeter Wemm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 840e3d5408SPeter Wemm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 850e3d5408SPeter Wemm * SUCH DAMAGE. 860e3d5408SPeter Wemm */ 870e3d5408SPeter Wemm 88*aae38d10SBaptiste Daroussin #include <reset_cmd.h> 890e3d5408SPeter Wemm #include <termcap.h> 90*aae38d10SBaptiste Daroussin #include <transform.h> 91*aae38d10SBaptiste Daroussin #include <tty_settings.h> 920e3d5408SPeter Wemm 930e3d5408SPeter Wemm #if HAVE_GETTTYNAM && HAVE_TTYENT_H 940e3d5408SPeter Wemm #include <ttyent.h> 950e3d5408SPeter Wemm #endif 960e3d5408SPeter Wemm #ifdef NeXT 970e3d5408SPeter Wemm char *ttyname(int fd); 980e3d5408SPeter Wemm #endif 990e3d5408SPeter Wemm 100*aae38d10SBaptiste Daroussin MODULE_ID("$Id: tset.c,v 1.120 2017/10/08 00:01:29 tom Exp $") 1010e3d5408SPeter Wemm 10206bfebdeSXin LI #ifndef environ 1030e3d5408SPeter Wemm extern char **environ; 10406bfebdeSXin LI #endif 1050e3d5408SPeter Wemm 1060e3d5408SPeter Wemm const char *_nc_progname = "tset"; 1070e3d5408SPeter Wemm 10839f2269fSPeter Wemm #define LOWERCASE(c) ((isalpha(UChar(c)) && isupper(UChar(c))) ? tolower(UChar(c)) : (c)) 1090e3d5408SPeter Wemm 110*aae38d10SBaptiste Daroussin static void exit_error(void) GCC_NORETURN; 111*aae38d10SBaptiste Daroussin 1120e3d5408SPeter Wemm static int 11315589c42SPeter Wemm CaselessCmp(const char *a, const char *b) 11415589c42SPeter Wemm { /* strcasecmp isn't portable */ 1150e3d5408SPeter Wemm while (*a && *b) { 1160e3d5408SPeter Wemm int cmp = LOWERCASE(*a) - LOWERCASE(*b); 1170e3d5408SPeter Wemm if (cmp != 0) 1180e3d5408SPeter Wemm break; 1190e3d5408SPeter Wemm a++, b++; 1200e3d5408SPeter Wemm } 1210e3d5408SPeter Wemm return LOWERCASE(*a) - LOWERCASE(*b); 1220e3d5408SPeter Wemm } 1230e3d5408SPeter Wemm 1240e3d5408SPeter Wemm static void 12539f2269fSPeter Wemm exit_error(void) 12639f2269fSPeter Wemm { 127*aae38d10SBaptiste Daroussin restore_tty_settings(); 12839f2269fSPeter Wemm (void) fprintf(stderr, "\n"); 12939f2269fSPeter Wemm fflush(stderr); 1304a1a9510SRong-En Fan ExitProgram(EXIT_FAILURE); 13139f2269fSPeter Wemm /* NOTREACHED */ 13239f2269fSPeter Wemm } 13339f2269fSPeter Wemm 13439f2269fSPeter Wemm static void 1350e3d5408SPeter Wemm err(const char *fmt,...) 1360e3d5408SPeter Wemm { 1370e3d5408SPeter Wemm va_list ap; 1380e3d5408SPeter Wemm va_start(ap, fmt); 1394a1a9510SRong-En Fan (void) fprintf(stderr, "%s: ", _nc_progname); 1400e3d5408SPeter Wemm (void) vfprintf(stderr, fmt, ap); 1410e3d5408SPeter Wemm va_end(ap); 14239f2269fSPeter Wemm exit_error(); 1430e3d5408SPeter Wemm /* NOTREACHED */ 1440e3d5408SPeter Wemm } 1450e3d5408SPeter Wemm 1460e3d5408SPeter Wemm static void 1470e3d5408SPeter Wemm failed(const char *msg) 1480e3d5408SPeter Wemm { 1490e3d5408SPeter Wemm char temp[BUFSIZ]; 15073f0a83dSXin LI size_t len = strlen(_nc_progname) + 2; 1514a1a9510SRong-En Fan 1525d08fb1fSRong-En Fan if ((int) len < (int) sizeof(temp) - 12) { 15373f0a83dSXin LI _nc_STRCPY(temp, _nc_progname, sizeof(temp)); 15473f0a83dSXin LI _nc_STRCAT(temp, ": ", sizeof(temp)); 1554a1a9510SRong-En Fan } else { 15673f0a83dSXin LI _nc_STRCPY(temp, "tset: ", sizeof(temp)); 1574a1a9510SRong-En Fan } 158*aae38d10SBaptiste Daroussin _nc_STRNCAT(temp, msg, sizeof(temp), sizeof(temp) - strlen(temp) - 2); 159*aae38d10SBaptiste Daroussin perror(temp); 16039f2269fSPeter Wemm exit_error(); 1610e3d5408SPeter Wemm /* NOTREACHED */ 1620e3d5408SPeter Wemm } 1630e3d5408SPeter Wemm 1640e3d5408SPeter Wemm /* Prompt the user for a terminal type. */ 1650e3d5408SPeter Wemm static const char * 1660e3d5408SPeter Wemm askuser(const char *dflt) 1670e3d5408SPeter Wemm { 1680e3d5408SPeter Wemm static char answer[256]; 1690e3d5408SPeter Wemm char *p; 1700e3d5408SPeter Wemm 1710e3d5408SPeter Wemm /* We can get recalled; if so, don't continue uselessly. */ 1724a1a9510SRong-En Fan clearerr(stdin); 1730e3d5408SPeter Wemm if (feof(stdin) || ferror(stdin)) { 1740e3d5408SPeter Wemm (void) fprintf(stderr, "\n"); 17539f2269fSPeter Wemm exit_error(); 17639f2269fSPeter Wemm /* NOTREACHED */ 1770e3d5408SPeter Wemm } 1780e3d5408SPeter Wemm for (;;) { 1790e3d5408SPeter Wemm if (dflt) 1800e3d5408SPeter Wemm (void) fprintf(stderr, "Terminal type? [%s] ", dflt); 1810e3d5408SPeter Wemm else 1820e3d5408SPeter Wemm (void) fprintf(stderr, "Terminal type? "); 1830e3d5408SPeter Wemm (void) fflush(stderr); 1840e3d5408SPeter Wemm 1850e3d5408SPeter Wemm if (fgets(answer, sizeof(answer), stdin) == 0) { 1860e3d5408SPeter Wemm if (dflt == 0) { 18739f2269fSPeter Wemm exit_error(); 18839f2269fSPeter Wemm /* NOTREACHED */ 1890e3d5408SPeter Wemm } 1900e3d5408SPeter Wemm return (dflt); 1910e3d5408SPeter Wemm } 1920e3d5408SPeter Wemm 1930e3d5408SPeter Wemm if ((p = strchr(answer, '\n')) != 0) 1940e3d5408SPeter Wemm *p = '\0'; 1950e3d5408SPeter Wemm if (answer[0]) 1960e3d5408SPeter Wemm return (answer); 1970e3d5408SPeter Wemm if (dflt != 0) 1980e3d5408SPeter Wemm return (dflt); 1990e3d5408SPeter Wemm } 2000e3d5408SPeter Wemm } 2010e3d5408SPeter Wemm 2020e3d5408SPeter Wemm /************************************************************************** 2030e3d5408SPeter Wemm * 2040e3d5408SPeter Wemm * Mapping logic begins here 2050e3d5408SPeter Wemm * 2060e3d5408SPeter Wemm **************************************************************************/ 2070e3d5408SPeter Wemm 2080e3d5408SPeter Wemm /* Baud rate conditionals for mapping. */ 2090e3d5408SPeter Wemm #define GT 0x01 2100e3d5408SPeter Wemm #define EQ 0x02 2110e3d5408SPeter Wemm #define LT 0x04 2120e3d5408SPeter Wemm #define NOT 0x08 2130e3d5408SPeter Wemm #define GE (GT | EQ) 2140e3d5408SPeter Wemm #define LE (LT | EQ) 2150e3d5408SPeter Wemm 2160e3d5408SPeter Wemm typedef struct map { 2170e3d5408SPeter Wemm struct map *next; /* Linked list of maps. */ 2180e3d5408SPeter Wemm const char *porttype; /* Port type, or "" for any. */ 2190e3d5408SPeter Wemm const char *type; /* Terminal type to select. */ 2200e3d5408SPeter Wemm int conditional; /* Baud rate conditionals bitmask. */ 22118259542SPeter Wemm int speed; /* Baud rate to compare against. */ 2220e3d5408SPeter Wemm } MAP; 2230e3d5408SPeter Wemm 2240e3d5408SPeter Wemm static MAP *cur, *maplist; 2250e3d5408SPeter Wemm 226*aae38d10SBaptiste Daroussin #define DATA(name,value) { { name }, value } 227*aae38d10SBaptiste Daroussin 2280e3d5408SPeter Wemm typedef struct speeds { 229*aae38d10SBaptiste Daroussin const char string[7]; 2300e3d5408SPeter Wemm int speed; 2310e3d5408SPeter Wemm } SPEEDS; 2320e3d5408SPeter Wemm 23315589c42SPeter Wemm static const SPEEDS speeds[] = 23415589c42SPeter Wemm { 235*aae38d10SBaptiste Daroussin DATA("0", B0), 236*aae38d10SBaptiste Daroussin DATA("50", B50), 237*aae38d10SBaptiste Daroussin DATA("75", B75), 238*aae38d10SBaptiste Daroussin DATA("110", B110), 239*aae38d10SBaptiste Daroussin DATA("134", B134), 240*aae38d10SBaptiste Daroussin DATA("134.5", B134), 241*aae38d10SBaptiste Daroussin DATA("150", B150), 242*aae38d10SBaptiste Daroussin DATA("200", B200), 243*aae38d10SBaptiste Daroussin DATA("300", B300), 244*aae38d10SBaptiste Daroussin DATA("600", B600), 245*aae38d10SBaptiste Daroussin DATA("1200", B1200), 246*aae38d10SBaptiste Daroussin DATA("1800", B1800), 247*aae38d10SBaptiste Daroussin DATA("2400", B2400), 248*aae38d10SBaptiste Daroussin DATA("4800", B4800), 249*aae38d10SBaptiste Daroussin DATA("9600", B9600), 25018259542SPeter Wemm /* sgttyb may define up to this point */ 25118259542SPeter Wemm #ifdef B19200 252*aae38d10SBaptiste Daroussin DATA("19200", B19200), 25318259542SPeter Wemm #endif 25418259542SPeter Wemm #ifdef B38400 255*aae38d10SBaptiste Daroussin DATA("38400", B38400), 25618259542SPeter Wemm #endif 25718259542SPeter Wemm #ifdef B19200 258*aae38d10SBaptiste Daroussin DATA("19200", B19200), 25918259542SPeter Wemm #endif 26018259542SPeter Wemm #ifdef B38400 261*aae38d10SBaptiste Daroussin DATA("38400", B38400), 26218259542SPeter Wemm #endif 2630e3d5408SPeter Wemm #ifdef B19200 264*aae38d10SBaptiste Daroussin DATA("19200", B19200), 2650e3d5408SPeter Wemm #else 2660e3d5408SPeter Wemm #ifdef EXTA 267*aae38d10SBaptiste Daroussin DATA("19200", EXTA), 2680e3d5408SPeter Wemm #endif 2690e3d5408SPeter Wemm #endif 2700e3d5408SPeter Wemm #ifdef B38400 271*aae38d10SBaptiste Daroussin DATA("38400", B38400), 2720e3d5408SPeter Wemm #else 2730e3d5408SPeter Wemm #ifdef EXTB 274*aae38d10SBaptiste Daroussin DATA("38400", EXTB), 2750e3d5408SPeter Wemm #endif 2760e3d5408SPeter Wemm #endif 2770e3d5408SPeter Wemm #ifdef B57600 278*aae38d10SBaptiste Daroussin DATA("57600", B57600), 279*aae38d10SBaptiste Daroussin #endif 280*aae38d10SBaptiste Daroussin #ifdef B76800 281*aae38d10SBaptiste Daroussin DATA("76800", B57600), 2820e3d5408SPeter Wemm #endif 2830e3d5408SPeter Wemm #ifdef B115200 284*aae38d10SBaptiste Daroussin DATA("115200", B115200), 285*aae38d10SBaptiste Daroussin #endif 286*aae38d10SBaptiste Daroussin #ifdef B153600 287*aae38d10SBaptiste Daroussin DATA("153600", B153600), 2880e3d5408SPeter Wemm #endif 2890e3d5408SPeter Wemm #ifdef B230400 290*aae38d10SBaptiste Daroussin DATA("230400", B230400), 291*aae38d10SBaptiste Daroussin #endif 292*aae38d10SBaptiste Daroussin #ifdef B307200 293*aae38d10SBaptiste Daroussin DATA("307200", B307200), 2940e3d5408SPeter Wemm #endif 2950e3d5408SPeter Wemm #ifdef B460800 296*aae38d10SBaptiste Daroussin DATA("460800", B460800), 2970e3d5408SPeter Wemm #endif 298*aae38d10SBaptiste Daroussin #ifdef B500000 299*aae38d10SBaptiste Daroussin DATA("500000", B500000), 300*aae38d10SBaptiste Daroussin #endif 301*aae38d10SBaptiste Daroussin #ifdef B576000 302*aae38d10SBaptiste Daroussin DATA("576000", B576000), 303*aae38d10SBaptiste Daroussin #endif 304*aae38d10SBaptiste Daroussin #ifdef B921600 305*aae38d10SBaptiste Daroussin DATA("921600", B921600), 306*aae38d10SBaptiste Daroussin #endif 307*aae38d10SBaptiste Daroussin #ifdef B1000000 308*aae38d10SBaptiste Daroussin DATA("1000000", B1000000), 309*aae38d10SBaptiste Daroussin #endif 310*aae38d10SBaptiste Daroussin #ifdef B1152000 311*aae38d10SBaptiste Daroussin DATA("1152000", B1152000), 312*aae38d10SBaptiste Daroussin #endif 313*aae38d10SBaptiste Daroussin #ifdef B1500000 314*aae38d10SBaptiste Daroussin DATA("1500000", B1500000), 315*aae38d10SBaptiste Daroussin #endif 316*aae38d10SBaptiste Daroussin #ifdef B2000000 317*aae38d10SBaptiste Daroussin DATA("2000000", B2000000), 318*aae38d10SBaptiste Daroussin #endif 319*aae38d10SBaptiste Daroussin #ifdef B2500000 320*aae38d10SBaptiste Daroussin DATA("2500000", B2500000), 321*aae38d10SBaptiste Daroussin #endif 322*aae38d10SBaptiste Daroussin #ifdef B3000000 323*aae38d10SBaptiste Daroussin DATA("3000000", B3000000), 324*aae38d10SBaptiste Daroussin #endif 325*aae38d10SBaptiste Daroussin #ifdef B3500000 326*aae38d10SBaptiste Daroussin DATA("3500000", B3500000), 327*aae38d10SBaptiste Daroussin #endif 328*aae38d10SBaptiste Daroussin #ifdef B4000000 329*aae38d10SBaptiste Daroussin DATA("4000000", B4000000), 330*aae38d10SBaptiste Daroussin #endif 3310e3d5408SPeter Wemm }; 332*aae38d10SBaptiste Daroussin #undef DATA 3330e3d5408SPeter Wemm 3340e3d5408SPeter Wemm static int 3350e3d5408SPeter Wemm tbaudrate(char *rate) 3360e3d5408SPeter Wemm { 337*aae38d10SBaptiste Daroussin const SPEEDS *sp = 0; 338*aae38d10SBaptiste Daroussin size_t n; 3390e3d5408SPeter Wemm 3400e3d5408SPeter Wemm /* The baudrate number can be preceded by a 'B', which is ignored. */ 3410e3d5408SPeter Wemm if (*rate == 'B') 3420e3d5408SPeter Wemm ++rate; 3430e3d5408SPeter Wemm 344*aae38d10SBaptiste Daroussin for (n = 0; n < SIZEOF(speeds); ++n) { 345*aae38d10SBaptiste Daroussin if (n > 0 && (speeds[n].speed <= speeds[n - 1].speed)) { 346*aae38d10SBaptiste Daroussin /* if the speeds are not increasing, likely a numeric overflow */ 347*aae38d10SBaptiste Daroussin break; 348*aae38d10SBaptiste Daroussin } 349*aae38d10SBaptiste Daroussin if (!CaselessCmp(rate, speeds[n].string)) { 350*aae38d10SBaptiste Daroussin sp = speeds + n; 3510e3d5408SPeter Wemm break; 3520e3d5408SPeter Wemm } 3530e3d5408SPeter Wemm } 354*aae38d10SBaptiste Daroussin if (sp == 0) 3550e3d5408SPeter Wemm err("unknown baud rate %s", rate); 3560e3d5408SPeter Wemm return (sp->speed); 3570e3d5408SPeter Wemm } 3580e3d5408SPeter Wemm 3590e3d5408SPeter Wemm /* 3600e3d5408SPeter Wemm * Syntax for -m: 3610e3d5408SPeter Wemm * [port-type][test baudrate]:terminal-type 3620e3d5408SPeter Wemm * The baud rate tests are: >, <, @, =, ! 3630e3d5408SPeter Wemm */ 3640e3d5408SPeter Wemm static void 3650e3d5408SPeter Wemm add_mapping(const char *port, char *arg) 3660e3d5408SPeter Wemm { 3670e3d5408SPeter Wemm MAP *mapp; 3680e3d5408SPeter Wemm char *copy, *p; 3690e3d5408SPeter Wemm const char *termp; 3700e3d5408SPeter Wemm char *base = 0; 3710e3d5408SPeter Wemm 3720e3d5408SPeter Wemm copy = strdup(arg); 37306bfebdeSXin LI mapp = typeMalloc(MAP, 1); 3740e3d5408SPeter Wemm if (copy == 0 || mapp == 0) 3750e3d5408SPeter Wemm failed("malloc"); 37606bfebdeSXin LI 37706bfebdeSXin LI assert(copy != 0); 37806bfebdeSXin LI assert(mapp != 0); 37906bfebdeSXin LI 3800e3d5408SPeter Wemm mapp->next = 0; 3810e3d5408SPeter Wemm if (maplist == 0) 3820e3d5408SPeter Wemm cur = maplist = mapp; 3830e3d5408SPeter Wemm else { 3840e3d5408SPeter Wemm cur->next = mapp; 3850e3d5408SPeter Wemm cur = mapp; 3860e3d5408SPeter Wemm } 3870e3d5408SPeter Wemm 3880e3d5408SPeter Wemm mapp->porttype = arg; 3890e3d5408SPeter Wemm mapp->conditional = 0; 3900e3d5408SPeter Wemm 3910e3d5408SPeter Wemm arg = strpbrk(arg, "><@=!:"); 3920e3d5408SPeter Wemm 3930e3d5408SPeter Wemm if (arg == 0) { /* [?]term */ 3940e3d5408SPeter Wemm mapp->type = mapp->porttype; 3950e3d5408SPeter Wemm mapp->porttype = 0; 3960e3d5408SPeter Wemm goto done; 3970e3d5408SPeter Wemm } 3980e3d5408SPeter Wemm 3990e3d5408SPeter Wemm if (arg == mapp->porttype) /* [><@=! baud]:term */ 4000e3d5408SPeter Wemm termp = mapp->porttype = 0; 4010e3d5408SPeter Wemm else 4020e3d5408SPeter Wemm termp = base = arg; 4030e3d5408SPeter Wemm 40415589c42SPeter Wemm for (;; ++arg) { /* Optional conditionals. */ 4050e3d5408SPeter Wemm switch (*arg) { 4060e3d5408SPeter Wemm case '<': 4070e3d5408SPeter Wemm if (mapp->conditional & GT) 4080e3d5408SPeter Wemm goto badmopt; 4090e3d5408SPeter Wemm mapp->conditional |= LT; 4100e3d5408SPeter Wemm break; 4110e3d5408SPeter Wemm case '>': 4120e3d5408SPeter Wemm if (mapp->conditional & LT) 4130e3d5408SPeter Wemm goto badmopt; 4140e3d5408SPeter Wemm mapp->conditional |= GT; 4150e3d5408SPeter Wemm break; 4160e3d5408SPeter Wemm case '@': 4170e3d5408SPeter Wemm case '=': /* Not documented. */ 4180e3d5408SPeter Wemm mapp->conditional |= EQ; 4190e3d5408SPeter Wemm break; 4200e3d5408SPeter Wemm case '!': 4210e3d5408SPeter Wemm mapp->conditional |= NOT; 4220e3d5408SPeter Wemm break; 4230e3d5408SPeter Wemm default: 4240e3d5408SPeter Wemm goto next; 4250e3d5408SPeter Wemm } 42615589c42SPeter Wemm } 4270e3d5408SPeter Wemm 42815589c42SPeter Wemm next: 42915589c42SPeter Wemm if (*arg == ':') { 4300e3d5408SPeter Wemm if (mapp->conditional) 4310e3d5408SPeter Wemm goto badmopt; 4320e3d5408SPeter Wemm ++arg; 4330e3d5408SPeter Wemm } else { /* Optional baudrate. */ 4340e3d5408SPeter Wemm arg = strchr(p = arg, ':'); 4350e3d5408SPeter Wemm if (arg == 0) 4360e3d5408SPeter Wemm goto badmopt; 4370e3d5408SPeter Wemm *arg++ = '\0'; 4380e3d5408SPeter Wemm mapp->speed = tbaudrate(p); 4390e3d5408SPeter Wemm } 4400e3d5408SPeter Wemm 4410e3d5408SPeter Wemm mapp->type = arg; 4420e3d5408SPeter Wemm 4430e3d5408SPeter Wemm /* Terminate porttype, if specified. */ 4440e3d5408SPeter Wemm if (termp != 0) 4450e3d5408SPeter Wemm *base = '\0'; 4460e3d5408SPeter Wemm 4470e3d5408SPeter Wemm /* If a NOT conditional, reverse the test. */ 4480e3d5408SPeter Wemm if (mapp->conditional & NOT) 4490e3d5408SPeter Wemm mapp->conditional = ~mapp->conditional & (EQ | GT | LT); 4500e3d5408SPeter Wemm 4510e3d5408SPeter Wemm /* If user specified a port with an option flag, set it. */ 4525d08fb1fSRong-En Fan done: 4535d08fb1fSRong-En Fan if (port) { 4545d08fb1fSRong-En Fan if (mapp->porttype) { 4555d08fb1fSRong-En Fan badmopt: 4565d08fb1fSRong-En Fan err("illegal -m option format: %s", copy); 4575d08fb1fSRong-En Fan } 4580e3d5408SPeter Wemm mapp->porttype = port; 4590e3d5408SPeter Wemm } 4605d08fb1fSRong-En Fan free(copy); 4610e3d5408SPeter Wemm #ifdef MAPDEBUG 4620e3d5408SPeter Wemm (void) printf("port: %s\n", mapp->porttype ? mapp->porttype : "ANY"); 4630e3d5408SPeter Wemm (void) printf("type: %s\n", mapp->type); 4640e3d5408SPeter Wemm (void) printf("conditional: "); 4650e3d5408SPeter Wemm p = ""; 4660e3d5408SPeter Wemm if (mapp->conditional & GT) { 4670e3d5408SPeter Wemm (void) printf("GT"); 4680e3d5408SPeter Wemm p = "/"; 4690e3d5408SPeter Wemm } 4700e3d5408SPeter Wemm if (mapp->conditional & EQ) { 4710e3d5408SPeter Wemm (void) printf("%sEQ", p); 4720e3d5408SPeter Wemm p = "/"; 4730e3d5408SPeter Wemm } 4740e3d5408SPeter Wemm if (mapp->conditional & LT) 4750e3d5408SPeter Wemm (void) printf("%sLT", p); 4760e3d5408SPeter Wemm (void) printf("\nspeed: %d\n", mapp->speed); 4770e3d5408SPeter Wemm #endif 4780e3d5408SPeter Wemm } 4790e3d5408SPeter Wemm 4800e3d5408SPeter Wemm /* 4810e3d5408SPeter Wemm * Return the type of terminal to use for a port of type 'type', as specified 4820e3d5408SPeter Wemm * by the first applicable mapping in 'map'. If no mappings apply, return 4830e3d5408SPeter Wemm * 'type'. 4840e3d5408SPeter Wemm */ 4850e3d5408SPeter Wemm static const char * 4860e3d5408SPeter Wemm mapped(const char *type) 4870e3d5408SPeter Wemm { 4880e3d5408SPeter Wemm MAP *mapp; 4890e3d5408SPeter Wemm int match; 4900e3d5408SPeter Wemm 4910e3d5408SPeter Wemm for (mapp = maplist; mapp; mapp = mapp->next) 4920e3d5408SPeter Wemm if (mapp->porttype == 0 || !strcmp(mapp->porttype, type)) { 4930e3d5408SPeter Wemm switch (mapp->conditional) { 4940e3d5408SPeter Wemm case 0: /* No test specified. */ 4950e3d5408SPeter Wemm match = TRUE; 4960e3d5408SPeter Wemm break; 4970e3d5408SPeter Wemm case EQ: 49873f0a83dSXin LI match = ((int) ospeed == mapp->speed); 4990e3d5408SPeter Wemm break; 5000e3d5408SPeter Wemm case GE: 50173f0a83dSXin LI match = ((int) ospeed >= mapp->speed); 5020e3d5408SPeter Wemm break; 5030e3d5408SPeter Wemm case GT: 50473f0a83dSXin LI match = ((int) ospeed > mapp->speed); 5050e3d5408SPeter Wemm break; 5060e3d5408SPeter Wemm case LE: 50773f0a83dSXin LI match = ((int) ospeed <= mapp->speed); 5080e3d5408SPeter Wemm break; 5090e3d5408SPeter Wemm case LT: 51073f0a83dSXin LI match = ((int) ospeed < mapp->speed); 5110e3d5408SPeter Wemm break; 5120e3d5408SPeter Wemm default: 5130e3d5408SPeter Wemm match = FALSE; 5140e3d5408SPeter Wemm } 5150e3d5408SPeter Wemm if (match) 5160e3d5408SPeter Wemm return (mapp->type); 5170e3d5408SPeter Wemm } 5180e3d5408SPeter Wemm /* No match found; return given type. */ 5190e3d5408SPeter Wemm return (type); 5200e3d5408SPeter Wemm } 5210e3d5408SPeter Wemm 5220e3d5408SPeter Wemm /************************************************************************** 5230e3d5408SPeter Wemm * 5240e3d5408SPeter Wemm * Entry fetching 5250e3d5408SPeter Wemm * 5260e3d5408SPeter Wemm **************************************************************************/ 5270e3d5408SPeter Wemm 5280e3d5408SPeter Wemm /* 5290e3d5408SPeter Wemm * Figure out what kind of terminal we're dealing with, and then read in 5300e3d5408SPeter Wemm * its termcap entry. 5310e3d5408SPeter Wemm */ 5320e3d5408SPeter Wemm static const char * 533*aae38d10SBaptiste Daroussin get_termcap_entry(int fd, char *userarg) 5340e3d5408SPeter Wemm { 5357a69bbfbSPeter Wemm int errret; 5360e3d5408SPeter Wemm char *p; 5370e3d5408SPeter Wemm const char *ttype; 5380e3d5408SPeter Wemm #if HAVE_GETTTYNAM 5390e3d5408SPeter Wemm struct ttyent *t; 5400e3d5408SPeter Wemm #else 5410e3d5408SPeter Wemm FILE *fp; 5420e3d5408SPeter Wemm #endif 5430e3d5408SPeter Wemm char *ttypath; 5440e3d5408SPeter Wemm 545*aae38d10SBaptiste Daroussin (void) fd; 546*aae38d10SBaptiste Daroussin 5470e3d5408SPeter Wemm if (userarg) { 5480e3d5408SPeter Wemm ttype = userarg; 5490e3d5408SPeter Wemm goto found; 5500e3d5408SPeter Wemm } 5510e3d5408SPeter Wemm 5520e3d5408SPeter Wemm /* Try the environment. */ 5530e3d5408SPeter Wemm if ((ttype = getenv("TERM")) != 0) 5540e3d5408SPeter Wemm goto map; 5550e3d5408SPeter Wemm 556*aae38d10SBaptiste Daroussin if ((ttypath = ttyname(fd)) != 0) { 55718259542SPeter Wemm p = _nc_basename(ttypath); 5580e3d5408SPeter Wemm #if HAVE_GETTTYNAM 5590e3d5408SPeter Wemm /* 5600e3d5408SPeter Wemm * We have the 4.3BSD library call getttynam(3); that means 5610e3d5408SPeter Wemm * there's an /etc/ttys to look up device-to-type mappings in. 5620e3d5408SPeter Wemm * Try ttyname(3); check for dialup or other mapping. 5630e3d5408SPeter Wemm */ 5640e3d5408SPeter Wemm if ((t = getttynam(p))) { 5650e3d5408SPeter Wemm ttype = t->ty_type; 5660e3d5408SPeter Wemm goto map; 5670e3d5408SPeter Wemm } 5680e3d5408SPeter Wemm #else 5690e3d5408SPeter Wemm if ((fp = fopen("/etc/ttytype", "r")) != 0 5700e3d5408SPeter Wemm || (fp = fopen("/etc/ttys", "r")) != 0) { 5710e3d5408SPeter Wemm char buffer[BUFSIZ]; 5720e3d5408SPeter Wemm char *s, *t, *d; 5730e3d5408SPeter Wemm 5740e3d5408SPeter Wemm while (fgets(buffer, sizeof(buffer) - 1, fp) != 0) { 5750e3d5408SPeter Wemm for (s = buffer, t = d = 0; *s; s++) { 57639f2269fSPeter Wemm if (isspace(UChar(*s))) 5770e3d5408SPeter Wemm *s = '\0'; 5780e3d5408SPeter Wemm else if (t == 0) 5790e3d5408SPeter Wemm t = s; 5800e3d5408SPeter Wemm else if (d == 0 && s != buffer && s[-1] == '\0') 5810e3d5408SPeter Wemm d = s; 5820e3d5408SPeter Wemm } 5830e3d5408SPeter Wemm if (t != 0 && d != 0 && !strcmp(d, p)) { 5840e3d5408SPeter Wemm ttype = strdup(t); 5850e3d5408SPeter Wemm fclose(fp); 5860e3d5408SPeter Wemm goto map; 5870e3d5408SPeter Wemm } 5880e3d5408SPeter Wemm } 5890e3d5408SPeter Wemm fclose(fp); 5900e3d5408SPeter Wemm } 5910e3d5408SPeter Wemm #endif /* HAVE_GETTTYNAM */ 5920e3d5408SPeter Wemm } 5930e3d5408SPeter Wemm 5940e3d5408SPeter Wemm /* If still undefined, use "unknown". */ 5950e3d5408SPeter Wemm ttype = "unknown"; 5960e3d5408SPeter Wemm 5970e3d5408SPeter Wemm map:ttype = mapped(ttype); 5980e3d5408SPeter Wemm 5990e3d5408SPeter Wemm /* 6000e3d5408SPeter Wemm * If not a path, remove TERMCAP from the environment so we get a 6010e3d5408SPeter Wemm * real entry from /etc/termcap. This prevents us from being fooled 6020e3d5408SPeter Wemm * by out of date stuff in the environment. 6030e3d5408SPeter Wemm */ 60473f0a83dSXin LI found: 60573f0a83dSXin LI if ((p = getenv("TERMCAP")) != 0 && !_nc_is_abs_path(p)) { 6060e3d5408SPeter Wemm /* 'unsetenv("TERMCAP")' is not portable. 6070e3d5408SPeter Wemm * The 'environ' array is better. 6080e3d5408SPeter Wemm */ 6090e3d5408SPeter Wemm int n; 6100e3d5408SPeter Wemm for (n = 0; environ[n] != 0; n++) { 61173f0a83dSXin LI if (!strncmp("TERMCAP=", environ[n], (size_t) 8)) { 6120e3d5408SPeter Wemm while ((environ[n] = environ[n + 1]) != 0) { 6130e3d5408SPeter Wemm n++; 6140e3d5408SPeter Wemm } 6150e3d5408SPeter Wemm break; 6160e3d5408SPeter Wemm } 6170e3d5408SPeter Wemm } 6180e3d5408SPeter Wemm } 6190e3d5408SPeter Wemm 6200e3d5408SPeter Wemm /* 6210e3d5408SPeter Wemm * ttype now contains a pointer to the type of the terminal. 6220e3d5408SPeter Wemm * If the first character is '?', ask the user. 6230e3d5408SPeter Wemm */ 6240e3d5408SPeter Wemm if (ttype[0] == '?') { 6250e3d5408SPeter Wemm if (ttype[1] != '\0') 6260e3d5408SPeter Wemm ttype = askuser(ttype + 1); 6270e3d5408SPeter Wemm else 6280e3d5408SPeter Wemm ttype = askuser(0); 6290e3d5408SPeter Wemm } 6300e3d5408SPeter Wemm /* Find the terminfo entry. If it doesn't exist, ask the user. */ 631*aae38d10SBaptiste Daroussin while (setupterm((NCURSES_CONST char *) ttype, fd, &errret) 6327a69bbfbSPeter Wemm != OK) { 6330e3d5408SPeter Wemm if (errret == 0) { 6344a1a9510SRong-En Fan (void) fprintf(stderr, "%s: unknown terminal type %s\n", 6354a1a9510SRong-En Fan _nc_progname, ttype); 6360e3d5408SPeter Wemm ttype = 0; 63715589c42SPeter Wemm } else { 63815589c42SPeter Wemm (void) fprintf(stderr, 6394a1a9510SRong-En Fan "%s: can't initialize terminal type %s (error %d)\n", 6404a1a9510SRong-En Fan _nc_progname, ttype, errret); 6410e3d5408SPeter Wemm ttype = 0; 6420e3d5408SPeter Wemm } 6430e3d5408SPeter Wemm ttype = askuser(ttype); 6440e3d5408SPeter Wemm } 6450e3d5408SPeter Wemm #if BROKEN_LINKER 6460e3d5408SPeter Wemm tgetflag("am"); /* force lib_termcap.o to be linked for 'ospeed' */ 6470e3d5408SPeter Wemm #endif 6480e3d5408SPeter Wemm return (ttype); 6490e3d5408SPeter Wemm } 6500e3d5408SPeter Wemm 6510e3d5408SPeter Wemm /************************************************************************** 6520e3d5408SPeter Wemm * 6530e3d5408SPeter Wemm * Main sequence 6540e3d5408SPeter Wemm * 6550e3d5408SPeter Wemm **************************************************************************/ 6560e3d5408SPeter Wemm 6570e3d5408SPeter Wemm /* 6580e3d5408SPeter Wemm * Convert the obsolete argument forms into something that getopt can handle. 6590e3d5408SPeter Wemm * This means that -e, -i and -k get default arguments supplied for them. 6600e3d5408SPeter Wemm */ 6610e3d5408SPeter Wemm static void 6620e3d5408SPeter Wemm obsolete(char **argv) 6630e3d5408SPeter Wemm { 6640e3d5408SPeter Wemm for (; *argv; ++argv) { 6650e3d5408SPeter Wemm char *parm = argv[0]; 6660e3d5408SPeter Wemm 66715589c42SPeter Wemm if (parm[0] == '-' && parm[1] == '\0') { 6680e3d5408SPeter Wemm argv[0] = strdup("-q"); 6690e3d5408SPeter Wemm continue; 6700e3d5408SPeter Wemm } 6710e3d5408SPeter Wemm 6720e3d5408SPeter Wemm if ((parm[0] != '-') 6730e3d5408SPeter Wemm || (argv[1] && argv[1][0] != '-') 6740e3d5408SPeter Wemm || (parm[1] != 'e' && parm[1] != 'i' && parm[1] != 'k') 6750e3d5408SPeter Wemm || (parm[2] != '\0')) 6760e3d5408SPeter Wemm continue; 6770e3d5408SPeter Wemm switch (argv[0][1]) { 6780e3d5408SPeter Wemm case 'e': 6790e3d5408SPeter Wemm argv[0] = strdup("-e^H"); 6800e3d5408SPeter Wemm break; 6810e3d5408SPeter Wemm case 'i': 6820e3d5408SPeter Wemm argv[0] = strdup("-i^C"); 6830e3d5408SPeter Wemm break; 6840e3d5408SPeter Wemm case 'k': 6850e3d5408SPeter Wemm argv[0] = strdup("-k^U"); 6860e3d5408SPeter Wemm break; 6870e3d5408SPeter Wemm } 6880e3d5408SPeter Wemm } 6890e3d5408SPeter Wemm } 6900e3d5408SPeter Wemm 6910e3d5408SPeter Wemm static void 692*aae38d10SBaptiste Daroussin print_shell_commands(const char *ttype) 693*aae38d10SBaptiste Daroussin { 694*aae38d10SBaptiste Daroussin const char *p; 695*aae38d10SBaptiste Daroussin int len; 696*aae38d10SBaptiste Daroussin char *var; 697*aae38d10SBaptiste Daroussin char *leaf; 698*aae38d10SBaptiste Daroussin /* 699*aae38d10SBaptiste Daroussin * Figure out what shell we're using. A hack, we look for an 700*aae38d10SBaptiste Daroussin * environmental variable SHELL ending in "csh". 701*aae38d10SBaptiste Daroussin */ 702*aae38d10SBaptiste Daroussin if ((var = getenv("SHELL")) != 0 703*aae38d10SBaptiste Daroussin && ((len = (int) strlen(leaf = _nc_basename(var))) >= 3) 704*aae38d10SBaptiste Daroussin && !strcmp(leaf + len - 3, "csh")) 705*aae38d10SBaptiste Daroussin p = "set noglob;\nsetenv TERM %s;\nunset noglob;\n"; 706*aae38d10SBaptiste Daroussin else 707*aae38d10SBaptiste Daroussin p = "TERM=%s;\n"; 708*aae38d10SBaptiste Daroussin (void) printf(p, ttype); 709*aae38d10SBaptiste Daroussin } 710*aae38d10SBaptiste Daroussin 711*aae38d10SBaptiste Daroussin static void 7124a1a9510SRong-En Fan usage(void) 7130e3d5408SPeter Wemm { 714*aae38d10SBaptiste Daroussin #define SKIP(s) /* nothing */ 715*aae38d10SBaptiste Daroussin #define KEEP(s) s "\n" 716*aae38d10SBaptiste Daroussin static const char msg[] = 7174a1a9510SRong-En Fan { 718*aae38d10SBaptiste Daroussin KEEP("") 719*aae38d10SBaptiste Daroussin KEEP("Options:") 720*aae38d10SBaptiste Daroussin SKIP(" -a arpanet (obsolete)") 721*aae38d10SBaptiste Daroussin KEEP(" -c set control characters") 722*aae38d10SBaptiste Daroussin SKIP(" -d dialup (obsolete)") 723*aae38d10SBaptiste Daroussin KEEP(" -e ch erase character") 724*aae38d10SBaptiste Daroussin KEEP(" -I no initialization strings") 725*aae38d10SBaptiste Daroussin KEEP(" -i ch interrupt character") 726*aae38d10SBaptiste Daroussin KEEP(" -k ch kill character") 727*aae38d10SBaptiste Daroussin KEEP(" -m mapping map identifier to type") 728*aae38d10SBaptiste Daroussin SKIP(" -p plugboard (obsolete)") 729*aae38d10SBaptiste Daroussin KEEP(" -Q do not output control key settings") 730*aae38d10SBaptiste Daroussin KEEP(" -q display term only, do no changes") 731*aae38d10SBaptiste Daroussin KEEP(" -r display term on stderr") 732*aae38d10SBaptiste Daroussin SKIP(" -S (obsolete)") 733*aae38d10SBaptiste Daroussin KEEP(" -s output TERM set command") 734*aae38d10SBaptiste Daroussin KEEP(" -V print curses-version") 735*aae38d10SBaptiste Daroussin KEEP(" -w set window-size") 736*aae38d10SBaptiste Daroussin KEEP("") 737*aae38d10SBaptiste Daroussin KEEP("If neither -c/-w are given, both are assumed.") 7384a1a9510SRong-En Fan }; 739*aae38d10SBaptiste Daroussin #undef KEEP 740*aae38d10SBaptiste Daroussin #undef SKIP 7414a1a9510SRong-En Fan (void) fprintf(stderr, "Usage: %s [options] [terminal]\n", _nc_progname); 742*aae38d10SBaptiste Daroussin fputs(msg, stderr); 743*aae38d10SBaptiste Daroussin ExitProgram(EXIT_FAILURE); 74439f2269fSPeter Wemm /* NOTREACHED */ 7450e3d5408SPeter Wemm } 7460e3d5408SPeter Wemm 74715589c42SPeter Wemm static char 74815589c42SPeter Wemm arg_to_char(void) 7490e3d5408SPeter Wemm { 7505d08fb1fSRong-En Fan return (char) ((optarg[0] == '^' && optarg[1] != '\0') 7510e3d5408SPeter Wemm ? ((optarg[1] == '?') ? '\177' : CTRL(optarg[1])) 7525d08fb1fSRong-En Fan : optarg[0]); 7530e3d5408SPeter Wemm } 7540e3d5408SPeter Wemm 7550e3d5408SPeter Wemm int 7560e3d5408SPeter Wemm main(int argc, char **argv) 7570e3d5408SPeter Wemm { 7580e3d5408SPeter Wemm int ch, noinit, noset, quiet, Sflag, sflag, showterm; 7590e3d5408SPeter Wemm const char *ttype; 760*aae38d10SBaptiste Daroussin int terasechar = -1; /* new erase character */ 761*aae38d10SBaptiste Daroussin int intrchar = -1; /* new interrupt character */ 762*aae38d10SBaptiste Daroussin int tkillchar = -1; /* new kill character */ 763*aae38d10SBaptiste Daroussin int my_fd; 764*aae38d10SBaptiste Daroussin bool opt_c = FALSE; /* set control-chars */ 765*aae38d10SBaptiste Daroussin bool opt_w = FALSE; /* set window-size */ 766*aae38d10SBaptiste Daroussin TTY mode, oldmode; 7670e3d5408SPeter Wemm 768*aae38d10SBaptiste Daroussin my_fd = STDERR_FILENO; 7690e3d5408SPeter Wemm obsolete(argv); 7700e3d5408SPeter Wemm noinit = noset = quiet = Sflag = sflag = showterm = 0; 771*aae38d10SBaptiste Daroussin while ((ch = getopt(argc, argv, "a:cd:e:Ii:k:m:p:qQrSsVw")) != -1) { 7720e3d5408SPeter Wemm switch (ch) { 7734a1a9510SRong-En Fan case 'c': /* set control-chars */ 7744a1a9510SRong-En Fan opt_c = TRUE; 7750e3d5408SPeter Wemm break; 7760e3d5408SPeter Wemm case 'a': /* OBSOLETE: map identifier to type */ 7770e3d5408SPeter Wemm add_mapping("arpanet", optarg); 7780e3d5408SPeter Wemm break; 7790e3d5408SPeter Wemm case 'd': /* OBSOLETE: map identifier to type */ 7800e3d5408SPeter Wemm add_mapping("dialup", optarg); 7810e3d5408SPeter Wemm break; 7820e3d5408SPeter Wemm case 'e': /* erase character */ 7830e3d5408SPeter Wemm terasechar = arg_to_char(); 7840e3d5408SPeter Wemm break; 7850e3d5408SPeter Wemm case 'I': /* no initialization strings */ 7860e3d5408SPeter Wemm noinit = 1; 7870e3d5408SPeter Wemm break; 7880e3d5408SPeter Wemm case 'i': /* interrupt character */ 7890e3d5408SPeter Wemm intrchar = arg_to_char(); 7900e3d5408SPeter Wemm break; 7910e3d5408SPeter Wemm case 'k': /* kill character */ 7920e3d5408SPeter Wemm tkillchar = arg_to_char(); 7930e3d5408SPeter Wemm break; 7940e3d5408SPeter Wemm case 'm': /* map identifier to type */ 7950e3d5408SPeter Wemm add_mapping(0, optarg); 7960e3d5408SPeter Wemm break; 7970e3d5408SPeter Wemm case 'p': /* OBSOLETE: map identifier to type */ 7980e3d5408SPeter Wemm add_mapping("plugboard", optarg); 7990e3d5408SPeter Wemm break; 8000e3d5408SPeter Wemm case 'Q': /* don't output control key settings */ 8010e3d5408SPeter Wemm quiet = 1; 8020e3d5408SPeter Wemm break; 8034a1a9510SRong-En Fan case 'q': /* display term only */ 8044a1a9510SRong-En Fan noset = 1; 8050e3d5408SPeter Wemm break; 8060e3d5408SPeter Wemm case 'r': /* display term on stderr */ 8070e3d5408SPeter Wemm showterm = 1; 8080e3d5408SPeter Wemm break; 8094a1a9510SRong-En Fan case 'S': /* OBSOLETE: output TERM & TERMCAP */ 8104a1a9510SRong-En Fan Sflag = 1; 8114a1a9510SRong-En Fan break; 8120e3d5408SPeter Wemm case 's': /* output TERM set command */ 8130e3d5408SPeter Wemm sflag = 1; 8140e3d5408SPeter Wemm break; 8154a1a9510SRong-En Fan case 'V': /* print curses-version */ 81618259542SPeter Wemm puts(curses_version()); 8174a1a9510SRong-En Fan ExitProgram(EXIT_SUCCESS); 8184a1a9510SRong-En Fan case 'w': /* set window-size */ 8194a1a9510SRong-En Fan opt_w = TRUE; 8204a1a9510SRong-En Fan break; 8210e3d5408SPeter Wemm case '?': 8220e3d5408SPeter Wemm default: 8234a1a9510SRong-En Fan usage(); 8240e3d5408SPeter Wemm } 8250e3d5408SPeter Wemm } 8264a1a9510SRong-En Fan 8274a1a9510SRong-En Fan _nc_progname = _nc_rootname(*argv); 8280e3d5408SPeter Wemm argc -= optind; 8290e3d5408SPeter Wemm argv += optind; 8300e3d5408SPeter Wemm 8310e3d5408SPeter Wemm if (argc > 1) 8324a1a9510SRong-En Fan usage(); 8334a1a9510SRong-En Fan 8344a1a9510SRong-En Fan if (!opt_c && !opt_w) 8354a1a9510SRong-En Fan opt_c = opt_w = TRUE; 8364a1a9510SRong-En Fan 837*aae38d10SBaptiste Daroussin my_fd = save_tty_settings(&mode, TRUE); 838*aae38d10SBaptiste Daroussin oldmode = mode; 8394a1a9510SRong-En Fan #ifdef TERMIOS 8405d08fb1fSRong-En Fan ospeed = (NCURSES_OSPEED) cfgetospeed(&mode); 8414a1a9510SRong-En Fan #else 8425d08fb1fSRong-En Fan ospeed = (NCURSES_OSPEED) mode.sg_ospeed; 8434a1a9510SRong-En Fan #endif 8444a1a9510SRong-En Fan 84506bfebdeSXin LI if (same_program(_nc_progname, PROG_RESET)) { 846*aae38d10SBaptiste Daroussin reset_start(stderr, TRUE, FALSE); 847*aae38d10SBaptiste Daroussin reset_tty_settings(my_fd, &mode); 848*aae38d10SBaptiste Daroussin } else { 849*aae38d10SBaptiste Daroussin reset_start(stderr, FALSE, TRUE); 8504a1a9510SRong-En Fan } 8510e3d5408SPeter Wemm 852*aae38d10SBaptiste Daroussin ttype = get_termcap_entry(my_fd, *argv); 8530e3d5408SPeter Wemm 8540e3d5408SPeter Wemm if (!noset) { 85573f0a83dSXin LI #if HAVE_SIZECHANGE 8564a1a9510SRong-En Fan if (opt_w) { 857*aae38d10SBaptiste Daroussin set_window_size(my_fd, &lines, &columns); 8584a1a9510SRong-En Fan } 8590e3d5408SPeter Wemm #endif 8604a1a9510SRong-En Fan if (opt_c) { 861*aae38d10SBaptiste Daroussin set_control_chars(&mode, terasechar, intrchar, tkillchar); 862*aae38d10SBaptiste Daroussin set_conversions(&mode); 8630e3d5408SPeter Wemm 864*aae38d10SBaptiste Daroussin if (!noinit) { 865*aae38d10SBaptiste Daroussin if (send_init_strings(my_fd, &oldmode)) { 866*aae38d10SBaptiste Daroussin (void) putc('\r', stderr); 867*aae38d10SBaptiste Daroussin (void) fflush(stderr); 868*aae38d10SBaptiste Daroussin (void) napms(1000); /* Settle the terminal. */ 8690e3d5408SPeter Wemm } 87015589c42SPeter Wemm } 871*aae38d10SBaptiste Daroussin 872*aae38d10SBaptiste Daroussin update_tty_settings(&oldmode, &mode); 873*aae38d10SBaptiste Daroussin } 8744a1a9510SRong-En Fan } 8750e3d5408SPeter Wemm 876*aae38d10SBaptiste Daroussin if (noset) { 8770e3d5408SPeter Wemm (void) printf("%s\n", ttype); 878*aae38d10SBaptiste Daroussin } else { 8790e3d5408SPeter Wemm if (showterm) 8800e3d5408SPeter Wemm (void) fprintf(stderr, "Terminal type is %s.\n", ttype); 8810e3d5408SPeter Wemm /* 8820e3d5408SPeter Wemm * If erase, kill and interrupt characters could have been 8830e3d5408SPeter Wemm * modified and not -Q, display the changes. 8840e3d5408SPeter Wemm */ 8850e3d5408SPeter Wemm if (!quiet) { 886*aae38d10SBaptiste Daroussin print_tty_chars(&oldmode, &mode); 8870e3d5408SPeter Wemm } 8880e3d5408SPeter Wemm } 8890e3d5408SPeter Wemm 8900e3d5408SPeter Wemm if (Sflag) 8910e3d5408SPeter Wemm err("The -S option is not supported under terminfo."); 8920e3d5408SPeter Wemm 8930e3d5408SPeter Wemm if (sflag) { 894*aae38d10SBaptiste Daroussin print_shell_commands(ttype); 8950e3d5408SPeter Wemm } 8960e3d5408SPeter Wemm 8974a1a9510SRong-En Fan ExitProgram(EXIT_SUCCESS); 8980e3d5408SPeter Wemm } 899