Version 1.5.26.
[libguestfs.git] / src / guestfs.c
index 871d713..df13d51 100644 (file)
@@ -33,7 +33,7 @@
 #include <sys/stat.h>
 #include <sys/select.h>
 #include <dirent.h>
-#include <signal.h>
+#include <assert.h>
 
 #include <rpc/types.h>
 #include <rpc/xdr.h>
@@ -63,7 +63,8 @@
 
 #include "c-ctype.h"
 #include "glthread/lock.h"
-#include "ignore-value.h"
+#include "hash.h"
+#include "hash-pjw.h"
 
 #include "guestfs.h"
 #include "guestfs-internal.h"
@@ -99,6 +100,7 @@ guestfs_create (void)
   g->error_cb_data = NULL;
 
   g->recovery_proc = 1;
+  g->autosync = 1;
 
   str = getenv ("LIBGUESTFS_DEBUG");
   g->verbose = str != NULL && STREQ (str, "1");
@@ -184,6 +186,8 @@ guestfs_close (guestfs_h *g)
   if (g->close_cb)
     g->close_cb (g, g->close_cb_data);
 
+  guestfs___free_inspect_info (g);
+
   /* Try to sync if autosync flag is set. */
   if (g->autosync && g->state == READY) {
     guestfs_umount_all (g);
@@ -218,12 +222,6 @@ guestfs_close (guestfs_h *g)
     snprintf (filename, sizeof filename, "%s/sock", g->tmpdir);
     unlink (filename);
 
-    snprintf (filename, sizeof filename, "%s/initrd", g->tmpdir);
-    unlink (filename);
-
-    snprintf (filename, sizeof filename, "%s/kernel", g->tmpdir);
-    unlink (filename);
-
     rmdir (g->tmpdir);
 
     free (g->tmpdir);
@@ -248,6 +246,8 @@ guestfs_close (guestfs_h *g)
   }
   gl_lock_unlock (handles_lock);
 
+  if (g->pda)
+    hash_free (g->pda);
   free (g->last_error);
   free (g->path);
   free (g->qemu);
@@ -605,6 +605,19 @@ guestfs__get_recovery_proc (guestfs_h *g)
   return g->recovery_proc;
 }
 
+int
+guestfs__set_network (guestfs_h *g, int v)
+{
+  g->enable_network = !!v;
+  return 0;
+}
+
+int
+guestfs__get_network (guestfs_h *g)
+{
+  return g->enable_network;
+}
+
 void
 guestfs_set_log_message_callback (guestfs_h *g,
                                   guestfs_log_message_cb cb, void *opaque)
@@ -636,3 +649,115 @@ guestfs_set_close_callback (guestfs_h *g,
   g->close_cb = cb;
   g->close_cb_data = opaque;
 }
+
+void
+guestfs_set_progress_callback (guestfs_h *g,
+                               guestfs_progress_cb cb, void *opaque)
+{
+  g->progress_cb = cb;
+  g->progress_cb_data = opaque;
+}
+
+/* Note the private data area is allocated lazily, since the vast
+ * majority of callers will never use it.  This means g->pda is
+ * likely to be NULL.
+ */
+struct pda_entry {
+  char *key;                    /* key */
+  void *data;                   /* opaque user data pointer */
+};
+
+static size_t
+hasher (void const *x, size_t table_size)
+{
+  struct pda_entry const *p = x;
+  return hash_pjw (p->key, table_size);
+}
+
+static bool
+comparator (void const *x, void const *y)
+{
+  struct pda_entry const *a = x;
+  struct pda_entry const *b = y;
+  return STREQ (a->key, b->key);
+}
+
+static void
+freer (void *x)
+{
+  if (x) {
+    struct pda_entry *p = x;
+    free (p->key);
+    free (p);
+  }
+}
+
+void
+guestfs_set_private (guestfs_h *g, const char *key, void *data)
+{
+  if (g->pda == NULL) {
+    g->pda = hash_initialize (16, NULL, hasher, comparator, freer);
+    if (g->pda == NULL)
+      g->abort_cb ();
+  }
+
+  struct pda_entry *new_entry = safe_malloc (g, sizeof *new_entry);
+  new_entry->key = safe_strdup (g, key);
+  new_entry->data = data;
+
+  struct pda_entry *old_entry = hash_delete (g->pda, new_entry);
+  freer (old_entry);
+
+  struct pda_entry *entry = hash_insert (g->pda, new_entry);
+  if (entry == NULL)
+    g->abort_cb ();
+  assert (entry == new_entry);
+}
+
+static inline char *
+bad_cast (char const *s)
+{
+  return (char *) s;
+}
+
+void *
+guestfs_get_private (guestfs_h *g, const char *key)
+{
+  if (g->pda == NULL)
+    return NULL;                /* no keys have been set */
+
+  const struct pda_entry k = { .key = bad_cast (key) };
+  struct pda_entry *entry = hash_lookup (g->pda, &k);
+  if (entry)
+    return entry->data;
+  else
+    return NULL;
+}
+
+/* When tracing, be careful how we print BufferIn parameters which
+ * usually contain large amounts of binary data (RHBZ#646822).
+ */
+void
+guestfs___print_BufferIn (FILE *out, const char *buf, size_t buf_size)
+{
+  size_t i;
+  size_t orig_size = buf_size;
+
+  if (buf_size > 256)
+    buf_size = 256;
+
+  fputc ('"', out);
+
+  for (i = 0; i < buf_size; ++i) {
+    if (c_isprint (buf[i]))
+      fputc (buf[i], out);
+    else
+      fprintf (out, "\\x%02x", (unsigned char) buf[i]);
+  }
+
+  fputc ('"', out);
+
+  if (orig_size > buf_size)
+    fprintf (out,
+             _("<truncated, original size %zu bytes>"), orig_size);
+}