Annotation of 43BSD/etc/getty/gettytab.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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