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

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

unix.superglobalmegacorp.com

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