/* 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 #include #include #include #include #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); }