Exemple #1
0
uint16_t
iso9660_pathtable_m_add_entry (void *pt,
                               const char name[],
                               uint32_t extent,
                               uint16_t parent)
{
  iso_path_table_t *ipt =
    (iso_path_table_t *)((char *)pt + iso9660_pathtable_get_size (pt));
  size_t name_len = strlen (name) ? strlen (name) : 1;
  unsigned int entrynum = 0;

  cdio_assert (iso9660_pathtable_get_size(pt) < ISO_BLOCKSIZE); /* fixme */

  memset(ipt, 0, sizeof (iso_path_table_t) + name_len); /* paranoia */

  ipt->name_len = to_711 (name_len);
  ipt->extent = to_732 (extent);
  ipt->parent = to_722 (parent);
  memcpy (ipt->name, name, name_len);

  pathtable_get_size_and_entries (pt, NULL, &entrynum);

  if (entrynum > 1)
    {
      const iso_path_table_t *ipt2
        = pathtable_get_entry (pt, entrynum - 2);

      cdio_assert (ipt2 != NULL);

      cdio_assert (from_722 (ipt2->parent) <= parent);
    }

  return entrynum;
}
Exemple #2
0
/*!
   Reads a single mode1 form1 or form2  sector from cd device 
   into data starting from lsn. Returns 0 if no error. 
 */
