--- /dev/null
+/* wrappi
+ * Copyright (C) 2011-2012 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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <rpc/xdr.h>
+
+#include "wrappi.h"
+#include "internal.h"
+#include "proto-xdr.h"
+
+void
+wrap_int_make_request_xdr (wrap_h *w, int proc_nr, const void *args, void *ret)
+{
+ XDR xdr;
+ xdrproc_t args_xdrproc;
+ xdrproc_t ret_xdrproc;
+ struct wrap_int_message_header hdr;
+ struct wrap_int_message_error err;
+
+ memset (&hdr, 0, sizeof hdr);
+
+ hdr.proc = (char *) wrap_int_proc_table[proc_nr].name;
+ assert (hdr.proc);
+ args_xdrproc = wrap_int_proc_table[proc_nr].args_xdrproc;
+ ret_xdrproc = wrap_int_proc_table[proc_nr].ret_xdrproc;
+
+ /* Construct the header. */
+ w->serial++;
+
+ hdr.magic = WRAP_INT_PROTO_MAGIC;
+ hdr.protocol = WRAP_INT_PROTOCOL;
+ hdr.serial = w->serial;
+ hdr.type = WRAP_INT_PROTO_TYPE_REQUEST;
+
+ /* Send the header. */
+ xdrstdio_create (&xdr, w->wfp, XDR_ENCODE);
+ if (!wrap_int_xdr_message_header (&xdr, &hdr)) {
+ set_error ("error sending request header");
+ xdr_destroy (&xdr);
+ return;
+ }
+
+ /* Send the request arguments. */
+ if (!args_xdrproc (&xdr, (void *) args)) {
+ set_error ("error sending request arguments");
+ xdr_destroy (&xdr);
+ return;
+ }
+ xdr_destroy (&xdr);
+
+ /* Receive the reply header. */
+ xdrstdio_create (&xdr, w->rfp, XDR_DECODE);
+ memset (&hdr, 0, sizeof hdr);
+ if (!wrap_int_xdr_message_header (&xdr, &hdr)) {
+ set_error ("error receiving reply header");
+ xdr_destroy (&xdr);
+ return;
+ }
+
+ /* Check the reply header. */
+ if (hdr.magic != WRAP_INT_PROTO_MAGIC) {
+ set_error ("error in reply: unexpected magic (%x)", hdr.magic);
+ xdr_destroy (&xdr);
+ xdr_free ((xdrproc_t) wrap_int_xdr_message_header, (void *) &hdr);
+ return;
+ }
+ if (hdr.protocol != WRAP_INT_PROTOCOL) {
+ set_error ("error in reply: unexpected protocol number (%d)", hdr.protocol);
+ xdr_destroy (&xdr);
+ xdr_free ((xdrproc_t) wrap_int_xdr_message_header, (void *) &hdr);
+ return;
+ }
+ if (hdr.serial != w->serial) {
+ set_error ("error in reply: unexpected serial (%d)", hdr.serial);
+ xdr_destroy (&xdr);
+ xdr_free ((xdrproc_t) wrap_int_xdr_message_header, (void *) &hdr);
+ return;
+ }
+
+ switch (hdr.type) {
+ case WRAP_INT_PROTO_TYPE_REPLY:
+ /* Receive the return value. */
+ if (!ret_xdrproc (&xdr, (void *) ret)) {
+ set_error ("error receiving return value");
+ xdr_destroy (&xdr);
+ xdr_free ((xdrproc_t) wrap_int_xdr_message_header, (void *) &hdr);
+ return;
+ }
+ break;
+
+ case WRAP_INT_PROTO_TYPE_ERROR:
+ /* Receive the error message etc. */
+ memset (&err, 0, sizeof err);
+ if (!wrap_int_xdr_message_error (&xdr, &err)) {
+ set_error ("error receiving error message");
+ xdr_destroy (&xdr);
+ xdr_free ((xdrproc_t) wrap_int_xdr_message_header, (void *) &hdr);
+ return;
+ }
+
+ /* XXX errno should be converted to an integer here */
+ /* XXX func should be set, but it's not static! */
+ set_error ("%s", err.error_message);
+ xdr_free ((xdrproc_t) wrap_int_xdr_message_error, (void *) &err);
+ xdr_free ((xdrproc_t) wrap_int_xdr_message_header, (void *) &hdr);
+
+ break;
+
+ default:
+ set_error ("error in reply: unexpected type (%x)", hdr.type);
+ xdr_destroy (&xdr);
+ xdr_free ((xdrproc_t) wrap_int_xdr_message_header, (void *) &hdr);
+ return;
+ }
+
+ xdr_destroy (&xdr);
+ xdr_free ((xdrproc_t) wrap_int_xdr_message_header, (void *) &hdr);
+}