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

📄 iso9660_fs.c

📁 linux下的MPEG1
💻 C
📖 第 1 页 / 共 3 页
字号:
      }      free(p_stat);	        offset += iso9660_get_dir_len(p_iso9660_dir);    }  cdio_assert (offset == (_root->secsize * ISO_BLOCKSIZE));    /* not found */  free (_dirbuf);  return NULL;}static iso9660_stat_t *_fs_iso_stat_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root, 		       char **splitpath, bool translate){  unsigned offset = 0;  uint8_t *_dirbuf = NULL;  int ret;  if (!splitpath[0])    {      iso9660_stat_t *p_stat;      unsigned int len=sizeof(iso9660_stat_t) + strlen(_root->filename)+1;      p_stat = _cdio_malloc(len);      memcpy(p_stat, _root, len);      return p_stat;    }  if (_root->type == _STAT_FILE)    return NULL;  cdio_assert (_root->type == _STAT_DIR);  if (_root->size != ISO_BLOCKSIZE * _root->secsize)    {      cdio_warn ("bad size for ISO9660 directory (%ud) should be (%lu)!",		 (unsigned) _root->size, 		 (unsigned long int) ISO_BLOCKSIZE * _root->secsize);    }    _dirbuf = _cdio_malloc (_root->secsize * ISO_BLOCKSIZE);  ret = iso9660_iso_seek_read (p_iso, _dirbuf, _root->lsn, _root->secsize);  if (ret!=ISO_BLOCKSIZE*_root->secsize) return NULL;    while (offset < (_root->secsize * ISO_BLOCKSIZE))    {      iso9660_dir_t *p_iso9660_dir = (void *) &_dirbuf[offset];      iso9660_stat_t *p_stat;      int cmp;      if (!iso9660_get_dir_len(p_iso9660_dir))	{	  offset++;	  continue;	}            p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, true, 					p_iso->i_joliet_level);      if (translate) {	char *trans_fname = malloc(strlen(p_stat->filename)+1);	int trans_len;		if (trans_fname == NULL) {	  cdio_warn("can't allocate %lu bytes", 		    (long unsigned int) strlen(p_stat->filename));	  return NULL;	}	trans_len = iso9660_name_translate_ext(p_stat->filename, trans_fname, 					       p_iso->i_joliet_level);	cmp = strcmp(splitpath[0], trans_fname);	free(trans_fname);      } else {	cmp = strcmp(splitpath[0], p_stat->filename);      }            if (!cmp) {	iso9660_stat_t *ret_stat 	  = _fs_iso_stat_traverse (p_iso, p_stat, &splitpath[1], translate);	free(p_stat);	free (_dirbuf);	return ret_stat;      }      free(p_stat);	        offset += iso9660_get_dir_len(p_iso9660_dir);    }  cdio_assert (offset == (_root->secsize * ISO_BLOCKSIZE));    /* not found */  free (_dirbuf);  return NULL;}/*!  Get file status for pathname into stat. NULL is returned on error. */iso9660_stat_t *iso9660_fs_stat (CdIo *p_cdio, const char pathname[]){  iso9660_stat_t *p_root;  char **p_psz_splitpath;  iso9660_stat_t *p_stat;  /* A bit of a hack, we'll assume track 1 contains ISO_PVD_SECTOR.*/  bool b_mode2;  if (!p_cdio)   return NULL;  if (!pathname) return NULL;  p_root = _fs_stat_root (p_cdio);  if (!p_root) return NULL;  b_mode2 = cdio_get_track_green(p_cdio, 1);  p_psz_splitpath = _cdio_strsplit (pathname, '/');  p_stat = _fs_stat_traverse (p_cdio, p_root, p_psz_splitpath, b_mode2, false);  free(p_root);  _cdio_strfreev (p_psz_splitpath);  return p_stat;}/*!  Get file status for pathname into stat. NULL is returned on error.  pathname version numbers in the ISO 9660  name are dropped, i.e. ;1 is removed and if level 1 ISO-9660 names  are lowercased. */iso9660_stat_t *iso9660_fs_stat_translate (CdIo *p_cdio, const char pathname[], 			   bool b_mode2){  iso9660_stat_t *p_root;  char **p_psz_splitpath;  iso9660_stat_t *p_stat;  if (!p_cdio)  return NULL;  if (pathname) return NULL;  p_root = _fs_stat_root (p_cdio);  if (!p_root) return NULL;  p_psz_splitpath = _cdio_strsplit (pathname, '/');  p_stat = _fs_stat_traverse (p_cdio, p_root, p_psz_splitpath, b_mode2, true);  free(p_root);  _cdio_strfreev (p_psz_splitpath);  return p_stat;}/*!  Get file status for pathname into stat. NULL is returned on error. */iso9660_stat_t *iso9660_ifs_stat (iso9660_t *p_iso, const char pathname[]){  iso9660_stat_t *p_root;  char **splitpath;  iso9660_stat_t *stat;  if (!p_iso)    return NULL;  if (!pathname) return NULL;  p_root = _fs_stat_iso_root (p_iso);  if (!p_root) return NULL;  splitpath = _cdio_strsplit (pathname, '/');  stat = _fs_iso_stat_traverse (p_iso, p_root, splitpath, false);  free(p_root);  /*** FIXME _cdio_strfreev (splitpath); ***/  return stat;}/*!  Get file status for pathname into stat. NULL is returned on error.  pathname version numbers in the ISO 9660  name are dropped, i.e. ;1 is removed and if level 1 ISO-9660 names  are lowercased. */iso9660_stat_t *iso9660_ifs_stat_translate (iso9660_t *p_iso, const char pathname[]){  iso9660_stat_t *p_root;  char **p_psz_splitpath;  iso9660_stat_t *p_stat;  if (!p_iso)    return NULL;  if (!pathname) return NULL;  p_root = _fs_stat_iso_root (p_iso);  if (NULL == p_root) return NULL;  p_psz_splitpath = _cdio_strsplit (pathname, '/');  p_stat = _fs_iso_stat_traverse (p_iso, p_root, p_psz_splitpath, true);  free(p_root);  _cdio_strfreev (p_psz_splitpath);  return p_stat;}/*!   Read pathname (a directory) and return a list of iso9660_stat_t  of the files inside that. The caller must free the returned result.*/CdioList * iso9660_fs_readdir (CdIo *p_cdio, const char pathname[], bool b_mode2){  generic_img_private_t *p_env;  iso9660_stat_t *p_stat;  if (!p_cdio)   return NULL;  if (!pathname) return NULL;  p_env = (generic_img_private_t *) p_cdio->env;  p_stat = iso9660_fs_stat (p_cdio, pathname);  if (!p_stat) return NULL;  if (p_stat->type != _STAT_DIR) {    free(p_stat);    return NULL;  }  {    unsigned offset = 0;    uint8_t *_dirbuf = NULL;    CdioList *retval = _cdio_list_new ();    if (p_stat->size != ISO_BLOCKSIZE * p_stat->secsize)      {	cdio_warn ("bad size for ISO9660 directory (%ud) should be (%lu)!",		   (unsigned) p_stat->size, 		   (unsigned long int) ISO_BLOCKSIZE * p_stat->secsize);      }    _dirbuf = _cdio_malloc (p_stat->secsize * ISO_BLOCKSIZE);    if (b_mode2) {      if (cdio_read_mode2_sectors (p_cdio, _dirbuf, p_stat->lsn, false, 				   p_stat->secsize))	cdio_assert_not_reached ();    } else {      if (cdio_read_mode1_sectors (p_cdio, _dirbuf, p_stat->lsn, false,				   p_stat->secsize))	cdio_assert_not_reached ();    }    while (offset < (p_stat->secsize * ISO_BLOCKSIZE))      {	iso9660_dir_t *p_iso9660_dir = (void *) &_dirbuf[offset];	iso9660_stat_t *p_iso9660_stat;		if (!iso9660_get_dir_len(p_iso9660_dir))	  {	    offset++;	    continue;	  }	p_iso9660_stat = _iso9660_dir_to_statbuf(p_iso9660_dir, b_mode2, 						 p_env->i_joliet_level);	_cdio_list_append (retval, p_iso9660_stat);	offset += iso9660_get_dir_len(p_iso9660_dir);      }    cdio_assert (offset == (p_stat->secsize * ISO_BLOCKSIZE));    free (_dirbuf);    free (p_stat);    return retval;  }}/*!   Read pathname (a directory) and return a list of iso9660_stat_t  of the files inside that. The caller must free the returned result.*/CdioList * iso9660_ifs_readdir (iso9660_t *p_iso, const char pathname[]){  iso9660_stat_t *p_stat;  if (!p_iso)    return NULL;  if (!pathname) return NULL;  p_stat = iso9660_ifs_stat (p_iso, pathname);  if (!p_stat)   return NULL;  if (p_stat->type != _STAT_DIR) {    free(p_stat);    return NULL;  }  {    long int ret;    unsigned offset = 0;    uint8_t *_dirbuf = NULL;    CdioList *retval = _cdio_list_new ();    if (p_stat->size != ISO_BLOCKSIZE * p_stat->secsize)      {	cdio_warn ("bad size for ISO9660 directory (%ud) should be (%lu)!",		   (unsigned int) p_stat->size, 		   (unsigned long int) ISO_BLOCKSIZE * p_stat->secsize);      }    _dirbuf = _cdio_malloc (p_stat->secsize * ISO_BLOCKSIZE);    ret = iso9660_iso_seek_read (p_iso, _dirbuf, p_stat->lsn, p_stat->secsize);    if (ret != ISO_BLOCKSIZE*p_stat->secsize) return NULL;        while (offset < (p_stat->secsize * ISO_BLOCKSIZE))      {	iso9660_dir_t *p_iso9660_dir = (void *) &_dirbuf[offset];	iso9660_stat_t *p_iso9660_stat;		if (!iso9660_get_dir_len(p_iso9660_dir))	  {	    offset++;	    continue;	  }	p_iso9660_stat = _iso9660_dir_to_statbuf(p_iso9660_dir, true,						 p_iso->i_joliet_level);	_cdio_list_append (retval, p_iso9660_stat);	offset += iso9660_get_dir_len(p_iso9660_dir);      }    cdio_assert (offset == (p_stat->secsize * ISO_BLOCKSIZE));    free (_dirbuf);    free (p_stat);    return retval;  }}static iso9660_stat_t *find_fs_lsn_recurse (CdIo *p_cdio, const char pathname[], lsn_t lsn){  CdioList *entlist = iso9660_fs_readdir (p_cdio, pathname, true);  CdioList *dirlist =  _cdio_list_new ();  CdioListNode *entnode;      cdio_assert (entlist != NULL);  /* iterate over each entry in the directory */    _CDIO_LIST_FOREACH (entnode, entlist)    {      iso9660_stat_t *statbuf = _cdio_list_node_data (entnode);      char _fullname[4096] = { 0, };      char *filename = (char *) statbuf->filename;      snprintf (_fullname, sizeof (_fullname), "%s%s/", pathname, filename);      if (statbuf->type == _STAT_DIR          && strcmp ((char *) statbuf->filename, ".")           && strcmp ((char *) statbuf->filename, ".."))        _cdio_list_append (dirlist, strdup (_fullname));      if (statbuf->lsn == lsn) {	unsigned int len=sizeof(iso9660_stat_t)+strlen(statbuf->filename)+1;	iso9660_stat_t *ret_stat = _cdio_malloc(len);	memcpy(ret_stat, statbuf, len);        _cdio_list_free (entlist, true);        _cdio_list_free (dirlist, true);        return ret_stat;      }          }  _cdio_list_free (entlist, true);  /* now recurse/descend over directories encountered */  _CDIO_LIST_FOREACH (entnode, dirlist)    {      char *_fullname = _cdio_list_node_data (entnode);      iso9660_stat_t *ret_stat = find_fs_lsn_recurse (p_cdio, _fullname, lsn);      if (NULL != ret_stat) {        _cdio_list_free (dirlist, true);        return ret_stat;      }    }  _cdio_list_free (dirlist, true);  return NULL;}/*!   Given a directory pointer, find the filesystem entry that contains   lsn and return information about it.   Returns stat_t of entry if we found lsn, or NULL otherwise. */iso9660_stat_t *iso9660_find_fs_lsn(CdIo *p_cdio, lsn_t i_lsn){  return find_fs_lsn_recurse (p_cdio, "/", i_lsn);}/*!  Return true if ISO 9660 image has extended attrributes (XA).*/bool iso9660_ifs_is_xa (const iso9660_t * p_iso) {  if (!p_iso) return false;  return p_iso->b_xa;}

⌨️ 快捷键说明

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