]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Mon Jun 11 12:45:00 BST 2007 Richard W.M. Jones <rjones@redhat.com>
authorRichard W.M. Jones <rjones@redhat.com>
Mon, 11 Jun 2007 11:47:01 +0000 (11:47 +0000)
committerRichard W.M. Jones <rjones@redhat.com>
Mon, 11 Jun 2007 11:47:01 +0000 (11:47 +0000)
* qemud/remote.c, qemud/remote_generate_stubs.pl,
  qemud/remote_dispatch_localvars.h,
  qemud/remote_dispatch_proc_switch.h,
  qemud/remote_dispatch_prototypes.h: Server side of
  the remote patch, deals with call dispatch.

ChangeLog
qemud/remote.c [new file with mode: 0644]
qemud/remote_dispatch_localvars.h [new file with mode: 0644]
qemud/remote_dispatch_proc_switch.h [new file with mode: 0644]
qemud/remote_dispatch_prototypes.h [new file with mode: 0644]
qemud/remote_generate_stubs.pl [new file with mode: 0755]

index d28d9652227b7d5f41fd82887602611bb8a99013..2a7fcf02637c62067a139596d3d5b804b7a77537 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Mon Jun 11 12:45:00 BST 2007 Richard W.M. Jones <rjones@redhat.com>
+
+       * qemud/remote.c, qemud/remote_generate_stubs.pl,
+         qemud/remote_dispatch_localvars.h,
+         qemud/remote_dispatch_proc_switch.h,
+         qemud/remote_dispatch_prototypes.h: Server side of
+         the remote patch, deals with call dispatch.
+
 Mon Jun 11 12:41:00 BST 2007 Richard W.M. Jones <rjones@redhat.com>
 
        * src/remote_internal.c, src/remote_internal.h,
