1 /*- 2 * Copyright (c) 1980, 1991 The Regents of the University of California. 3 * 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 35 char copyright[] = 36 "@(#) Copyright (c) 1980, 1991 The Regents of the University of California.\n\ 37 All rights reserved.\n"; 38 #endif /* not lint */ 39 40 #ifndef lint 41 /*static char sccsid[] = "from: @(#)tset.c 5.22 (Berkeley) 2/11/93";*/ 42 static char rcsid[] = "$Id: tset.c,v 1.3 1993/08/01 18:04:22 mycroft Exp $"; 43 #endif /* not lint */ 44 45 #include <sys/types.h> 46 #include <sys/ioctl.h> 47 #include <termios.h> 48 #include <errno.h> 49 #include <unistd.h> 50 #include <stdlib.h> 51 #include <stdio.h> 52 #include <ctype.h> 53 #include <string.h> 54 #include "extern.h" 55 56 void obsolete __P((char *[])); 57 void report __P((char *, int, u_int)); 58 void usage __P((void)); 59 60 struct termios mode, oldmode; 61 62 int erasechar; /* new erase character */ 63 int intrchar; /* new interrupt character */ 64 int isreset; /* invoked as reset */ 65 int killchar; /* new kill character */ 66 int lines, columns; /* window size */ 67 68 int 69 main(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 85 if (p = strrchr(*argv, '/')) 86 ++p; 87 else 88 p = *argv; 89 usingupper = isupper(*p); 90 if (!strcasecmp(p, "reset")) { 91 isreset = 1; 92 reset_mode(); 93 } 94 95 obsolete(argv); 96 noinit = noset = quiet = Sflag = sflag = showterm = 0; 97 while ((ch = getopt(argc, argv, "-a:d:e:Ii:k:m:np:QSrs")) != EOF) { 98 switch (ch) { 99 case '-': /* display term only */ 100 noset = 1; 101 break; 102 case 'a': /* OBSOLETE: map identifier to type */ 103 add_mapping("arpanet", optarg); 104 break; 105 case 'd': /* OBSOLETE: map identifier to type */ 106 add_mapping("dialup", optarg); 107 break; 108 case 'e': /* erase character */ 109 erasechar = optarg[0] == '^' && optarg[1] != '\0' ? 110 optarg[1] == '?' ? '\177' : CTRL(optarg[1]) : 111 optarg[0]; 112 break; 113 case 'I': /* no initialization strings */ 114 noinit = 1; 115 break; 116 case 'i': /* interrupt character */ 117 intrchar = optarg[0] == '^' && optarg[1] != '\0' ? 118 optarg[1] == '?' ? '\177' : CTRL(optarg[1]) : 119 optarg[0]; 120 break; 121 case 'k': /* kill character */ 122 killchar = optarg[0] == '^' && optarg[1] != '\0' ? 123 optarg[1] == '?' ? '\177' : CTRL(optarg[1]) : 124 optarg[0]; 125 break; 126 case 'm': /* map identifier to type */ 127 add_mapping(NULL, optarg); 128 break; 129 case 'n': /* OBSOLETE: set new tty driver */ 130 break; 131 case 'p': /* OBSOLETE: map identifier to type */ 132 add_mapping("plugboard", optarg); 133 break; 134 case 'Q': /* don't output control key settings */ 135 quiet = 1; 136 break; 137 case 'S': /* output TERM/TERMCAP strings */ 138 Sflag = 1; 139 break; 140 case 'r': /* display term on stderr */ 141 showterm = 1; 142 break; 143 case 's': /* output TERM/TERMCAP strings */ 144 sflag = 1; 145 break; 146 case '?': 147 default: 148 usage(); 149 } 150 } 151 argc -= optind; 152 argv += optind; 153 154 if (argc > 1) 155 usage(); 156 157 ttype = get_termcap_entry(*argv, &tcapbuf); 158 159 if (!noset) { 160 columns = tgetnum("co"); 161 lines = tgetnum("li"); 162 163 #ifdef TIOCGWINSZ 164 /* Set window size */ 165 (void)ioctl(STDERR_FILENO, TIOCGWINSZ, &win); 166 if (win.ws_row == 0 && win.ws_col == 0 && 167 lines > 0 && columns > 0) { 168 win.ws_row = lines; 169 win.ws_col = columns; 170 (void)ioctl(STDERR_FILENO, TIOCSWINSZ, &win); 171 } 172 #endif 173 set_control_chars(); 174 set_conversions(usingupper); 175 176 if (!noinit) 177 set_init(); 178 179 /* Set the modes if they've changed. */ 180 if (memcmp(&mode, &oldmode, sizeof(mode))) 181 tcsetattr(STDERR_FILENO, TCSADRAIN, &mode); 182 } 183 184 /* Get the terminal name from the entry. */ 185 p = tcapbuf; 186 if (p != NULL && *p != ':') { 187 t = p; 188 if (p = strpbrk(p, "|:")) { 189 savech = *p; 190 *p = '\0'; 191 if ((ttype = strdup(t)) == NULL) 192 err("%s", strerror(errno)); 193 *p = savech; 194 } 195 } 196 197 if (noset) 198 (void)printf("%s\n", ttype); 199 else { 200 if (showterm) 201 (void)fprintf(stderr, "Terminal type is %s.\n", ttype); 202 /* 203 * If erase, kill and interrupt characters could have been 204 * modified and not -Q, display the changes. 205 */ 206 if (!quiet) { 207 report("Erase", VERASE, CERASE); 208 report("Kill", VKILL, CKILL); 209 report("Interrupt", VINTR, CINTR); 210 } 211 } 212 213 if (Sflag) { 214 (void)printf("%s ", ttype); 215 wrtermcap(tcapbuf); 216 } 217 218 if (sflag) { 219 /* 220 * Figure out what shell we're using. A hack, we look for an 221 * environmental variable SHELL ending in "csh". 222 */ 223 if ((p = getenv("SHELL")) && 224 !strcmp(p + strlen(p) - 3, "csh")) { 225 p = "set noglob;\nsetenv TERM %s;\nsetenv TERMCAP '"; 226 t = "';\nunset noglob;\n"; 227 } else { 228 p = "TERM=%s;\nTERMCAP='"; 229 t = "';\nexport TERMCAP TERM;\n"; 230 } 231 (void)printf(p, ttype); 232 wrtermcap(tcapbuf); 233 (void)printf(t); 234 } 235 236 exit(0); 237 } 238 239 /* 240 * Tell the user if a control key has been changed from the default value. 241 */ 242 void 243 report(name, which, def) 244 char *name; 245 int which; 246 u_int def; 247 { 248 u_int old, new; 249 char *bp, buf[1024]; 250 251 new = mode.c_cc[which]; 252 old = oldmode.c_cc[which]; 253 254 if (old == new && old == def) 255 return; 256 257 (void)fprintf(stderr, "%s %s ", name, old == new ? "is" : "set to"); 258 259 bp = buf; 260 if (tgetstr("kb", &bp) && new == buf[0] && buf[1] == '\0') 261 (void)fprintf(stderr, "backspace.\n"); 262 else if (new == 0177) 263 (void)fprintf(stderr, "delete.\n"); 264 else if (new < 040) { 265 new ^= 0100; 266 (void)fprintf(stderr, "control-%c (^%c).\n", new, new); 267 } else 268 (void)fprintf(stderr, "%c.\n", new); 269 } 270 271 /* 272 * Convert the obsolete argument form into something that getopt can handle. 273 * This means that -e, -i and -k get default arguments supplied for them. 274 */ 275 void 276 obsolete(argv) 277 char *argv[]; 278 { 279 for (; *argv; ++argv) { 280 if (argv[0][0] != '-' || argv[1] && argv[1][0] != '-' || 281 argv[0][1] != 'e' && argv[0][1] != 'i' && 282 argv[0][1] != 'k' || argv[0][2] != '\0') 283 continue; 284 switch(argv[0][1]) { 285 case 'e': 286 argv[0] = "-e^H"; 287 break; 288 case 'i': 289 argv[0] = "-i^C"; 290 break; 291 case 'k': 292 argv[0] = "-k^U"; 293 break; 294 } 295 } 296 } 297 298 void 299 usage() 300 { 301 (void)fprintf(stderr, 302 "usage: tset [-IQrSs] [-] [-e ch] [-i ch] [-k ch] [-m mapping] [terminal]\n"); 303 exit(1); 304 } 305