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

unix.superglobalmegacorp.com

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