Marcus Watts writes:
> If you can't figure out how it works or find they aren't useful
> as they stand, then you will need to figure out how to parse directories
> on your own. The file include/afs/dir.h has some structures and other
> manifests that should make this possible. It may help to know that
> entries are stored in a list of one or more contiguous 32-byte blobs
> (struct DirEntry and struct DirXEntry). Directories are enumerated
> by reading through the hash table ((struct DirHeader).hashTable), which
> is found at the start of the directory, and then traversing each chain
> so found (the hash link is (struct DirEntry).next).
Hmm... I suspect my dump-parser is rather more primitive than the
one Marcus describes above. However, one of the things I do is parse
the contents of directories, sort of. The code below is what I currently
use for parsing directory contents; it ignores the hash tables and instead
simply examines a flag in each directory entry which seems to correlate
well with whether the entry is in use. Eventually, I'll refine it to
actually use the hash tables; in the meantime, this might be useful...
-- Jeffrey T. Hutzelman (N3NHS) <[EMAIL PROTECTED]>
Systems Programmer, CMU SCS Research Facility
Please send requests and problem reports to [EMAIL PROTECTED]
static int ParseDirectory(FILE *f, char *tag)
{
static char buffer[AFS_PAGESIZE];
struct DirPage1 *page = (struct DirPage1 *)buffer;
struct {
struct DirEntry e;
int32 pad;
} *entry = &page->entry;
int code, size, len, i;
int count = AFS_PAGESIZE;
int page0 = 1, slot = 0;
printf(" Contents: Slot Vnode Uniqifier Name\n");
if (code = ReadInt32(f, &size)) return code;
while (size) {
if (size < AFS_PAGESIZE)
{
bzero(buffer, AFS_PAGESIZE);
count = size;
}
if (fread(buffer, 1, count, f) != count) {
if (ferror(f)) return errno;
else return -1;
}
if (page0 && htonl(page->header.tag) != 1234) {
printf("Invalid page tag: %d should be 1234\n", ntohl(page->header.tag));
return -3;
}
for (i = page0 ? DHE : 0; i < EPP-1; i++, slot++) {
if (!entry[i].e.flag) continue; /* Free entry, we hope */
if (!entry[i].e.name[0]) continue;
printf(" %4d %10d %10d %s\n", slot,
ntohl(entry[i].e.fid.vnode), ntohl(entry[i].e.fid.vunique),
entry[i].e.name);
len = strlen(entry[i].e.name);
if (len > 15) /* Account for extension blobs */
i += (len - 16) / 32 + 1;
}
page0 = 0;
size -= count;
}
return ReadByte(f, tag);
}