119907Sdist /* 240169Skarels * Copyright (c) 1980, 1989 Regents of the University of California. 319907Sdist * All rights reserved. The Berkeley software License Agreement 419907Sdist * specifies the terms and conditions for redistribution. 519907Sdist */ 619907Sdist 713073Ssam #ifndef lint 819907Sdist char copyright[] = 940169Skarels "@(#) Copyright (c) 1980, 1989 Regents of the University of California.\n\ 1019907Sdist All rights reserved.\n"; 1119907Sdist #endif not lint 1219907Sdist 1319907Sdist #ifndef lint 14*43323Smarc static char sccsid[] = "@(#)stty.c 5.14 (Berkeley) 06/20/90"; 1519907Sdist #endif not lint 1619907Sdist 171179Sbill /* 181179Sbill * set teletype modes 191179Sbill */ 201179Sbill 2138674Smarc #include <sys/types.h> 2238674Smarc #include <sys/stat.h> 2337609Sbostic #include <sys/ioctl.h> 2438674Smarc #include <sys/syslog.h> 2538674Smarc #define KERNEL 2638674Smarc #include <sys/tty.h> 2738674Smarc #undef KERNEL 2838674Smarc #include <sys/termios.h> 2938674Smarc #include <sys/file.h> 3038674Smarc #include <errno.h> 3138674Smarc #include <ctype.h> 321179Sbill #include <stdio.h> 331179Sbill 3440170Smarc #define eq(s1, s2) (strcmp((s1), (s2)) == 0) 3538674Smarc #define WRAPCOL 65 3638674Smarc 3740170Smarc struct modes { 3838674Smarc char *name; 3938674Smarc long set; 4038674Smarc long unset; 411179Sbill }; 421179Sbill 4340170Smarc struct modes imodes[] = { 4438674Smarc "ignbrk", IGNBRK, 0, 4538674Smarc "-ignbrk", 0, IGNBRK, 4638674Smarc "brkint", BRKINT, 0, 4738674Smarc "-brkint", 0, BRKINT, 4838674Smarc "ignpar", IGNPAR, 0, 4938674Smarc "-ignpar", 0, IGNPAR, 5038674Smarc "parmrk", PARMRK, 0, 5138674Smarc "-parmrk", 0, PARMRK, 5238674Smarc "inpck", INPCK, 0, 5338674Smarc "-inpck", 0, INPCK, 5438674Smarc "istrip", ISTRIP, 0, 5538674Smarc "-istrip", 0, ISTRIP, 5638674Smarc "inlcr", INLCR, 0, 5738674Smarc "-inlcr", 0, INLCR, 5838674Smarc "igncr", IGNCR, 0, 5938674Smarc "-igncr", 0, IGNCR, 6038674Smarc "icrnl", ICRNL, 0, 6138674Smarc "-icrnl", 0, ICRNL, 6238674Smarc "ixon", IXON, 0, 6338674Smarc "-ixon", 0, IXON, 6438674Smarc "flow", IXON, 0, 6538674Smarc "-flow", 0, IXON, 6638674Smarc "ixoff", IXOFF, 0, 6738674Smarc "-ixoff", 0, IXOFF, 6838674Smarc "tandem", IXOFF, 0, 6938674Smarc "-tandem", 0, IXOFF, 7038674Smarc "ixany", IXANY, 0, 7138674Smarc "-ixany", 0, IXANY, 7238674Smarc "decctlq", 0, IXANY, 7338674Smarc "-decctlq", IXANY, 0, 7438674Smarc "imaxbel", IMAXBEL, 0, 7538674Smarc "-imaxbel", 0, IMAXBEL, 7638674Smarc 0 7738674Smarc }; 781179Sbill 7940170Smarc struct modes omodes[] = { 8038674Smarc "opost", OPOST, 0, 8138674Smarc "-opost", 0, OPOST, 8238674Smarc "-litout", OPOST, 0, 8338674Smarc "litout", 0, OPOST, 8438674Smarc "onlcr", ONLCR, 0, 8538674Smarc "-onlcr", 0, ONLCR, 8638674Smarc "tabs", 0, OXTABS, /* "preserve" tabs */ 8738674Smarc "-tabs", OXTABS, 0, 8840210Smarc "xtabs", OXTABS, 0, 8940210Smarc "-xtabs", 0, OXTABS, 9038674Smarc "oxtabs", OXTABS, 0, 9138674Smarc "-oxtabs", 0, OXTABS, 921179Sbill 0 931179Sbill }; 941179Sbill 9540170Smarc struct modes cmodes[] = { 9638674Smarc "cs5", CS5, CSIZE, 9738674Smarc "cs6", CS6, CSIZE, 9838674Smarc "cs7", CS7, CSIZE, 9938674Smarc "cs8", CS8, CSIZE, 10038674Smarc "cstopb", CSTOPB, 0, 10138674Smarc "-cstopb", 0, CSTOPB, 10238674Smarc "cread", CREAD, 0, 10338674Smarc "-cread", 0, CREAD, 10438674Smarc "parenb", PARENB, 0, 10538674Smarc "-parenb", 0, PARENB, 10638674Smarc "parodd", PARODD, 0, 10738674Smarc "-parodd", 0, PARODD, 10838674Smarc "parity", PARENB | CS7, PARODD | CSIZE, 10938674Smarc "evenp", PARENB | CS7, PARODD | CSIZE, 11038674Smarc "oddp", PARENB | CS7 | PARODD, CSIZE, 11138674Smarc "-parity", CS8, PARODD | PARENB | CSIZE, 11240169Skarels "pass8", CS8, PARODD | PARENB | CSIZE, 11338674Smarc "-evenp", CS8, PARODD | PARENB | CSIZE, 11438674Smarc "-oddp", CS8, PARODD | PARENB | CSIZE, 11538674Smarc "hupcl", HUPCL, 0, 11638674Smarc "-hupcl", 0, HUPCL, 11738674Smarc "hup", HUPCL, 0, 11838674Smarc "-hup", 0, HUPCL, 11938674Smarc "clocal", CLOCAL, 0, 12038674Smarc "-clocal", 0, CLOCAL, 12138674Smarc "crtscts", CRTSCTS, 0, 12238674Smarc "-crtscts", 0, CRTSCTS, 12338674Smarc 0 12438674Smarc }; 12538674Smarc 12640170Smarc struct modes lmodes[] = { 12738674Smarc "echo", ECHO, 0, 12838674Smarc "-echo", 0, ECHO, 12938674Smarc "echoe", ECHOE, 0, 13038674Smarc "-echoe", 0, ECHOE, 13138674Smarc "crterase", ECHOE, 0, 13238674Smarc "-crterase", 0, ECHOE, 13338674Smarc "crtbs", ECHOE, 0, /* crtbs not supported, close enough */ 13438674Smarc "-crtbs", 0, ECHOE, 13538674Smarc "echok", ECHOK, 0, 13638674Smarc "-echok", 0, ECHOK, 13738674Smarc "echoke", ECHOKE, 0, 13838674Smarc "-echoke", 0, ECHOKE, 13938674Smarc "crtkill", ECHOKE, 0, 14038674Smarc "-crtkill", 0, ECHOKE, 14138674Smarc "altwerase", ALTWERASE, 0, 14238674Smarc "-altwerase", 0, ALTWERASE, 14338674Smarc "iexten", IEXTEN, 0, 14438674Smarc "-iexten", 0, IEXTEN, 14538674Smarc "echonl", ECHONL, 0, 14638674Smarc "-echonl", 0, ECHONL, 14738674Smarc "echoctl", ECHOCTL, 0, 14838674Smarc "-echoctl", 0, ECHOCTL, 14938674Smarc "ctlecho", ECHOCTL, 0, 15038674Smarc "-ctlecho", 0, ECHOCTL, 15138674Smarc "echoprt", ECHOPRT, 0, 15238674Smarc "-echoprt", 0, ECHOPRT, 15338674Smarc "prterase", ECHOPRT, 0, 15438674Smarc "-prterase", 0, ECHOPRT, 15538674Smarc "isig", ISIG, 0, 15638674Smarc "-isig", 0, ISIG, 15738674Smarc "icanon", ICANON, 0, 15838674Smarc "-icanon", 0, ICANON, 15938674Smarc "noflsh", NOFLSH, 0, 16038674Smarc "-noflsh", 0, NOFLSH, 16138674Smarc "tostop", TOSTOP, 0, 16238674Smarc "-tostop", 0, TOSTOP, 16338674Smarc "mdmbuf", MDMBUF, 0, 16438674Smarc "-mdmbuf", 0, MDMBUF, 16538674Smarc "flusho", FLUSHO, 0, 16638674Smarc "-flusho", 0, FLUSHO, 16738674Smarc "pendin", PENDIN, 0, 16838674Smarc "-pendin", 0, PENDIN, 16938674Smarc "crt", ECHOE|ECHOKE|ECHOCTL, ECHOK|ECHOPRT, 17038674Smarc "-crt", ECHOK, ECHOE|ECHOKE|ECHOCTL, 17138674Smarc "newcrt", ECHOE|ECHOKE|ECHOCTL, ECHOK|ECHOPRT, 17238674Smarc "-newcrt", ECHOK, ECHOE|ECHOKE|ECHOCTL, 17338674Smarc 0 17438674Smarc }; 17538674Smarc 17638674Smarc /* 17738674Smarc * Special control characters. 17838674Smarc * 17938674Smarc * Each entry has a list of names. The first is the primary name 18038674Smarc * and is used when printing the control character in the "name = val;" 18138674Smarc * form. The second is an abbreviation which is guaranteed to be less 18238674Smarc * than or equal to four characters in length and is primarily used 18338674Smarc * when printing the values in columunar form (guarantees all will 18438674Smarc * fit within 80 cols). The rest are optional aliases. 18538674Smarc * All names are recognized on the command line. 18638674Smarc */ 18740170Smarc #define MAXNAMES 3 18840170Smarc struct { 18940210Smarc char *names[MAXNAMES+1]; 19038674Smarc int sub; 19138674Smarc u_char def; 19238674Smarc } cchars[] = { 19343098Sbostic {{ "erase", "era" }, VERASE, CERASE, }, 19443098Sbostic {{ "werase", "wera" }, VWERASE, CWERASE, }, 19543098Sbostic {{ "kill", "kill" }, VKILL, CKILL, }, 19643098Sbostic {{ "intr", "int" }, VINTR, CINTR, }, 19743098Sbostic {{ "quit", "quit" }, VQUIT, CQUIT, }, 19843098Sbostic {{ "susp", "susp" }, VSUSP, CSUSP, }, 19943098Sbostic {{ "dsusp", "dsus" }, VDSUSP, CDSUSP, }, 20043098Sbostic {{ "eof", "eof" }, VEOF, CEOF, }, 20143098Sbostic {{ "eol", "eol", "brk" }, VEOL, CEOL, }, 20243098Sbostic {{ "eol2", "eol2" }, VEOL2, CEOL, }, 20343098Sbostic {{ "stop", "stop", "xoff" }, VSTOP, CSTOP, }, 20443098Sbostic {{ "start", "star", "xon" }, VSTART, CSTART, }, 20543098Sbostic {{ "lnext", "lnxt" }, VLNEXT, CLNEXT, }, 20643100Smarc {{ "discard", "disc", }, VDISCARD, CDISCARD, }, 20743098Sbostic {{ "reprint", "rpnt", "rprnt" }, VREPRINT, CREPRINT, }, 20843098Sbostic {{ "info", "info" }, VINFO, CINFO, }, 20938674Smarc 0 21038674Smarc }; 21143098Sbostic 21240170Smarc struct winsize win; 21340170Smarc int ldisc; 21440170Smarc int dodisc; 21540170Smarc int debug = 0; 21640170Smarc int trace, dotrace; 21738674Smarc 21838674Smarc #define OUT stdout /* informational output stream */ 21938674Smarc #define ERR stderr /* error message stream */ 22038674Smarc #define CTL 0 /* default control descriptor */ 22140170Smarc int ctl = CTL; 22238674Smarc 22338674Smarc extern errno; 22438674Smarc 22538674Smarc #define NORMAL 0 /* only print modes differing from defaults */ 22638674Smarc #define ALL 1 /* print all modes - POSIX standard format */ 22738674Smarc #define ALL_BSD 2 /* print all modes - using BSD shorthand for cc's */ 228*43323Smarc #define GFMT 3 /* print modes in form suitable to be re-input */ 22938674Smarc 23038674Smarc main(argc, argv) 23138674Smarc char *argv[]; 2321179Sbill { 23338674Smarc struct termios t; 23438674Smarc int i, fmt = NORMAL; 23538674Smarc extern char *optarg; 23638674Smarc extern int optind; 23738674Smarc int ch; 2381179Sbill 23938674Smarc argc--, argv++; 24038674Smarc if (argc > 0 && eq(argv[0], "-a")) { 24138674Smarc fmt = ALL; 24238674Smarc argc--, argv++; 2431179Sbill } 244*43323Smarc if (argc > 0 && eq(argv[0], "-g")) { 245*43323Smarc fmt = GFMT; 246*43323Smarc argc--, argv++; 247*43323Smarc } 24838674Smarc if (argc > 0 && eq(argv[0], "-f")) { 24938674Smarc argc--, argv++; 25038674Smarc if ((ctl = open(argv[0], O_RDONLY | O_NONBLOCK)) < 0) 25138674Smarc syserrexit(*argv); 25238674Smarc argc--, argv++; 2531179Sbill } 25438674Smarc if (ioctl(ctl, TIOCGETD, &ldisc) < 0) 25538674Smarc syserrexit("TIOCGETD"); 25638674Smarc if (tcgetattr(ctl, &t) < 0) 25738674Smarc syserrexit("tcgetattr"); 25838674Smarc if (ioctl(ctl, TIOCGWINSZ, &win) < 0) 25940170Smarc warning("TIOCGWINSZ: %s", strerror(errno)); 26038674Smarc checkredirect(); /* conversion aid */ 26138674Smarc 26238674Smarc if (argc == 0 || fmt) { 26338674Smarc prmode(&t, ldisc, fmt); 2641179Sbill exit(0); 2651179Sbill } 26638674Smarc 26738674Smarc while (*argv) { 26838674Smarc if (eq("everything", *argv)) { 26938674Smarc prmode(&t, ldisc, ALL_BSD); 27038674Smarc exit(0); 2711179Sbill } 27238674Smarc if (eq("all", *argv)) { 27338674Smarc prmode(&t, ldisc, ALL); 27438674Smarc exit(0); 2751179Sbill } 27638674Smarc if (eq("old", *argv)) { 27738674Smarc goto next; 2781179Sbill } 27938674Smarc if (eq("new", *argv)) { 28038674Smarc goto next; 2811179Sbill } 28238674Smarc if (eq("nl", *argv)) { 28338674Smarc t.c_iflag &= ~ICRNL; 28438674Smarc t.c_oflag &= ~ONLCR; 28538674Smarc goto next; 2861179Sbill } 28738674Smarc if (eq("-nl", *argv)) { 28838674Smarc t.c_iflag |= ICRNL; 28938674Smarc t.c_oflag |= ONLCR; 29038674Smarc goto next; 2913797Sroot } 29238674Smarc if (eq("dec", *argv)){ 29338674Smarc t.c_cc[VERASE] = (u_char)0177; 29438674Smarc t.c_cc[VKILL] = CTRL('u'); 29538674Smarc t.c_cc[VINTR] = CTRL('c'); 29638674Smarc t.c_lflag &= ~ECHOPRT; 29738674Smarc t.c_lflag |= ECHOE|ECHOKE|ECHOCTL; 29838674Smarc t.c_iflag &= ~IXANY; 29938674Smarc goto next; 3001179Sbill } 30140169Skarels if (eq("raw", *argv)) { 30240169Skarels cfmakeraw(&t); 30340169Skarels t.c_cflag &= ~(CSIZE|PARENB); 30440169Skarels t.c_cflag |= CS8; 30540169Skarels goto next; 30640169Skarels } 30740169Skarels if (eq("cooked", *argv) || eq("-raw", *argv) || 30840169Skarels eq("sane", *argv)) { 30940169Skarels t.c_cflag = TTYDEF_CFLAG | (t.c_cflag & CLOCAL); 31040169Skarels t.c_iflag = TTYDEF_IFLAG; 31140169Skarels t.c_iflag |= ICRNL; 31240169Skarels /* preserve user-preference flags in lflag */ 31340169Skarels #define LKEEP (ECHOKE|ECHOE|ECHOK|ECHOPRT|ECHOCTL|ALTWERASE|TOSTOP|NOFLSH) 31440169Skarels t.c_lflag = TTYDEF_LFLAG | (t.c_lflag & LKEEP); 31540169Skarels t.c_oflag = TTYDEF_OFLAG; 31640169Skarels goto next; 31740169Skarels } 31838674Smarc if (eq("rows", *argv)) { 31938674Smarc if (*(argv+1) == 0) 32038674Smarc goto setit; 32118023Sbloom win.ws_row = atoi(*++argv); 32238674Smarc goto next; 32318023Sbloom } 32438674Smarc if (eq("ispeed", *argv)) { 32538674Smarc int code; 32638674Smarc if (*(argv+1) == 0) 32738674Smarc errexit("missing ispeed"); 32838674Smarc cfsetispeed(&t, atoi(*++argv)); 32938674Smarc goto next; 33038674Smarc } 33138674Smarc if (eq("ospeed", *argv)) { 33238674Smarc if (*(argv+1) == 0) 33338674Smarc errexit("missing ospeed"); 33438674Smarc cfsetospeed(&t, atoi(*++argv)); 33538674Smarc goto next; 33638674Smarc } 33738674Smarc if (eq("cols", *argv) || eq("columns", *argv)) { 33838674Smarc if (*(argv+1) == 0) 33938674Smarc goto setit; 34018023Sbloom win.ws_col = atoi(*++argv); 34138674Smarc goto next; 34218023Sbloom } 34338674Smarc if (eq("size", *argv)) { 34438674Smarc put("%d %d\n", win.ws_row, win.ws_col); 34525791Skarels exit(0); 34625791Skarels } 34738674Smarc if (eq("speed", *argv)) { 34838674Smarc put("%d\n", cfgetospeed(&t)); 34938674Smarc exit(0); 35038674Smarc } 35138674Smarc for (i=0; imodes[i].name; i++) 35238674Smarc if (eq(imodes[i].name, *argv)) { 35338674Smarc t.c_iflag &= ~imodes[i].unset; 35438674Smarc t.c_iflag |= imodes[i].set; 35538674Smarc goto next; 3561179Sbill } 35738674Smarc for (i=0; omodes[i].name; i++) 35838674Smarc if (eq(omodes[i].name, *argv)) { 35938674Smarc t.c_oflag &= ~omodes[i].unset; 36038674Smarc t.c_oflag |= omodes[i].set; 36138674Smarc goto next; 36238674Smarc } 36338674Smarc for (i=0; cmodes[i].name; i++) 36438674Smarc if (eq(cmodes[i].name, *argv)) { 36538674Smarc t.c_cflag &= ~cmodes[i].unset; 36638674Smarc t.c_cflag |= cmodes[i].set; 36738674Smarc goto next; 36838674Smarc } 36938674Smarc for (i=0; lmodes[i].name; i++) 37038674Smarc if (eq(lmodes[i].name, *argv)) { 37138674Smarc t.c_lflag &= ~lmodes[i].unset; 37238674Smarc t.c_lflag |= lmodes[i].set; 37338674Smarc goto next; 37438674Smarc } 37538674Smarc for (i=0; *cchars[i].names; i++) { 37638674Smarc char **cp = cchars[i].names; 37738674Smarc while (*cp) { 37838674Smarc if (eq(*cp, *argv)) { 37938674Smarc if (*++argv == 0) 38038674Smarc goto setit; 38138674Smarc if (eq(*argv, "undef") || 38238674Smarc eq(*argv, "disable")) 38338674Smarc t.c_cc[cchars[i].sub] = 38438674Smarc _POSIX_VDISABLE; 38538674Smarc else if (**argv == '^') 38638674Smarc t.c_cc[cchars[i].sub] = 38738674Smarc ((*argv)[1] == '?') ? 0177 : 38838674Smarc ((*argv)[1] == '-') ? 38938674Smarc _POSIX_VDISABLE : 39038674Smarc (*argv)[1] & 037; 39138674Smarc else 39238674Smarc t.c_cc[cchars[i].sub] = **argv; 39338674Smarc goto next; 3941179Sbill } 39538674Smarc cp++; 39638674Smarc } 3971179Sbill } 39838674Smarc if (isdigit(**argv)) { 39938674Smarc cfsetospeed(&t, atoi(*argv)); 40038674Smarc cfsetispeed(&t, atoi(*argv)); 40138674Smarc goto next; 40238674Smarc } 403*43323Smarc if (strncmp(*argv, "-gfmt", sizeof ("-gfmt") - 1) == 0) { 404*43323Smarc gfmtset(&t, *argv); 405*43323Smarc goto next; 406*43323Smarc } 40738674Smarc /* didn't match anything */ 40838674Smarc errexit("unknown option: %s", *argv); 40938674Smarc exit(1); 41038674Smarc next: 41138674Smarc argv++; 4121179Sbill } 41338674Smarc setit: 41438674Smarc if (tcsetattr(ctl, 0, &t) < 0) 41538674Smarc syserrexit("tcsetattr"); 41638674Smarc if (ioctl(ctl, TIOCSWINSZ, &win) < 0) 41738674Smarc warning("can't set window size"); 41838674Smarc 41938674Smarc exit(0); 4201179Sbill } 4211179Sbill 422*43323Smarc gfmtset(tp, s) 423*43323Smarc register struct termios *tp; 424*43323Smarc char *s; 425*43323Smarc { 426*43323Smarc register int cnt; 427*43323Smarc char sep; 428*43323Smarc char *saves = s; 429*43323Smarc int cval; 430*43323Smarc #define advance(c) while (*(s) && *(s) != (c)) (s)++; if (*s) (s)++ ; \ 431*43323Smarc else \ 432*43323Smarc errexit("bad gfmt operand: %s", saves) 433*43323Smarc #define chkeq(string) if (strncmp(s, (string), strlen(string))) \ 434*43323Smarc errexit("bad gfmt operand: %s", saves) 435*43323Smarc 436*43323Smarc if (s == NULL) 437*43323Smarc errexit("missing gfmt string"); 438*43323Smarc advance(':'); 439*43323Smarc chkeq("iflag="); 440*43323Smarc advance('='); 441*43323Smarc sscanf(s, "%x", &tp->c_iflag); 442*43323Smarc 443*43323Smarc advance(':'); 444*43323Smarc chkeq("oflag"); 445*43323Smarc advance('='); 446*43323Smarc sscanf(s, "%x", &tp->c_oflag); 447*43323Smarc 448*43323Smarc advance(':'); 449*43323Smarc chkeq("cflag"); 450*43323Smarc advance('='); 451*43323Smarc sscanf(s, "%x", &tp->c_cflag); 452*43323Smarc 453*43323Smarc advance(':'); 454*43323Smarc chkeq("lflag"); 455*43323Smarc advance('='); 456*43323Smarc sscanf(s, "%x", &tp->c_lflag); 457*43323Smarc 458*43323Smarc advance(':'); 459*43323Smarc chkeq("cc="); 460*43323Smarc 461*43323Smarc for (cnt = 0, sep = '='; cnt < NCCS; cnt++, sep = ',') { 462*43323Smarc advance(sep); 463*43323Smarc sscanf(s, "%o", &cval); 464*43323Smarc tp->c_cc[cnt] = cval; 465*43323Smarc } 466*43323Smarc 467*43323Smarc advance(':'); 468*43323Smarc chkeq("ispeed="); 469*43323Smarc advance('='); 470*43323Smarc sscanf(s, "%d", &tp->c_ispeed); 471*43323Smarc 472*43323Smarc advance(':'); 473*43323Smarc chkeq("ospeed="); 474*43323Smarc advance('='); 475*43323Smarc sscanf(s, "%d", &tp->c_ospeed); 4761179Sbill } 4771179Sbill 47838674Smarc prmode(tp, ldisc, fmt) 47938674Smarc struct termios *tp; 4801179Sbill { 48138674Smarc long i = tp->c_iflag, 48238674Smarc o = tp->c_oflag, 48338674Smarc c = tp->c_cflag, 48438674Smarc l = tp->c_lflag; 48538674Smarc u_char *cc = tp->c_cc; 48638674Smarc int ispeed = cfgetispeed(tp), 48738674Smarc ospeed = cfgetospeed(tp); 48838674Smarc char unknown[32], 48938674Smarc *ld; 49038674Smarc char *ccval(); 491*43323Smarc 492*43323Smarc if (fmt == GFMT) { 493*43323Smarc int cnt; 494*43323Smarc char sep; 495*43323Smarc 496*43323Smarc printf("-gfmt:iflag=%x:oflag=%x:cflag=%x:lflag=%x:cc", 497*43323Smarc i, o, c, l); 498*43323Smarc for (cnt = 0, sep = '='; cnt < NCCS; cnt++, sep = ',') 499*43323Smarc printf("%c%o", sep, cc[cnt]); 500*43323Smarc printf(":ispeed=%d:ospeed=%d:\n", ispeed, ospeed); 501*43323Smarc return; 502*43323Smarc } 50338674Smarc 50438674Smarc /* 50538674Smarc * line discipline 50638674Smarc */ 50738674Smarc if (ldisc != TTYDISC) { 50838674Smarc switch(ldisc) { 50938674Smarc case TABLDISC: 51038674Smarc ld = "tablet"; 5111179Sbill break; 51238674Smarc case SLIPDISC: 51340170Smarc ld = "slip"; 5141179Sbill break; 51538674Smarc default: 51638674Smarc sprintf(unknown, "#%d", ldisc); 51738674Smarc ld = unknown; 5181179Sbill } 51938674Smarc put("%s disc; ", ld); 52038674Smarc } 52138674Smarc /* 52238674Smarc * line speed 52338674Smarc */ 52438674Smarc if (ispeed != ospeed) 52538674Smarc put("ispeed %d baud; ospeed %d baud;", 52638674Smarc ispeed, ospeed); 52738674Smarc else 52838674Smarc put("speed %d baud;", ispeed); 52938674Smarc if (fmt) 53038674Smarc put(" %d rows; %d columns;", win.ws_row, win.ws_col); 53138674Smarc put("\n"); 53213817Ssam 53338674Smarc #define lput(n, f, d) if (fmt || on(f) != d) mdput(n+on(f)) 53438674Smarc /* 53538674Smarc * "local" flags 53638674Smarc */ 53738674Smarc #define on(f) ((l&f) != 0) 53838674Smarc if (debug) mdput("LFLAG: "); 53938674Smarc lput("-icanon ",ICANON, 1); 54038674Smarc lput("-isig ", ISIG, 1); 54138674Smarc lput("-iexten ", IEXTEN, 1); 54238674Smarc lput("-echo ",ECHO, 1); 54338674Smarc lput("-echoe ",ECHOE, 0); 54438674Smarc lput("-echok ",ECHOK, 0); 54538674Smarc lput("-echoke ",ECHOKE, 0); 54638674Smarc lput("-echonl ",ECHONL, 0); 54738674Smarc lput("-echoctl ",ECHOCTL, 0); 54838674Smarc lput("-echoprt ",ECHOPRT, 0); 54938674Smarc lput("-altwerase ",ALTWERASE, 0); 55038674Smarc lput("-noflsh ",NOFLSH, 0); 55138674Smarc lput("-tostop ",TOSTOP, 0); 55238674Smarc lput("-mdmbuf ",MDMBUF, 0); 55338674Smarc lput("-flusho ",FLUSHO, 0); 55438674Smarc lput("-pendin ",PENDIN, 0); 55538674Smarc /* 55638674Smarc * input flags 55738674Smarc */ 55838674Smarc #undef on 55938674Smarc #define on(f) ((i&f) != 0) 56038674Smarc mdput(0); 56138674Smarc if (debug) mdput("IFLAG: "); 56238674Smarc lput("-istrip ", ISTRIP, 0); 56338674Smarc lput("-icrnl ", ICRNL, 1); 56438674Smarc lput("-inlcr ", INLCR, 0); 56538674Smarc lput("-igncr ", IGNCR, 0); 56638674Smarc lput("-ixon ", IXON, 1); 56738674Smarc lput("-ixoff ", IXOFF, 0); 56838674Smarc lput("-ixany ", IXANY, 1); 56938674Smarc lput("-imaxbel ", IMAXBEL, 1); 57038674Smarc lput("-ignbrk ", IGNBRK, 0); 57138674Smarc lput("-brkint ", BRKINT, 1); 57238674Smarc lput("-inpck ", INPCK, 0); 57338674Smarc lput("-ignpar ", IGNPAR, 0); 57438674Smarc lput("-parmrk ", PARMRK, 0); 57538674Smarc #undef on 57638674Smarc /* 57738674Smarc * output flags 57838674Smarc */ 57938674Smarc #define on(f) ((o&f) != 0) 58038674Smarc mdput(0); 58138674Smarc if (debug) mdput("OFLAG: "); 58238674Smarc lput("-opost ", OPOST, 1); 58338674Smarc lput("-onlcr ", ONLCR, 1); 58438674Smarc lput("-oxtabs ", OXTABS, 1); 58538674Smarc #undef on 58638674Smarc /* 58738674Smarc * control flags (hardware state) 58838674Smarc */ 58938674Smarc #define on(f) ((c&f) != 0) 59038674Smarc mdput(0); 59138674Smarc if (debug) mdput("CFLAG: "); 59238674Smarc lput("-cread ", CREAD, 1); 59338674Smarc switch(c&CSIZE) { 59438674Smarc case CS5: mdput("cs5 "); break; 59538674Smarc case CS6: mdput("cs6 "); break; 59638674Smarc case CS7: mdput("cs7 "); break; 59738674Smarc case CS8: mdput("cs8 "); break; 59838674Smarc } 59938674Smarc mdput("-parenb "+on(PARENB)); 60038674Smarc lput("-parodd ", PARODD, 0); 60138674Smarc lput("-hupcl ", HUPCL, 1); 60238674Smarc lput("-clocal ", CLOCAL, 0); 60338674Smarc lput("-cstopb ", CSTOPB, 0); 60438674Smarc lput("-crtscts ", CRTSCTS, 0); 60538674Smarc mdput(0); 60638674Smarc #undef on 60738674Smarc /* 60838674Smarc * special control characters 60938674Smarc */ 61038674Smarc if (debug) mdput("CCHARS: "); 61138674Smarc if (fmt != 2) { 61238674Smarc for (i=0; *cchars[i].names; i++) { 61338674Smarc char temp[64]; 61438674Smarc 61538674Smarc if (fmt || cc[cchars[i].sub] != cchars[i].def) { 61638674Smarc sprintf(temp, "%s = %s; ", *cchars[i].names, 61738674Smarc ccval(cc[cchars[i].sub]), fmt); 61838674Smarc mdput(temp); 61938674Smarc } 6201179Sbill } 62138674Smarc mdput(0); 62238674Smarc } else { 62338674Smarc for (i=0; *cchars[i].names; i++) 62438674Smarc put("%*s", strlen(*(cchars[i].names+1)) + (i>0?1:0), 62538674Smarc *(cchars[i].names+1)); 62638674Smarc printf("\n"); 62738674Smarc for (i=0; *cchars[i].names; i++) 62838674Smarc put("%*s", strlen(*(cchars[i].names+1)) + (i>0?1:0), 62938674Smarc ccval(cc[cchars[i].sub], fmt)); 63038674Smarc printf("\n"); 6311179Sbill } 6321179Sbill } 6331179Sbill 63438674Smarc /* 63538674Smarc * gross, but since we're changing the control descriptor 63638674Smarc * from 1 to 0, most users will be probably be doing 63738674Smarc * "stty > /dev/sometty" by accident. If 1 and 2 are both ttys, 63838674Smarc * but not the same, assume that 1 was incorrectly redirected. 63938674Smarc */ 64038674Smarc checkredirect() { 64138674Smarc struct stat st1, st2; 64238674Smarc 64338674Smarc if (isatty(1) && isatty(2) && fstat(1, &st1) != -1 && 64438674Smarc fstat(2, &st2) != -1 && (st1.st_rdev != st2.st_rdev)) 64538674Smarc warning("stdout appears redirected, but stdin is the control descriptor"); 64638674Smarc } 64738674Smarc 64840170Smarc char * 64938674Smarc ccval(c, fmt) 65038674Smarc unsigned char c; 6511179Sbill { 65238674Smarc static char buf[128]; 65338674Smarc char *bp; 6541179Sbill 65538674Smarc *buf = 0, bp = buf; 65638674Smarc if (c == _POSIX_VDISABLE) 65738674Smarc if (fmt == 2) 65838674Smarc return("<u>"); 65938674Smarc else 66038674Smarc return("<undef>"); 66138674Smarc if (c & 0200) { 66238674Smarc strcat(buf, "M-"); 66338674Smarc *bp++ = 'M'; 66438674Smarc *bp++ = '-'; 66538674Smarc c &= 0177; 6661179Sbill } 66738674Smarc if (c == 0177) { 66838674Smarc *bp++ = '^'; 66938674Smarc *bp++ = '?'; 6701179Sbill } 67138674Smarc else if (c < 040) { 67238674Smarc *bp++ = '^'; 67338674Smarc *bp++ = c + '@'; 67438674Smarc } 67538674Smarc else 67638674Smarc *bp++ = c; 67738674Smarc *bp = 0; 67838674Smarc return(buf); 6791179Sbill } 6801179Sbill 68140170Smarc 68238674Smarc mdput(s) 68338674Smarc char *s; 6841179Sbill { 68538674Smarc static int col = 0; 6861179Sbill 68738674Smarc if (s == (char *)0) { 68838674Smarc if (col) { 68938674Smarc put("\n"); 69038674Smarc col = 0; 69138674Smarc } 6921179Sbill return; 6931179Sbill } 69438674Smarc if ((col += strlen(s)) > WRAPCOL) { 69538674Smarc put("\n"); 69638674Smarc col = strlen(s); 6971179Sbill } 69838674Smarc put(s); 6991179Sbill } 7001179Sbill 70140170Smarc #include <varargs.h> 70240170Smarc 70340170Smarc put(va_alist) 70440170Smarc va_dcl 7051179Sbill { 70640170Smarc char *fmt; 70740170Smarc va_list ap; 70840170Smarc 70940170Smarc va_start(ap); 71040170Smarc fmt = va_arg(ap, char *); 71140170Smarc (void) vfprintf(OUT, fmt, ap); 71240170Smarc va_end(ap); 71338674Smarc } 7141179Sbill 71540170Smarc 71640170Smarc warning(va_alist) 71740170Smarc va_dcl 71838674Smarc { 71940170Smarc char *fmt; 72040170Smarc va_list ap; 72140170Smarc 72238674Smarc fprintf(ERR, "stty: warning: "); 72340170Smarc va_start(ap); 72440170Smarc fmt = va_arg(ap, char *); 72540170Smarc (void) vfprintf(ERR, fmt, ap); 72640170Smarc va_end(ap); 72738674Smarc fprintf(ERR, "\n"); 7281179Sbill } 7291179Sbill 73040170Smarc 73140170Smarc errexit(va_alist) 73240170Smarc va_dcl 73338674Smarc { 73440170Smarc char *fmt; 73540170Smarc va_list ap; 73640170Smarc 73738674Smarc fprintf(ERR, "stty: "); 73840170Smarc va_start(ap); 73940170Smarc fmt = va_arg(ap, char *); 74040170Smarc (void) vfprintf(ERR, fmt, ap); 74140170Smarc va_end(ap); 74238674Smarc fprintf(ERR, "\n"); 74338674Smarc exit(1); 74438674Smarc } 7451179Sbill 74640170Smarc 74740170Smarc syserrexit(va_alist) 74840170Smarc va_dcl 7491179Sbill { 75040170Smarc char *fmt; 75140170Smarc va_list ap; 75240170Smarc 75338674Smarc fprintf(ERR, "stty: "); 75440170Smarc va_start(ap); 75540170Smarc fmt = va_arg(ap, char *); 75640170Smarc (void) vfprintf(ERR, fmt, ap); 75740170Smarc va_end(ap); 75840170Smarc fprintf(ERR, ": %s\n", strerror(errno)); 75938674Smarc exit(1); 7601179Sbill } 761