Exemple #1
0
ssize_t
ext2lib_pread(fsi_file_t *file, void *buf, size_t nbytes, uint64_t off)
{
	ext2_file_t *f = fsip_file_data(file);
	__u64 tmpoff;
	unsigned int n;
	int err;

	if ((err = ext2fs_file_llseek(*f, 0, EXT2_SEEK_CUR, &tmpoff)) != 0) {
		errno = EINVAL;
		return (-1);
	}

	if ((err = ext2fs_file_llseek(*f, off, EXT2_SEEK_SET, NULL)) != 0) {
		errno = EINVAL;
		return (-1);
	}

	err = ext2fs_file_read(*f, buf, nbytes, &n);

	ext2fs_file_llseek(*f, tmpoff, EXT2_SEEK_SET, NULL);

	if (err != 0) {
		errno = EINVAL;
		return (-1);
	}

	return (n);
}
Exemple #2
0
int op_read (const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi)
{
	__u64 pos;
	errcode_t rc;
	unsigned int bytes;
	ext2_file_t efile = EXT2FS_FILE(fi->fh);
	ext2_filsys e2fs = current_ext2fs();

	debugf("enter");
	debugf("path = %s", path);

	efile = do_open(e2fs, path, O_RDONLY);
	rc = ext2fs_file_llseek(efile, offset, SEEK_SET, &pos);
	if (rc) {
		do_release(efile);
		return -EINVAL;
	}

	rc = ext2fs_file_read(efile, buf, size, &bytes);
	if (rc) {
		do_release(efile);
		return -EIO;
	}
	do_release(efile);

	debugf("leave");
	return bytes;
}
static errcode_t get_file(ext2_filsys fs, const char * filename,
		   struct mem_file *ret_file)
{
	errcode_t	retval;
	char 		*buf;
	ext2_file_t	e2_file = NULL;
	unsigned int	got;
	struct ext2_inode inode;
	ext2_ino_t	ino;

	ret_file->buf = 0;
	ret_file->size = 0;
	ret_file->ptr = 0;

	retval = ext2fs_namei(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
			      filename, &ino);
	if (retval)
		return retval;

	retval = ext2fs_read_inode(fs, ino, &inode);
	if (retval)
		return retval;

	if (inode.i_size_high || (inode.i_size > 65536))
		return EFBIG;

	buf = malloc(inode.i_size + 1);
	if (!buf)
		return ENOMEM;
	memset(buf, 0, inode.i_size+1);

	retval = ext2fs_file_open(fs, ino, 0, &e2_file);
	if (retval)
		goto errout;

	retval = ext2fs_file_read(e2_file, buf, inode.i_size, &got);
	if (retval)
		goto errout;

	retval = ext2fs_file_close(e2_file);
	if (retval)
		goto errout;

