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