Annotation of 42BSD/lib/libc/vax/gen/disktab.c, revision 1.1.1.1

1.1       root        1: /*     @(#)disktab.c   4.2 (Berkeley) 2/8/83   */
                      2: 
                      3: #include <disktab.h>
                      4: #include <stdio.h>
                      5: 
                      6: static char *dgetstr();
                      7: 
                      8: struct disktab *
                      9: getdiskbyname(name)
                     10:        char *name;
                     11: {
                     12:        static struct disktab disk;
                     13:        static char localbuf[100], *cp = localbuf;
                     14:        register struct disktab *dp = &disk;
                     15:        register struct partition *pp;
                     16:        char p, psize[3], pbsize[3], pfsize[3];
                     17:        char buf[BUFSIZ];
                     18: 
                     19:        if (dgetent(buf, name) <= 0)
                     20:                return ((struct disktab *)0);
                     21:        dp->d_name = cp;
                     22:        strcpy(cp, name);
                     23:        cp += strlen(name) + 1;
                     24:        dp->d_type = dgetstr("ty", &cp);
                     25:        dp->d_secsize = dgetnum("se");
                     26:        if (dp->d_secsize < 0)
                     27:                dp->d_secsize = 512;
                     28:        dp->d_ntracks = dgetnum("nt");
                     29:        dp->d_nsectors = dgetnum("ns");
                     30:        dp->d_ncylinders = dgetnum("nc");
                     31:        dp->d_rpm = dgetnum("rm");
                     32:        if (dp->d_rpm < 0)
                     33:                dp->d_rpm = 3600;
                     34:        strcpy(psize, "px");
                     35:        strcpy(pbsize, "bx");
                     36:        strcpy(pfsize, "fx");
                     37:        for (p = 'a'; p < 'i'; p++) {
                     38:                psize[1] = pbsize[1] = pfsize[1] = p;
                     39:                pp = &dp->d_partitions[p - 'a'];
                     40:                pp->p_size = dgetnum(psize);
                     41:                pp->p_bsize = dgetnum(pbsize);
                     42:                pp->p_fsize = dgetnum(pfsize);
                     43:        }
                     44:        return (dp);
                     45: }
                     46: 
                     47: #include <ctype.h>
                     48: 
                     49: static char *tbuf;
                     50: static char *dskip();
                     51: static char *ddecode();
                     52: 
                     53: /*
                     54:  * Get an entry for disk name in buffer bp,
                     55:  * from the diskcap file.  Parse is very rudimentary;
                     56:  * we just notice escaped newlines.
                     57:  */
                     58: static
                     59: dgetent(bp, name)
                     60:        char *bp, *name;
                     61: {
                     62:        register char *cp;
                     63:        register int c;
                     64:        register int i = 0, cnt = 0;
                     65:        char ibuf[BUFSIZ];
                     66:        int tf;
                     67: 
                     68:        tbuf = bp;
                     69:        tf = open(DISKTAB, 0);
                     70:        if (tf < 0)
                     71:                return (-1);
                     72:        for (;;) {
                     73:                cp = bp;
                     74:                for (;;) {
                     75:                        if (i == cnt) {
                     76:                                cnt = read(tf, ibuf, BUFSIZ);
                     77:                                if (cnt <= 0) {
                     78:                                        close(tf);
                     79:                                        return (0);
                     80:                                }
                     81:                                i = 0;
                     82:                        }
                     83:                        c = ibuf[i++];
                     84:                        if (c == '\n') {
                     85:                                if (cp > bp && cp[-1] == '\\'){
                     86:                                        cp--;
                     87:                                        continue;
                     88:                                }
                     89:                                break;
                     90:                        }
                     91:                        if (cp >= bp+BUFSIZ) {
                     92:                                write(2,"Disktab entry too long\n", 23);
                     93:                                break;
                     94:                        } else
                     95:                                *cp++ = c;
                     96:                }
                     97:                *cp = 0;
                     98: 
                     99:                /*
                    100:                 * The real work for the match.
                    101:                 */
                    102:                if (dnamatch(name)) {
                    103:                        close(tf);
                    104:                        return (1);
                    105:                }
                    106:        }
                    107: }
                    108: 
                    109: /*
                    110:  * Dnamatch deals with name matching.  The first field of the disktab
                    111:  * entry is a sequence of names separated by |'s, so we compare
                    112:  * against each such name.  The normal : terminator after the last
                    113:  * name (before the first field) stops us.
                    114:  */
                    115: static
                    116: dnamatch(np)
                    117:        char *np;
                    118: {
                    119:        register char *Np, *Bp;
                    120: 
                    121:        Bp = tbuf;
                    122:        if (*Bp == '#')
                    123:                return (0);
                    124:        for (;;) {
                    125:                for (Np = np; *Np && *Bp == *Np; Bp++, Np++)
                    126:                        continue;
                    127:                if (*Np == 0 && (*Bp == '|' || *Bp == ':' || *Bp == 0))
                    128:                        return (1);
                    129:                while (*Bp && *Bp != ':' && *Bp != '|')
                    130:                        Bp++;
                    131:                if (*Bp == 0 || *Bp == ':')
                    132:                        return (0);
                    133:                Bp++;
                    134:        }
                    135: }
                    136: 
                    137: /*
                    138:  * Skip to the next field.  Notice that this is very dumb, not
                    139:  * knowing about \: escapes or any such.  If necessary, :'s can be put
                    140:  * into the diskcap file in octal.
                    141:  */
                    142: static char *
                    143: dskip(bp)
                    144:        register char *bp;
                    145: {
                    146: 
                    147:        while (*bp && *bp != ':')
                    148:                bp++;
                    149:        if (*bp == ':')
                    150:                bp++;
                    151:        return (bp);
                    152: }
                    153: 
                    154: /*
                    155:  * Return the (numeric) option id.
                    156:  * Numeric options look like
                    157:  *     li#80
                    158:  * i.e. the option string is separated from the numeric value by
                    159:  * a # character.  If the option is not found we return -1.
                    160:  * Note that we handle octal numbers beginning with 0.
                    161:  */
                    162: static
                    163: dgetnum(id)
                    164:        char *id;
                    165: {
                    166:        register int i, base;
                    167:        register char *bp = tbuf;
                    168: 
                    169:        for (;;) {
                    170:                bp = dskip(bp);
                    171:                if (*bp == 0)
                    172:                        return (-1);
                    173:                if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
                    174:                        continue;
                    175:                if (*bp == '@')
                    176:                        return (-1);
                    177:                if (*bp != '#')
                    178:                        continue;
                    179:                bp++;
                    180:                base = 10;
                    181:                if (*bp == '0')
                    182:                        base = 8;
                    183:                i = 0;
                    184:                while (isdigit(*bp))
                    185:                        i *= base, i += *bp++ - '0';
                    186:                return (i);
                    187:        }
                    188: }
                    189: 
                    190: /*
                    191:  * Handle a flag option.
                    192:  * Flag options are given "naked", i.e. followed by a : or the end
                    193:  * of the buffer.  Return 1 if we find the option, or 0 if it is
                    194:  * not given.
                    195:  */
                    196: static
                    197: dgetflag(id)
                    198:        char *id;
                    199: {
                    200:        register char *bp = tbuf;
                    201: 
                    202:        for (;;) {
                    203:                bp = dskip(bp);
                    204:                if (!*bp)
                    205:                        return (0);
                    206:                if (*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) {
                    207:                        if (!*bp || *bp == ':')
                    208:                                return (1);
                    209:                        else if (*bp == '@')
                    210:                                return (0);
                    211:                }
                    212:        }
                    213: }
                    214: 
                    215: /*
                    216:  * Get a string valued option.
                    217:  * These are given as
                    218:  *     cl=^Z
                    219:  * Much decoding is done on the strings, and the strings are
                    220:  * placed in area, which is a ref parameter which is updated.
                    221:  * No checking on area overflow.
                    222:  */
                    223: static char *
                    224: dgetstr(id, area)
                    225:        char *id, **area;
                    226: {
                    227:        register char *bp = tbuf;
                    228: 
                    229:        for (;;) {
                    230:                bp = dskip(bp);
                    231:                if (!*bp)
                    232:                        return (0);
                    233:                if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
                    234:                        continue;
                    235:                if (*bp == '@')
                    236:                        return (0);
                    237:                if (*bp != '=')
                    238:                        continue;
                    239:                bp++;
                    240:                return (ddecode(bp, area));
                    241:        }
                    242: }
                    243: 
                    244: /*
                    245:  * Tdecode does the grung work to decode the
                    246:  * string capability escapes.
                    247:  */
                    248: static char *
                    249: ddecode(str, area)
                    250:        register char *str;
                    251:        char **area;
                    252: {
                    253:        register char *cp;
                    254:        register int c;
                    255:        register char *dp;
                    256:        int i;
                    257: 
                    258:        cp = *area;
                    259:        while ((c = *str++) && c != ':') {
                    260:                switch (c) {
                    261: 
                    262:                case '^':
                    263:                        c = *str++ & 037;
                    264:                        break;
                    265: 
                    266:                case '\\':
                    267:                        dp = "E\033^^\\\\::n\nr\rt\tb\bf\f";
                    268:                        c = *str++;
                    269: nextc:
                    270:                        if (*dp++ == c) {
                    271:                                c = *dp++;
                    272:                                break;
                    273:                        }
                    274:                        dp++;
                    275:                        if (*dp)
                    276:                                goto nextc;
                    277:                        if (isdigit(c)) {
                    278:                                c -= '0', i = 2;
                    279:                                do
                    280:                                        c <<= 3, c |= *str++ - '0';
                    281:                                while (--i && isdigit(*str));
                    282:                        }
                    283:                        break;
                    284:                }
                    285:                *cp++ = c;
                    286:        }
                    287:        *cp++ = 0;
                    288:        str = *area;
                    289:        *area = cp;
                    290:        return (str);
                    291: }

unix.superglobalmegacorp.com

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