	ret_file->buf = buf;
	ret_file->size = (int) got;
	return 0;

errout:
	free(buf);
	if (e2_file)
		ext2fs_file_close(e2_file);
	return retval;
}
Exemple #4
0
static void rdump_symlink(ext2_ino_t ino, struct ext2_inode *inode,
			  const char *fullname)
{
	ext2_file_t e2_file;
	char *buf;
	errcode_t retval;

	buf = malloc(inode->i_size + 1);
	if (!buf) {
		com_err("rdump", errno, "while allocating for symlink");
		goto errout;
	}

	/* Apparently, this is the right way to detect and handle fast
	 * symlinks; see do_stat() in debugfs.c. */
	if (inode->i_blocks == 0)
		strcpy(buf, (char *) inode->i_block);
	else {
		unsigned bytes = inode->i_size;
		char *p = buf;
		retval = ext2fs_file_open(current_fs, ino, 0, &e2_file);
		if (retval) {
			com_err("rdump", retval, "while opening symlink");
			goto errout;
		}
		for (;;) {
			unsigned int got;
			retval = ext2fs_file_read(e2_file, p, bytes, &got);
			if (retval) {
				com_err("rdump", retval, "while reading symlink");
				goto errout;
			}
			bytes -= got;
			p += got;
			if (got == 0 || bytes == 0)
				break;
		}
		buf[inode->i_size] = 0;
		retval = ext2fs_file_close(e2_file);
		if (retval)
			com_err("rdump", retval, "while closing symlink");
	}

	if (symlink(buf, fullname) == -1) {
		com_err("rdump", errno, "while creating symlink %s -> %s", buf, fullname);
		goto errout;
	}

errout:
	free(buf);
}
Exemple #5
0
ssize_t
ext2lib_read(fsi_file_t *file, void *buf, size_t nbytes)
{
	ext2_file_t *f = fsip_file_data(file);
	unsigned int n;
	int err;

	err = ext2fs_file_read(*f, buf, nbytes, &n);
	if (err != 0) {
		errno = EINVAL;
		return (-1);
	}

	return (n);
}
Exemple #6
0
static void dump_file(const char *cmdname, ext2_ino_t ino, int fd,
		      int preserve, char *outname)
{
	errcode_t retval;
	struct ext2_inode	inode;
	char		*buf = 0;
	ext2_file_t	e2_file;
	int		nbytes;
	unsigned int	got, blocksize = current_fs->blocksize;

	if (debugfs_read_inode(ino, &inode, cmdname))
		return;

	retval = ext2fs_file_open(current_fs, ino, 0, &e2_file);
	if (retval) {
		com_err(cmdname, retval, "while opening ext2 file");
		return;
	}
	retval = ext2fs_get_mem(blocksize, &buf);
	if (retval) {
		com_err(cmdname, retval, "while allocating memory");
		return;
	}
	while (1) {
		retval = ext2fs_file_read(e2_file, buf, blocksize, &got);
		if (retval)
			com_err(cmdname, retval, "while reading ext2 file");
		if (got == 0)
			break;
		nbytes = write(fd, buf, got);
		if ((unsigned) nbytes != got)
			com_err(cmdname, errno, "while writing file");
	}
	if (buf)
		ext2fs_free_mem(&buf);
	retval = ext2fs_file_close(e2_file);
	if (retval) {
		com_err(cmdname, retval, "while closing ext2 file");
		return;
	}

	if (preserve)
		fix_perms("dump_file", &inode, fd, outname);
	else if (fd != 1)
		close(fd);

	return;
}
Exemple #7
0
ssize_t ext2_read_r (struct _reent *r, int fd, char *ptr, size_t len)
{
   // ext2_log_trace("fd %p, ptr %p, len %i\n", (void *) fd, ptr, len);

    ext2_file_state* file = STATE(fd);

    // Sanity check
    if (!file || !file->vd || !file->fd) {
        r->_errno = EINVAL;
        return -1;
    }

    // Short circuit cases where we don't actually have to do anything
    if (!ptr || len <= 0) {
        return 0;
    }

    // Lock
    ext2Lock(file->vd);

    // Check that we are allowed to read from this file
    if (!file->read) {
        ext2Unlock(file->vd);
        r->_errno = EACCES;
        return -1;
    }

    u32 read = 0;
    errcode_t err = 0;

    // Read from the files data attribute
    err = ext2fs_file_read(file->fd, ptr, len, &read);
    if (err || read <= 0 || read > len) {
        ext2Unlock(file->vd);
        r->_errno = errno;
        return err ? err : -1;
    }

    // Unlock
    ext2Unlock(file->vd);

    return (read == 0) ? -1 : read;
}
Exemple #8
0
static errcode_t inode_read_blk64(io_channel channel,
				unsigned long long block, int count, void *buf)
{
	struct inode_private_data *data;
	errcode_t	retval;

	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
	data = (struct inode_private_data *) channel->private_data;
	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);

	if ((retval = ext2fs_file_lseek(data->file,
					block * channel->block_size,
					EXT2_SEEK_SET, 0)))
		return retval;

	count = (count < 0) ? -count : (count * channel->block_size);

	return ext2fs_file_read(data->file, buf, count, 0);
}
Exemple #9
0
static int read_journal_block(const char *cmd, struct journal_source *source,
			      ext2_loff_t offset, char *buf, unsigned int size)
{
	int retval;
	unsigned int got;

	if (source->where == JOURNAL_IS_EXTERNAL) {
		if (lseek(source->fd, offset, SEEK_SET) < 0) {
			retval = errno;
			goto seek_err;
		}
		retval = read(source->fd, buf, size);
		if (retval < 0) {
			retval = errno;
			goto read_err;
		}
		got = retval;
		retval = 0;
	} else {
		retval = ext2fs_file_llseek(source->file, offset,
					    EXT2_SEEK_SET, NULL);
		if (retval) {
		seek_err:
			com_err(cmd, retval, "while seeking in reading journal");
			return retval;
		}
		retval = ext2fs_file_read(source->file, buf, size, &got);
		if (retval) {
		read_err:
			com_err(cmd, retval, "while reading journal");
			return retval;
		}
	}
	if (got != size) {
		com_err(cmd, 0, "short read (read %u, expected %u) "
			"while reading journal", got, size);
		retval = -1;
	}
	return retval;
}
Exemple #10
0
static int read_journal_block(const char *cmd, struct journal_source *source,
			      off_t offset, char *buf, int size,
			      unsigned int *got)
{
	int retval;

	if (source->where == JOURNAL_IS_EXTERNAL) {
		if (lseek(source->fd, offset, SEEK_SET) < 0) {
			retval = errno;
			com_err(cmd, retval, "while seeking in reading journal");
			return retval;
		}
		retval = read(source->fd, buf, size);
		if (retval >= 0) {
			*got = retval;
			retval = 0;
		} else
			retval = errno;
	} else {
		retval = ext2fs_file_lseek(source->file, offset,
					   EXT2_SEEK_SET, NULL);
		if (retval) {
			com_err(cmd, retval, "while seeking in reading journal");
			return retval;
		}

		retval = ext2fs_file_read(source->file, buf, size, got);
	}

	if (retval)
		com_err(cmd, retval, "while reading journal");
	else if (*got != (unsigned int) size) {
		com_err(cmd, 0, "short read (read %d, expected %d) "
			"while reading journal", *got, size);
		retval = -1;
	}

	return retval;
}
Exemple #11
0
static void print_inline_journal_information(ext2_filsys fs)
{
	journal_superblock_t	*jsb;
	struct ext2_inode	inode;
	ext2_file_t		journal_file;
	errcode_t		retval;
	ino_t			ino = fs->super->s_journal_inum;
	char			buf[1024];
	__u32			*mask_ptr, mask, m;
	int			i, j, size, printed = 0;

	if (fs->flags & EXT2_FLAG_IMAGE_FILE)
		return;
	retval = ext2fs_read_inode(fs, ino,  &inode);
	if (retval) {
		com_err(program_name, retval, "%s",
			_("while reading journal inode"));
		exit(1);
	}
	retval = ext2fs_file_open2(fs, ino, &inode, 0, &journal_file);
	if (retval) {
		com_err(program_name, retval, "%s",
			_("while opening journal inode"));
		exit(1);
	}
	retval = ext2fs_file_read(journal_file, buf, sizeof(buf), 0);
	if (retval) {
		com_err(program_name, retval, "%s",
			_("while reading journal super block"));
		exit(1);
	}
	ext2fs_file_close(journal_file);
	jsb = (journal_superblock_t *) buf;
	if (be32_to_cpu(jsb->s_header.h_magic) != JFS_MAGIC_NUMBER) {
		fprintf(stderr, "%s",
			_("Journal superblock magic number invalid!\n"));
		exit(1);
	}
	printf("%s", _("Journal features:        "));
	for (i=0, mask_ptr=&jsb->s_feature_compat; i <3; i++,mask_ptr++) {
		mask = be32_to_cpu(*mask_ptr);
		for (j=0,m=1; j < 32; j++, m<<=1) {
			if (mask & m) {
				printf(" %s", e2p_jrnl_feature2string(i, m));
				printed++;
			}
		}
	}
	if (printed == 0)
		printf(" (none)");
	printf("\n");
	fputs(_("Journal size:             "), stdout);
	if ((fs->super->s_feature_ro_compat &
	     EXT4_FEATURE_RO_COMPAT_HUGE_FILE) &&
	    (inode.i_flags & EXT4_HUGE_FILE_FL))
		size = inode.i_blocks / (fs->blocksize / 1024);
	else
		size = inode.i_blocks >> 1;
	if (size < 8192)
		printf("%uk\n", size);
	else
		printf("%uM\n", size >> 10);
	printf(_("Journal length:           %u\n"
		 "Journal sequence:         0x%08x\n"
		 "Journal start:            %u\n"),
	       (unsigned int)ntohl(jsb->s_maxlen),
	       (unsigned int)ntohl(jsb->s_sequence),
	       (unsigned int)ntohl(jsb->s_start));
	if (jsb->s_feature_compat &
	    ext2fs_cpu_to_be32(JFS_FEATURE_COMPAT_CHECKSUM))
		printf(_("Journal checksum type:    crc32\n"));
	if (jsb->s_feature_incompat &
	    ext2fs_cpu_to_be32(JFS_FEATURE_INCOMPAT_CSUM_V2))
		printf(_("Journal checksum type:    %s\n"
			 "Journal checksum:         0x%08x\n"),
		       journal_checksum_type_str(jsb->s_checksum_type),
		       ext2fs_be32_to_cpu(jsb->s_checksum));
	if (jsb->s_errno != 0)
		printf(_("Journal errno:            %d\n"),
		       (int) ntohl(jsb->s_errno));
}
Exemple #12
0
/* Name:	tail()
 *
 * Description:
 *
 * This function displays the last lines at the end of a file in an ext2
 * file system.
 *
 * Algorithm:
 *
 * Get the directory and basename of the file
 * Determine the inode number for the file
 * Open the file for reading
 * Skip to the last block in the file
 * While we have not found the last num_lines of newline characters
 *	  Skip backwards in the file one block and read it
 * Display the contents of the block from that point on.
 * Display the rest of the file if not contained in the block
 * Save the current location of the file.
 * If we are following the file as it grows
 *	  While forever
 *		  Sleep
 *		  Re-read the inode for the file
 *		  If the size has changed
 *			  Display the file from the saved point on
 *            Save the current location of the file.
 *	  
 *	  
 * Global Variables:
 *
 * None
 *
 * Arguments:
 *
 * ext2_filsys *fs;             Our filesystem
 * ext2_ino_t root;             The root directory inode number
 * char *input;                 The name of the input file to tail
 * int num_lines;               The number of lines to display
 * int follow;                  Flag indicating if the we should follow any
 *                              new contents to the file.
 * int sleep_int;               The number of seconds to sleep between checking
 *                              for new lines
 * char *cur_filesys
 *
 * Return Values:
 *
 * 0 - the last number of lines was displayed correctly.
 * an error occurred.
 *
 * Author: Keith W. Sheffield
 * Date:   08/07/2002
 *
 * Modification History:
 *
 * MM/DD/YY		 Name				Description
 */
