⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hfs.c

📁 创建一个符合iso-9660标准的iso文件系统
💻 C
📖 第 1 页 / 共 3 页
字号:
  /* store this info in the volume info */  vol.hce = hce;#endif /* APPLE_HYB */  /* 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;    }#ifndef APPLE_HYB  if (close(vol.fd) < 0 && result == 0)    {      ERROR(errno, "error closing device");      result = -1;    }#endif /* APPLE_HYB */  FREE(vol.ext.map);  FREE(vol.cat.map);  return result;}/* High-Level Directory Routines =========================================== *//* * NAME:	hfs->chdir() * DESCRIPTION:	change current HFS directory */int hfs_chdir(vol, path)	hfsvol	*vol;	char	*path;{  CatDataRec data;  if (v_getvol(&vol) < 0 ||      v_resolve(&vol, path, &data, 0, 0, 0) <= 0)    return -1;  if (data.cdrType != cdrDirRec)    {      ERROR(ENOTDIR, 0);      return -1;    }  vol->cwd = data.u.dir.dirDirID;  return 0;}/* * NAME:	hfs->getcwd() * DESCRIPTION:	return the current working directory ID */long hfs_getcwd(vol)	hfsvol	*vol;{  if (v_getvol(&vol) < 0)    return 0;  return vol->cwd;}/* * NAME:	hfs->setcwd() * DESCRIPTION:	set the current working directory ID */int hfs_setcwd(vol, id)	hfsvol	*vol;	long	id;{  if (v_getvol(&vol) < 0)    return -1;  if (id == vol->cwd)    return 0;  /* make sure the directory exists */  if (v_getdthread(vol, id, 0, 0) <= 0)    return -1;  vol->cwd = id;  return 0;}/* * NAME:	hfs->dirinfo() * DESCRIPTION:	given a directory ID, return its (name and) parent ID */int hfs_dirinfo(vol, id, name)	hfsvol	*vol;	long	*id;	char	*name;{  CatDataRec thread;  if (v_getvol(&vol) < 0 ||      v_getdthread(vol, *id, &thread, 0) <= 0)    return -1;  *id = thread.u.dthd.thdParID;  if (name)    strcpy(name, thread.u.dthd.thdCName);  return 0;}/* * NAME:	hfs->opendir() * DESCRIPTION:	prepare to read the contents of a directory */hfsdir *hfs_opendir(vol, path)	hfsvol	*vol;	char	*path;{  hfsdir *dir;  CatKeyRec key;  CatDataRec data;  unsigned char pkey[HFS_CATKEYLEN];  if (v_getvol(&vol) < 0)    return 0;  dir = ALLOC(hfsdir, 1);  if (dir == 0)    {      ERROR(ENOMEM, 0);      return 0;    }  dir->vol = vol;  if (*path == 0)    {      /* meta-directory containing root dirs from all mounted volumes */      dir->dirid = 0;      dir->vptr  = hfs_mounts;    }  else    {      if (v_resolve(&vol, path, &data, 0, 0, 0) <= 0)	{	  FREE(dir);	  return 0;	}      if (data.cdrType != cdrDirRec)	{	  FREE(dir);	  ERROR(ENOTDIR, 0);	  return 0;	}      dir->dirid = data.u.dir.dirDirID;      dir->vptr  = 0;      r_makecatkey(&key, dir->dirid, "");      r_packcatkey(&key, pkey, 0);      if (bt_search(&vol->cat, pkey, &dir->n) <= 0)	{	  FREE(dir);	  return 0;	}    }  dir->prev = 0;  dir->next = vol->dirs;  if (vol->dirs)    vol->dirs->prev = dir;  vol->dirs = dir;  return dir;}/* * NAME:	hfs->readdir() * DESCRIPTION:	return the next entry in the directory */int hfs_readdir(dir, ent)	hfsdir	*dir;	hfsdirent *ent;{  CatKeyRec key;  CatDataRec data;  unsigned char *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 == 0)	{	  ERROR(ENOENT, "no more entries");	  return -1;	}      if (v_getdthread(vol, HFS_CNID_ROOTDIR, &data, 0) <= 0 ||	  v_catsearch(vol, HFS_CNID_ROOTPAR, data.u.dthd.thdCName,		      &data, cname, 0) < 0)	return -1;      r_unpackdirent(HFS_CNID_ROOTPAR, cname, &data, ent);      dir->vptr = vol->next;      return 0;    }  if (dir->n.rnum == -1)    {      ERROR(ENOENT, "no more entries");      return -1;    }  while (1)    {      ++dir->n.rnum;      while (dir->n.rnum >= dir->n.nd.ndNRecs)	{	  dir->n.nnum = dir->n.nd.ndFLink;	  if (dir->n.nnum == 0)	    {	      dir->n.rnum = -1;	      ERROR(ENOENT, "no more entries");	      return -1;	    }	  if (bt_getnode(&dir->n) < 0)	    {	      dir->n.rnum = -1;	      return -1;	    }	  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");	  return -1;	}      r_unpackcatdata(HFS_RECDATA(ptr), &data);      switch (data.cdrType)	{	case cdrDirRec:	case cdrFilRec:	  r_unpackdirent(key.ckrParID, key.ckrCName, &data, ent);	  return 0;	case cdrThdRec:	case cdrFThdRec:	  break;	default:	  dir->n.rnum = -1;	  ERROR(EIO, "unexpected directory entry found");	  return -1;	}    }}/* * NAME:	hfs->closedir() * DESCRIPTION:	stop reading a directory */int hfs_closedir(dir)	hfsdir	*dir;{  hfsvol *vol = dir->vol;  if (dir->prev)    dir->prev->next = dir->next;  if (dir->next)    dir->next->prev = dir->prev;  if (dir == vol->dirs)    vol->dirs = dir->next;  FREE(dir);  return 0;}/* High-Level File Routines ================================================ *//* * NAME:	hfs->open() * DESCRIPTION:	prepare a file for I/O */hfsfile *hfs_open(vol, path)	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;}/* * NAME:	hfs->setfork() * DESCRIPTION:	select file fork for I/O operations */int hfs_setfork(file, ffork)	hfsfile	*file;	int	ffork;{  int result = 0;  if (! (file->vol->flags & HFS_READONLY) &&      f_trunc(file) < 0)    result = -1;  f_selectfork(file, ffork);  return result;}/* * NAME:	hfs->getfork() * DESCRIPTION:	return the current fork for I/O operations */int hfs_getfork(file)	hfsfile	*file;{  return file->fork != fkData;}/* * NAME:	hfs->read() * DESCRIPTION:	read from an open file */long hfs_read(file, buf, len)	hfsfile		*file;	void		*buf;	unsigned long	len;{  unsigned long *lglen, count;  unsigned char *ptr = buf;  f_getptrs(file, &lglen, 0, 0);  if (file->pos + len > *lglen)    len = *lglen - file->pos;  count = len;  while (count)    {      block b;      unsigned long bnum, offs, chunk;      bnum  = file->pos / HFS_BLOCKSZ;      offs  = file->pos % HFS_BLOCKSZ;      chunk = HFS_BLOCKSZ - offs;      if (chunk > count)	chunk = count;      if (f_getblock(file, bnum, &b) < 0)	return -1;      memcpy(ptr, b + offs, chunk);      ptr += chunk;      file->pos += chunk;      count     -= chunk;    }  return len;}/* * NAME:	hfs->write() * DESCRIPTION:	write to an open file */long hfs_write(file, buf, len)	hfsfile		*file;	void		*buf;	unsigned long	len;{  unsigned long *lglen, *pylen, count;  unsigned char *ptr = buf;  if (file->vol->flags & HFS_READONLY)    {      ERROR(EROFS, 0);      return -1;    }  f_getptrs(file, &lglen, &pylen, 0);  count = len;  /* set flag to update (at least) the modification time */  if (count)    {      file->cat.u.fil.filMdDat = d_tomtime(time(0));      file->flags |= HFS_UPDATE_CATREC;    }  while (count)    {      block b;      unsigned long bnum, offs, chunk;      bnum  = file->pos / HFS_BLOCKSZ;      offs  = file->pos % HFS_BLOCKSZ;      chunk = HFS_BLOCKSZ - offs;      if (chunk > count)	chunk = count;      if (file->pos + chunk > *pylen)	{	  if (bt_space(&file->vol->ext, 1) < 0 ||	      f_alloc(file) < 0)	    return -1;	}#ifndef APPLE_HYB      /* Ignore this part as we are always writing new files to an empty disk	 i.e. offs will always be 0 */      if (offs > 0 || chunk < HFS_BLOCKSZ)	{	  if (f_getblock(file, bnum, &b) < 0)	    return -1;	}#endif /* APPLE_HYB */      memcpy(b + offs, ptr, chunk);      ptr += chunk;      if (f_putblock(file, bnum, &b) < 0)	return -1;      file->pos += chunk;      count     -= chunk;      if (file->pos > *lglen)	*lglen = file->pos;    }  return len;}/* * NAME:	hfs->truncate() * DESCRIPTION:	truncate an open file */int hfs_truncate(file, len)	hfsfile		*file;	unsigned long	len;{  unsigned long *lglen;  f_getptrs(file, &lglen, 0, 0);  if (*lglen > len)    {      if (file->vol->flags & HFS_READONLY)	{	  ERROR(EROFS, 0);	  return -1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -