Beispiel #1
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 #2
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 #3
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 #4
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 */