home *** CD-ROM | disk | FTP | other *** search
- /*
- * dcheck - check directory consistency
- */
- #define NI 16
- #define NB 10
- #define NDIR (BSIZE/sizeof(struct direct))
-
- #include <stdio.h>
- #include <sys/param.h>
- #include <sys/inode.h>
- #include <sys/ino.h>
- #include <sys/dir.h>
- #include <sys/filsys.h>
- #include <sys/fblk.h>
-
-
- struct filsys sblock;
- struct dinode itab[INOPB*NI];
- daddr_t iaddr[NADDR];
- ino_t ilist[NB];
-
- int fi;
- ino_t ino;
- char *ecount;
- int headpr;
- unsigned 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; i<NB; i++) {
- n = atol(argv[1]);
- if(n == 0)
- break;
- ilist[i] = n;
- argv++;
- argc--;
- }
- ilist[i] = 0;
- continue;
-
- default:
- printf("Bad flag %c\n", (*argv)[1]);
- nerror++;
- }
- check(*argv);
- }
- return(nerror);
- }
-
- check(file)
- char *file;
- {
- register i;
- register j;
-
- fi = open(file, 0);
- if(fi < 0) {
- printf("cannot open %s\n", file);
- nerror++;
- return;
- }
- headpr = 0;
- printf("%s:\n", file);
- sync();
- bread((daddr_t)1, (char *)&sblock, sizeof(sblock));
- nfiles = (sblock.s_isize-2)*INOPB;
- if (nfiles > 40000) {
- printf("Only doing 40000 files\n");
- nfiles = 40000;
- }
- ecount = malloc(nfiles+1);
- if (ecount==NULL) {
- printf("Not enough core\n");
- exit(04);
- }
- for (i=0; i<=nfiles; i++)
- ecount[i] = 0;
- ino = 0;
- for(i=2;; i+=NI) {
- if(ino >= nfiles)
- break;
- bread((daddr_t)i, (char *)itab, sizeof(itab));
- for(j=0; j<INOPB*NI; j++) {
- if(ino >= nfiles)
- break;
- ino++;
- pass1(&itab[j]);
- }
- }
- ino = 0;
- for(i=2;; i+=NI) {
- if(ino >= nfiles)
- break;
- bread((daddr_t)i, (char *)itab, sizeof(itab));
- for(j=0; j<INOPB*NI; j++) {
- if(ino >= nfiles)
- break;
- ino++;
- pass2(&itab[j]);
- }
- }
- free(ecount);
- }
-
- pass1(ip)
- register struct dinode *ip;
- {
- struct direct dbuf[NDIR];
- long doff;
- struct direct *dp;
- register i, j;
- int k;
- daddr_t d;
- ino_t kno;
-
- if((ip->di_mode&IFMT) != IFDIR)
- return;
- l3tol(iaddr, ip->di_addr, NADDR);
- doff = 0;
- for(i=0;; i++) {
- if(doff >= ip->di_size)
- break;
- d = bmap(i);
- if(d == 0)
- break;
- bread(d, (char *)dbuf, BSIZE);
- for(j=0; j<NDIR; j++) {
- if(doff >= ip->di_size)
- break;
- doff += sizeof(struct direct);
- dp = &dbuf[j];
- kno = dp->d_ino;
- if(kno == 0)
- continue;
- if(kno > nfiles || kno <= 1) {
- printf("%5u bad; %u/%.14s\n", kno, ino, dp->d_name);
- nerror++;
- continue;
- }
- for (k=0; ilist[k] != 0; k++)
- if (ilist[k]==kno) {
- printf("%5u arg; %u/%.14s\n", kno, ino, dp->d_name);
- nerror++;
- }
- ecount[kno]++;
- if (ecount[kno] == 0)
- ecount[kno] = 0377;
- }
- }
- }
-
- 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])&0377) && ip->di_nlink!=0)
- return;
- if (ino < ROOTINO && ip->di_nlink==0 && ecount[i]==0)
- return;
- if (headpr==0) {
- printf(" entries link cnt\n");
- headpr++;
- }
- printf("%u %d %d\n", ino,
- ecount[i]&0377, ip->di_nlink);
- }
-
- bread(bno, buf, cnt)
- daddr_t bno;
- char *buf;
- {
- register i;
-
- lseek(fi, bno*BSIZE, 0);
- if (read(fi, buf, cnt) != cnt) {
- printf("read error %D\n", bno);
- for(i=0; i<BSIZE; i++)
- buf[i] = 0;
- }
- }
-
-
- daddr_t
- bmap(i)
- {
- daddr_t ibuf[NINDIR];
-
- if(i < NADDR-3)
- return(iaddr[i]);
- i -= NADDR-3;
- if(i > NINDIR) {
- printf("%u - huge directory\n", ino);
- return((daddr_t)0);
- }
- bread(iaddr[NADDR-3], (char *)ibuf, sizeof(ibuf));
- return(ibuf[i]);
- }
-