Annotation of 43BSDTahoe/etc/ncheck.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1980 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[] = "@(#)ncheck.c   5.7 (Berkeley) 5/2/88";
                     15: #endif not lint
                     16: 
                     17: /*
                     18:  * ncheck -- obtain file names from reading filesystem
                     19:  */
                     20: 
                     21: #define        NB              500
                     22: #define        MAXNINDIR       (MAXBSIZE / sizeof (daddr_t))
                     23: 
                     24: #include <sys/param.h>
                     25: #include <sys/inode.h>
                     26: #include <sys/fs.h>
                     27: #include <sys/dir.h>
                     28: #include <stdio.h>
                     29: 
                     30: struct fs      sblock;
                     31: struct dinode  itab[MAXBSIZE/sizeof(struct dinode)];
                     32: struct         dinode  *gip;
                     33: struct ilist {
                     34:        ino_t   ino;
                     35:        u_short mode;
                     36:        short   uid;
                     37:        short   gid;
                     38: } ilist[NB];
                     39: struct htab
                     40: {
                     41:        ino_t   h_ino;
                     42:        ino_t   h_pino;
                     43:        char    *h_name;
                     44: } *htab;
                     45: char *strngtab;
                     46: long hsize;
                     47: int strngloc;
                     48: 
                     49: struct dirstuff {
                     50:        int loc;
                     51:        struct dinode *ip;
                     52:        char dbuf[MAXBSIZE];
                     53: };
                     54: 
                     55: int    aflg;
                     56: int    sflg;
                     57: int    iflg; /* number of inodes being searched for */
                     58: int    mflg;
                     59: int    fi;
                     60: ino_t  ino;
                     61: int    nhent;
                     62: int    nxfile;
                     63: long   dev_bsize = 1;
                     64: 
                     65: int    nerror;
                     66: daddr_t        bmap();
                     67: long   atol();
                     68: struct htab *lookup();
                     69: 
                     70: main(argc, argv)
                     71:        int argc;
                     72:        char *argv[];
                     73: {
                     74:        register i;
                     75:        long n;
                     76: 
                     77:        while (--argc) {
                     78:                argv++;
                     79:                if (**argv=='-')
                     80:                switch ((*argv)[1]) {
                     81: 
                     82:                case 'a':
                     83:                        aflg++;
                     84:                        continue;
                     85: 
                     86:                case 'i':
                     87:                        for(iflg=0; iflg<NB; iflg++) {
                     88:                                n = atol(argv[1]);
                     89:                                if(n == 0)
                     90:                                        break;
                     91:                                ilist[iflg].ino = n;
                     92:                                nxfile = iflg;
                     93:                                argv++;
                     94:                                argc--;
                     95:                        }
                     96:                        continue;
                     97: 
                     98:                case 'm':
                     99:                        mflg++;
                    100:                        continue;
                    101: 
                    102:                case 's':
                    103:                        sflg++;
                    104:                        continue;
                    105: 
                    106:                default:
                    107:                        fprintf(stderr, "ncheck: bad flag %c\n", (*argv)[1]);
                    108:                        nerror++;
                    109:                }
                    110:                check(*argv);
                    111:        }
                    112:        return(nerror);
                    113: }
                    114: 
                    115: check(file)
                    116:        char *file;
                    117: {
                    118:        register int i, j, c;
                    119:        int nfiles;
                    120: 
                    121:        fi = open(file, 0);
                    122:        if(fi < 0) {
                    123:                fprintf(stderr, "ncheck: cannot open %s\n", file);
                    124:                nerror++;
                    125:                return;
                    126:        }
                    127:        nhent = 0;
                    128:        printf("%s:\n", file);
                    129:        sync();
                    130:        bread(SBOFF, (char *)&sblock, SBSIZE);
                    131:        if (sblock.fs_magic != FS_MAGIC) {
                    132:                printf("%s: not a file system\n", file);
                    133:                nerror++;
                    134:                return;
                    135:        }
                    136:        dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1);
                    137:        hsize = sblock.fs_ipg * sblock.fs_ncg - sblock.fs_cstotal.cs_nifree + 1;
                    138:        htab = (struct htab *)malloc(hsize * sizeof(struct htab));
                    139:        strngtab = (char *)malloc(30 * hsize);
                    140:        if (htab == 0 || strngtab == 0) {
                    141:                printf("not enough memory to allocate tables\n");
                    142:                nerror++;
                    143:                return;
                    144:        }
                    145:        ino = 0;
                    146:        for (c = 0; c < sblock.fs_ncg; c++) {
                    147:                for (i = 0;
                    148:                     i < sblock.fs_ipg / INOPF(&sblock);
                    149:                     i += sblock.fs_frag) {
                    150:                        bread(fsbtodb(&sblock, cgimin(&sblock, c) + i),
                    151:                            (char *)itab, sblock.fs_bsize);
                    152:                        for (j = 0; j < INOPB(&sblock); j++) {
                    153:                                if (itab[j].di_mode != 0)
                    154:                                        pass1(&itab[j]);
                    155:                                ino++;
                    156:                        }
                    157:                }
                    158:        }
                    159:        ilist[nxfile+1].ino = 0;
                    160:        ino = 0;
                    161:        for (c = 0; c < sblock.fs_ncg; c++) {
                    162:                for (i = 0;
                    163:                     i < sblock.fs_ipg / INOPF(&sblock);
                    164:                     i += sblock.fs_frag) {
                    165:                        bread(fsbtodb(&sblock, cgimin(&sblock, c) + i),
                    166:                            (char *)itab, sblock.fs_bsize);
                    167:                        for (j = 0; j < INOPB(&sblock); j++) {
                    168:                                if (itab[j].di_mode != 0)
                    169:                                        pass2(&itab[j]);
                    170:                                ino++;
                    171:                        }
                    172:                }
                    173:        }
                    174:        ino = 0;
                    175:        for (c = 0; c < sblock.fs_ncg; c++) {
                    176:                for (i = 0;
                    177:                     i < sblock.fs_ipg / INOPF(&sblock);
                    178:                     i += sblock.fs_frag) {
                    179:                        bread(fsbtodb(&sblock, cgimin(&sblock, c) + i),
                    180:                            (char *)itab, sblock.fs_bsize);
                    181:                        for (j = 0; j < INOPB(&sblock); j++) {
                    182:                                if (itab[j].di_mode != 0)
                    183:                                        pass3(&itab[j]);
                    184:                                ino++;
                    185:                        }
                    186:                }
                    187:        }
                    188:        close(fi);
                    189:        for (i = 0; i < hsize; i++)
                    190:                htab[i].h_ino = 0;
                    191:        for (i = iflg; i < NB; i++)
                    192:                ilist[i].ino = 0;
                    193:        nxfile = iflg;
                    194: }
                    195: 
                    196: pass1(ip)
                    197:        register struct dinode *ip;
                    198: {
                    199:        int i;
                    200: 
                    201:        if (mflg)
                    202:                for (i = 0; i < iflg; i++)
                    203:                        if (ino == ilist[i].ino) {
                    204:                                ilist[i].mode = ip->di_mode;
                    205:                                ilist[i].uid = ip->di_uid;
                    206:                                ilist[i].gid = ip->di_gid;
                    207:                        }
                    208:        if ((ip->di_mode & IFMT) != IFDIR) {
                    209:                if (sflg==0 || nxfile>=NB)
                    210:                        return;
                    211:                if ((ip->di_mode&IFMT)==IFBLK || (ip->di_mode&IFMT)==IFCHR
                    212:                  || ip->di_mode&(ISUID|ISGID)) {
                    213:                        ilist[nxfile].ino = ino;
                    214:                        ilist[nxfile].mode = ip->di_mode;
                    215:                        ilist[nxfile].uid = ip->di_uid;
                    216:                        ilist[nxfile++].gid = ip->di_gid;
                    217:                        return;
                    218:                }
                    219:        }
                    220:        lookup(ino, 1);
                    221: }
                    222: 
                    223: pass2(ip)
                    224:        register struct dinode *ip;
                    225: {
                    226:        register struct direct *dp;
                    227:        struct dirstuff dirp;
                    228:        struct htab *hp;
                    229: 
                    230:        if((ip->di_mode&IFMT) != IFDIR)
                    231:                return;
                    232:        dirp.loc = 0;
                    233:        dirp.ip = ip;
                    234:        gip = ip;
                    235:        for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
                    236:                if(dp->d_ino == 0)
                    237:                        continue;
                    238:                hp = lookup(dp->d_ino, 0);
                    239:                if(hp == 0)
                    240:                        continue;
                    241:                if(dotname(dp))
                    242:                        continue;
                    243:                hp->h_pino = ino;
                    244:                hp->h_name = &strngtab[strngloc];
                    245:                strngloc += strlen(dp->d_name) + 1;
                    246:                strcpy(hp->h_name, dp->d_name);
                    247:        }
                    248: }
                    249: 
                    250: pass3(ip)
                    251:        register struct dinode *ip;
                    252: {
                    253:        register struct direct *dp;
                    254:        struct dirstuff dirp;
                    255:        int k;
                    256: 
                    257:        if((ip->di_mode&IFMT) != IFDIR)
                    258:                return;
                    259:        dirp.loc = 0;
                    260:        dirp.ip = ip;
                    261:        gip = ip;
                    262:        for(dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
                    263:                if(aflg==0 && dotname(dp))
                    264:                        continue;
                    265:                if(sflg == 0 && iflg == 0)
                    266:                        goto pr;
                    267:                for(k = 0; ilist[k].ino != 0; k++)
                    268:                        if(ilist[k].ino == dp->d_ino)
                    269:                                break;
                    270:                if (ilist[k].ino == 0)
                    271:                        continue;
                    272:                if (mflg)
                    273:                        printf("mode %-6o uid %-5d gid %-5d ino ",
                    274:                            ilist[k].mode, ilist[k].uid, ilist[k].gid);
                    275:        pr:
                    276:                printf("%-5u\t", dp->d_ino);
                    277:                pname(ino, 0);
                    278:                printf("/%s", dp->d_name);
                    279:                if (lookup(dp->d_ino, 0))
                    280:                        printf("/.");
                    281:                printf("\n");
                    282:        }
                    283: }
                    284: 
                    285: /*
                    286:  * get next entry in a directory.
                    287:  */
                    288: struct direct *
                    289: readdir(dirp)
                    290:        register struct dirstuff *dirp;
                    291: {
                    292:        register struct direct *dp;
                    293:        daddr_t lbn, d;
                    294: 
                    295:        for(;;) {
                    296:                if (dirp->loc >= dirp->ip->di_size)
                    297:                        return NULL;
                    298:                if (blkoff(&sblock, dirp->loc) == 0) {
                    299:                        lbn = lblkno(&sblock, dirp->loc);
                    300:                        d = bmap(lbn);
                    301:                        if(d == 0)
                    302:                                return NULL;
                    303:                        bread(fsbtodb(&sblock, d), dirp->dbuf,
                    304:                            dblksize(&sblock, dirp->ip, lbn));
                    305:                }
                    306:                dp = (struct direct *)
                    307:                    (dirp->dbuf + blkoff(&sblock, dirp->loc));
                    308:                dirp->loc += dp->d_reclen;
                    309:                if (dp->d_ino == 0)
                    310:                        continue;
                    311:                return (dp);
                    312:        }
                    313: }
                    314: 
                    315: dotname(dp)
                    316:        register struct direct *dp;
                    317: {
                    318: 
                    319:        if (dp->d_name[0]=='.')
                    320:                if (dp->d_name[1]==0 ||
                    321:                   (dp->d_name[1]=='.' && dp->d_name[2]==0))
                    322:                        return(1);
                    323:        return(0);
                    324: }
                    325: 
                    326: pname(i, lev)
                    327:        ino_t i;
                    328:        int lev;
                    329: {
                    330:        register struct htab *hp;
                    331: 
                    332:        if (i==ROOTINO)
                    333:                return;
                    334:        if ((hp = lookup(i, 0)) == 0) {
                    335:                printf("???");
                    336:                return;
                    337:        }
                    338:        if (lev > 10) {
                    339:                printf("...");
                    340:                return;
                    341:        }
                    342:        pname(hp->h_pino, ++lev);
                    343:        printf("/%s", hp->h_name);
                    344: }
                    345: 
                    346: struct htab *
                    347: lookup(i, ef)
                    348:        ino_t i;
                    349:        int ef;
                    350: {
                    351:        register struct htab *hp;
                    352: 
                    353:        for (hp = &htab[i%hsize]; hp->h_ino;) {
                    354:                if (hp->h_ino==i)
                    355:                        return(hp);
                    356:                if (++hp >= &htab[hsize])
                    357:                        hp = htab;
                    358:        }
                    359:        if (ef==0)
                    360:                return(0);
                    361:        if (++nhent >= hsize) {
                    362:                fprintf(stderr, "ncheck: hsize of %d is too small\n", hsize);
                    363:                exit(1);
                    364:        }
                    365:        hp->h_ino = i;
                    366:        return(hp);
                    367: }
                    368: 
                    369: bread(bno, buf, cnt)
                    370:        daddr_t bno;
                    371:        char *buf;
                    372:        int cnt;
                    373: {
                    374:        register i;
                    375: 
                    376:        lseek(fi, bno * dev_bsize, 0);
                    377:        if (read(fi, buf, cnt) != cnt) {
                    378:                fprintf(stderr, "ncheck: read error %d\n", bno);
                    379:                for(i=0; i < cnt; i++)
                    380:                        buf[i] = 0;
                    381:        }
                    382: }
                    383: 
                    384: /*
                    385:  * Swiped from standalone sys.c.
                    386:  */
                    387: #define        NBUFS   4
                    388: char   b[NBUFS][MAXBSIZE];
                    389: daddr_t        blknos[NBUFS];
                    390: 
                    391: daddr_t
                    392: bmap(bn)
                    393:        register daddr_t bn;
                    394: {
                    395:        register int j;
                    396:        int i, sh;
                    397:        daddr_t nb, *bap;
                    398: 
                    399:        if (bn < 0) {
                    400:                fprintf(stderr, "ncheck: bn %d negative\n", bn);
                    401:                return ((daddr_t)0);
                    402:        }
                    403: 
                    404:        /*
                    405:         * blocks 0..NDADDR are direct blocks
                    406:         */
                    407:        if(bn < NDADDR)
                    408:                return(gip->di_db[bn]);
                    409: 
                    410:        /*
                    411:         * addresses NIADDR have single and double indirect blocks.
                    412:         * the first step is to determine how many levels of indirection.
                    413:         */
                    414:        sh = 1;
                    415:        bn -= NDADDR;
                    416:        for (j = NIADDR; j > 0; j--) {
                    417:                sh *= NINDIR(&sblock);
                    418:                if (bn < sh)
                    419:                        break;
                    420:                bn -= sh;
                    421:        }
                    422:        if (j == 0) {
                    423:                printf("ncheck: bn %ld ovf, ino %u\n", bn, ino);
                    424:                return ((daddr_t)0);
                    425:        }
                    426: 
                    427:        /*
                    428:         * fetch the first indirect block address from the inode
                    429:         */
                    430:        nb = gip->di_ib[NIADDR - j];
                    431:        if (nb == 0) {
                    432:                printf("ncheck: bn %ld void1, ino %u\n", bn, ino);
                    433:                return ((daddr_t)0);
                    434:        }
                    435: 
                    436:        /*
                    437:         * fetch through the indirect blocks
                    438:         */
                    439:        for (; j <= NIADDR; j++) {
                    440:                if (blknos[j] != nb) {
                    441:                        bread(fsbtodb(&sblock, nb), b[j], sblock.fs_bsize);
                    442:                        blknos[j] = nb;
                    443:                }
                    444:                bap = (daddr_t *)b[j];
                    445:                sh /= NINDIR(&sblock);
                    446:                i = (bn / sh) % NINDIR(&sblock);
                    447:                nb = bap[i];
                    448:                if(nb == 0) {
                    449:                        printf("ncheck: bn %ld void2, ino %u\n", bn, ino);
                    450:                        return ((daddr_t)0);
                    451:                }
                    452:        }
                    453:        return (nb);
                    454: }

unix.superglobalmegacorp.com

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