/* 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 "../lib/proto-xdr.h" static void main_loop (void); static wrap_h *w; int main (int argc, char *argv[]) { /* Command line XXX */ w = wrap_create (); if (!w) { fprintf (stderr, "could not allocate wrappi handle\n"); exit (EXIT_FAILURE); } wrap_connect (w); if (wrap_error (w)) exit (EXIT_FAILURE); main_loop (); wrap_close (w); exit (EXIT_SUCCESS); } static void main_loop (void) { XDR xdr; struct wrap_int_message_header hdr; struct wrap_int_message_error err; xdrproc_t args_xdrproc; xdrproc_t ret_xdrproc; void *argsv, *retv; for (;;) { /* Receive the request header. */ xdrstdio_create (&xdr, stdin, XDR_DECODE); memset (&hdr, 0, sizeof hdr); if (!wrap_int_xdr_message_header (&xdr, &hdr)) { /* No error message here, because this is the expected * exit place when the connection is closed. */ xdr_destroy (&xdr); return; } if (hdr.magic != WRAP_INT_PROTO_MAGIC) { fprintf (stderr, "error in request: unexpected magic (%x)\n", hdr.magic); xdr_destroy (&xdr); return; } if (hdr.protocol != WRAP_INT_PROTOCOL) { fprintf (stderr, "error in request: unexpected protocol number (%d)\n", hdr.protocol); xdr_destroy (&xdr); return; } if (hdr.type != WRAP_INT_PROTO_TYPE_REQUEST) { fprintf (stderr, "error in request: unexpected type (%d)\n", hdr.type); xdr_destroy (&xdr); return; } args_xdrproc = wrap_call_get_args_xdrproc (w, hdr.proc); if (wrap_error (w)) { xdr_destroy (&xdr); return; } ret_xdrproc = wrap_call_get_ret_xdrproc (w, hdr.proc); if (wrap_error (w)) { xdr_destroy (&xdr); return; } argsv = calloc (1, wrap_call_get_args_struct_size (w, hdr.proc)); if (argsv == NULL) { perror ("malloc"); exit (EXIT_FAILURE); } retv = calloc (1, wrap_call_get_ret_struct_size (w, hdr.proc)); if (retv == NULL) { perror ("malloc"); exit (EXIT_FAILURE); } /* Receive the arguments. */ if (!args_xdrproc (&xdr, argsv)) { fprintf (stderr, "error receiving request arguments\n"); xdr_destroy (&xdr); free (argsv); free (retv); return; } xdr_destroy (&xdr); /* Call the underlying API. */ wrap_call (w, hdr.proc, argsv, retv); free (argsv); xdrstdio_create (&xdr, stdout, XDR_ENCODE); if (! wrap_error (w)) { /* Send back a normal reply. */ hdr.type = WRAP_INT_PROTO_TYPE_REPLY; if (!wrap_int_xdr_message_header (&xdr, &hdr)) { fprintf (stderr, "error sending reply header\n"); xdr_destroy (&xdr); free (retv); return; } if (!ret_xdrproc (&xdr, retv)) { fprintf (stderr, "error sending reply return value\n"); xdr_destroy (&xdr); free (retv); return; } } else { /* Send back an error reply. */ err.error_message = (char *) wrap_get_error (w); err.error_func = (char *) wrap_get_error_func (w); err.error_errno = (char *) ""; /* XXX set this properly */ hdr.type = WRAP_INT_PROTO_TYPE_ERROR; if (!wrap_int_xdr_message_header (&xdr, &hdr)) { fprintf (stderr, "error sending reply error header\n"); xdr_destroy (&xdr); free (retv); return; } if (!wrap_int_xdr_message_error (&xdr, &err)) { fprintf (stderr, "error sending reply error struct\n"); xdr_destroy (&xdr); free (retv); return; } } free (retv); xdr_destroy (&xdr); xdr_free ((xdrproc_t) wrap_int_xdr_message_header, (void *) &hdr); } }