diagnostic comment only works for Bourne Shell
[unix-history] / usr / src / bin / stty / stty.c
... / ...
CommitLineData
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
7#ifndef lint
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
14static char sccsid[] = "@(#)stty.c 5.5 (Berkeley) %G%";
15#endif not lint
16
17/*
18 * set teletype modes
19 */
20
21#include <stdio.h>
22#include <sys/ioctl.h>
23
24struct
25{
26 char *string;
27 int speed;
28} speeds[] = {
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,
49};
50struct
51{
52 char *string;
53 int set;
54 int reset;
55 int lset;
56 int lreset;
57} modes[] = {
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,
119 "pass8", 0, 0, LPASS8, 0,
120 "-pass8", 0, 0, 0, LPASS8,
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,
127#ifdef notdef
128 "etxack", 0, 0, LETXACK, 0,
129 "-etxack", 0, 0, 0, LETXACK,
130#endif
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,
140};
141
142struct tchars tc;
143struct ltchars ltc;
144struct sgttyb mode;
145struct winsize win;
146int lmode;
147int oldisc, ldisc;
148
149struct special {
150 char *name;
151 char *cp;
152 char def;
153} special[] = {
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,
168 0
169};
170char *arg;
171
172int argc;
173char **argv;
174main(iargc, iargv)
175char **iargv;
176{
177 int i;
178 register struct special *sp;
179 char obuf[BUFSIZ];
180
181 setbuf(stderr, obuf);
182 argc = iargc;
183 argv = iargv;
184 ioctl(1, TIOCGETP, &mode);
185 ioctl(1, TIOCGETD, &ldisc);
186 oldisc = ldisc;
187 ioctl(1, TIOCGETC, &tc);
188 ioctl(1, TIOCLGET, &lmode);
189 ioctl(1, TIOCGLTC, &ltc);
190 ioctl(1, TIOCGWINSZ, &win);
191 if(argc == 1) {
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 }
203/*
204 if (argc == 2 && !strcmp(argv[1], "all")) {
205 prmodes(2);
206 exit(0);
207 }
208*/
209 while(--argc > 0) {
210 arg = *++argv;
211 if (eq("ek")){
212 mode.sg_erase = '#';
213 mode.sg_kill = '@';
214 continue;
215 }
216 if (eq("new")){
217 ldisc = NTTYDISC;
218 if (ioctl(1, TIOCSETD, &ldisc)<0)
219 perror("ioctl");
220 continue;
221 }
222 if (eq("newcrt")){
223 ldisc = NTTYDISC;
224 lmode &= ~LPRTERA;
225 lmode |= LCRTBS|LCTLECH;
226 if (mode.sg_ospeed >= B1200)
227 lmode |= LCRTERA|LCRTKIL;
228 if (ioctl(1, TIOCSETD, &ldisc)<0)
229 perror("ioctl");
230 continue;
231 }
232 if (eq("crt")){
233 lmode &= ~LPRTERA;
234 lmode |= LCRTBS|LCTLECH;
235 if (mode.sg_ospeed >= B1200)
236 lmode |= LCRTERA|LCRTKIL;
237 continue;
238 }
239 if (eq("old")){
240 ldisc = 0;
241 if (ioctl(1, TIOCSETD, &ldisc)<0)
242 perror("ioctl");
243 continue;
244 }
245 if (eq("dec")){
246 mode.sg_erase = 0177;
247 mode.sg_kill = CKILL;
248 tc.t_intrc = CINTR;
249 ldisc = NTTYDISC;
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)
255 perror("ioctl");
256 continue;
257 }
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 == '^')
265 *sp->cp = ((*argv)[1] == '?') ?
266 0177 : (*argv)[1] & 037;
267 else
268 *sp->cp = **argv;
269 goto cont;
270 }
271 if (eq("gspeed")) {
272 mode.sg_ispeed = B300;
273 mode.sg_ospeed = B9600;
274 continue;
275 }
276 if (eq("hup")) {
277 ioctl(1, TIOCHPCL, NULL);
278 continue;
279 }
280 if (eq("rows")) {
281 if (--argc == 0)
282 goto done;
283 win.ws_row = atoi(*++argv);
284 }
285 if (eq("cols") || eq("columns")) {
286 if (--argc == 0)
287 goto done;
288 win.ws_col = atoi(*++argv);
289 }
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 }
295 for(i=0; speeds[i].string; i++)
296 if(eq(speeds[i].string)) {
297 mode.sg_ispeed = mode.sg_ospeed = speeds[i].speed;
298 goto cont;
299 }
300 if (eq("speed")) {
301 ioctl(open("/dev/tty", 0), TIOCGETP, &mode);
302 for(i=0; speeds[i].string; i++)
303 if (mode.sg_ospeed == speeds[i].speed) {
304 printf("%s\n", speeds[i].string);
305 exit(0);
306 }
307 printf("unknown\n");
308 exit(1);
309 }
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;
316 }
317 if(arg)
318 fprintf(stderr,"unknown mode: %s\n", arg);
319cont:
320 ;
321 }
322done:
323 ioctl(1, TIOCSETN, &mode);
324 ioctl(1, TIOCSETC, &tc);
325 ioctl(1, TIOCSLTC, &ltc);
326 ioctl(1, TIOCLSET, &lmode);
327 ioctl(1, TIOCSWINSZ, &win);
328}
329
330eq(string)
331char *string;
332{
333 int i;
334
335 if(!arg)
336 return(0);
337 i = 0;
338loop:
339 if(arg[i] != string[i])
340 return(0);
341 if(arg[i++] != '\0')
342 goto loop;
343 arg = 0;
344 return(1);
345}
346
347prmodes(all)
348{
349 register m;
350 int any;
351
352 if(ldisc==NETLDISC)
353 fprintf(stderr, "net discipline, ");
354 else if(ldisc==NTTYDISC)
355 fprintf(stderr, "new tty, ");
356 else if(all==2)
357 fprintf(stderr, "old tty, ");
358 if(mode.sg_ispeed != mode.sg_ospeed) {
359 prspeed("input speed ", mode.sg_ispeed);
360 prspeed("output speed ", mode.sg_ospeed);
361 } else
362 prspeed("speed ", mode.sg_ispeed);
363 if (all)
364 fprintf(stderr, ", %d rows, %d columns", win.ws_row, win.ws_col);
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 ");
370 }
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");
394 if (all)
395 fprintf(stderr,"\n");
396#define lpit(what,str) \
397 if (all==2||(lmode&what)) { \
398 fprintf(stderr,str+((lmode&what)!=0)); any++; \
399 }
400 if (ldisc == NTTYDISC) {
401 int newcrt = (lmode&(LCTLECH|LCRTBS)) == (LCTLECH|LCRTBS) &&
402 (lmode&(LCRTERA|LCRTKIL)) ==
403 ((mode.sg_ospeed > B300) ? LCRTERA|LCRTKIL : 0);
404 int nothing = 1;
405 if (newcrt) {
406 if (all==2)
407 fprintf(stderr, "crt: (crtbs crterase crtkill ctlecho) ");
408 else
409 fprintf(stderr, "crt ");
410 any++;
411 } else {
412 lpit(LCRTBS, "-crtbs ");
413 lpit(LCRTERA, "-crterase ");
414 lpit(LCRTKIL, "-crtkill ");
415 lpit(LCTLECH, "-ctlecho ");
416 lpit(LPRTERA, "-prterase ");
417 }
418 lpit(LTOSTOP, "-tostop ");
419 if (all==2) {
420 fprintf(stderr, "\n");
421 any = 0;
422 nothing = 0;
423 }
424 lpit(LTILDE, "-tilde ");
425 lpit(LFLUSHO, "-flusho ");
426 lpit(LMDMBUF, "-mdmbuf ");
427 lpit(LLITOUT, "-litout ");
428 lpit(LPASS8, "-pass8 ");
429 lpit(LNOHANG, "-nohang ");
430 if (any) {
431 fprintf(stderr,"\n");
432 any = 0;
433 nothing = 0;
434 }
435#ifdef notdef
436 lpit(LETXACK, "-etxack ");
437#endif
438 lpit(LPENDIN, "-pendin ");
439 lpit(LDECCTQ, "-decctlq ");
440 lpit(LNOFLSH, "-noflsh ");
441 if (any || nothing)
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");
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);
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");
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);
476 fprintf(stderr,"\n");
477 break;
478 }
479 } else if (ldisc != NETLDISC) {
480 register struct special *sp;
481 int first = 1;
482
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 };
488 if (sp->cp == &tc.t_brkc && ldisc == 0)
489 break;
490 }
491 if (!first)
492 fprintf(stderr, "\n");
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)
562char *s;
563{
564
565 if(m)
566 fprintf(stderr,"%s%d ", s, m);
567}
568
569int speed[] = {
570 0,50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400
571};
572
573prspeed(c, s)
574char *c;
575{
576
577 fprintf(stderr,"%s%d baud", c, speed[s]);
578}