#include <stdio.h> #include <sgtty.h> #define CTRL(x) ('x'&037) extern int errno, ntty_ld, tty_ld; int ttyfd; struct { char *s_name; int s_define; int s_speed; } speeds[] = { "0", B0, 0, "50", B50, 50, "75", B75, 75, "110", B110, 110, "134", B134, 134, "150", B150, 150, "200", B200, 200, "300", B300, 300, "600", B600, 600, "1200", B1200, 1200, "1800", B1800, 1800, "2400", B2400, 2400, "4800", B4800, 4800, "9600", B9600, 9600, "exta", EXTA, 19200, "extb", EXTB, 0, "19200", EXTA, 19200, /* must follow extb */ 0, }; struct { char *string; int set; int reset; int ntty; } 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", LCRTBS, LPRTERA, 1 }, { "-crtbs", 0, LCRTBS, 1 }, { "prterase", LPRTERA, LCRTBS+LCRTKIL+LCRTERA, 1 }, { "-prterase", 0, LPRTERA, 1 }, { "crterase", LCRTERA, LPRTERA, 1 }, { "-crterase", 0, LCRTERA, 1 }, { "crtkill", LCRTKIL, LPRTERA, 1 }, { "-crtkill", 0, LCRTKIL, 1 }, { "ctlecho", LCTLECH, 0, 1 }, { "-ctlecho", 0, LCTLECH, 1 }, { "tilde", LTILDE, 0, 1 }, { "-tilde", 0, LTILDE, 1 }, { "litout", LLITOUT, 0, 1 }, { "-litout", 0, LLITOUT, 1 }, { "flusho", LFLUSHO, 0, 1 }, { "-flusho", 0, LFLUSHO, 1 }, { "nohang", LNOHANG, 0, 1 }, { "-nohang", 0, LNOHANG, 1 }, { "decctq", LDECCTQ, 0, 1 }, { "-decctq", 0, LDECCTQ, 1 }, /* { "pendin", LPENDIN, 0, 1 }, { "-pendin", 0, LPENDIN, 1 }, { "mdmbuf", LMDMBUF, 0, 1 }, { "-mdmbuf", 0, LMDMBUF, 1 }, { "tostop", LTOSTOP, 0, 1 }, { "-tostop", 0, LTOSTOP, 1 }, { "etxack", LETXACK, 0, 1 }, { "-etxack", 0, LETXACK, 1 }, { "intrup", LINTRUP, 0, 1 }, { "-intrup", 0, LINTRUP, 1 }, */ 0, }; struct sgttyb mode; struct tchars tc; struct ltchars ltc; struct luchars luc; struct special { char *name; char *cp; char def; } special[] = { "erase", &mode.sg_erase, CTRL(h), "kill", &mode.sg_kill, '@', "intr", &tc.t_intrc, 0177, "quit", &tc.t_quitc, CTRL(\\), "start", &tc.t_startc, CTRL(q), "stop", &tc.t_stopc, CTRL(s), "eof", &tc.t_eofc, CTRL(d), "brk", &tc.t_brkc, 0377, "susp", <c.t_suspc, CTRL(z), "dsusp", <c.t_dsuspc, CTRL(y), "rprnt", <c.t_rprntc, CTRL(r), "flush", <c.t_flushc, CTRL(o), "werase", <c.t_werasc, CTRL(w), "lnext", <c.t_lnextc, CTRL(v), "undo", &luc.t_undoc, 0377, "urot", &luc.t_urotc, 0377, 0 }; char *ego; int ldisc; /* current line disc */ int lmode; /* new tty local mode bits */ main (argc, argv) int argc; char *argv[]; { char *arg, obuf[BUFSIZ]; int i; struct special *sp; ego = argv[0]; setbuf (stderr, obuf); if ((ttyfd = open("/dev/tty", 1)) < 0) { fprintf(stderr, "%s: can't open /dev/tty\n", ego); exit(1); } (void) getmodes(); /* if (argc>=2 && ldisc!=tty_ld && ldisc!=ntty_ld) fprintf(stderr, "%s: warning: no tty line discipline.\n", ego); */ if (argc < 2) { prmodes(); exit (0); } for (arg = *++argv; --argc > 0; arg = *++argv) { #define eq(x) (!strcmp (arg, x)) if (eq ("all")) { prmodes(); continue; } if (eq ("old") || eq ("-new")) if (swdisc (tty_ld)) goto done1; else continue; if (eq ("new")) if (swdisc (ntty_ld)) goto done1; else continue; if (eq ("crt")) { lmode |= LCRTBS | LCTLECH; if (speeds[mode.sg_ispeed].s_speed >= 1200) lmode |= LCRTERA | LCRTKIL; continue; } if (eq ("ek")) { mode.sg_erase = '#'; mode.sg_kill = '@'; continue; } if (eq ("hup")) { (void) ioctl (ttyfd, TIOCHPCL, NULL); continue; } for (sp = special; sp->name; sp++) if (eq (sp->name)) { if (--argc > 0) { arg = *++argv; if (*arg == 'u') *sp->cp = 0377; else if (*arg == '^') *sp->cp = (arg[1] == '?') ? 0177 : arg[1] & 037; else *sp->cp = *arg; goto cont; } fprintf(stderr, "%s: missing %s character\n", ego, arg); goto done1; } for (i = 0; speeds[i].s_name; i++) if (eq (speeds[i].s_name)) { mode.sg_ispeed = mode.sg_ospeed = speeds[i].s_define; goto cont; } if (eq ("gspeed")) { mode.sg_ispeed = B300; mode.sg_ospeed = B9600; continue; } for (i = 0; modes[i].string; i++) if (eq (modes[i].string)) { if (modes[i].ntty) { lmode &= ~modes[i].reset; lmode |= modes[i].set; } else { mode.sg_flags &= ~modes[i].reset; mode.sg_flags |= modes[i].set; } goto cont; } fprintf(stderr, "%s: %s: unknown mode\n", ego, arg); done1: setmodes(); exit (1); cont: ; } setmodes(); exit (0); } getmodes() { int ret; ldisc = ioctl (ttyfd, FIOLOOKLD, 0); ret = ioctl (ttyfd, TIOCGETP, &mode) == -1; (void) ioctl (ttyfd, TIOCGETC, &tc); if (ldisc == ntty_ld) { (void) ioctl (ttyfd, TIOCLGET, &lmode); (void) ioctl (ttyfd, TIOCGLTC, <c); (void) ioctl (ttyfd, TIOCGLUC, &luc); } return ret; } pit (what, itsname, sep) unsigned char what; char *itsname, *sep; { printf("%s", itsname); if (what == 0377) { printf(" <undef>%s", sep); return; } printf(" = "); if (what & 0200) { printf("M-"); what &= ~ 0200; } if (what == 0177) { printf("^"); what = '?'; } else if (what < ' ') { printf("^"); what += '@'; } printf("%c%s", what, sep); return; } prmodes() { register int m; if (mode.sg_ispeed != mode.sg_ospeed) printf("input speed: %d baud, output speed: %d baud\n", speeds[mode.sg_ispeed].s_speed, speeds[mode.sg_ospeed].s_speed); else printf("speed: %d baud\n", speeds[mode.sg_ispeed].s_speed); pit (mode.sg_erase, "erase", "; "); pit (mode.sg_kill, "kill", "; "); pit (tc.t_intrc, "intr", "; "); pit (tc.t_quitc, "quit", "\n"); pit (tc.t_startc, "start", "; "); pit (tc.t_stopc, "stop", "; "); pit (tc.t_eofc, "eof", "; "); pit (tc.t_brkc, "brk", "\n"); if (ldisc == ntty_ld) { pit (ltc.t_werasc, "werase", "; "); pit (ltc.t_rprntc, "rprnt", "; "); pit (ltc.t_flushc, "flush", "; "); pit (ltc.t_lnextc, "lnext", "\n"); pit (ltc.t_suspc, "susp", "; "); pit (ltc.t_dsuspc, "dsusp", "; "); pit (luc.t_undoc, "undo", "; "); pit (luc.t_urotc, "urot", "\n"); } if (ldisc == tty_ld) printf("old "); else if (ldisc == ntty_ld) printf("new "); m = mode.sg_flags; if (m & EVENP) printf("even "); if (m & ODDP) printf("odd "); #define mpit(what,str) printf(str + ((m & what) != 0)) mpit (RAW, "-raw "); printf("-nl " + ((m & CRMOD) == 0)); mpit (ECHO, "-echo "); mpit (LCASE, "-lcase "); printf("-tabs " + ((m & XTABS) != XTABS)); mpit (CBREAK, "-cbreak "); mpit (TANDEM, "-tandem "); #define delay(x,y) printf("%s%d ", y, x) delay ((m & NLDELAY) / NL1, "nl"); if ((m & TBDELAY) != XTABS) delay ((m & TBDELAY) / TAB1, "tab"); delay ((m & CRDELAY) / CR1, "cr"); delay ((m & VTDELAY) / FF1, "ff"); delay ((m & BSDELAY) / BS1, "bs"); printf("\n"); if (ldisc == ntty_ld) { m = lmode; mpit (LCRTBS, "-crtbs "); mpit (LCRTERA, "-crterase "); mpit (LCRTKIL, "-crtkill "); mpit (LCTLECH, "-ctlecho "); mpit (LPRTERA, "-prterase "); printf("\n"); mpit (LTILDE, "-tilde "); mpit (LFLUSHO, "-flusho "); mpit (LLITOUT, "-litout "); mpit (LNOHANG, "-nohang "); mpit (LDECCTQ, "-decctq "); printf("\n"); /* mpit (LMDMBUF, "-mdmbuf "); mpit (LTOSTOP, "-tostop "); mpit (LINTRUP, "-intrup "); mpit (LETXACK, "-etxack "); mpit (LPENDIN, "-pendin "); printf("\n"); */ } return; } setmodes() { (void) ioctl (ttyfd, TIOCSETN, &mode); (void) ioctl (ttyfd, TIOCSETC, &tc); if (ldisc == ntty_ld) { (void) ioctl (ttyfd, TIOCSLTC, <c); (void) ioctl (ttyfd, TIOCSLUC, &luc); (void) ioctl (ttyfd, TIOCLSET, &lmode); } return; } int swdisc (newld) int newld; { int curld = ioctl(ttyfd, FIOLOOKLD, 0); if ((curld==tty_ld || curld==ntty_ld) && 0 <= ioctl (ttyfd, FIOPOPLD, 0)) { if (0 <= ioctl (ttyfd, FIOPUSHLD, &newld)) { (void) ioctl (ttyfd, TIOCSETN, &mode); (void) ioctl (ttyfd, TIOCSETC, &tc); getmodes(); return (0); } else { (void) ioctl (ttyfd, FIOPUSHLD, &ldisc); setmodes(); } } fprintf(stderr, "%s: can't switch line disciplines\n", ego); return (-1); }