|
|
1.1 ! root 1: #include "fs.h" ! 2: ! 3: dirblocks() ! 4: { int i; ! 5: i = -1; ! 6: loop: ! 7: if(++i >= lblk) ! 8: return; ! 9: switch(bmap[i].type) { ! 10: default: ! 11: pmesg("strange blk type %d in dirblocks\n", bmap[i].type); ! 12: bmap[i].type = Bad; ! 13: goto loop; ! 14: case Unk: case Sblock: case Inode: case Free: case Data: case Ind: ! 15: case Ind2: case Ind3: case Bits: case Ioerr: case Bad: case Boot: ! 16: goto loop; ! 17: case First: ! 18: if(bread(i, buf, 1)) { ! 19: pmesg("dir %d first read %d failed\n", bmap[i].ino, i); ! 20: bmap[i].type = Ioerr; ! 21: direrror(Efirstio, bmap[i].ino); ! 22: goto loop; ! 23: } ! 24: dofirst(i); ! 25: doother(i); ! 26: goto loop; ! 27: case Other: ! 28: if(bread(i, buf, 1)) { ! 29: pmesg("dir %d blk read %d failed\n", bmap[i].ino, i); ! 30: bmap[i].type = Ioerr; ! 31: direrror(Edirio, bmap[i].ino); ! 32: goto loop; ! 33: } ! 34: doother(i); ! 35: goto loop; ! 36: } ! 37: } ! 38: ! 39: /* check that the first two entries are named . and .., and that .'s ino is ours */ ! 40: /* also check the directory's length somewhere FIX */ ! 41: dofirst(i) ! 42: { struct direct *dp; ! 43: int ino = bmap[i].ino; ! 44: dp = (struct direct *) buf; ! 45: if(dp->d_name[0] != '.' || dp->d_name[1] != 0) ! 46: direrror(Enotdot, ino, 0); ! 47: if(dp->d_ino != ino) ! 48: direrror(Edotino, ino, dp->d_ino); ! 49: dp++; ! 50: if(dp->d_name[0] != '.' || dp->d_name[1] != '.' || dp->d_name[2] != 0) ! 51: direrror(Enotdotdot, ino, 0); ! 52: else { ! 53: if(imap[ino].dotdot) ! 54: direrror(Emulti, ino, imap[ino].dotdot); ! 55: imap[ino].dotdot = dp->d_ino; /* unchecked FIX */ ! 56: } ! 57: if(ino == imap[ino].dotdot && ino != ROOTINO) ! 58: direrror(Efakeroot, ino, 0); ! 59: } ! 60: ! 61: doother(n) ! 62: { register int ino = bmap[n].ino, j; ! 63: register struct direct *dp = (struct direct *) buf, *dend; ! 64: register char *p; ! 65: register im *ip; ! 66: dend = (struct direct *) (buf + bsize); ! 67: if(dmapptr+(dend-dp) >= dmaplen) { ! 68: dmaplen *= 3; ! 69: dmap = (dm *) realloc((char *) dmap, dmaplen*sizeof(dm)); ! 70: if(!dmap) ! 71: fatal("doother realloc(%d) failed\n", dmaplen); ! 72: } ! 73: for(; dp < dend; dp++) { ! 74: if(dp->d_ino == 0) ! 75: continue; ! 76: if(dp->d_ino < 1 || dp->d_ino >= ninode) { ! 77: direrror(Ebadino, ino, n); ! 78: continue; ! 79: } ! 80: ip = imap + dp->d_ino; ! 81: if(ip->type == Dir) { ! 82: dmap[dmapptr].dino = ino; ! 83: dmap[dmapptr].ino = dp->d_ino; ! 84: dmapptr++; ! 85: } ! 86: else if(ip->type == Unalloc) { ! 87: direrror(Ebadino, ino, n); ! 88: /* should we look more closely at inode? FIX */ ! 89: } ! 90: ip->nrefs++; ! 91: p = dp->d_name; ! 92: if(p[0] != '.' || (p[1] != '.' && p[1]) || p[2] != 0) ! 93: ip->parent = ino; /* ., .. don't help */ ! 94: for(j = 0; j < DIRSIZ; j++, p++) ! 95: if(*p <= 0 || *p > 127) ! 96: break; ! 97: if(j >= DIRSIZ) ! 98: continue; ! 99: if(*p) { ! 100: direrror(Ebadname, ino, dp->d_ino); ! 101: continue; ! 102: } ! 103: for(; j < DIRSIZ; j++, p++) ! 104: if(*p) ! 105: break; ! 106: if(j >= DIRSIZ) ! 107: continue; ! 108: direrror(Ebadname, ino, dp->d_ino); ! 109: } ! 110: } ! 111: ! 112: dcmp(a, b) ! 113: register dm *a, *b; ! 114: { ! 115: return(a->dino - b->dino); ! 116: } ! 117: ! 118: dirtree() ! 119: { register int i, last = -1; ! 120: /* sort by directory */ ! 121: qsort((char *)dmap, dmapptr, sizeof(dm), dcmp); ! 122: for(i = 0; i < dmapptr; i++) ! 123: if(dmap[i].dino != last) { ! 124: last = dmap[i].dino; ! 125: imap[last].ptr = i; ! 126: } ! 127: /* is dotdot really a parent pointer? */ ! 128: for(i = 1; i < ninode; i++) { ! 129: if(imap[i].type != Dir) ! 130: continue; ! 131: if(dirin(i, imap[i].dotdot)) ! 132: continue; ! 133: direrror(Ebadparent, i, imap[i].dotdot); ! 134: } ! 135: /* are they all accessible from the root? */ ! 136: if(imap[ROOTINO].type != Dir) ! 137: fatal("root ino %d not a directory\n", ROOTINO); /* FIX */ ! 138: chtree(ROOTINO); ! 139: for(i = 0; i < ninode; i++) { ! 140: if(imap[i].type != Dir) ! 141: continue; ! 142: if(!imap[i].seen) ! 143: direrror(Eattach, i, 0); ! 144: } ! 145: } ! 146: ! 147: chtree(n) ! 148: { dm *d; ! 149: if(!imap[n].ptr && n != ROOTINO) { ! 150: pmesg("dir %s contains nothing\n", prino(n)); ! 151: return; ! 152: } ! 153: imap[n].seen = 1; ! 154: for(d = dmap + imap[n].ptr; d->dino == n; d++) /* end condition? FIX */ ! 155: if(!imap[d->ino].seen) ! 156: chtree(d->ino); ! 157: } ! 158: ! 159: dirin(child, parent) ! 160: { int n, i; ! 161: for(n = imap[parent].ptr; n < dmapptr && dmap[n].dino == parent; n++) ! 162: if(dmap[n].ino == child) ! 163: return(1); ! 164: return(0); ! 165: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.