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

unix.superglobalmegacorp.com

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