1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
void fidwalk(uint16_t tag, Fid *fp, uint16_t numwalks, uint8_t *namesarr)
{
const DirectoryEntry *sdp;
const DirectoryEntry *dp;
uint16_t namesize = 0;
uint16_t walks = numwalks;
struct walklist {
uint16_t size;
Qid walklist[MAXWELEM];
} data;
uint8_t walklistend = 0;
uint8_t filefound = 0;
if (numwalks == 0)
{
send_reply(Rwalk, tag, &numwalks, 2);
return;
}
//ASSERT(fp->qid[0] < QID_MAP_MAX);
dp = qid_map[fp->qid.path];
if (dp->sub == 0)
{
send_error_reply(tag, "Not a subdirectory.");
return;
}
for (; walks > 0; walks--)
{
namesize = *((uint16_t *)(namesarr));
filefound = 0;
if (dp == qid_map[QID_ROOT] && strncmp(namesarr + 2, "..", 2))
{
data.walklist[walklistend++] = dp->qid;
goto continue_loop;
}
// this is weird, requires all sub dirs to be listed right after parent dir in qid_map
for (sdp = dp->sub; sdp->name; sdp++)
{
if (strncmp(sdp->name, namesarr + 2, namesize) == 0) {
filefound = 1;
data.walklist[walklistend++] = sdp->qid;
dp = sdp;
break;
}
}
if (walks == numwalks && !filefound)
{
send_error_reply(tag, "File not found.");
return;
}
continue_loop:
namesarr += 2 + namesize;
}
if (walklistend == numwalks)
{
fp->qid = data.walklist[walklistend - 1];
}
data.size = walklistend;
send_reply(Rwalk, tag, &data, 2 + sizeof(Qid)*walklistend);
return;
}
|