static char *sccsid ="@(#)stty.c 4.12 (Berkeley) 2/8/83"; /* * set teletype modes */ #include <stdio.h> #include <sgtty.h> struct { char *string; int speed; } speeds[] = { { "0", B0 }, { "50", B50 }, { "75", B75 }, { "110", B110 }, { "134", B134 }, { "134.5", B134 }, { "150", B150 }, { "200", B200 }, { "300", B300 }, { "600", B600 }, { "1200", B1200 }, { "1800", B1800 }, { "2400", B2400 }, { "4800", B4800 }, { "9600", B9600 }, { "exta", EXTA }, { "19200", EXTA }, { "extb", EXTB }, { "38400", EXTB }, { 0 }, }; struct { char *string; long set; long reset; } modes[] = { { "even", EVENP, 0 }, { "-even", 0, EVENP }, { "odd", ODDP, 0 }, { "-odd", 0, ODDP }, { "raw", RAW, 0 }, { "-raw", 0, RAW }, { "cooked", 0, RAW }, { "-nl", CRMOD, 0 }, { "nl", 0, CRMOD }, { "echo", ECHO, 0 }, { "-echo", 0, ECHO }, { "LCASE", LCASE, 0 }, { "lcase", LCASE, 0 }, { "-LCASE", 0, LCASE }, { "-lcase", 0, LCASE }, { "-tabs", XTABS, 0 }, { "tabs", 0, XTABS }, { "tandem", TANDEM, 0 }, { "-tandem", 0, TANDEM }, { "cbreak", CBREAK, 0 }, { "-cbreak", 0, CBREAK }, { "cr0", CR0, CR3 }, { "cr1", CR1, CR3 }, { "cr2", CR2, CR3 }, { "cr3", CR3, CR3 }, { "tab0", TAB0, XTABS }, { "tab1", TAB1, XTABS }, { "tab2", TAB2, XTABS }, { "nl0", NL0, NL3 }, { "nl1", NL1, NL3 }, { "nl2", NL2, NL3 }, { "nl3", NL3, NL3 }, { "ff0", FF0, FF1 }, { "ff1", FF1, FF1 }, { "bs0", BS0, BS1 }, { "bs1", BS1, BS1 }, { "33", CR1, ALLDELAY }, { "tty33", CR1, ALLDELAY }, { "37", FF1+CR2+TAB1+NL1, ALLDELAY }, { "tty37", FF1+CR2+TAB1+NL1, ALLDELAY }, { "05", NL2, ALLDELAY }, { "vt05", NL2, ALLDELAY }, { "tn", CR1, ALLDELAY }, { "tn300", CR1, ALLDELAY }, { "ti", CR2, ALLDELAY }, { "ti700", CR2, ALLDELAY }, { "tek", FF1, ALLDELAY }, { "crtbs", CRTBS, PRTERA }, { "-crtbs", 0, CRTBS }, { "prterase", PRTERA, CRTBS+CRTKIL+CRTERA }, { "-prterase", 0, PRTERA }, { "crterase", CRTERA, PRTERA }, { "-crterase", 0, CRTERA }, { "crtkill", CRTKIL, PRTERA }, { "-crtkill", 0, CRTKIL }, { "tilde", TILDE, 0 }, { "-tilde", 0, TILDE }, { "mdmbuf", MDMBUF, 0 }, { "-mdmbuf", 0, MDMBUF }, { "litout", LITOUT, 0 }, { "-litout", 0, LITOUT }, { "tostop", TOSTOP, 0 }, { "-tostop", 0, TOSTOP }, { "flusho", FLUSHO, 0 }, { "-flusho", 0, FLUSHO }, { "nohang", NOHANG, 0 }, { "-nohang", 0, NOHANG }, #ifdef notdef { "etxack", ETXACK, 0 }, { "-etxack", 0, ETXACK }, #endif { "ctlecho", CTLECH, 0 }, { "-ctlecho", 0, CTLECH }, { "pendin", PENDIN, 0 }, { "-pendin", 0, PENDIN }, { "decctlq", DECCTQ, 0 }, { "-decctlq", 0, DECCTQ }, { "noflsh", NOFLSH, 0 }, { "-noflsh", 0, NOFLSH }, { 0 }, }; struct ttychars tc; struct sgttyb sb; long flags; int oldisc, ldisc; struct special { char *name; char *cp; char def; } special[] = { { "erase", &tc.tc_erase, CERASE }, { "kill", &tc.tc_kill, CKILL }, { "intr", &tc.tc_intrc, CINTR }, { "quit", &tc.tc_quitc, CQUIT }, { "start", &tc.tc_startc, CSTART }, { "stop", &tc.tc_stopc, CSTOP }, { "eof", &tc.tc_eofc, CEOF }, { "brk", &tc.tc_brkc, CBRK }, { "susp", &tc.tc_suspc, CSUSP }, { "dsusp", &tc.tc_dsuspc, CDSUSP }, { "rprnt", &tc.tc_rprntc, CRPRNT }, { "flush", &tc.tc_flushc, CFLUSH }, { "werase", &tc.tc_werasc, CWERASE }, { "lnext", &tc.tc_lnextc, CLNEXT }, 0 }; char *arg; int argc; char **argv; main(iargc, iargv) int iargc; char *iargv[]; { int i; register struct special *sp; char obuf[BUFSIZ]; setbuf(stderr, obuf); argc = iargc; argv = iargv; ioctl(1, TIOCCGET, (char *)&tc); ioctl(1, TIOCGET, (char *)&flags); ioctl(1, TIOCGETD, &ldisc); #ifndef notdef ioctl(1, TIOCGETP, (char *)&sb); #endif oldisc = ldisc; if (argc == 1) { prmodes(0); exit(0); } if (argc == 2 && !strcmp(argv[1], "all")) { prmodes(1); exit(0); } if (argc == 2 && !strcmp(argv[1], "everything")) { prmodes(2); exit(0); } while (--argc > 0) { arg = *++argv; if (eq("ek")) { tc.tc_erase = '#'; tc.tc_kill = '@'; continue; } if (eq("new")) { ldisc = NTTYDISC; if (ioctl(1, TIOCSETD, &ldisc) < 0) perror("ioctl"); continue; } if (eq("newcrt")) { ldisc = NTTYDISC; flags &= ~PRTERA; flags |= CRTBS|CTLECH; if (sb.sg_ospeed >= B1200) flags |= CRTERA|CRTKIL; if (ioctl(1, TIOCSETD, &ldisc) < 0) perror("ioctl"); continue; } if (eq("crt")) { flags &= ~PRTERA; flags |= CRTBS|CTLECH; if (sb.sg_ospeed >= B1200) flags |= CRTERA|CRTKIL; continue; } if (eq("old")) { ldisc = OTTYDISC; if (ioctl(1, TIOCSETD, &ldisc) < 0) perror("ioctl"); continue; } if (eq("dec")) { tc.tc_erase = 0177; tc.tc_kill = CTRL(u); tc.tc_intrc = CTRL(c); ldisc = NTTYDISC; flags &= ~PRTERA; flags |= CRTBS|CTLECH|DECCTQ; if (sb.sg_ospeed >= B1200) flags |= CRTERA|CRTKIL; if (ioctl(1, TIOCSETD, &ldisc) < 0) perror("ioctl"); continue; } for (sp = special; sp->name; sp++) if (eq(sp->name)) { if (--argc == 0) goto done; if (**++argv == 'u') *sp->cp = 0377; else if (**argv == '^') *sp->cp = ((*argv)[1] == '?') ? 0177 : (*argv)[1] & 037; else *sp->cp = **argv; goto cont; } if (eq("gspeed")) { sb.sg_ispeed = B300; sb.sg_ospeed = B9600; continue; } if (eq("hup")) { if (ioctl(1, TIOCHPCL, NULL) < 0) perror("ioctl"); continue; } for (i = 0; speeds[i].string; i++) if (eq(speeds[i].string)) { sb.sg_ispeed = sb.sg_ospeed = speeds[i].speed; goto cont; } if (eq("speed")) { int fd = open("/dev/tty", 0); if (fd < 0) { perror("open"); exit(1); } ioctl(fd, TIOCGETP, &sb); for (i = 0; speeds[i].string; i++) if (sb.sg_ospeed == speeds[i].speed) { printf("%s\n", speeds[i].string); exit(0); } printf("unknown\n"); exit(1); } for (i = 0; modes[i].string; i++) if (eq(modes[i].string)) { flags &= ~modes[i].reset; flags |= modes[i].set; } if (arg) fprintf(stderr,"unknown mode: %s\n", arg); cont: ; } done: #ifndef notdef ioctl(1, TIOCSETN, &sb); #endif ioctl(1, TIOCSET, &flags); ioctl(1, TIOCCSET, &tc); } eq(string) char *string; { int i; if (!arg) return (0); i = 0; loop: if (arg[i] != string[i]) return(0); if (arg[i++] != '\0') goto loop; arg = 0; return (1); } prmodes(all) int all; { register m; int any; if (ldisc == NETLDISC) fprintf(stderr, "net discipline, "); else if (ldisc == NTTYDISC) fprintf(stderr, "new tty, "); else if (all == 2) fprintf(stderr, "old tty, "); if(sb.sg_ispeed != sb.sg_ospeed) { prspeed("input speed ", sb.sg_ispeed); prspeed("output speed ", sb.sg_ospeed); } else prspeed("speed ", sb.sg_ispeed); fprintf(stderr, all == 2 ? "\n" : "; "); m = flags; if (all == 2 || (m&(EVENP|ODDP)) != (EVENP|ODDP)) { if (m & EVENP) fprintf(stderr,"even "); if (m & ODDP) fprintf(stderr,"odd "); } if (all == 2 || m&RAW) fprintf(stderr,"-raw " + ((m&RAW) != 0)); if (all == 2 || (m&CRMOD) == 0) fprintf(stderr,"-nl " + ((m&CRMOD) == 0)); if (all == 2 || (m&ECHO) == 0) fprintf(stderr,"-echo " + ((m&ECHO) != 0)); if (all == 2 || m&LCASE) fprintf(stderr,"-lcase " + ((m&LCASE) != 0)); if (all == 2 || m&TANDEM) fprintf(stderr,"-tandem " + ((m&TANDEM) != 0)); fprintf(stderr,"-tabs " + ((m&XTABS) != XTABS)); if (all == 2 || m&CBREAK) fprintf(stderr,"-cbreak " + ((m&CBREAK) != 0)); if (all == 2 || m&NLDELAY) delay((m&NLDELAY) / NL1, "nl"); if ((m&TBDELAY) != XTABS) delay((m&TBDELAY)/ TAB1, "tab"); if (all == 2 || m&CRDELAY) delay((m&CRDELAY) / CR1, "cr"); if (all == 2 || m&VTDELAY) delay((m&VTDELAY) / FF1, "ff"); if (all == 2 || m&BSDELAY) delay((m&BSDELAY) / BS1, "bs"); if (all) fprintf(stderr,"\n"); #define lpit(what,str) \ if (all == 2 || flags&what) { \ fprintf(stderr,str + ((flags&what) != 0)); any++; \ } if (ldisc == NTTYDISC) { int newcrt = (flags&(CTLECH|CRTBS)) == (CTLECH|CRTBS) && (flags&(CRTERA|CRTKIL)) == ((sb.sg_ospeed > B300) ? CRTERA|CRTKIL : 0); if (newcrt) { fprintf(stderr, all != 2 ? "crt " : "crt: (crtbs crterase crtkill ctlecho) "); any++; } else { lpit(CRTBS, "-crtbs "); lpit(CRTERA, "-crterase "); lpit(CRTKIL, "-crtkill "); lpit(CTLECH, "-ctlecho "); lpit(PRTERA, "-prterase "); } lpit(TOSTOP, "-tostop "); if (all == 2) { fprintf(stderr, "\n"); any = 0; } lpit(TILDE, "-tilde "); lpit(FLUSHO, "-flusho "); lpit(MDMBUF, "-mdmbuf "); lpit(LITOUT, "-litout "); lpit(NOHANG, "-nohang "); if (any) { fprintf(stderr,"\n"); any = 0; } #ifdef notdef lpit(ETXACK, "-etxack "); #endif lpit(PENDIN, "-pendin "); lpit(DECCTQ, "-decctlq "); lpit(NOFLSH, "-noflsh "); if (any) fprintf(stderr,"\n"); } else if (!all) fprintf(stderr,"\n"); if (all) { switch (ldisc) { case 0: fprintf(stderr,"\ erase kill intr quit stop eof\ \n"); pcol(tc.tc_erase, -1); pcol(tc.tc_kill, -1); pcol(tc.tc_intrc, -1); pcol(tc.tc_quitc, -1); pcol(tc.tc_stopc, tc.tc_startc); pcol(tc.tc_eofc, tc.tc_brkc); fprintf(stderr,"\n"); break; case NTTYDISC: fprintf(stderr,"\ erase kill werase rprnt flush lnext susp intr quit stop eof\ \n"); pcol(tc.tc_erase, -1); pcol(tc.tc_kill, -1); pcol(tc.tc_werasc, -1); pcol(tc.tc_rprntc, -1); pcol(tc.tc_flushc, -1); pcol(tc.tc_lnextc, -1); pcol(tc.tc_suspc, tc.tc_dsuspc); pcol(tc.tc_intrc, -1); pcol(tc.tc_quitc, -1); pcol(tc.tc_stopc, tc.tc_startc); pcol(tc.tc_eofc, tc.tc_brkc); fprintf(stderr,"\n"); break; } } else if (ldisc != NETLDISC) { register struct special *sp; int first = 1; for (sp = special; sp->name; sp++) { if ((*sp->cp&0377) != (sp->def&0377)) { pit(*sp->cp, sp->name, first ? "" : ", "); first = 0; }; if (sp->cp == &tc.tc_brkc && ldisc == 0) break; } fprintf(stderr, "\n"); } } pcol(ch1, ch2) int ch1, ch2; { int nout = 0; ch1 &= 0377; ch2 &= 0377; if (ch1 == ch2) ch2 = 0377; for (; ch1 != 0377 || ch2 != 0377; ch1 = ch2, ch2 = 0377) { if (ch1 == 0377) continue; if (ch1 & 0200) { fprintf(stderr, "M-"); nout += 2; ch1 &= ~ 0200; } if (ch1 == 0177) { fprintf(stderr, "^"); nout++; ch1 = '?'; } else if (ch1 < ' ') { fprintf(stderr, "^"); nout++; ch1 += '@'; } fprintf(stderr, "%c", ch1); nout++; if (ch2 != 0377) { fprintf(stderr, "/"); nout++; } } while (nout < 7) { fprintf(stderr, " "); nout++; } } pit(what, itsname, sep) unsigned what; char *itsname, *sep; { what &= 0377; fprintf(stderr, "%s%s", sep, itsname); if (what == 0377) { fprintf(stderr, " <undef>"); return; } fprintf(stderr, " = "); if (what & 0200) { fprintf(stderr, "M-"); what &= ~ 0200; } if (what == 0177) { fprintf(stderr, "^"); what = '?'; } else if (what < ' ') { fprintf(stderr, "^"); what += '@'; } fprintf(stderr, "%c", what); } delay(m, s) char *s; { if (m) fprintf(stderr,"%s%d ", s, m); } int speed[] = { 0,50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400 }; prspeed(c, s) char *c; { fprintf(stderr,"%s%d baud", c, speed[s]); }