1 /* libguestfs - the guestfsd daemon
2 * Copyright (C) 2009 Red Hat Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program 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
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #include <sys/param.h> /* defines MIN */
29 #include <rpc/types.h>
33 #include "../src/guestfs_protocol.h"
35 /* XXX We should make this configurable from /proc/cmdline so that the
36 * verbose setting of the guestfs_h can be inherited here.
40 /* The message currently being processed. */
44 /* The daemon communications socket. */
54 struct guestfs_message_header hdr;
59 /* Read the length word. */
60 xread (sock, lenbuf, 4);
61 xdrmem_create (&xdr, lenbuf, 4, XDR_DECODE);
62 xdr_uint32_t (&xdr, &len);
65 if (len > GUESTFS_MESSAGE_MAX) {
66 fprintf (stderr, "guestfsd: incoming message is too long (%u bytes)\n",
73 reply_with_perror ("malloc");
77 xread (sock, buf, len);
82 for (i = 0; i < len; i += 16) {
84 for (j = i; j < MIN (i+16, len); ++j)
85 printf ("%02x ", (unsigned char) buf[j]);
89 for (j = i; j < MIN (i+16, len); ++j)
91 printf ("%c", buf[j]);
100 /* Decode the message header. */
101 xdrmem_create (&xdr, buf, len, XDR_DECODE);
102 if (!xdr_guestfs_message_header (&xdr, &hdr)) {
103 fprintf (stderr, "guestfsd: could not decode message header\n");
107 /* Check the version etc. */
108 if (hdr.prog != GUESTFS_PROGRAM) {
109 reply_with_error ("wrong program (%d)", hdr.prog);
112 if (hdr.vers != GUESTFS_PROTOCOL_VERSION) {
113 reply_with_error ("wrong protocol version (%d)", hdr.vers);
116 if (hdr.direction != GUESTFS_DIRECTION_CALL) {
117 reply_with_error ("unexpected message direction (%d)", hdr.direction);
120 if (hdr.status != GUESTFS_STATUS_OK) {
121 reply_with_error ("unexpected message status (%d)", hdr.status);
125 /* Now start to process this message. */
128 dispatch_incoming_message (&xdr);
129 /* Note that dispatch_incoming_message will also send a reply. */
137 static void send_error (const char *msg);
140 reply_with_error (const char *fs, ...)
142 char err[GUESTFS_ERROR_LEN];
146 vsnprintf (err, sizeof err, fs, args);
153 reply_with_perror (const char *fs, ...)
155 char buf1[GUESTFS_ERROR_LEN];
156 char buf2[GUESTFS_ERROR_LEN];
161 vsnprintf (buf1, sizeof buf1, fs, args);
164 snprintf (buf2, sizeof buf2, "%s: %s", buf1, strerror (err));
170 send_error (const char *msg)
173 char buf[GUESTFS_ERROR_LEN + 200];
175 struct guestfs_message_header hdr;
176 struct guestfs_message_error err;
179 fprintf (stderr, "guestfsd: error: %s\n", msg);
181 xdrmem_create (&xdr, buf, sizeof buf, XDR_ENCODE);
183 hdr.prog = GUESTFS_PROGRAM;
184 hdr.vers = GUESTFS_PROTOCOL_VERSION;
185 hdr.direction = GUESTFS_DIRECTION_REPLY;
186 hdr.status = GUESTFS_STATUS_ERROR;
190 if (!xdr_guestfs_message_header (&xdr, &hdr)) {
191 fprintf (stderr, "guestfsd: failed to encode error message header\n");
195 err.error = (char *) msg;
197 if (!xdr_guestfs_message_error (&xdr, &err)) {
198 fprintf (stderr, "guestfsd: failed to encode error message body\n");
202 len = xdr_getpos (&xdr);
205 xdrmem_create (&xdr, lenbuf, 4, XDR_ENCODE);
206 xdr_uint32_t (&xdr, &len);
209 xwrite (sock, lenbuf, 4);
210 xwrite (sock, buf, len);
214 reply (xdrproc_t xdrp, char *ret)
217 char buf[GUESTFS_MESSAGE_MAX];
219 struct guestfs_message_header hdr;
222 xdrmem_create (&xdr, buf, sizeof buf, XDR_ENCODE);
224 hdr.prog = GUESTFS_PROGRAM;
225 hdr.vers = GUESTFS_PROTOCOL_VERSION;
226 hdr.direction = GUESTFS_DIRECTION_REPLY;
227 hdr.status = GUESTFS_STATUS_OK;
231 if (!xdr_guestfs_message_header (&xdr, &hdr)) {
232 fprintf (stderr, "guestfsd: failed to encode reply header\n");
237 if (!(*xdrp) (&xdr, ret)) {
238 fprintf (stderr, "guestfsd: failed to encode reply body\n");
243 len = xdr_getpos (&xdr);
246 xdrmem_create (&xdr, lenbuf, 4, XDR_ENCODE);
247 xdr_uint32_t (&xdr, &len);
250 xwrite (sock, lenbuf, 4);
251 xwrite (sock, buf, len);