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