xref: /freebsd/contrib/ncurses/progs/tset.c (revision 39f2269fcb4873fd97d70af944ec49f4230fadea)
10e3d5408SPeter Wemm /****************************************************************************
239f2269fSPeter Wemm  * Copyright (c) 1998,1999,2000,2001 Free Software Foundation, Inc.         *
30e3d5408SPeter Wemm  *                                                                          *
40e3d5408SPeter Wemm  * Permission is hereby granted, free of charge, to any person obtaining a  *
50e3d5408SPeter Wemm  * copy of this software and associated documentation files (the            *
60e3d5408SPeter Wemm  * "Software"), to deal in the Software without restriction, including      *
70e3d5408SPeter Wemm  * without limitation the rights to use, copy, modify, merge, publish,      *
80e3d5408SPeter Wemm  * distribute, distribute with modifications, sublicense, and/or sell       *
90e3d5408SPeter Wemm  * copies of the Software, and to permit persons to whom the Software is    *
100e3d5408SPeter Wemm  * furnished to do so, subject to the following conditions:                 *
110e3d5408SPeter Wemm  *                                                                          *
120e3d5408SPeter Wemm  * The above copyright notice and this permission notice shall be included  *
130e3d5408SPeter Wemm  * in all copies or substantial portions of the Software.                   *
140e3d5408SPeter Wemm  *                                                                          *
150e3d5408SPeter Wemm  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
160e3d5408SPeter Wemm  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
170e3d5408SPeter Wemm  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
180e3d5408SPeter Wemm  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
190e3d5408SPeter Wemm  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
200e3d5408SPeter Wemm  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
210e3d5408SPeter Wemm  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
220e3d5408SPeter Wemm  *                                                                          *
230e3d5408SPeter Wemm  * Except as contained in this notice, the name(s) of the above copyright   *
240e3d5408SPeter Wemm  * holders shall not be used in advertising or otherwise to promote the     *
250e3d5408SPeter Wemm  * sale, use or other dealings in this Software without prior written       *
260e3d5408SPeter Wemm  * authorization.                                                           *
270e3d5408SPeter Wemm  ****************************************************************************/
280e3d5408SPeter Wemm 
290e3d5408SPeter Wemm /****************************************************************************
300e3d5408SPeter Wemm  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
310e3d5408SPeter Wemm  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
320e3d5408SPeter Wemm  ****************************************************************************/
330e3d5408SPeter Wemm 
340e3d5408SPeter Wemm /*
350e3d5408SPeter Wemm  * tset.c - terminal initialization utility
360e3d5408SPeter Wemm  *
370e3d5408SPeter Wemm  * This code was mostly swiped from 4.4BSD tset, with some obsolescent
380e3d5408SPeter Wemm  * cruft removed and substantial portions rewritten.  A Regents of the
390e3d5408SPeter Wemm  * University of California copyright applies to some portions of the
400e3d5408SPeter Wemm  * code, and is reproduced below:
410e3d5408SPeter Wemm  */
420e3d5408SPeter Wemm /*-
430e3d5408SPeter Wemm  * Copyright (c) 1980, 1991, 1993
440e3d5408SPeter Wemm  *	The Regents of the University of California.  All rights reserved.
450e3d5408SPeter Wemm  *
460e3d5408SPeter Wemm  * Redistribution and use in source and binary forms, with or without
470e3d5408SPeter Wemm  * modification, are permitted provided that the following conditions
480e3d5408SPeter Wemm  * are met:
490e3d5408SPeter Wemm  * 1. Redistributions of source code must retain the above copyright
500e3d5408SPeter Wemm  *    notice, this list of conditions and the following disclaimer.
510e3d5408SPeter Wemm  * 2. Redistributions in binary form must reproduce the above copyright
520e3d5408SPeter Wemm  *    notice, this list of conditions and the following disclaimer in the
530e3d5408SPeter Wemm  *    documentation and/or other materials provided with the distribution.
540e3d5408SPeter Wemm  * 3. All advertising materials mentioning features or use of this software
550e3d5408SPeter Wemm  *    must display the following acknowledgement:
560e3d5408SPeter Wemm  *	This product includes software developed by the University of
570e3d5408SPeter Wemm  *	California, Berkeley and its contributors.
580e3d5408SPeter Wemm  * 4. Neither the name of the University nor the names of its contributors
590e3d5408SPeter Wemm  *    may be used to endorse or promote products derived from this software
600e3d5408SPeter Wemm  *    without specific prior written permission.
610e3d5408SPeter Wemm  *
620e3d5408SPeter Wemm  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
630e3d5408SPeter Wemm  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
640e3d5408SPeter Wemm  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
650e3d5408SPeter Wemm  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
660e3d5408SPeter Wemm  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
670e3d5408SPeter Wemm  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
680e3d5408SPeter Wemm  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
690e3d5408SPeter Wemm  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
700e3d5408SPeter Wemm  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
710e3d5408SPeter Wemm  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
720e3d5408SPeter Wemm  * SUCH DAMAGE.
730e3d5408SPeter Wemm  */
740e3d5408SPeter Wemm 
750e3d5408SPeter Wemm #define __INTERNAL_CAPS_VISIBLE	/* we need to see has_hardware_tabs */
760e3d5408SPeter Wemm #include <progs.priv.h>
770e3d5408SPeter Wemm 
780e3d5408SPeter Wemm #include <errno.h>
790e3d5408SPeter Wemm #include <stdio.h>
800e3d5408SPeter Wemm #include <termcap.h>
810e3d5408SPeter Wemm #include <fcntl.h>
820e3d5408SPeter Wemm 
830e3d5408SPeter Wemm #if HAVE_GETTTYNAM && HAVE_TTYENT_H
840e3d5408SPeter Wemm #include <ttyent.h>
850e3d5408SPeter Wemm #endif
860e3d5408SPeter Wemm #ifdef NeXT
870e3d5408SPeter Wemm char *ttyname(int fd);
880e3d5408SPeter Wemm #endif
890e3d5408SPeter Wemm 
900e3d5408SPeter Wemm /* this is just to stifle a missing-prototype warning */
910e3d5408SPeter Wemm #ifdef linux
920e3d5408SPeter Wemm # include <sys/ioctl.h>
930e3d5408SPeter Wemm #endif
940e3d5408SPeter Wemm 
950e3d5408SPeter Wemm #if NEED_PTEM_H
960e3d5408SPeter Wemm /* they neglected to define struct winsize in termios.h -- it's only
970e3d5408SPeter Wemm    in termio.h	*/
980e3d5408SPeter Wemm #include <sys/stream.h>
990e3d5408SPeter Wemm #include <sys/ptem.h>
1000e3d5408SPeter Wemm #endif
1010e3d5408SPeter Wemm 
1020e3d5408SPeter Wemm #include <curses.h>		/* for bool typedef */
1030e3d5408SPeter Wemm #include <dump_entry.h>
10418259542SPeter Wemm #include <transform.h>
1050e3d5408SPeter Wemm 
10639f2269fSPeter Wemm MODULE_ID("$Id: tset.c,v 0.52 2001/09/29 21:13:56 tom Exp $")
1070e3d5408SPeter Wemm 
1080e3d5408SPeter Wemm extern char **environ;
1090e3d5408SPeter Wemm 
1100e3d5408SPeter Wemm #undef CTRL
1110e3d5408SPeter Wemm #define CTRL(x)	((x) & 0x1f)
1120e3d5408SPeter Wemm 
1130e3d5408SPeter Wemm const char *_nc_progname = "tset";
1140e3d5408SPeter Wemm 
11539f2269fSPeter Wemm static TTY mode, oldmode, original;
1160e3d5408SPeter Wemm 
11739f2269fSPeter Wemm static bool can_restore = FALSE;
11818259542SPeter Wemm static bool isreset = FALSE;	/* invoked as reset */
1190e3d5408SPeter Wemm static int terasechar = -1;	/* new erase character */
1200e3d5408SPeter Wemm static int intrchar = -1;	/* new interrupt character */
1210e3d5408SPeter Wemm static int tkillchar = -1;	/* new kill character */
1220e3d5408SPeter Wemm static int tlines, tcolumns;	/* window size */
1230e3d5408SPeter Wemm 
12439f2269fSPeter Wemm #define LOWERCASE(c) ((isalpha(UChar(c)) && isupper(UChar(c))) ? tolower(UChar(c)) : (c))
1250e3d5408SPeter Wemm 
1260e3d5408SPeter Wemm static int
12715589c42SPeter Wemm CaselessCmp(const char *a, const char *b)
12815589c42SPeter Wemm {				/* strcasecmp isn't portable */
1290e3d5408SPeter Wemm     while (*a && *b) {
1300e3d5408SPeter Wemm 	int cmp = LOWERCASE(*a) - LOWERCASE(*b);
1310e3d5408SPeter Wemm 	if (cmp != 0)
1320e3d5408SPeter Wemm 	    break;
1330e3d5408SPeter Wemm 	a++, b++;
1340e3d5408SPeter Wemm     }
1350e3d5408SPeter Wemm     return LOWERCASE(*a) - LOWERCASE(*b);
1360e3d5408SPeter Wemm }
1370e3d5408SPeter Wemm 
1380e3d5408SPeter Wemm static void
13939f2269fSPeter Wemm exit_error(void)
14039f2269fSPeter Wemm {
14139f2269fSPeter Wemm     if (can_restore)
14239f2269fSPeter Wemm 	SET_TTY(STDERR_FILENO, &original);
14339f2269fSPeter Wemm     (void) fprintf(stderr, "\n");
14439f2269fSPeter Wemm     fflush(stderr);
14539f2269fSPeter Wemm     exit(EXIT_FAILURE);
14639f2269fSPeter Wemm     /* NOTREACHED */
14739f2269fSPeter Wemm }
14839f2269fSPeter Wemm 
14939f2269fSPeter Wemm static void
1500e3d5408SPeter Wemm err(const char *fmt,...)
1510e3d5408SPeter Wemm {
1520e3d5408SPeter Wemm     va_list ap;
1530e3d5408SPeter Wemm     va_start(ap, fmt);
1540e3d5408SPeter Wemm     (void) fprintf(stderr, "tset: ");
1550e3d5408SPeter Wemm     (void) vfprintf(stderr, fmt, ap);
1560e3d5408SPeter Wemm     va_end(ap);
15739f2269fSPeter Wemm     exit_error();
1580e3d5408SPeter Wemm     /* NOTREACHED */
1590e3d5408SPeter Wemm }
1600e3d5408SPeter Wemm 
1610e3d5408SPeter Wemm static void
1620e3d5408SPeter Wemm failed(const char *msg)
1630e3d5408SPeter Wemm {
1640e3d5408SPeter Wemm     char temp[BUFSIZ];
16515589c42SPeter Wemm     perror(strncat(strcpy(temp, "tset: "), msg, sizeof(temp) - 10));
16639f2269fSPeter Wemm     exit_error();
1670e3d5408SPeter Wemm     /* NOTREACHED */
1680e3d5408SPeter Wemm }
1690e3d5408SPeter Wemm 
1700e3d5408SPeter Wemm static void
1710e3d5408SPeter Wemm cat(char *file)
1720e3d5408SPeter Wemm {
17339f2269fSPeter Wemm     FILE *fp;
17439f2269fSPeter Wemm     size_t nr;
1750e3d5408SPeter Wemm     char buf[BUFSIZ];
1760e3d5408SPeter Wemm 
17739f2269fSPeter Wemm     if ((fp = fopen(file, "r")) == 0)
1780e3d5408SPeter Wemm 	failed(file);
1790e3d5408SPeter Wemm 
18039f2269fSPeter Wemm     while ((nr = fread(buf, sizeof(char), sizeof(buf), fp)) != 0)
18139f2269fSPeter Wemm 	if (fwrite(buf, sizeof(char), nr, stderr) != nr)
1820e3d5408SPeter Wemm 	      failed("write to stderr");
18339f2269fSPeter Wemm     fclose(fp);
1840e3d5408SPeter Wemm }
1850e3d5408SPeter Wemm 
1860e3d5408SPeter Wemm static int
1870e3d5408SPeter Wemm outc(int c)
1880e3d5408SPeter Wemm {
1890e3d5408SPeter Wemm     return putc(c, stderr);
1900e3d5408SPeter Wemm }
1910e3d5408SPeter Wemm 
1920e3d5408SPeter Wemm /* Prompt the user for a terminal type. */
1930e3d5408SPeter Wemm static const char *
1940e3d5408SPeter Wemm askuser(const char *dflt)
1950e3d5408SPeter Wemm {
1960e3d5408SPeter Wemm     static char answer[256];
1970e3d5408SPeter Wemm     char *p;
1980e3d5408SPeter Wemm 
1990e3d5408SPeter Wemm     /* We can get recalled; if so, don't continue uselessly. */
2000e3d5408SPeter Wemm     if (feof(stdin) || ferror(stdin)) {
2010e3d5408SPeter Wemm 	(void) fprintf(stderr, "\n");
20239f2269fSPeter Wemm 	exit_error();
20339f2269fSPeter Wemm 	/* NOTREACHED */
2040e3d5408SPeter Wemm     }
2050e3d5408SPeter Wemm     for (;;) {
2060e3d5408SPeter Wemm 	if (dflt)
2070e3d5408SPeter Wemm 	    (void) fprintf(stderr, "Terminal type? [%s] ", dflt);
2080e3d5408SPeter Wemm 	else
2090e3d5408SPeter Wemm 	    (void) fprintf(stderr, "Terminal type? ");
2100e3d5408SPeter Wemm 	(void) fflush(stderr);
2110e3d5408SPeter Wemm 
2120e3d5408SPeter Wemm 	if (fgets(answer, sizeof(answer), stdin) == 0) {
2130e3d5408SPeter Wemm 	    if (dflt == 0) {
21439f2269fSPeter Wemm 		exit_error();
21539f2269fSPeter Wemm 		/* NOTREACHED */
2160e3d5408SPeter Wemm 	    }
2170e3d5408SPeter Wemm 	    return (dflt);
2180e3d5408SPeter Wemm 	}
2190e3d5408SPeter Wemm 
2200e3d5408SPeter Wemm 	if ((p = strchr(answer, '\n')) != 0)
2210e3d5408SPeter Wemm 	    *p = '\0';
2220e3d5408SPeter Wemm 	if (answer[0])
2230e3d5408SPeter Wemm 	    return (answer);
2240e3d5408SPeter Wemm 	if (dflt != 0)
2250e3d5408SPeter Wemm 	    return (dflt);
2260e3d5408SPeter Wemm     }
2270e3d5408SPeter Wemm }
2280e3d5408SPeter Wemm 
2290e3d5408SPeter Wemm /**************************************************************************
2300e3d5408SPeter Wemm  *
2310e3d5408SPeter Wemm  * Mapping logic begins here
2320e3d5408SPeter Wemm  *
2330e3d5408SPeter Wemm  **************************************************************************/
2340e3d5408SPeter Wemm 
2350e3d5408SPeter Wemm /* Baud rate conditionals for mapping. */
2360e3d5408SPeter Wemm #define	GT		0x01
2370e3d5408SPeter Wemm #define	EQ		0x02
2380e3d5408SPeter Wemm #define	LT		0x04
2390e3d5408SPeter Wemm #define	NOT		0x08
2400e3d5408SPeter Wemm #define	GE		(GT | EQ)
2410e3d5408SPeter Wemm #define	LE		(LT | EQ)
2420e3d5408SPeter Wemm 
2430e3d5408SPeter Wemm typedef struct map {
2440e3d5408SPeter Wemm     struct map *next;		/* Linked list of maps. */
2450e3d5408SPeter Wemm     const char *porttype;	/* Port type, or "" for any. */
2460e3d5408SPeter Wemm     const char *type;		/* Terminal type to select. */
2470e3d5408SPeter Wemm     int conditional;		/* Baud rate conditionals bitmask. */
24818259542SPeter Wemm     int speed;			/* Baud rate to compare against. */
2490e3d5408SPeter Wemm } MAP;
2500e3d5408SPeter Wemm 
2510e3d5408SPeter Wemm static MAP *cur, *maplist;
2520e3d5408SPeter Wemm 
2530e3d5408SPeter Wemm typedef struct speeds {
2540e3d5408SPeter Wemm     const char *string;
2550e3d5408SPeter Wemm     int speed;
2560e3d5408SPeter Wemm } SPEEDS;
2570e3d5408SPeter Wemm 
25815589c42SPeter Wemm static const SPEEDS speeds[] =
25915589c42SPeter Wemm {
2600e3d5408SPeter Wemm     {"0", B0},
2610e3d5408SPeter Wemm     {"50", B50},
2620e3d5408SPeter Wemm     {"75", B75},
2630e3d5408SPeter Wemm     {"110", B110},
2640e3d5408SPeter Wemm     {"134", B134},
2650e3d5408SPeter Wemm     {"134.5", B134},
2660e3d5408SPeter Wemm     {"150", B150},
2670e3d5408SPeter Wemm     {"200", B200},
2680e3d5408SPeter Wemm     {"300", B300},
2690e3d5408SPeter Wemm     {"600", B600},
2700e3d5408SPeter Wemm     {"1200", B1200},
2710e3d5408SPeter Wemm     {"1800", B1800},
2720e3d5408SPeter Wemm     {"2400", B2400},
2730e3d5408SPeter Wemm     {"4800", B4800},
2740e3d5408SPeter Wemm     {"9600", B9600},
27518259542SPeter Wemm     /* sgttyb may define up to this point */
27618259542SPeter Wemm #ifdef B19200
2770e3d5408SPeter Wemm     {"19200", B19200},
27818259542SPeter Wemm #endif
27918259542SPeter Wemm #ifdef B38400
2800e3d5408SPeter Wemm     {"38400", B38400},
28118259542SPeter Wemm #endif
28218259542SPeter Wemm #ifdef B19200
2830e3d5408SPeter Wemm     {"19200", B19200},
28418259542SPeter Wemm #endif
28518259542SPeter Wemm #ifdef B38400
2860e3d5408SPeter Wemm     {"38400", B38400},
28718259542SPeter Wemm #endif
2880e3d5408SPeter Wemm #ifdef B19200
2890e3d5408SPeter Wemm     {"19200", B19200},
2900e3d5408SPeter Wemm #else
2910e3d5408SPeter Wemm #ifdef EXTA
2920e3d5408SPeter Wemm     {"19200", EXTA},
2930e3d5408SPeter Wemm #endif
2940e3d5408SPeter Wemm #endif
2950e3d5408SPeter Wemm #ifdef B38400
2960e3d5408SPeter Wemm     {"38400", B38400},
2970e3d5408SPeter Wemm #else
2980e3d5408SPeter Wemm #ifdef EXTB
2990e3d5408SPeter Wemm     {"38400", EXTB},
3000e3d5408SPeter Wemm #endif
3010e3d5408SPeter Wemm #endif
3020e3d5408SPeter Wemm #ifdef B57600
3030e3d5408SPeter Wemm     {"57600", B57600},
3040e3d5408SPeter Wemm #endif
3050e3d5408SPeter Wemm #ifdef B115200
3060e3d5408SPeter Wemm     {"115200", B115200},
3070e3d5408SPeter Wemm #endif
3080e3d5408SPeter Wemm #ifdef B230400
3090e3d5408SPeter Wemm     {"230400", B230400},
3100e3d5408SPeter Wemm #endif
3110e3d5408SPeter Wemm #ifdef B460800
3120e3d5408SPeter Wemm     {"460800", B460800},
3130e3d5408SPeter Wemm #endif
3140e3d5408SPeter Wemm     {(char *) 0, 0}
3150e3d5408SPeter Wemm };
3160e3d5408SPeter Wemm 
3170e3d5408SPeter Wemm static int
3180e3d5408SPeter Wemm tbaudrate(char *rate)
3190e3d5408SPeter Wemm {
3200e3d5408SPeter Wemm     const SPEEDS *sp;
3210e3d5408SPeter Wemm     int found = FALSE;
3220e3d5408SPeter Wemm 
3230e3d5408SPeter Wemm     /* The baudrate number can be preceded by a 'B', which is ignored. */
3240e3d5408SPeter Wemm     if (*rate == 'B')
3250e3d5408SPeter Wemm 	++rate;
3260e3d5408SPeter Wemm 
3270e3d5408SPeter Wemm     for (sp = speeds; sp->string; ++sp) {
3280e3d5408SPeter Wemm 	if (!CaselessCmp(rate, sp->string)) {
3290e3d5408SPeter Wemm 	    found = TRUE;
3300e3d5408SPeter Wemm 	    break;
3310e3d5408SPeter Wemm 	}
3320e3d5408SPeter Wemm     }
3330e3d5408SPeter Wemm     if (!found)
3340e3d5408SPeter Wemm 	err("unknown baud rate %s", rate);
3350e3d5408SPeter Wemm     return (sp->speed);
3360e3d5408SPeter Wemm }
3370e3d5408SPeter Wemm 
3380e3d5408SPeter Wemm /*
3390e3d5408SPeter Wemm  * Syntax for -m:
3400e3d5408SPeter Wemm  * [port-type][test baudrate]:terminal-type
3410e3d5408SPeter Wemm  * The baud rate tests are: >, <, @, =, !
3420e3d5408SPeter Wemm  */
3430e3d5408SPeter Wemm static void
3440e3d5408SPeter Wemm add_mapping(const char *port, char *arg)
3450e3d5408SPeter Wemm {
3460e3d5408SPeter Wemm     MAP *mapp;
3470e3d5408SPeter Wemm     char *copy, *p;
3480e3d5408SPeter Wemm     const char *termp;
3490e3d5408SPeter Wemm     char *base = 0;
3500e3d5408SPeter Wemm 
3510e3d5408SPeter Wemm     copy = strdup(arg);
3520e3d5408SPeter Wemm     mapp = malloc(sizeof(MAP));
3530e3d5408SPeter Wemm     if (copy == 0 || mapp == 0)
3540e3d5408SPeter Wemm 	failed("malloc");
3550e3d5408SPeter Wemm     mapp->next = 0;
3560e3d5408SPeter Wemm     if (maplist == 0)
3570e3d5408SPeter Wemm 	cur = maplist = mapp;
3580e3d5408SPeter Wemm     else {
3590e3d5408SPeter Wemm 	cur->next = mapp;
3600e3d5408SPeter Wemm 	cur = mapp;
3610e3d5408SPeter Wemm     }
3620e3d5408SPeter Wemm 
3630e3d5408SPeter Wemm     mapp->porttype = arg;
3640e3d5408SPeter Wemm     mapp->conditional = 0;
3650e3d5408SPeter Wemm 
3660e3d5408SPeter Wemm     arg = strpbrk(arg, "><@=!:");
3670e3d5408SPeter Wemm 
3680e3d5408SPeter Wemm     if (arg == 0) {		/* [?]term */
3690e3d5408SPeter Wemm 	mapp->type = mapp->porttype;
3700e3d5408SPeter Wemm 	mapp->porttype = 0;
3710e3d5408SPeter Wemm 	goto done;
3720e3d5408SPeter Wemm     }
3730e3d5408SPeter Wemm 
3740e3d5408SPeter Wemm     if (arg == mapp->porttype)	/* [><@=! baud]:term */
3750e3d5408SPeter Wemm 	termp = mapp->porttype = 0;
3760e3d5408SPeter Wemm     else
3770e3d5408SPeter Wemm 	termp = base = arg;
3780e3d5408SPeter Wemm 
37915589c42SPeter Wemm     for (;; ++arg) {		/* Optional conditionals. */
3800e3d5408SPeter Wemm 	switch (*arg) {
3810e3d5408SPeter Wemm 	case '<':
3820e3d5408SPeter Wemm 	    if (mapp->conditional & GT)
3830e3d5408SPeter Wemm 		goto badmopt;
3840e3d5408SPeter Wemm 	    mapp->conditional |= LT;
3850e3d5408SPeter Wemm 	    break;
3860e3d5408SPeter Wemm 	case '>':
3870e3d5408SPeter Wemm 	    if (mapp->conditional & LT)
3880e3d5408SPeter Wemm 		goto badmopt;
3890e3d5408SPeter Wemm 	    mapp->conditional |= GT;
3900e3d5408SPeter Wemm 	    break;
3910e3d5408SPeter Wemm 	case '@':
3920e3d5408SPeter Wemm 	case '=':		/* Not documented. */
3930e3d5408SPeter Wemm 	    mapp->conditional |= EQ;
3940e3d5408SPeter Wemm 	    break;
3950e3d5408SPeter Wemm 	case '!':
3960e3d5408SPeter Wemm 	    mapp->conditional |= NOT;
3970e3d5408SPeter Wemm 	    break;
3980e3d5408SPeter Wemm 	default:
3990e3d5408SPeter Wemm 	    goto next;
4000e3d5408SPeter Wemm 	}
40115589c42SPeter Wemm     }
4020e3d5408SPeter Wemm 
40315589c42SPeter Wemm   next:
40415589c42SPeter Wemm     if (*arg == ':') {
4050e3d5408SPeter Wemm 	if (mapp->conditional)
4060e3d5408SPeter Wemm 	    goto badmopt;
4070e3d5408SPeter Wemm 	++arg;
4080e3d5408SPeter Wemm     } else {			/* Optional baudrate. */
4090e3d5408SPeter Wemm 	arg = strchr(p = arg, ':');
4100e3d5408SPeter Wemm 	if (arg == 0)
4110e3d5408SPeter Wemm 	    goto badmopt;
4120e3d5408SPeter Wemm 	*arg++ = '\0';
4130e3d5408SPeter Wemm 	mapp->speed = tbaudrate(p);
4140e3d5408SPeter Wemm     }
4150e3d5408SPeter Wemm 
4160e3d5408SPeter Wemm     if (arg == (char *) 0)	/* Non-optional type. */
4170e3d5408SPeter Wemm 	goto badmopt;
4180e3d5408SPeter Wemm 
4190e3d5408SPeter Wemm     mapp->type = arg;
4200e3d5408SPeter Wemm 
4210e3d5408SPeter Wemm     /* Terminate porttype, if specified. */
4220e3d5408SPeter Wemm     if (termp != 0)
4230e3d5408SPeter Wemm 	*base = '\0';
4240e3d5408SPeter Wemm 
4250e3d5408SPeter Wemm     /* If a NOT conditional, reverse the test. */
4260e3d5408SPeter Wemm     if (mapp->conditional & NOT)
4270e3d5408SPeter Wemm 	mapp->conditional = ~mapp->conditional & (EQ | GT | LT);
4280e3d5408SPeter Wemm 
4290e3d5408SPeter Wemm     /* If user specified a port with an option flag, set it. */
4300e3d5408SPeter Wemm   done:if (port) {
4310e3d5408SPeter Wemm 	if (mapp->porttype)
4320e3d5408SPeter Wemm 	  badmopt:err("illegal -m option format: %s", copy);
4330e3d5408SPeter Wemm 	mapp->porttype = port;
4340e3d5408SPeter Wemm     }
4350e3d5408SPeter Wemm #ifdef MAPDEBUG
4360e3d5408SPeter Wemm     (void) printf("port: %s\n", mapp->porttype ? mapp->porttype : "ANY");
4370e3d5408SPeter Wemm     (void) printf("type: %s\n", mapp->type);
4380e3d5408SPeter Wemm     (void) printf("conditional: ");
4390e3d5408SPeter Wemm     p = "";
4400e3d5408SPeter Wemm     if (mapp->conditional & GT) {
4410e3d5408SPeter Wemm 	(void) printf("GT");
4420e3d5408SPeter Wemm 	p = "/";
4430e3d5408SPeter Wemm     }
4440e3d5408SPeter Wemm     if (mapp->conditional & EQ) {
4450e3d5408SPeter Wemm 	(void) printf("%sEQ", p);
4460e3d5408SPeter Wemm 	p = "/";
4470e3d5408SPeter Wemm     }
4480e3d5408SPeter Wemm     if (mapp->conditional & LT)
4490e3d5408SPeter Wemm 	(void) printf("%sLT", p);
4500e3d5408SPeter Wemm     (void) printf("\nspeed: %d\n", mapp->speed);
4510e3d5408SPeter Wemm #endif
4520e3d5408SPeter Wemm }
4530e3d5408SPeter Wemm 
4540e3d5408SPeter Wemm /*
4550e3d5408SPeter Wemm  * Return the type of terminal to use for a port of type 'type', as specified
4560e3d5408SPeter Wemm  * by the first applicable mapping in 'map'.  If no mappings apply, return
4570e3d5408SPeter Wemm  * 'type'.
4580e3d5408SPeter Wemm  */
4590e3d5408SPeter Wemm static const char *
4600e3d5408SPeter Wemm mapped(const char *type)
4610e3d5408SPeter Wemm {
4620e3d5408SPeter Wemm     MAP *mapp;
4630e3d5408SPeter Wemm     int match;
4640e3d5408SPeter Wemm 
4650e3d5408SPeter Wemm     for (mapp = maplist; mapp; mapp = mapp->next)
4660e3d5408SPeter Wemm 	if (mapp->porttype == 0 || !strcmp(mapp->porttype, type)) {
4670e3d5408SPeter Wemm 	    switch (mapp->conditional) {
4680e3d5408SPeter Wemm 	    case 0:		/* No test specified. */
4690e3d5408SPeter Wemm 		match = TRUE;
4700e3d5408SPeter Wemm 		break;
4710e3d5408SPeter Wemm 	    case EQ:
4720e3d5408SPeter Wemm 		match = (ospeed == mapp->speed);
4730e3d5408SPeter Wemm 		break;
4740e3d5408SPeter Wemm 	    case GE:
4750e3d5408SPeter Wemm 		match = (ospeed >= mapp->speed);
4760e3d5408SPeter Wemm 		break;
4770e3d5408SPeter Wemm 	    case GT:
4780e3d5408SPeter Wemm 		match = (ospeed > mapp->speed);
4790e3d5408SPeter Wemm 		break;
4800e3d5408SPeter Wemm 	    case LE:
4810e3d5408SPeter Wemm 		match = (ospeed <= mapp->speed);
4820e3d5408SPeter Wemm 		break;
4830e3d5408SPeter Wemm 	    case LT:
4840e3d5408SPeter Wemm 		match = (ospeed < mapp->speed);
4850e3d5408SPeter Wemm 		break;
4860e3d5408SPeter Wemm 	    default:
4870e3d5408SPeter Wemm 		match = FALSE;
4880e3d5408SPeter Wemm 	    }
4890e3d5408SPeter Wemm 	    if (match)
4900e3d5408SPeter Wemm 		return (mapp->type);
4910e3d5408SPeter Wemm 	}
4920e3d5408SPeter Wemm     /* No match found; return given type. */
4930e3d5408SPeter Wemm     return (type);
4940e3d5408SPeter Wemm }
4950e3d5408SPeter Wemm 
4960e3d5408SPeter Wemm /**************************************************************************
4970e3d5408SPeter Wemm  *
4980e3d5408SPeter Wemm  * Entry fetching
4990e3d5408SPeter Wemm  *
5000e3d5408SPeter Wemm  **************************************************************************/
5010e3d5408SPeter Wemm 
5020e3d5408SPeter Wemm /*
5030e3d5408SPeter Wemm  * Figure out what kind of terminal we're dealing with, and then read in
5040e3d5408SPeter Wemm  * its termcap entry.
5050e3d5408SPeter Wemm  */
5060e3d5408SPeter Wemm static const char *
5070e3d5408SPeter Wemm get_termcap_entry(char *userarg)
5080e3d5408SPeter Wemm {
5097a69bbfbSPeter Wemm     int errret;
5100e3d5408SPeter Wemm     char *p;
5110e3d5408SPeter Wemm     const char *ttype;
5120e3d5408SPeter Wemm #if HAVE_GETTTYNAM
5130e3d5408SPeter Wemm     struct ttyent *t;
5140e3d5408SPeter Wemm #else
5150e3d5408SPeter Wemm     FILE *fp;
5160e3d5408SPeter Wemm #endif
5170e3d5408SPeter Wemm     char *ttypath;
5180e3d5408SPeter Wemm 
5190e3d5408SPeter Wemm     if (userarg) {
5200e3d5408SPeter Wemm 	ttype = userarg;
5210e3d5408SPeter Wemm 	goto found;
5220e3d5408SPeter Wemm     }
5230e3d5408SPeter Wemm 
5240e3d5408SPeter Wemm     /* Try the environment. */
5250e3d5408SPeter Wemm     if ((ttype = getenv("TERM")) != 0)
5260e3d5408SPeter Wemm 	goto map;
5270e3d5408SPeter Wemm 
5280e3d5408SPeter Wemm     if ((ttypath = ttyname(STDERR_FILENO)) != 0) {
52918259542SPeter Wemm 	p = _nc_basename(ttypath);
5300e3d5408SPeter Wemm #if HAVE_GETTTYNAM
5310e3d5408SPeter Wemm 	/*
5320e3d5408SPeter Wemm 	 * We have the 4.3BSD library call getttynam(3); that means
5330e3d5408SPeter Wemm 	 * there's an /etc/ttys to look up device-to-type mappings in.
5340e3d5408SPeter Wemm 	 * Try ttyname(3); check for dialup or other mapping.
5350e3d5408SPeter Wemm 	 */
5360e3d5408SPeter Wemm 	if ((t = getttynam(p))) {
5370e3d5408SPeter Wemm 	    ttype = t->ty_type;
5380e3d5408SPeter Wemm 	    goto map;
5390e3d5408SPeter Wemm 	}
5400e3d5408SPeter Wemm #else
5410e3d5408SPeter Wemm 	if ((fp = fopen("/etc/ttytype", "r")) != 0
5420e3d5408SPeter Wemm 	    || (fp = fopen("/etc/ttys", "r")) != 0) {
5430e3d5408SPeter Wemm 	    char buffer[BUFSIZ];
5440e3d5408SPeter Wemm 	    char *s, *t, *d;
5450e3d5408SPeter Wemm 
5460e3d5408SPeter Wemm 	    while (fgets(buffer, sizeof(buffer) - 1, fp) != 0) {
5470e3d5408SPeter Wemm 		for (s = buffer, t = d = 0; *s; s++) {
54839f2269fSPeter Wemm 		    if (isspace(UChar(*s)))
5490e3d5408SPeter Wemm 			*s = '\0';
5500e3d5408SPeter Wemm 		    else if (t == 0)
5510e3d5408SPeter Wemm 			t = s;
5520e3d5408SPeter Wemm 		    else if (d == 0 && s != buffer && s[-1] == '\0')
5530e3d5408SPeter Wemm 			d = s;
5540e3d5408SPeter Wemm 		}
5550e3d5408SPeter Wemm 		if (t != 0 && d != 0 && !strcmp(d, p)) {
5560e3d5408SPeter Wemm 		    ttype = strdup(t);
5570e3d5408SPeter Wemm 		    fclose(fp);
5580e3d5408SPeter Wemm 		    goto map;
5590e3d5408SPeter Wemm 		}
5600e3d5408SPeter Wemm 	    }
5610e3d5408SPeter Wemm 	    fclose(fp);
5620e3d5408SPeter Wemm 	}
5630e3d5408SPeter Wemm #endif /* HAVE_GETTTYNAM */
5640e3d5408SPeter Wemm     }
5650e3d5408SPeter Wemm 
5660e3d5408SPeter Wemm     /* If still undefined, use "unknown". */
5670e3d5408SPeter Wemm     ttype = "unknown";
5680e3d5408SPeter Wemm 
5690e3d5408SPeter Wemm   map:ttype = mapped(ttype);
5700e3d5408SPeter Wemm 
5710e3d5408SPeter Wemm     /*
5720e3d5408SPeter Wemm      * If not a path, remove TERMCAP from the environment so we get a
5730e3d5408SPeter Wemm      * real entry from /etc/termcap.  This prevents us from being fooled
5740e3d5408SPeter Wemm      * by out of date stuff in the environment.
5750e3d5408SPeter Wemm      */
5760e3d5408SPeter Wemm   found:if ((p = getenv("TERMCAP")) != 0 && *p != '/') {
5770e3d5408SPeter Wemm 	/* 'unsetenv("TERMCAP")' is not portable.
5780e3d5408SPeter Wemm 	 * The 'environ' array is better.
5790e3d5408SPeter Wemm 	 */
5800e3d5408SPeter Wemm 	int n;
5810e3d5408SPeter Wemm 	for (n = 0; environ[n] != 0; n++) {
5820e3d5408SPeter Wemm 	    if (!strncmp("TERMCAP=", environ[n], 8)) {
5830e3d5408SPeter Wemm 		while ((environ[n] = environ[n + 1]) != 0) {
5840e3d5408SPeter Wemm 		    n++;
5850e3d5408SPeter Wemm 		}
5860e3d5408SPeter Wemm 		break;
5870e3d5408SPeter Wemm 	    }
5880e3d5408SPeter Wemm 	}
5890e3d5408SPeter Wemm     }
5900e3d5408SPeter Wemm 
5910e3d5408SPeter Wemm     /*
5920e3d5408SPeter Wemm      * ttype now contains a pointer to the type of the terminal.
5930e3d5408SPeter Wemm      * If the first character is '?', ask the user.
5940e3d5408SPeter Wemm      */
5950e3d5408SPeter Wemm     if (ttype[0] == '?') {
5960e3d5408SPeter Wemm 	if (ttype[1] != '\0')
5970e3d5408SPeter Wemm 	    ttype = askuser(ttype + 1);
5980e3d5408SPeter Wemm 	else
5990e3d5408SPeter Wemm 	    ttype = askuser(0);
6000e3d5408SPeter Wemm     }
6010e3d5408SPeter Wemm     /* Find the terminfo entry.  If it doesn't exist, ask the user. */
6027a69bbfbSPeter Wemm     while (setupterm((NCURSES_CONST char *) ttype, STDOUT_FILENO, &errret)
6037a69bbfbSPeter Wemm 	   != OK) {
6040e3d5408SPeter Wemm 	if (errret == 0) {
6050e3d5408SPeter Wemm 	    (void) fprintf(stderr, "tset: unknown terminal type %s\n",
6060e3d5408SPeter Wemm 			   ttype);
6070e3d5408SPeter Wemm 	    ttype = 0;
60815589c42SPeter Wemm 	} else {
60915589c42SPeter Wemm 	    (void) fprintf(stderr,
61015589c42SPeter Wemm 			   "tset: can't initialize terminal type %s (error %d)\n",
61115589c42SPeter Wemm 			   ttype, errret);
6120e3d5408SPeter Wemm 	    ttype = 0;
6130e3d5408SPeter Wemm 	}
6140e3d5408SPeter Wemm 	ttype = askuser(ttype);
6150e3d5408SPeter Wemm     }
6160e3d5408SPeter Wemm #if BROKEN_LINKER
6170e3d5408SPeter Wemm     tgetflag("am");		/* force lib_termcap.o to be linked for 'ospeed' */
6180e3d5408SPeter Wemm #endif
6190e3d5408SPeter Wemm     return (ttype);
6200e3d5408SPeter Wemm }
6210e3d5408SPeter Wemm 
6220e3d5408SPeter Wemm /**************************************************************************
6230e3d5408SPeter Wemm  *
6240e3d5408SPeter Wemm  * Mode-setting logic
6250e3d5408SPeter Wemm  *
6260e3d5408SPeter Wemm  **************************************************************************/
6270e3d5408SPeter Wemm 
6280e3d5408SPeter Wemm /* some BSD systems have these built in, some systems are missing
6290e3d5408SPeter Wemm  * one or more definitions. The safest solution is to override.
6300e3d5408SPeter Wemm  */
6310e3d5408SPeter Wemm #undef CEOF
6320e3d5408SPeter Wemm #undef CERASE
6330e3d5408SPeter Wemm #undef CINTR
6340e3d5408SPeter Wemm #undef CKILL
6350e3d5408SPeter Wemm #undef CLNEXT
6360e3d5408SPeter Wemm #undef CRPRNT
6370e3d5408SPeter Wemm #undef CQUIT
6380e3d5408SPeter Wemm #undef CSTART
6390e3d5408SPeter Wemm #undef CSTOP
6400e3d5408SPeter Wemm #undef CSUSP
6410e3d5408SPeter Wemm 
6420e3d5408SPeter Wemm /* control-character defaults */
6430e3d5408SPeter Wemm #define CEOF	CTRL('D')
6440e3d5408SPeter Wemm #define CERASE	CTRL('H')
6450e3d5408SPeter Wemm #define CINTR	127		/* ^? */
6460e3d5408SPeter Wemm #define CKILL	CTRL('U')
6470e3d5408SPeter Wemm #define CLNEXT  CTRL('v')
6480e3d5408SPeter Wemm #define CRPRNT  CTRL('r')
6490e3d5408SPeter Wemm #define CQUIT	CTRL('\\')
6500e3d5408SPeter Wemm #define CSTART	CTRL('Q')
6510e3d5408SPeter Wemm #define CSTOP	CTRL('S')
6520e3d5408SPeter Wemm #define CSUSP	CTRL('Z')
6530e3d5408SPeter Wemm 
6540e3d5408SPeter Wemm #define	CHK(val, dft)	((int)val <= 0 ? dft : val)
6550e3d5408SPeter Wemm 
6560e3d5408SPeter Wemm static bool set_tabs(void);
6570e3d5408SPeter Wemm 
6580e3d5408SPeter Wemm /*
6590e3d5408SPeter Wemm  * Reset the terminal mode bits to a sensible state.  Very useful after
6600e3d5408SPeter Wemm  * a child program dies in raw mode.
6610e3d5408SPeter Wemm  */
6620e3d5408SPeter Wemm static void
6630e3d5408SPeter Wemm reset_mode(void)
6640e3d5408SPeter Wemm {
6650e3d5408SPeter Wemm #ifdef TERMIOS
6660e3d5408SPeter Wemm     tcgetattr(STDERR_FILENO, &mode);
6670e3d5408SPeter Wemm #else
6680e3d5408SPeter Wemm     stty(STDERR_FILENO, &mode);
6690e3d5408SPeter Wemm #endif
6700e3d5408SPeter Wemm 
6710e3d5408SPeter Wemm #ifdef TERMIOS
6720e3d5408SPeter Wemm #if defined(VDISCARD) && defined(CDISCARD)
6730e3d5408SPeter Wemm     mode.c_cc[VDISCARD] = CHK(mode.c_cc[VDISCARD], CDISCARD);
6740e3d5408SPeter Wemm #endif
6750e3d5408SPeter Wemm     mode.c_cc[VEOF] = CHK(mode.c_cc[VEOF], CEOF);
6760e3d5408SPeter Wemm     mode.c_cc[VERASE] = CHK(mode.c_cc[VERASE], CERASE);
6770e3d5408SPeter Wemm #if defined(VFLUSH) && defined(CFLUSH)
6780e3d5408SPeter Wemm     mode.c_cc[VFLUSH] = CHK(mode.c_cc[VFLUSH], CFLUSH);
6790e3d5408SPeter Wemm #endif
6800e3d5408SPeter Wemm     mode.c_cc[VINTR] = CHK(mode.c_cc[VINTR], CINTR);
6810e3d5408SPeter Wemm     mode.c_cc[VKILL] = CHK(mode.c_cc[VKILL], CKILL);
6820e3d5408SPeter Wemm #if defined(VLNEXT) && defined(CLNEXT)
6830e3d5408SPeter Wemm     mode.c_cc[VLNEXT] = CHK(mode.c_cc[VLNEXT], CLNEXT);
6840e3d5408SPeter Wemm #endif
6850e3d5408SPeter Wemm     mode.c_cc[VQUIT] = CHK(mode.c_cc[VQUIT], CQUIT);
6860e3d5408SPeter Wemm #if defined(VREPRINT) && defined(CRPRNT)
6870e3d5408SPeter Wemm     mode.c_cc[VREPRINT] = CHK(mode.c_cc[VREPRINT], CRPRNT);
6880e3d5408SPeter Wemm #endif
6890e3d5408SPeter Wemm #if defined(VSTART) && defined(CSTART)
6900e3d5408SPeter Wemm     mode.c_cc[VSTART] = CHK(mode.c_cc[VSTART], CSTART);
6910e3d5408SPeter Wemm #endif
6920e3d5408SPeter Wemm #if defined(VSTOP) && defined(CSTOP)
6930e3d5408SPeter Wemm     mode.c_cc[VSTOP] = CHK(mode.c_cc[VSTOP], CSTOP);
6940e3d5408SPeter Wemm #endif
6950e3d5408SPeter Wemm #if defined(VSUSP) && defined(CSUSP)
6960e3d5408SPeter Wemm     mode.c_cc[VSUSP] = CHK(mode.c_cc[VSUSP], CSUSP);
6970e3d5408SPeter Wemm #endif
6980e3d5408SPeter Wemm #if defined(VWERASE) && defined(CWERASE)
6990e3d5408SPeter Wemm     mode.c_cc[VWERASE] = CHK(mode.c_cc[VWERASE], CWERASE);
7000e3d5408SPeter Wemm #endif
7010e3d5408SPeter Wemm 
7020e3d5408SPeter Wemm     mode.c_iflag &= ~(IGNBRK | PARMRK | INPCK | ISTRIP | INLCR | IGNCR
7030e3d5408SPeter Wemm #ifdef IUCLC
7040e3d5408SPeter Wemm 		      | IUCLC
7050e3d5408SPeter Wemm #endif
7060e3d5408SPeter Wemm #ifdef IXANY
7070e3d5408SPeter Wemm 		      | IXANY
7080e3d5408SPeter Wemm #endif
7090e3d5408SPeter Wemm 		      | IXOFF);
7100e3d5408SPeter Wemm 
7110e3d5408SPeter Wemm     mode.c_iflag |= (BRKINT | IGNPAR | ICRNL | IXON
7120e3d5408SPeter Wemm #ifdef IMAXBEL
7130e3d5408SPeter Wemm 		     | IMAXBEL
7140e3d5408SPeter Wemm #endif
7150e3d5408SPeter Wemm 	);
7160e3d5408SPeter Wemm 
7170e3d5408SPeter Wemm     mode.c_oflag &= ~(0
7180e3d5408SPeter Wemm #ifdef OLCUC
7190e3d5408SPeter Wemm 		      | OLCUC
7200e3d5408SPeter Wemm #endif
7210e3d5408SPeter Wemm #ifdef OCRNL
7220e3d5408SPeter Wemm 		      | OCRNL
7230e3d5408SPeter Wemm #endif
7240e3d5408SPeter Wemm #ifdef ONOCR
7250e3d5408SPeter Wemm 		      | ONOCR
7260e3d5408SPeter Wemm #endif
7270e3d5408SPeter Wemm #ifdef ONLRET
7280e3d5408SPeter Wemm 		      | ONLRET
7290e3d5408SPeter Wemm #endif
7300e3d5408SPeter Wemm #ifdef OFILL
7310e3d5408SPeter Wemm 		      | OFILL
7320e3d5408SPeter Wemm #endif
7330e3d5408SPeter Wemm #ifdef OFDEL
7340e3d5408SPeter Wemm 		      | OFDEL
7350e3d5408SPeter Wemm #endif
7360e3d5408SPeter Wemm #ifdef NLDLY
7370e3d5408SPeter Wemm 		      | NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY
7380e3d5408SPeter Wemm #endif
7390e3d5408SPeter Wemm 	);
7400e3d5408SPeter Wemm 
7410e3d5408SPeter Wemm     mode.c_oflag |= (OPOST
7420e3d5408SPeter Wemm #ifdef ONLCR
7430e3d5408SPeter Wemm 		     | ONLCR
7440e3d5408SPeter Wemm #endif
7450e3d5408SPeter Wemm 	);
7460e3d5408SPeter Wemm 
7470e3d5408SPeter Wemm     mode.c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD | CLOCAL);
7480e3d5408SPeter Wemm     mode.c_cflag |= (CS8 | CREAD);
7490e3d5408SPeter Wemm     mode.c_lflag &= ~(ECHONL | NOFLSH
7500e3d5408SPeter Wemm #ifdef TOSTOP
7510e3d5408SPeter Wemm 		      | TOSTOP
7520e3d5408SPeter Wemm #endif
7530e3d5408SPeter Wemm #ifdef ECHOPTR
7540e3d5408SPeter Wemm 		      | ECHOPRT
7550e3d5408SPeter Wemm #endif
7560e3d5408SPeter Wemm #ifdef XCASE
7570e3d5408SPeter Wemm 		      | XCASE
7580e3d5408SPeter Wemm #endif
7590e3d5408SPeter Wemm 	);
7600e3d5408SPeter Wemm 
7610e3d5408SPeter Wemm     mode.c_lflag |= (ISIG | ICANON | ECHO | ECHOE | ECHOK
7620e3d5408SPeter Wemm #ifdef ECHOCTL
7630e3d5408SPeter Wemm 		     | ECHOCTL
7640e3d5408SPeter Wemm #endif
7650e3d5408SPeter Wemm #ifdef ECHOKE
7660e3d5408SPeter Wemm 		     | ECHOKE
7670e3d5408SPeter Wemm #endif
7680e3d5408SPeter Wemm 	);
7690e3d5408SPeter Wemm #endif
7700e3d5408SPeter Wemm 
77139f2269fSPeter Wemm     SET_TTY(STDERR_FILENO, &mode);
7720e3d5408SPeter Wemm }
7730e3d5408SPeter Wemm 
7740e3d5408SPeter Wemm /*
7750e3d5408SPeter Wemm  * Returns a "good" value for the erase character.  This is loosely based on
7760e3d5408SPeter Wemm  * the BSD4.4 logic.
7770e3d5408SPeter Wemm  */
77818259542SPeter Wemm #ifdef TERMIOS
7790e3d5408SPeter Wemm static int
7800e3d5408SPeter Wemm default_erase(void)
7810e3d5408SPeter Wemm {
7820e3d5408SPeter Wemm     int result;
7830e3d5408SPeter Wemm 
7840e3d5408SPeter Wemm     if (over_strike
7850e3d5408SPeter Wemm 	&& key_backspace != 0
7860e3d5408SPeter Wemm 	&& strlen(key_backspace) == 1)
7870e3d5408SPeter Wemm 	result = key_backspace[0];
7880e3d5408SPeter Wemm     else
7890e3d5408SPeter Wemm 	result = CERASE;
7900e3d5408SPeter Wemm 
7910e3d5408SPeter Wemm     return result;
7920e3d5408SPeter Wemm }
79318259542SPeter Wemm #endif
7940e3d5408SPeter Wemm 
7950e3d5408SPeter Wemm /*
7960e3d5408SPeter Wemm  * Update the values of the erase, interrupt, and kill characters in 'mode'.
7970e3d5408SPeter Wemm  *
7980e3d5408SPeter Wemm  * SVr4 tset (e.g., Solaris 2.5) only modifies the intr, quit or erase
7990e3d5408SPeter Wemm  * characters if they're unset, or if we specify them as options.  This differs
8000e3d5408SPeter Wemm  * from BSD 4.4 tset, which always sets erase.
8010e3d5408SPeter Wemm  */
8020e3d5408SPeter Wemm static void
8030e3d5408SPeter Wemm set_control_chars(void)
8040e3d5408SPeter Wemm {
8050e3d5408SPeter Wemm #ifdef TERMIOS
8060e3d5408SPeter Wemm     if (mode.c_cc[VERASE] == 0 || terasechar >= 0)
8070e3d5408SPeter Wemm 	mode.c_cc[VERASE] = terasechar >= 0 ? terasechar : default_erase();
8080e3d5408SPeter Wemm 
8090e3d5408SPeter Wemm     if (mode.c_cc[VINTR] == 0 || intrchar >= 0)
8100e3d5408SPeter Wemm 	mode.c_cc[VINTR] = intrchar >= 0 ? intrchar : CINTR;
8110e3d5408SPeter Wemm 
8120e3d5408SPeter Wemm     if (mode.c_cc[VKILL] == 0 || tkillchar >= 0)
8130e3d5408SPeter Wemm 	mode.c_cc[VKILL] = tkillchar >= 0 ? tkillchar : CKILL;
8140e3d5408SPeter Wemm #endif
8150e3d5408SPeter Wemm }
8160e3d5408SPeter Wemm 
8170e3d5408SPeter Wemm /*
8180e3d5408SPeter Wemm  * Set up various conversions in 'mode', including parity, tabs, returns,
8190e3d5408SPeter Wemm  * echo, and case, according to the termcap entry.  If the program we're
8200e3d5408SPeter Wemm  * running was named with a leading upper-case character, map external
8210e3d5408SPeter Wemm  * uppercase to internal lowercase.
8220e3d5408SPeter Wemm  */
8230e3d5408SPeter Wemm static void
8240e3d5408SPeter Wemm set_conversions(void)
8250e3d5408SPeter Wemm {
8260e3d5408SPeter Wemm #ifdef __OBSOLETE__
8270e3d5408SPeter Wemm     /*
8280e3d5408SPeter Wemm      * Conversion logic for some *really* ancient terminal glitches,
8290e3d5408SPeter Wemm      * not supported in terminfo.  Left here for succeeding generations
8300e3d5408SPeter Wemm      * to marvel at.
8310e3d5408SPeter Wemm      */
8320e3d5408SPeter Wemm     if (tgetflag("UC")) {
8330e3d5408SPeter Wemm #ifdef IUCLC
8340e3d5408SPeter Wemm 	mode.c_iflag |= IUCLC;
8350e3d5408SPeter Wemm 	mode.c_oflag |= OLCUC;
8360e3d5408SPeter Wemm #endif
8370e3d5408SPeter Wemm     } else if (tgetflag("LC")) {
8380e3d5408SPeter Wemm #ifdef IUCLC
8390e3d5408SPeter Wemm 	mode.c_iflag &= ~IUCLC;
8400e3d5408SPeter Wemm 	mode.c_oflag &= ~OLCUC;
8410e3d5408SPeter Wemm #endif
8420e3d5408SPeter Wemm     }
8430e3d5408SPeter Wemm     mode.c_iflag &= ~(PARMRK | INPCK);
8440e3d5408SPeter Wemm     mode.c_lflag |= ICANON;
8450e3d5408SPeter Wemm     if (tgetflag("EP")) {
8460e3d5408SPeter Wemm 	mode.c_cflag |= PARENB;
8470e3d5408SPeter Wemm 	mode.c_cflag &= ~PARODD;
8480e3d5408SPeter Wemm     }
8490e3d5408SPeter Wemm     if (tgetflag("OP")) {
8500e3d5408SPeter Wemm 	mode.c_cflag |= PARENB;
8510e3d5408SPeter Wemm 	mode.c_cflag |= PARODD;
8520e3d5408SPeter Wemm     }
8530e3d5408SPeter Wemm #endif /* __OBSOLETE__ */
8540e3d5408SPeter Wemm 
8550e3d5408SPeter Wemm #ifdef TERMIOS
8560e3d5408SPeter Wemm #ifdef ONLCR
8570e3d5408SPeter Wemm     mode.c_oflag |= ONLCR;
8580e3d5408SPeter Wemm #endif
8590e3d5408SPeter Wemm     mode.c_iflag |= ICRNL;
8600e3d5408SPeter Wemm     mode.c_lflag |= ECHO;
8610e3d5408SPeter Wemm #ifdef OXTABS
8620e3d5408SPeter Wemm     mode.c_oflag |= OXTABS;
8630e3d5408SPeter Wemm #endif /* OXTABS */
8640e3d5408SPeter Wemm 
8650e3d5408SPeter Wemm     /* test used to be tgetflag("NL") */
8660e3d5408SPeter Wemm     if (newline != (char *) 0 && newline[0] == '\n' && !newline[1]) {
8670e3d5408SPeter Wemm 	/* Newline, not linefeed. */
8680e3d5408SPeter Wemm #ifdef ONLCR
8690e3d5408SPeter Wemm 	mode.c_oflag &= ~ONLCR;
8700e3d5408SPeter Wemm #endif
8710e3d5408SPeter Wemm 	mode.c_iflag &= ~ICRNL;
8720e3d5408SPeter Wemm     }
8730e3d5408SPeter Wemm #ifdef __OBSOLETE__
8740e3d5408SPeter Wemm     if (tgetflag("HD"))		/* Half duplex. */
8750e3d5408SPeter Wemm 	mode.c_lflag &= ~ECHO;
8760e3d5408SPeter Wemm #endif /* __OBSOLETE__ */
8770e3d5408SPeter Wemm #ifdef OXTABS
8780e3d5408SPeter Wemm     /* test used to be tgetflag("pt") */
8790e3d5408SPeter Wemm     if (has_hardware_tabs)	/* Print tabs. */
8800e3d5408SPeter Wemm 	mode.c_oflag &= ~OXTABS;
8810e3d5408SPeter Wemm #endif /* OXTABS */
8820e3d5408SPeter Wemm     mode.c_lflag |= (ECHOE | ECHOK);
8830e3d5408SPeter Wemm #endif
8840e3d5408SPeter Wemm }
8850e3d5408SPeter Wemm 
8860e3d5408SPeter Wemm /* Output startup string. */
8870e3d5408SPeter Wemm static void
8880e3d5408SPeter Wemm set_init(void)
8890e3d5408SPeter Wemm {
8900e3d5408SPeter Wemm     char *p;
8910e3d5408SPeter Wemm     bool settle;
8920e3d5408SPeter Wemm 
8930e3d5408SPeter Wemm #ifdef __OBSOLETE__
8940e3d5408SPeter Wemm     if (pad_char != (char *) 0)	/* Get/set pad character. */
8950e3d5408SPeter Wemm 	PC = pad_char[0];
8960e3d5408SPeter Wemm #endif /* OBSOLETE */
8970e3d5408SPeter Wemm 
8980e3d5408SPeter Wemm #ifdef TAB3
8990e3d5408SPeter Wemm     if (oldmode.c_oflag & (TAB3 | ONLCR | OCRNL | ONLRET)) {
9000e3d5408SPeter Wemm 	oldmode.c_oflag &= (TAB3 | ONLCR | OCRNL | ONLRET);
90139f2269fSPeter Wemm 	SET_TTY(STDERR_FILENO, &oldmode);
9020e3d5408SPeter Wemm     }
9030e3d5408SPeter Wemm #endif
9040e3d5408SPeter Wemm     settle = set_tabs();
9050e3d5408SPeter Wemm 
9060e3d5408SPeter Wemm     if (isreset) {
9070e3d5408SPeter Wemm 	if ((p = reset_1string) != 0) {
9080e3d5408SPeter Wemm 	    tputs(p, 0, outc);
9090e3d5408SPeter Wemm 	    settle = TRUE;
9100e3d5408SPeter Wemm 	}
9110e3d5408SPeter Wemm 	if ((p = reset_2string) != 0) {
9120e3d5408SPeter Wemm 	    tputs(p, 0, outc);
9130e3d5408SPeter Wemm 	    settle = TRUE;
9140e3d5408SPeter Wemm 	}
9150e3d5408SPeter Wemm 	/* What about rf, rs3, as per terminfo man page? */
9160e3d5408SPeter Wemm 	/* also might be nice to send rmacs, rmul, rmm */
9170e3d5408SPeter Wemm 	if ((p = reset_file) != 0
9180e3d5408SPeter Wemm 	    || (p = init_file) != 0) {
9190e3d5408SPeter Wemm 	    cat(p);
9200e3d5408SPeter Wemm 	    settle = TRUE;
9210e3d5408SPeter Wemm 	}
9220e3d5408SPeter Wemm     }
9230e3d5408SPeter Wemm 
9240e3d5408SPeter Wemm     if (settle) {
9250e3d5408SPeter Wemm 	(void) putc('\r', stderr);
9260e3d5408SPeter Wemm 	(void) fflush(stderr);
9270e3d5408SPeter Wemm 	(void) napms(1000);	/* Settle the terminal. */
9280e3d5408SPeter Wemm     }
9290e3d5408SPeter Wemm }
9300e3d5408SPeter Wemm 
9310e3d5408SPeter Wemm /*
9320e3d5408SPeter Wemm  * Set the hardware tabs on the terminal, using the ct (clear all tabs),
9330e3d5408SPeter Wemm  * st (set one tab) and ch (horizontal cursor addressing) capabilities.
9340e3d5408SPeter Wemm  * This is done before if and is, so they can patch in case we blow this.
9350e3d5408SPeter Wemm  * Return TRUE if we set any tab stops, FALSE if not.
9360e3d5408SPeter Wemm  */
9370e3d5408SPeter Wemm static bool
9380e3d5408SPeter Wemm set_tabs()
9390e3d5408SPeter Wemm {
9400e3d5408SPeter Wemm     if (set_tab && clear_all_tabs) {
9410e3d5408SPeter Wemm 	int c;
9420e3d5408SPeter Wemm 
9430e3d5408SPeter Wemm 	(void) putc('\r', stderr);	/* Force to left margin. */
9440e3d5408SPeter Wemm 	tputs(clear_all_tabs, 0, outc);
9450e3d5408SPeter Wemm 
9460e3d5408SPeter Wemm 	for (c = 8; c < tcolumns; c += 8) {
9470e3d5408SPeter Wemm 	    /* Get to the right column.  In BSD tset, this
9480e3d5408SPeter Wemm 	     * used to try a bunch of half-clever things
9490e3d5408SPeter Wemm 	     * with cup and hpa, for an average saving of
9500e3d5408SPeter Wemm 	     * somewhat less than two character times per
9510e3d5408SPeter Wemm 	     * tab stop, less that .01 sec at 2400cps. We
9520e3d5408SPeter Wemm 	     * lost all this cruft because it seemed to be
9530e3d5408SPeter Wemm 	     * introducing some odd bugs.
9540e3d5408SPeter Wemm 	     * ----------12345678----------- */
9550e3d5408SPeter Wemm 	    (void) fputs("        ", stderr);
9560e3d5408SPeter Wemm 	    tputs(set_tab, 0, outc);
9570e3d5408SPeter Wemm 	}
9580e3d5408SPeter Wemm 	putc('\r', stderr);
9590e3d5408SPeter Wemm 	return (TRUE);
9600e3d5408SPeter Wemm     }
9610e3d5408SPeter Wemm     return (FALSE);
9620e3d5408SPeter Wemm }
9630e3d5408SPeter Wemm 
9640e3d5408SPeter Wemm /**************************************************************************
9650e3d5408SPeter Wemm  *
9660e3d5408SPeter Wemm  * Main sequence
9670e3d5408SPeter Wemm  *
9680e3d5408SPeter Wemm  **************************************************************************/
9690e3d5408SPeter Wemm 
9700e3d5408SPeter Wemm /*
9710e3d5408SPeter Wemm  * Tell the user if a control key has been changed from the default value.
9720e3d5408SPeter Wemm  */
97318259542SPeter Wemm #ifdef TERMIOS
9740e3d5408SPeter Wemm static void
9750e3d5408SPeter Wemm report(const char *name, int which, unsigned def)
9760e3d5408SPeter Wemm {
9770e3d5408SPeter Wemm     unsigned older, newer;
9780e3d5408SPeter Wemm     char *p;
9790e3d5408SPeter Wemm 
9800e3d5408SPeter Wemm     newer = mode.c_cc[which];
9810e3d5408SPeter Wemm     older = oldmode.c_cc[which];
9820e3d5408SPeter Wemm 
9830e3d5408SPeter Wemm     if (older == newer && older == def)
9840e3d5408SPeter Wemm 	return;
9850e3d5408SPeter Wemm 
9860e3d5408SPeter Wemm     (void) fprintf(stderr, "%s %s ", name, older == newer ? "is" : "set to");
9870e3d5408SPeter Wemm 
9880e3d5408SPeter Wemm     /*
9890e3d5408SPeter Wemm      * Check 'delete' before 'backspace', since the key_backspace value
9900e3d5408SPeter Wemm      * is ambiguous.
9910e3d5408SPeter Wemm      */
9920e3d5408SPeter Wemm     if (newer == 0177)
9930e3d5408SPeter Wemm 	(void) fprintf(stderr, "delete.\n");
9940e3d5408SPeter Wemm     else if ((p = key_backspace) != 0
9950e3d5408SPeter Wemm 	     && newer == (unsigned char) p[0]
9960e3d5408SPeter Wemm 	     && p[1] == '\0')
9970e3d5408SPeter Wemm 	(void) fprintf(stderr, "backspace.\n");
9980e3d5408SPeter Wemm     else if (newer < 040) {
9990e3d5408SPeter Wemm 	newer ^= 0100;
10000e3d5408SPeter Wemm 	(void) fprintf(stderr, "control-%c (^%c).\n", newer, newer);
10010e3d5408SPeter Wemm     } else
10020e3d5408SPeter Wemm 	(void) fprintf(stderr, "%c.\n", newer);
10030e3d5408SPeter Wemm }
100418259542SPeter Wemm #endif
10050e3d5408SPeter Wemm 
10060e3d5408SPeter Wemm /*
10070e3d5408SPeter Wemm  * Convert the obsolete argument forms into something that getopt can handle.
10080e3d5408SPeter Wemm  * This means that -e, -i and -k get default arguments supplied for them.
10090e3d5408SPeter Wemm  */
10100e3d5408SPeter Wemm static void
10110e3d5408SPeter Wemm obsolete(char **argv)
10120e3d5408SPeter Wemm {
10130e3d5408SPeter Wemm     for (; *argv; ++argv) {
10140e3d5408SPeter Wemm 	char *parm = argv[0];
10150e3d5408SPeter Wemm 
101615589c42SPeter Wemm 	if (parm[0] == '-' && parm[1] == '\0') {
10170e3d5408SPeter Wemm 	    argv[0] = strdup("-q");
10180e3d5408SPeter Wemm 	    continue;
10190e3d5408SPeter Wemm 	}
10200e3d5408SPeter Wemm 
10210e3d5408SPeter Wemm 	if ((parm[0] != '-')
10220e3d5408SPeter Wemm 	    || (argv[1] && argv[1][0] != '-')
10230e3d5408SPeter Wemm 	    || (parm[1] != 'e' && parm[1] != 'i' && parm[1] != 'k')
10240e3d5408SPeter Wemm 	    || (parm[2] != '\0'))
10250e3d5408SPeter Wemm 	    continue;
10260e3d5408SPeter Wemm 	switch (argv[0][1]) {
10270e3d5408SPeter Wemm 	case 'e':
10280e3d5408SPeter Wemm 	    argv[0] = strdup("-e^H");
10290e3d5408SPeter Wemm 	    break;
10300e3d5408SPeter Wemm 	case 'i':
10310e3d5408SPeter Wemm 	    argv[0] = strdup("-i^C");
10320e3d5408SPeter Wemm 	    break;
10330e3d5408SPeter Wemm 	case 'k':
10340e3d5408SPeter Wemm 	    argv[0] = strdup("-k^U");
10350e3d5408SPeter Wemm 	    break;
10360e3d5408SPeter Wemm 	}
10370e3d5408SPeter Wemm     }
10380e3d5408SPeter Wemm }
10390e3d5408SPeter Wemm 
10400e3d5408SPeter Wemm static void
10410e3d5408SPeter Wemm usage(const char *pname)
10420e3d5408SPeter Wemm {
10430e3d5408SPeter Wemm     (void) fprintf(stderr,
104439f2269fSPeter Wemm 		   "usage: %s [-IQVrs] [-] [-e ch] [-i ch] [-k ch] [-m mapping] [terminal]", pname);
104539f2269fSPeter Wemm     exit_error();
104639f2269fSPeter Wemm     /* NOTREACHED */
10470e3d5408SPeter Wemm }
10480e3d5408SPeter Wemm 
104915589c42SPeter Wemm static char
105015589c42SPeter Wemm arg_to_char(void)
10510e3d5408SPeter Wemm {
10520e3d5408SPeter Wemm     return (optarg[0] == '^' && optarg[1] != '\0')
10530e3d5408SPeter Wemm 	? ((optarg[1] == '?') ? '\177' : CTRL(optarg[1]))
10540e3d5408SPeter Wemm 	: optarg[0];
10550e3d5408SPeter Wemm }
10560e3d5408SPeter Wemm 
10570e3d5408SPeter Wemm int
10580e3d5408SPeter Wemm main(int argc, char **argv)
10590e3d5408SPeter Wemm {
10600e3d5408SPeter Wemm #if defined(TIOCGWINSZ) && defined(TIOCSWINSZ)
10610e3d5408SPeter Wemm     struct winsize win;
10620e3d5408SPeter Wemm #endif
10630e3d5408SPeter Wemm     int ch, noinit, noset, quiet, Sflag, sflag, showterm;
10640e3d5408SPeter Wemm     const char *p;
10650e3d5408SPeter Wemm     const char *ttype;
10660e3d5408SPeter Wemm 
106718259542SPeter Wemm     if (GET_TTY(STDERR_FILENO, &mode) < 0)
10680e3d5408SPeter Wemm 	failed("standard error");
106939f2269fSPeter Wemm     can_restore = TRUE;
107039f2269fSPeter Wemm     original = oldmode = mode;
107118259542SPeter Wemm #ifdef TERMIOS
10720e3d5408SPeter Wemm     ospeed = cfgetospeed(&mode);
10730e3d5408SPeter Wemm #else
10740e3d5408SPeter Wemm     ospeed = mode.sg_ospeed;
10750e3d5408SPeter Wemm #endif
10760e3d5408SPeter Wemm 
107739f2269fSPeter Wemm     p = _nc_rootname(*argv);
107818259542SPeter Wemm     if (!strcmp(p, PROG_RESET)) {
107918259542SPeter Wemm 	isreset = TRUE;
10800e3d5408SPeter Wemm 	reset_mode();
10810e3d5408SPeter Wemm     }
10820e3d5408SPeter Wemm 
10830e3d5408SPeter Wemm     obsolete(argv);
10840e3d5408SPeter Wemm     noinit = noset = quiet = Sflag = sflag = showterm = 0;
108518259542SPeter Wemm     while ((ch = getopt(argc, argv, "a:d:e:Ii:k:m:np:qQSrsV")) != EOF) {
10860e3d5408SPeter Wemm 	switch (ch) {
10870e3d5408SPeter Wemm 	case 'q':		/* display term only */
10880e3d5408SPeter Wemm 	    noset = 1;
10890e3d5408SPeter Wemm 	    break;
10900e3d5408SPeter Wemm 	case 'a':		/* OBSOLETE: map identifier to type */
10910e3d5408SPeter Wemm 	    add_mapping("arpanet", optarg);
10920e3d5408SPeter Wemm 	    break;
10930e3d5408SPeter Wemm 	case 'd':		/* OBSOLETE: map identifier to type */
10940e3d5408SPeter Wemm 	    add_mapping("dialup", optarg);
10950e3d5408SPeter Wemm 	    break;
10960e3d5408SPeter Wemm 	case 'e':		/* erase character */
10970e3d5408SPeter Wemm 	    terasechar = arg_to_char();
10980e3d5408SPeter Wemm 	    break;
10990e3d5408SPeter Wemm 	case 'I':		/* no initialization strings */
11000e3d5408SPeter Wemm 	    noinit = 1;
11010e3d5408SPeter Wemm 	    break;
11020e3d5408SPeter Wemm 	case 'i':		/* interrupt character */
11030e3d5408SPeter Wemm 	    intrchar = arg_to_char();
11040e3d5408SPeter Wemm 	    break;
11050e3d5408SPeter Wemm 	case 'k':		/* kill character */
11060e3d5408SPeter Wemm 	    tkillchar = arg_to_char();
11070e3d5408SPeter Wemm 	    break;
11080e3d5408SPeter Wemm 	case 'm':		/* map identifier to type */
11090e3d5408SPeter Wemm 	    add_mapping(0, optarg);
11100e3d5408SPeter Wemm 	    break;
11110e3d5408SPeter Wemm 	case 'n':		/* OBSOLETE: set new tty driver */
11120e3d5408SPeter Wemm 	    break;
11130e3d5408SPeter Wemm 	case 'p':		/* OBSOLETE: map identifier to type */
11140e3d5408SPeter Wemm 	    add_mapping("plugboard", optarg);
11150e3d5408SPeter Wemm 	    break;
11160e3d5408SPeter Wemm 	case 'Q':		/* don't output control key settings */
11170e3d5408SPeter Wemm 	    quiet = 1;
11180e3d5408SPeter Wemm 	    break;
11190e3d5408SPeter Wemm 	case 'S':		/* OBSOLETE: output TERM & TERMCAP */
11200e3d5408SPeter Wemm 	    Sflag = 1;
11210e3d5408SPeter Wemm 	    break;
11220e3d5408SPeter Wemm 	case 'r':		/* display term on stderr */
11230e3d5408SPeter Wemm 	    showterm = 1;
11240e3d5408SPeter Wemm 	    break;
11250e3d5408SPeter Wemm 	case 's':		/* output TERM set command */
11260e3d5408SPeter Wemm 	    sflag = 1;
11270e3d5408SPeter Wemm 	    break;
112818259542SPeter Wemm 	case 'V':
112918259542SPeter Wemm 	    puts(curses_version());
113018259542SPeter Wemm 	    return EXIT_SUCCESS;
11310e3d5408SPeter Wemm 	case '?':
11320e3d5408SPeter Wemm 	default:
11330e3d5408SPeter Wemm 	    usage(*argv);
11340e3d5408SPeter Wemm 	}
11350e3d5408SPeter Wemm     }
11360e3d5408SPeter Wemm     argc -= optind;
11370e3d5408SPeter Wemm     argv += optind;
11380e3d5408SPeter Wemm 
11390e3d5408SPeter Wemm     if (argc > 1)
11400e3d5408SPeter Wemm 	usage(*argv);
11410e3d5408SPeter Wemm 
11420e3d5408SPeter Wemm     ttype = get_termcap_entry(*argv);
11430e3d5408SPeter Wemm 
11440e3d5408SPeter Wemm     if (!noset) {
11450e3d5408SPeter Wemm 	tcolumns = columns;
11460e3d5408SPeter Wemm 	tlines = lines;
11470e3d5408SPeter Wemm 
11480e3d5408SPeter Wemm #if defined(TIOCGWINSZ) && defined(TIOCSWINSZ)
11490e3d5408SPeter Wemm 	/* Set window size */
11500e3d5408SPeter Wemm 	(void) ioctl(STDERR_FILENO, TIOCGWINSZ, &win);
11510e3d5408SPeter Wemm 	if (win.ws_row == 0 && win.ws_col == 0 &&
11520e3d5408SPeter Wemm 	    tlines > 0 && tcolumns > 0) {
11530e3d5408SPeter Wemm 	    win.ws_row = tlines;
11540e3d5408SPeter Wemm 	    win.ws_col = tcolumns;
11550e3d5408SPeter Wemm 	    (void) ioctl(STDERR_FILENO, TIOCSWINSZ, &win);
11560e3d5408SPeter Wemm 	}
11570e3d5408SPeter Wemm #endif
11580e3d5408SPeter Wemm 	set_control_chars();
11590e3d5408SPeter Wemm 	set_conversions();
11600e3d5408SPeter Wemm 
11610e3d5408SPeter Wemm 	if (!noinit)
11620e3d5408SPeter Wemm 	    set_init();
11630e3d5408SPeter Wemm 
11640e3d5408SPeter Wemm 	/* Set the modes if they've changed. */
116515589c42SPeter Wemm 	if (memcmp(&mode, &oldmode, sizeof(mode))) {
116639f2269fSPeter Wemm 	    SET_TTY(STDERR_FILENO, &mode);
11670e3d5408SPeter Wemm 	}
116815589c42SPeter Wemm     }
11690e3d5408SPeter Wemm 
11700e3d5408SPeter Wemm     /* Get the terminal name from the entry. */
11710e3d5408SPeter Wemm     ttype = _nc_first_name(cur_term->type.term_names);
11720e3d5408SPeter Wemm 
11730e3d5408SPeter Wemm     if (noset)
11740e3d5408SPeter Wemm 	(void) printf("%s\n", ttype);
11750e3d5408SPeter Wemm     else {
11760e3d5408SPeter Wemm 	if (showterm)
11770e3d5408SPeter Wemm 	    (void) fprintf(stderr, "Terminal type is %s.\n", ttype);
11780e3d5408SPeter Wemm 	/*
11790e3d5408SPeter Wemm 	 * If erase, kill and interrupt characters could have been
11800e3d5408SPeter Wemm 	 * modified and not -Q, display the changes.
11810e3d5408SPeter Wemm 	 */
118218259542SPeter Wemm #ifdef TERMIOS
11830e3d5408SPeter Wemm 	if (!quiet) {
11840e3d5408SPeter Wemm 	    report("Erase", VERASE, CERASE);
11850e3d5408SPeter Wemm 	    report("Kill", VKILL, CINTR);
11860e3d5408SPeter Wemm 	    report("Interrupt", VINTR, CKILL);
11870e3d5408SPeter Wemm 	}
118818259542SPeter Wemm #endif
11890e3d5408SPeter Wemm     }
11900e3d5408SPeter Wemm 
11910e3d5408SPeter Wemm     if (Sflag)
11920e3d5408SPeter Wemm 	err("The -S option is not supported under terminfo.");
11930e3d5408SPeter Wemm 
11940e3d5408SPeter Wemm     if (sflag) {
11950e3d5408SPeter Wemm 	/*
11960e3d5408SPeter Wemm 	 * Figure out what shell we're using.  A hack, we look for an
11970e3d5408SPeter Wemm 	 * environmental variable SHELL ending in "csh".
11980e3d5408SPeter Wemm 	 */
11990e3d5408SPeter Wemm 	if ((p = getenv("SHELL")) != 0
12000e3d5408SPeter Wemm 	    && !strcmp(p + strlen(p) - 3, "csh"))
12010e3d5408SPeter Wemm 	    p = "set noglob;\nsetenv TERM %s;\nunset noglob;\n";
12020e3d5408SPeter Wemm 	else
12030e3d5408SPeter Wemm 	    p = "TERM=%s;\n";
12040e3d5408SPeter Wemm 	(void) printf(p, ttype);
12050e3d5408SPeter Wemm     }
12060e3d5408SPeter Wemm 
12070e3d5408SPeter Wemm     return EXIT_SUCCESS;
12080e3d5408SPeter Wemm }
12090e3d5408SPeter Wemm 
12100e3d5408SPeter Wemm /* tset.c ends here */
1211