|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.