Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
void ext2CloseFile (ext2_file_state *file)
{
    // Sanity check
    if (!file || !file->vd)
        return;

    ext2fs_file_close(file->fd);

    // Sync the file (and its attributes) to disc
    if(file->write)
        ext2UpdateTimes(file->vd, file->ni, EXT2_UPDATE_ACTIME);

    if (file->read)
        ext2UpdateTimes(file->vd, file->ni, EXT2_UPDATE_ATIME);

    ext2Sync(file->vd, file->ni);

    // Close the file (if open)
    if (file->ni)
        ext2CloseEntry(file->vd, file->ni);

    // Reset the file state
    file->ni = NULL;
    file->fd = NULL;
    file->flags = 0;
    file->read = false;
    file->write = false;
    file->append = false;

    return;
}
Ejemplo n.º 3
0
int
ext2lib_close(fsi_file_t *file)
{
	ext2_file_t *f = fsip_file_data(file);
	ext2fs_file_close(*f);
	free(f);
	return (0);
}
Ejemplo n.º 4
0
errcode_t quota_write_inode(quota_ctx_t qctx, int qtype)
{
	int		retval = 0, i;
	dict_t		*dict;
	ext2_filsys	fs;
	struct quota_handle *h = NULL;
	int		fmt = QFMT_VFS_V1;

	if (!qctx)
		return 0;

	fs = qctx->fs;
	retval = ext2fs_get_mem(sizeof(struct quota_handle), &h);
	if (retval) {
		log_err("Unable to allocate quota handle", "");
		goto out;
	}

	ext2fs_read_bitmaps(fs);

	for (i = 0; i < MAXQUOTAS; i++) {
		if ((qtype != -1) && (i != qtype))
			continue;

		dict = qctx->quota_dict[i];
		if (!dict)
			continue;

		retval = quota_file_create(h, fs, i, fmt);
		if (retval < 0) {
			log_err("Cannot initialize io on quotafile", "");
			continue;
		}

		write_dquots(dict, h);
		retval = quota_file_close(h);
		if (retval < 0) {
			log_err("Cannot finish IO on new quotafile: %s",
				strerror(errno));
			if (h->qh_qf.e2_file)
				ext2fs_file_close(h->qh_qf.e2_file);
			quota_inode_truncate(fs, h->qh_qf.ino);
			continue;
		}

		/* Set quota inode numbers in superblock. */
		quota_set_sb_inum(fs, h->qh_qf.ino, i);
		ext2fs_mark_super_dirty(fs);
		ext2fs_mark_bb_dirty(fs);
		fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
	}

	ext2fs_write_bitmaps(fs);
out:
	if (h)
		ext2fs_free_mem(&h);
	return retval;
}
Ejemplo n.º 5
0
errcode_t write_quota_inode(quota_ctx_t qctx, int qtype)
{
	int		retval, i;
	unsigned long	qf_inums[MAXQUOTAS];
	struct dquot	*dquot;
	dict_t		*dict;
	ext2_filsys	fs;
	struct quota_handle *h;
	int		fmt = QFMT_VFS_V1;

	if (!qctx)
		return;

	fs = qctx->fs;
	h = smalloc(sizeof(struct quota_handle));
	ext2fs_read_bitmaps(fs);

	for (i = 0; i < MAXQUOTAS; i++) {
		if ((qtype != -1) && (i != qtype))
			continue;

		dict = qctx->quota_dict[i];
		if (!dict)
			continue;

		retval = new_io(h, fs, i, fmt);
		if (retval < 0) {
			log_err("Cannot initialize io on quotafile", "");
			continue;
		}

		write_dquots(dict, h);
		retval = end_io(h);
		if (retval < 0) {
			log_err("Cannot finish IO on new quotafile: %s",
				strerror(errno));
			if (h->qh_qf.e2_file)
				ext2fs_file_close(h->qh_qf.e2_file);
			truncate_quota_inode(fs, h->qh_qf.ino);
			continue;
		}

		/* Set quota inode numbers in superblock. */
		set_sb_quota_inum(fs, h->qh_qf.ino, i);
		ext2fs_mark_super_dirty(fs);
		ext2fs_mark_bb_dirty(fs);
		fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
	}

	ext2fs_write_bitmaps(fs);
out:
	free(h);
	return retval;
}
Ejemplo n.º 6
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);
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
static errcode_t inode_close(io_channel channel)
{
	struct inode_private_data *data;
	errcode_t	retval = 0;

	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 (--channel->refcount > 0)
		return 0;

	retval = ext2fs_file_close(data->file);

	ext2fs_free_mem(&channel->private_data);
	if (channel->name)
		ext2fs_free_mem(&channel->name);
	ext2fs_free_mem(&channel);
	return retval;
}
Ejemplo n.º 9
0
static errcode_t
ext2fs_inline_data_file_expand(ext2_filsys fs, ext2_ino_t ino,
                               struct ext2_inode *inode, char *buf, size_t size)
{
    ext2_file_t e2_file;
    errcode_t retval;

