|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980, 1989 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: char copyright[] = ! 9: "@(#) Copyright (c) 1980, 1989 Regents of the University of California.\n\ ! 10: All rights reserved.\n"; ! 11: #endif not lint ! 12: ! 13: #ifndef lint ! 14: static char sccsid[] = "@(#)stty.c 5.16 (Berkeley) 6/29/90"; ! 15: #endif not lint ! 16: ! 17: /* ! 18: * set teletype modes ! 19: */ ! 20: ! 21: #include <sys/types.h> ! 22: #include <sys/stat.h> ! 23: #include <sys/ioctl.h> ! 24: #include <sys/syslog.h> ! 25: #define KERNEL ! 26: #include <sys/tty.h> ! 27: #undef KERNEL ! 28: #include <sys/termios.h> ! 29: #include <sys/file.h> ! 30: #include <errno.h> ! 31: #include <ctype.h> ! 32: #include <stdio.h> ! 33: ! 34: #define eq(s1, s2) (strcmp((s1), (s2)) == 0) ! 35: #define WRAPCOL 65 ! 36: ! 37: struct modes { ! 38: char *name; ! 39: long set; ! 40: long unset; ! 41: }; ! 42: ! 43: struct modes imodes[] = { ! 44: "ignbrk", IGNBRK, 0, ! 45: "-ignbrk", 0, IGNBRK, ! 46: "brkint", BRKINT, 0, ! 47: "-brkint", 0, BRKINT, ! 48: "ignpar", IGNPAR, 0, ! 49: "-ignpar", 0, IGNPAR, ! 50: "parmrk", PARMRK, 0, ! 51: "-parmrk", 0, PARMRK, ! 52: "inpck", INPCK, 0, ! 53: "-inpck", 0, INPCK, ! 54: "istrip", ISTRIP, 0, ! 55: "-istrip", 0, ISTRIP, ! 56: "inlcr", INLCR, 0, ! 57: "-inlcr", 0, INLCR, ! 58: "igncr", IGNCR, 0, ! 59: "-igncr", 0, IGNCR, ! 60: "icrnl", ICRNL, 0, ! 61: "-icrnl", 0, ICRNL, ! 62: "ixon", IXON, 0, ! 63: "-ixon", 0, IXON, ! 64: "flow", IXON, 0, ! 65: "-flow", 0, IXON, ! 66: "ixoff", IXOFF, 0, ! 67: "-ixoff", 0, IXOFF, ! 68: "tandem", IXOFF, 0, ! 69: "-tandem", 0, IXOFF, ! 70: "ixany", IXANY, 0, ! 71: "-ixany", 0, IXANY, ! 72: "decctlq", 0, IXANY, ! 73: "-decctlq", IXANY, 0, ! 74: "imaxbel", IMAXBEL, 0, ! 75: "-imaxbel", 0, IMAXBEL, ! 76: 0 ! 77: }; ! 78: ! 79: struct modes omodes[] = { ! 80: "opost", OPOST, 0, ! 81: "-opost", 0, OPOST, ! 82: "-litout", OPOST, 0, ! 83: "litout", 0, OPOST, ! 84: "onlcr", ONLCR, 0, ! 85: "-onlcr", 0, ONLCR, ! 86: "tabs", 0, OXTABS, /* "preserve" tabs */ ! 87: "-tabs", OXTABS, 0, ! 88: "xtabs", OXTABS, 0, ! 89: "-xtabs", 0, OXTABS, ! 90: "oxtabs", OXTABS, 0, ! 91: "-oxtabs", 0, OXTABS, ! 92: 0 ! 93: }; ! 94: ! 95: struct modes cmodes[] = { ! 96: "cs5", CS5, CSIZE, ! 97: "cs6", CS6, CSIZE, ! 98: "cs7", CS7, CSIZE, ! 99: "cs8", CS8, CSIZE, ! 100: "cstopb", CSTOPB, 0, ! 101: "-cstopb", 0, CSTOPB, ! 102: "cread", CREAD, 0, ! 103: "-cread", 0, CREAD, ! 104: "parenb", PARENB, 0, ! 105: "-parenb", 0, PARENB, ! 106: "parodd", PARODD, 0, ! 107: "-parodd", 0, PARODD, ! 108: "parity", PARENB | CS7, PARODD | CSIZE, ! 109: "evenp", PARENB | CS7, PARODD | CSIZE, ! 110: "oddp", PARENB | CS7 | PARODD, CSIZE, ! 111: "-parity", CS8, PARODD | PARENB | CSIZE, ! 112: "pass8", CS8, PARODD | PARENB | CSIZE, ! 113: "-evenp", CS8, PARODD | PARENB | CSIZE, ! 114: "-oddp", CS8, PARODD | PARENB | CSIZE, ! 115: "hupcl", HUPCL, 0, ! 116: "-hupcl", 0, HUPCL, ! 117: "hup", HUPCL, 0, ! 118: "-hup", 0, HUPCL, ! 119: "clocal", CLOCAL, 0, ! 120: "-clocal", 0, CLOCAL, ! 121: "crtscts", CRTSCTS, 0, ! 122: "-crtscts", 0, CRTSCTS, ! 123: 0 ! 124: }; ! 125: ! 126: struct modes lmodes[] = { ! 127: "echo", ECHO, 0, ! 128: "-echo", 0, ECHO, ! 129: "echoe", ECHOE, 0, ! 130: "-echoe", 0, ECHOE, ! 131: "crterase", ECHOE, 0, ! 132: "-crterase", 0, ECHOE, ! 133: "crtbs", ECHOE, 0, /* crtbs not supported, close enough */ ! 134: "-crtbs", 0, ECHOE, ! 135: "echok", ECHOK, 0, ! 136: "-echok", 0, ECHOK, ! 137: "echoke", ECHOKE, 0, ! 138: "-echoke", 0, ECHOKE, ! 139: "crtkill", ECHOKE, 0, ! 140: "-crtkill", 0, ECHOKE, ! 141: "altwerase", ALTWERASE, 0, ! 142: "-altwerase", 0, ALTWERASE, ! 143: "iexten", IEXTEN, 0, ! 144: "-iexten", 0, IEXTEN, ! 145: "echonl", ECHONL, 0, ! 146: "-echonl", 0, ECHONL, ! 147: "echoctl", ECHOCTL, 0, ! 148: "-echoctl", 0, ECHOCTL, ! 149: "ctlecho", ECHOCTL, 0, ! 150: "-ctlecho", 0, ECHOCTL, ! 151: "echoprt", ECHOPRT, 0, ! 152: "-echoprt", 0, ECHOPRT, ! 153: "prterase", ECHOPRT, 0, ! 154: "-prterase", 0, ECHOPRT, ! 155: "isig", ISIG, 0, ! 156: "-isig", 0, ISIG, ! 157: "icanon", ICANON, 0, ! 158: "-icanon", 0, ICANON, ! 159: "noflsh", NOFLSH, 0, ! 160: "-noflsh", 0, NOFLSH, ! 161: "tostop", TOSTOP, 0, ! 162: "-tostop", 0, TOSTOP, ! 163: "mdmbuf", MDMBUF, 0, ! 164: "-mdmbuf", 0, MDMBUF, ! 165: "flusho", FLUSHO, 0, ! 166: "-flusho", 0, FLUSHO, ! 167: "pendin", PENDIN, 0, ! 168: "-pendin", 0, PENDIN, ! 169: "crt", ECHOE|ECHOKE|ECHOCTL, ECHOK|ECHOPRT, ! 170: "-crt", ECHOK, ECHOE|ECHOKE|ECHOCTL, ! 171: "newcrt", ECHOE|ECHOKE|ECHOCTL, ECHOK|ECHOPRT, ! 172: "-newcrt", ECHOK, ECHOE|ECHOKE|ECHOCTL, ! 173: 0 ! 174: }; ! 175: ! 176: /* ! 177: * Special control characters. ! 178: * ! 179: * Each entry has a list of names. The first is the primary name ! 180: * and is used when printing the control character in the "name = val;" ! 181: * form. The second is an abbreviation which is guaranteed to be less ! 182: * than or equal to four characters in length and is primarily used ! 183: * when printing the values in columunar form (guarantees all will ! 184: * fit within 80 cols). The rest are optional aliases. ! 185: * All names are recognized on the command line. ! 186: */ ! 187: #define MAXNAMES 3 ! 188: struct { ! 189: char *names[MAXNAMES+1]; ! 190: int sub; ! 191: u_char def; ! 192: } cchars[] = { ! 193: {{ "erase", "era" }, VERASE, CERASE, }, ! 194: {{ "werase", "wera" }, VWERASE, CWERASE, }, ! 195: {{ "kill", "kill" }, VKILL, CKILL, }, ! 196: {{ "intr", "int" }, VINTR, CINTR, }, ! 197: {{ "quit", "quit" }, VQUIT, CQUIT, }, ! 198: {{ "susp", "susp" }, VSUSP, CSUSP, }, ! 199: {{ "dsusp", "dsus" }, VDSUSP, CDSUSP, }, ! 200: {{ "eof", "eof" }, VEOF, CEOF, }, ! 201: {{ "eol", "eol", "brk" }, VEOL, CEOL, }, ! 202: {{ "eol2", "eol2" }, VEOL2, CEOL, }, ! 203: {{ "stop", "stop", "xoff" }, VSTOP, CSTOP, }, ! 204: {{ "start", "star", "xon" }, VSTART, CSTART, }, ! 205: {{ "lnext", "lnxt" }, VLNEXT, CLNEXT, }, ! 206: {{ "discard", "disc", "flush" }, VDISCARD, CDISCARD, }, ! 207: {{ "reprint", "rpnt", "rprnt" }, VREPRINT, CREPRINT, }, ! 208: {{ "status", "stat" }, VSTATUS, CSTATUS, }, ! 209: 0 ! 210: }; ! 211: ! 212: struct winsize win; ! 213: int ldisc; ! 214: int dodisc; ! 215: int debug = 0; ! 216: int trace, dotrace; ! 217: ! 218: #define OUT stdout /* informational output stream */ ! 219: #define ERR stderr /* error message stream */ ! 220: #define CTL 0 /* default control descriptor */ ! 221: int ctl = CTL; ! 222: ! 223: extern errno; ! 224: ! 225: #define NORMAL 0 /* only print modes differing from defaults */ ! 226: #define ALL 1 /* print all modes - POSIX standard format */ ! 227: #define ALL_BSD 2 /* print all modes - using BSD shorthand for cc's */ ! 228: #define GFMT 3 /* print modes in form suitable to be re-input */ ! 229: ! 230: main(argc, argv) ! 231: char *argv[]; ! 232: { ! 233: struct termios t; ! 234: int i, fmt = NORMAL; ! 235: extern char *optarg; ! 236: extern int optind; ! 237: int ch; ! 238: ! 239: argc--, argv++; ! 240: if (argc > 0 && eq(argv[0], "-a")) { ! 241: fmt = ALL; ! 242: argc--, argv++; ! 243: } ! 244: if (argc > 0 && eq(argv[0], "-g")) { ! 245: fmt = GFMT; ! 246: argc--, argv++; ! 247: } ! 248: if (argc > 0 && eq(argv[0], "-f")) { ! 249: argc--, argv++; ! 250: if ((ctl = open(argv[0], O_RDONLY | O_NONBLOCK)) < 0) ! 251: syserrexit(*argv); ! 252: argc--, argv++; ! 253: } ! 254: if (ioctl(ctl, TIOCGETD, &ldisc) < 0) ! 255: syserrexit("TIOCGETD"); ! 256: if (tcgetattr(ctl, &t) < 0) ! 257: syserrexit("tcgetattr"); ! 258: if (ioctl(ctl, TIOCGWINSZ, &win) < 0) ! 259: warning("TIOCGWINSZ: %s", strerror(errno)); ! 260: checkredirect(); /* conversion aid */ ! 261: ! 262: if (argc == 0 || fmt) { ! 263: prmode(&t, ldisc, fmt); ! 264: exit(0); ! 265: } ! 266: ! 267: while (*argv) { ! 268: if (eq("everything", *argv)) { ! 269: prmode(&t, ldisc, ALL_BSD); ! 270: exit(0); ! 271: } ! 272: if (eq("all", *argv)) { ! 273: prmode(&t, ldisc, ALL); ! 274: exit(0); ! 275: } ! 276: if (eq("old", *argv)) { ! 277: goto next; ! 278: } ! 279: if (eq("new", *argv)) { ! 280: goto next; ! 281: } ! 282: if (eq("nl", *argv)) { ! 283: t.c_iflag &= ~ICRNL; ! 284: t.c_oflag &= ~ONLCR; ! 285: goto next; ! 286: } ! 287: if (eq("-nl", *argv)) { ! 288: t.c_iflag |= ICRNL; ! 289: t.c_oflag |= ONLCR; ! 290: goto next; ! 291: } ! 292: if (eq("dec", *argv)){ ! 293: t.c_cc[VERASE] = (u_char)0177; ! 294: t.c_cc[VKILL] = CTRL('u'); ! 295: t.c_cc[VINTR] = CTRL('c'); ! 296: t.c_lflag &= ~ECHOPRT; ! 297: t.c_lflag |= ECHOE|ECHOKE|ECHOCTL; ! 298: t.c_iflag &= ~IXANY; ! 299: goto next; ! 300: } ! 301: if (eq("raw", *argv)) { ! 302: cfmakeraw(&t); ! 303: t.c_cflag &= ~(CSIZE|PARENB); ! 304: t.c_cflag |= CS8; ! 305: goto next; ! 306: } ! 307: if (eq("cooked", *argv) || eq("-raw", *argv) || ! 308: eq("sane", *argv)) { ! 309: t.c_cflag = TTYDEF_CFLAG | (t.c_cflag & CLOCAL); ! 310: t.c_iflag = TTYDEF_IFLAG; ! 311: t.c_iflag |= ICRNL; ! 312: /* preserve user-preference flags in lflag */ ! 313: #define LKEEP (ECHOKE|ECHOE|ECHOK|ECHOPRT|ECHOCTL|ALTWERASE|TOSTOP|NOFLSH) ! 314: t.c_lflag = TTYDEF_LFLAG | (t.c_lflag & LKEEP); ! 315: t.c_oflag = TTYDEF_OFLAG; ! 316: goto next; ! 317: } ! 318: if (eq("rows", *argv)) { ! 319: if (*(argv+1) == 0) ! 320: goto setit; ! 321: win.ws_row = atoi(*++argv); ! 322: goto next; ! 323: } ! 324: if (eq("ispeed", *argv)) { ! 325: int code; ! 326: if (*(argv+1) == 0) ! 327: errexit("missing ispeed"); ! 328: cfsetispeed(&t, atoi(*++argv)); ! 329: goto next; ! 330: } ! 331: if (eq("ospeed", *argv)) { ! 332: if (*(argv+1) == 0) ! 333: errexit("missing ospeed"); ! 334: cfsetospeed(&t, atoi(*++argv)); ! 335: goto next; ! 336: } ! 337: if (eq("cols", *argv) || eq("columns", *argv)) { ! 338: if (*(argv+1) == 0) ! 339: goto setit; ! 340: win.ws_col = atoi(*++argv); ! 341: goto next; ! 342: } ! 343: if (eq("size", *argv)) { ! 344: put("%d %d\n", win.ws_row, win.ws_col); ! 345: exit(0); ! 346: } ! 347: if (eq("speed", *argv)) { ! 348: put("%d\n", cfgetospeed(&t)); ! 349: exit(0); ! 350: } ! 351: for (i=0; imodes[i].name; i++) ! 352: if (eq(imodes[i].name, *argv)) { ! 353: t.c_iflag &= ~imodes[i].unset; ! 354: t.c_iflag |= imodes[i].set; ! 355: goto next; ! 356: } ! 357: for (i=0; omodes[i].name; i++) ! 358: if (eq(omodes[i].name, *argv)) { ! 359: t.c_oflag &= ~omodes[i].unset; ! 360: t.c_oflag |= omodes[i].set; ! 361: goto next; ! 362: } ! 363: for (i=0; cmodes[i].name; i++) ! 364: if (eq(cmodes[i].name, *argv)) { ! 365: t.c_cflag &= ~cmodes[i].unset; ! 366: t.c_cflag |= cmodes[i].set; ! 367: goto next; ! 368: } ! 369: for (i=0; lmodes[i].name; i++) ! 370: if (eq(lmodes[i].name, *argv)) { ! 371: t.c_lflag &= ~lmodes[i].unset; ! 372: t.c_lflag |= lmodes[i].set; ! 373: goto next; ! 374: } ! 375: for (i=0; *cchars[i].names; i++) { ! 376: char **cp = cchars[i].names; ! 377: while (*cp) { ! 378: if (eq(*cp, *argv)) { ! 379: if (*++argv == 0) ! 380: goto setit; ! 381: if (eq(*argv, "undef") || ! 382: eq(*argv, "disable")) ! 383: t.c_cc[cchars[i].sub] = ! 384: _POSIX_VDISABLE; ! 385: else if (**argv == '^') ! 386: t.c_cc[cchars[i].sub] = ! 387: ((*argv)[1] == '?') ? 0177 : ! 388: ((*argv)[1] == '-') ? ! 389: _POSIX_VDISABLE : ! 390: (*argv)[1] & 037; ! 391: else ! 392: t.c_cc[cchars[i].sub] = **argv; ! 393: goto next; ! 394: } ! 395: cp++; ! 396: } ! 397: } ! 398: if (isdigit(**argv)) { ! 399: cfsetospeed(&t, atoi(*argv)); ! 400: cfsetispeed(&t, atoi(*argv)); ! 401: goto next; ! 402: } ! 403: if (strncmp(*argv, "-gfmt", sizeof ("-gfmt") - 1) == 0) { ! 404: gfmtset(&t, *argv); ! 405: goto next; ! 406: } ! 407: /* didn't match anything */ ! 408: errexit("unknown option: %s", *argv); ! 409: exit(1); ! 410: next: ! 411: argv++; ! 412: } ! 413: setit: ! 414: if (tcsetattr(ctl, 0, &t) < 0) ! 415: syserrexit("tcsetattr"); ! 416: if (ioctl(ctl, TIOCSWINSZ, &win) < 0) ! 417: warning("can't set window size"); ! 418: ! 419: exit(0); ! 420: } ! 421: ! 422: gfmtset(tp, s) ! 423: register struct termios *tp; ! 424: char *s; ! 425: { ! 426: register int cnt; ! 427: char sep; ! 428: char *saves = s; ! 429: int cval; ! 430: #define advance(c) while (*(s) && *(s) != (c)) (s)++; if (*s) (s)++ ; \ ! 431: else \ ! 432: errexit("bad gfmt operand: %s", saves) ! 433: #define chkeq(string) if (strncmp(s, (string), strlen(string))) \ ! 434: errexit("bad gfmt operand: %s", saves) ! 435: ! 436: if (s == NULL) ! 437: errexit("missing gfmt string"); ! 438: advance(':'); ! 439: chkeq("iflag="); ! 440: advance('='); ! 441: sscanf(s, "%x", &tp->c_iflag); ! 442: ! 443: advance(':'); ! 444: chkeq("oflag"); ! 445: advance('='); ! 446: sscanf(s, "%x", &tp->c_oflag); ! 447: ! 448: advance(':'); ! 449: chkeq("cflag"); ! 450: advance('='); ! 451: sscanf(s, "%x", &tp->c_cflag); ! 452: ! 453: advance(':'); ! 454: chkeq("lflag"); ! 455: advance('='); ! 456: sscanf(s, "%x", &tp->c_lflag); ! 457: ! 458: advance(':'); ! 459: chkeq("cc="); ! 460: ! 461: for (cnt = 0, sep = '='; cnt < NCCS; cnt++, sep = ',') { ! 462: advance(sep); ! 463: sscanf(s, "%o", &cval); ! 464: tp->c_cc[cnt] = cval; ! 465: } ! 466: ! 467: advance(':'); ! 468: chkeq("ispeed="); ! 469: advance('='); ! 470: sscanf(s, "%d", &tp->c_ispeed); ! 471: ! 472: advance(':'); ! 473: chkeq("ospeed="); ! 474: advance('='); ! 475: sscanf(s, "%d", &tp->c_ospeed); ! 476: } ! 477: ! 478: prmode(tp, ldisc, fmt) ! 479: struct termios *tp; ! 480: { ! 481: long i = tp->c_iflag, ! 482: o = tp->c_oflag, ! 483: c = tp->c_cflag, ! 484: l = tp->c_lflag; ! 485: u_char *cc = tp->c_cc; ! 486: int ispeed = cfgetispeed(tp), ! 487: ospeed = cfgetospeed(tp); ! 488: char unknown[32], ! 489: *ld; ! 490: char *ccval(); ! 491: ! 492: if (fmt == GFMT) { ! 493: int cnt; ! 494: char sep; ! 495: ! 496: printf("-gfmt:iflag=%x:oflag=%x:cflag=%x:lflag=%x:cc", ! 497: i, o, c, l); ! 498: for (cnt = 0, sep = '='; cnt < NCCS; cnt++, sep = ',') ! 499: printf("%c%o", sep, cc[cnt]); ! 500: printf(":ispeed=%d:ospeed=%d:\n", ispeed, ospeed); ! 501: return; ! 502: } ! 503: ! 504: /* ! 505: * line discipline ! 506: */ ! 507: if (ldisc != TTYDISC) { ! 508: switch(ldisc) { ! 509: case TABLDISC: ! 510: ld = "tablet"; ! 511: break; ! 512: case SLIPDISC: ! 513: ld = "slip"; ! 514: break; ! 515: default: ! 516: sprintf(unknown, "#%d", ldisc); ! 517: ld = unknown; ! 518: } ! 519: put("%s disc; ", ld); ! 520: } ! 521: /* ! 522: * line speed ! 523: */ ! 524: if (ispeed != ospeed) ! 525: put("ispeed %d baud; ospeed %d baud;", ! 526: ispeed, ospeed); ! 527: else ! 528: put("speed %d baud;", ispeed); ! 529: if (fmt) ! 530: put(" %d rows; %d columns;", win.ws_row, win.ws_col); ! 531: put("\n"); ! 532: ! 533: #define lput(n, f, d) if (fmt || on(f) != d) mdput(n+on(f)) ! 534: /* ! 535: * "local" flags ! 536: */ ! 537: #define on(f) ((l&f) != 0) ! 538: if (debug) mdput("LFLAG: "); ! 539: lput("-icanon ",ICANON, 1); ! 540: lput("-isig ", ISIG, 1); ! 541: lput("-iexten ", IEXTEN, 1); ! 542: lput("-echo ",ECHO, 1); ! 543: lput("-echoe ",ECHOE, 0); ! 544: lput("-echok ",ECHOK, 0); ! 545: lput("-echoke ",ECHOKE, 0); ! 546: lput("-echonl ",ECHONL, 0); ! 547: lput("-echoctl ",ECHOCTL, 0); ! 548: lput("-echoprt ",ECHOPRT, 0); ! 549: lput("-altwerase ",ALTWERASE, 0); ! 550: lput("-noflsh ",NOFLSH, 0); ! 551: lput("-tostop ",TOSTOP, 0); ! 552: lput("-mdmbuf ",MDMBUF, 0); ! 553: lput("-flusho ",FLUSHO, 0); ! 554: lput("-pendin ",PENDIN, 0); ! 555: /* ! 556: * input flags ! 557: */ ! 558: #undef on ! 559: #define on(f) ((i&f) != 0) ! 560: mdput(0); ! 561: if (debug) mdput("IFLAG: "); ! 562: lput("-istrip ", ISTRIP, 0); ! 563: lput("-icrnl ", ICRNL, 1); ! 564: lput("-inlcr ", INLCR, 0); ! 565: lput("-igncr ", IGNCR, 0); ! 566: lput("-ixon ", IXON, 1); ! 567: lput("-ixoff ", IXOFF, 0); ! 568: lput("-ixany ", IXANY, 1); ! 569: lput("-imaxbel ", IMAXBEL, 1); ! 570: lput("-ignbrk ", IGNBRK, 0); ! 571: lput("-brkint ", BRKINT, 1); ! 572: lput("-inpck ", INPCK, 0); ! 573: lput("-ignpar ", IGNPAR, 0); ! 574: lput("-parmrk ", PARMRK, 0); ! 575: #undef on ! 576: /* ! 577: * output flags ! 578: */ ! 579: #define on(f) ((o&f) != 0) ! 580: mdput(0); ! 581: if (debug) mdput("OFLAG: "); ! 582: lput("-opost ", OPOST, 1); ! 583: lput("-onlcr ", ONLCR, 1); ! 584: lput("-oxtabs ", OXTABS, 1); ! 585: #undef on ! 586: /* ! 587: * control flags (hardware state) ! 588: */ ! 589: #define on(f) ((c&f) != 0) ! 590: mdput(0); ! 591: if (debug) mdput("CFLAG: "); ! 592: lput("-cread ", CREAD, 1); ! 593: switch(c&CSIZE) { ! 594: case CS5: mdput("cs5 "); break; ! 595: case CS6: mdput("cs6 "); break; ! 596: case CS7: mdput("cs7 "); break; ! 597: case CS8: mdput("cs8 "); break; ! 598: } ! 599: mdput("-parenb "+on(PARENB)); ! 600: lput("-parodd ", PARODD, 0); ! 601: lput("-hupcl ", HUPCL, 1); ! 602: lput("-clocal ", CLOCAL, 0); ! 603: lput("-cstopb ", CSTOPB, 0); ! 604: lput("-crtscts ", CRTSCTS, 0); ! 605: mdput(0); ! 606: #undef on ! 607: /* ! 608: * special control characters ! 609: */ ! 610: if (debug) mdput("CCHARS: "); ! 611: if (fmt != 2) { ! 612: for (i=0; *cchars[i].names; i++) { ! 613: char temp[64]; ! 614: ! 615: if (fmt || cc[cchars[i].sub] != cchars[i].def) { ! 616: sprintf(temp, "%s = %s; ", *cchars[i].names, ! 617: ccval(cc[cchars[i].sub]), fmt); ! 618: mdput(temp); ! 619: } ! 620: } ! 621: mdput(0); ! 622: } else { ! 623: for (i=0; *cchars[i].names; i++) ! 624: put("%*s", strlen(*(cchars[i].names+1)) + (i>0?1:0), ! 625: *(cchars[i].names+1)); ! 626: printf("\n"); ! 627: for (i=0; *cchars[i].names; i++) ! 628: put("%*s", strlen(*(cchars[i].names+1)) + (i>0?1:0), ! 629: ccval(cc[cchars[i].sub], fmt)); ! 630: printf("\n"); ! 631: } ! 632: } ! 633: ! 634: /* ! 635: * gross, but since we're changing the control descriptor ! 636: * from 1 to 0, most users will be probably be doing ! 637: * "stty > /dev/sometty" by accident. If 1 and 2 are both ttys, ! 638: * but not the same, assume that 1 was incorrectly redirected. ! 639: */ ! 640: checkredirect() { ! 641: struct stat st1, st2; ! 642: ! 643: if (isatty(1) && isatty(2) && fstat(1, &st1) != -1 && ! 644: fstat(2, &st2) != -1 && (st1.st_rdev != st2.st_rdev)) ! 645: warning("stdout appears redirected, but stdin is the control descriptor"); ! 646: } ! 647: ! 648: char * ! 649: ccval(c, fmt) ! 650: unsigned char c; ! 651: { ! 652: static char buf[128]; ! 653: char *bp; ! 654: ! 655: *buf = 0, bp = buf; ! 656: if (c == _POSIX_VDISABLE) ! 657: if (fmt == 2) ! 658: return("<u>"); ! 659: else ! 660: return("<undef>"); ! 661: if (c & 0200) { ! 662: strcat(buf, "M-"); ! 663: *bp++ = 'M'; ! 664: *bp++ = '-'; ! 665: c &= 0177; ! 666: } ! 667: if (c == 0177) { ! 668: *bp++ = '^'; ! 669: *bp++ = '?'; ! 670: } ! 671: else if (c < 040) { ! 672: *bp++ = '^'; ! 673: *bp++ = c + '@'; ! 674: } ! 675: else ! 676: *bp++ = c; ! 677: *bp = 0; ! 678: return(buf); ! 679: } ! 680: ! 681: ! 682: mdput(s) ! 683: char *s; ! 684: { ! 685: static int col = 0; ! 686: ! 687: if (s == (char *)0) { ! 688: if (col) { ! 689: put("\n"); ! 690: col = 0; ! 691: } ! 692: return; ! 693: } ! 694: if ((col += strlen(s)) > WRAPCOL) { ! 695: put("\n"); ! 696: col = strlen(s); ! 697: } ! 698: put(s); ! 699: } ! 700: ! 701: #include <varargs.h> ! 702: ! 703: put(va_alist) ! 704: va_dcl ! 705: { ! 706: char *fmt; ! 707: va_list ap; ! 708: ! 709: va_start(ap); ! 710: fmt = va_arg(ap, char *); ! 711: (void) vfprintf(OUT, fmt, ap); ! 712: va_end(ap); ! 713: } ! 714: ! 715: ! 716: warning(va_alist) ! 717: va_dcl ! 718: { ! 719: char *fmt; ! 720: va_list ap; ! 721: ! 722: fprintf(ERR, "stty: warning: "); ! 723: va_start(ap); ! 724: fmt = va_arg(ap, char *); ! 725: (void) vfprintf(ERR, fmt, ap); ! 726: va_end(ap); ! 727: fprintf(ERR, "\n"); ! 728: } ! 729: ! 730: ! 731: errexit(va_alist) ! 732: va_dcl ! 733: { ! 734: char *fmt; ! 735: va_list ap; ! 736: ! 737: fprintf(ERR, "stty: "); ! 738: va_start(ap); ! 739: fmt = va_arg(ap, char *); ! 740: (void) vfprintf(ERR, fmt, ap); ! 741: va_end(ap); ! 742: fprintf(ERR, "\n"); ! 743: exit(1); ! 744: } ! 745: ! 746: ! 747: syserrexit(va_alist) ! 748: va_dcl ! 749: { ! 750: char *fmt; ! 751: va_list ap; ! 752: ! 753: fprintf(ERR, "stty: "); ! 754: va_start(ap); ! 755: fmt = va_arg(ap, char *); ! 756: (void) vfprintf(ERR, fmt, ap); ! 757: va_end(ap); ! 758: fprintf(ERR, ": %s\n", strerror(errno)); ! 759: exit(1); ! 760: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.