1: #ifndef lint 2: static char *sccsid ="@(#)stty.c 4.7 (Berkeley) 7/18/81"; 3: #endif 4: /* 5: * set teletype modes 6: */ 7: 8: #include <whoami.h> 9: #include <stdio.h> 10: #include <sgtty.h> 11: 12: struct 13: { 14: char *string; 15: int speed; 16: } speeds[] = { 17: "0", B0, 18: "50", B50, 19: "75", B75, 20: "110", B110, 21: "134", B134, 22: "134.5",B134, 23: "150", B150, 24: "200", B200, 25: "300", B300, 26: "600", B600, 27: "1200", B1200, 28: "1800", B1800, 29: "2400", B2400, 30: "4800", B4800, 31: "9600", B9600, 32: "exta", EXTA, 33: "extb", EXTB, 34: 0, 35: }; 36: struct 37: { 38: char *string; 39: int set; 40: int reset; 41: int lset; 42: int lreset; 43: } modes[] = { 44: "even", EVENP, 0, 0, 0, 45: "-even", 0, EVENP, 0, 0, 46: "odd", ODDP, 0, 0, 0, 47: "-odd", 0, ODDP, 0, 0, 48: "raw", RAW, 0, 0, 0, 49: "-raw", 0, RAW, 0, 0, 50: "cooked", 0, RAW, 0, 0, 51: "-nl", CRMOD, 0, 0, 0, 52: "nl", 0, CRMOD, 0, 0, 53: "echo", ECHO, 0, 0, 0, 54: "-echo", 0, ECHO, 0, 0, 55: "LCASE", LCASE, 0, 0, 0, 56: "lcase", LCASE, 0, 0, 0, 57: "-LCASE", 0, LCASE, 0, 0, 58: "-lcase", 0, LCASE, 0, 0, 59: "-tabs", XTABS, 0, 0, 0, 60: "tabs", 0, XTABS, 0, 0, 61: "tandem", TANDEM, 0, 0, 0, 62: "-tandem", 0, TANDEM, 0, 0, 63: "cbreak", CBREAK, 0, 0, 0, 64: "-cbreak", 0, CBREAK, 0, 0, 65: "cr0", CR0, CR3, 0, 0, 66: "cr1", CR1, CR3, 0, 0, 67: "cr2", CR2, CR3, 0, 0, 68: "cr3", CR3, CR3, 0, 0, 69: "tab0", TAB0, XTABS, 0, 0, 70: "tab1", TAB1, XTABS, 0, 0, 71: "tab2", TAB2, XTABS, 0, 0, 72: "nl0", NL0, NL3, 0, 0, 73: "nl1", NL1, NL3, 0, 0, 74: "nl2", NL2, NL3, 0, 0, 75: "nl3", NL3, NL3, 0, 0, 76: "ff0", FF0, FF1, 0, 0, 77: "ff1", FF1, FF1, 0, 0, 78: "bs0", BS0, BS1, 0, 0, 79: "bs1", BS1, BS1, 0, 0, 80: "33", CR1, ALLDELAY, 0, 0, 81: "tty33", CR1, ALLDELAY, 0, 0, 82: "37", FF1+CR2+TAB1+NL1, ALLDELAY, 0, 0, 83: "tty37", FF1+CR2+TAB1+NL1, ALLDELAY, 0, 0, 84: "05", NL2, ALLDELAY, 0, 0, 85: "vt05", NL2, ALLDELAY, 0, 0, 86: "tn", CR1, ALLDELAY, 0, 0, 87: "tn300", CR1, ALLDELAY, 0, 0, 88: "ti", CR2, ALLDELAY, 0, 0, 89: "ti700", CR2, ALLDELAY, 0, 0, 90: "tek", FF1, ALLDELAY, 0, 0, 91: "crtbs", 0, 0, LCRTBS, LPRTERA, 92: "-crtbs", 0, 0, 0, LCRTBS, 93: "prterase", 0, 0, LPRTERA, LCRTBS+LCRTKIL+LCRTERA, 94: "-prterase", 0, 0, 0, LPRTERA, 95: "crterase", 0, 0, LCRTERA, LPRTERA, 96: "-crterase", 0, 0, 0, LCRTERA, 97: "crtkill", 0, 0, LCRTKIL, LPRTERA, 98: "-crtkill", 0, 0, 0, LCRTKIL, 99: "tilde", 0, 0, LTILDE, 0, 100: "-tilde", 0, 0, 0, LTILDE, 101: "mdmbuf", 0, 0, LMDMBUF, 0, 102: "-mdmbuf", 0, 0, 0, LMDMBUF, 103: "litout", 0, 0, LLITOUT, 0, 104: "-litout", 0, 0, 0, LLITOUT, 105: "tostop", 0, 0, LTOSTOP, 0, 106: "-tostop", 0, 0, 0, LTOSTOP, 107: "flusho", 0, 0, LFLUSHO, 0, 108: "-flusho", 0, 0, 0, LFLUSHO, 109: "nohang", 0, 0, LNOHANG, 0, 110: "-nohang", 0, 0, 0, LNOHANG, 111: "etxack", 0, 0, LETXACK, 0, 112: "-etxack", 0, 0, 0, LETXACK, 113: "intrup", 0, 0, LINTRUP, 0, 114: "-intrup", 0, 0, 0, LINTRUP, 115: "ctlecho", 0, 0, LCTLECH, 0, 116: "-ctlecho", 0, 0, 0, LCTLECH, 117: "pendin", 0, 0, LPENDIN, 0, 118: "-pendin", 0, 0, 0, LPENDIN, 119: "decctlq", 0, 0, LDECCTQ, 0, 120: "-decctlq", 0, 0, 0, LDECCTQ, 121: "noflsh", 0, 0, LNOFLSH, 0, 122: "-noflsh", 0, 0, 0, LNOFLSH, 123: 0, 124: }; 125: 126: struct tchars tc; 127: struct ltchars ltc; 128: struct sgttyb mode; 129: int lmode; 130: int oldisc, ldisc; 131: 132: #define CTRL(x) ('x'&037) 133: 134: struct special { 135: char *name; 136: char *cp; 137: char def; 138: } special[] = { 139: "erase", &mode.sg_erase, CTRL(h), 140: "kill", &mode.sg_kill, '@', 141: "intr", &tc.t_intrc, 0177, 142: "quit", &tc.t_quitc, CTRL(\\\\), 143: "start", &tc.t_startc, CTRL(q), 144: "stop", &tc.t_stopc, CTRL(s), 145: "eof", &tc.t_eofc, CTRL(d), 146: "brk", &tc.t_brkc, 0377, 147: "susp", <c.t_suspc, CTRL(z), 148: "dsusp", <c.t_dsuspc, CTRL(y), 149: "rprnt", <c.t_rprntc, CTRL(r), 150: "flush", <c.t_flushc, CTRL(o), 151: "werase", <c.t_werasc, CTRL(w), 152: "lnext", <c.t_lnextc, CTRL(v), 153: 0 154: }; 155: char *arg; 156: 157: int argc; 158: char **argv; 159: main(iargc, iargv) 160: char **iargv; 161: { 162: int i; 163: register struct special *sp; 164: char obuf[BUFSIZ]; 165: 166: setbuf(stderr, obuf); 167: argc = iargc; 168: argv = iargv; 169: gtty(1, &mode); 170: ioctl(1, TIOCGETD, (struct sgttyb *) &ldisc); 171: oldisc = ldisc; 172: ioctl(1, TIOCGETC, (struct sgttyb *) &tc); 173: ioctl(1, TIOCLGET, (struct sgttyb *) &lmode); 174: ioctl(1, TIOCGLTC, (struct sgttyb *) <c); 175: if(argc == 1) { 176: prmodes(0); 177: exit(0); 178: } 179: if (argc == 2 && !strcmp(argv[1], "all")) { 180: prmodes(1); 181: exit(0); 182: } 183: if (argc == 2 && !strcmp(argv[1], "everything")) { 184: prmodes(2); 185: exit(0); 186: } 187: /* 188: if (argc == 2 && !strcmp(argv[1], "all")) { 189: prmodes(2); 190: exit(0); 191: } 192: */ 193: while(--argc > 0) { 194: arg = *++argv; 195: if (eq("ek")){ 196: mode.sg_erase = '#'; 197: mode.sg_kill = '@'; 198: continue; 199: } 200: if (eq("new")){ 201: ldisc = NTTYDISC; 202: if (ioctl(1, TIOCSETD, (struct sgttyb *) &ldisc)<0) 203: perror("ioctl"); 204: continue; 205: } 206: if (eq("newcrt")){ 207: ldisc = NTTYDISC; 208: lmode &= ~LPRTERA; 209: lmode |= LCRTBS|LCTLECH; 210: if (mode.sg_ospeed >= B1200) 211: lmode |= LCRTERA|LCRTKIL; 212: if (ioctl(1, TIOCSETD, (struct sgttyb *) &ldisc)<0) 213: perror("ioctl"); 214: continue; 215: } 216: if (eq("crt")){ 217: lmode &= ~LPRTERA; 218: lmode |= LCRTBS|LCTLECH; 219: if (mode.sg_ospeed >= B1200) 220: lmode |= LCRTERA|LCRTKIL; 221: continue; 222: } 223: if (eq("old")){ 224: ldisc = OTTYDISC; 225: if (ioctl(1, TIOCSETD, (struct sgttyb *) &ldisc)<0) 226: perror("ioctl"); 227: continue; 228: } 229: if (eq("dec")){ 230: mode.sg_erase = 0177; 231: mode.sg_kill = CTRL(u); 232: tc.t_intrc = CTRL(c); 233: ldisc = NTTYDISC; 234: lmode &= ~LPRTERA; 235: lmode |= LCRTBS|LCTLECH|LDECCTQ; 236: if (mode.sg_ospeed >= B1200) 237: lmode |= LCRTERA|LCRTKIL; 238: if (ioctl(1, TIOCSETD, (struct sgttyb *) &ldisc)<0) 239: perror("ioctl"); 240: continue; 241: } 242: for (sp = special; sp->name; sp++) 243: if (eq(sp->name)) { 244: if (--argc == 0) 245: goto done; 246: if (**++argv == 'u') 247: *sp->cp = 0377; 248: else if (**argv == '^') 249: *sp->cp = ((*argv)[1] == '?') ? 250: 0177 : (*argv)[1] & 037; 251: else 252: *sp->cp = **argv; 253: goto cont; 254: } 255: if (eq("gspeed")) { 256: mode.sg_ispeed = B300; 257: mode.sg_ospeed = B9600; 258: continue; 259: } 260: if (eq("hup")) { 261: ioctl(1, TIOCHPCL, (struct sgttyb *) NULL); 262: continue; 263: } 264: for(i=0; speeds[i].string; i++) 265: if(eq(speeds[i].string)) { 266: mode.sg_ispeed = mode.sg_ospeed = speeds[i].speed; 267: goto cont; 268: } 269: if (eq("speed")) { 270: gtty(open("/dev/tty", 0), &mode); 271: for(i=0; speeds[i].string; i++) 272: if (mode.sg_ospeed == speeds[i].speed) { 273: printf("%s\n", speeds[i].string); 274: exit(0); 275: } 276: printf("unknown\n"); 277: exit(1); 278: } 279: for(i=0; modes[i].string; i++) 280: if(eq(modes[i].string)) { 281: mode.sg_flags &= ~modes[i].reset; 282: mode.sg_flags |= modes[i].set; 283: lmode &= ~modes[i].lreset; 284: lmode |= modes[i].lset; 285: } 286: if(arg) 287: fprintf(stderr,"unknown mode: %s\n", arg); 288: cont: 289: ; 290: } 291: done: 292: ioctl(1, TIOCSETN, (struct sgttyb *) &mode); 293: ioctl(1, TIOCSETC, (struct sgttyb *) &tc); 294: ioctl(1, TIOCSLTC, (struct sgttyb *) <c); 295: ioctl(1, TIOCLSET, (struct sgttyb *) &lmode); 296: } 297: 298: eq(string) 299: char *string; 300: { 301: int i; 302: 303: if(!arg) 304: return(0); 305: i = 0; 306: loop: 307: if(arg[i] != string[i]) 308: return(0); 309: if(arg[i++] != '\0') 310: goto loop; 311: arg = 0; 312: return(1); 313: } 314: 315: prmodes(all) 316: { 317: register m; 318: int any; 319: 320: if(ldisc==NETLDISC) 321: fprintf(stderr, "net discipline, "); 322: else if(ldisc==NTTYDISC) 323: fprintf(stderr, "new tty, "); 324: else if(all==2) 325: fprintf(stderr, "old tty, "); 326: if(mode.sg_ispeed != mode.sg_ospeed) { 327: prspeed("input speed ", mode.sg_ispeed); 328: prspeed("output speed ", mode.sg_ospeed); 329: } else 330: prspeed("speed ", mode.sg_ispeed); 331: fprintf(stderr, all==2 ? "\n" : "; "); 332: m = mode.sg_flags; 333: if(all==2 || (m&(EVENP|ODDP))!=(EVENP|ODDP)) { 334: if(m & EVENP) fprintf(stderr,"even "); 335: if(m & ODDP) fprintf(stderr,"odd "); 336: } 337: if(all==2 || m&RAW) 338: fprintf(stderr,"-raw "+((m&RAW)!=0)); 339: if(all==2 || (m&CRMOD)==0) 340: fprintf(stderr,"-nl "+((m&CRMOD)==0)); 341: if(all==2 || (m&ECHO)==0) 342: fprintf(stderr,"-echo "+((m&ECHO)!=0)); 343: if(all==2 || (m&LCASE)) 344: fprintf(stderr,"-lcase "+((m&LCASE)!=0)); 345: if(all==2 || (m&TANDEM)) 346: fprintf(stderr,"-tandem "+((m&TANDEM)!=0)); 347: fprintf(stderr,"-tabs "+((m&XTABS)!=XTABS)); 348: if(all==2 || (m&CBREAK)) 349: fprintf(stderr,"-cbreak "+((m&CBREAK)!=0)); 350: if(all==2 || (m&NLDELAY)) 351: delay((m&NLDELAY)/NL1, "nl"); 352: if ((m&TBDELAY)!=XTABS) 353: delay((m&TBDELAY)/TAB1, "tab"); 354: if(all==2 || (m&CRDELAY)) 355: delay((m&CRDELAY)/CR1, "cr"); 356: if(all==2 || (m&VTDELAY)) 357: delay((m&VTDELAY)/FF1, "ff"); 358: if(all==2 || (m&BSDELAY)) 359: delay((m&BSDELAY)/BS1, "bs"); 360: if (all) 361: fprintf(stderr,"\n"); 362: #define lpit(what,str) \ 363: if (all==2||(lmode&what)) { \ 364: fprintf(stderr,str+((lmode&what)!=0)); any++; \ 365: } 366: if (ldisc == NTTYDISC) { 367: int newcrt = (lmode&(LCTLECH|LCRTBS)) == (LCTLECH|LCRTBS) && 368: (lmode&(LCRTERA|LCRTKIL)) == 369: ((mode.sg_ospeed > B300) ? LCRTERA|LCRTKIL : 0); 370: if (newcrt) { 371: if (all==2) 372: fprintf(stderr, "crt: (crtbs crterase crtkill ctlecho) "); 373: else 374: fprintf(stderr, "crt "); 375: any++; 376: } else { 377: lpit(LCRTBS, "-crtbs "); 378: lpit(LCRTERA, "-crterase "); 379: lpit(LCRTKIL, "-crtkill "); 380: lpit(LCTLECH, "-ctlecho "); 381: lpit(LPRTERA, "-prterase "); 382: } 383: lpit(LTOSTOP, "-tostop "); 384: lpit(LINTRUP, "-intrup "); 385: if (all==2) { 386: fprintf(stderr, "\n"); 387: any = 0; 388: } 389: lpit(LTILDE, "-tilde "); 390: lpit(LFLUSHO, "-flusho "); 391: lpit(LMDMBUF, "-mdmbuf "); 392: lpit(LLITOUT, "-litout "); 393: lpit(LNOHANG, "-nohang "); 394: if (any) { 395: fprintf(stderr,"\n"); 396: any = 0; 397: } 398: lpit(LETXACK, "-etxack "); 399: lpit(LPENDIN, "-pendin "); 400: lpit(LDECCTQ, "-decctlq "); 401: lpit(LNOFLSH, "-noflsh "); 402: if (any) 403: fprintf(stderr,"\n"); 404: } else if (!all) 405: fprintf(stderr,"\n"); 406: if (all) { 407: switch (ldisc) { 408: 409: case OTTYDISC: 410: fprintf(stderr,"\ 411: erase kill intr quit stop eof\ 412: \n"); 413: pcol(mode.sg_erase, -1); 414: pcol(mode.sg_kill, -1); 415: pcol(tc.t_intrc, -1); 416: pcol(tc.t_quitc, -1); 417: pcol(tc.t_stopc, tc.t_startc); 418: pcol(tc.t_eofc, tc.t_brkc); 419: fprintf(stderr,"\n"); 420: break; 421: 422: case NTTYDISC: 423: fprintf(stderr,"\ 424: erase kill werase rprnt flush lnext susp intr quit stop eof\ 425: \n"); 426: pcol(mode.sg_erase, -1); 427: pcol(mode.sg_kill, -1); 428: pcol(ltc.t_werasc, -1); 429: pcol(ltc.t_rprntc, -1); 430: pcol(ltc.t_flushc, -1); 431: pcol(ltc.t_lnextc, -1); 432: pcol(ltc.t_suspc, ltc.t_dsuspc); 433: pcol(tc.t_intrc, -1); 434: pcol(tc.t_quitc, -1); 435: pcol(tc.t_stopc, tc.t_startc); 436: pcol(tc.t_eofc, tc.t_brkc); 437: fprintf(stderr,"\n"); 438: break; 439: } 440: } else if (ldisc != NETLDISC) { 441: register struct special *sp; 442: int first = 1; 443: for (sp = special; sp->name; sp++) { 444: if ((*sp->cp&0377) != (sp->def&0377)) { 445: pit((unsigned) (*sp->cp), sp->name, first ? "" : ", "); 446: first = 0; 447: }; 448: if (sp->cp == &tc.t_brkc && ldisc == OTTYDISC) 449: break; 450: } 451: if (first == 0) 452: fprintf(stderr, "\n"); 453: } 454: } 455: 456: pcol(ch1, ch2) 457: int ch1, ch2; 458: { 459: int nout = 0; 460: 461: ch1 &= 0377; 462: ch2 &= 0377; 463: if (ch1 == ch2) 464: ch2 = 0377; 465: for (; ch1 != 0377 || ch2 != 0377; ch1 = ch2, ch2 = 0377) { 466: if (ch1 == 0377) 467: continue; 468: if (ch1 & 0200) { 469: fprintf(stderr, "M-"); 470: nout += 2; 471: ch1 &= ~ 0200; 472: } 473: if (ch1 == 0177) { 474: fprintf(stderr, "^"); 475: nout++; 476: ch1 = '?'; 477: } else if (ch1 < ' ') { 478: fprintf(stderr, "^"); 479: nout++; 480: ch1 += '@'; 481: } 482: fprintf(stderr, "%c", ch1); 483: nout++; 484: if (ch2 != 0377) { 485: fprintf(stderr, "/"); 486: nout++; 487: } 488: } 489: while (nout < 7) { 490: fprintf(stderr, " "); 491: nout++; 492: } 493: } 494: 495: pit(what, itsname, sep) 496: unsigned what; 497: char *itsname, *sep; 498: { 499: 500: what &= 0377; 501: fprintf(stderr, "%s%s", sep, itsname); 502: if (what == 0377) { 503: fprintf(stderr, " <undef>"); 504: return; 505: } 506: fprintf(stderr, " = "); 507: if (what & 0200) { 508: fprintf(stderr, "M-"); 509: what &= ~ 0200; 510: } 511: if (what == 0177) { 512: fprintf(stderr, "^"); 513: what = '?'; 514: } else if (what < ' ') { 515: fprintf(stderr, "^"); 516: what += '@'; 517: } 518: fprintf(stderr, "%c", what); 519: } 520: 521: delay(m, s) 522: char *s; 523: { 524: 525: if(m) 526: fprintf(stderr,"%s%d ", s, m); 527: } 528: 529: int speed[] = { 530: 0,50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,0,0 531: }; 532: 533: prspeed(c, s) 534: char *c; 535: { 536: 537: fprintf(stderr,"%s%d baud", c, speed[s]); 538: }