Beispiel #1
0
static int ntfs_copy(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const file_info_t *file)
{
  const unsigned long int first_inode=file->st_ino;
  ntfs_inode *inode;
  struct ntfs_dir_struct *ls=(struct ntfs_dir_struct*)dir_data->private_dir_data;
  inode = ntfs_inode_open (ls->vol, first_inode);
  if (!inode) {
    log_error("ntfs_copy: ntfs_inode_open failed for %s\n", dir_data->current_directory);
    return -1;
  }
  {
    char *buffer;
    char *new_file;
    ntfs_attr *attr=NULL;
    FILE *f_out;
    char *stream_name;
    s64 offset;
    u32 block_size;
    buffer = (char *)MALLOC(bufsize);
    if (!buffer)
    {
      ntfs_inode_close(inode);
      return -2;
    }
    stream_name=strrchr(dir_data->current_directory, ':');
    if(stream_name)
      stream_name++;
    if(stream_name != NULL)
    {
      ntfschar *stream_name_ucs=NULL;
#ifdef NTFS_MBSTOUCS_HAVE_TWO_ARGUMENTS
      const int len=ntfs_mbstoucs(stream_name, &stream_name_ucs);
#else
      const int len=ntfs_mbstoucs(stream_name, &stream_name_ucs, 0);
#endif
      if(len < 0)
	log_error("ntfs_mbstoucs failed\n");
      else
	attr = ntfs_attr_open(inode, AT_DATA, stream_name_ucs, len);
    }
    else
      attr = ntfs_attr_open(inode, AT_DATA, NULL, 0);
    if (!attr)
    {
      log_error("Cannot find attribute type 0x%lx.\n", (long) AT_DATA);
      free(buffer);
      ntfs_inode_close(inode);
      return -3;
    }
    if ((inode->mft_no < 2) && (attr->type == AT_DATA))
      block_size = ls->vol->mft_record_size;
    else if (attr->type == AT_INDEX_ALLOCATION)
      block_size = index_get_size(inode);
    else
      block_size = 0;
#if defined(__CYGWIN__) || defined(__MINGW32__)
    if(stream_name)
    {
      /* fopen() create normal files instead of ADS with ':' replaced by an UTF char
       * replace ':' by '_' instead */
      stream_name--;
      *stream_name='_';
      f_out=fopen_local(&new_file, dir_data->local_dir, dir_data->current_directory);
    }
    else
      f_out=fopen_local(&new_file, dir_data->local_dir, dir_data->current_directory);
#else
    f_out=fopen_local(&new_file, dir_data->local_dir, dir_data->current_directory);
#endif
    if(!f_out)
    {
      log_critical("Can't create file %s: %s\n",new_file, strerror(errno));
      free(new_file);
      ntfs_attr_close(attr);
      free(buffer);
      ntfs_inode_close(inode);
      return -4;
    }
    offset = 0;
    for (;;)
    {
      s64 bytes_read, written;
      if (block_size > 0) {
	// These types have fixup
	bytes_read = ntfs_attr_mst_pread(attr, offset, 1, block_size, buffer);
	bytes_read *= block_size;
      } else {
	bytes_read = ntfs_attr_pread(attr, offset, bufsize, buffer);
      }
      //ntfs_log_info("read %lld bytes\n", bytes_read);
      if (bytes_read < 0) {
	log_error("ERROR: Couldn't read file");
	break;
      }
      if (!bytes_read)
	break;

      written = fwrite(buffer, 1, bytes_read, f_out);
      if (written != bytes_read)
      {
	log_error("ERROR: Couldn't output all data!");
	break;
      }
      offset += bytes_read;
    }
    fclose(f_out);
    set_date(new_file, file->td_atime, file->td_mtime);
    free(new_file);
    ntfs_attr_close(attr);
    free(buffer);
  }
  /* Finished with the inode; release it. */
  ntfs_inode_close(inode);
  return 0;
}
Beispiel #2
0
static int ext2_copy(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const file_info_t *file)
{
  int error=0;
  FILE *f_out;
  const struct ext2_dir_struct *ls = (const struct ext2_dir_struct *)dir_data->private_dir_data;
  char *new_file;
  f_out=fopen_local(&new_file, dir_data->local_dir, dir_data->current_directory);
  if(!f_out)
  {
    log_critical("Can't create file %s: %s\n", new_file, strerror(errno));
    free(new_file);
    return -4;
  }
  {
    errcode_t retval;
    struct ext2_inode       inode;
    char            buffer[8192];
    ext2_file_t     e2_file;

    if (ext2fs_read_inode(ls->current_fs, file->st_ino, &inode)!=0)
    {
      free(new_file);
      fclose(f_out);
      return -1;
    }

    retval = ext2fs_file_open(ls->current_fs, file->st_ino, 0, &e2_file);
    if (retval) {
      log_error("Error while opening ext2 file %s\n", dir_data->current_directory);
      free(new_file);
      fclose(f_out);
      return -2;
    }
    while (1)
    {
      int             nbytes; 
      unsigned int    got;
      retval = ext2fs_file_read(e2_file, buffer, sizeof(buffer), &got);
      if (retval)
      {
	log_error("Error while reading ext2 file %s\n", dir_data->current_directory);
	error = -3;
      }
      if (got == 0)
	break;
      nbytes = fwrite(buffer, 1, got, f_out);
      if ((unsigned) nbytes != got)
      {
	log_error("Error while writing file %s\n", new_file);
      error = -5;
      }
    }
    retval = ext2fs_file_close(e2_file);
    if (retval)
    {
      log_error("Error while closing ext2 file\n");
      error = -6;
    }
    fclose(f_out);
    set_date(new_file, file->td_atime, file->td_mtime);
    (void)set_mode(new_file, file->st_mode);
  }
  free(new_file);
  return error;
}
Beispiel #3
0
static int reiser_copy(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const file_data_t *file)
{
  reiserfs_file_t *in;
  FILE *f_out;
  char *new_file;
  struct rfs_dir_struct *ls=(struct rfs_dir_struct*)dir_data->private_dir_data;
  int error=0;
  uint64_t file_size;
  f_out=fopen_local(&new_file, dir_data->local_dir, dir_data->current_directory);
  if(!f_out)
  {
    log_critical("Can't create file %s: %s\n", new_file, strerror(errno));
    free(new_file);
    return -4;
  }
  log_error("Try to open rfs file %s\n", dir_data->current_directory);
  log_flush();
  in=reiserfs_file_open(ls->current_fs, dir_data->current_directory, O_RDONLY);
  if (in==NULL)
  {
    log_error("Error while opening rfs file %s\n", dir_data->current_directory);
    free(new_file);
    fclose(f_out);
    return -1;
  }
  log_error("open rfs file %s done\n", dir_data->current_directory);
  log_flush();
  file_size = reiserfs_file_size(in);
#if 0
  /* TODO: do not use so much memory */
  {
    void *buf=MALLOC(file_size+1);
    if (reiserfs_file_read(in, buf, file_size) != file_size)
    {
      log_error("Error while reading rfs file %s\n", dir_data->current_directory);
      error = -3;
    }
    else if (fwrite(buf, file_size, 1, f_out) != 1)
    {
      log_error("Error while writing file %s\n", new_file);
      error = -5;
    }
    free(buf);
  }
#else
  {
    /* require progsreiserfs-file-read.patch */
    char buf[4096];
    uint64_t offset=0;
    while(file_size > 0)
    {
      int read_size=(file_size < sizeof(buf) ? file_size : sizeof(buf));
      if (reiserfs_file_read(in, buf, read_size) == 0)
      {
	log_error("Error while reading rfs file %s\n", dir_data->current_directory);
	error = -3;
      }
      else if (fwrite(buf, read_size, 1, f_out) != 1)
      {
	log_error("Error while writing file %s\n", new_file);
	error = -5;
      }
      file_size -= read_size;
      offset += read_size;
    }
  }
#endif
  reiserfs_file_close(in);
  fclose(f_out);
  set_date(new_file, file->td_atime, file->td_mtime);
  set_mode(new_file, file->st_mode);
  free(new_file);
  return error;
}
Beispiel #4
0
static int exfat_copy(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const file_info_t *file)
{
  char *new_file;	
  FILE *f_out;
  const struct exfat_dir_struct *ls=(const struct exfat_dir_struct*)dir_data->private_dir_data;
  const struct exfat_super_block *exfat_header=ls->boot_sector;
  const unsigned int cluster_shift=exfat_header->block_per_clus_bits + exfat_header->blocksize_bits;
  unsigned char *buffer_file=(unsigned char *)MALLOC(1<<cluster_shift);
  unsigned int cluster;
  uint64_t file_size=file->st_size;
  exfat_method_t exfat_meth=exFAT_FOLLOW_CLUSTER;
  uint64_t start_exfat1,clus_blocknr;
  unsigned long int total_clusters;
  f_out=fopen_local(&new_file, dir_data->local_dir, dir_data->current_directory);
  if(!f_out)
  {
    log_critical("Can't create file %s: \n",new_file);
    free(new_file);
    free(buffer_file);
    return -1;
  }
  cluster = file->st_ino;
  start_exfat1=le32(exfat_header->fat_blocknr) << exfat_header->blocksize_bits;
  clus_blocknr=le32(exfat_header->clus_blocknr);
  total_clusters=le32(exfat_header->total_clusters);
  log_trace("exfat_copy dst=%s first_cluster=%u (%llu) size=%lu\n", new_file,
      cluster,
      (long long unsigned)(((cluster-2) << exfat_header->block_per_clus_bits) + clus_blocknr),
      (long unsigned)file_size);

  while(cluster>=2 && cluster<=total_clusters && file_size>0)
  {
    unsigned int toread = 1 << cluster_shift;
    if (toread > file_size)
      toread = file_size;
    if((unsigned)exfat_read_cluster(disk, partition, exfat_header, buffer_file, cluster) < toread)
    {
      log_error("exfat_copy: Can't read cluster %u.\n", cluster);
    }
    if(fwrite(buffer_file, 1, toread, f_out) != toread)
    {
      log_error("exfat_copy: no space left on destination.\n");
      fclose(f_out);
      set_date(new_file, file->td_atime, file->td_mtime);
      free(new_file);
      free(buffer_file);
      return -1;
    }
    file_size -= toread;
    if(file_size>0)
    {
      if(exfat_meth==exFAT_FOLLOW_CLUSTER)
      {
	const unsigned int next_cluster=exfat_get_next_cluster(disk, partition, start_exfat1, cluster);
	if(next_cluster>=2 && next_cluster<=total_clusters)
	  cluster=next_cluster;
	else if(cluster==file->st_ino && next_cluster==0)
	  exfat_meth=exFAT_NEXT_FREE_CLUSTER;	/* Recovery of a deleted file */
	else
	  exfat_meth=exFAT_NEXT_CLUSTER;		/* exFAT is corrupted, don't trust it */
      }
      if(exfat_meth==exFAT_NEXT_CLUSTER)
	cluster++;
      else if(exfat_meth==exFAT_NEXT_FREE_CLUSTER)
      {	/* Deleted file are composed of "free" clusters */
	while(++cluster<total_clusters &&
	    exfat_get_next_cluster(disk, partition, start_exfat1, cluster)!=0);
      }
    }
  }
  fclose(f_out);
  set_date(new_file, file->td_atime, file->td_mtime);
  free(new_file);
  free(buffer_file);
  return 0;
}