make ANSI C compatible; use supplied defines
[unix-history] / usr / src / bin / stty / stty.c
CommitLineData
18949a0b
DF
1/*
2 * Copyright (c) 1980 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
ba3dc8b4 7#ifndef lint
18949a0b
DF
8char copyright[] =
9"@(#) Copyright (c) 1980 Regents of the University of California.\n\
10 All rights reserved.\n";
11#endif not lint
12
13#ifndef lint
19f9b1ee 14static char sccsid[] = "@(#)stty.c 5.5 (Berkeley) %G%";
18949a0b
DF
15#endif not lint
16
16b6b22b
BJ
17/*
18 * set teletype modes
19 */
20
21#include <stdio.h>
4f05342b 22#include <sys/ioctl.h>
16b6b22b 23
ba3dc8b4
SL
24struct
25{
16b6b22b
BJ
26 char *string;
27 int speed;
28} speeds[] = {
ba3dc8b4
SL
29 "0", B0,
30 "50", B50,
31 "75", B75,
32 "110", B110,
33 "134", B134,
34 "134.5",B134,
35 "150", B150,
36 "200", B200,
37 "300", B300,
38 "600", B600,
39 "1200", B1200,
40 "1800", B1800,
41 "2400", B2400,
42 "4800", B4800,
43 "9600", B9600,
44 "exta", EXTA,
45 "19200", EXTA,
46 "extb", EXTB,
47 "38400", EXTB,
48 0,
16b6b22b 49};
ba3dc8b4
SL
50struct
51{
16b6b22b 52 char *string;
ba3dc8b4
SL
53 int set;
54 int reset;
55 int lset;
56 int lreset;
16b6b22b 57} modes[] = {
ba3dc8b4
SL
58 "even", EVENP, 0, 0, 0,
59 "-even", 0, EVENP, 0, 0,
60 "odd", ODDP, 0, 0, 0,
61 "-odd", 0, ODDP, 0, 0,
62 "raw", RAW, 0, 0, 0,
63 "-raw", 0, RAW, 0, 0,
64 "cooked", 0, RAW, 0, 0,
65 "-nl", CRMOD, 0, 0, 0,
66 "nl", 0, CRMOD, 0, 0,
67 "echo", ECHO, 0, 0, 0,
68 "-echo", 0, ECHO, 0, 0,
69 "LCASE", LCASE, 0, 0, 0,
70 "lcase", LCASE, 0, 0, 0,
71 "-LCASE", 0, LCASE, 0, 0,
72 "-lcase", 0, LCASE, 0, 0,
73 "-tabs", XTABS, 0, 0, 0,
74 "tabs", 0, XTABS, 0, 0,
75 "tandem", TANDEM, 0, 0, 0,
76 "-tandem", 0, TANDEM, 0, 0,
77 "cbreak", CBREAK, 0, 0, 0,
78 "-cbreak", 0, CBREAK, 0, 0,
79 "cr0", CR0, CR3, 0, 0,
80 "cr1", CR1, CR3, 0, 0,
81 "cr2", CR2, CR3, 0, 0,
82 "cr3", CR3, CR3, 0, 0,
83 "tab0", TAB0, XTABS, 0, 0,
84 "tab1", TAB1, XTABS, 0, 0,
85 "tab2", TAB2, XTABS, 0, 0,
86 "nl0", NL0, NL3, 0, 0,
87 "nl1", NL1, NL3, 0, 0,
88 "nl2", NL2, NL3, 0, 0,
89 "nl3", NL3, NL3, 0, 0,
90 "ff0", FF0, FF1, 0, 0,
91 "ff1", FF1, FF1, 0, 0,
92 "bs0", BS0, BS1, 0, 0,
93 "bs1", BS1, BS1, 0, 0,
94 "33", CR1, ALLDELAY, 0, 0,
95 "tty33", CR1, ALLDELAY, 0, 0,
96 "37", FF1+CR2+TAB1+NL1, ALLDELAY, 0, 0,
97 "tty37", FF1+CR2+TAB1+NL1, ALLDELAY, 0, 0,
98 "05", NL2, ALLDELAY, 0, 0,
99 "vt05", NL2, ALLDELAY, 0, 0,
100 "tn", CR1, ALLDELAY, 0, 0,
101 "tn300", CR1, ALLDELAY, 0, 0,
102 "ti", CR2, ALLDELAY, 0, 0,
103 "ti700", CR2, ALLDELAY, 0, 0,
104 "tek", FF1, ALLDELAY, 0, 0,
105 "crtbs", 0, 0, LCRTBS, LPRTERA,
106 "-crtbs", 0, 0, 0, LCRTBS,
107 "prterase", 0, 0, LPRTERA, LCRTBS+LCRTKIL+LCRTERA,
108 "-prterase", 0, 0, 0, LPRTERA,
109 "crterase", 0, 0, LCRTERA, LPRTERA,
110 "-crterase", 0, 0, 0, LCRTERA,
111 "crtkill", 0, 0, LCRTKIL, LPRTERA,
112 "-crtkill", 0, 0, 0, LCRTKIL,
113 "tilde", 0, 0, LTILDE, 0,
114 "-tilde", 0, 0, 0, LTILDE,
115 "mdmbuf", 0, 0, LMDMBUF, 0,
116 "-mdmbuf", 0, 0, 0, LMDMBUF,
117 "litout", 0, 0, LLITOUT, 0,
118 "-litout", 0, 0, 0, LLITOUT,
b06ffe83
JL
119 "pass8", 0, 0, LPASS8, 0,
120 "-pass8", 0, 0, 0, LPASS8,
ba3dc8b4
SL
121 "tostop", 0, 0, LTOSTOP, 0,
122 "-tostop", 0, 0, 0, LTOSTOP,
123 "flusho", 0, 0, LFLUSHO, 0,
124 "-flusho", 0, 0, 0, LFLUSHO,
125 "nohang", 0, 0, LNOHANG, 0,
126 "-nohang", 0, 0, 0, LNOHANG,
2be6f1d1 127#ifdef notdef
ba3dc8b4
SL
128 "etxack", 0, 0, LETXACK, 0,
129 "-etxack", 0, 0, 0, LETXACK,
2be6f1d1 130#endif
ba3dc8b4
SL
131 "ctlecho", 0, 0, LCTLECH, 0,
132 "-ctlecho", 0, 0, 0, LCTLECH,
133 "pendin", 0, 0, LPENDIN, 0,
134 "-pendin", 0, 0, 0, LPENDIN,
135 "decctlq", 0, 0, LDECCTQ, 0,
136 "-decctlq", 0, 0, 0, LDECCTQ,
137 "noflsh", 0, 0, LNOFLSH, 0,
138 "-noflsh", 0, 0, 0, LNOFLSH,
139 0,
16b6b22b
BJ
140};
141
ba3dc8b4
SL
142struct tchars tc;
143struct ltchars ltc;
144struct sgttyb mode;
4f05342b 145struct winsize win;
ba3dc8b4 146int lmode;
16b6b22b
BJ
147int oldisc, ldisc;
148
16b6b22b
BJ
149struct special {
150 char *name;
151 char *cp;
152 char def;
153} special[] = {
ba3dc8b4
SL
154 "erase", &mode.sg_erase, CERASE,
155 "kill", &mode.sg_kill, CKILL,
156 "intr", &tc.t_intrc, CINTR,
157 "quit", &tc.t_quitc, CQUIT,
158 "start", &tc.t_startc, CSTART,
159 "stop", &tc.t_stopc, CSTOP,
160 "eof", &tc.t_eofc, CEOF,
161 "brk", &tc.t_brkc, CBRK,
162 "susp", &ltc.t_suspc, CSUSP,
163 "dsusp", &ltc.t_dsuspc, CDSUSP,
164 "rprnt", &ltc.t_rprntc, CRPRNT,
165 "flush", &ltc.t_flushc, CFLUSH,
166 "werase", &ltc.t_werasc, CWERASE,
167 "lnext", &ltc.t_lnextc, CLNEXT,
16b6b22b
BJ
168 0
169};
170char *arg;
171
172int argc;
173char **argv;
174main(iargc, iargv)
ba3dc8b4 175char **iargv;
16b6b22b
BJ
176{
177 int i;
178 register struct special *sp;
179 char obuf[BUFSIZ];
180
181 setbuf(stderr, obuf);
182 argc = iargc;
183 argv = iargv;
ba3dc8b4 184 ioctl(1, TIOCGETP, &mode);
16b6b22b
BJ
185 ioctl(1, TIOCGETD, &ldisc);
186 oldisc = ldisc;
ba3dc8b4
SL
187 ioctl(1, TIOCGETC, &tc);
188 ioctl(1, TIOCLGET, &lmode);
189 ioctl(1, TIOCGLTC, &ltc);
4f05342b 190 ioctl(1, TIOCGWINSZ, &win);
ba3dc8b4 191 if(argc == 1) {
16b6b22b
BJ
192 prmodes(0);
193 exit(0);
194 }
195 if (argc == 2 && !strcmp(argv[1], "all")) {
196 prmodes(1);
197 exit(0);
198 }
199 if (argc == 2 && !strcmp(argv[1], "everything")) {
200 prmodes(2);
201 exit(0);
202 }
ba3dc8b4
SL
203/*
204 if (argc == 2 && !strcmp(argv[1], "all")) {
205 prmodes(2);
206 exit(0);
207 }
208*/
209 while(--argc > 0) {
16b6b22b 210 arg = *++argv;
ba3dc8b4
SL
211 if (eq("ek")){
212 mode.sg_erase = '#';
213 mode.sg_kill = '@';
16b6b22b
BJ
214 continue;
215 }
ba3dc8b4 216 if (eq("new")){
16b6b22b 217 ldisc = NTTYDISC;
ba3dc8b4 218 if (ioctl(1, TIOCSETD, &ldisc)<0)
16b6b22b
BJ
219 perror("ioctl");
220 continue;
221 }
ba3dc8b4 222 if (eq("newcrt")){
16b6b22b 223 ldisc = NTTYDISC;
ba3dc8b4
SL
224 lmode &= ~LPRTERA;
225 lmode |= LCRTBS|LCTLECH;
226 if (mode.sg_ospeed >= B1200)
227 lmode |= LCRTERA|LCRTKIL;
228 if (ioctl(1, TIOCSETD, &ldisc)<0)
16b6b22b
BJ
229 perror("ioctl");
230 continue;
231 }
ba3dc8b4
SL
232 if (eq("crt")){
233 lmode &= ~LPRTERA;
234 lmode |= LCRTBS|LCTLECH;
235 if (mode.sg_ospeed >= B1200)
236 lmode |= LCRTERA|LCRTKIL;
16b6b22b
BJ
237 continue;
238 }
ba3dc8b4
SL
239 if (eq("old")){
240 ldisc = 0;
241 if (ioctl(1, TIOCSETD, &ldisc)<0)
16b6b22b
BJ
242 perror("ioctl");
243 continue;
244 }
ba3dc8b4
SL
245 if (eq("dec")){
246 mode.sg_erase = 0177;
19f9b1ee
KB
247 mode.sg_kill = CKILL;
248 tc.t_intrc = CINTR;
5e9810bc 249 ldisc = NTTYDISC;
ba3dc8b4
SL
250 lmode &= ~LPRTERA;
251 lmode |= LCRTBS|LCTLECH|LDECCTQ;
252 if (mode.sg_ospeed >= B1200)
253 lmode |= LCRTERA|LCRTKIL;
254 if (ioctl(1, TIOCSETD, &ldisc)<0)
5e9810bc
BJ
255 perror("ioctl");
256 continue;
257 }
16b6b22b
BJ
258 for (sp = special; sp->name; sp++)
259 if (eq(sp->name)) {
260 if (--argc == 0)
261 goto done;
262 if (**++argv == 'u')
263 *sp->cp = 0377;
264 else if (**argv == '^')
49d29e41 265 *sp->cp = ((*argv)[1] == '?') ?
16b6b22b
BJ
266 0177 : (*argv)[1] & 037;
267 else
268 *sp->cp = **argv;
269 goto cont;
270 }
271 if (eq("gspeed")) {
ba3dc8b4
SL
272 mode.sg_ispeed = B300;
273 mode.sg_ospeed = B9600;
16b6b22b
BJ
274 continue;
275 }
276 if (eq("hup")) {
ba3dc8b4 277 ioctl(1, TIOCHPCL, NULL);
16b6b22b
BJ
278 continue;
279 }
4f05342b
JB
280 if (eq("rows")) {
281 if (--argc == 0)
282 goto done;
283 win.ws_row = atoi(*++argv);
284 }
9cc510cb 285 if (eq("cols") || eq("columns")) {
4f05342b
JB
286 if (--argc == 0)
287 goto done;
288 win.ws_col = atoi(*++argv);
289 }
d6f0b7e6
MK
290 if (eq("size")) {
291 ioctl(open("/dev/tty", 0), TIOCGWINSZ, &win);
292 printf("%d %d\n", win.ws_row, win.ws_col);
293 exit(0);
294 }
ba3dc8b4
SL
295 for(i=0; speeds[i].string; i++)
296 if(eq(speeds[i].string)) {
297 mode.sg_ispeed = mode.sg_ospeed = speeds[i].speed;
16b6b22b
BJ
298 goto cont;
299 }
300 if (eq("speed")) {
ba3dc8b4
SL
301 ioctl(open("/dev/tty", 0), TIOCGETP, &mode);
302 for(i=0; speeds[i].string; i++)
303 if (mode.sg_ospeed == speeds[i].speed) {
16b6b22b
BJ
304 printf("%s\n", speeds[i].string);
305 exit(0);
306 }
307 printf("unknown\n");
308 exit(1);
309 }
ba3dc8b4
SL
310 for(i=0; modes[i].string; i++)
311 if(eq(modes[i].string)) {
312 mode.sg_flags &= ~modes[i].reset;
313 mode.sg_flags |= modes[i].set;
314 lmode &= ~modes[i].lreset;
315 lmode |= modes[i].lset;
16b6b22b 316 }
ba3dc8b4 317 if(arg)
16b6b22b
BJ
318 fprintf(stderr,"unknown mode: %s\n", arg);
319cont:
320 ;
321 }
322done:
ba3dc8b4
SL
323 ioctl(1, TIOCSETN, &mode);
324 ioctl(1, TIOCSETC, &tc);
325 ioctl(1, TIOCSLTC, &ltc);
326 ioctl(1, TIOCLSET, &lmode);
4f05342b 327 ioctl(1, TIOCSWINSZ, &win);
16b6b22b
BJ
328}
329
330eq(string)
ba3dc8b4 331char *string;
16b6b22b
BJ
332{
333 int i;
334
ba3dc8b4
SL
335 if(!arg)
336 return(0);
16b6b22b
BJ
337 i = 0;
338loop:
ba3dc8b4 339 if(arg[i] != string[i])
16b6b22b 340 return(0);
ba3dc8b4 341 if(arg[i++] != '\0')
16b6b22b
BJ
342 goto loop;
343 arg = 0;
ba3dc8b4 344 return(1);
16b6b22b
BJ
345}
346
347prmodes(all)
348{
349 register m;
350 int any;
351
ba3dc8b4 352 if(ldisc==NETLDISC)
16b6b22b 353 fprintf(stderr, "net discipline, ");
ba3dc8b4 354 else if(ldisc==NTTYDISC)
16b6b22b 355 fprintf(stderr, "new tty, ");
ba3dc8b4 356 else if(all==2)
16b6b22b 357 fprintf(stderr, "old tty, ");
ba3dc8b4
SL
358 if(mode.sg_ispeed != mode.sg_ospeed) {
359 prspeed("input speed ", mode.sg_ispeed);
360 prspeed("output speed ", mode.sg_ospeed);
16b6b22b 361 } else
ba3dc8b4 362 prspeed("speed ", mode.sg_ispeed);
4f05342b
JB
363 if (all)
364 fprintf(stderr, ", %d rows, %d columns", win.ws_row, win.ws_col);
ba3dc8b4
SL
365 fprintf(stderr, all==2 ? "\n" : "; ");
366 m = mode.sg_flags;
367 if(all==2 || (m&(EVENP|ODDP))!=(EVENP|ODDP)) {
368 if(m & EVENP) fprintf(stderr,"even ");
369 if(m & ODDP) fprintf(stderr,"odd ");
16b6b22b 370 }
ba3dc8b4
SL
371 if(all==2 || m&RAW)
372 fprintf(stderr,"-raw "+((m&RAW)!=0));
373 if(all==2 || (m&CRMOD)==0)
374 fprintf(stderr,"-nl "+((m&CRMOD)==0));
375 if(all==2 || (m&ECHO)==0)
376 fprintf(stderr,"-echo "+((m&ECHO)!=0));
377 if(all==2 || (m&LCASE))
378 fprintf(stderr,"-lcase "+((m&LCASE)!=0));
379 if(all==2 || (m&TANDEM))
380 fprintf(stderr,"-tandem "+((m&TANDEM)!=0));
381 fprintf(stderr,"-tabs "+((m&XTABS)!=XTABS));
382 if(all==2 || (m&CBREAK))
383 fprintf(stderr,"-cbreak "+((m&CBREAK)!=0));
384 if(all==2 || (m&NLDELAY))
385 delay((m&NLDELAY)/NL1, "nl");
386 if ((m&TBDELAY)!=XTABS)
387 delay((m&TBDELAY)/TAB1, "tab");
388 if(all==2 || (m&CRDELAY))
389 delay((m&CRDELAY)/CR1, "cr");
390 if(all==2 || (m&VTDELAY))
391 delay((m&VTDELAY)/FF1, "ff");
392 if(all==2 || (m&BSDELAY))
393 delay((m&BSDELAY)/BS1, "bs");
16b6b22b
BJ
394 if (all)
395 fprintf(stderr,"\n");
396#define lpit(what,str) \
ba3dc8b4
SL
397 if (all==2||(lmode&what)) { \
398 fprintf(stderr,str+((lmode&what)!=0)); any++; \
16b6b22b
BJ
399 }
400 if (ldisc == NTTYDISC) {
ba3dc8b4
SL
401 int newcrt = (lmode&(LCTLECH|LCRTBS)) == (LCTLECH|LCRTBS) &&
402 (lmode&(LCRTERA|LCRTKIL)) ==
403 ((mode.sg_ospeed > B300) ? LCRTERA|LCRTKIL : 0);
74a327ac 404 int nothing = 1;
16b6b22b 405 if (newcrt) {
ba3dc8b4
SL
406 if (all==2)
407 fprintf(stderr, "crt: (crtbs crterase crtkill ctlecho) ");
408 else
409 fprintf(stderr, "crt ");
16b6b22b
BJ
410 any++;
411 } else {
ba3dc8b4
SL
412 lpit(LCRTBS, "-crtbs ");
413 lpit(LCRTERA, "-crterase ");
414 lpit(LCRTKIL, "-crtkill ");
415 lpit(LCTLECH, "-ctlecho ");
416 lpit(LPRTERA, "-prterase ");
16b6b22b 417 }
ba3dc8b4
SL
418 lpit(LTOSTOP, "-tostop ");
419 if (all==2) {
16b6b22b
BJ
420 fprintf(stderr, "\n");
421 any = 0;
74a327ac 422 nothing = 0;
16b6b22b 423 }
ba3dc8b4
SL
424 lpit(LTILDE, "-tilde ");
425 lpit(LFLUSHO, "-flusho ");
426 lpit(LMDMBUF, "-mdmbuf ");
427 lpit(LLITOUT, "-litout ");
b06ffe83 428 lpit(LPASS8, "-pass8 ");
ba3dc8b4 429 lpit(LNOHANG, "-nohang ");
7ef182e7
BJ
430 if (any) {
431 fprintf(stderr,"\n");
432 any = 0;
74a327ac 433 nothing = 0;
7ef182e7 434 }
2be6f1d1 435#ifdef notdef
ba3dc8b4 436 lpit(LETXACK, "-etxack ");
2be6f1d1 437#endif
ba3dc8b4
SL
438 lpit(LPENDIN, "-pendin ");
439 lpit(LDECCTQ, "-decctlq ");
440 lpit(LNOFLSH, "-noflsh ");
74a327ac 441 if (any || nothing)
16b6b22b
BJ
442 fprintf(stderr,"\n");
443 } else if (!all)
444 fprintf(stderr,"\n");
445 if (all) {
446 switch (ldisc) {
447
448 case 0:
449 fprintf(stderr,"\
450erase kill intr quit stop eof\
451\n");
ba3dc8b4
SL
452 pcol(mode.sg_erase, -1);
453 pcol(mode.sg_kill, -1);
454 pcol(tc.t_intrc, -1);
455 pcol(tc.t_quitc, -1);
456 pcol(tc.t_stopc, tc.t_startc);
457 pcol(tc.t_eofc, tc.t_brkc);
16b6b22b
BJ
458 fprintf(stderr,"\n");
459 break;
460
461 case NTTYDISC:
462 fprintf(stderr,"\
463erase kill werase rprnt flush lnext susp intr quit stop eof\
464\n");
ba3dc8b4
SL
465 pcol(mode.sg_erase, -1);
466 pcol(mode.sg_kill, -1);
467 pcol(ltc.t_werasc, -1);
468 pcol(ltc.t_rprntc, -1);
469 pcol(ltc.t_flushc, -1);
470 pcol(ltc.t_lnextc, -1);
471 pcol(ltc.t_suspc, ltc.t_dsuspc);
472 pcol(tc.t_intrc, -1);
473 pcol(tc.t_quitc, -1);
474 pcol(tc.t_stopc, tc.t_startc);
475 pcol(tc.t_eofc, tc.t_brkc);
16b6b22b
BJ
476 fprintf(stderr,"\n");
477 break;
478 }
479 } else if (ldisc != NETLDISC) {
480 register struct special *sp;
481 int first = 1;
74a327ac 482
16b6b22b
BJ
483 for (sp = special; sp->name; sp++) {
484 if ((*sp->cp&0377) != (sp->def&0377)) {
485 pit(*sp->cp, sp->name, first ? "" : ", ");
486 first = 0;
487 };
ba3dc8b4 488 if (sp->cp == &tc.t_brkc && ldisc == 0)
16b6b22b
BJ
489 break;
490 }
74a327ac 491 if (!first)
ba3dc8b4 492 fprintf(stderr, "\n");
16b6b22b
BJ
493 }
494}
495
496pcol(ch1, ch2)
497 int ch1, ch2;
498{
499 int nout = 0;
500
501 ch1 &= 0377;
502 ch2 &= 0377;
503 if (ch1 == ch2)
504 ch2 = 0377;
505 for (; ch1 != 0377 || ch2 != 0377; ch1 = ch2, ch2 = 0377) {
506 if (ch1 == 0377)
507 continue;
508 if (ch1 & 0200) {
509 fprintf(stderr, "M-");
510 nout += 2;
511 ch1 &= ~ 0200;
512 }
513 if (ch1 == 0177) {
514 fprintf(stderr, "^");
515 nout++;
516 ch1 = '?';
517 } else if (ch1 < ' ') {
518 fprintf(stderr, "^");
519 nout++;
520 ch1 += '@';
521 }
522 fprintf(stderr, "%c", ch1);
523 nout++;
524 if (ch2 != 0377) {
525 fprintf(stderr, "/");
526 nout++;
527 }
528 }
529 while (nout < 7) {
530 fprintf(stderr, " ");
531 nout++;
532 }
533}
534
535pit(what, itsname, sep)
536 unsigned what;
537 char *itsname, *sep;
538{
539
540 what &= 0377;
541 fprintf(stderr, "%s%s", sep, itsname);
542 if (what == 0377) {
543 fprintf(stderr, " <undef>");
544 return;
545 }
546 fprintf(stderr, " = ");
547 if (what & 0200) {
548 fprintf(stderr, "M-");
549 what &= ~ 0200;
550 }
551 if (what == 0177) {
552 fprintf(stderr, "^");
553 what = '?';
554 } else if (what < ' ') {
555 fprintf(stderr, "^");
556 what += '@';
557 }
558 fprintf(stderr, "%c", what);
559}
560
561delay(m, s)
ba3dc8b4 562char *s;
16b6b22b
BJ
563{
564
ba3dc8b4 565 if(m)
16b6b22b
BJ
566 fprintf(stderr,"%s%d ", s, m);
567}
568
569int speed[] = {
6bf7d5d9 570 0,50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400
16b6b22b
BJ
571};
572
573prspeed(c, s)
574char *c;
575{
576
577 fprintf(stderr,"%s%d baud", c, speed[s]);
578}