int
cdio_read_mode1_sector (const CdIo *cdio, void *data, lsn_t lsn, bool is_form2)
{
  uint32_t size = is_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE ;
  char buf[M2RAW_SECTOR_SIZE] = { 0, };
  int ret;
  
  cdio_assert (cdio != NULL);
  cdio_assert (data != NULL);

  if (cdio->op.lseek && cdio->op.read) {
    if (0 > cdio_lseek(cdio, CDIO_CD_FRAMESIZE*lsn, SEEK_SET))
      return -1;
    if (0 > cdio_read(cdio, buf, CDIO_CD_FRAMESIZE))
      return -1;
    memcpy (data, buf, size);
    return 0;
  } else {
    ret = cdio_read_mode2_sector(cdio, data, lsn, is_form2);
    if (ret == 0) 
      memcpy (data, buf+CDIO_CD_SUBHEADER_SIZE, size);
  }
  return ret;

}
Exemple #3
0
static const iso_path_table_t *
pathtable_get_entry (const void *pt, unsigned int entrynum)
{
  const uint8_t *tmp = pt;
  unsigned int offset = 0;
  unsigned int count = 0;

  cdio_assert (pt != NULL);

  while (from_711 (*tmp))
    {
      if (count == entrynum)
        break;

      cdio_assert (count < entrynum);

      offset += sizeof (iso_path_table_t);
      offset += from_711 (*tmp);
      if (offset % 2)
        offset++;
      tmp = (uint8_t *)pt + offset;
      count++;
    }

  if (!from_711 (*tmp))
    return NULL;

  return (const void *) tmp;
}
Exemple #4
0
void
iso9660_dir_init_new_su (void *dir,
                         uint32_t self,
                         uint32_t ssize,
                         const void *ssu_data,
                         unsigned int ssu_size,
                         uint32_t parent,
                         uint32_t psize,
                         const void *psu_data,
                         unsigned int psu_size,
                         const time_t *dir_time)
{
  cdio_assert (ssize > 0 && !(ssize % ISO_BLOCKSIZE));
  cdio_assert (psize > 0 && !(psize % ISO_BLOCKSIZE));
  cdio_assert (dir != NULL);

  memset (dir, 0, ssize);

  /* "\0" -- working hack due to padding  */
  iso9660_dir_add_entry_su (dir, "\0", self, ssize, ISO_DIRECTORY, ssu_data,
                            ssu_size, dir_time);

  iso9660_dir_add_entry_su (dir, "\1", parent, psize, ISO_DIRECTORY, psu_data,
                            psu_size, dir_time);
}
Exemple #5
0
void * /* list of char* -- caller must free it */
iso9660_fs_readdir (const CdIo *cdio, const char pathname[], bool is_mode2)
{
  iso9660_stat_t stat;

  cdio_assert (cdio != NULL);
  cdio_assert (pathname != NULL);

  if (iso9660_fs_stat (cdio, pathname, &stat, is_mode2))
    return NULL;

  if (stat.type != _STAT_DIR)
    return NULL;

  {
    unsigned offset = 0;
    uint8_t *_dirbuf = NULL;
    CdioList *retval = _cdio_list_new ();

    if (stat.size != ISO_BLOCKSIZE * stat.secsize)
      {
	cdio_warn ("bad size for ISO9660 directory (%ud) should be (%lu)!",
		   (unsigned) stat.size, 
		   (unsigned long int) ISO_BLOCKSIZE * stat.secsize);
      }

    _dirbuf = _cdio_malloc (stat.secsize * ISO_BLOCKSIZE);

    if (is_mode2) {
      if (cdio_read_mode2_sectors (cdio, _dirbuf, stat.lsn, false, 
				   stat.secsize))
	cdio_assert_not_reached ();
    } else {
      if (cdio_read_mode1_sectors (cdio, _dirbuf, stat.lsn, false,
				   stat.secsize))
	cdio_assert_not_reached ();
    }

    while (offset < (stat.secsize * ISO_BLOCKSIZE))
      {
	const iso9660_dir_t *idr = (void *) &_dirbuf[offset];

	if (!iso9660_get_dir_len(idr))
	  {
	    offset++;
	    continue;
	  }

	_cdio_list_append (retval, _idr2name (idr));

	offset += iso9660_get_dir_len(idr);
      }

    cdio_assert (offset == (stat.secsize * ISO_BLOCKSIZE));

    free (_dirbuf);
    return retval;
  }
}
Exemple #6
0
/* Zero's out pathable. Do this first.  */
void
iso9660_pathtable_init (void *pt)
{
  cdio_assert (sizeof (iso_path_table_t) == 8);

  cdio_assert (pt != NULL);

  memset (pt, 0, ISO_BLOCKSIZE); /* fixme */
}
Exemple #7
0
/*!
  Set the arg "key" with "value" in the source device.
*/
int
cdio_set_arg (CdIo *cdio, const char key[], const char value[])
{
  cdio_assert (cdio != NULL);
  cdio_assert (cdio->op.set_arg != NULL);
  cdio_assert (key != NULL);

  return cdio->op.set_arg (cdio->env, key, value);
}
Exemple #8
0
int
cdio_read_audio_sector (const CdIo *cdio, void *buf, lsn_t lsn) 
{
  cdio_assert (cdio != NULL);
  cdio_assert (buf != NULL);

  if  (cdio->op.read_audio_sectors != NULL)
    return cdio->op.read_audio_sectors (cdio->env, buf, lsn, 1);
  return -1;
}
Exemple #9
0
int
cdio_read_audio_sectors (const CdIo *cdio, void *buf, lsn_t lsn,
                         unsigned int nblocks) 
{
  cdio_assert (cdio != NULL);
  cdio_assert (buf != NULL);

  if  (cdio->op.read_audio_sectors != NULL)
    return cdio->op.read_audio_sectors (cdio->env, buf, lsn, nblocks);
  return -1;
}
Exemple #10
0
int
cdio_read_mode2_sectors (const CdIo *cdio, void *buf, lsn_t lsn, bool mode2raw, 
                         unsigned num_sectors)
{
  cdio_assert (cdio != NULL);
  cdio_assert (buf != NULL);
  cdio_assert (cdio->op.read_mode2_sectors != NULL);
  
  return cdio->op.read_mode2_sectors (cdio->env, buf, lsn,
                                     mode2raw, num_sectors);
}
Exemple #11
0
void 
_cdio_list_foreach (CdioList *list, _cdio_list_iterfunc func, void *user_data)
{
  CdioListNode *node;

  cdio_assert (list != NULL);
  cdio_assert (func != 0);
  
  for (node = _cdio_list_begin (list);
       node != NULL;
       node = _cdio_list_node_next (node))
    func (_cdio_list_node_data (node), user_data);
}
Exemple #12
0
void 
_cdio_list_foreach (CdioList_t *p_list, _cdio_list_iterfunc_t func, 
                    void *p_user_data)
{
  CdioListNode_t *node;

  cdio_assert (p_list != NULL);
  cdio_assert (func != 0);
  
  for (node = _cdio_list_begin (p_list);
       node != NULL;
       node = _cdio_list_node_next (node))
    func (_cdio_list_node_data (node), p_user_data);
}
Exemple #13
0
void 
_cdio_list_node_free (CdioListNode *node, int free_data)
{
  CdioList *list;
  CdioListNode *prev_node;

  cdio_assert (node != NULL);
  
  list = node->list;

  cdio_assert (_cdio_list_length (list) > 0);

  if (free_data)
    free (_cdio_list_node_data (node));

  if (_cdio_list_length (list) == 1)
    {
      cdio_assert (list->begin == list->end);

      list->end = list->begin = NULL;
      list->length = 0;
      free (node);
      return;
    }

  cdio_assert (list->begin != list->end);

  if (list->begin == node)
    {
      list->begin = node->next;
      free (node);
      list->length--;
      return;
    }

  for (prev_node = list->begin; prev_node->next; prev_node = prev_node->next)
    if (prev_node->next == node)
      break;

  cdio_assert (prev_node->next != NULL);

  if (list->end == node)
    list->end = prev_node;

  prev_node->next = node->next;

  list->length--;

  free (node);
}
Exemple #14
0
void 
_cdio_list_node_free (CdioListNode_t *p_node, int free_data)
{
  CdioList_t *p_list;
  CdioListNode_t *prev_node;

  cdio_assert (p_node != NULL);
  
  p_list = p_node->list;

  cdio_assert (_cdio_list_length (p_list) > 0);

  if (free_data)
    free (_cdio_list_node_data (p_node));

  if (_cdio_list_length (p_list) == 1)
    {
      cdio_assert (p_list->begin == p_list->end);

      p_list->end = p_list->begin = NULL;
      p_list->length = 0;
      free (p_node);
      return;
    }

  cdio_assert (p_list->begin != p_list->end);

  if (p_list->begin == p_node)
    {
      p_list->begin = p_node->next;
      free (p_node);
      p_list->length--;
      return;
    }

  for (prev_node = p_list->begin; prev_node->next; prev_node = prev_node->next)
    if (prev_node->next == p_node)
      break;

  cdio_assert (prev_node->next != NULL);

  if (p_list->end == p_node)
    p_list->end = prev_node;

  prev_node->next = p_node->next;

  p_list->length--;

  free (p_node);
}
Exemple #15
0
CdioListNode *
_cdio_list_end (CdioList *list)
{
  cdio_assert (list != NULL);

  return list->end;
}
Exemple #16
0
CdioListNode *
_cdio_list_begin (const CdioList *list)
{
  cdio_assert (list != NULL);

  return list->begin;
}
Exemple #17
0
CdioListNode *
_cdio_list_find (CdioList *list, _cdio_list_iterfunc cmp_func, void *user_data)
{
  CdioListNode *node;

  cdio_assert (list != NULL);
  cdio_assert (cmp_func != 0);
  
  for (node = _cdio_list_begin (list);
       node != NULL;
       node = _cdio_list_node_next (node))
    if (cmp_func (_cdio_list_node_data (node), user_data))
      break;

  return node;
}
Exemple #18
0
uint32_t
cdio_stat_size (const CdIo *cdio)
{
  cdio_assert (cdio != NULL);

  return cdio->op.stat_size (cdio->env);
}
Exemple #19
0
unsigned
_cdio_list_length (const CdioList_t *p_list)
{
  cdio_assert (p_list != NULL);

  return p_list->length;
}
Exemple #20
0
CdioListNode_t *
_cdio_list_begin (const CdioList_t *p_list)
{
  cdio_assert (p_list != NULL);

  return p_list->begin;
}
Exemple #21
0
CdioListNode_t *
_cdio_list_end (CdioList_t *p_list)
{
  cdio_assert (p_list != NULL);

  return p_list->end;
}
Exemple #22
0
/*!
  Read the Super block of an ISO 9660 image. This is the 
  Primary Volume Descriptor (PVD) and perhaps a Supplemental Volume 
  Descriptor if (Joliet) extensions are acceptable.
*/
bool 
iso9660_fs_read_superblock (CdIo_t *p_cdio, 
			    iso_extension_mask_t iso_extension_mask)
{
  if (!p_cdio) return false;
  
  {
    generic_img_private_t *p_env = (generic_img_private_t *) p_cdio->env;
    iso9660_pvd_t         *p_pvd = &(p_env->pvd);
    iso9660_svd_t         *p_svd = &(p_env->svd);
    char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, };
    driver_return_code_t driver_return;

    if ( !iso9660_fs_read_pvd(p_cdio, p_pvd) )
      return false;
    
    p_env->i_joliet_level = 0;
    
    driver_return = 
      cdio_read_data_sectors ( p_cdio, buf, ISO_PVD_SECTOR+1, ISO_BLOCKSIZE,
			       1 );

    if (DRIVER_OP_SUCCESS == driver_return) {
      /* The size of a PVD or SVD is smaller than a sector. So we
	 allocated a bigger block above (buf) and now we'll copy just
	 the part we need to save.
      */
      cdio_assert (sizeof(buf) >= sizeof (iso9660_svd_t));
      memcpy(p_svd, buf, sizeof(iso9660_svd_t));
  
      if ( ISO_VD_SUPPLEMENTARY == from_711(p_svd->type) ) {
	if (p_svd->escape_sequences[0] == 0x25 
	    && p_svd->escape_sequences[1] == 0x2f) {
	  switch (p_svd->escape_sequences[2]) {
	  case 0x40:
	    if (iso_extension_mask & ISO_EXTENSION_JOLIET_LEVEL1) 
	      p_env->i_joliet_level = 1;
	    break;
	  case 0x43:
	    if (iso_extension_mask & ISO_EXTENSION_JOLIET_LEVEL2) 
	      p_env->i_joliet_level = 2;
	    break;
	  case 0x45:
	    if (iso_extension_mask & ISO_EXTENSION_JOLIET_LEVEL3) 
	      p_env->i_joliet_level = 3;
	    break;
	  default:
	    cdio_info("Supplementary Volume Descriptor found, but not Joliet");
	  }
	  if (p_env->i_joliet_level > 0) {
	    cdio_info("Found Extension: Joliet Level %d", 
		      p_env->i_joliet_level);
	  }
	}
      }
    }
  }

  return true;
}
Exemple #23
0
void
cdio_lsn_to_msf (lsn_t lsn, msf_t *msf)
{
  int m, s, f;

  cdio_assert (msf != 0);

  if ( lsn >= -CDIO_PREGAP_SECTORS ){
    m    = (lsn + CDIO_PREGAP_SECTORS) / CDIO_CD_FRAMES_PER_MIN;
    lsn -= m * CDIO_CD_FRAMES_PER_MIN;
    s    = (lsn + CDIO_PREGAP_SECTORS) / CDIO_CD_FRAMES_PER_SEC;
    lsn -= s * CDIO_CD_FRAMES_PER_SEC;
    f    = lsn + CDIO_PREGAP_SECTORS;
  } else {
    m    = (lsn + CDIO_CD_MAX_LSN)     / CDIO_CD_FRAMES_PER_MIN;
    lsn -= m * (CDIO_CD_FRAMES_PER_MIN);
    s    = (lsn+CDIO_CD_MAX_LSN)       / CDIO_CD_FRAMES_PER_SEC;
    lsn -= s * CDIO_CD_FRAMES_PER_SEC;
    f    = lsn + CDIO_CD_MAX_LSN;
  }

  if (m > 6) {
    cdio_warn ("number of minutes (%d) truncated to 99.", m);
    m = 6;
  }

  msf->m = cdio_to_bcd8 (m);
  msf->s = cdio_to_bcd8 (s);
  msf->f = cdio_to_bcd8 (f);
}
Exemple #24
0
void
pathtable_get_size_and_entries (const void *pt,
                                unsigned int *size,
                                unsigned int *entries)
{
  const uint8_t *tmp = pt;
  unsigned int offset = 0;
  unsigned int count = 0;

  cdio_assert (pt != NULL);

  while (from_711 (*tmp))
    {
      offset += sizeof (iso_path_table_t);
      offset += from_711 (*tmp);
      if (offset % 2)
        offset++;
      tmp = (uint8_t *)pt + offset;
      count++;
    }

  if (size)
    *size = offset;

  if (entries)
    *entries = count;
}
Exemple #25
0
/*! 
  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_t * 
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_t *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;
  }
}
Exemple #26
0
/*!
   Reads a single mode2 sector from cd device into data starting
   from lsn. Returns 0 if no error. 
 */
