xref: /dflybsd-src/contrib/ncurses/progs/tset.c (revision 0cadad7e49c6219b0de0675ef6a6f44683d177d4)
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