15f4613f2SJohn Marino /****************************************************************************
2*32bb5217SDaniel Fojt * Copyright 2020 Thomas E. Dickey *
3*32bb5217SDaniel Fojt * Copyright 1998-2016,2017 Free Software Foundation, Inc. *
45f4613f2SJohn Marino * *
55f4613f2SJohn Marino * Permission is hereby granted, free of charge, to any person obtaining a *
65f4613f2SJohn Marino * copy of this software and associated documentation files (the *
75f4613f2SJohn Marino * "Software"), to deal in the Software without restriction, including *
85f4613f2SJohn Marino * without limitation the rights to use, copy, modify, merge, publish, *
95f4613f2SJohn Marino * distribute, distribute with modifications, sublicense, and/or sell *
105f4613f2SJohn Marino * copies of the Software, and to permit persons to whom the Software is *
115f4613f2SJohn Marino * furnished to do so, subject to the following conditions: *
125f4613f2SJohn Marino * *
135f4613f2SJohn Marino * The above copyright notice and this permission notice shall be included *
145f4613f2SJohn Marino * in all copies or substantial portions of the Software. *
155f4613f2SJohn Marino * *
165f4613f2SJohn Marino * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
175f4613f2SJohn Marino * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
185f4613f2SJohn Marino * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
195f4613f2SJohn Marino * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
205f4613f2SJohn Marino * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
215f4613f2SJohn Marino * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
225f4613f2SJohn Marino * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
235f4613f2SJohn Marino * *
245f4613f2SJohn Marino * Except as contained in this notice, the name(s) of the above copyright *
255f4613f2SJohn Marino * holders shall not be used in advertising or otherwise to promote the *
265f4613f2SJohn Marino * sale, use or other dealings in this Software without prior written *
275f4613f2SJohn Marino * authorization. *
285f4613f2SJohn Marino ****************************************************************************/
295f4613f2SJohn Marino
305f4613f2SJohn Marino /****************************************************************************
315f4613f2SJohn Marino * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
325f4613f2SJohn Marino * and: Eric S. Raymond <esr@snark.thyrsus.com> *
335f4613f2SJohn Marino * and: Thomas E. Dickey 1996-on *
345f4613f2SJohn Marino ****************************************************************************/
355f4613f2SJohn Marino
365f4613f2SJohn Marino /*
375f4613f2SJohn Marino * Notes:
385f4613f2SJohn Marino * The initial adaptation from 4.4BSD Lite sources in September 1995 used 686
395f4613f2SJohn Marino * lines from that version, and made changes/additions for 150 lines. There
405f4613f2SJohn Marino * was no reformatting, so with/without ignoring whitespace, the amount of
415f4613f2SJohn Marino * change is the same.
425f4613f2SJohn Marino *
435f4613f2SJohn Marino * Comparing with current (2009) source, excluding this comment:
445f4613f2SJohn Marino * a) 209 lines match identically to the 4.4BSD Lite sources, with 771 lines
455f4613f2SJohn Marino * changed/added.
465f4613f2SJohn Marino * a) Ignoring whitespace, the current version still uses 516 lines from the
475f4613f2SJohn Marino * 4.4BSD Lite sources, with 402 lines changed/added.
485f4613f2SJohn Marino *
495f4613f2SJohn Marino * Raymond's original comment on this follows...
505f4613f2SJohn Marino */
515f4613f2SJohn Marino
525f4613f2SJohn Marino /*
535f4613f2SJohn Marino * tset.c - terminal initialization utility
545f4613f2SJohn Marino *
555f4613f2SJohn Marino * This code was mostly swiped from 4.4BSD tset, with some obsolescent
565f4613f2SJohn Marino * cruft removed and substantial portions rewritten. A Regents of the
575f4613f2SJohn Marino * University of California copyright applies to some portions of the
585f4613f2SJohn Marino * code, and is reproduced below:
595f4613f2SJohn Marino */
605f4613f2SJohn Marino /*-
615f4613f2SJohn Marino * Copyright (c) 1980, 1991, 1993
625f4613f2SJohn Marino * The Regents of the University of California. All rights reserved.
635f4613f2SJohn Marino *
645f4613f2SJohn Marino * Redistribution and use in source and binary forms, with or without
655f4613f2SJohn Marino * modification, are permitted provided that the following conditions
665f4613f2SJohn Marino * are met:
675f4613f2SJohn Marino * 1. Redistributions of source code must retain the above copyright
685f4613f2SJohn Marino * notice, this list of conditions and the following disclaimer.
695f4613f2SJohn Marino * 2. Redistributions in binary form must reproduce the above copyright
705f4613f2SJohn Marino * notice, this list of conditions and the following disclaimer in the
715f4613f2SJohn Marino * documentation and/or other materials provided with the distribution.
725f4613f2SJohn Marino * 3. Neither the name of the University nor the names of its contributors
735f4613f2SJohn Marino * may be used to endorse or promote products derived from this software
745f4613f2SJohn Marino * without specific prior written permission.
755f4613f2SJohn Marino *
765f4613f2SJohn Marino * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
775f4613f2SJohn Marino * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
785f4613f2SJohn Marino * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
795f4613f2SJohn Marino * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
805f4613f2SJohn Marino * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
815f4613f2SJohn Marino * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
825f4613f2SJohn Marino * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
835f4613f2SJohn Marino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
845f4613f2SJohn Marino * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
855f4613f2SJohn Marino * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
865f4613f2SJohn Marino * SUCH DAMAGE.
875f4613f2SJohn Marino */
885f4613f2SJohn Marino
89*32bb5217SDaniel Fojt #include <reset_cmd.h>
905f4613f2SJohn Marino #include <termcap.h>
91*32bb5217SDaniel Fojt #include <transform.h>
92*32bb5217SDaniel Fojt #include <tty_settings.h>
935f4613f2SJohn Marino
945f4613f2SJohn Marino #if HAVE_GETTTYNAM && HAVE_TTYENT_H
955f4613f2SJohn Marino #include <ttyent.h>
965f4613f2SJohn Marino #endif
975f4613f2SJohn Marino #ifdef NeXT
985f4613f2SJohn Marino char *ttyname(int fd);
995f4613f2SJohn Marino #endif
1005f4613f2SJohn Marino
101*32bb5217SDaniel Fojt MODULE_ID("$Id: tset.c,v 1.121 2020/02/02 23:34:34 tom Exp $")
1025f4613f2SJohn Marino
1035f4613f2SJohn Marino #ifndef environ
1045f4613f2SJohn Marino extern char **environ;
1055f4613f2SJohn Marino #endif
1065f4613f2SJohn Marino
1075f4613f2SJohn Marino const char *_nc_progname = "tset";
1085f4613f2SJohn Marino
1095f4613f2SJohn Marino #define LOWERCASE(c) ((isalpha(UChar(c)) && isupper(UChar(c))) ? tolower(UChar(c)) : (c))
1105f4613f2SJohn Marino
111*32bb5217SDaniel Fojt static void exit_error(void) GCC_NORETURN;
112*32bb5217SDaniel Fojt
1135f4613f2SJohn Marino static int
CaselessCmp(const char * a,const char * b)1145f4613f2SJohn Marino CaselessCmp(const char *a, const char *b)
1155f4613f2SJohn Marino { /* strcasecmp isn't portable */
1165f4613f2SJohn Marino while (*a && *b) {
1175f4613f2SJohn Marino int cmp = LOWERCASE(*a) - LOWERCASE(*b);
1185f4613f2SJohn Marino if (cmp != 0)
1195f4613f2SJohn Marino break;
1205f4613f2SJohn Marino a++, b++;
1215f4613f2SJohn Marino }
1225f4613f2SJohn Marino return LOWERCASE(*a) - LOWERCASE(*b);
1235f4613f2SJohn Marino }
1245f4613f2SJohn Marino
1255f4613f2SJohn Marino static void
exit_error(void)1265f4613f2SJohn Marino exit_error(void)
1275f4613f2SJohn Marino {
128*32bb5217SDaniel Fojt restore_tty_settings();
1295f4613f2SJohn Marino (void) fprintf(stderr, "\n");
1305f4613f2SJohn Marino fflush(stderr);
1315f4613f2SJohn Marino ExitProgram(EXIT_FAILURE);
1325f4613f2SJohn Marino /* NOTREACHED */
1335f4613f2SJohn Marino }
1345f4613f2SJohn Marino
1355f4613f2SJohn Marino static void
err(const char * fmt,...)1365f4613f2SJohn Marino err(const char *fmt,...)
1375f4613f2SJohn Marino {
1385f4613f2SJohn Marino va_list ap;
1395f4613f2SJohn Marino va_start(ap, fmt);
1405f4613f2SJohn Marino (void) fprintf(stderr, "%s: ", _nc_progname);
1415f4613f2SJohn Marino (void) vfprintf(stderr, fmt, ap);
1425f4613f2SJohn Marino va_end(ap);
1435f4613f2SJohn Marino exit_error();
1445f4613f2SJohn Marino /* NOTREACHED */
1455f4613f2SJohn Marino }
1465f4613f2SJohn Marino
1475f4613f2SJohn Marino static void
failed(const char * msg)1485f4613f2SJohn Marino failed(const char *msg)
1495f4613f2SJohn Marino {
1505f4613f2SJohn Marino char temp[BUFSIZ];
1513468e90cSJohn Marino size_t len = strlen(_nc_progname) + 2;
1525f4613f2SJohn Marino
1535f4613f2SJohn Marino if ((int) len < (int) sizeof(temp) - 12) {
1543468e90cSJohn Marino _nc_STRCPY(temp, _nc_progname, sizeof(temp));
1553468e90cSJohn Marino _nc_STRCAT(temp, ": ", sizeof(temp));
1565f4613f2SJohn Marino } else {
1573468e90cSJohn Marino _nc_STRCPY(temp, "tset: ", sizeof(temp));
1585f4613f2SJohn Marino }
159*32bb5217SDaniel Fojt _nc_STRNCAT(temp, msg, sizeof(temp), sizeof(temp) - strlen(temp) - 2);
160*32bb5217SDaniel Fojt perror(temp);
1615f4613f2SJohn Marino exit_error();
1625f4613f2SJohn Marino /* NOTREACHED */
1635f4613f2SJohn Marino }
1645f4613f2SJohn Marino
1655f4613f2SJohn Marino /* Prompt the user for a terminal type. */
1665f4613f2SJohn Marino static const char *
askuser(const char * dflt)1675f4613f2SJohn Marino askuser(const char *dflt)
1685f4613f2SJohn Marino {
1695f4613f2SJohn Marino static char answer[256];
1705f4613f2SJohn Marino char *p;
1715f4613f2SJohn Marino
1725f4613f2SJohn Marino /* We can get recalled; if so, don't continue uselessly. */
1735f4613f2SJohn Marino clearerr(stdin);
1745f4613f2SJohn Marino if (feof(stdin) || ferror(stdin)) {
1755f4613f2SJohn Marino (void) fprintf(stderr, "\n");
1765f4613f2SJohn Marino exit_error();
1775f4613f2SJohn Marino /* NOTREACHED */
1785f4613f2SJohn Marino }
1795f4613f2SJohn Marino for (;;) {
1805f4613f2SJohn Marino if (dflt)
1815f4613f2SJohn Marino (void) fprintf(stderr, "Terminal type? [%s] ", dflt);
1825f4613f2SJohn Marino else
1835f4613f2SJohn Marino (void) fprintf(stderr, "Terminal type? ");
1845f4613f2SJohn Marino (void) fflush(stderr);
1855f4613f2SJohn Marino
1865f4613f2SJohn Marino if (fgets(answer, sizeof(answer), stdin) == 0) {
1875f4613f2SJohn Marino if (dflt == 0) {
1885f4613f2SJohn Marino exit_error();
1895f4613f2SJohn Marino /* NOTREACHED */
1905f4613f2SJohn Marino }
1915f4613f2SJohn Marino return (dflt);
1925f4613f2SJohn Marino }
1935f4613f2SJohn Marino
1945f4613f2SJohn Marino if ((p = strchr(answer, '\n')) != 0)
1955f4613f2SJohn Marino *p = '\0';
1965f4613f2SJohn Marino if (answer[0])
1975f4613f2SJohn Marino return (answer);
1985f4613f2SJohn Marino if (dflt != 0)
1995f4613f2SJohn Marino return (dflt);
2005f4613f2SJohn Marino }
2015f4613f2SJohn Marino }
2025f4613f2SJohn Marino
2035f4613f2SJohn Marino /**************************************************************************
2045f4613f2SJohn Marino *
2055f4613f2SJohn Marino * Mapping logic begins here
2065f4613f2SJohn Marino *
2075f4613f2SJohn Marino **************************************************************************/
2085f4613f2SJohn Marino
2095f4613f2SJohn Marino /* Baud rate conditionals for mapping. */
2105f4613f2SJohn Marino #define GT 0x01
2115f4613f2SJohn Marino #define EQ 0x02
2125f4613f2SJohn Marino #define LT 0x04
2135f4613f2SJohn Marino #define NOT 0x08
2145f4613f2SJohn Marino #define GE (GT | EQ)
2155f4613f2SJohn Marino #define LE (LT | EQ)
2165f4613f2SJohn Marino
2175f4613f2SJohn Marino typedef struct map {
2185f4613f2SJohn Marino struct map *next; /* Linked list of maps. */
2195f4613f2SJohn Marino const char *porttype; /* Port type, or "" for any. */
2205f4613f2SJohn Marino const char *type; /* Terminal type to select. */
2215f4613f2SJohn Marino int conditional; /* Baud rate conditionals bitmask. */
2225f4613f2SJohn Marino int speed; /* Baud rate to compare against. */
2235f4613f2SJohn Marino } MAP;
2245f4613f2SJohn Marino
2255f4613f2SJohn Marino static MAP *cur, *maplist;
2265f4613f2SJohn Marino
2273468e90cSJohn Marino #define DATA(name,value) { { name }, value }
2283468e90cSJohn Marino
2295f4613f2SJohn Marino typedef struct speeds {
2303468e90cSJohn Marino const char string[7];
2315f4613f2SJohn Marino int speed;
2325f4613f2SJohn Marino } SPEEDS;
2335f4613f2SJohn Marino
2345f4613f2SJohn Marino static const SPEEDS speeds[] =
2355f4613f2SJohn Marino {
2363468e90cSJohn Marino DATA("0", B0),
2373468e90cSJohn Marino DATA("50", B50),
2383468e90cSJohn Marino DATA("75", B75),
2393468e90cSJohn Marino DATA("110", B110),
2403468e90cSJohn Marino DATA("134", B134),
2413468e90cSJohn Marino DATA("134.5", B134),
2423468e90cSJohn Marino DATA("150", B150),
2433468e90cSJohn Marino DATA("200", B200),
2443468e90cSJohn Marino DATA("300", B300),
2453468e90cSJohn Marino DATA("600", B600),
2463468e90cSJohn Marino DATA("1200", B1200),
2473468e90cSJohn Marino DATA("1800", B1800),
2483468e90cSJohn Marino DATA("2400", B2400),
2493468e90cSJohn Marino DATA("4800", B4800),
2503468e90cSJohn Marino DATA("9600", B9600),
2515f4613f2SJohn Marino /* sgttyb may define up to this point */
2525f4613f2SJohn Marino #ifdef B19200
2533468e90cSJohn Marino DATA("19200", B19200),
2545f4613f2SJohn Marino #endif
2555f4613f2SJohn Marino #ifdef B38400
2563468e90cSJohn Marino DATA("38400", B38400),
2575f4613f2SJohn Marino #endif
2585f4613f2SJohn Marino #ifdef B19200
2593468e90cSJohn Marino DATA("19200", B19200),
2605f4613f2SJohn Marino #endif
2615f4613f2SJohn Marino #ifdef B38400
2623468e90cSJohn Marino DATA("38400", B38400),
2635f4613f2SJohn Marino #endif
2645f4613f2SJohn Marino #ifdef B19200
2653468e90cSJohn Marino DATA("19200", B19200),
2665f4613f2SJohn Marino #else
2675f4613f2SJohn Marino #ifdef EXTA
2683468e90cSJohn Marino DATA("19200", EXTA),
2695f4613f2SJohn Marino #endif
2705f4613f2SJohn Marino #endif
2715f4613f2SJohn Marino #ifdef B38400
2723468e90cSJohn Marino DATA("38400", B38400),
2735f4613f2SJohn Marino #else
2745f4613f2SJohn Marino #ifdef EXTB
2753468e90cSJohn Marino DATA("38400", EXTB),
2765f4613f2SJohn Marino #endif
2775f4613f2SJohn Marino #endif
2785f4613f2SJohn Marino #ifdef B57600
2793468e90cSJohn Marino DATA("57600", B57600),
2805f4613f2SJohn Marino #endif
281*32bb5217SDaniel Fojt #ifdef B76800
282*32bb5217SDaniel Fojt DATA("76800", B57600),
283*32bb5217SDaniel Fojt #endif
2845f4613f2SJohn Marino #ifdef B115200
2853468e90cSJohn Marino DATA("115200", B115200),
2865f4613f2SJohn Marino #endif
287*32bb5217SDaniel Fojt #ifdef B153600
288*32bb5217SDaniel Fojt DATA("153600", B153600),
289*32bb5217SDaniel Fojt #endif
2905f4613f2SJohn Marino #ifdef B230400
2913468e90cSJohn Marino DATA("230400", B230400),
2925f4613f2SJohn Marino #endif
293*32bb5217SDaniel Fojt #ifdef B307200
294*32bb5217SDaniel Fojt DATA("307200", B307200),
295*32bb5217SDaniel Fojt #endif
2965f4613f2SJohn Marino #ifdef B460800
2973468e90cSJohn Marino DATA("460800", B460800),
2985f4613f2SJohn Marino #endif
299*32bb5217SDaniel Fojt #ifdef B500000
300*32bb5217SDaniel Fojt DATA("500000", B500000),
301*32bb5217SDaniel Fojt #endif
302*32bb5217SDaniel Fojt #ifdef B576000
303*32bb5217SDaniel Fojt DATA("576000", B576000),
304*32bb5217SDaniel Fojt #endif
305*32bb5217SDaniel Fojt #ifdef B921600
306*32bb5217SDaniel Fojt DATA("921600", B921600),
307*32bb5217SDaniel Fojt #endif
308*32bb5217SDaniel Fojt #ifdef B1000000
309*32bb5217SDaniel Fojt DATA("1000000", B1000000),
310*32bb5217SDaniel Fojt #endif
311*32bb5217SDaniel Fojt #ifdef B1152000
312*32bb5217SDaniel Fojt DATA("1152000", B1152000),
313*32bb5217SDaniel Fojt #endif
314*32bb5217SDaniel Fojt #ifdef B1500000
315*32bb5217SDaniel Fojt DATA("1500000", B1500000),
316*32bb5217SDaniel Fojt #endif
317*32bb5217SDaniel Fojt #ifdef B2000000
318*32bb5217SDaniel Fojt DATA("2000000", B2000000),
319*32bb5217SDaniel Fojt #endif
320*32bb5217SDaniel Fojt #ifdef B2500000
321*32bb5217SDaniel Fojt DATA("2500000", B2500000),
322*32bb5217SDaniel Fojt #endif
323*32bb5217SDaniel Fojt #ifdef B3000000
324*32bb5217SDaniel Fojt DATA("3000000", B3000000),
325*32bb5217SDaniel Fojt #endif
326*32bb5217SDaniel Fojt #ifdef B3500000
327*32bb5217SDaniel Fojt DATA("3500000", B3500000),
328*32bb5217SDaniel Fojt #endif
329*32bb5217SDaniel Fojt #ifdef B4000000
330*32bb5217SDaniel Fojt DATA("4000000", B4000000),
331*32bb5217SDaniel Fojt #endif
3325f4613f2SJohn Marino };
3333468e90cSJohn Marino #undef DATA
3345f4613f2SJohn Marino
3355f4613f2SJohn Marino static int
tbaudrate(char * rate)3365f4613f2SJohn Marino tbaudrate(char *rate)
3375f4613f2SJohn Marino {
3383468e90cSJohn Marino const SPEEDS *sp = 0;
3393468e90cSJohn Marino size_t n;
3405f4613f2SJohn Marino
3415f4613f2SJohn Marino /* The baudrate number can be preceded by a 'B', which is ignored. */
3425f4613f2SJohn Marino if (*rate == 'B')
3435f4613f2SJohn Marino ++rate;
3445f4613f2SJohn Marino
3453468e90cSJohn Marino for (n = 0; n < SIZEOF(speeds); ++n) {
346*32bb5217SDaniel Fojt if (n > 0 && (speeds[n].speed <= speeds[n - 1].speed)) {
347*32bb5217SDaniel Fojt /* if the speeds are not increasing, likely a numeric overflow */
348*32bb5217SDaniel Fojt break;
349*32bb5217SDaniel Fojt }
3503468e90cSJohn Marino if (!CaselessCmp(rate, speeds[n].string)) {
3513468e90cSJohn Marino sp = speeds + n;
3525f4613f2SJohn Marino break;
3535f4613f2SJohn Marino }
3545f4613f2SJohn Marino }
3553468e90cSJohn Marino if (sp == 0)
3565f4613f2SJohn Marino err("unknown baud rate %s", rate);
3575f4613f2SJohn Marino return (sp->speed);
3585f4613f2SJohn Marino }
3595f4613f2SJohn Marino
3605f4613f2SJohn Marino /*
3615f4613f2SJohn Marino * Syntax for -m:
3625f4613f2SJohn Marino * [port-type][test baudrate]:terminal-type
3635f4613f2SJohn Marino * The baud rate tests are: >, <, @, =, !
3645f4613f2SJohn Marino */
3655f4613f2SJohn Marino static void
add_mapping(const char * port,char * arg)3665f4613f2SJohn Marino add_mapping(const char *port, char *arg)
3675f4613f2SJohn Marino {
3685f4613f2SJohn Marino MAP *mapp;
3695f4613f2SJohn Marino char *copy, *p;
3705f4613f2SJohn Marino const char *termp;
3715f4613f2SJohn Marino char *base = 0;
3725f4613f2SJohn Marino
3735f4613f2SJohn Marino copy = strdup(arg);
3745f4613f2SJohn Marino mapp = typeMalloc(MAP, 1);
3755f4613f2SJohn Marino if (copy == 0 || mapp == 0)
3765f4613f2SJohn Marino failed("malloc");
3775f4613f2SJohn Marino
3785f4613f2SJohn Marino assert(copy != 0);
3795f4613f2SJohn Marino assert(mapp != 0);
3805f4613f2SJohn Marino
3815f4613f2SJohn Marino mapp->next = 0;
3825f4613f2SJohn Marino if (maplist == 0)
3835f4613f2SJohn Marino cur = maplist = mapp;
3845f4613f2SJohn Marino else {
3855f4613f2SJohn Marino cur->next = mapp;
3865f4613f2SJohn Marino cur = mapp;
3875f4613f2SJohn Marino }
3885f4613f2SJohn Marino
3895f4613f2SJohn Marino mapp->porttype = arg;
3905f4613f2SJohn Marino mapp->conditional = 0;
3915f4613f2SJohn Marino
3925f4613f2SJohn Marino arg = strpbrk(arg, "><@=!:");
3935f4613f2SJohn Marino
3945f4613f2SJohn Marino if (arg == 0) { /* [?]term */
3955f4613f2SJohn Marino mapp->type = mapp->porttype;
3965f4613f2SJohn Marino mapp->porttype = 0;
3975f4613f2SJohn Marino goto done;
3985f4613f2SJohn Marino }
3995f4613f2SJohn Marino
4005f4613f2SJohn Marino if (arg == mapp->porttype) /* [><@=! baud]:term */
4015f4613f2SJohn Marino termp = mapp->porttype = 0;
4025f4613f2SJohn Marino else
4035f4613f2SJohn Marino termp = base = arg;
4045f4613f2SJohn Marino
4055f4613f2SJohn Marino for (;; ++arg) { /* Optional conditionals. */
4065f4613f2SJohn Marino switch (*arg) {
4075f4613f2SJohn Marino case '<':
4085f4613f2SJohn Marino if (mapp->conditional & GT)
4095f4613f2SJohn Marino goto badmopt;
4105f4613f2SJohn Marino mapp->conditional |= LT;
4115f4613f2SJohn Marino break;
4125f4613f2SJohn Marino case '>':
4135f4613f2SJohn Marino if (mapp->conditional & LT)
4145f4613f2SJohn Marino goto badmopt;
4155f4613f2SJohn Marino mapp->conditional |= GT;
4165f4613f2SJohn Marino break;
4175f4613f2SJohn Marino case '@':
4185f4613f2SJohn Marino case '=': /* Not documented. */
4195f4613f2SJohn Marino mapp->conditional |= EQ;
4205f4613f2SJohn Marino break;
4215f4613f2SJohn Marino case '!':
4225f4613f2SJohn Marino mapp->conditional |= NOT;
4235f4613f2SJohn Marino break;
4245f4613f2SJohn Marino default:
4255f4613f2SJohn Marino goto next;
4265f4613f2SJohn Marino }
4275f4613f2SJohn Marino }
4285f4613f2SJohn Marino
4295f4613f2SJohn Marino next:
4305f4613f2SJohn Marino if (*arg == ':') {
4315f4613f2SJohn Marino if (mapp->conditional)
4325f4613f2SJohn Marino goto badmopt;
4335f4613f2SJohn Marino ++arg;
4345f4613f2SJohn Marino } else { /* Optional baudrate. */
4355f4613f2SJohn Marino arg = strchr(p = arg, ':');
4365f4613f2SJohn Marino if (arg == 0)
4375f4613f2SJohn Marino goto badmopt;
4385f4613f2SJohn Marino *arg++ = '\0';
4395f4613f2SJohn Marino mapp->speed = tbaudrate(p);
4405f4613f2SJohn Marino }
4415f4613f2SJohn Marino
4425f4613f2SJohn Marino mapp->type = arg;
4435f4613f2SJohn Marino
4445f4613f2SJohn Marino /* Terminate porttype, if specified. */
4455f4613f2SJohn Marino if (termp != 0)
4465f4613f2SJohn Marino *base = '\0';
4475f4613f2SJohn Marino
4485f4613f2SJohn Marino /* If a NOT conditional, reverse the test. */
4495f4613f2SJohn Marino if (mapp->conditional & NOT)
4505f4613f2SJohn Marino mapp->conditional = ~mapp->conditional & (EQ | GT | LT);
4515f4613f2SJohn Marino
4525f4613f2SJohn Marino /* If user specified a port with an option flag, set it. */
4535f4613f2SJohn Marino done:
4545f4613f2SJohn Marino if (port) {
4555f4613f2SJohn Marino if (mapp->porttype) {
4565f4613f2SJohn Marino badmopt:
4575f4613f2SJohn Marino err("illegal -m option format: %s", copy);
4585f4613f2SJohn Marino }
4595f4613f2SJohn Marino mapp->porttype = port;
4605f4613f2SJohn Marino }
4615f4613f2SJohn Marino free(copy);
4625f4613f2SJohn Marino #ifdef MAPDEBUG
4635f4613f2SJohn Marino (void) printf("port: %s\n", mapp->porttype ? mapp->porttype : "ANY");
4645f4613f2SJohn Marino (void) printf("type: %s\n", mapp->type);
4655f4613f2SJohn Marino (void) printf("conditional: ");
4665f4613f2SJohn Marino p = "";
4675f4613f2SJohn Marino if (mapp->conditional & GT) {
4685f4613f2SJohn Marino (void) printf("GT");
4695f4613f2SJohn Marino p = "/";
4705f4613f2SJohn Marino }
4715f4613f2SJohn Marino if (mapp->conditional & EQ) {
4725f4613f2SJohn Marino (void) printf("%sEQ", p);
4735f4613f2SJohn Marino p = "/";
4745f4613f2SJohn Marino }
4755f4613f2SJohn Marino if (mapp->conditional & LT)
4765f4613f2SJohn Marino (void) printf("%sLT", p);
4775f4613f2SJohn Marino (void) printf("\nspeed: %d\n", mapp->speed);
4785f4613f2SJohn Marino #endif
4795f4613f2SJohn Marino }
4805f4613f2SJohn Marino
4815f4613f2SJohn Marino /*
4825f4613f2SJohn Marino * Return the type of terminal to use for a port of type 'type', as specified
4835f4613f2SJohn Marino * by the first applicable mapping in 'map'. If no mappings apply, return
4845f4613f2SJohn Marino * 'type'.
4855f4613f2SJohn Marino */
4865f4613f2SJohn Marino static const char *
mapped(const char * type)4875f4613f2SJohn Marino mapped(const char *type)
4885f4613f2SJohn Marino {
4895f4613f2SJohn Marino MAP *mapp;
4905f4613f2SJohn Marino int match;
4915f4613f2SJohn Marino
4925f4613f2SJohn Marino for (mapp = maplist; mapp; mapp = mapp->next)
4935f4613f2SJohn Marino if (mapp->porttype == 0 || !strcmp(mapp->porttype, type)) {
4945f4613f2SJohn Marino switch (mapp->conditional) {
4955f4613f2SJohn Marino case 0: /* No test specified. */
4965f4613f2SJohn Marino match = TRUE;
4975f4613f2SJohn Marino break;
4985f4613f2SJohn Marino case EQ:
4993468e90cSJohn Marino match = ((int) ospeed == mapp->speed);
5005f4613f2SJohn Marino break;
5015f4613f2SJohn Marino case GE:
5023468e90cSJohn Marino match = ((int) ospeed >= mapp->speed);
5035f4613f2SJohn Marino break;
5045f4613f2SJohn Marino case GT:
5053468e90cSJohn Marino match = ((int) ospeed > mapp->speed);
5065f4613f2SJohn Marino break;
5075f4613f2SJohn Marino case LE:
5083468e90cSJohn Marino match = ((int) ospeed <= mapp->speed);
5095f4613f2SJohn Marino break;
5105f4613f2SJohn Marino case LT:
5113468e90cSJohn Marino match = ((int) ospeed < mapp->speed);
5125f4613f2SJohn Marino break;
5135f4613f2SJohn Marino default:
5145f4613f2SJohn Marino match = FALSE;
5155f4613f2SJohn Marino }
5165f4613f2SJohn Marino if (match)
5175f4613f2SJohn Marino return (mapp->type);
5185f4613f2SJohn Marino }
5195f4613f2SJohn Marino /* No match found; return given type. */
5205f4613f2SJohn Marino return (type);
5215f4613f2SJohn Marino }
5225f4613f2SJohn Marino
5235f4613f2SJohn Marino /**************************************************************************
5245f4613f2SJohn Marino *
5255f4613f2SJohn Marino * Entry fetching
5265f4613f2SJohn Marino *
5275f4613f2SJohn Marino **************************************************************************/
5285f4613f2SJohn Marino
5295f4613f2SJohn Marino /*
5305f4613f2SJohn Marino * Figure out what kind of terminal we're dealing with, and then read in
5315f4613f2SJohn Marino * its termcap entry.
5325f4613f2SJohn Marino */
5335f4613f2SJohn Marino static const char *
get_termcap_entry(int fd,char * userarg)534*32bb5217SDaniel Fojt get_termcap_entry(int fd, char *userarg)
5355f4613f2SJohn Marino {
5365f4613f2SJohn Marino int errret;
5375f4613f2SJohn Marino char *p;
5385f4613f2SJohn Marino const char *ttype;
5395f4613f2SJohn Marino #if HAVE_GETTTYNAM
5405f4613f2SJohn Marino struct ttyent *t;
5415f4613f2SJohn Marino #else
5425f4613f2SJohn Marino FILE *fp;
5435f4613f2SJohn Marino #endif
5445f4613f2SJohn Marino char *ttypath;
5455f4613f2SJohn Marino
546*32bb5217SDaniel Fojt (void) fd;
547*32bb5217SDaniel Fojt
5485f4613f2SJohn Marino if (userarg) {
5495f4613f2SJohn Marino ttype = userarg;
5505f4613f2SJohn Marino goto found;
5515f4613f2SJohn Marino }
5525f4613f2SJohn Marino
5535f4613f2SJohn Marino /* Try the environment. */
5545f4613f2SJohn Marino if ((ttype = getenv("TERM")) != 0)
5555f4613f2SJohn Marino goto map;
5565f4613f2SJohn Marino
557*32bb5217SDaniel Fojt if ((ttypath = ttyname(fd)) != 0) {
5585f4613f2SJohn Marino p = _nc_basename(ttypath);
5595f4613f2SJohn Marino #if HAVE_GETTTYNAM
5605f4613f2SJohn Marino /*
5615f4613f2SJohn Marino * We have the 4.3BSD library call getttynam(3); that means
5625f4613f2SJohn Marino * there's an /etc/ttys to look up device-to-type mappings in.
5635f4613f2SJohn Marino * Try ttyname(3); check for dialup or other mapping.
5645f4613f2SJohn Marino */
5655f4613f2SJohn Marino if ((t = getttynam(p))) {
5665f4613f2SJohn Marino ttype = t->ty_type;
5675f4613f2SJohn Marino goto map;
5685f4613f2SJohn Marino }
5695f4613f2SJohn Marino #else
5705f4613f2SJohn Marino if ((fp = fopen("/etc/ttytype", "r")) != 0
5715f4613f2SJohn Marino || (fp = fopen("/etc/ttys", "r")) != 0) {
5725f4613f2SJohn Marino char buffer[BUFSIZ];
5735f4613f2SJohn Marino char *s, *t, *d;
5745f4613f2SJohn Marino
5755f4613f2SJohn Marino while (fgets(buffer, sizeof(buffer) - 1, fp) != 0) {
5765f4613f2SJohn Marino for (s = buffer, t = d = 0; *s; s++) {
5775f4613f2SJohn Marino if (isspace(UChar(*s)))
5785f4613f2SJohn Marino *s = '\0';
5795f4613f2SJohn Marino else if (t == 0)
5805f4613f2SJohn Marino t = s;
5815f4613f2SJohn Marino else if (d == 0 && s != buffer && s[-1] == '\0')
5825f4613f2SJohn Marino d = s;
5835f4613f2SJohn Marino }
5845f4613f2SJohn Marino if (t != 0 && d != 0 && !strcmp(d, p)) {
5855f4613f2SJohn Marino ttype = strdup(t);
5865f4613f2SJohn Marino fclose(fp);
5875f4613f2SJohn Marino goto map;
5885f4613f2SJohn Marino }
5895f4613f2SJohn Marino }
5905f4613f2SJohn Marino fclose(fp);
5915f4613f2SJohn Marino }
5925f4613f2SJohn Marino #endif /* HAVE_GETTTYNAM */
5935f4613f2SJohn Marino }
5945f4613f2SJohn Marino
5955f4613f2SJohn Marino /* If still undefined, use "unknown". */
5965f4613f2SJohn Marino ttype = "unknown";
5975f4613f2SJohn Marino
5985f4613f2SJohn Marino map:ttype = mapped(ttype);
5995f4613f2SJohn Marino
6005f4613f2SJohn Marino /*
6015f4613f2SJohn Marino * If not a path, remove TERMCAP from the environment so we get a
6025f4613f2SJohn Marino * real entry from /etc/termcap. This prevents us from being fooled
6035f4613f2SJohn Marino * by out of date stuff in the environment.
6045f4613f2SJohn Marino */
6053468e90cSJohn Marino found:
6063468e90cSJohn Marino if ((p = getenv("TERMCAP")) != 0 && !_nc_is_abs_path(p)) {
6075f4613f2SJohn Marino /* 'unsetenv("TERMCAP")' is not portable.
6085f4613f2SJohn Marino * The 'environ' array is better.
6095f4613f2SJohn Marino */
6105f4613f2SJohn Marino int n;
6115f4613f2SJohn Marino for (n = 0; environ[n] != 0; n++) {
6123468e90cSJohn Marino if (!strncmp("TERMCAP=", environ[n], (size_t) 8)) {
6135f4613f2SJohn Marino while ((environ[n] = environ[n + 1]) != 0) {
6145f4613f2SJohn Marino n++;
6155f4613f2SJohn Marino }
6165f4613f2SJohn Marino break;
6175f4613f2SJohn Marino }
6185f4613f2SJohn Marino }
6195f4613f2SJohn Marino }
6205f4613f2SJohn Marino
6215f4613f2SJohn Marino /*
6225f4613f2SJohn Marino * ttype now contains a pointer to the type of the terminal.
6235f4613f2SJohn Marino * If the first character is '?', ask the user.
6245f4613f2SJohn Marino */
6255f4613f2SJohn Marino if (ttype[0] == '?') {
6265f4613f2SJohn Marino if (ttype[1] != '\0')
6275f4613f2SJohn Marino ttype = askuser(ttype + 1);
6285f4613f2SJohn Marino else
6295f4613f2SJohn Marino ttype = askuser(0);
6305f4613f2SJohn Marino }
6315f4613f2SJohn Marino /* Find the terminfo entry. If it doesn't exist, ask the user. */
632*32bb5217SDaniel Fojt while (setupterm((NCURSES_CONST char *) ttype, fd, &errret)
6335f4613f2SJohn Marino != OK) {
6345f4613f2SJohn Marino if (errret == 0) {
6355f4613f2SJohn Marino (void) fprintf(stderr, "%s: unknown terminal type %s\n",
6365f4613f2SJohn Marino _nc_progname, ttype);
6375f4613f2SJohn Marino ttype = 0;
6385f4613f2SJohn Marino } else {
6395f4613f2SJohn Marino (void) fprintf(stderr,
6405f4613f2SJohn Marino "%s: can't initialize terminal type %s (error %d)\n",
6415f4613f2SJohn Marino _nc_progname, ttype, errret);
6425f4613f2SJohn Marino ttype = 0;
6435f4613f2SJohn Marino }
6445f4613f2SJohn Marino ttype = askuser(ttype);
6455f4613f2SJohn Marino }
6465f4613f2SJohn Marino #if BROKEN_LINKER
6475f4613f2SJohn Marino tgetflag("am"); /* force lib_termcap.o to be linked for 'ospeed' */
6485f4613f2SJohn Marino #endif
6495f4613f2SJohn Marino return (ttype);
6505f4613f2SJohn Marino }
6515f4613f2SJohn Marino
6525f4613f2SJohn Marino /**************************************************************************
6535f4613f2SJohn Marino *
6545f4613f2SJohn Marino * Main sequence
6555f4613f2SJohn Marino *
6565f4613f2SJohn Marino **************************************************************************/
6575f4613f2SJohn Marino
6585f4613f2SJohn Marino /*
6595f4613f2SJohn Marino * Convert the obsolete argument forms into something that getopt can handle.
6605f4613f2SJohn Marino * This means that -e, -i and -k get default arguments supplied for them.
6615f4613f2SJohn Marino */
6625f4613f2SJohn Marino static void
obsolete(char ** argv)6635f4613f2SJohn Marino obsolete(char **argv)
6645f4613f2SJohn Marino {
6655f4613f2SJohn Marino for (; *argv; ++argv) {
6665f4613f2SJohn Marino char *parm = argv[0];
6675f4613f2SJohn Marino
6685f4613f2SJohn Marino if (parm[0] == '-' && parm[1] == '\0') {
6695f4613f2SJohn Marino argv[0] = strdup("-q");
6705f4613f2SJohn Marino continue;
6715f4613f2SJohn Marino }
6725f4613f2SJohn Marino
6735f4613f2SJohn Marino if ((parm[0] != '-')
6745f4613f2SJohn Marino || (argv[1] && argv[1][0] != '-')
6755f4613f2SJohn Marino || (parm[1] != 'e' && parm[1] != 'i' && parm[1] != 'k')
6765f4613f2SJohn Marino || (parm[2] != '\0'))
6775f4613f2SJohn Marino continue;
6785f4613f2SJohn Marino switch (argv[0][1]) {
6795f4613f2SJohn Marino case 'e':
6805f4613f2SJohn Marino argv[0] = strdup("-e^H");
6815f4613f2SJohn Marino break;
6825f4613f2SJohn Marino case 'i':
6835f4613f2SJohn Marino argv[0] = strdup("-i^C");
6845f4613f2SJohn Marino break;
6855f4613f2SJohn Marino case 'k':
6865f4613f2SJohn Marino argv[0] = strdup("-k^U");
6875f4613f2SJohn Marino break;
6885f4613f2SJohn Marino }
6895f4613f2SJohn Marino }
6905f4613f2SJohn Marino }
6915f4613f2SJohn Marino
6925f4613f2SJohn Marino static void
print_shell_commands(const char * ttype)693*32bb5217SDaniel Fojt print_shell_commands(const char *ttype)
694*32bb5217SDaniel Fojt {
695*32bb5217SDaniel Fojt const char *p;
696*32bb5217SDaniel Fojt int len;
697*32bb5217SDaniel Fojt char *var;
698*32bb5217SDaniel Fojt char *leaf;
699*32bb5217SDaniel Fojt /*
700*32bb5217SDaniel Fojt * Figure out what shell we're using. A hack, we look for an
701*32bb5217SDaniel Fojt * environmental variable SHELL ending in "csh".
702*32bb5217SDaniel Fojt */
703*32bb5217SDaniel Fojt if ((var = getenv("SHELL")) != 0
704*32bb5217SDaniel Fojt && ((len = (int) strlen(leaf = _nc_basename(var))) >= 3)
705*32bb5217SDaniel Fojt && !strcmp(leaf + len - 3, "csh"))
706*32bb5217SDaniel Fojt p = "set noglob;\nsetenv TERM %s;\nunset noglob;\n";
707*32bb5217SDaniel Fojt else
708*32bb5217SDaniel Fojt p = "TERM=%s;\n";
709*32bb5217SDaniel Fojt (void) printf(p, ttype);
710*32bb5217SDaniel Fojt }
711*32bb5217SDaniel Fojt
712*32bb5217SDaniel Fojt static void
usage(void)7135f4613f2SJohn Marino usage(void)
7145f4613f2SJohn Marino {
715*32bb5217SDaniel Fojt #define SKIP(s) /* nothing */
716*32bb5217SDaniel Fojt #define KEEP(s) s "\n"
7173468e90cSJohn Marino static const char msg[] =
7185f4613f2SJohn Marino {
719*32bb5217SDaniel Fojt KEEP("")
720*32bb5217SDaniel Fojt KEEP("Options:")
721*32bb5217SDaniel Fojt SKIP(" -a arpanet (obsolete)")
722*32bb5217SDaniel Fojt KEEP(" -c set control characters")
723*32bb5217SDaniel Fojt SKIP(" -d dialup (obsolete)")
724*32bb5217SDaniel Fojt KEEP(" -e ch erase character")
725*32bb5217SDaniel Fojt KEEP(" -I no initialization strings")
726*32bb5217SDaniel Fojt KEEP(" -i ch interrupt character")
727*32bb5217SDaniel Fojt KEEP(" -k ch kill character")
728*32bb5217SDaniel Fojt KEEP(" -m mapping map identifier to type")
729*32bb5217SDaniel Fojt SKIP(" -p plugboard (obsolete)")
730*32bb5217SDaniel Fojt KEEP(" -Q do not output control key settings")
731*32bb5217SDaniel Fojt KEEP(" -q display term only, do no changes")
732*32bb5217SDaniel Fojt KEEP(" -r display term on stderr")
733*32bb5217SDaniel Fojt SKIP(" -S (obsolete)")
734*32bb5217SDaniel Fojt KEEP(" -s output TERM set command")
735*32bb5217SDaniel Fojt KEEP(" -V print curses-version")
736*32bb5217SDaniel Fojt KEEP(" -w set window-size")
737*32bb5217SDaniel Fojt KEEP("")
738*32bb5217SDaniel Fojt KEEP("If neither -c/-w are given, both are assumed.")
7395f4613f2SJohn Marino };
740*32bb5217SDaniel Fojt #undef KEEP
741*32bb5217SDaniel Fojt #undef SKIP
7425f4613f2SJohn Marino (void) fprintf(stderr, "Usage: %s [options] [terminal]\n", _nc_progname);
7433468e90cSJohn Marino fputs(msg, stderr);
744*32bb5217SDaniel Fojt ExitProgram(EXIT_FAILURE);
7455f4613f2SJohn Marino /* NOTREACHED */
7465f4613f2SJohn Marino }
7475f4613f2SJohn Marino
7485f4613f2SJohn Marino static char
arg_to_char(void)7495f4613f2SJohn Marino arg_to_char(void)
7505f4613f2SJohn Marino {
7515f4613f2SJohn Marino return (char) ((optarg[0] == '^' && optarg[1] != '\0')
7525f4613f2SJohn Marino ? ((optarg[1] == '?') ? '\177' : CTRL(optarg[1]))
7535f4613f2SJohn Marino : optarg[0]);
7545f4613f2SJohn Marino }
7555f4613f2SJohn Marino
7565f4613f2SJohn Marino int
main(int argc,char ** argv)7575f4613f2SJohn Marino main(int argc, char **argv)
7585f4613f2SJohn Marino {
7595f4613f2SJohn Marino int ch, noinit, noset, quiet, Sflag, sflag, showterm;
7605f4613f2SJohn Marino const char *ttype;
761*32bb5217SDaniel Fojt int terasechar = -1; /* new erase character */
762*32bb5217SDaniel Fojt int intrchar = -1; /* new interrupt character */
763*32bb5217SDaniel Fojt int tkillchar = -1; /* new kill character */
764*32bb5217SDaniel Fojt int my_fd;
765*32bb5217SDaniel Fojt bool opt_c = FALSE; /* set control-chars */
766*32bb5217SDaniel Fojt bool opt_w = FALSE; /* set window-size */
767*32bb5217SDaniel Fojt TTY mode, oldmode;
7685f4613f2SJohn Marino
769*32bb5217SDaniel Fojt my_fd = STDERR_FILENO;
7705f4613f2SJohn Marino obsolete(argv);
7715f4613f2SJohn Marino noinit = noset = quiet = Sflag = sflag = showterm = 0;
772*32bb5217SDaniel Fojt while ((ch = getopt(argc, argv, "a:cd:e:Ii:k:m:p:qQrSsVw")) != -1) {
7735f4613f2SJohn Marino switch (ch) {
7745f4613f2SJohn Marino case 'c': /* set control-chars */
7755f4613f2SJohn Marino opt_c = TRUE;
7765f4613f2SJohn Marino break;
7775f4613f2SJohn Marino case 'a': /* OBSOLETE: map identifier to type */
7785f4613f2SJohn Marino add_mapping("arpanet", optarg);
7795f4613f2SJohn Marino break;
7805f4613f2SJohn Marino case 'd': /* OBSOLETE: map identifier to type */
7815f4613f2SJohn Marino add_mapping("dialup", optarg);
7825f4613f2SJohn Marino break;
7835f4613f2SJohn Marino case 'e': /* erase character */
7845f4613f2SJohn Marino terasechar = arg_to_char();
7855f4613f2SJohn Marino break;
7865f4613f2SJohn Marino case 'I': /* no initialization strings */
7875f4613f2SJohn Marino noinit = 1;
7885f4613f2SJohn Marino break;
7895f4613f2SJohn Marino case 'i': /* interrupt character */
7905f4613f2SJohn Marino intrchar = arg_to_char();
7915f4613f2SJohn Marino break;
7925f4613f2SJohn Marino case 'k': /* kill character */
7935f4613f2SJohn Marino tkillchar = arg_to_char();
7945f4613f2SJohn Marino break;
7955f4613f2SJohn Marino case 'm': /* map identifier to type */
7965f4613f2SJohn Marino add_mapping(0, optarg);
7975f4613f2SJohn Marino break;
7985f4613f2SJohn Marino case 'p': /* OBSOLETE: map identifier to type */
7995f4613f2SJohn Marino add_mapping("plugboard", optarg);
8005f4613f2SJohn Marino break;
8015f4613f2SJohn Marino case 'Q': /* don't output control key settings */
8025f4613f2SJohn Marino quiet = 1;
8035f4613f2SJohn Marino break;
8045f4613f2SJohn Marino case 'q': /* display term only */
8055f4613f2SJohn Marino noset = 1;
8065f4613f2SJohn Marino break;
8075f4613f2SJohn Marino case 'r': /* display term on stderr */
8085f4613f2SJohn Marino showterm = 1;
8095f4613f2SJohn Marino break;
8105f4613f2SJohn Marino case 'S': /* OBSOLETE: output TERM & TERMCAP */
8115f4613f2SJohn Marino Sflag = 1;
8125f4613f2SJohn Marino break;
8135f4613f2SJohn Marino case 's': /* output TERM set command */
8145f4613f2SJohn Marino sflag = 1;
8155f4613f2SJohn Marino break;
8165f4613f2SJohn Marino case 'V': /* print curses-version */
8175f4613f2SJohn Marino puts(curses_version());
8185f4613f2SJohn Marino ExitProgram(EXIT_SUCCESS);
8195f4613f2SJohn Marino case 'w': /* set window-size */
8205f4613f2SJohn Marino opt_w = TRUE;
8215f4613f2SJohn Marino break;
8225f4613f2SJohn Marino case '?':
8235f4613f2SJohn Marino default:
8245f4613f2SJohn Marino usage();
8255f4613f2SJohn Marino }
8265f4613f2SJohn Marino }
8275f4613f2SJohn Marino
8285f4613f2SJohn Marino _nc_progname = _nc_rootname(*argv);
8295f4613f2SJohn Marino argc -= optind;
8305f4613f2SJohn Marino argv += optind;
8315f4613f2SJohn Marino
8325f4613f2SJohn Marino if (argc > 1)
8335f4613f2SJohn Marino usage();
8345f4613f2SJohn Marino
8355f4613f2SJohn Marino if (!opt_c && !opt_w)
8365f4613f2SJohn Marino opt_c = opt_w = TRUE;
8375f4613f2SJohn Marino
838*32bb5217SDaniel Fojt my_fd = save_tty_settings(&mode, TRUE);
839*32bb5217SDaniel Fojt oldmode = mode;
8405f4613f2SJohn Marino #ifdef TERMIOS
8415f4613f2SJohn Marino ospeed = (NCURSES_OSPEED) cfgetospeed(&mode);
8425f4613f2SJohn Marino #else
8435f4613f2SJohn Marino ospeed = (NCURSES_OSPEED) mode.sg_ospeed;
8445f4613f2SJohn Marino #endif
8455f4613f2SJohn Marino
8465f4613f2SJohn Marino if (same_program(_nc_progname, PROG_RESET)) {
847*32bb5217SDaniel Fojt reset_start(stderr, TRUE, FALSE);
848*32bb5217SDaniel Fojt reset_tty_settings(my_fd, &mode);
849*32bb5217SDaniel Fojt } else {
850*32bb5217SDaniel Fojt reset_start(stderr, FALSE, TRUE);
8515f4613f2SJohn Marino }
8525f4613f2SJohn Marino
853*32bb5217SDaniel Fojt ttype = get_termcap_entry(my_fd, *argv);
8545f4613f2SJohn Marino
8555f4613f2SJohn Marino if (!noset) {
8563468e90cSJohn Marino #if HAVE_SIZECHANGE
8575f4613f2SJohn Marino if (opt_w) {
858*32bb5217SDaniel Fojt set_window_size(my_fd, &lines, &columns);
8595f4613f2SJohn Marino }
8605f4613f2SJohn Marino #endif
8615f4613f2SJohn Marino if (opt_c) {
862*32bb5217SDaniel Fojt set_control_chars(&mode, terasechar, intrchar, tkillchar);
863*32bb5217SDaniel Fojt set_conversions(&mode);
8645f4613f2SJohn Marino
865*32bb5217SDaniel Fojt if (!noinit) {
866*32bb5217SDaniel Fojt if (send_init_strings(my_fd, &oldmode)) {
867*32bb5217SDaniel Fojt (void) putc('\r', stderr);
868*32bb5217SDaniel Fojt (void) fflush(stderr);
869*32bb5217SDaniel Fojt (void) napms(1000); /* Settle the terminal. */
8705f4613f2SJohn Marino }
8715f4613f2SJohn Marino }
8725f4613f2SJohn Marino
873*32bb5217SDaniel Fojt update_tty_settings(&oldmode, &mode);
874*32bb5217SDaniel Fojt }
875*32bb5217SDaniel Fojt }
876*32bb5217SDaniel Fojt
877*32bb5217SDaniel Fojt if (noset) {
8785f4613f2SJohn Marino (void) printf("%s\n", ttype);
879*32bb5217SDaniel Fojt } else {
8805f4613f2SJohn Marino if (showterm)
8815f4613f2SJohn Marino (void) fprintf(stderr, "Terminal type is %s.\n", ttype);
8825f4613f2SJohn Marino /*
8835f4613f2SJohn Marino * If erase, kill and interrupt characters could have been
8845f4613f2SJohn Marino * modified and not -Q, display the changes.
8855f4613f2SJohn Marino */
8865f4613f2SJohn Marino if (!quiet) {
887*32bb5217SDaniel Fojt print_tty_chars(&oldmode, &mode);
8885f4613f2SJohn Marino }
8895f4613f2SJohn Marino }
8905f4613f2SJohn Marino
8915f4613f2SJohn Marino if (Sflag)
8925f4613f2SJohn Marino err("The -S option is not supported under terminfo.");
8935f4613f2SJohn Marino
8945f4613f2SJohn Marino if (sflag) {
895*32bb5217SDaniel Fojt print_shell_commands(ttype);
8965f4613f2SJohn Marino }
8975f4613f2SJohn Marino
8985f4613f2SJohn Marino ExitProgram(EXIT_SUCCESS);
8995f4613f2SJohn Marino }
900