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