|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 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 Regents of the University of California.\n\ ! 10: All rights reserved.\n"; ! 11: #endif not lint ! 12: ! 13: #ifndef lint ! 14: static char sccsid[] = "@(#)tset.c 5.8 (Berkeley) 4/28/86"; ! 15: #endif not lint ! 16: ! 17: /* ! 18: ** TSET -- set terminal modes ! 19: ** ! 20: ** This program does sophisticated terminal initialization. ! 21: ** I recommend that you include it in your .profile or .login ! 22: ** file to initialize whatever terminal you are on. ! 23: ** ! 24: ** There are several features: ! 25: ** ! 26: ** A special file or sequence (as controlled by the termcap file) ! 27: ** is sent to the terminal. ! 28: ** ! 29: ** Mode bits are set on a per-terminal_type basis (much better ! 30: ** than UNIX itself). This allows special delays, automatic ! 31: ** tabs, etc. ! 32: ** ! 33: ** Erase and Kill characters can be set to whatever you want. ! 34: ** Default is to change erase to control-H on a terminal which ! 35: ** can overstrike, and leave it alone on anything else. Kill ! 36: ** is always left alone unless specifically requested. These ! 37: ** characters can be represented as "^X" meaning control-X; ! 38: ** X is any character. ! 39: ** ! 40: ** Terminals which are dialups or plugboard types can be aliased ! 41: ** to whatever type you may have in your home or office. Thus, ! 42: ** if you know that when you dial up you will always be on a ! 43: ** TI 733, you can specify that fact to tset. You can represent ! 44: ** a type as "?type". This will ask you what type you want it ! 45: ** to be -- if you reply with just a newline, it will default ! 46: ** to the type given. ! 47: ** ! 48: ** The current terminal type can be queried. ! 49: ** ! 50: ** Usage: ! 51: ** tset [-] [-EC] [-eC] [-kC] [-iC] [-s] [-h] [-u] [-r] ! 52: ** [-m [ident] [test baudrate] :type] ! 53: ** [-Q] [-I] [-S] [type] ! 54: ** ! 55: ** In systems with environments, use: ! 56: ** eval `tset -s ...` ! 57: ** Actually, this doesn't work in old csh's. ! 58: ** Instead, use: ! 59: ** tset -s ... > tset.tmp ! 60: ** source tset.tmp ! 61: ** rm tset.tmp ! 62: ** or: ! 63: ** set noglob ! 64: ** set term=(`tset -S ....`) ! 65: ** setenv TERM $term[1] ! 66: ** setenv TERMCAP "$term[2]" ! 67: ** unset term ! 68: ** unset noglob ! 69: ** ! 70: ** Positional Parameters: ! 71: ** type -- the terminal type to force. If this is ! 72: ** specified, initialization is for this ! 73: ** terminal type. ! 74: ** ! 75: ** Flags: ! 76: ** - -- report terminal type. Whatever type is ! 77: ** decided on is reported. If no other flags ! 78: ** are stated, the only affect is to write ! 79: ** the terminal type on the standard output. ! 80: ** -r -- report to user in addition to other flags. ! 81: ** -EC -- set the erase character to C on all terminals ! 82: ** except those which cannot backspace (e.g., ! 83: ** a TTY 33). C defaults to control-H. ! 84: ** -eC -- set the erase character to C on all terminals. ! 85: ** C defaults to control-H. If not specified, ! 86: ** the erase character is untouched; however, if ! 87: ** not specified and the erase character is NULL ! 88: ** (zero byte), the erase character is set to delete. ! 89: ** -kC -- set the kill character to C on all terminals. ! 90: ** Default for C is control-X. If not specified, ! 91: ** the kill character is untouched; however, if ! 92: ** not specified and the kill character is NULL ! 93: ** (zero byte), the kill character is set to control-U. ! 94: ** -iC -- set the interrupt character to C on all terminals. ! 95: ** Default for C is control-C. If not specified, the ! 96: ** interrupt character is untouched; however, if ! 97: ** not specified and the interrupt character is NULL ! 98: ** (zero byte), the interrupt character is set to ! 99: ** control-C. ! 100: ** -qC -- reserved for setable quit character. ! 101: ** -m -- map the system identified type to some user ! 102: ** specified type. The mapping can be baud rate ! 103: ** dependent. This replaces the old -d, -p flags. ! 104: ** (-d type -> -m dialup:type) ! 105: ** (-p type -> -m plug:type) ! 106: ** Syntax: -m identifier [test baudrate] :type ! 107: ** where: ``identifier'' is terminal type found in ! 108: ** /etc/ttys for this port, (abscence of an identifier ! 109: ** matches any identifier); ``test'' may be any combination ! 110: ** of > = < ! @; ``baudrate'' is as with stty(1); ! 111: ** ``type'' is the actual terminal type to use if the ! 112: ** mapping condition is met. Multiple maps are scanned ! 113: ** in order and the first match prevails. ! 114: ** -n -- If the new tty driver from UCB is available, this flag ! 115: ** will activate the new options for erase and kill ! 116: ** processing. This will be different for printers ! 117: ** and crt's. For crts, if the baud rate is < 1200 then ! 118: ** erase and kill don't remove characters from the screen. ! 119: ** -h -- don't read htmp file. Normally the terminal type ! 120: ** is determined by reading the htmp file or the ! 121: ** environment (unless some mapping is specified). ! 122: ** This forces a read of the ttytype file -- useful ! 123: ** when htmp is somehow wrong. (V6 only) ! 124: ** -u -- don't update htmp. It seemed like this should ! 125: ** be put in. Note that htmp is never actually ! 126: ** written if there are no changes, so don't bother ! 127: ** bother using this for efficiency reasons alone. ! 128: ** -s -- output setenv commands for TERM. This can be ! 129: ** used with ! 130: ** `tset -s ...` ! 131: ** and is to be prefered to: ! 132: ** setenv TERM `tset - ...` ! 133: ** because -s sets the TERMCAP variable also. ! 134: ** -S -- Similar to -s but outputs 2 strings suitable for ! 135: ** use in csh .login files as follows: ! 136: ** set noglob ! 137: ** set term=(`tset -S .....`) ! 138: ** setenv TERM $term[1] ! 139: ** setenv TERMCAP "$term[2]" ! 140: ** unset term ! 141: ** unset noglob ! 142: ** -Q -- be quiet. don't output 'Erase set to' etc. ! 143: ** -I -- don't do terminal initialization (is & if ! 144: ** strings). ! 145: ** -v -- On virtual terminal systems, don't set up a ! 146: ** virtual terminal. Otherwise tset will tell ! 147: ** the operating system what kind of terminal you ! 148: ** are on (if it is a known terminal) and fix up ! 149: ** the output of -s to use virtual terminal sequences. ! 150: ** ! 151: ** Files: ! 152: ** /etc/ttys ! 153: ** contains a terminal id -> terminal type ! 154: ** mapping; used when any user mapping is specified, ! 155: ** or the environment doesn't have TERM set. ! 156: ** /etc/termcap ! 157: ** a terminal_type -> terminal_capabilities ! 158: ** mapping. ! 159: ** ! 160: ** Return Codes: ! 161: ** -1 -- couldn't open ttycap. ! 162: ** 1 -- bad terminal type, or standard output not tty. ! 163: ** 0 -- ok. ! 164: ** ! 165: ** Defined Constants: ! 166: ** DIALUP -- the type code for a dialup port. ! 167: ** PLUGBOARD -- the type code for a plugboard port. ! 168: ** ARPANET -- the type code for an arpanet port. ! 169: ** BACKSPACE -- control-H, the default for -e. ! 170: ** CNTL('X') -- control-X, the default for -k. ! 171: ** OLDERASE -- the system default erase character. ! 172: ** OLDKILL -- the system default kill character. ! 173: ** FILEDES -- the file descriptor to do the operation ! 174: ** on, nominally 1 or 2. ! 175: ** STDOUT -- the standard output file descriptor. ! 176: ** UIDMASK -- the bit pattern to mask with the getuid() ! 177: ** call to get just the user id. ! 178: ** GTTYN -- defines file containing generalized ttynames ! 179: ** and compiles code to look there. ! 180: ** ! 181: ** Requires: ! 182: ** Routines to handle htmp, ttys, and ttycap. ! 183: ** ! 184: ** Compilation Flags: ! 185: ** OLDFLAGS -- must be defined to compile code for any of ! 186: ** the -d, -p, or -a flags. ! 187: ** OLDDIALUP -- accept the -d flag. ! 188: ** OLDPLUGBOARD -- accept the -p flag. ! 189: ** OLDARPANET -- accept the -a flag. ! 190: ** V6 -- if clear, use environments, not htmp. ! 191: ** also use TIOCSETN rather than stty to avoid flushing ! 192: ** GTTYN -- if set, compiles code to look at /etc/ttys. ! 193: ** UCB_NTTY -- set to handle new tty driver modes. ! 194: ** ! 195: ** Trace Flags: ! 196: ** none ! 197: ** ! 198: ** Diagnostics: ! 199: ** Bad flag ! 200: ** An incorrect option was specified. ! 201: ** Too few args ! 202: ** more command line arguments are required. ! 203: ** Unexpected arg ! 204: ** wrong type of argument was encountered. ! 205: ** Cannot open ... ! 206: ** The specified file could not be openned. ! 207: ** Type ... unknown ! 208: ** An unknown terminal type was specified. ! 209: ** Cannot update htmp ! 210: ** Cannot update htmp file when the standard ! 211: ** output is not a terminal. ! 212: ** Erase set to ... ! 213: ** Telling that the erase character has been ! 214: ** set to the specified character. ! 215: ** Kill set to ... ! 216: ** Ditto for kill ! 217: ** Erase is ... Kill is ... ! 218: ** Tells that the erase/kill characters were ! 219: ** wierd before, but they are being left as-is. ! 220: ** Not a terminal ! 221: ** Set if FILEDES is not a terminal. ! 222: ** ! 223: ** Compilation Instructions: ! 224: ** cc -n -O tset.c -ltermlib ! 225: ** mv a.out tset ! 226: ** chown bin tset ! 227: ** chmod 4755 tset ! 228: ** ! 229: ** where 'bin' should be whoever owns the 'htmp' file. ! 230: ** If 'htmp' is 666, then tset need not be setuid. ! 231: ** ! 232: ** For version 6 the compile command should be: ! 233: ** cc -n -O -I/usr/include/retrofit tset.c -ltermlib -lretro -lS ! 234: ** ! 235: ** Author: ! 236: ** Eric Allman ! 237: ** Electronics Research Labs ! 238: ** U.C. Berkeley ! 239: ** ! 240: ** History: ! 241: ** 1/81 -- Added alias checking for mapping identifiers. ! 242: ** 9/80 -- Added UCB_NTTY mods to setup the new tty driver. ! 243: ** Added the 'reset ...' invocation. ! 244: ** 7/80 -- '-S' added. '-m' mapping added. TERMCAP string ! 245: ** cleaned up. ! 246: ** 3/80 -- Changed to use tputs. Prc & flush added. ! 247: ** 10/79 -- '-s' option extended to handle TERMCAP ! 248: ** variable, set noglob, quote the entry, ! 249: ** and know about the Bourne shell. Terminal ! 250: ** initialization moved to before any information ! 251: ** output so screen clears would not screw you. ! 252: ** '-Q' option added. ! 253: ** 8/79 -- '-' option alone changed to only output ! 254: ** type. '-s' option added. 'VERSION7' ! 255: ** changed to 'V6' for compatibility. ! 256: ** 12/78 -- modified for eventual migration to VAX/UNIX, ! 257: ** so the '-' option is changed to output only ! 258: ** the terminal type to STDOUT instead of ! 259: ** FILEDES. ! 260: ** 9/78 -- '-' and '-p' options added (now fully ! 261: ** compatible with ttytype!), and spaces are ! 262: ** permitted between the -d and the type. ! 263: ** 8/78 -- The sense of -h and -u were reversed, and the ! 264: ** -f flag is dropped -- same effect is available ! 265: ** by just stating the terminal type. ! 266: ** 10/77 -- Written. ! 267: */ ! 268: ! 269: #define UCB_NTTY ! 270: ! 271: # ifdef USG ! 272: # define index strchr ! 273: # define rindex strrchr ! 274: # define curerase mode.c_cc[VERASE] ! 275: # define curkill mode.c_cc[VKILL] ! 276: # define curintr mode.c_cc[VINTR] ! 277: # define olderase oldmode.c_cc[VERASE] ! 278: # define oldkill oldmode.c_cc[VKILL] ! 279: # define oldintr oldmode.c_cc[VINTR] ! 280: # else ! 281: # define curerase mode.sg_erase ! 282: # define curkill mode.sg_kill ! 283: # define curintr tchar.t_intrc ! 284: # define olderase oldmode.sg_erase ! 285: # define oldkill oldmode.sg_kill ! 286: # define oldintr oldtchar.t_intrc ! 287: # endif ! 288: ! 289: # ifndef V6 ! 290: # define GTTYN ! 291: # include <ttyent.h> ! 292: # endif ! 293: ! 294: # ifndef USG ! 295: # include <sgtty.h> ! 296: # else ! 297: # include <termio.h> ! 298: # endif ! 299: ! 300: # include <stdio.h> ! 301: # include <signal.h> ! 302: # ifdef V6 ! 303: # include <retrofit.h> ! 304: # endif ! 305: ! 306: # define YES 1 ! 307: # define NO 0 ! 308: #undef CNTL ! 309: # define CNTL(c) ((c)&037) ! 310: # define BACKSPACE (CNTL('H')) ! 311: # define CHK(val, dft) (val<=0 ? dft : val) ! 312: # define isdigit(c) (c >= '0' && c <= '9') ! 313: # define isalnum(c) (c > ' ' && (index("<@=>!:|\177", c) == NULL)) ! 314: # define OLDERASE '#' ! 315: # define OLDKILL '@' ! 316: # define OLDINTR '\177' /* del */ ! 317: ! 318: /* default special characters */ ! 319: #ifndef CERASE ! 320: #define CERASE '\177' ! 321: #endif ! 322: #ifndef CKILL ! 323: #define CKILL CNTL('U') ! 324: #endif ! 325: #ifndef CINTR ! 326: #define CINTR CNTL('C') ! 327: #endif ! 328: #ifndef CDSUSP ! 329: #define CQUIT 034 /* FS, ^\ */ ! 330: #define CSTART CNTL('Q') ! 331: #define CSTOP CNTL('S') ! 332: #define CEOF CNTL('D') ! 333: #define CEOT CEOF ! 334: #define CBRK 0377 ! 335: #define CSUSP CNTL('Z') ! 336: #define CDSUSP CNTL('Y') ! 337: #define CRPRNT CNTL('R') ! 338: #define CFLUSH CNTL('O') ! 339: #define CWERASE CNTL('W') ! 340: #define CLNEXT CNTL('V') ! 341: #endif ! 342: ! 343: # define FILEDES 2 /* do gtty/stty on this descriptor */ ! 344: # define STDOUT 1 /* output of -s/-S to this descriptor */ ! 345: ! 346: # ifdef V6 ! 347: # define UIDMASK 0377 ! 348: # else ! 349: # define UIDMASK -1 ! 350: # endif ! 351: ! 352: # ifdef UCB_NTTY ! 353: # define USAGE "usage: tset [-] [-nrsIQS] [-eC] [-kC] [-iC] [-m [ident][test speed]:type] [type]\n" ! 354: # else ! 355: # define USAGE "usage: tset [-] [-rsIQS] [-eC] [-kC] [-iC] [-m [ident][test speed]:type] [type]\n" ! 356: # endif ! 357: ! 358: # define OLDFLAGS ! 359: # define DIALUP "dialup" ! 360: # define OLDDIALUP "sd" ! 361: # define PLUGBOARD "plugboard" ! 362: # define OLDPLUGBOARD "sp" ! 363: /*** ! 364: # define ARPANET "arpanet" ! 365: # define OLDARPANET "sa" ! 366: /***/ ! 367: ! 368: # define DEFTYPE "unknown" ! 369: ! 370: ! 371: # ifdef GTTYN ! 372: # define NOTTY 0 ! 373: # else ! 374: # define NOTTY 'x' ! 375: # endif ! 376: ! 377: /* ! 378: * Baud Rate Conditionals ! 379: */ ! 380: # define ANY 0 ! 381: # define GT 1 ! 382: # define EQ 2 ! 383: # define LT 4 ! 384: # define GE (GT|EQ) ! 385: # define LE (LT|EQ) ! 386: # define NE (GT|LT) ! 387: # define ALL (GT|EQ|LT) ! 388: ! 389: ! 390: ! 391: # define NMAP 10 ! 392: ! 393: struct map { ! 394: char *Ident; ! 395: char Test; ! 396: char Speed; ! 397: char *Type; ! 398: } map[NMAP]; ! 399: ! 400: struct map *Map = map; ! 401: ! 402: /* This should be available in an include file */ ! 403: struct ! 404: { ! 405: char *string; ! 406: int speed; ! 407: int baudrate; ! 408: } speeds[] = { ! 409: "0", B0, 0, ! 410: "50", B50, 50, ! 411: "75", B75, 75, ! 412: "110", B110, 110, ! 413: "134", B134, 134, ! 414: "134.5",B134, 134, ! 415: "150", B150, 150, ! 416: "200", B200, 200, ! 417: "300", B300, 300, ! 418: "600", B600, 600, ! 419: "1200", B1200, 1200, ! 420: "1800", B1800, 1800, ! 421: "2400", B2400, 2400, ! 422: "4800", B4800, 4800, ! 423: "9600", B9600, 9600, ! 424: "19200",EXTA, 19200, ! 425: "exta", EXTA, 19200, ! 426: "extb", EXTB, 38400, ! 427: 0, ! 428: }; ! 429: ! 430: #ifdef CBVIRTTERM ! 431: struct vterm { ! 432: char cap[2]; ! 433: char *value; ! 434: } vtab [] = { ! 435: "al", "\033\120", ! 436: "cd", "\033\114", ! 437: "ce", "\033\113", ! 438: "cm", "\033\107%r%.%.", ! 439: "cl", "\033\112", ! 440: "dc", "\033\115", ! 441: "dl", "\033\116", ! 442: "ic", "\033\117", ! 443: "kl", "\033\104", ! 444: "kr", "\033\103", ! 445: "ku", "\033\101", ! 446: "kd", "\033\102", ! 447: "kh", "\033\105", ! 448: "nd", "\033\103", ! 449: "se", "\033\142\004", ! 450: "so", "\033\141\004", ! 451: "ue", "\033\142\001", ! 452: "up", "\033\101", ! 453: "us", "\033\141\001", ! 454: "\0\0", NULL, ! 455: }; ! 456: ! 457: int VirTermNo = -2; ! 458: int HasAM; /* True if terminal has automatic margins */ ! 459: # endif CBVIRTTERM ! 460: ! 461: char Erase_char; /* new erase character */ ! 462: char Kill_char; /* new kill character */ ! 463: char Intr_char; /* new interrupt character */ ! 464: char Specialerase; /* set => Erase_char only on terminals with backspace */ ! 465: ! 466: # ifdef GTTYN ! 467: char *Ttyid = NOTTY; /* terminal identifier */ ! 468: # else ! 469: char Ttyid = NOTTY; /* terminal identifier */ ! 470: # endif ! 471: char *TtyType; /* type of terminal */ ! 472: char *DefType; /* default type if none other computed */ ! 473: char *NewType; /* mapping identifier based on old flags */ ! 474: int Mapped; /* mapping has been specified */ ! 475: int Dash_u; /* don't update htmp */ ! 476: int Dash_h; /* don't read htmp */ ! 477: int DoSetenv; /* output setenv commands */ ! 478: int BeQuiet; /* be quiet */ ! 479: int NoInit; /* don't output initialization string */ ! 480: int IsReset; /* invoked as reset */ ! 481: int Report; /* report current type */ ! 482: int Ureport; /* report to user */ ! 483: int RepOnly; /* report only */ ! 484: int CmndLine; /* output full command lines (-s option) */ ! 485: int Ask; /* ask user for termtype */ ! 486: int DoVirtTerm = YES; /* Set up a virtual terminal */ ! 487: int PadBaud; /* Min rate of padding needed */ ! 488: int lines, columns; ! 489: ! 490: # define CAPBUFSIZ 1024 ! 491: char Capbuf[CAPBUFSIZ]; /* line from /etc/termcap for this TtyType */ ! 492: char *Ttycap; /* termcap line from termcap or environ */ ! 493: ! 494: char Aliasbuf[128]; ! 495: char *Alias[16]; ! 496: ! 497: extern char *strcpy(); ! 498: extern char *index(); ! 499: ! 500: struct delay ! 501: { ! 502: int d_delay; ! 503: int d_bits; ! 504: }; ! 505: ! 506: # include "tset.delays.h" ! 507: ! 508: # ifndef USG ! 509: struct sgttyb mode; ! 510: struct sgttyb oldmode; ! 511: struct tchars tchar; ! 512: struct tchars oldtchar; ! 513: # else ! 514: struct termio mode; ! 515: struct termio oldmode; ! 516: # endif ! 517: # ifdef CBVIRTTERM ! 518: struct termcb block = {0, 2, 0, 0, 0, 20}; ! 519: # endif CBVIRTTERM ! 520: ! 521: ! 522: main(argc, argv) ! 523: int argc; ! 524: char *argv[]; ! 525: { ! 526: char buf[CAPBUFSIZ]; ! 527: char termbuf[32]; ! 528: auto char *bufp; ! 529: register char *p; ! 530: char *command; ! 531: register int i; ! 532: # ifdef CBVIRTTERM ! 533: int j; ! 534: # endif CBVIRTTERM ! 535: int Break; ! 536: int Not; ! 537: char *nextarg(); ! 538: char *mapped(); ! 539: extern char *rindex(); ! 540: struct winsize win; ! 541: # ifdef V6 ! 542: extern char *hsgettype(); ! 543: # else ! 544: extern char *getenv(); ! 545: # endif ! 546: # ifdef GTTYN ! 547: char *stypeof(); ! 548: extern char *ttyname(); ! 549: extern char *tgetstr(); ! 550: # endif ! 551: char bs_char; ! 552: int csh; ! 553: int settle; ! 554: int setmode(); ! 555: extern prc(); ! 556: extern char PC; ! 557: # ifdef V6 ! 558: extern int ospeed; ! 559: # else ! 560: extern short ospeed; ! 561: # endif ! 562: # ifdef UCB_NTTY ! 563: int lmode; ! 564: int ldisc; ! 565: ! 566: (void) ioctl(FILEDES, TIOCLGET, (char *)&lmode); ! 567: (void) ioctl(FILEDES, TIOCGETD, (char *)&ldisc); ! 568: # endif ! 569: ! 570: # ifndef USG ! 571: if (gtty(FILEDES, &mode) < 0) ! 572: # else ! 573: if (ioctl(FILEDES, TCGETA, (char *)&mode) < 0) ! 574: # endif ! 575: { ! 576: prs("Not a terminal\n"); ! 577: exit(1); ! 578: } ! 579: bmove((char *)&mode, (char *)&oldmode, sizeof mode); ! 580: # ifdef TIOCGETC ! 581: (void) ioctl(FILEDES, TIOCGETC, (char *)&tchar); ! 582: bmove((char *)&tchar, (char *)&oldtchar, sizeof tchar); ! 583: # endif ! 584: # ifndef USG ! 585: ospeed = mode.sg_ospeed & 017; ! 586: # else ! 587: ospeed = mode.c_cflag & CBAUD; ! 588: # endif ! 589: (void) signal(SIGINT, setmode); ! 590: (void) signal(SIGQUIT, setmode); ! 591: (void) signal(SIGTERM, setmode); ! 592: ! 593: if (command = rindex(argv[0], '/')) ! 594: command++; ! 595: else ! 596: command = argv[0]; ! 597: if (sequal(command, "reset") ) ! 598: { ! 599: /* ! 600: * reset the teletype mode bits to a sensible state. ! 601: * Copied from the program by Kurt Shoens & Mark Horton. ! 602: * Very useful after crapping out in raw. ! 603: */ ! 604: # ifndef V6 ! 605: # ifdef UCB_NTTY ! 606: struct ltchars ltc; ! 607: ! 608: if (ldisc == NTTYDISC) ! 609: { ! 610: (void) ioctl(FILEDES, TIOCGLTC, (char *)<c); ! 611: ltc.t_suspc = CHK(ltc.t_suspc, CSUSP); ! 612: ltc.t_dsuspc = CHK(ltc.t_dsuspc, CDSUSP); ! 613: ltc.t_rprntc = CHK(ltc.t_rprntc, CRPRNT); ! 614: ltc.t_flushc = CHK(ltc.t_flushc, CFLUSH); ! 615: ltc.t_werasc = CHK(ltc.t_werasc, CWERASE); ! 616: ltc.t_lnextc = CHK(ltc.t_lnextc, CLNEXT); ! 617: (void) ioctl(FILEDES, TIOCSLTC, (char *)<c); ! 618: } ! 619: # endif UCB_NTTY ! 620: # ifndef USG ! 621: # ifdef TIOCGETC ! 622: tchar.t_intrc = CHK(tchar.t_intrc, CINTR); ! 623: tchar.t_quitc = CHK(tchar.t_quitc, CQUIT); ! 624: tchar.t_startc = CHK(tchar.t_startc, CSTART); ! 625: tchar.t_stopc = CHK(tchar.t_stopc, CSTOP); ! 626: tchar.t_eofc = CHK(tchar.t_eofc, CEOF); ! 627: /* brkc is left alone */ ! 628: (void) ioctl(FILEDES, TIOCSETC, (char *)&tchar); ! 629: # endif TIOCGETC ! 630: mode.sg_flags &= ~(RAW ! 631: # ifdef CBREAK ! 632: |CBREAK ! 633: # endif CBREAK ! 634: |VTDELAY|ALLDELAY); ! 635: mode.sg_flags |= XTABS|ECHO|CRMOD|ANYP; ! 636: curerase = CHK(curerase, CERASE); ! 637: curkill = CHK(curkill, CKILL); ! 638: curintr = CHK(curintr, CINTR); ! 639: # else USG ! 640: (void) ioctl(FILEDES, TCGETA, (char *)&mode); ! 641: curerase = CHK(curerase, OLDERASE); ! 642: curkill = CHK(curkill, OLDKILL); ! 643: curintr = CHK(curintr, OLDINTR); ! 644: mode.c_cc[VQUIT] = CHK(mode.c_cc[VQUIT], CQUIT); ! 645: mode.c_cc[VEOF] = CHK(mode.c_cc[VEOF], CEOF); ! 646: ! 647: mode.c_iflag |= (BRKINT|ISTRIP|ICRNL|IXON); ! 648: mode.c_iflag &= ~(IGNBRK|PARMRK|INPCK|INLCR|IGNCR|IUCLC|IXOFF); ! 649: mode.c_oflag |= (OPOST|ONLCR); ! 650: mode.c_oflag &= ~(OLCUC|OCRNL|ONOCR|ONLRET|OFILL|OFDEL| ! 651: NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY); ! 652: mode.c_cflag |= (CS7|CREAD); ! 653: mode.c_cflag &= ~(CSIZE|PARODD|CLOCAL); ! 654: mode.c_lflag |= (ISIG|ICANON|ECHO|ECHOK); ! 655: mode.c_lflag &= ~(XCASE|ECHONL|NOFLSH); ! 656: (void) ioctl(FILEDES, TCSETAW, (char *)&mode); ! 657: # endif USG ! 658: # endif V6 ! 659: Dash_u = YES; ! 660: BeQuiet = YES; ! 661: IsReset = YES; ! 662: } ! 663: else if (argc == 2 && sequal(argv[1], "-")) ! 664: { ! 665: RepOnly = YES; ! 666: Dash_u = YES; ! 667: } ! 668: argc--; ! 669: ! 670: /* scan argument list and collect flags */ ! 671: while (--argc >= 0) ! 672: { ! 673: p = *++argv; ! 674: if (*p == '-') ! 675: { ! 676: if (*++p == NULL) ! 677: Report = YES; /* report current terminal type */ ! 678: else while (*p) switch (*p++) ! 679: { ! 680: ! 681: # ifdef UCB_NTTY ! 682: case 'n': ! 683: ldisc = NTTYDISC; ! 684: if (ioctl(FILEDES, TIOCSETD, (char *)&ldisc)<0) ! 685: fatal("ioctl ", "new"); ! 686: continue; ! 687: # endif ! 688: ! 689: case 'r': /* report to user */ ! 690: Ureport = YES; ! 691: continue; ! 692: ! 693: case 'E': /* special erase: operate on all but TTY33 */ ! 694: Specialerase = YES; ! 695: /* explicit fall-through to -e case */ ! 696: ! 697: case 'e': /* erase character */ ! 698: if (*p == NULL) ! 699: Erase_char = -1; ! 700: else ! 701: { ! 702: if (*p == '^' && p[1] != NULL) ! 703: if (*++p == '?') ! 704: Erase_char = '\177'; ! 705: else ! 706: Erase_char = CNTL(*p); ! 707: else ! 708: Erase_char = *p; ! 709: p++; ! 710: } ! 711: continue; ! 712: ! 713: # if defined(USG) || defined(TIOCGETC) ! 714: case 'i': /* interrupt character */ ! 715: if (*p == NULL) ! 716: Intr_char = CNTL('C'); ! 717: else ! 718: { ! 719: if (*p == '^' && p[1] != NULL) ! 720: if (*++p == '?') ! 721: Intr_char = '\177'; ! 722: else ! 723: Intr_char = CNTL(*p); ! 724: else ! 725: Intr_char = *p; ! 726: p++; ! 727: } ! 728: continue; ! 729: # endif ! 730: ! 731: case 'k': /* kill character */ ! 732: if (*p == NULL) ! 733: Kill_char = CNTL('X'); ! 734: else ! 735: { ! 736: if (*p == '^' && p[1] != NULL) ! 737: if (*++p == '?') ! 738: Kill_char = '\177'; ! 739: else ! 740: Kill_char = CNTL(*p); ! 741: else ! 742: Kill_char = *p; ! 743: p++; ! 744: } ! 745: continue; ! 746: ! 747: # ifdef OLDFLAGS ! 748: # ifdef OLDDIALUP ! 749: case 'd': /* dialup type */ ! 750: NewType = DIALUP; ! 751: goto mapold; ! 752: # endif ! 753: ! 754: # ifdef OLDPLUGBOARD ! 755: case 'p': /* plugboard type */ ! 756: NewType = PLUGBOARD; ! 757: goto mapold; ! 758: # endif ! 759: ! 760: # ifdef OLDARPANET ! 761: case 'a': /* arpanet type */ ! 762: Newtype = ARPANET; ! 763: goto mapold; ! 764: # endif ! 765: ! 766: mapold: Map->Ident = NewType; ! 767: Map->Test = ALL; ! 768: if (*p == NULL) ! 769: { ! 770: p = nextarg(argc--, argv++); ! 771: } ! 772: Map->Type = p; ! 773: Map++; ! 774: Mapped = YES; ! 775: p = ""; ! 776: continue; ! 777: # endif ! 778: ! 779: case 'm': /* map identifier to type */ ! 780: /* This code is very loose. Almost no ! 781: ** syntax checking is done!! However, ! 782: ** illegal syntax will only produce ! 783: ** weird results. ! 784: */ ! 785: if (*p == NULL) ! 786: { ! 787: p = nextarg(argc--, argv++); ! 788: } ! 789: if (isalnum(*p)) ! 790: { ! 791: Map->Ident = p; /* identifier */ ! 792: while (isalnum(*p)) p++; ! 793: } ! 794: else ! 795: Map->Ident = ""; ! 796: Break = NO; ! 797: Not = NO; ! 798: while (!Break) switch (*p) ! 799: { ! 800: case NULL: ! 801: p = nextarg(argc--, argv++); ! 802: continue; ! 803: ! 804: case ':': /* mapped type */ ! 805: *p++ = NULL; ! 806: Break = YES; ! 807: continue; ! 808: ! 809: case '>': /* conditional */ ! 810: Map->Test |= GT; ! 811: *p++ = NULL; ! 812: continue; ! 813: ! 814: case '<': /* conditional */ ! 815: Map->Test |= LT; ! 816: *p++ = NULL; ! 817: continue; ! 818: ! 819: case '=': /* conditional */ ! 820: case '@': ! 821: Map->Test |= EQ; ! 822: *p++ = NULL; ! 823: continue; ! 824: ! 825: case '!': /* invert conditions */ ! 826: Not = ~Not; ! 827: *p++ = NULL; ! 828: continue; ! 829: ! 830: case 'B': /* Baud rate */ ! 831: p++; ! 832: /* intentional fallthru */ ! 833: default: ! 834: if (isdigit(*p) || *p == 'e') ! 835: { ! 836: Map->Speed = baudrate(p); ! 837: while (isalnum(*p) || *p == '.') ! 838: p++; ! 839: } ! 840: else ! 841: Break = YES; ! 842: continue; ! 843: } ! 844: if (Not) /* invert sense of test */ ! 845: { ! 846: Map->Test = (~(Map->Test))&ALL; ! 847: } ! 848: if (*p == NULL) ! 849: { ! 850: p = nextarg(argc--, argv++); ! 851: } ! 852: Map->Type = p; ! 853: p = ""; ! 854: Map++; ! 855: Mapped = YES; ! 856: continue; ! 857: ! 858: case 'h': /* don't get type from htmp or env */ ! 859: Dash_h = YES; ! 860: continue; ! 861: ! 862: case 'u': /* don't update htmp */ ! 863: Dash_u = YES; ! 864: continue; ! 865: ! 866: case 's': /* output setenv commands */ ! 867: DoSetenv = YES; ! 868: CmndLine = YES; ! 869: continue; ! 870: ! 871: case 'S': /* output setenv strings */ ! 872: DoSetenv = YES; ! 873: CmndLine = NO; ! 874: continue; ! 875: ! 876: case 'Q': /* be quiet */ ! 877: BeQuiet = YES; ! 878: continue; ! 879: ! 880: case 'I': /* no initialization */ ! 881: NoInit = YES; ! 882: continue; ! 883: ! 884: case 'A': /* Ask user */ ! 885: Ask = YES; ! 886: continue; ! 887: ! 888: case 'v': /* no virtual terminal */ ! 889: DoVirtTerm = NO; ! 890: continue; ! 891: ! 892: default: ! 893: *p-- = NULL; ! 894: fatal("Bad flag -", p); ! 895: } ! 896: } ! 897: else ! 898: { ! 899: /* terminal type */ ! 900: DefType = p; ! 901: } ! 902: } ! 903: ! 904: if (DefType) ! 905: { ! 906: if (Mapped) ! 907: { ! 908: Map->Ident = ""; /* means "map any type" */ ! 909: Map->Test = ALL; /* at all baud rates */ ! 910: Map->Type = DefType; /* to the default type */ ! 911: } ! 912: else ! 913: TtyType = DefType; ! 914: } ! 915: ! 916: # ifndef V6 ! 917: /* ! 918: * Get rid of $TERMCAP, if it's there, so we get a real ! 919: * entry from /etc/termcap. This prevents us from being ! 920: * fooled by out of date stuff in the environment, and ! 921: * makes tabs work right on CB/Unix. ! 922: */ ! 923: bufp = getenv("TERMCAP"); ! 924: if (bufp && *bufp != '/') ! 925: (void) strcpy(bufp-8, "NOTHING"); /* overwrite only "TERMCAP" */ ! 926: /* get current idea of terminal type from environment */ ! 927: if (!Dash_h && TtyType == 0) ! 928: TtyType = getenv("TERM"); ! 929: # endif ! 930: ! 931: /* determine terminal id if needed */ ! 932: # ifdef V6 ! 933: if (Ttyid == NOTTY && (TtyType == 0 || !Dash_h || !Dash_u)) ! 934: Ttyid = ttyn(FILEDES); ! 935: # else ! 936: if (!RepOnly && Ttyid == NOTTY && (TtyType == 0 || !Dash_h)) ! 937: Ttyid = ttyname(FILEDES); ! 938: # endif ! 939: ! 940: # ifdef V6 ! 941: /* get htmp if ever used */ ! 942: if (!Dash_u || (TtyType == 0 && !Dash_h)) ! 943: { ! 944: /* get htmp entry -- if error or wrong user use ttytype */ ! 945: if (Ttyid == NOTTY || hget(Ttyid) < 0 || ! 946: hgettype() == 0 || hgetuid() != (getuid() & UIDMASK)) ! 947: Dash_h++; ! 948: } ! 949: ! 950: /* find terminal type (if not already known) */ ! 951: if (TtyType == 0 && !Dash_h) ! 952: { ! 953: /* get type from /etc/htmp */ ! 954: TtyType = hsgettype(); ! 955: } ! 956: # endif ! 957: ! 958: # ifdef GTTYN ! 959: /* If still undefined, look at /etc/ttytype */ ! 960: if (TtyType == 0) ! 961: { ! 962: TtyType = stypeof(Ttyid); ! 963: } ! 964: # endif ! 965: ! 966: /* If still undefined, use DEFTYPE */ ! 967: if (TtyType == 0) ! 968: { ! 969: TtyType = DEFTYPE; ! 970: } ! 971: ! 972: /* check for dialup or other mapping */ ! 973: if (Mapped) ! 974: { ! 975: if (!(Alias[0] && isalias(TtyType))) ! 976: if (tgetent(Capbuf, TtyType) > 0) ! 977: makealias(Capbuf); ! 978: TtyType = mapped(TtyType); ! 979: } ! 980: ! 981: /* TtyType now contains a pointer to the type of the terminal */ ! 982: /* If the first character is '?', ask the user */ ! 983: if (TtyType[0] == '?') ! 984: { ! 985: Ask = YES; ! 986: TtyType++; ! 987: if (TtyType[0] == '\0') ! 988: TtyType = DEFTYPE; ! 989: } ! 990: if (Ask) ! 991: { ! 992: ask: ! 993: prs("TERM = ("); ! 994: prs(TtyType); ! 995: prs(") "); ! 996: flush(); ! 997: ! 998: /* read the terminal. If not empty, set type */ ! 999: i = read(2, termbuf, sizeof termbuf - 1); ! 1000: if (i > 0) ! 1001: { ! 1002: if (termbuf[i - 1] == '\n') ! 1003: i--; ! 1004: termbuf[i] = '\0'; ! 1005: if (termbuf[0] != '\0') ! 1006: TtyType = termbuf; ! 1007: } ! 1008: } ! 1009: ! 1010: /* get terminal capabilities */ ! 1011: if (!(Alias[0] && isalias(TtyType))) { ! 1012: switch (tgetent(Capbuf, TtyType)) ! 1013: { ! 1014: case -1: ! 1015: prs("Cannot find termcap\n"); ! 1016: flush(); ! 1017: exit(-1); ! 1018: ! 1019: case 0: ! 1020: prs("Type "); ! 1021: prs(TtyType); ! 1022: prs(" unknown\n"); ! 1023: flush(); ! 1024: if (DoSetenv) ! 1025: { ! 1026: TtyType = DEFTYPE; ! 1027: Alias[0] = '\0'; ! 1028: goto ask; ! 1029: } ! 1030: else ! 1031: exit(1); ! 1032: } ! 1033: } ! 1034: Ttycap = Capbuf; ! 1035: ! 1036: if (!RepOnly) ! 1037: { ! 1038: /* determine erase and kill characters */ ! 1039: if (Specialerase && !tgetflag("bs")) ! 1040: Erase_char = 0; ! 1041: bufp = buf; ! 1042: p = tgetstr("kb", &bufp); ! 1043: if (p == NULL || p[1] != '\0') ! 1044: p = tgetstr("bc", &bufp); ! 1045: if (p != NULL && p[1] == '\0') ! 1046: bs_char = p[0]; ! 1047: else if (tgetflag("bs")) ! 1048: bs_char = BACKSPACE; ! 1049: else ! 1050: bs_char = 0; ! 1051: if (Erase_char == 0 && !tgetflag("os") && curerase == OLDERASE) ! 1052: { ! 1053: if (tgetflag("bs") || bs_char != 0) ! 1054: Erase_char = -1; ! 1055: } ! 1056: if (Erase_char < 0) ! 1057: Erase_char = (bs_char != 0) ? bs_char : BACKSPACE; ! 1058: ! 1059: if (curerase == 0) ! 1060: curerase = CERASE; ! 1061: if (Erase_char != 0) ! 1062: curerase = Erase_char; ! 1063: ! 1064: if (curintr == 0) ! 1065: curintr = CINTR; ! 1066: if (Intr_char != 0) ! 1067: curintr = Intr_char; ! 1068: ! 1069: if (curkill == 0) ! 1070: curkill = CKILL; ! 1071: if (Kill_char != 0) ! 1072: curkill = Kill_char; ! 1073: ! 1074: /* set modes */ ! 1075: PadBaud = tgetnum("pb"); /* OK if fails */ ! 1076: for (i=0; speeds[i].string; i++) ! 1077: if (speeds[i].baudrate == PadBaud) { ! 1078: PadBaud = speeds[i].speed; ! 1079: break; ! 1080: } ! 1081: # ifndef USG ! 1082: setdelay("dC", CRdelay, CRbits, &mode.sg_flags); ! 1083: setdelay("dN", NLdelay, NLbits, &mode.sg_flags); ! 1084: setdelay("dB", BSdelay, BSbits, &mode.sg_flags); ! 1085: setdelay("dF", FFdelay, FFbits, &mode.sg_flags); ! 1086: setdelay("dT", TBdelay, TBbits, &mode.sg_flags); ! 1087: if (tgetflag("UC") || (command[0] & 0140) == 0100) ! 1088: mode.sg_flags |= LCASE; ! 1089: else if (tgetflag("LC")) ! 1090: mode.sg_flags &= ~LCASE; ! 1091: mode.sg_flags &= ~(EVENP | ODDP | RAW); ! 1092: # ifdef CBREAK ! 1093: mode.sg_flags &= ~CBREAK; ! 1094: # endif ! 1095: if (tgetflag("EP")) ! 1096: mode.sg_flags |= EVENP; ! 1097: if (tgetflag("OP")) ! 1098: mode.sg_flags |= ODDP; ! 1099: if ((mode.sg_flags & (EVENP | ODDP)) == 0) ! 1100: mode.sg_flags |= EVENP | ODDP; ! 1101: mode.sg_flags |= CRMOD | ECHO | XTABS; ! 1102: if (tgetflag("NL")) /* new line, not line feed */ ! 1103: mode.sg_flags &= ~CRMOD; ! 1104: if (tgetflag("HD")) /* half duplex */ ! 1105: mode.sg_flags &= ~ECHO; ! 1106: if (tgetflag("pt")) /* print tabs */ ! 1107: mode.sg_flags &= ~XTABS; ! 1108: # else ! 1109: setdelay("dC", CRdelay, CRbits, &mode.c_oflag); ! 1110: setdelay("dN", NLdelay, NLbits, &mode.c_oflag); ! 1111: setdelay("dB", BSdelay, BSbits, &mode.c_oflag); ! 1112: setdelay("dF", FFdelay, FFbits, &mode.c_oflag); ! 1113: setdelay("dT", TBdelay, TBbits, &mode.c_oflag); ! 1114: setdelay("dV", VTdelay, VTbits, &mode.c_oflag); ! 1115: ! 1116: if (tgetflag("UC") || (command[0] & 0140) == 0100) { ! 1117: mode.c_iflag |= IUCLC; ! 1118: mode.c_oflag |= OLCUC; ! 1119: } ! 1120: else if (tgetflag("LC")) { ! 1121: mode.c_iflag &= ~IUCLC; ! 1122: mode.c_oflag &= ~OLCUC; ! 1123: } ! 1124: mode.c_iflag &= ~(PARMRK|INPCK); ! 1125: mode.c_lflag |= ICANON; ! 1126: if (tgetflag("EP")) { ! 1127: mode.c_cflag |= PARENB; ! 1128: mode.c_cflag &= ~PARODD; ! 1129: } ! 1130: if (tgetflag("OP")) { ! 1131: mode.c_cflag |= PARENB; ! 1132: mode.c_cflag |= PARODD; ! 1133: } ! 1134: ! 1135: mode.c_oflag |= ONLCR; ! 1136: mode.c_iflag |= ICRNL; ! 1137: mode.c_lflag |= ECHO; ! 1138: mode.c_oflag |= TAB3; ! 1139: if (tgetflag("NL")) { /* new line, not line feed */ ! 1140: mode.c_oflag &= ~ONLCR; ! 1141: mode.c_iflag &= ~ICRNL; ! 1142: } ! 1143: if (tgetflag("HD")) /* half duplex */ ! 1144: mode.c_lflag &= ~ECHO; ! 1145: if (tgetflag("pt")) /* print tabs */ ! 1146: mode.c_oflag &= ~TAB3; ! 1147: ! 1148: mode.c_lflag |= (ECHOE|ECHOK); ! 1149: # endif ! 1150: # ifdef CBVIRTTERM ! 1151: HasAM = tgetflag("am"); ! 1152: # endif CBVIRTTERM ! 1153: # ifdef UCB_NTTY ! 1154: if (ldisc == NTTYDISC) ! 1155: { ! 1156: lmode |= LCTLECH; /* display ctrl chars */ ! 1157: if (tgetflag("hc")) ! 1158: { /** set printer modes **/ ! 1159: lmode &= ~(LCRTBS|LCRTERA|LCRTKIL); ! 1160: lmode |= LPRTERA; ! 1161: } ! 1162: else ! 1163: { /** set crt modes **/ ! 1164: if (!tgetflag("os")) ! 1165: { ! 1166: lmode &= ~LPRTERA; ! 1167: lmode |= LCRTBS; ! 1168: if (mode.sg_ospeed >= B1200) ! 1169: lmode |= LCRTERA|LCRTKIL; ! 1170: } ! 1171: } ! 1172: } ! 1173: if (IsReset) ! 1174: lmode &= ~(LMDMBUF|LLITOUT|LPASS8); ! 1175: (void) ioctl(FILEDES, TIOCLSET, (char *)&lmode); ! 1176: # endif ! 1177: ! 1178: /* get pad character */ ! 1179: bufp = buf; ! 1180: if (tgetstr("pc", &bufp) != 0) ! 1181: PC = buf[0]; ! 1182: ! 1183: columns = tgetnum("co"); ! 1184: lines = tgetnum("li"); ! 1185: ! 1186: /* Set window size */ ! 1187: (void) ioctl(FILEDES, TIOCGWINSZ, (char *)&win); ! 1188: if (win.ws_row == 0 && win.ws_col == 0 && ! 1189: lines > 0 && columns > 0) { ! 1190: win.ws_row = lines; ! 1191: win.ws_col = columns; ! 1192: (void) ioctl(FILEDES, TIOCSWINSZ, (char *)&win); ! 1193: } ! 1194: /* output startup string */ ! 1195: if (!NoInit) ! 1196: { ! 1197: # ifndef USG ! 1198: if (oldmode.sg_flags&(XTABS|CRMOD)) ! 1199: { ! 1200: oldmode.sg_flags &= ~(XTABS|CRMOD); ! 1201: setmode(-1); ! 1202: } ! 1203: # else ! 1204: if (oldmode.c_oflag&(TAB3|ONLCR|OCRNL|ONLRET)) ! 1205: { ! 1206: oldmode.c_oflag &= (TAB3|ONLCR|OCRNL|ONLRET); ! 1207: setmode(-1); ! 1208: } ! 1209: # endif ! 1210: # ifdef CBVIRTTERM ! 1211: block.st_termt = 0; ! 1212: (void) ioctl(FILEDES, LDSETT, (char *)&block); ! 1213: # endif CBVIRTTERM ! 1214: if (settabs()) { ! 1215: settle = YES; ! 1216: flush(); ! 1217: } ! 1218: bufp = buf; ! 1219: if (IsReset && tgetstr("rs", &bufp) != 0 || ! 1220: tgetstr("is", &bufp) != 0) ! 1221: { ! 1222: tputs(buf, 0, prc); ! 1223: settle = YES; ! 1224: flush(); ! 1225: } ! 1226: bufp = buf; ! 1227: if (IsReset && tgetstr("rf", &bufp) != 0 || ! 1228: tgetstr("if", &bufp) != 0) ! 1229: { ! 1230: cat(buf); ! 1231: settle = YES; ! 1232: } ! 1233: if (settle) ! 1234: { ! 1235: prc('\r'); ! 1236: flush(); ! 1237: sleep(1); /* let terminal settle down */ ! 1238: } ! 1239: } ! 1240: ! 1241: # ifdef CBVIRTTERM ! 1242: if (DoVirtTerm) { ! 1243: j = tgetnum("vt"); ! 1244: VirTermNo = -1; ! 1245: for (i=0; vt_map[i].stdnum; i++) ! 1246: if (vt_map[i].stdnum == j) ! 1247: VirTermNo = vt_map[i].localnum; ! 1248: } else ! 1249: VirTermNo = -1; ! 1250: # endif CBVIRTTERM ! 1251: ! 1252: setmode(0); /* set new modes, if they've changed */ ! 1253: ! 1254: /* set up environment for the shell we are using */ ! 1255: /* (this code is rather heuristic, checking for $SHELL */ ! 1256: /* ending in the 3 characters "csh") */ ! 1257: csh = NO; ! 1258: if (DoSetenv) ! 1259: { ! 1260: # ifndef V6 ! 1261: char *sh; ! 1262: ! 1263: if ((sh = getenv("SHELL")) && (i = strlen(sh)) >= 3) ! 1264: { ! 1265: if ((csh = sequal(&sh[i-3], "csh")) && CmndLine) ! 1266: (void) write(STDOUT, "set noglob;\n", 12); ! 1267: } ! 1268: if (!csh) ! 1269: # endif ! 1270: /* running Bourne shell */ ! 1271: (void) write(STDOUT, "export TERMCAP TERM;\n", 21); ! 1272: } ! 1273: } ! 1274: ! 1275: /* report type if appropriate */ ! 1276: if (DoSetenv || Report || Ureport) ! 1277: { ! 1278: /* if type is the short name, find first alias (if any) */ ! 1279: makealias(Ttycap); ! 1280: if (sequal(TtyType, Alias[0]) && Alias[1]) { ! 1281: TtyType = Alias[1]; ! 1282: } ! 1283: ! 1284: if (DoSetenv) ! 1285: { ! 1286: if (csh) ! 1287: { ! 1288: if (CmndLine) ! 1289: (void) write(STDOUT, "setenv TERM ", 12); ! 1290: (void) write(STDOUT, TtyType, strlen(TtyType)); ! 1291: (void) write(STDOUT, " ", 1); ! 1292: if (CmndLine) ! 1293: (void) write(STDOUT, ";\n", 2); ! 1294: } ! 1295: else ! 1296: { ! 1297: (void) write(STDOUT, "TERM=", 5); ! 1298: (void) write(STDOUT, TtyType, strlen(TtyType)); ! 1299: (void) write(STDOUT, ";\n", 2); ! 1300: } ! 1301: } ! 1302: else if (Report) ! 1303: { ! 1304: (void) write(STDOUT, TtyType, strlen(TtyType)); ! 1305: (void) write(STDOUT, "\n", 1); ! 1306: } ! 1307: if (Ureport) ! 1308: { ! 1309: prs("Terminal type is "); ! 1310: prs(TtyType); ! 1311: prs("\n"); ! 1312: flush(); ! 1313: } ! 1314: ! 1315: if (DoSetenv) ! 1316: { ! 1317: if (csh) ! 1318: { ! 1319: if (CmndLine) ! 1320: (void) write(STDOUT, "setenv TERMCAP '", 16); ! 1321: } ! 1322: else ! 1323: (void) write(STDOUT, "TERMCAP='", 9); ! 1324: wrtermcap(Ttycap); ! 1325: if (csh) ! 1326: { ! 1327: if (CmndLine) ! 1328: { ! 1329: (void) write(STDOUT, "';\n", 3); ! 1330: (void) write(STDOUT, "unset noglob;\n", 14); ! 1331: } ! 1332: } ! 1333: else ! 1334: (void) write(STDOUT, "';\n", 3); ! 1335: } ! 1336: } ! 1337: ! 1338: if (RepOnly) ! 1339: exit(0); ! 1340: ! 1341: /* tell about changing erase, kill and interrupt characters */ ! 1342: reportek("Erase", curerase, olderase, OLDERASE); ! 1343: reportek("Kill", curkill, oldkill, OLDKILL); ! 1344: reportek("Interrupt", curintr, oldintr, OLDINTR); ! 1345: ! 1346: # ifdef V6 ! 1347: /* update htmp */ ! 1348: if (!Dash_u) ! 1349: { ! 1350: if (Ttyid == 0) ! 1351: Ttyid = ttyn(FILEDES); ! 1352: if (Ttyid == 'x') ! 1353: { ! 1354: prs("Cannot update htmp\n"); ! 1355: flush(); ! 1356: } ! 1357: else ! 1358: { ! 1359: /* update htmp file only if changed */ ! 1360: if (!bequal(Capbuf, hsgettype(), 2)) ! 1361: { ! 1362: hsettype(Capbuf[0] | (Capbuf[1] << 8)); ! 1363: hput(Ttyid); ! 1364: } ! 1365: } ! 1366: } ! 1367: # endif ! 1368: ! 1369: exit(0); ! 1370: } ! 1371: ! 1372: /* ! 1373: * Set the hardware tabs on the terminal, using the ct (clear all tabs), ! 1374: * st (set one tab) and ch (horizontal cursor addressing) capabilities. ! 1375: * This is done before if and is, so they can patch in case we blow this. ! 1376: */ ! 1377: settabs() ! 1378: { ! 1379: char caps[100]; ! 1380: char *capsp = caps; ! 1381: char *clear_tabs, *set_tab, *set_column, *set_pos; ! 1382: char *tg_out, *tgoto(); ! 1383: int c; ! 1384: ! 1385: clear_tabs = tgetstr("ct", &capsp); ! 1386: set_tab = tgetstr("st", &capsp); ! 1387: set_column = tgetstr("ch", &capsp); ! 1388: if (set_column == 0) ! 1389: set_pos = tgetstr("cm", &capsp); ! 1390: ! 1391: if (clear_tabs && set_tab) { ! 1392: prc('\r'); /* force to be at left margin */ ! 1393: tputs(clear_tabs, 0, prc); ! 1394: } ! 1395: if (set_tab) { ! 1396: for (c=8; c<columns; c += 8) { ! 1397: /* get to that column. */ ! 1398: tg_out = "OOPS"; /* also returned by tgoto */ ! 1399: if (set_column) ! 1400: tg_out = tgoto(set_column, 0, c); ! 1401: if (*tg_out == 'O' && set_pos) ! 1402: tg_out = tgoto(set_pos, c, lines-1); ! 1403: if (*tg_out != 'O') ! 1404: tputs(tg_out, 1, prc); ! 1405: else { ! 1406: prc(' '); prc(' '); prc(' '); prc(' '); ! 1407: prc(' '); prc(' '); prc(' '); prc(' '); ! 1408: } ! 1409: /* set the tab */ ! 1410: tputs(set_tab, 0, prc); ! 1411: } ! 1412: prc('\r'); ! 1413: return 1; ! 1414: } ! 1415: return 0; ! 1416: } ! 1417: ! 1418: setmode(flag) ! 1419: int flag; ! 1420: /* flag serves several purposes: ! 1421: * if called as the result of a signal, flag will be > 0. ! 1422: * if called from terminal init, flag == -1 means reset "oldmode". ! 1423: * called with flag == 0 at end of normal mode processing. ! 1424: */ ! 1425: { ! 1426: # ifndef USG ! 1427: struct sgttyb *ttymode; ! 1428: # else ! 1429: struct termio *ttymode; ! 1430: # endif ! 1431: # ifdef TIOCGETC ! 1432: struct tchars *ttytchars; ! 1433: # endif ! 1434: ! 1435: if (flag < 0) { /* unconditionally reset oldmode (called from init) */ ! 1436: ttymode = &oldmode; ! 1437: # ifdef TIOCGETC ! 1438: ttytchars = &oldtchar; ! 1439: # endif ! 1440: } else if (!bequal((char *)&mode, (char *)&oldmode, sizeof mode)) { ! 1441: ttymode = &mode; ! 1442: # ifdef TIOCGETC ! 1443: ttytchars = &tchar; ! 1444: # endif ! 1445: } else { /* don't need it */ ! 1446: # ifndef USG ! 1447: ttymode = (struct sgttyb *)0; ! 1448: # else ! 1449: ttymode = (struct termio *)0; ! 1450: # endif ! 1451: # ifdef TIOCGETC ! 1452: ttytchars = (struct tchars *)0; ! 1453: # endif ! 1454: } ! 1455: ! 1456: if (ttymode) ! 1457: { ! 1458: # ifdef USG ! 1459: (void) ioctl(FILEDES, TCSETAW, (char *)ttymode); ! 1460: # else ! 1461: # ifndef V6 ! 1462: /* don't flush */ ! 1463: (void) ioctl(FILEDES, TIOCSETN, (char *)ttymode); ! 1464: # else ! 1465: stty(FILEDES, ttymode); ! 1466: # endif ! 1467: # endif ! 1468: } ! 1469: # ifdef TIOCGETC ! 1470: if (ttytchars) { ! 1471: (void) ioctl(FILEDES, TIOCSETC, (char *)ttytchars); ! 1472: } ! 1473: # endif ! 1474: # ifdef CBVIRTTERM ! 1475: if (VirTermNo != -2) { ! 1476: int r1, r2; ! 1477: extern int errno; ! 1478: ! 1479: r1 = ioctl(FILEDES, LDGETT, (char *)&block); ! 1480: block.st_flgs |= TM_SET; ! 1481: block.st_termt = VirTermNo; ! 1482: if (block.st_termt < 0) ! 1483: block.st_termt = 0; ! 1484: if (!HasAM) ! 1485: block.st_flgs |= TM_ANL; ! 1486: else ! 1487: block.st_flgs &= ~TM_ANL; ! 1488: r2 = ioctl(FILEDES, LDSETT, (char *)&block); ! 1489: } ! 1490: # endif ! 1491: ! 1492: if (flag > 0) /* trapped signal */ ! 1493: exit(1); ! 1494: } ! 1495: ! 1496: reportek(name, new, old, def) ! 1497: char *name; ! 1498: char old; ! 1499: char new; ! 1500: char def; ! 1501: { ! 1502: register char o; ! 1503: register char n; ! 1504: register char *p; ! 1505: char buf[32]; ! 1506: char *bufp; ! 1507: ! 1508: if (BeQuiet) ! 1509: return; ! 1510: o = old; ! 1511: n = new; ! 1512: ! 1513: if (o == n && n == def) ! 1514: return; ! 1515: prs(name); ! 1516: if (o == n) ! 1517: prs(" is "); ! 1518: else ! 1519: prs(" set to "); ! 1520: bufp = buf; ! 1521: if (tgetstr("kb", &bufp) > 0 && n == buf[0] && buf[1] == NULL) ! 1522: prs("Backspace\n"); ! 1523: else if (n == 0177) ! 1524: prs("Delete\n"); ! 1525: else ! 1526: { ! 1527: if (n < 040) ! 1528: { ! 1529: prs("Ctrl-"); ! 1530: n ^= 0100; ! 1531: } ! 1532: p = "x\n"; ! 1533: p[0] = n; ! 1534: prs(p); ! 1535: } ! 1536: flush(); ! 1537: } ! 1538: ! 1539: ! 1540: ! 1541: ! 1542: setdelay(cap, dtab, bits, flags) ! 1543: char *cap; ! 1544: struct delay dtab[]; ! 1545: int bits; ! 1546: short *flags; ! 1547: { ! 1548: register int i; ! 1549: register struct delay *p; ! 1550: # ifdef V6 ! 1551: extern int ospeed; ! 1552: # else ! 1553: extern short ospeed; ! 1554: # endif ! 1555: ! 1556: /* see if this capability exists at all */ ! 1557: i = tgetnum(cap); ! 1558: if (i < 0) ! 1559: i = 0; ! 1560: /* No padding at speeds below PadBaud */ ! 1561: if (PadBaud > ospeed) ! 1562: i = 0; ! 1563: ! 1564: /* clear out the bits, replace with new ones */ ! 1565: *flags &= ~bits; ! 1566: ! 1567: /* scan dtab for first entry with adequate delay */ ! 1568: for (p = dtab; p->d_delay >= 0; p++) ! 1569: { ! 1570: if (p->d_delay >= i) ! 1571: { ! 1572: p++; ! 1573: break; ! 1574: } ! 1575: } ! 1576: ! 1577: /* use last entry if none will do */ ! 1578: *flags |= (--p)->d_bits; ! 1579: } ! 1580: ! 1581: ! 1582: prs(s) ! 1583: char *s; ! 1584: { ! 1585: while (*s != '\0') ! 1586: prc(*s++); ! 1587: } ! 1588: ! 1589: ! 1590: char OutBuf[256]; ! 1591: int OutPtr; ! 1592: ! 1593: prc(c) ! 1594: char c; ! 1595: { ! 1596: OutBuf[OutPtr++] = c; ! 1597: if (OutPtr >= sizeof OutBuf) ! 1598: flush(); ! 1599: } ! 1600: ! 1601: flush() ! 1602: { ! 1603: if (OutPtr > 0) ! 1604: (void) write(2, OutBuf, OutPtr); ! 1605: OutPtr = 0; ! 1606: } ! 1607: ! 1608: ! 1609: cat(file) ! 1610: char *file; ! 1611: { ! 1612: register int fd; ! 1613: register int i; ! 1614: char buf[BUFSIZ]; ! 1615: ! 1616: fd = open(file, 0); ! 1617: if (fd < 0) ! 1618: { ! 1619: prs("Cannot open "); ! 1620: prs(file); ! 1621: prs("\n"); ! 1622: flush(); ! 1623: return; ! 1624: } ! 1625: ! 1626: while ((i = read(fd, buf, BUFSIZ)) > 0) ! 1627: (void) write(FILEDES, buf, i); ! 1628: ! 1629: (void) close(fd); ! 1630: } ! 1631: ! 1632: ! 1633: ! 1634: bmove(from, to, length) ! 1635: char *from; ! 1636: char *to; ! 1637: int length; ! 1638: { ! 1639: register char *p, *q; ! 1640: register int i; ! 1641: ! 1642: i = length; ! 1643: p = from; ! 1644: q = to; ! 1645: ! 1646: while (i-- > 0) ! 1647: *q++ = *p++; ! 1648: } ! 1649: ! 1650: ! 1651: ! 1652: bequal(a, b, len) /* must be same thru len chars */ ! 1653: char *a; ! 1654: char *b; ! 1655: int len; ! 1656: { ! 1657: register char *p, *q; ! 1658: register int i; ! 1659: ! 1660: i = len; ! 1661: p = a; ! 1662: q = b; ! 1663: ! 1664: while ((*p == *q) && --i > 0) ! 1665: { ! 1666: p++; q++; ! 1667: } ! 1668: return ((*p == *q) && i >= 0); ! 1669: } ! 1670: ! 1671: sequal(a, b) /* must be same thru NULL */ ! 1672: char *a; ! 1673: char *b; ! 1674: { ! 1675: register char *p = a, *q = b; ! 1676: ! 1677: while (*p && *q && (*p == *q)) ! 1678: { ! 1679: p++; q++; ! 1680: } ! 1681: return (*p == *q); ! 1682: } ! 1683: ! 1684: makealias(buf) ! 1685: char *buf; ! 1686: { ! 1687: register int i; ! 1688: register char *a; ! 1689: register char *b; ! 1690: ! 1691: Alias[0] = a = Aliasbuf; ! 1692: b = buf; ! 1693: i = 1; ! 1694: while (*b && *b != ':') { ! 1695: if (*b == '|') { ! 1696: *a++ = NULL; ! 1697: Alias[i++] = a; ! 1698: b++; ! 1699: } ! 1700: else ! 1701: *a++ = *b++; ! 1702: } ! 1703: *a = NULL; ! 1704: Alias[i] = NULL; ! 1705: # ifdef DEB ! 1706: for(i = 0; Alias[i]; printf("A:%s\n", Alias[i++])); ! 1707: # endif ! 1708: } ! 1709: ! 1710: isalias(ident) /* is ident same as one of the aliases? */ ! 1711: char *ident; ! 1712: { ! 1713: char **a = Alias; ! 1714: ! 1715: if (*a) ! 1716: while (*a) ! 1717: if (sequal(ident, *a)) ! 1718: return(YES); ! 1719: else ! 1720: a++; ! 1721: return(NO); ! 1722: } ! 1723: ! 1724: # ifdef GTTYN ! 1725: char * ! 1726: stypeof(ttyid) ! 1727: char *ttyid; ! 1728: { ! 1729: register char *PortType; ! 1730: register char *TtyId; ! 1731: struct ttyent *t; ! 1732: ! 1733: if (ttyid == NOTTY) ! 1734: return (DEFTYPE); ! 1735: ! 1736: /* split off end of name */ ! 1737: TtyId = ttyid; ! 1738: while (*ttyid) ! 1739: if (*ttyid++ == '/') ! 1740: TtyId = ttyid; ! 1741: ! 1742: /* scan the file */ ! 1743: if ((t = getttynam(TtyId)) != NULL) ! 1744: { ! 1745: PortType = t->ty_type; ! 1746: /* get aliases from termcap entry */ ! 1747: if (Mapped && tgetent(Capbuf, PortType) > 0) { ! 1748: makealias(Capbuf); ! 1749: if (sequal(Alias[0], PortType) && Alias[1]) ! 1750: PortType = Alias[1]; ! 1751: } ! 1752: return (PortType); ! 1753: } ! 1754: return (DEFTYPE); ! 1755: } ! 1756: # endif ! 1757: ! 1758: /* ! 1759: * routine to output the string for the environment TERMCAP variable ! 1760: */ ! 1761: #define WHITE(c) (c == ' ' || c == '\t') ! 1762: char delcap[128][2]; ! 1763: int ncap = 0; ! 1764: ! 1765: wrtermcap(bp) ! 1766: char *bp; ! 1767: { ! 1768: char buf[CAPBUFSIZ]; ! 1769: char *p = buf; ! 1770: char *tp; ! 1771: char *putbuf(); ! 1772: int space, empty; ! 1773: # ifdef CBVIRTTERM ! 1774: register int i; ! 1775: # endif CBVIRTTERM ! 1776: ! 1777: /* discard names with blanks */ ! 1778: /** May not be desireable ? **/ ! 1779: while (*bp && *bp != ':') { ! 1780: if (*bp == '|') { ! 1781: tp = bp+1; ! 1782: space = NO; ! 1783: while (*tp && *tp != '|' && *tp != ':') { ! 1784: space = (space || WHITE(*tp) ); ! 1785: tp++; ! 1786: } ! 1787: if (space) { ! 1788: bp = tp; ! 1789: continue; ! 1790: } ! 1791: } ! 1792: *p++ = *bp++; ! 1793: } ! 1794: /**/ ! 1795: ! 1796: # ifdef CBVIRTTERM ! 1797: if (VirTermNo > 0) { ! 1798: p = putbuf(p, ":am"); /* All virt terms have auto margins */ ! 1799: cancelled("am"); ! 1800: } ! 1801: # endif ! 1802: while (*bp) { ! 1803: switch (*bp) { ! 1804: case ':': /* discard empty, cancelled or dupl fields */ ! 1805: tp = bp+1; ! 1806: empty = YES; ! 1807: while (*tp && *tp != ':') { ! 1808: empty = (empty && WHITE(*tp) ); ! 1809: tp++; ! 1810: } ! 1811: # ifdef CBVIRTTERM ! 1812: /* ! 1813: * Virtual terminals use ic, not im or ei. Turn ! 1814: * any of them into ic - duplicates will be cancelled ! 1815: * below. I assume that terminals needing im+ic+ei ! 1816: * are handled by the kernel. ! 1817: */ ! 1818: if (VirTermNo > 0 && !HasAM && ! 1819: (bp[1]=='i' && bp[2]=='m' || ! 1820: bp[1]=='e' && bp[2]=='i')) { ! 1821: bp[1] = 'i'; ! 1822: bp[2] = 'c'; ! 1823: } ! 1824: if (VirTermNo > 0 && !HasAM && ! 1825: (bp[1]=='c' && bp[2]=='s')) { ! 1826: bp[1] = 'd'; ! 1827: bp[2] = 'l'; ! 1828: /* Also need al, so kludge: */ ! 1829: if (!cancelled("al")) ! 1830: p = putbuf(p, ":al=\033\120"); ! 1831: } ! 1832: # endif CBVIRTTERM ! 1833: if (empty || cancelled(bp+1)) { ! 1834: bp = tp; ! 1835: continue; ! 1836: } ! 1837: # ifdef CBVIRTTERM ! 1838: if (VirTermNo > 0 && !HasAM) ! 1839: for (i = 0; vtab[i].value; i++) { ! 1840: if (vtab[i].cap[0] == bp[1] && ! 1841: vtab[i].cap[1] == bp[2]) { ! 1842: *p++ = *bp++; /* colon */ ! 1843: *p++ = *bp++; /* first char */ ! 1844: *p++ = *bp++; /* second " */ ! 1845: *p++ = *bp++; /* = sign */ ! 1846: p = putbuf(p, vtab[i].value); ! 1847: bp = tp; ! 1848: goto contin; ! 1849: } ! 1850: } ! 1851: # endif CBVIRTTERM ! 1852: break; ! 1853: ! 1854: case ' ': /* no spaces in output */ ! 1855: p = putbuf(p, "\\040"); ! 1856: bp++; ! 1857: continue; ! 1858: ! 1859: case '!': /* the shell thinks this is history */ ! 1860: p = putbuf(p, "\\041"); ! 1861: bp++; ! 1862: continue; ! 1863: ! 1864: case ',': /* the shell thinks this is history */ ! 1865: p = putbuf(p, "\\054"); ! 1866: bp++; ! 1867: continue; ! 1868: ! 1869: case '"': /* no quotes in output */ ! 1870: p = putbuf(p, "\\042"); ! 1871: bp++; ! 1872: continue; ! 1873: ! 1874: case '\'': /* no quotes in output */ ! 1875: p = putbuf(p, "\\047"); ! 1876: bp++; ! 1877: continue; ! 1878: ! 1879: case '`': /* no back quotes in output */ ! 1880: p = putbuf(p, "\\140"); ! 1881: bp++; ! 1882: continue; ! 1883: ! 1884: case '\\': ! 1885: case '^': /* anything following is OK */ ! 1886: *p++ = *bp++; ! 1887: # ifdef CBVIRTTERM ! 1888: if (*bp == 'E' && VirTermNo > 0 && ! 1889: (bp[-3]!='\\'||bp[-2]!='E') && ! 1890: (bp[1]!='\\'||bp[2]!='E')) ! 1891: p = putbuf(p, "E\\"); ! 1892: # endif CBVIRTTERM ! 1893: } ! 1894: *p++ = *bp++; ! 1895: # ifdef CBVIRTTERM ! 1896: contin: ; ! 1897: # endif CBVIRTTERM ! 1898: } ! 1899: *p++ = ':'; /* we skipped the last : with the : lookahead hack */ ! 1900: (void) write (STDOUT, buf, p-buf); ! 1901: } ! 1902: ! 1903: cancelled(cap) ! 1904: char *cap; ! 1905: { ! 1906: register int i; ! 1907: ! 1908: for (i = 0; i < ncap; i++) ! 1909: { ! 1910: if (cap[0] == delcap[i][0] && cap[1] == delcap[i][1]) ! 1911: return (YES); ! 1912: } ! 1913: /* delete a second occurrance of the same capability */ ! 1914: delcap[ncap][0] = cap[0]; ! 1915: delcap[ncap][1] = cap[1]; ! 1916: ncap++; ! 1917: return (cap[2] == '@'); ! 1918: } ! 1919: ! 1920: char * ! 1921: putbuf(ptr, str) ! 1922: char *ptr; ! 1923: char *str; ! 1924: { ! 1925: char buf[20]; ! 1926: ! 1927: while (*str) { ! 1928: switch (*str) { ! 1929: case '\033': ! 1930: ptr = putbuf(ptr, "\\E"); ! 1931: str++; ! 1932: break; ! 1933: default: ! 1934: if (*str <= ' ') { ! 1935: (void) sprintf(buf, "\\%03o", *str); ! 1936: ptr = putbuf(ptr, buf); ! 1937: str++; ! 1938: } else ! 1939: *ptr++ = *str++; ! 1940: } ! 1941: } ! 1942: return (ptr); ! 1943: } ! 1944: ! 1945: ! 1946: baudrate(p) ! 1947: char *p; ! 1948: { ! 1949: char buf[8]; ! 1950: int i = 0; ! 1951: ! 1952: while (i < 7 && (isalnum(*p) || *p == '.')) ! 1953: buf[i++] = *p++; ! 1954: buf[i] = NULL; ! 1955: for (i=0; speeds[i].string; i++) ! 1956: if (sequal(speeds[i].string, buf)) ! 1957: return (speeds[i].speed); ! 1958: return (-1); ! 1959: } ! 1960: ! 1961: char * ! 1962: mapped(type) ! 1963: char *type; ! 1964: { ! 1965: # ifdef V6 ! 1966: extern int ospeed; ! 1967: # else ! 1968: extern short ospeed; ! 1969: # endif ! 1970: int match; ! 1971: ! 1972: # ifdef DEB ! 1973: printf ("spd:%d\n", ospeed); ! 1974: prmap(); ! 1975: # endif ! 1976: Map = map; ! 1977: while (Map->Ident) ! 1978: { ! 1979: if (*(Map->Ident) == NULL || sequal(Map->Ident, type) || isalias(Map->Ident)) ! 1980: { ! 1981: match = NO; ! 1982: switch (Map->Test) ! 1983: { ! 1984: case ANY: /* no test specified */ ! 1985: case ALL: ! 1986: match = YES; ! 1987: break; ! 1988: ! 1989: case GT: ! 1990: match = (ospeed > Map->Speed); ! 1991: break; ! 1992: ! 1993: case GE: ! 1994: match = (ospeed >= Map->Speed); ! 1995: break; ! 1996: ! 1997: case EQ: ! 1998: match = (ospeed == Map->Speed); ! 1999: break; ! 2000: ! 2001: case LE: ! 2002: match = (ospeed <= Map->Speed); ! 2003: break; ! 2004: ! 2005: case LT: ! 2006: match = (ospeed < Map->Speed); ! 2007: break; ! 2008: ! 2009: case NE: ! 2010: match = (ospeed != Map->Speed); ! 2011: break; ! 2012: } ! 2013: if (match) ! 2014: return (Map->Type); ! 2015: } ! 2016: Map++; ! 2017: } ! 2018: /* no match found; return given type */ ! 2019: return (type); ! 2020: } ! 2021: ! 2022: # ifdef DEB ! 2023: prmap() ! 2024: { ! 2025: Map = map; ! 2026: while (Map->Ident) ! 2027: { ! 2028: printf ("%s t:%d s:%d %s\n", ! 2029: Map->Ident, Map->Test, Map->Speed, Map->Type); ! 2030: Map++; ! 2031: } ! 2032: } ! 2033: # endif ! 2034: ! 2035: char * ! 2036: nextarg(argc, argv) ! 2037: int argc; ! 2038: char *argv[]; ! 2039: { ! 2040: if (argc <= 0) ! 2041: fatal ("Too few args: ", *argv); ! 2042: if (*(*++argv) == '-') ! 2043: fatal ("Unexpected arg: ", *argv); ! 2044: return (*argv); ! 2045: } ! 2046: ! 2047: fatal (mesg, obj) ! 2048: char *mesg; ! 2049: char *obj; ! 2050: { ! 2051: prs (mesg); ! 2052: prs (obj); ! 2053: prc ('\n'); ! 2054: prs (USAGE); ! 2055: flush(); ! 2056: exit(1); ! 2057: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.