    /* Update inode */
    if (EXT2_HAS_INCOMPAT_FEATURE(fs->super,
                                  EXT3_FEATURE_INCOMPAT_EXTENTS)) {
        int i;
        struct ext3_extent_header *eh;

        eh = (struct ext3_extent_header *) &inode->i_block[0];
        eh->eh_depth = 0;
        eh->eh_entries = 0;
        eh->eh_magic = ext2fs_cpu_to_le16(EXT3_EXT_MAGIC);
        i = (sizeof(inode->i_block) - sizeof(*eh)) /
            sizeof(struct ext3_extent);
        eh->eh_max = ext2fs_cpu_to_le16(i);
        inode->i_flags |= EXT4_EXTENTS_FL;
    }
    inode->i_flags &= ~EXT4_INLINE_DATA_FL;
    inode->i_size = 0;
    retval = ext2fs_write_inode(fs, ino, inode);
    if (retval)
        return retval;

    /* Write out the block buffer */
    retval = ext2fs_file_open(fs, ino, EXT2_FILE_WRITE, &e2_file);
    if (retval)
        return retval;
    retval = ext2fs_file_write(e2_file, buf, size, 0);
    ext2fs_file_close(e2_file);
    return retval;
}
Ejemplo n.º 10
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));
}
Ejemplo n.º 11
0
void do_logdump(int argc, char **argv)
{
	int		c;
	int		retval;
	char		*out_fn;
	FILE		*out_file;
	
	char		*inode_spec = NULL;
	char		*journal_fn = NULL;
	int		journal_fd = 0;
	int		use_sb = 0;
	ext2_ino_t	journal_inum;
	struct ext2_inode journal_inode;
	ext2_file_t 	journal_file;
	char		*tmp;
	struct journal_source journal_source;
	struct ext2_super_block *es = NULL;
	
	journal_source.where = 0;
	journal_source.fd = 0;
	journal_source.file = 0;
	dump_all = 0;
	dump_contents = 0;
	dump_descriptors = 1;
	block_to_dump = ANY_BLOCK;
	bitmap_to_dump = -1;
	inode_block_to_dump = ANY_BLOCK;
	inode_to_dump = -1;
	
	reset_getopt();
	while ((c = getopt (argc, argv, "ab:ci:f:s")) != EOF) {
		switch (c) {
		case 'a':
			dump_all++;
			break;
		case 'b':
			block_to_dump = strtoul(optarg, &tmp, 0);
			if (*tmp) {
				com_err(argv[0], 0,
					"Bad block number - %s", optarg);
				return;
			}
			dump_descriptors = 0;
			break;
		case 'c':
			dump_contents++;
			break;
		case 'f':
			journal_fn = optarg;
			break;
		case 'i':
			inode_spec = optarg;
			dump_descriptors = 0;
			break;
		case 's':
			use_sb++;
			break;
		default:
			goto print_usage;
		}
	}
	if (optind != argc && optind != argc-1) {
		goto print_usage;
	}

	if (current_fs)
		es = current_fs->super;

	if (inode_spec) {
		int inode_group, group_offset, inodes_per_block;

		if (check_fs_open(argv[0]))
			return;

		inode_to_dump = string_to_inode(inode_spec);
		if (!inode_to_dump)
			return;

		inode_group = ((inode_to_dump - 1)
			       / es->s_inodes_per_group);
		group_offset = ((inode_to_dump - 1)
				% es->s_inodes_per_group);
		inodes_per_block = (current_fs->blocksize 
				    / sizeof(struct ext2_inode));
		
		inode_block_to_dump = 
			current_fs->group_desc[inode_group].bg_inode_table + 
			(group_offset / inodes_per_block);
		inode_offset_to_dump = ((group_offset % inodes_per_block)
					* sizeof(struct ext2_inode));
		printf("Inode %u is at group %u, block %u, offset %u\n",
		       inode_to_dump, inode_group,
		       inode_block_to_dump, inode_offset_to_dump);
	}

	if (optind == argc) {
		out_file = stdout;
	} else {
		out_fn = argv[optind];
		out_file = fopen(out_fn, "w");
		if (!out_file < 0) {
			com_err(argv[0], errno, "while opening %s for logdump",
				out_fn);
			return;
		}
	}

	if (block_to_dump != ANY_BLOCK && current_fs != NULL) {
		group_to_dump = ((block_to_dump - 
				  es->s_first_data_block)
				 / es->s_blocks_per_group);
		bitmap_to_dump = current_fs->group_desc[group_to_dump].bg_block_bitmap;
	}

	if (!journal_fn && check_fs_open(argv[0]))
		return;

	if (journal_fn) {
		/* Set up to read journal from a regular file somewhere */
		journal_fd = open(journal_fn, O_RDONLY, 0);
		if (journal_fd < 0) {
			com_err(argv[0], errno, "while opening %s for logdump",
				journal_fn);
			return;
		}
		
		journal_source.where = JOURNAL_IS_EXTERNAL;
		journal_source.fd = journal_fd;
	} else if ((journal_inum = es->s_journal_inum)) {
		if (use_sb) {
			if (es->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS) {
				com_err(argv[0], 0,
					"no journal backup in super block\n");
				return;
			}
			memset(&journal_inode, 0, sizeof(struct ext2_inode));
			memcpy(&journal_inode.i_block[0], es->s_jnl_blocks, 
			       EXT2_N_BLOCKS*4);
			journal_inode.i_size = es->s_jnl_blocks[16];
			journal_inode.i_links_count = 1;
			journal_inode.i_mode = LINUX_S_IFREG | 0600;
		} else {
			if (debugfs_read_inode(journal_inum, &journal_inode, 
					       argv[0]))
				return;
		}
		
		retval = ext2fs_file_open2(current_fs, journal_inum,
					   &journal_inode, 0, &journal_file);
		if (retval) {
			com_err(argv[0], retval, "while opening ext2 file");
			return;
		}
		journal_source.where = JOURNAL_IS_INTERNAL;
		journal_source.file = journal_file;
	} else {
		char uuid[37];
		
		uuid_unparse(es->s_journal_uuid, uuid);
		journal_fn = blkid_get_devname(NULL, "UUID", uuid);
		if (!journal_fn)
				journal_fn = blkid_devno_to_devname(es->s_journal_dev);
		if (!journal_fn) {
			com_err(argv[0], 0, "filesystem has no journal");
			return;
		}
		journal_fd = open(journal_fn, O_RDONLY, 0);
		if (journal_fd < 0) {
			com_err(argv[0], errno, "while opening %s for logdump",
				journal_fn);
			free(journal_fn);
			return;
		}
		fprintf(out_file, "Using external journal found at %s\n",
			journal_fn);
		free(journal_fn);
		journal_source.where = JOURNAL_IS_EXTERNAL;
		journal_source.fd = journal_fd;
	}

	dump_journal(argv[0], out_file, &journal_source);

	if (journal_source.where == JOURNAL_IS_INTERNAL)
		ext2fs_file_close(journal_file);
	else
		close(journal_fd);

	if (out_file != stdout)
		fclose(out_file);

	return;

print_usage:
	fprintf(stderr, "%s: Usage: logdump [-ac] [-b<block>] [-i<inode>]\n\t"
		"[-f<journal_file>] [output_file]\n", argv[0]);
}
Ejemplo n.º 12
0
Archivo: tail.c Proyecto: ndim/e2tools
/* 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);
}
Ejemplo n.º 13
0
errcode_t quota_write_inode(quota_ctx_t qctx, unsigned int qtype_bits)
{
	int		retval = 0;
	enum quota_type	qtype;
	dict_t		*dict;
	ext2_filsys	fs;
	struct quota_handle *h = NULL;
	int		fmt = QFMT_VFS_V1;

	if (!qctx)
		return 0;

	fs = qctx->fs;
	retval = ext2fs_get_mem(sizeof(struct quota_handle), &h);
	if (retval) {
		log_debug("Unable to allocate quota handle: %s",
			error_message(retval));
		goto out;
	}

	retval = ext2fs_read_bitmaps(fs);
	if (retval) {
		log_debug("Couldn't read bitmaps: %s", error_message(retval));
		goto out;
	}

	for (qtype = 0; qtype < MAXQUOTAS; qtype++) {
		if (((1 << qtype) & qtype_bits) == 0)
			continue;

		dict = qctx->quota_dict[qtype];
		if (!dict)
			continue;

		retval = quota_file_create(h, fs, qtype, fmt);
		if (retval) {
			log_debug("Cannot initialize io on quotafile: %s",
				  error_message(retval));
			goto out;
		}

		write_dquots(dict, h);
		retval = quota_file_close(qctx, h);
		if (retval) {
			log_debug("Cannot finish IO on new quotafile: %s",
				  strerror(errno));
			if (h->qh_qf.e2_file)
				ext2fs_file_close(h->qh_qf.e2_file);
			(void) quota_inode_truncate(fs, h->qh_qf.ino);
			goto out;
		}

		/* Set quota inode numbers in superblock. */
		quota_set_sb_inum(fs, h->qh_qf.ino, qtype);
		ext2fs_mark_super_dirty(fs);
		ext2fs_mark_bb_dirty(fs);
		fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
	}

	retval = ext2fs_write_bitmaps(fs);
	if (retval) {
		log_debug("Couldn't write bitmaps: %s", error_message(retval));
		goto out;
	}
