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