Beispiel #1
0
/* Make a directory in the fs */
errcode_t do_mkdir_internal(ext2_filsys fs, ext2_ino_t cwd, const char *name,
			    struct stat *st, ext2_ino_t root)
{
	char			*cp;
	ext2_ino_t		parent_ino;
	errcode_t		retval;


	cp = strrchr(name, '/');
	if (cp) {
		*cp = 0;
		retval = ext2fs_namei(fs, root, cwd, name, &parent_ino);
		if (retval) {
			com_err(name, retval, 0);
			return retval;
		}
		name = cp+1;
	} else
		parent_ino = cwd;

try_again:
	retval = ext2fs_mkdir(fs, parent_ino, 0, name);
	if (retval == EXT2_ET_DIR_NO_SPACE) {
		retval = ext2fs_expand_dir(fs, parent_ino);
		if (retval) {
			com_err(__func__, retval, "while expanding directory");
			return retval;
		}
		goto try_again;
	}
	if (retval)
		com_err("ext2fs_mkdir", retval, 0);
	return retval;
}
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;
}
Beispiel #3
0
int do_readinode (ext2_filsys e2fs, const char *path, ext2_ino_t *ino, struct ext2_inode *inode)
{
	errcode_t rc;
	rc = ext2fs_namei(e2fs, EXT2_ROOT_INO, EXT2_ROOT_INO, path, ino);
	if (rc) {
		debugf("ext2fs_namei(e2fs, EXT2_ROOT_INO, EXT2_ROOT_INO, %s, ino); failed", path);
		return -ENOENT;
	}
	rc = ext2fs_read_inode(e2fs, *ino, inode);
	if (rc) {
		debugf("ext2fs_read_inode(e2fs, *ino, inode); failed");
		return -EIO;
	}
	return 0;
}
Beispiel #4
0
/*
 * This routine is used whenever a command needs to turn a string into
 * an inode.
 */
ext2_ino_t string_to_inode(char *str)
{
	ext2_ino_t	ino;
	int		len = strlen(str);
	char		*end;
	int		retval;

	/*
	 * If the string is of the form <ino>, then treat it as an
	 * inode number.
	 */
	if ((len > 2) && (str[0] == '<') && (str[len-1] == '>')) {
		ino = strtoul(str+1, &end, 0);
		if (*end=='>')
			return ino;
	}

	retval = ext2fs_namei(current_fs, root, cwd, str, &ino);
	if (retval) {
		com_err(str, retval, 0);
		return 0;
	}
	return ino;
}
Beispiel #5
0
/* Make a symlink name -> target */
errcode_t do_symlink_internal(ext2_filsys fs, ext2_ino_t cwd, const char *name,
			      char *target, ext2_ino_t root)
{
	char			*cp;
	ext2_ino_t		parent_ino;
	errcode_t		retval;
	struct ext2_inode	inode;
	struct stat		st;

	cp = strrchr(name, '/');
	if (cp) {
		*cp = 0;
		retval = ext2fs_namei(fs, root, cwd, name, &parent_ino);
		if (retval) {
			com_err(name, retval, 0);
			return retval;
		}
		name = cp+1;
	} else
		parent_ino = cwd;

try_again:
	retval = ext2fs_symlink(fs, parent_ino, 0, name, target);
	if (retval == EXT2_ET_DIR_NO_SPACE) {
		retval = ext2fs_expand_dir(fs, parent_ino);
		if (retval) {
			com_err("do_symlink_internal", retval,
				"while expanding directory");
			return retval;
		}
		goto try_again;
	}
	if (retval)
		com_err("ext2fs_symlink", retval, 0);
	return retval;
}
Beispiel #6
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);
}
Beispiel #7
0
Datei: ln.c Projekt: er13/e2tools
/* Name:	do_ln()
 *
 * Description:
 *
 * This function reads the command line arguments and creates a link
 * in an ext2fs file system
 *
 * Algorithm:
 *
 * Read any command line switches
 * Get the source file specification
 * Open the file system
 * Get the directory and basename of the source file
 * Determine the inode number for the source file
 * If the destination file is not given or if it's a .
 *     use the current directory and the basename of the source file
 * Otherwise
 *     Get the directory and basename of the destination file
 * Create the link
 *
 * Global Variables:
 *
 * None
 *
 * Arguments:
 *
 * int argc;             The number of arguments
 * char *argv[];         The command line arguments
 *
 * Return Values:
 *
 * 0 - the link was created successfully
 * an error occurred.
 *
 * Author: Keith W. Sheffield
 * Date:   03/05/2002
 *
 * Modification History:
 *
 * MM/DD/YY      Name               Description
 * 03/06/02      K. Sheffield       Modified to perform file moves
 * 03/20/02      K. Sheffield       Moved the mv operation to a separate file
 */
