Annotation of src/usr.bin/tset/tset.c, Revision 1.1
1.1 ! deraadt 1: /* $NetBSD: tset.c,v 1.4 1994/12/07 05:08:15 jtc Exp $ */
! 2:
! 3: /*-
! 4: * Copyright (c) 1980, 1991, 1993
! 5: * The Regents of the University of California. All rights reserved.
! 6: *
! 7: * Redistribution and use in source and binary forms, with or without
! 8: * modification, are permitted provided that the following conditions
! 9: * are met:
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: * 2. Redistributions in binary form must reproduce the above copyright
! 13: * notice, this list of conditions and the following disclaimer in the
! 14: * documentation and/or other materials provided with the distribution.
! 15: * 3. All advertising materials mentioning features or use of this software
! 16: * must display the following acknowledgement:
! 17: * This product includes software developed by the University of
! 18: * California, Berkeley and its contributors.
! 19: * 4. Neither the name of the University nor the names of its contributors
! 20: * may be used to endorse or promote products derived from this software
! 21: * without specific prior written permission.
! 22: *
! 23: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 24: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 25: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 26: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 27: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 28: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 29: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 31: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 32: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 33: * SUCH DAMAGE.
! 34: */
! 35:
! 36: #ifndef lint
! 37: static char copyright[] =
! 38: "@(#) Copyright (c) 1980, 1991, 1993\n\
! 39: The Regents of the University of California. All rights reserved.\n";
! 40: #endif /* not lint */
! 41:
! 42: #ifndef lint
! 43: #if 0
! 44: static char sccsid[] = "@(#)tset.c 8.1 (Berkeley) 6/9/93";
! 45: #endif
! 46: static char rcsid[] = "$NetBSD: tset.c,v 1.4 1994/12/07 05:08:15 jtc Exp $";
! 47: #endif /* not lint */
! 48:
! 49: #include <sys/types.h>
! 50: #include <sys/ioctl.h>
! 51: #include <termios.h>
! 52: #include <errno.h>
! 53: #include <unistd.h>
! 54: #include <stdlib.h>
! 55: #include <stdio.h>
! 56: #include <ctype.h>
! 57: #include <string.h>
! 58: #include "extern.h"
! 59:
! 60: void obsolete __P((char *[]));
! 61: void report __P((char *, int, u_int));
! 62: void usage __P((void));
! 63:
! 64: struct termios mode, oldmode;
! 65:
! 66: int erasechar; /* new erase character */
! 67: int intrchar; /* new interrupt character */
! 68: int isreset; /* invoked as reset */
! 69: int killchar; /* new kill character */
! 70: int lines, columns; /* window size */
! 71:
! 72: int
! 73: main(argc, argv)
! 74: int argc;
! 75: char *argv[];
! 76: {
! 77: #ifdef TIOCGWINSZ
! 78: struct winsize win;
! 79: #endif
! 80: int ch, noinit, noset, quiet, Sflag, sflag, showterm, usingupper;
! 81: char savech, *p, *t, *tcapbuf, *ttype;
! 82:
! 83: if (tcgetattr(STDERR_FILENO, &mode) < 0)
! 84: err("standard error: %s", strerror(errno));
! 85:
! 86: oldmode = mode;
! 87: ospeed = cfgetospeed(&mode);
! 88:
! 89: if (p = strrchr(*argv, '/'))
! 90: ++p;
! 91: else
! 92: p = *argv;
! 93: usingupper = isupper(*p);
! 94: if (!strcasecmp(p, "reset")) {
! 95: isreset = 1;
! 96: reset_mode();
! 97: }
! 98:
! 99: obsolete(argv);
! 100: noinit = noset = quiet = Sflag = sflag = showterm = 0;
! 101: while ((ch = getopt(argc, argv, "-a:d:e:Ii:k:m:np:QSrs")) != EOF) {
! 102: switch (ch) {
! 103: case '-': /* display term only */
! 104: noset = 1;
! 105: break;
! 106: case 'a': /* OBSOLETE: map identifier to type */
! 107: add_mapping("arpanet", optarg);
! 108: break;
! 109: case 'd': /* OBSOLETE: map identifier to type */
! 110: add_mapping("dialup", optarg);
! 111: break;
! 112: case 'e': /* erase character */
! 113: erasechar = optarg[0] == '^' && optarg[1] != '\0' ?
! 114: optarg[1] == '?' ? '\177' : CTRL(optarg[1]) :
! 115: optarg[0];
! 116: break;
! 117: case 'I': /* no initialization strings */
! 118: noinit = 1;
! 119: break;
! 120: case 'i': /* interrupt character */
! 121: intrchar = optarg[0] == '^' && optarg[1] != '\0' ?
! 122: optarg[1] == '?' ? '\177' : CTRL(optarg[1]) :
! 123: optarg[0];
! 124: break;
! 125: case 'k': /* kill character */
! 126: killchar = optarg[0] == '^' && optarg[1] != '\0' ?
! 127: optarg[1] == '?' ? '\177' : CTRL(optarg[1]) :
! 128: optarg[0];
! 129: break;
! 130: case 'm': /* map identifier to type */
! 131: add_mapping(NULL, optarg);
! 132: break;
! 133: case 'n': /* OBSOLETE: set new tty driver */
! 134: break;
! 135: case 'p': /* OBSOLETE: map identifier to type */
! 136: add_mapping("plugboard", optarg);
! 137: break;
! 138: case 'Q': /* don't output control key settings */
! 139: quiet = 1;
! 140: break;
! 141: case 'S': /* output TERM/TERMCAP strings */
! 142: Sflag = 1;
! 143: break;
! 144: case 'r': /* display term on stderr */
! 145: showterm = 1;
! 146: break;
! 147: case 's': /* output TERM/TERMCAP strings */
! 148: sflag = 1;
! 149: break;
! 150: case '?':
! 151: default:
! 152: usage();
! 153: }
! 154: }
! 155: argc -= optind;
! 156: argv += optind;
! 157:
! 158: if (argc > 1)
! 159: usage();
! 160:
! 161: ttype = get_termcap_entry(*argv, &tcapbuf);
! 162:
! 163: if (!noset) {
! 164: columns = tgetnum("co");
! 165: lines = tgetnum("li");
! 166:
! 167: #ifdef TIOCGWINSZ
! 168: /* Set window size */
! 169: (void)ioctl(STDERR_FILENO, TIOCGWINSZ, &win);
! 170: if (win.ws_row == 0 && win.ws_col == 0 &&
! 171: lines > 0 && columns > 0) {
! 172: win.ws_row = lines;
! 173: win.ws_col = columns;
! 174: (void)ioctl(STDERR_FILENO, TIOCSWINSZ, &win);
! 175: }
! 176: #endif
! 177: set_control_chars();
! 178: set_conversions(usingupper);
! 179:
! 180: if (!noinit)
! 181: set_init();
! 182:
! 183: /* Set the modes if they've changed. */
! 184: if (memcmp(&mode, &oldmode, sizeof(mode)))
! 185: tcsetattr(STDERR_FILENO, TCSADRAIN, &mode);
! 186: }
! 187:
! 188: /* Get the terminal name from the entry. */
! 189: p = tcapbuf;
! 190: if (p != NULL && *p != ':') {
! 191: t = p;
! 192: if (p = strpbrk(p, "|:")) {
! 193: savech = *p;
! 194: *p = '\0';
! 195: if ((ttype = strdup(t)) == NULL)
! 196: err("%s", strerror(errno));
! 197: *p = savech;
! 198: }
! 199: }
! 200:
! 201: if (noset)
! 202: (void)printf("%s\n", ttype);
! 203: else {
! 204: if (showterm)
! 205: (void)fprintf(stderr, "Terminal type is %s.\n", ttype);
! 206: /*
! 207: * If erase, kill and interrupt characters could have been
! 208: * modified and not -Q, display the changes.
! 209: */
! 210: if (!quiet) {
! 211: report("Erase", VERASE, CERASE);
! 212: report("Kill", VKILL, CKILL);
! 213: report("Interrupt", VINTR, CINTR);
! 214: }
! 215: }
! 216:
! 217: if (Sflag) {
! 218: (void)printf("%s ", ttype);
! 219: wrtermcap(tcapbuf);
! 220: }
! 221:
! 222: if (sflag) {
! 223: /*
! 224: * Figure out what shell we're using. A hack, we look for an
! 225: * environmental variable SHELL ending in "csh".
! 226: */
! 227: if ((p = getenv("SHELL")) &&
! 228: !strcmp(p + strlen(p) - 3, "csh")) {
! 229: p = "set noglob;\nsetenv TERM %s;\nsetenv TERMCAP '";
! 230: t = "';\nunset noglob;\n";
! 231: } else {
! 232: p = "TERM=%s;\nTERMCAP='";
! 233: t = "';\nexport TERMCAP TERM;\n";
! 234: }
! 235: (void)printf(p, ttype);
! 236: wrtermcap(tcapbuf);
! 237: (void)printf(t);
! 238: }
! 239:
! 240: exit(0);
! 241: }
! 242:
! 243: /*
! 244: * Tell the user if a control key has been changed from the default value.
! 245: */
! 246: void
! 247: report(name, which, def)
! 248: char *name;
! 249: int which;
! 250: u_int def;
! 251: {
! 252: u_int old, new;
! 253: char *bp, buf[1024];
! 254:
! 255: new = mode.c_cc[which];
! 256: old = oldmode.c_cc[which];
! 257:
! 258: if (old == new && old == def)
! 259: return;
! 260:
! 261: (void)fprintf(stderr, "%s %s ", name, old == new ? "is" : "set to");
! 262:
! 263: bp = buf;
! 264: if (tgetstr("kb", &bp) && new == buf[0] && buf[1] == '\0')
! 265: (void)fprintf(stderr, "backspace.\n");
! 266: else if (new == 0177)
! 267: (void)fprintf(stderr, "delete.\n");
! 268: else if (new < 040) {
! 269: new ^= 0100;
! 270: (void)fprintf(stderr, "control-%c (^%c).\n", new, new);
! 271: } else
! 272: (void)fprintf(stderr, "%c.\n", new);
! 273: }
! 274:
! 275: /*
! 276: * Convert the obsolete argument form into something that getopt can handle.
! 277: * This means that -e, -i and -k get default arguments supplied for them.
! 278: */
! 279: void
! 280: obsolete(argv)
! 281: char *argv[];
! 282: {
! 283: for (; *argv; ++argv) {
! 284: if (argv[0][0] != '-' || argv[1] && argv[1][0] != '-' ||
! 285: argv[0][1] != 'e' && argv[0][1] != 'i' &&
! 286: argv[0][1] != 'k' || argv[0][2] != '\0')
! 287: continue;
! 288: switch(argv[0][1]) {
! 289: case 'e':
! 290: argv[0] = "-e^H";
! 291: break;
! 292: case 'i':
! 293: argv[0] = "-i^C";
! 294: break;
! 295: case 'k':
! 296: argv[0] = "-k^U";
! 297: break;
! 298: }
! 299: }
! 300: }
! 301:
! 302: void
! 303: usage()
! 304: {
! 305: (void)fprintf(stderr,
! 306: "usage: tset [-IQrSs] [-] [-e ch] [-i ch] [-k ch] [-m mapping] [terminal]\n");
! 307: exit(1);
! 308: }