Esempio n. 1
0
uint16_t
iso9660_pathtable_l_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_731 (extent);
  ipt->parent = to_721 (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_721 (ipt2->parent) <= parent);
    }

  return entrynum;
}
Esempio n. 2
0
static int
parse_rock_ridge_stat_internal(iso9660_dir_t *p_iso9660_dir,
			       iso9660_stat_t *p_stat, int regard_xa)
{
  int len;
  unsigned char * chr;
  int symlink_len = 0;
  CONTINUE_DECLS;

  if (nope == p_stat->rr.b3_rock) return 0;

  SETUP_ROCK_RIDGE(p_iso9660_dir, chr, len);
  if (regard_xa)
    {
      chr+=14;
      len-=14;
      if (len<0) len=0;
    }
  
  /* repeat:*/
  {
    int sig;
    iso_extension_record_t * rr;
    int rootflag;
    
    while (len > 1){ /* There may be one byte for padding somewhere */
      rr = (iso_extension_record_t *) chr;
      if (rr->len == 0) goto out; /* Something got screwed up here */
      sig = from_721(*chr);
      chr += rr->len; 
      len -= rr->len;
      
      switch(sig){
      case SIG('S','P'):
	CHECK_SP(goto out);
	break;
      case SIG('C','E'):
	CHECK_CE;
	break;
      case SIG('E','R'):
	p_stat->rr.b3_rock = yep;
	cdio_debug("ISO 9660 Extensions: ");
	{ int p;
	  for(p=0;p<rr->u.ER.len_id;p++) cdio_debug("%c",rr->u.ER.data[p]);
	}
	break;
      case SIG('P','X'):
	p_stat->rr.st_mode   = from_733(rr->u.PX.st_mode);
	p_stat->rr.st_nlinks = from_733(rr->u.PX.st_nlinks);
	p_stat->rr.st_uid    = from_733(rr->u.PX.st_uid);
	p_stat->rr.st_gid    = from_733(rr->u.PX.st_gid);
	break;
      case SIG('P','N'):
	/* Device major,minor number */
	{ int32_t high, low;
	  high = from_733(rr->u.PN.dev_high);
	  low = from_733(rr->u.PN.dev_low);
	  /*
	   * The Rock Ridge standard specifies that if sizeof(dev_t) <= 4,
	   * then the high field is unused, and the device number is completely
	   * stored in the low field.  Some writers may ignore this subtlety,
	   * and as a result we test to see if the entire device number is
	   * stored in the low field, and use that.
	   */
	  if((low & ~0xff) && high == 0) {
	    p_stat->rr.i_rdev = CDIO_MKDEV(low >> 8, low & 0xff);
	  } else {
	    p_stat->rr.i_rdev = CDIO_MKDEV(high, low);
	  }
	}
	break;
      case SIG('T','F'): 
	/* Time stamp(s) for a file */
	{
	  int cnt = 0;
	  add_time(ISO_ROCK_TF_CREATE,     create);
	  add_time(ISO_ROCK_TF_MODIFY,     modify);
	  add_time(ISO_ROCK_TF_ACCESS,     access);
	  add_time(ISO_ROCK_TF_ATTRIBUTES, attributes);
	  add_time(ISO_ROCK_TF_BACKUP,     backup);
	  add_time(ISO_ROCK_TF_EXPIRATION, expiration);
	  add_time(ISO_ROCK_TF_EFFECTIVE,  effective);
	  p_stat->rr.b3_rock = yep;
	  break;
	}
      case SIG('S','L'):
	{
	  /* Symbolic link */
	  uint8_t slen;
	  iso_rock_sl_part_t * p_sl;
	  iso_rock_sl_part_t * p_oldsl;
	  slen = rr->len - 5;
	  p_sl = &rr->u.SL.link;
	  p_stat->rr.i_symlink = symlink_len;
	  while (slen > 1){
	    rootflag = 0;
	    switch(p_sl->flags &~1){
	    case 0:
	      realloc_symlink(p_stat, p_sl->len);
	      memcpy(&(p_stat->rr.psz_symlink[p_stat->rr.i_symlink]),
		     p_sl->text, p_sl->len);
	      p_stat->rr.i_symlink += p_sl->len;
	      break;
	    case 4:
	      realloc_symlink(p_stat, 1);
	      p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '.';
	      /* continue into next case. */
	    case 2:
	      realloc_symlink(p_stat, 1);
	      p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '.';
	      break;
	    case 8:
	      rootflag = 1;
	      realloc_symlink(p_stat, 1);
	      p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '/';
	      p_stat->rr.i_symlink++;
	      break;
	    default:
	      cdio_warn("Symlink component flag not implemented");
	    }
	    slen -= p_sl->len + 2;
	    p_oldsl = p_sl;
	    p_sl = (iso_rock_sl_part_t *) (((char *) p_sl) + p_sl->len + 2);
	    
	    if (slen < 2) {
	      if (((rr->u.SL.flags & 1) != 0) && ((p_oldsl->flags & 1) == 0)) 
		p_stat->rr.i_symlink += 1;
	      break;
	    }
	    
	    /*
	     * If this component record isn't continued, then append a '/'.
	     */
	    if (!rootflag && (p_oldsl->flags & 1) == 0) {
	      realloc_symlink(p_stat, 1);
	      p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '/';
	    }
	  }
	}
	symlink_len = p_stat->rr.i_symlink;
	realloc_symlink(p_stat, 1);
	p_stat->rr.psz_symlink[symlink_len]='\0';
	break;
      case SIG('R','E'):
	cdio_warn("Attempt to read p_stat for relocated directory");
	goto out;
#ifdef FINISHED
      case SIG('C','L'): 
	{
	  iso9660_stat_t * reloc;
	  ISOFS_I(p_stat)->i_first_extent = from_733(rr->u.CL.location);
	  reloc = isofs_iget(p_stat->rr.i_sb, p_stat->rr.i_first_extent, 0);
	  if (!reloc)
	    goto out;
	  p_stat->rr.st_mode   = reloc->st_mode;
	  p_stat->rr.st_nlinks = reloc->st_nlinks;
	  p_stat->rr.st_uid    = reloc->st_uid;
	  p_stat->rr.st_gid    = reloc->st_gid;
	  p_stat->rr.i_rdev    = reloc->i_rdev;
	  p_stat->rr.i_symlink = reloc->i_symlink;
	  p_stat->rr.i_blocks  = reloc->i_blocks;
	  p_stat->rr.i_atime   = reloc->i_atime;
	  p_stat->rr.i_ctime   = reloc->i_ctime;
	  p_stat->rr.i_mtime   = reloc->i_mtime;
	  iput(reloc);
	}
	break;
#endif
      default:
	break;
      }
    }