1: /* 2: * ncheck -- obtain file names from reading filesystem 3: */ 4: 5: #define NI 16 6: #define NB 100 7: #define HSIZE 2503 8: #define NDIR (BSIZE/sizeof(struct direct)) 9: 10: #include <stdio.h> 11: #include <sys/param.h> 12: #include <sys/inode.h> 13: #include <sys/ino.h> 14: #include <sys/dir.h> 15: #include <sys/filsys.h> 16: #include <sys/fblk.h> 17: 18: struct filsys sblock; 19: struct dinode itab[INOPB*NI]; 20: daddr_t iaddr[NADDR]; 21: ino_t ilist[NB]; 22: struct htab 23: { 24: ino_t h_ino; 25: ino_t h_pino; 26: char h_name[DIRSIZ]; 27: } htab[HSIZE]; 28: 29: int aflg; 30: int sflg; 31: int fi; 32: ino_t ino; 33: int nhent; 34: int nxfile; 35: 36: int nerror; 37: daddr_t bmap(); 38: long atol(); 39: struct htab *lookup(); 40: 41: main(argc, argv) 42: char *argv[]; 43: { 44: register i; 45: long n; 46: 47: while (--argc) { 48: argv++; 49: if (**argv=='-') 50: switch ((*argv)[1]) { 51: 52: case 'a': 53: aflg++; 54: continue; 55: 56: case 'i': 57: for(i=0; i<NB; i++) { 58: n = atol(argv[1]); 59: if(n == 0) 60: break; 61: ilist[i] = n; 62: nxfile = i; 63: argv++; 64: argc--; 65: } 66: continue; 67: 68: case 's': 69: sflg++; 70: continue; 71: 72: default: 73: fprintf(stderr, "ncheck: bad flag %c\n", (*argv)[1]); 74: nerror++; 75: } 76: check(*argv); 77: } 78: return(nerror); 79: } 80: 81: check(file) 82: char *file; 83: { 84: register i, j; 85: ino_t mino; 86: 87: fi = open(file, 0); 88: if(fi < 0) { 89: fprintf(stderr, "ncheck: cannot open %s\n", file); 90: nerror++; 91: return; 92: } 93: nhent = 0; 94: printf("%s:\n", file); 95: sync(); 96: bread((daddr_t)1, (char *)&sblock, sizeof(sblock)); 97: mino = (sblock.s_isize-2) * INOPB; 98: ino = 0; 99: for(i=2;; i+=NI) { 100: if(ino >= mino) 101: break; 102: bread((daddr_t)i, (char *)itab, sizeof(itab)); 103: for(j=0; j<INOPB*NI; j++) { 104: if(ino >= mino) 105: break; 106: ino++; 107: pass1(&itab[j]); 108: } 109: } 110: ilist[nxfile+1] = 0; 111: ino = 0; 112: for(i=2;; i+=NI) { 113: if(ino >= mino) 114: break; 115: bread((daddr_t)i, (char *)itab, sizeof(itab)); 116: for(j=0; j<INOPB*NI; j++) { 117: if(ino >= mino) 118: break; 119: ino++; 120: pass2(&itab[j]); 121: } 122: } 123: ino = 0; 124: for(i=2;; i+=NI) { 125: if(ino >= mino) 126: break; 127: bread((daddr_t)i, (char *)itab, sizeof(itab)); 128: for(j=0; j<INOPB*NI; j++) { 129: if(ino >= mino) 130: break; 131: ino++; 132: pass3(&itab[j]); 133: } 134: } 135: } 136: 137: pass1(ip) 138: register struct dinode *ip; 139: { 140: if((ip->di_mode & IFMT) != IFDIR) { 141: if (sflg==0 || nxfile>=NB) 142: return; 143: if ((ip->di_mode&IFMT)==IFBLK || (ip->di_mode&IFMT)==IFCHR 144: || ip->di_mode&(ISUID|ISGID)) 145: ilist[nxfile++] = ino; 146: return; 147: } 148: lookup(ino, 1); 149: } 150: 151: pass2(ip) 152: register struct dinode *ip; 153: { 154: struct direct dbuf[NDIR]; 155: long doff; 156: struct direct *dp; 157: register i, j; 158: int k; 159: struct htab *hp; 160: daddr_t d; 161: ino_t kno; 162: 163: if((ip->di_mode&IFMT) != IFDIR) 164: return; 165: l3tol(iaddr, ip->di_addr, NADDR); 166: doff = 0; 167: for(i=0;; i++) { 168: if(doff >= ip->di_size) 169: break; 170: d = bmap(i); 171: if(d == 0) 172: break; 173: bread(d, (char *)dbuf, sizeof(dbuf)); 174: for(j=0; j<NDIR; j++) { 175: if(doff >= ip->di_size) 176: break; 177: doff += sizeof(struct direct); 178: dp = dbuf+j; 179: kno = dp->d_ino; 180: if(kno == 0) 181: continue; 182: hp = lookup(kno, 0); 183: if(hp == 0) 184: continue; 185: if(dotname(dp)) 186: continue; 187: hp->h_pino = ino; 188: for(k=0; k<DIRSIZ; k++) 189: hp->h_name[k] = dp->d_name[k]; 190: } 191: } 192: } 193: 194: pass3(ip) 195: register struct dinode *ip; 196: { 197: struct direct dbuf[NDIR]; 198: long doff; 199: struct direct *dp; 200: register i, j; 201: int k; 202: daddr_t d; 203: ino_t kno; 204: 205: if((ip->di_mode&IFMT) != IFDIR) 206: return; 207: l3tol(iaddr, ip->di_addr, NADDR); 208: doff = 0; 209: for(i=0;; i++) { 210: if(doff >= ip->di_size) 211: break; 212: d = bmap(i); 213: if(d == 0) 214: break; 215: bread(d, (char *)dbuf, sizeof(dbuf)); 216: for(j=0; j<NDIR; j++) { 217: if(doff >= ip->di_size) 218: break; 219: doff += sizeof(struct direct); 220: dp = dbuf+j; 221: kno = dp->d_ino; 222: if(kno == 0) 223: continue; 224: if(aflg==0 && dotname(dp)) 225: continue; 226: if(ilist[0] == 0) 227: goto pr; 228: for(k=0; ilist[k] != 0; k++) 229: if(ilist[k] == kno) 230: goto pr; 231: continue; 232: pr: 233: printf("%u ", kno); 234: pname(ino, 0); 235: printf("/%.14s", dp->d_name); 236: if (lookup(kno, 0)) 237: printf("/."); 238: printf("\n"); 239: } 240: } 241: } 242: 243: dotname(dp) 244: register struct direct *dp; 245: { 246: 247: if (dp->d_name[0]=='.') 248: if (dp->d_name[1]==0 || (dp->d_name[1]=='.' && dp->d_name[2]==0)) 249: return(1); 250: return(0); 251: } 252: 253: pname(i, lev) 254: ino_t i; 255: { 256: register struct htab *hp; 257: 258: if (i==ROOTINO) 259: return; 260: if ((hp = lookup(i, 0)) == 0) { 261: printf("???"); 262: return; 263: } 264: if (lev > 10) { 265: printf("..."); 266: return; 267: } 268: pname(hp->h_pino, ++lev); 269: printf("/%.14s", hp->h_name); 270: } 271: 272: struct htab * 273: lookup(i, ef) 274: ino_t i; 275: { 276: register struct htab *hp; 277: 278: for (hp = &htab[i%HSIZE]; hp->h_ino;) { 279: if (hp->h_ino==i) 280: return(hp); 281: if (++hp >= &htab[HSIZE]) 282: hp = htab; 283: } 284: if (ef==0) 285: return(0); 286: if (++nhent >= HSIZE) { 287: fprintf(stderr, "ncheck: out of core-- increase HSIZE\n"); 288: exit(1); 289: } 290: hp->h_ino = i; 291: return(hp); 292: } 293: 294: bread(bno, buf, cnt) 295: daddr_t bno; 296: char *buf; 297: { 298: register i; 299: 300: lseek(fi, bno*BSIZE, 0); 301: if (read(fi, buf, cnt) != cnt) { 302: fprintf(stderr, "ncheck: read error %d\n", bno); 303: for(i=0; i<BSIZE; i++) 304: buf[i] = 0; 305: } 306: } 307: 308: daddr_t 309: bmap(i) 310: { 311: daddr_t ibuf[NINDIR]; 312: 313: if(i < NADDR-3) 314: return(iaddr[i]); 315: i -= NADDR-3; 316: if(i > NINDIR) { 317: fprintf(stderr, "ncheck: %u - huge directory\n", ino); 318: return((daddr_t)0); 319: } 320: bread(iaddr[NADDR-3], (char *)ibuf, sizeof(ibuf)); 321: return(ibuf[i]); 322: }