tset.c revision 24360
167754Smsmith/*- 267754Smsmith * Copyright (c) 1980, 1991, 1993 377424Smsmith * The Regents of the University of California. All rights reserved. 467754Smsmith * 567754Smsmith * Redistribution and use in source and binary forms, with or without 667754Smsmith * modification, are permitted provided that the following conditions 7217365Sjkim * are met: 8217365Sjkim * 1. Redistributions of source code must retain the above copyright 970243Smsmith * notice, this list of conditions and the following disclaimer. 1067754Smsmith * 2. Redistributions in binary form must reproduce the above copyright 11217365Sjkim * notice, this list of conditions and the following disclaimer in the 12217365Sjkim * documentation and/or other materials provided with the distribution. 13217365Sjkim * 3. All advertising materials mentioning features or use of this software 14217365Sjkim * must display the following acknowledgement: 15217365Sjkim * This product includes software developed by the University of 16217365Sjkim * California, Berkeley and its contributors. 17217365Sjkim * 4. Neither the name of the University nor the names of its contributors 18217365Sjkim * may be used to endorse or promote products derived from this software 19217365Sjkim * without specific prior written permission. 20217365Sjkim * 21217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22217365Sjkim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23217365Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24217365Sjkim * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2567754Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2967754Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30217365Sjkim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31217365Sjkim * SUCH DAMAGE. 32217365Sjkim */ 33217365Sjkim 34217365Sjkim#ifndef lint 35217365Sjkimstatic char copyright[] = 36217365Sjkim"@(#) Copyright (c) 1980, 1991, 1993\n\ 37217365Sjkim The Regents of the University of California. All rights reserved.\n"; 38217365Sjkim#endif /* not lint */ 39217365Sjkim 40217365Sjkim#ifndef lint 41217365Sjkimstatic char sccsid[] = "@(#)tset.c 8.1 (Berkeley) 6/9/93"; 42217365Sjkim#endif /* not lint */ 4367754Smsmith 4467754Smsmith#include <sys/types.h> 4567754Smsmith#include <sys/ioctl.h> 4667754Smsmith#include <termios.h> 47193341Sjkim#include <errno.h> 48193341Sjkim#include <unistd.h> 49193341Sjkim#include <stdlib.h> 50193341Sjkim#include <stdio.h> 5167754Smsmith#include <ctype.h> 5277424Smsmith#include <string.h> 5391116Smsmith#include "extern.h" 5467754Smsmith 55151937Sjkimvoid obsolete __P((char *[])); 5667754Smsmithvoid report __P((char *, int, u_int)); 57151937Sjkimvoid usage __P((void)); 58151937Sjkim 59151937Sjkimstruct termios mode, oldmode; 60151937Sjkim 61151937Sjkimint erasechar; /* new erase character */ 62151937Sjkimint intrchar; /* new interrupt character */ 63151937Sjkimint isreset; /* invoked as reset */ 64151937Sjkimint killchar; /* new kill character */ 65151937Sjkimint lines, columns; /* window size */ 66151937Sjkimspeed_t Ospeed; 67151937Sjkim 68151937Sjkimint 69151937Sjkimmain(argc, argv) 70151937Sjkim int argc; 71151937Sjkim char *argv[]; 72151937Sjkim{ 73167802Sjkim#ifdef TIOCGWINSZ 74167802Sjkim struct winsize win; 75167802Sjkim#endif 76167802Sjkim int ch, noinit, noset, quiet, Sflag, sflag, showterm, usingupper; 77167802Sjkim char savech, *p, *t, *tcapbuf, *ttype; 78167802Sjkim 79167802Sjkim if (tcgetattr(STDERR_FILENO, &mode) < 0) 80167802Sjkim err("standard error: %s", strerror(errno)); 81167802Sjkim 82167802Sjkim oldmode = mode; 83167802Sjkim Ospeed = cfgetospeed(&mode); 84167802Sjkim 85167802Sjkim if (p = strrchr(*argv, '/')) 86167802Sjkim ++p; 8767754Smsmith else 8867754Smsmith p = *argv; 89167802Sjkim usingupper = isupper(*p); 90167802Sjkim if (!strcasecmp(p, "reset")) { 91167802Sjkim isreset = 1; 92167802Sjkim reset_mode(); 93167802Sjkim } 94167802Sjkim 95167802Sjkim obsolete(argv); 96167802Sjkim noinit = noset = quiet = Sflag = sflag = showterm = 0; 97167802Sjkim while ((ch = getopt(argc, argv, "-a:d:e:Ii:k:m:np:QSrs")) != -1) { 98167802Sjkim switch (ch) { 99167802Sjkim case '-': /* display term only */ 100167802Sjkim noset = 1; 101167802Sjkim break; 102167802Sjkim case 'a': /* OBSOLETE: map identifier to type */ 103167802Sjkim add_mapping("arpanet", optarg); 104167802Sjkim break; 105167802Sjkim case 'd': /* OBSOLETE: map identifier to type */ 106167802Sjkim add_mapping("dialup", optarg); 107167802Sjkim break; 108167802Sjkim case 'e': /* erase character */ 109167802Sjkim erasechar = optarg[0] == '^' && optarg[1] != '\0' ? 110167802Sjkim optarg[1] == '?' ? '\177' : CTRL(optarg[1]) : 111167802Sjkim optarg[0]; 112167802Sjkim break; 113167802Sjkim case 'I': /* no initialization strings */ 114167802Sjkim noinit = 1; 115167802Sjkim break; 116167802Sjkim case 'i': /* interrupt character */ 117167802Sjkim intrchar = optarg[0] == '^' && optarg[1] != '\0' ? 118167802Sjkim optarg[1] == '?' ? '\177' : CTRL(optarg[1]) : 119167802Sjkim optarg[0]; 120167802Sjkim break; 121167802Sjkim case 'k': /* kill character */ 122200553Sjkim killchar = optarg[0] == '^' && optarg[1] != '\0' ? 123167802Sjkim optarg[1] == '?' ? '\177' : CTRL(optarg[1]) : 124167802Sjkim optarg[0]; 125167802Sjkim break; 126167802Sjkim case 'm': /* map identifier to type */ 127167802Sjkim add_mapping(NULL, optarg); 128167802Sjkim break; 129167802Sjkim case 'n': /* OBSOLETE: set new tty driver */ 130167802Sjkim break; 131167802Sjkim case 'p': /* OBSOLETE: map identifier to type */ 132167802Sjkim add_mapping("plugboard", optarg); 133167802Sjkim break; 134167802Sjkim case 'Q': /* don't output control key settings */ 135167802Sjkim quiet = 1; 136167802Sjkim break; 137167802Sjkim case 'S': /* output TERM/TERMCAP strings */ 138167802Sjkim Sflag = 1; 139167802Sjkim break; 140167802Sjkim case 'r': /* display term on stderr */ 141167802Sjkim showterm = 1; 142167802Sjkim break; 143167802Sjkim case 's': /* output TERM/TERMCAP strings */ 144167802Sjkim sflag = 1; 145167802Sjkim break; 146167802Sjkim case '?': 147167802Sjkim default: 148167802Sjkim usage(); 149167802Sjkim } 150167802Sjkim } 151167802Sjkim argc -= optind; 152167802Sjkim argv += optind; 15367754Smsmith 15467754Smsmith if (argc > 1) 155167802Sjkim usage(); 156167802Sjkim 15767754Smsmith ttype = get_termcap_entry(*argv, &tcapbuf); 15867754Smsmith 15977424Smsmith if (!noset) { 16067754Smsmith columns = tgetnum("co"); 16167754Smsmith lines = tgetnum("li"); 162167802Sjkim 163167802Sjkim#ifdef TIOCGWINSZ 16467754Smsmith /* Set window size */ 16567754Smsmith (void)ioctl(STDERR_FILENO, TIOCGWINSZ, &win); 16667754Smsmith if (win.ws_row == 0 && win.ws_col == 0 && 16767754Smsmith lines > 0 && columns > 0) { 16867754Smsmith win.ws_row = lines; 16967754Smsmith win.ws_col = columns; 17067754Smsmith (void)ioctl(STDERR_FILENO, TIOCSWINSZ, &win); 17167754Smsmith } 17267754Smsmith#endif 17367754Smsmith set_control_chars(); 17467754Smsmith set_conversions(usingupper); 17567754Smsmith 17667754Smsmith if (!noinit) 17767754Smsmith set_init(); 17867754Smsmith 17967754Smsmith /* Set the modes if they've changed. */ 180167802Sjkim if (memcmp(&mode, &oldmode, sizeof(mode))) 18167754Smsmith tcsetattr(STDERR_FILENO, TCSADRAIN, &mode); 18267754Smsmith } 183167802Sjkim 18467754Smsmith if (noset) 18577424Smsmith (void)printf("%s\n", ttype); 186167802Sjkim else { 18767754Smsmith if (showterm) 188167802Sjkim (void)fprintf(stderr, "Terminal type is %s.\n", ttype); 18991116Smsmith /* 19091116Smsmith * If erase, kill and interrupt characters could have been 19191116Smsmith * modified and not -Q, display the changes. 19291116Smsmith */ 19391116Smsmith if (!quiet) { 194167802Sjkim report("Erase", VERASE, CERASE); 19567754Smsmith report("Kill", VKILL, CKILL); 19667754Smsmith report("Interrupt", VINTR, CINTR); 19767754Smsmith } 198167802Sjkim } 19967754Smsmith 200167802Sjkim if (Sflag) { 20167754Smsmith (void)printf("%s ", ttype); 20267754Smsmith wrtermcap(tcapbuf); 20367754Smsmith } 20467754Smsmith 205167802Sjkim if (sflag) { 20667754Smsmith /* 207167802Sjkim * Figure out what shell we're using. A hack, we look for an 20867754Smsmith * environmental variable SHELL ending in "csh". 20967754Smsmith */ 21077424Smsmith if ((p = getenv("SHELL")) && 21167754Smsmith !strcmp(p + strlen(p) - 3, "csh")) { 21267754Smsmith p = "set noglob;\nsetenv TERM %s;\nsetenv TERMCAP '"; 213167802Sjkim t = "';\nunset noglob;\n"; 214167802Sjkim } else { 21567754Smsmith p = "TERM=%s;\nTERMCAP='"; 21667754Smsmith t = "';\nexport TERMCAP TERM;\n"; 21767754Smsmith } 21867754Smsmith (void)printf(p, ttype); 21967754Smsmith wrtermcap(tcapbuf); 22067754Smsmith (void)printf(t); 22167754Smsmith } 22267754Smsmith 22367754Smsmith exit(0); 22467754Smsmith} 22567754Smsmith 22667754Smsmith/* 22767754Smsmith * Tell the user if a control key has been changed from the default value. 22867754Smsmith */ 22967754Smsmithvoid 23067754Smsmithreport(name, which, def) 231167802Sjkim char *name; 23267754Smsmith int which; 23367754Smsmith u_int def; 234167802Sjkim{ 23567754Smsmith u_int old, new; 23683174Smsmith 237167802Sjkim new = mode.c_cc[which]; 23867754Smsmith old = oldmode.c_cc[which]; 239167802Sjkim 24091116Smsmith if (old == new && old == def) 24191116Smsmith return; 24291116Smsmith 24391116Smsmith (void)fprintf(stderr, "%s %s ", name, old == new ? "is" : "set to"); 24491116Smsmith 245167802Sjkim if (new == 010) 24667754Smsmith (void)fprintf(stderr, "backspace.\n"); 24767754Smsmith else if (new == 0177) 24867754Smsmith (void)fprintf(stderr, "delete.\n"); 249167802Sjkim else if (new < 040) { 25067754Smsmith new ^= 0100; 251167802Sjkim (void)fprintf(stderr, "control-%c (^%c).\n", new, new); 25267754Smsmith } else 25367754Smsmith (void)fprintf(stderr, "%c.\n", new); 25467754Smsmith} 25567754Smsmith 256167802Sjkim/* 25767754Smsmith * Convert the obsolete argument form into something that getopt can handle. 258167802Sjkim * This means that -e, -i and -k get default arguments supplied for them. 25967754Smsmith */ 26067754Smsmithvoid 26177424Smsmithobsolete(argv) 26267754Smsmith char *argv[]; 26367754Smsmith{ 264167802Sjkim for (; *argv; ++argv) { 265167802Sjkim if (argv[0][0] != '-' || argv[1] && argv[1][0] != '-' || 26667754Smsmith argv[0][1] != 'e' && argv[0][1] != 'i' && 26767754Smsmith argv[0][1] != 'k' || argv[0][2] != '\0') 26867754Smsmith continue; 26967754Smsmith switch(argv[0][1]) { 27067754Smsmith case 'e': 27167754Smsmith argv[0] = "-e^H"; 27267754Smsmith break; 27367754Smsmith case 'i': 27467754Smsmith argv[0] = "-i^C"; 27567754Smsmith break; 27667754Smsmith case 'k': 27767754Smsmith argv[0] = "-k^U"; 27867754Smsmith break; 279167802Sjkim } 28067754Smsmith } 28167754Smsmith} 282167802Sjkim 28367754Smsmithvoid 28477424Smsmithusage() 285167802Sjkim{ 28667754Smsmith (void)fprintf(stderr, 287167802Sjkim"usage: tset [-IQrSs] [-] [-e ch] [-i ch] [-k ch] [-m mapping] [terminal]\n"); 28891116Smsmith exit(1); 28991116Smsmith} 29091116Smsmith