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

unix.superglobalmegacorp.com

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