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