out:
	if (h)
		ext2fs_free_mem(&h);
	return retval;
}
Ejemplo n.º 14
0
static errcode_t copy_file(ext2_filsys fs, int fd, ext2_ino_t newfile,
			   int bufsize, int make_holes)
{
	ext2_file_t	e2_file;
	errcode_t	retval, close_ret;
	int		got;
	unsigned int	written;
	char		*buf;
	char		*ptr;
	char		*zero_buf;
	int		cmp;

	retval = ext2fs_file_open(fs, newfile,
				  EXT2_FILE_WRITE, &e2_file);
	if (retval)
		return retval;

	retval = ext2fs_get_mem(bufsize, &buf);
	if (retval) {
		com_err("copy_file", retval, "can't allocate buffer\n");
		goto out_close;
	}

	/* This is used for checking whether the whole block is zero */
	retval = ext2fs_get_memzero(bufsize, &zero_buf);
	if (retval) {
		com_err("copy_file", retval, "can't allocate zero buffer\n");
		goto out_free_buf;
	}

	while (1) {
		got = read(fd, buf, bufsize);
		if (got == 0)
			break;
		if (got < 0) {
			retval = errno;
			goto fail;
		}
		ptr = buf;

		/* Sparse copy */
		if (make_holes) {
			/* Check whether all is zero */
			cmp = memcmp(ptr, zero_buf, got);
			if (cmp == 0) {
				 /* The whole block is zero, make a hole */
				retval = ext2fs_file_lseek(e2_file, got,
							   EXT2_SEEK_CUR,
							   NULL);
				if (retval)
					goto fail;
				got = 0;
			}
		}

		/* Normal copy */
		while (got > 0) {
			retval = ext2fs_file_write(e2_file, ptr,
						   got, &written);
			if (retval)
				goto fail;

			got -= written;
			ptr += written;
		}
	}

fail:
	ext2fs_free_mem(&zero_buf);
out_free_buf:
	ext2fs_free_mem(&buf);
out_close:
	close_ret = ext2fs_file_close(e2_file);
	if (retval == 0)
		retval = close_ret;
	return retval;
}
Ejemplo n.º 15
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;
}