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