static long
tail(ext2_filsys *fs_ptr, ext2_ino_t root, char *input, int num_lines,
     int follow, int sleep_int, char *cur_filesys)
{
  ext2_filsys fs = *fs_ptr;
  ext2_ino_t cwd;
  ext2_ino_t tail_ino;
  ext2_ino_t t_tail_ino;
  char *tail_dir;
  char *tail_name;
  long retval;
  char buf[BLK_SIZE];
  unsigned int bytes_to_read;
  unsigned int bytes_read;
  char *ptr;
  struct ext2_inode inode;
  ext2_file_t tail_fd;    
  ext2_off_t offset;
  ext2_off_t cur_pos;

  if (get_file_parts(fs, root, input, &cwd, &tail_dir, &tail_name))
    {
      ext2fs_close(fs);
      return(-1);
    }          

  /* get the inode number for the source file */
  if ((retval = ext2fs_namei(fs, cwd, cwd, tail_name, &tail_ino)))
    {
      fprintf(stderr, "%s: file %s\n",error_message(retval),
              tail_name);
      return(retval);
    }

  /* open the file */
  if ((retval = ext2fs_file_open(fs, tail_ino, 0, &tail_fd)))
    {
      fputs(error_message(retval), stderr);
      return retval;
    }

  /* get the length of the file and determine where to start reading */
  inode.i_size = offset = ext2fs_file_get_size(tail_fd);
  bytes_to_read = offset % BLK_SIZE;
  if (bytes_to_read == 0)
    bytes_to_read = BLK_SIZE;

  offset -= bytes_to_read;
  if (((int32_t)offset) < 0)
    offset = 0;

  do
    {
      /* seek to the start of the last block in the file */
      if ((retval = ext2fs_file_lseek(tail_fd, offset, EXT2_SEEK_SET, NULL)))
        {
          fputs(error_message(retval), stderr);
          return retval;
        }
      /* read the last block in the file */
      if ((retval = ext2fs_file_read(tail_fd, buf, bytes_to_read,
                                     &bytes_read)))
        {
          fputs(error_message(retval), stderr);
          return retval;
        }
      if (bytes_to_read != bytes_read)
        {
          fputs("error reading file\n", stderr);
          return(-1);
        }
      
      ptr = buf + bytes_read - 1;
      while (bytes_to_read--)
        {
          if (*ptr == '\n' && num_lines-- == 0)
            {
              /* if the newline wasn't the last character in the buffer, then
               * print what's remaining.
               */
              if (bytes_to_read != bytes_read - 1)
                {
                  ptr++;
		  if (0 > write(1, ptr, bytes_read - bytes_to_read - 1))
		    {
		      perror("writing bytes to stdout");
		      return -1;
		    }
                }
              offset = 0;       /* make sure we break out of the main loop */
              break;
            }
          ptr--;
        }

      offset -= (offset < BLK_SIZE) ? offset : BLK_SIZE;
      bytes_to_read = BLK_SIZE;
    }
  while (offset > 0);

  /* if we are here and have any lines left, we hit the beginning, so
   * dump the rest of what's in memory out.
   */
  
  if (num_lines > 0)
    {
      if (0 > write(1, buf, bytes_read)) {
	perror("writing bytes to stdout");
	return -1;
      }
    }
    
  /* retreive the current position in the file */
  if ((retval = ext2fs_file_lseek(tail_fd, 0, EXT2_SEEK_CUR, &cur_pos)))
    {
      fputs(error_message(retval), stderr);
      return retval;
    }

  /* ok, if we are before the end of the file, then dump the rest of it */
  if (cur_pos < inode.i_size)
    {
      if ((retval = read_to_eof(tail_fd, 1, cur_pos, &cur_pos)))
        {
          return retval;
        }
    }

  if ((retval = ext2fs_file_close(tail_fd)))
    {
      fputs(error_message(retval), stderr);
      return retval;
    }

  if (follow)
    {
      while(1)
        {
          sleep(sleep_int);
          /* I don't know how to force a re-read of the file system info yet,
           * so, just close the file system and reopen it.
           */
          ext2fs_close(fs);
          if ((retval = open_filesystem(cur_filesys, &fs, &root, 0)))
            {
              *fs_ptr = NULL;
              fprintf(stderr, "%s: %s\n", error_message(retval), cur_filesys);
              return retval;
            }
          *fs_ptr = fs;

          /* if we are following the name, find the directory and file name
           * again.
           */
          if (follow == FOLLOW_NAME)
            {
              cwd = root;
              
              if (tail_dir != NULL && *tail_dir != '\0' &&
                  strcmp(tail_dir, ",") != 0 &&
                  (retval = change_cwd(fs, root, &cwd, tail_dir)))
                {
                  fprintf(stderr, "Error changing to directory %s\n",
                          tail_dir);
                  return(retval);
                }

              /* get the inode number for the source file */
              if ((retval = ext2fs_namei(fs, cwd, cwd, tail_name,
                                         &t_tail_ino)))
                {
                  fprintf(stderr, "%s: file %s\n",error_message(retval),
                          tail_name);
                  return(retval);
                }

              /* if we are dealing with a new file, then start from the
               * beginning.
               */
              
              if (t_tail_ino != tail_ino)
                {
                  tail_ino = t_tail_ino;
                  cur_pos = 0;
                }
            }
          
          if ((retval = ext2fs_read_inode(fs, tail_ino, &inode)))
            {
              fputs(error_message(retval), stderr);
              return retval;
            }
          if (inode.i_size > cur_pos)
            {
              if ((retval = retrieve_data(fs, tail_ino, 1, NULL, 0, cur_pos,
                                          &cur_pos)))
                {
                  fputs(error_message(retval), stderr);
                  return retval;
                }
            }
          else if (inode.i_size < cur_pos)
            {
              /* the file was truncated, so bail */
              return(0);
            }          
        }
    }
  return(0);
}
Exemple #13
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;
}