Example #1
0
/*
 * NAME:	vol->readmdb()
 * DESCRIPTION:	load Master Directory Block into memory
 */
int v_readmdb(hfsvol *vol)
{
    if (l_getmdb(vol, &vol->mdb, 0) == -1)
        goto fail;

    if (vol->mdb.drSigWord != HFS_SIGWORD)
    {
        if (vol->mdb.drSigWord == HFS_SIGWORD_MFS)
            ERROR(EINVAL, "MFS volume format not supported");
        else
            ERROR(EINVAL, "not a Macintosh HFS volume");
    }

    if (vol->mdb.drAlBlkSiz % HFS_BLOCKSZ != 0)
        ERROR(EINVAL, "bad volume allocation block size");

    vol->lpa = vol->mdb.drAlBlkSiz >> HFS_BLOCKSZ_BITS;

    /* extents pseudo-file structs */

    vol->ext.f.cat.u.fil.filStBlk   = vol->mdb.drXTExtRec[0].xdrStABN;
    vol->ext.f.cat.u.fil.filLgLen   = vol->mdb.drXTFlSize;
    vol->ext.f.cat.u.fil.filPyLen   = vol->mdb.drXTFlSize;

    vol->ext.f.cat.u.fil.filCrDat   = vol->mdb.drCrDate;
    vol->ext.f.cat.u.fil.filMdDat   = vol->mdb.drLsMod;

    vol->ext.f.cat.u.fil.filClpSize = vol->mdb.drXTClpSiz;

    memcpy(&vol->ext.f.cat.u.fil.filExtRec,
           &vol->mdb.drXTExtRec, sizeof(ExtDataRec));

    f_selectfork(&vol->ext.f, fkData);

    /* catalog pseudo-file structs */

    vol->cat.f.cat.u.fil.filStBlk   = vol->mdb.drCTExtRec[0].xdrStABN;
    vol->cat.f.cat.u.fil.filLgLen   = vol->mdb.drCTFlSize;
    vol->cat.f.cat.u.fil.filPyLen   = vol->mdb.drCTFlSize;

    vol->cat.f.cat.u.fil.filCrDat   = vol->mdb.drCrDate;
    vol->cat.f.cat.u.fil.filMdDat   = vol->mdb.drLsMod;

    vol->cat.f.cat.u.fil.filClpSize = vol->mdb.drCTClpSiz;

    memcpy(&vol->cat.f.cat.u.fil.filExtRec,
           &vol->mdb.drCTExtRec, sizeof(ExtDataRec));

    f_selectfork(&vol->cat.f, fkData);

    return 0;

fail:
    return -1;
}
Example #2
0
/*
 * NAME:	file->init()
 * DESCRIPTION:	initialize file structure
 */
void f_init(hfsfile *file, hfsvol *vol, long cnid, const char *name)
{
  int i;

  file->vol   = vol;
  file->parid = 0;

  strcpy(file->name, name);

  file->cat.cdrType          = cdrFilRec;
  file->cat.cdrResrv2        = 0;

  file->cat.u.fil.filFlags   = 0;
  file->cat.u.fil.filTyp     = 0;

  file->cat.u.fil.filUsrWds.fdType       = 0;
  file->cat.u.fil.filUsrWds.fdCreator    = 0;
  file->cat.u.fil.filUsrWds.fdFlags      = 0;
  file->cat.u.fil.filUsrWds.fdLocation.v = 0;
  file->cat.u.fil.filUsrWds.fdLocation.h = 0;
  file->cat.u.fil.filUsrWds.fdFldr       = 0;

  file->cat.u.fil.filFlNum   = cnid;
  file->cat.u.fil.filStBlk   = 0;
  file->cat.u.fil.filLgLen   = 0;
  file->cat.u.fil.filPyLen   = 0;
  file->cat.u.fil.filRStBlk  = 0;
  file->cat.u.fil.filRLgLen  = 0;
  file->cat.u.fil.filRPyLen  = 0;
  file->cat.u.fil.filCrDat   = 0;
  file->cat.u.fil.filMdDat   = 0;
  file->cat.u.fil.filBkDat   = 0;

  file->cat.u.fil.filFndrInfo.fdIconID = 0;
  for (i = 0; i < 4; ++i)
    file->cat.u.fil.filFndrInfo.fdUnused[i] = 0;
  file->cat.u.fil.filFndrInfo.fdComment = 0;
  file->cat.u.fil.filFndrInfo.fdPutAway = 0;

  file->cat.u.fil.filClpSize = 0;

  for (i = 0; i < 3; ++i)
    {
      file->cat.u.fil.filExtRec[i].xdrStABN     = 0;
      file->cat.u.fil.filExtRec[i].xdrNumABlks  = 0;

      file->cat.u.fil.filRExtRec[i].xdrStABN    = 0;
      file->cat.u.fil.filRExtRec[i].xdrNumABlks = 0;
    }

  file->cat.u.fil.filResrv   = 0;

  f_selectfork(file, fkData);

  file->flags = 0;

  file->prev  = 0;
  file->next  = 0;
}
Example #3
0
File: hfs.c Project: 3a9LL/panda
/*
 * NAME:	hfs->setfork()
 * DESCRIPTION:	select file fork for I/O operations
 */
int hfs_setfork(hfsfile *file, int fork)
{
  int result = 0;

  f_selectfork(file, fork ? fkRsrc : fkData);

  return result;
}
Example #4
0
/*
 * NAME:	hfs->setfork()
 * DESCRIPTION:	select file fork for I/O operations
 */
int hfs_setfork(hfsfile *file, int fork)
{
  int result = 0;

  if (f_trunc(file) == -1)
    result = -1;

  f_selectfork(file, fork ? fkRsrc : fkData);

  return result;
}
Example #5
0
/*
 * NAME:	hfs->setfork()
 * DESCRIPTION:	select file fork for I/O operations
 */
int hfs_setfork(hfsfile *file, int fork)
{
  int result = 0;

  if (! (file->vol->flags & HFS_READONLY) &&
      f_trunc(file) < 0)
    result = -1;

  f_selectfork(file, fork);

  return result;
}
Example #6
0
/*
 * NAME:	hfs->open()
 * DESCRIPTION:	prepare a file for I/O
 */
hfsfile *hfs_open(hfsvol *vol, const char *path)
{
  hfsfile *file = 0;
  hfsfile *f = 0;

  if (getvol(&vol) == -1)
    ERROR(ENODEV, 0);

  file = ALLOC(hfsfile, 1);
  if (file == 0)
    ERROR(ENOMEM, 0);

  if (v_resolve(&vol, path, &file->cat, &file->parid, file->name, 0) <= 0)
	ERROR(ENOENT, 0);

  if (file->cat.cdrType != cdrFilRec)
    ERROR(EISDIR, 0);
	
  // see if it's already open
  for(f = vol->files; f; f = f->next) {
	  if (f->cat.u.fil.filFlNum == file->cat.u.fil.filFlNum) {
		  // already open, increment refcount and return
		  FREE(file);
		  file = f;
		  file->refs++;
		  printf("REOPEN: file %s now has %d refs\n", path, file->refs);
		  return file;
	  }
  }

  /* package file handle for user */
  file->refs  = 1;
  file->vol   = vol;
  file->flags = 0;

  f_selectfork(file, fkData);

  file->prev = 0;
  file->next = vol->files;

  if (vol->files)
    vol->files->prev = file;

  vol->files = file;

  return file;

fail:
  FREE(file);
  return 0;
}
Example #7
0
/*
 * NAME:	hfs->open()
 * DESCRIPTION:	prepare a file for I/O
 */
hfsfile *hfs_open(hfsvol *vol, char *path)
{
  hfsfile *file;

  if (v_getvol(&vol) < 0)
    return 0;

  file = ALLOC(hfsfile, 1);
  if (file == 0)
    {
      ERROR(ENOMEM, 0);
      return 0;
    }

  if (v_resolve(&vol, path, &file->cat, &file->parid, file->name, 0) <= 0)
    {
      FREE(file);
      return 0;
    }

  if (file->cat.cdrType != cdrFilRec)
    {
      FREE(file);
      ERROR(EISDIR, 0);
      return 0;
    }

  file->vol   = vol;
  file->clump = file->cat.u.fil.filClpSize;
  file->flags = 0;

  f_selectfork(file, 0);

  file->prev = 0;
  file->next = vol->files;

  if (vol->files)
    vol->files->prev = file;

  vol->files = file;

  return file;
}
Example #8
0
File: hfs.c Project: 3a9LL/panda
/*
 * NAME:	hfs->open()
 * DESCRIPTION:	prepare a file for I/O
 */
