/* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ #ifndef lint char copyright[] = "@(#) Copyright (c) 1980 Regents of the University of California.\n\ All rights reserved.\n"; #endif not lint #ifndef lint static char sccsid[] = "@(#)dcheck.c 5.1 (Berkeley) 6/6/85"; #endif not lint /* * dcheck - check directory consistency */ #define NB 10 #define MAXNINDIR (MAXBSIZE / sizeof (daddr_t)) #include #include #include #include #include union { struct fs fs; char pad[MAXBSIZE]; } fsun; #define sblock fsun.fs struct dirstuff { int loc; struct dinode *ip; char dbuf[MAXBSIZE]; }; struct dinode itab[MAXIPG]; struct dinode *gip; ino_t ilist[NB]; int fi; ino_t ino; ino_t *ecount; int headpr; int nfiles; int nerror; daddr_t bmap(); long atol(); char *malloc(); main(argc, argv) char *argv[]; { register i; long n; while (--argc) { argv++; if (**argv=='-') switch ((*argv)[1]) { case 'i': for(i=0; idi_mode&IFMT) != IFDIR) return; dirp.loc = 0; dirp.ip = ip; gip = ip; for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { if(dp->d_ino == 0) continue; if(dp->d_ino > nfiles || dp->d_ino < ROOTINO) { printf("%d bad; %d/%s\n", dp->d_ino, ino, dp->d_name); nerror++; continue; } for (k = 0; ilist[k] != 0; k++) if (ilist[k] == dp->d_ino) { printf("%d arg; %d/%s\n", dp->d_ino, ino, dp->d_name); nerror++; } ecount[dp->d_ino]++; } } pass2(ip) register struct dinode *ip; { register i; i = ino; if ((ip->di_mode&IFMT)==0 && ecount[i]==0) return; if (ip->di_nlink==ecount[i] && ip->di_nlink!=0) return; if (headpr==0) { printf(" entries link cnt\n"); headpr++; } printf("%u\t%d\t%d\n", ino, ecount[i], ip->di_nlink); } /* * get next entry in a directory. */ struct direct * readdir(dirp) register struct dirstuff *dirp; { register struct direct *dp; daddr_t lbn, d; for(;;) { if (dirp->loc >= dirp->ip->di_size) return NULL; if ((lbn = lblkno(&sblock, dirp->loc)) == 0) { d = bmap(lbn); if(d == 0) return NULL; bread(fsbtodb(&sblock, d), dirp->dbuf, dblksize(&sblock, dirp->ip, lbn)); } dp = (struct direct *) (dirp->dbuf + blkoff(&sblock, dirp->loc)); dirp->loc += dp->d_reclen; if (dp->d_ino == 0) continue; return (dp); } } bread(bno, buf, cnt) daddr_t bno; char *buf; { register i; lseek(fi, bno * DEV_BSIZE, 0); if (read(fi, buf, cnt) != cnt) { printf("read error %d\n", bno); for(i=0; i < cnt; i++) buf[i] = 0; } } daddr_t bmap(i) { daddr_t ibuf[MAXNINDIR]; if(i < NDADDR) return(gip->di_db[i]); i -= NDADDR; if(i > NINDIR(&sblock)) { printf("%u - huge directory\n", ino); return((daddr_t)0); } bread(fsbtodb(&sblock, gip->di_ib[0]), (char *)ibuf, sizeof(ibuf)); return(ibuf[i]); }