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

unix.superglobalmegacorp.com

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