long
do_ln(int argc, char *argv[])
{
  int verbose=0;
  int force=0;
  int symlink=0;
  int errcnt=0;
  char *cur_filesys = NULL;
  ext2_filsys fs = NULL;
  ext2_ino_t root;
  ext2_ino_t srcd;
  ext2_ino_t destd;
  ext2_ino_t source_file;
  char *src_dir;
  char *dest_dir;
  char *src_name;
  char *dest_name;
  long retval;
  int c;

#ifdef HAVE_OPTRESET
  optreset = 1;		/* Makes BSD getopt happy */
#endif
  while ((c = getopt(argc, argv, "vfs")) != EOF)
    {
      switch (c)
        {
        case 'v':
          verbose = 1;
          break;
        case 'f':
          force = E2T_FORCE;
          break;
        case 's':
          symlink = 1;
          break;
        default:
          errcnt++;
          break;
        }
    }

  if (errcnt || argc == optind)
    {
      fputs(USAGE, stderr);
      return(1);
    }

  if (symlink)
    {
      fputs("Not implemented yet\n", stderr);
      return(1);
    }

  cur_filesys = argv[optind++];
  if (NULL == (src_dir = strchr(cur_filesys, ':')))
    {
      fprintf(stderr, "Invalid file specification: %s\n", cur_filesys);
      return(1);
    }
  *src_dir++ = '\0';

  if (*src_dir == '\0')
    {
      fputs(USAGE, stderr);
      return(1);
    }

  if ((retval = open_filesystem(cur_filesys, &fs, &root, 1)))
    {
      fprintf(stderr, "%s: %s\n", error_message(retval), cur_filesys);
      return retval;
    }

  /* move to the source directory */

  if (get_file_parts(fs, root, src_dir, &srcd, &src_dir, &src_name))
    {
      ext2fs_close(fs);
      return(-1);
    }

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

  /* get the destination directory */
  destd = root;
  if (argc == optind || strcmp(dest_dir = argv[optind], ".") == 0)
    dest_name = src_name;
  else
    {
      if (get_file_parts(fs, root, dest_dir, &destd, &dest_dir,
                         &dest_name))
        {
          ext2fs_close(fs);
          return(-1);
        }
    }

  /* now create the link */
  if ((retval = create_hard_link(fs, destd, source_file, dest_name, force)))
    {
      fprintf(stderr, "Error linking %s/%s as %s/%s\n",
              ((src_dir == NULL) ? "." : src_dir), src_name,
              ((dest_dir == NULL) ? "." : dest_dir), dest_name);
      ext2fs_close(fs);
      return(1);
    }

  if (verbose)
    fprintf(stderr, "linked %s/%s as %s/%s\n",
            ((src_dir == NULL) ? "." : src_dir), src_name,
            ((dest_dir == NULL) ? "." : dest_dir), dest_name);

  ext2fs_close(fs);
  return(0);

} /* end of do_ln */
Beispiel #8
0
Datei: ln.c Projekt: er13/e2tools
/* Name:	create_hard_link()
 *
 * Description:
 *
 * This function creates a hard link to an existing file
 *
 * Algorithm:
 *
 * Check input parameters
 * Check to see if the new file name already exists
 * Make sure the new file is not an existing directory
 * If the file exists, remove it if the del_current flag is set
 * Add the new file name and it's inode to the current directory.
 * Get the inode structure for the current inode number
 * update the number of links
 * Write the inode structure back out to the file system.
 *
 * Global Variables:
 *
 * None.
 *
 * Arguments:
 *
 * ext2_filsys fs;			  The current file system
 * ext2_ino_t cwd;			  The current working directory
 * ext2_ino_t new_file_ino;	  The inode number of the new file
 * char *newfile;			  The name of the new file
 * int ln_flags;			  Flags affecting hard_link action
 *
 * Return Values:
 *
 * 0 - the new file link was created successfully
 * any other value indicates an error
 *
 * Author: Keith W. Sheffield
 * Date:   03/05/2002
 *
 * Modification History:
 *
 * MM/DD/YY		 Name				Description
 * 06/30/02		 K.Sheffield		Directory link flag is now based on the
 *									type of file being linked.	This was
 *									causing problems if a directory was
 *									renamed.
 */
