Use GUESTFS_LAUNCH_FLAG in the daemon, and use correct uint32_t.
[libguestfs.git] / src / generator.ml
index 6df04a5..8c75b93 100755 (executable)
@@ -1253,7 +1253,6 @@ Reread the partition table on C<device>.
 
 This uses the L<blockdev(8)> command.");
 
-(*
   ("upload", (RErr, [FileIn "filename"; String "remotefilename"]), 66, [],
    [],
    "upload a file from the local machine",
@@ -1275,7 +1274,6 @@ on the local machine.
 C<filename> can also be a named pipe.
 
 See also C<guestfs_upload>, C<guestfs_cat>.");
-*)
 
 ]
 
@@ -1926,9 +1924,17 @@ and generate_xdr () =
 
   (* Message header, etc. *)
   pr "\
+/* The communication protocol is now documented in the guestfs(3)
+ * manpage.
+ */
+
 const GUESTFS_PROGRAM = 0x2000F5F5;
 const GUESTFS_PROTOCOL_VERSION = 1;
 
+/* These constants must be larger than any possible message length. */
+const GUESTFS_LAUNCH_FLAG = 0xf5f55f5f;
+const GUESTFS_CANCEL_FLAG = 0xffffeeee;
+
 enum guestfs_message_direction {
   GUESTFS_DIRECTION_CALL = 0,        /* client -> daemon */
   GUESTFS_DIRECTION_REPLY = 1        /* daemon -> client */
@@ -1945,19 +1951,6 @@ struct guestfs_message_error {
   string error_message<GUESTFS_ERROR_LEN>;
 };
 
-/* For normal requests and replies (not involving any FileIn or
- * FileOut parameters), the protocol is:
- *
- * For requests:
- *   total length (header + args, but not including length word itself)
- *   header
- *   guestfs_foo_args struct
- * For replies:
- *   total length (as above)
- *   header
- *   guestfs_foo_ret struct
- */
-
 struct guestfs_message_header {
   unsigned prog;                     /* GUESTFS_PROGRAM */
   unsigned vers;                     /* GUESTFS_PROTOCOL_VERSION */
@@ -1967,23 +1960,6 @@ struct guestfs_message_header {
   guestfs_message_status status;
 };
 
-/* Chunked encoding used to transfer files, for FileIn and FileOut
- * parameters.
- *
- * For requests which have >= 1 FileIn parameter:
- *   length of header + args (but not length word itself, and not chunks)
- *   header
- *   guestfs_foo_args struct
- *   sequence of chunks for FileIn param #0
- *   sequence of chunks for FileIn param #1 etc
- *
- * For replies which have >= 1 FileOut parameter:
- *   length of header + ret (but not length word itself, and not chunks)
- *   header
- *   guestfs_foo_ret struct
- *   sequence of chunks for FileOut param #0
- *   sequence of chunks for FileOut param #1 etc
- */
 const GUESTFS_MAX_CHUNK_SIZE = 8192;
 
 struct guestfs_chunk {
@@ -2146,8 +2122,7 @@ check_state (guestfs_h *g, const char *caller)
       pr "  /* This flag is set by the callbacks, so we know we've done\n";
       pr "   * the callbacks as expected, and in the right sequence.\n";
       pr "   * 0 = not called, 1 = send called,\n";
-      pr "   * 2.. = send_file called,\n";
-      pr "   * 1000 = reply called.\n";
+      pr "   * 1001 = reply called.\n";
       pr "   */\n";
       pr "  int cb_sequence;\n";
       pr "  struct guestfs_message_header hdr;\n";
@@ -2167,24 +2142,14 @@ check_state (guestfs_h *g, const char *caller)
       pr "};\n";
       pr "\n";
 
-      (* Generate the send callback function. *)
-      pr "static void %s_send_cb (guestfs_h *g, void *data)\n" shortname;
-      pr "{\n";
-      pr "  guestfs_main_loop *ml = guestfs_get_main_loop (g);\n";
-      pr "  struct %s_ctx *ctx = (struct %s_ctx *) data;\n" shortname shortname;
-      pr "\n";
-      pr "  guestfs__switch_to_receiving (g);\n";
-      pr "  ctx->cb_sequence = 1;\n";
-      pr "  ml->main_loop_quit (ml, g);\n";
-      pr "}\n";
-      pr "\n";
-
       (* Generate the reply callback function. *)
       pr "static void %s_reply_cb (guestfs_h *g, void *data, XDR *xdr)\n" shortname;
       pr "{\n";
       pr "  guestfs_main_loop *ml = guestfs_get_main_loop (g);\n";
       pr "  struct %s_ctx *ctx = (struct %s_ctx *) data;\n" shortname shortname;
       pr "\n";
+      pr "  ml->main_loop_quit (ml, g);\n";
+      pr "\n";
       pr "  if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {\n";
       pr "    error (g, \"%%s: failed to parse reply header\", \"%s\");\n" name;
       pr "    return;\n";
@@ -2215,8 +2180,7 @@ check_state (guestfs_h *g, const char *caller)
       );
 
       pr " done:\n";
-      pr "  ctx->cb_sequence = 1000;\n";
-      pr "  ml->main_loop_quit (ml, g);\n";
+      pr "  ctx->cb_sequence = 1001;\n";
       pr "}\n\n";
 
       (* Generate the action stub. *)
@@ -2250,10 +2214,10 @@ check_state (guestfs_h *g, const char *caller)
       pr "  memset (&ctx, 0, sizeof ctx);\n";
       pr "\n";
 
-      (* Dispatch the main header and arguments. *)
+      (* Send the main header and arguments. *)
       (match snd style with
        | [] ->
-          pr "  serial = guestfs__send (g, GUESTFS_PROC_%s, NULL, NULL);\n"
+          pr "  serial = guestfs__send_sync (g, GUESTFS_PROC_%s, NULL, NULL);\n"
             (String.uppercase shortname)
        | args ->
           List.iter (
@@ -2271,7 +2235,7 @@ check_state (guestfs_h *g, const char *caller)
                 pr "  args.%s = %s;\n" n n
             | FileIn _ | FileOut _ -> ()
           ) args;
-          pr "  serial = guestfs__send (g, GUESTFS_PROC_%s,\n"
+          pr "  serial = guestfs__send_sync (g, GUESTFS_PROC_%s,\n"
             (String.uppercase shortname);
           pr "        (xdrproc_t) xdr_%s_args, (char *) &args);\n"
             name;
@@ -2280,33 +2244,23 @@ check_state (guestfs_h *g, const char *caller)
       pr "    return %s;\n" error_code;
       pr "\n";
 
-      (* Send the request. *)
-      pr "  ctx.cb_sequence = 0;\n";
-      pr "  guestfs_set_send_callback (g, %s_send_cb, &ctx);\n" shortname;
-      pr "  (void) ml->main_loop_run (ml, g);\n";
-      pr "  guestfs_set_send_callback (g, NULL, NULL);\n";
-      pr "  if (ctx.cb_sequence != 1) {\n";
-      pr "    error (g, \"%%s send failed, see earlier error messages\", \"%s\");\n" name;
-      pr "    return %s;\n" error_code;
-      pr "  }\n";
-      pr "\n";
-
-      (* Send any additional files requested. *)
+      (* Send any additional files (FileIn) requested. *)
       List.iter (
        function
        | FileIn n ->
-           pr "  if (send_file (g, %s) == -1)\n" n;
+           pr "  if (guestfs__send_file_sync (g, %s) == -1)\n" n;
            pr "    return %s;\n" error_code;
            pr "\n";
        | _ -> ()
       ) (snd style);
 
       (* Wait for the reply from the remote end. *)
+      pr "  guestfs__switch_to_receiving (g);\n";
       pr "  ctx.cb_sequence = 0;\n";
       pr "  guestfs_set_reply_callback (g, %s_reply_cb, &ctx);\n" shortname;
       pr "  (void) ml->main_loop_run (ml, g);\n";
       pr "  guestfs_set_reply_callback (g, NULL, NULL);\n";
-      pr "  if (ctx.cb_sequence != 1000) {\n";
+      pr "  if (ctx.cb_sequence != 1001) {\n";
       pr "    error (g, \"%%s reply failed, see earlier error messages\", \"%s\");\n" name;
       pr "    return %s;\n" error_code;
       pr "  }\n";
@@ -2327,7 +2281,7 @@ check_state (guestfs_h *g, const char *caller)
       List.iter (
        function
        | FileOut n ->
-           pr "  if (receive_file (g, %s) == -1)\n" n;
+           pr "  if (guestfs__receive_file_sync (g, %s) == -1)\n" n;
            pr "    return %s;\n" error_code;
            pr "\n";
        | _ -> ()