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