aa7a7823c314608bf373714d7db0b7d197482b7a
[wrappi.git] / lib / proto-xdr.c
1 /* wrappi
2  * Copyright (C) 2011-2012 Red Hat Inc.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18
19 #include <config.h>
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <assert.h>
24 #include <rpc/xdr.h>
25
26 #include "wrappi.h"
27 #include "internal.h"
28 #include "proto-xdr.h"
29
30 bool_t
31 wrap_int_xdr_message_header (XDR *xdrs, struct wrap_int_message_header *hdr)
32 {
33   if (!xdr_uint32_t (xdrs, &hdr->magic)) return FALSE;
34   if (!xdr_uint32_t (xdrs, &hdr->protocol)) return FALSE;
35   if (!xdr_uint32_t (xdrs, &hdr->serial)) return FALSE;
36   if (!xdr_string (xdrs, &hdr->proc, ~0)) return FALSE;
37   if (!xdr_uint32_t (xdrs, &hdr->type)) return FALSE;
38
39   return TRUE;
40 }
41
42 bool_t
43 wrap_int_xdr_message_error (XDR *xdrs, struct wrap_int_message_error *err)
44 {
45   if (!xdr_string (xdrs, &err->error_message, ~0)) return FALSE;
46   if (!xdr_string (xdrs, &err->error_errno, 32)) return FALSE;
47   if (!xdr_string (xdrs, &err->error_func, 256)) return FALSE;
48
49   return TRUE;
50 }
51
52 void
53 wrap_int_make_request_xdr (wrap_h *w, int proc_nr, const void *args, void *ret)
54 {
55   XDR xdr;
56   xdrproc_t xdrp_args;
57   xdrproc_t xdrp_ret;
58   struct wrap_int_message_header hdr;
59   struct wrap_int_message_error err;
60
61   memset (&hdr, 0, sizeof hdr);
62
63   hdr.proc = (char *) wrap_int_proc_table[proc_nr].name;
64   assert (hdr.proc);
65   xdrp_args = wrap_int_proc_table[proc_nr].xdr_args;
66   assert (xdrp_args);
67   xdrp_ret = wrap_int_proc_table[proc_nr].xdr_ret;
68   assert (xdrp_ret);
69
70   /* Construct the header. */
71   w->serial++;
72
73   hdr.magic = WRAP_INT_PROTO_MAGIC;
74   hdr.protocol = WRAP_INT_PROTOCOL;
75   hdr.serial = w->serial;
76   hdr.type = WRAP_INT_PROTO_TYPE_REQUEST;
77
78   /* Send the header. */
79   xdrstdio_create (&xdr, w->wfp, XDR_ENCODE);
80   if (!wrap_int_xdr_message_header (&xdr, &hdr)) {
81     set_error ("error sending request header");
82     xdr_destroy (&xdr);
83     return;
84   }
85
86   /* Send the request arguments. */
87   if (!xdrp_args (&xdr, (void *) args)) {
88     set_error ("error sending request arguments");
89     xdr_destroy (&xdr);
90     return;
91   }
92   xdr_destroy (&xdr);
93
94   /* Receive the reply header. */
95   xdrstdio_create (&xdr, w->rfp, XDR_DECODE);
96   memset (&hdr, 0, sizeof hdr);
97   if (!wrap_int_xdr_message_header (&xdr, &hdr)) {
98     set_error ("error receiving reply header");
99     xdr_destroy (&xdr);
100     return;
101   }
102
103   /* Check the reply header. */
104   if (hdr.magic != WRAP_INT_PROTO_MAGIC) {
105     set_error ("error in reply: unexpected magic (%x)", hdr.magic);
106     xdr_destroy (&xdr);
107     return;
108   }
109   if (hdr.protocol != WRAP_INT_PROTOCOL) {
110     set_error ("error in reply: unexpected protocol number (%d)", hdr.protocol);
111     xdr_destroy (&xdr);
112     return;
113   }
114   if (hdr.serial != w->serial) {
115     set_error ("error in reply: unexpected serial (%d)", hdr.serial);
116     xdr_destroy (&xdr);
117     return;
118   }
119
120   switch (hdr.type) {
121   case WRAP_INT_PROTO_TYPE_REPLY:
122     /* Receive the return value. */
123     if (!xdrp_ret (&xdr, (void *) ret)) {
124       set_error ("error receiving return value");
125       xdr_destroy (&xdr);
126       return;
127     }
128     break;
129
130   case WRAP_INT_PROTO_TYPE_ERROR:
131     /* Receive the error message etc. */
132     memset (&err, 0, sizeof err);
133     if (!wrap_int_xdr_message_error (&xdr, &err)) {
134       set_error ("error receiving error message");
135       xdr_destroy (&xdr);
136       return;
137     }
138
139     /* XXX errno should be converted to an integer here */
140     /* XXX func should be set, but it's not static! */
141     set_error ("%s", err.error_message);
142     xdr_free ((xdrproc_t) wrap_int_xdr_message_error, (void *) &err);
143
144     break;
145
146   default:
147     set_error ("error in reply: unexpected type (%x)", hdr.type);
148     xdr_destroy (&xdr);
149     return;
150   }
151
152   xdr_destroy (&xdr);
153 }