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