trailing comment after #else or #endif
[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
277ca15f 15static char sccsid[] = "@(#)tset.c 5.22 (Berkeley) %G%";
3e928ffa 16#endif /* not lint */
6a19f69a 17
973c9dcf 18#include <sys/types.h>
c2ee5c3e 19#include <sys/ioctl.h>
973c9dcf 20#include <termios.h>
81ee81b5 21#include <errno.h>
973c9dcf
MT
22#include <unistd.h>
23#include <stdlib.h>
81ee81b5 24#include <stdio.h>
973c9dcf
MT
25#include <ctype.h>
26#include <string.h>
81ee81b5 27#include "extern.h"
973c9dcf 28
81ee81b5
KB
29void obsolete __P((char *[]));
30void report __P((char *, int, u_int));
31void usage __P((void));
973c9dcf 32
81ee81b5 33struct termios mode, oldmode;
973c9dcf 34
81ee81b5
KB
35int erasechar; /* new erase character */
36int intrchar; /* new interrupt character */
37int isreset; /* invoked as reset */
38int killchar; /* new kill character */
81ee81b5 39int lines, columns; /* window size */
973c9dcf 40
81ee81b5 41int
177ed6dd 42main(argc, argv)
81ee81b5
KB
43 int argc;
44 char *argv[];
177ed6dd 45{
973c9dcf 46#ifdef TIOCGWINSZ
81ee81b5 47 struct winsize win;
973c9dcf 48#endif
f666f4df 49 int ch, noinit, noset, quiet, Sflag, sflag, showterm, usingupper;
81ee81b5 50 char savech, *p, *t, *tcapbuf, *ttype;
973c9dcf 51
81ee81b5
KB
52 if (tcgetattr(STDERR_FILENO, &mode) < 0)
53 err("standard error: %s", strerror(errno));
973c9dcf 54
973c9dcf 55 oldmode = mode;
973c9dcf
MT
56 ospeed = cfgetospeed(&mode);
57
81ee81b5
KB
58 if (p = strrchr(*argv, '/'))
59 ++p;
6a19f69a 60 else
81ee81b5
KB
61 p = *argv;
62 usingupper = isupper(*p);
63 if (!strcasecmp(p, "reset")) {
64 isreset = 1;
973c9dcf 65 reset_mode();
6a19f69a 66 }
6a19f69a 67
81ee81b5 68 obsolete(argv);
f666f4df
KB
69 noinit = noset = quiet = Sflag = sflag = showterm = 0;
70 while ((ch = getopt(argc, argv, "-a:d:e:Ii:k:m:np:QSrs")) != EOF) {
81ee81b5 71 switch (ch) {
f666f4df 72 case '-': /* display term only */
81ee81b5
KB
73 noset = 1;
74 break;
c8d0758d
KB
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;
81ee81b5
KB
81 case 'e': /* erase character */
82 erasechar = optarg[0] == '^' && optarg[1] != '\0' ?
83 optarg[1] == '?' ? '\177' : CTRL(optarg[1]) :
84 optarg[0];
85 break;
f666f4df 86 case 'I': /* no initialization strings */
81ee81b5
KB
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 */
c8d0758d
KB
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);
81ee81b5 106 break;
f666f4df 107 case 'Q': /* don't output control key settings */
81ee81b5
KB
108 quiet = 1;
109 break;
f666f4df
KB
110 case 'S': /* output TERM/TERMCAP strings */
111 Sflag = 1;
112 break;
c8d0758d
KB
113 case 'r': /* display term on stderr */
114 showterm = 1;
115 break;
f666f4df
KB
116 case 's': /* output TERM/TERMCAP strings */
117 sflag = 1;
81ee81b5
KB
118 break;
119 case '?':
120 default:
121 usage();
122 }
177ed6dd 123 }
81ee81b5
KB
124 argc -= optind;
125 argv += optind;
177ed6dd 126
81ee81b5 127 if (argc > 1)
973c9dcf 128 usage();
177ed6dd 129
81ee81b5 130 ttype = get_termcap_entry(*argv, &tcapbuf);
177ed6dd 131
81ee81b5 132 if (!noset) {
48e4fbf9
JB
133 columns = tgetnum("co");
134 lines = tgetnum("li");
135
973c9dcf 136#ifdef TIOCGWINSZ
48e4fbf9 137 /* Set window size */
81ee81b5 138 (void)ioctl(STDERR_FILENO, TIOCGWINSZ, &win);
0b1d4860
JB
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;
81ee81b5 143 (void)ioctl(STDERR_FILENO, TIOCSWINSZ, &win);
48e4fbf9 144 }
973c9dcf 145#endif
81ee81b5
KB
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);
177ed6dd
BJ
155 }
156
277ca15f
EA
157 /* Get the terminal name from the entry. */
158 p = tcapbuf;
159 if (p != NULL && *p != ':') {
160 t = p;
81ee81b5
KB
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;
177ed6dd
BJ
167 }
168 }
169
c8d0758d 170 if (noset)
81ee81b5 171 (void)printf("%s\n", ttype);
c8d0758d
KB
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 }
973c9dcf
MT
184 }
185
f666f4df
KB
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 }
c8d0758d 208
81ee81b5 209 exit(0);
177ed6dd
BJ
210}
211
6a19f69a 212/*
81ee81b5 213 * Tell the user if a control key has been changed from the default value.
6a19f69a 214 */
010bfa9a 215void
81ee81b5
KB
216report(name, which, def)
217 char *name;
218 int which;
219 u_int def;
6a19f69a 220{
81ee81b5
KB
221 u_int old, new;
222 char *bp, buf[1024];
6a19f69a 223
81ee81b5
KB
224 new = mode.c_cc[which];
225 old = oldmode.c_cc[which];
973c9dcf 226
81ee81b5 227 if (old == new && old == def)
6a19f69a 228 return;
177ed6dd 229
81ee81b5
KB
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);
177ed6dd 242}
177ed6dd 243
81ee81b5
KB
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 */
973c9dcf 248void
81ee81b5
KB
249obsolete(argv)
250 char *argv[];
177ed6dd 251{
81ee81b5
KB
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')
6a19f69a 256 continue;
81ee81b5
KB
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";
6a19f69a 266 break;
177ed6dd 267 }
177ed6dd 268 }
177ed6dd 269}
c8d0758d 270
973c9dcf
MT
271void
272usage()
177ed6dd 273{
81ee81b5 274 (void)fprintf(stderr,
f666f4df 275"usage: tset [-IQrSs] [-] [-e ch] [-i ch] [-k ch] [-m mapping] [terminal]\n");
177ed6dd
BJ
276 exit(1);
277}