tset.c revision 3397
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 /* Get the terminal name from the entry. */ 213 p = tcapbuf; 214 if (p != NULL && *p != ':') { 215 t = p; 216 if (p = strpbrk(p, "|:")) { 217 savech = *p; 218 *p = '\0'; 219 if ((ttype = strdup(t)) == NULL) 220 err("%s", strerror(errno)); 221 *p = savech; 222 } 223 } 224 225 if (noset) 226 (void)printf("%s\n", ttype); 227 else { 228 if (showterm) 229 (void)fprintf(stderr, "Terminal type is %s.\n", ttype); 230 /* 231 * If erase, kill and interrupt characters could have been 232 * modified and not -Q, display the changes. 233 */ 234 if (!quiet) { 235 report("Erase", VERASE, CERASE); 236 report("Kill", VKILL, CKILL); 237 report("Interrupt", VINTR, CINTR); 238 } 239 } 240 241 if (Sflag) { 242 (void)printf("%s ", ttype); 243 wrtermcap(tcapbuf); 244 } 245 246 if (sflag) { 247 /* 248 * Figure out what shell we're using. A hack, we look for an 249 * environmental variable SHELL ending in "csh". 250 */ 251 if ((p = getenv("SHELL")) && 252 !strcmp(p + strlen(p) - 3, "csh")) { 253 p = "set noglob;\nsetenv TERM %s;\nsetenv TERMCAP '"; 254 t = "';\nunset noglob;\n"; 255 } else { 256 p = "TERM=%s;\nTERMCAP='"; 257 t = "';\nexport TERMCAP TERM;\n"; 258 } 259 (void)printf(p, ttype); 260 wrtermcap(tcapbuf); 261 (void)printf(t); 262 } 263 264 exit(0); 265} 266 267/* 268 * Tell the user if a control key has been changed from the default value. 269 */ 270void 271report(name, which, def) 272 char *name; 273 int which; 274 u_int def; 275{ 276 u_int old, new; 277 char *bp, buf[1024]; 278 279 new = mode.c_cc[which]; 280 old = oldmode.c_cc[which]; 281 282 if (old == new && old == def) 283 return; 284 285 (void)fprintf(stderr, "%s %s ", name, old == new ? "is" : "set to"); 286 287 bp = buf; 288 if (tgetstr("kb", &bp) && new == buf[0] && buf[1] == '\0') 289 (void)fprintf(stderr, "backspace.\n"); 290 else if (new == 0177) 291 (void)fprintf(stderr, "delete.\n"); 292 else if (new < 040) { 293 new ^= 0100; 294 (void)fprintf(stderr, "control-%c (^%c).\n", new, new); 295 } else 296 (void)fprintf(stderr, "%c.\n", new); 297} 298 299/* 300 * Convert the obsolete argument form into something that getopt can handle. 301 * This means that -e, -i and -k get default arguments supplied for them. 302 */ 303void 304obsolete(argv) 305 char *argv[]; 306{ 307 for (; *argv; ++argv) { 308 if (argv[0][0] != '-' || argv[1] && argv[1][0] != '-' || 309 argv[0][1] != 'e' && argv[0][1] != 'i' && 310 argv[0][1] != 'k' || argv[0][2] != '\0') 311 continue; 312 switch(argv[0][1]) { 313 case 'e': 314 argv[0] = "-e^H"; 315 break; 316 case 'i': 317 argv[0] = "-i^C"; 318 break; 319 case 'k': 320 argv[0] = "-k^U"; 321 break; 322 } 323 } 324} 325 326void 327usage() 328{ 329 (void)fprintf(stderr, 330"usage: tset [-IQrSs] [-] [-e ch] [-i ch] [-k ch] [-m mapping] [terminal]\n"); 331 exit(1); 332} 333