int
cdio_read_mode2_sector (const CdIo *cdio, void *buf, lsn_t lsn, 
                        bool is_form2)
{
  cdio_assert (cdio != NULL);
  cdio_assert (buf != NULL);
  cdio_assert (cdio->op.read_mode2_sector != NULL 
	      || cdio->op.read_mode2_sectors != NULL);

  if (cdio->op.read_mode2_sector)
    return cdio->op.read_mode2_sector (cdio->env, buf, lsn, is_form2);

  /* fallback */
  if (cdio->op.read_mode2_sectors != NULL)
    return cdio_read_mode2_sectors (cdio, buf, lsn, is_form2, 1);
  return 1;
}
Exemple #27
0
CdioListNode_t *
_cdio_list_find (CdioList_t *p_list, _cdio_list_iterfunc_t cmp_func, 
                 void *p_user_data)
{
  CdioListNode_t *p_node;

  cdio_assert (p_list != NULL);
  cdio_assert (cmp_func != 0);
  
  for (p_node = _cdio_list_begin (p_list);
       p_node != NULL;
       p_node = _cdio_list_node_next (p_node))
    if (cmp_func (_cdio_list_node_data (p_node), p_user_data))
      break;

  return p_node;
}
Exemple #28
0
/*!
  Check that pathname is a valid ISO-9660 pathname.

  A valid pathname contains a valid directory name, if one appears and
  the filename portion should be no more than 8 characters for the
  file prefix and 3 characters in the extension (or portion after a
  dot). There should be exactly one dot somewhere in the filename
  portion and the filename should be composed of only DCHARs.

  True is returned if pathname is valid.
 */
