Annotation of 43BSDReno/libexec/getty/gettytab.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1983 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted
                      6:  * provided that: (1) source distributions retain this entire copyright
                      7:  * notice and comment, and (2) distributions including binaries display
                      8:  * the following acknowledgement:  ``This product includes software
                      9:  * developed by the University of California, Berkeley and its contributors''
                     10:  * in the documentation or other materials provided with the distribution
                     11:  * and in all advertising materials mentioning features or use of this
                     12:  * software. Neither the name of the University nor the names of its
                     13:  * contributors may be used to endorse or promote products derived
                     14:  * from this software without specific prior written permission.
                     15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     16:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     18:  */
                     19: 
                     20: #ifndef lint
                     21: static char sccsid[] = "@(#)gettytab.c 5.4 (Berkeley) 6/1/90";
                     22: #endif /* not lint */
                     23: 
                     24: #include <sys/file.h>
                     25: #include <ctype.h>
                     26: #include "pathnames.h"
                     27: 
                     28: #define        TABBUFSIZ       512
                     29: 
                     30: static char *tbuf;
                     31: int    hopcount;       /* detect infinite loops in termcap, init 0 */
                     32: char   *skip();
                     33: char   *getstr();
                     34: char   *decode();
                     35: 
                     36: /*
                     37:  * Get an entry for terminal name in buffer bp,
                     38:  * from the termcap file.  Parse is very rudimentary;
                     39:  * we just notice escaped newlines.
                     40:  */
                     41: getent(bp, name)
                     42:        char *bp, *name;
                     43: {
                     44:        register char *cp;
                     45:        register int c;
                     46:        register int i = 0, cnt = 0;
                     47:        char ibuf[TABBUFSIZ];
                     48:        char *cp2;
                     49:        int tf;
                     50: 
                     51:        tbuf = bp;
                     52:        tf = open(_PATH_GETTYTAB, O_RDONLY, 0);
                     53:        if (tf < 0)
                     54:                return (-1);
                     55:        for (;;) {
                     56:                cp = bp;
                     57:                for (;;) {
                     58:                        if (i == cnt) {
                     59:                                cnt = read(tf, ibuf, TABBUFSIZ);
                     60:                                if (cnt <= 0) {
                     61:                                        close(tf);
                     62:                                        return (0);
                     63:                                }
                     64:                                i = 0;
                     65:                        }
                     66:                        c = ibuf[i++];
                     67:                        if (c == '\n') {
                     68:                                if (cp > bp && cp[-1] == '\\'){
                     69:                                        cp--;
                     70:                                        continue;
                     71:                                }
                     72:                                break;
                     73:                        }
                     74:                        if (cp >= bp+TABBUFSIZ) {
                     75:                                write(2,"Gettytab entry too long\n", 24);
                     76:                                break;
                     77:                        } else
                     78:                                *cp++ = c;
                     79:                }
                     80:                *cp = 0;
                     81: 
                     82:                /*
                     83:                 * The real work for the match.
                     84:                 */
                     85:                if (namatch(name)) {
                     86:                        close(tf);
                     87:                        return(nchktc());
                     88:                }
                     89:        }
                     90: }
                     91: 
                     92: /*
                     93:  * tnchktc: check the last entry, see if it's tc=xxx. If so,
                     94:  * recursively find xxx and append that entry (minus the names)
                     95:  * to take the place of the tc=xxx entry. This allows termcap
                     96:  * entries to say "like an HP2621 but doesn't turn on the labels".
                     97:  * Note that this works because of the left to right scan.
                     98:  */
                     99: #define        MAXHOP  32
                    100: nchktc()
                    101: {
                    102:        register char *p, *q;
                    103:        char tcname[16];        /* name of similar terminal */
                    104:        char tcbuf[TABBUFSIZ];
                    105:        char *holdtbuf = tbuf;
                    106:        int l;
                    107: 
                    108:        p = tbuf + strlen(tbuf) - 2;    /* before the last colon */
                    109:        while (*--p != ':')
                    110:                if (p<tbuf) {
                    111:                        write(2, "Bad gettytab entry\n", 19);
                    112:                        return (0);
                    113:                }
                    114:        p++;
                    115:        /* p now points to beginning of last field */
                    116:        if (p[0] != 't' || p[1] != 'c')
                    117:                return(1);
                    118:        strcpy(tcname,p+3);
                    119:        q = tcname;
                    120:        while (q && *q != ':')
                    121:                q++;
                    122:        *q = 0;
                    123:        if (++hopcount > MAXHOP) {
                    124:                write(2, "Getty: infinite tc= loop\n", 25);
                    125:                return (0);
                    126:        }
                    127:        if (getent(tcbuf, tcname) != 1)
                    128:                return(0);
                    129:        for (q=tcbuf; *q != ':'; q++)
                    130:                ;
                    131:        l = p - holdtbuf + strlen(q);
                    132:        if (l > TABBUFSIZ) {
                    133:                write(2, "Gettytab entry too long\n", 24);
                    134:                q[TABBUFSIZ - (p-tbuf)] = 0;
                    135:        }
                    136:        strcpy(p, q+1);
                    137:        tbuf = holdtbuf;
                    138:        return(1);
                    139: }
                    140: 
                    141: /*
                    142:  * Tnamatch deals with name matching.  The first field of the termcap
                    143:  * entry is a sequence of names separated by |'s, so we compare
                    144:  * against each such name.  The normal : terminator after the last
                    145:  * name (before the first field) stops us.
                    146:  */
                    147: namatch(np)
                    148:        char *np;
                    149: {
                    150:        register char *Np, *Bp;
                    151: 
                    152:        Bp = tbuf;
                    153:        if (*Bp == '#')
                    154:                return(0);
                    155:        for (;;) {
                    156:                for (Np = np; *Np && *Bp == *Np; Bp++, Np++)
                    157:                        continue;
                    158:                if (*Np == 0 && (*Bp == '|' || *Bp == ':' || *Bp == 0))
                    159:                        return (1);
                    160:                while (*Bp && *Bp != ':' && *Bp != '|')
                    161:                        Bp++;
                    162:                if (*Bp == 0 || *Bp == ':')
                    163:                        return (0);
                    164:                Bp++;
                    165:        }
                    166: }
                    167: 
                    168: /*
                    169:  * Skip to the next field.  Notice that this is very dumb, not
                    170:  * knowing about \: escapes or any such.  If necessary, :'s can be put
                    171:  * into the termcap file in octal.
                    172:  */
                    173: static char *
                    174: skip(bp)
                    175:        register char *bp;
                    176: {
                    177: 
                    178:        while (*bp && *bp != ':')
                    179:                bp++;
                    180:        if (*bp == ':')
                    181:                bp++;
                    182:        return (bp);
                    183: }
                    184: 
                    185: /*
                    186:  * Return the (numeric) option id.
                    187:  * Numeric options look like
                    188:  *     li#80
                    189:  * i.e. the option string is separated from the numeric value by
                    190:  * a # character.  If the option is not found we return -1.
                    191:  * Note that we handle octal numbers beginning with 0.
                    192:  */
                    193: long
                    194: getnum(id)
                    195:        char *id;
                    196: {
                    197:        register long i, base;
                    198:        register char *bp = tbuf;
                    199: 
                    200:        for (;;) {
                    201:                bp = skip(bp);
                    202:                if (*bp == 0)
                    203:                        return (-1);
                    204:                if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
                    205:                        continue;
                    206:                if (*bp == '@')
                    207:                        return(-1);
                    208:                if (*bp != '#')
                    209:                        continue;
                    210:                bp++;
                    211:                base = 10;
                    212:                if (*bp == '0')
                    213:                        base = 8;
                    214:                i = 0;
                    215:                while (isdigit(*bp))
                    216:                        i *= base, i += *bp++ - '0';
                    217:                return (i);
                    218:        }
                    219: }
                    220: 
                    221: /*
                    222:  * Handle a flag option.
                    223:  * Flag options are given "naked", i.e. followed by a : or the end
                    224:  * of the buffer.  Return 1 if we find the option, or 0 if it is
                    225:  * not given.
                    226:  */
                    227: getflag(id)
                    228:        char *id;
                    229: {
                    230:        register char *bp = tbuf;
                    231: 
                    232:        for (;;) {
                    233:                bp = skip(bp);
                    234:                if (!*bp)
                    235:                        return (-1);
                    236:                if (*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) {
                    237:                        if (!*bp || *bp == ':')
                    238:                                return (1);
                    239:                        else if (*bp == '!')
                    240:                                return (0);
                    241:                        else if (*bp == '@')
                    242:                                return(-1);
                    243:                }
                    244:        }
                    245: }
                    246: 
                    247: /*
                    248:  * Get a string valued option.
                    249:  * These are given as
                    250:  *     cl=^Z
                    251:  * Much decoding is done on the strings, and the strings are
                    252:  * placed in area, which is a ref parameter which is updated.
                    253:  * No checking on area overflow.
                    254:  */
                    255: char *
                    256: getstr(id, area)
                    257:        char *id, **area;
                    258: {
                    259:        register char *bp = tbuf;
                    260: 
                    261:        for (;;) {
                    262:                bp = skip(bp);
                    263:                if (!*bp)
                    264:                        return (0);
                    265:                if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
                    266:                        continue;
                    267:                if (*bp == '@')
                    268:                        return(0);
                    269:                if (*bp != '=')
                    270:                        continue;
                    271:                bp++;
                    272:                return (decode(bp, area));
                    273:        }
                    274: }
                    275: 
                    276: /*
                    277:  * Tdecode does the grung work to decode the
                    278:  * string capability escapes.
                    279:  */
                    280: static char *
                    281: decode(str, area)
                    282:        register char *str;
                    283:        char **area;
                    284: {
                    285:        register char *cp;
                    286:        register int c;
                    287:        register char *dp;
                    288:        int i;
                    289: 
                    290:        cp = *area;
                    291:        while ((c = *str++) && c != ':') {
                    292:                switch (c) {
                    293: 
                    294:                case '^':
                    295:                        c = *str++ & 037;
                    296:                        break;
                    297: 
                    298:                case '\\':
                    299:                        dp = "E\033^^\\\\::n\nr\rt\tb\bf\f";
                    300:                        c = *str++;
                    301: nextc:
                    302:                        if (*dp++ == c) {
                    303:                                c = *dp++;
                    304:                                break;
                    305:                        }
                    306:                        dp++;
                    307:                        if (*dp)
                    308:                                goto nextc;
                    309:                        if (isdigit(c)) {
                    310:                                c -= '0', i = 2;
                    311:                                do
                    312:                                        c <<= 3, c |= *str++ - '0';
                    313:                                while (--i && isdigit(*str));
                    314:                        }
                    315:                        break;
                    316:                }
                    317:                *cp++ = c;
                    318:        }
                    319:        *cp++ = 0;
                    320:        str = *area;
                    321:        *area = cp;
                    322:        return (str);
                    323: }

unix.superglobalmegacorp.com

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