|
|
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.7 (Berkeley) 5/2/88"; ! 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 <sys/inode.h> ! 26: #include <sys/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: long dev_bsize = 1; ! 64: ! 65: int nerror; ! 66: daddr_t bmap(); ! 67: long atol(); ! 68: struct htab *lookup(); ! 69: ! 70: main(argc, argv) ! 71: int argc; ! 72: char *argv[]; ! 73: { ! 74: register i; ! 75: long n; ! 76: ! 77: while (--argc) { ! 78: argv++; ! 79: if (**argv=='-') ! 80: switch ((*argv)[1]) { ! 81: ! 82: case 'a': ! 83: aflg++; ! 84: continue; ! 85: ! 86: case 'i': ! 87: for(iflg=0; iflg<NB; iflg++) { ! 88: n = atol(argv[1]); ! 89: if(n == 0) ! 90: break; ! 91: ilist[iflg].ino = n; ! 92: nxfile = iflg; ! 93: argv++; ! 94: argc--; ! 95: } ! 96: continue; ! 97: ! 98: case 'm': ! 99: mflg++; ! 100: continue; ! 101: ! 102: case 's': ! 103: sflg++; ! 104: continue; ! 105: ! 106: default: ! 107: fprintf(stderr, "ncheck: bad flag %c\n", (*argv)[1]); ! 108: nerror++; ! 109: } ! 110: check(*argv); ! 111: } ! 112: return(nerror); ! 113: } ! 114: ! 115: check(file) ! 116: char *file; ! 117: { ! 118: register int i, j, c; ! 119: int nfiles; ! 120: ! 121: fi = open(file, 0); ! 122: if(fi < 0) { ! 123: fprintf(stderr, "ncheck: cannot open %s\n", file); ! 124: nerror++; ! 125: return; ! 126: } ! 127: nhent = 0; ! 128: printf("%s:\n", file); ! 129: sync(); ! 130: bread(SBOFF, (char *)&sblock, SBSIZE); ! 131: if (sblock.fs_magic != FS_MAGIC) { ! 132: printf("%s: not a file system\n", file); ! 133: nerror++; ! 134: return; ! 135: } ! 136: dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1); ! 137: hsize = sblock.fs_ipg * sblock.fs_ncg - sblock.fs_cstotal.cs_nifree + 1; ! 138: htab = (struct htab *)malloc(hsize * sizeof(struct htab)); ! 139: strngtab = (char *)malloc(30 * hsize); ! 140: if (htab == 0 || strngtab == 0) { ! 141: printf("not enough memory to allocate tables\n"); ! 142: nerror++; ! 143: return; ! 144: } ! 145: ino = 0; ! 146: for (c = 0; c < sblock.fs_ncg; c++) { ! 147: for (i = 0; ! 148: i < sblock.fs_ipg / INOPF(&sblock); ! 149: i += sblock.fs_frag) { ! 150: bread(fsbtodb(&sblock, cgimin(&sblock, c) + i), ! 151: (char *)itab, sblock.fs_bsize); ! 152: for (j = 0; j < INOPB(&sblock); j++) { ! 153: if (itab[j].di_mode != 0) ! 154: pass1(&itab[j]); ! 155: ino++; ! 156: } ! 157: } ! 158: } ! 159: ilist[nxfile+1].ino = 0; ! 160: ino = 0; ! 161: for (c = 0; c < sblock.fs_ncg; c++) { ! 162: for (i = 0; ! 163: i < sblock.fs_ipg / INOPF(&sblock); ! 164: i += sblock.fs_frag) { ! 165: bread(fsbtodb(&sblock, cgimin(&sblock, c) + i), ! 166: (char *)itab, sblock.fs_bsize); ! 167: for (j = 0; j < INOPB(&sblock); j++) { ! 168: if (itab[j].di_mode != 0) ! 169: pass2(&itab[j]); ! 170: ino++; ! 171: } ! 172: } ! 173: } ! 174: ino = 0; ! 175: for (c = 0; c < sblock.fs_ncg; c++) { ! 176: for (i = 0; ! 177: i < sblock.fs_ipg / INOPF(&sblock); ! 178: i += sblock.fs_frag) { ! 179: bread(fsbtodb(&sblock, cgimin(&sblock, c) + i), ! 180: (char *)itab, sblock.fs_bsize); ! 181: for (j = 0; j < INOPB(&sblock); j++) { ! 182: if (itab[j].di_mode != 0) ! 183: pass3(&itab[j]); ! 184: ino++; ! 185: } ! 186: } ! 187: } ! 188: close(fi); ! 189: for (i = 0; i < hsize; i++) ! 190: htab[i].h_ino = 0; ! 191: for (i = iflg; i < NB; i++) ! 192: ilist[i].ino = 0; ! 193: nxfile = iflg; ! 194: } ! 195: ! 196: pass1(ip) ! 197: register struct dinode *ip; ! 198: { ! 199: int i; ! 200: ! 201: if (mflg) ! 202: for (i = 0; i < iflg; i++) ! 203: if (ino == ilist[i].ino) { ! 204: ilist[i].mode = ip->di_mode; ! 205: ilist[i].uid = ip->di_uid; ! 206: ilist[i].gid = ip->di_gid; ! 207: } ! 208: if ((ip->di_mode & IFMT) != IFDIR) { ! 209: if (sflg==0 || nxfile>=NB) ! 210: return; ! 211: if ((ip->di_mode&IFMT)==IFBLK || (ip->di_mode&IFMT)==IFCHR ! 212: || ip->di_mode&(ISUID|ISGID)) { ! 213: ilist[nxfile].ino = ino; ! 214: ilist[nxfile].mode = ip->di_mode; ! 215: ilist[nxfile].uid = ip->di_uid; ! 216: ilist[nxfile++].gid = ip->di_gid; ! 217: return; ! 218: } ! 219: } ! 220: lookup(ino, 1); ! 221: } ! 222: ! 223: pass2(ip) ! 224: register struct dinode *ip; ! 225: { ! 226: register struct direct *dp; ! 227: struct dirstuff dirp; ! 228: struct htab *hp; ! 229: ! 230: if((ip->di_mode&IFMT) != IFDIR) ! 231: return; ! 232: dirp.loc = 0; ! 233: dirp.ip = ip; ! 234: gip = ip; ! 235: for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { ! 236: if(dp->d_ino == 0) ! 237: continue; ! 238: hp = lookup(dp->d_ino, 0); ! 239: if(hp == 0) ! 240: continue; ! 241: if(dotname(dp)) ! 242: continue; ! 243: hp->h_pino = ino; ! 244: hp->h_name = &strngtab[strngloc]; ! 245: strngloc += strlen(dp->d_name) + 1; ! 246: strcpy(hp->h_name, dp->d_name); ! 247: } ! 248: } ! 249: ! 250: pass3(ip) ! 251: register struct dinode *ip; ! 252: { ! 253: register struct direct *dp; ! 254: struct dirstuff dirp; ! 255: int k; ! 256: ! 257: if((ip->di_mode&IFMT) != IFDIR) ! 258: return; ! 259: dirp.loc = 0; ! 260: dirp.ip = ip; ! 261: gip = ip; ! 262: for(dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { ! 263: if(aflg==0 && dotname(dp)) ! 264: continue; ! 265: if(sflg == 0 && iflg == 0) ! 266: goto pr; ! 267: for(k = 0; ilist[k].ino != 0; k++) ! 268: if(ilist[k].ino == dp->d_ino) ! 269: break; ! 270: if (ilist[k].ino == 0) ! 271: continue; ! 272: if (mflg) ! 273: printf("mode %-6o uid %-5d gid %-5d ino ", ! 274: ilist[k].mode, ilist[k].uid, ilist[k].gid); ! 275: pr: ! 276: printf("%-5u\t", dp->d_ino); ! 277: pname(ino, 0); ! 278: printf("/%s", dp->d_name); ! 279: if (lookup(dp->d_ino, 0)) ! 280: printf("/."); ! 281: printf("\n"); ! 282: } ! 283: } ! 284: ! 285: /* ! 286: * get next entry in a directory. ! 287: */ ! 288: struct direct * ! 289: readdir(dirp) ! 290: register struct dirstuff *dirp; ! 291: { ! 292: register struct direct *dp; ! 293: daddr_t lbn, d; ! 294: ! 295: for(;;) { ! 296: if (dirp->loc >= dirp->ip->di_size) ! 297: return NULL; ! 298: if (blkoff(&sblock, dirp->loc) == 0) { ! 299: lbn = lblkno(&sblock, dirp->loc); ! 300: d = bmap(lbn); ! 301: if(d == 0) ! 302: return NULL; ! 303: bread(fsbtodb(&sblock, d), dirp->dbuf, ! 304: dblksize(&sblock, dirp->ip, lbn)); ! 305: } ! 306: dp = (struct direct *) ! 307: (dirp->dbuf + blkoff(&sblock, dirp->loc)); ! 308: dirp->loc += dp->d_reclen; ! 309: if (dp->d_ino == 0) ! 310: continue; ! 311: return (dp); ! 312: } ! 313: } ! 314: ! 315: dotname(dp) ! 316: register struct direct *dp; ! 317: { ! 318: ! 319: if (dp->d_name[0]=='.') ! 320: if (dp->d_name[1]==0 || ! 321: (dp->d_name[1]=='.' && dp->d_name[2]==0)) ! 322: return(1); ! 323: return(0); ! 324: } ! 325: ! 326: pname(i, lev) ! 327: ino_t i; ! 328: int lev; ! 329: { ! 330: register struct htab *hp; ! 331: ! 332: if (i==ROOTINO) ! 333: return; ! 334: if ((hp = lookup(i, 0)) == 0) { ! 335: printf("???"); ! 336: return; ! 337: } ! 338: if (lev > 10) { ! 339: printf("..."); ! 340: return; ! 341: } ! 342: pname(hp->h_pino, ++lev); ! 343: printf("/%s", hp->h_name); ! 344: } ! 345: ! 346: struct htab * ! 347: lookup(i, ef) ! 348: ino_t i; ! 349: int ef; ! 350: { ! 351: register struct htab *hp; ! 352: ! 353: for (hp = &htab[i%hsize]; hp->h_ino;) { ! 354: if (hp->h_ino==i) ! 355: return(hp); ! 356: if (++hp >= &htab[hsize]) ! 357: hp = htab; ! 358: } ! 359: if (ef==0) ! 360: return(0); ! 361: if (++nhent >= hsize) { ! 362: fprintf(stderr, "ncheck: hsize of %d is too small\n", hsize); ! 363: exit(1); ! 364: } ! 365: hp->h_ino = i; ! 366: return(hp); ! 367: } ! 368: ! 369: bread(bno, buf, cnt) ! 370: daddr_t bno; ! 371: char *buf; ! 372: int cnt; ! 373: { ! 374: register i; ! 375: ! 376: lseek(fi, bno * dev_bsize, 0); ! 377: if (read(fi, buf, cnt) != cnt) { ! 378: fprintf(stderr, "ncheck: read error %d\n", bno); ! 379: for(i=0; i < cnt; i++) ! 380: buf[i] = 0; ! 381: } ! 382: } ! 383: ! 384: /* ! 385: * Swiped from standalone sys.c. ! 386: */ ! 387: #define NBUFS 4 ! 388: char b[NBUFS][MAXBSIZE]; ! 389: daddr_t blknos[NBUFS]; ! 390: ! 391: daddr_t ! 392: bmap(bn) ! 393: register daddr_t bn; ! 394: { ! 395: register int j; ! 396: int i, sh; ! 397: daddr_t nb, *bap; ! 398: ! 399: if (bn < 0) { ! 400: fprintf(stderr, "ncheck: bn %d negative\n", bn); ! 401: return ((daddr_t)0); ! 402: } ! 403: ! 404: /* ! 405: * blocks 0..NDADDR are direct blocks ! 406: */ ! 407: if(bn < NDADDR) ! 408: return(gip->di_db[bn]); ! 409: ! 410: /* ! 411: * addresses NIADDR have single and double indirect blocks. ! 412: * the first step is to determine how many levels of indirection. ! 413: */ ! 414: sh = 1; ! 415: bn -= NDADDR; ! 416: for (j = NIADDR; j > 0; j--) { ! 417: sh *= NINDIR(&sblock); ! 418: if (bn < sh) ! 419: break; ! 420: bn -= sh; ! 421: } ! 422: if (j == 0) { ! 423: printf("ncheck: bn %ld ovf, ino %u\n", bn, ino); ! 424: return ((daddr_t)0); ! 425: } ! 426: ! 427: /* ! 428: * fetch the first indirect block address from the inode ! 429: */ ! 430: nb = gip->di_ib[NIADDR - j]; ! 431: if (nb == 0) { ! 432: printf("ncheck: bn %ld void1, ino %u\n", bn, ino); ! 433: return ((daddr_t)0); ! 434: } ! 435: ! 436: /* ! 437: * fetch through the indirect blocks ! 438: */ ! 439: for (; j <= NIADDR; j++) { ! 440: if (blknos[j] != nb) { ! 441: bread(fsbtodb(&sblock, nb), b[j], sblock.fs_bsize); ! 442: blknos[j] = nb; ! 443: } ! 444: bap = (daddr_t *)b[j]; ! 445: sh /= NINDIR(&sblock); ! 446: i = (bn / sh) % NINDIR(&sblock); ! 447: nb = bap[i]; ! 448: if(nb == 0) { ! 449: printf("ncheck: bn %ld void2, ino %u\n", bn, ino); ! 450: return ((daddr_t)0); ! 451: } ! 452: } ! 453: return (nb); ! 454: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.