Annotation of 42BSD/ucb/tset/tset.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.