/* 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); } }
/* 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; }
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); }
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); }