示例#1
0
/*
 * NAME:	vol->catsearch()
 * DESCRIPTION:	search catalog tree
 */
int v_catsearch(hfsvol *vol, long parid, const char *name,
                CatDataRec *data, char *cname, node *np)
{
    CatKeyRec key;
    byte pkey[HFS_CATKEYLEN];
    const byte *ptr;
    node n;
    int found;

    if (np == 0)
        np = &n;

    r_makecatkey(&key, parid, name);
    r_packcatkey(&key, pkey, 0);

    found = bt_search(&vol->cat, pkey, np);
    if (found <= 0)
        return found;

    ptr = HFS_NODEREC(*np, np->rnum);

    if (cname)
    {
        r_unpackcatkey(ptr, &key);
        strcpy(cname, key.ckrCName);
    }

    if (data)
        r_unpackcatdata(HFS_RECDATA(ptr), data);

    return 1;
}
示例#2
0
/*
 * NAME:	vol->scavenge()
 * DESCRIPTION:	safeguard blocks in the volume bitmap
 */
int v_scavenge(hfsvol *vol)
{
    const block *vbm = vol->vbm;
    node n;
    unsigned int pt, blks;

    if (vbm == 0)
        goto done;

    markexts(vbm, &vol->mdb.drXTExtRec);
    markexts(vbm, &vol->mdb.drCTExtRec);

    vol->flags |= HFS_VOL_UPDATE_VBM;

    /* scavenge the extents overflow file */

    n.bt   = &vol->ext;
    n.nnum = vol->ext.hdr.bthFNode;

    if (n.nnum > 0)
    {
        if (bt_getnode(&n) == -1)
            goto fail;

        n.rnum = 0;

        while (1)
        {
            ExtDataRec data;
            const byte *ptr;

            while (n.rnum >= n.nd.ndNRecs)
            {
                n.nnum = n.nd.ndFLink;
                if (n.nnum == 0)
                    break;

                if (bt_getnode(&n) == -1)
                    goto fail;

                n.rnum = 0;
            }

            if (n.nnum == 0)
                break;

            ptr = HFS_NODEREC(n, n.rnum);
            r_unpackextdata(HFS_RECDATA(ptr), &data);

            markexts(vbm, &data);

            ++n.rnum;
        }
    }

    /* scavenge the catalog file */

    n.bt   = &vol->cat;
    n.nnum = vol->cat.hdr.bthFNode;

    if (n.nnum > 0)
    {
        if (bt_getnode(&n) == -1)
            goto fail;

        n.rnum = 0;

        while (1)
        {
            CatDataRec data;
            const byte *ptr;

            while (n.rnum >= n.nd.ndNRecs)
            {
                n.nnum = n.nd.ndFLink;
                if (n.nnum == 0)
                    break;

                if (bt_getnode(&n) == -1)
                    goto fail;

                n.rnum = 0;
            }

            if (n.nnum == 0)
                break;

            ptr = HFS_NODEREC(n, n.rnum);
            r_unpackcatdata(HFS_RECDATA(ptr), &data);

            if (data.cdrType == cdrFilRec)
            {
                markexts(vbm, &data.u.fil.filExtRec);
                markexts(vbm, &data.u.fil.filRExtRec);
            }

            ++n.rnum;
        }
    }

    for (blks = 0, pt = vol->mdb.drNmAlBlks; pt--; )
    {
        if (! BMTST(vbm, pt))
            ++blks;
    }

    if (vol->mdb.drFreeBks != blks)
    {
        vol->mdb.drFreeBks = blks;
        vol->flags |= HFS_VOL_UPDATE_MDB;
    }

done:
    return 0;

fail:
    return -1;
}
示例#3
0
文件: hfs.c 项目: 3a9LL/panda
/*
 * NAME:	hfs->readdir()
 * DESCRIPTION:	return the next entry in the directory
 */
int hfs_readdir(hfsdir *dir, hfsdirent *ent)
{
  CatKeyRec key;
  CatDataRec data;
  const byte *ptr;

  if (dir->dirid == 0)
    {
      hfsvol *vol;
      char cname[HFS_MAX_FLEN + 1];

      for (vol = hfs_mounts; vol; vol = vol->next)
	{
	  if (vol == dir->vptr)
	    break;
	}

      if (vol == NULL)
	ERROR(ENOENT, "no more entries");

      if (v_getdthread(vol, HFS_CNID_ROOTDIR, &data, NULL) <= 0 ||
	  v_catsearch(vol, HFS_CNID_ROOTPAR, data.u.dthd.thdCName,
                      &data, cname, NULL) <= 0)
	goto fail;

      r_unpackdirent(HFS_CNID_ROOTPAR, cname, &data, ent);

      dir->vptr = vol->next;

      goto done;
    }

  if (dir->n.rnum == -1)
    ERROR(ENOENT, "no more entries");

  while (1)
    {
      ++dir->n.rnum;

      while (dir->n.rnum >= dir->n.nd.ndNRecs)
	{
	  if (dir->n.nd.ndFLink == 0)
	    {
	      dir->n.rnum = -1;
	      ERROR(ENOENT, "no more entries");
	    }

	  if (bt_getnode(&dir->n, dir->n.bt, dir->n.nd.ndFLink) == -1)
	    {
	      dir->n.rnum = -1;
	      goto fail;
	    }

	  dir->n.rnum = 0;
	}

      ptr = HFS_NODEREC(dir->n, dir->n.rnum);

      r_unpackcatkey(ptr, &key);

      if (key.ckrParID != dir->dirid)
	{
	  dir->n.rnum = -1;
	  ERROR(ENOENT, "no more entries");
	}

      r_unpackcatdata(HFS_RECDATA(ptr), &data);

      switch (data.cdrType)
	{
	case cdrDirRec:
	case cdrFilRec:
	  r_unpackdirent(key.ckrParID, key.ckrCName, &data, ent);
	  goto done;

	case cdrThdRec:
	case cdrFThdRec:
	  break;

	default:
	  dir->n.rnum = -1;
	  ERROR(EIO, "unexpected directory entry found");
	}
    }

done:
  return 0;

fail:
  return -1;
}