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