1*47843Sbostic /*- 2*47843Sbostic * Copyright (c) 1980, 1989, 1991 The Regents of the University of California. 3*47843Sbostic * All rights reserved. 4*47843Sbostic * 5*47843Sbostic * %sccs.include.proprietary.c% 619907Sdist */ 719907Sdist 813073Ssam #ifndef lint 919907Sdist char copyright[] = 10*47843Sbostic "@(#) Copyright (c) 1980, 1989, 1991 The Regents of the University of California.\n\ 1119907Sdist All rights reserved.\n"; 12*47843Sbostic #endif /* not lint */ 1319907Sdist 1419907Sdist #ifndef lint 15*47843Sbostic static char sccsid[] = "@(#)stty.c 5.20 (Berkeley) 04/08/91"; 16*47843Sbostic #endif /* not lint */ 1719907Sdist 181179Sbill /* 191179Sbill * set teletype modes 201179Sbill */ 211179Sbill 2238674Smarc #include <sys/types.h> 2338674Smarc #include <sys/stat.h> 2437609Sbostic #include <sys/ioctl.h> 2538674Smarc #include <sys/syslog.h> 2638674Smarc #define KERNEL 2738674Smarc #include <sys/tty.h> 2838674Smarc #undef KERNEL 2938674Smarc #include <sys/termios.h> 3038674Smarc #include <sys/file.h> 3138674Smarc #include <errno.h> 3238674Smarc #include <ctype.h> 331179Sbill #include <stdio.h> 341179Sbill 3540170Smarc #define eq(s1, s2) (strcmp((s1), (s2)) == 0) 3638674Smarc #define WRAPCOL 65 3738674Smarc 3840170Smarc struct modes { 3938674Smarc char *name; 4038674Smarc long set; 4138674Smarc long unset; 421179Sbill }; 431179Sbill 4440170Smarc struct modes imodes[] = { 4538674Smarc "ignbrk", IGNBRK, 0, 4638674Smarc "-ignbrk", 0, IGNBRK, 4738674Smarc "brkint", BRKINT, 0, 4838674Smarc "-brkint", 0, BRKINT, 4938674Smarc "ignpar", IGNPAR, 0, 5038674Smarc "-ignpar", 0, IGNPAR, 5138674Smarc "parmrk", PARMRK, 0, 5238674Smarc "-parmrk", 0, PARMRK, 5338674Smarc "inpck", INPCK, 0, 5438674Smarc "-inpck", 0, INPCK, 5538674Smarc "istrip", ISTRIP, 0, 5638674Smarc "-istrip", 0, ISTRIP, 5738674Smarc "inlcr", INLCR, 0, 5838674Smarc "-inlcr", 0, INLCR, 5938674Smarc "igncr", IGNCR, 0, 6038674Smarc "-igncr", 0, IGNCR, 6138674Smarc "icrnl", ICRNL, 0, 6238674Smarc "-icrnl", 0, ICRNL, 6338674Smarc "ixon", IXON, 0, 6438674Smarc "-ixon", 0, IXON, 6538674Smarc "flow", IXON, 0, 6638674Smarc "-flow", 0, IXON, 6738674Smarc "ixoff", IXOFF, 0, 6838674Smarc "-ixoff", 0, IXOFF, 6938674Smarc "tandem", IXOFF, 0, 7038674Smarc "-tandem", 0, IXOFF, 7138674Smarc "ixany", IXANY, 0, 7238674Smarc "-ixany", 0, IXANY, 7338674Smarc "decctlq", 0, IXANY, 7438674Smarc "-decctlq", IXANY, 0, 7538674Smarc "imaxbel", IMAXBEL, 0, 7638674Smarc "-imaxbel", 0, IMAXBEL, 7738674Smarc 0 7838674Smarc }; 791179Sbill 8040170Smarc struct modes omodes[] = { 8138674Smarc "opost", OPOST, 0, 8238674Smarc "-opost", 0, OPOST, 8338674Smarc "-litout", OPOST, 0, 8438674Smarc "litout", 0, OPOST, 8538674Smarc "onlcr", ONLCR, 0, 8638674Smarc "-onlcr", 0, ONLCR, 8738674Smarc "tabs", 0, OXTABS, /* "preserve" tabs */ 8838674Smarc "-tabs", OXTABS, 0, 8940210Smarc "xtabs", OXTABS, 0, 9040210Smarc "-xtabs", 0, OXTABS, 9138674Smarc "oxtabs", OXTABS, 0, 9238674Smarc "-oxtabs", 0, OXTABS, 931179Sbill 0 941179Sbill }; 951179Sbill 9640170Smarc struct modes cmodes[] = { 9738674Smarc "cs5", CS5, CSIZE, 9838674Smarc "cs6", CS6, CSIZE, 9938674Smarc "cs7", CS7, CSIZE, 10038674Smarc "cs8", CS8, CSIZE, 10138674Smarc "cstopb", CSTOPB, 0, 10238674Smarc "-cstopb", 0, CSTOPB, 10338674Smarc "cread", CREAD, 0, 10438674Smarc "-cread", 0, CREAD, 10538674Smarc "parenb", PARENB, 0, 10638674Smarc "-parenb", 0, PARENB, 10738674Smarc "parodd", PARODD, 0, 10838674Smarc "-parodd", 0, PARODD, 10938674Smarc "parity", PARENB | CS7, PARODD | CSIZE, 11038674Smarc "evenp", PARENB | CS7, PARODD | CSIZE, 11138674Smarc "oddp", PARENB | CS7 | PARODD, CSIZE, 11238674Smarc "-parity", CS8, PARODD | PARENB | CSIZE, 11340169Skarels "pass8", CS8, PARODD | PARENB | CSIZE, 11438674Smarc "-evenp", CS8, PARODD | PARENB | CSIZE, 11538674Smarc "-oddp", CS8, PARODD | PARENB | CSIZE, 11638674Smarc "hupcl", HUPCL, 0, 11738674Smarc "-hupcl", 0, HUPCL, 11838674Smarc "hup", HUPCL, 0, 11938674Smarc "-hup", 0, HUPCL, 12038674Smarc "clocal", CLOCAL, 0, 12138674Smarc "-clocal", 0, CLOCAL, 12238674Smarc "crtscts", CRTSCTS, 0, 12338674Smarc "-crtscts", 0, CRTSCTS, 12438674Smarc 0 12538674Smarc }; 12638674Smarc 12740170Smarc struct modes lmodes[] = { 12838674Smarc "echo", ECHO, 0, 12938674Smarc "-echo", 0, ECHO, 13038674Smarc "echoe", ECHOE, 0, 13138674Smarc "-echoe", 0, ECHOE, 13238674Smarc "crterase", ECHOE, 0, 13338674Smarc "-crterase", 0, ECHOE, 13438674Smarc "crtbs", ECHOE, 0, /* crtbs not supported, close enough */ 13538674Smarc "-crtbs", 0, ECHOE, 13638674Smarc "echok", ECHOK, 0, 13738674Smarc "-echok", 0, ECHOK, 13838674Smarc "echoke", ECHOKE, 0, 13938674Smarc "-echoke", 0, ECHOKE, 14038674Smarc "crtkill", ECHOKE, 0, 14138674Smarc "-crtkill", 0, ECHOKE, 14238674Smarc "altwerase", ALTWERASE, 0, 14338674Smarc "-altwerase", 0, ALTWERASE, 14438674Smarc "iexten", IEXTEN, 0, 14538674Smarc "-iexten", 0, IEXTEN, 14638674Smarc "echonl", ECHONL, 0, 14738674Smarc "-echonl", 0, ECHONL, 14838674Smarc "echoctl", ECHOCTL, 0, 14938674Smarc "-echoctl", 0, ECHOCTL, 15038674Smarc "ctlecho", ECHOCTL, 0, 15138674Smarc "-ctlecho", 0, ECHOCTL, 15238674Smarc "echoprt", ECHOPRT, 0, 15338674Smarc "-echoprt", 0, ECHOPRT, 15438674Smarc "prterase", ECHOPRT, 0, 15538674Smarc "-prterase", 0, ECHOPRT, 15638674Smarc "isig", ISIG, 0, 15738674Smarc "-isig", 0, ISIG, 15838674Smarc "icanon", ICANON, 0, 15938674Smarc "-icanon", 0, ICANON, 16038674Smarc "noflsh", NOFLSH, 0, 16138674Smarc "-noflsh", 0, NOFLSH, 16238674Smarc "tostop", TOSTOP, 0, 16338674Smarc "-tostop", 0, TOSTOP, 16438674Smarc "mdmbuf", MDMBUF, 0, 16538674Smarc "-mdmbuf", 0, MDMBUF, 16638674Smarc "flusho", FLUSHO, 0, 16738674Smarc "-flusho", 0, FLUSHO, 16838674Smarc "pendin", PENDIN, 0, 16938674Smarc "-pendin", 0, PENDIN, 17038674Smarc "crt", ECHOE|ECHOKE|ECHOCTL, ECHOK|ECHOPRT, 17138674Smarc "-crt", ECHOK, ECHOE|ECHOKE|ECHOCTL, 17238674Smarc "newcrt", ECHOE|ECHOKE|ECHOCTL, ECHOK|ECHOPRT, 17338674Smarc "-newcrt", ECHOK, ECHOE|ECHOKE|ECHOCTL, 17445235Sborman "nokerninfo", NOKERNINFO, 0, 17545235Sborman "-nokerninfo", 0, NOKERNINFO, 17645235Sborman "kerninfo", 0, NOKERNINFO, 17745235Sborman "-kerninfo", NOKERNINFO, 0, 17838674Smarc 0 17938674Smarc }; 18038674Smarc 18138674Smarc /* 18238674Smarc * Special control characters. 18338674Smarc * 18438674Smarc * Each entry has a list of names. The first is the primary name 18538674Smarc * and is used when printing the control character in the "name = val;" 18638674Smarc * form. The second is an abbreviation which is guaranteed to be less 18738674Smarc * than or equal to four characters in length and is primarily used 18838674Smarc * when printing the values in columunar form (guarantees all will 18938674Smarc * fit within 80 cols). The rest are optional aliases. 19038674Smarc * All names are recognized on the command line. 19138674Smarc */ 19240170Smarc #define MAXNAMES 3 19340170Smarc struct { 19440210Smarc char *names[MAXNAMES+1]; 19538674Smarc int sub; 19638674Smarc u_char def; 19738674Smarc } cchars[] = { 19843098Sbostic {{ "erase", "era" }, VERASE, CERASE, }, 19943098Sbostic {{ "werase", "wera" }, VWERASE, CWERASE, }, 20043098Sbostic {{ "kill", "kill" }, VKILL, CKILL, }, 20143098Sbostic {{ "intr", "int" }, VINTR, CINTR, }, 20243098Sbostic {{ "quit", "quit" }, VQUIT, CQUIT, }, 20343098Sbostic {{ "susp", "susp" }, VSUSP, CSUSP, }, 20443098Sbostic {{ "dsusp", "dsus" }, VDSUSP, CDSUSP, }, 20543098Sbostic {{ "eof", "eof" }, VEOF, CEOF, }, 20643098Sbostic {{ "eol", "eol", "brk" }, VEOL, CEOL, }, 20743098Sbostic {{ "eol2", "eol2" }, VEOL2, CEOL, }, 20843098Sbostic {{ "stop", "stop", "xoff" }, VSTOP, CSTOP, }, 20943098Sbostic {{ "start", "star", "xon" }, VSTART, CSTART, }, 21043098Sbostic {{ "lnext", "lnxt" }, VLNEXT, CLNEXT, }, 21144286Smarc {{ "discard", "disc", "flush" }, VDISCARD, CDISCARD, }, 21243098Sbostic {{ "reprint", "rpnt", "rprnt" }, VREPRINT, CREPRINT, }, 21344286Smarc {{ "status", "stat" }, VSTATUS, CSTATUS, }, 21438674Smarc 0 21538674Smarc }; 21643098Sbostic 21740170Smarc struct winsize win; 21840170Smarc int ldisc; 21940170Smarc int debug = 0; 22040170Smarc int trace, dotrace; 22145235Sborman int extproc; 22238674Smarc 22338674Smarc #define OUT stdout /* informational output stream */ 22438674Smarc #define ERR stderr /* error message stream */ 22538674Smarc #define CTL 0 /* default control descriptor */ 22640170Smarc int ctl = CTL; 22738674Smarc 22838674Smarc extern errno; 22938674Smarc 23038674Smarc #define NORMAL 0 /* only print modes differing from defaults */ 23138674Smarc #define ALL 1 /* print all modes - POSIX standard format */ 23238674Smarc #define ALL_BSD 2 /* print all modes - using BSD shorthand for cc's */ 23343323Smarc #define GFMT 3 /* print modes in form suitable to be re-input */ 23438674Smarc 23538674Smarc main(argc, argv) 23638674Smarc char *argv[]; 2371179Sbill { 23838674Smarc struct termios t; 23938674Smarc int i, fmt = NORMAL; 24038674Smarc extern char *optarg; 24138674Smarc extern int optind; 24238674Smarc int ch; 2431179Sbill 24438674Smarc argc--, argv++; 24538674Smarc if (argc > 0 && eq(argv[0], "-a")) { 24638674Smarc fmt = ALL; 24738674Smarc argc--, argv++; 2481179Sbill } 24943323Smarc if (argc > 0 && eq(argv[0], "-g")) { 25043323Smarc fmt = GFMT; 25143323Smarc argc--, argv++; 25243323Smarc } 25338674Smarc if (argc > 0 && eq(argv[0], "-f")) { 25438674Smarc argc--, argv++; 25538674Smarc if ((ctl = open(argv[0], O_RDONLY | O_NONBLOCK)) < 0) 25638674Smarc syserrexit(*argv); 25738674Smarc argc--, argv++; 2581179Sbill } 25938674Smarc if (ioctl(ctl, TIOCGETD, &ldisc) < 0) 26038674Smarc syserrexit("TIOCGETD"); 26138674Smarc if (tcgetattr(ctl, &t) < 0) 26238674Smarc syserrexit("tcgetattr"); 26338674Smarc if (ioctl(ctl, TIOCGWINSZ, &win) < 0) 26440170Smarc warning("TIOCGWINSZ: %s", strerror(errno)); 26538674Smarc checkredirect(); /* conversion aid */ 26638674Smarc 26738674Smarc if (argc == 0 || fmt) { 26838674Smarc prmode(&t, ldisc, fmt); 2691179Sbill exit(0); 2701179Sbill } 27138674Smarc 27238674Smarc while (*argv) { 27338674Smarc if (eq("everything", *argv)) { 27438674Smarc prmode(&t, ldisc, ALL_BSD); 27538674Smarc exit(0); 2761179Sbill } 27738674Smarc if (eq("all", *argv)) { 27838674Smarc prmode(&t, ldisc, ALL); 27938674Smarc exit(0); 2801179Sbill } 28146310Skarels if (eq("tty", *argv) || eq("old", *argv) || eq("new", *argv)) { 28246310Skarels int nldisc = TTYDISC; 28346310Skarels 28446310Skarels if (ioctl(0, TIOCSETD, &nldisc) < 0) 28546310Skarels syserrexit("TIOCSETD"); 28638674Smarc goto next; 2871179Sbill } 28838674Smarc if (eq("nl", *argv)) { 28938674Smarc t.c_iflag &= ~ICRNL; 29038674Smarc t.c_oflag &= ~ONLCR; 29138674Smarc goto next; 2921179Sbill } 29338674Smarc if (eq("-nl", *argv)) { 29438674Smarc t.c_iflag |= ICRNL; 29538674Smarc t.c_oflag |= ONLCR; 29638674Smarc goto next; 2973797Sroot } 29838674Smarc if (eq("dec", *argv)){ 29938674Smarc t.c_cc[VERASE] = (u_char)0177; 30038674Smarc t.c_cc[VKILL] = CTRL('u'); 30138674Smarc t.c_cc[VINTR] = CTRL('c'); 30238674Smarc t.c_lflag &= ~ECHOPRT; 30338674Smarc t.c_lflag |= ECHOE|ECHOKE|ECHOCTL; 30438674Smarc t.c_iflag &= ~IXANY; 30538674Smarc goto next; 3061179Sbill } 30740169Skarels if (eq("raw", *argv)) { 30840169Skarels cfmakeraw(&t); 30940169Skarels t.c_cflag &= ~(CSIZE|PARENB); 31040169Skarels t.c_cflag |= CS8; 31140169Skarels goto next; 31240169Skarels } 31345029Smarc if (eq("cbreak", *argv)) { 31445029Smarc t.c_iflag | BRKINT|IXON|IMAXBEL; 31545029Smarc t.c_oflag |= OPOST; 31645029Smarc t.c_lflag |= ISIG|IEXTEN; 31745029Smarc t.c_lflag &= ~ICANON; 31845029Smarc } 31940169Skarels if (eq("cooked", *argv) || eq("-raw", *argv) || 32045029Smarc eq("sane", *argv) || eq("-cbreak", *argv)) { 32140169Skarels t.c_cflag = TTYDEF_CFLAG | (t.c_cflag & CLOCAL); 32240169Skarels t.c_iflag = TTYDEF_IFLAG; 32340169Skarels t.c_iflag |= ICRNL; 32440169Skarels /* preserve user-preference flags in lflag */ 32540169Skarels #define LKEEP (ECHOKE|ECHOE|ECHOK|ECHOPRT|ECHOCTL|ALTWERASE|TOSTOP|NOFLSH) 32640169Skarels t.c_lflag = TTYDEF_LFLAG | (t.c_lflag & LKEEP); 32740169Skarels t.c_oflag = TTYDEF_OFLAG; 32840169Skarels goto next; 32940169Skarels } 33038674Smarc if (eq("rows", *argv)) { 33138674Smarc if (*(argv+1) == 0) 33238674Smarc goto setit; 33318023Sbloom win.ws_row = atoi(*++argv); 33438674Smarc goto next; 33518023Sbloom } 33638674Smarc if (eq("ispeed", *argv)) { 33738674Smarc int code; 33838674Smarc if (*(argv+1) == 0) 33938674Smarc errexit("missing ispeed"); 34038674Smarc cfsetispeed(&t, atoi(*++argv)); 34138674Smarc goto next; 34238674Smarc } 34338674Smarc if (eq("ospeed", *argv)) { 34438674Smarc if (*(argv+1) == 0) 34538674Smarc errexit("missing ospeed"); 34638674Smarc cfsetospeed(&t, atoi(*++argv)); 34738674Smarc goto next; 34838674Smarc } 34938674Smarc if (eq("cols", *argv) || eq("columns", *argv)) { 35038674Smarc if (*(argv+1) == 0) 35138674Smarc goto setit; 35218023Sbloom win.ws_col = atoi(*++argv); 35338674Smarc goto next; 35418023Sbloom } 35538674Smarc if (eq("size", *argv)) { 35638674Smarc put("%d %d\n", win.ws_row, win.ws_col); 35725791Skarels exit(0); 35825791Skarels } 35945235Sborman if (eq("extrpc", *argv) || eq("-extproc", *argv)) { 36045235Sborman if (**argv == '-') 36145235Sborman extproc = 0; 36245235Sborman else 36345235Sborman extproc = 1; 36445235Sborman ioctl(ctl, TIOCEXT, &extproc); 36545235Sborman } 36638674Smarc if (eq("speed", *argv)) { 36738674Smarc put("%d\n", cfgetospeed(&t)); 36838674Smarc exit(0); 36938674Smarc } 37038674Smarc for (i=0; imodes[i].name; i++) 37138674Smarc if (eq(imodes[i].name, *argv)) { 37238674Smarc t.c_iflag &= ~imodes[i].unset; 37338674Smarc t.c_iflag |= imodes[i].set; 37438674Smarc goto next; 3751179Sbill } 37638674Smarc for (i=0; omodes[i].name; i++) 37738674Smarc if (eq(omodes[i].name, *argv)) { 37838674Smarc t.c_oflag &= ~omodes[i].unset; 37938674Smarc t.c_oflag |= omodes[i].set; 38038674Smarc goto next; 38138674Smarc } 38238674Smarc for (i=0; cmodes[i].name; i++) 38338674Smarc if (eq(cmodes[i].name, *argv)) { 38438674Smarc t.c_cflag &= ~cmodes[i].unset; 38538674Smarc t.c_cflag |= cmodes[i].set; 38638674Smarc goto next; 38738674Smarc } 38838674Smarc for (i=0; lmodes[i].name; i++) 38938674Smarc if (eq(lmodes[i].name, *argv)) { 39038674Smarc t.c_lflag &= ~lmodes[i].unset; 39138674Smarc t.c_lflag |= lmodes[i].set; 39238674Smarc goto next; 39338674Smarc } 39438674Smarc for (i=0; *cchars[i].names; i++) { 39538674Smarc char **cp = cchars[i].names; 39638674Smarc while (*cp) { 39738674Smarc if (eq(*cp, *argv)) { 39838674Smarc if (*++argv == 0) 39938674Smarc goto setit; 40038674Smarc if (eq(*argv, "undef") || 40138674Smarc eq(*argv, "disable")) 40238674Smarc t.c_cc[cchars[i].sub] = 40338674Smarc _POSIX_VDISABLE; 40438674Smarc else if (**argv == '^') 40538674Smarc t.c_cc[cchars[i].sub] = 40638674Smarc ((*argv)[1] == '?') ? 0177 : 40738674Smarc ((*argv)[1] == '-') ? 40838674Smarc _POSIX_VDISABLE : 40938674Smarc (*argv)[1] & 037; 41038674Smarc else 41138674Smarc t.c_cc[cchars[i].sub] = **argv; 41238674Smarc goto next; 4131179Sbill } 41438674Smarc cp++; 41538674Smarc } 4161179Sbill } 41738674Smarc if (isdigit(**argv)) { 41838674Smarc cfsetospeed(&t, atoi(*argv)); 41938674Smarc cfsetispeed(&t, atoi(*argv)); 42038674Smarc goto next; 42138674Smarc } 42243323Smarc if (strncmp(*argv, "-gfmt", sizeof ("-gfmt") - 1) == 0) { 42343323Smarc gfmtset(&t, *argv); 42443323Smarc goto next; 42543323Smarc } 42638674Smarc /* didn't match anything */ 42738674Smarc errexit("unknown option: %s", *argv); 42838674Smarc exit(1); 42938674Smarc next: 43038674Smarc argv++; 4311179Sbill } 43238674Smarc setit: 43338674Smarc if (tcsetattr(ctl, 0, &t) < 0) 43438674Smarc syserrexit("tcsetattr"); 43538674Smarc if (ioctl(ctl, TIOCSWINSZ, &win) < 0) 43638674Smarc warning("can't set window size"); 43738674Smarc 43838674Smarc exit(0); 4391179Sbill } 4401179Sbill 44143323Smarc gfmtset(tp, s) 44243323Smarc register struct termios *tp; 44343323Smarc char *s; 44443323Smarc { 44543323Smarc register int cnt; 44643323Smarc char sep; 44743323Smarc char *saves = s; 44843323Smarc int cval; 44943323Smarc #define advance(c) while (*(s) && *(s) != (c)) (s)++; if (*s) (s)++ ; \ 45043323Smarc else \ 45143323Smarc errexit("bad gfmt operand: %s", saves) 45243323Smarc #define chkeq(string) if (strncmp(s, (string), strlen(string))) \ 45343323Smarc errexit("bad gfmt operand: %s", saves) 45443323Smarc 45543323Smarc if (s == NULL) 45643323Smarc errexit("missing gfmt string"); 45743323Smarc advance(':'); 45843323Smarc chkeq("iflag="); 45943323Smarc advance('='); 46043323Smarc sscanf(s, "%x", &tp->c_iflag); 46143323Smarc 46243323Smarc advance(':'); 46343323Smarc chkeq("oflag"); 46443323Smarc advance('='); 46543323Smarc sscanf(s, "%x", &tp->c_oflag); 46643323Smarc 46743323Smarc advance(':'); 46843323Smarc chkeq("cflag"); 46943323Smarc advance('='); 47043323Smarc sscanf(s, "%x", &tp->c_cflag); 47143323Smarc 47243323Smarc advance(':'); 47343323Smarc chkeq("lflag"); 47443323Smarc advance('='); 47543323Smarc sscanf(s, "%x", &tp->c_lflag); 47643323Smarc 47743323Smarc advance(':'); 47843323Smarc chkeq("cc="); 47943323Smarc 48043323Smarc for (cnt = 0, sep = '='; cnt < NCCS; cnt++, sep = ',') { 48143323Smarc advance(sep); 48243323Smarc sscanf(s, "%o", &cval); 48343323Smarc tp->c_cc[cnt] = cval; 48443323Smarc } 48543323Smarc 48643323Smarc advance(':'); 48743323Smarc chkeq("ispeed="); 48843323Smarc advance('='); 48943323Smarc sscanf(s, "%d", &tp->c_ispeed); 49043323Smarc 49143323Smarc advance(':'); 49243323Smarc chkeq("ospeed="); 49343323Smarc advance('='); 49443323Smarc sscanf(s, "%d", &tp->c_ospeed); 4951179Sbill } 4961179Sbill 49738674Smarc prmode(tp, ldisc, fmt) 49838674Smarc struct termios *tp; 4991179Sbill { 50038674Smarc long i = tp->c_iflag, 50138674Smarc o = tp->c_oflag, 50238674Smarc c = tp->c_cflag, 50338674Smarc l = tp->c_lflag; 50438674Smarc u_char *cc = tp->c_cc; 50538674Smarc int ispeed = cfgetispeed(tp), 50638674Smarc ospeed = cfgetospeed(tp); 50738674Smarc char unknown[32], 50838674Smarc *ld; 50938674Smarc char *ccval(); 51043323Smarc 51143323Smarc if (fmt == GFMT) { 51243323Smarc int cnt; 51343323Smarc char sep; 51443323Smarc 51543323Smarc printf("-gfmt:iflag=%x:oflag=%x:cflag=%x:lflag=%x:cc", 51643323Smarc i, o, c, l); 51743323Smarc for (cnt = 0, sep = '='; cnt < NCCS; cnt++, sep = ',') 51843323Smarc printf("%c%o", sep, cc[cnt]); 51943323Smarc printf(":ispeed=%d:ospeed=%d:\n", ispeed, ospeed); 52043323Smarc return; 52143323Smarc } 52238674Smarc 52338674Smarc /* 52438674Smarc * line discipline 52538674Smarc */ 52638674Smarc if (ldisc != TTYDISC) { 52738674Smarc switch(ldisc) { 52838674Smarc case TABLDISC: 52938674Smarc ld = "tablet"; 5301179Sbill break; 53138674Smarc case SLIPDISC: 53240170Smarc ld = "slip"; 5331179Sbill break; 53438674Smarc default: 53538674Smarc sprintf(unknown, "#%d", ldisc); 53638674Smarc ld = unknown; 53746310Skarels break; 5381179Sbill } 53938674Smarc put("%s disc; ", ld); 54038674Smarc } 54138674Smarc /* 54238674Smarc * line speed 54338674Smarc */ 54438674Smarc if (ispeed != ospeed) 54538674Smarc put("ispeed %d baud; ospeed %d baud;", 54638674Smarc ispeed, ospeed); 54738674Smarc else 54838674Smarc put("speed %d baud;", ispeed); 54938674Smarc if (fmt) 55038674Smarc put(" %d rows; %d columns;", win.ws_row, win.ws_col); 55138674Smarc put("\n"); 55213817Ssam 55338674Smarc #define lput(n, f, d) if (fmt || on(f) != d) mdput(n+on(f)) 55438674Smarc /* 55538674Smarc * "local" flags 55638674Smarc */ 55738674Smarc #define on(f) ((l&f) != 0) 55838674Smarc if (debug) mdput("LFLAG: "); 55938674Smarc lput("-icanon ",ICANON, 1); 56038674Smarc lput("-isig ", ISIG, 1); 56138674Smarc lput("-iexten ", IEXTEN, 1); 56238674Smarc lput("-echo ",ECHO, 1); 56338674Smarc lput("-echoe ",ECHOE, 0); 56438674Smarc lput("-echok ",ECHOK, 0); 56538674Smarc lput("-echoke ",ECHOKE, 0); 56638674Smarc lput("-echonl ",ECHONL, 0); 56738674Smarc lput("-echoctl ",ECHOCTL, 0); 56838674Smarc lput("-echoprt ",ECHOPRT, 0); 56938674Smarc lput("-altwerase ",ALTWERASE, 0); 57038674Smarc lput("-noflsh ",NOFLSH, 0); 57138674Smarc lput("-tostop ",TOSTOP, 0); 57238674Smarc lput("-mdmbuf ",MDMBUF, 0); 57338674Smarc lput("-flusho ",FLUSHO, 0); 57438674Smarc lput("-pendin ",PENDIN, 0); 57545235Sborman lput("-nokerninfo ",NOKERNINFO, 0); 57645235Sborman lput("-extproc ",EXTPROC, 0); 57738674Smarc /* 57838674Smarc * input flags 57938674Smarc */ 58038674Smarc #undef on 58138674Smarc #define on(f) ((i&f) != 0) 58238674Smarc mdput(0); 58338674Smarc if (debug) mdput("IFLAG: "); 58438674Smarc lput("-istrip ", ISTRIP, 0); 58538674Smarc lput("-icrnl ", ICRNL, 1); 58638674Smarc lput("-inlcr ", INLCR, 0); 58738674Smarc lput("-igncr ", IGNCR, 0); 58838674Smarc lput("-ixon ", IXON, 1); 58938674Smarc lput("-ixoff ", IXOFF, 0); 59038674Smarc lput("-ixany ", IXANY, 1); 59138674Smarc lput("-imaxbel ", IMAXBEL, 1); 59238674Smarc lput("-ignbrk ", IGNBRK, 0); 59338674Smarc lput("-brkint ", BRKINT, 1); 59438674Smarc lput("-inpck ", INPCK, 0); 59538674Smarc lput("-ignpar ", IGNPAR, 0); 59638674Smarc lput("-parmrk ", PARMRK, 0); 59738674Smarc #undef on 59838674Smarc /* 59938674Smarc * output flags 60038674Smarc */ 60138674Smarc #define on(f) ((o&f) != 0) 60238674Smarc mdput(0); 60338674Smarc if (debug) mdput("OFLAG: "); 60438674Smarc lput("-opost ", OPOST, 1); 60538674Smarc lput("-onlcr ", ONLCR, 1); 60638674Smarc lput("-oxtabs ", OXTABS, 1); 60738674Smarc #undef on 60838674Smarc /* 60938674Smarc * control flags (hardware state) 61038674Smarc */ 61138674Smarc #define on(f) ((c&f) != 0) 61238674Smarc mdput(0); 61338674Smarc if (debug) mdput("CFLAG: "); 61438674Smarc lput("-cread ", CREAD, 1); 61538674Smarc switch(c&CSIZE) { 61638674Smarc case CS5: mdput("cs5 "); break; 61738674Smarc case CS6: mdput("cs6 "); break; 61838674Smarc case CS7: mdput("cs7 "); break; 61938674Smarc case CS8: mdput("cs8 "); break; 62038674Smarc } 62138674Smarc mdput("-parenb "+on(PARENB)); 62238674Smarc lput("-parodd ", PARODD, 0); 62338674Smarc lput("-hupcl ", HUPCL, 1); 62438674Smarc lput("-clocal ", CLOCAL, 0); 62538674Smarc lput("-cstopb ", CSTOPB, 0); 62638674Smarc lput("-crtscts ", CRTSCTS, 0); 62738674Smarc mdput(0); 62838674Smarc #undef on 62938674Smarc /* 63038674Smarc * special control characters 63138674Smarc */ 63238674Smarc if (debug) mdput("CCHARS: "); 63338674Smarc if (fmt != 2) { 63438674Smarc for (i=0; *cchars[i].names; i++) { 63538674Smarc char temp[64]; 63638674Smarc 63738674Smarc if (fmt || cc[cchars[i].sub] != cchars[i].def) { 63838674Smarc sprintf(temp, "%s = %s; ", *cchars[i].names, 63938674Smarc ccval(cc[cchars[i].sub]), fmt); 64038674Smarc mdput(temp); 64138674Smarc } 6421179Sbill } 64338674Smarc mdput(0); 64438674Smarc } else { 64538674Smarc for (i=0; *cchars[i].names; i++) 64638674Smarc put("%*s", strlen(*(cchars[i].names+1)) + (i>0?1:0), 64738674Smarc *(cchars[i].names+1)); 64838674Smarc printf("\n"); 64938674Smarc for (i=0; *cchars[i].names; i++) 65038674Smarc put("%*s", strlen(*(cchars[i].names+1)) + (i>0?1:0), 65138674Smarc ccval(cc[cchars[i].sub], fmt)); 65238674Smarc printf("\n"); 6531179Sbill } 6541179Sbill } 6551179Sbill 65638674Smarc /* 65738674Smarc * gross, but since we're changing the control descriptor 65838674Smarc * from 1 to 0, most users will be probably be doing 65938674Smarc * "stty > /dev/sometty" by accident. If 1 and 2 are both ttys, 66038674Smarc * but not the same, assume that 1 was incorrectly redirected. 66138674Smarc */ 66238674Smarc checkredirect() { 66338674Smarc struct stat st1, st2; 66438674Smarc 66538674Smarc if (isatty(1) && isatty(2) && fstat(1, &st1) != -1 && 66638674Smarc fstat(2, &st2) != -1 && (st1.st_rdev != st2.st_rdev)) 66738674Smarc warning("stdout appears redirected, but stdin is the control descriptor"); 66838674Smarc } 66938674Smarc 67040170Smarc char * 67138674Smarc ccval(c, fmt) 67238674Smarc unsigned char c; 6731179Sbill { 67438674Smarc static char buf[128]; 67538674Smarc char *bp; 6761179Sbill 67738674Smarc *buf = 0, bp = buf; 67838674Smarc if (c == _POSIX_VDISABLE) 67938674Smarc if (fmt == 2) 68038674Smarc return("<u>"); 68138674Smarc else 68238674Smarc return("<undef>"); 68338674Smarc if (c & 0200) { 68438674Smarc strcat(buf, "M-"); 68538674Smarc *bp++ = 'M'; 68638674Smarc *bp++ = '-'; 68738674Smarc c &= 0177; 6881179Sbill } 68938674Smarc if (c == 0177) { 69038674Smarc *bp++ = '^'; 69138674Smarc *bp++ = '?'; 6921179Sbill } 69338674Smarc else if (c < 040) { 69438674Smarc *bp++ = '^'; 69538674Smarc *bp++ = c + '@'; 69638674Smarc } 69738674Smarc else 69838674Smarc *bp++ = c; 69938674Smarc *bp = 0; 70038674Smarc return(buf); 7011179Sbill } 7021179Sbill 70340170Smarc 70438674Smarc mdput(s) 70538674Smarc char *s; 7061179Sbill { 70738674Smarc static int col = 0; 7081179Sbill 70938674Smarc if (s == (char *)0) { 71038674Smarc if (col) { 71138674Smarc put("\n"); 71238674Smarc col = 0; 71338674Smarc } 7141179Sbill return; 7151179Sbill } 71638674Smarc if ((col += strlen(s)) > WRAPCOL) { 71738674Smarc put("\n"); 71838674Smarc col = strlen(s); 7191179Sbill } 72038674Smarc put(s); 7211179Sbill } 7221179Sbill 72340170Smarc #include <varargs.h> 72440170Smarc 72540170Smarc put(va_alist) 72640170Smarc va_dcl 7271179Sbill { 72840170Smarc char *fmt; 72940170Smarc va_list ap; 73040170Smarc 73140170Smarc va_start(ap); 73240170Smarc fmt = va_arg(ap, char *); 73340170Smarc (void) vfprintf(OUT, fmt, ap); 73440170Smarc va_end(ap); 73538674Smarc } 7361179Sbill 73740170Smarc 73840170Smarc warning(va_alist) 73940170Smarc va_dcl 74038674Smarc { 74140170Smarc char *fmt; 74240170Smarc va_list ap; 74340170Smarc 74438674Smarc fprintf(ERR, "stty: warning: "); 74540170Smarc va_start(ap); 74640170Smarc fmt = va_arg(ap, char *); 74740170Smarc (void) vfprintf(ERR, fmt, ap); 74840170Smarc va_end(ap); 74938674Smarc fprintf(ERR, "\n"); 7501179Sbill } 7511179Sbill 75240170Smarc 75340170Smarc errexit(va_alist) 75440170Smarc va_dcl 75538674Smarc { 75640170Smarc char *fmt; 75740170Smarc va_list ap; 75840170Smarc 75938674Smarc fprintf(ERR, "stty: "); 76040170Smarc va_start(ap); 76140170Smarc fmt = va_arg(ap, char *); 76240170Smarc (void) vfprintf(ERR, fmt, ap); 76340170Smarc va_end(ap); 76438674Smarc fprintf(ERR, "\n"); 76538674Smarc exit(1); 76638674Smarc } 7671179Sbill 76840170Smarc 76940170Smarc syserrexit(va_alist) 77040170Smarc va_dcl 7711179Sbill { 77240170Smarc char *fmt; 77340170Smarc va_list ap; 77440170Smarc 77538674Smarc fprintf(ERR, "stty: "); 77640170Smarc va_start(ap); 77740170Smarc fmt = va_arg(ap, char *); 77840170Smarc (void) vfprintf(ERR, fmt, ap); 77940170Smarc va_end(ap); 78040170Smarc fprintf(ERR, ": %s\n", strerror(errno)); 78138674Smarc exit(1); 7821179Sbill } 783