Commit | Line | Data |
---|---|---|
18949a0b | 1 | /* |
c086ab51 | 2 | * Copyright (c) 1980, 1989 Regents of the University of California. |
18949a0b DF |
3 | * All rights reserved. The Berkeley software License Agreement |
4 | * specifies the terms and conditions for redistribution. | |
5 | */ | |
6 | ||
ba3dc8b4 | 7 | #ifndef lint |
18949a0b | 8 | char copyright[] = |
c086ab51 | 9 | "@(#) Copyright (c) 1980, 1989 Regents of the University of California.\n\ |
18949a0b DF |
10 | All rights reserved.\n"; |
11 | #endif not lint | |
12 | ||
13 | #ifndef lint | |
6b85d402 | 14 | static char sccsid[] = "@(#)stty.c 5.10 (Berkeley) %G%"; |
18949a0b DF |
15 | #endif not lint |
16 | ||
16b6b22b BJ |
17 | /* |
18 | * set teletype modes | |
19 | */ | |
20 | ||
2ea9e68e MT |
21 | #include <sys/types.h> |
22 | #include <sys/stat.h> | |
4f05342b | 23 | #include <sys/ioctl.h> |
2ea9e68e MT |
24 | #include <sys/syslog.h> |
25 | #define KERNEL | |
26 | #include <sys/tty.h> | |
27 | #undef KERNEL | |
28 | #include <sys/termios.h> | |
29 | #include <sys/file.h> | |
30 | #include <errno.h> | |
31 | #include <ctype.h> | |
14fd0bf8 | 32 | #include <stdio.h> |
16b6b22b | 33 | |
b24648a6 | 34 | #define eq(s1, s2) (strcmp((s1), (s2)) == 0) |
2ea9e68e | 35 | #define WRAPCOL 65 |
2ea9e68e | 36 | |
b24648a6 | 37 | struct modes { |
2ea9e68e MT |
38 | char *name; |
39 | long set; | |
40 | long unset; | |
41 | }; | |
42 | ||
b24648a6 | 43 | struct modes imodes[] = { |
2ea9e68e MT |
44 | "ignbrk", IGNBRK, 0, |
45 | "-ignbrk", 0, IGNBRK, | |
46 | "brkint", BRKINT, 0, | |
47 | "-brkint", 0, BRKINT, | |
48 | "ignpar", IGNPAR, 0, | |
49 | "-ignpar", 0, IGNPAR, | |
50 | "parmrk", PARMRK, 0, | |
51 | "-parmrk", 0, PARMRK, | |
52 | "inpck", INPCK, 0, | |
53 | "-inpck", 0, INPCK, | |
54 | "istrip", ISTRIP, 0, | |
55 | "-istrip", 0, ISTRIP, | |
56 | "inlcr", INLCR, 0, | |
57 | "-inlcr", 0, INLCR, | |
58 | "igncr", IGNCR, 0, | |
59 | "-igncr", 0, IGNCR, | |
60 | "icrnl", ICRNL, 0, | |
61 | "-icrnl", 0, ICRNL, | |
62 | "ixon", IXON, 0, | |
63 | "-ixon", 0, IXON, | |
64 | "flow", IXON, 0, | |
65 | "-flow", 0, IXON, | |
66 | "ixoff", IXOFF, 0, | |
67 | "-ixoff", 0, IXOFF, | |
68 | "tandem", IXOFF, 0, | |
69 | "-tandem", 0, IXOFF, | |
70 | "ixany", IXANY, 0, | |
71 | "-ixany", 0, IXANY, | |
72 | "decctlq", 0, IXANY, | |
73 | "-decctlq", IXANY, 0, | |
74 | "imaxbel", IMAXBEL, 0, | |
75 | "-imaxbel", 0, IMAXBEL, | |
76 | 0 | |
77 | }; | |
78 | ||
b24648a6 | 79 | struct modes omodes[] = { |
2ea9e68e MT |
80 | "opost", OPOST, 0, |
81 | "-opost", 0, OPOST, | |
82 | "-litout", OPOST, 0, | |
83 | "litout", 0, OPOST, | |
84 | "onlcr", ONLCR, 0, | |
85 | "-onlcr", 0, ONLCR, | |
86 | "tabs", 0, OXTABS, /* "preserve" tabs */ | |
87 | "-tabs", OXTABS, 0, | |
6b85d402 MT |
88 | "xtabs", OXTABS, 0, |
89 | "-xtabs", 0, OXTABS, | |
2ea9e68e MT |
90 | "oxtabs", OXTABS, 0, |
91 | "-oxtabs", 0, OXTABS, | |
92 | 0 | |
16b6b22b BJ |
93 | }; |
94 | ||
b24648a6 | 95 | struct modes cmodes[] = { |
2ea9e68e MT |
96 | "cs5", CS5, CSIZE, |
97 | "cs6", CS6, CSIZE, | |
98 | "cs7", CS7, CSIZE, | |
99 | "cs8", CS8, CSIZE, | |
100 | "cstopb", CSTOPB, 0, | |
101 | "-cstopb", 0, CSTOPB, | |
102 | "cread", CREAD, 0, | |
103 | "-cread", 0, CREAD, | |
104 | "parenb", PARENB, 0, | |
105 | "-parenb", 0, PARENB, | |
106 | "parodd", PARODD, 0, | |
107 | "-parodd", 0, PARODD, | |
108 | "parity", PARENB | CS7, PARODD | CSIZE, | |
109 | "evenp", PARENB | CS7, PARODD | CSIZE, | |
110 | "oddp", PARENB | CS7 | PARODD, CSIZE, | |
111 | "-parity", CS8, PARODD | PARENB | CSIZE, | |
c086ab51 | 112 | "pass8", CS8, PARODD | PARENB | CSIZE, |
2ea9e68e MT |
113 | "-evenp", CS8, PARODD | PARENB | CSIZE, |
114 | "-oddp", CS8, PARODD | PARENB | CSIZE, | |
115 | "hupcl", HUPCL, 0, | |
116 | "-hupcl", 0, HUPCL, | |
117 | "hup", HUPCL, 0, | |
118 | "-hup", 0, HUPCL, | |
119 | "clocal", CLOCAL, 0, | |
120 | "-clocal", 0, CLOCAL, | |
121 | "crtscts", CRTSCTS, 0, | |
122 | "-crtscts", 0, CRTSCTS, | |
16b6b22b BJ |
123 | 0 |
124 | }; | |
16b6b22b | 125 | |
b24648a6 | 126 | struct modes lmodes[] = { |
2ea9e68e MT |
127 | "echo", ECHO, 0, |
128 | "-echo", 0, ECHO, | |
129 | "echoe", ECHOE, 0, | |
130 | "-echoe", 0, ECHOE, | |
131 | "crterase", ECHOE, 0, | |
132 | "-crterase", 0, ECHOE, | |
133 | "crtbs", ECHOE, 0, /* crtbs not supported, close enough */ | |
134 | "-crtbs", 0, ECHOE, | |
135 | "echok", ECHOK, 0, | |
136 | "-echok", 0, ECHOK, | |
137 | "echoke", ECHOKE, 0, | |
138 | "-echoke", 0, ECHOKE, | |
139 | "crtkill", ECHOKE, 0, | |
140 | "-crtkill", 0, ECHOKE, | |
141 | "altwerase", ALTWERASE, 0, | |
142 | "-altwerase", 0, ALTWERASE, | |
143 | "iexten", IEXTEN, 0, | |
144 | "-iexten", 0, IEXTEN, | |
145 | "echonl", ECHONL, 0, | |
146 | "-echonl", 0, ECHONL, | |
147 | "echoctl", ECHOCTL, 0, | |
148 | "-echoctl", 0, ECHOCTL, | |
149 | "ctlecho", ECHOCTL, 0, | |
150 | "-ctlecho", 0, ECHOCTL, | |
151 | "echoprt", ECHOPRT, 0, | |
152 | "-echoprt", 0, ECHOPRT, | |
153 | "prterase", ECHOPRT, 0, | |
154 | "-prterase", 0, ECHOPRT, | |
155 | "isig", ISIG, 0, | |
156 | "-isig", 0, ISIG, | |
157 | "icanon", ICANON, 0, | |
158 | "-icanon", 0, ICANON, | |
159 | "noflsh", NOFLSH, 0, | |
160 | "-noflsh", 0, NOFLSH, | |
161 | "tostop", TOSTOP, 0, | |
162 | "-tostop", 0, TOSTOP, | |
163 | "mdmbuf", MDMBUF, 0, | |
164 | "-mdmbuf", 0, MDMBUF, | |
165 | "nohang", NOHANG, 0, | |
166 | "-nohang", 0, NOHANG, | |
167 | "flusho", FLUSHO, 0, | |
168 | "-flusho", 0, FLUSHO, | |
169 | "pendin", PENDIN, 0, | |
170 | "-pendin", 0, PENDIN, | |
171 | "crt", ECHOE|ECHOKE|ECHOCTL, ECHOK|ECHOPRT, | |
172 | "-crt", ECHOK, ECHOE|ECHOKE|ECHOCTL, | |
173 | "newcrt", ECHOE|ECHOKE|ECHOCTL, ECHOK|ECHOPRT, | |
174 | "-newcrt", ECHOK, ECHOE|ECHOKE|ECHOCTL, | |
175 | 0 | |
176 | }; | |
177 | ||
178 | /* | |
179 | * Special control characters. | |
180 | * | |
181 | * Each entry has a list of names. The first is the primary name | |
182 | * and is used when printing the control character in the "name = val;" | |
183 | * form. The second is an abbreviation which is guaranteed to be less | |
184 | * than or equal to four characters in length and is primarily used | |
185 | * when printing the values in columunar form (guarantees all will | |
186 | * fit within 80 cols). The rest are optional aliases. | |
187 | * All names are recognized on the command line. | |
188 | */ | |
b24648a6 MT |
189 | #define MAXNAMES 3 |
190 | struct { | |
6b85d402 | 191 | char *names[MAXNAMES+1]; |
2ea9e68e MT |
192 | int sub; |
193 | u_char def; | |
194 | } cchars[] = { | |
195 | { "erase", "era" }, VERASE, CERASE, | |
196 | { "werase", "wera" }, VWERASE, CWERASE, | |
197 | { "kill", "kill" }, VKILL, CKILL, | |
198 | { "intr", "int" }, VINTR, CINTR, | |
199 | { "quit", "quit" }, VQUIT, CQUIT, | |
200 | { "susp", "susp" }, VSUSP, CSUSP, | |
201 | { "dsusp", "dsus" }, VDSUSP, CDSUSP, | |
202 | { "eof", "eof" }, VEOF, CEOF, | |
203 | { "eol", "eol", "brk" }, VEOL, CEOL, | |
204 | { "eol2", "eol2" }, VEOL2, CEOL, | |
205 | { "stop", "stop", "xoff" }, VSTOP, CSTOP, | |
206 | { "start", "star", "xon" }, VSTART, CSTART, | |
207 | { "lnext", "lnxt" }, VLNEXT, CLNEXT, | |
208 | { "flusho", "fls", "flush" }, VFLUSHO, CFLUSHO, | |
209 | { "reprint", "rpnt", "rprnt" }, VREPRINT, CREPRINT, | |
c086ab51 | 210 | { "info", "info" }, VINFO, CINFO, |
2ea9e68e MT |
211 | 0 |
212 | }; | |
213 | ||
b24648a6 MT |
214 | struct winsize win; |
215 | int ldisc; | |
216 | int dodisc; | |
217 | int debug = 0; | |
218 | int trace, dotrace; | |
2ea9e68e MT |
219 | |
220 | #define OUT stdout /* informational output stream */ | |
221 | #define ERR stderr /* error message stream */ | |
222 | #define CTL 0 /* default control descriptor */ | |
b24648a6 | 223 | int ctl = CTL; |
2ea9e68e MT |
224 | |
225 | extern errno; | |
2ea9e68e MT |
226 | |
227 | #define NORMAL 0 /* only print modes differing from defaults */ | |
228 | #define ALL 1 /* print all modes - POSIX standard format */ | |
229 | #define ALL_BSD 2 /* print all modes - using BSD shorthand for cc's */ | |
230 | #define GFMT 3 /* print modes in a form that can be re-input to stty */ | |
231 | ||
b24648a6 | 232 | |
2ea9e68e MT |
233 | main(argc, argv) |
234 | char *argv[]; | |
16b6b22b | 235 | { |
2ea9e68e MT |
236 | struct termios t; |
237 | int i, fmt = NORMAL; | |
238 | extern char *optarg; | |
239 | extern int optind; | |
240 | int ch; | |
241 | ||
242 | argc--, argv++; | |
243 | if (argc > 0 && eq(argv[0], "-a")) { | |
244 | fmt = ALL; | |
245 | argc--, argv++; | |
16b6b22b | 246 | } |
2ea9e68e MT |
247 | if (argc > 0 && eq(argv[0], "-f")) { |
248 | argc--, argv++; | |
249 | if ((ctl = open(argv[0], O_RDONLY | O_NONBLOCK)) < 0) | |
250 | syserrexit(*argv); | |
251 | argc--, argv++; | |
16b6b22b | 252 | } |
2ea9e68e MT |
253 | if (ioctl(ctl, TIOCGETD, &ldisc) < 0) |
254 | syserrexit("TIOCGETD"); | |
255 | if (tcgetattr(ctl, &t) < 0) | |
256 | syserrexit("tcgetattr"); | |
257 | if (ioctl(ctl, TIOCGWINSZ, &win) < 0) | |
b24648a6 | 258 | warning("TIOCGWINSZ: %s", strerror(errno)); |
2ea9e68e | 259 | checkredirect(); /* conversion aid */ |
2ea9e68e MT |
260 | |
261 | if (argc == 0 || fmt) { | |
262 | prmode(&t, ldisc, fmt); | |
ba3dc8b4 | 263 | exit(0); |
2ea9e68e MT |
264 | } else if (argc == 1 && strlen(argv[0]) > 2 && *(argv[0]+2) == ':') { |
265 | gfmtset(argv[0]); | |
266 | goto setit; | |
ba3dc8b4 | 267 | } |
2ea9e68e MT |
268 | |
269 | while (*argv) { | |
270 | if (eq("everything", *argv)) { | |
271 | prmode(&t, ldisc, ALL_BSD); | |
272 | exit(0); | |
16b6b22b | 273 | } |
2ea9e68e MT |
274 | if (eq("all", *argv)) { |
275 | prmode(&t, ldisc, ALL); | |
276 | exit(0); | |
16b6b22b | 277 | } |
2ea9e68e MT |
278 | if (eq("old", *argv)) { |
279 | goto next; | |
16b6b22b | 280 | } |
2ea9e68e MT |
281 | if (eq("new", *argv)) { |
282 | goto next; | |
16b6b22b | 283 | } |
2ea9e68e MT |
284 | if (eq("nl", *argv)) { |
285 | t.c_iflag &= ~ICRNL; | |
286 | t.c_oflag &= ~ONLCR; | |
287 | goto next; | |
5e9810bc | 288 | } |
2ea9e68e MT |
289 | if (eq("-nl", *argv)) { |
290 | t.c_iflag |= ICRNL; | |
291 | t.c_oflag |= ONLCR; | |
292 | goto next; | |
16b6b22b | 293 | } |
2ea9e68e MT |
294 | if (eq("dec", *argv)){ |
295 | t.c_cc[VERASE] = (u_char)0177; | |
296 | t.c_cc[VKILL] = CTRL('u'); | |
297 | t.c_cc[VINTR] = CTRL('c'); | |
298 | t.c_lflag &= ~ECHOPRT; | |
299 | t.c_lflag |= ECHOE|ECHOKE|ECHOCTL; | |
300 | t.c_iflag &= ~IXANY; | |
301 | goto next; | |
16b6b22b | 302 | } |
c086ab51 MK |
303 | if (eq("raw", *argv)) { |
304 | cfmakeraw(&t); | |
305 | t.c_cflag &= ~(CSIZE|PARENB); | |
306 | t.c_cflag |= CS8; | |
307 | goto next; | |
308 | } | |
309 | if (eq("cooked", *argv) || eq("-raw", *argv) || | |
310 | eq("sane", *argv)) { | |
311 | t.c_cflag = TTYDEF_CFLAG | (t.c_cflag & CLOCAL); | |
312 | t.c_iflag = TTYDEF_IFLAG; | |
313 | t.c_iflag |= ICRNL; | |
314 | /* preserve user-preference flags in lflag */ | |
315 | #define LKEEP (ECHOKE|ECHOE|ECHOK|ECHOPRT|ECHOCTL|ALTWERASE|TOSTOP|NOFLSH) | |
316 | t.c_lflag = TTYDEF_LFLAG | (t.c_lflag & LKEEP); | |
317 | t.c_oflag = TTYDEF_OFLAG; | |
c086ab51 MK |
318 | goto next; |
319 | } | |
2ea9e68e MT |
320 | if (eq("rows", *argv)) { |
321 | if (*(argv+1) == 0) | |
322 | goto setit; | |
4f05342b | 323 | win.ws_row = atoi(*++argv); |
2ea9e68e MT |
324 | goto next; |
325 | } | |
326 | if (eq("ispeed", *argv)) { | |
327 | int code; | |
328 | if (*(argv+1) == 0) | |
329 | errexit("missing ispeed"); | |
330 | cfsetispeed(&t, atoi(*++argv)); | |
331 | goto next; | |
332 | } | |
333 | if (eq("ospeed", *argv)) { | |
2ea9e68e MT |
334 | if (*(argv+1) == 0) |
335 | errexit("missing ospeed"); | |
336 | cfsetospeed(&t, atoi(*++argv)); | |
337 | goto next; | |
4f05342b | 338 | } |
2ea9e68e MT |
339 | if (eq("cols", *argv) || eq("columns", *argv)) { |
340 | if (*(argv+1) == 0) | |
341 | goto setit; | |
4f05342b | 342 | win.ws_col = atoi(*++argv); |
2ea9e68e | 343 | goto next; |
4f05342b | 344 | } |
2ea9e68e MT |
345 | if (eq("size", *argv)) { |
346 | put("%d %d\n", win.ws_row, win.ws_col); | |
d6f0b7e6 MK |
347 | exit(0); |
348 | } | |
2ea9e68e MT |
349 | if (eq("speed", *argv)) { |
350 | put("%d\n", cfgetospeed(&t)); | |
351 | exit(0); | |
352 | } | |
353 | for (i=0; imodes[i].name; i++) | |
354 | if (eq(imodes[i].name, *argv)) { | |
355 | t.c_iflag &= ~imodes[i].unset; | |
356 | t.c_iflag |= imodes[i].set; | |
357 | goto next; | |
358 | } | |
359 | for (i=0; omodes[i].name; i++) | |
360 | if (eq(omodes[i].name, *argv)) { | |
361 | t.c_oflag &= ~omodes[i].unset; | |
362 | t.c_oflag |= omodes[i].set; | |
363 | goto next; | |
16b6b22b | 364 | } |
2ea9e68e MT |
365 | for (i=0; cmodes[i].name; i++) |
366 | if (eq(cmodes[i].name, *argv)) { | |
367 | t.c_cflag &= ~cmodes[i].unset; | |
368 | t.c_cflag |= cmodes[i].set; | |
369 | goto next; | |
370 | } | |
371 | for (i=0; lmodes[i].name; i++) | |
372 | if (eq(lmodes[i].name, *argv)) { | |
373 | t.c_lflag &= ~lmodes[i].unset; | |
374 | t.c_lflag |= lmodes[i].set; | |
375 | goto next; | |
376 | } | |
377 | for (i=0; *cchars[i].names; i++) { | |
378 | char **cp = cchars[i].names; | |
379 | while (*cp) { | |
380 | if (eq(*cp, *argv)) { | |
381 | if (*++argv == 0) | |
382 | goto setit; | |
383 | if (eq(*argv, "undef") || | |
384 | eq(*argv, "disable")) | |
385 | t.c_cc[cchars[i].sub] = | |
386 | _POSIX_VDISABLE; | |
387 | else if (**argv == '^') | |
388 | t.c_cc[cchars[i].sub] = | |
389 | ((*argv)[1] == '?') ? 0177 : | |
390 | ((*argv)[1] == '-') ? | |
391 | _POSIX_VDISABLE : | |
392 | (*argv)[1] & 037; | |
393 | else | |
394 | t.c_cc[cchars[i].sub] = **argv; | |
395 | goto next; | |
16b6b22b | 396 | } |
2ea9e68e | 397 | cp++; |
16b6b22b | 398 | } |
2ea9e68e MT |
399 | } |
400 | if (isdigit(**argv)) { | |
401 | cfsetospeed(&t, atoi(*argv)); | |
402 | cfsetispeed(&t, atoi(*argv)); | |
403 | goto next; | |
404 | } | |
405 | /* didn't match anything */ | |
406 | errexit("unknown option: %s", *argv); | |
407 | exit(1); | |
408 | next: | |
409 | argv++; | |
16b6b22b | 410 | } |
2ea9e68e MT |
411 | setit: |
412 | if (tcsetattr(ctl, 0, &t) < 0) | |
413 | syserrexit("tcsetattr"); | |
414 | if (ioctl(ctl, TIOCSWINSZ, &win) < 0) | |
415 | warning("can't set window size"); | |
416 | ||
417 | exit(0); | |
16b6b22b BJ |
418 | } |
419 | ||
2ea9e68e | 420 | gfmtset() { |
16b6b22b BJ |
421 | } |
422 | ||
2ea9e68e MT |
423 | prmode(tp, ldisc, fmt) |
424 | struct termios *tp; | |
16b6b22b | 425 | { |
2ea9e68e MT |
426 | long i = tp->c_iflag, |
427 | o = tp->c_oflag, | |
428 | c = tp->c_cflag, | |
429 | l = tp->c_lflag; | |
430 | u_char *cc = tp->c_cc; | |
431 | int ispeed = cfgetispeed(tp), | |
432 | ospeed = cfgetospeed(tp); | |
433 | char unknown[32], | |
434 | *ld; | |
435 | char *ccval(); | |
436 | ||
16b6b22b | 437 | |
2ea9e68e MT |
438 | /* |
439 | * line discipline | |
440 | */ | |
441 | if (ldisc != TTYDISC) { | |
442 | switch(ldisc) { | |
443 | case TABLDISC: | |
444 | ld = "tablet"; | |
445 | break; | |
446 | case SLIPDISC: | |
b24648a6 | 447 | ld = "slip"; |
16b6b22b | 448 | break; |
2ea9e68e MT |
449 | default: |
450 | sprintf(unknown, "#%d", ldisc); | |
451 | ld = unknown; | |
16b6b22b | 452 | } |
2ea9e68e MT |
453 | put("%s disc; ", ld); |
454 | } | |
455 | /* | |
456 | * line speed | |
457 | */ | |
458 | if (ispeed != ospeed) | |
459 | put("ispeed %d baud; ospeed %d baud;", | |
460 | ispeed, ospeed); | |
461 | else | |
462 | put("speed %d baud;", ispeed); | |
463 | if (fmt) | |
464 | put(" %d rows; %d columns;", win.ws_row, win.ws_col); | |
465 | put("\n"); | |
466 | ||
467 | #define lput(n, f, d) if (fmt || on(f) != d) mdput(n+on(f)) | |
468 | /* | |
469 | * "local" flags | |
470 | */ | |
471 | #define on(f) ((l&f) != 0) | |
472 | if (debug) mdput("LFLAG: "); | |
473 | lput("-icanon ",ICANON, 1); | |
474 | lput("-isig ", ISIG, 1); | |
475 | lput("-iexten ", IEXTEN, 1); | |
476 | lput("-echo ",ECHO, 1); | |
477 | lput("-echoe ",ECHOE, 0); | |
478 | lput("-echok ",ECHOK, 0); | |
479 | lput("-echoke ",ECHOKE, 0); | |
480 | lput("-echonl ",ECHONL, 0); | |
481 | lput("-echoctl ",ECHOCTL, 0); | |
482 | lput("-echoprt ",ECHOPRT, 0); | |
483 | lput("-altwerase ",ALTWERASE, 0); | |
484 | lput("-noflsh ",NOFLSH, 0); | |
485 | lput("-tostop ",TOSTOP, 0); | |
486 | lput("-mdmbuf ",MDMBUF, 0); | |
487 | lput("-nohang ",NOHANG, 0); | |
488 | lput("-flusho ",FLUSHO, 0); | |
489 | lput("-pendin ",PENDIN, 0); | |
490 | /* | |
491 | * input flags | |
492 | */ | |
493 | #undef on | |
494 | #define on(f) ((i&f) != 0) | |
495 | mdput(0); | |
496 | if (debug) mdput("IFLAG: "); | |
497 | lput("-istrip ", ISTRIP, 0); | |
498 | lput("-icrnl ", ICRNL, 1); | |
499 | lput("-inlcr ", INLCR, 0); | |
500 | lput("-igncr ", IGNCR, 0); | |
501 | lput("-ixon ", IXON, 1); | |
502 | lput("-ixoff ", IXOFF, 0); | |
503 | lput("-ixany ", IXANY, 1); | |
504 | lput("-imaxbel ", IMAXBEL, 1); | |
505 | lput("-ignbrk ", IGNBRK, 0); | |
506 | lput("-brkint ", BRKINT, 1); | |
507 | lput("-inpck ", INPCK, 0); | |
508 | lput("-ignpar ", IGNPAR, 0); | |
509 | lput("-parmrk ", PARMRK, 0); | |
510 | #undef on | |
511 | /* | |
512 | * output flags | |
513 | */ | |
514 | #define on(f) ((o&f) != 0) | |
515 | mdput(0); | |
516 | if (debug) mdput("OFLAG: "); | |
517 | lput("-opost ", OPOST, 1); | |
518 | lput("-onlcr ", ONLCR, 1); | |
519 | lput("-oxtabs ", OXTABS, 1); | |
520 | #undef on | |
521 | /* | |
522 | * control flags (hardware state) | |
523 | */ | |
524 | #define on(f) ((c&f) != 0) | |
525 | mdput(0); | |
526 | if (debug) mdput("CFLAG: "); | |
527 | lput("-cread ", CREAD, 1); | |
528 | switch(c&CSIZE) { | |
529 | case CS5: mdput("cs5 "); break; | |
530 | case CS6: mdput("cs6 "); break; | |
531 | case CS7: mdput("cs7 "); break; | |
532 | case CS8: mdput("cs8 "); break; | |
533 | } | |
534 | mdput("-parenb "+on(PARENB)); | |
535 | lput("-parodd ", PARODD, 0); | |
536 | lput("-hupcl ", HUPCL, 1); | |
537 | lput("-clocal ", CLOCAL, 0); | |
538 | lput("-cstopb ", CSTOPB, 0); | |
539 | lput("-crtscts ", CRTSCTS, 0); | |
540 | mdput(0); | |
541 | #undef on | |
542 | /* | |
543 | * special control characters | |
544 | */ | |
545 | if (debug) mdput("CCHARS: "); | |
546 | if (fmt != 2) { | |
547 | for (i=0; *cchars[i].names; i++) { | |
548 | char temp[64]; | |
549 | ||
550 | if (fmt || cc[cchars[i].sub] != cchars[i].def) { | |
551 | sprintf(temp, "%s = %s; ", *cchars[i].names, | |
552 | ccval(cc[cchars[i].sub]), fmt); | |
553 | mdput(temp); | |
554 | } | |
16b6b22b | 555 | } |
2ea9e68e MT |
556 | mdput(0); |
557 | } else { | |
558 | for (i=0; *cchars[i].names; i++) | |
559 | put("%*s", strlen(*(cchars[i].names+1)) + (i>0?1:0), | |
560 | *(cchars[i].names+1)); | |
561 | printf("\n"); | |
562 | for (i=0; *cchars[i].names; i++) | |
563 | put("%*s", strlen(*(cchars[i].names+1)) + (i>0?1:0), | |
564 | ccval(cc[cchars[i].sub], fmt)); | |
565 | printf("\n"); | |
16b6b22b BJ |
566 | } |
567 | } | |
568 | ||
2ea9e68e MT |
569 | /* |
570 | * gross, but since we're changing the control descriptor | |
571 | * from 1 to 0, most users will be probably be doing | |
572 | * "stty > /dev/sometty" by accident. If 1 and 2 are both ttys, | |
573 | * but not the same, assume that 1 was incorrectly redirected. | |
574 | */ | |
575 | checkredirect() { | |
576 | struct stat st1, st2; | |
577 | ||
578 | if (isatty(1) && isatty(2) && fstat(1, &st1) != -1 && | |
579 | fstat(2, &st2) != -1 && (st1.st_rdev != st2.st_rdev)) | |
580 | warning("stdout appears redirected, but stdin is the control descriptor"); | |
581 | } | |
2ea9e68e | 582 | |
b24648a6 | 583 | char * |
2ea9e68e MT |
584 | ccval(c, fmt) |
585 | unsigned char c; | |
16b6b22b | 586 | { |
2ea9e68e MT |
587 | static char buf[128]; |
588 | char *bp; | |
589 | ||
590 | *buf = 0, bp = buf; | |
591 | if (c == _POSIX_VDISABLE) | |
592 | if (fmt == 2) | |
593 | return("<u>"); | |
594 | else | |
595 | return("<undef>"); | |
596 | if (c & 0200) { | |
597 | strcat(buf, "M-"); | |
598 | *bp++ = 'M'; | |
599 | *bp++ = '-'; | |
600 | c &= 0177; | |
601 | } | |
602 | if (c == 0177) { | |
603 | *bp++ = '^'; | |
604 | *bp++ = '?'; | |
16b6b22b | 605 | } |
2ea9e68e MT |
606 | else if (c < 040) { |
607 | *bp++ = '^'; | |
608 | *bp++ = c + '@'; | |
16b6b22b | 609 | } |
2ea9e68e MT |
610 | else |
611 | *bp++ = c; | |
612 | *bp = 0; | |
613 | return(buf); | |
16b6b22b BJ |
614 | } |
615 | ||
b24648a6 | 616 | |
2ea9e68e MT |
617 | mdput(s) |
618 | char *s; | |
16b6b22b | 619 | { |
2ea9e68e | 620 | static int col = 0; |
16b6b22b | 621 | |
2ea9e68e MT |
622 | if (s == (char *)0) { |
623 | if (col) { | |
624 | put("\n"); | |
625 | col = 0; | |
626 | } | |
16b6b22b BJ |
627 | return; |
628 | } | |
2ea9e68e MT |
629 | if ((col += strlen(s)) > WRAPCOL) { |
630 | put("\n"); | |
631 | col = strlen(s); | |
16b6b22b | 632 | } |
2ea9e68e | 633 | put(s); |
16b6b22b BJ |
634 | } |
635 | ||
b24648a6 MT |
636 | #include <varargs.h> |
637 | ||
638 | put(va_alist) | |
639 | va_dcl | |
16b6b22b | 640 | { |
b24648a6 MT |
641 | char *fmt; |
642 | va_list ap; | |
643 | ||
644 | va_start(ap); | |
645 | fmt = va_arg(ap, char *); | |
646 | (void) vfprintf(OUT, fmt, ap); | |
647 | va_end(ap); | |
16b6b22b BJ |
648 | } |
649 | ||
b24648a6 MT |
650 | |
651 | warning(va_alist) | |
652 | va_dcl | |
2ea9e68e | 653 | { |
b24648a6 MT |
654 | char *fmt; |
655 | va_list ap; | |
656 | ||
2ea9e68e | 657 | fprintf(ERR, "stty: warning: "); |
b24648a6 MT |
658 | va_start(ap); |
659 | fmt = va_arg(ap, char *); | |
660 | (void) vfprintf(ERR, fmt, ap); | |
661 | va_end(ap); | |
2ea9e68e MT |
662 | fprintf(ERR, "\n"); |
663 | } | |
16b6b22b | 664 | |
b24648a6 MT |
665 | |
666 | errexit(va_alist) | |
667 | va_dcl | |
16b6b22b | 668 | { |
b24648a6 MT |
669 | char *fmt; |
670 | va_list ap; | |
671 | ||
2ea9e68e | 672 | fprintf(ERR, "stty: "); |
b24648a6 MT |
673 | va_start(ap); |
674 | fmt = va_arg(ap, char *); | |
675 | (void) vfprintf(ERR, fmt, ap); | |
676 | va_end(ap); | |
2ea9e68e MT |
677 | fprintf(ERR, "\n"); |
678 | exit(1); | |
679 | } | |
16b6b22b | 680 | |
b24648a6 MT |
681 | |
682 | syserrexit(va_alist) | |
683 | va_dcl | |
2ea9e68e | 684 | { |
b24648a6 MT |
685 | char *fmt; |
686 | va_list ap; | |
687 | ||
2ea9e68e | 688 | fprintf(ERR, "stty: "); |
b24648a6 MT |
689 | va_start(ap); |
690 | fmt = va_arg(ap, char *); | |
691 | (void) vfprintf(ERR, fmt, ap); | |
692 | va_end(ap); | |
693 | fprintf(ERR, ": %s\n", strerror(errno)); | |
2ea9e68e | 694 | exit(1); |
16b6b22b | 695 | } |