+/* Access current state. */
+int
+guestfs__is_config (guestfs_h *g)
+{
+ return g->state == CONFIG;
+}
+
+int
+guestfs__is_launching (guestfs_h *g)
+{
+ return g->state == LAUNCHING;
+}
+
+int
+guestfs__is_ready (guestfs_h *g)
+{
+ return g->state == READY;
+}
+
+int
+guestfs__is_busy (guestfs_h *g)
+{
+ return g->state == BUSY;
+}
+
+int
+guestfs__get_state (guestfs_h *g)
+{
+ return g->state;
+}
+
+void
+guestfs_set_log_message_callback (guestfs_h *g,
+ guestfs_log_message_cb cb, void *opaque)
+{
+ g->log_message_cb = cb;
+ g->log_message_cb_data = opaque;
+}
+
+void
+guestfs_set_subprocess_quit_callback (guestfs_h *g,
+ guestfs_subprocess_quit_cb cb, void *opaque)
+{
+ g->subprocess_quit_cb = cb;
+ g->subprocess_quit_cb_data = opaque;
+}
+
+void
+guestfs_set_launch_done_callback (guestfs_h *g,
+ guestfs_launch_done_cb cb, void *opaque)
+{
+ g->launch_done_cb = cb;
+ g->launch_done_cb_data = opaque;
+}
+
+/*----------------------------------------------------------------------*/
+
+/* This is the code used to send and receive RPC messages and (for
+ * certain types of message) to perform file transfers. This code is
+ * driven from the generated actions (src/guestfs-actions.c). There
+ * are five different cases to consider:
+ *
+ * (1) A non-daemon function. There is no RPC involved at all, it's
+ * all handled inside the library.
+ *
+ * (2) A simple RPC (eg. "mount"). We write the request, then read
+ * the reply. The sequence of calls is:
+ *
+ * guestfs___set_busy
+ * guestfs___send
+ * guestfs___recv
+ * guestfs___end_busy
+ *
+ * (3) An RPC with FileOut parameters (eg. "upload"). We write the
+ * request, then write the file(s), then read the reply. The sequence
+ * of calls is:
+ *
+ * guestfs___set_busy
+ * guestfs___send
+ * guestfs___send_file (possibly multiple times)
+ * guestfs___recv
+ * guestfs___end_busy
+ *
+ * (4) An RPC with FileIn parameters (eg. "download"). We write the
+ * request, then read the reply, then read the file(s). The sequence
+ * of calls is:
+ *
+ * guestfs___set_busy
+ * guestfs___send
+ * guestfs___recv
+ * guestfs___recv_file (possibly multiple times)
+ * guestfs___end_busy
+ *
+ * (5) Both FileOut and FileIn parameters. There are no calls like
+ * this in the current API, but they would be implemented as a
+ * combination of cases (3) and (4).
+ *
+ * During all writes and reads, we also select(2) on qemu stdout
+ * looking for messages (guestfsd stderr and guest kernel dmesg), and
+ * anything received is passed up through the log_message_cb. This is
+ * also the reason why all the sockets are non-blocking. We also have
+ * to check for EOF (qemu died). All of this is handled by the
+ * functions send_to_daemon and recv_from_daemon.