Annotation of 43BSD/etc/mkproto.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1983 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: char copyright[] =
                      9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
                     10:  All rights reserved.\n";
                     11: #endif not lint
                     12: 
                     13: #ifndef lint
                     14: static char sccsid[] = "@(#)mkproto.c  5.1 (Berkeley) 5/28/85";
                     15: #endif not lint
                     16: 
                     17: /*
                     18:  * Make a file system prototype.
                     19:  * usage: mkproto filsys proto
                     20:  */
                     21: #include <stdio.h>
                     22: #include <sys/param.h>
                     23: #include <sys/inode.h>
                     24: #include <sys/fs.h>
                     25: #include <sys/dir.h>
                     26: 
                     27: union {
                     28:        struct  fs fs;
                     29:        char    fsx[SBSIZE];
                     30: } ufs;
                     31: #define sblock ufs.fs
                     32: union {
                     33:        struct  cg cg;
                     34:        char    cgx[MAXBSIZE];
                     35: } ucg;
                     36: #define        acg     ucg.cg
                     37: struct fs *fs;
                     38: struct csum *fscs;
                     39: int    fso, fsi;
                     40: FILE   *proto;
                     41: char   token[BUFSIZ];
                     42: int    errs;
                     43: int    ino = 10;
                     44: long   getnum();
                     45: char   *strcpy();
                     46: 
                     47: main(argc, argv)
                     48:        int argc;
                     49:        char *argv[];
                     50: {
                     51:        int i;
                     52: 
                     53:        if (argc != 3) {
                     54:                fprintf(stderr, "usage: mkproto filsys proto\n");
                     55:                exit(1);
                     56:        }
                     57:        fso = open(argv[1], 1);
                     58:        fsi = open(argv[1], 0);
                     59:        if (fso < 0 || fsi < 0) {
                     60:                perror(argv[1]);
                     61:                exit(1);
                     62:        }
                     63:        fs = &sblock;
                     64:        rdfs(SBLOCK, SBSIZE, (char *)fs);
                     65:        fscs = (struct csum *)calloc(1, fs->fs_cssize);
                     66:        for (i = 0; i < fs->fs_cssize; i += fs->fs_bsize)
                     67:                rdfs(fsbtodb(fs, fs->fs_csaddr + numfrags(fs, i)),
                     68:                        (int)(fs->fs_cssize - i < fs->fs_bsize ?
                     69:                            fs->fs_cssize - i : fs->fs_bsize),
                     70:                        ((char *)fscs) + i);
                     71:        proto = fopen(argv[2], "r");
                     72:        descend((struct inode *)0);
                     73:        wtfs(SBLOCK, SBSIZE, (char *)fs);
                     74:        for (i = 0; i < fs->fs_cssize; i += fs->fs_bsize)
                     75:                wtfs(fsbtodb(&sblock, fs->fs_csaddr + numfrags(&sblock, i)),
                     76:                        (int)(fs->fs_cssize - i < fs->fs_bsize ?
                     77:                            fs->fs_cssize - i : fs->fs_bsize),
                     78:                        ((char *)fscs) + i);
                     79:        exit(errs);
                     80: }
                     81: 
                     82: descend(par)
                     83:        struct inode *par;
                     84: {
                     85:        struct inode in;
                     86:        int ibc = 0;
                     87:        int i, f, c;
                     88:        struct dinode *dip, inos[MAXBSIZE / sizeof (struct dinode)];
                     89:        daddr_t ib[MAXBSIZE / sizeof (daddr_t)];
                     90:        char buf[MAXBSIZE];
                     91: 
                     92:        getstr();
                     93:        in.i_mode = gmode(token[0], "-bcd", IFREG, IFBLK, IFCHR, IFDIR);
                     94:        in.i_mode |= gmode(token[1], "-u", 0, ISUID, 0, 0);
                     95:        in.i_mode |= gmode(token[2], "-g", 0, ISGID, 0, 0);
                     96:        for (i = 3; i < 6; i++) {
                     97:                c = token[i];
                     98:                if (c < '0' || c > '7') {
                     99:                        printf("%c/%s: bad octal mode digit\n", c, token);
                    100:                        errs++;
                    101:                        c = 0;
                    102:                }
                    103:                in.i_mode |= (c-'0')<<(15-3*i);
                    104:        }
                    105:        in.i_uid = getnum(); in.i_gid = getnum();
                    106:        for (i = 0; i < fs->fs_bsize; i++)
                    107:                buf[i] = 0;
                    108:        for (i = 0; i < NINDIR(fs); i++)
                    109:                ib[i] = (daddr_t)0;
                    110:        in.i_nlink = 1;
                    111:        in.i_size = 0;
                    112:        for (i = 0; i < NDADDR; i++)
                    113:                in.i_db[i] = (daddr_t)0;
                    114:        for (i = 0; i < NIADDR; i++)
                    115:                in.i_ib[i] = (daddr_t)0;
                    116:        if (par != (struct inode *)0) {
                    117:                ialloc(&in);
                    118:        } else {
                    119:                par = &in;
                    120:                i = itod(fs, ROOTINO);
                    121:                rdfs(fsbtodb(fs, i), fs->fs_bsize, (char *)inos);
                    122:                dip = &inos[ROOTINO % INOPB(fs)];
                    123:                in.i_number = ROOTINO;
                    124:                in.i_nlink = dip->di_nlink;
                    125:                in.i_size = dip->di_size;
                    126:                in.i_db[0] = dip->di_db[0];
                    127:                rdfs(fsbtodb(fs, in.i_db[0]), fs->fs_bsize, buf);
                    128:        }
                    129: 
                    130:        switch (in.i_mode&IFMT) {
                    131: 
                    132:        case IFREG:
                    133:                getstr();
                    134:                f = open(token, 0);
                    135:                if (f < 0) {
                    136:                        printf("%s: cannot open\n", token);
                    137:                        errs++;
                    138:                        break;
                    139:                }
                    140:                while ((i = read(f, buf, (int)fs->fs_bsize)) > 0) {
                    141:                        in.i_size += i;
                    142:                        newblk(buf, &ibc, ib, (int)blksize(fs, &in, ibc));
                    143:                }
                    144:                close(f);
                    145:                break;
                    146: 
                    147:        case IFBLK:
                    148:        case IFCHR:
                    149:                /*
                    150:                 * special file
                    151:                 * content is maj/min types
                    152:                 */
                    153: 
                    154:                i = getnum() & 0377;
                    155:                f = getnum() & 0377;
                    156:                in.i_rdev = (i << 8) | f;
                    157:                break;
                    158: 
                    159:        case IFDIR:
                    160:                /*
                    161:                 * directory
                    162:                 * put in extra links
                    163:                 * call recursively until
                    164:                 * name of "$" found
                    165:                 */
                    166: 
                    167:                if (in.i_number != ROOTINO) {
                    168:                        par->i_nlink++;
                    169:                        in.i_nlink++;
                    170:                        entry(&in, in.i_number, ".", buf);
                    171:                        entry(&in, par->i_number, "..", buf);
                    172:                }
                    173:                for (;;) {
                    174:                        getstr();
                    175:                        if (token[0]=='$' && token[1]=='\0')
                    176:                                break;
                    177:                        entry(&in, (ino_t)(ino+1), token, buf);
                    178:                        descend(&in);
                    179:                }
                    180:                if (in.i_number != ROOTINO)
                    181:                        newblk(buf, &ibc, ib, (int)blksize(fs, &in, 0));
                    182:                else
                    183:                        wtfs(fsbtodb(fs, in.i_db[0]), (int)fs->fs_bsize, buf);
                    184:                break;
                    185:        }
                    186:        iput(&in, &ibc, ib);
                    187: }
                    188: 
                    189: /*ARGSUSED*/
                    190: gmode(c, s, m0, m1, m2, m3)
                    191:        char c, *s;
                    192: {
                    193:        int i;
                    194: 
                    195:        for (i = 0; s[i]; i++)
                    196:                if (c == s[i])
                    197:                        return((&m0)[i]);
                    198:        printf("%c/%s: bad mode\n", c, token);
                    199:        errs++;
                    200:        return(0);
                    201: }
                    202: 
                    203: long
                    204: getnum()
                    205: {
                    206:        int i, c;
                    207:        long n;
                    208: 
                    209:        getstr();
                    210:        n = 0;
                    211:        i = 0;
                    212:        for (i = 0; c=token[i]; i++) {
                    213:                if (c<'0' || c>'9') {
                    214:                        printf("%s: bad number\n", token);
                    215:                        errs++;
                    216:                        return((long)0);
                    217:                }
                    218:                n = n*10 + (c-'0');
                    219:        }
                    220:        return(n);
                    221: }
                    222: 
                    223: getstr()
                    224: {
                    225:        int i, c;
                    226: 
                    227: loop:
                    228:        switch (c = getc(proto)) {
                    229: 
                    230:        case ' ':
                    231:        case '\t':
                    232:        case '\n':
                    233:                goto loop;
                    234: 
                    235:        case EOF:
                    236:                printf("Unexpected EOF\n");
                    237:                exit(1);
                    238: 
                    239:        case ':':
                    240:                while (getc(proto) != '\n')
                    241:                        ;
                    242:                goto loop;
                    243: 
                    244:        }
                    245:        i = 0;
                    246:        do {
                    247:                token[i++] = c;
                    248:                c = getc(proto);
                    249:        } while (c != ' ' && c != '\t' && c != '\n' && c != '\0');
                    250:        token[i] = 0;
                    251: }
                    252: 
                    253: entry(ip, inum, str, buf)
                    254:        struct inode *ip;
                    255:        ino_t inum;
                    256:        char *str;
                    257:        char *buf;
                    258: {
                    259:        register struct direct *dp, *odp;
                    260:        int oldsize, newsize, spacefree;
                    261: 
                    262:        odp = dp = (struct direct *)buf;
                    263:        while ((int)dp - (int)buf < ip->i_size) {
                    264:                odp = dp;
                    265:                dp = (struct direct *)((int)dp + dp->d_reclen);
                    266:        }
                    267:        if (odp != dp)
                    268:                oldsize = DIRSIZ(odp);
                    269:        else
                    270:                oldsize = 0;
                    271:        spacefree = odp->d_reclen - oldsize;
                    272:        dp = (struct direct *)((int)odp + oldsize);
                    273:        dp->d_ino = inum;
                    274:        dp->d_namlen = strlen(str);
                    275:        newsize = DIRSIZ(dp);
                    276:        if (spacefree >= newsize) {
                    277:                odp->d_reclen = oldsize;
                    278:                dp->d_reclen = spacefree;
                    279:        } else {
                    280:                dp = (struct direct *)((int)odp + odp->d_reclen);
                    281:                if ((int)dp - (int)buf >= fs->fs_bsize) {
                    282:                        printf("directory too large\n");
                    283:                        exit(1);
                    284:                }
                    285:                dp->d_ino = inum;
                    286:                dp->d_namlen = strlen(str);
                    287:                dp->d_reclen = DIRBLKSIZ;
                    288:        }
                    289:        strcpy(dp->d_name, str);
                    290:        ip->i_size = (int)dp - (int)buf + newsize;
                    291: }
                    292: 
                    293: newblk(buf, aibc, ib, size)
                    294:        int *aibc;
                    295:        char *buf;
                    296:        daddr_t *ib;
                    297:        int size;
                    298: {
                    299:        int i;
                    300:        daddr_t bno;
                    301: 
                    302:        bno = alloc(size);
                    303:        wtfs(fsbtodb(fs, bno), (int)fs->fs_bsize, buf);
                    304:        for (i = 0; i < fs->fs_bsize; i++)
                    305:                buf[i] = 0;
                    306:        ib[(*aibc)++] = bno;
                    307:        if (*aibc >= NINDIR(fs)) {
                    308:                printf("indirect block full\n");
                    309:                errs++;
                    310:                *aibc = 0;
                    311:        }
                    312: }
                    313: 
                    314: iput(ip, aibc, ib)
                    315:        struct inode *ip;
                    316:        int *aibc;
                    317:        daddr_t *ib;
                    318: {
                    319:        daddr_t d;
                    320:        int i;
                    321:        struct dinode buf[MAXBSIZE / sizeof (struct dinode)];
                    322: 
                    323:        ip->i_atime = ip->i_mtime = ip->i_ctime = time((long *)0);
                    324:        switch (ip->i_mode&IFMT) {
                    325: 
                    326:        case IFDIR:
                    327:        case IFREG:
                    328:                for (i = 0; i < *aibc; i++) {
                    329:                        if (i >= NDADDR)
                    330:                                break;
                    331:                        ip->i_db[i] = ib[i];
                    332:                }
                    333:                if (*aibc > NDADDR) {
                    334:                        ip->i_ib[0] = alloc((int)fs->fs_bsize);
                    335:                        for (i = 0; i < NINDIR(fs) - NDADDR; i++) {
                    336:                                ib[i] = ib[i+NDADDR];
                    337:                                ib[i+NDADDR] = (daddr_t)0;
                    338:                        }
                    339:                        wtfs(fsbtodb(fs, ip->i_ib[0]),
                    340:                            (int)fs->fs_bsize, (char *)ib);
                    341:                }
                    342:                break;
                    343: 
                    344:        case IFBLK:
                    345:        case IFCHR:
                    346:                break;
                    347: 
                    348:        default:
                    349:                printf("bad mode %o\n", ip->i_mode);
                    350:                exit(1);
                    351:        }
                    352:        d = fsbtodb(fs, itod(fs, ip->i_number));
                    353:        rdfs(d, (int)fs->fs_bsize, (char *)buf);
                    354:        buf[itoo(fs, ip->i_number)].di_ic = ip->i_ic;
                    355:        wtfs(d, (int)fs->fs_bsize, (char *)buf);
                    356: }
                    357: 
                    358: daddr_t
                    359: alloc(size)
                    360:        int size;
                    361: {
                    362:        int i, frag;
                    363:        daddr_t d;
                    364:        static int cg = 0;
                    365: 
                    366: again:
                    367:        rdfs(fsbtodb(&sblock, cgtod(&sblock, cg)), (int)sblock.fs_cgsize,
                    368:            (char *)&acg);
                    369:        if (acg.cg_magic != CG_MAGIC) {
                    370:                printf("cg %d: bad magic number\n", cg);
                    371:                return (0);
                    372:        }
                    373:        if (acg.cg_cs.cs_nbfree == 0) {
                    374:                cg++;
                    375:                if (cg >= fs->fs_ncg) {
                    376:                        printf("ran out of space\n");
                    377:                        return (0);
                    378:                }
                    379:                goto again;
                    380:        }
                    381:        for (d = 0; d < acg.cg_ndblk; d += sblock.fs_frag)
                    382:                if (isblock(&sblock, (u_char *)acg.cg_free, d / sblock.fs_frag))
                    383:                        goto goth;
                    384:        printf("internal error: can't find block in cyl %d\n", cg);
                    385:        return (0);
                    386: goth:
                    387:        clrblock(&sblock, (u_char *)acg.cg_free, d / sblock.fs_frag);
                    388:        acg.cg_cs.cs_nbfree--;
                    389:        sblock.fs_cstotal.cs_nbfree--;
                    390:        fscs[cg].cs_nbfree--;
                    391:        acg.cg_btot[cbtocylno(&sblock, d)]--;
                    392:        acg.cg_b[cbtocylno(&sblock, d)][cbtorpos(&sblock, d)]--;
                    393:        if (size != sblock.fs_bsize) {
                    394:                frag = howmany(size, sblock.fs_fsize);
                    395:                fscs[cg].cs_nffree += sblock.fs_frag - frag;
                    396:                sblock.fs_cstotal.cs_nffree += sblock.fs_frag - frag;
                    397:                acg.cg_cs.cs_nffree += sblock.fs_frag - frag;
                    398:                acg.cg_frsum[sblock.fs_frag - frag]++;
                    399:                for (i = frag; i < sblock.fs_frag; i++)
                    400:                        setbit(acg.cg_free, d + i);
                    401:        }
                    402:        wtfs(fsbtodb(&sblock, cgtod(&sblock, cg)), (int)sblock.fs_cgsize,
                    403:            (char *)&acg);
                    404:        return (acg.cg_cgx * fs->fs_fpg + d);
                    405: }
                    406: 
                    407: /*
                    408:  * Allocate an inode on the disk
                    409:  */
                    410: ialloc(ip)
                    411:        register struct inode *ip;
                    412: {
                    413:        struct dinode buf[MAXBSIZE / sizeof (struct dinode)];
                    414:        daddr_t d;
                    415:        int c;
                    416: 
                    417:        ip->i_number = ++ino;
                    418:        c = itog(&sblock, ip->i_number);
                    419:        rdfs(fsbtodb(&sblock, cgtod(&sblock, c)), (int)sblock.fs_cgsize,
                    420:            (char *)&acg);
                    421:        if (acg.cg_magic != CG_MAGIC) {
                    422:                printf("cg %d: bad magic number\n", c);
                    423:                exit(1);
                    424:        }
                    425:        if (ip->i_mode & IFDIR) {
                    426:                acg.cg_cs.cs_ndir++;
                    427:                sblock.fs_cstotal.cs_ndir++;
                    428:                fscs[c].cs_ndir++;
                    429:        }
                    430:        acg.cg_cs.cs_nifree--;
                    431:        setbit(acg.cg_iused, ip->i_number);
                    432:        wtfs(fsbtodb(&sblock, cgtod(&sblock, c)), (int)sblock.fs_cgsize,
                    433:            (char *)&acg);
                    434:        sblock.fs_cstotal.cs_nifree--;
                    435:        fscs[c].cs_nifree--;
                    436:        if(ip->i_number >= sblock.fs_ipg * sblock.fs_ncg) {
                    437:                printf("fsinit: inode value out of range (%d).\n",
                    438:                    ip->i_number);
                    439:                exit(1);
                    440:        }
                    441:        return (ip->i_number);
                    442: }
                    443: 
                    444: /*
                    445:  * read a block from the file system
                    446:  */
                    447: rdfs(bno, size, bf)
                    448:        int bno, size;
                    449:        char *bf;
                    450: {
                    451:        int n;
                    452: 
                    453:        if (lseek(fsi, bno * DEV_BSIZE, 0) < 0) {
                    454:                printf("seek error: %ld\n", bno);
                    455:                perror("rdfs");
                    456:                exit(1);
                    457:        }
                    458:        n = read(fsi, bf, size);
                    459:        if(n != size) {
                    460:                printf("read error: %ld\n", bno);
                    461:                perror("rdfs");
                    462:                exit(1);
                    463:        }
                    464: }
                    465: 
                    466: /*
                    467:  * write a block to the file system
                    468:  */
                    469: wtfs(bno, size, bf)
                    470:        int bno, size;
                    471:        char *bf;
                    472: {
                    473:        int n;
                    474: 
                    475:        lseek(fso, bno * DEV_BSIZE, 0);
                    476:        if (lseek(fso, bno * DEV_BSIZE, 0) < 0) {
                    477:                printf("seek error: %ld\n", bno);
                    478:                perror("wtfs");
                    479:                exit(1);
                    480:        }
                    481:        n = write(fso, bf, size);
                    482:        if(n != size) {
                    483:                printf("write error: %D\n", bno);
                    484:                perror("wtfs");
                    485:                exit(1);
                    486:        }
                    487: }
                    488: /*
                    489:  * check if a block is available
                    490:  */
                    491: isblock(fs, cp, h)
                    492:        struct fs *fs;
                    493:        unsigned char *cp;
                    494:        int h;
                    495: {
                    496:        unsigned char mask;
                    497: 
                    498:        switch (fs->fs_frag) {
                    499:        case 8:
                    500:                return (cp[h] == 0xff);
                    501:        case 4:
                    502:                mask = 0x0f << ((h & 0x1) << 2);
                    503:                return ((cp[h >> 1] & mask) == mask);
                    504:        case 2:
                    505:                mask = 0x03 << ((h & 0x3) << 1);
                    506:                return ((cp[h >> 2] & mask) == mask);
                    507:        case 1:
                    508:                mask = 0x01 << (h & 0x7);
                    509:                return ((cp[h >> 3] & mask) == mask);
                    510:        default:
                    511:                fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag);
                    512:                return (0);
                    513:        }
                    514:        /*NOTREACHED*/
                    515: }
                    516: 
                    517: /*
                    518:  * take a block out of the map
                    519:  */
                    520: clrblock(fs, cp, h)
                    521:        struct fs *fs;
                    522:        unsigned char *cp;
                    523:        int h;
                    524: {
                    525:        switch ((fs)->fs_frag) {
                    526:        case 8:
                    527:                cp[h] = 0;
                    528:                return;
                    529:        case 4:
                    530:                cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
                    531:                return;
                    532:        case 2:
                    533:                cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
                    534:                return;
                    535:        case 1:
                    536:                cp[h >> 3] &= ~(0x01 << (h & 0x7));
                    537:                return;
                    538:        default:
                    539:                fprintf(stderr, "clrblock bad fs_frag %d\n", fs->fs_frag);
                    540:                return;
                    541:        }
                    542: }
                    543: 

unix.superglobalmegacorp.com

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