|
|
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.