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

📄 hfs.c

📁 创建一个符合iso-9660标准的iso文件系统
💻 C
📖 第 1 页 / 共 3 页
字号:
	}      *lglen = len;      file->cat.u.fil.filMdDat = d_tomtime(time(0));      file->flags |= HFS_UPDATE_CATREC;      if (file->pos > len)	file->pos = len;    }  return 0;}/* * NAME:	hfs->lseek() * DESCRIPTION:	change file seek pointer */long hfs_lseek(file, offset, from)	hfsfile	*file;	long	offset;	int	from;{  unsigned long *lglen;  long newpos;  f_getptrs(file, &lglen, 0, 0);  switch (from)    {    case SEEK_SET:      newpos = offset;      break;    case SEEK_CUR:      newpos = file->pos + offset;      break;    case SEEK_END:      newpos = *lglen + offset;      break;    default:      ERROR(EINVAL, 0);      return -1;    }  if (newpos < 0)    newpos = 0;  else if (newpos > *lglen)    newpos = *lglen;  file->pos = newpos;  return newpos;}/* * NAME:	hfs->close() * DESCRIPTION:	close a file */#ifdef APPLE_HYB/* extra args are used to set the start of the forks in the ISO volume */int hfs_close(file, dext, rext)	hfsfile	*file;	long	dext;	long	rext;{  int offset;#elseint hfs_close(hfsfile *file){#endif /* APPLE_HYB */  hfsvol *vol = file->vol;  int result = 0;  if (f_trunc(file) < 0 ||      f_flush(file) < 0)    result = -1;#ifdef APPLE_HYB  /* "start" of file is relative to the first available block */  offset = vol->hce->hfs_hdr_size + vol->hce->hfs_map_size;  /* update the "real" starting extent and re-flush the file */  if (dext)    file->cat.u.fil.filExtRec[0].xdrStABN = (dext - offset)/vol->lpa;  if (rext)    file->cat.u.fil.filRExtRec[0].xdrStABN = (rext - offset)/vol->lpa;  if (dext || rext)    file->flags |= HFS_UPDATE_CATREC;  if (f_flush(file) < 0)    result = -1;#endif /*APPLE_HYB */  if (file->prev)    file->prev->next = file->next;  if (file->next)    file->next->prev = file->prev;  if (file == vol->files)    vol->files = file->next;  FREE(file);  return result;}/* High-Level Catalog Routines ============================================= *//* * NAME:	hfs->stat() * DESCRIPTION:	return catalog information for an arbitrary path */int hfs_stat(vol, path, ent)	hfsvol		*vol;	char		*path;	hfsdirent	*ent;{  CatDataRec data;  long parid;  char name[HFS_MAX_FLEN + 1];  if (v_getvol(&vol) < 0 ||      v_resolve(&vol, path, &data, &parid, name, 0) <= 0)    return -1;  r_unpackdirent(parid, name, &data, ent);  return 0;}/* * NAME:	hfs->fstat() * DESCRIPTION:	return catalog information for an open file */int hfs_fstat(file, ent)	hfsfile		*file;	hfsdirent	*ent;{  r_unpackdirent(file->parid, file->name, &file->cat, ent);  return 0;}/* * NAME:	hfs->setattr() * DESCRIPTION:	change a file's attributes */int hfs_setattr(vol, path, ent)	hfsvol		*vol;	char		*path;	hfsdirent	*ent;{  CatDataRec data;  node n;  if (v_getvol(&vol) < 0 ||      v_resolve(&vol, path, &data, 0, 0, &n) <= 0)    return -1;  if (vol->flags & HFS_READONLY)    {      ERROR(EROFS, 0);      return -1;    }  r_packdirent(&data, ent);  if (v_putcatrec(&data, &n) < 0)    return -1;  return 0;}/* * NAME:	hfs->fsetattr() * DESCRIPTION:	change an open file's attributes */int hfs_fsetattr(file, ent)	hfsfile		*file;	hfsdirent	*ent;{  if (file->vol->flags & HFS_READONLY)    {      ERROR(EROFS, 0);      return -1;    }  r_packdirent(&file->cat, ent);  file->flags |= HFS_UPDATE_CATREC;  return 0;}/* * NAME:	hfs->mkdir() * DESCRIPTION:	create a new directory */int hfs_mkdir(vol, path)	hfsvol		*vol;	char		*path;{  CatDataRec data;  long parid;  char name[HFS_MAX_FLEN + 1];  int found;  if (v_getvol(&vol) < 0)    return -1;  found = v_resolve(&vol, path, &data, &parid, name, 0);  if (found < 0 || parid == 0)    return -1;  else if (found)    {      ERROR(EEXIST, 0);      return -1;    }  if (parid == HFS_CNID_ROOTPAR)    {      ERROR(EINVAL, 0);      return -1;    }  if (vol->flags & HFS_READONLY)    {      ERROR(EROFS, 0);      return -1;    }  if (v_newfolder(vol, parid, name) < 0)    return -1;  return 0;}/* * NAME:	hfs->rmdir() * DESCRIPTION:	delete an empty directory */int hfs_rmdir(vol, path)	hfsvol	*vol;	char	*path;{  CatKeyRec key;  CatDataRec data;  long parid;  char name[HFS_MAX_FLEN + 1];  unsigned char pkey[HFS_CATKEYLEN];  if (v_getvol(&vol) < 0 ||      v_resolve(&vol, path, &data, &parid, name, 0) <= 0)    return -1;  if (data.cdrType != cdrDirRec)    {      ERROR(ENOTDIR, 0);      return -1;    }  if (data.u.dir.dirVal != 0)    {      ERROR(ENOTEMPTY, 0);      return -1;    }  if (parid == HFS_CNID_ROOTPAR)    {      ERROR(EINVAL, 0);      return -1;    }  if (vol->flags & HFS_READONLY)    {      ERROR(EROFS, 0);      return -1;    }  /* delete directory record */  r_makecatkey(&key, parid, name);  r_packcatkey(&key, pkey, 0);  if (bt_delete(&vol->cat, pkey) < 0)    return -1;  /* delete thread record */  r_makecatkey(&key, data.u.dir.dirDirID, "");  r_packcatkey(&key, pkey, 0);  if (bt_delete(&vol->cat, pkey) < 0 ||      v_adjvalence(vol, parid, 1, -1) < 0)    return -1;  return 0;}/* * NAME:	hfs->create() * DESCRIPTION:	create a new file */int hfs_create(vol, path, type, creator)	hfsvol	*vol;	char	*path;	char	*type;	char	*creator;{  CatKeyRec key;  CatDataRec data;  long id, parid;  char name[HFS_MAX_FLEN + 1];  unsigned char record[HFS_CATRECMAXLEN];  int found, i, reclen;  if (v_getvol(&vol) < 0)    return -1;  found = v_resolve(&vol, path, &data, &parid, name, 0);  if (found < 0 || parid == 0)    return -1;  else if (found)    {      ERROR(EEXIST, 0);      return -1;    }  if (parid == HFS_CNID_ROOTPAR)    {      ERROR(EINVAL, 0);      return -1;    }  if (vol->flags & HFS_READONLY)    {      ERROR(EROFS, 0);      return -1;    }  /* create file `name' in parent `parid' */  if (bt_space(&vol->cat, 1) < 0)    return -1;  id = vol->mdb.drNxtCNID++;  vol->flags |= HFS_UPDATE_MDB;  /* create file record */  data.cdrType   = cdrFilRec;  data.cdrResrv2 = 0;  data.u.fil.filFlags = 0;  data.u.fil.filTyp   = 0;  memset(&data.u.fil.filUsrWds, 0, sizeof(data.u.fil.filUsrWds));  data.u.fil.filUsrWds.fdType    = d_getl((unsigned char *) type);  data.u.fil.filUsrWds.fdCreator = d_getl((unsigned char *) creator);  data.u.fil.filFlNum  = id;  data.u.fil.filStBlk  = 0;  data.u.fil.filLgLen  = 0;  data.u.fil.filPyLen  = 0;  data.u.fil.filRStBlk = 0;  data.u.fil.filRLgLen = 0;  data.u.fil.filRPyLen = 0;  data.u.fil.filCrDat  = d_tomtime(time(0));  data.u.fil.filMdDat  = data.u.fil.filCrDat;  data.u.fil.filBkDat  = 0;  memset(&data.u.fil.filFndrInfo, 0, sizeof(data.u.fil.filFndrInfo));  data.u.fil.filClpSize = 0;  for (i = 0; i < 3; ++i)    {      data.u.fil.filExtRec[i].xdrStABN     = 0;      data.u.fil.filExtRec[i].xdrNumABlks  = 0;      data.u.fil.filRExtRec[i].xdrStABN    = 0;      data.u.fil.filRExtRec[i].xdrNumABlks = 0;    }  data.u.fil.filResrv = 0;  r_makecatkey(&key, parid, name);  r_packcatkey(&key, record, &reclen);  r_packcatdata(&data, HFS_RECDATA(record), &reclen);  if (bt_insert(&vol->cat, record, reclen) < 0 ||      v_adjvalence(vol, parid, 0, 1) < 0)    return -1;  return 0;}/* * NAME:	hfs->delete() * DESCRIPTION:	remove both forks of a file */int hfs_delete(vol, path)	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, "");      r_packcatkey(&key, pkey, 0);      if (bt_delete(&vol->cat, pkey) < 0)	return -1;    }  return 0;}/* * NAME:	hfs->rename() * DESCRIPTION:	change the name of and/or move a file or directory */int hfs_rename(vol, srcpath, dstpath)	hfsvol	*vol;	char	*srcpath;	char	*dstpath;{  hfsvol *srcvol;  CatDataRec src, dst;  long srcid, dstid;  CatKeyRec key;  char srcname[HFS_MAX_FLEN + 1], dstname[HFS_MAX_FLEN + 1];  unsigned char record[HFS_CATRECMAXLEN];  int found, isdir, moving, reclen;  node n;  if (v_getvol(&vol) < 0 ||      v_resolve(&vol, srcpath, &src, &srcid, srcname, 0) <= 0)    return -1;  isdir  = (src.cdrType == cdrDirRec);  srcvol = vol;  found = v_resolve(&vol, dstpath, &dst, &dstid, dstname, 0);  if (found < 0)    return -1;  if (vol != srcvol)    {      ERROR(EINVAL, "can't move across volumes");      return -1;    }  if (dstid == 0)    {      ERROR(ENOENT, "bad destination path");      return -1;    }  if (found &&      dst.cdrType == cdrDirRec &&      dst.u.dir.dirDirID != src.u.dir.dirDirID)    {      dstid = dst.u.dir.dirDirID;      strcpy(dstname, srcname);      found = v_catsearch(vol, dstid, dstname, 0, 0, 0);      if (found < 0)	return -1;    }  moving = (srcid != dstid);  if (found)    {      char *ptr;      ptr = strrchr(dstpath, ':');      if (ptr == 0)	ptr = dstpath;      else	++ptr;      if (*ptr)	strcpy(dstname, ptr);      if (! moving && strcmp(srcname, dstname) == 0)	return 0;  /* source and destination are the same */      if (moving || d_relstring(srcname, dstname))	{	  ERROR(EEXIST, "can't use destination name");	  return -1;	}    }  /* can't move anything into the root directory's parent */  if (moving && dstid == HFS_CNID_ROOTPAR)    {      ERROR(EINVAL, "can't move above root directory");      return -1;    }  if (moving && isdir)    {      long id;      /* can't move root directory anywhere */      if (src.u.dir.dirDirID == HFS_CNID_ROOTDIR)	{	  ERROR(EINVAL, "can't move root directory");	  return -1;	}      /* make sure we aren't trying to move a directory inside itself */      for (id = dstid; id != HFS_CNID_ROOTDIR; id = dst.u.dthd.thdParID)	{	  if (id == src.u.dir.dirDirID)	    {	      ERROR(EINVAL, "can't move directory inside itself");	      return -1;	    }	  if (v_getdthread(vol, id, &dst, 0) <= 0)	    return -1;	}    }  if (vol->flags & HFS_READONLY)    {      ERROR(EROFS, 0);      return -1;    }  /* change volume name */  if (dstid == HFS_CNID_ROOTPAR)    {      if (strlen(dstname) > HFS_MAX_VLEN)	{	  ERROR(ENAMETOOLONG, 0);	  return -1;	}      strcpy(vol->mdb.drVN, dstname);      vol->flags |= HFS_UPDATE_MDB;    }  /* remove source record */  r_makecatkey(&key, srcid, srcname);  r_packcatkey(&key, record, 0);  if (bt_delete(&vol->cat, record) < 0)    return -1;  /* insert destination record */  r_makecatkey(&key, dstid, dstname);  r_packcatkey(&key, record, &reclen);  r_packcatdata(&src, HFS_RECDATA(record), &reclen);  if (bt_insert(&vol->cat, record, reclen) < 0)    return -1;  /* update thread record */  if (isdir)    {      if (v_getdthread(vol, src.u.dir.dirDirID, &dst, &n) <= 0)	return -1;      dst.u.dthd.thdParID = dstid;      strcpy(dst.u.dthd.thdCName, dstname);      if (v_putcatrec(&dst, &n) < 0)	return -1;    }  else    {      found = v_getfthread(vol, src.u.fil.filFlNum, &dst, &n);      if (found < 0)	return -1;      if (found)	{	  dst.u.fthd.fthdParID = dstid;	  strcpy(dst.u.fthd.fthdCName, dstname);	  if (v_putcatrec(&dst, &n) < 0)	    return -1;	}    }  /* update directory valences */  if (moving)    {      if (v_adjvalence(vol, srcid, isdir, -1) < 0 ||	  v_adjvalence(vol, dstid, isdir,  1) < 0)	return -1;    }  return 0;}#ifdef APPLE_HYB/* * NAME:        hfs->hfs_get_drAllocPtr() * DESCRIPTION: get the current start of next allocation search  */unsigned shorthfs_get_drAllocPtr(file)	hfsfile	*file;{  return(file->vol->mdb.drAllocPtr);}/* * NAME:        hfs->hfs_set_drAllocPtr() * DESCRIPTION: set the current start of next allocation search  */#ifdef	PROTOTYPESinthfs_set_drAllocPtr(hfsfile *file, unsigned short drAllocPtr, int size)#elseinthfs_set_drAllocPtr(file, drAllocPtr, size)	hfsfile		*file;	unsigned short	drAllocPtr;	int		size;#endif{  hfsvol *vol = file->vol;  int result = 0;  /* truncate the current fork */  if (f_trunc(file) < 0 ||      f_flush(file) < 0)    result = -1;  /* convert the fork size into allocation blocks */  size = (size + vol->mdb.drAlBlkSiz - 1)/vol->mdb.drAlBlkSiz;  /* set the start of next allocation search to be after this fork */  vol->mdb.drAllocPtr = drAllocPtr + size;  vol->flags |= HFS_UPDATE_MDB;  return result;}#endif /* APPLE_HYB */

⌨️ 快捷键说明

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