hfsfile *hfs_open(hfsvol *vol, const char *path)
{
  hfsfile *file = NULL;

  if (getvol(&vol) == -1)
    goto fail;

  file = ALLOC(hfsfile, 1);
  if (file == NULL)
    ERROR(ENOMEM, NULL);

  if (v_resolve(&vol, path, &file->cat, &file->parid, file->name, NULL) <= 0)
    goto fail;

  if (file->cat.cdrType != cdrFilRec)
    ERROR(EISDIR, NULL);

  /* package file handle for user */

  file->vol   = vol;
  file->flags = 0;

  f_selectfork(file, fkData);

  file->prev = NULL;
  file->next = vol->files;

  if (vol->files)
    vol->files->prev = file;

  vol->files = file;

  return file;

fail:
  FREE(file);
  return NULL;
}
Example #9
0
/*
 * NAME:	low->readmdb()
 * DESCRIPTION:	read the master directory block into memory
 */
int l_readmdb(hfsvol *vol)
{
  block b;
  unsigned char *ptr = b;
  MDB *mdb = &vol->mdb;
  hfsfile *ext = &vol->ext.f;
  hfsfile *cat = &vol->cat.f;
  int i;

  if (b_readlb(vol, 2, &b) < 0)
    return -1;

  d_fetchw(&ptr, &mdb->drSigWord);
  d_fetchl(&ptr, &mdb->drCrDate);
  d_fetchl(&ptr, &mdb->drLsMod);
  d_fetchw(&ptr, &mdb->drAtrb);
  d_fetchw(&ptr, (short *) &mdb->drNmFls);
  d_fetchw(&ptr, (short *) &mdb->drVBMSt);
  d_fetchw(&ptr, (short *) &mdb->drAllocPtr);
  d_fetchw(&ptr, (short *) &mdb->drNmAlBlks);
  d_fetchl(&ptr, (long *) &mdb->drAlBlkSiz);
  d_fetchl(&ptr, (long *) &mdb->drClpSiz);
  d_fetchw(&ptr, (short *) &mdb->drAlBlSt);
  d_fetchl(&ptr, &mdb->drNxtCNID);
  d_fetchw(&ptr, (short *) &mdb->drFreeBks);

  d_fetchs(&ptr, mdb->drVN, sizeof(mdb->drVN));

  if (ptr - b != 64)
    abort();

  d_fetchl(&ptr, &mdb->drVolBkUp);
  d_fetchw(&ptr, &mdb->drVSeqNum);
  d_fetchl(&ptr, (long *) &mdb->drWrCnt);
  d_fetchl(&ptr, (long *) &mdb->drXTClpSiz);
  d_fetchl(&ptr, (long *) &mdb->drCTClpSiz);
  d_fetchw(&ptr, (short *) &mdb->drNmRtDirs);
  d_fetchl(&ptr, (long *) &mdb->drFilCnt);
  d_fetchl(&ptr, (long *) &mdb->drDirCnt);

  for (i = 0; i < 8; ++i)
    d_fetchl(&ptr, &mdb->drFndrInfo[i]);

  if (ptr - b != 124)
    abort();

  d_fetchw(&ptr, (short *) &mdb->drVCSize);
  d_fetchw(&ptr, (short *) &mdb->drVBMCSize);
  d_fetchw(&ptr, (short *) &mdb->drCtlCSize);

  d_fetchl(&ptr, (long *) &mdb->drXTFlSize);

  for (i = 0; i < 3; ++i)
    {
      d_fetchw(&ptr, (short *) &mdb->drXTExtRec[i].xdrStABN);
      d_fetchw(&ptr, (short *) &mdb->drXTExtRec[i].xdrNumABlks);
    }

  if (ptr - b != 146)
    abort();

  d_fetchl(&ptr, (long *) &mdb->drCTFlSize);

  for (i = 0; i < 3; ++i)
    {
      d_fetchw(&ptr, (short *) &mdb->drCTExtRec[i].xdrStABN);
      d_fetchw(&ptr, (short *) &mdb->drCTExtRec[i].xdrNumABlks);
    }

  if (ptr - b != 162)
    abort();

  vol->lpa = mdb->drAlBlkSiz / HFS_BLOCKSZ;

  /* extents pseudo-file structs */

  ext->vol   = vol;
  ext->parid = 0;
  strcpy(ext->name, "extents overflow");

  ext->cat.cdrType          = cdrFilRec;
  /* ext->cat.cdrResrv2 */
  ext->cat.u.fil.filFlags   = 0;
  ext->cat.u.fil.filTyp     = 0;
  /* ext->cat.u.fil.filUsrWds */
  ext->cat.u.fil.filFlNum   = HFS_CNID_EXT;
  ext->cat.u.fil.filStBlk   = mdb->drXTExtRec[0].xdrStABN;
  ext->cat.u.fil.filLgLen   = mdb->drXTFlSize;
  ext->cat.u.fil.filPyLen   = mdb->drXTFlSize;
  ext->cat.u.fil.filRStBlk  = 0;
  ext->cat.u.fil.filRLgLen  = 0;
  ext->cat.u.fil.filRPyLen  = 0;
  ext->cat.u.fil.filCrDat   = mdb->drCrDate;
  ext->cat.u.fil.filMdDat   = mdb->drLsMod;
  ext->cat.u.fil.filBkDat   = 0;
  /* ext->cat.u.fil.filFndrInfo */
  ext->cat.u.fil.filClpSize = 0;

  memcpy(ext->cat.u.fil.filExtRec, mdb->drXTExtRec, sizeof(ExtDataRec));
  for (i = 0; i < 3; ++i)
    {
      ext->cat.u.fil.filRExtRec[i].xdrStABN    = 0;
      ext->cat.u.fil.filRExtRec[i].xdrNumABlks = 0;
    }
  f_selectfork(ext, 0);

  ext->clump = mdb->drXTClpSiz;
  ext->flags = 0;

  ext->prev = ext->next = 0;

  /* catalog pseudo-file structs */

  cat->vol   = vol;
  cat->parid = 0;
  strcpy(cat->name, "catalog");

  cat->cat.cdrType          = cdrFilRec;
  /* cat->cat.cdrResrv2 */
  cat->cat.u.fil.filFlags   = 0;
  cat->cat.u.fil.filTyp     = 0;
  /* cat->cat.u.fil.filUsrWds */
  cat->cat.u.fil.filFlNum   = HFS_CNID_CAT;
  cat->cat.u.fil.filStBlk   = mdb->drCTExtRec[0].xdrStABN;
  cat->cat.u.fil.filLgLen   = mdb->drCTFlSize;
  cat->cat.u.fil.filPyLen   = mdb->drCTFlSize;
  cat->cat.u.fil.filRStBlk  = 0;
  cat->cat.u.fil.filRLgLen  = 0;
  cat->cat.u.fil.filRPyLen  = 0;
  cat->cat.u.fil.filCrDat   = mdb->drCrDate;
  cat->cat.u.fil.filMdDat   = mdb->drLsMod;
  cat->cat.u.fil.filBkDat   = 0;
  /* cat->cat.u.fil.filFndrInfo */
  cat->cat.u.fil.filClpSize = 0;

  memcpy(cat->cat.u.fil.filExtRec, mdb->drCTExtRec, sizeof(ExtDataRec));
  for (i = 0; i < 3; ++i)
    {
      cat->cat.u.fil.filRExtRec[i].xdrStABN    = 0;
      cat->cat.u.fil.filRExtRec[i].xdrNumABlks = 0;
    }
  f_selectfork(cat, 0);

  cat->clump = mdb->drCTClpSiz;
  cat->flags = 0;

  cat->prev = cat->next = 0;

  return 0;
}
Example #10
0
/*
 * NAME:	hfs->delete()
 * DESCRIPTION:	remove both forks of a file
 */
int hfs_delete(hfsvol *vol, const char *path)
{
  hfsfile file;
  CatKeyRec key;
  byte pkey[HFS_CATKEYLEN];
  int found;

  if (getvol(&vol) == -1 ||
      v_resolve(&vol, path, &file.cat, &file.parid, file.name, 0) <= 0)
    goto fail;

  if (file.cat.cdrType != cdrFilRec)
    ERROR(EISDIR, 0);

  if (file.parid == HFS_CNID_ROOTPAR)
    ERROR(EINVAL, 0);

  if (vol->flags & HFS_VOL_READONLY)
    ERROR(EROFS, 0);

  /* free allocation blocks */

  file.vol   = vol;
  file.flags = 0;

  file.cat.u.fil.filLgLen  = 0;
  file.cat.u.fil.filRLgLen = 0;

  f_selectfork(&file, fkData);
  if (f_trunc(&file) == -1)
    goto fail;

  f_selectfork(&file, fkRsrc);
  if (f_trunc(&file) == -1)
    goto fail;

  /* delete file record */

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

  if (bt_delete(&vol->cat, pkey) == -1 ||
      v_adjvalence(vol, file.parid, 0, -1) == -1)
    goto fail;

  /* delete file thread, if any */

  found = v_getfthread(vol, file.cat.u.fil.filFlNum, 0, 0);
  if (found == -1)
    goto fail;

  if (found)
    {
      r_makecatkey(&key, file.cat.u.fil.filFlNum, "");
      r_packcatkey(&key, pkey, 0);

      if (bt_delete(&vol->cat, pkey) == -1)
	goto fail;
    }

  return 0;

fail:
  return -1;
}
Example #11
0
/*
 * NAME:	hfs->format()
 * DESCRIPTION:	write a new filesystem
 */
