1 /* 2 * Copyright (c) 1980, 1989 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 */ 6 7 #ifndef lint 8 char copyright[] = 9 "@(#) Copyright (c) 1980, 1989 Regents of the University of California.\n\ 10 All rights reserved.\n"; 11 #endif not lint 12 13 #ifndef lint 14 static char sccsid[] = "@(#)stty.c 5.14 (Berkeley) 06/20/90"; 15 #endif not lint 16 17 /* 18 * set teletype modes 19 */ 20 21 #include <sys/types.h> 22 #include <sys/stat.h> 23 #include <sys/ioctl.h> 24 #include <sys/syslog.h> 25 #define KERNEL 26 #include <sys/tty.h> 27 #undef KERNEL 28 #include <sys/termios.h> 29 #include <sys/file.h> 30 #include <errno.h> 31 #include <ctype.h> 32 #include <stdio.h> 33 34 #define eq(s1, s2) (strcmp((s1), (s2)) == 0) 35 #define WRAPCOL 65 36 37 struct modes { 38 char *name; 39 long set; 40 long unset; 41 }; 42 43 struct modes imodes[] = { 44 "ignbrk", IGNBRK, 0, 45 "-ignbrk", 0, IGNBRK, 46 "brkint", BRKINT, 0, 47 "-brkint", 0, BRKINT, 48 "ignpar", IGNPAR, 0, 49 "-ignpar", 0, IGNPAR, 50 "parmrk", PARMRK, 0, 51 "-parmrk", 0, PARMRK, 52 "inpck", INPCK, 0, 53 "-inpck", 0, INPCK, 54 "istrip", ISTRIP, 0, 55 "-istrip", 0, ISTRIP, 56 "inlcr", INLCR, 0, 57 "-inlcr", 0, INLCR, 58 "igncr", IGNCR, 0, 59 "-igncr", 0, IGNCR, 60 "icrnl", ICRNL, 0, 61 "-icrnl", 0, ICRNL, 62 "ixon", IXON, 0, 63 "-ixon", 0, IXON, 64 "flow", IXON, 0, 65 "-flow", 0, IXON, 66 "ixoff", IXOFF, 0, 67 "-ixoff", 0, IXOFF, 68 "tandem", IXOFF, 0, 69 "-tandem", 0, IXOFF, 70 "ixany", IXANY, 0, 71 "-ixany", 0, IXANY, 72 "decctlq", 0, IXANY, 73 "-decctlq", IXANY, 0, 74 "imaxbel", IMAXBEL, 0, 75 "-imaxbel", 0, IMAXBEL, 76 0 77 }; 78 79 struct modes omodes[] = { 80 "opost", OPOST, 0, 81 "-opost", 0, OPOST, 82 "-litout", OPOST, 0, 83 "litout", 0, OPOST, 84 "onlcr", ONLCR, 0, 85 "-onlcr", 0, ONLCR, 86 "tabs", 0, OXTABS, /* "preserve" tabs */ 87 "-tabs", OXTABS, 0, 88 "xtabs", OXTABS, 0, 89 "-xtabs", 0, OXTABS, 90 "oxtabs", OXTABS, 0, 91 "-oxtabs", 0, OXTABS, 92 0 93 }; 94 95 struct modes cmodes[] = { 96 "cs5", CS5, CSIZE, 97 "cs6", CS6, CSIZE, 98 "cs7", CS7, CSIZE, 99 "cs8", CS8, CSIZE, 100 "cstopb", CSTOPB, 0, 101 "-cstopb", 0, CSTOPB, 102 "cread", CREAD, 0, 103 "-cread", 0, CREAD, 104 "parenb", PARENB, 0, 105 "-parenb", 0, PARENB, 106 "parodd", PARODD, 0, 107 "-parodd", 0, PARODD, 108 "parity", PARENB | CS7, PARODD | CSIZE, 109 "evenp", PARENB | CS7, PARODD | CSIZE, 110 "oddp", PARENB | CS7 | PARODD, CSIZE, 111 "-parity", CS8, PARODD | PARENB | CSIZE, 112 "pass8", CS8, PARODD | PARENB | CSIZE, 113 "-evenp", CS8, PARODD | PARENB | CSIZE, 114 "-oddp", CS8, PARODD | PARENB | CSIZE, 115 "hupcl", HUPCL, 0, 116 "-hupcl", 0, HUPCL, 117 "hup", HUPCL, 0, 118 "-hup", 0, HUPCL, 119 "clocal", CLOCAL, 0, 120 "-clocal", 0, CLOCAL, 121 "crtscts", CRTSCTS, 0, 122 "-crtscts", 0, CRTSCTS, 123 0 124 }; 125 126 struct modes lmodes[] = { 127 "echo", ECHO, 0, 128 "-echo", 0, ECHO, 129 "echoe", ECHOE, 0, 130 "-echoe", 0, ECHOE, 131 "crterase", ECHOE, 0, 132 "-crterase", 0, ECHOE, 133 "crtbs", ECHOE, 0, /* crtbs not supported, close enough */ 134 "-crtbs", 0, ECHOE, 135 "echok", ECHOK, 0, 136 "-echok", 0, ECHOK, 137 "echoke", ECHOKE, 0, 138 "-echoke", 0, ECHOKE, 139 "crtkill", ECHOKE, 0, 140 "-crtkill", 0, ECHOKE, 141 "altwerase", ALTWERASE, 0, 142 "-altwerase", 0, ALTWERASE, 143 "iexten", IEXTEN, 0, 144 "-iexten", 0, IEXTEN, 145 "echonl", ECHONL, 0, 146 "-echonl", 0, ECHONL, 147 "echoctl", ECHOCTL, 0, 148 "-echoctl", 0, ECHOCTL, 149 "ctlecho", ECHOCTL, 0, 150 "-ctlecho", 0, ECHOCTL, 151 "echoprt", ECHOPRT, 0, 152 "-echoprt", 0, ECHOPRT, 153 "prterase", ECHOPRT, 0, 154 "-prterase", 0, ECHOPRT, 155 "isig", ISIG, 0, 156 "-isig", 0, ISIG, 157 "icanon", ICANON, 0, 158 "-icanon", 0, ICANON, 159 "noflsh", NOFLSH, 0, 160 "-noflsh", 0, NOFLSH, 161 "tostop", TOSTOP, 0, 162 "-tostop", 0, TOSTOP, 163 "mdmbuf", MDMBUF, 0, 164 "-mdmbuf", 0, MDMBUF, 165 "flusho", FLUSHO, 0, 166 "-flusho", 0, FLUSHO, 167 "pendin", PENDIN, 0, 168 "-pendin", 0, PENDIN, 169 "crt", ECHOE|ECHOKE|ECHOCTL, ECHOK|ECHOPRT, 170 "-crt", ECHOK, ECHOE|ECHOKE|ECHOCTL, 171 "newcrt", ECHOE|ECHOKE|ECHOCTL, ECHOK|ECHOPRT, 172 "-newcrt", ECHOK, ECHOE|ECHOKE|ECHOCTL, 173 0 174 }; 175 176 /* 177 * Special control characters. 178 * 179 * Each entry has a list of names. The first is the primary name 180 * and is used when printing the control character in the "name = val;" 181 * form. The second is an abbreviation which is guaranteed to be less 182 * than or equal to four characters in length and is primarily used 183 * when printing the values in columunar form (guarantees all will 184 * fit within 80 cols). The rest are optional aliases. 185 * All names are recognized on the command line. 186 */ 187 #define MAXNAMES 3 188 struct { 189 char *names[MAXNAMES+1]; 190 int sub; 191 u_char def; 192 } cchars[] = { 193 {{ "erase", "era" }, VERASE, CERASE, }, 194 {{ "werase", "wera" }, VWERASE, CWERASE, }, 195 {{ "kill", "kill" }, VKILL, CKILL, }, 196 {{ "intr", "int" }, VINTR, CINTR, }, 197 {{ "quit", "quit" }, VQUIT, CQUIT, }, 198 {{ "susp", "susp" }, VSUSP, CSUSP, }, 199 {{ "dsusp", "dsus" }, VDSUSP, CDSUSP, }, 200 {{ "eof", "eof" }, VEOF, CEOF, }, 201 {{ "eol", "eol", "brk" }, VEOL, CEOL, }, 202 {{ "eol2", "eol2" }, VEOL2, CEOL, }, 203 {{ "stop", "stop", "xoff" }, VSTOP, CSTOP, }, 204 {{ "start", "star", "xon" }, VSTART, CSTART, }, 205 {{ "lnext", "lnxt" }, VLNEXT, CLNEXT, }, 206 {{ "discard", "disc", }, VDISCARD, CDISCARD, }, 207 {{ "reprint", "rpnt", "rprnt" }, VREPRINT, CREPRINT, }, 208 {{ "info", "info" }, VINFO, CINFO, }, 209 0 210 }; 211 212 struct winsize win; 213 int ldisc; 214 int dodisc; 215 int debug = 0; 216 int trace, dotrace; 217 218 #define OUT stdout /* informational output stream */ 219 #define ERR stderr /* error message stream */ 220 #define CTL 0 /* default control descriptor */ 221 int ctl = CTL; 222 223 extern errno; 224 225 #define NORMAL 0 /* only print modes differing from defaults */ 226 #define ALL 1 /* print all modes - POSIX standard format */ 227 #define ALL_BSD 2 /* print all modes - using BSD shorthand for cc's */ 228 #define GFMT 3 /* print modes in form suitable to be re-input */ 229 230 main(argc, argv) 231 char *argv[]; 232 { 233 struct termios t; 234 int i, fmt = NORMAL; 235 extern char *optarg; 236 extern int optind; 237 int ch; 238 239 argc--, argv++; 240 if (argc > 0 && eq(argv[0], "-a")) { 241 fmt = ALL; 242 argc--, argv++; 243 } 244 if (argc > 0 && eq(argv[0], "-g")) { 245 fmt = GFMT; 246 argc--, argv++; 247 } 248 if (argc > 0 && eq(argv[0], "-f")) { 249 argc--, argv++; 250 if ((ctl = open(argv[0], O_RDONLY | O_NONBLOCK)) < 0) 251 syserrexit(*argv); 252 argc--, argv++; 253 } 254 if (ioctl(ctl, TIOCGETD, &ldisc) < 0) 255 syserrexit("TIOCGETD"); 256 if (tcgetattr(ctl, &t) < 0) 257 syserrexit("tcgetattr"); 258 if (ioctl(ctl, TIOCGWINSZ, &win) < 0) 259 warning("TIOCGWINSZ: %s", strerror(errno)); 260 checkredirect(); /* conversion aid */ 261 262 if (argc == 0 || fmt) { 263 prmode(&t, ldisc, fmt); 264 exit(0); 265 } 266 267 while (*argv) { 268 if (eq("everything", *argv)) { 269 prmode(&t, ldisc, ALL_BSD); 270 exit(0); 271 } 272 if (eq("all", *argv)) { 273 prmode(&t, ldisc, ALL); 274 exit(0); 275 } 276 if (eq("old", *argv)) { 277 goto next; 278 } 279 if (eq("new", *argv)) { 280 goto next; 281 } 282 if (eq("nl", *argv)) { 283 t.c_iflag &= ~ICRNL; 284 t.c_oflag &= ~ONLCR; 285 goto next; 286 } 287 if (eq("-nl", *argv)) { 288 t.c_iflag |= ICRNL; 289 t.c_oflag |= ONLCR; 290 goto next; 291 } 292 if (eq("dec", *argv)){ 293 t.c_cc[VERASE] = (u_char)0177; 294 t.c_cc[VKILL] = CTRL('u'); 295 t.c_cc[VINTR] = CTRL('c'); 296 t.c_lflag &= ~ECHOPRT; 297 t.c_lflag |= ECHOE|ECHOKE|ECHOCTL; 298 t.c_iflag &= ~IXANY; 299 goto next; 300 } 301 if (eq("raw", *argv)) { 302 cfmakeraw(&t); 303 t.c_cflag &= ~(CSIZE|PARENB); 304 t.c_cflag |= CS8; 305 goto next; 306 } 307 if (eq("cooked", *argv) || eq("-raw", *argv) || 308 eq("sane", *argv)) { 309 t.c_cflag = TTYDEF_CFLAG | (t.c_cflag & CLOCAL); 310 t.c_iflag = TTYDEF_IFLAG; 311 t.c_iflag |= ICRNL; 312 /* preserve user-preference flags in lflag */ 313 #define LKEEP (ECHOKE|ECHOE|ECHOK|ECHOPRT|ECHOCTL|ALTWERASE|TOSTOP|NOFLSH) 314 t.c_lflag = TTYDEF_LFLAG | (t.c_lflag & LKEEP); 315 t.c_oflag = TTYDEF_OFLAG; 316 goto next; 317 } 318 if (eq("rows", *argv)) { 319 if (*(argv+1) == 0) 320 goto setit; 321 win.ws_row = atoi(*++argv); 322 goto next; 323 } 324 if (eq("ispeed", *argv)) { 325 int code; 326 if (*(argv+1) == 0) 327 errexit("missing ispeed"); 328 cfsetispeed(&t, atoi(*++argv)); 329 goto next; 330 } 331 if (eq("ospeed", *argv)) { 332 if (*(argv+1) == 0) 333 errexit("missing ospeed"); 334 cfsetospeed(&t, atoi(*++argv)); 335 goto next; 336 } 337 if (eq("cols", *argv) || eq("columns", *argv)) { 338 if (*(argv+1) == 0) 339 goto setit; 340 win.ws_col = atoi(*++argv); 341 goto next; 342 } 343 if (eq("size", *argv)) { 344 put("%d %d\n", win.ws_row, win.ws_col); 345 exit(0); 346 } 347 if (eq("speed", *argv)) { 348 put("%d\n", cfgetospeed(&t)); 349 exit(0); 350 } 351 for (i=0; imodes[i].name; i++) 352 if (eq(imodes[i].name, *argv)) { 353 t.c_iflag &= ~imodes[i].unset; 354 t.c_iflag |= imodes[i].set; 355 goto next; 356 } 357 for (i=0; omodes[i].name; i++) 358 if (eq(omodes[i].name, *argv)) { 359 t.c_oflag &= ~omodes[i].unset; 360 t.c_oflag |= omodes[i].set; 361 goto next; 362 } 363 for (i=0; cmodes[i].name; i++) 364 if (eq(cmodes[i].name, *argv)) { 365 t.c_cflag &= ~cmodes[i].unset; 366 t.c_cflag |= cmodes[i].set; 367 goto next; 368 } 369 for (i=0; lmodes[i].name; i++) 370 if (eq(lmodes[i].name, *argv)) { 371 t.c_lflag &= ~lmodes[i].unset; 372 t.c_lflag |= lmodes[i].set; 373 goto next; 374 } 375 for (i=0; *cchars[i].names; i++) { 376 char **cp = cchars[i].names; 377 while (*cp) { 378 if (eq(*cp, *argv)) { 379 if (*++argv == 0) 380 goto setit; 381 if (eq(*argv, "undef") || 382 eq(*argv, "disable")) 383 t.c_cc[cchars[i].sub] = 384 _POSIX_VDISABLE; 385 else if (**argv == '^') 386 t.c_cc[cchars[i].sub] = 387 ((*argv)[1] == '?') ? 0177 : 388 ((*argv)[1] == '-') ? 389 _POSIX_VDISABLE : 390 (*argv)[1] & 037; 391 else 392 t.c_cc[cchars[i].sub] = **argv; 393 goto next; 394 } 395 cp++; 396 } 397 } 398 if (isdigit(**argv)) { 399 cfsetospeed(&t, atoi(*argv)); 400 cfsetispeed(&t, atoi(*argv)); 401 goto next; 402 } 403 if (strncmp(*argv, "-gfmt", sizeof ("-gfmt") - 1) == 0) { 404 gfmtset(&t, *argv); 405 goto next; 406 } 407 /* didn't match anything */ 408 errexit("unknown option: %s", *argv); 409 exit(1); 410 next: 411 argv++; 412 } 413 setit: 414 if (tcsetattr(ctl, 0, &t) < 0) 415 syserrexit("tcsetattr"); 416 if (ioctl(ctl, TIOCSWINSZ, &win) < 0) 417 warning("can't set window size"); 418 419 exit(0); 420 } 421 422 gfmtset(tp, s) 423 register struct termios *tp; 424 char *s; 425 { 426 register int cnt; 427 char sep; 428 char *saves = s; 429 int cval; 430 #define advance(c) while (*(s) && *(s) != (c)) (s)++; if (*s) (s)++ ; \ 431 else \ 432 errexit("bad gfmt operand: %s", saves) 433 #define chkeq(string) if (strncmp(s, (string), strlen(string))) \ 434 errexit("bad gfmt operand: %s", saves) 435 436 if (s == NULL) 437 errexit("missing gfmt string"); 438 advance(':'); 439 chkeq("iflag="); 440 advance('='); 441 sscanf(s, "%x", &tp->c_iflag); 442 443 advance(':'); 444 chkeq("oflag"); 445 advance('='); 446 sscanf(s, "%x", &tp->c_oflag); 447 448 advance(':'); 449 chkeq("cflag"); 450 advance('='); 451 sscanf(s, "%x", &tp->c_cflag); 452 453 advance(':'); 454 chkeq("lflag"); 455 advance('='); 456 sscanf(s, "%x", &tp->c_lflag); 457 458 advance(':'); 459 chkeq("cc="); 460 461 for (cnt = 0, sep = '='; cnt < NCCS; cnt++, sep = ',') { 462 advance(sep); 463 sscanf(s, "%o", &cval); 464 tp->c_cc[cnt] = cval; 465 } 466 467 advance(':'); 468 chkeq("ispeed="); 469 advance('='); 470 sscanf(s, "%d", &tp->c_ispeed); 471 472 advance(':'); 473 chkeq("ospeed="); 474 advance('='); 475 sscanf(s, "%d", &tp->c_ospeed); 476 } 477 478 prmode(tp, ldisc, fmt) 479 struct termios *tp; 480 { 481 long i = tp->c_iflag, 482 o = tp->c_oflag, 483 c = tp->c_cflag, 484 l = tp->c_lflag; 485 u_char *cc = tp->c_cc; 486 int ispeed = cfgetispeed(tp), 487 ospeed = cfgetospeed(tp); 488 char unknown[32], 489 *ld; 490 char *ccval(); 491 492 if (fmt == GFMT) { 493 int cnt; 494 char sep; 495 496 printf("-gfmt:iflag=%x:oflag=%x:cflag=%x:lflag=%x:cc", 497 i, o, c, l); 498 for (cnt = 0, sep = '='; cnt < NCCS; cnt++, sep = ',') 499 printf("%c%o", sep, cc[cnt]); 500 printf(":ispeed=%d:ospeed=%d:\n", ispeed, ospeed); 501 return; 502 } 503 504 /* 505 * line discipline 506 */ 507 if (ldisc != TTYDISC) { 508 switch(ldisc) { 509 case TABLDISC: 510 ld = "tablet"; 511 break; 512 case SLIPDISC: 513 ld = "slip"; 514 break; 515 default: 516 sprintf(unknown, "#%d", ldisc); 517 ld = unknown; 518 } 519 put("%s disc; ", ld); 520 } 521 /* 522 * line speed 523 */ 524 if (ispeed != ospeed) 525 put("ispeed %d baud; ospeed %d baud;", 526 ispeed, ospeed); 527 else 528 put("speed %d baud;", ispeed); 529 if (fmt) 530 put(" %d rows; %d columns;", win.ws_row, win.ws_col); 531 put("\n"); 532 533 #define lput(n, f, d) if (fmt || on(f) != d) mdput(n+on(f)) 534 /* 535 * "local" flags 536 */ 537 #define on(f) ((l&f) != 0) 538 if (debug) mdput("LFLAG: "); 539 lput("-icanon ",ICANON, 1); 540 lput("-isig ", ISIG, 1); 541 lput("-iexten ", IEXTEN, 1); 542 lput("-echo ",ECHO, 1); 543 lput("-echoe ",ECHOE, 0); 544 lput("-echok ",ECHOK, 0); 545 lput("-echoke ",ECHOKE, 0); 546 lput("-echonl ",ECHONL, 0); 547 lput("-echoctl ",ECHOCTL, 0); 548 lput("-echoprt ",ECHOPRT, 0); 549 lput("-altwerase ",ALTWERASE, 0); 550 lput("-noflsh ",NOFLSH, 0); 551 lput("-tostop ",TOSTOP, 0); 552 lput("-mdmbuf ",MDMBUF, 0); 553 lput("-flusho ",FLUSHO, 0); 554 lput("-pendin ",PENDIN, 0); 555 /* 556 * input flags 557 */ 558 #undef on 559 #define on(f) ((i&f) != 0) 560 mdput(0); 561 if (debug) mdput("IFLAG: "); 562 lput("-istrip ", ISTRIP, 0); 563 lput("-icrnl ", ICRNL, 1); 564 lput("-inlcr ", INLCR, 0); 565 lput("-igncr ", IGNCR, 0); 566 lput("-ixon ", IXON, 1); 567 lput("-ixoff ", IXOFF, 0); 568 lput("-ixany ", IXANY, 1); 569 lput("-imaxbel ", IMAXBEL, 1); 570 lput("-ignbrk ", IGNBRK, 0); 571 lput("-brkint ", BRKINT, 1); 572 lput("-inpck ", INPCK, 0); 573 lput("-ignpar ", IGNPAR, 0); 574 lput("-parmrk ", PARMRK, 0); 575 #undef on 576 /* 577 * output flags 578 */ 579 #define on(f) ((o&f) != 0) 580 mdput(0); 581 if (debug) mdput("OFLAG: "); 582 lput("-opost ", OPOST, 1); 583 lput("-onlcr ", ONLCR, 1); 584 lput("-oxtabs ", OXTABS, 1); 585 #undef on 586 /* 587 * control flags (hardware state) 588 */ 589 #define on(f) ((c&f) != 0) 590 mdput(0); 591 if (debug) mdput("CFLAG: "); 592 lput("-cread ", CREAD, 1); 593 switch(c&CSIZE) { 594 case CS5: mdput("cs5 "); break; 595 case CS6: mdput("cs6 "); break; 596 case CS7: mdput("cs7 "); break; 597 case CS8: mdput("cs8 "); break; 598 } 599 mdput("-parenb "+on(PARENB)); 600 lput("-parodd ", PARODD, 0); 601 lput("-hupcl ", HUPCL, 1); 602 lput("-clocal ", CLOCAL, 0); 603 lput("-cstopb ", CSTOPB, 0); 604 lput("-crtscts ", CRTSCTS, 0); 605 mdput(0); 606 #undef on 607 /* 608 * special control characters 609 */ 610 if (debug) mdput("CCHARS: "); 611 if (fmt != 2) { 612 for (i=0; *cchars[i].names; i++) { 613 char temp[64]; 614 615 if (fmt || cc[cchars[i].sub] != cchars[i].def) { 616 sprintf(temp, "%s = %s; ", *cchars[i].names, 617 ccval(cc[cchars[i].sub]), fmt); 618 mdput(temp); 619 } 620 } 621 mdput(0); 622 } else { 623 for (i=0; *cchars[i].names; i++) 624 put("%*s", strlen(*(cchars[i].names+1)) + (i>0?1:0), 625 *(cchars[i].names+1)); 626 printf("\n"); 627 for (i=0; *cchars[i].names; i++) 628 put("%*s", strlen(*(cchars[i].names+1)) + (i>0?1:0), 629 ccval(cc[cchars[i].sub], fmt)); 630 printf("\n"); 631 } 632 } 633 634 /* 635 * gross, but since we're changing the control descriptor 636 * from 1 to 0, most users will be probably be doing 637 * "stty > /dev/sometty" by accident. If 1 and 2 are both ttys, 638 * but not the same, assume that 1 was incorrectly redirected. 639 */ 640 checkredirect() { 641 struct stat st1, st2; 642 643 if (isatty(1) && isatty(2) && fstat(1, &st1) != -1 && 644 fstat(2, &st2) != -1 && (st1.st_rdev != st2.st_rdev)) 645 warning("stdout appears redirected, but stdin is the control descriptor"); 646 } 647 648 char * 649 ccval(c, fmt) 650 unsigned char c; 651 { 652 static char buf[128]; 653 char *bp; 654 655 *buf = 0, bp = buf; 656 if (c == _POSIX_VDISABLE) 657 if (fmt == 2) 658 return("<u>"); 659 else 660 return("<undef>"); 661 if (c & 0200) { 662 strcat(buf, "M-"); 663 *bp++ = 'M'; 664 *bp++ = '-'; 665 c &= 0177; 666 } 667 if (c == 0177) { 668 *bp++ = '^'; 669 *bp++ = '?'; 670 } 671 else if (c < 040) { 672 *bp++ = '^'; 673 *bp++ = c + '@'; 674 } 675 else 676 *bp++ = c; 677 *bp = 0; 678 return(buf); 679 } 680 681 682 mdput(s) 683 char *s; 684 { 685 static int col = 0; 686 687 if (s == (char *)0) { 688 if (col) { 689 put("\n"); 690 col = 0; 691 } 692 return; 693 } 694 if ((col += strlen(s)) > WRAPCOL) { 695 put("\n"); 696 col = strlen(s); 697 } 698 put(s); 699 } 700 701 #include <varargs.h> 702 703 put(va_alist) 704 va_dcl 705 { 706 char *fmt; 707 va_list ap; 708 709 va_start(ap); 710 fmt = va_arg(ap, char *); 711 (void) vfprintf(OUT, fmt, ap); 712 va_end(ap); 713 } 714 715 716 warning(va_alist) 717 va_dcl 718 { 719 char *fmt; 720 va_list ap; 721 722 fprintf(ERR, "stty: warning: "); 723 va_start(ap); 724 fmt = va_arg(ap, char *); 725 (void) vfprintf(ERR, fmt, ap); 726 va_end(ap); 727 fprintf(ERR, "\n"); 728 } 729 730 731 errexit(va_alist) 732 va_dcl 733 { 734 char *fmt; 735 va_list ap; 736 737 fprintf(ERR, "stty: "); 738 va_start(ap); 739 fmt = va_arg(ap, char *); 740 (void) vfprintf(ERR, fmt, ap); 741 va_end(ap); 742 fprintf(ERR, "\n"); 743 exit(1); 744 } 745 746 747 syserrexit(va_alist) 748 va_dcl 749 { 750 char *fmt; 751 va_list ap; 752 753 fprintf(ERR, "stty: "); 754 va_start(ap); 755 fmt = va_arg(ap, char *); 756 (void) vfprintf(ERR, fmt, ap); 757 va_end(ap); 758 fprintf(ERR, ": %s\n", strerror(errno)); 759 exit(1); 760 } 761