+
+ return send_file_complete_sync (g);
+}
+
+/* Send a chunk of file data. */
+static int
+send_file_data_sync (guestfs_h *g, const char *buf, size_t len)
+{
+ return send_file_chunk_sync (g, 0, buf, len);
+}
+
+/* Send a cancellation message. */
+static int
+send_file_cancellation_sync (guestfs_h *g)
+{
+ return send_file_chunk_sync (g, 1, NULL, 0);
+}
+
+/* Send a file complete chunk. */
+static int
+send_file_complete_sync (guestfs_h *g)
+{
+ char buf[1];
+ return send_file_chunk_sync (g, 0, buf, 0);
+}
+
+/* Send a chunk, cancellation or end of file, synchronously (ie. wait
+ * for it to go).
+ */
+static int check_for_daemon_cancellation (guestfs_h *g);
+
+static int
+send_file_chunk_sync (guestfs_h *g, int cancel, const char *buf, size_t len)
+{
+ char data[GUESTFS_MAX_CHUNK_SIZE + 48];
+ unsigned datalen;
+ int sent;
+ guestfs_chunk chunk;
+ XDR xdr;
+ guestfs_main_loop *ml = guestfs_get_main_loop (g);
+
+ if (g->state != BUSY) {
+ error (g, "send_file_chunk_sync: state %d != READY", g->state);
+ return -1;
+ }
+
+ /* Did the daemon send a cancellation message? */
+ if (check_for_daemon_cancellation (g)) {
+ if (g->verbose)
+ fprintf (stderr, "got daemon cancellation\n");
+ return -2;
+ }
+
+ /* Serialize the chunk. */
+ chunk.cancel = cancel;
+ chunk.data.data_len = len;
+ chunk.data.data_val = (char *) buf;
+
+ if (g->verbose)
+ fprintf (stderr,
+ "library sending chunk cancel = %d, len = %zu, buf = %p\n",
+ cancel, len, buf);
+
+ xdrmem_create (&xdr, data, sizeof data, XDR_ENCODE);
+ if (!xdr_guestfs_chunk (&xdr, &chunk)) {
+ error (g, "xdr_guestfs_chunk failed (buf = %p, len = %zu)", buf, len);
+ xdr_destroy (&xdr);