Annotation of 43BSDReno/usr.sbin/mtree/spec.c, revision 1.1.1.1

1.1       root        1: /*-
                      2:  * Copyright (c) 1989 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted provided
                      6:  * that: (1) source distributions retain this entire copyright notice and
                      7:  * comment, and (2) distributions including binaries display the following
                      8:  * acknowledgement:  ``This product includes software developed by the
                      9:  * University of California, Berkeley and its contributors'' in the
                     10:  * documentation or other materials provided with the distribution and in
                     11:  * all advertising materials mentioning features or use of this software.
                     12:  * Neither the name of the University nor the names of its contributors may
                     13:  * be used to endorse or promote products derived from this software without
                     14:  * specific prior written permission.
                     15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     16:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     17:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     18:  */
                     19: 
                     20: #ifndef lint
                     21: static char sccsid[] = "@(#)spec.c     5.12 (Berkeley) 5/25/90";
                     22: #endif /* not lint */
                     23: 
                     24: #include <sys/types.h>
                     25: #include <pwd.h>
                     26: #include <grp.h>
                     27: #include <stdio.h>
                     28: #include <errno.h>
                     29: #include <ctype.h>
                     30: #include "mtree.h"
                     31: 
                     32: extern NODE *root;                     /* root of the tree */
                     33: 
                     34: static int lineno;                     /* current spec line number */
                     35: 
                     36: spec()
                     37: {
                     38:        register NODE *centry, *last;
                     39:        register char *p;
                     40:        NODE ginfo, *emalloc();
                     41:        char buf[2048];
                     42: 
                     43:        bzero((void *)&ginfo, sizeof(ginfo));
                     44:        for (lineno = 1; fgets(buf, sizeof(buf), stdin); ++lineno) {
                     45:                if (!(p = index(buf, '\n'))) {
                     46:                        (void)fprintf(stderr,
                     47:                            "mtree: line %d too long, ignored.\n", lineno);
                     48:                        exit(1);
                     49:                }
                     50:                *p = '\0';
                     51:                for (p = buf; *p && isspace(*p); ++p);
                     52:                if (!*p || *p == '#')
                     53:                        continue;
                     54: 
                     55:                /* grab file name, "$", "set", or "unset" */
                     56:                if (!(p = strtok(p, "\n\t ")))
                     57:                        specerr();
                     58: 
                     59:                if (p[0] == '/')
                     60:                        switch(p[1]) {
                     61:                        case 's':
                     62:                                if (strcmp(p + 1, "set"))
                     63:                                        break;
                     64:                                set(&ginfo);
                     65:                                continue;
                     66:                        case 'u':
                     67:                                if (strncmp(p + 1, "unset"))
                     68:                                        break;
                     69:                                unset(&ginfo);
                     70:                                continue;
                     71:                        }
                     72: 
                     73:                if (index(p, '/')) {
                     74:                        (void)fprintf(stderr,
                     75:                            "mtree: file names may not contain slashes.\n");
                     76:                        specerr();
                     77:                }
                     78: 
                     79:                if (!strcmp(p, "..")) {
                     80:                        /* don't go up, if haven't gone down */
                     81:                        if (!root)
                     82:                                noparent();
                     83:                        if (last->type != F_DIR || last->flags & F_DONE) {
                     84:                                if (last == root)
                     85:                                        noparent();
                     86:                                last = last->parent;
                     87:                        }
                     88:                        last->flags |= F_DONE;
                     89:                        continue;
                     90:                }
                     91: 
                     92:                centry = emalloc(sizeof(NODE) + strlen(p));
                     93:                *centry = ginfo;
                     94:                (void)strcpy(centry->name, p);
                     95: #define        MAGIC   "?*["
                     96:                if (strpbrk(p, MAGIC))
                     97:                        centry->flags |= F_MAGIC;
                     98:                set(centry);
                     99: 
                    100:                if (!root) {
                    101:                        last = root = centry;
                    102:                        root->parent = root;
                    103:                } else if (last->type == F_DIR && !(last->flags & F_DONE)) {
                    104:                        centry->parent = last;
                    105:                        last = last->child = centry;
                    106:                } else {
                    107:                        centry->parent = last->parent;
                    108:                        centry->prev = last;
                    109:                        last = last->next = centry;
                    110:                }
                    111:        }
                    112: }
                    113: 
                    114: set(ip)
                    115:        register NODE *ip;
                    116: {
                    117:        register int type;
                    118:        register char *kw, *val;
                    119:        gid_t getgroup();
                    120:        uid_t getowner();
                    121:        long atol(), strtol();
                    122: 
                    123:        while (kw = strtok((char *)NULL, "= \t\n")) {
                    124:                ip->flags |= type = key(kw);
                    125:                val = strtok((char *)NULL, " \t\n");
                    126:                if (!val)
                    127:                        specerr();
                    128:                switch(type) {
                    129:                case F_CKSUM:
                    130:                        ip->cksum = atol(val);
                    131:                        break;
                    132:                case F_GROUP:
                    133:                        ip->st_gid = getgroup(val);
                    134:                        break;
                    135:                case F_IGN:
                    136:                        /* just set flag bit */
                    137:                        break;
                    138:                case F_MODE: {
                    139:                        mode_t *m, *setmode();
                    140: 
                    141:                        if (!(m = setmode(val))) {
                    142:                                (void)fprintf(stderr,
                    143:                                    "mtree: invalid file mode %s.\n", val);
                    144:                                specerr();
                    145:                        }
                    146:                        ip->st_mode = getmode(m, 0);
                    147:                        break;
                    148:                }
                    149:                case F_NLINK:
                    150:                        ip->st_nlink = atoi(val);
                    151:                        break;
                    152:                case F_OWNER:
                    153:                        ip->st_uid = getowner(val);
                    154:                        break;
                    155:                case F_SIZE:
                    156:                        ip->st_size = atol(val);
                    157:                        break;
                    158:                case F_SLINK:
                    159:                        if (!(ip->slink = strdup(val)))
                    160:                                nomem();
                    161:                        break;
                    162:                case F_TIME:
                    163:                        ip->st_mtime = atol(val);
                    164:                        break;
                    165:                case F_TYPE:
                    166:                        switch(*val) {
                    167:                        case 'b':
                    168:                                if (!strcmp(val, "block"))
                    169:                                        ip->type = F_BLOCK;
                    170:                                break;
                    171:                        case 'c':
                    172:                                if (!strcmp(val, "char"))
                    173:                                        ip->type = F_CHAR;
                    174:                                break;
                    175:                        case 'd':
                    176:                                if (!strcmp(val, "dir"))
                    177:                                        ip->type = F_DIR;
                    178:                                break;
                    179:                        case 'f':
                    180:                                if (!strcmp(val, "file"))
                    181:                                        ip->type = F_FILE;
                    182:                                if (!strcmp(val, "fifo"))
                    183:                                        ip->type = F_FIFO;
                    184:                                break;
                    185:                        case 'l':
                    186:                                if (!strcmp(val, "link"))
                    187:                                        ip->type = F_LINK;
                    188:                                break;
                    189:                        case 's':
                    190:                                if (!strcmp(val, "socket"))
                    191:                                        ip->type = F_SOCK;
                    192:                                break;
                    193:                        default:
                    194:                                (void)fprintf(stderr,
                    195:                                    "mtree: unknown file type %s.\n", val);
                    196:                                specerr();
                    197:                        }
                    198:                        break;
                    199:                }
                    200:        }
                    201: }
                    202: 
                    203: unset(ip)
                    204:        register NODE *ip;
                    205: {
                    206:        register char *p;
                    207: 
                    208:        while (p = strtok((char *)NULL, "\n\t "))
                    209:                ip->flags &= ~key(p);
                    210: }
                    211: 
                    212: key(p)
                    213:        char *p;
                    214: {
                    215:        switch(*p) {
                    216:        case 'c':
                    217:                if (!strcmp(p, "cksum"))
                    218:                        return(F_CKSUM);
                    219:                break;
                    220:        case 'g':
                    221:                if (!strcmp(p, "group"))
                    222:                        return(F_GROUP);
                    223:                break;
                    224:        case 'i':
                    225:                if (!strcmp(p, "ignore"))
                    226:                        return(F_IGN);
                    227:                break;
                    228:        case 'l':
                    229:                if (!strcmp(p, "link"))
                    230:                        return(F_SLINK);
                    231:                break;
                    232:        case 'm':
                    233:                if (!strcmp(p, "mode"))
                    234:                        return(F_MODE);
                    235:                break;
                    236:        case 'n':
                    237:                if (!strcmp(p, "nlink"))
                    238:                        return(F_NLINK);
                    239:                break;
                    240:        case 'o':
                    241:                if (!strcmp(p, "owner"))
                    242:                        return(F_OWNER);
                    243:                break;
                    244:        case 's':
                    245:                if (!strcmp(p, "size"))
                    246:                        return(F_SIZE);
                    247:                break;
                    248:        case 't':
                    249:                if (!strcmp(p, "type"))
                    250:                        return(F_TYPE);
                    251:                if (!strcmp(p, "time"))
                    252:                        return(F_TIME);
                    253:                break;
                    254:        }
                    255:        (void)fprintf(stderr, "mtree: unknown keyword %s.\n", p);
                    256:        specerr();
                    257:        /* NOTREACHED */
                    258: }
                    259: 
                    260: 
                    261: uid_t
                    262: getowner(p)
                    263:        register char *p;
                    264: {
                    265:        struct passwd *pw;
                    266:        int val;
                    267: 
                    268:        if (isdigit(*p)) {
                    269:                if ((val = atoi(p)) >= 0)
                    270:                        return((uid_t)val);
                    271:                (void)fprintf(stderr, "mtree: illegal uid value %s.\n", p);
                    272:        } else if (pw = getpwnam(p))
                    273:                return(pw->pw_uid);
                    274:        else
                    275:                (void)fprintf(stderr, "mtree: unknown user %s.\n", p);
                    276:        specerr();
                    277:        /* NOTREACHED */
                    278: }
                    279: 
                    280: gid_t
                    281: getgroup(p)
                    282:        register char *p;
                    283: {
                    284:        struct group *gr;
                    285:        int val;
                    286: 
                    287:        if (isdigit(*p)) {
                    288:                if ((val = atoi(p)) >= 0)
                    289:                        return((gid_t)val);
                    290:                (void)fprintf(stderr, "mtree: illegal gid value %s.\n", p);
                    291:        } else if (gr = getgrnam(p))
                    292:                return(gr->gr_gid);
                    293:        else
                    294:                (void)fprintf(stderr, "mtree: unknown group %s.\n", p);
                    295:        specerr();
                    296:        /* NOTREACHED */
                    297: }
                    298: 
                    299: noparent()
                    300: {
                    301:        (void)fprintf(stderr, "mtree: no parent node.\n");
                    302:        specerr();
                    303: }
                    304: 
                    305: specerr()
                    306: {
                    307:        (void)fprintf(stderr,
                    308:            "mtree: line %d of the specification is incorrect.\n", lineno);
                    309:        exit(1);
                    310: }
                    311: 
                    312: NODE *
                    313: emalloc(size)
                    314:        int size;
                    315: {
                    316:        void *p;
                    317: 
                    318:        /* NOSTRICT */
                    319:        if (!(p = malloc((u_int)size)))
                    320:                nomem();
                    321:        bzero(p, size);
                    322:        return((NODE *)p);
                    323: }
                    324: 
                    325: nomem()
                    326: {
                    327:        (void)fprintf(stderr, "mtree: %s.\n", strerror(ENOMEM));
                    328:        exit(1);
                    329: }

unix.superglobalmegacorp.com

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