|
|
1.1 ! root 1: # ! 2: /* ! 3: ** TSET -- set terminal modes ! 4: ** ! 5: ** This program does sophisticated terminal initialization. ! 6: ** I recommend that you include it in your .start_up or .login ! 7: ** file to initialize whatever terminal you are on. ! 8: ** ! 9: ** There are several features: ! 10: ** ! 11: ** A special file or sequence (as controlled by the ttycap file) ! 12: ** is sent to the terminal. ! 13: ** ! 14: ** Mode bits are set on a per-terminal_type basis (much better ! 15: ** than UNIX itself). This allows special delays, automatic ! 16: ** tabs, etc. ! 17: ** ! 18: ** Erase and Kill characters can be set to whatever you want. ! 19: ** Default is to change erase to control-H on a terminal which ! 20: ** can overstrike, and leave it alone on anything else. Kill ! 21: ** is always left alone unless specifically requested. These ! 22: ** characters can be represented as "^X" meaning control-X; ! 23: ** X is any character. ! 24: ** ! 25: ** Terminals which are dialups or plugboard types can be aliased ! 26: ** to whatever type you may have in your home or office. Thus, ! 27: ** if you know that when you dial up you will always be on a ! 28: ** TI 733, you can specify that fact to tset. You can represent ! 29: ** a type as "?type". This will ask you what type you want it ! 30: ** to be -- if you reply with just a newline, it will default ! 31: ** to the type given. ! 32: ** ! 33: ** The htmp file, used by ex, etc., can be updated. ! 34: ** ! 35: ** The current terminal type can be queried. ! 36: ** ! 37: ** Usage: ! 38: ** tset [-] [-EC] [-eC] [-kC] [-s] [-h] [-u] ! 39: ** [-d type] [-p type] [-b type] [-a type] ! 40: ** [-Q] [-I] [type] ! 41: ** ! 42: ** In systems with environments, use: ! 43: ** `tset -s ...` ! 44: ** Actually, this doesn't work because of a shell bug. ! 45: ** Instead, use: ! 46: ** tset -s ... > tset.tmp ! 47: ** source tset.tmp ! 48: ** rm tset.tmp ! 49: ** ! 50: ** Positional Parameters: ! 51: ** type -- the terminal type to force. If this is ! 52: ** specified, initialization is for this ! 53: ** terminal type. ! 54: ** ! 55: ** Flags: ! 56: ** - -- report terminal type. Whatever type is ! 57: ** decided on is reported. If no other flags ! 58: ** are stated, the only affect is to write ! 59: ** the terminal type on the standard output. ! 60: ** -EC -- set the erase character to C on all terminals ! 61: ** except those which cannot backspace (e.g., ! 62: ** a TTY 33). C defaults to control-H. ! 63: ** -eC -- set the erase character to C on all terminals. ! 64: ** C defaults to control-H. If neither -E or -e ! 65: ** are specified, the erase character is set to ! 66: ** control-H if the terminal can both backspace ! 67: ** and not overstrike (e.g., a CRT). If the erase ! 68: ** character is NULL (zero byte), it will be reset ! 69: ** to '#' if nothing else is specified. ! 70: ** -kC -- set the kill character to C on all terminals. ! 71: ** Default for C is control-X. If not specified, ! 72: ** the kill character is untouched; however, if ! 73: ** not specified and the kill character is NULL ! 74: ** (zero byte), the kill character is set to '@'. ! 75: ** -iC -- reserved for setable interrupt character. ! 76: ** -qC -- reserved for setable quit character. ! 77: ** -d type -- set the dialup type to be type. If the ! 78: ** terminal type seems to be dialup, make it ! 79: ** 'type' instead. There need not be a space ! 80: ** between 'd' and 'type'. ! 81: ** -p type -- ditto for a plugboard. ! 82: ** -b type -- ditto for a bussiplexor. ! 83: ** -a type -- ditto for an arpanet link. ! 84: ** -h -- don't read htmp file. Normally the terminal type ! 85: ** is determined by reading the htmp file (unless ! 86: ** -d or -p are specified). This forces a read ! 87: ** of the ttytype file -- useful when htmp is ! 88: ** somehow wrong. ! 89: ** -u -- don't update htmp. It seemed like this should ! 90: ** be put in. Note that htmp is never actually ! 91: ** written if there are no changes, so don't bother ! 92: ** bother using this for efficiency reasons alone. ! 93: ** -s -- output setenv commands for TERM. This can be ! 94: ** used with ! 95: ** `tset -s ...` ! 96: ** and is to be prefered to: ! 97: ** setenv TERM `tset - ...` ! 98: ** because -s sets the TERMCAP variable also. ! 99: ** -Q -- be quiet. don't output 'Erase set to' etc. ! 100: ** -I -- don't do terminal initialization (is & if ! 101: ** strings). ! 102: ** ! 103: ** Files: ! 104: ** /etc/ttytype ! 105: ** contains a terminal id -> terminal type ! 106: ** mapping; used when -h, -d, or -p is used. ! 107: ** /etc/termcap ! 108: ** a terminal_type -> terminal_capabilities ! 109: ** mapping. ! 110: ** ! 111: ** Return Codes: ! 112: ** -1 -- couldn't open ttycap. ! 113: ** 1 -- bad terminal type, or standard output not tty. ! 114: ** 0 -- ok. ! 115: ** ! 116: ** Defined Constants: ! 117: ** DIALUP -- the type code for a dialup port ! 118: ** PLUGBOARD -- the code for a plugboard port. ! 119: ** BUSSIPLEXER -- the code for a bussiplexer port. ! 120: ** ARPANET -- the code for an arpanet port. ! 121: ** BACKSPACE -- control-H, the default for -e. ! 122: ** CONTROLX -- control-X, the default for -k. ! 123: ** OLDERASE -- the system default erase character. ! 124: ** OLDKILL -- the system default kill character. ! 125: ** FILEDES -- the file descriptor to do the operation ! 126: ** on, nominally 1 or 2. ! 127: ** STDOUT -- the standard output file descriptor. ! 128: ** UIDMASK -- the bit pattern to mask with the getuid() ! 129: ** call to get just the user id. ! 130: ** ! 131: ** Requires: ! 132: ** Routines to handle htmp, ttytype, and ttycap. ! 133: ** ! 134: ** Compilation Flags: ! 135: ** PLUGBOARD -- if defined, accept the -p flag. ! 136: ** BUSSIPLEXER -- if defined, accept the -b flag. ! 137: ** FULLLOGIN -- if defined, login sets the ttytype from ! 138: ** /etc/ttytype file. ! 139: ** V6 -- if clear, use environments, not htmp. ! 140: ** also use TIOCSETN rather than stty to avoid flushing ! 141: ** GTTYN -- if set, uses generalized tty names. ! 142: ** ! 143: ** Trace Flags: ! 144: ** none ! 145: ** ! 146: ** Diagnostics: ! 147: ** Bad flag ! 148: ** An incorrect option was specified. ! 149: ** Cannot open ... ! 150: ** The specified file could not be openned. ! 151: ** Type ... unknown ! 152: ** An unknown terminal type was specified. ! 153: ** Cannot update htmp ! 154: ** Cannot update htmp file when the standard ! 155: ** output is not a terminal. ! 156: ** Erase set to ... ! 157: ** Telling that the erase character has been ! 158: ** set to the specified character. ! 159: ** Kill set to ... ! 160: ** Ditto for kill ! 161: ** Erase is ... Kill is ... ! 162: ** Tells that the erase/kill characters were ! 163: ** wierd before, but they are being left as-is. ! 164: ** Not a terminal ! 165: ** Set if FILEDES is not a terminal. ! 166: ** ! 167: ** Compilation Instructions: ! 168: ** cc -n -O tset.c -lX ! 169: ** mv a.out tset ! 170: ** chown bin tset ! 171: ** chmod 4755 tset ! 172: ** ! 173: ** where 'bin' should be whoever owns the 'htmp' file. ! 174: ** If 'htmp' is 666, then tset need not be setuid. ! 175: ** ! 176: ** Author: ! 177: ** Eric Allman ! 178: ** Electronics Research Labs ! 179: ** U.C. Berkeley ! 180: ** ! 181: ** History: ! 182: ** 10/79 -- '-s' option extended to handle TERMCAP ! 183: ** variable, set noglob, quote the entry, ! 184: ** and know about the Bourne shell. Terminal ! 185: ** initialization moved to before any information ! 186: ** output so screen clears would not screw you. ! 187: ** '-Q' option added. ! 188: ** 8/79 -- '-' option alone changed to only output ! 189: ** type. '-s' option added. 'VERSION7' ! 190: ** changed to 'V6' for compatibility. ! 191: ** 12/78 -- modified for eventual migration to VAX/UNIX, ! 192: ** so the '-' option is changed to output only ! 193: ** the terminal type to STDOUT instead of ! 194: ** FILEDES. FULLLOGIN flag added. ! 195: ** 9/78 -- '-' and '-p' options added (now fully ! 196: ** compatible with ttytype!), and spaces are ! 197: ** permitted between the -d and the type. ! 198: ** 8/78 -- The sense of -h and -u were reversed, and the ! 199: ** -f flag is dropped -- same effect is available ! 200: ** by just stating the terminal type. ! 201: ** 10/77 -- Written. ! 202: */ ! 203: ! 204: /* ! 205: # define FULLLOGIN 1 ! 206: */ ! 207: # ifndef V6 ! 208: # define GTTYN 1 ! 209: # endif ! 210: ! 211: # include <sgtty.h> ! 212: # include <stdio.h> ! 213: ! 214: # define BACKSPACE ('H' & 037) ! 215: # define CONTROLX ('X' & 037) ! 216: # define OLDERASE '#' ! 217: # define OLDKILL '@' ! 218: ! 219: # define FILEDES 2 ! 220: # define STDOUT 1 ! 221: ! 222: # ifdef V6 ! 223: # define UIDMASK 0377 ! 224: # else ! 225: # define UIDMASK -1 ! 226: # endif ! 227: ! 228: # define DIALUP "sd" ! 229: # define PLUGBOARD "sp" ! 230: # define BUSSIPLEXER "sb" ! 231: # define ARPANET "sa" ! 232: ! 233: # ifdef GTTYN ! 234: typedef char *ttyid_t; ! 235: # define NOTTY 0 ! 236: # else ! 237: typedef char ttyid_t; ! 238: # define NOTTY 'x' ! 239: # endif ! 240: ! 241: ! 242: ! 243: ! 244: ! 245: ! 246: char Erase_char; /* new erase character */ ! 247: char Kill_char; /* new kill character */ ! 248: char Specialerase; /* set => Erase_char only on terminals with backspace */ ! 249: ! 250: ttyid_t Ttyid = NOTTY; /* terminal identifier */ ! 251: char *TtyType; /* type of terminal */ ! 252: char *DefType; /* default type if none other computed */ ! 253: char *DialType; /* override type if dialup port */ ! 254: char *PlugType; /* override type if plugboard port */ ! 255: char *BxType; /* override type if bussiplexer port */ ! 256: char *AnType; /* override type if arpanet port */ ! 257: int Dash_u; /* don't update htmp */ ! 258: int Dash_h; /* don't read htmp */ ! 259: int DoSetenv; /* output setenv commands */ ! 260: int BeQuiet; /* be quiet */ ! 261: int NoInit; /* don't output initialization string */ ! 262: int Report; /* report current type */ ! 263: int Ureport; /* report to user */ ! 264: int RepOnly; /* report only */ ! 265: ! 266: char Usage[] = "usage: tset [-] [-r] [-s] [-eC] [-kC] [-d T] [-p T] [-b T] [-a T]\n\t[-Q] [-I] [-h] [-u] [type]\n"; ! 267: ! 268: char Capbuf[1024]; /* line from /etc/termcap for this TtyType */ ! 269: char *Ttycap; /* termcap line from termcap or environ */ ! 270: ! 271: struct delay ! 272: { ! 273: int d_delay; ! 274: int d_bits; ! 275: }; ! 276: ! 277: # include "tset.delays.h" ! 278: ! 279: ! 280: ! 281: main(argc, argv) ! 282: int argc; ! 283: char *argv[]; ! 284: { ! 285: struct sgttyb mode; ! 286: struct sgttyb oldmode; ! 287: char buf[256]; ! 288: auto char *bufp; ! 289: register char *p; ! 290: char *command; ! 291: register int i; ! 292: register int error; ! 293: extern char *stypeof(); ! 294: # ifdef V6 ! 295: extern char *hsgettype(); ! 296: # else ! 297: extern char *getenv(); ! 298: # endif ! 299: # ifdef GTTYN ! 300: extern char *ttyname(); ! 301: extern char *tgetstr(); ! 302: # endif ! 303: char bs_char; ! 304: int csh; ! 305: ! 306: /* scan argument list and collect flags */ ! 307: error = 0; ! 308: command = argv[0]; ! 309: if (argc == 2 && argv[1][0] == '-' && argv[1][1] == '\0') ! 310: RepOnly++; ! 311: argc--; ! 312: while (--argc >= 0) ! 313: { ! 314: p = *++argv; ! 315: if (p[0] == '-') ! 316: { ! 317: switch (p[1]) ! 318: { ! 319: ! 320: case 0: /* report current terminal type */ ! 321: Report++; ! 322: continue; ! 323: ! 324: case 'r': /* report to user */ ! 325: Ureport++; ! 326: continue; ! 327: ! 328: case 'E': /* special erase: operate on all but TTY33 */ ! 329: Specialerase++; ! 330: /* explicit fall-through to -e case */ ! 331: ! 332: case 'e': /* erase character */ ! 333: if (p[2] == 0) ! 334: Erase_char = -1; ! 335: else if (p[2] == '^' && p[3] != '\0') ! 336: Erase_char = p[3] & 037; ! 337: else ! 338: Erase_char = p[2]; ! 339: continue; ! 340: ! 341: case 'k': /* kill character */ ! 342: if (p[2] == 0) ! 343: Kill_char = CONTROLX; ! 344: else if (p[2] == '^' && p[3] != '\0') ! 345: Kill_char = p[3] & 037; ! 346: else ! 347: Kill_char = p[2]; ! 348: continue; ! 349: ! 350: case 'd': /* dialup type */ ! 351: if (p[2] != 0) ! 352: DialType = &p[2]; ! 353: else if (--argc < 0 || argv[1][0] == '-') ! 354: error++; ! 355: else ! 356: DialType = *++argv; ! 357: continue; ! 358: ! 359: # ifdef PLUGBOARD ! 360: case 'p': /* plugboard type */ ! 361: if (p[2] != 0) ! 362: PlugType = &p[2]; ! 363: else if (--argc < 0 || argv[1][0] == '-') ! 364: error++; ! 365: else ! 366: PlugType = *++argv; ! 367: continue; ! 368: # endif ! 369: ! 370: # ifdef BUSSIPLEXER ! 371: case 'b': /* bussiplexer type */ ! 372: if (p[2] != 0) ! 373: BxType = &p[2]; ! 374: else if (--argc < 0 || argv[1][0] == '-') ! 375: error++; ! 376: else ! 377: BxType = *++argv; ! 378: # endif ! 379: ! 380: # ifdef ARPANET ! 381: case 'a': /* arpanet type */ ! 382: if (p[2] != 0) ! 383: AnType = &p[2]; ! 384: else if (--argc < 0 || argv[1][0] == '-') ! 385: error++; ! 386: else ! 387: AnType = *++argv; ! 388: # endif ! 389: ! 390: case 'h': /* don't get type from htmp or env */ ! 391: Dash_h++; ! 392: continue; ! 393: ! 394: case 'u': /* don't update htmp */ ! 395: Dash_u++; ! 396: continue; ! 397: ! 398: case 's': /* output setenv commands */ ! 399: DoSetenv++; ! 400: continue; ! 401: ! 402: case 'Q': /* be quiet */ ! 403: BeQuiet++; ! 404: continue; ! 405: ! 406: case 'I': /* no initialization */ ! 407: NoInit++; ! 408: continue; ! 409: ! 410: default: ! 411: prs("Bad flag "); ! 412: prs(p); ! 413: prs("\n"); ! 414: error++; ! 415: ! 416: } ! 417: } ! 418: else ! 419: { ! 420: /* terminal type */ ! 421: DefType = p; ! 422: } ! 423: } ! 424: ! 425: if (error) ! 426: { ! 427: prs(Usage); ! 428: exit(1); ! 429: } ! 430: ! 431: /* if dialup is specified, check ttytype not htmp */ ! 432: if (DialType == 0 && PlugType == 0 && BxType == 0 && AnType == 0) ! 433: TtyType = DefType; ! 434: # ifndef FULLLOGIN ! 435: else ! 436: Dash_h++; ! 437: # endif ! 438: ! 439: /* if report only, say that we won't update htmp */ ! 440: if (RepOnly) ! 441: Dash_u++; ! 442: ! 443: # ifndef V6 ! 444: /* get current idea of terminal type from environment */ ! 445: if (!Dash_h && TtyType == 0) ! 446: TtyType = getenv("TERM"); ! 447: # endif ! 448: ! 449: /* determine terminal id if needed */ ! 450: # ifdef V6 ! 451: if (Ttyid == NOTTY && (TtyType == 0 || !Dash_h || !Dash_u)) ! 452: Ttyid = ttyn(FILEDES); ! 453: # else ! 454: if (!RepOnly && Ttyid == NOTTY && (TtyType == 0 || !Dash_h)) ! 455: Ttyid = ttyname(FILEDES); ! 456: # endif ! 457: ! 458: # ifdef V6 ! 459: /* get htmp if ever used */ ! 460: if (!Dash_u || (TtyType == 0 && !Dash_h)) ! 461: { ! 462: /* get htmp entry -- if error or wrong user use ttytype */ ! 463: if (Ttyid == NOTTY || hget(Ttyid) < 0 || ! 464: hgettype() == 0 || hgetuid() != (getuid() & UIDMASK)) ! 465: Dash_h++; ! 466: } ! 467: # endif ! 468: ! 469: /* find terminal type (if not already known) */ ! 470: if (TtyType == 0) ! 471: { ! 472: /* get type from /etc/ttytype or /etc/htmp */ ! 473: if (!Dash_h) ! 474: { ! 475: # ifdef V6 ! 476: TtyType = hsgettype(); ! 477: # else ! 478: TtyType = getenv("TERM"); ! 479: # endif ! 480: } ! 481: if (TtyType == 0) ! 482: { ! 483: TtyType = stypeof(Ttyid); ! 484: } ! 485: ! 486: /* check for dialup or plugboard override */ ! 487: if (DialType != 0 && bequal(TtyType, DIALUP, 2)) ! 488: TtyType = DialType; ! 489: # ifdef PLUGBOARD ! 490: else if (PlugType != 0 && bequal(TtyType, PLUGBOARD, 2)) ! 491: TtyType = PlugType; ! 492: # endif ! 493: # ifdef BUSSIPLEXER ! 494: else if (BxType != 0 && bequal(TtyType, BUSSIPLEXER, 2)) ! 495: TtyType = BxType; ! 496: # endif ! 497: # ifdef ARPANET ! 498: else if (AnType != 0 && bequal(TtyType, ARPANET, 2)) ! 499: TtyType = AnType; ! 500: # endif ! 501: else if (DefType != 0) ! 502: TtyType = DefType; ! 503: } ! 504: ! 505: /* TtyType now contains a pointer to the type of the terminal */ ! 506: /* If the first character is '?', ask the user */ ! 507: if (TtyType[0] == '?') ! 508: { ! 509: if (*++TtyType == '\0') ! 510: TtyType = "dumb"; ! 511: prs("TERM = ("); ! 512: prs(TtyType); ! 513: prs(") "); ! 514: ! 515: /* read the terminal. If not empty, set type */ ! 516: i = read(2, buf, sizeof buf - 1); ! 517: if (i >= 0) ! 518: { ! 519: if (buf[i - 1] == '\n') ! 520: i--; ! 521: buf[i] = '\0'; ! 522: if (buf[0] != '\0') ! 523: TtyType = buf; ! 524: } ! 525: } ! 526: ! 527: if (Ttycap == 0) ! 528: { ! 529: /* get terminal capabilities */ ! 530: switch (tgetent(Capbuf, TtyType)) ! 531: { ! 532: case -1: ! 533: prs("Cannot open termcap file\n"); ! 534: exit(-1); ! 535: ! 536: case 0: ! 537: prs("Type "); ! 538: prs(TtyType); ! 539: prs(" unknown\n"); ! 540: exit(1); ! 541: } ! 542: Ttycap = Capbuf; ! 543: } ! 544: ! 545: /* output startup string */ ! 546: if (!RepOnly && !NoInit) ! 547: { ! 548: bufp = buf; ! 549: if (tgetstr("is", &bufp) != 0) ! 550: prs(buf); ! 551: bufp = buf; ! 552: if (tgetstr("if", &bufp) != 0) ! 553: cat(buf); ! 554: sleep(1); /* let terminal settle down */ ! 555: } ! 556: ! 557: /* set up environment for the shell we are using */ ! 558: /* (this code is rather heuristic) */ ! 559: csh = 0; ! 560: if (DoSetenv) ! 561: { ! 562: # ifndef V6 ! 563: if (bequal(getenv("SHELL"), "/bin/csh", 9)) ! 564: { ! 565: # endif ! 566: /* running csh */ ! 567: csh++; ! 568: write(STDOUT, "set noglob;\n", 12); ! 569: # ifndef V6 ! 570: } ! 571: else ! 572: { ! 573: /* running system shell */ ! 574: write(STDOUT, "export TERMCAP TERM;\n", 21); ! 575: } ! 576: # endif ! 577: } ! 578: ! 579: /* report type if appropriate */ ! 580: if (DoSetenv || Report || Ureport) ! 581: { ! 582: /* find first alias (if any) */ ! 583: for (p = Ttycap; *p != 0 && *p != '|' && *p != ':'; p++) ! 584: continue; ! 585: if (*p == 0 || *p == ':') ! 586: p = Ttycap; ! 587: else ! 588: p++; ! 589: bufp = p; ! 590: while (*p != '|' && *p != ':' && *p != 0) ! 591: p++; ! 592: i = *p; ! 593: if (DoSetenv) ! 594: { ! 595: if (csh) ! 596: write(STDOUT, "setenv TERM ", 12); ! 597: else ! 598: write(STDOUT, "TERM=", 5); ! 599: } ! 600: if (Report || DoSetenv) ! 601: { ! 602: write(STDOUT, bufp, p - bufp); ! 603: if (DoSetenv) ! 604: write(STDOUT, ";", 1); ! 605: write(STDOUT, "\n", 1); ! 606: } ! 607: if (Ureport) ! 608: { ! 609: *p = '\0'; ! 610: prs("Terminal type is "); ! 611: prs(bufp); ! 612: prs("\n"); ! 613: } ! 614: *p = i; ! 615: if (DoSetenv) ! 616: { ! 617: for (p = Ttycap; *p != '\0'; p++) ! 618: continue; ! 619: if (csh) ! 620: write(STDOUT, "setenv TERMCAP '", 16); ! 621: else ! 622: write(STDOUT, "TERMCAP='", 9); ! 623: write(STDOUT, Ttycap, p - Ttycap); ! 624: write(STDOUT, "';\n", 3); ! 625: ! 626: /* reset noglob */ ! 627: if (csh) ! 628: write(STDOUT, "unset noglob;\n", 14); ! 629: } ! 630: } ! 631: ! 632: /* exit if report only mode */ ! 633: if (RepOnly) ! 634: exit(0); ! 635: ! 636: if (gtty(FILEDES, &mode) < 0) ! 637: { ! 638: prs("Not a terminal\n"); ! 639: exit(1); ! 640: } ! 641: bmove(&mode, &oldmode, sizeof mode); ! 642: ! 643: /* determine erase and kill characters */ ! 644: if (Specialerase && !tgetflag("bs")) ! 645: Erase_char = 0; ! 646: bufp = buf; ! 647: p = tgetstr("bc", &bufp); ! 648: if (p != NULL) ! 649: bs_char = p[0]; ! 650: else if (tgetflag("bs")) ! 651: bs_char = BACKSPACE; ! 652: else ! 653: bs_char = 0; ! 654: if (Erase_char == 0 && !tgetflag("os")) ! 655: { ! 656: if (tgetflag("bs") || bs_char != 0) ! 657: Erase_char = -1; ! 658: } ! 659: if (Erase_char < 0) ! 660: Erase_char = (bs_char != 0) ? bs_char : BACKSPACE; ! 661: ! 662: if (mode.sg_erase == 0) ! 663: mode.sg_erase = OLDERASE; ! 664: if (Erase_char != 0) ! 665: mode.sg_erase = Erase_char; ! 666: ! 667: if (mode.sg_kill == 0) ! 668: mode.sg_kill = OLDKILL; ! 669: if (Kill_char != 0) ! 670: mode.sg_kill = Kill_char; ! 671: ! 672: /* set modes */ ! 673: setdelay("dC", CRdelay, CRbits, &mode.sg_flags); ! 674: setdelay("dN", NLdelay, NLbits, &mode.sg_flags); ! 675: setdelay("dB", BSdelay, BSbits, &mode.sg_flags); ! 676: setdelay("dF", FFdelay, FFbits, &mode.sg_flags); ! 677: setdelay("dT", TBdelay, TBbits, &mode.sg_flags); ! 678: if (tgetflag("UC") || command[0] == 'T') ! 679: mode.sg_flags |= LCASE; ! 680: else if (tgetflag("LC")) ! 681: mode.sg_flags &= ~LCASE; ! 682: mode.sg_flags &= ~(EVENP | ODDP | RAW); ! 683: # ifndef V6 ! 684: mode.sg_flags &= ~CBREAK; ! 685: # endif ! 686: if (tgetflag("EP")) ! 687: mode.sg_flags |= EVENP; ! 688: if (tgetflag("OP")) ! 689: mode.sg_flags |= ODDP; ! 690: if ((mode.sg_flags & (EVENP | ODDP)) == 0) ! 691: mode.sg_flags |= EVENP | ODDP; ! 692: mode.sg_flags |= CRMOD | ECHO | XTABS; ! 693: if (tgetflag("NL")) /* new line, not line feed */ ! 694: mode.sg_flags &= ~CRMOD; ! 695: if (tgetflag("HD")) /* half duplex */ ! 696: mode.sg_flags &= ~ECHO; ! 697: if (tgetflag("pt")) /* print tabs */ ! 698: mode.sg_flags &= ~XTABS; ! 699: if (!bequal(&mode, &oldmode, sizeof mode)) ! 700: # ifndef V6 ! 701: ioctl(FILEDES, TIOCSETN, &mode); ! 702: # else ! 703: stty(FILEDES, &mode); ! 704: # endif ! 705: ! 706: /* tell about changing erase and kill characters */ ! 707: reportek("Erase", mode.sg_erase, oldmode.sg_erase, OLDERASE); ! 708: reportek("Kill", mode.sg_kill, oldmode.sg_kill, OLDKILL); ! 709: ! 710: # ifdef V6 ! 711: /* update htmp */ ! 712: if (!Dash_u) ! 713: { ! 714: if (Ttyid == 0) ! 715: Ttyid = ttyn(FILEDES); ! 716: if (Ttyid == 'x') ! 717: prs("Cannot update htmp\n"); ! 718: else ! 719: { ! 720: /* update htmp file only if changed */ ! 721: if (!bequal(Capbuf, hsgettype(), 2)) ! 722: { ! 723: hsettype(Capbuf[0] | (Capbuf[1] << 8)); ! 724: hput(Ttyid); ! 725: } ! 726: } ! 727: } ! 728: # endif ! 729: ! 730: exit(0); ! 731: } ! 732: ! 733: ! 734: reportek(name, new, old, def) ! 735: char *name; ! 736: char old; ! 737: char new; ! 738: char def; ! 739: { ! 740: register char o; ! 741: register char n; ! 742: register char *p; ! 743: ! 744: if (BeQuiet) ! 745: return; ! 746: o = old; ! 747: n = new; ! 748: ! 749: if (o == n && n == def) ! 750: return; ! 751: prs(name); ! 752: if (o == n) ! 753: prs(" is "); ! 754: else ! 755: prs(" set to "); ! 756: if (n < 040) ! 757: { ! 758: prs("control-"); ! 759: n = (n & 037) | 0100; ! 760: } ! 761: p = "x\n"; ! 762: p[0] = n; ! 763: prs(p); ! 764: } ! 765: ! 766: ! 767: ! 768: ! 769: setdelay(cap, dtab, bits, flags) ! 770: char *cap; ! 771: struct delay dtab[]; ! 772: int bits; ! 773: int *flags; ! 774: { ! 775: register int i; ! 776: register struct delay *p; ! 777: ! 778: /* see if this capability exists at all */ ! 779: i = tgetnum(cap); ! 780: if (i < 0) ! 781: i = 0; ! 782: ! 783: /* clear out the bits, replace with new ones */ ! 784: *flags &= ~bits; ! 785: ! 786: /* scan dtab for first entry with adequate delay */ ! 787: for (p = dtab; p->d_delay >= 0; p++) ! 788: { ! 789: if (p->d_delay >= i) ! 790: { ! 791: p++; ! 792: break; ! 793: } ! 794: } ! 795: ! 796: /* use last entry if none will do */ ! 797: *flags |= (--p)->d_bits; ! 798: } ! 799: ! 800: ! 801: prs(s) ! 802: char *s; ! 803: { ! 804: register char *p; ! 805: register char *q; ! 806: register int i; ! 807: ! 808: p = q = s; ! 809: i = 0; ! 810: while (*q++ != 0) ! 811: i++; ! 812: ! 813: if (i > 0) ! 814: write(FILEDES, p, i); ! 815: } ! 816: ! 817: ! 818: cat(file) ! 819: char *file; ! 820: { ! 821: register int fd; ! 822: register int i; ! 823: char buf[BUFSIZ]; ! 824: ! 825: fd = open(file, 0); ! 826: if (fd < 0) ! 827: { ! 828: prs("Cannot open "); ! 829: prs(file); ! 830: prs("\n"); ! 831: exit(-1); ! 832: } ! 833: ! 834: while ((i = read(fd, buf, BUFSIZ)) > 0) ! 835: write(FILEDES, buf, i); ! 836: ! 837: close(fd); ! 838: } ! 839: ! 840: ! 841: ! 842: bmove(from, to, length) ! 843: char *from; ! 844: char *to; ! 845: int length; ! 846: { ! 847: register char *p, *q; ! 848: register int i; ! 849: ! 850: i = length; ! 851: p = from; ! 852: q = to; ! 853: ! 854: while (i-- > 0) ! 855: *q++ = *p++; ! 856: } ! 857: ! 858: ! 859: ! 860: bequal(a, b, len) ! 861: char *a; ! 862: char *b; ! 863: int len; ! 864: { ! 865: register char *p, *q; ! 866: register int i; ! 867: ! 868: i = len; ! 869: p = a; ! 870: q = b; ! 871: ! 872: while (i-- > 0) ! 873: if (*p++ != *q++) ! 874: return (0); ! 875: return (1); ! 876: } ! 877: ! 878: # ifdef GTTYN ! 879: char * ! 880: stypeof(ttyid) ! 881: char *ttyid; ! 882: { ! 883: static char typebuf[3]; ! 884: char buf[50]; ! 885: register char *p; ! 886: register FILE *f; ! 887: register char *t; ! 888: register char *q; ! 889: ! 890: if (ttyid == NOTTY) ! 891: return ("un"); ! 892: f = fopen("/etc/ttytype", "r"); ! 893: if (f == NULL) ! 894: return ("un"); ! 895: ! 896: /* split off end of name */ ! 897: for (p = q = ttyid; *p != 0; p++) ! 898: if (*p == '/') ! 899: q = p + 1; ! 900: ! 901: /* scan the file */ ! 902: while (fgets(buf, sizeof buf, f) != NULL) ! 903: { ! 904: for (p = q, t = &buf[3]; *p != '\0'; p++, t++) ! 905: if (*p != *t) ! 906: break; ! 907: if (*p == '\0' && (*t == '\n' || *t == '\t')) ! 908: { ! 909: typebuf[0] = buf[0]; ! 910: typebuf[1] = buf[1]; ! 911: typebuf[2] = '\0'; ! 912: fclose(f); ! 913: return (typebuf); ! 914: } ! 915: } ! 916: fclose (f); ! 917: return ("un"); ! 918: } ! 919: # endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.