int hfs_format(char *path, int pnum, char *vname)
{
  hfsvol vol;
  btree *ext = &vol.ext;
  btree *cat = &vol.cat;
  unsigned int vbmsz;
  int i, result = 0;
  block vbm[16];
  char *map;

  if (mystrchr(vname, ':'))
    {
      ERROR(EINVAL, "volume name may not contain colons");
      return -1;
    }

  i = strlen(vname);
  if (i < 1 || i > HFS_MAX_VLEN)
    {
      ERROR(EINVAL, "volume name must be 1-27 chars");
      return -1;
    }

  vol.flags  = 0;
  vol.pnum   = pnum;
  vol.vstart = 0;
  vol.vlen   = 0;
  vol.lpa    = 0;
  vol.vbm    = vbm;
  vol.cwd    = HFS_CNID_ROOTDIR;

  vol.refs   = 0;
  vol.files  = 0;
  vol.dirs   = 0;
  vol.prev   = 0;
  vol.next   = 0;

#if 0
  vol.fd = open(path, O_RDWR);

  if (vol.fd < 0)
    {
      ERROR(errno, "error opening device for writing");
      return -1;
    }
#endif

  if (l_lockvol(&vol) < 0)
    {
#if 0
      close(vol.fd);
#endif
      return -1;
    }

  if (pnum > 0)
    {
      if (l_readpm(&vol) < 0)
	{
#if 0
	  close(vol.fd);
#endif
	  return -1;
	}
    }
  else  /* determine size of entire device */
    {
      unsigned long low, high, mid;
      block b;

      for (low = 0, high = 2879; b_readlb(&vol, high, &b) >= 0; high *= 2)
	low = high;

      while (low < high - 1)
	{
	  mid = (low + high) / 2;

	  if (b_readlb(&vol, mid, &b) < 0)
	    high = mid;
	  else
	    low = mid;
	}

      vol.vlen = low + 1;
    }

  if (vol.vlen < 800 * 1024 / HFS_BLOCKSZ)
    {
#if 0
      close(vol.fd);
#endif

      ERROR(EINVAL, "volume size must be >= 800K");
      return -1;
    }

  /* initialize volume geometry */

  vol.lpa = 1 + vol.vlen / 65536;

  vbmsz = (vol.vlen / vol.lpa + 4095) / 4096;

  vol.mdb.drSigWord  = 0x4244;
  vol.mdb.drCrDate   = d_tomtime(/*time*/(0));
  vol.mdb.drLsMod    = vol.mdb.drCrDate;
  vol.mdb.drAtrb     = 0;
  vol.mdb.drNmFls    = 0;
  vol.mdb.drVBMSt    = 3;
  vol.mdb.drAllocPtr = 0;
  vol.mdb.drNmAlBlks = (vol.vlen - 5 - vbmsz) / vol.lpa;
  vol.mdb.drAlBlkSiz = vol.lpa * HFS_BLOCKSZ;
  vol.mdb.drClpSiz   = vol.mdb.drAlBlkSiz * 4;
  vol.mdb.drAlBlSt   = 3 + vbmsz;
  vol.mdb.drNxtCNID  = HFS_CNID_ROOTDIR;  /* modified later */
  vol.mdb.drFreeBks  = vol.mdb.drNmAlBlks;

  strcpy(vol.mdb.drVN, vname);

  vol.mdb.drVolBkUp  = 0;
  vol.mdb.drVSeqNum  = 0;
  vol.mdb.drWrCnt    = 0;
  vol.mdb.drXTClpSiz = vol.mdb.drNmAlBlks / 128 * vol.mdb.drAlBlkSiz;
  vol.mdb.drCTClpSiz = vol.mdb.drXTClpSiz;
  vol.mdb.drNmRtDirs = 0;
  vol.mdb.drFilCnt   = 0;
  vol.mdb.drDirCnt   = -1;  /* incremented when root folder is created */

  for (i = 0; i < 8; ++i)
    vol.mdb.drFndrInfo[i] = 0;

  vol.mdb.drVCSize   = 0;
  vol.mdb.drVBMCSize = 0;
  vol.mdb.drCtlCSize = 0;

  vol.mdb.drXTFlSize = 0;
  vol.mdb.drCTFlSize = 0;

  for (i = 0; i < 3; ++i)
    {
      vol.mdb.drXTExtRec[i].xdrStABN    = 0;
      vol.mdb.drXTExtRec[i].xdrNumABlks = 0;

      vol.mdb.drCTExtRec[i].xdrStABN    = 0;
      vol.mdb.drCTExtRec[i].xdrNumABlks = 0;
    }

  /* initialize volume bitmap */

  memset(vol.vbm, 0, sizeof(vbm));

  /* create extents overflow file */

  ext->f.vol   = &vol;
  ext->f.parid = 0;
  strcpy(ext->f.name, "extents overflow");

  ext->f.cat.cdrType          = cdrFilRec;
  /* ext->f.cat.cdrResrv2 */
  ext->f.cat.u.fil.filFlags   = 0;
  ext->f.cat.u.fil.filTyp     = 0;
  /* ext->f.cat.u.fil.filUsrWds */
  ext->f.cat.u.fil.filFlNum   = HFS_CNID_EXT;
  ext->f.cat.u.fil.filStBlk   = 0;
  ext->f.cat.u.fil.filLgLen   = 0;
  ext->f.cat.u.fil.filPyLen   = 0;
  ext->f.cat.u.fil.filRStBlk  = 0;
  ext->f.cat.u.fil.filRLgLen  = 0;
  ext->f.cat.u.fil.filRPyLen  = 0;
  ext->f.cat.u.fil.filCrDat   = vol.mdb.drCrDate;
  ext->f.cat.u.fil.filMdDat   = vol.mdb.drLsMod;
  ext->f.cat.u.fil.filBkDat   = 0;
  /* ext->f.cat.u.fil.filFndrInfo */
  ext->f.cat.u.fil.filClpSize = 0;

  for (i = 0; i < 3; ++i)
    {
      ext->f.cat.u.fil.filExtRec[i].xdrStABN     = 0;
      ext->f.cat.u.fil.filExtRec[i].xdrNumABlks  = 0;

      ext->f.cat.u.fil.filRExtRec[i].xdrStABN    = 0;
      ext->f.cat.u.fil.filRExtRec[i].xdrNumABlks = 0;
    }
  /* ext->f.cat.u.fil.filResrv */
  f_selectfork(&ext->f, 0);

  ext->f.clump = vol.mdb.drXTClpSiz;
  ext->f.flags = 0;

  ext->f.prev = ext->f.next = 0;

  n_init(&ext->hdrnd, ext, ndHdrNode, 0);

  ext->hdrnd.nnum       = 0;
  ext->hdrnd.nd.ndNRecs = 3;
  ext->hdrnd.roff[1]    = 0x078;
  ext->hdrnd.roff[2]    = 0x0f8;
  ext->hdrnd.roff[3]    = 0x1f8;

  memset(HFS_NODEREC(ext->hdrnd, 1), 0, 128);

  ext->hdr.bthDepth    = 0;
  ext->hdr.bthRoot     = 0;
  ext->hdr.bthNRecs    = 0;
  ext->hdr.bthFNode    = 0;
  ext->hdr.bthLNode    = 0;
  ext->hdr.bthNodeSize = HFS_BLOCKSZ;
  ext->hdr.bthKeyLen   = 0x07;
  ext->hdr.bthNNodes   = 0;
  ext->hdr.bthFree     = 0;
  for (i = 0; i < 76; ++i)
    ext->hdr.bthResv[i] = 0;

  map = ALLOC(char, HFS_MAP1SZ);
  if (map == 0)
    {
      if (result == 0)
	{
	  ERROR(ENOMEM, 0);
	  result = -1;
	}
    }
  else
    {
      memset(map, 0, HFS_MAP1SZ);
      BMSET(map, 0);
    }

  ext->map     = map;
  ext->mapsz   = HFS_MAP1SZ;
  ext->flags   = HFS_UPDATE_BTHDR;
  ext->compare = r_compareextkeys;

  if (result == 0 && bt_space(ext, 1) < 0)
    result = -1;

  --ext->hdr.bthFree;

  /* create catalog file */

  cat->f.vol   = &vol;
  cat->f.parid = 0;
  strcpy(cat->f.name, "catalog");

  cat->f.cat.cdrType          = cdrFilRec;
  /* cat->f.cat.cdrResrv2 */
  cat->f.cat.u.fil.filFlags   = 0;
  cat->f.cat.u.fil.filTyp     = 0;
  /* cat->f.cat.u.fil.filUsrWds */
  cat->f.cat.u.fil.filFlNum   = HFS_CNID_CAT;
  cat->f.cat.u.fil.filStBlk   = 0;
  cat->f.cat.u.fil.filLgLen   = 0;
  cat->f.cat.u.fil.filPyLen   = 0;
  cat->f.cat.u.fil.filRStBlk  = 0;
  cat->f.cat.u.fil.filRLgLen  = 0;
  cat->f.cat.u.fil.filRPyLen  = 0;
  cat->f.cat.u.fil.filCrDat   = vol.mdb.drCrDate;
  cat->f.cat.u.fil.filMdDat   = vol.mdb.drLsMod;
  cat->f.cat.u.fil.filBkDat   = 0;
  /* cat->f.cat.u.fil.filFndrInfo */
  cat->f.cat.u.fil.filClpSize = 0;

  for (i = 0; i < 3; ++i)
    {
      cat->f.cat.u.fil.filExtRec[i].xdrStABN     = 0;
      cat->f.cat.u.fil.filExtRec[i].xdrNumABlks  = 0;

      cat->f.cat.u.fil.filRExtRec[i].xdrStABN    = 0;
      cat->f.cat.u.fil.filRExtRec[i].xdrNumABlks = 0;
    }
  /* cat->f.cat.u.fil.filResrv */
  f_selectfork(&cat->f, 0);

  cat->f.clump = vol.mdb.drCTClpSiz;
  cat->f.flags = 0;

  cat->f.prev = cat->f.next = 0;

  n_init(&cat->hdrnd, cat, ndHdrNode, 0);

  cat->hdrnd.nnum       = 0;
  cat->hdrnd.nd.ndNRecs = 3;
  cat->hdrnd.roff[1]    = 0x078;
  cat->hdrnd.roff[2]    = 0x0f8;
  cat->hdrnd.roff[3]    = 0x1f8;

  memset(HFS_NODEREC(cat->hdrnd, 1), 0, 128);

  cat->hdr.bthDepth    = 0;
  cat->hdr.bthRoot     = 0;
  cat->hdr.bthNRecs    = 0;
  cat->hdr.bthFNode    = 0;
  cat->hdr.bthLNode    = 0;
  cat->hdr.bthNodeSize = HFS_BLOCKSZ;
  cat->hdr.bthKeyLen   = 0x25;
  cat->hdr.bthNNodes   = 0;
  cat->hdr.bthFree     = 0;
  for (i = 0; i < 76; ++i)
    cat->hdr.bthResv[i] = 0;

  map = ALLOC(char, HFS_MAP1SZ);
  if (map == 0)
    {
      if (result == 0)
	{
	  ERROR(ENOMEM, 0);
	  result = -1;
	}
    }
  else
    {
      memset(map, 0, HFS_MAP1SZ);
      BMSET(map, 0);
    }

  cat->map     = map;
  cat->mapsz   = HFS_MAP1SZ;
  cat->flags   = HFS_UPDATE_BTHDR;
  cat->compare = r_comparecatkeys;

  if (result == 0 && bt_space(cat, 1) < 0)
    result = -1;

  --cat->hdr.bthFree;

  /* create root folder */

  if (result == 0 && v_newfolder(&vol, HFS_CNID_ROOTPAR, vname) < 0)
    result = -1;

  vol.mdb.drNxtCNID = 16;

  /* finish up */

  if (result == 0)
    {
      block b;

      /* write boot blocks */

      memset(&b, 0, sizeof(b));
      b_writelb(&vol, 0, &b);
      b_writelb(&vol, 1, &b);

      /* flush other disk state */

      vol.flags |= HFS_UPDATE_MDB | HFS_UPDATE_ALTMDB | HFS_UPDATE_VBM;

      if (v_flush(&vol, 1) < 0)
	result = -1;
    }

  if (
#if 0
      close(vol.fd) < 0 && 
#endif
      result == 0)
    {
      ERROR(errno, "error closing device");
      result = -1;
    }

  FREE(vol.ext.map);
  FREE(vol.cat.map);

  return result;
}
Example #12
0
/*
 * NAME:	hfs->delete()
 * DESCRIPTION:	remove both forks of a file
 */
