static int do_log (void) { CLEANUP_FREE_STRING_LIST char **roots = NULL; char *root; CLEANUP_FREE char *type = NULL; CLEANUP_FREE_STRING_LIST char **journal_files = NULL; /* Get root mountpoint. fish/inspect.c guarantees the assertions * below. */ roots = guestfs_inspect_get_roots (g); assert (roots); assert (roots[0] != NULL); assert (roots[1] == NULL); root = roots[0]; type = guestfs_inspect_get_type (g, root); if (!type) return -1; /* Windows needs special handling. */ if (STREQ (type, "windows")) { if (guestfs_inspect_get_major_version (g, root) >= 6) return do_log_windows_evtx (); fprintf (stderr, _("%s: Windows Event Log for pre-Vista guests is not supported.\n"), guestfs_int_program_name); return -1; } /* systemd journal? */ guestfs_push_error_handler (g, NULL, NULL); journal_files = guestfs_ls (g, JOURNAL_DIR); guestfs_pop_error_handler (g); if (STREQ (type, "linux") && journal_files != NULL && journal_files[0] != NULL) return do_log_journal (); /* Regular /var/log text files with different names. */ if (STRNEQ (type, "windows")) { const char *logfiles[] = { "/var/log/syslog", "/var/log/messages", NULL }; size_t i; for (i = 0; logfiles[i] != NULL; ++i) { if (guestfs_is_file_opts (g, logfiles[i], GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1, -1) == 1) return do_log_text_file (logfiles[i]); } } /* Otherwise, there are no log files. Hmm, is this right? XXX */ return 0; }
static void edit_files (int argc, char *argv[]) { int i; char *root; CLEANUP_FREE_STRING_LIST char **roots = guestfs_inspect_get_roots (g); if (!roots) exit (EXIT_FAILURE); /* Get root mountpoint. */ /* see fish/inspect.c:inspect_mount */ assert (roots[0] != NULL && roots[1] == NULL); root = roots[0]; for (i = 0; i < argc; ++i) edit (argv[i], root); }
int main (int argc, char *argv[]) { /* Set global program name that is not polluted with libtool artifacts. */ set_program_name (argv[0]); setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEBASEDIR); textdomain (PACKAGE); /* We use random(3) below. */ srandom (time (NULL)); enum { HELP_OPTION = CHAR_MAX + 1 }; static const char *options = "a:b:c:d:e:vVx"; static const struct option long_options[] = { { "add", 1, 0, 'a' }, { "backup", 1, 0, 'b' }, { "connect", 1, 0, 'c' }, { "domain", 1, 0, 'd' }, { "echo-keys", 0, 0, 0 }, { "expr", 1, 0, 'e' }, { "format", 2, 0, 0 }, { "help", 0, 0, HELP_OPTION }, { "keys-from-stdin", 0, 0, 0 }, { "verbose", 0, 0, 'v' }, { "version", 0, 0, 'V' }, { 0, 0, 0, 0 } }; struct drv *drvs = NULL; struct drv *drv; const char *format = NULL; int c; int option_index; char *root, **roots; g = guestfs_create (); if (g == NULL) { fprintf (stderr, _("guestfs_create: failed to create handle\n")); exit (EXIT_FAILURE); } argv[0] = bad_cast (program_name); for (;;) { c = getopt_long (argc, argv, options, long_options, &option_index); if (c == -1) break; switch (c) { case 0: /* options which are long only */ if (STREQ (long_options[option_index].name, "keys-from-stdin")) { keys_from_stdin = 1; } else if (STREQ (long_options[option_index].name, "echo-keys")) { echo_keys = 1; } else if (STREQ (long_options[option_index].name, "format")) { if (!optarg || STREQ (optarg, "")) format = NULL; else format = optarg; } else { fprintf (stderr, _("%s: unknown long option: %s (%d)\n"), program_name, long_options[option_index].name, option_index); exit (EXIT_FAILURE); } break; case 'a': OPTION_a; break; case 'b': if (backup_extension) { fprintf (stderr, _("%s: -b option given multiple times\n"), program_name); exit (EXIT_FAILURE); } backup_extension = optarg; break; case 'c': OPTION_c; break; case 'd': OPTION_d; break; case 'e': if (perl_expr) { fprintf (stderr, _("%s: -e option given multiple times\n"), program_name); exit (EXIT_FAILURE); } perl_expr = optarg; break; case 'h': usage (EXIT_SUCCESS); case 'v': OPTION_v; break; case 'V': OPTION_V; break; case 'x': OPTION_x; break; case HELP_OPTION: usage (EXIT_SUCCESS); default: usage (EXIT_FAILURE); } } /* Old-style syntax? There were no -a or -d options in the old * virt-edit which is how we detect this. */ if (drvs == NULL) { /* argc - 1 because last parameter is the single filename. */ while (optind < argc - 1) { if (strchr (argv[optind], '/') || access (argv[optind], F_OK) == 0) { /* simulate -a option */ drv = malloc (sizeof (struct drv)); if (!drv) { perror ("malloc"); exit (EXIT_FAILURE); } drv->type = drv_a; drv->a.filename = argv[optind]; drv->a.format = NULL; drv->next = drvs; drvs = drv; } else { /* simulate -d option */ drv = malloc (sizeof (struct drv)); if (!drv) { perror ("malloc"); exit (EXIT_FAILURE); } drv->type = drv_d; drv->d.guest = argv[optind]; drv->next = drvs; drvs = drv; } optind++; } } /* These are really constants, but they have to be variables for the * options parsing code. Assert here that they have known-good * values. */ assert (read_only == 0); assert (inspector == 1); assert (live == 0); /* User must specify at least one filename on the command line. */ if (optind >= argc || argc - optind < 1) usage (EXIT_FAILURE); /* User must have specified some drives. */ if (drvs == NULL) usage (EXIT_FAILURE); /* Add drives. */ add_drives (drvs, 'a'); if (guestfs_launch (g) == -1) exit (EXIT_FAILURE); inspect_mount (); /* Free up data structures, no longer needed after this point. */ free_drives (drvs); /* Get root mountpoint. */ roots = guestfs_inspect_get_roots (g); if (!roots) exit (EXIT_FAILURE); /* see fish/inspect.c:inspect_mount */ assert (roots[0] != NULL && roots[1] == NULL); root = roots[0]; free (roots); while (optind < argc) { edit (argv[optind], root); optind++; } free (root); /* Cleanly unmount the disks after editing. */ if (guestfs_umount_all (g) == -1 || guestfs_sync (g) == -1) exit (EXIT_FAILURE); guestfs_close (g); exit (EXIT_SUCCESS); }
int main (int argc, char *argv[]) { /* Set global program name that is not polluted with libtool artifacts. */ set_program_name (argv[0]); setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEBASEDIR); textdomain (PACKAGE); enum { HELP_OPTION = CHAR_MAX + 1 }; static const char *options = "a:c:d:vVx"; static const struct option long_options[] = { { "add", 1, 0, 'a' }, { "connect", 1, 0, 'c' }, { "domain", 1, 0, 'd' }, { "echo-keys", 0, 0, 0 }, { "format", 2, 0, 0 }, { "help", 0, 0, HELP_OPTION }, { "keys-from-stdin", 0, 0, 0 }, { "verbose", 0, 0, 'v' }, { "version", 0, 0, 'V' }, { 0, 0, 0, 0 } }; struct drv *drvs = NULL; struct drv *drv; const char *format = NULL; int c; int option_index; g = guestfs_create (); if (g == NULL) { fprintf (stderr, _("guestfs_create: failed to create handle\n")); exit (EXIT_FAILURE); } argv[0] = bad_cast (program_name); for (;;) { c = getopt_long (argc, argv, options, long_options, &option_index); if (c == -1) break; switch (c) { case 0: /* options which are long only */ if (STREQ (long_options[option_index].name, "keys-from-stdin")) { keys_from_stdin = 1; } else if (STREQ (long_options[option_index].name, "echo-keys")) { echo_keys = 1; } else if (STREQ (long_options[option_index].name, "format")) { if (!optarg || STREQ (optarg, "")) format = NULL; else format = optarg; } else { fprintf (stderr, _("%s: unknown long option: %s (%d)\n"), program_name, long_options[option_index].name, option_index); exit (EXIT_FAILURE); } break; case 'a': OPTION_a; break; case 'c': OPTION_c; break; case 'd': OPTION_d; break; case 'v': OPTION_v; break; case 'V': OPTION_V; break; case 'x': OPTION_x; break; case HELP_OPTION: usage (EXIT_SUCCESS); default: usage (EXIT_FAILURE); } } /* Old-style syntax? There were no -a or -d options in the old * virt-cat which is how we detect this. */ if (drvs == NULL) { /* argc - 1 because last parameter is the single filename. */ while (optind < argc - 1) { if (strchr (argv[optind], '/') || access (argv[optind], F_OK) == 0) { /* simulate -a option */ drv = calloc (1, sizeof (struct drv)); if (!drv) { perror ("malloc"); exit (EXIT_FAILURE); } drv->type = drv_a; drv->a.filename = argv[optind]; drv->next = drvs; drvs = drv; } else { /* simulate -d option */ drv = calloc (1, sizeof (struct drv)); if (!drv) { perror ("malloc"); exit (EXIT_FAILURE); } drv->type = drv_d; drv->d.guest = argv[optind]; drv->next = drvs; drvs = drv; } optind++; } } /* These are really constants, but they have to be variables for the * options parsing code. Assert here that they have known-good * values. */ assert (read_only == 1); assert (inspector == 1); assert (live == 0); /* User must specify at least one filename on the command line. */ if (optind >= argc || argc - optind < 1) usage (EXIT_FAILURE); /* User must have specified some drives. */ if (drvs == NULL) usage (EXIT_FAILURE); /* Add drives, inspect and mount. Note that inspector is always true, * and there is no -m option. */ add_drives (drvs, 'a'); if (guestfs_launch (g) == -1) exit (EXIT_FAILURE); inspect_mount (); /* Free up data structures, no longer needed after this point. */ free_drives (drvs); unsigned errors = 0; int windows; char *root, **roots; /* Get root mountpoint. See: fish/inspect.c:inspect_mount */ roots = guestfs_inspect_get_roots (g); assert (roots); assert (roots[0] != NULL); assert (roots[1] == NULL); root = roots[0]; free (roots); /* Windows? Special handling is required. */ windows = is_windows (g, root); for (; optind < argc; optind++) { char *filename_to_free = NULL; const char *filename = argv[optind]; if (windows) { filename = filename_to_free = windows_path (g, root, filename); if (filename == NULL) { errors++; continue; } } if (guestfs_download (g, filename, "/dev/stdout") == -1) errors++; free (filename_to_free); } free (root); guestfs_close (g); exit (errors == 0 ? EXIT_SUCCESS : EXIT_FAILURE); }