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

1.1     ! root        1: #
        !             2: /*
        !             3: **  TSET -- set terminal modes
        !             4: **
        !             5: **     This program does sophisticated terminal initialization.
        !             6: **     I recommend that you include it in your .start_up or .login
        !             7: **     file to initialize whatever terminal you are on.
        !             8: **
        !             9: **     There are several features:
        !            10: **
        !            11: **     A special file or sequence (as controlled by the ttycap file)
        !            12: **     is sent to the terminal.
        !            13: **
        !            14: **     Mode bits are set on a per-terminal_type basis (much better
        !            15: **     than UNIX itself).  This allows special delays, automatic
        !            16: **     tabs, etc.
        !            17: **
        !            18: **     Erase and Kill characters can be set to whatever you want.
        !            19: **     Default is to change erase to control-H on a terminal which
        !            20: **     can overstrike, and leave it alone on anything else.  Kill
        !            21: **     is always left alone unless specifically requested.  These
        !            22: **     characters can be represented as "^X" meaning control-X;
        !            23: **     X is any character.
        !            24: **
        !            25: **     Terminals which are dialups or plugboard types can be aliased
        !            26: **     to whatever type you may have in your home or office.  Thus,
        !            27: **     if you know that when you dial up you will always be on a
        !            28: **     TI 733, you can specify that fact to tset.  You can represent
        !            29: **     a type as "?type".  This will ask you what type you want it
        !            30: **     to be -- if you reply with just a newline, it will default
        !            31: **     to the type given.
        !            32: **
        !            33: **     The htmp file, used by ex, etc., can be updated.
        !            34: **
        !            35: **     The current terminal type can be queried.
        !            36: **
        !            37: **     Usage:
        !            38: **             tset [-] [-EC] [-eC] [-kC] [-s] [-h] [-u] 
        !            39: **                     [-d type] [-p type] [-b type] [-a type]
        !            40: **                     [-Q] [-I] [type]
        !            41: **
        !            42: **             In systems with environments, use:
        !            43: **                     `tset -s ...`
        !            44: **             Actually, this doesn't work because of a shell bug.
        !            45: **             Instead, use:
        !            46: **                     tset -s ... > tset.tmp
        !            47: **                     source tset.tmp
        !            48: **                     rm tset.tmp
        !            49: **
        !            50: **     Positional Parameters:
        !            51: **             type -- the terminal type to force.  If this is
        !            52: **                     specified, initialization is for this
        !            53: **                     terminal type.
        !            54: **
        !            55: **     Flags:
        !            56: **             - -- report terminal type.  Whatever type is
        !            57: **                     decided on is reported.  If no other flags
        !            58: **                     are stated, the only affect is to write
        !            59: **                     the terminal type on the standard output.
        !            60: **             -EC -- set the erase character to C on all terminals
        !            61: **                     except those which cannot backspace (e.g.,
        !            62: **                     a TTY 33).  C defaults to control-H.
        !            63: **             -eC -- set the erase character to C on all terminals.
        !            64: **                     C defaults to control-H.  If neither -E or -e
        !            65: **                     are specified, the erase character is set to
        !            66: **                     control-H if the terminal can both backspace
        !            67: **                     and not overstrike (e.g., a CRT).  If the erase
        !            68: **                     character is NULL (zero byte), it will be reset
        !            69: **                     to '#' if nothing else is specified.
        !            70: **             -kC -- set the kill character to C on all terminals.
        !            71: **                     Default for C is control-X.  If not specified,
        !            72: **                     the kill character is untouched; however, if
        !            73: **                     not specified and the kill character is NULL
        !            74: **                     (zero byte), the kill character is set to '@'.
        !            75: **             -iC -- reserved for setable interrupt character.
        !            76: **             -qC -- reserved for setable quit character.
        !            77: **             -d type -- set the dialup type to be type.  If the
        !            78: **                     terminal type seems to be dialup, make it
        !            79: **                     'type' instead.  There need not be a space
        !            80: **                     between 'd' and 'type'.
        !            81: **             -p type -- ditto for a plugboard.
        !            82: **             -b type -- ditto for a bussiplexor.
        !            83: **             -a type -- ditto for an arpanet link.
        !            84: **             -h -- don't read htmp file.  Normally the terminal type
        !            85: **                     is determined by reading the htmp file (unless
        !            86: **                     -d or -p are specified).  This forces a read
        !            87: **                     of the ttytype file -- useful when htmp is
        !            88: **                     somehow wrong.
        !            89: **             -u -- don't update htmp.  It seemed like this should
        !            90: **                     be put in.  Note that htmp is never actually
        !            91: **                     written if there are no changes, so don't bother
        !            92: **                     bother using this for efficiency reasons alone.
        !            93: **             -s -- output setenv commands for TERM.  This can be
        !            94: **                     used with
        !            95: **                             `tset -s ...`
        !            96: **                     and is to be prefered to:
        !            97: **                             setenv TERM `tset - ...`
        !            98: **                     because -s sets the TERMCAP variable also.
        !            99: **             -Q -- be quiet.  don't output 'Erase set to' etc.
        !           100: **             -I -- don't do terminal initialization (is & if
        !           101: **                     strings).
        !           102: **
        !           103: **     Files:
        !           104: **             /etc/ttytype
        !           105: **                     contains a terminal id -> terminal type
        !           106: **                     mapping; used when -h, -d, or -p is used.
        !           107: **             /etc/termcap
        !           108: **                     a terminal_type -> terminal_capabilities
        !           109: **                     mapping.
        !           110: **
        !           111: **     Return Codes:
        !           112: **             -1 -- couldn't open ttycap.
        !           113: **             1 -- bad terminal type, or standard output not tty.
        !           114: **             0 -- ok.
        !           115: **
        !           116: **     Defined Constants:
        !           117: **             DIALUP -- the type code for a dialup port
        !           118: **             PLUGBOARD -- the code for a plugboard port.
        !           119: **             BUSSIPLEXER -- the code for a bussiplexer port.
        !           120: **             ARPANET -- the code for an arpanet port.
        !           121: **             BACKSPACE -- control-H, the default for -e.
        !           122: **             CONTROLX -- control-X, the default for -k.
        !           123: **             OLDERASE -- the system default erase character.
        !           124: **             OLDKILL -- the system default kill character.
        !           125: **             FILEDES -- the file descriptor to do the operation
        !           126: **                     on, nominally 1 or 2.
        !           127: **             STDOUT -- the standard output file descriptor.
        !           128: **             UIDMASK -- the bit pattern to mask with the getuid()
        !           129: **                     call to get just the user id.
        !           130: **
        !           131: **     Requires:
        !           132: **             Routines to handle htmp, ttytype, and ttycap.
        !           133: **
        !           134: **     Compilation Flags:
        !           135: **             PLUGBOARD -- if defined, accept the -p flag.
        !           136: **             BUSSIPLEXER -- if defined, accept the -b flag.
        !           137: **             FULLLOGIN -- if defined, login sets the ttytype from
        !           138: **                     /etc/ttytype file.
        !           139: **             V6 -- if clear, use environments, not htmp.
        !           140: **                     also use TIOCSETN rather than stty to avoid flushing
        !           141: **             GTTYN -- if set, uses generalized tty names.
        !           142: **
        !           143: **     Trace Flags:
        !           144: **             none
        !           145: **
        !           146: **     Diagnostics:
        !           147: **             Bad flag
        !           148: **                     An incorrect option was specified.
        !           149: **             Cannot open ...
        !           150: **                     The specified file could not be openned.
        !           151: **             Type ... unknown
        !           152: **                     An unknown terminal type was specified.
        !           153: **             Cannot update htmp
        !           154: **                     Cannot update htmp file when the standard
        !           155: **                     output is not a terminal.
        !           156: **             Erase set to ...
        !           157: **                     Telling that the erase character has been
        !           158: **                     set to the specified character.
        !           159: **             Kill set to ...
        !           160: **                     Ditto for kill
        !           161: **             Erase is ...    Kill is ...
        !           162: **                     Tells that the erase/kill characters were
        !           163: **                     wierd before, but they are being left as-is.
        !           164: **             Not a terminal
        !           165: **                     Set if FILEDES is not a terminal.
        !           166: **
        !           167: **     Compilation Instructions:
        !           168: **             cc -n -O tset.c -lX
        !           169: **             mv a.out tset
        !           170: **             chown bin tset
        !           171: **             chmod 4755 tset
        !           172: **
        !           173: **             where 'bin' should be whoever owns the 'htmp' file.
        !           174: **             If 'htmp' is 666, then tset need not be setuid.
        !           175: **
        !           176: **     Author:
        !           177: **             Eric Allman
        !           178: **             Electronics Research Labs
        !           179: **             U.C. Berkeley
        !           180: **
        !           181: **     History:
        !           182: **             10/79 -- '-s' option extended to handle TERMCAP
        !           183: **                     variable, set noglob, quote the entry,
        !           184: **                     and know about the Bourne shell.  Terminal
        !           185: **                     initialization moved to before any information
        !           186: **                     output so screen clears would not screw you.
        !           187: **                     '-Q' option added.
        !           188: **             8/79 -- '-' option alone changed to only output
        !           189: **                     type.  '-s' option added.  'VERSION7'
        !           190: **                     changed to 'V6' for compatibility.
        !           191: **             12/78 -- modified for eventual migration to VAX/UNIX,
        !           192: **                     so the '-' option is changed to output only
        !           193: **                     the terminal type to STDOUT instead of
        !           194: **                     FILEDES.  FULLLOGIN flag added.
        !           195: **             9/78 -- '-' and '-p' options added (now fully
        !           196: **                     compatible with ttytype!), and spaces are
        !           197: **                     permitted between the -d and the type.
        !           198: **             8/78 -- The sense of -h and -u were reversed, and the
        !           199: **                     -f flag is dropped -- same effect is available
        !           200: **                     by just stating the terminal type.
        !           201: **             10/77 -- Written.
        !           202: */
        !           203: 
        !           204: /*
        !           205: # define       FULLLOGIN       1
        !           206: */
        !           207: # ifndef V6
        !           208: # define       GTTYN           1
        !           209: # endif
        !           210: 
        !           211: # include      <sgtty.h>
        !           212: # include      <stdio.h>
        !           213: 
        !           214: # define       BACKSPACE       ('H' & 037)
        !           215: # define       CONTROLX        ('X' & 037)
        !           216: # define       OLDERASE        '#'
        !           217: # define       OLDKILL         '@'
        !           218: 
        !           219: # define       FILEDES         2
        !           220: # define       STDOUT          1
        !           221: 
        !           222: # ifdef V6
        !           223: # define       UIDMASK         0377
        !           224: # else
        !           225: # define       UIDMASK         -1
        !           226: # endif
        !           227: 
        !           228: # define       DIALUP          "sd"
        !           229: # define       PLUGBOARD       "sp"
        !           230: # define       BUSSIPLEXER     "sb"
        !           231: # define       ARPANET         "sa"
        !           232: 
        !           233: # ifdef GTTYN
        !           234: typedef char   *ttyid_t;
        !           235: # define       NOTTY           0
        !           236: # else
        !           237: typedef char   ttyid_t;
        !           238: # define       NOTTY           'x'
        !           239: # endif
        !           240: 
        !           241: 
        !           242: 
        !           243: 
        !           244: 
        !           245: 
        !           246: char   Erase_char;             /* new erase character */
        !           247: char   Kill_char;              /* new kill character */
        !           248: char   Specialerase;           /* set => Erase_char only on terminals with backspace */
        !           249: 
        !           250: ttyid_t        Ttyid = NOTTY;          /* terminal identifier */
        !           251: char   *TtyType;               /* type of terminal */
        !           252: char   *DefType;               /* default type if none other computed */
        !           253: char   *DialType;              /* override type if dialup port */
        !           254: char   *PlugType;              /* override type if plugboard port */
        !           255: char   *BxType;                /* override type if bussiplexer port */
        !           256: char   *AnType;                /* override type if arpanet port */
        !           257: int    Dash_u;                 /* don't update htmp */
        !           258: int    Dash_h;                 /* don't read htmp */
        !           259: int    DoSetenv;               /* output setenv commands */
        !           260: int    BeQuiet;                /* be quiet */
        !           261: int    NoInit;                 /* don't output initialization string */
        !           262: int    Report;                 /* report current type */
        !           263: int    Ureport;                /* report to user */
        !           264: int    RepOnly;                /* report only */
        !           265: 
        !           266: char   Usage[] = "usage: tset [-] [-r] [-s] [-eC] [-kC] [-d T] [-p T] [-b T] [-a T]\n\t[-Q] [-I] [-h] [-u] [type]\n";
        !           267: 
        !           268: char   Capbuf[1024];           /* line from /etc/termcap for this TtyType */
        !           269: char   *Ttycap;                /* termcap line from termcap or environ */
        !           270: 
        !           271: struct delay
        !           272: {
        !           273:        int     d_delay;
        !           274:        int     d_bits;
        !           275: };
        !           276: 
        !           277: # include      "tset.delays.h"
        !           278: 
        !           279: 
        !           280: 
        !           281: main(argc, argv)
        !           282: int    argc;
        !           283: char   *argv[];
        !           284: {
        !           285:        struct sgttyb   mode;
        !           286:        struct sgttyb   oldmode;
        !           287:        char            buf[256];
        !           288:        auto char       *bufp;
        !           289:        register char   *p;
        !           290:        char            *command;
        !           291:        register int    i;
        !           292:        register int    error;
        !           293:        extern char     *stypeof();
        !           294: # ifdef V6
        !           295:        extern char     *hsgettype();
        !           296: # else
        !           297:        extern char     *getenv();
        !           298: # endif
        !           299: # ifdef GTTYN
        !           300:        extern char     *ttyname();
        !           301:        extern char     *tgetstr();
        !           302: # endif
        !           303:        char            bs_char;
        !           304:        int             csh;
        !           305: 
        !           306:        /* scan argument list and collect flags */
        !           307:        error = 0;
        !           308:        command = argv[0];
        !           309:        if (argc == 2 && argv[1][0] == '-' && argv[1][1] == '\0')
        !           310:                RepOnly++;
        !           311:        argc--;
        !           312:        while (--argc >= 0)
        !           313:        {
        !           314:                p = *++argv;
        !           315:                if (p[0] == '-')
        !           316:                {
        !           317:                        switch (p[1])
        !           318:                        {
        !           319: 
        !           320:                          case 0:       /* report current terminal type */
        !           321:                                Report++;
        !           322:                                continue;
        !           323: 
        !           324:                          case 'r':     /* report to user */
        !           325:                                Ureport++;
        !           326:                                continue;
        !           327: 
        !           328:                          case 'E':     /* special erase: operate on all but TTY33 */
        !           329:                                Specialerase++;
        !           330:                                /* explicit fall-through to -e case */
        !           331: 
        !           332:                          case 'e':     /* erase character */
        !           333:                                if (p[2] == 0)
        !           334:                                        Erase_char = -1;
        !           335:                                else if (p[2] == '^' && p[3] != '\0')
        !           336:                                        Erase_char = p[3] & 037;
        !           337:                                else
        !           338:                                        Erase_char = p[2];
        !           339:                                continue;
        !           340: 
        !           341:                          case 'k':     /* kill character */
        !           342:                                if (p[2] == 0)
        !           343:                                        Kill_char = CONTROLX;
        !           344:                                else if (p[2] == '^' && p[3] != '\0')
        !           345:                                        Kill_char = p[3] & 037;
        !           346:                                else
        !           347:                                        Kill_char = p[2];
        !           348:                                continue;
        !           349: 
        !           350:                          case 'd':     /* dialup type */
        !           351:                                if (p[2] != 0)
        !           352:                                        DialType = &p[2];
        !           353:                                else if (--argc < 0 || argv[1][0] == '-')
        !           354:                                        error++;
        !           355:                                else
        !           356:                                        DialType = *++argv;
        !           357:                                continue;
        !           358: 
        !           359: # ifdef PLUGBOARD
        !           360:                          case 'p':     /* plugboard type */
        !           361:                                if (p[2] != 0)
        !           362:                                        PlugType = &p[2];
        !           363:                                else if (--argc < 0 || argv[1][0] == '-')
        !           364:                                        error++;
        !           365:                                else
        !           366:                                        PlugType = *++argv;
        !           367:                                continue;
        !           368: # endif
        !           369: 
        !           370: # ifdef BUSSIPLEXER
        !           371:                          case 'b':     /* bussiplexer type */
        !           372:                                if (p[2] != 0)
        !           373:                                        BxType = &p[2];
        !           374:                                else if (--argc < 0 || argv[1][0] == '-')
        !           375:                                        error++;
        !           376:                                else
        !           377:                                        BxType = *++argv;
        !           378: # endif
        !           379: 
        !           380: # ifdef ARPANET
        !           381:                          case 'a':     /* arpanet type */
        !           382:                                if (p[2] != 0)
        !           383:                                        AnType = &p[2];
        !           384:                                else if (--argc < 0 || argv[1][0] == '-')
        !           385:                                        error++;
        !           386:                                else
        !           387:                                        AnType = *++argv;
        !           388: # endif
        !           389: 
        !           390:                          case 'h':     /* don't get type from htmp or env */
        !           391:                                Dash_h++;
        !           392:                                continue;
        !           393: 
        !           394:                          case 'u':     /* don't update htmp */
        !           395:                                Dash_u++;
        !           396:                                continue;
        !           397:                          
        !           398:                          case 's':     /* output setenv commands */
        !           399:                                DoSetenv++;
        !           400:                                continue;
        !           401:                          
        !           402:                          case 'Q':     /* be quiet */
        !           403:                                BeQuiet++;
        !           404:                                continue;
        !           405:                          
        !           406:                          case 'I':     /* no initialization */
        !           407:                                NoInit++;
        !           408:                                continue;
        !           409: 
        !           410:                          default:
        !           411:                                prs("Bad flag ");
        !           412:                                prs(p);
        !           413:                                prs("\n");
        !           414:                                error++;
        !           415: 
        !           416:                        }
        !           417:                }
        !           418:                else
        !           419:                {
        !           420:                        /* terminal type */
        !           421:                        DefType = p;
        !           422:                }
        !           423:        }
        !           424: 
        !           425:        if (error)
        !           426:        {
        !           427:                prs(Usage);
        !           428:                exit(1);
        !           429:        }
        !           430: 
        !           431:        /* if dialup is specified, check ttytype not htmp */
        !           432:        if (DialType == 0 && PlugType == 0 && BxType == 0 && AnType == 0)
        !           433:                TtyType = DefType;
        !           434: # ifndef FULLLOGIN
        !           435:        else
        !           436:                Dash_h++;
        !           437: # endif
        !           438:        
        !           439:        /* if report only, say that we won't update htmp */
        !           440:        if (RepOnly)
        !           441:                Dash_u++;
        !           442: 
        !           443: # ifndef V6
        !           444:        /* get current idea of terminal type from environment */
        !           445:        if (!Dash_h && TtyType == 0)
        !           446:                TtyType = getenv("TERM");
        !           447: # endif
        !           448: 
        !           449:        /* determine terminal id if needed */
        !           450: # ifdef V6
        !           451:        if (Ttyid == NOTTY && (TtyType == 0 || !Dash_h || !Dash_u))
        !           452:                Ttyid = ttyn(FILEDES);
        !           453: # else
        !           454:        if (!RepOnly && Ttyid == NOTTY && (TtyType == 0 || !Dash_h))
        !           455:                Ttyid = ttyname(FILEDES);
        !           456: # endif
        !           457: 
        !           458: # ifdef V6
        !           459:        /* get htmp if ever used */
        !           460:        if (!Dash_u || (TtyType == 0 && !Dash_h))
        !           461:        {
        !           462:                /* get htmp entry -- if error or wrong user use ttytype */
        !           463:                if (Ttyid == NOTTY || hget(Ttyid) < 0 ||
        !           464:                    hgettype() == 0 || hgetuid() != (getuid() & UIDMASK))
        !           465:                        Dash_h++;
        !           466:        }
        !           467: # endif
        !           468: 
        !           469:        /* find terminal type (if not already known) */
        !           470:        if (TtyType == 0)
        !           471:        {
        !           472:                /* get type from /etc/ttytype or /etc/htmp */
        !           473:                if (!Dash_h)
        !           474:                {
        !           475: # ifdef V6
        !           476:                        TtyType = hsgettype();
        !           477: # else
        !           478:                        TtyType = getenv("TERM");
        !           479: # endif
        !           480:                }
        !           481:                if (TtyType == 0)
        !           482:                {
        !           483:                        TtyType = stypeof(Ttyid);
        !           484:                }
        !           485: 
        !           486:                /* check for dialup or plugboard override */
        !           487:                if (DialType != 0 && bequal(TtyType, DIALUP, 2))
        !           488:                        TtyType = DialType;
        !           489: # ifdef PLUGBOARD
        !           490:                else if (PlugType != 0 && bequal(TtyType, PLUGBOARD, 2))
        !           491:                        TtyType = PlugType;
        !           492: # endif
        !           493: # ifdef BUSSIPLEXER
        !           494:                else if (BxType != 0 && bequal(TtyType, BUSSIPLEXER, 2))
        !           495:                        TtyType = BxType;
        !           496: # endif
        !           497: # ifdef ARPANET
        !           498:                else if (AnType != 0 && bequal(TtyType, ARPANET, 2))
        !           499:                        TtyType = AnType;
        !           500: # endif
        !           501:                else if (DefType != 0)
        !           502:                        TtyType = DefType;
        !           503:        }
        !           504: 
        !           505:        /* TtyType now contains a pointer to the type of the terminal */
        !           506:        /* If the first character is '?', ask the user */
        !           507:        if (TtyType[0] == '?')
        !           508:        {
        !           509:                if (*++TtyType == '\0')
        !           510:                        TtyType = "dumb";
        !           511:                prs("TERM = (");
        !           512:                prs(TtyType);
        !           513:                prs(") ");
        !           514: 
        !           515:                /* read the terminal.  If not empty, set type */
        !           516:                i = read(2, buf, sizeof buf - 1);
        !           517:                if (i >= 0)
        !           518:                {
        !           519:                        if (buf[i - 1] == '\n')
        !           520:                                i--;
        !           521:                        buf[i] = '\0';
        !           522:                        if (buf[0] != '\0')
        !           523:                                TtyType = buf;
        !           524:                }
        !           525:        }
        !           526: 
        !           527:        if (Ttycap == 0)
        !           528:        {
        !           529:                /* get terminal capabilities */
        !           530:                switch (tgetent(Capbuf, TtyType))
        !           531:                {
        !           532:                  case -1:
        !           533:                        prs("Cannot open termcap file\n");
        !           534:                        exit(-1);
        !           535: 
        !           536:                  case 0:
        !           537:                        prs("Type ");
        !           538:                        prs(TtyType);
        !           539:                        prs(" unknown\n");
        !           540:                        exit(1);
        !           541:                }
        !           542:                Ttycap = Capbuf;
        !           543:        }
        !           544: 
        !           545:        /* output startup string */
        !           546:        if (!RepOnly && !NoInit)
        !           547:        {
        !           548:                bufp = buf;
        !           549:                if (tgetstr("is", &bufp) != 0)
        !           550:                        prs(buf);
        !           551:                bufp = buf;
        !           552:                if (tgetstr("if", &bufp) != 0)
        !           553:                        cat(buf);
        !           554:                sleep(1);       /* let terminal settle down */
        !           555:        }
        !           556: 
        !           557:        /* set up environment for the shell we are using */
        !           558:        /* (this code is rather heuristic) */
        !           559:        csh = 0;
        !           560:        if (DoSetenv)
        !           561:        {
        !           562: # ifndef V6
        !           563:                if (bequal(getenv("SHELL"), "/bin/csh", 9))
        !           564:                {
        !           565: # endif
        !           566:                        /* running csh */
        !           567:                        csh++;
        !           568:                        write(STDOUT, "set noglob;\n", 12);
        !           569: # ifndef V6
        !           570:                }
        !           571:                else
        !           572:                {
        !           573:                        /* running system shell */
        !           574:                        write(STDOUT, "export TERMCAP TERM;\n", 21);
        !           575:                }
        !           576: # endif
        !           577:        }
        !           578: 
        !           579:        /* report type if appropriate */
        !           580:        if (DoSetenv || Report || Ureport)
        !           581:        {
        !           582:                /* find first alias (if any) */
        !           583:                for (p = Ttycap; *p != 0 && *p != '|' && *p != ':'; p++)
        !           584:                        continue;
        !           585:                if (*p == 0 || *p == ':')
        !           586:                        p = Ttycap;
        !           587:                else
        !           588:                        p++;
        !           589:                bufp = p;
        !           590:                while (*p != '|' && *p != ':' && *p != 0)
        !           591:                        p++;
        !           592:                i = *p;
        !           593:                if (DoSetenv)
        !           594:                {
        !           595:                        if (csh)
        !           596:                                write(STDOUT, "setenv TERM ", 12);
        !           597:                        else
        !           598:                                write(STDOUT, "TERM=", 5);
        !           599:                }
        !           600:                if (Report || DoSetenv)
        !           601:                {
        !           602:                        write(STDOUT, bufp, p - bufp);
        !           603:                        if (DoSetenv)
        !           604:                                write(STDOUT, ";", 1);
        !           605:                        write(STDOUT, "\n", 1);
        !           606:                }
        !           607:                if (Ureport)
        !           608:                {
        !           609:                        *p = '\0';
        !           610:                        prs("Terminal type is ");
        !           611:                        prs(bufp);
        !           612:                        prs("\n");
        !           613:                }
        !           614:                *p = i;
        !           615:                if (DoSetenv)
        !           616:                {
        !           617:                        for (p = Ttycap; *p != '\0'; p++)
        !           618:                                continue;
        !           619:                        if (csh)
        !           620:                                write(STDOUT, "setenv TERMCAP '", 16);
        !           621:                        else
        !           622:                                write(STDOUT, "TERMCAP='", 9);
        !           623:                        write(STDOUT, Ttycap, p - Ttycap);
        !           624:                        write(STDOUT, "';\n", 3);
        !           625: 
        !           626:                        /* reset noglob */
        !           627:                        if (csh)
        !           628:                                write(STDOUT, "unset noglob;\n", 14);
        !           629:                }
        !           630:        }
        !           631: 
        !           632:        /* exit if report only mode */
        !           633:        if (RepOnly)
        !           634:                exit(0);
        !           635: 
        !           636:        if (gtty(FILEDES, &mode) < 0)
        !           637:        {
        !           638:                prs("Not a terminal\n");
        !           639:                exit(1);
        !           640:        }
        !           641:        bmove(&mode, &oldmode, sizeof mode);
        !           642: 
        !           643:        /* determine erase and kill characters */
        !           644:        if (Specialerase && !tgetflag("bs"))
        !           645:                Erase_char = 0;
        !           646:        bufp = buf;
        !           647:        p = tgetstr("bc", &bufp);
        !           648:        if (p != NULL)
        !           649:                bs_char = p[0];
        !           650:        else if (tgetflag("bs"))
        !           651:                bs_char = BACKSPACE;
        !           652:        else
        !           653:                bs_char = 0;
        !           654:        if (Erase_char == 0 && !tgetflag("os"))
        !           655:        {
        !           656:                if (tgetflag("bs") || bs_char != 0)
        !           657:                        Erase_char = -1;
        !           658:        }
        !           659:        if (Erase_char < 0)
        !           660:                Erase_char = (bs_char != 0) ? bs_char : BACKSPACE;
        !           661: 
        !           662:        if (mode.sg_erase == 0)
        !           663:                mode.sg_erase = OLDERASE;
        !           664:        if (Erase_char != 0)
        !           665:                mode.sg_erase = Erase_char;
        !           666: 
        !           667:        if (mode.sg_kill == 0)
        !           668:                mode.sg_kill = OLDKILL;
        !           669:        if (Kill_char != 0)
        !           670:                mode.sg_kill = Kill_char;
        !           671: 
        !           672:        /* set modes */
        !           673:        setdelay("dC", CRdelay, CRbits, &mode.sg_flags);
        !           674:        setdelay("dN", NLdelay, NLbits, &mode.sg_flags);
        !           675:        setdelay("dB", BSdelay, BSbits, &mode.sg_flags);
        !           676:        setdelay("dF", FFdelay, FFbits, &mode.sg_flags);
        !           677:        setdelay("dT", TBdelay, TBbits, &mode.sg_flags);
        !           678:        if (tgetflag("UC") || command[0] == 'T')
        !           679:                mode.sg_flags |= LCASE;
        !           680:        else if (tgetflag("LC"))
        !           681:                mode.sg_flags &= ~LCASE;
        !           682:        mode.sg_flags &= ~(EVENP | ODDP | RAW);
        !           683: # ifndef V6
        !           684:        mode.sg_flags &= ~CBREAK;
        !           685: # endif
        !           686:        if (tgetflag("EP"))
        !           687:                mode.sg_flags |= EVENP;
        !           688:        if (tgetflag("OP"))
        !           689:                mode.sg_flags |= ODDP;
        !           690:        if ((mode.sg_flags & (EVENP | ODDP)) == 0)
        !           691:                mode.sg_flags |= EVENP | ODDP;
        !           692:        mode.sg_flags |= CRMOD | ECHO | XTABS;
        !           693:        if (tgetflag("NL"))     /* new line, not line feed */
        !           694:                mode.sg_flags &= ~CRMOD;
        !           695:        if (tgetflag("HD"))     /* half duplex */
        !           696:                mode.sg_flags &= ~ECHO;
        !           697:        if (tgetflag("pt"))     /* print tabs */
        !           698:                mode.sg_flags &= ~XTABS;
        !           699:        if (!bequal(&mode, &oldmode, sizeof mode))
        !           700: # ifndef V6
        !           701:                ioctl(FILEDES, TIOCSETN, &mode);
        !           702: # else
        !           703:                stty(FILEDES, &mode);
        !           704: # endif
        !           705: 
        !           706:        /* tell about changing erase and kill characters */
        !           707:        reportek("Erase", mode.sg_erase, oldmode.sg_erase, OLDERASE);
        !           708:        reportek("Kill", mode.sg_kill, oldmode.sg_kill, OLDKILL);
        !           709: 
        !           710: # ifdef V6
        !           711:        /* update htmp */
        !           712:        if (!Dash_u)
        !           713:        {
        !           714:                if (Ttyid == 0)
        !           715:                        Ttyid = ttyn(FILEDES);
        !           716:                if (Ttyid == 'x')
        !           717:                        prs("Cannot update htmp\n");
        !           718:                else
        !           719:                {
        !           720:                        /* update htmp file only if changed */
        !           721:                        if (!bequal(Capbuf, hsgettype(), 2))
        !           722:                        {
        !           723:                                hsettype(Capbuf[0] | (Capbuf[1] << 8));
        !           724:                                hput(Ttyid);
        !           725:                        }
        !           726:                }
        !           727:        }
        !           728: # endif
        !           729: 
        !           730:        exit(0);
        !           731: }
        !           732: 
        !           733: 
        !           734: reportek(name, new, old, def)
        !           735: char   *name;
        !           736: char   old;
        !           737: char   new;
        !           738: char   def;
        !           739: {
        !           740:        register char   o;
        !           741:        register char   n;
        !           742:        register char   *p;
        !           743: 
        !           744:        if (BeQuiet)
        !           745:                return;
        !           746:        o = old;
        !           747:        n = new;
        !           748: 
        !           749:        if (o == n && n == def)
        !           750:                return;
        !           751:        prs(name);
        !           752:        if (o == n)
        !           753:                prs(" is ");
        !           754:        else
        !           755:                prs(" set to ");
        !           756:        if (n < 040)
        !           757:        {
        !           758:                prs("control-");
        !           759:                n = (n & 037) | 0100;
        !           760:        }
        !           761:        p = "x\n";
        !           762:        p[0] = n;
        !           763:        prs(p);
        !           764: }
        !           765: 
        !           766: 
        !           767: 
        !           768: 
        !           769: setdelay(cap, dtab, bits, flags)
        !           770: char           *cap;
        !           771: struct delay   dtab[];
        !           772: int            bits;
        !           773: int            *flags;
        !           774: {
        !           775:        register int    i;
        !           776:        register struct delay   *p;
        !           777: 
        !           778:        /* see if this capability exists at all */
        !           779:        i = tgetnum(cap);
        !           780:        if (i < 0)
        !           781:                i = 0;
        !           782: 
        !           783:        /* clear out the bits, replace with new ones */
        !           784:        *flags &= ~bits;
        !           785: 
        !           786:        /* scan dtab for first entry with adequate delay */
        !           787:        for (p = dtab; p->d_delay >= 0; p++)
        !           788:        {
        !           789:                if (p->d_delay >= i)
        !           790:                {
        !           791:                        p++;
        !           792:                        break;
        !           793:                }
        !           794:        }
        !           795: 
        !           796:        /* use last entry if none will do */
        !           797:        *flags |= (--p)->d_bits;
        !           798: }
        !           799: 
        !           800: 
        !           801: prs(s)
        !           802: char   *s;
        !           803: {
        !           804:        register char   *p;
        !           805:        register char   *q;
        !           806:        register int    i;
        !           807: 
        !           808:        p = q = s;
        !           809:        i = 0;
        !           810:        while (*q++ != 0)
        !           811:                i++;
        !           812: 
        !           813:        if (i > 0)
        !           814:                write(FILEDES, p, i);
        !           815: }
        !           816: 
        !           817: 
        !           818: cat(file)
        !           819: char   *file;
        !           820: {
        !           821:        register int    fd;
        !           822:        register int    i;
        !           823:        char            buf[BUFSIZ];
        !           824: 
        !           825:        fd = open(file, 0);
        !           826:        if (fd < 0)
        !           827:        {
        !           828:                prs("Cannot open ");
        !           829:                prs(file);
        !           830:                prs("\n");
        !           831:                exit(-1);
        !           832:        }
        !           833: 
        !           834:        while ((i = read(fd, buf, BUFSIZ)) > 0)
        !           835:                write(FILEDES, buf, i);
        !           836: 
        !           837:        close(fd);
        !           838: }
        !           839: 
        !           840: 
        !           841: 
        !           842: bmove(from, to, length)
        !           843: char   *from;
        !           844: char   *to;
        !           845: int    length;
        !           846: {
        !           847:        register char   *p, *q;
        !           848:        register int    i;
        !           849: 
        !           850:        i = length;
        !           851:        p = from;
        !           852:        q = to;
        !           853: 
        !           854:        while (i-- > 0)
        !           855:                *q++ = *p++;
        !           856: }
        !           857: 
        !           858: 
        !           859: 
        !           860: bequal(a, b, len)
        !           861: char   *a;
        !           862: char   *b;
        !           863: int    len;
        !           864: {
        !           865:        register char   *p, *q;
        !           866:        register int    i;
        !           867: 
        !           868:        i = len;
        !           869:        p = a;
        !           870:        q = b;
        !           871: 
        !           872:        while (i-- > 0)
        !           873:                if (*p++ != *q++)
        !           874:                        return (0);
        !           875:        return (1);
        !           876: }
        !           877: 
        !           878: # ifdef GTTYN
        !           879: char *
        !           880: stypeof(ttyid)
        !           881: char   *ttyid;
        !           882: {
        !           883:        static char     typebuf[3];
        !           884:        char            buf[50];
        !           885:        register char   *p;
        !           886:        register FILE   *f;
        !           887:        register char   *t;
        !           888:        register char   *q;
        !           889: 
        !           890:        if (ttyid == NOTTY)
        !           891:                return ("un");
        !           892:        f = fopen("/etc/ttytype", "r");
        !           893:        if (f == NULL)
        !           894:                return ("un");
        !           895: 
        !           896:        /* split off end of name */
        !           897:        for (p = q = ttyid; *p != 0; p++)
        !           898:                if (*p == '/')
        !           899:                        q = p + 1;
        !           900: 
        !           901:        /* scan the file */
        !           902:        while (fgets(buf, sizeof buf, f) != NULL)
        !           903:        {
        !           904:                for (p = q, t = &buf[3]; *p != '\0'; p++, t++)
        !           905:                        if (*p != *t)
        !           906:                                break;
        !           907:                if (*p == '\0' && (*t == '\n' || *t == '\t'))
        !           908:                {
        !           909:                        typebuf[0] = buf[0];
        !           910:                        typebuf[1] = buf[1];
        !           911:                        typebuf[2] = '\0';
        !           912:                        fclose(f);
        !           913:                        return (typebuf);
        !           914:                }
        !           915:        }
        !           916:        fclose (f);
        !           917:        return ("un");
        !           918: }
        !           919: # endif

unix.superglobalmegacorp.com

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