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