int hfs_delete(hfsvol *vol, char *path)
{
  hfsfile file;
  CatKeyRec key;
  unsigned char pkey[HFS_CATKEYLEN];
  int found;

  if (v_getvol(&vol) < 0 ||
      v_resolve(&vol, path, &file.cat, &file.parid, file.name, 0) <= 0)
    return -1;

  if (file.cat.cdrType != cdrFilRec)
    {
      ERROR(EISDIR, 0);
      return -1;
    }

  if (file.parid == HFS_CNID_ROOTPAR)
    {
      ERROR(EINVAL, 0);
      return -1;
    }

  if (vol->flags & HFS_READONLY)
    {
      ERROR(EROFS, 0);
      return -1;
    }

  /* free disk blocks */

  file.vol   = vol;
  file.flags = 0;

  file.cat.u.fil.filLgLen  = 0;
  file.cat.u.fil.filRLgLen = 0;

  f_selectfork(&file, 0);
  if (f_trunc(&file) < 0)
    return -1;

  f_selectfork(&file, 1);
  if (f_trunc(&file) < 0)
    return -1;

  /* delete file record */

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

  if (bt_delete(&vol->cat, pkey) < 0 ||
      v_adjvalence(vol, file.parid, 0, -1) < 0)
    return -1;

  /* delete file thread, if any */

  found = v_getfthread(vol, file.cat.u.fil.filFlNum, 0, 0);
  if (found < 0)
    return -1;

  if (found)
    {
      r_makecatkey(&key, file.cat.u.fil.filFlNum, (char *)"");
      r_packcatkey(&key, pkey, 0);

      if (bt_delete(&vol->cat, pkey) < 0)
	return -1;
    }

  return 0;
}