long
create_hard_link(ext2_filsys fs, ext2_ino_t cwd, ext2_ino_t new_file_ino,
                 char *newfile, int ln_flags)
{
  ext2_ino_t curr_ino;
  struct ext2_inode inode;
  long retval;
  int dir_flag;

  if (fs == NULL || newfile == NULL)
    {
      fputs("Invalid input parameter.  Exiting create_hard_link() with -1\n",
            stderr);
      return (-1);
    }

  /* check to see if the file name already exists in the current directory */
  if ((retval = ext2fs_namei(fs, cwd, cwd, newfile, &curr_ino)))
    {
      if (retval != EXT2_ET_FILE_NOT_FOUND)
        {
          fprintf(stderr, "%s\n",error_message(retval));
          return(retval);
        }

    }
  /* file name exists, let's see if is a directory */
  else if ((retval = ext2fs_check_directory(fs, curr_ino)))
    {
      if (retval != EXT2_ET_NO_DIRECTORY)
        {
          fprintf(stderr, "%s\n",error_message(retval));
          return(retval);
        }

      /* delete the existing file if needed */
      if ((ln_flags & E2T_FORCE) &&
          (curr_ino != new_file_ino))
        {
          if ((retval = rm_file(fs, cwd, newfile, curr_ino)))
            {
              fprintf(stderr, "%s\n",error_message(retval));
              return(retval);
            }
        }
      else
        {
          fprintf(stderr, "ln: %s: File exists\n", newfile);
          return(1);
        }
    }
  else
    {
    /* if we get here, then it's an existing directory */
      fprintf(stderr, "%s is a directory!\n", newfile);
      return(1);
    }

  /* read the inode associated with the file */
  if ((retval = read_inode(fs, new_file_ino, &inode)))
      {
      fprintf(stderr, "%s\n", error_message(retval));
      return (retval);
      }

  /* determine how to link into the directory based on the type of file */
  switch(inode.i_mode & LINUX_S_IFMT)
    {
    case LINUX_S_IFREG:
      dir_flag = EXT2_FT_REG_FILE;
      break;
    case LINUX_S_IFLNK:
      dir_flag = EXT2_FT_SYMLINK;
      break;
    case LINUX_S_IFDIR:
      dir_flag = EXT2_FT_DIR;
      break;
    case LINUX_S_IFSOCK:
      dir_flag = EXT2_FT_SOCK;
      break;
    case LINUX_S_IFBLK:
      dir_flag = EXT2_FT_BLKDEV;
      break;
    case LINUX_S_IFCHR:
      dir_flag = EXT2_FT_CHRDEV;
      break;
    case LINUX_S_IFIFO:
      dir_flag = EXT2_FT_FIFO;
      break;
    default:
      dir_flag = EXT2_FT_UNKNOWN;
      break;
    }


  if ((retval = ext2fs_link(fs, cwd, newfile, new_file_ino, dir_flag)))
    {
      /* check to see if we ran out of space in the directory */
      if (retval == EXT2_ET_DIR_NO_SPACE)
        {
          /* try resizing the directory and try again */
          if (0 == (retval = ext2fs_expand_dir(fs, cwd)))
            retval = ext2fs_link(fs, cwd, newfile, new_file_ino, dir_flag);
        }
      if (retval)
        {
          fprintf(stderr, "%s\n", error_message(retval));
          return retval;
        }
    }


  /* update the inode stat information */
  if ((ln_flags & E2T_DO_MV) == 0)
    {
      inode.i_links_count++;
      if ((retval = write_inode(fs, new_file_ino, &inode)))
        {
          fprintf(stderr, "%s\n", error_message(retval));
          return (retval);
        }
    }

  return(0);

} /* end of create_hard_link */
Beispiel #9
0
/* Name:    do_mv()
 *
 * Description:
 *
 * This function reads the command line arguments and moves or renames files
 * in an ext2fs file system
 *
 * Algorithm:
 *
 * Read any command line switches
 * Get the first source file specification
 * If we are performing a file swap, call do_swap()
 * Open the file system
 * Get the destination and determine if it is a directory
 *    If not, then get the destination's directory and basename
 *    Also check that the number of source files are no more than one
 * For each source file
 *    Get the directory and basename of the source file
 *    Determine the inode number for the source file
 *    Create the link
 *    Unlink the original source file.
 *
 * Global Variables:
 *
 * None
 *
 * Arguments:
 *
 * int argc;             The number of arguments
 * char *argv[];         The command line arguments
 *
 * Return Values:
 *
 * 0 - the file was move successfully
 * an error occurred.
 *
 * Author: Keith W. Sheffield
 * Date:   03/20/2002
 *
 * Modification History:
 *
 * MM/DD/YY      Name               Description
 */
