static void try_df (const char *name, const char *uuid, const char *dev, int offset) { struct guestfs_statvfs *stat = NULL; guestfs_error_handler_cb old_error_cb; void *old_error_data; if (verbose) fprintf (stderr, "try_df %s %s %d\n", name, dev, offset); /* Try mounting and stating the device. This might reasonably fail, * so don't show errors. */ old_error_cb = guestfs_get_error_handler (g, &old_error_data); guestfs_set_error_handler (g, NULL, NULL); if (guestfs_mount_ro (g, dev, "/") == 0) { stat = guestfs_statvfs (g, "/"); guestfs_umount_all (g); } guestfs_set_error_handler (g, old_error_cb, old_error_data); if (stat) { print_stat (name, uuid, dev, offset, stat); guestfs_free_statvfs (stat); } }
int run_supported (const char *cmd, size_t argc, char *argv[]) { char **groups; /* As a side-effect this also checks that we've called 'launch'. */ groups = guestfs_available_all_groups (g); if (groups == NULL) return -1; /* Temporarily replace the error handler so that messages don't get * printed to stderr while we are issuing commands. */ guestfs_error_handler_cb old_error_cb; void *old_error_cb_data; old_error_cb = guestfs_get_error_handler (g, &old_error_cb_data); guestfs_set_error_handler (g, NULL, NULL); /* Work out the max string length of any group name. */ size_t i; size_t len = 0; for (i = 0; groups[i] != NULL; ++i) { size_t l = strlen (groups[i]); if (l > len) len = l; } for (i = 0; groups[i] != NULL; ++i) { size_t l = strlen (groups[i]); size_t j; for (j = 0; j < len-l; ++j) putchar (' '); printf ("%s", groups[i]); putchar (' '); char *gg[] = { groups[i], NULL }; int r = guestfs_available (g, gg); if (r == 0) printf ("%s", _("yes")); else printf ("%s", _("no")); putchar ('\n'); } /* Free groups list. */ for (i = 0; groups[i] != NULL; ++i) free (groups[i]); free (groups); /* Restore error handler. */ guestfs_set_error_handler (g, old_error_cb, old_error_cb_data); return 0; }
/* Guestfs.create */ CAMLprim value ocaml_guestfs_create (void) { CAMLparam0 (); CAMLlocal1 (gv); guestfs_h *g; value *v; g = guestfs_create (); if (g == NULL) caml_failwith ("failed to create guestfs handle"); guestfs_set_error_handler (g, NULL, NULL); gv = Val_guestfs (g); /* Store the OCaml handle into the C handle. This is only so we can * map the C handle to the OCaml handle in event_callback_wrapper. */ v = guestfs_safe_malloc (g, sizeof *v); *v = gv; /* XXX This global root is generational, but we cannot rely on every * user having the OCaml 3.11 version which supports this. */ caml_register_global_root (v); guestfs_set_private (g, "_ocaml_g", v); CAMLreturn (gv); }
/* Guestfs.create */ value ocaml_guestfs_create (value environmentv, value close_on_exitv, value unitv) { CAMLparam3 (environmentv, close_on_exitv, unitv); CAMLlocal1 (gv); unsigned flags = 0; guestfs_h *g; if (environmentv != Val_int (0) && !Bool_val (Field (environmentv, 0))) flags |= GUESTFS_CREATE_NO_ENVIRONMENT; if (close_on_exitv != Val_int (0) && !Bool_val (Field (close_on_exitv, 0))) flags |= GUESTFS_CREATE_NO_CLOSE_ON_EXIT; g = guestfs_create_flags (flags); if (g == NULL) caml_failwith ("failed to create guestfs handle"); guestfs_set_error_handler (g, NULL, NULL); gv = Val_guestfs (g); CAMLreturn (gv); }
void guestfs_push_error_handler (guestfs_h *g, guestfs_error_handler_cb cb, void *data) { struct error_cb_stack *old_stack; old_stack = g->error_cb_stack; g->error_cb_stack = safe_malloc (g, sizeof (struct error_cb_stack)); g->error_cb_stack->next = old_stack; g->error_cb_stack->error_cb = g->error_cb; g->error_cb_stack->error_cb_data = g->error_cb_data; guestfs_set_error_handler (g, cb, data); }
JNIEXPORT jlong JNICALL Java_com_redhat_et_libguestfs_GuestFS__1create (JNIEnv *env, jobject obj_unused, jint flags) { guestfs_h *g; g = guestfs_create_flags ((int) flags); if (g == NULL) { throw_exception (env, "GuestFS.create: failed to allocate handle"); return 0; } guestfs_set_error_handler (g, NULL, NULL); return (jlong) (long) g; }
void guestfs_pop_error_handler (guestfs_h *g) { struct error_cb_stack *next_stack; if (g->error_cb_stack) { next_stack = g->error_cb_stack->next; guestfs_set_error_handler (g, g->error_cb_stack->error_cb, g->error_cb_stack->error_cb_data); free (g->error_cb_stack); g->error_cb_stack = next_stack; } else guestfs___init_error_handler (g); }
PyObject * py_guestfs_create (PyObject *self, PyObject *args) { guestfs_h *g; g = guestfs_create (); if (g == NULL) { PyErr_SetString (PyExc_RuntimeError, "guestfs.create: failed to allocate handle"); return NULL; } guestfs_set_error_handler (g, NULL, NULL); /* This can return NULL, but in that case put_handle will have * set the Python error string. */ return put_handle (g); }
/* Guestfs.create */ value ocaml_guestfs_create (value environmentv, value close_on_exitv, value unitv) { CAMLparam3 (environmentv, close_on_exitv, unitv); CAMLlocal1 (gv); unsigned flags = 0; guestfs_h *g; value *v; if (environmentv != Val_int (0) && !Bool_val (Field (environmentv, 0))) flags |= GUESTFS_CREATE_NO_ENVIRONMENT; if (close_on_exitv != Val_int (0) && !Bool_val (Field (close_on_exitv, 0))) flags |= GUESTFS_CREATE_NO_CLOSE_ON_EXIT; g = guestfs_create_flags (flags); if (g == NULL) caml_failwith ("failed to create guestfs handle"); guestfs_set_error_handler (g, NULL, NULL); gv = Val_guestfs (g); /* Store the OCaml handle into the C handle. This is only so we can * map the C handle to the OCaml handle in event_callback_wrapper. */ v = guestfs_int_safe_malloc (g, sizeof *v); *v = gv; /* XXX This global root is generational, but we cannot rely on every * user having the OCaml 3.11 version which supports this. */ caml_register_global_root (v); guestfs_set_private (g, "_ocaml_g", v); CAMLreturn (gv); }
int main (int argc, char *argv[]) { setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEBASEDIR); textdomain (PACKAGE); parse_config (); enum { HELP_OPTION = CHAR_MAX + 1 }; /* The command line arguments are broadly compatible with (a subset * of) guestfish. Thus we have to deal mainly with -a, -m and --ro. */ static const char *options = "a:c:d:im:no:rv?Vwx"; static const struct option long_options[] = { { "add", 1, 0, 'a' }, { "connect", 1, 0, 'c' }, { "dir-cache-timeout", 1, 0, 0 }, { "domain", 1, 0, 'd' }, { "echo-keys", 0, 0, 0 }, { "format", 2, 0, 0 }, { "fuse-help", 0, 0, 0 }, { "help", 0, 0, HELP_OPTION }, { "inspector", 0, 0, 'i' }, { "keys-from-stdin", 0, 0, 0 }, { "live", 0, 0, 0 }, { "mount", 1, 0, 'm' }, { "no-sync", 0, 0, 'n' }, { "option", 1, 0, 'o' }, { "ro", 0, 0, 'r' }, { "rw", 0, 0, 'w' }, { "selinux", 0, 0, 0 }, { "trace", 0, 0, 'x' }, { "verbose", 0, 0, 'v' }, { "version", 0, 0, 'V' }, { 0, 0, 0, 0 } }; struct drv *drvs = NULL; struct drv *drv; struct mp *mps = NULL; struct mp *mp; char *p; const char *format = NULL; int c, r; int option_index; struct sigaction sa; int fuse_argc = 0; const char **fuse_argv = NULL; #define ADD_FUSE_ARG(str) \ do { \ fuse_argc ++; \ fuse_argv = realloc (fuse_argv, (1+fuse_argc) * sizeof (char *)); \ if (!fuse_argv) { \ perror ("realloc"); \ exit (EXIT_FAILURE); \ } \ fuse_argv[fuse_argc-1] = (str); \ fuse_argv[fuse_argc] = NULL; \ } while (0) /* LC_ALL=C is required so we can parse error messages. */ setenv ("LC_ALL", "C", 1); /* Set global program name that is not polluted with libtool artifacts. */ set_program_name (argv[0]); memset (&sa, 0, sizeof sa); sa.sa_handler = SIG_IGN; sa.sa_flags = SA_RESTART; sigaction (SIGPIPE, &sa, NULL); /* Various initialization. */ init_dir_caches (); g = guestfs_create (); if (g == NULL) { fprintf (stderr, _("guestfs_create: failed to create handle\n")); exit (EXIT_FAILURE); } guestfs_set_recovery_proc (g, 0); ADD_FUSE_ARG (program_name); /* MUST be single-threaded. You cannot have two threads accessing the * same libguestfs handle, and opening more than one handle is likely * to be very expensive. */ ADD_FUSE_ARG ("-s"); 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, "dir-cache-timeout")) dir_cache_timeout = atoi (optarg); else if (STREQ (long_options[option_index].name, "fuse-help")) fuse_help (); else if (STREQ (long_options[option_index].name, "selinux")) guestfs_set_selinux (g, 1); else if (STREQ (long_options[option_index].name, "format")) { if (!optarg || STREQ (optarg, "")) format = NULL; else format = optarg; } else 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, "live")) { live = 1; } 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 'i': OPTION_i; break; case 'm': OPTION_m; break; case 'n': OPTION_n; break; case 'o': ADD_FUSE_ARG ("-o"); ADD_FUSE_ARG (optarg); break; case 'r': OPTION_r; break; case 'v': OPTION_v; break; case 'V': OPTION_V; break; case 'w': OPTION_w; break; case 'x': OPTION_x; ADD_FUSE_ARG ("-f"); guestfs_set_recovery_proc (g, 1); trace_calls = 1; break; case HELP_OPTION: usage (EXIT_SUCCESS); default: usage (EXIT_FAILURE); } } /* Check we have the right options. */ if (!live) { if (!drvs || !(mps || inspector)) { fprintf (stderr, _("%s: must have at least one -a/-d and at least one -m/-i option\n"), program_name); exit (EXIT_FAILURE); } } else { size_t count_d = 0, count_other = 0; struct drv *drv; if (read_only) { fprintf (stderr, _("%s: --live is not compatible with --ro option\n"), program_name); exit (EXIT_FAILURE); } if (inspector) { fprintf (stderr, _("%s: --live is not compatible with -i option\n"), program_name); exit (EXIT_FAILURE); } /* --live: make sure there was one -d option and no -a options */ for (drv = drvs; drv; drv = drv->next) { if (drv->type == drv_d) count_d++; else count_other++; } if (count_d != 1) { fprintf (stderr, _("%s: with --live, you must use exactly one -d option\n"), program_name); exit (EXIT_FAILURE); } if (count_other != 0) { fprintf (stderr, _("%s: --live is not compatible with -a option\n"), program_name); exit (EXIT_FAILURE); } } /* We'd better have a mountpoint. */ if (optind+1 != argc) { fprintf (stderr, _("%s: you must specify a mountpoint in the host filesystem\n"), program_name); exit (EXIT_FAILURE); } /* Do the guest drives and mountpoints. */ add_drives (drvs, 'a'); if (guestfs_launch (g) == -1) exit (EXIT_FAILURE); if (inspector) inspect_mount (); mount_mps (mps); free_drives (drvs); free_mps (mps); /* FUSE example does this, not clear if it's necessary, but ... */ if (guestfs_umask (g, 0) == -1) exit (EXIT_FAILURE); /* At the last minute, remove the libguestfs error handler. In code * above this point, the default error handler has been used which * sends all errors to stderr. Now before entering FUSE itself we * want to silence errors so we can convert them (see error() * function above). */ guestfs_set_error_handler (g, NULL, NULL); /* Finish off FUSE args. */ ADD_FUSE_ARG (argv[optind]); /* It says about the line containing the for-statement: error: assuming signed overflow does not occur when simplifying conditional to constant [-Wstrict-overflow] if (verbose) { fprintf (stderr, "guestmount: invoking FUSE with args ["); for (i = 0; i < fuse_argc; ++i) { if (i > 0) fprintf (stderr, ", "); fprintf (stderr, "%s", fuse_argv[i]); } fprintf (stderr, "]\n"); } */ r = fuse_main (fuse_argc, (char **) fuse_argv, &fg_operations, NULL); /* Cleanup. */ guestfs_close (g); free_dir_caches (); exit (r == 0 ? EXIT_SUCCESS : EXIT_FAILURE); }
int run_reopen (const char *cmd, size_t argc, char *argv[]) { guestfs_h *g2; int r; const char *p; guestfs_error_handler_cb cb; void *cb_data; if (argc > 0) { fprintf (stderr, _("'reopen' command takes no parameters\n")); return -1; } if (guestfs_shutdown (g) == -1) return -1; /* Open the new handle first, so we can copy the settings from the * old one to the new one, and also so if it fails we still have an * open handle. */ g2 = guestfs_create (); if (g2 == NULL) { fprintf (stderr, _("reopen: guestfs_create: failed to create handle\n")); return -1; } /* Now copy some of the settings from the old handle. The settings * we copy are those which are set by guestfish itself. */ cb = guestfs_get_error_handler (g, &cb_data); guestfs_set_error_handler (g2, cb, cb_data); r = guestfs_get_verbose (g); if (r >= 0) guestfs_set_verbose (g2, r); r = guestfs_get_trace (g); if (r >= 0) guestfs_set_trace (g2, r); r = guestfs_get_autosync (g); if (r >= 0) guestfs_set_autosync (g2, r); p = guestfs_get_path (g); if (p) guestfs_set_path (g2, p); r = guestfs_get_pgroup (g); if (r >= 0) guestfs_set_pgroup (g2, r); if (progress_bars) guestfs_set_event_callback (g2, progress_callback, GUESTFS_EVENT_PROGRESS, 0, NULL); /* Close the original handle. */ guestfs_close (g); g = g2; /* We don't bother copying event handlers over to the new handle, * but we have to reset the list because they were registered * against the old handle. */ free_event_handlers (); init_event_handlers (); return 0; }