Annotation of 41BSD/cmd/tset/tset.c, revision 1.1

1.1     ! root        1: /*
        !             2: # define DEB
        !             3: /*
        !             4: **  TSET -- set terminal modes
        !             5: **
        !             6: **     This program does sophisticated terminal initialization.
        !             7: **     I recommend that you include it in your .start_up or .login
        !             8: **     file to initialize whatever terminal you are on.
        !             9: **
        !            10: **     There are several features:
        !            11: **
        !            12: **     A special file or sequence (as controlled by the ttycap file)
        !            13: **     is sent to the terminal.
        !            14: **
        !            15: **     Mode bits are set on a per-terminal_type basis (much better
        !            16: **     than UNIX itself).  This allows special delays, automatic
        !            17: **     tabs, etc.
        !            18: **
        !            19: **     Erase and Kill characters can be set to whatever you want.
        !            20: **     Default is to change erase to control-H on a terminal which
        !            21: **     can overstrike, and leave it alone on anything else.  Kill
        !            22: **     is always left alone unless specifically requested.  These
        !            23: **     characters can be represented as "^X" meaning control-X;
        !            24: **     X is any character.
        !            25: **
        !            26: **     Terminals which are dialups or plugboard types can be aliased
        !            27: **     to whatever type you may have in your home or office.  Thus,
        !            28: **     if you know that when you dial up you will always be on a
        !            29: **     TI 733, you can specify that fact to tset.  You can represent
        !            30: **     a type as "?type".  This will ask you what type you want it
        !            31: **     to be -- if you reply with just a newline, it will default
        !            32: **     to the type given.
        !            33: **
        !            34: **     The htmp file, used by ex, etc., can be updated.
        !            35: **
        !            36: **     The current terminal type can be queried.
        !            37: **
        !            38: **     Usage:
        !            39: **             tset [-] [-EC] [-eC] [-kC] [-s] [-h] [-u] [-r]
        !            40: **                     [-m [ident] [test baudrate] :type]
        !            41: **                     [-Q] [-I] [-S] [type]
        !            42: **
        !            43: **             In systems with environments, use:
        !            44: **                     `tset -s ...`
        !            45: **             Actually, this doesn't work because of a shell bug.
        !            46: **             Instead, use:
        !            47: **                     tset -s ... > tset.tmp
        !            48: **                     source tset.tmp
        !            49: **                     rm tset.tmp
        !            50: **             or:
        !            51: **                     set noglob
        !            52: **                     set term=(`tset -S ....`)
        !            53: **                     setenv TERM $term[1]
        !            54: **                     setenv TERMCAP "$term[2]"
        !            55: **                     unset term
        !            56: **                     unset noglob
        !            57: **
        !            58: **     Positional Parameters:
        !            59: **             type -- the terminal type to force.  If this is
        !            60: **                     specified, initialization is for this
        !            61: **                     terminal type.
        !            62: **
        !            63: **     Flags:
        !            64: **             - -- report terminal type.  Whatever type is
        !            65: **                     decided on is reported.  If no other flags
        !            66: **                     are stated, the only affect is to write
        !            67: **                     the terminal type on the standard output.
        !            68: **             -r -- report to user in addition to other flags.
        !            69: **             -EC -- set the erase character to C on all terminals
        !            70: **                     except those which cannot backspace (e.g.,
        !            71: **                     a TTY 33).  C defaults to control-H.
        !            72: **             -eC -- set the erase character to C on all terminals.
        !            73: **                     C defaults to control-H.  If neither -E or -e
        !            74: **                     are specified, the erase character is set to
        !            75: **                     control-H if the terminal can both backspace
        !            76: **                     and not overstrike (e.g., a CRT).  If the erase
        !            77: **                     character is NULL (zero byte), it will be reset
        !            78: **                     to '#' if nothing else is specified.
        !            79: **             -kC -- set the kill character to C on all terminals.
        !            80: **                     Default for C is control-X.  If not specified,
        !            81: **                     the kill character is untouched; however, if
        !            82: **                     not specified and the kill character is NULL
        !            83: **                     (zero byte), the kill character is set to '@'.
        !            84: **             -iC -- reserved for setable interrupt character.
        !            85: **             -qC -- reserved for setable quit character.
        !            86: **             -m -- map the system identified type to some user
        !            87: **                     specified type. The mapping can be baud rate
        !            88: **                     dependent. This replaces the old -d, -p flags.
        !            89: **                     (-d type  ->  -m dialup:type)
        !            90: **                     (-p type  ->  -m plug:type)
        !            91: **                     Syntax: -m identifier [test baudrate] :type
        !            92: **                     where: ``identifier'' is whatever is found in
        !            93: **                     /etc/ttytype for this port, (abscence of an identifier
        !            94: **                     matches any identifier); ``test'' may be any combination
        !            95: **                     of  >  =  <  !  @; ``baudrate'' is as with stty(1);
        !            96: **                     ``type'' is the actual terminal type to use if the
        !            97: **                     mapping condition is met. Multiple maps are scanned
        !            98: **                     in order and the first match prevails.
        !            99: **             -h -- don't read htmp file.  Normally the terminal type
        !           100: **                     is determined by reading the htmp file or the
        !           101: **                     environment (unless some mapping is specified).
        !           102: **                     This forces a read of the ttytype file -- useful
        !           103: **                     when htmp is somehow wrong.
        !           104: **             -u -- don't update htmp.  It seemed like this should
        !           105: **                     be put in.  Note that htmp is never actually
        !           106: **                     written if there are no changes, so don't bother
        !           107: **                     bother using this for efficiency reasons alone.
        !           108: **             -s -- output setenv commands for TERM.  This can be
        !           109: **                     used with
        !           110: **                             `tset -s ...`
        !           111: **                     and is to be prefered to:
        !           112: **                             setenv TERM `tset - ...`
        !           113: **                     because -s sets the TERMCAP variable also.
        !           114: **             -S -- Similar to -s but outputs 2 strings suitable for
        !           115: **                     use in csh .login files as follows:
        !           116: **                             set noglob
        !           117: **                             set term=(`tset -S .....`)
        !           118: **                             setenv TERM $term[1]
        !           119: **                             setenv TERMCAP "$term[2]"
        !           120: **                             unset term
        !           121: **                             unset noglob
        !           122: **             -Q -- be quiet.  don't output 'Erase set to' etc.
        !           123: **             -I -- don't do terminal initialization (is & if
        !           124: **                     strings).
        !           125: **
        !           126: **     Files:
        !           127: **             /etc/ttytype
        !           128: **                     contains a terminal id -> terminal type
        !           129: **                     mapping; used when any user mapping is specified,
        !           130: **                     or the environment doesn't have TERM set.
        !           131: **             /etc/termcap
        !           132: **                     a terminal_type -> terminal_capabilities
        !           133: **                     mapping.
        !           134: **
        !           135: **     Return Codes:
        !           136: **             -1 -- couldn't open ttycap.
        !           137: **             1 -- bad terminal type, or standard output not tty.
        !           138: **             0 -- ok.
        !           139: **
        !           140: **     Defined Constants:
        !           141: **             DIALUP -- the type code for a dialup port
        !           142: **             PLUGBOARD -- the code for a plugboard port.
        !           143: **             ARPANET -- the code for an arpanet port.
        !           144: **             BACKSPACE -- control-H, the default for -e.
        !           145: **             CONTROLX -- control-X, the default for -k.
        !           146: **             OLDERASE -- the system default erase character.
        !           147: **             OLDKILL -- the system default kill character.
        !           148: **             FILEDES -- the file descriptor to do the operation
        !           149: **                     on, nominally 1 or 2.
        !           150: **             STDOUT -- the standard output file descriptor.
        !           151: **             UIDMASK -- the bit pattern to mask with the getuid()
        !           152: **                     call to get just the user id.
        !           153: **             GTTYN -- defines file containing generalized ttynames
        !           154: **                     and compiles code to look there.
        !           155: **
        !           156: **     Requires:
        !           157: **             Routines to handle htmp, ttytype, and ttycap.
        !           158: **
        !           159: **     Compilation Flags:
        !           160: **             OLDDIALUP -- accept the -d flag. Map "sd" to "dialup".
        !           161: **             OLDPLUGBOARD -- accept the -p flag. Map "sp" to "plugboard".
        !           162: **             OLDARPANET -- accept the -a flag. Map "sa" to "arpanet".
        !           163: **             OLDFLAGS -- must be defined to compile code for any of
        !           164: **                     the -d, -p, or -a flags.
        !           165: **             FULLLOGIN -- if defined, login sets the ttytype from
        !           166: **                     /etc/ttytype file.
        !           167: **             V6 -- if clear, use environments, not htmp.
        !           168: **                     also use TIOCSETN rather than stty to avoid flushing
        !           169: **             GTTYN -- if set, compiles code to look at /etc/ttytype.
        !           170: **
        !           171: **     Trace Flags:
        !           172: **             none
        !           173: **
        !           174: **     Diagnostics:
        !           175: **             Bad flag
        !           176: **                     An incorrect option was specified.
        !           177: **             Too few args
        !           178: **                     more command line arguments are required.
        !           179: **             Unexpected arg
        !           180: **                     wrong type of argument was encountered.
        !           181: **             Cannot open ...
        !           182: **                     The specified file could not be openned.
        !           183: **             Type ... unknown
        !           184: **                     An unknown terminal type was specified.
        !           185: **             Cannot update htmp
        !           186: **                     Cannot update htmp file when the standard
        !           187: **                     output is not a terminal.
        !           188: **             Erase set to ...
        !           189: **                     Telling that the erase character has been
        !           190: **                     set to the specified character.
        !           191: **             Kill set to ...
        !           192: **                     Ditto for kill
        !           193: **             Erase is ...    Kill is ...
        !           194: **                     Tells that the erase/kill characters were
        !           195: **                     wierd before, but they are being left as-is.
        !           196: **             Not a terminal
        !           197: **                     Set if FILEDES is not a terminal.
        !           198: **
        !           199: **     Compilation Instructions:
        !           200: **             cc -n -O tset.c -ltermlib
        !           201: **             mv a.out tset
        !           202: **             chown bin tset
        !           203: **             chmod 4755 tset
        !           204: **
        !           205: **             where 'bin' should be whoever owns the 'htmp' file.
        !           206: **             If 'htmp' is 666, then tset need not be setuid.
        !           207: **
        !           208: **     Author:
        !           209: **             Eric Allman
        !           210: **             Electronics Research Labs
        !           211: **             U.C. Berkeley
        !           212: **
        !           213: **     History:
        !           214: **             7/80 -- '-S' added. -m mapping added. TERMCAP string
        !           215: **                     cleaned up.
        !           216: **             3/80 -- Changed to use tputs.  Prc & flush added.
        !           217: **             10/79 -- '-s' option extended to handle TERMCAP
        !           218: **                     variable, set noglob, quote the entry,
        !           219: **                     and know about the Bourne shell.  Terminal
        !           220: **                     initialization moved to before any information
        !           221: **                     output so screen clears would not screw you.
        !           222: **                     '-Q' option added.
        !           223: **             8/79 -- '-' option alone changed to only output
        !           224: **                     type.  '-s' option added.  'VERSION7'
        !           225: **                     changed to 'V6' for compatibility.
        !           226: **             12/78 -- modified for eventual migration to VAX/UNIX,
        !           227: **                     so the '-' option is changed to output only
        !           228: **                     the terminal type to STDOUT instead of
        !           229: **                     FILEDES.  FULLLOGIN flag added.
        !           230: **             9/78 -- '-' and '-p' options added (now fully
        !           231: **                     compatible with ttytype!), and spaces are
        !           232: **                     permitted between the -d and the type.
        !           233: **             8/78 -- The sense of -h and -u were reversed, and the
        !           234: **                     -f flag is dropped -- same effect is available
        !           235: **                     by just stating the terminal type.
        !           236: **             10/77 -- Written.
        !           237: */
        !           238: 
        !           239: /*
        !           240: # define       FULLLOGIN       1
        !           241: */
        !           242: # ifndef V6
        !           243: # define       GTTYN           "/etc/ttytype"
        !           244: # endif
        !           245: 
        !           246: # include      <ctype.h>
        !           247: # include      <sgtty.h>
        !           248: # include      <stdio.h>
        !           249: 
        !           250: # define       BACKSPACE       ('H' & 037)
        !           251: # define       CONTROLX        ('X' & 037)
        !           252: # define       OLDERASE        '#'
        !           253: # define       OLDKILL         '@'
        !           254: 
        !           255: # define       FILEDES         2
        !           256: # define       STDOUT          1
        !           257: 
        !           258: # ifdef V6
        !           259: # define       UIDMASK         0377
        !           260: # else
        !           261: # define       UIDMASK         -1
        !           262: # endif
        !           263: 
        !           264: # define       DEFTYPE         "unknown"
        !           265: # define       USAGE\
        !           266: "usage: tset [-] [-hrsuIQS] [-eC] [-kC] [-m [ident][test speed]:type] [type]\n"
        !           267: 
        !           268: # define       DIALUP          "dialup"
        !           269: # define       OLDDIALUP       "sd"
        !           270: # define       PLUGBOARD       "plugboard"
        !           271: # define       OLDPLUGBOARD    "sp"
        !           272: /***
        !           273: # define       ARPANET         "arpanet"
        !           274: # define       OLDARPANET      "sa"
        !           275: ***/
        !           276: # define       OLDFLAGS
        !           277: 
        !           278: 
        !           279: 
        !           280: # ifdef GTTYN
        !           281: typedef char   *ttyid_t;
        !           282: # define       NOTTY           0
        !           283: # else
        !           284: typedef char   ttyid_t;
        !           285: # define       NOTTY           'x'
        !           286: # endif
        !           287: 
        !           288: /*
        !           289:  * Baud Rate Conditionals
        !           290:  */
        !           291: # define       ANY             0
        !           292: # define       GT              1
        !           293: # define       EQ              2
        !           294: # define       LT              4
        !           295: # define       GE              (GT|EQ)
        !           296: # define       LE              (LT|EQ)
        !           297: # define       NE              (GT|LT)
        !           298: # define       ALL             (GT|EQ|LT)
        !           299: 
        !           300: 
        !           301: 
        !           302: # define       NMAP            10
        !           303: 
        !           304: struct map {
        !           305:        char *Ident;
        !           306:        char Test;
        !           307:        char Speed;
        !           308:        char *Type;
        !           309: } map[NMAP];
        !           310: 
        !           311: struct map *Map = map;
        !           312: 
        !           313: struct
        !           314: {
        !           315:        char    *string;
        !           316:        int     speed;
        !           317: } speeds[] = {
        !           318:        "0",    B0,
        !           319:        "50",   B50,
        !           320:        "75",   B75,
        !           321:        "110",  B110,
        !           322:        "134",  B134,
        !           323:        "134.5",B134,
        !           324:        "150",  B150,
        !           325:        "200",  B200,
        !           326:        "300",  B300,
        !           327:        "600",  B600,
        !           328:        "1200", B1200,
        !           329:        "1800", B1800,
        !           330:        "2400", B2400,
        !           331:        "4800", B4800,
        !           332:        "9600", B9600,
        !           333:        "exta", EXTA,
        !           334:        "extb", EXTB,
        !           335:        0,
        !           336: };
        !           337: 
        !           338: char   Erase_char;             /* new erase character */
        !           339: char   Kill_char;              /* new kill character */
        !           340: char   Specialerase;           /* set => Erase_char only on terminals with backspace */
        !           341: 
        !           342: ttyid_t        Ttyid = NOTTY;          /* terminal identifier */
        !           343: char   *TtyType;               /* type of terminal */
        !           344: char   *DefType;               /* default type if none other computed */
        !           345: char   *NewType;               /* mapping identifier based on old flags */
        !           346: int    Dash_u;                 /* don't update htmp */
        !           347: int    Dash_h;                 /* don't read htmp */
        !           348: int    DoSetenv;               /* output setenv commands */
        !           349: int    BeQuiet;                /* be quiet */
        !           350: int    NoInit;                 /* don't output initialization string */
        !           351: int    Report;                 /* report current type */
        !           352: int    Ureport;                /* report to user */
        !           353: int    RepOnly;                /* report only */
        !           354: int    CmndLine;               /* output full command lines (-s option) */
        !           355: int    Ask;                    /* ask user for termtype */
        !           356: 
        !           357: # define CAPBUFSIZ     1024
        !           358: char   Capbuf[CAPBUFSIZ];      /* line from /etc/termcap for this TtyType */
        !           359: char   *Ttycap;                /* termcap line from termcap or environ */
        !           360: 
        !           361: struct delay
        !           362: {
        !           363:        int     d_delay;
        !           364:        int     d_bits;
        !           365: };
        !           366: 
        !           367: # include      "tset.delays.h"
        !           368: 
        !           369: 
        !           370: 
        !           371: main(argc, argv)
        !           372: int    argc;
        !           373: char   *argv[];
        !           374: {
        !           375:        struct sgttyb   mode;
        !           376:        struct sgttyb   oldmode;
        !           377:        char            buf[256];
        !           378:        auto char       *bufp;
        !           379:        register char   *p;
        !           380:        char            *command;
        !           381:        register int    i;
        !           382:        int             Break;
        !           383:        int             Not;
        !           384:        int             Mapped;
        !           385:        extern char     *nextarg();
        !           386:        extern char     *mapped();
        !           387: # ifdef V6
        !           388:        extern char     *hsgettype();
        !           389: # else
        !           390:        extern char     *getenv();
        !           391: # endif
        !           392: # ifdef GTTYN
        !           393:        extern char     *stypeof();
        !           394:        extern char     *ttyname();
        !           395:        extern char     *tgetstr();
        !           396: # endif
        !           397:        char            bs_char;
        !           398:        int             csh;
        !           399:        extern          prc();
        !           400:        extern char     PC;
        !           401:        extern short    ospeed;
        !           402: 
        !           403:        if (gtty(FILEDES, &mode) < 0)
        !           404:        {
        !           405:                prs("Not a terminal\n");
        !           406:                exit(1);
        !           407:        }
        !           408:        bmove(&mode, &oldmode, sizeof mode);
        !           409:        ospeed = mode.sg_ospeed;
        !           410: 
        !           411:        /* scan argument list and collect flags */
        !           412:        command = argv[0];
        !           413:        if (argc == 2 && argv[1][0] == '-' && argv[1][1] == '\0')
        !           414:        {
        !           415:                RepOnly++;
        !           416:                Dash_u++;
        !           417:        }
        !           418:        argc--;
        !           419:        while (--argc >= 0)
        !           420:        {
        !           421:                p = *++argv;
        !           422:                if (*p == '-')
        !           423:                {
        !           424:                        if (*++p == NULL)
        !           425:                                Report++; /* report current terminal type */
        !           426:                        else while (*p) switch (*p++)
        !           427:                        {
        !           428: 
        !           429:                          case 'r':     /* report to user */
        !           430:                                Ureport++;
        !           431:                                continue;
        !           432: 
        !           433:                          case 'E':     /* special erase: operate on all but TTY33 */
        !           434:                                Specialerase++;
        !           435:                                /* explicit fall-through to -e case */
        !           436: 
        !           437:                          case 'e':     /* erase character */
        !           438:                                if (*p == NULL)
        !           439:                                        Erase_char = -1;
        !           440:                                else
        !           441:                                {
        !           442:                                        if (*p == '^' && p[1] != NULL)
        !           443:                                                Erase_char = *++p & 037;
        !           444:                                        else
        !           445:                                                Erase_char = *p;
        !           446:                                        p++;
        !           447:                                }
        !           448:                                continue;
        !           449: 
        !           450:                          case 'k':     /* kill character */
        !           451:                                if (*p == NULL)
        !           452:                                        Kill_char = CONTROLX;
        !           453:                                else
        !           454:                                {
        !           455:                                        if (*p == '^' && p[1] != NULL)
        !           456:                                                Kill_char = *++p & 037;
        !           457:                                        else
        !           458:                                                Kill_char = *p;
        !           459:                                        p++;
        !           460:                                }
        !           461:                                continue;
        !           462: 
        !           463: # ifdef OLDFLAGS
        !           464: # ifdef        OLDDIALUP
        !           465:                          case 'd':     /* dialup type */
        !           466:                                NewType = DIALUP;
        !           467:                                goto mapold;
        !           468: # endif
        !           469: 
        !           470: # ifdef OLDPLUGBOARD
        !           471:                          case 'p':     /* plugboard type */
        !           472:                                NewType = PLUGBOARD;
        !           473:                                goto mapold;
        !           474: # endif
        !           475: 
        !           476: # ifdef OLDARPANET
        !           477:                          case 'a':     /* arpanet type */
        !           478:                                Newtype = ARPANET;
        !           479:                                goto mapold;
        !           480: # endif
        !           481: 
        !           482: mapold:                                Map->Ident = NewType;
        !           483:                                Map->Test = ALL;
        !           484:                                if (*p == NULL)
        !           485:                                {
        !           486:                                        p = nextarg(argc--, argv++);
        !           487:                                }
        !           488:                                Map->Type = p;
        !           489:                                Map++;
        !           490:                                Mapped++;
        !           491:                                p = "";
        !           492:                                continue;
        !           493: # endif
        !           494: 
        !           495:                          case 'm':     /* map identifier to type */
        !           496:                                /* This code is very loose. Almost no
        !           497:                                ** syntax checking is done!! However,
        !           498:                                ** illegal syntax will only produce
        !           499:                                ** weird results.
        !           500:                                */
        !           501:                                if (*p == NULL)
        !           502:                                {
        !           503:                                        p = nextarg(argc--, argv++);
        !           504:                                }
        !           505:                                if (isalnum(*p))
        !           506:                                {
        !           507:                                        Map->Ident = p; /* identifier */
        !           508:                                        while (isalnum(*p)) p++;
        !           509:                                }
        !           510:                                else
        !           511:                                        Map->Ident = "";
        !           512:                                Break = 0;
        !           513:                                Not = 0;
        !           514:                                while (!Break) switch (*p)
        !           515:                                {
        !           516:                                        case NULL:
        !           517:                                                p = nextarg(argc--, argv++);
        !           518:                                                continue;
        !           519: 
        !           520:                                        case ':':       /* mapped type */
        !           521:                                                *p++ = NULL;
        !           522:                                                Break++;
        !           523:                                                continue;
        !           524: 
        !           525:                                        case '>':       /* conditional */
        !           526:                                                Map->Test |= GT;
        !           527:                                                *p++ = NULL;
        !           528:                                                continue;
        !           529: 
        !           530:                                        case '<':       /* conditional */
        !           531:                                                Map->Test |= LT;
        !           532:                                                *p++ = NULL;
        !           533:                                                continue;
        !           534: 
        !           535:                                        case '=':       /* conditional */
        !           536:                                        case '@':
        !           537:                                                Map->Test |= EQ;
        !           538:                                                *p++ = NULL;
        !           539:                                                continue;
        !           540:                                        
        !           541:                                        case '!':       /* invert conditions */
        !           542:                                                Not = ~Not;
        !           543:                                                *p++ = NULL;
        !           544:                                                continue;
        !           545: 
        !           546:                                        case 'B':       /* Baud rate */
        !           547:                                                p++;
        !           548:                                                /* intentional fallthru */
        !           549:                                        default:
        !           550:                                                if (isdigit(*p) || *p == 'e')
        !           551:                                                {
        !           552:                                                        Map->Speed = baudrate(p);
        !           553:                                                        while (isalnum(*p) || *p == '.')
        !           554:                                                                p++;
        !           555:                                                }
        !           556:                                                else
        !           557:                                                        Break++;
        !           558:                                                continue;
        !           559:                                }
        !           560:                                if (Not)        /* invert sense of test */
        !           561:                                {
        !           562:                                        Map->Test = (~(Map->Test))&ALL;
        !           563:                                }
        !           564:                                if (*p == NULL)
        !           565:                                {
        !           566:                                        p = nextarg(argc--, argv++);
        !           567:                                }
        !           568:                                Map->Type = p;
        !           569:                                p = "";
        !           570:                                Map++;
        !           571:                                Mapped++;
        !           572:                                continue;
        !           573: 
        !           574:                          case 'h':     /* don't get type from htmp or env */
        !           575:                                Dash_h++;
        !           576:                                continue;
        !           577: 
        !           578:                          case 'u':     /* don't update htmp */
        !           579:                                Dash_u++;
        !           580:                                continue;
        !           581: 
        !           582:                          case 's':     /* output setenv commands */
        !           583:                                DoSetenv++;
        !           584:                                CmndLine++;
        !           585:                                continue;
        !           586: 
        !           587:                          case 'S':     /* output setenv strings */
        !           588:                                DoSetenv++;
        !           589:                                CmndLine=0;
        !           590:                                continue;
        !           591: 
        !           592:                          case 'Q':     /* be quiet */
        !           593:                                BeQuiet++;
        !           594:                                continue;
        !           595: 
        !           596:                          case 'I':     /* no initialization */
        !           597:                                NoInit++;
        !           598:                                continue;
        !           599: 
        !           600:                          case 'A':     /* Ask user */
        !           601:                                Ask++;
        !           602:                                continue;
        !           603: 
        !           604:                          default:
        !           605:                                *p-- = NULL;
        !           606:                                fatal("Bad flag -", p);
        !           607:                        }
        !           608:                }
        !           609:                else
        !           610:                {
        !           611:                        /* terminal type */
        !           612:                        DefType = p;
        !           613:                }
        !           614:        }
        !           615: 
        !           616:        if (DefType)
        !           617:        {
        !           618:                if (Mapped)
        !           619:                {
        !           620:                        Map->Ident = "";        /* means "map any type" */
        !           621:                        Map->Test = ALL;        /* at all baud rates */
        !           622:                        Map->Type = DefType;    /* to the default type */
        !           623:                }
        !           624:                else
        !           625:                        TtyType = DefType;
        !           626:        }
        !           627: 
        !           628: # ifndef V6
        !           629:        /* get current idea of terminal type from environment */
        !           630:        if (!Dash_h && !Mapped && TtyType == 0)
        !           631:                TtyType = getenv("TERM");
        !           632: # endif
        !           633: 
        !           634:        /* determine terminal id if needed */
        !           635: # ifdef V6
        !           636:        if (Ttyid == NOTTY && (TtyType == 0 || !Dash_h || !Dash_u))
        !           637:                Ttyid = ttyn(FILEDES);
        !           638: # else
        !           639:        if (!RepOnly && Ttyid == NOTTY && (TtyType == 0 || !Dash_h))
        !           640:                Ttyid = ttyname(FILEDES);
        !           641: # endif
        !           642: 
        !           643: # ifdef V6
        !           644:        /* get htmp if ever used */
        !           645:        if (!Dash_u || (TtyType == 0 && !Dash_h))
        !           646:        {
        !           647:                /* get htmp entry -- if error or wrong user use ttytype */
        !           648:                if (Ttyid == NOTTY || hget(Ttyid) < 0 ||
        !           649:                    hgettype() == 0 || hgetuid() != (getuid() & UIDMASK))
        !           650:                        Dash_h++;
        !           651:        }
        !           652: 
        !           653:        /* find terminal type (if not already known) */
        !           654:        if (TtyType == 0 && !Dash_h)
        !           655:        {
        !           656:                /* get type from /etc/htmp */
        !           657:                TtyType = hsgettype();
        !           658:        }
        !           659: # endif
        !           660: 
        !           661: # ifdef GTTYN
        !           662:        /* If still undefined, look at /etc/ttytype */
        !           663:        if (TtyType == 0)
        !           664:        {
        !           665:                TtyType = stypeof(Ttyid);
        !           666:        }
        !           667: # endif
        !           668: 
        !           669:        /* If still undefined, use DEFTYPE */
        !           670:        if (TtyType == 0)
        !           671:        {
        !           672:                TtyType = DEFTYPE;
        !           673:        }
        !           674: 
        !           675:        /* check for dialup or other mapping */
        !           676:        if (Mapped)
        !           677:                TtyType = mapped(TtyType, ospeed);
        !           678: 
        !           679:        /* TtyType now contains a pointer to the type of the terminal */
        !           680:        /* If the first character is '?', ask the user */
        !           681:        if (TtyType[0] == '?')
        !           682:        {
        !           683:                Ask++;
        !           684:                TtyType++;
        !           685:                if (TtyType[0] == '\0')
        !           686:                        TtyType = DEFTYPE;
        !           687:        }
        !           688:        if (Ask)
        !           689:        {
        !           690:                prs("TERM = (");
        !           691:                prs(TtyType);
        !           692:                prs(") ");
        !           693:                flush();
        !           694: 
        !           695:                /* read the terminal.  If not empty, set type */
        !           696:                i = read(2, buf, sizeof buf - 1);
        !           697:                if (i >= 0)
        !           698:                {
        !           699:                        if (buf[i - 1] == '\n')
        !           700:                                i--;
        !           701:                        buf[i] = '\0';
        !           702:                        if (buf[0] != '\0')
        !           703:                                TtyType = buf;
        !           704:                }
        !           705:        }
        !           706: 
        !           707:        if (Ttycap == 0)
        !           708:        {
        !           709:                /* get terminal capabilities */
        !           710:                switch (tgetent(Capbuf, TtyType))
        !           711:                {
        !           712:                  case -1:
        !           713:                        prs("Cannot open termcap file\n");
        !           714:                        flush();
        !           715:                        exit(-1);
        !           716: 
        !           717:                  case 0:
        !           718:                        prs("Type ");
        !           719:                        prs(TtyType);
        !           720:                        prs(" unknown\n");
        !           721:                        flush();
        !           722:                        exit(1);
        !           723:                }
        !           724:                Ttycap = Capbuf;
        !           725:        }
        !           726: 
        !           727:        if (!RepOnly)
        !           728:        {
        !           729:                /* determine erase and kill characters */
        !           730:                if (Specialerase && !tgetflag("bs"))
        !           731:                        Erase_char = 0;
        !           732:                bufp = buf;
        !           733:                p = tgetstr("kb", &bufp);
        !           734:                if (p == NULL || p[1] != '\0')
        !           735:                        p = tgetstr("bc", &bufp);
        !           736:                if (p != NULL && p[1] == '\0')
        !           737:                        bs_char = p[0];
        !           738:                else if (tgetflag("bs"))
        !           739:                        bs_char = BACKSPACE;
        !           740:                else
        !           741:                        bs_char = 0;
        !           742:                if (Erase_char == 0 && !tgetflag("os") && mode.sg_erase == OLDERASE)
        !           743:                {
        !           744:                        if (tgetflag("bs") || bs_char != 0)
        !           745:                                Erase_char = -1;
        !           746:                }
        !           747:                if (Erase_char < 0)
        !           748:                        Erase_char = (bs_char != 0) ? bs_char : BACKSPACE;
        !           749: 
        !           750:                if (mode.sg_erase == 0)
        !           751:                        mode.sg_erase = OLDERASE;
        !           752:                if (Erase_char != 0)
        !           753:                        mode.sg_erase = Erase_char;
        !           754: 
        !           755:                if (mode.sg_kill == 0)
        !           756:                        mode.sg_kill = OLDKILL;
        !           757:                if (Kill_char != 0)
        !           758:                        mode.sg_kill = Kill_char;
        !           759: 
        !           760:                /* set modes */
        !           761:                setdelay("dC", CRdelay, CRbits, &mode.sg_flags);
        !           762:                setdelay("dN", NLdelay, NLbits, &mode.sg_flags);
        !           763:                setdelay("dB", BSdelay, BSbits, &mode.sg_flags);
        !           764:                setdelay("dF", FFdelay, FFbits, &mode.sg_flags);
        !           765:                setdelay("dT", TBdelay, TBbits, &mode.sg_flags);
        !           766:                if (tgetflag("UC") || command[0] == 'T')
        !           767:                        mode.sg_flags |= LCASE;
        !           768:                else if (tgetflag("LC"))
        !           769:                        mode.sg_flags &= ~LCASE;
        !           770:                mode.sg_flags &= ~(EVENP | ODDP | RAW);
        !           771: # ifndef V6
        !           772:                mode.sg_flags &= ~CBREAK;
        !           773: # endif
        !           774:                if (tgetflag("EP"))
        !           775:                        mode.sg_flags |= EVENP;
        !           776:                if (tgetflag("OP"))
        !           777:                        mode.sg_flags |= ODDP;
        !           778:                if ((mode.sg_flags & (EVENP | ODDP)) == 0)
        !           779:                        mode.sg_flags |= EVENP | ODDP;
        !           780:                mode.sg_flags |= CRMOD | ECHO | XTABS;
        !           781:                if (tgetflag("NL"))     /* new line, not line feed */
        !           782:                        mode.sg_flags &= ~CRMOD;
        !           783:                if (tgetflag("HD"))     /* half duplex */
        !           784:                        mode.sg_flags &= ~ECHO;
        !           785:                if (tgetflag("pt"))     /* print tabs */
        !           786:                        mode.sg_flags &= ~XTABS;
        !           787:                if (!bequal(&mode, &oldmode, sizeof mode))
        !           788: # ifndef V6
        !           789:                        ioctl(FILEDES, TIOCSETN, &mode);
        !           790: # else
        !           791:                        stty(FILEDES, &mode);
        !           792: # endif
        !           793: 
        !           794:                /* get pad character */
        !           795:                bufp = buf;
        !           796:                if (tgetstr("pc", &bufp) != 0)
        !           797:                        PC = buf[0];
        !           798: 
        !           799:                /* output startup string */
        !           800:                if (!NoInit)
        !           801:                {
        !           802:                        bufp = buf;
        !           803:                        if (tgetstr("is", &bufp) != 0)
        !           804:                                tputs(buf, 0, prc);
        !           805:                        flush();
        !           806:                        bufp = buf;
        !           807:                        if (tgetstr("if", &bufp) != 0)
        !           808:                                cat(buf);
        !           809:                        sleep(1);       /* let terminal settle down */
        !           810:                }
        !           811: 
        !           812:                /* set up environment for the shell we are using */
        !           813:                /* (this code is rather heuristic) */
        !           814:                csh = 0;
        !           815:                if (DoSetenv)
        !           816:                {
        !           817: # ifndef V6
        !           818:                        char *sh;
        !           819: 
        !           820:                        if ((sh = getenv("SHELL")) && (i = strlen(sh)) >= 3)
        !           821:                        {
        !           822:                                p = &sh[i-3];
        !           823:                                if ((csh = sequal(p, "csh")) && CmndLine)
        !           824:                                        write(STDOUT, "set noglob;\n", 12);
        !           825:                        }
        !           826:                        if (!csh)
        !           827: # endif
        !           828:                                /* running system shell */
        !           829:                                write(STDOUT, "export TERMCAP TERM;\n", 21);
        !           830:                }
        !           831:        }
        !           832: 
        !           833:        /* report type if appropriate */
        !           834:        if (DoSetenv || Report || Ureport)
        !           835:        {
        !           836:                /* find first alias (if any) */
        !           837:                for (p = Ttycap; *p != 0 && *p != '|' && *p != ':'; p++)
        !           838:                        continue;
        !           839:                if (*p == 0 || *p == ':')
        !           840:                        p = Ttycap;
        !           841:                else
        !           842:                        p++;
        !           843:                bufp = p;
        !           844:                while (*p != '|' && *p != ':' && *p != 0)
        !           845:                        p++;
        !           846:                i = *p;
        !           847:                if (DoSetenv)
        !           848:                {
        !           849:                        if (csh)
        !           850:                        {
        !           851:                                if (CmndLine)
        !           852:                                        write(STDOUT, "setenv TERM ", 12);
        !           853:                                write(STDOUT, bufp, p - bufp);
        !           854:                                write(STDOUT, " ", 1);
        !           855:                                if (CmndLine)
        !           856:                                        write(STDOUT, ";\n", 2);
        !           857:                        }
        !           858:                        else
        !           859:                        {
        !           860:                                write(STDOUT, "TERM=", 5);
        !           861:                                write(STDOUT, bufp, p - bufp);
        !           862:                                write(STDOUT, ";\n", 2);
        !           863:                        }
        !           864:                }
        !           865:                if (Report && !DoSetenv)
        !           866:                {
        !           867:                        write(STDOUT, bufp, p - bufp);
        !           868:                        write(STDOUT, "\n", 1);
        !           869:                }
        !           870:                if (Ureport)
        !           871:                {
        !           872:                        *p = '\0';
        !           873:                        prs("Terminal type is ");
        !           874:                        prs(bufp);
        !           875:                        prs("\n");
        !           876:                        flush();
        !           877:                }
        !           878:                *p = i;
        !           879:                if (DoSetenv)
        !           880:                {
        !           881:                        if (csh)
        !           882:                        {
        !           883:                                if (CmndLine)
        !           884:                                        write(STDOUT, "setenv TERMCAP '", 16);
        !           885:                        }
        !           886:                        else
        !           887:                                write(STDOUT, "TERMCAP='", 9);
        !           888:                        wrtermcap(Ttycap);
        !           889:                        if (csh)
        !           890:                        {
        !           891:                                if (CmndLine)
        !           892:                                {
        !           893:                                        write(STDOUT, "';\n", 3);
        !           894:                                        write(STDOUT, "unset noglob;\n", 14);
        !           895:                                }
        !           896:                        }
        !           897:                        else
        !           898:                                write(STDOUT, "';\n", 3);
        !           899:                }
        !           900:        }
        !           901: 
        !           902:        if (RepOnly)
        !           903:                exit(0);
        !           904: 
        !           905:        /* tell about changing erase and kill characters */
        !           906:        reportek("Erase", mode.sg_erase, oldmode.sg_erase, OLDERASE);
        !           907:        reportek("Kill", mode.sg_kill, oldmode.sg_kill, OLDKILL);
        !           908: 
        !           909: # ifdef V6
        !           910:        /* update htmp */
        !           911:        if (!Dash_u)
        !           912:        {
        !           913:                if (Ttyid == 0)
        !           914:                        Ttyid = ttyn(FILEDES);
        !           915:                if (Ttyid == 'x')
        !           916:                {
        !           917:                        prs("Cannot update htmp\n");
        !           918:                        flush();
        !           919:                }
        !           920:                else
        !           921:                {
        !           922:                        /* update htmp file only if changed */
        !           923:                        if (!bequal(Capbuf, hsgettype(), 2))
        !           924:                        {
        !           925:                                hsettype(Capbuf[0] | (Capbuf[1] << 8));
        !           926:                                hput(Ttyid);
        !           927:                        }
        !           928:                }
        !           929:        }
        !           930: # endif
        !           931: 
        !           932:        exit(0);
        !           933: }
        !           934: 
        !           935: reportek(name, new, old, def)
        !           936: char   *name;
        !           937: char   old;
        !           938: char   new;
        !           939: char   def;
        !           940: {
        !           941:        register char   o;
        !           942:        register char   n;
        !           943:        register char   *p;
        !           944: 
        !           945:        if (BeQuiet)
        !           946:                return;
        !           947:        o = old;
        !           948:        n = new;
        !           949: 
        !           950:        if (o == n && n == def)
        !           951:                return;
        !           952:        prs(name);
        !           953:        if (o == n)
        !           954:                prs(" is ");
        !           955:        else
        !           956:                prs(" set to ");
        !           957:        if (n < 040)
        !           958:        {
        !           959:                prs("control-");
        !           960:                n = (n & 037) | 0100;
        !           961:        }
        !           962:        p = "x\n";
        !           963:        p[0] = n;
        !           964:        prs(p);
        !           965:        flush();
        !           966: }
        !           967: 
        !           968: 
        !           969: 
        !           970: 
        !           971: setdelay(cap, dtab, bits, flags)
        !           972: char           *cap;
        !           973: struct delay   dtab[];
        !           974: int            bits;
        !           975: int            *flags;
        !           976: {
        !           977:        register int    i;
        !           978:        register struct delay   *p;
        !           979: 
        !           980:        /* see if this capability exists at all */
        !           981:        i = tgetnum(cap);
        !           982:        if (i < 0)
        !           983:                i = 0;
        !           984: 
        !           985:        /* clear out the bits, replace with new ones */
        !           986:        *flags &= ~bits;
        !           987: 
        !           988:        /* scan dtab for first entry with adequate delay */
        !           989:        for (p = dtab; p->d_delay >= 0; p++)
        !           990:        {
        !           991:                if (p->d_delay >= i)
        !           992:                {
        !           993:                        p++;
        !           994:                        break;
        !           995:                }
        !           996:        }
        !           997: 
        !           998:        /* use last entry if none will do */
        !           999:        *flags |= (--p)->d_bits;
        !          1000: }
        !          1001: 
        !          1002: 
        !          1003: prs(s)
        !          1004: char   *s;
        !          1005: {
        !          1006:        while (*s != '\0')
        !          1007:                prc(*s++);
        !          1008: }
        !          1009: 
        !          1010: 
        !          1011: char   OutBuf[256];
        !          1012: int    OutPtr;
        !          1013: 
        !          1014: prc(c)
        !          1015:        char c;
        !          1016: {
        !          1017:        OutBuf[OutPtr++] = c;
        !          1018:        if (OutPtr >= sizeof OutBuf)
        !          1019:                flush();
        !          1020: }
        !          1021: 
        !          1022: flush()
        !          1023: {
        !          1024:        if (OutPtr > 0)
        !          1025:                write(2, OutBuf, OutPtr);
        !          1026:        OutPtr = 0;
        !          1027: }
        !          1028: 
        !          1029: 
        !          1030: cat(file)
        !          1031: char   *file;
        !          1032: {
        !          1033:        register int    fd;
        !          1034:        register int    i;
        !          1035:        char            buf[BUFSIZ];
        !          1036: 
        !          1037:        fd = open(file, 0);
        !          1038:        if (fd < 0)
        !          1039:        {
        !          1040:                prs("Cannot open ");
        !          1041:                prs(file);
        !          1042:                prs("\n");
        !          1043:                flush();
        !          1044:                exit(-1);
        !          1045:        }
        !          1046: 
        !          1047:        flush();
        !          1048:        while ((i = read(fd, buf, BUFSIZ)) > 0)
        !          1049:                write(FILEDES, buf, i);
        !          1050: 
        !          1051:        close(fd);
        !          1052: }
        !          1053: 
        !          1054: 
        !          1055: 
        !          1056: bmove(from, to, length)
        !          1057: char   *from;
        !          1058: char   *to;
        !          1059: int    length;
        !          1060: {
        !          1061:        register char   *p, *q;
        !          1062:        register int    i;
        !          1063: 
        !          1064:        i = length;
        !          1065:        p = from;
        !          1066:        q = to;
        !          1067: 
        !          1068:        while (i-- > 0)
        !          1069:                *q++ = *p++;
        !          1070: }
        !          1071: 
        !          1072: 
        !          1073: 
        !          1074: bequal(a, b, len)
        !          1075: char   *a;
        !          1076: char   *b;
        !          1077: int    len;
        !          1078: {
        !          1079:        register char   *p, *q;
        !          1080:        register int    i;
        !          1081: 
        !          1082:        i = len;
        !          1083:        p = a;
        !          1084:        q = b;
        !          1085: 
        !          1086:        while (*p && *q && (*p == *q) && --i > 0)
        !          1087:        {
        !          1088:                p++; q++;
        !          1089:        }
        !          1090:        return ((*p == *q) && i >= 0);
        !          1091: }
        !          1092: 
        !          1093: sequal(a, b)
        !          1094: char   *a;
        !          1095: char   *b;
        !          1096: {
        !          1097:        register char *p = a, *q = b;
        !          1098: 
        !          1099:        while (*p && *q && (*p == *q))
        !          1100:        {
        !          1101:                p++; q++;
        !          1102:        }
        !          1103:        return (*p == *q);
        !          1104: }
        !          1105: 
        !          1106: # ifdef GTTYN
        !          1107: char *
        !          1108: stypeof(ttyid)
        !          1109: char   *ttyid;
        !          1110: {
        !          1111:        static char     typebuf[50];
        !          1112:        register char   *PortType;
        !          1113:        register char   *PortName;
        !          1114:        register char   *TtyId;
        !          1115:        register char   *p;
        !          1116:        register FILE   *f;
        !          1117: 
        !          1118:        if (ttyid == NOTTY)
        !          1119:                return (DEFTYPE);
        !          1120:        f = fopen(GTTYN, "r");
        !          1121:        if (f == NULL)
        !          1122:                return (DEFTYPE);
        !          1123: 
        !          1124:        /* split off end of name */
        !          1125:        TtyId = ttyid;
        !          1126:        while (*ttyid)
        !          1127:                if (*ttyid++ == '/')
        !          1128:                        TtyId = ttyid;
        !          1129: 
        !          1130:        /* scan the file */
        !          1131:        while (fgets(typebuf, sizeof typebuf, f) != NULL)
        !          1132:        {
        !          1133:                p = PortType = typebuf;
        !          1134:                while (*p && isalnum(*p))
        !          1135:                        p++;
        !          1136:                *p++ = NULL;
        !          1137: 
        !          1138:                /* skip separator */
        !          1139:                while (*p && !isalnum(*p))
        !          1140:                        p++;
        !          1141: 
        !          1142:                PortName = p;
        !          1143:                /* put NULL at end of name */
        !          1144:                while (*p && isalnum(*p))
        !          1145:                        p++;
        !          1146:                *p = NULL;
        !          1147: 
        !          1148:                /* check match on port name */
        !          1149:                if (sequal(PortName, TtyId))    /* found it */
        !          1150:                {
        !          1151: # ifdef OLDDIALUP
        !          1152:                        if (sequal(PortType, OLDDIALUP))
        !          1153:                                PortType = DIALUP;
        !          1154: # endif
        !          1155: 
        !          1156: # ifdef OLDPLUGBOARD
        !          1157:                        if (sequal(PortType, OLDPLUGBOARD))
        !          1158:                                PortType = PLUGBOARD;
        !          1159: # endif
        !          1160: 
        !          1161: # ifdef OLDARPANET
        !          1162:                        if (sequal(PortType, OLDARPANET))
        !          1163:                                PortType = ARPANET;
        !          1164: # endif
        !          1165:                        fclose (f);
        !          1166:                        return(PortType);
        !          1167:                }
        !          1168:        }
        !          1169:        fclose (f);
        !          1170:        return (DEFTYPE);
        !          1171: }
        !          1172: # endif
        !          1173: 
        !          1174: #define        YES     1
        !          1175: #define        NO      0
        !          1176: /*
        !          1177:  * routine to output the string for the environment TERMCAP variable
        !          1178:  */
        !          1179: #define        WHITE(c)        (c == ' ' || c == '\t')
        !          1180: char delcap[128][2];
        !          1181: int ncap = 0;
        !          1182: 
        !          1183: wrtermcap(bp)
        !          1184: char *bp;
        !          1185: {
        !          1186:        char buf[CAPBUFSIZ];
        !          1187:        char *p = buf;
        !          1188:        char *tp;
        !          1189:        char *putbuf();
        !          1190:        int space, empty;
        !          1191: 
        !          1192:        /* discard names with blanks */
        !          1193: /** May not be desireable ? **/
        !          1194:        while (*bp && *bp != ':') {
        !          1195:                if (*bp == '|') {
        !          1196:                        tp = bp+1;
        !          1197:                        space = NO;
        !          1198:                        while (*tp && *tp != '|' && *tp != ':') {
        !          1199:                                space = (space || WHITE(*tp) );
        !          1200:                                tp++;
        !          1201:                        }
        !          1202:                        if (space) {
        !          1203:                                bp = tp;
        !          1204:                                continue;
        !          1205:                        }
        !          1206:                }
        !          1207:                *p++ = *bp++;
        !          1208:        }
        !          1209: /**/
        !          1210: 
        !          1211:        while (*bp) {
        !          1212:                switch (*bp) {
        !          1213:                case ':':       /* discard empty, cancelled  or dupl fields */
        !          1214:                        tp = bp+1;
        !          1215:                        empty = YES;
        !          1216:                        while (*tp && *tp != ':') {
        !          1217:                                empty = (empty && WHITE(*tp) );
        !          1218:                                tp++;
        !          1219:                        }
        !          1220:                        if (empty || cancelled(bp+1)) {
        !          1221:                                bp = tp;
        !          1222:                                continue;
        !          1223:                        }
        !          1224:                        break;
        !          1225: 
        !          1226:                case ' ':       /* no spaces in output */
        !          1227:                        p = putbuf(p, "\\040");
        !          1228:                        bp++;
        !          1229:                        continue;
        !          1230: 
        !          1231:                case '"':       /* no quotes in output */
        !          1232:                        p = putbuf(p, "\\042");
        !          1233:                        bp++;
        !          1234:                        continue;
        !          1235: 
        !          1236:                case '\'':      /* no quotes in output */
        !          1237:                        p = putbuf(p, "\\047");
        !          1238:                        bp++;
        !          1239:                        continue;
        !          1240: 
        !          1241:                case '\\':
        !          1242:                case '^':       /* anything following is OK */
        !          1243:                        *p++ = *bp++;
        !          1244:                }
        !          1245:                *p++ = *bp++;
        !          1246:        }
        !          1247:        write (STDOUT, buf, p-buf);
        !          1248: }
        !          1249: 
        !          1250: cancelled(cap)
        !          1251: char   *cap;
        !          1252: {
        !          1253:        register int i;
        !          1254: 
        !          1255:        for (i = 0; i < ncap; i++)
        !          1256:        {
        !          1257:                if (cap[0] == delcap[i][0] && cap[1] == delcap[i][1])
        !          1258:                        return (YES);
        !          1259:        }
        !          1260:        /* delete a second occurrance of the same capability */
        !          1261:        delcap[ncap][0] = cap[0];
        !          1262:        delcap[ncap][1] = cap[1];
        !          1263:        ncap++;
        !          1264:        return (cap[2] == '@');
        !          1265: }
        !          1266: 
        !          1267: char *
        !          1268: putbuf(ptr, str)
        !          1269: char   *ptr;
        !          1270: char   *str;
        !          1271: {
        !          1272:        while (*str)
        !          1273:                *ptr++ = *str++;
        !          1274:        return (ptr);
        !          1275: }
        !          1276: 
        !          1277: 
        !          1278: baudrate(p)
        !          1279: char   *p;
        !          1280: {
        !          1281:        char buf[8];
        !          1282:        int i = 0;
        !          1283: 
        !          1284:        while (i < 7 && (isalnum(*p) || *p == '.'))
        !          1285:                buf[i++] = *p++;
        !          1286:        buf[i] = NULL;
        !          1287:        for (i=0; speeds[i].string; i++)
        !          1288:                if (sequal(speeds[i].string, buf))
        !          1289:                        return (speeds[i].speed);
        !          1290:        return (-1);
        !          1291: }
        !          1292: 
        !          1293: char *
        !          1294: mapped(type, speed)
        !          1295: char   *type;
        !          1296: short  speed;
        !          1297: {
        !          1298:        int     match;
        !          1299: 
        !          1300: # ifdef DEB
        !          1301:        printf ("spd:%d\n", speed);
        !          1302:        prmap();
        !          1303: # endif
        !          1304:        Map = map;
        !          1305:        while (Map->Ident)
        !          1306:        {
        !          1307:                if (*(Map->Ident) == NULL || bequal(Map->Ident, type, 4))
        !          1308:                {
        !          1309:                        match = NO;
        !          1310:                        switch (Map->Test)
        !          1311:                        {
        !          1312:                                case ANY:       /* no test specified */
        !          1313:                                case ALL:
        !          1314:                                        match = YES;
        !          1315:                                        break;
        !          1316:                                
        !          1317:                                case GT:
        !          1318:                                        match = (speed > Map->Speed);
        !          1319:                                        break;
        !          1320: 
        !          1321:                                case GE:
        !          1322:                                        match = (speed >= Map->Speed);
        !          1323:                                        break;
        !          1324: 
        !          1325:                                case EQ:
        !          1326:                                        match = (speed == Map->Speed);
        !          1327:                                        break;
        !          1328: 
        !          1329:                                case LE:
        !          1330:                                        match = (speed <= Map->Speed);
        !          1331:                                        break;
        !          1332: 
        !          1333:                                case LT:
        !          1334:                                        match = (speed < Map->Speed);
        !          1335:                                        break;
        !          1336: 
        !          1337:                                case NE:
        !          1338:                                        match = (speed != Map->Speed);
        !          1339:                                        break;
        !          1340:                        }
        !          1341:                        if (match)
        !          1342:                                return (Map->Type);
        !          1343:                }
        !          1344:                Map++;
        !          1345:        }
        !          1346:        /* no match found; return given type */
        !          1347:        return (type);
        !          1348: }
        !          1349: 
        !          1350: # ifdef DEB
        !          1351: prmap()
        !          1352: {
        !          1353:        Map = map;
        !          1354:        while (Map->Ident)
        !          1355:        {
        !          1356:        printf ("%s t:%d s:%d %s\n",
        !          1357:                Map->Ident, Map->Test, Map->Speed, Map->Type);
        !          1358:        Map++;
        !          1359:        }
        !          1360: }
        !          1361: # endif
        !          1362: 
        !          1363: char *
        !          1364: nextarg(argc, argv)
        !          1365: int    argc;
        !          1366: char   *argv[];
        !          1367: {
        !          1368:        if (argc <= 0)
        !          1369:                fatal ("Too few args: ", *argv);
        !          1370:        if (*(*++argv) == '-')
        !          1371:                fatal ("Unexpected arg: ", *argv);
        !          1372:        return (*argv);
        !          1373: }
        !          1374: 
        !          1375: fatal (mesg, obj)
        !          1376: char   *mesg;
        !          1377: char   *obj;
        !          1378: {
        !          1379:        prs (mesg);
        !          1380:        prs (obj);
        !          1381:        prc ('\n');
        !          1382:        prs (USAGE);
        !          1383:        flush();
        !          1384:        exit(1);
        !          1385: }

unix.superglobalmegacorp.com

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