Beispiel #1
0
int
run_edit (const char *cmd, size_t argc, char *argv[])
{
  const char *editor;
  CLEANUP_FREE char *remotefilename = NULL;
  int r;

  if (argc != 1) {
    fprintf (stderr, _("use '%s filename' to edit a file\n"), cmd);
    return -1;
  }

  /* Choose an editor. */
  if (STRCASEEQ (cmd, "vi"))
    editor = "vi";
  else if (STRCASEEQ (cmd, "emacs"))
    editor = "emacs -nw";
  else
    editor = NULL; /* use $EDITOR */

  /* Handle 'win:...' prefix. */
  remotefilename = win_prefix (argv[0]);
  if (remotefilename == NULL)
    return -1;

  r = edit_file_editor (g, remotefilename, editor, NULL, 0 /* not verbose */);

  return r == -1 ? -1 : 0;
}
Beispiel #2
0
int
run_copy_out (const char *cmd, size_t argc, char *argv[])
{
  if (argc < 2) {
    fprintf (stderr,
             _("use 'copy-out <remote> [<remote>...] <localdir>' to copy files out of the image\n"));
    return -1;
  }

  /* Local directory is always the last arg. */
  const char *local = argv[argc-1];
  const int nr_remotes = argc-1;

  /* Download each remote one at a time using copy-out. */
  int i, r;
  for (i = 0; i < nr_remotes; ++i) {
    CLEANUP_FREE char *remote = NULL;

    /* Allow win:... prefix on remotes. */
    remote = win_prefix (argv[i]);
    if (remote == NULL)
      return -1;

    r = guestfs_copy_out (g, remote, local);
    if (r == -1)
      return -1;
  }

  return 0;
}
Beispiel #3
0
int
run_copy_in (const char *cmd, size_t argc, char *argv[])
{
  CLEANUP_FREE char *remote = NULL;

  if (argc < 2) {
    fprintf (stderr,
             _("use 'copy-in <local> [<local>...] <remotedir>' to copy files into the image\n"));
    return -1;
  }

  /* Remote directory is always the last arg.
   * Allow "win:" prefix on remote.
   */
  remote = win_prefix (argv[argc-1]);
  if (remote == NULL)
    return -1;

  const int nr_locals = argc-1;

  /* Upload each local one at a time using copy-in. */
  int i;
  for (i = 0; i < nr_locals; ++i) {
    int r = guestfs_copy_in (g, argv[i], remote);
    if (r == -1)
      return -1;
  }

  return 0;
}
Beispiel #4
0
int
run_copy_in (const char *cmd, size_t argc, char *argv[])
{
    if (argc < 2) {
        fprintf (stderr,
                 _("use 'copy-in <local> [<local>...] <remotedir>' to copy files into the image\n"));
        return -1;
    }

    /* Remote directory is always the last arg. */
    char *remote = argv[argc-1];

    /* Allow win: prefix on remote. */
    remote = win_prefix (remote);
    if (remote == NULL)
        return -1;

    int nr_locals = argc-1;

    int remote_is_dir = guestfs_is_dir (g, remote);
    if (remote_is_dir == -1) {
        free (remote);
        return -1;
    }

    if (!remote_is_dir) {
        fprintf (stderr, _("copy-in: target '%s' is not a directory\n"), remote);
        free (remote);
        return -1;
    }

    /* Upload each local one at a time using tar-in. */
    int i;
    for (i = 0; i < nr_locals; ++i) {
        struct fd_pid fdpid = make_tar_from_local (argv[i]);
        if (fdpid.fd == -1) {
            free (remote);
            return -1;
        }

        char fdbuf[64];
        snprintf (fdbuf, sizeof fdbuf, "/dev/fd/%d", fdpid.fd);

        int r = guestfs_tar_in (g, fdbuf, remote);

        if (close (fdpid.fd) == -1) {
            perror ("close (tar-from-local subprocess)");
            r = -1;
        }

        int status;
        if (waitpid (fdpid.pid, &status, 0) == -1) {
            perror ("wait (tar-from-local subprocess)");
            free (remote);
            return -1;
        }
        if (!(WIFEXITED (status) && WEXITSTATUS (status) == 0)) {
            free (remote);
            return -1;
        }

        if (r == -1) {
            free (remote);
            return -1;
        }
    }

    free (remote);

    return 0;
}
Beispiel #5
0
int
run_copy_out (const char *cmd, size_t argc, char *argv[])
{
    if (argc < 2) {
        fprintf (stderr,
                 _("use 'copy-out <remote> [<remote>...] <localdir>' to copy files out of the image\n"));
        return -1;
    }

    /* Local directory is always the last arg. */
    const char *local = argv[argc-1];
    int nr_remotes = argc-1;

    struct stat statbuf;
    if (stat (local, &statbuf) == -1 ||
            ! (S_ISDIR (statbuf.st_mode))) {
        fprintf (stderr, _("copy-out: target '%s' is not a directory\n"), local);
        return -1;
    }

    /* Download each remote one at a time using tar-out. */
    int i, r;
    for (i = 0; i < nr_remotes; ++i) {
        char *remote = argv[i];

        /* Allow win:... prefix on remotes. */
        remote = win_prefix (remote);
        if (remote == NULL)
            return -1;

        /* If the remote is a file, download it.  If it's a directory,
         * create the directory in local first before using tar-out.
         */
        r = guestfs_is_file (g, remote);
        if (r == -1) {
            free (remote);
            return -1;
        }
        if (r == 1) {               /* is file */
            char buf[PATH_MAX];
            const char *basename;
            if (split_path (buf, sizeof buf, remote, NULL, &basename) == -1) {
                free (remote);
                return -1;
            }

            char filename[PATH_MAX];
            snprintf (filename, sizeof filename, "%s/%s", local, basename);
            if (guestfs_download (g, remote, filename) == -1) {
                free (remote);
                return -1;
            }
        }
        else {                      /* not a regular file */
            r = guestfs_is_dir (g, remote);
            if (r == -1) {
                free (remote);
                return -1;
            }

            if (r == 0) {
                fprintf (stderr, _("copy-out: '%s' is not a file or directory\n"),
                         remote);
                free (remote);
                return -1;
            }

            char buf[PATH_MAX];
            const char *basename;
            if (split_path (buf, sizeof buf, remote, NULL, &basename) == -1) {
                free (remote);
                return -1;
            }

            struct fd_pid fdpid = make_tar_output (local, basename);
            if (fdpid.fd == -1) {
                free (remote);
                return -1;
            }

            char fdbuf[64];
            snprintf (fdbuf, sizeof fdbuf, "/dev/fd/%d", fdpid.fd);

            int r = guestfs_tar_out (g, remote, fdbuf);

            if (close (fdpid.fd) == -1) {
                perror ("close (tar-output subprocess)");
                free (remote);
                r = -1;
            }

            int status;
            if (waitpid (fdpid.pid, &status, 0) == -1) {
                perror ("wait (tar-output subprocess)");
                free (remote);
                return -1;
            }
            if (!(WIFEXITED (status) && WEXITSTATUS (status) == 0)) {
                free (remote);
                return -1;
            }

            if (r == -1) {
                free (remote);
                return -1;
            }
        }

        free (remote);
    }

    return 0;
}
Beispiel #6
0
int
run_edit (const char *cmd, size_t argc, char *argv[])
{
  CLEANUP_FREE char *tmpdir = guestfs_get_tmpdir (g);
  CLEANUP_UNLINK_FREE char *filename = NULL;
  char buf[256];
  const char *editor;
  CLEANUP_FREE char *remotefilename = NULL, *newname = NULL;
  struct stat oldstat, newstat;
  int r, fd;

  if (argc != 1) {
    fprintf (stderr, _("use '%s filename' to edit a file\n"), cmd);
    return -1;
  }

  /* Choose an editor. */
  if (STRCASEEQ (cmd, "vi"))
    editor = "vi";
  else if (STRCASEEQ (cmd, "emacs"))
    editor = "emacs -nw";
  else {
    editor = getenv ("EDITOR");
    if (editor == NULL)
      editor = "vi"; /* could be cruel here and choose ed(1) */
  }

  /* Handle 'win:...' prefix. */
  remotefilename = win_prefix (argv[0]);
  if (remotefilename == NULL)
    return -1;

  /* Download the file and write it to a temporary. */
  if (asprintf (&filename, "%s/guestfishXXXXXX", tmpdir) == -1) {
    perror ("asprintf");
    return -1;
  }

  fd = mkstemp (filename);
  if (fd == -1) {
    perror ("mkstemp");
    return -1;
  }

  snprintf (buf, sizeof buf, "/dev/fd/%d", fd);

  if (guestfs_download (g, remotefilename, buf) == -1) {
    close (fd);
    return -1;
  }

  if (close (fd) == -1) {
    perror (filename);
    return -1;
  }

  /* Get the old stat. */
  if (stat (filename, &oldstat) == -1) {
    perror (filename);
    return -1;
  }

  /* Edit it. */
  /* XXX Safe? */
  snprintf (buf, sizeof buf, "%s %s", editor, filename);

  r = system (buf);
  if (r != 0) {
    perror (buf);
    return -1;
  }

  /* Get the new stat. */
  if (stat (filename, &newstat) == -1) {
    perror (filename);
    return -1;
  }

  /* Changed? */
  if (oldstat.st_ctime == newstat.st_ctime &&
      oldstat.st_size == newstat.st_size)
    return 0;

  /* Upload to a new file in the same directory, so if it fails we
   * don't end up with a partially written file.  Give the new file
   * a completely random name so we have only a tiny chance of
   * overwriting some existing file.
   */
  newname = generate_random_name (remotefilename);
  if (!newname)
    return -1;

  /* Write new content. */
  if (guestfs_upload (g, filename, newname) == -1)
    return -1;

  /* Set the permissions, UID, GID and SELinux context of the new
   * file to match the old file (RHBZ#788641).
   */
  if (guestfs_copy_attributes (g, remotefilename, newname,
      GUESTFS_COPY_ATTRIBUTES_ALL, 1, -1) == -1)
    return -1;

  if (guestfs_mv (g, newname, remotefilename) == -1)
    return -1;

  return 0;
}
Beispiel #7
0
int
run_more (const char *cmd, size_t argc, char *argv[])
{
  CLEANUP_FREE char *tmpdir = guestfs_get_tmpdir (g);
  CLEANUP_UNLINK_FREE char *filename = NULL;
  char buf[256];
  CLEANUP_FREE char *remote = NULL;
  const char *pager;
  int r, fd;

  if (argc != 1) {
    fprintf (stderr, _("use '%s filename' to page a file\n"), cmd);
    return -1;
  }

  /* Choose a pager. */
  if (STRCASEEQ (cmd, "less"))
    pager = "less";
  else {
    pager = getenv ("PAGER");
    if (pager == NULL)
      pager = "more";
  }

  /* Allow win:... prefix on remote. */
  remote = win_prefix (argv[0]);
  if (remote == NULL)
    return -1;

  /* Download the file and write it to a temporary. */
  if (asprintf (&filename, "%s/guestfishXXXXXX", tmpdir) == -1) {
    perror ("asprintf");
    return -1;
  }

  fd = mkstemp (filename);
  if (fd == -1) {
    perror ("mkstemp");
    return -1;
  }

  snprintf (buf, sizeof buf, "/dev/fd/%d", fd);

  if (guestfs_download (g, remote, buf) == -1) {
    close (fd);
    return -1;
  }

  if (close (fd) == -1) {
    perror (filename);
    return -1;
  }

  /* View it. */
  /* XXX Safe? */
  snprintf (buf, sizeof buf, "%s %s", pager, filename);

  r = system (buf);
  if (r != 0) {
    perror (buf);
    return -1;
  }

  return 0;
}
Beispiel #8
0
int
run_more (const char *cmd, size_t argc, char *argv[])
{
  TMP_TEMPLATE_ON_STACK (filename);
  char buf[256];
  char *remote;
  const char *pager;
  int r, fd;

  if (argc != 1) {
    fprintf (stderr, _("use '%s filename' to page a file\n"), cmd);
    return -1;
  }

  /* Choose a pager. */
  if (STRCASEEQ (cmd, "less"))
    pager = "less";
  else {
    pager = getenv ("PAGER");
    if (pager == NULL)
      pager = "more";
  }

  remote = argv[0];

  /* Allow win:... prefix on remote. */
  remote = win_prefix (remote);
  if (remote == NULL)
    return -1;

  /* Download the file and write it to a temporary. */
  fd = mkstemp (filename);
  if (fd == -1) {
    perror ("mkstemp");
    free (remote);
    return -1;
  }

  snprintf (buf, sizeof buf, "/dev/fd/%d", fd);

  if (guestfs_download (g, remote, buf) == -1) {
    close (fd);
    unlink (filename);
    free (remote);
    return -1;
  }

  if (close (fd) == -1) {
    perror (filename);
    unlink (filename);
    free (remote);
    return -1;
  }

  /* View it. */
  /* XXX Safe? */
  snprintf (buf, sizeof buf, "%s %s", pager, filename);

  r = system (buf);
  unlink (filename);
  if (r != 0) {
    perror (buf);
    free (remote);
    return -1;
  }

  free (remote);
  return 0;
}
Beispiel #9
0
int
run_display (const char *cmd, size_t argc, char *argv[])
{
  TMP_TEMPLATE_ON_STACK (filename);
  char *remote;
  const char *display;
  char buf[256];
  int r, fd;

  if (argc != 1) {
    fprintf (stderr, _("display filename\n"));
    return -1;
  }

  /* Choose a display command. */
  display = getenv ("GUESTFISH_DISPLAY_IMAGE");
  if (display == NULL)
    display = "display";

  remote = argv[0];

  /* Allow win:... prefix on remote. */
  remote = win_prefix (remote);
  if (remote == NULL)
    return -1;

  /* Download the file and write it to a temporary. */
  fd = mkstemp (filename);
  if (fd == -1) {
    perror ("mkstemp");
    free (remote);
    return -1;
  }

  snprintf (buf, sizeof buf, "/dev/fd/%d", fd);

  if (guestfs_download (g, remote, buf) == -1) {
    close (fd);
    unlink (filename);
    free (remote);
    return -1;
  }

  if (close (fd) == -1) {
    perror (filename);
    unlink (filename);
    free (remote);
    return -1;
  }

  /* View it. */
  snprintf (buf, sizeof buf, "%s %s", display, filename);

  r = system (buf);
  unlink (filename);
  if (r != 0) {
    perror (buf);
    free (remote);
    return -1;
  }

  free (remote);
  return 0;
}
Beispiel #10
0
int
run_display (const char *cmd, size_t argc, char *argv[])
{
  CLEANUP_FREE char *tmpdir = guestfs_get_tmpdir (g), *filename = NULL;
  CLEANUP_FREE char *remote = NULL;
  const char *display;
  char buf[256];
  int r, fd;

  if (argc != 1) {
    fprintf (stderr, _("display filename\n"));
    return -1;
  }

  /* Choose a display command. */
  display = getenv ("GUESTFISH_DISPLAY_IMAGE");
  if (display == NULL)
    display = "display";

  /* Allow win:... prefix on remote. */
  remote = win_prefix (argv[0]);
  if (remote == NULL)
    return -1;

  /* Download the file and write it to a temporary. */
  if (asprintf (&filename, "%s/guestfishXXXXXX", tmpdir) == -1) {
    perror ("asprintf");
    return -1;
  }

  fd = mkstemp (filename);
  if (fd == -1) {
    perror ("mkstemp");
    return -1;
  }

  snprintf (buf, sizeof buf, "/dev/fd/%d", fd);

  if (guestfs_download (g, remote, buf) == -1) {
    close (fd);
    unlink (filename);
    return -1;
  }

  if (close (fd) == -1) {
    perror (filename);
    unlink (filename);
    return -1;
  }

  /* View it. */
  snprintf (buf, sizeof buf, "%s %s", display, filename);

  r = system (buf);
  unlink (filename);
  if (r != 0) {
    perror (buf);
    return -1;
  }

  return 0;
}