diff --git a/qemud/remote.c b/qemud/remote.c
new file mode 100644 (file)
index 0000000..9454079
--- /dev/null
@@ -0,0 +1,1575 @@
+/*
+ * remote.c: code handling remote requests (from remote_internal.c)
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * Author: Richard W.M. Jones <rjones@redhat.com>
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <limits.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/poll.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <syslog.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+#include <ctype.h>
+#include <assert.h>
+
+#include <libvirt/virterror.h>
+
+#include "internal.h"
+#include "../src/internal.h"
+#include "dispatch.h"
+#include "driver.h"
+#include "conf.h"
+#include "iptables.h"
+
+#define DEBUG 0
+
+static void remoteDispatchError (struct qemud_client *client,
+                                 remote_message_header *req,
+                                 const char *fmt, ...);
+static virDomainPtr get_nonnull_domain (virConnectPtr conn, remote_nonnull_domain domain);
+static virNetworkPtr get_nonnull_network (virConnectPtr conn, remote_nonnull_network network);
+static void make_nonnull_domain (remote_nonnull_domain *dom_dst, virDomainPtr dom_src);
+static void make_nonnull_network (remote_nonnull_network *net_dst, virNetworkPtr net_src);
+
+#include "remote_dispatch_prototypes.h"
+
+typedef int (*dispatch_fn) (struct qemud_client *client, remote_message_header *req, char *args, char *ret);
+
+/* This function gets called from qemud when it detects an incoming
+ * remote protocol message.  At this point, client->buffer contains
+ * the full call message (including length word which we skip).
+ */
+void
+remoteDispatchClientRequest (struct qemud_server *server ATTRIBUTE_UNUSED,
+                             struct qemud_client *client)
+{
+    XDR xdr;
+    remote_message_header req, rep;
+    dispatch_fn fn;
+    xdrproc_t args_filter = (xdrproc_t) xdr_void;
+    xdrproc_t ret_filter = (xdrproc_t) xdr_void;
+    char *args = NULL, *ret = NULL;
+    int rv, len;
+
+#include "remote_dispatch_localvars.h"
+
+    /* Parse the header. */
+    xdrmem_create (&xdr, client->buffer+4, client->bufferLength-4, XDR_DECODE);
+
+    if (!xdr_remote_message_header (&xdr, &req)) {
+        remoteDispatchError (client, NULL, "xdr_remote_message_header");
+        xdr_destroy (&xdr);
+        return;
+    }
+
+    /* Check version, etc. */
+    if (req.prog != REMOTE_PROGRAM) {
+        remoteDispatchError (client, &req, "program mismatch (actual %x, expected %x)",
+                             req.prog, REMOTE_PROGRAM);
+        xdr_destroy (&xdr);
+        return;
+    }
+    if (req.vers != REMOTE_PROTOCOL_VERSION) {
+        remoteDispatchError (client, &req, "version mismatch (actual %x, expected %x)",
+                             req.vers, REMOTE_PROTOCOL_VERSION);
+        xdr_destroy (&xdr);
+        return;
+    }
+    if (req.direction != REMOTE_CALL) {
+        remoteDispatchError (client, &req, "direction (%d) != REMOTE_CALL",
+                             (int) req.direction);
+        xdr_destroy (&xdr);
+        return;
+    }
+    if (req.status != REMOTE_OK) {
+        remoteDispatchError (client, &req, "status (%d) != REMOTE_OK",
+                             (int) req.status);
+        xdr_destroy (&xdr);
+        return;
+    }
+
+    /* Based on the procedure number, dispatch.  In future we may base
+     * this on the version number as well.
+     */
+    switch (req.proc) {
+#include "remote_dispatch_proc_switch.h"
+
+    default:
+        remoteDispatchError (client, &req, "unknown procedure: %d",
+                             req.proc);
+        xdr_destroy (&xdr);
+        return;
+    }
+
+    /* Parse args. */
+    if (!(*args_filter) (&xdr, args)) {
+        remoteDispatchError (client, &req, "parse args failed");
+        xdr_destroy (&xdr);
+        return;
+    }
+
+    xdr_destroy (&xdr);
+
+    /* Call function. */
+    rv = fn (client, &req, args, ret);
+    xdr_free (args_filter, args);
+
+    /* Dispatch function must return -2, -1 or 0.  Anything else is
+     * an internal error.
+     */
+    if (rv < -2 || rv > 0) {
+        remoteDispatchError (client, &req, "internal error - dispatch function returned invalid code %d", rv);
+        return;
+    }
+
+    /* Dispatch error?  If so then the function has already set up the
+     * return buffer, so just return immediately.
+     */
+    if (rv == -2) return;
+
+    /* Return header. */
+    rep.prog = req.prog;
+    rep.vers = req.vers;
+    rep.proc = req.proc;
+    rep.direction = REMOTE_REPLY;
+    rep.serial = req.serial;
+    rep.status = rv == 0 ? REMOTE_OK : REMOTE_ERROR;
+
+    /* Serialise the return header. */
+    xdrmem_create (&xdr, client->buffer, sizeof client->buffer, XDR_ENCODE);
+
+    len = 0; /* We'll come back and write this later. */
+    if (!xdr_int (&xdr, &len)) {
+        remoteDispatchError (client, &req, "dummy length");
+        xdr_destroy (&xdr);
+        if (rv == 0) xdr_free (ret_filter, ret);
+        return;
+    }
+
+    if (!xdr_remote_message_header (&xdr, &rep)) {
+        remoteDispatchError (client, &req, "serialise reply header");
+        xdr_destroy (&xdr);
+        if (rv == 0) xdr_free (ret_filter, ret);
+        return;
+    }
+
+    /* If OK, serialise return structure, if error serialise error. */
+    if (rv == 0) {
+        if (!(*ret_filter) (&xdr, ret)) {
+            remoteDispatchError (client, &req, "serialise return struct");
+            xdr_destroy (&xdr);
+            return;
+        }
+        xdr_free (ret_filter, ret);
+    } else /* error */ {
+        virErrorPtr verr;
+        remote_error error;
+        remote_nonnull_domain dom;
+        remote_nonnull_network net;
+
+        verr = client->conn
+            ? virConnGetLastError (client->conn)
+            : virGetLastError ();
+
+        if (verr) {
+            error.code = verr->code;
+            error.domain = verr->domain;
+            error.message = verr->message ? &verr->message : NULL;
+            error.level = verr->level;
+            if (verr->dom) {
+                dom.name = verr->dom->name;
+                memcpy (dom.uuid, verr->dom->uuid, VIR_UUID_BUFLEN);
+                dom.id = verr->dom->id;
+            }
+            error.dom = verr->dom ? &dom : NULL;
+            error.str1 = verr->str1 ? &verr->str1 : NULL;
+            error.str2 = verr->str2 ? &verr->str2 : NULL;
+            error.str3 = verr->str3 ? &verr->str3 : NULL;
+            error.int1 = verr->int1;
+            error.int2 = verr->int2;
+            if (verr->net) {
+                net.name = verr->net->name;
+                memcpy (net.uuid, verr->net->uuid, VIR_UUID_BUFLEN);
+            }
+            error.net = verr->net ? &net : NULL;
+        } else {
+            /* Error was NULL so synthesize an error. */
+            char msgbuf[] = "remoteDispatchClientRequest: internal error: library function returned error but did not set virterror";
+            char *msg = msgbuf;
+
+            error.code = VIR_ERR_RPC;
+            error.domain = VIR_FROM_REMOTE;
+            error.message = &msg;
+            error.level = VIR_ERR_ERROR;
+            error.dom = NULL;
+            error.str1 = &msg;
+            error.str2 = NULL;
+            error.str3 = NULL;
+            error.int1 = 0;
+            error.int2 = 0;
+            error.net = NULL;
+        }
+
+        if (!xdr_remote_error (&xdr, &error)) {
+            remoteDispatchError (client, &req, "serialise return error");
+            xdr_destroy (&xdr);
+            return;
+        }
+    }
+
+    /* Write the length word. */
+    len = xdr_getpos (&xdr);
+    if (xdr_setpos (&xdr, 0) == 0) {
+        remoteDispatchError (client, &req, "xdr_setpos");
+        xdr_destroy (&xdr);
+        return;
+    }
+
+    if (!xdr_int (&xdr, &len)) {
+        remoteDispatchError (client, &req, "serialise return length");
+        xdr_destroy (&xdr);
+        return;
+    }
+
+    xdr_destroy (&xdr);
+
+    /* Set up the output buffer. */
+    client->mode = QEMUD_MODE_TX_PACKET;
+    client->bufferLength = len;
+    client->bufferOffset = 0;
+    if (client->tls) client->direction = QEMUD_TLS_DIRECTION_WRITE;
+}
+
+/* An error occurred during the dispatching process itself (ie. not
+ * an error from the function being called).  We return an error
+ * reply.
+ */
+static void
+remoteDispatchError (struct qemud_client *client,
+                     remote_message_header *req,
+                     const char *fmt, ...)
+{
+    remote_message_header rep;
+    remote_error error;
+    va_list args;
+    char msgbuf[1024];
+    char *msg = msgbuf;
+    XDR xdr;
+    int len;
+
+    va_start (args, fmt);
+    vsnprintf (msgbuf, sizeof msgbuf, fmt, args);
+    va_end (args);
+
+    qemudDebug ("%s", msgbuf);
+
+    /* Future versions of the protocol may use different vers or prog.  Try
+     * our hardest to send back a message that such clients could see.
+     */
+    if (req) {
+        rep.prog = req->prog;
+        rep.vers = req->vers;
+        rep.proc = req->proc;
+        rep.direction = REMOTE_REPLY;
+        rep.serial = req->serial;
+        rep.status = REMOTE_ERROR;
+    } else {
+        rep.prog = REMOTE_PROGRAM;
+        rep.vers = REMOTE_PROTOCOL_VERSION;
+        rep.proc = REMOTE_PROC_OPEN;
+        rep.direction = REMOTE_REPLY;
+        rep.serial = 1;
+        rep.status = REMOTE_ERROR;
+    }
+
+    /* Construct the error. */
+    error.code = VIR_ERR_RPC;
+    error.domain = VIR_FROM_REMOTE;
+    error.message = &msg;
+    error.level = VIR_ERR_ERROR;
+    error.dom = NULL;
+    error.str1 = &msg;
+    error.str2 = NULL;
+    error.str3 = NULL;
+    error.int1 = 0;
+    error.int2 = 0;
+    error.net = NULL;
+
+    /* Serialise the return header and error. */
+    xdrmem_create (&xdr, client->buffer, sizeof client->buffer, XDR_ENCODE);
+
+    len = 0; /* We'll come back and write this later. */
+    if (!xdr_int (&xdr, &len)) {
+        xdr_destroy (&xdr);
+        return;
+    }
+
+    if (!xdr_remote_message_header (&xdr, &rep)) {
+        xdr_destroy (&xdr);
+        return;
+    }
+
+    if (!xdr_remote_error (&xdr, &error)) {
+        xdr_destroy (&xdr);
+        return;
+    }
+
+    len = xdr_getpos (&xdr);
+    if (xdr_setpos (&xdr, 0) == 0) {
+        xdr_destroy (&xdr);
+        return;
+    }
+
+    if (!xdr_int (&xdr, &len)) {
+        xdr_destroy (&xdr);
+        return;
+    }
+
+    xdr_destroy (&xdr);
+
+    /* Send it. */
+    client->mode = QEMUD_MODE_TX_PACKET;
+    client->bufferLength = len;
+    client->bufferOffset = 0;
+    if (client->tls) client->direction = QEMUD_TLS_DIRECTION_WRITE;
+}
+
+/*----- Functions. -----*/
+
+static int
+remoteDispatchOpen (struct qemud_client *client, remote_message_header *req,
+                    struct remote_open_args *args, void *ret ATTRIBUTE_UNUSED)
+{
+    const char *name;
+    int flags;
+
+    /* Already opened? */
+    if (client->conn) {
+        remoteDispatchError (client, req, "connection already open");
+        return -2;
+    }
+
+    name = args->name ? *args->name : NULL;
+
+#if DEBUG
+    fprintf (stderr, "remoteDispatchOpen: name = %s\n", name);
+#endif
+
+    /* If this connection arrived on a readonly socket, force
+     * the connection to be readonly.
+     */
+    flags = args->flags;
+    if (client->readonly) flags |= VIR_CONNECT_RO;
+
+    client->conn =
+        flags & VIR_CONNECT_RO
+        ? virConnectOpenReadOnly (name)
+        : virConnectOpen (name);
+
+    return client->conn ? 0 : -1;
+}
+
+#define CHECK_CONN(client)                      \
+    if (!client->conn) {                        \
+        remoteDispatchError (client, req, "connection not open");   \
+        return -2;                                                  \
+    }
+
+static int
+remoteDispatchClose (struct qemud_client *client, remote_message_header *req,
+                     void *args ATTRIBUTE_UNUSED, void *ret ATTRIBUTE_UNUSED)
+{
+    int rv;
+    CHECK_CONN(client);
+
+    rv = virConnectClose (client->conn);
+    if (rv == 0) client->conn = NULL;
+
+    return rv;
+}
+
+static int
+remoteDispatchGetType (struct qemud_client *client, remote_message_header *req,
+                       void *args ATTRIBUTE_UNUSED, remote_get_type_ret *ret)
+{
+    const char *type;
+    CHECK_CONN(client);
+
+    type = virConnectGetType (client->conn);
+    if (type == NULL) return -1;
+
+    /* We have to strdup because remoteDispatchClientRequest will
+     * free this string after it's been serialised.
+     */
+    ret->type = strdup (type);
+    if (!ret->type) {
+        remoteDispatchError (client, req, "out of memory in strdup");
+        return -2;
+    }
+
+    return 0;
+}
+
+static int
+remoteDispatchGetVersion (struct qemud_client *client,
+                          remote_message_header *req,
+                          void *args ATTRIBUTE_UNUSED,
+                          remote_get_version_ret *ret)
+{
+    unsigned long hvVer;
+    CHECK_CONN(client);
+
+    if (virConnectGetVersion (client->conn, &hvVer) == -1)
+        return -1;
+
+    ret->hv_ver = hvVer;
+    return 0;
+}
+
+static int
+remoteDispatchGetMaxVcpus (struct qemud_client *client,
+                           remote_message_header *req,
+                           remote_get_max_vcpus_args *args,
+                           remote_get_max_vcpus_ret *ret)
+{
+    char *type;
+    CHECK_CONN(client);
+
+    type = args->type ? *args->type : NULL;
+    ret->max_vcpus = virConnectGetMaxVcpus (client->conn, type);
+    if (ret->max_vcpus == -1) return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchNodeGetInfo (struct qemud_client *client,
+                           remote_message_header *req,
+                           void *args ATTRIBUTE_UNUSED,
+                           remote_node_get_info_ret *ret)
+{
+    virNodeInfo info;
+    CHECK_CONN(client);
+
+    if (virNodeGetInfo (client->conn, &info) == -1)
+        return -1;
+
+    memcpy (ret->model, info.model, sizeof ret->model);
+    ret->memory = info.memory;
+    ret->cpus = info.cpus;
+    ret->mhz = info.mhz;
+    ret->nodes = info.nodes;
+    ret->sockets = info.sockets;
+    ret->cores = info.cores;
+    ret->threads = info.threads;
+
+    return 0;
+}
+
+static int
+remoteDispatchGetCapabilities (struct qemud_client *client,
+                               remote_message_header *req,
+                               void *args ATTRIBUTE_UNUSED,
+                               remote_get_capabilities_ret *ret)
+{
+    char *caps;
+    CHECK_CONN(client);
+
+    caps = virConnectGetCapabilities (client->conn);
+    if (caps == NULL) return -1;
+
+    ret->capabilities = caps;
+    return 0;
+}
+
+static int
+remoteDispatchDomainAttachDevice (struct qemud_client *client,
+                                  remote_message_header *req,
+                                  remote_domain_attach_device_args *args,
+                                  void *ret ATTRIBUTE_UNUSED)
+{
+    virDomainPtr dom;
+    CHECK_CONN(client);
+
+    dom = get_nonnull_domain (client->conn, args->dom);
+    if (dom == NULL) {
+        remoteDispatchError (client, req, "domain not found");
+        return -2;
+    }
+
+    if (virDomainAttachDevice (dom, args->xml) == -1)
+        return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainCreate (struct qemud_client *client,
+                            remote_message_header *req,
+                            remote_domain_create_args *args,
+                            void *ret ATTRIBUTE_UNUSED)
+{
+    virDomainPtr dom;
+    CHECK_CONN(client);
+
+    dom = get_nonnull_domain (client->conn, args->dom);
+    if (dom == NULL) {
+        remoteDispatchError (client, req, "domain not found");
+        return -2;
+    }
+
+    if (virDomainCreate (dom) == -1)
+        return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainCreateLinux (struct qemud_client *client,
+                                 remote_message_header *req,
+                                 remote_domain_create_linux_args *args,
+                                 remote_domain_create_linux_ret *ret)
+{
+    virDomainPtr dom;
+    CHECK_CONN(client);
+
+    dom = virDomainCreateLinux (client->conn, args->xml_desc, args->flags);
+    if (dom == NULL) return -1;
+
+    make_nonnull_domain (&ret->dom, dom);
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainDefineXml (struct qemud_client *client,
+                               remote_message_header *req,
+                               remote_domain_define_xml_args *args,
+                               remote_domain_define_xml_ret *ret)
+{
+    virDomainPtr dom;
+    CHECK_CONN(client);
+
+    dom = virDomainDefineXML (client->conn, args->xml);
+    if (dom == NULL) return -1;
+
+    make_nonnull_domain (&ret->dom, dom);
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainDestroy (struct qemud_client *client,
+                             remote_message_header *req,
+                             remote_domain_destroy_args *args,
+                             void *ret ATTRIBUTE_UNUSED)
+{
+    virDomainPtr dom;
+    CHECK_CONN(client);
+
+    dom = get_nonnull_domain (client->conn, args->dom);
+    if (dom == NULL) {
+        remoteDispatchError (client, req, "domain not found");
+        return -2;
+    }
+
+    if (virDomainDestroy (dom) == -1)
+        return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainDetachDevice (struct qemud_client *client,
+                                  remote_message_header *req,
+                                  remote_domain_detach_device_args *args,
+                                  void *ret ATTRIBUTE_UNUSED)
+{
+    virDomainPtr dom;
+    CHECK_CONN(client);
+
+    dom = get_nonnull_domain (client->conn, args->dom);
+    if (dom == NULL) {
+        remoteDispatchError (client, req, "domain not found");
+        return -2;
+    }
+
+    if (virDomainDetachDevice (dom, args->xml) == -1)
+        return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainDumpXml (struct qemud_client *client,
+                             remote_message_header *req,
+                             remote_domain_dump_xml_args *args,
+                             remote_domain_dump_xml_ret *ret)
+{
+    virDomainPtr dom;
+    CHECK_CONN(client);
+
+    dom = get_nonnull_domain (client->conn, args->dom);
+    if (dom == NULL) {
+        remoteDispatchError (client, req, "domain not found");
+        return -2;
+    }
+
+    /* remoteDispatchClientRequest will free this. */
+    ret->xml = virDomainGetXMLDesc (dom, args->flags);
+    if (!ret->xml) return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainGetAutostart (struct qemud_client *client,
+                                  remote_message_header *req,
+                                  remote_domain_get_autostart_args *args,
+                                  remote_domain_get_autostart_ret *ret)
+{
+    virDomainPtr dom;
+    CHECK_CONN(client);
+
+    dom = get_nonnull_domain (client->conn, args->dom);
+    if (dom == NULL) {
+        remoteDispatchError (client, req, "domain not found");
+        return -2;
+    }
+
+    if (virDomainGetAutostart (dom, &ret->autostart) == -1)
+        return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainGetInfo (struct qemud_client *client,
+                             remote_message_header *req,
+                             remote_domain_get_info_args *args,
+                             remote_domain_get_info_ret *ret)
+{
+    virDomainPtr dom;
+    virDomainInfo info;
+    CHECK_CONN(client);
+
+    dom = get_nonnull_domain (client->conn, args->dom);
+    if (dom == NULL) {
+        remoteDispatchError (client, req, "domain not found");
+        return -2;
+    }
+
+    if (virDomainGetInfo (dom, &info) == -1)
+        return -1;
+
+    ret->state = info.state;
+    ret->max_mem = info.maxMem;
+    ret->memory = info.memory;
+    ret->nr_virt_cpu = info.nrVirtCpu;
+    ret->cpu_time = info.cpuTime;
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainGetMaxMemory (struct qemud_client *client,
+                                  remote_message_header *req,
+                                  remote_domain_get_max_memory_args *args,
+                                  remote_domain_get_max_memory_ret *ret)
+{
+    virDomainPtr dom;
+    CHECK_CONN(client);
+
+    dom = get_nonnull_domain (client->conn, args->dom);
+    if (dom == NULL) {
+        remoteDispatchError (client, req, "domain not found");
+        return -2;
+    }
+
+    ret->memory = virDomainGetMaxMemory (dom);
+    if (ret->memory == 0) return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainGetMaxVcpus (struct qemud_client *client,
+                                 remote_message_header *req,
+                                 remote_domain_get_max_vcpus_args *args,
+                                 remote_domain_get_max_vcpus_ret *ret)
+{
+    virDomainPtr dom;
+    CHECK_CONN(client);
+
+    dom = get_nonnull_domain (client->conn, args->dom);
+    if (dom == NULL) {
+        remoteDispatchError (client, req, "domain not found");
+        return -2;
+    }
+
+    ret->num = virDomainGetMaxVcpus (dom);
+    if (ret->num == -1) return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainGetOsType (struct qemud_client *client,
+                               remote_message_header *req,
+                               remote_domain_get_os_type_args *args,
+                               remote_domain_get_os_type_ret *ret)
+{
+    virDomainPtr dom;
+    CHECK_CONN(client);
+
+    dom = get_nonnull_domain (client->conn, args->dom);
+    if (dom == NULL) {
+        remoteDispatchError (client, req, "domain not found");
+        return -2;
+    }
+
+    /* remoteDispatchClientRequest will free this */
+    ret->type = virDomainGetOSType (dom);
+    if (ret->type == NULL) return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainGetVcpus (struct qemud_client *client,
+                              remote_message_header *req,
+                              remote_domain_get_vcpus_args *args,
+                              remote_domain_get_vcpus_ret *ret)
+{
+    virDomainPtr dom;
+    virVcpuInfoPtr info;
+    unsigned char *cpumaps;
+    int info_len, i;
+    CHECK_CONN(client);
+
+    dom = get_nonnull_domain (client->conn, args->dom);
+    if (dom == NULL) {
+        remoteDispatchError (client, req, "domain not found");
+        return -2;
+    }
+
+    if (args->maxinfo > REMOTE_VCPUINFO_MAX) {
+        remoteDispatchError (client, req, "maxinfo > REMOTE_VCPUINFO_MAX");
+        return -2;
+    }
+
+    if (args->maplen > REMOTE_CPUMAPS_MAX) {
+        remoteDispatchError (client, req, "maplen > REMOTE_CPUMAPS_MAX");
+        return -2;
+    }
+
+    /* Allocate buffers to take the results. */
+    info = calloc (args->maxinfo, sizeof (virVcpuInfo));
+    cpumaps = calloc (args->maplen, sizeof (unsigned char));
+
+    info_len = virDomainGetVcpus (dom,
+                                  info, args->maxinfo,
+                                  cpumaps, args->maplen);
+    if (info_len == -1) return -1;
+
+    /* Allocate the return buffer for info. */
+    ret->info.info_len = info_len;
+    ret->info.info_val = calloc (info_len, sizeof (remote_vcpu_info));
+
+    for (i = 0; i < info_len; ++i) {
+        ret->info.info_val[i].number = info[i].number;
+        ret->info.info_val[i].state = info[i].state;
+        ret->info.info_val[i].cpu_time = info[i].cpuTime;
+        ret->info.info_val[i].cpu = info[i].cpu;
+    }
+
+    /* Don't need to allocate/copy the cpumaps if we make the reasonable
+     * assumption that unsigned char and char are the same size.
+     * Note that remoteDispatchClientRequest will free.
+     */
+    ret->cpumaps.cpumaps_len = args->maplen;
+    ret->cpumaps.cpumaps_val = (char *) cpumaps;
+
+    return 0;
+}
+
+static int
+remoteDispatchListDefinedDomains (struct qemud_client *client,
+                                  remote_message_header *req,
+                                  remote_list_defined_domains_args *args,
+                                  remote_list_defined_domains_ret *ret)
+{
+    CHECK_CONN(client);
+
+    if (args->maxnames > REMOTE_DOMAIN_NAME_LIST_MAX) {
+        remoteDispatchError (client, req,
+                             "maxnames > REMOTE_DOMAIN_NAME_LIST_MAX");
+        return -2;
+    }
+
+    /* Allocate return buffer. */
+    ret->names.names_val = calloc (args->maxnames, sizeof (char *));
+
+    ret->names.names_len =
+        virConnectListDefinedDomains (client->conn,
+                                      ret->names.names_val, args->maxnames);
+    if (ret->names.names_len == -1) return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainLookupById (struct qemud_client *client,
+                                remote_message_header *req,
+                                remote_domain_lookup_by_id_args *args,
+                                remote_domain_lookup_by_id_ret *ret)
+{
+    virDomainPtr dom;
+    CHECK_CONN(client);
+
+    dom = virDomainLookupByID (client->conn, args->id);
+    if (dom == NULL) return -1;
+
+    make_nonnull_domain (&ret->dom, dom);
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainLookupByName (struct qemud_client *client,
+                                  remote_message_header *req,
+                                  remote_domain_lookup_by_name_args *args,
+                                  remote_domain_lookup_by_name_ret *ret)
+{
+    virDomainPtr dom;
+    CHECK_CONN(client);
+
+    dom = virDomainLookupByName (client->conn, args->name);
+    if (dom == NULL) return -1;
+
+    make_nonnull_domain (&ret->dom, dom);
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainLookupByUuid (struct qemud_client *client,
+                                  remote_message_header *req,
+                                  remote_domain_lookup_by_uuid_args *args,
+                                  remote_domain_lookup_by_uuid_ret *ret)
+{
+    virDomainPtr dom;
+    CHECK_CONN(client);
+
+    dom = virDomainLookupByUUID (client->conn, (unsigned char *) args->uuid);
+    if (dom == NULL) return -1;
+
+    make_nonnull_domain (&ret->dom, dom);
+
+    return 0;
+}
+
+static int
+remoteDispatchNumOfDefinedDomains (struct qemud_client *client,
+                                   remote_message_header *req,
+                                   void *args ATTRIBUTE_UNUSED,
+                                   remote_num_of_defined_domains_ret *ret)
+{
+    CHECK_CONN(client);
+
+    ret->num = virConnectNumOfDefinedDomains (client->conn);
+    if (ret->num == -1) return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainPinVcpu (struct qemud_client *client,
+                             remote_message_header *req,
+                             remote_domain_pin_vcpu_args *args,
+                             void *ret ATTRIBUTE_UNUSED)
+{
+    virDomainPtr dom;
+    int rv;
+    CHECK_CONN(client);
+
+    dom = get_nonnull_domain (client->conn, args->dom);
+    if (dom == NULL) {
+        remoteDispatchError (client, req, "domain not found");
+        return -2;
+    }
+
+    if (args->cpumap.cpumap_len > REMOTE_CPUMAP_MAX) {
+        remoteDispatchError (client, req, "cpumap_len > REMOTE_CPUMAP_MAX");
+        return -2;
+    }
+
+    rv = virDomainPinVcpu (dom, args->vcpu,
+                           (unsigned char *) args->cpumap.cpumap_val,
+                           args->cpumap.cpumap_len);
+    if (rv == -1) return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainReboot (struct qemud_client *client,
+                            remote_message_header *req,
+                            remote_domain_reboot_args *args,
+                            void *ret ATTRIBUTE_UNUSED)
+{
+    virDomainPtr dom;
+    CHECK_CONN(client);
+
+    dom = get_nonnull_domain (client->conn, args->dom);
+    if (dom == NULL) {
+        remoteDispatchError (client, req, "domain not found");
+        return -2;
+    }
+
+    if (virDomainReboot (dom, args->flags) == -1)
+        return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainRestore (struct qemud_client *client,
+                             remote_message_header *req,
+                             remote_domain_restore_args *args,
+                             void *ret ATTRIBUTE_UNUSED)
+{
+    CHECK_CONN(client);
+
+    if (virDomainRestore (client->conn, args->from) == -1)
+        return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainResume (struct qemud_client *client,
+                            remote_message_header *req,
+                            remote_domain_resume_args *args,
+                            void *ret ATTRIBUTE_UNUSED)
+{
+    virDomainPtr dom;
+    CHECK_CONN(client);
+
+    dom = get_nonnull_domain (client->conn, args->dom);
+    if (dom == NULL) {
+        remoteDispatchError (client, req, "domain not found");
+        return -2;
+    }
+
+    if (virDomainResume (dom) == -1)
+        return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainSave (struct qemud_client *client,
+                          remote_message_header *req,
+                          remote_domain_save_args *args,
+                          void *ret ATTRIBUTE_UNUSED)
+{
+    virDomainPtr dom;
+    CHECK_CONN(client);
+
+    dom = get_nonnull_domain (client->conn, args->dom);
+    if (dom == NULL) {
+        remoteDispatchError (client, req, "domain not found");
+        return -2;
+    }
+
+    if (virDomainSave (dom, args->to) == -1)
+        return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainCoreDump (struct qemud_client *client,
+                              remote_message_header *req,
+                              remote_domain_core_dump_args *args,
+                              void *ret ATTRIBUTE_UNUSED)
+{
+    virDomainPtr dom;
+    CHECK_CONN(client);
+
+    dom = get_nonnull_domain (client->conn, args->dom);
+    if (dom == NULL) {
+        remoteDispatchError (client, req, "domain not found");
+        return -2;
+    }
+
+    if (virDomainCoreDump (dom, args->to, args->flags) == -1)
+        return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainSetAutostart (struct qemud_client *client,
+                                  remote_message_header *req,
+                                  remote_domain_set_autostart_args *args,
+                                  void *ret ATTRIBUTE_UNUSED)
+{
+    virDomainPtr dom;
+    CHECK_CONN(client);
+
+    dom = get_nonnull_domain (client->conn, args->dom);
+    if (dom == NULL) {
+        remoteDispatchError (client, req, "domain not found");
+        return -2;
+    }
+
+    if (virDomainSetAutostart (dom, args->autostart) == -1)
+        return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainSetMaxMemory (struct qemud_client *client,
+                                  remote_message_header *req,
+                                  remote_domain_set_max_memory_args *args,
+                                  void *ret ATTRIBUTE_UNUSED)
+{
+    virDomainPtr dom;
+    CHECK_CONN(client);
+
+    dom = get_nonnull_domain (client->conn, args->dom);
+    if (dom == NULL) {
+        remoteDispatchError (client, req, "domain not found");
+        return -2;
+    }
+
+    if (virDomainSetMaxMemory (dom, args->memory) == -1)
+        return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainSetMemory (struct qemud_client *client,
+                               remote_message_header *req,
+                               remote_domain_set_memory_args *args,
+                               void *ret ATTRIBUTE_UNUSED)
+{
+    virDomainPtr dom;
+    CHECK_CONN(client);
+
+    dom = get_nonnull_domain (client->conn, args->dom);
+    if (dom == NULL) {
+        remoteDispatchError (client, req, "domain not found");
+        return -2;
+    }
+
+    if (virDomainSetMemory (dom, args->memory) == -1)
+        return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainSetVcpus (struct qemud_client *client,
+                              remote_message_header *req,
+                              remote_domain_set_vcpus_args *args,
+                              void *ret ATTRIBUTE_UNUSED)
+{
+    virDomainPtr dom;
+    CHECK_CONN(client);
+
+    dom = get_nonnull_domain (client->conn, args->dom);
+    if (dom == NULL) {
+        remoteDispatchError (client, req, "domain not found");
+        return -2;
+    }
+
+    if (virDomainSetVcpus (dom, args->nvcpus) == -1)
+        return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainShutdown (struct qemud_client *client,
+                              remote_message_header *req,
+                              remote_domain_shutdown_args *args,
+                              void *ret ATTRIBUTE_UNUSED)
+{
+    virDomainPtr dom;
+    CHECK_CONN(client);
+
+    dom = get_nonnull_domain (client->conn, args->dom);
+    if (dom == NULL) {
+        remoteDispatchError (client, req, "domain not found");
+        return -2;
+    }
+
+    if (virDomainShutdown (dom) == -1)
+        return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainSuspend (struct qemud_client *client,
+                             remote_message_header *req,
+                             remote_domain_suspend_args *args,
+                             void *ret ATTRIBUTE_UNUSED)
+{
+    virDomainPtr dom;
+    CHECK_CONN(client);
+
+    dom = get_nonnull_domain (client->conn, args->dom);
+    if (dom == NULL) {
+        remoteDispatchError (client, req, "domain not found");
+        return -2;
+    }
+
+    if (virDomainSuspend (dom) == -1)
+        return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchDomainUndefine (struct qemud_client *client,
+                              remote_message_header *req,
+                              remote_domain_undefine_args *args,
+                              void *ret ATTRIBUTE_UNUSED)
+{
+    virDomainPtr dom;
+    CHECK_CONN(client);
+
+    dom = get_nonnull_domain (client->conn, args->dom);
+    if (dom == NULL) {
+        remoteDispatchError (client, req, "domain not found");
+        return -2;
+    }
+
+    if (virDomainUndefine (dom) == -1)
+        return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchListDefinedNetworks (struct qemud_client *client,
+                                   remote_message_header *req,
+                                   remote_list_defined_networks_args *args,
+                                   remote_list_defined_networks_ret *ret)
+{
+    CHECK_CONN(client);
+
+    if (args->maxnames > REMOTE_NETWORK_NAME_LIST_MAX) {
+        remoteDispatchError (client, req,
+                             "maxnames > REMOTE_NETWORK_NAME_LIST_MAX");
+        return -2;
+    }
+
+    /* Allocate return buffer. */
+    ret->names.names_val = calloc (args->maxnames, sizeof (char *));
+
+    ret->names.names_len =
+        virConnectListDefinedNetworks (client->conn,
+                                       ret->names.names_val, args->maxnames);
+    if (ret->names.names_len == -1) return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchListDomains (struct qemud_client *client,
+                           remote_message_header *req,
+                           remote_list_domains_args *args,
+                           remote_list_domains_ret *ret)
+{
+    CHECK_CONN(client);
+
+    if (args->maxids > REMOTE_DOMAIN_ID_LIST_MAX) {
+        remoteDispatchError (client, req,
+                             "maxids > REMOTE_DOMAIN_ID_LIST_MAX");
+        return -2;
+    }
+
+    /* Allocate return buffer. */
+    ret->ids.ids_val = calloc (args->maxids, sizeof (int));
+
+    ret->ids.ids_len = virConnectListDomains (client->conn,
+                                              ret->ids.ids_val, args->maxids);
+    if (ret->ids.ids_len == -1) return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchListNetworks (struct qemud_client *client,
+                            remote_message_header *req,
+                            remote_list_networks_args *args,
+                            remote_list_networks_ret *ret)
+{
+    CHECK_CONN(client);
+
+    if (args->maxnames > REMOTE_NETWORK_NAME_LIST_MAX) {
+        remoteDispatchError (client, req,
+                             "maxnames > REMOTE_NETWORK_NAME_LIST_MAX");
+        return -2;
+    }
+
+    /* Allocate return buffer. */
+    ret->names.names_val = calloc (args->maxnames, sizeof (char *));
+
+    ret->names.names_len =
+        virConnectListNetworks (client->conn,
+                                ret->names.names_val, args->maxnames);
+    if (ret->names.names_len == -1) return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchNetworkCreate (struct qemud_client *client,
+                             remote_message_header *req,
+                             remote_network_create_args *args,
+                             void *ret ATTRIBUTE_UNUSED)
+{
+    virNetworkPtr net;
+    CHECK_CONN(client);
+
+    net = get_nonnull_network (client->conn, args->net);
+    if (net == NULL) {
+        remoteDispatchError (client, req, "network not found");
+        return -2;
+    }
+
+    if (virNetworkCreate (net) == -1)
+        return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchNetworkCreateXml (struct qemud_client *client,
+                                remote_message_header *req,
+                                remote_network_create_xml_args *args,
+                                remote_network_create_xml_ret *ret)
+{
+    virNetworkPtr net;
+    CHECK_CONN(client);
+
+    net = virNetworkCreateXML (client->conn, args->xml);
+    if (net == NULL) return -1;
+
+    make_nonnull_network (&ret->net, net);
+
+    return 0;
+}
+
+static int
+remoteDispatchNetworkDefineXml (struct qemud_client *client,
+                                remote_message_header *req,
+                                remote_network_define_xml_args *args,
+                                remote_network_define_xml_ret *ret)
+{
+    virNetworkPtr net;
+    CHECK_CONN(client);
+
+    net = virNetworkDefineXML (client->conn, args->xml);
+    if (net == NULL) return -1;
+
+    make_nonnull_network (&ret->net, net);
+
+    return 0;
+}
+
+static int
+remoteDispatchNetworkDestroy (struct qemud_client *client,
+                              remote_message_header *req,
+                              remote_network_destroy_args *args,
+                              void *ret ATTRIBUTE_UNUSED)
+{
+    virNetworkPtr net;
+    CHECK_CONN(client);
+
+    net = get_nonnull_network (client->conn, args->net);
+    if (net == NULL) {
+        remoteDispatchError (client, req, "network not found");
+        return -2;
+    }
+
+    if (virNetworkDestroy (net) == -1)
+        return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchNetworkDumpXml (struct qemud_client *client,
+                              remote_message_header *req,
+                              remote_network_dump_xml_args *args,
+                              remote_network_dump_xml_ret *ret)
+{
+    virNetworkPtr net;
+    CHECK_CONN(client);
+
+    net = get_nonnull_network (client->conn, args->net);
+    if (net == NULL) {
+        remoteDispatchError (client, req, "network not found");
+        return -2;
+    }
+
+    /* remoteDispatchClientRequest will free this. */
+    ret->xml = virNetworkGetXMLDesc (net, args->flags);
+    if (!ret->xml) return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchNetworkGetAutostart (struct qemud_client *client,
+                                   remote_message_header *req,
+                                   remote_network_get_autostart_args *args,
+                                   remote_network_get_autostart_ret *ret)
+{
+    virNetworkPtr net;
+    CHECK_CONN(client);
+
+    net = get_nonnull_network (client->conn, args->net);
+    if (net == NULL) {
+        remoteDispatchError (client, req, "network not found");
+        return -2;
+    }
+
+    if (virNetworkGetAutostart (net, &ret->autostart) == -1)
+        return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchNetworkGetBridgeName (struct qemud_client *client,
+                                    remote_message_header *req,
+                                    remote_network_get_bridge_name_args *args,
+                                    remote_network_get_bridge_name_ret *ret)
+{
+    virNetworkPtr net;
+    CHECK_CONN(client);
+
+    net = get_nonnull_network (client->conn, args->net);
+    if (net == NULL) {
+        remoteDispatchError (client, req, "network not found");
+        return -2;
+    }
+
+    /* remoteDispatchClientRequest will free this. */
+    ret->name = virNetworkGetBridgeName (net);
+    if (!ret->name) return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchNetworkLookupByName (struct qemud_client *client,
+                                   remote_message_header *req,
+                                   remote_network_lookup_by_name_args *args,
+                                   remote_network_lookup_by_name_ret *ret)
+{
+    virNetworkPtr net;
+    CHECK_CONN(client);
+
+    net = virNetworkLookupByName (client->conn, args->name);
+    if (net == NULL) return -1;
+
+    make_nonnull_network (&ret->net, net);
+
+    return 0;
+}
+
+static int
+remoteDispatchNetworkLookupByUuid (struct qemud_client *client,
+                                   remote_message_header *req,
+                                   remote_network_lookup_by_uuid_args *args,
+                                   remote_network_lookup_by_uuid_ret *ret)
+{
+    virNetworkPtr net;
+    CHECK_CONN(client);
+
+    net = virNetworkLookupByUUID (client->conn, (unsigned char *) args->uuid);
+    if (net == NULL) return -1;
+
+    make_nonnull_network (&ret->net, net);
+
+    return 0;
+}
+
+static int
+remoteDispatchNetworkSetAutostart (struct qemud_client *client,
+                                   remote_message_header *req,
+                                   remote_network_set_autostart_args *args,
+                                   void *ret ATTRIBUTE_UNUSED)
+{
+    virNetworkPtr net;
+    CHECK_CONN(client);
+
+    net = get_nonnull_network (client->conn, args->net);
+    if (net == NULL) {
+        remoteDispatchError (client, req, "network not found");
+        return -2;
+    }
+
+    if (virNetworkSetAutostart (net, args->autostart) == -1)
+        return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchNetworkUndefine (struct qemud_client *client,
+                               remote_message_header *req,
+                               remote_network_undefine_args *args,
+                               void *ret ATTRIBUTE_UNUSED)
+{
+    virNetworkPtr net;
+    CHECK_CONN(client);
+
+    net = get_nonnull_network (client->conn, args->net);
+    if (net == NULL) {
+        remoteDispatchError (client, req, "network not found");
+        return -2;
+    }
+
+    if (virNetworkUndefine (net) == -1)
+        return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchNumOfDefinedNetworks (struct qemud_client *client,
+                                    remote_message_header *req,
+                                    void *args ATTRIBUTE_UNUSED,
+                                    remote_num_of_defined_networks_ret *ret)
+{
+    CHECK_CONN(client);
+
+    ret->num = virConnectNumOfDefinedNetworks (client->conn);
+    if (ret->num == -1) return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchNumOfDomains (struct qemud_client *client,
+                            remote_message_header *req,
+                            void *args ATTRIBUTE_UNUSED,
+                            remote_num_of_domains_ret *ret)
+{
+    CHECK_CONN(client);
+
+    ret->num = virConnectNumOfDomains (client->conn);
+    if (ret->num == -1) return -1;
+
+    return 0;
+}
+
+static int
+remoteDispatchNumOfNetworks (struct qemud_client *client,
+                             remote_message_header *req,
+                             void *args ATTRIBUTE_UNUSED,
+                             remote_num_of_networks_ret *ret)
+{
+    CHECK_CONN(client);
+
+    ret->num = virConnectNumOfNetworks (client->conn);
+    if (ret->num == -1) return -1;
+
+    return 0;
+}
+
+/*----- Helpers. -----*/
+
+/* get_nonnull_domain and get_nonnull_network turn an on-wire
+ * (name, uuid) pair into virDomainPtr or virNetworkPtr object.
+ * virDomainPtr or virNetworkPtr cannot be NULL.
+ *
+ * NB. If these return NULL then the caller must return an error.
+ */
+static virDomainPtr
+get_nonnull_domain (virConnectPtr conn, remote_nonnull_domain domain)
+{
+    virDomainPtr dom;
+    dom = virGetDomain (conn, domain.name, BAD_CAST domain.uuid);
+    /* Should we believe the domain.id sent by the client?  Maybe
+     * this should be a check rather than an assignment? XXX
+     */
+    if (dom) dom->id = domain.id;
+    return dom;
+}
+
+static virNetworkPtr
+get_nonnull_network (virConnectPtr conn, remote_nonnull_network network)
+{
+    return virGetNetwork (conn, network.name, BAD_CAST network.uuid);
+}
+
+/* Make remote_nonnull_domain and remote_nonnull_network. */
+static void
+make_nonnull_domain (remote_nonnull_domain *dom_dst, virDomainPtr dom_src)
+{
+    dom_dst->id = dom_src->id;
+    dom_dst->name = strdup (dom_src->name);
+    memcpy (dom_dst->uuid, dom_src->uuid, VIR_UUID_BUFLEN);
+}
+
+static void
+make_nonnull_network (remote_nonnull_network *net_dst, virNetworkPtr net_src)
+{
+    net_dst->name = strdup (net_src->name);
+    memcpy (net_dst->uuid, net_src->uuid, VIR_UUID_BUFLEN);
+}
+
+/*
+ * Local variables:
+ *  indent-tabs-mode: nil
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 4
+ * End:
+ */
diff --git a/qemud/remote_dispatch_localvars.h b/qemud/remote_dispatch_localvars.h
new file mode 100644 (file)
index 0000000..12543d5
--- /dev/null
@@ -0,0 +1,82 @@
+/* Automatically generated by remote_generate_stubs.pl.
+ * Do not edit this file.  Any changes you make will be lost.
+ */
+
+remote_network_lookup_by_name_args lv_remote_network_lookup_by_name_args;
+remote_network_lookup_by_name_ret lv_remote_network_lookup_by_name_ret;
+remote_domain_lookup_by_uuid_args lv_remote_domain_lookup_by_uuid_args;
+remote_domain_lookup_by_uuid_ret lv_remote_domain_lookup_by_uuid_ret;
+remote_num_of_defined_domains_ret lv_remote_num_of_defined_domains_ret;
+remote_domain_detach_device_args lv_remote_domain_detach_device_args;
+remote_domain_save_args lv_remote_domain_save_args;
+remote_domain_shutdown_args lv_remote_domain_shutdown_args;
+remote_list_defined_domains_args lv_remote_list_defined_domains_args;
+remote_list_defined_domains_ret lv_remote_list_defined_domains_ret;
+remote_get_capabilities_ret lv_remote_get_capabilities_ret;
+remote_domain_set_max_memory_args lv_remote_domain_set_max_memory_args;
+remote_domain_undefine_args lv_remote_domain_undefine_args;
+remote_domain_get_os_type_args lv_remote_domain_get_os_type_args;
+remote_domain_get_os_type_ret lv_remote_domain_get_os_type_ret;
+remote_domain_get_autostart_args lv_remote_domain_get_autostart_args;
+remote_domain_get_autostart_ret lv_remote_domain_get_autostart_ret;
+remote_domain_set_vcpus_args lv_remote_domain_set_vcpus_args;
+remote_network_undefine_args lv_remote_network_undefine_args;
+remote_domain_create_args lv_remote_domain_create_args;
+remote_domain_suspend_args lv_remote_domain_suspend_args;
+remote_get_version_ret lv_remote_get_version_ret;
+remote_network_destroy_args lv_remote_network_destroy_args;
+remote_network_set_autostart_args lv_remote_network_set_autostart_args;
+remote_network_get_autostart_args lv_remote_network_get_autostart_args;
+remote_network_get_autostart_ret lv_remote_network_get_autostart_ret;
+remote_domain_pin_vcpu_args lv_remote_domain_pin_vcpu_args;
+remote_list_defined_networks_args lv_remote_list_defined_networks_args;
+remote_list_defined_networks_ret lv_remote_list_defined_networks_ret;
+remote_network_create_xml_args lv_remote_network_create_xml_args;
+remote_network_create_xml_ret lv_remote_network_create_xml_ret;
+remote_domain_core_dump_args lv_remote_domain_core_dump_args;
+remote_open_args lv_remote_open_args;
+remote_list_domains_args lv_remote_list_domains_args;
+remote_list_domains_ret lv_remote_list_domains_ret;
+remote_network_define_xml_args lv_remote_network_define_xml_args;
+remote_network_define_xml_ret lv_remote_network_define_xml_ret;
+remote_domain_get_max_memory_args lv_remote_domain_get_max_memory_args;
+remote_domain_get_max_memory_ret lv_remote_domain_get_max_memory_ret;
+remote_get_type_ret lv_remote_get_type_ret;
+remote_num_of_domains_ret lv_remote_num_of_domains_ret;
+remote_list_networks_args lv_remote_list_networks_args;
+remote_list_networks_ret lv_remote_list_networks_ret;
+remote_network_dump_xml_args lv_remote_network_dump_xml_args;
+remote_network_dump_xml_ret lv_remote_network_dump_xml_ret;
+remote_domain_set_autostart_args lv_remote_domain_set_autostart_args;
+remote_domain_reboot_args lv_remote_domain_reboot_args;
+remote_domain_set_memory_args lv_remote_domain_set_memory_args;
+remote_domain_create_linux_args lv_remote_domain_create_linux_args;
+remote_domain_create_linux_ret lv_remote_domain_create_linux_ret;
+remote_domain_attach_device_args lv_remote_domain_attach_device_args;
+remote_domain_lookup_by_id_args lv_remote_domain_lookup_by_id_args;
+remote_domain_lookup_by_id_ret lv_remote_domain_lookup_by_id_ret;
+remote_num_of_networks_ret lv_remote_num_of_networks_ret;
+remote_domain_restore_args lv_remote_domain_restore_args;
+remote_domain_get_max_vcpus_args lv_remote_domain_get_max_vcpus_args;
+remote_domain_get_max_vcpus_ret lv_remote_domain_get_max_vcpus_ret;
+remote_domain_get_info_args lv_remote_domain_get_info_args;
+remote_domain_get_info_ret lv_remote_domain_get_info_ret;
+remote_network_create_args lv_remote_network_create_args;
+remote_num_of_defined_networks_ret lv_remote_num_of_defined_networks_ret;
+remote_domain_lookup_by_name_args lv_remote_domain_lookup_by_name_args;
+remote_domain_lookup_by_name_ret lv_remote_domain_lookup_by_name_ret;
+remote_network_lookup_by_uuid_args lv_remote_network_lookup_by_uuid_args;
+remote_network_lookup_by_uuid_ret lv_remote_network_lookup_by_uuid_ret;
+remote_domain_resume_args lv_remote_domain_resume_args;
+remote_network_get_bridge_name_args lv_remote_network_get_bridge_name_args;
+remote_network_get_bridge_name_ret lv_remote_network_get_bridge_name_ret;
+remote_domain_destroy_args lv_remote_domain_destroy_args;
+remote_domain_define_xml_args lv_remote_domain_define_xml_args;
+remote_domain_define_xml_ret lv_remote_domain_define_xml_ret;
+remote_domain_get_vcpus_args lv_remote_domain_get_vcpus_args;
+remote_domain_get_vcpus_ret lv_remote_domain_get_vcpus_ret;
+remote_domain_dump_xml_args lv_remote_domain_dump_xml_args;
+remote_domain_dump_xml_ret lv_remote_domain_dump_xml_ret;
+remote_get_max_vcpus_args lv_remote_get_max_vcpus_args;
+remote_get_max_vcpus_ret lv_remote_get_max_vcpus_ret;
+remote_node_get_info_ret lv_remote_node_get_info_ret;
diff --git a/qemud/remote_dispatch_proc_switch.h b/qemud/remote_dispatch_proc_switch.h
new file mode 100644 (file)
index 0000000..900af3e
--- /dev/null
@@ -0,0 +1,403 @@
+/* Automatically generated by remote_generate_stubs.pl.
+ * Do not edit this file.  Any changes you make will be lost.
+ */
+
+case REMOTE_PROC_CLOSE:
+       fn = (dispatch_fn) remoteDispatchClose;
+       break;
+case REMOTE_PROC_DOMAIN_ATTACH_DEVICE:
+       fn = (dispatch_fn) remoteDispatchDomainAttachDevice;
+       args_filter = (xdrproc_t) xdr_remote_domain_attach_device_args;
+       args = (char *) &lv_remote_domain_attach_device_args;
+       memset (&lv_remote_domain_attach_device_args, 0, sizeof lv_remote_domain_attach_device_args);
+       break;
+case REMOTE_PROC_DOMAIN_CORE_DUMP:
+       fn = (dispatch_fn) remoteDispatchDomainCoreDump;
+       args_filter = (xdrproc_t) xdr_remote_domain_core_dump_args;
+       args = (char *) &lv_remote_domain_core_dump_args;
+       memset (&lv_remote_domain_core_dump_args, 0, sizeof lv_remote_domain_core_dump_args);
+       break;
+case REMOTE_PROC_DOMAIN_CREATE:
+       fn = (dispatch_fn) remoteDispatchDomainCreate;
+       args_filter = (xdrproc_t) xdr_remote_domain_create_args;
+       args = (char *) &lv_remote_domain_create_args;
+       memset (&lv_remote_domain_create_args, 0, sizeof lv_remote_domain_create_args);
+       break;
+case REMOTE_PROC_DOMAIN_CREATE_LINUX:
+       fn = (dispatch_fn) remoteDispatchDomainCreateLinux;
+       args_filter = (xdrproc_t) xdr_remote_domain_create_linux_args;
+       args = (char *) &lv_remote_domain_create_linux_args;
+       memset (&lv_remote_domain_create_linux_args, 0, sizeof lv_remote_domain_create_linux_args);
+       ret_filter = (xdrproc_t) xdr_remote_domain_create_linux_ret;
+       ret = (char *) &lv_remote_domain_create_linux_ret;
+       memset (&lv_remote_domain_create_linux_ret, 0, sizeof lv_remote_domain_create_linux_ret);
+       break;
+case REMOTE_PROC_DOMAIN_DEFINE_XML:
+       fn = (dispatch_fn) remoteDispatchDomainDefineXml;
+       args_filter = (xdrproc_t) xdr_remote_domain_define_xml_args;
+       args = (char *) &lv_remote_domain_define_xml_args;
+       memset (&lv_remote_domain_define_xml_args, 0, sizeof lv_remote_domain_define_xml_args);
+       ret_filter = (xdrproc_t) xdr_remote_domain_define_xml_ret;
+       ret = (char *) &lv_remote_domain_define_xml_ret;
+       memset (&lv_remote_domain_define_xml_ret, 0, sizeof lv_remote_domain_define_xml_ret);
+       break;
+case REMOTE_PROC_DOMAIN_DESTROY:
+       fn = (dispatch_fn) remoteDispatchDomainDestroy;
+       args_filter = (xdrproc_t) xdr_remote_domain_destroy_args;
+       args = (char *) &lv_remote_domain_destroy_args;
+       memset (&lv_remote_domain_destroy_args, 0, sizeof lv_remote_domain_destroy_args);
+       break;
+case REMOTE_PROC_DOMAIN_DETACH_DEVICE:
+       fn = (dispatch_fn) remoteDispatchDomainDetachDevice;
+       args_filter = (xdrproc_t) xdr_remote_domain_detach_device_args;
+       args = (char *) &lv_remote_domain_detach_device_args;
+       memset (&lv_remote_domain_detach_device_args, 0, sizeof lv_remote_domain_detach_device_args);
+       break;
+case REMOTE_PROC_DOMAIN_DUMP_XML:
+       fn = (dispatch_fn) remoteDispatchDomainDumpXml;
+       args_filter = (xdrproc_t) xdr_remote_domain_dump_xml_args;
+       args = (char *) &lv_remote_domain_dump_xml_args;
+       memset (&lv_remote_domain_dump_xml_args, 0, sizeof lv_remote_domain_dump_xml_args);
+       ret_filter = (xdrproc_t) xdr_remote_domain_dump_xml_ret;
+       ret = (char *) &lv_remote_domain_dump_xml_ret;
+       memset (&lv_remote_domain_dump_xml_ret, 0, sizeof lv_remote_domain_dump_xml_ret);
+       break;
+case REMOTE_PROC_DOMAIN_GET_AUTOSTART:
+       fn = (dispatch_fn) remoteDispatchDomainGetAutostart;
+       args_filter = (xdrproc_t) xdr_remote_domain_get_autostart_args;
+       args = (char *) &lv_remote_domain_get_autostart_args;
+       memset (&lv_remote_domain_get_autostart_args, 0, sizeof lv_remote_domain_get_autostart_args);
+       ret_filter = (xdrproc_t) xdr_remote_domain_get_autostart_ret;
+       ret = (char *) &lv_remote_domain_get_autostart_ret;
+       memset (&lv_remote_domain_get_autostart_ret, 0, sizeof lv_remote_domain_get_autostart_ret);
+       break;
+case REMOTE_PROC_DOMAIN_GET_INFO:
+       fn = (dispatch_fn) remoteDispatchDomainGetInfo;
+       args_filter = (xdrproc_t) xdr_remote_domain_get_info_args;
+       args = (char *) &lv_remote_domain_get_info_args;
+       memset (&lv_remote_domain_get_info_args, 0, sizeof lv_remote_domain_get_info_args);
+       ret_filter = (xdrproc_t) xdr_remote_domain_get_info_ret;
+       ret = (char *) &lv_remote_domain_get_info_ret;
+       memset (&lv_remote_domain_get_info_ret, 0, sizeof lv_remote_domain_get_info_ret);
+       break;
+case REMOTE_PROC_DOMAIN_GET_MAX_MEMORY:
+       fn = (dispatch_fn) remoteDispatchDomainGetMaxMemory;
+       args_filter = (xdrproc_t) xdr_remote_domain_get_max_memory_args;
+       args = (char *) &lv_remote_domain_get_max_memory_args;
+       memset (&lv_remote_domain_get_max_memory_args, 0, sizeof lv_remote_domain_get_max_memory_args);
+       ret_filter = (xdrproc_t) xdr_remote_domain_get_max_memory_ret;
+       ret = (char *) &lv_remote_domain_get_max_memory_ret;
+       memset (&lv_remote_domain_get_max_memory_ret, 0, sizeof lv_remote_domain_get_max_memory_ret);
+       break;
+case REMOTE_PROC_DOMAIN_GET_MAX_VCPUS:
+       fn = (dispatch_fn) remoteDispatchDomainGetMaxVcpus;
+       args_filter = (xdrproc_t) xdr_remote_domain_get_max_vcpus_args;
+       args = (char *) &lv_remote_domain_get_max_vcpus_args;
+       memset (&lv_remote_domain_get_max_vcpus_args, 0, sizeof lv_remote_domain_get_max_vcpus_args);
+       ret_filter = (xdrproc_t) xdr_remote_domain_get_max_vcpus_ret;
+       ret = (char *) &lv_remote_domain_get_max_vcpus_ret;
+       memset (&lv_remote_domain_get_max_vcpus_ret, 0, sizeof lv_remote_domain_get_max_vcpus_ret);
+       break;
+case REMOTE_PROC_DOMAIN_GET_OS_TYPE:
+       fn = (dispatch_fn) remoteDispatchDomainGetOsType;
+       args_filter = (xdrproc_t) xdr_remote_domain_get_os_type_args;
+       args = (char *) &lv_remote_domain_get_os_type_args;
+       memset (&lv_remote_domain_get_os_type_args, 0, sizeof lv_remote_domain_get_os_type_args);
+       ret_filter = (xdrproc_t) xdr_remote_domain_get_os_type_ret;
+       ret = (char *) &lv_remote_domain_get_os_type_ret;
+       memset (&lv_remote_domain_get_os_type_ret, 0, sizeof lv_remote_domain_get_os_type_ret);
+       break;
+case REMOTE_PROC_DOMAIN_GET_VCPUS:
+       fn = (dispatch_fn) remoteDispatchDomainGetVcpus;
+       args_filter = (xdrproc_t) xdr_remote_domain_get_vcpus_args;
+       args = (char *) &lv_remote_domain_get_vcpus_args;
+       memset (&lv_remote_domain_get_vcpus_args, 0, sizeof lv_remote_domain_get_vcpus_args);
+       ret_filter = (xdrproc_t) xdr_remote_domain_get_vcpus_ret;
+       ret = (char *) &lv_remote_domain_get_vcpus_ret;
+       memset (&lv_remote_domain_get_vcpus_ret, 0, sizeof lv_remote_domain_get_vcpus_ret);
+       break;
+case REMOTE_PROC_DOMAIN_LOOKUP_BY_ID:
+       fn = (dispatch_fn) remoteDispatchDomainLookupById;
+       args_filter = (xdrproc_t) xdr_remote_domain_lookup_by_id_args;
+       args = (char *) &lv_remote_domain_lookup_by_id_args;
+       memset (&lv_remote_domain_lookup_by_id_args, 0, sizeof lv_remote_domain_lookup_by_id_args);
+       ret_filter = (xdrproc_t) xdr_remote_domain_lookup_by_id_ret;
+       ret = (char *) &lv_remote_domain_lookup_by_id_ret;
+       memset (&lv_remote_domain_lookup_by_id_ret, 0, sizeof lv_remote_domain_lookup_by_id_ret);
+       break;
+case REMOTE_PROC_DOMAIN_LOOKUP_BY_NAME:
+       fn = (dispatch_fn) remoteDispatchDomainLookupByName;
+       args_filter = (xdrproc_t) xdr_remote_domain_lookup_by_name_args;
+       args = (char *) &lv_remote_domain_lookup_by_name_args;
+       memset (&lv_remote_domain_lookup_by_name_args, 0, sizeof lv_remote_domain_lookup_by_name_args);
+       ret_filter = (xdrproc_t) xdr_remote_domain_lookup_by_name_ret;
+       ret = (char *) &lv_remote_domain_lookup_by_name_ret;
+       memset (&lv_remote_domain_lookup_by_name_ret, 0, sizeof lv_remote_domain_lookup_by_name_ret);
+       break;
+case REMOTE_PROC_DOMAIN_LOOKUP_BY_UUID:
+       fn = (dispatch_fn) remoteDispatchDomainLookupByUuid;
+       args_filter = (xdrproc_t) xdr_remote_domain_lookup_by_uuid_args;
+       args = (char *) &lv_remote_domain_lookup_by_uuid_args;
+       memset (&lv_remote_domain_lookup_by_uuid_args, 0, sizeof lv_remote_domain_lookup_by_uuid_args);
+       ret_filter = (xdrproc_t) xdr_remote_domain_lookup_by_uuid_ret;
+       ret = (char *) &lv_remote_domain_lookup_by_uuid_ret;
+       memset (&lv_remote_domain_lookup_by_uuid_ret, 0, sizeof lv_remote_domain_lookup_by_uuid_ret);
+       break;
+case REMOTE_PROC_DOMAIN_PIN_VCPU:
+       fn = (dispatch_fn) remoteDispatchDomainPinVcpu;
+       args_filter = (xdrproc_t) xdr_remote_domain_pin_vcpu_args;
+       args = (char *) &lv_remote_domain_pin_vcpu_args;
+       memset (&lv_remote_domain_pin_vcpu_args, 0, sizeof lv_remote_domain_pin_vcpu_args);
+       break;
+case REMOTE_PROC_DOMAIN_REBOOT:
+       fn = (dispatch_fn) remoteDispatchDomainReboot;
+       args_filter = (xdrproc_t) xdr_remote_domain_reboot_args;
+       args = (char *) &lv_remote_domain_reboot_args;
+       memset (&lv_remote_domain_reboot_args, 0, sizeof lv_remote_domain_reboot_args);
+       break;
+case REMOTE_PROC_DOMAIN_RESTORE:
+       fn = (dispatch_fn) remoteDispatchDomainRestore;
+       args_filter = (xdrproc_t) xdr_remote_domain_restore_args;
+       args = (char *) &lv_remote_domain_restore_args;
+       memset (&lv_remote_domain_restore_args, 0, sizeof lv_remote_domain_restore_args);
+       break;
+case REMOTE_PROC_DOMAIN_RESUME:
+       fn = (dispatch_fn) remoteDispatchDomainResume;
+       args_filter = (xdrproc_t) xdr_remote_domain_resume_args;
+       args = (char *) &lv_remote_domain_resume_args;
+       memset (&lv_remote_domain_resume_args, 0, sizeof lv_remote_domain_resume_args);
+       break;
+case REMOTE_PROC_DOMAIN_SAVE:
+       fn = (dispatch_fn) remoteDispatchDomainSave;
+       args_filter = (xdrproc_t) xdr_remote_domain_save_args;
+       args = (char *) &lv_remote_domain_save_args;
+       memset (&lv_remote_domain_save_args, 0, sizeof lv_remote_domain_save_args);
+       break;
+case REMOTE_PROC_DOMAIN_SET_AUTOSTART:
+       fn = (dispatch_fn) remoteDispatchDomainSetAutostart;
+       args_filter = (xdrproc_t) xdr_remote_domain_set_autostart_args;
+       args = (char *) &lv_remote_domain_set_autostart_args;
+       memset (&lv_remote_domain_set_autostart_args, 0, sizeof lv_remote_domain_set_autostart_args);
+       break;
+case REMOTE_PROC_DOMAIN_SET_MAX_MEMORY:
+       fn = (dispatch_fn) remoteDispatchDomainSetMaxMemory;
+       args_filter = (xdrproc_t) xdr_remote_domain_set_max_memory_args;
+       args = (char *) &lv_remote_domain_set_max_memory_args;
+       memset (&lv_remote_domain_set_max_memory_args, 0, sizeof lv_remote_domain_set_max_memory_args);
+       break;
+case REMOTE_PROC_DOMAIN_SET_MEMORY:
+       fn = (dispatch_fn) remoteDispatchDomainSetMemory;
+       args_filter = (xdrproc_t) xdr_remote_domain_set_memory_args;
+       args = (char *) &lv_remote_domain_set_memory_args;
+       memset (&lv_remote_domain_set_memory_args, 0, sizeof lv_remote_domain_set_memory_args);
+       break;
+case REMOTE_PROC_DOMAIN_SET_VCPUS:
+       fn = (dispatch_fn) remoteDispatchDomainSetVcpus;
+       args_filter = (xdrproc_t) xdr_remote_domain_set_vcpus_args;
+       args = (char *) &lv_remote_domain_set_vcpus_args;
+       memset (&lv_remote_domain_set_vcpus_args, 0, sizeof lv_remote_domain_set_vcpus_args);
+       break;
+case REMOTE_PROC_DOMAIN_SHUTDOWN:
+       fn = (dispatch_fn) remoteDispatchDomainShutdown;
+       args_filter = (xdrproc_t) xdr_remote_domain_shutdown_args;
+       args = (char *) &lv_remote_domain_shutdown_args;
+       memset (&lv_remote_domain_shutdown_args, 0, sizeof lv_remote_domain_shutdown_args);
+       break;
+case REMOTE_PROC_DOMAIN_SUSPEND:
+       fn = (dispatch_fn) remoteDispatchDomainSuspend;
+       args_filter = (xdrproc_t) xdr_remote_domain_suspend_args;
+       args = (char *) &lv_remote_domain_suspend_args;
+       memset (&lv_remote_domain_suspend_args, 0, sizeof lv_remote_domain_suspend_args);
+       break;
+case REMOTE_PROC_DOMAIN_UNDEFINE:
+       fn = (dispatch_fn) remoteDispatchDomainUndefine;
+       args_filter = (xdrproc_t) xdr_remote_domain_undefine_args;
+       args = (char *) &lv_remote_domain_undefine_args;
+       memset (&lv_remote_domain_undefine_args, 0, sizeof lv_remote_domain_undefine_args);
+       break;
+case REMOTE_PROC_GET_CAPABILITIES:
+       fn = (dispatch_fn) remoteDispatchGetCapabilities;
+       ret_filter = (xdrproc_t) xdr_remote_get_capabilities_ret;
+       ret = (char *) &lv_remote_get_capabilities_ret;
+       memset (&lv_remote_get_capabilities_ret, 0, sizeof lv_remote_get_capabilities_ret);
+       break;
+case REMOTE_PROC_GET_MAX_VCPUS:
+       fn = (dispatch_fn) remoteDispatchGetMaxVcpus;
+       args_filter = (xdrproc_t) xdr_remote_get_max_vcpus_args;
+       args = (char *) &lv_remote_get_max_vcpus_args;
+       memset (&lv_remote_get_max_vcpus_args, 0, sizeof lv_remote_get_max_vcpus_args);
+       ret_filter = (xdrproc_t) xdr_remote_get_max_vcpus_ret;
+       ret = (char *) &lv_remote_get_max_vcpus_ret;
+       memset (&lv_remote_get_max_vcpus_ret, 0, sizeof lv_remote_get_max_vcpus_ret);
+       break;
+case REMOTE_PROC_GET_TYPE:
+       fn = (dispatch_fn) remoteDispatchGetType;
+       ret_filter = (xdrproc_t) xdr_remote_get_type_ret;
+       ret = (char *) &lv_remote_get_type_ret;
+       memset (&lv_remote_get_type_ret, 0, sizeof lv_remote_get_type_ret);
+       break;
+case REMOTE_PROC_GET_VERSION:
+       fn = (dispatch_fn) remoteDispatchGetVersion;
+       ret_filter = (xdrproc_t) xdr_remote_get_version_ret;
+       ret = (char *) &lv_remote_get_version_ret;
+       memset (&lv_remote_get_version_ret, 0, sizeof lv_remote_get_version_ret);
+       break;
+case REMOTE_PROC_LIST_DEFINED_DOMAINS:
+       fn = (dispatch_fn) remoteDispatchListDefinedDomains;
+       args_filter = (xdrproc_t) xdr_remote_list_defined_domains_args;
+       args = (char *) &lv_remote_list_defined_domains_args;
+       memset (&lv_remote_list_defined_domains_args, 0, sizeof lv_remote_list_defined_domains_args);
+       ret_filter = (xdrproc_t) xdr_remote_list_defined_domains_ret;
+       ret = (char *) &lv_remote_list_defined_domains_ret;
+       memset (&lv_remote_list_defined_domains_ret, 0, sizeof lv_remote_list_defined_domains_ret);
+       break;
+case REMOTE_PROC_LIST_DEFINED_NETWORKS:
+       fn = (dispatch_fn) remoteDispatchListDefinedNetworks;
+       args_filter = (xdrproc_t) xdr_remote_list_defined_networks_args;
+       args = (char *) &lv_remote_list_defined_networks_args;
+       memset (&lv_remote_list_defined_networks_args, 0, sizeof lv_remote_list_defined_networks_args);
+       ret_filter = (xdrproc_t) xdr_remote_list_defined_networks_ret;
+       ret = (char *) &lv_remote_list_defined_networks_ret;
+       memset (&lv_remote_list_defined_networks_ret, 0, sizeof lv_remote_list_defined_networks_ret);
+       break;
+case REMOTE_PROC_LIST_DOMAINS:
+       fn = (dispatch_fn) remoteDispatchListDomains;
+       args_filter = (xdrproc_t) xdr_remote_list_domains_args;
+       args = (char *) &lv_remote_list_domains_args;
+       memset (&lv_remote_list_domains_args, 0, sizeof lv_remote_list_domains_args);
+       ret_filter = (xdrproc_t) xdr_remote_list_domains_ret;
+       ret = (char *) &lv_remote_list_domains_ret;
+       memset (&lv_remote_list_domains_ret, 0, sizeof lv_remote_list_domains_ret);
+       break;
+case REMOTE_PROC_LIST_NETWORKS:
+       fn = (dispatch_fn) remoteDispatchListNetworks;
+       args_filter = (xdrproc_t) xdr_remote_list_networks_args;
+       args = (char *) &lv_remote_list_networks_args;
+       memset (&lv_remote_list_networks_args, 0, sizeof lv_remote_list_networks_args);
+       ret_filter = (xdrproc_t) xdr_remote_list_networks_ret;
+       ret = (char *) &lv_remote_list_networks_ret;
+       memset (&lv_remote_list_networks_ret, 0, sizeof lv_remote_list_networks_ret);
+       break;
+case REMOTE_PROC_NETWORK_CREATE:
+       fn = (dispatch_fn) remoteDispatchNetworkCreate;
+       args_filter = (xdrproc_t) xdr_remote_network_create_args;
+       args = (char *) &lv_remote_network_create_args;
+       memset (&lv_remote_network_create_args, 0, sizeof lv_remote_network_create_args);
+       break;
+case REMOTE_PROC_NETWORK_CREATE_XML:
+       fn = (dispatch_fn) remoteDispatchNetworkCreateXml;
+       args_filter = (xdrproc_t) xdr_remote_network_create_xml_args;
+       args = (char *) &lv_remote_network_create_xml_args;
+       memset (&lv_remote_network_create_xml_args, 0, sizeof lv_remote_network_create_xml_args);
+       ret_filter = (xdrproc_t) xdr_remote_network_create_xml_ret;
+       ret = (char *) &lv_remote_network_create_xml_ret;
+       memset (&lv_remote_network_create_xml_ret, 0, sizeof lv_remote_network_create_xml_ret);
+       break;
+case REMOTE_PROC_NETWORK_DEFINE_XML:
+       fn = (dispatch_fn) remoteDispatchNetworkDefineXml;
+       args_filter = (xdrproc_t) xdr_remote_network_define_xml_args;
+       args = (char *) &lv_remote_network_define_xml_args;
+       memset (&lv_remote_network_define_xml_args, 0, sizeof lv_remote_network_define_xml_args);
+       ret_filter = (xdrproc_t) xdr_remote_network_define_xml_ret;
+       ret = (char *) &lv_remote_network_define_xml_ret;
+       memset (&lv_remote_network_define_xml_ret, 0, sizeof lv_remote_network_define_xml_ret);
+       break;
+case REMOTE_PROC_NETWORK_DESTROY:
+       fn = (dispatch_fn) remoteDispatchNetworkDestroy;
+       args_filter = (xdrproc_t) xdr_remote_network_destroy_args;
+       args = (char *) &lv_remote_network_destroy_args;
+       memset (&lv_remote_network_destroy_args, 0, sizeof lv_remote_network_destroy_args);
+       break;
+case REMOTE_PROC_NETWORK_DUMP_XML:
+       fn = (dispatch_fn) remoteDispatchNetworkDumpXml;
+       args_filter = (xdrproc_t) xdr_remote_network_dump_xml_args;
+       args = (char *) &lv_remote_network_dump_xml_args;
+       memset (&lv_remote_network_dump_xml_args, 0, sizeof lv_remote_network_dump_xml_args);
+       ret_filter = (xdrproc_t) xdr_remote_network_dump_xml_ret;
+       ret = (char *) &lv_remote_network_dump_xml_ret;
+       memset (&lv_remote_network_dump_xml_ret, 0, sizeof lv_remote_network_dump_xml_ret);
+       break;
+case REMOTE_PROC_NETWORK_GET_AUTOSTART:
+       fn = (dispatch_fn) remoteDispatchNetworkGetAutostart;
+       args_filter = (xdrproc_t) xdr_remote_network_get_autostart_args;
+       args = (char *) &lv_remote_network_get_autostart_args;
+       memset (&lv_remote_network_get_autostart_args, 0, sizeof lv_remote_network_get_autostart_args);
+       ret_filter = (xdrproc_t) xdr_remote_network_get_autostart_ret;
+       ret = (char *) &lv_remote_network_get_autostart_ret;
+       memset (&lv_remote_network_get_autostart_ret, 0, sizeof lv_remote_network_get_autostart_ret);
+       break;
+case REMOTE_PROC_NETWORK_GET_BRIDGE_NAME:
+       fn = (dispatch_fn) remoteDispatchNetworkGetBridgeName;
+       args_filter = (xdrproc_t) xdr_remote_network_get_bridge_name_args;
+       args = (char *) &lv_remote_network_get_bridge_name_args;
+       memset (&lv_remote_network_get_bridge_name_args, 0, sizeof lv_remote_network_get_bridge_name_args);
+       ret_filter = (xdrproc_t) xdr_remote_network_get_bridge_name_ret;
+       ret = (char *) &lv_remote_network_get_bridge_name_ret;
+       memset (&lv_remote_network_get_bridge_name_ret, 0, sizeof lv_remote_network_get_bridge_name_ret);
+       break;
+case REMOTE_PROC_NETWORK_LOOKUP_BY_NAME:
+       fn = (dispatch_fn) remoteDispatchNetworkLookupByName;
+       args_filter = (xdrproc_t) xdr_remote_network_lookup_by_name_args;
+       args = (char *) &lv_remote_network_lookup_by_name_args;
+       memset (&lv_remote_network_lookup_by_name_args, 0, sizeof lv_remote_network_lookup_by_name_args);
+       ret_filter = (xdrproc_t) xdr_remote_network_lookup_by_name_ret;
+       ret = (char *) &lv_remote_network_lookup_by_name_ret;
+       memset (&lv_remote_network_lookup_by_name_ret, 0, sizeof lv_remote_network_lookup_by_name_ret);
+       break;
+case REMOTE_PROC_NETWORK_LOOKUP_BY_UUID:
+       fn = (dispatch_fn) remoteDispatchNetworkLookupByUuid;
+       args_filter = (xdrproc_t) xdr_remote_network_lookup_by_uuid_args;
+       args = (char *) &lv_remote_network_lookup_by_uuid_args;
+       memset (&lv_remote_network_lookup_by_uuid_args, 0, sizeof lv_remote_network_lookup_by_uuid_args);
+       ret_filter = (xdrproc_t) xdr_remote_network_lookup_by_uuid_ret;
+       ret = (char *) &lv_remote_network_lookup_by_uuid_ret;
+       memset (&lv_remote_network_lookup_by_uuid_ret, 0, sizeof lv_remote_network_lookup_by_uuid_ret);
+       break;
+case REMOTE_PROC_NETWORK_SET_AUTOSTART:
+       fn = (dispatch_fn) remoteDispatchNetworkSetAutostart;
+       args_filter = (xdrproc_t) xdr_remote_network_set_autostart_args;
+       args = (char *) &lv_remote_network_set_autostart_args;
+       memset (&lv_remote_network_set_autostart_args, 0, sizeof lv_remote_network_set_autostart_args);
+       break;
+case REMOTE_PROC_NETWORK_UNDEFINE:
+       fn = (dispatch_fn) remoteDispatchNetworkUndefine;
+       args_filter = (xdrproc_t) xdr_remote_network_undefine_args;
+       args = (char *) &lv_remote_network_undefine_args;
+       memset (&lv_remote_network_undefine_args, 0, sizeof lv_remote_network_undefine_args);
+       break;
+case REMOTE_PROC_NODE_GET_INFO:
+       fn = (dispatch_fn) remoteDispatchNodeGetInfo;
+       ret_filter = (xdrproc_t) xdr_remote_node_get_info_ret;
+       ret = (char *) &lv_remote_node_get_info_ret;
+       memset (&lv_remote_node_get_info_ret, 0, sizeof lv_remote_node_get_info_ret);
+       break;
+case REMOTE_PROC_NUM_OF_DEFINED_DOMAINS:
+       fn = (dispatch_fn) remoteDispatchNumOfDefinedDomains;
+       ret_filter = (xdrproc_t) xdr_remote_num_of_defined_domains_ret;
+       ret = (char *) &lv_remote_num_of_defined_domains_ret;
+       memset (&lv_remote_num_of_defined_domains_ret, 0, sizeof lv_remote_num_of_defined_domains_ret);
+       break;
+case REMOTE_PROC_NUM_OF_DEFINED_NETWORKS:
+       fn = (dispatch_fn) remoteDispatchNumOfDefinedNetworks;
+       ret_filter = (xdrproc_t) xdr_remote_num_of_defined_networks_ret;
+       ret = (char *) &lv_remote_num_of_defined_networks_ret;
+       memset (&lv_remote_num_of_defined_networks_ret, 0, sizeof lv_remote_num_of_defined_networks_ret);
+       break;
+case REMOTE_PROC_NUM_OF_DOMAINS:
+       fn = (dispatch_fn) remoteDispatchNumOfDomains;
+       ret_filter = (xdrproc_t) xdr_remote_num_of_domains_ret;
+       ret = (char *) &lv_remote_num_of_domains_ret;
+       memset (&lv_remote_num_of_domains_ret, 0, sizeof lv_remote_num_of_domains_ret);
+       break;
+case REMOTE_PROC_NUM_OF_NETWORKS:
+       fn = (dispatch_fn) remoteDispatchNumOfNetworks;
+       ret_filter = (xdrproc_t) xdr_remote_num_of_networks_ret;
+       ret = (char *) &lv_remote_num_of_networks_ret;
+       memset (&lv_remote_num_of_networks_ret, 0, sizeof lv_remote_num_of_networks_ret);
+       break;
+case REMOTE_PROC_OPEN:
+       fn = (dispatch_fn) remoteDispatchOpen;
+       args_filter = (xdrproc_t) xdr_remote_open_args;
+       args = (char *) &lv_remote_open_args;
+       memset (&lv_remote_open_args, 0, sizeof lv_remote_open_args);
+       break;
diff --git a/qemud/remote_dispatch_prototypes.h b/qemud/remote_dispatch_prototypes.h
new file mode 100644 (file)
index 0000000..9bd23cd
--- /dev/null
@@ -0,0 +1,59 @@
+/* Automatically generated by remote_generate_stubs.pl.
+ * Do not edit this file.  Any changes you make will be lost.
+ */
+
+static int remoteDispatchClose (struct qemud_client *client, remote_message_header *req, void *args, void *ret);
+static int remoteDispatchDomainAttachDevice (struct qemud_client *client, remote_message_header *req, remote_domain_attach_device_args *args, void *ret);
+static int remoteDispatchDomainCoreDump (struct qemud_client *client, remote_message_header *req, remote_domain_core_dump_args *args, void *ret);
+static int remoteDispatchDomainCreate (struct qemud_client *client, remote_message_header *req, remote_domain_create_args *args, void *ret);
+static int remoteDispatchDomainCreateLinux (struct qemud_client *client, remote_message_header *req, remote_domain_create_linux_args *args, remote_domain_create_linux_ret *ret);
+static int remoteDispatchDomainDefineXml (struct qemud_client *client, remote_message_header *req, remote_domain_define_xml_args *args, remote_domain_define_xml_ret *ret);
+static int remoteDispatchDomainDestroy (struct qemud_client *client, remote_message_header *req, remote_domain_destroy_args *args, void *ret);
+static int remoteDispatchDomainDetachDevice (struct qemud_client *client, remote_message_header *req, remote_domain_detach_device_args *args, void *ret);
+static int remoteDispatchDomainDumpXml (struct qemud_client *client, remote_message_header *req, remote_domain_dump_xml_args *args, remote_domain_dump_xml_ret *ret);
+static int remoteDispatchDomainGetAutostart (struct qemud_client *client, remote_message_header *req, remote_domain_get_autostart_args *args, remote_domain_get_autostart_ret *ret);
+static int remoteDispatchDomainGetInfo (struct qemud_client *client, remote_message_header *req, remote_domain_get_info_args *args, remote_domain_get_info_ret *ret);
+static int remoteDispatchDomainGetMaxMemory (struct qemud_client *client, remote_message_header *req, remote_domain_get_max_memory_args *args, remote_domain_get_max_memory_ret *ret);
+static int remoteDispatchDomainGetMaxVcpus (struct qemud_client *client, remote_message_header *req, remote_domain_get_max_vcpus_args *args, remote_domain_get_max_vcpus_ret *ret);
+static int remoteDispatchDomainGetOsType (struct qemud_client *client, remote_message_header *req, remote_domain_get_os_type_args *args, remote_domain_get_os_type_ret *ret);
+static int remoteDispatchDomainGetVcpus (struct qemud_client *client, remote_message_header *req, remote_domain_get_vcpus_args *args, remote_domain_get_vcpus_ret *ret);
+static int remoteDispatchDomainLookupById (struct qemud_client *client, remote_message_header *req, remote_domain_lookup_by_id_args *args, remote_domain_lookup_by_id_ret *ret);
+static int remoteDispatchDomainLookupByName (struct qemud_client *client, remote_message_header *req, remote_domain_lookup_by_name_args *args, remote_domain_lookup_by_name_ret *ret);
+static int remoteDispatchDomainLookupByUuid (struct qemud_client *client, remote_message_header *req, remote_domain_lookup_by_uuid_args *args, remote_domain_lookup_by_uuid_ret *ret);
+static int remoteDispatchDomainPinVcpu (struct qemud_client *client, remote_message_header *req, remote_domain_pin_vcpu_args *args, void *ret);
+static int remoteDispatchDomainReboot (struct qemud_client *client, remote_message_header *req, remote_domain_reboot_args *args, void *ret);
+static int remoteDispatchDomainRestore (struct qemud_client *client, remote_message_header *req, remote_domain_restore_args *args, void *ret);
+static int remoteDispatchDomainResume (struct qemud_client *client, remote_message_header *req, remote_domain_resume_args *args, void *ret);
+static int remoteDispatchDomainSave (struct qemud_client *client, remote_message_header *req, remote_domain_save_args *args, void *ret);
+static int remoteDispatchDomainSetAutostart (struct qemud_client *client, remote_message_header *req, remote_domain_set_autostart_args *args, void *ret);
+static int remoteDispatchDomainSetMaxMemory (struct qemud_client *client, remote_message_header *req, remote_domain_set_max_memory_args *args, void *ret);
+static int remoteDispatchDomainSetMemory (struct qemud_client *client, remote_message_header *req, remote_domain_set_memory_args *args, void *ret);
+static int remoteDispatchDomainSetVcpus (struct qemud_client *client, remote_message_header *req, remote_domain_set_vcpus_args *args, void *ret);
+static int remoteDispatchDomainShutdown (struct qemud_client *client, remote_message_header *req, remote_domain_shutdown_args *args, void *ret);
+static int remoteDispatchDomainSuspend (struct qemud_client *client, remote_message_header *req, remote_domain_suspend_args *args, void *ret);
+static int remoteDispatchDomainUndefine (struct qemud_client *client, remote_message_header *req, remote_domain_undefine_args *args, void *ret);
+static int remoteDispatchGetCapabilities (struct qemud_client *client, remote_message_header *req, void *args, remote_get_capabilities_ret *ret);
+static int remoteDispatchGetMaxVcpus (struct qemud_client *client, remote_message_header *req, remote_get_max_vcpus_args *args, remote_get_max_vcpus_ret *ret);
+static int remoteDispatchGetType (struct qemud_client *client, remote_message_header *req, void *args, remote_get_type_ret *ret);
+static int remoteDispatchGetVersion (struct qemud_client *client, remote_message_header *req, void *args, remote_get_version_ret *ret);
+static int remoteDispatchListDefinedDomains (struct qemud_client *client, remote_message_header *req, remote_list_defined_domains_args *args, remote_list_defined_domains_ret *ret);
+static int remoteDispatchListDefinedNetworks (struct qemud_client *client, remote_message_header *req, remote_list_defined_networks_args *args, remote_list_defined_networks_ret *ret);
+static int remoteDispatchListDomains (struct qemud_client *client, remote_message_header *req, remote_list_domains_args *args, remote_list_domains_ret *ret);
+static int remoteDispatchListNetworks (struct qemud_client *client, remote_message_header *req, remote_list_networks_args *args, remote_list_networks_ret *ret);
+static int remoteDispatchNetworkCreate (struct qemud_client *client, remote_message_header *req, remote_network_create_args *args, void *ret);
+static int remoteDispatchNetworkCreateXml (struct qemud_client *client, remote_message_header *req, remote_network_create_xml_args *args, remote_network_create_xml_ret *ret);
+static int remoteDispatchNetworkDefineXml (struct qemud_client *client, remote_message_header *req, remote_network_define_xml_args *args, remote_network_define_xml_ret *ret);
+static int remoteDispatchNetworkDestroy (struct qemud_client *client, remote_message_header *req, remote_network_destroy_args *args, void *ret);
+static int remoteDispatchNetworkDumpXml (struct qemud_client *client, remote_message_header *req, remote_network_dump_xml_args *args, remote_network_dump_xml_ret *ret);
+static int remoteDispatchNetworkGetAutostart (struct qemud_client *client, remote_message_header *req, remote_network_get_autostart_args *args, remote_network_get_autostart_ret *ret);
+static int remoteDispatchNetworkGetBridgeName (struct qemud_client *client, remote_message_header *req, remote_network_get_bridge_name_args *args, remote_network_get_bridge_name_ret *ret);
+static int remoteDispatchNetworkLookupByName (struct qemud_client *client, remote_message_header *req, remote_network_lookup_by_name_args *args, remote_network_lookup_by_name_ret *ret);
+static int remoteDispatchNetworkLookupByUuid (struct qemud_client *client, remote_message_header *req, remote_network_lookup_by_uuid_args *args, remote_network_lookup_by_uuid_ret *ret);
+static int remoteDispatchNetworkSetAutostart (struct qemud_client *client, remote_message_header *req, remote_network_set_autostart_args *args, void *ret);
+static int remoteDispatchNetworkUndefine (struct qemud_client *client, remote_message_header *req, remote_network_undefine_args *args, void *ret);
+static int remoteDispatchNodeGetInfo (struct qemud_client *client, remote_message_header *req, void *args, remote_node_get_info_ret *ret);
+static int remoteDispatchNumOfDefinedDomains (struct qemud_client *client, remote_message_header *req, void *args, remote_num_of_defined_domains_ret *ret);
+static int remoteDispatchNumOfDefinedNetworks (struct qemud_client *client, remote_message_header *req, void *args, remote_num_of_defined_networks_ret *ret);
+static int remoteDispatchNumOfDomains (struct qemud_client *client, remote_message_header *req, void *args, remote_num_of_domains_ret *ret);
+static int remoteDispatchNumOfNetworks (struct qemud_client *client, remote_message_header *req, void *args, remote_num_of_networks_ret *ret);
+static int remoteDispatchOpen (struct qemud_client *client, remote_message_header *req, remote_open_args *args, void *ret);
diff --git a/qemud/remote_generate_stubs.pl b/qemud/remote_generate_stubs.pl
new file mode 100755 (executable)
index 0000000..ae46f9c
--- /dev/null
@@ -0,0 +1,223 @@
+#!/usr/bin/perl -w
+#
+# This script parses remote_protocol.x and produces lots of boilerplate
+# code for both ends of the remote connection.
+#
+# By Richard Jones <rjones@redhat.com>
+#
+# $Id$
+
+use strict;
+
+use Getopt::Std;
+
+# Command line options.
+our ($opt_c, $opt_d, $opt_i, $opt_s, $opt_v, $opt_w);
+getopts ('cdisvw');
+
+# Convert name_of_call to NameOfCall.
+sub name_to_ProcName {
+    my $name = shift;
+    my @elems = split /_/, $name;
+    @elems = map ucfirst, @elems;
+    join "", @elems
+}
+
+# Read the input file (usually remote_protocol.x) and form an
+# opinion about the name, args and return type of each RPC.
+my ($name, $ProcName, %calls);
+while (<>) {
+    if (/^struct remote_(.*)_args/) {
+       $name = $1;
+       $ProcName = name_to_ProcName ($name);
+
+       die "duplicate definition of remote_${name}_args"
+           if exists $calls{$name};
+
+       $calls{$name} = {
+           name => $name,
+           ProcName => $ProcName,
+           UC_NAME => uc $name,
+           args => "remote_${name}_args",
+           ret => "void",
+       };
+
+    } elsif (/^struct remote_(.*)_ret/) {
+       $name = $1;
+       $ProcName = name_to_ProcName ($name);
+
+       if (exists $calls{$name}) {
+           $calls{$name}->{ret} = "remote_${name}_ret";
+       } else {
+           $calls{$name} = {
+               name => $name,
+               ProcName => $ProcName,
+               UC_NAME => uc $name,
+               args => "void",
+               ret => "remote_${name}_ret"
+           }
+       }
+    }
+}
+
+# REMOTE_PROC_CLOSE has no args or ret.
+$calls{close} = {
+    name => "close",
+    ProcName => "Close",
+    UC_NAME => "CLOSE",
+    args => "void",
+    ret => "void",
+};
+
+#----------------------------------------------------------------------
+# Output
+
+print <<__EOF__;
+/* Automatically generated by remote_generate_stubs.pl.
+ * Do not edit this file.  Any changes you make will be lost.
+ */
+
+__EOF__
+
+# Debugging.
+if ($opt_d) {
+    my @keys = sort (keys %calls);
+    foreach (@keys) {
+       print "$_:\n";
+       print "\tname $calls{$_}->{name} ($calls{$_}->{ProcName})\n";
+       print "\t$calls{$_}->{args} -> $calls{$_}->{ret}\n";
+    }
+}
+
+# Prototypes for dispatch functions ("remote_dispatch_prototypes.h").
+elsif ($opt_i) {
+    my @keys = sort (keys %calls);
+    foreach (@keys) {
+       print "static int remoteDispatch$calls{$_}->{ProcName} (struct qemud_client *client, remote_message_header *req, $calls{$_}->{args} *args, $calls{$_}->{ret} *ret);\n";
+    }
+}
+
+# Local variables used inside remoteDispatchClientRequest
+# ("remote_dispatch_localvars.h").
+elsif ($opt_v) {
+    my @values = values %calls;
+    foreach (@values) {
+       if ($_->{args} ne "void") {
+           print "$_->{args} lv_$_->{args};\n";
+       }
+       if ($_->{ret} ne "void") {
+           print "$_->{ret} lv_$_->{ret};\n";
+       }
+    }
+}
+
+# Inside the switch statement, prepare the 'fn', 'args_filter', etc
+# ("remote_dispatch_proc_switch.h").
+elsif ($opt_w) {
+    my @keys = sort (keys %calls);
+    foreach (@keys) {
+       print "case REMOTE_PROC_$calls{$_}->{UC_NAME}:\n";
+       print "\tfn = (dispatch_fn) remoteDispatch$calls{$_}->{ProcName};\n";
+       if ($calls{$_}->{args} ne "void") {
+           print "\targs_filter = (xdrproc_t) xdr_$calls{$_}->{args};\n";
+           print "\targs = (char *) &lv_$calls{$_}->{args};\n";
+           print "\tmemset (&lv_$calls{$_}->{args}, 0, sizeof lv_$calls{$_}->{args});\n"
+       }
+       if ($calls{$_}->{ret} ne "void") {
+           print "\tret_filter = (xdrproc_t) xdr_$calls{$_}->{ret};\n";
+           print "\tret = (char *) &lv_$calls{$_}->{ret};\n";
+           print "\tmemset (&lv_$calls{$_}->{ret}, 0, sizeof lv_$calls{$_}->{ret});\n"
+       }
+       print "\tbreak;\n";
+    }
+}
+
+# Generate client stubs - just used to generate the first
+# version of the stubs in remote_internal.c.  They need
+# hand-hacking afterwards.
+elsif ($opt_c) {
+    my @keys = sort (keys %calls);
+
+    foreach (@keys) {
+       my $args = $calls{$_}->{args};
+       my $argsvoid = $args eq "void";
+       my $ret = $calls{$_}->{ret};
+       my $retvoid = $ret eq "void";
+
+       print "static @@\n";
+       print "remote$calls{$_}->{ProcName} (@@)\n";
+       print "{\n";
+       if (!$argsvoid) {
+           print "    $args args;\n";
+       }
+       if (!$retvoid) {
+           print "    $ret ret;\n";
+       }
+       print "    GET_PRIVATE (conn, @@);\n";
+       print "\n";
+       if (!$argsvoid) {
+           print "    @@\n";
+           print "\n";
+       }
+       if (!$retvoid) {
+           print "    memset (&ret, 0, sizeof ret);\n";
+       }
+       print "    if (call (conn, priv, 0, REMOTE_PROC_$calls{$_}->{UC_NAME},\n";
+       print "              (xdrproc_t) xdr_$args, (char *) ";
+       if ($argsvoid) {
+           print "NULL";
+       } else {
+           print "&args";
+       }
+       print ",\n";
+       print "              (xdrproc_t) xdr_$ret, (char *) ";
+       if ($retvoid) {
+           print "NULL";
+       } else {
+           print "&ret";
+       }
+       print ") == -1)\n";
+       print "        return -1;\n";
+       print "\n    @@\n";
+       print "}\n\n";
+    }
+}
+
+# Generate server stubs - just used to generate the first
+# version of the stubs in remote.c.  They need hand-hacking
+# afterwards.
+elsif ($opt_s) {
+    my @keys = sort (keys %calls);
+
+    foreach (@keys) {
+       my $args = $calls{$_}->{args};
+       my $argsvoid = $args eq "void";
+       my $ret = $calls{$_}->{ret};
+       my $retvoid = $ret eq "void";
+
+       print "static int\n";
+       print "remoteDispatch$calls{$_}->{ProcName} (struct qemud_client *client,\n";
+       print "            remote_message_header *req,\n";
+       print "            remote_get_max_vcpus_args *args,\n";
+       print "            remote_get_max_vcpus_ret *ret)\n";
+       print "{\n";
+       if (!$argsvoid || !$retvoid) {
+           print "    @@\n";
+       }
+       print "    CHECK_CONN;\n";
+       print "\n";
+       if (!$argsvoid) {
+           print "    @@\n";
+           print "\n";
+       }
+       print "    @@ = vir$calls{$_}->{ProcName} (@@);\n";
+       print "    if (@@) return -1;\n";
+       print "\n";
+       if (!$retvoid) {
+           print "    @@\n";
+           print "\n";
+       }
+       print "    return 0;\n";
+       print "}\n\n";
+    }
+}