long
do_mv(int argc, char *argv[])
{
  int verbose=0;
  int force=0;
  int swap_files=0;
  int errcnt=0;
  char *cur_filesys = NULL;
  ext2_filsys fs = NULL;
  ext2_ino_t root;
  ext2_ino_t srcd;
  ext2_ino_t destd;
  ext2_ino_t source_file;
  char *src_dir;
  char *dest_dir;
  char *src_name;
  char *dest_name;
  char *result_name;
  long retval;
  int c;
  int curidx;

#ifdef HAVE_OPTRESET
  optreset = 1;     /* Makes BSD getopt happy */
#endif
  while ((c = getopt(argc, argv, "vfs")) != EOF)
    {
      switch (c)
        {
        case 'v':
          verbose = 1;
          break;
        case 'f':
          force = E2T_FORCE;
          break;
        case 's':
          swap_files = 1;
          break;
        default:
          errcnt++;
          break;
        }
    }

  curidx = optind;

  force |= E2T_DO_MV;

  if (errcnt || argc < curidx+2)
    {
      fputs(USAGE, stderr);
      return(1);
    }

  if (swap_files)
    return(do_swap(force, verbose, curidx, argc, argv));

  cur_filesys = argv[curidx++];
  if (NULL == (src_dir = strchr(cur_filesys, ':')))
    {
      fprintf(stderr, "Invalid file specification: %s\n", cur_filesys);
      return(1);
    }
  *src_dir++ = '\0';

  if ((retval = open_filesystem(cur_filesys, &fs, &root, 1)))
    {
      return retval;
    }


  /* get the destination directory */
  dest_name = NULL;
  if (strcmp(dest_dir = argv[argc-1], ".") != 0)
    {
      /* check to see if the file name already exists in the current
       * directory  and also see if it is a directory.
       */
      if ((retval = ext2fs_namei(fs, root, root, dest_dir, &destd)) ||
          (retval = ext2fs_check_directory(fs, destd)))
        {
          if (retval != EXT2_ET_FILE_NOT_FOUND &&
              retval != EXT2_ET_NO_DIRECTORY)
            {
              fprintf(stderr, "%s\n",error_message(retval));
              ext2fs_close(fs);
              return(retval);
            }

          /* ok, so it's either not there or it's not a directory, so
           * get the real destination directory and file name.
           */
          if (curidx+1 < argc)
            {
              fprintf(stderr, "%s must be a directory!\n", dest_dir);
              ext2fs_close(fs);
              return(1);
            }

          if (get_file_parts(fs, root, dest_dir, &destd, &dest_dir,
                             &dest_name))
            {
              ext2fs_close(fs);
              return(-1);
            }
        }
      else                  /* we have a directory!!! */
        dest_name = NULL;
    }
  else
    {
      destd = root;
      dest_name = NULL;
    }

  do
    {
      /* move to the source directory */
      if (get_file_parts(fs, root, src_dir, &srcd, &src_dir, &src_name))
        {
          ext2fs_close(fs);
          return(-1);
        }

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

      result_name = (dest_name) ? dest_name : src_name;

      /* now create the link */
      if ((retval = create_hard_link(fs, destd, source_file, result_name,
                                     force)))
        {
          fprintf(stderr, "Error renaming %s/%s as %s/%s\n",
                  ((src_dir == NULL) ? "." : src_dir), src_name,
                  ((dest_dir == NULL) ? "." : dest_dir), result_name);
          ext2fs_close(fs);
          return(1);
        }

      if ((retval = ext2fs_unlink(fs, srcd, src_name, 0, 0)))
        {
          fprintf(stderr, "%s - %s\n", src_name, error_message(retval));
          ext2fs_close(fs);
          return(retval);
        }

      if (verbose)
        fprintf(stderr, "moved %s/%s as %s/%s\n",
                ((src_dir == NULL) ? "." : src_dir), src_name,
                ((dest_dir == NULL) ? "." : dest_dir), result_name);
      src_dir = argv[curidx++];
    }
  while (curidx < argc);

  ext2fs_close(fs);
  return(0);

} /* end of do_mv */
Beispiel #10
0
static long
do_swap(int force, int verbose, int curidx, int argc, char **argv)
{
  char *cur_filesys = NULL;
  ext2_filsys fs = NULL;
  ext2_ino_t root;
  ext2_ino_t file1_dirno;
  ext2_ino_t file2_dirno;
  ext2_ino_t file3_dirno;
  ext2_ino_t file1_no;
  ext2_ino_t file2_no;
  char *file1_dir;
  char *file2_dir;
  char *file3_dir;
  char *file1_name;
  char *file2_name;
  char *file3_name;
  long retval;

  if (curidx + 2 > argc)
    {
      fputs(USAGE, stderr);
      return(1);
    }

  cur_filesys = argv[curidx++];
  if (NULL == (file1_dir = strchr(cur_filesys, ':')))
    {
      fprintf(stderr, "Invalid file specification: %s\n", cur_filesys);
      return(1);
    }
  *file1_dir++ = '\0';

  if ((retval = open_filesystem(cur_filesys, &fs, &root, 1)))
    {
      return retval;
    }

  /* move to the file 1 directory */
  if (get_file_parts(fs, root, file1_dir, &file1_dirno, &file1_dir,
                     &file1_name))
    {
      ext2fs_close(fs);
      return(-1);
    }

  /* get the inode number for the file 1 file */
  if ((retval = ext2fs_namei(fs, file1_dirno, file1_dirno, file1_name,
                             &file1_no)))
    {
      fprintf(stderr, "%s: file 1 file %s\n",error_message(retval),
              file1_name);
      ext2fs_close(fs);
      return(retval);
    }


  /* move to the file 2 directory */
  if (get_file_parts(fs, root, argv[curidx++], &file2_dirno, &file2_dir,
                     &file2_name))
    {
      ext2fs_close(fs);
      return(-1);
    }

  /* get the inode number for the file 2 file */
  if ((retval = ext2fs_namei(fs, file2_dirno, file2_dirno, file2_name,
                             &file2_no)))
    {
      fprintf(stderr, "%s: file 2 file %s\n",error_message(retval),
              file2_name);
      ext2fs_close(fs);
      return(retval);
    }

  if (curidx < argc)
    {
      /* move to the file 3 directory */
      if (get_file_parts(fs, root, argv[curidx++], &file3_dirno, &file3_dir,
                         &file3_name))
        {
          ext2fs_close(fs);
          return(-1);
        }

      /* now move the first file to the 3rd */
      if ((retval = create_hard_link(fs, file3_dirno, file1_no, file3_name,
                                     force)))
        {
          fprintf(stderr, "Error renaming %s/%s as %s/%s\n",
                  ((file1_dir == NULL) ? "." : file1_dir), file1_name,
                  ((file3_dir == NULL) ? "." : file3_dir), file3_name);
          ext2fs_close(fs);
          return(1);
        }

      if ((retval = ext2fs_unlink(fs, file1_dirno, file1_name, 0, 0)))
        {
          fprintf(stderr, "%s - %s\n", file1_name, error_message(retval));
          ext2fs_close(fs);
          return(retval);
        }


      /* now move the 2nd file to the 1st */
      if ((retval = create_hard_link(fs, file1_dirno, file2_no, file1_name,
                                     force)))
        {
          fprintf(stderr, "Error renaming %s/%s as %s/%s\n",
                  ((file2_dir == NULL) ? "." : file2_dir), file2_name,
                  ((file1_dir == NULL) ? "." : file1_dir), file1_name);
          ext2fs_close(fs);
          return(1);
        }

      if ((retval = ext2fs_unlink(fs, file2_dirno, file2_name, 0, 0)))
        {
          fprintf(stderr, "%s - %s\n", file2_name, error_message(retval));
          ext2fs_close(fs);
          return(retval);
        }

      if (verbose)
        fprintf(stderr, "renamed file %s/%s as %s/%s\n"
                "renamed file %s/%s as %s/%s\n",
                ((file1_dir == NULL) ? "." : file1_dir), file1_name,
                ((file3_dir == NULL) ? "." : file3_dir), file3_name,
                ((file2_dir == NULL) ? "." : file2_dir), file2_name,
                ((file1_dir == NULL) ? "." : file1_dir), file1_name);
    }
  else
    {
      /* now remove the first file */
      if ((retval = ext2fs_unlink(fs, file1_dirno, file1_name, 0, 0)))
        {
          fprintf(stderr, "%s - %s\n", file1_name, error_message(retval));
          ext2fs_close(fs);
          return(retval);
        }

      /* now move the 2nd file to the 1st */
      if ((retval = create_hard_link(fs, file1_dirno, file2_no, file1_name,
                                     force)))
        {
          fprintf(stderr, "Error renaming %s/%s as %s/%s\n",
                  ((file2_dir == NULL) ? "." : file2_dir), file2_name,
                  ((file1_dir == NULL) ? "." : file1_dir), file1_name);
          ext2fs_close(fs);
          return(1);
        }

      if ((retval = ext2fs_unlink(fs, file2_dirno, file2_name, 0, 0)))
        {
          fprintf(stderr, "%s - %s\n", file2_name, error_message(retval));
          ext2fs_close(fs);
          return(retval);
        }

      if ((retval = create_hard_link(fs, file2_dirno, file1_no, file2_name,
                                     force)))
          {
          fprintf(stderr, "Error renaming %s/%s as %s/%s\n",
                  ((file1_dir == NULL) ? "." : file1_dir), file1_name,
                  ((file2_dir == NULL) ? "." : file2_dir), file2_name);
          ext2fs_close(fs);
          return(1);
        }

      if (verbose)
        fprintf(stderr, "swapped files %s/%s <-> %s/%s\n",
                ((file1_dir == NULL) ? "." : file1_dir), file1_name,
                ((file2_dir == NULL) ? "." : file2_dir), file2_name);

    }

  ext2fs_close(fs);
  return(0);

} /* end of do_swap */
Beispiel #11
0
/* Copy files from source_dir to fs */
static errcode_t __populate_fs(ext2_filsys fs, ext2_ino_t parent_ino,
			       const char *source_dir, ext2_ino_t root,
			       struct hdlinks_s *hdlinks)
{
	const char	*name;
	DIR		*dh;
	struct dirent	*dent;
	struct stat	st;
	char		ln_target[PATH_MAX];
	unsigned int	save_inode;
	ext2_ino_t	ino;
	errcode_t	retval = 0;
	int		read_cnt;
	int		hdlink;

