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: #if !defined(lint) && defined(DOSCCS) 8: char copyright[] = 9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 10: All rights reserved.\n"; 11: static char sccsid[] = "@(#)ncheck.c 5.4 (Berkeley) 1/9/86"; 12: #endif 13: 14: /* 15: * ncheck -- obtain file names from reading filesystem 16: */ 17: 18: #define NI 8 19: #define NB 100 20: #define HSIZE 1503 21: 22: #include <sys/param.h> 23: #include <sys/inode.h> 24: #include <sys/fs.h> 25: #include <sys/dir.h> 26: #include <stdio.h> 27: 28: struct fs sblock; 29: struct dinode itab[NI * INOPB]; 30: struct dinode *gip; 31: struct ilist { 32: ino_t ino; 33: u_short mode; 34: uid_t uid; 35: gid_t gid; 36: } ilist[NB]; 37: struct htab 38: { 39: ino_t h_ino; 40: ino_t h_pino; 41: char *h_name; 42: } htab[HSIZE]; 43: 44: struct dirstuff { 45: off_t loc; 46: struct dinode *ip; 47: char dbuf[MAXBSIZE]; 48: }; 49: 50: int aflg; 51: int sflg; 52: int iflg; /* number of inodes being searched for */ 53: int mflg; 54: int fi; 55: ino_t ino; 56: int nhent; 57: int nxfile; 58: 59: int nerror; 60: daddr_t bmap(); 61: long atol(); 62: struct htab *lookup(); 63: 64: main(argc, argv) 65: int argc; 66: char *argv[]; 67: { 68: register i; 69: long n; 70: 71: while (--argc) { 72: argv++; 73: if (**argv=='-') 74: switch ((*argv)[1]) { 75: 76: case 'a': 77: aflg++; 78: continue; 79: 80: case 'i': 81: for(iflg=0; iflg<NB; iflg++) { 82: n = atol(argv[1]); 83: if(n == 0) 84: break; 85: ilist[iflg].ino = (ino_t)n; 86: nxfile = iflg; 87: argv++; 88: argc--; 89: } 90: continue; 91: 92: case 'm': 93: mflg++; 94: continue; 95: 96: case 's': 97: sflg++; 98: continue; 99: 100: default: 101: fprintf(stderr, "ncheck: bad flag %c\n", (*argv)[1]); 102: nerror++; 103: } 104: check(*argv); 105: } 106: return(nerror); 107: } 108: 109: check(file) 110: char *file; 111: { 112: register int i, j; 113: int mino; 114: 115: fi = open(file, 0); 116: if(fi < 0) { 117: fprintf(stderr, "ncheck: cannot open %s\n", file); 118: nerror++; 119: return; 120: } 121: nhent = 0; 122: printf("%s:\n", file); 123: sync(); 124: bread(SBLOCK, (char *)&sblock, SBSIZE); 125: ino = 0; 126: mino = (sblock.fs_isize-2) * INOPB; 127: for (i = 2; ; i+=NI) { 128: if (ino >= mino) 129: break; 130: bread((daddr_t) i, (char *)itab, sizeof (itab)); 131: for (j = 0; j < INOPB * NI; j++) { 132: if (ino >= mino) 133: break; 134: ino++; 135: pass1(&itab[j]); 136: } 137: } 138: ilist[nxfile+1].ino = 0; 139: ino = 0; 140: for (i = 2; ; i+=NI) { 141: if (ino >= mino) 142: break; 143: bread((daddr_t) i, (char *)itab, sizeof (itab)); 144: for (j = 0; j < INOPB * NI; j++) { 145: if (ino >= mino) 146: break; 147: ino++; 148: pass2(&itab[j]); 149: } 150: } 151: ino = 0; 152: for (i = 2; ; i+=NI) { 153: if (ino >= mino) 154: break; 155: bread((daddr_t) i, (char *)itab, sizeof (itab)); 156: for (j = 0; j < INOPB * NI; j++) { 157: if (ino >= mino) 158: break; 159: ino++; 160: pass3(&itab[j]); 161: } 162: } 163: close(fi); 164: for (i = 0; i < HSIZE; i++) { 165: if (htab[i].h_name) 166: free(htab[i].h_name); 167: htab[i].h_ino = 0; 168: htab[i].h_name = 0; 169: } 170: for (i = iflg; i < NB; i++) 171: ilist[i].ino = 0; 172: nxfile = iflg; 173: } 174: 175: pass1(ip) 176: register struct dinode *ip; 177: { 178: register int i; 179: 180: if (mflg) 181: for (i = 0; i < iflg; i++) 182: if (ino == ilist[i].ino) { 183: ilist[i].mode = ip->di_mode; 184: ilist[i].uid = ip->di_uid; 185: ilist[i].gid = ip->di_gid; 186: } 187: if ((ip->di_mode & IFMT) != IFDIR) { 188: if (sflg==0 || nxfile>=NB) 189: return; 190: if ((ip->di_mode&IFMT)==IFBLK || (ip->di_mode&IFMT)==IFCHR 191: || ip->di_mode&(ISUID|ISGID)) { 192: ilist[nxfile].ino = ino; 193: ilist[nxfile].mode = ip->di_mode; 194: ilist[nxfile].uid = ip->di_uid; 195: ilist[nxfile++].gid = ip->di_gid; 196: return; 197: } 198: } 199: lookup(ino, 1); 200: } 201: 202: pass2(ip) 203: register struct dinode *ip; 204: { 205: register struct direct *dp; 206: struct dirstuff dirp; 207: struct htab *hp; 208: 209: if((ip->di_mode&IFMT) != IFDIR) 210: return; 211: dirp.loc = 0; 212: dirp.ip = ip; 213: gip = ip; 214: for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { 215: if(dp->d_ino == 0) 216: continue; 217: hp = lookup((ino_t)dp->d_ino, 0); 218: if(hp == 0) 219: continue; 220: if(dotname(dp)) 221: continue; 222: hp->h_pino = ino; 223: hp->h_name = (char *)malloc(strlen(dp->d_name) + 1); 224: if (hp->h_name == (char *)NULL) { 225: fprintf(stderr, "no memory for name %s\n",dp->d_name); 226: return; 227: } 228: strcpy(hp->h_name, dp->d_name); 229: } 230: } 231: 232: pass3(ip) 233: register struct dinode *ip; 234: { 235: register struct direct *dp; 236: struct dirstuff dirp; 237: int k; 238: 239: if((ip->di_mode&IFMT) != IFDIR) 240: return; 241: dirp.loc = 0; 242: dirp.ip = ip; 243: gip = ip; 244: for(dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { 245: if(aflg==0 && dotname(dp)) 246: continue; 247: if(sflg == 0 && iflg == 0) 248: goto pr; 249: for(k = 0; ilist[k].ino != 0; k++) 250: if(ilist[k].ino == dp->d_ino) 251: break; 252: if (ilist[k].ino == 0) 253: continue; 254: if (mflg) 255: printf("mode %-6o uid %-5d gid %-5d ino ", 256: ilist[k].mode, ilist[k].uid, ilist[k].gid); 257: pr: 258: printf("%-5u\t", (ino_t)dp->d_ino); 259: pname(ino, 0); 260: printf("/%s", dp->d_name); 261: if (lookup((ino_t)dp->d_ino, 0)) 262: printf("/."); 263: printf("\n"); 264: } 265: } 266: 267: /* 268: * get next entry in a directory. 269: */ 270: struct direct * 271: readdir(dirp) 272: register struct dirstuff *dirp; 273: { 274: register struct direct *dp; 275: daddr_t lbn, d; 276: 277: for(;;) { 278: if (dirp->loc >= dirp->ip->di_size) 279: return NULL; 280: if (blkoff(dirp->loc) == 0) { 281: lbn = lblkno(dirp->loc); 282: d = bmap(lbn); 283: if(d == 0) 284: return NULL; 285: bread(d, dirp->dbuf, DEV_BSIZE); 286: } 287: dp = (struct direct *) (dirp->dbuf + blkoff(dirp->loc)); 288: dirp->loc += dp->d_reclen; 289: if (dp->d_ino == 0) 290: continue; 291: return (dp); 292: } 293: } 294: 295: dotname(dp) 296: register struct direct *dp; 297: { 298: 299: if (dp->d_name[0]=='.') 300: if (dp->d_name[1]==0 || 301: (dp->d_name[1]=='.' && dp->d_name[2]==0)) 302: return(1); 303: return(0); 304: } 305: 306: pname(i, lev) 307: ino_t i; 308: int lev; 309: { 310: register struct htab *hp; 311: 312: if (i==ROOTINO) 313: return; 314: if ((hp = lookup(i, 0)) == 0) { 315: printf("???"); 316: return; 317: } 318: if (lev > 10) { 319: printf("..."); 320: return; 321: } 322: pname(hp->h_pino, ++lev); 323: printf("/%s", hp->h_name); 324: } 325: 326: struct htab * 327: lookup(i, ef) 328: ino_t i; 329: int ef; 330: { 331: register struct htab *hp; 332: 333: for (hp = &htab[i%HSIZE]; hp->h_ino;) { 334: if (hp->h_ino==i) 335: return(hp); 336: if (++hp >= &htab[HSIZE]) 337: hp = htab; 338: } 339: if (ef==0) 340: return(0); 341: if (++nhent >= HSIZE) { 342: fprintf(stderr, "ncheck: HSIZE of %d is too small\n", HSIZE); 343: exit(1); 344: } 345: hp->h_ino = i; 346: return(hp); 347: } 348: 349: bread(bno, buf, cnt) 350: daddr_t bno; 351: char *buf; 352: register int cnt; 353: { 354: 355: lseek(fi, bno * DEV_BSIZE, 0); 356: if (read(fi, buf, cnt) != cnt) { 357: fprintf(stderr, "ncheck: read error %d\n", bno); 358: bzero(buf, cnt); 359: } 360: } 361: 362: daddr_t 363: bmap(i) 364: daddr_t i; 365: { 366: daddr_t ibuf[NINDIR]; 367: 368: if(i < NDADDR) 369: return(gip->di_addr[i]); 370: i -= NDADDR; 371: if(i > NINDIR) { 372: fprintf(stderr, "ncheck: %u - huge directory\n", ino); 373: return((daddr_t)0); 374: } 375: bread(gip->di_addr[NDADDR], (char *)ibuf, sizeof(ibuf)); 376: return(ibuf[i]); 377: }