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