	if (chdir(source_dir) < 0) {
		com_err(__func__, errno,
			_("while changing working directory to \"%s\""),
			source_dir);
		return errno;
	}

	if (!(dh = opendir("."))) {
		com_err(__func__, errno,
			_("while opening directory \"%s\""), source_dir);
		return errno;
	}

	while ((dent = readdir(dh))) {
		if ((!strcmp(dent->d_name, ".")) ||
		    (!strcmp(dent->d_name, "..")))
			continue;
		if (lstat(dent->d_name, &st)) {
			com_err(__func__, errno, _("while lstat \"%s\""),
				dent->d_name);
			goto out;
		}
		name = dent->d_name;

		/* Check for hardlinks */
		save_inode = 0;
		if (!S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode) &&
		    st.st_nlink > 1) {
			hdlink = is_hardlink(hdlinks, st.st_dev, st.st_ino);
			if (hdlink >= 0) {
				retval = add_link(fs, parent_ino,
						  hdlinks->hdl[hdlink].dst_ino,
						  name);
				if (retval) {
					com_err(__func__, retval,
						"while linking %s", name);
					goto out;
				}
				continue;
			} else
				save_inode = 1;
		}

		switch(st.st_mode & S_IFMT) {
		case S_IFCHR:
		case S_IFBLK:
		case S_IFIFO:
		case S_IFSOCK:
			retval = do_mknod_internal(fs, parent_ino, name, &st);
			if (retval) {
				com_err(__func__, retval,
					_("while creating special file "
					  "\"%s\""), name);
				goto out;
			}
			break;
		case S_IFLNK:
			read_cnt = readlink(name, ln_target,
					    sizeof(ln_target) - 1);
			if (read_cnt == -1) {
				com_err(__func__, errno,
					_("while trying to readlink \"%s\""),
					name);
				retval = errno;
				goto out;
			}
			ln_target[read_cnt] = '\0';
			retval = do_symlink_internal(fs, parent_ino, name,
						     ln_target, root);
			if (retval) {
				com_err(__func__, retval,
					_("while writing symlink\"%s\""),
					name);
				goto out;
			}
			break;
		case S_IFREG:
			retval = do_write_internal(fs, parent_ino, name, name,
						   root);
			if (retval) {
				com_err(__func__, retval,
					_("while writing file \"%s\""), name);
				goto out;
			}
			break;
		case S_IFDIR:
			retval = do_mkdir_internal(fs, parent_ino, name, &st,
						   root);
			if (retval) {
				com_err(__func__, retval,
					_("while making dir \"%s\""), name);
				goto out;
			}
			retval = ext2fs_namei(fs, root, parent_ino,
					      name, &ino);
			if (retval) {
				com_err(name, retval, 0);
					goto out;
			}
			/* Populate the dir recursively*/
			retval = __populate_fs(fs, ino, name, root, hdlinks);
			if (retval) {
				com_err(__func__, retval,
					_("while adding dir \"%s\""), name);
				goto out;
			}
			if (chdir("..")) {
				com_err(__func__, errno, _("during cd .."));
				retval = errno;
				goto out;
			}
			break;
		default:
			com_err(__func__, 0,
				_("ignoring entry \"%s\""), name);
		}

