|
|
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[] = "@(#)dcheck.c 5.1 (Berkeley) 6/6/85"; ! 15: #endif not lint ! 16: ! 17: /* ! 18: * dcheck - check directory consistency ! 19: */ ! 20: #define NB 10 ! 21: #define MAXNINDIR (MAXBSIZE / sizeof (daddr_t)) ! 22: ! 23: #include <sys/param.h> ! 24: #include <sys/inode.h> ! 25: #include <sys/fs.h> ! 26: #include <sys/dir.h> ! 27: #include <stdio.h> ! 28: ! 29: union { ! 30: struct fs fs; ! 31: char pad[MAXBSIZE]; ! 32: } fsun; ! 33: #define sblock fsun.fs ! 34: ! 35: struct dirstuff { ! 36: int loc; ! 37: struct dinode *ip; ! 38: char dbuf[MAXBSIZE]; ! 39: }; ! 40: ! 41: struct dinode itab[MAXIPG]; ! 42: struct dinode *gip; ! 43: ino_t ilist[NB]; ! 44: ! 45: int fi; ! 46: ino_t ino; ! 47: ino_t *ecount; ! 48: int headpr; ! 49: int nfiles; ! 50: ! 51: int nerror; ! 52: daddr_t bmap(); ! 53: long atol(); ! 54: char *malloc(); ! 55: ! 56: main(argc, argv) ! 57: char *argv[]; ! 58: { ! 59: register i; ! 60: long n; ! 61: ! 62: while (--argc) { ! 63: argv++; ! 64: if (**argv=='-') ! 65: switch ((*argv)[1]) { ! 66: ! 67: case 'i': ! 68: for(i=0; i<NB; i++) { ! 69: n = atol(argv[1]); ! 70: if(n == 0) ! 71: break; ! 72: ilist[i] = n; ! 73: argv++; ! 74: argc--; ! 75: } ! 76: ilist[i] = 0; ! 77: continue; ! 78: ! 79: default: ! 80: printf("Bad flag %c\n", (*argv)[1]); ! 81: nerror++; ! 82: } ! 83: check(*argv); ! 84: } ! 85: return(nerror); ! 86: } ! 87: ! 88: check(file) ! 89: char *file; ! 90: { ! 91: register i, j, c; ! 92: ! 93: fi = open(file, 0); ! 94: if(fi < 0) { ! 95: printf("cannot open %s\n", file); ! 96: nerror++; ! 97: return; ! 98: } ! 99: headpr = 0; ! 100: printf("%s:\n", file); ! 101: sync(); ! 102: bread(SBLOCK, (char *)&sblock, SBSIZE); ! 103: if (sblock.fs_magic != FS_MAGIC) { ! 104: printf("%s: not a file system\n", file); ! 105: nerror++; ! 106: return; ! 107: } ! 108: nfiles = sblock.fs_ipg * sblock.fs_ncg; ! 109: ecount = (ino_t *)malloc((nfiles+1) * sizeof (*ecount)); ! 110: if (ecount == 0) { ! 111: printf("%s: not enough core for %d files\n", file, nfiles); ! 112: exit(04); ! 113: } ! 114: for (i = 0; i<=nfiles; i++) ! 115: ecount[i] = 0; ! 116: ino = 0; ! 117: for (c = 0; c < sblock.fs_ncg; c++) { ! 118: bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab, ! 119: sblock.fs_ipg * sizeof (struct dinode)); ! 120: for (j = 0; j < sblock.fs_ipg; j++) { ! 121: pass1(&itab[j]); ! 122: ino++; ! 123: } ! 124: } ! 125: ino = 0; ! 126: for (c = 0; c < sblock.fs_ncg; c++) { ! 127: bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab, ! 128: sblock.fs_ipg * sizeof (struct dinode)); ! 129: for (j = 0; j < sblock.fs_ipg; j++) { ! 130: pass2(&itab[j]); ! 131: ino++; ! 132: } ! 133: } ! 134: free(ecount); ! 135: } ! 136: ! 137: pass1(ip) ! 138: register struct dinode *ip; ! 139: { ! 140: register struct direct *dp; ! 141: struct dirstuff dirp; ! 142: int k; ! 143: ! 144: if((ip->di_mode&IFMT) != IFDIR) ! 145: return; ! 146: dirp.loc = 0; ! 147: dirp.ip = ip; ! 148: gip = ip; ! 149: for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { ! 150: if(dp->d_ino == 0) ! 151: continue; ! 152: if(dp->d_ino > nfiles || dp->d_ino < ROOTINO) { ! 153: printf("%d bad; %d/%s\n", ! 154: dp->d_ino, ino, dp->d_name); ! 155: nerror++; ! 156: continue; ! 157: } ! 158: for (k = 0; ilist[k] != 0; k++) ! 159: if (ilist[k] == dp->d_ino) { ! 160: printf("%d arg; %d/%s\n", ! 161: dp->d_ino, ino, dp->d_name); ! 162: nerror++; ! 163: } ! 164: ecount[dp->d_ino]++; ! 165: } ! 166: } ! 167: ! 168: pass2(ip) ! 169: register struct dinode *ip; ! 170: { ! 171: register i; ! 172: ! 173: i = ino; ! 174: if ((ip->di_mode&IFMT)==0 && ecount[i]==0) ! 175: return; ! 176: if (ip->di_nlink==ecount[i] && ip->di_nlink!=0) ! 177: return; ! 178: if (headpr==0) { ! 179: printf(" entries link cnt\n"); ! 180: headpr++; ! 181: } ! 182: printf("%u\t%d\t%d\n", ino, ! 183: ecount[i], ip->di_nlink); ! 184: } ! 185: ! 186: /* ! 187: * get next entry in a directory. ! 188: */ ! 189: struct direct * ! 190: readdir(dirp) ! 191: register struct dirstuff *dirp; ! 192: { ! 193: register struct direct *dp; ! 194: daddr_t lbn, d; ! 195: ! 196: for(;;) { ! 197: if (dirp->loc >= dirp->ip->di_size) ! 198: return NULL; ! 199: if ((lbn = lblkno(&sblock, dirp->loc)) == 0) { ! 200: d = bmap(lbn); ! 201: if(d == 0) ! 202: return NULL; ! 203: bread(fsbtodb(&sblock, d), dirp->dbuf, ! 204: dblksize(&sblock, dirp->ip, lbn)); ! 205: } ! 206: dp = (struct direct *) ! 207: (dirp->dbuf + blkoff(&sblock, dirp->loc)); ! 208: dirp->loc += dp->d_reclen; ! 209: if (dp->d_ino == 0) ! 210: continue; ! 211: return (dp); ! 212: } ! 213: } ! 214: ! 215: bread(bno, buf, cnt) ! 216: daddr_t bno; ! 217: char *buf; ! 218: { ! 219: register i; ! 220: ! 221: lseek(fi, bno * DEV_BSIZE, 0); ! 222: if (read(fi, buf, cnt) != cnt) { ! 223: printf("read error %d\n", bno); ! 224: for(i=0; i < cnt; i++) ! 225: buf[i] = 0; ! 226: } ! 227: } ! 228: ! 229: daddr_t ! 230: bmap(i) ! 231: { ! 232: daddr_t ibuf[MAXNINDIR]; ! 233: ! 234: if(i < NDADDR) ! 235: return(gip->di_db[i]); ! 236: i -= NDADDR; ! 237: if(i > NINDIR(&sblock)) { ! 238: printf("%u - huge directory\n", ino); ! 239: return((daddr_t)0); ! 240: } ! 241: bread(fsbtodb(&sblock, gip->di_ib[0]), (char *)ibuf, sizeof(ibuf)); ! 242: return(ibuf[i]); ! 243: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.