示例#1
0
/* External command failed. */
void
guestfs_int_external_command_failed (guestfs_h *g, int status,
				     const char *cmd_name, const char *extra)
{
  size_t len = 80 + strlen (cmd_name);
  char status_string[len];

  guestfs_int_exit_status_to_string (status, cmd_name, status_string, len);

  if (g->verbose) {
    if (!extra)
      error (g, _("%s, see debug messages above"), status_string);
    else
      error (g, _("%s: %s: %s, see debug messages above"),
             cmd_name, extra, status_string);
  }
  else {
    if (!extra)
      error (g, _(
		  "%s.\n"
		  "To see full error messages you may need to enable debugging.\n"
		  DEBUG_ADVICE),
             status_string);
    else
      error (g, _(
		  "%s: %s: %s.\n"
		  "To see full error messages you may need to enable debugging.\n"
		  DEBUG_ADVICE),
             cmd_name, extra, status_string);
  }
}
示例#2
0
/* For Windows >= Vista, if evtxdump.py is installed then we can
 * use it to dump the System.evtx log.
 */
static int
do_log_windows_evtx (void)
{
  CLEANUP_FREE char *filename = NULL;
  CLEANUP_FREE char *tmpdir = guestfs_get_tmpdir (g);
  CLEANUP_UNLINK_FREE char *localfile = NULL;
  CLEANUP_FREE char *cmd = NULL;
  char dev_fd[64];
  int fd, status;

  if (system ("evtxdump.py -h >/dev/null 2>&1") != 0) {
    fprintf (stderr, _("%s: you need to install 'evtxdump.py' (from the python-evtx package)\n"
                       "in order to parse Windows Event Logs.  If you cannot install this, then\n"
                       "use virt-copy-out(1) to copy the contents of /Windows/System32/winevt/Logs\n"
                       "from this guest, and examine in a binary file viewer.\n"),
             guestfs_int_program_name);
    return -1;
  }

  /* Check if System.evtx exists.  XXX Allow the filename to be
   * configurable, since there are many logs.
   */
  filename = guestfs_case_sensitive_path (g, "/Windows/System32/winevt/Logs/System.evtx");
  if (filename == NULL)
    return -1;

  /* Note that guestfs_case_sensitive_path does NOT check for existence. */
  if (guestfs_is_file_opts (g, filename,
                            GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1,
                            -1) <= 0) {
    fprintf (stderr, _("%s: Windows Event Log file (%s) not found\n"),
             guestfs_int_program_name, filename);
    return -1;
  }

  /* Download the file to a temporary.  Python-evtx wants to mmap
   * the file so we cannot use a pipe.
   */
  if (asprintf (&localfile, "%s/virtlogXXXXXX", tmpdir) == -1) {
    perror ("asprintf");
    return -1;
  }
  if ((fd = mkstemp (localfile)) == -1) {
    perror ("mkstemp");
    return -1;
  }

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

  if (guestfs_download (g, filename, dev_fd) == -1)
    return -1;
  close (fd);

  /* This should be safe as long as $TMPDIR is not set to something wild. */
  if (asprintf (&cmd, "evtxdump.py '%s'", localfile) == -1) {
    perror ("asprintf");
    return -1;
  }

  status = system (cmd);
  if (status) {
    char buf[256];
    fprintf (stderr, "%s: %s\n",
             guestfs_int_program_name,
             guestfs_int_exit_status_to_string (status, "evtxdump.py",
                                                buf, sizeof buf));
    return -1;
  }

  return 0;
}
示例#3
0
int
main (int argc, char *argv[])
{
  char *skip;
  int pipefd[2];
  pid_t pid;
  int r, status;

  /* Allow the test to be skipped. */
  skip = getenv ("SKIP_TEST_FUSE_SH");
  if (skip && guestfs_int_is_true (skip) > 0)
    error (77, 0, "test skipped because environment variable set");

  skip = getenv ("SKIP_TEST_GUESTUNMOUNT_FD");
  if (skip && guestfs_int_is_true (skip) > 0)
    error (77, 0, "test skipped because environment variable set");

  /* Create the pipe. */
  if (pipe (pipefd) == -1)
    error (EXIT_FAILURE, errno, "pipe");

  /* Create the guestunmount subprocess. */
  pid = fork ();
  if (pid == -1)
    error (EXIT_FAILURE, errno, "fork");

  if (pid == 0) {               /* child - guestunmount */
    char fd_str[64];

    close (pipefd[1]);

    snprintf (fd_str, sizeof fd_str, "%d", pipefd[0]);

    execlp ("guestunmount", "guestunmount", "--fd", fd_str, "/", NULL);
    perror ("execlp");
    _exit (EXIT_FAILURE);
  }

  /* Parent continues. */
  close (pipefd[0]);
  ignore_value (fcntl (pipefd[1], F_SETFD, FD_CLOEXEC));

  /* Sleep a bit and test that the guestunmount process is still running. */
  sleep (2);

  r = waitpid (pid, &status, WNOHANG);
  if (r == -1)
    error (EXIT_FAILURE, errno, "waitpid");
  if (r != 0) {
    char status_string[80];

    error (EXIT_FAILURE, 0,
           "test failed: %s",
           guestfs_int_exit_status_to_string (r, "guestunmount",
                                              status_string,
                                              sizeof status_string));
  }

  /* Close the write side of the pipe.  This should cause guestunmount
   * to exit.  It should exit with status code _3_ because we gave it
   * a directory which isn't a FUSE mountpoint.
   */
  close (pipefd[1]);

  r = waitpid (pid, &status, 0);
  if (r == -1)
    error (EXIT_FAILURE, errno, "waitpid");
  if (!WIFEXITED (status) || WEXITSTATUS (status) != 3) {
    char status_string[80];

    error (EXIT_FAILURE, 0,
           "test failed: guestunmount didn't return status code 3; %s",
           guestfs_int_exit_status_to_string (status, "guestunmount",
                                              status_string,
                                              sizeof status_string));
  }

  exit (EXIT_SUCCESS);
}
示例#4
0
int
main (int argc, char *argv[])
{
  char *skip;
  int pipefd[2];
  pid_t pid;
  char c;
  int r, status;

  /* Allow the test to be skipped. */
  skip = getenv ("SKIP_TEST_FUSE_SH");
  if (skip && guestfs_int_is_true (skip) > 0)
    error (77, 0, "test skipped because environment variable set");

  skip = getenv ("SKIP_TEST_GUESTMOUNT_FD");
  if (skip && guestfs_int_is_true (skip) > 0)
    error (77, 0, "test skipped because environment variable set");

  /* Skip the test if the test image can't be found. */
  if (access (TEST_IMAGE, R_OK) == -1)
    error (77, errno, "access: %s", TEST_IMAGE);

  /* Skip the test if /dev/fuse is not writable, because guestmount
   * will fail.
   */
  if (access ("/dev/fuse", W_OK) == -1)
    error (77, errno, "access: %s", "/dev/fuse");

  /* Create the pipe. */
  if (pipe (pipefd) == -1)
    error (EXIT_FAILURE, errno, "pipe");

  /* Create the mount point. */
  ignore_value (rmdir (MOUNTPOINT));
  if (mkdir (MOUNTPOINT, 0700) == -1)
    error (EXIT_FAILURE, errno, "mkdir: %s", MOUNTPOINT);

  /* Create the guestmount subprocess. */
  pid = fork ();
  if (pid == -1)
    error (EXIT_FAILURE, errno, "fork");

  if (pid == 0) {               /* child - guestmount */
    char fd_str[64];

    close (pipefd[0]);

    snprintf (fd_str, sizeof fd_str, "%d", pipefd[1]);

    execlp (GUESTMOUNT_BINARY,
            "guestmount",
            "--fd", fd_str, "--no-fork",
            "--ro", "-a", TEST_IMAGE, "-i", MOUNTPOINT, NULL);
    perror ("execlp");
    _exit (EXIT_FAILURE);
  }

  /* Parent continues. */
  close (pipefd[1]);

  /* Wait for guestmount to start up. */
  r = read (pipefd[0], &c, 1);
  if (r == -1) {
    perror ("read (pipefd)");
    ignore_value (rmdir (MOUNTPOINT));
    exit (EXIT_FAILURE);
  }
  if (r == 0) {
    fprintf (stderr, "%s: unexpected end of file on pipe fd.\n",
             getprogname ());
    ignore_value (rmdir (MOUNTPOINT));
    exit (EXIT_FAILURE);
  }

  /* Check that the test image was mounted. */
  if (access (TEST_FILE, R_OK) == -1) {
    fprintf (stderr, "%s: test failed because test image is not mounted and ready.",
             getprogname ());
    ignore_value (rmdir (MOUNTPOINT));
    exit (EXIT_FAILURE);
  }

  /* Unmount it. */
  r = system (GUESTUNMOUNT_BINARY " " MOUNTPOINT);
  if (r != 0) {
    char status_string[80];

    fprintf (stderr, "%s: test failed: %s\n", getprogname (),
             guestfs_int_exit_status_to_string (r, GUESTUNMOUNT_BINARY,
						status_string,
						sizeof status_string));
    ignore_value (rmdir (MOUNTPOINT));
    exit (EXIT_FAILURE);
  }

  close (pipefd[0]);

  /* Wait for guestmount to exit, and check it exits cleanly. */
  r = waitpid (pid, &status, 0);
  if (r == -1) {
    perror ("waitpid");
    ignore_value (rmdir (MOUNTPOINT));
    exit (EXIT_FAILURE);
  }
  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0) {
    char status_string[80];

    fprintf (stderr, "%s: test failed: %s\n",
             getprogname (),
             guestfs_int_exit_status_to_string (status, GUESTMOUNT_BINARY,
						status_string,
						sizeof status_string));
    ignore_value (rmdir (MOUNTPOINT));
    exit (EXIT_FAILURE);
  }

  ignore_value (rmdir (MOUNTPOINT));

  exit (EXIT_SUCCESS);
}