Remote protocol working.
[wrappi.git] / daemon / wrappid.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 <string.h>
24 #include <rpc/xdr.h>
25
26 #include "wrappi.h"
27 #include "../lib/proto-xdr.h"
28
29 static void main_loop (void);
30
31 static wrap_h *w;
32
33 int
34 main (int argc, char *argv[])
35 {
36   /* Command line XXX */
37
38   w = wrap_create ();
39   if (!w) {
40     fprintf (stderr, "could not allocate wrappi handle\n");
41     exit (EXIT_FAILURE);
42   }
43
44   wrap_connect (w);
45   if (wrap_error (w))
46     exit (EXIT_FAILURE);
47
48   main_loop ();
49
50   wrap_close (w);
51
52   exit (EXIT_SUCCESS);
53 }
54
55 static void
56 main_loop (void)
57 {
58   XDR xdr;
59   struct wrap_int_message_header hdr;
60   struct wrap_int_message_error err;
61   xdrproc_t args_xdrproc;
62   xdrproc_t ret_xdrproc;
63   void *argsv, *retv;
64
65   for (;;) {
66     /* Receive the request header. */
67     xdrstdio_create (&xdr, stdin, XDR_DECODE);
68     memset (&hdr, 0, sizeof hdr);
69     if (!wrap_int_xdr_message_header (&xdr, &hdr)) {
70       fprintf (stderr, "error receiving request header\n");
71       xdr_destroy (&xdr);
72       return;
73     }
74
75     if (hdr.magic != WRAP_INT_PROTO_MAGIC) {
76       fprintf (stderr, "error in request: unexpected magic (%x)\n",
77                hdr.magic);
78       xdr_destroy (&xdr);
79       return;
80     }
81     if (hdr.protocol != WRAP_INT_PROTOCOL) {
82       fprintf (stderr, "error in request: unexpected protocol number (%d)\n",
83                hdr.protocol);
84       xdr_destroy (&xdr);
85       return;
86     }
87     if (hdr.type != WRAP_INT_PROTO_TYPE_REQUEST) {
88       fprintf (stderr, "error in request: unexpected type (%d)\n",
89                hdr.type);
90       xdr_destroy (&xdr);
91       return;
92     }
93
94     args_xdrproc = wrap_call_get_args_xdrproc (w, hdr.proc);
95     if (wrap_error (w)) {
96       xdr_destroy (&xdr);
97       return;
98     }
99     ret_xdrproc = wrap_call_get_ret_xdrproc (w, hdr.proc);
100     if (wrap_error (w)) {
101       xdr_destroy (&xdr);
102       return;
103     }
104
105     argsv = calloc (1, wrap_call_get_args_struct_size (w, hdr.proc));
106     if (argsv == NULL) {
107       perror ("malloc");
108       exit (EXIT_FAILURE);
109     }
110     retv = calloc (1, wrap_call_get_ret_struct_size (w, hdr.proc));
111     if (retv == NULL) {
112       perror ("malloc");
113       exit (EXIT_FAILURE);
114     }
115
116     /* Receive the arguments. */
117     if (!args_xdrproc (&xdr, argsv)) {
118       fprintf (stderr, "error receiving request arguments\n");
119       xdr_destroy (&xdr);
120       free (argsv);
121       free (retv);
122       return;
123     }
124
125     xdr_destroy (&xdr);
126
127     /* Call the underlying API. */
128     wrap_call (w, hdr.proc, argsv, retv);
129     free (argsv);
130
131     xdrstdio_create (&xdr, stdout, XDR_ENCODE);
132
133     if (! wrap_error (w)) {
134       /* Send back a normal reply. */
135       hdr.type = WRAP_INT_PROTO_TYPE_REPLY;
136
137       if (!wrap_int_xdr_message_header (&xdr, &hdr)) {
138         fprintf (stderr, "error sending reply header\n");
139         xdr_destroy (&xdr);
140         free (retv);
141         return;
142       }
143
144       if (!ret_xdrproc (&xdr, retv)) {
145         fprintf (stderr, "error sending reply return value\n");
146         xdr_destroy (&xdr);
147         free (retv);
148         return;
149       }
150     }
151     else {
152       /* Send back an error reply. */
153       err.error_message = (char *) wrap_get_error (w);
154       err.error_func = (char *) wrap_get_error_func (w);
155       err.error_errno = (char *) ""; /* XXX set this properly */
156
157       hdr.type = WRAP_INT_PROTO_TYPE_ERROR;
158
159       if (!wrap_int_xdr_message_header (&xdr, &hdr)) {
160         fprintf (stderr, "error sending reply error header\n");
161         xdr_destroy (&xdr);
162         free (retv);
163         return;
164       }
165
166       if (!wrap_int_xdr_message_error (&xdr, &err)) {
167         fprintf (stderr, "error sending reply error struct\n");
168         xdr_destroy (&xdr);
169         free (retv);
170         return;
171       }
172     }
173
174     free (retv);
175     xdr_destroy (&xdr);
176     xdr_free ((xdrproc_t) wrap_int_xdr_message_header, (void *) &hdr);
177   }
178 }