bool
iso9660_pathname_valid_p (const char pathname[])
{
  const char *p = NULL;

  cdio_assert (pathname != NULL);

  if ((p = strrchr (pathname, '/')))
    {
      bool rc;
      char *_tmp = strdup (pathname);

      *strrchr (_tmp, '/') = '\0';

      rc = iso9660_dirname_valid_p (_tmp);

      free (_tmp);

      if (!rc)
        return false;

      p++;
    }
  else
    p = pathname;

  if (strlen (pathname) > (MAX_ISOPATHNAME - 6))
    return false;

  {
    int len = 0;
    int dots = 0;

    for (; *p; p++)
      if (iso9660_is_dchar (*p))
        {
          len++;
          if (dots == 0 ? len > 8 : len > 3)
            return false;
        }
      else if (*p == '.')
        {
          dots++;
          if (dots > 1)
            return false;
          if (!len)
            return false;
          len = 0;
        }
      else
        return false;

    if (dots != 1)
      return false;
  }

  return true;
}
Exemple #29
0
int
main (int argc, const char *argv[])
{
  cdio_assert (argc < 2);

  cdio_assert_not_reached ();

  return 0;
}
Exemple #30
0
void
iso9660_set_evd(void *pd)
{
  iso_volume_descriptor_t ied;

  cdio_assert (sizeof(iso_volume_descriptor_t) == ISO_BLOCKSIZE);

  cdio_assert (pd != NULL);

  memset(&ied, 0, sizeof(ied));

  ied.type = to_711(ISO_VD_END);
  iso9660_strncpy_pad (ied.id, ISO_STANDARD_ID, sizeof(ied.id),
                       ISO9660_DCHARS);
  ied.version = to_711(ISO_VERSION);

  memcpy(pd, &ied, sizeof(ied));
}