		retval =  ext2fs_namei(fs, root, parent_ino, name, &ino);
		if (retval) {
			com_err(name, retval, 0);
			goto out;
		}

		retval = set_inode_extra(fs, parent_ino, ino, &st);
		if (retval) {
			com_err(__func__, retval,
				_("while setting inode for \"%s\""), name);
			goto out;
		}

		retval = set_inode_xattr(fs, ino, name);
		if (retval) {
			com_err(__func__, retval,
				_("while setting xattrs for \"%s\""), name);
			goto out;
		}

		/* Save the hardlink ino */
		if (save_inode) {
			/*
			 * Check whether need more memory, and we don't need
			 * free() since the lifespan will be over after the fs
			 * populated.
			 */
			if (hdlinks->count == hdlinks->size) {
				void *p = realloc(hdlinks->hdl,
						(hdlinks->size + HDLINK_CNT) *
						sizeof(struct hdlink_s));
				if (p == NULL) {
					com_err(name, errno,
						_("Not enough memory"));
					retval = EXT2_ET_NO_MEMORY;
					goto out;
				}
				hdlinks->hdl = p;
				hdlinks->size += HDLINK_CNT;
			}
			hdlinks->hdl[hdlinks->count].src_dev = st.st_dev;
			hdlinks->hdl[hdlinks->count].src_ino = st.st_ino;
			hdlinks->hdl[hdlinks->count].dst_ino = ino;
			hdlinks->count++;
		}
	}

