#include <sys/cdefs.h>
__COPYRIGHT("@(#) Copyright (c) 1980, 1991, 1993\
The Regents of the University of California. All rights reserved.");
__RCSID("$NetBSD: tset.c,v 1.20 2011/09/06 18:34:12 joerg Exp $");
#include <sys/types.h>
#include <sys/ioctl.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <term.h>
#include <termios.h>
#include <unistd.h>
#include "extern.h"
static void obsolete(char *[]);
static void report(const char *, int, u_int);
__dead static void usage(void);
struct termios mode, oldmode;
int isreset;
int nlines, ncolumns;
int
main(int argc, char *argv[])
{
#ifdef TIOCGWINSZ
struct winsize win;
#endif
int ch, noinit, noset, quiet, sflag, showterm;
int erasechar = 0, intrchar = 0, killchar = 0;
int usingupper;
char *p;
const char *k1, *k2;
const char *ttype;
if (tcgetattr(STDERR_FILENO, &mode) < 0)
err(1, "standard error");
oldmode = mode;
ospeed = cfgetospeed(&mode);
if ((p = strrchr(*argv, '/')) != NULL)
++p;
else
p = *argv;
usingupper = isupper((unsigned char)*p);
if (!strcasecmp(p, "reset")) {
isreset = 1;
reset_mode();
}
obsolete(argv);
noinit = noset = quiet = sflag = showterm = 0;
while ((ch = getopt(argc, argv, "-a:d:e:EIi:k:m:np:QSrs")) != -1) {
switch (ch) {
case '-':
noset = 1;
break;
case 'a':
add_mapping("arpanet", optarg);
break;
case 'd':
add_mapping("dialup", optarg);
break;
case 'e':
erasechar = optarg[0] == '^' && optarg[1] != '\0' ?
optarg[1] == '?' ? '\177' : CTRL(optarg[1]) :
optarg[0];
break;
case 'E':
break;
case 'I':
noinit = 1;
break;
case 'i':
intrchar = optarg[0] == '^' && optarg[1] != '\0' ?
optarg[1] == '?' ? '\177' : CTRL(optarg[1]) :
optarg[0];
break;
case 'k':
killchar = optarg[0] == '^' && optarg[1] != '\0' ?
optarg[1] == '?' ? '\177' : CTRL(optarg[1]) :
optarg[0];
break;
case 'm':
add_mapping(NULL, optarg);
break;
case 'n':
break;
case 'p':
add_mapping("plugboard", optarg);
break;
case 'Q':
quiet = 1;
break;
case 'S':
break;
case 'r':
showterm = 1;
break;
case 's':
sflag = 1;
break;
case '?':
default:
usage();
}
}
argc -= optind;
argv += optind;
if (argc > 1)
usage();
ttype = get_terminfo_entry(*argv);
if (!noset) {
ncolumns = columns;
nlines = lines;
#ifdef TIOCGWINSZ
(void)ioctl(STDERR_FILENO, TIOCGWINSZ, &win);
if (win.ws_row > 0 && win.ws_col > 0) {
nlines = win.ws_row;
ncolumns = win.ws_col;
} else if (win.ws_row == 0 && win.ws_col == 0 &&
nlines > 0 && columns > 0) {
win.ws_row = nlines;
win.ws_col = ncolumns;
(void)ioctl(STDERR_FILENO, TIOCSWINSZ, &win);
}
#endif
set_control_chars(erasechar, intrchar, killchar);
set_conversions(usingupper);
if (!noinit)
set_init();
if (memcmp(&mode, &oldmode, sizeof(mode)))
tcsetattr(STDERR_FILENO, TCSADRAIN, &mode);
}
if (noset)
(void)printf("%s\n", ttype);
else {
if (showterm)
(void)fprintf(stderr, "Terminal type is %s.\n", ttype);
if (!quiet) {
report("Erase", VERASE, CERASE);
report("Kill", VKILL, CKILL);
report("Interrupt", VINTR, CINTR);
}
}
if (sflag) {
if ((p = getenv("SHELL")) &&
!strcmp(p + strlen(p) - 3, "csh")) {
k1 = "set noglob;\nsetenv TERM ";
k2 = ";\nunset noglob;\n";
} else {
k1 = "TERM=";
k2 = ";\nexport TERM;\n";
}
(void)printf("%s%s%s", k1, ttype, k2);
}
exit(0);
}
static void
report(const char *name, int which, u_int def)
{
u_int old, new;
new = mode.c_cc[which];
old = oldmode.c_cc[which];
if (old == new && old == def)
return;
(void)fprintf(stderr, "%s %s ", name, old == new ? "is" : "set to");
if (key_backspace != NULL &&
new == (unsigned int)key_backspace[0] &&
key_backspace[1] == '\0')
(void)fprintf(stderr, "backspace.\n");
else if (new == 0177)
(void)fprintf(stderr, "delete.\n");
else if (new < 040) {
new ^= 0100;
(void)fprintf(stderr, "control-%c (^%c).\n", new, new);
} else if (new == _POSIX_VDISABLE)
(void)fprintf(stderr, "<undef>.\n");
else
(void)fprintf(stderr, "%c.\n", new);
}
void
obsolete(char *argv[])
{
static char earg[5] = { '-', 'e', '^', 'H', '\0' };
static char iarg[5] = { '-', 'i', '^', 'C', '\0' };
static char karg[5] = { '-', 'k', '^', 'U', '\0' };
for (; *argv; ++argv) {
if (argv[0][0] != '-' || (argv[1] && argv[1][0] != '-') ||
(argv[0][1] != 'e' && argv[0][1] != 'i' &&
argv[0][1] != 'k') || argv[0][2] != '\0')
continue;
switch(argv[0][1]) {
case 'e':
argv[0] = earg;
break;
case 'i':
argv[0] = iarg;
break;
case 'k':
argv[0] = karg;
break;
}
}
}
static void
usage(void)
{
(void)fprintf(stderr,
"usage: %s [-EIQrSs] [-] [-e ch] [-i ch] [-k ch] [-m mapping] [terminal]\n",
getprogname());
exit(1);
}