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