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