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