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