#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
+#include <rpc/xdr.h>
#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)
{
- /* XXX */
+ 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);
+ }
}