Annotation of 42BSD/etc/mkproto.c, revision 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.