out:
	closedir(dh);
	return retval;
}
Beispiel #12
0
/* Copy the native file to the fs */
errcode_t do_write_internal(ext2_filsys fs, ext2_ino_t cwd, const char *src,
			    const char *dest, ext2_ino_t root)
{
	int		fd;
	struct stat	statbuf;
	ext2_ino_t	newfile;
	errcode_t	retval;
	struct ext2_inode inode;
	int		bufsize = IO_BUFSIZE;
	int		make_holes = 0;

	fd = ext2fs_open_file(src, O_RDONLY, 0);
	if (fd < 0) {
		com_err(src, errno, 0);
		return errno;
	}
	if (fstat(fd, &statbuf) < 0) {
		com_err(src, errno, 0);
		close(fd);
		return errno;
	}

	retval = ext2fs_namei(fs, root, cwd, dest, &newfile);
	if (retval == 0) {
		close(fd);
		return EXT2_ET_FILE_EXISTS;
	}

	retval = ext2fs_new_inode(fs, cwd, 010755, 0, &newfile);
	if (retval) {
		com_err(__func__, retval, 0);
		close(fd);
		return retval;
	}
#ifdef DEBUGFS
	printf("Allocated inode: %u\n", newfile);
#endif
	retval = ext2fs_link(fs, cwd, dest, newfile,
				EXT2_FT_REG_FILE);
	if (retval == EXT2_ET_DIR_NO_SPACE) {
		retval = ext2fs_expand_dir(fs, cwd);
		if (retval) {
			com_err(__func__, retval, "while expanding directory");
			close(fd);
			return retval;
		}
		retval = ext2fs_link(fs, cwd, dest, newfile,
					EXT2_FT_REG_FILE);
	}
	if (retval) {
		com_err(dest, retval, 0);
		close(fd);
		return errno;
	}
	if (ext2fs_test_inode_bitmap2(fs->inode_map, newfile))
		com_err(__func__, 0, "Warning: inode already set");
	ext2fs_inode_alloc_stats2(fs, newfile, +1, 0);
	memset(&inode, 0, sizeof(inode));
	inode.i_mode = (statbuf.st_mode & ~LINUX_S_IFMT) | LINUX_S_IFREG;
	inode.i_atime = inode.i_ctime = inode.i_mtime =
		fs->now ? fs->now : time(0);
	inode.i_links_count = 1;
	retval = ext2fs_inode_size_set(fs, &inode, statbuf.st_size);
	if (retval) {
		com_err(dest, retval, 0);
		close(fd);
		return retval;
	}
	if (EXT2_HAS_INCOMPAT_FEATURE(fs->super,
				      EXT4_FEATURE_INCOMPAT_INLINE_DATA)) {
		inode.i_flags |= EXT4_INLINE_DATA_FL;
	} else if (fs->super->s_feature_incompat &
		   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;
	}

	retval = ext2fs_write_new_inode(fs, newfile, &inode);
	if (retval) {
		com_err(__func__, retval, "while creating inode %u", newfile);
		close(fd);
		return retval;
	}
	if (inode.i_flags & EXT4_INLINE_DATA_FL) {
		retval = ext2fs_inline_data_init(fs, newfile);
		if (retval) {
			com_err("copy_file", retval, 0);
			close(fd);
			return retval;
		}
	}
	if (LINUX_S_ISREG(inode.i_mode)) {
		if (statbuf.st_blocks < statbuf.st_size / S_BLKSIZE) {
			make_holes = 1;
			/*
			 * Use I/O blocksize as buffer size when
			 * copying sparse files.
			 */
			bufsize = statbuf.st_blksize;
		}
		retval = copy_file(fs, fd, newfile, bufsize, make_holes);
		if (retval)
			com_err("copy_file", retval, 0);
	}
	close(fd);

	return retval;
}