#include /* Hacked to run under Winodoze - JNC 28/Mar/2014 * * Three passes: * - 1 loads directory inode numbers into htab table (in hino field) * - 2 loads parent directory inode numbers (in hpino field), and * also directory entry for the child inode * - 3 with table completely filled, run down list printing path for * each entry * * Note that bug where doubly linked inodes will got over-written in pass * 2 has been semi-fixed to note when it happens (flag -o suppresses this * notification) */ char *dargv[] = { 0 }; #include "../sys/h/wino.h" #include "../sys/h/wfilsys.h" #define BLKSIZ 512 #define ISIZ sizeof(struct inode) #define NIBLK (BLKSIZ / ISIZ) #define NINODE (16*NIBLK) struct filsys sblock; struct inode inode[NINODE]; int aflg; int dflg; int oflg; #define NI 20 #define NDIRS 787 int ilist[NI] = { -1}; FILE *fi; struct htab { int hino; int hpino; char hname[14]; } htab[NDIRS]; int nhent = 10; int ino; int nerror; int nfiles; struct dir { short int ino; char name[14]; }; #define DSIZ sizeof(struct dir) struct htab *lookup(); struct dir *dread(); main(argc, argv) char **argv; { register char **p; register int *lp; int n; if (argc == 1) { for (p = dargv; *p;) check(*p++); return(nerror); } while (--argc) { argv++; if (**argv=='-') switch ((*argv)[1]) { case 'a': aflg++; continue; case 'd': dflg++; continue; case 'o': oflg++; continue; case 'i': lp = &ilist[0]; while (lp < &ilist[NI-1] && (n = number(argv[1]))) { *lp++ = n; argv++; argc--; } *lp++ = -1; continue; default: printf2("Bad flag\n"); } check(*argv); } return(nerror); } check(file) char *file; { register i, j, pno; fi = fopen(file, "rb"); if (fi <= 0) { printf2("cannot open %s\n", file); return; } printf2("%s:\n", file); bread(1, ((char *) &sblock), 512); nfiles = sblock.s_isize * NIBLK; if (dflg) printf("Ninodes: %d\n", nfiles); for (i=0; ii_mode&IALLOC)==0 || (ip->i_mode&IFMT)!=IFDIR) return; lookup(ino, 1); } pass2(ip) struct inode *ip; { register doff; register struct htab *hp; register struct dir *dp; int i; if ((ip->i_mode&IALLOC)==0 || (ip->i_mode&IFMT)!=IFDIR) return; doff = 0; while (dp = dread(ip, doff)) { doff += DSIZ; if (dp->ino==0) continue; if ((hp = lookup(dp->ino, 0)) == 0) continue; if (dotname(dp)) continue; if ((hp->hpino != 0) && !oflg) printf2("Multiple link to inode lost %d '%.14s'\n", hp->hpino, &hp->hname[0]); hp->hpino = ino; for (i=0; i<14; i++) hp->hname[i] = dp->name[i]; } } pass3(ip, grp, ent) struct inode *ip; { register doff; register struct dir *dp; register int *ilp; if ((ip->i_mode&IALLOC)==0 || (ip->i_mode&IFMT)!=IFDIR) return; if (dflg) printf("p3: %d %d\n", (grp/NIBLK), ent); doff = 0; while (dp = dread(ip, doff)) { doff += DSIZ; if (dp->ino==0) continue; if (aflg==0 && dotname(dp)) continue; for (ilp=&ilist[0]; *ilp >= 0; ilp++) if (*ilp == dp->ino) break; if ((ilp > &ilist[0]) && (*ilp != dp->ino)) continue; printf("%-8d", dp->ino); pname(ino, 0); printf("/%.14s\n", dp->name); } } dotname(adp) struct dir *adp; { register struct dir *dp; dp = adp; if (dp->name[0]=='.') if (dp->name[1]==0 || dp->name[1]=='.' && dp->name[2]==0) return(1); return(0); } pname(i, lev) { register struct htab *hp; if (i==1) return; if ((hp = lookup(i, 0)) == 0) { printf("???"); return; } if (lev > 10) { printf("..."); return; } pname(hp->hpino, ++lev); printf("/%.14s", hp->hname); } struct htab *lookup(i, ef) { register struct htab *hp; for (hp = &htab[i%NDIRS]; hp->hino;) { if (hp->hino==i) return(hp); if (++hp >= &htab[NDIRS]) hp = &htab[0]; } if (ef==0) return(0); if (++nhent >= NDIRS) { printf("Out of core-- increase NDIRS\n"); exit(1); } hp->hino = i; return(hp); } struct dir *dread(aip, aoff) struct inode *aip; { int b; register int off; register struct inode *ip; static short int ibuf[256]; static char buf[512]; b = -1; off = aoff; ip = aip; if ((off&0777)==0) { if (off==0177000) { printf2("Monstrous directory %l\n", ino); return(0); } if ((ip->i_mode&ILARG)==0) { if (off>=010000 || (b = ip->i_addr[off>>9])==0) return(0); bread(b, &buf[0], 512); } else { if (off==0) { if (ip->i_addr[0]==0) return(0); bread(ip->i_addr[0], ((char *) &ibuf[0]), 512); } if ((b = ibuf[(off>>9)&0177])==0) return(0); bread(b, &buf[0], 512); } } return(((struct dir *) &buf[off&0777])); } bread(bno, buf, cnt) char *buf; { fseek(fi, (bno * BLKSIZ), SEEK_SET); if (fread(buf, sizeof(char), cnt, fi) != cnt) { printf("read error %d\n", bno); exit(); } } number(as) char *as; { register n, c; register char *s; s = as; n = 0; while ((c = *s++) >= '0' && c <= '9') { n = n*10+c-'0'; } return(n); } printf2(s, a1, a2) char *s; { printf(s, a1, a2); fflush(stdout); }