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