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);
}

Reply via email to