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