10e3d5408SPeter Wemm /**************************************************************************** 2e1865124SBaptiste Daroussin * Copyright 2020 Thomas E. Dickey * 3e1865124SBaptiste 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*7a656419SBaptiste Daroussin MODULE_ID("$Id: tset.c,v 1.125 2020/09/05 22:54:47 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 { 230*7a656419SBaptiste Daroussin const char string[8]; 2310e3d5408SPeter Wemm int speed; 2320e3d5408SPeter Wemm } SPEEDS; 2330e3d5408SPeter Wemm 234*7a656419SBaptiste Daroussin #if defined(EXP_WIN32_DRIVER) 235*7a656419SBaptiste Daroussin static const SPEEDS speeds[] = 236*7a656419SBaptiste Daroussin { 237*7a656419SBaptiste Daroussin {"0", 0} 238*7a656419SBaptiste Daroussin }; 239*7a656419SBaptiste Daroussin #else 24015589c42SPeter Wemm static const SPEEDS speeds[] = 24115589c42SPeter Wemm { 242aae38d10SBaptiste Daroussin DATA("0", B0), 243aae38d10SBaptiste Daroussin DATA("50", B50), 244aae38d10SBaptiste Daroussin DATA("75", B75), 245aae38d10SBaptiste Daroussin DATA("110", B110), 246aae38d10SBaptiste Daroussin DATA("134", B134), 247aae38d10SBaptiste Daroussin DATA("134.5", B134), 248aae38d10SBaptiste Daroussin DATA("150", B150), 249aae38d10SBaptiste Daroussin DATA("200", B200), 250aae38d10SBaptiste Daroussin DATA("300", B300), 251aae38d10SBaptiste Daroussin DATA("600", B600), 252aae38d10SBaptiste Daroussin DATA("1200", B1200), 253aae38d10SBaptiste Daroussin DATA("1800", B1800), 254aae38d10SBaptiste Daroussin DATA("2400", B2400), 255aae38d10SBaptiste Daroussin DATA("4800", B4800), 256aae38d10SBaptiste Daroussin DATA("9600", B9600), 25718259542SPeter Wemm /* sgttyb may define up to this point */ 25818259542SPeter Wemm #ifdef B19200 259aae38d10SBaptiste Daroussin DATA("19200", B19200), 26018259542SPeter Wemm #endif 26118259542SPeter Wemm #ifdef B38400 262aae38d10SBaptiste Daroussin DATA("38400", B38400), 26318259542SPeter Wemm #endif 26418259542SPeter Wemm #ifdef B19200 265aae38d10SBaptiste Daroussin DATA("19200", B19200), 26618259542SPeter Wemm #endif 26718259542SPeter Wemm #ifdef B38400 268aae38d10SBaptiste Daroussin DATA("38400", B38400), 26918259542SPeter Wemm #endif 2700e3d5408SPeter Wemm #ifdef B19200 271aae38d10SBaptiste Daroussin DATA("19200", B19200), 2720e3d5408SPeter Wemm #else 2730e3d5408SPeter Wemm #ifdef EXTA 274aae38d10SBaptiste Daroussin DATA("19200", EXTA), 2750e3d5408SPeter Wemm #endif 2760e3d5408SPeter Wemm #endif 2770e3d5408SPeter Wemm #ifdef B38400 278aae38d10SBaptiste Daroussin DATA("38400", B38400), 2790e3d5408SPeter Wemm #else 2800e3d5408SPeter Wemm #ifdef EXTB 281aae38d10SBaptiste Daroussin DATA("38400", EXTB), 2820e3d5408SPeter Wemm #endif 2830e3d5408SPeter Wemm #endif 2840e3d5408SPeter Wemm #ifdef B57600 285aae38d10SBaptiste Daroussin DATA("57600", B57600), 286aae38d10SBaptiste Daroussin #endif 287aae38d10SBaptiste Daroussin #ifdef B76800 288aae38d10SBaptiste Daroussin DATA("76800", B57600), 2890e3d5408SPeter Wemm #endif 2900e3d5408SPeter Wemm #ifdef B115200 291aae38d10SBaptiste Daroussin DATA("115200", B115200), 292aae38d10SBaptiste Daroussin #endif 293aae38d10SBaptiste Daroussin #ifdef B153600 294aae38d10SBaptiste Daroussin DATA("153600", B153600), 2950e3d5408SPeter Wemm #endif 2960e3d5408SPeter Wemm #ifdef B230400 297aae38d10SBaptiste Daroussin DATA("230400", B230400), 298aae38d10SBaptiste Daroussin #endif 299aae38d10SBaptiste Daroussin #ifdef B307200 300aae38d10SBaptiste Daroussin DATA("307200", B307200), 3010e3d5408SPeter Wemm #endif 3020e3d5408SPeter Wemm #ifdef B460800 303aae38d10SBaptiste Daroussin DATA("460800", B460800), 3040e3d5408SPeter Wemm #endif 305aae38d10SBaptiste Daroussin #ifdef B500000 306aae38d10SBaptiste Daroussin DATA("500000", B500000), 307aae38d10SBaptiste Daroussin #endif 308aae38d10SBaptiste Daroussin #ifdef B576000 309aae38d10SBaptiste Daroussin DATA("576000", B576000), 310aae38d10SBaptiste Daroussin #endif 311aae38d10SBaptiste Daroussin #ifdef B921600 312aae38d10SBaptiste Daroussin DATA("921600", B921600), 313aae38d10SBaptiste Daroussin #endif 314aae38d10SBaptiste Daroussin #ifdef B1000000 315aae38d10SBaptiste Daroussin DATA("1000000", B1000000), 316aae38d10SBaptiste Daroussin #endif 317aae38d10SBaptiste Daroussin #ifdef B1152000 318aae38d10SBaptiste Daroussin DATA("1152000", B1152000), 319aae38d10SBaptiste Daroussin #endif 320aae38d10SBaptiste Daroussin #ifdef B1500000 321aae38d10SBaptiste Daroussin DATA("1500000", B1500000), 322aae38d10SBaptiste Daroussin #endif 323aae38d10SBaptiste Daroussin #ifdef B2000000 324aae38d10SBaptiste Daroussin DATA("2000000", B2000000), 325aae38d10SBaptiste Daroussin #endif 326aae38d10SBaptiste Daroussin #ifdef B2500000 327aae38d10SBaptiste Daroussin DATA("2500000", B2500000), 328aae38d10SBaptiste Daroussin #endif 329aae38d10SBaptiste Daroussin #ifdef B3000000 330aae38d10SBaptiste Daroussin DATA("3000000", B3000000), 331aae38d10SBaptiste Daroussin #endif 332aae38d10SBaptiste Daroussin #ifdef B3500000 333aae38d10SBaptiste Daroussin DATA("3500000", B3500000), 334aae38d10SBaptiste Daroussin #endif 335aae38d10SBaptiste Daroussin #ifdef B4000000 336aae38d10SBaptiste Daroussin DATA("4000000", B4000000), 337aae38d10SBaptiste Daroussin #endif 3380e3d5408SPeter Wemm }; 339aae38d10SBaptiste Daroussin #undef DATA 340*7a656419SBaptiste Daroussin #endif 3410e3d5408SPeter Wemm 3420e3d5408SPeter Wemm static int 3430e3d5408SPeter Wemm tbaudrate(char *rate) 3440e3d5408SPeter Wemm { 345aae38d10SBaptiste Daroussin const SPEEDS *sp = 0; 346aae38d10SBaptiste Daroussin size_t n; 3470e3d5408SPeter Wemm 3480e3d5408SPeter Wemm /* The baudrate number can be preceded by a 'B', which is ignored. */ 3490e3d5408SPeter Wemm if (*rate == 'B') 3500e3d5408SPeter Wemm ++rate; 3510e3d5408SPeter Wemm 352aae38d10SBaptiste Daroussin for (n = 0; n < SIZEOF(speeds); ++n) { 353aae38d10SBaptiste Daroussin if (n > 0 && (speeds[n].speed <= speeds[n - 1].speed)) { 354aae38d10SBaptiste Daroussin /* if the speeds are not increasing, likely a numeric overflow */ 355aae38d10SBaptiste Daroussin break; 356aae38d10SBaptiste Daroussin } 357aae38d10SBaptiste Daroussin if (!CaselessCmp(rate, speeds[n].string)) { 358aae38d10SBaptiste Daroussin sp = speeds + n; 3590e3d5408SPeter Wemm break; 3600e3d5408SPeter Wemm } 3610e3d5408SPeter Wemm } 362aae38d10SBaptiste Daroussin if (sp == 0) 3630e3d5408SPeter Wemm err("unknown baud rate %s", rate); 3640e3d5408SPeter Wemm return (sp->speed); 3650e3d5408SPeter Wemm } 3660e3d5408SPeter Wemm 3670e3d5408SPeter Wemm /* 3680e3d5408SPeter Wemm * Syntax for -m: 3690e3d5408SPeter Wemm * [port-type][test baudrate]:terminal-type 3700e3d5408SPeter Wemm * The baud rate tests are: >, <, @, =, ! 3710e3d5408SPeter Wemm */ 3720e3d5408SPeter Wemm static void 3730e3d5408SPeter Wemm add_mapping(const char *port, char *arg) 3740e3d5408SPeter Wemm { 3750e3d5408SPeter Wemm MAP *mapp; 3760e3d5408SPeter Wemm char *copy, *p; 3770e3d5408SPeter Wemm const char *termp; 3780e3d5408SPeter Wemm char *base = 0; 3790e3d5408SPeter Wemm 3800e3d5408SPeter Wemm copy = strdup(arg); 38106bfebdeSXin LI mapp = typeMalloc(MAP, 1); 3820e3d5408SPeter Wemm if (copy == 0 || mapp == 0) 3830e3d5408SPeter Wemm failed("malloc"); 38406bfebdeSXin LI 38506bfebdeSXin LI assert(copy != 0); 38606bfebdeSXin LI assert(mapp != 0); 38706bfebdeSXin LI 3880e3d5408SPeter Wemm mapp->next = 0; 3890e3d5408SPeter Wemm if (maplist == 0) 3900e3d5408SPeter Wemm cur = maplist = mapp; 3910e3d5408SPeter Wemm else { 3920e3d5408SPeter Wemm cur->next = mapp; 3930e3d5408SPeter Wemm cur = mapp; 3940e3d5408SPeter Wemm } 3950e3d5408SPeter Wemm 3960e3d5408SPeter Wemm mapp->porttype = arg; 3970e3d5408SPeter Wemm mapp->conditional = 0; 3980e3d5408SPeter Wemm 3990e3d5408SPeter Wemm arg = strpbrk(arg, "><@=!:"); 4000e3d5408SPeter Wemm 4010e3d5408SPeter Wemm if (arg == 0) { /* [?]term */ 4020e3d5408SPeter Wemm mapp->type = mapp->porttype; 4030e3d5408SPeter Wemm mapp->porttype = 0; 4040e3d5408SPeter Wemm goto done; 4050e3d5408SPeter Wemm } 4060e3d5408SPeter Wemm 4070e3d5408SPeter Wemm if (arg == mapp->porttype) /* [><@=! baud]:term */ 4080e3d5408SPeter Wemm termp = mapp->porttype = 0; 4090e3d5408SPeter Wemm else 4100e3d5408SPeter Wemm termp = base = arg; 4110e3d5408SPeter Wemm 41215589c42SPeter Wemm for (;; ++arg) { /* Optional conditionals. */ 4130e3d5408SPeter Wemm switch (*arg) { 4140e3d5408SPeter Wemm case '<': 4150e3d5408SPeter Wemm if (mapp->conditional & GT) 4160e3d5408SPeter Wemm goto badmopt; 4170e3d5408SPeter Wemm mapp->conditional |= LT; 4180e3d5408SPeter Wemm break; 4190e3d5408SPeter Wemm case '>': 4200e3d5408SPeter Wemm if (mapp->conditional & LT) 4210e3d5408SPeter Wemm goto badmopt; 4220e3d5408SPeter Wemm mapp->conditional |= GT; 4230e3d5408SPeter Wemm break; 4240e3d5408SPeter Wemm case '@': 4250e3d5408SPeter Wemm case '=': /* Not documented. */ 4260e3d5408SPeter Wemm mapp->conditional |= EQ; 4270e3d5408SPeter Wemm break; 4280e3d5408SPeter Wemm case '!': 4290e3d5408SPeter Wemm mapp->conditional |= NOT; 4300e3d5408SPeter Wemm break; 4310e3d5408SPeter Wemm default: 4320e3d5408SPeter Wemm goto next; 4330e3d5408SPeter Wemm } 43415589c42SPeter Wemm } 4350e3d5408SPeter Wemm 43615589c42SPeter Wemm next: 43715589c42SPeter Wemm if (*arg == ':') { 4380e3d5408SPeter Wemm if (mapp->conditional) 4390e3d5408SPeter Wemm goto badmopt; 4400e3d5408SPeter Wemm ++arg; 4410e3d5408SPeter Wemm } else { /* Optional baudrate. */ 4420e3d5408SPeter Wemm arg = strchr(p = arg, ':'); 4430e3d5408SPeter Wemm if (arg == 0) 4440e3d5408SPeter Wemm goto badmopt; 4450e3d5408SPeter Wemm *arg++ = '\0'; 4460e3d5408SPeter Wemm mapp->speed = tbaudrate(p); 4470e3d5408SPeter Wemm } 4480e3d5408SPeter Wemm 4490e3d5408SPeter Wemm mapp->type = arg; 4500e3d5408SPeter Wemm 4510e3d5408SPeter Wemm /* Terminate porttype, if specified. */ 4520e3d5408SPeter Wemm if (termp != 0) 4530e3d5408SPeter Wemm *base = '\0'; 4540e3d5408SPeter Wemm 4550e3d5408SPeter Wemm /* If a NOT conditional, reverse the test. */ 4560e3d5408SPeter Wemm if (mapp->conditional & NOT) 4570e3d5408SPeter Wemm mapp->conditional = ~mapp->conditional & (EQ | GT | LT); 4580e3d5408SPeter Wemm 4590e3d5408SPeter Wemm /* If user specified a port with an option flag, set it. */ 4605d08fb1fSRong-En Fan done: 4615d08fb1fSRong-En Fan if (port) { 4625d08fb1fSRong-En Fan if (mapp->porttype) { 4635d08fb1fSRong-En Fan badmopt: 4645d08fb1fSRong-En Fan err("illegal -m option format: %s", copy); 4655d08fb1fSRong-En Fan } 4660e3d5408SPeter Wemm mapp->porttype = port; 4670e3d5408SPeter Wemm } 4685d08fb1fSRong-En Fan free(copy); 4690e3d5408SPeter Wemm #ifdef MAPDEBUG 4700e3d5408SPeter Wemm (void) printf("port: %s\n", mapp->porttype ? mapp->porttype : "ANY"); 4710e3d5408SPeter Wemm (void) printf("type: %s\n", mapp->type); 4720e3d5408SPeter Wemm (void) printf("conditional: "); 4730e3d5408SPeter Wemm p = ""; 4740e3d5408SPeter Wemm if (mapp->conditional & GT) { 4750e3d5408SPeter Wemm (void) printf("GT"); 4760e3d5408SPeter Wemm p = "/"; 4770e3d5408SPeter Wemm } 4780e3d5408SPeter Wemm if (mapp->conditional & EQ) { 4790e3d5408SPeter Wemm (void) printf("%sEQ", p); 4800e3d5408SPeter Wemm p = "/"; 4810e3d5408SPeter Wemm } 4820e3d5408SPeter Wemm if (mapp->conditional & LT) 4830e3d5408SPeter Wemm (void) printf("%sLT", p); 4840e3d5408SPeter Wemm (void) printf("\nspeed: %d\n", mapp->speed); 4850e3d5408SPeter Wemm #endif 4860e3d5408SPeter Wemm } 4870e3d5408SPeter Wemm 4880e3d5408SPeter Wemm /* 4890e3d5408SPeter Wemm * Return the type of terminal to use for a port of type 'type', as specified 4900e3d5408SPeter Wemm * by the first applicable mapping in 'map'. If no mappings apply, return 4910e3d5408SPeter Wemm * 'type'. 4920e3d5408SPeter Wemm */ 4930e3d5408SPeter Wemm static const char * 4940e3d5408SPeter Wemm mapped(const char *type) 4950e3d5408SPeter Wemm { 4960e3d5408SPeter Wemm MAP *mapp; 4970e3d5408SPeter Wemm int match; 4980e3d5408SPeter Wemm 4990e3d5408SPeter Wemm for (mapp = maplist; mapp; mapp = mapp->next) 5000e3d5408SPeter Wemm if (mapp->porttype == 0 || !strcmp(mapp->porttype, type)) { 5010e3d5408SPeter Wemm switch (mapp->conditional) { 5020e3d5408SPeter Wemm case 0: /* No test specified. */ 5030e3d5408SPeter Wemm match = TRUE; 5040e3d5408SPeter Wemm break; 5050e3d5408SPeter Wemm case EQ: 50673f0a83dSXin LI match = ((int) ospeed == mapp->speed); 5070e3d5408SPeter Wemm break; 5080e3d5408SPeter Wemm case GE: 50973f0a83dSXin LI match = ((int) ospeed >= mapp->speed); 5100e3d5408SPeter Wemm break; 5110e3d5408SPeter Wemm case GT: 51273f0a83dSXin LI match = ((int) ospeed > mapp->speed); 5130e3d5408SPeter Wemm break; 5140e3d5408SPeter Wemm case LE: 51573f0a83dSXin LI match = ((int) ospeed <= mapp->speed); 5160e3d5408SPeter Wemm break; 5170e3d5408SPeter Wemm case LT: 51873f0a83dSXin LI match = ((int) ospeed < mapp->speed); 5190e3d5408SPeter Wemm break; 5200e3d5408SPeter Wemm default: 5210e3d5408SPeter Wemm match = FALSE; 5220e3d5408SPeter Wemm } 5230e3d5408SPeter Wemm if (match) 5240e3d5408SPeter Wemm return (mapp->type); 5250e3d5408SPeter Wemm } 5260e3d5408SPeter Wemm /* No match found; return given type. */ 5270e3d5408SPeter Wemm return (type); 5280e3d5408SPeter Wemm } 5290e3d5408SPeter Wemm 5300e3d5408SPeter Wemm /************************************************************************** 5310e3d5408SPeter Wemm * 5320e3d5408SPeter Wemm * Entry fetching 5330e3d5408SPeter Wemm * 5340e3d5408SPeter Wemm **************************************************************************/ 5350e3d5408SPeter Wemm 5360e3d5408SPeter Wemm /* 5370e3d5408SPeter Wemm * Figure out what kind of terminal we're dealing with, and then read in 5380e3d5408SPeter Wemm * its termcap entry. 5390e3d5408SPeter Wemm */ 5400e3d5408SPeter Wemm static const char * 541aae38d10SBaptiste Daroussin get_termcap_entry(int fd, char *userarg) 5420e3d5408SPeter Wemm { 5437a69bbfbSPeter Wemm int errret; 5440e3d5408SPeter Wemm char *p; 5450e3d5408SPeter Wemm const char *ttype; 5460e3d5408SPeter Wemm #if HAVE_GETTTYNAM 5470e3d5408SPeter Wemm struct ttyent *t; 5480e3d5408SPeter Wemm #else 5490e3d5408SPeter Wemm FILE *fp; 5500e3d5408SPeter Wemm #endif 5510e3d5408SPeter Wemm char *ttypath; 5520e3d5408SPeter Wemm 553aae38d10SBaptiste Daroussin (void) fd; 554aae38d10SBaptiste Daroussin 5550e3d5408SPeter Wemm if (userarg) { 5560e3d5408SPeter Wemm ttype = userarg; 5570e3d5408SPeter Wemm goto found; 5580e3d5408SPeter Wemm } 5590e3d5408SPeter Wemm 5600e3d5408SPeter Wemm /* Try the environment. */ 5610e3d5408SPeter Wemm if ((ttype = getenv("TERM")) != 0) 5620e3d5408SPeter Wemm goto map; 5630e3d5408SPeter Wemm 564aae38d10SBaptiste Daroussin if ((ttypath = ttyname(fd)) != 0) { 56518259542SPeter Wemm p = _nc_basename(ttypath); 5660e3d5408SPeter Wemm #if HAVE_GETTTYNAM 5670e3d5408SPeter Wemm /* 5680e3d5408SPeter Wemm * We have the 4.3BSD library call getttynam(3); that means 5690e3d5408SPeter Wemm * there's an /etc/ttys to look up device-to-type mappings in. 5700e3d5408SPeter Wemm * Try ttyname(3); check for dialup or other mapping. 5710e3d5408SPeter Wemm */ 5720e3d5408SPeter Wemm if ((t = getttynam(p))) { 5730e3d5408SPeter Wemm ttype = t->ty_type; 5740e3d5408SPeter Wemm goto map; 5750e3d5408SPeter Wemm } 5760e3d5408SPeter Wemm #else 5770e3d5408SPeter Wemm if ((fp = fopen("/etc/ttytype", "r")) != 0 5780e3d5408SPeter Wemm || (fp = fopen("/etc/ttys", "r")) != 0) { 5790e3d5408SPeter Wemm char buffer[BUFSIZ]; 5800e3d5408SPeter Wemm char *s, *t, *d; 5810e3d5408SPeter Wemm 5820e3d5408SPeter Wemm while (fgets(buffer, sizeof(buffer) - 1, fp) != 0) { 5830e3d5408SPeter Wemm for (s = buffer, t = d = 0; *s; s++) { 58439f2269fSPeter Wemm if (isspace(UChar(*s))) 5850e3d5408SPeter Wemm *s = '\0'; 5860e3d5408SPeter Wemm else if (t == 0) 5870e3d5408SPeter Wemm t = s; 5880e3d5408SPeter Wemm else if (d == 0 && s != buffer && s[-1] == '\0') 5890e3d5408SPeter Wemm d = s; 5900e3d5408SPeter Wemm } 5910e3d5408SPeter Wemm if (t != 0 && d != 0 && !strcmp(d, p)) { 5920e3d5408SPeter Wemm ttype = strdup(t); 5930e3d5408SPeter Wemm fclose(fp); 5940e3d5408SPeter Wemm goto map; 5950e3d5408SPeter Wemm } 5960e3d5408SPeter Wemm } 5970e3d5408SPeter Wemm fclose(fp); 5980e3d5408SPeter Wemm } 5990e3d5408SPeter Wemm #endif /* HAVE_GETTTYNAM */ 6000e3d5408SPeter Wemm } 6010e3d5408SPeter Wemm 6020e3d5408SPeter Wemm /* If still undefined, use "unknown". */ 6030e3d5408SPeter Wemm ttype = "unknown"; 6040e3d5408SPeter Wemm 6050e3d5408SPeter Wemm map:ttype = mapped(ttype); 6060e3d5408SPeter Wemm 6070e3d5408SPeter Wemm /* 6080e3d5408SPeter Wemm * If not a path, remove TERMCAP from the environment so we get a 6090e3d5408SPeter Wemm * real entry from /etc/termcap. This prevents us from being fooled 6100e3d5408SPeter Wemm * by out of date stuff in the environment. 6110e3d5408SPeter Wemm */ 61273f0a83dSXin LI found: 61373f0a83dSXin LI if ((p = getenv("TERMCAP")) != 0 && !_nc_is_abs_path(p)) { 6140e3d5408SPeter Wemm /* 'unsetenv("TERMCAP")' is not portable. 6150e3d5408SPeter Wemm * The 'environ' array is better. 6160e3d5408SPeter Wemm */ 6170e3d5408SPeter Wemm int n; 6180e3d5408SPeter Wemm for (n = 0; environ[n] != 0; n++) { 61973f0a83dSXin LI if (!strncmp("TERMCAP=", environ[n], (size_t) 8)) { 6200e3d5408SPeter Wemm while ((environ[n] = environ[n + 1]) != 0) { 6210e3d5408SPeter Wemm n++; 6220e3d5408SPeter Wemm } 6230e3d5408SPeter Wemm break; 6240e3d5408SPeter Wemm } 6250e3d5408SPeter Wemm } 6260e3d5408SPeter Wemm } 6270e3d5408SPeter Wemm 6280e3d5408SPeter Wemm /* 6290e3d5408SPeter Wemm * ttype now contains a pointer to the type of the terminal. 6300e3d5408SPeter Wemm * If the first character is '?', ask the user. 6310e3d5408SPeter Wemm */ 6320e3d5408SPeter Wemm if (ttype[0] == '?') { 6330e3d5408SPeter Wemm if (ttype[1] != '\0') 6340e3d5408SPeter Wemm ttype = askuser(ttype + 1); 6350e3d5408SPeter Wemm else 6360e3d5408SPeter Wemm ttype = askuser(0); 6370e3d5408SPeter Wemm } 6380e3d5408SPeter Wemm /* Find the terminfo entry. If it doesn't exist, ask the user. */ 639aae38d10SBaptiste Daroussin while (setupterm((NCURSES_CONST char *) ttype, fd, &errret) 6407a69bbfbSPeter Wemm != OK) { 6410e3d5408SPeter Wemm if (errret == 0) { 6424a1a9510SRong-En Fan (void) fprintf(stderr, "%s: unknown terminal type %s\n", 6434a1a9510SRong-En Fan _nc_progname, ttype); 6440e3d5408SPeter Wemm ttype = 0; 64515589c42SPeter Wemm } else { 64615589c42SPeter Wemm (void) fprintf(stderr, 6474a1a9510SRong-En Fan "%s: can't initialize terminal type %s (error %d)\n", 6484a1a9510SRong-En Fan _nc_progname, ttype, errret); 6490e3d5408SPeter Wemm ttype = 0; 6500e3d5408SPeter Wemm } 6510e3d5408SPeter Wemm ttype = askuser(ttype); 6520e3d5408SPeter Wemm } 6530e3d5408SPeter Wemm #if BROKEN_LINKER 6540e3d5408SPeter Wemm tgetflag("am"); /* force lib_termcap.o to be linked for 'ospeed' */ 6550e3d5408SPeter Wemm #endif 6560e3d5408SPeter Wemm return (ttype); 6570e3d5408SPeter Wemm } 6580e3d5408SPeter Wemm 6590e3d5408SPeter Wemm /************************************************************************** 6600e3d5408SPeter Wemm * 6610e3d5408SPeter Wemm * Main sequence 6620e3d5408SPeter Wemm * 6630e3d5408SPeter Wemm **************************************************************************/ 6640e3d5408SPeter Wemm 6650e3d5408SPeter Wemm /* 6660e3d5408SPeter Wemm * Convert the obsolete argument forms into something that getopt can handle. 6670e3d5408SPeter Wemm * This means that -e, -i and -k get default arguments supplied for them. 6680e3d5408SPeter Wemm */ 6690e3d5408SPeter Wemm static void 6700e3d5408SPeter Wemm obsolete(char **argv) 6710e3d5408SPeter Wemm { 6720e3d5408SPeter Wemm for (; *argv; ++argv) { 6730e3d5408SPeter Wemm char *parm = argv[0]; 6740e3d5408SPeter Wemm 67515589c42SPeter Wemm if (parm[0] == '-' && parm[1] == '\0') { 6760e3d5408SPeter Wemm argv[0] = strdup("-q"); 6770e3d5408SPeter Wemm continue; 6780e3d5408SPeter Wemm } 6790e3d5408SPeter Wemm 6800e3d5408SPeter Wemm if ((parm[0] != '-') 6810e3d5408SPeter Wemm || (argv[1] && argv[1][0] != '-') 6820e3d5408SPeter Wemm || (parm[1] != 'e' && parm[1] != 'i' && parm[1] != 'k') 6830e3d5408SPeter Wemm || (parm[2] != '\0')) 6840e3d5408SPeter Wemm continue; 6850e3d5408SPeter Wemm switch (argv[0][1]) { 6860e3d5408SPeter Wemm case 'e': 6870e3d5408SPeter Wemm argv[0] = strdup("-e^H"); 6880e3d5408SPeter Wemm break; 6890e3d5408SPeter Wemm case 'i': 6900e3d5408SPeter Wemm argv[0] = strdup("-i^C"); 6910e3d5408SPeter Wemm break; 6920e3d5408SPeter Wemm case 'k': 6930e3d5408SPeter Wemm argv[0] = strdup("-k^U"); 6940e3d5408SPeter Wemm break; 6950e3d5408SPeter Wemm } 6960e3d5408SPeter Wemm } 6970e3d5408SPeter Wemm } 6980e3d5408SPeter Wemm 6990e3d5408SPeter Wemm static void 700aae38d10SBaptiste Daroussin print_shell_commands(const char *ttype) 701aae38d10SBaptiste Daroussin { 702aae38d10SBaptiste Daroussin const char *p; 703aae38d10SBaptiste Daroussin int len; 704aae38d10SBaptiste Daroussin char *var; 705aae38d10SBaptiste Daroussin char *leaf; 706aae38d10SBaptiste Daroussin /* 707aae38d10SBaptiste Daroussin * Figure out what shell we're using. A hack, we look for an 708aae38d10SBaptiste Daroussin * environmental variable SHELL ending in "csh". 709aae38d10SBaptiste Daroussin */ 710aae38d10SBaptiste Daroussin if ((var = getenv("SHELL")) != 0 711aae38d10SBaptiste Daroussin && ((len = (int) strlen(leaf = _nc_basename(var))) >= 3) 712aae38d10SBaptiste Daroussin && !strcmp(leaf + len - 3, "csh")) 713aae38d10SBaptiste Daroussin p = "set noglob;\nsetenv TERM %s;\nunset noglob;\n"; 714aae38d10SBaptiste Daroussin else 715aae38d10SBaptiste Daroussin p = "TERM=%s;\n"; 716aae38d10SBaptiste Daroussin (void) printf(p, ttype); 717aae38d10SBaptiste Daroussin } 718aae38d10SBaptiste Daroussin 719aae38d10SBaptiste Daroussin static void 7204a1a9510SRong-En Fan usage(void) 7210e3d5408SPeter Wemm { 722aae38d10SBaptiste Daroussin #define SKIP(s) /* nothing */ 723aae38d10SBaptiste Daroussin #define KEEP(s) s "\n" 724aae38d10SBaptiste Daroussin static const char msg[] = 7254a1a9510SRong-En Fan { 726aae38d10SBaptiste Daroussin KEEP("") 727aae38d10SBaptiste Daroussin KEEP("Options:") 728aae38d10SBaptiste Daroussin SKIP(" -a arpanet (obsolete)") 729aae38d10SBaptiste Daroussin KEEP(" -c set control characters") 730aae38d10SBaptiste Daroussin SKIP(" -d dialup (obsolete)") 731aae38d10SBaptiste Daroussin KEEP(" -e ch erase character") 732aae38d10SBaptiste Daroussin KEEP(" -I no initialization strings") 733aae38d10SBaptiste Daroussin KEEP(" -i ch interrupt character") 734aae38d10SBaptiste Daroussin KEEP(" -k ch kill character") 735aae38d10SBaptiste Daroussin KEEP(" -m mapping map identifier to type") 736aae38d10SBaptiste Daroussin SKIP(" -p plugboard (obsolete)") 737aae38d10SBaptiste Daroussin KEEP(" -Q do not output control key settings") 738aae38d10SBaptiste Daroussin KEEP(" -q display term only, do no changes") 739aae38d10SBaptiste Daroussin KEEP(" -r display term on stderr") 740aae38d10SBaptiste Daroussin SKIP(" -S (obsolete)") 741aae38d10SBaptiste Daroussin KEEP(" -s output TERM set command") 742aae38d10SBaptiste Daroussin KEEP(" -V print curses-version") 743aae38d10SBaptiste Daroussin KEEP(" -w set window-size") 744aae38d10SBaptiste Daroussin KEEP("") 745aae38d10SBaptiste Daroussin KEEP("If neither -c/-w are given, both are assumed.") 7464a1a9510SRong-En Fan }; 747aae38d10SBaptiste Daroussin #undef KEEP 748aae38d10SBaptiste Daroussin #undef SKIP 7494a1a9510SRong-En Fan (void) fprintf(stderr, "Usage: %s [options] [terminal]\n", _nc_progname); 750aae38d10SBaptiste Daroussin fputs(msg, stderr); 751aae38d10SBaptiste Daroussin ExitProgram(EXIT_FAILURE); 75239f2269fSPeter Wemm /* NOTREACHED */ 7530e3d5408SPeter Wemm } 7540e3d5408SPeter Wemm 75515589c42SPeter Wemm static char 75615589c42SPeter Wemm arg_to_char(void) 7570e3d5408SPeter Wemm { 7585d08fb1fSRong-En Fan return (char) ((optarg[0] == '^' && optarg[1] != '\0') 7590e3d5408SPeter Wemm ? ((optarg[1] == '?') ? '\177' : CTRL(optarg[1])) 7605d08fb1fSRong-En Fan : optarg[0]); 7610e3d5408SPeter Wemm } 7620e3d5408SPeter Wemm 7630e3d5408SPeter Wemm int 7640e3d5408SPeter Wemm main(int argc, char **argv) 7650e3d5408SPeter Wemm { 7660e3d5408SPeter Wemm int ch, noinit, noset, quiet, Sflag, sflag, showterm; 7670e3d5408SPeter Wemm const char *ttype; 768aae38d10SBaptiste Daroussin int terasechar = -1; /* new erase character */ 769aae38d10SBaptiste Daroussin int intrchar = -1; /* new interrupt character */ 770aae38d10SBaptiste Daroussin int tkillchar = -1; /* new kill character */ 771aae38d10SBaptiste Daroussin int my_fd; 772aae38d10SBaptiste Daroussin bool opt_c = FALSE; /* set control-chars */ 773aae38d10SBaptiste Daroussin bool opt_w = FALSE; /* set window-size */ 774aae38d10SBaptiste Daroussin TTY mode, oldmode; 7750e3d5408SPeter Wemm 776aae38d10SBaptiste Daroussin my_fd = STDERR_FILENO; 7770e3d5408SPeter Wemm obsolete(argv); 7780e3d5408SPeter Wemm noinit = noset = quiet = Sflag = sflag = showterm = 0; 779aae38d10SBaptiste Daroussin while ((ch = getopt(argc, argv, "a:cd:e:Ii:k:m:p:qQrSsVw")) != -1) { 7800e3d5408SPeter Wemm switch (ch) { 7814a1a9510SRong-En Fan case 'c': /* set control-chars */ 7824a1a9510SRong-En Fan opt_c = TRUE; 7830e3d5408SPeter Wemm break; 7840e3d5408SPeter Wemm case 'a': /* OBSOLETE: map identifier to type */ 7850e3d5408SPeter Wemm add_mapping("arpanet", optarg); 7860e3d5408SPeter Wemm break; 7870e3d5408SPeter Wemm case 'd': /* OBSOLETE: map identifier to type */ 7880e3d5408SPeter Wemm add_mapping("dialup", optarg); 7890e3d5408SPeter Wemm break; 7900e3d5408SPeter Wemm case 'e': /* erase character */ 7910e3d5408SPeter Wemm terasechar = arg_to_char(); 7920e3d5408SPeter Wemm break; 7930e3d5408SPeter Wemm case 'I': /* no initialization strings */ 7940e3d5408SPeter Wemm noinit = 1; 7950e3d5408SPeter Wemm break; 7960e3d5408SPeter Wemm case 'i': /* interrupt character */ 7970e3d5408SPeter Wemm intrchar = arg_to_char(); 7980e3d5408SPeter Wemm break; 7990e3d5408SPeter Wemm case 'k': /* kill character */ 8000e3d5408SPeter Wemm tkillchar = arg_to_char(); 8010e3d5408SPeter Wemm break; 8020e3d5408SPeter Wemm case 'm': /* map identifier to type */ 8030e3d5408SPeter Wemm add_mapping(0, optarg); 8040e3d5408SPeter Wemm break; 8050e3d5408SPeter Wemm case 'p': /* OBSOLETE: map identifier to type */ 8060e3d5408SPeter Wemm add_mapping("plugboard", optarg); 8070e3d5408SPeter Wemm break; 8080e3d5408SPeter Wemm case 'Q': /* don't output control key settings */ 8090e3d5408SPeter Wemm quiet = 1; 8100e3d5408SPeter Wemm break; 8114a1a9510SRong-En Fan case 'q': /* display term only */ 8124a1a9510SRong-En Fan noset = 1; 8130e3d5408SPeter Wemm break; 8140e3d5408SPeter Wemm case 'r': /* display term on stderr */ 8150e3d5408SPeter Wemm showterm = 1; 8160e3d5408SPeter Wemm break; 8174a1a9510SRong-En Fan case 'S': /* OBSOLETE: output TERM & TERMCAP */ 8184a1a9510SRong-En Fan Sflag = 1; 8194a1a9510SRong-En Fan break; 8200e3d5408SPeter Wemm case 's': /* output TERM set command */ 8210e3d5408SPeter Wemm sflag = 1; 8220e3d5408SPeter Wemm break; 8234a1a9510SRong-En Fan case 'V': /* print curses-version */ 82418259542SPeter Wemm puts(curses_version()); 8254a1a9510SRong-En Fan ExitProgram(EXIT_SUCCESS); 8264a1a9510SRong-En Fan case 'w': /* set window-size */ 8274a1a9510SRong-En Fan opt_w = TRUE; 8284a1a9510SRong-En Fan break; 8290e3d5408SPeter Wemm case '?': 8300e3d5408SPeter Wemm default: 8314a1a9510SRong-En Fan usage(); 8320e3d5408SPeter Wemm } 8330e3d5408SPeter Wemm } 8344a1a9510SRong-En Fan 8354a1a9510SRong-En Fan _nc_progname = _nc_rootname(*argv); 8360e3d5408SPeter Wemm argc -= optind; 8370e3d5408SPeter Wemm argv += optind; 8380e3d5408SPeter Wemm 8390e3d5408SPeter Wemm if (argc > 1) 8404a1a9510SRong-En Fan usage(); 8414a1a9510SRong-En Fan 8424a1a9510SRong-En Fan if (!opt_c && !opt_w) 8434a1a9510SRong-En Fan opt_c = opt_w = TRUE; 8444a1a9510SRong-En Fan 845aae38d10SBaptiste Daroussin my_fd = save_tty_settings(&mode, TRUE); 846aae38d10SBaptiste Daroussin oldmode = mode; 8474a1a9510SRong-En Fan #ifdef TERMIOS 8485d08fb1fSRong-En Fan ospeed = (NCURSES_OSPEED) cfgetospeed(&mode); 849*7a656419SBaptiste Daroussin #elif defined(EXP_WIN32_DRIVER) 850*7a656419SBaptiste Daroussin ospeed = 0; 8514a1a9510SRong-En Fan #else 8525d08fb1fSRong-En Fan ospeed = (NCURSES_OSPEED) mode.sg_ospeed; 8534a1a9510SRong-En Fan #endif 8544a1a9510SRong-En Fan 85506bfebdeSXin LI if (same_program(_nc_progname, PROG_RESET)) { 856aae38d10SBaptiste Daroussin reset_start(stderr, TRUE, FALSE); 857aae38d10SBaptiste Daroussin reset_tty_settings(my_fd, &mode); 858aae38d10SBaptiste Daroussin } else { 859aae38d10SBaptiste Daroussin reset_start(stderr, FALSE, TRUE); 8604a1a9510SRong-En Fan } 8610e3d5408SPeter Wemm 862aae38d10SBaptiste Daroussin ttype = get_termcap_entry(my_fd, *argv); 8630e3d5408SPeter Wemm 8640e3d5408SPeter Wemm if (!noset) { 86573f0a83dSXin LI #if HAVE_SIZECHANGE 8664a1a9510SRong-En Fan if (opt_w) { 867aae38d10SBaptiste Daroussin set_window_size(my_fd, &lines, &columns); 8684a1a9510SRong-En Fan } 8690e3d5408SPeter Wemm #endif 8704a1a9510SRong-En Fan if (opt_c) { 871aae38d10SBaptiste Daroussin set_control_chars(&mode, terasechar, intrchar, tkillchar); 872aae38d10SBaptiste Daroussin set_conversions(&mode); 8730e3d5408SPeter Wemm 874aae38d10SBaptiste Daroussin if (!noinit) { 875aae38d10SBaptiste Daroussin if (send_init_strings(my_fd, &oldmode)) { 876aae38d10SBaptiste Daroussin (void) putc('\r', stderr); 877aae38d10SBaptiste Daroussin (void) fflush(stderr); 878aae38d10SBaptiste Daroussin (void) napms(1000); /* Settle the terminal. */ 8790e3d5408SPeter Wemm } 88015589c42SPeter Wemm } 881aae38d10SBaptiste Daroussin 882aae38d10SBaptiste Daroussin update_tty_settings(&oldmode, &mode); 883aae38d10SBaptiste Daroussin } 8844a1a9510SRong-En Fan } 8850e3d5408SPeter Wemm 886aae38d10SBaptiste Daroussin if (noset) { 8870e3d5408SPeter Wemm (void) printf("%s\n", ttype); 888aae38d10SBaptiste Daroussin } else { 8890e3d5408SPeter Wemm if (showterm) 8900e3d5408SPeter Wemm (void) fprintf(stderr, "Terminal type is %s.\n", ttype); 8910e3d5408SPeter Wemm /* 8920e3d5408SPeter Wemm * If erase, kill and interrupt characters could have been 8930e3d5408SPeter Wemm * modified and not -Q, display the changes. 8940e3d5408SPeter Wemm */ 8950e3d5408SPeter Wemm if (!quiet) { 896aae38d10SBaptiste Daroussin print_tty_chars(&oldmode, &mode); 8970e3d5408SPeter Wemm } 8980e3d5408SPeter Wemm } 8990e3d5408SPeter Wemm 9000e3d5408SPeter Wemm if (Sflag) 9010e3d5408SPeter Wemm err("The -S option is not supported under terminfo."); 9020e3d5408SPeter Wemm 9030e3d5408SPeter Wemm if (sflag) { 904aae38d10SBaptiste Daroussin print_shell_commands(ttype); 9050e3d5408SPeter Wemm } 9060e3d5408SPeter Wemm 9074a1a9510SRong-En Fan ExitProgram(EXIT_SUCCESS); 9080e3d5408SPeter Wemm } 909