guestfs_send -> guestfs__send, in case we want a future command called "send".
[libguestfs.git] / src / guestfs-actions.c
1 /* libguestfs generated file
2  * WARNING: THIS FILE IS GENERATED BY 'src/generator.ml'.
3  * ANY CHANGES YOU MAKE TO THIS FILE WILL BE LOST.
4  *
5  * Copyright (C) 2009 Red Hat Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24
25 #include "guestfs.h"
26 #include "guestfs_protocol.h"
27
28 #define error guestfs_error
29 #define perrorf guestfs_perrorf
30 #define safe_malloc guestfs_safe_malloc
31 #define safe_realloc guestfs_safe_realloc
32 #define safe_strdup guestfs_safe_strdup
33 #define safe_memdup guestfs_safe_memdup
34
35 /* Check the return message from a call for validity. */
36 static int
37 check_reply_header (guestfs_h *g,
38                     const struct guestfs_message_header *hdr,
39                     int proc_nr, int serial)
40 {
41   if (hdr->prog != GUESTFS_PROGRAM) {
42     error (g, "wrong program (%d/%d)", hdr->prog, GUESTFS_PROGRAM);
43     return -1;
44   }
45   if (hdr->vers != GUESTFS_PROTOCOL_VERSION) {
46     error (g, "wrong protocol version (%d/%d)",
47            hdr->vers, GUESTFS_PROTOCOL_VERSION);
48     return -1;
49   }
50   if (hdr->direction != GUESTFS_DIRECTION_REPLY) {
51     error (g, "unexpected message direction (%d/%d)",
52            hdr->direction, GUESTFS_DIRECTION_REPLY);
53     return -1;
54   }
55   if (hdr->proc != proc_nr) {
56     error (g, "unexpected procedure number (%d/%d)", hdr->proc, proc_nr);
57     return -1;
58   }
59   if (hdr->serial != serial) {
60     error (g, "unexpected serial (%d/%d)", hdr->serial, serial);
61     return -1;
62   }
63
64   return 0;
65 }
66
67 /* Check we are in the right state to run a high-level action. */
68 static int
69 check_state (guestfs_h *g, const char *caller)
70 {
71   if (!guestfs_is_ready (g)) {
72     if (guestfs_is_config (g))
73       error (g, "%s: call launch() before using this function",
74         caller);
75     else if (guestfs_is_launching (g))
76       error (g, "%s: call wait_ready() before using this function",
77         caller);
78     else
79       error (g, "%s called from the wrong state, %d != READY",
80         caller, guestfs_get_state (g));
81     return -1;
82   }
83   return 0;
84 }
85
86 struct mount_state {
87   int cb_state;
88   struct guestfs_message_header hdr;
89   struct guestfs_message_error err;
90 };
91
92 static void mount_cb (guestfs_h *g, void *data, XDR *xdr)
93 {
94   guestfs_main_loop *ml = guestfs_get_main_loop (g);
95   struct mount_state *state = (struct mount_state *) data;
96
97   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
98     error (g, "guestfs_mount: failed to parse reply header");
99     return;
100   }
101   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
102     if (!xdr_guestfs_message_error (xdr, &state->err)) {
103       error (g, "guestfs_mount: failed to parse reply error");
104       return;
105     }
106     goto done;
107   }
108  done:
109   state->cb_state = 1;
110   ml->main_loop_quit (ml, g);
111 }
112
113 int guestfs_mount (guestfs_h *g,
114                 const char *device,
115                 const char *mountpoint)
116 {
117   struct guestfs_mount_args args;
118   struct mount_state state;
119   guestfs_main_loop *ml = guestfs_get_main_loop (g);
120   int serial;
121
122   if (check_state (g, "guestfs_mount") == -1) return -1;
123
124   memset (&state, 0, sizeof state);
125
126   args.device = (char *) device;
127   args.mountpoint = (char *) mountpoint;
128   serial = guestfs__send (g, GUESTFS_PROC_MOUNT,
129                      (xdrproc_t) xdr_guestfs_mount_args, (char *) &args);
130   if (serial == -1)
131     return -1;
132
133   state.cb_state = 0;
134   guestfs_set_reply_callback (g, mount_cb, &state);
135   (void) ml->main_loop_run (ml, g);
136   guestfs_set_reply_callback (g, NULL, NULL);
137   if (!state.cb_state) {
138     error (g, "guestfs_mount failed, see earlier error messages");
139     return -1;
140   }
141
142   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_MOUNT, serial) == -1)
143     return -1;
144
145   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
146     error (g, "%s", state.err.error_message);
147     return -1;
148   }
149
150   return 0;
151 }
152
153 struct sync_state {
154   int cb_state;
155   struct guestfs_message_header hdr;
156   struct guestfs_message_error err;
157 };
158
159 static void sync_cb (guestfs_h *g, void *data, XDR *xdr)
160 {
161   guestfs_main_loop *ml = guestfs_get_main_loop (g);
162   struct sync_state *state = (struct sync_state *) data;
163
164   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
165     error (g, "guestfs_sync: failed to parse reply header");
166     return;
167   }
168   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
169     if (!xdr_guestfs_message_error (xdr, &state->err)) {
170       error (g, "guestfs_sync: failed to parse reply error");
171       return;
172     }
173     goto done;
174   }
175  done:
176   state->cb_state = 1;
177   ml->main_loop_quit (ml, g);
178 }
179
180 int guestfs_sync (guestfs_h *g)
181 {
182   struct sync_state state;
183   guestfs_main_loop *ml = guestfs_get_main_loop (g);
184   int serial;
185
186   if (check_state (g, "guestfs_sync") == -1) return -1;
187
188   memset (&state, 0, sizeof state);
189
190   serial = guestfs__send (g, GUESTFS_PROC_SYNC, NULL, NULL);
191   if (serial == -1)
192     return -1;
193
194   state.cb_state = 0;
195   guestfs_set_reply_callback (g, sync_cb, &state);
196   (void) ml->main_loop_run (ml, g);
197   guestfs_set_reply_callback (g, NULL, NULL);
198   if (!state.cb_state) {
199     error (g, "guestfs_sync failed, see earlier error messages");
200     return -1;
201   }
202
203   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_SYNC, serial) == -1)
204     return -1;
205
206   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
207     error (g, "%s", state.err.error_message);
208     return -1;
209   }
210
211   return 0;
212 }
213
214 struct touch_state {
215   int cb_state;
216   struct guestfs_message_header hdr;
217   struct guestfs_message_error err;
218 };
219
220 static void touch_cb (guestfs_h *g, void *data, XDR *xdr)
221 {
222   guestfs_main_loop *ml = guestfs_get_main_loop (g);
223   struct touch_state *state = (struct touch_state *) data;
224
225   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
226     error (g, "guestfs_touch: failed to parse reply header");
227     return;
228   }
229   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
230     if (!xdr_guestfs_message_error (xdr, &state->err)) {
231       error (g, "guestfs_touch: failed to parse reply error");
232       return;
233     }
234     goto done;
235   }
236  done:
237   state->cb_state = 1;
238   ml->main_loop_quit (ml, g);
239 }
240
241 int guestfs_touch (guestfs_h *g,
242                 const char *path)
243 {
244   struct guestfs_touch_args args;
245   struct touch_state state;
246   guestfs_main_loop *ml = guestfs_get_main_loop (g);
247   int serial;
248
249   if (check_state (g, "guestfs_touch") == -1) return -1;
250
251   memset (&state, 0, sizeof state);
252
253   args.path = (char *) path;
254   serial = guestfs__send (g, GUESTFS_PROC_TOUCH,
255                      (xdrproc_t) xdr_guestfs_touch_args, (char *) &args);
256   if (serial == -1)
257     return -1;
258
259   state.cb_state = 0;
260   guestfs_set_reply_callback (g, touch_cb, &state);
261   (void) ml->main_loop_run (ml, g);
262   guestfs_set_reply_callback (g, NULL, NULL);
263   if (!state.cb_state) {
264     error (g, "guestfs_touch failed, see earlier error messages");
265     return -1;
266   }
267
268   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_TOUCH, serial) == -1)
269     return -1;
270
271   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
272     error (g, "%s", state.err.error_message);
273     return -1;
274   }
275
276   return 0;
277 }
278
279 struct cat_state {
280   int cb_state;
281   struct guestfs_message_header hdr;
282   struct guestfs_message_error err;
283   struct guestfs_cat_ret ret;
284 };
285
286 static void cat_cb (guestfs_h *g, void *data, XDR *xdr)
287 {
288   guestfs_main_loop *ml = guestfs_get_main_loop (g);
289   struct cat_state *state = (struct cat_state *) data;
290
291   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
292     error (g, "guestfs_cat: failed to parse reply header");
293     return;
294   }
295   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
296     if (!xdr_guestfs_message_error (xdr, &state->err)) {
297       error (g, "guestfs_cat: failed to parse reply error");
298       return;
299     }
300     goto done;
301   }
302   if (!xdr_guestfs_cat_ret (xdr, &state->ret)) {
303     error (g, "guestfs_cat: failed to parse reply");
304     return;
305   }
306  done:
307   state->cb_state = 1;
308   ml->main_loop_quit (ml, g);
309 }
310
311 char *guestfs_cat (guestfs_h *g,
312                 const char *path)
313 {
314   struct guestfs_cat_args args;
315   struct cat_state state;
316   guestfs_main_loop *ml = guestfs_get_main_loop (g);
317   int serial;
318
319   if (check_state (g, "guestfs_cat") == -1) return NULL;
320
321   memset (&state, 0, sizeof state);
322
323   args.path = (char *) path;
324   serial = guestfs__send (g, GUESTFS_PROC_CAT,
325                      (xdrproc_t) xdr_guestfs_cat_args, (char *) &args);
326   if (serial == -1)
327     return NULL;
328
329   state.cb_state = 0;
330   guestfs_set_reply_callback (g, cat_cb, &state);
331   (void) ml->main_loop_run (ml, g);
332   guestfs_set_reply_callback (g, NULL, NULL);
333   if (!state.cb_state) {
334     error (g, "guestfs_cat failed, see earlier error messages");
335     return NULL;
336   }
337
338   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_CAT, serial) == -1)
339     return NULL;
340
341   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
342     error (g, "%s", state.err.error_message);
343     return NULL;
344   }
345
346   return state.ret.content; /* caller will free */
347 }
348
349 struct ll_state {
350   int cb_state;
351   struct guestfs_message_header hdr;
352   struct guestfs_message_error err;
353   struct guestfs_ll_ret ret;
354 };
355
356 static void ll_cb (guestfs_h *g, void *data, XDR *xdr)
357 {
358   guestfs_main_loop *ml = guestfs_get_main_loop (g);
359   struct ll_state *state = (struct ll_state *) data;
360
361   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
362     error (g, "guestfs_ll: failed to parse reply header");
363     return;
364   }
365   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
366     if (!xdr_guestfs_message_error (xdr, &state->err)) {
367       error (g, "guestfs_ll: failed to parse reply error");
368       return;
369     }
370     goto done;
371   }
372   if (!xdr_guestfs_ll_ret (xdr, &state->ret)) {
373     error (g, "guestfs_ll: failed to parse reply");
374     return;
375   }
376  done:
377   state->cb_state = 1;
378   ml->main_loop_quit (ml, g);
379 }
380
381 char *guestfs_ll (guestfs_h *g,
382                 const char *directory)
383 {
384   struct guestfs_ll_args args;
385   struct ll_state state;
386   guestfs_main_loop *ml = guestfs_get_main_loop (g);
387   int serial;
388
389   if (check_state (g, "guestfs_ll") == -1) return NULL;
390
391   memset (&state, 0, sizeof state);
392
393   args.directory = (char *) directory;
394   serial = guestfs__send (g, GUESTFS_PROC_LL,
395                      (xdrproc_t) xdr_guestfs_ll_args, (char *) &args);
396   if (serial == -1)
397     return NULL;
398
399   state.cb_state = 0;
400   guestfs_set_reply_callback (g, ll_cb, &state);
401   (void) ml->main_loop_run (ml, g);
402   guestfs_set_reply_callback (g, NULL, NULL);
403   if (!state.cb_state) {
404     error (g, "guestfs_ll failed, see earlier error messages");
405     return NULL;
406   }
407
408   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_LL, serial) == -1)
409     return NULL;
410
411   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
412     error (g, "%s", state.err.error_message);
413     return NULL;
414   }
415
416   return state.ret.listing; /* caller will free */
417 }
418
419 struct ls_state {
420   int cb_state;
421   struct guestfs_message_header hdr;
422   struct guestfs_message_error err;
423   struct guestfs_ls_ret ret;
424 };
425
426 static void ls_cb (guestfs_h *g, void *data, XDR *xdr)
427 {
428   guestfs_main_loop *ml = guestfs_get_main_loop (g);
429   struct ls_state *state = (struct ls_state *) data;
430
431   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
432     error (g, "guestfs_ls: failed to parse reply header");
433     return;
434   }
435   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
436     if (!xdr_guestfs_message_error (xdr, &state->err)) {
437       error (g, "guestfs_ls: failed to parse reply error");
438       return;
439     }
440     goto done;
441   }
442   if (!xdr_guestfs_ls_ret (xdr, &state->ret)) {
443     error (g, "guestfs_ls: failed to parse reply");
444     return;
445   }
446  done:
447   state->cb_state = 1;
448   ml->main_loop_quit (ml, g);
449 }
450
451 char **guestfs_ls (guestfs_h *g,
452                 const char *directory)
453 {
454   struct guestfs_ls_args args;
455   struct ls_state state;
456   guestfs_main_loop *ml = guestfs_get_main_loop (g);
457   int serial;
458
459   if (check_state (g, "guestfs_ls") == -1) return NULL;
460
461   memset (&state, 0, sizeof state);
462
463   args.directory = (char *) directory;
464   serial = guestfs__send (g, GUESTFS_PROC_LS,
465                      (xdrproc_t) xdr_guestfs_ls_args, (char *) &args);
466   if (serial == -1)
467     return NULL;
468
469   state.cb_state = 0;
470   guestfs_set_reply_callback (g, ls_cb, &state);
471   (void) ml->main_loop_run (ml, g);
472   guestfs_set_reply_callback (g, NULL, NULL);
473   if (!state.cb_state) {
474     error (g, "guestfs_ls failed, see earlier error messages");
475     return NULL;
476   }
477
478   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_LS, serial) == -1)
479     return NULL;
480
481   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
482     error (g, "%s", state.err.error_message);
483     return NULL;
484   }
485
486   /* caller will free this, but we need to add a NULL entry */
487   state.ret.listing.listing_val =
488     safe_realloc (g, state.ret.listing.listing_val,
489                   sizeof (char *) * (state.ret.listing.listing_len + 1));
490   state.ret.listing.listing_val[state.ret.listing.listing_len] = NULL;
491   return state.ret.listing.listing_val;
492 }
493
494 struct list_devices_state {
495   int cb_state;
496   struct guestfs_message_header hdr;
497   struct guestfs_message_error err;
498   struct guestfs_list_devices_ret ret;
499 };
500
501 static void list_devices_cb (guestfs_h *g, void *data, XDR *xdr)
502 {
503   guestfs_main_loop *ml = guestfs_get_main_loop (g);
504   struct list_devices_state *state = (struct list_devices_state *) data;
505
506   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
507     error (g, "guestfs_list_devices: failed to parse reply header");
508     return;
509   }
510   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
511     if (!xdr_guestfs_message_error (xdr, &state->err)) {
512       error (g, "guestfs_list_devices: failed to parse reply error");
513       return;
514     }
515     goto done;
516   }
517   if (!xdr_guestfs_list_devices_ret (xdr, &state->ret)) {
518     error (g, "guestfs_list_devices: failed to parse reply");
519     return;
520   }
521  done:
522   state->cb_state = 1;
523   ml->main_loop_quit (ml, g);
524 }
525
526 char **guestfs_list_devices (guestfs_h *g)
527 {
528   struct list_devices_state state;
529   guestfs_main_loop *ml = guestfs_get_main_loop (g);
530   int serial;
531
532   if (check_state (g, "guestfs_list_devices") == -1) return NULL;
533
534   memset (&state, 0, sizeof state);
535
536   serial = guestfs__send (g, GUESTFS_PROC_LIST_DEVICES, NULL, NULL);
537   if (serial == -1)
538     return NULL;
539
540   state.cb_state = 0;
541   guestfs_set_reply_callback (g, list_devices_cb, &state);
542   (void) ml->main_loop_run (ml, g);
543   guestfs_set_reply_callback (g, NULL, NULL);
544   if (!state.cb_state) {
545     error (g, "guestfs_list_devices failed, see earlier error messages");
546     return NULL;
547   }
548
549   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_LIST_DEVICES, serial) == -1)
550     return NULL;
551
552   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
553     error (g, "%s", state.err.error_message);
554     return NULL;
555   }
556
557   /* caller will free this, but we need to add a NULL entry */
558   state.ret.devices.devices_val =
559     safe_realloc (g, state.ret.devices.devices_val,
560                   sizeof (char *) * (state.ret.devices.devices_len + 1));
561   state.ret.devices.devices_val[state.ret.devices.devices_len] = NULL;
562   return state.ret.devices.devices_val;
563 }
564
565 struct list_partitions_state {
566   int cb_state;
567   struct guestfs_message_header hdr;
568   struct guestfs_message_error err;
569   struct guestfs_list_partitions_ret ret;
570 };
571
572 static void list_partitions_cb (guestfs_h *g, void *data, XDR *xdr)
573 {
574   guestfs_main_loop *ml = guestfs_get_main_loop (g);
575   struct list_partitions_state *state = (struct list_partitions_state *) data;
576
577   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
578     error (g, "guestfs_list_partitions: failed to parse reply header");
579     return;
580   }
581   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
582     if (!xdr_guestfs_message_error (xdr, &state->err)) {
583       error (g, "guestfs_list_partitions: failed to parse reply error");
584       return;
585     }
586     goto done;
587   }
588   if (!xdr_guestfs_list_partitions_ret (xdr, &state->ret)) {
589     error (g, "guestfs_list_partitions: failed to parse reply");
590     return;
591   }
592  done:
593   state->cb_state = 1;
594   ml->main_loop_quit (ml, g);
595 }
596
597 char **guestfs_list_partitions (guestfs_h *g)
598 {
599   struct list_partitions_state state;
600   guestfs_main_loop *ml = guestfs_get_main_loop (g);
601   int serial;
602
603   if (check_state (g, "guestfs_list_partitions") == -1) return NULL;
604
605   memset (&state, 0, sizeof state);
606
607   serial = guestfs__send (g, GUESTFS_PROC_LIST_PARTITIONS, NULL, NULL);
608   if (serial == -1)
609     return NULL;
610
611   state.cb_state = 0;
612   guestfs_set_reply_callback (g, list_partitions_cb, &state);
613   (void) ml->main_loop_run (ml, g);
614   guestfs_set_reply_callback (g, NULL, NULL);
615   if (!state.cb_state) {
616     error (g, "guestfs_list_partitions failed, see earlier error messages");
617     return NULL;
618   }
619
620   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_LIST_PARTITIONS, serial) == -1)
621     return NULL;
622
623   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
624     error (g, "%s", state.err.error_message);
625     return NULL;
626   }
627
628   /* caller will free this, but we need to add a NULL entry */
629   state.ret.partitions.partitions_val =
630     safe_realloc (g, state.ret.partitions.partitions_val,
631                   sizeof (char *) * (state.ret.partitions.partitions_len + 1));
632   state.ret.partitions.partitions_val[state.ret.partitions.partitions_len] = NULL;
633   return state.ret.partitions.partitions_val;
634 }
635
636 struct pvs_state {
637   int cb_state;
638   struct guestfs_message_header hdr;
639   struct guestfs_message_error err;
640   struct guestfs_pvs_ret ret;
641 };
642
643 static void pvs_cb (guestfs_h *g, void *data, XDR *xdr)
644 {
645   guestfs_main_loop *ml = guestfs_get_main_loop (g);
646   struct pvs_state *state = (struct pvs_state *) data;
647
648   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
649     error (g, "guestfs_pvs: failed to parse reply header");
650     return;
651   }
652   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
653     if (!xdr_guestfs_message_error (xdr, &state->err)) {
654       error (g, "guestfs_pvs: failed to parse reply error");
655       return;
656     }
657     goto done;
658   }
659   if (!xdr_guestfs_pvs_ret (xdr, &state->ret)) {
660     error (g, "guestfs_pvs: failed to parse reply");
661     return;
662   }
663  done:
664   state->cb_state = 1;
665   ml->main_loop_quit (ml, g);
666 }
667
668 char **guestfs_pvs (guestfs_h *g)
669 {
670   struct pvs_state state;
671   guestfs_main_loop *ml = guestfs_get_main_loop (g);
672   int serial;
673
674   if (check_state (g, "guestfs_pvs") == -1) return NULL;
675
676   memset (&state, 0, sizeof state);
677
678   serial = guestfs__send (g, GUESTFS_PROC_PVS, NULL, NULL);
679   if (serial == -1)
680     return NULL;
681
682   state.cb_state = 0;
683   guestfs_set_reply_callback (g, pvs_cb, &state);
684   (void) ml->main_loop_run (ml, g);
685   guestfs_set_reply_callback (g, NULL, NULL);
686   if (!state.cb_state) {
687     error (g, "guestfs_pvs failed, see earlier error messages");
688     return NULL;
689   }
690
691   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_PVS, serial) == -1)
692     return NULL;
693
694   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
695     error (g, "%s", state.err.error_message);
696     return NULL;
697   }
698
699   /* caller will free this, but we need to add a NULL entry */
700   state.ret.physvols.physvols_val =
701     safe_realloc (g, state.ret.physvols.physvols_val,
702                   sizeof (char *) * (state.ret.physvols.physvols_len + 1));
703   state.ret.physvols.physvols_val[state.ret.physvols.physvols_len] = NULL;
704   return state.ret.physvols.physvols_val;
705 }
706
707 struct vgs_state {
708   int cb_state;
709   struct guestfs_message_header hdr;
710   struct guestfs_message_error err;
711   struct guestfs_vgs_ret ret;
712 };
713
714 static void vgs_cb (guestfs_h *g, void *data, XDR *xdr)
715 {
716   guestfs_main_loop *ml = guestfs_get_main_loop (g);
717   struct vgs_state *state = (struct vgs_state *) data;
718
719   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
720     error (g, "guestfs_vgs: failed to parse reply header");
721     return;
722   }
723   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
724     if (!xdr_guestfs_message_error (xdr, &state->err)) {
725       error (g, "guestfs_vgs: failed to parse reply error");
726       return;
727     }
728     goto done;
729   }
730   if (!xdr_guestfs_vgs_ret (xdr, &state->ret)) {
731     error (g, "guestfs_vgs: failed to parse reply");
732     return;
733   }
734  done:
735   state->cb_state = 1;
736   ml->main_loop_quit (ml, g);
737 }
738
739 char **guestfs_vgs (guestfs_h *g)
740 {
741   struct vgs_state state;
742   guestfs_main_loop *ml = guestfs_get_main_loop (g);
743   int serial;
744
745   if (check_state (g, "guestfs_vgs") == -1) return NULL;
746
747   memset (&state, 0, sizeof state);
748
749   serial = guestfs__send (g, GUESTFS_PROC_VGS, NULL, NULL);
750   if (serial == -1)
751     return NULL;
752
753   state.cb_state = 0;
754   guestfs_set_reply_callback (g, vgs_cb, &state);
755   (void) ml->main_loop_run (ml, g);
756   guestfs_set_reply_callback (g, NULL, NULL);
757   if (!state.cb_state) {
758     error (g, "guestfs_vgs failed, see earlier error messages");
759     return NULL;
760   }
761
762   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_VGS, serial) == -1)
763     return NULL;
764
765   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
766     error (g, "%s", state.err.error_message);
767     return NULL;
768   }
769
770   /* caller will free this, but we need to add a NULL entry */
771   state.ret.volgroups.volgroups_val =
772     safe_realloc (g, state.ret.volgroups.volgroups_val,
773                   sizeof (char *) * (state.ret.volgroups.volgroups_len + 1));
774   state.ret.volgroups.volgroups_val[state.ret.volgroups.volgroups_len] = NULL;
775   return state.ret.volgroups.volgroups_val;
776 }
777
778 struct lvs_state {
779   int cb_state;
780   struct guestfs_message_header hdr;
781   struct guestfs_message_error err;
782   struct guestfs_lvs_ret ret;
783 };
784
785 static void lvs_cb (guestfs_h *g, void *data, XDR *xdr)
786 {
787   guestfs_main_loop *ml = guestfs_get_main_loop (g);
788   struct lvs_state *state = (struct lvs_state *) data;
789
790   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
791     error (g, "guestfs_lvs: failed to parse reply header");
792     return;
793   }
794   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
795     if (!xdr_guestfs_message_error (xdr, &state->err)) {
796       error (g, "guestfs_lvs: failed to parse reply error");
797       return;
798     }
799     goto done;
800   }
801   if (!xdr_guestfs_lvs_ret (xdr, &state->ret)) {
802     error (g, "guestfs_lvs: failed to parse reply");
803     return;
804   }
805  done:
806   state->cb_state = 1;
807   ml->main_loop_quit (ml, g);
808 }
809
810 char **guestfs_lvs (guestfs_h *g)
811 {
812   struct lvs_state state;
813   guestfs_main_loop *ml = guestfs_get_main_loop (g);
814   int serial;
815
816   if (check_state (g, "guestfs_lvs") == -1) return NULL;
817
818   memset (&state, 0, sizeof state);
819
820   serial = guestfs__send (g, GUESTFS_PROC_LVS, NULL, NULL);
821   if (serial == -1)
822     return NULL;
823
824   state.cb_state = 0;
825   guestfs_set_reply_callback (g, lvs_cb, &state);
826   (void) ml->main_loop_run (ml, g);
827   guestfs_set_reply_callback (g, NULL, NULL);
828   if (!state.cb_state) {
829     error (g, "guestfs_lvs failed, see earlier error messages");
830     return NULL;
831   }
832
833   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_LVS, serial) == -1)
834     return NULL;
835
836   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
837     error (g, "%s", state.err.error_message);
838     return NULL;
839   }
840
841   /* caller will free this, but we need to add a NULL entry */
842   state.ret.logvols.logvols_val =
843     safe_realloc (g, state.ret.logvols.logvols_val,
844                   sizeof (char *) * (state.ret.logvols.logvols_len + 1));
845   state.ret.logvols.logvols_val[state.ret.logvols.logvols_len] = NULL;
846   return state.ret.logvols.logvols_val;
847 }
848
849 struct pvs_full_state {
850   int cb_state;
851   struct guestfs_message_header hdr;
852   struct guestfs_message_error err;
853   struct guestfs_pvs_full_ret ret;
854 };
855
856 static void pvs_full_cb (guestfs_h *g, void *data, XDR *xdr)
857 {
858   guestfs_main_loop *ml = guestfs_get_main_loop (g);
859   struct pvs_full_state *state = (struct pvs_full_state *) data;
860
861   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
862     error (g, "guestfs_pvs_full: failed to parse reply header");
863     return;
864   }
865   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
866     if (!xdr_guestfs_message_error (xdr, &state->err)) {
867       error (g, "guestfs_pvs_full: failed to parse reply error");
868       return;
869     }
870     goto done;
871   }
872   if (!xdr_guestfs_pvs_full_ret (xdr, &state->ret)) {
873     error (g, "guestfs_pvs_full: failed to parse reply");
874     return;
875   }
876  done:
877   state->cb_state = 1;
878   ml->main_loop_quit (ml, g);
879 }
880
881 struct guestfs_lvm_pv_list *guestfs_pvs_full (guestfs_h *g)
882 {
883   struct pvs_full_state state;
884   guestfs_main_loop *ml = guestfs_get_main_loop (g);
885   int serial;
886
887   if (check_state (g, "guestfs_pvs_full") == -1) return NULL;
888
889   memset (&state, 0, sizeof state);
890
891   serial = guestfs__send (g, GUESTFS_PROC_PVS_FULL, NULL, NULL);
892   if (serial == -1)
893     return NULL;
894
895   state.cb_state = 0;
896   guestfs_set_reply_callback (g, pvs_full_cb, &state);
897   (void) ml->main_loop_run (ml, g);
898   guestfs_set_reply_callback (g, NULL, NULL);
899   if (!state.cb_state) {
900     error (g, "guestfs_pvs_full failed, see earlier error messages");
901     return NULL;
902   }
903
904   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_PVS_FULL, serial) == -1)
905     return NULL;
906
907   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
908     error (g, "%s", state.err.error_message);
909     return NULL;
910   }
911
912   /* caller will free this */
913   return safe_memdup (g, &state.ret.physvols, sizeof (state.ret.physvols));
914 }
915
916 struct vgs_full_state {
917   int cb_state;
918   struct guestfs_message_header hdr;
919   struct guestfs_message_error err;
920   struct guestfs_vgs_full_ret ret;
921 };
922
923 static void vgs_full_cb (guestfs_h *g, void *data, XDR *xdr)
924 {
925   guestfs_main_loop *ml = guestfs_get_main_loop (g);
926   struct vgs_full_state *state = (struct vgs_full_state *) data;
927
928   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
929     error (g, "guestfs_vgs_full: failed to parse reply header");
930     return;
931   }
932   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
933     if (!xdr_guestfs_message_error (xdr, &state->err)) {
934       error (g, "guestfs_vgs_full: failed to parse reply error");
935       return;
936     }
937     goto done;
938   }
939   if (!xdr_guestfs_vgs_full_ret (xdr, &state->ret)) {
940     error (g, "guestfs_vgs_full: failed to parse reply");
941     return;
942   }
943  done:
944   state->cb_state = 1;
945   ml->main_loop_quit (ml, g);
946 }
947
948 struct guestfs_lvm_vg_list *guestfs_vgs_full (guestfs_h *g)
949 {
950   struct vgs_full_state state;
951   guestfs_main_loop *ml = guestfs_get_main_loop (g);
952   int serial;
953
954   if (check_state (g, "guestfs_vgs_full") == -1) return NULL;
955
956   memset (&state, 0, sizeof state);
957
958   serial = guestfs__send (g, GUESTFS_PROC_VGS_FULL, NULL, NULL);
959   if (serial == -1)
960     return NULL;
961
962   state.cb_state = 0;
963   guestfs_set_reply_callback (g, vgs_full_cb, &state);
964   (void) ml->main_loop_run (ml, g);
965   guestfs_set_reply_callback (g, NULL, NULL);
966   if (!state.cb_state) {
967     error (g, "guestfs_vgs_full failed, see earlier error messages");
968     return NULL;
969   }
970
971   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_VGS_FULL, serial) == -1)
972     return NULL;
973
974   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
975     error (g, "%s", state.err.error_message);
976     return NULL;
977   }
978
979   /* caller will free this */
980   return safe_memdup (g, &state.ret.volgroups, sizeof (state.ret.volgroups));
981 }
982
983 struct lvs_full_state {
984   int cb_state;
985   struct guestfs_message_header hdr;
986   struct guestfs_message_error err;
987   struct guestfs_lvs_full_ret ret;
988 };
989
990 static void lvs_full_cb (guestfs_h *g, void *data, XDR *xdr)
991 {
992   guestfs_main_loop *ml = guestfs_get_main_loop (g);
993   struct lvs_full_state *state = (struct lvs_full_state *) data;
994
995   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
996     error (g, "guestfs_lvs_full: failed to parse reply header");
997     return;
998   }
999   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
1000     if (!xdr_guestfs_message_error (xdr, &state->err)) {
1001       error (g, "guestfs_lvs_full: failed to parse reply error");
1002       return;
1003     }
1004     goto done;
1005   }
1006   if (!xdr_guestfs_lvs_full_ret (xdr, &state->ret)) {
1007     error (g, "guestfs_lvs_full: failed to parse reply");
1008     return;
1009   }
1010  done:
1011   state->cb_state = 1;
1012   ml->main_loop_quit (ml, g);
1013 }
1014
1015 struct guestfs_lvm_lv_list *guestfs_lvs_full (guestfs_h *g)
1016 {
1017   struct lvs_full_state state;
1018   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1019   int serial;
1020
1021   if (check_state (g, "guestfs_lvs_full") == -1) return NULL;
1022
1023   memset (&state, 0, sizeof state);
1024
1025   serial = guestfs__send (g, GUESTFS_PROC_LVS_FULL, NULL, NULL);
1026   if (serial == -1)
1027     return NULL;
1028
1029   state.cb_state = 0;
1030   guestfs_set_reply_callback (g, lvs_full_cb, &state);
1031   (void) ml->main_loop_run (ml, g);
1032   guestfs_set_reply_callback (g, NULL, NULL);
1033   if (!state.cb_state) {
1034     error (g, "guestfs_lvs_full failed, see earlier error messages");
1035     return NULL;
1036   }
1037
1038   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_LVS_FULL, serial) == -1)
1039     return NULL;
1040
1041   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
1042     error (g, "%s", state.err.error_message);
1043     return NULL;
1044   }
1045
1046   /* caller will free this */
1047   return safe_memdup (g, &state.ret.logvols, sizeof (state.ret.logvols));
1048 }
1049
1050 struct read_lines_state {
1051   int cb_state;
1052   struct guestfs_message_header hdr;
1053   struct guestfs_message_error err;
1054   struct guestfs_read_lines_ret ret;
1055 };
1056
1057 static void read_lines_cb (guestfs_h *g, void *data, XDR *xdr)
1058 {
1059   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1060   struct read_lines_state *state = (struct read_lines_state *) data;
1061
1062   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
1063     error (g, "guestfs_read_lines: failed to parse reply header");
1064     return;
1065   }
1066   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
1067     if (!xdr_guestfs_message_error (xdr, &state->err)) {
1068       error (g, "guestfs_read_lines: failed to parse reply error");
1069       return;
1070     }
1071     goto done;
1072   }
1073   if (!xdr_guestfs_read_lines_ret (xdr, &state->ret)) {
1074     error (g, "guestfs_read_lines: failed to parse reply");
1075     return;
1076   }
1077  done:
1078   state->cb_state = 1;
1079   ml->main_loop_quit (ml, g);
1080 }
1081
1082 char **guestfs_read_lines (guestfs_h *g,
1083                 const char *path)
1084 {
1085   struct guestfs_read_lines_args args;
1086   struct read_lines_state state;
1087   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1088   int serial;
1089
1090   if (check_state (g, "guestfs_read_lines") == -1) return NULL;
1091
1092   memset (&state, 0, sizeof state);
1093
1094   args.path = (char *) path;
1095   serial = guestfs__send (g, GUESTFS_PROC_READ_LINES,
1096                      (xdrproc_t) xdr_guestfs_read_lines_args, (char *) &args);
1097   if (serial == -1)
1098     return NULL;
1099
1100   state.cb_state = 0;
1101   guestfs_set_reply_callback (g, read_lines_cb, &state);
1102   (void) ml->main_loop_run (ml, g);
1103   guestfs_set_reply_callback (g, NULL, NULL);
1104   if (!state.cb_state) {
1105     error (g, "guestfs_read_lines failed, see earlier error messages");
1106     return NULL;
1107   }
1108
1109   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_READ_LINES, serial) == -1)
1110     return NULL;
1111
1112   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
1113     error (g, "%s", state.err.error_message);
1114     return NULL;
1115   }
1116
1117   /* caller will free this, but we need to add a NULL entry */
1118   state.ret.lines.lines_val =
1119     safe_realloc (g, state.ret.lines.lines_val,
1120                   sizeof (char *) * (state.ret.lines.lines_len + 1));
1121   state.ret.lines.lines_val[state.ret.lines.lines_len] = NULL;
1122   return state.ret.lines.lines_val;
1123 }
1124
1125 struct aug_init_state {
1126   int cb_state;
1127   struct guestfs_message_header hdr;
1128   struct guestfs_message_error err;
1129 };
1130
1131 static void aug_init_cb (guestfs_h *g, void *data, XDR *xdr)
1132 {
1133   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1134   struct aug_init_state *state = (struct aug_init_state *) data;
1135
1136   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
1137     error (g, "guestfs_aug_init: failed to parse reply header");
1138     return;
1139   }
1140   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
1141     if (!xdr_guestfs_message_error (xdr, &state->err)) {
1142       error (g, "guestfs_aug_init: failed to parse reply error");
1143       return;
1144     }
1145     goto done;
1146   }
1147  done:
1148   state->cb_state = 1;
1149   ml->main_loop_quit (ml, g);
1150 }
1151
1152 int guestfs_aug_init (guestfs_h *g,
1153                 const char *root,
1154                 int flags)
1155 {
1156   struct guestfs_aug_init_args args;
1157   struct aug_init_state state;
1158   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1159   int serial;
1160
1161   if (check_state (g, "guestfs_aug_init") == -1) return -1;
1162
1163   memset (&state, 0, sizeof state);
1164
1165   args.root = (char *) root;
1166   args.flags = flags;
1167   serial = guestfs__send (g, GUESTFS_PROC_AUG_INIT,
1168                      (xdrproc_t) xdr_guestfs_aug_init_args, (char *) &args);
1169   if (serial == -1)
1170     return -1;
1171
1172   state.cb_state = 0;
1173   guestfs_set_reply_callback (g, aug_init_cb, &state);
1174   (void) ml->main_loop_run (ml, g);
1175   guestfs_set_reply_callback (g, NULL, NULL);
1176   if (!state.cb_state) {
1177     error (g, "guestfs_aug_init failed, see earlier error messages");
1178     return -1;
1179   }
1180
1181   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_INIT, serial) == -1)
1182     return -1;
1183
1184   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
1185     error (g, "%s", state.err.error_message);
1186     return -1;
1187   }
1188
1189   return 0;
1190 }
1191
1192 struct aug_close_state {
1193   int cb_state;
1194   struct guestfs_message_header hdr;
1195   struct guestfs_message_error err;
1196 };
1197
1198 static void aug_close_cb (guestfs_h *g, void *data, XDR *xdr)
1199 {
1200   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1201   struct aug_close_state *state = (struct aug_close_state *) data;
1202
1203   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
1204     error (g, "guestfs_aug_close: failed to parse reply header");
1205     return;
1206   }
1207   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
1208     if (!xdr_guestfs_message_error (xdr, &state->err)) {
1209       error (g, "guestfs_aug_close: failed to parse reply error");
1210       return;
1211     }
1212     goto done;
1213   }
1214  done:
1215   state->cb_state = 1;
1216   ml->main_loop_quit (ml, g);
1217 }
1218
1219 int guestfs_aug_close (guestfs_h *g)
1220 {
1221   struct aug_close_state state;
1222   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1223   int serial;
1224
1225   if (check_state (g, "guestfs_aug_close") == -1) return -1;
1226
1227   memset (&state, 0, sizeof state);
1228
1229   serial = guestfs__send (g, GUESTFS_PROC_AUG_CLOSE, NULL, NULL);
1230   if (serial == -1)
1231     return -1;
1232
1233   state.cb_state = 0;
1234   guestfs_set_reply_callback (g, aug_close_cb, &state);
1235   (void) ml->main_loop_run (ml, g);
1236   guestfs_set_reply_callback (g, NULL, NULL);
1237   if (!state.cb_state) {
1238     error (g, "guestfs_aug_close failed, see earlier error messages");
1239     return -1;
1240   }
1241
1242   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_CLOSE, serial) == -1)
1243     return -1;
1244
1245   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
1246     error (g, "%s", state.err.error_message);
1247     return -1;
1248   }
1249
1250   return 0;
1251 }
1252
1253 struct aug_defvar_state {
1254   int cb_state;
1255   struct guestfs_message_header hdr;
1256   struct guestfs_message_error err;
1257   struct guestfs_aug_defvar_ret ret;
1258 };
1259
1260 static void aug_defvar_cb (guestfs_h *g, void *data, XDR *xdr)
1261 {
1262   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1263   struct aug_defvar_state *state = (struct aug_defvar_state *) data;
1264
1265   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
1266     error (g, "guestfs_aug_defvar: failed to parse reply header");
1267     return;
1268   }
1269   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
1270     if (!xdr_guestfs_message_error (xdr, &state->err)) {
1271       error (g, "guestfs_aug_defvar: failed to parse reply error");
1272       return;
1273     }
1274     goto done;
1275   }
1276   if (!xdr_guestfs_aug_defvar_ret (xdr, &state->ret)) {
1277     error (g, "guestfs_aug_defvar: failed to parse reply");
1278     return;
1279   }
1280  done:
1281   state->cb_state = 1;
1282   ml->main_loop_quit (ml, g);
1283 }
1284
1285 int guestfs_aug_defvar (guestfs_h *g,
1286                 const char *name,
1287                 const char *expr)
1288 {
1289   struct guestfs_aug_defvar_args args;
1290   struct aug_defvar_state state;
1291   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1292   int serial;
1293
1294   if (check_state (g, "guestfs_aug_defvar") == -1) return -1;
1295
1296   memset (&state, 0, sizeof state);
1297
1298   args.name = (char *) name;
1299   args.expr = expr ? (char **) &expr : NULL;
1300   serial = guestfs__send (g, GUESTFS_PROC_AUG_DEFVAR,
1301                      (xdrproc_t) xdr_guestfs_aug_defvar_args, (char *) &args);
1302   if (serial == -1)
1303     return -1;
1304
1305   state.cb_state = 0;
1306   guestfs_set_reply_callback (g, aug_defvar_cb, &state);
1307   (void) ml->main_loop_run (ml, g);
1308   guestfs_set_reply_callback (g, NULL, NULL);
1309   if (!state.cb_state) {
1310     error (g, "guestfs_aug_defvar failed, see earlier error messages");
1311     return -1;
1312   }
1313
1314   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_DEFVAR, serial) == -1)
1315     return -1;
1316
1317   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
1318     error (g, "%s", state.err.error_message);
1319     return -1;
1320   }
1321
1322   return state.ret.nrnodes;
1323 }
1324
1325 struct aug_defnode_state {
1326   int cb_state;
1327   struct guestfs_message_header hdr;
1328   struct guestfs_message_error err;
1329   struct guestfs_aug_defnode_ret ret;
1330 };
1331
1332 static void aug_defnode_cb (guestfs_h *g, void *data, XDR *xdr)
1333 {
1334   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1335   struct aug_defnode_state *state = (struct aug_defnode_state *) data;
1336
1337   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
1338     error (g, "guestfs_aug_defnode: failed to parse reply header");
1339     return;
1340   }
1341   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
1342     if (!xdr_guestfs_message_error (xdr, &state->err)) {
1343       error (g, "guestfs_aug_defnode: failed to parse reply error");
1344       return;
1345     }
1346     goto done;
1347   }
1348   if (!xdr_guestfs_aug_defnode_ret (xdr, &state->ret)) {
1349     error (g, "guestfs_aug_defnode: failed to parse reply");
1350     return;
1351   }
1352  done:
1353   state->cb_state = 1;
1354   ml->main_loop_quit (ml, g);
1355 }
1356
1357 struct guestfs_int_bool *guestfs_aug_defnode (guestfs_h *g,
1358                 const char *name,
1359                 const char *expr,
1360                 const char *val)
1361 {
1362   struct guestfs_aug_defnode_args args;
1363   struct aug_defnode_state state;
1364   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1365   int serial;
1366
1367   if (check_state (g, "guestfs_aug_defnode") == -1) return NULL;
1368
1369   memset (&state, 0, sizeof state);
1370
1371   args.name = (char *) name;
1372   args.expr = (char *) expr;
1373   args.val = (char *) val;
1374   serial = guestfs__send (g, GUESTFS_PROC_AUG_DEFNODE,
1375                      (xdrproc_t) xdr_guestfs_aug_defnode_args, (char *) &args);
1376   if (serial == -1)
1377     return NULL;
1378
1379   state.cb_state = 0;
1380   guestfs_set_reply_callback (g, aug_defnode_cb, &state);
1381   (void) ml->main_loop_run (ml, g);
1382   guestfs_set_reply_callback (g, NULL, NULL);
1383   if (!state.cb_state) {
1384     error (g, "guestfs_aug_defnode failed, see earlier error messages");
1385     return NULL;
1386   }
1387
1388   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_DEFNODE, serial) == -1)
1389     return NULL;
1390
1391   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
1392     error (g, "%s", state.err.error_message);
1393     return NULL;
1394   }
1395
1396   /* caller with free this */
1397   return safe_memdup (g, &state.ret, sizeof (state.ret));
1398 }
1399
1400 struct aug_get_state {
1401   int cb_state;
1402   struct guestfs_message_header hdr;
1403   struct guestfs_message_error err;
1404   struct guestfs_aug_get_ret ret;
1405 };
1406
1407 static void aug_get_cb (guestfs_h *g, void *data, XDR *xdr)
1408 {
1409   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1410   struct aug_get_state *state = (struct aug_get_state *) data;
1411
1412   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
1413     error (g, "guestfs_aug_get: failed to parse reply header");
1414     return;
1415   }
1416   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
1417     if (!xdr_guestfs_message_error (xdr, &state->err)) {
1418       error (g, "guestfs_aug_get: failed to parse reply error");
1419       return;
1420     }
1421     goto done;
1422   }
1423   if (!xdr_guestfs_aug_get_ret (xdr, &state->ret)) {
1424     error (g, "guestfs_aug_get: failed to parse reply");
1425     return;
1426   }
1427  done:
1428   state->cb_state = 1;
1429   ml->main_loop_quit (ml, g);
1430 }
1431
1432 char *guestfs_aug_get (guestfs_h *g,
1433                 const char *path)
1434 {
1435   struct guestfs_aug_get_args args;
1436   struct aug_get_state state;
1437   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1438   int serial;
1439
1440   if (check_state (g, "guestfs_aug_get") == -1) return NULL;
1441
1442   memset (&state, 0, sizeof state);
1443
1444   args.path = (char *) path;
1445   serial = guestfs__send (g, GUESTFS_PROC_AUG_GET,
1446                      (xdrproc_t) xdr_guestfs_aug_get_args, (char *) &args);
1447   if (serial == -1)
1448     return NULL;
1449
1450   state.cb_state = 0;
1451   guestfs_set_reply_callback (g, aug_get_cb, &state);
1452   (void) ml->main_loop_run (ml, g);
1453   guestfs_set_reply_callback (g, NULL, NULL);
1454   if (!state.cb_state) {
1455     error (g, "guestfs_aug_get failed, see earlier error messages");
1456     return NULL;
1457   }
1458
1459   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_GET, serial) == -1)
1460     return NULL;
1461
1462   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
1463     error (g, "%s", state.err.error_message);
1464     return NULL;
1465   }
1466
1467   return state.ret.val; /* caller will free */
1468 }
1469
1470 struct aug_set_state {
1471   int cb_state;
1472   struct guestfs_message_header hdr;
1473   struct guestfs_message_error err;
1474 };
1475
1476 static void aug_set_cb (guestfs_h *g, void *data, XDR *xdr)
1477 {
1478   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1479   struct aug_set_state *state = (struct aug_set_state *) data;
1480
1481   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
1482     error (g, "guestfs_aug_set: failed to parse reply header");
1483     return;
1484   }
1485   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
1486     if (!xdr_guestfs_message_error (xdr, &state->err)) {
1487       error (g, "guestfs_aug_set: failed to parse reply error");
1488       return;
1489     }
1490     goto done;
1491   }
1492  done:
1493   state->cb_state = 1;
1494   ml->main_loop_quit (ml, g);
1495 }
1496
1497 int guestfs_aug_set (guestfs_h *g,
1498                 const char *path,
1499                 const char *val)
1500 {
1501   struct guestfs_aug_set_args args;
1502   struct aug_set_state state;
1503   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1504   int serial;
1505
1506   if (check_state (g, "guestfs_aug_set") == -1) return -1;
1507
1508   memset (&state, 0, sizeof state);
1509
1510   args.path = (char *) path;
1511   args.val = (char *) val;
1512   serial = guestfs__send (g, GUESTFS_PROC_AUG_SET,
1513                      (xdrproc_t) xdr_guestfs_aug_set_args, (char *) &args);
1514   if (serial == -1)
1515     return -1;
1516
1517   state.cb_state = 0;
1518   guestfs_set_reply_callback (g, aug_set_cb, &state);
1519   (void) ml->main_loop_run (ml, g);
1520   guestfs_set_reply_callback (g, NULL, NULL);
1521   if (!state.cb_state) {
1522     error (g, "guestfs_aug_set failed, see earlier error messages");
1523     return -1;
1524   }
1525
1526   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_SET, serial) == -1)
1527     return -1;
1528
1529   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
1530     error (g, "%s", state.err.error_message);
1531     return -1;
1532   }
1533
1534   return 0;
1535 }
1536
1537 struct aug_insert_state {
1538   int cb_state;
1539   struct guestfs_message_header hdr;
1540   struct guestfs_message_error err;
1541 };
1542
1543 static void aug_insert_cb (guestfs_h *g, void *data, XDR *xdr)
1544 {
1545   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1546   struct aug_insert_state *state = (struct aug_insert_state *) data;
1547
1548   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
1549     error (g, "guestfs_aug_insert: failed to parse reply header");
1550     return;
1551   }
1552   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
1553     if (!xdr_guestfs_message_error (xdr, &state->err)) {
1554       error (g, "guestfs_aug_insert: failed to parse reply error");
1555       return;
1556     }
1557     goto done;
1558   }
1559  done:
1560   state->cb_state = 1;
1561   ml->main_loop_quit (ml, g);
1562 }
1563
1564 int guestfs_aug_insert (guestfs_h *g,
1565                 const char *path,
1566                 const char *label,
1567                 int before)
1568 {
1569   struct guestfs_aug_insert_args args;
1570   struct aug_insert_state state;
1571   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1572   int serial;
1573
1574   if (check_state (g, "guestfs_aug_insert") == -1) return -1;
1575
1576   memset (&state, 0, sizeof state);
1577
1578   args.path = (char *) path;
1579   args.label = (char *) label;
1580   args.before = before;
1581   serial = guestfs__send (g, GUESTFS_PROC_AUG_INSERT,
1582                      (xdrproc_t) xdr_guestfs_aug_insert_args, (char *) &args);
1583   if (serial == -1)
1584     return -1;
1585
1586   state.cb_state = 0;
1587   guestfs_set_reply_callback (g, aug_insert_cb, &state);
1588   (void) ml->main_loop_run (ml, g);
1589   guestfs_set_reply_callback (g, NULL, NULL);
1590   if (!state.cb_state) {
1591     error (g, "guestfs_aug_insert failed, see earlier error messages");
1592     return -1;
1593   }
1594
1595   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_INSERT, serial) == -1)
1596     return -1;
1597
1598   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
1599     error (g, "%s", state.err.error_message);
1600     return -1;
1601   }
1602
1603   return 0;
1604 }
1605
1606 struct aug_rm_state {
1607   int cb_state;
1608   struct guestfs_message_header hdr;
1609   struct guestfs_message_error err;
1610   struct guestfs_aug_rm_ret ret;
1611 };
1612
1613 static void aug_rm_cb (guestfs_h *g, void *data, XDR *xdr)
1614 {
1615   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1616   struct aug_rm_state *state = (struct aug_rm_state *) data;
1617
1618   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
1619     error (g, "guestfs_aug_rm: failed to parse reply header");
1620     return;
1621   }
1622   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
1623     if (!xdr_guestfs_message_error (xdr, &state->err)) {
1624       error (g, "guestfs_aug_rm: failed to parse reply error");
1625       return;
1626     }
1627     goto done;
1628   }
1629   if (!xdr_guestfs_aug_rm_ret (xdr, &state->ret)) {
1630     error (g, "guestfs_aug_rm: failed to parse reply");
1631     return;
1632   }
1633  done:
1634   state->cb_state = 1;
1635   ml->main_loop_quit (ml, g);
1636 }
1637
1638 int guestfs_aug_rm (guestfs_h *g,
1639                 const char *path)
1640 {
1641   struct guestfs_aug_rm_args args;
1642   struct aug_rm_state state;
1643   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1644   int serial;
1645
1646   if (check_state (g, "guestfs_aug_rm") == -1) return -1;
1647
1648   memset (&state, 0, sizeof state);
1649
1650   args.path = (char *) path;
1651   serial = guestfs__send (g, GUESTFS_PROC_AUG_RM,
1652                      (xdrproc_t) xdr_guestfs_aug_rm_args, (char *) &args);
1653   if (serial == -1)
1654     return -1;
1655
1656   state.cb_state = 0;
1657   guestfs_set_reply_callback (g, aug_rm_cb, &state);
1658   (void) ml->main_loop_run (ml, g);
1659   guestfs_set_reply_callback (g, NULL, NULL);
1660   if (!state.cb_state) {
1661     error (g, "guestfs_aug_rm failed, see earlier error messages");
1662     return -1;
1663   }
1664
1665   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_RM, serial) == -1)
1666     return -1;
1667
1668   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
1669     error (g, "%s", state.err.error_message);
1670     return -1;
1671   }
1672
1673   return state.ret.nrnodes;
1674 }
1675
1676 struct aug_mv_state {
1677   int cb_state;
1678   struct guestfs_message_header hdr;
1679   struct guestfs_message_error err;
1680 };
1681
1682 static void aug_mv_cb (guestfs_h *g, void *data, XDR *xdr)
1683 {
1684   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1685   struct aug_mv_state *state = (struct aug_mv_state *) data;
1686
1687   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
1688     error (g, "guestfs_aug_mv: failed to parse reply header");
1689     return;
1690   }
1691   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
1692     if (!xdr_guestfs_message_error (xdr, &state->err)) {
1693       error (g, "guestfs_aug_mv: failed to parse reply error");
1694       return;
1695     }
1696     goto done;
1697   }
1698  done:
1699   state->cb_state = 1;
1700   ml->main_loop_quit (ml, g);
1701 }
1702
1703 int guestfs_aug_mv (guestfs_h *g,
1704                 const char *src,
1705                 const char *dest)
1706 {
1707   struct guestfs_aug_mv_args args;
1708   struct aug_mv_state state;
1709   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1710   int serial;
1711
1712   if (check_state (g, "guestfs_aug_mv") == -1) return -1;
1713
1714   memset (&state, 0, sizeof state);
1715
1716   args.src = (char *) src;
1717   args.dest = (char *) dest;
1718   serial = guestfs__send (g, GUESTFS_PROC_AUG_MV,
1719                      (xdrproc_t) xdr_guestfs_aug_mv_args, (char *) &args);
1720   if (serial == -1)
1721     return -1;
1722
1723   state.cb_state = 0;
1724   guestfs_set_reply_callback (g, aug_mv_cb, &state);
1725   (void) ml->main_loop_run (ml, g);
1726   guestfs_set_reply_callback (g, NULL, NULL);
1727   if (!state.cb_state) {
1728     error (g, "guestfs_aug_mv failed, see earlier error messages");
1729     return -1;
1730   }
1731
1732   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_MV, serial) == -1)
1733     return -1;
1734
1735   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
1736     error (g, "%s", state.err.error_message);
1737     return -1;
1738   }
1739
1740   return 0;
1741 }
1742
1743 struct aug_match_state {
1744   int cb_state;
1745   struct guestfs_message_header hdr;
1746   struct guestfs_message_error err;
1747   struct guestfs_aug_match_ret ret;
1748 };
1749
1750 static void aug_match_cb (guestfs_h *g, void *data, XDR *xdr)
1751 {
1752   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1753   struct aug_match_state *state = (struct aug_match_state *) data;
1754
1755   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
1756     error (g, "guestfs_aug_match: failed to parse reply header");
1757     return;
1758   }
1759   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
1760     if (!xdr_guestfs_message_error (xdr, &state->err)) {
1761       error (g, "guestfs_aug_match: failed to parse reply error");
1762       return;
1763     }
1764     goto done;
1765   }
1766   if (!xdr_guestfs_aug_match_ret (xdr, &state->ret)) {
1767     error (g, "guestfs_aug_match: failed to parse reply");
1768     return;
1769   }
1770  done:
1771   state->cb_state = 1;
1772   ml->main_loop_quit (ml, g);
1773 }
1774
1775 char **guestfs_aug_match (guestfs_h *g,
1776                 const char *path)
1777 {
1778   struct guestfs_aug_match_args args;
1779   struct aug_match_state state;
1780   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1781   int serial;
1782
1783   if (check_state (g, "guestfs_aug_match") == -1) return NULL;
1784
1785   memset (&state, 0, sizeof state);
1786
1787   args.path = (char *) path;
1788   serial = guestfs__send (g, GUESTFS_PROC_AUG_MATCH,
1789                      (xdrproc_t) xdr_guestfs_aug_match_args, (char *) &args);
1790   if (serial == -1)
1791     return NULL;
1792
1793   state.cb_state = 0;
1794   guestfs_set_reply_callback (g, aug_match_cb, &state);
1795   (void) ml->main_loop_run (ml, g);
1796   guestfs_set_reply_callback (g, NULL, NULL);
1797   if (!state.cb_state) {
1798     error (g, "guestfs_aug_match failed, see earlier error messages");
1799     return NULL;
1800   }
1801
1802   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_MATCH, serial) == -1)
1803     return NULL;
1804
1805   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
1806     error (g, "%s", state.err.error_message);
1807     return NULL;
1808   }
1809
1810   /* caller will free this, but we need to add a NULL entry */
1811   state.ret.matches.matches_val =
1812     safe_realloc (g, state.ret.matches.matches_val,
1813                   sizeof (char *) * (state.ret.matches.matches_len + 1));
1814   state.ret.matches.matches_val[state.ret.matches.matches_len] = NULL;
1815   return state.ret.matches.matches_val;
1816 }
1817
1818 struct aug_save_state {
1819   int cb_state;
1820   struct guestfs_message_header hdr;
1821   struct guestfs_message_error err;
1822 };
1823
1824 static void aug_save_cb (guestfs_h *g, void *data, XDR *xdr)
1825 {
1826   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1827   struct aug_save_state *state = (struct aug_save_state *) data;
1828
1829   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
1830     error (g, "guestfs_aug_save: failed to parse reply header");
1831     return;
1832   }
1833   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
1834     if (!xdr_guestfs_message_error (xdr, &state->err)) {
1835       error (g, "guestfs_aug_save: failed to parse reply error");
1836       return;
1837     }
1838     goto done;
1839   }
1840  done:
1841   state->cb_state = 1;
1842   ml->main_loop_quit (ml, g);
1843 }
1844
1845 int guestfs_aug_save (guestfs_h *g)
1846 {
1847   struct aug_save_state state;
1848   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1849   int serial;
1850
1851   if (check_state (g, "guestfs_aug_save") == -1) return -1;
1852
1853   memset (&state, 0, sizeof state);
1854
1855   serial = guestfs__send (g, GUESTFS_PROC_AUG_SAVE, NULL, NULL);
1856   if (serial == -1)
1857     return -1;
1858
1859   state.cb_state = 0;
1860   guestfs_set_reply_callback (g, aug_save_cb, &state);
1861   (void) ml->main_loop_run (ml, g);
1862   guestfs_set_reply_callback (g, NULL, NULL);
1863   if (!state.cb_state) {
1864     error (g, "guestfs_aug_save failed, see earlier error messages");
1865     return -1;
1866   }
1867
1868   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_SAVE, serial) == -1)
1869     return -1;
1870
1871   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
1872     error (g, "%s", state.err.error_message);
1873     return -1;
1874   }
1875
1876   return 0;
1877 }
1878
1879 struct aug_load_state {
1880   int cb_state;
1881   struct guestfs_message_header hdr;
1882   struct guestfs_message_error err;
1883 };
1884
1885 static void aug_load_cb (guestfs_h *g, void *data, XDR *xdr)
1886 {
1887   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1888   struct aug_load_state *state = (struct aug_load_state *) data;
1889
1890   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
1891     error (g, "guestfs_aug_load: failed to parse reply header");
1892     return;
1893   }
1894   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
1895     if (!xdr_guestfs_message_error (xdr, &state->err)) {
1896       error (g, "guestfs_aug_load: failed to parse reply error");
1897       return;
1898     }
1899     goto done;
1900   }
1901  done:
1902   state->cb_state = 1;
1903   ml->main_loop_quit (ml, g);
1904 }
1905
1906 int guestfs_aug_load (guestfs_h *g)
1907 {
1908   struct aug_load_state state;
1909   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1910   int serial;
1911
1912   if (check_state (g, "guestfs_aug_load") == -1) return -1;
1913
1914   memset (&state, 0, sizeof state);
1915
1916   serial = guestfs__send (g, GUESTFS_PROC_AUG_LOAD, NULL, NULL);
1917   if (serial == -1)
1918     return -1;
1919
1920   state.cb_state = 0;
1921   guestfs_set_reply_callback (g, aug_load_cb, &state);
1922   (void) ml->main_loop_run (ml, g);
1923   guestfs_set_reply_callback (g, NULL, NULL);
1924   if (!state.cb_state) {
1925     error (g, "guestfs_aug_load failed, see earlier error messages");
1926     return -1;
1927   }
1928
1929   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_LOAD, serial) == -1)
1930     return -1;
1931
1932   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
1933     error (g, "%s", state.err.error_message);
1934     return -1;
1935   }
1936
1937   return 0;
1938 }
1939
1940 struct aug_ls_state {
1941   int cb_state;
1942   struct guestfs_message_header hdr;
1943   struct guestfs_message_error err;
1944   struct guestfs_aug_ls_ret ret;
1945 };
1946
1947 static void aug_ls_cb (guestfs_h *g, void *data, XDR *xdr)
1948 {
1949   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1950   struct aug_ls_state *state = (struct aug_ls_state *) data;
1951
1952   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
1953     error (g, "guestfs_aug_ls: failed to parse reply header");
1954     return;
1955   }
1956   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
1957     if (!xdr_guestfs_message_error (xdr, &state->err)) {
1958       error (g, "guestfs_aug_ls: failed to parse reply error");
1959       return;
1960     }
1961     goto done;
1962   }
1963   if (!xdr_guestfs_aug_ls_ret (xdr, &state->ret)) {
1964     error (g, "guestfs_aug_ls: failed to parse reply");
1965     return;
1966   }
1967  done:
1968   state->cb_state = 1;
1969   ml->main_loop_quit (ml, g);
1970 }
1971
1972 char **guestfs_aug_ls (guestfs_h *g,
1973                 const char *path)
1974 {
1975   struct guestfs_aug_ls_args args;
1976   struct aug_ls_state state;
1977   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1978   int serial;
1979
1980   if (check_state (g, "guestfs_aug_ls") == -1) return NULL;
1981
1982   memset (&state, 0, sizeof state);
1983
1984   args.path = (char *) path;
1985   serial = guestfs__send (g, GUESTFS_PROC_AUG_LS,
1986                      (xdrproc_t) xdr_guestfs_aug_ls_args, (char *) &args);
1987   if (serial == -1)
1988     return NULL;
1989
1990   state.cb_state = 0;
1991   guestfs_set_reply_callback (g, aug_ls_cb, &state);
1992   (void) ml->main_loop_run (ml, g);
1993   guestfs_set_reply_callback (g, NULL, NULL);
1994   if (!state.cb_state) {
1995     error (g, "guestfs_aug_ls failed, see earlier error messages");
1996     return NULL;
1997   }
1998
1999   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_LS, serial) == -1)
2000     return NULL;
2001
2002   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
2003     error (g, "%s", state.err.error_message);
2004     return NULL;
2005   }
2006
2007   /* caller will free this, but we need to add a NULL entry */
2008   state.ret.matches.matches_val =
2009     safe_realloc (g, state.ret.matches.matches_val,
2010                   sizeof (char *) * (state.ret.matches.matches_len + 1));
2011   state.ret.matches.matches_val[state.ret.matches.matches_len] = NULL;
2012   return state.ret.matches.matches_val;
2013 }
2014
2015 struct rm_state {
2016   int cb_state;
2017   struct guestfs_message_header hdr;
2018   struct guestfs_message_error err;
2019 };
2020
2021 static void rm_cb (guestfs_h *g, void *data, XDR *xdr)
2022 {
2023   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2024   struct rm_state *state = (struct rm_state *) data;
2025
2026   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
2027     error (g, "guestfs_rm: failed to parse reply header");
2028     return;
2029   }
2030   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
2031     if (!xdr_guestfs_message_error (xdr, &state->err)) {
2032       error (g, "guestfs_rm: failed to parse reply error");
2033       return;
2034     }
2035     goto done;
2036   }
2037  done:
2038   state->cb_state = 1;
2039   ml->main_loop_quit (ml, g);
2040 }
2041
2042 int guestfs_rm (guestfs_h *g,
2043                 const char *path)
2044 {
2045   struct guestfs_rm_args args;
2046   struct rm_state state;
2047   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2048   int serial;
2049
2050   if (check_state (g, "guestfs_rm") == -1) return -1;
2051
2052   memset (&state, 0, sizeof state);
2053
2054   args.path = (char *) path;
2055   serial = guestfs__send (g, GUESTFS_PROC_RM,
2056                      (xdrproc_t) xdr_guestfs_rm_args, (char *) &args);
2057   if (serial == -1)
2058     return -1;
2059
2060   state.cb_state = 0;
2061   guestfs_set_reply_callback (g, rm_cb, &state);
2062   (void) ml->main_loop_run (ml, g);
2063   guestfs_set_reply_callback (g, NULL, NULL);
2064   if (!state.cb_state) {
2065     error (g, "guestfs_rm failed, see earlier error messages");
2066     return -1;
2067   }
2068
2069   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_RM, serial) == -1)
2070     return -1;
2071
2072   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
2073     error (g, "%s", state.err.error_message);
2074     return -1;
2075   }
2076
2077   return 0;
2078 }
2079
2080 struct rmdir_state {
2081   int cb_state;
2082   struct guestfs_message_header hdr;
2083   struct guestfs_message_error err;
2084 };
2085
2086 static void rmdir_cb (guestfs_h *g, void *data, XDR *xdr)
2087 {
2088   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2089   struct rmdir_state *state = (struct rmdir_state *) data;
2090
2091   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
2092     error (g, "guestfs_rmdir: failed to parse reply header");
2093     return;
2094   }
2095   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
2096     if (!xdr_guestfs_message_error (xdr, &state->err)) {
2097       error (g, "guestfs_rmdir: failed to parse reply error");
2098       return;
2099     }
2100     goto done;
2101   }
2102  done:
2103   state->cb_state = 1;
2104   ml->main_loop_quit (ml, g);
2105 }
2106
2107 int guestfs_rmdir (guestfs_h *g,
2108                 const char *path)
2109 {
2110   struct guestfs_rmdir_args args;
2111   struct rmdir_state state;
2112   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2113   int serial;
2114
2115   if (check_state (g, "guestfs_rmdir") == -1) return -1;
2116
2117   memset (&state, 0, sizeof state);
2118
2119   args.path = (char *) path;
2120   serial = guestfs__send (g, GUESTFS_PROC_RMDIR,
2121                      (xdrproc_t) xdr_guestfs_rmdir_args, (char *) &args);
2122   if (serial == -1)
2123     return -1;
2124
2125   state.cb_state = 0;
2126   guestfs_set_reply_callback (g, rmdir_cb, &state);
2127   (void) ml->main_loop_run (ml, g);
2128   guestfs_set_reply_callback (g, NULL, NULL);
2129   if (!state.cb_state) {
2130     error (g, "guestfs_rmdir failed, see earlier error messages");
2131     return -1;
2132   }
2133
2134   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_RMDIR, serial) == -1)
2135     return -1;
2136
2137   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
2138     error (g, "%s", state.err.error_message);
2139     return -1;
2140   }
2141
2142   return 0;
2143 }
2144
2145 struct rm_rf_state {
2146   int cb_state;
2147   struct guestfs_message_header hdr;
2148   struct guestfs_message_error err;
2149 };
2150
2151 static void rm_rf_cb (guestfs_h *g, void *data, XDR *xdr)
2152 {
2153   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2154   struct rm_rf_state *state = (struct rm_rf_state *) data;
2155
2156   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
2157     error (g, "guestfs_rm_rf: failed to parse reply header");
2158     return;
2159   }
2160   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
2161     if (!xdr_guestfs_message_error (xdr, &state->err)) {
2162       error (g, "guestfs_rm_rf: failed to parse reply error");
2163       return;
2164     }
2165     goto done;
2166   }
2167  done:
2168   state->cb_state = 1;
2169   ml->main_loop_quit (ml, g);
2170 }
2171
2172 int guestfs_rm_rf (guestfs_h *g,
2173                 const char *path)
2174 {
2175   struct guestfs_rm_rf_args args;
2176   struct rm_rf_state state;
2177   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2178   int serial;
2179
2180   if (check_state (g, "guestfs_rm_rf") == -1) return -1;
2181
2182   memset (&state, 0, sizeof state);
2183
2184   args.path = (char *) path;
2185   serial = guestfs__send (g, GUESTFS_PROC_RM_RF,
2186                      (xdrproc_t) xdr_guestfs_rm_rf_args, (char *) &args);
2187   if (serial == -1)
2188     return -1;
2189
2190   state.cb_state = 0;
2191   guestfs_set_reply_callback (g, rm_rf_cb, &state);
2192   (void) ml->main_loop_run (ml, g);
2193   guestfs_set_reply_callback (g, NULL, NULL);
2194   if (!state.cb_state) {
2195     error (g, "guestfs_rm_rf failed, see earlier error messages");
2196     return -1;
2197   }
2198
2199   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_RM_RF, serial) == -1)
2200     return -1;
2201
2202   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
2203     error (g, "%s", state.err.error_message);
2204     return -1;
2205   }
2206
2207   return 0;
2208 }
2209
2210 struct mkdir_state {
2211   int cb_state;
2212   struct guestfs_message_header hdr;
2213   struct guestfs_message_error err;
2214 };
2215
2216 static void mkdir_cb (guestfs_h *g, void *data, XDR *xdr)
2217 {
2218   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2219   struct mkdir_state *state = (struct mkdir_state *) data;
2220
2221   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
2222     error (g, "guestfs_mkdir: failed to parse reply header");
2223     return;
2224   }
2225   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
2226     if (!xdr_guestfs_message_error (xdr, &state->err)) {
2227       error (g, "guestfs_mkdir: failed to parse reply error");
2228       return;
2229     }
2230     goto done;
2231   }
2232  done:
2233   state->cb_state = 1;
2234   ml->main_loop_quit (ml, g);
2235 }
2236
2237 int guestfs_mkdir (guestfs_h *g,
2238                 const char *path)
2239 {
2240   struct guestfs_mkdir_args args;
2241   struct mkdir_state state;
2242   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2243   int serial;
2244
2245   if (check_state (g, "guestfs_mkdir") == -1) return -1;
2246
2247   memset (&state, 0, sizeof state);
2248
2249   args.path = (char *) path;
2250   serial = guestfs__send (g, GUESTFS_PROC_MKDIR,
2251                      (xdrproc_t) xdr_guestfs_mkdir_args, (char *) &args);
2252   if (serial == -1)
2253     return -1;
2254
2255   state.cb_state = 0;
2256   guestfs_set_reply_callback (g, mkdir_cb, &state);
2257   (void) ml->main_loop_run (ml, g);
2258   guestfs_set_reply_callback (g, NULL, NULL);
2259   if (!state.cb_state) {
2260     error (g, "guestfs_mkdir failed, see earlier error messages");
2261     return -1;
2262   }
2263
2264   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_MKDIR, serial) == -1)
2265     return -1;
2266
2267   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
2268     error (g, "%s", state.err.error_message);
2269     return -1;
2270   }
2271
2272   return 0;
2273 }
2274
2275 struct mkdir_p_state {
2276   int cb_state;
2277   struct guestfs_message_header hdr;
2278   struct guestfs_message_error err;
2279 };
2280
2281 static void mkdir_p_cb (guestfs_h *g, void *data, XDR *xdr)
2282 {
2283   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2284   struct mkdir_p_state *state = (struct mkdir_p_state *) data;
2285
2286   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
2287     error (g, "guestfs_mkdir_p: failed to parse reply header");
2288     return;
2289   }
2290   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
2291     if (!xdr_guestfs_message_error (xdr, &state->err)) {
2292       error (g, "guestfs_mkdir_p: failed to parse reply error");
2293       return;
2294     }
2295     goto done;
2296   }
2297  done:
2298   state->cb_state = 1;
2299   ml->main_loop_quit (ml, g);
2300 }
2301
2302 int guestfs_mkdir_p (guestfs_h *g,
2303                 const char *path)
2304 {
2305   struct guestfs_mkdir_p_args args;
2306   struct mkdir_p_state state;
2307   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2308   int serial;
2309
2310   if (check_state (g, "guestfs_mkdir_p") == -1) return -1;
2311
2312   memset (&state, 0, sizeof state);
2313
2314   args.path = (char *) path;
2315   serial = guestfs__send (g, GUESTFS_PROC_MKDIR_P,
2316                      (xdrproc_t) xdr_guestfs_mkdir_p_args, (char *) &args);
2317   if (serial == -1)
2318     return -1;
2319
2320   state.cb_state = 0;
2321   guestfs_set_reply_callback (g, mkdir_p_cb, &state);
2322   (void) ml->main_loop_run (ml, g);
2323   guestfs_set_reply_callback (g, NULL, NULL);
2324   if (!state.cb_state) {
2325     error (g, "guestfs_mkdir_p failed, see earlier error messages");
2326     return -1;
2327   }
2328
2329   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_MKDIR_P, serial) == -1)
2330     return -1;
2331
2332   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
2333     error (g, "%s", state.err.error_message);
2334     return -1;
2335   }
2336
2337   return 0;
2338 }
2339
2340 struct chmod_state {
2341   int cb_state;
2342   struct guestfs_message_header hdr;
2343   struct guestfs_message_error err;
2344 };
2345
2346 static void chmod_cb (guestfs_h *g, void *data, XDR *xdr)
2347 {
2348   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2349   struct chmod_state *state = (struct chmod_state *) data;
2350
2351   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
2352     error (g, "guestfs_chmod: failed to parse reply header");
2353     return;
2354   }
2355   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
2356     if (!xdr_guestfs_message_error (xdr, &state->err)) {
2357       error (g, "guestfs_chmod: failed to parse reply error");
2358       return;
2359     }
2360     goto done;
2361   }
2362  done:
2363   state->cb_state = 1;
2364   ml->main_loop_quit (ml, g);
2365 }
2366
2367 int guestfs_chmod (guestfs_h *g,
2368                 int mode,
2369                 const char *path)
2370 {
2371   struct guestfs_chmod_args args;
2372   struct chmod_state state;
2373   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2374   int serial;
2375
2376   if (check_state (g, "guestfs_chmod") == -1) return -1;
2377
2378   memset (&state, 0, sizeof state);
2379
2380   args.mode = mode;
2381   args.path = (char *) path;
2382   serial = guestfs__send (g, GUESTFS_PROC_CHMOD,
2383                      (xdrproc_t) xdr_guestfs_chmod_args, (char *) &args);
2384   if (serial == -1)
2385     return -1;
2386
2387   state.cb_state = 0;
2388   guestfs_set_reply_callback (g, chmod_cb, &state);
2389   (void) ml->main_loop_run (ml, g);
2390   guestfs_set_reply_callback (g, NULL, NULL);
2391   if (!state.cb_state) {
2392     error (g, "guestfs_chmod failed, see earlier error messages");
2393     return -1;
2394   }
2395
2396   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_CHMOD, serial) == -1)
2397     return -1;
2398
2399   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
2400     error (g, "%s", state.err.error_message);
2401     return -1;
2402   }
2403
2404   return 0;
2405 }
2406
2407 struct chown_state {
2408   int cb_state;
2409   struct guestfs_message_header hdr;
2410   struct guestfs_message_error err;
2411 };
2412
2413 static void chown_cb (guestfs_h *g, void *data, XDR *xdr)
2414 {
2415   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2416   struct chown_state *state = (struct chown_state *) data;
2417
2418   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
2419     error (g, "guestfs_chown: failed to parse reply header");
2420     return;
2421   }
2422   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
2423     if (!xdr_guestfs_message_error (xdr, &state->err)) {
2424       error (g, "guestfs_chown: failed to parse reply error");
2425       return;
2426     }
2427     goto done;
2428   }
2429  done:
2430   state->cb_state = 1;
2431   ml->main_loop_quit (ml, g);
2432 }
2433
2434 int guestfs_chown (guestfs_h *g,
2435                 int owner,
2436                 int group,
2437                 const char *path)
2438 {
2439   struct guestfs_chown_args args;
2440   struct chown_state state;
2441   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2442   int serial;
2443
2444   if (check_state (g, "guestfs_chown") == -1) return -1;
2445
2446   memset (&state, 0, sizeof state);
2447
2448   args.owner = owner;
2449   args.group = group;
2450   args.path = (char *) path;
2451   serial = guestfs__send (g, GUESTFS_PROC_CHOWN,
2452                      (xdrproc_t) xdr_guestfs_chown_args, (char *) &args);
2453   if (serial == -1)
2454     return -1;
2455
2456   state.cb_state = 0;
2457   guestfs_set_reply_callback (g, chown_cb, &state);
2458   (void) ml->main_loop_run (ml, g);
2459   guestfs_set_reply_callback (g, NULL, NULL);
2460   if (!state.cb_state) {
2461     error (g, "guestfs_chown failed, see earlier error messages");
2462     return -1;
2463   }
2464
2465   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_CHOWN, serial) == -1)
2466     return -1;
2467
2468   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
2469     error (g, "%s", state.err.error_message);
2470     return -1;
2471   }
2472
2473   return 0;
2474 }
2475
2476 struct exists_state {
2477   int cb_state;
2478   struct guestfs_message_header hdr;
2479   struct guestfs_message_error err;
2480   struct guestfs_exists_ret ret;
2481 };
2482
2483 static void exists_cb (guestfs_h *g, void *data, XDR *xdr)
2484 {
2485   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2486   struct exists_state *state = (struct exists_state *) data;
2487
2488   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
2489     error (g, "guestfs_exists: failed to parse reply header");
2490     return;
2491   }
2492   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
2493     if (!xdr_guestfs_message_error (xdr, &state->err)) {
2494       error (g, "guestfs_exists: failed to parse reply error");
2495       return;
2496     }
2497     goto done;
2498   }
2499   if (!xdr_guestfs_exists_ret (xdr, &state->ret)) {
2500     error (g, "guestfs_exists: failed to parse reply");
2501     return;
2502   }
2503  done:
2504   state->cb_state = 1;
2505   ml->main_loop_quit (ml, g);
2506 }
2507
2508 int guestfs_exists (guestfs_h *g,
2509                 const char *path)
2510 {
2511   struct guestfs_exists_args args;
2512   struct exists_state state;
2513   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2514   int serial;
2515
2516   if (check_state (g, "guestfs_exists") == -1) return -1;
2517
2518   memset (&state, 0, sizeof state);
2519
2520   args.path = (char *) path;
2521   serial = guestfs__send (g, GUESTFS_PROC_EXISTS,
2522                      (xdrproc_t) xdr_guestfs_exists_args, (char *) &args);
2523   if (serial == -1)
2524     return -1;
2525
2526   state.cb_state = 0;
2527   guestfs_set_reply_callback (g, exists_cb, &state);
2528   (void) ml->main_loop_run (ml, g);
2529   guestfs_set_reply_callback (g, NULL, NULL);
2530   if (!state.cb_state) {
2531     error (g, "guestfs_exists failed, see earlier error messages");
2532     return -1;
2533   }
2534
2535   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_EXISTS, serial) == -1)
2536     return -1;
2537
2538   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
2539     error (g, "%s", state.err.error_message);
2540     return -1;
2541   }
2542
2543   return state.ret.existsflag;
2544 }
2545
2546 struct is_file_state {
2547   int cb_state;
2548   struct guestfs_message_header hdr;
2549   struct guestfs_message_error err;
2550   struct guestfs_is_file_ret ret;
2551 };
2552
2553 static void is_file_cb (guestfs_h *g, void *data, XDR *xdr)
2554 {
2555   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2556   struct is_file_state *state = (struct is_file_state *) data;
2557
2558   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
2559     error (g, "guestfs_is_file: failed to parse reply header");
2560     return;
2561   }
2562   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
2563     if (!xdr_guestfs_message_error (xdr, &state->err)) {
2564       error (g, "guestfs_is_file: failed to parse reply error");
2565       return;
2566     }
2567     goto done;
2568   }
2569   if (!xdr_guestfs_is_file_ret (xdr, &state->ret)) {
2570     error (g, "guestfs_is_file: failed to parse reply");
2571     return;
2572   }
2573  done:
2574   state->cb_state = 1;
2575   ml->main_loop_quit (ml, g);
2576 }
2577
2578 int guestfs_is_file (guestfs_h *g,
2579                 const char *path)
2580 {
2581   struct guestfs_is_file_args args;
2582   struct is_file_state state;
2583   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2584   int serial;
2585
2586   if (check_state (g, "guestfs_is_file") == -1) return -1;
2587
2588   memset (&state, 0, sizeof state);
2589
2590   args.path = (char *) path;
2591   serial = guestfs__send (g, GUESTFS_PROC_IS_FILE,
2592                      (xdrproc_t) xdr_guestfs_is_file_args, (char *) &args);
2593   if (serial == -1)
2594     return -1;
2595
2596   state.cb_state = 0;
2597   guestfs_set_reply_callback (g, is_file_cb, &state);
2598   (void) ml->main_loop_run (ml, g);
2599   guestfs_set_reply_callback (g, NULL, NULL);
2600   if (!state.cb_state) {
2601     error (g, "guestfs_is_file failed, see earlier error messages");
2602     return -1;
2603   }
2604
2605   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_IS_FILE, serial) == -1)
2606     return -1;
2607
2608   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
2609     error (g, "%s", state.err.error_message);
2610     return -1;
2611   }
2612
2613   return state.ret.fileflag;
2614 }
2615
2616 struct is_dir_state {
2617   int cb_state;
2618   struct guestfs_message_header hdr;
2619   struct guestfs_message_error err;
2620   struct guestfs_is_dir_ret ret;
2621 };
2622
2623 static void is_dir_cb (guestfs_h *g, void *data, XDR *xdr)
2624 {
2625   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2626   struct is_dir_state *state = (struct is_dir_state *) data;
2627
2628   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
2629     error (g, "guestfs_is_dir: failed to parse reply header");
2630     return;
2631   }
2632   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
2633     if (!xdr_guestfs_message_error (xdr, &state->err)) {
2634       error (g, "guestfs_is_dir: failed to parse reply error");
2635       return;
2636     }
2637     goto done;
2638   }
2639   if (!xdr_guestfs_is_dir_ret (xdr, &state->ret)) {
2640     error (g, "guestfs_is_dir: failed to parse reply");
2641     return;
2642   }
2643  done:
2644   state->cb_state = 1;
2645   ml->main_loop_quit (ml, g);
2646 }
2647
2648 int guestfs_is_dir (guestfs_h *g,
2649                 const char *path)
2650 {
2651   struct guestfs_is_dir_args args;
2652   struct is_dir_state state;
2653   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2654   int serial;
2655
2656   if (check_state (g, "guestfs_is_dir") == -1) return -1;
2657
2658   memset (&state, 0, sizeof state);
2659
2660   args.path = (char *) path;
2661   serial = guestfs__send (g, GUESTFS_PROC_IS_DIR,
2662                      (xdrproc_t) xdr_guestfs_is_dir_args, (char *) &args);
2663   if (serial == -1)
2664     return -1;
2665
2666   state.cb_state = 0;
2667   guestfs_set_reply_callback (g, is_dir_cb, &state);
2668   (void) ml->main_loop_run (ml, g);
2669   guestfs_set_reply_callback (g, NULL, NULL);
2670   if (!state.cb_state) {
2671     error (g, "guestfs_is_dir failed, see earlier error messages");
2672     return -1;
2673   }
2674
2675   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_IS_DIR, serial) == -1)
2676     return -1;
2677
2678   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
2679     error (g, "%s", state.err.error_message);
2680     return -1;
2681   }
2682
2683   return state.ret.dirflag;
2684 }
2685
2686 struct pvcreate_state {
2687   int cb_state;
2688   struct guestfs_message_header hdr;
2689   struct guestfs_message_error err;
2690 };
2691
2692 static void pvcreate_cb (guestfs_h *g, void *data, XDR *xdr)
2693 {
2694   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2695   struct pvcreate_state *state = (struct pvcreate_state *) data;
2696
2697   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
2698     error (g, "guestfs_pvcreate: failed to parse reply header");
2699     return;
2700   }
2701   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
2702     if (!xdr_guestfs_message_error (xdr, &state->err)) {
2703       error (g, "guestfs_pvcreate: failed to parse reply error");
2704       return;
2705     }
2706     goto done;
2707   }
2708  done:
2709   state->cb_state = 1;
2710   ml->main_loop_quit (ml, g);
2711 }
2712
2713 int guestfs_pvcreate (guestfs_h *g,
2714                 const char *device)
2715 {
2716   struct guestfs_pvcreate_args args;
2717   struct pvcreate_state state;
2718   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2719   int serial;
2720
2721   if (check_state (g, "guestfs_pvcreate") == -1) return -1;
2722
2723   memset (&state, 0, sizeof state);
2724
2725   args.device = (char *) device;
2726   serial = guestfs__send (g, GUESTFS_PROC_PVCREATE,
2727                      (xdrproc_t) xdr_guestfs_pvcreate_args, (char *) &args);
2728   if (serial == -1)
2729     return -1;
2730
2731   state.cb_state = 0;
2732   guestfs_set_reply_callback (g, pvcreate_cb, &state);
2733   (void) ml->main_loop_run (ml, g);
2734   guestfs_set_reply_callback (g, NULL, NULL);
2735   if (!state.cb_state) {
2736     error (g, "guestfs_pvcreate failed, see earlier error messages");
2737     return -1;
2738   }
2739
2740   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_PVCREATE, serial) == -1)
2741     return -1;
2742
2743   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
2744     error (g, "%s", state.err.error_message);
2745     return -1;
2746   }
2747
2748   return 0;
2749 }
2750
2751 struct vgcreate_state {
2752   int cb_state;
2753   struct guestfs_message_header hdr;
2754   struct guestfs_message_error err;
2755 };
2756
2757 static void vgcreate_cb (guestfs_h *g, void *data, XDR *xdr)
2758 {
2759   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2760   struct vgcreate_state *state = (struct vgcreate_state *) data;
2761
2762   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
2763     error (g, "guestfs_vgcreate: failed to parse reply header");
2764     return;
2765   }
2766   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
2767     if (!xdr_guestfs_message_error (xdr, &state->err)) {
2768       error (g, "guestfs_vgcreate: failed to parse reply error");
2769       return;
2770     }
2771     goto done;
2772   }
2773  done:
2774   state->cb_state = 1;
2775   ml->main_loop_quit (ml, g);
2776 }
2777
2778 int guestfs_vgcreate (guestfs_h *g,
2779                 const char *volgroup,
2780                 char * const* const physvols)
2781 {
2782   struct guestfs_vgcreate_args args;
2783   struct vgcreate_state state;
2784   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2785   int serial;
2786
2787   if (check_state (g, "guestfs_vgcreate") == -1) return -1;
2788
2789   memset (&state, 0, sizeof state);
2790
2791   args.volgroup = (char *) volgroup;
2792   args.physvols.physvols_val = (char **) physvols;
2793   for (args.physvols.physvols_len = 0; physvols[args.physvols.physvols_len]; args.physvols.physvols_len++) ;
2794   serial = guestfs__send (g, GUESTFS_PROC_VGCREATE,
2795                      (xdrproc_t) xdr_guestfs_vgcreate_args, (char *) &args);
2796   if (serial == -1)
2797     return -1;
2798
2799   state.cb_state = 0;
2800   guestfs_set_reply_callback (g, vgcreate_cb, &state);
2801   (void) ml->main_loop_run (ml, g);
2802   guestfs_set_reply_callback (g, NULL, NULL);
2803   if (!state.cb_state) {
2804     error (g, "guestfs_vgcreate failed, see earlier error messages");
2805     return -1;
2806   }
2807
2808   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_VGCREATE, serial) == -1)
2809     return -1;
2810
2811   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
2812     error (g, "%s", state.err.error_message);
2813     return -1;
2814   }
2815
2816   return 0;
2817 }
2818
2819 struct lvcreate_state {
2820   int cb_state;
2821   struct guestfs_message_header hdr;
2822   struct guestfs_message_error err;
2823 };
2824
2825 static void lvcreate_cb (guestfs_h *g, void *data, XDR *xdr)
2826 {
2827   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2828   struct lvcreate_state *state = (struct lvcreate_state *) data;
2829
2830   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
2831     error (g, "guestfs_lvcreate: failed to parse reply header");
2832     return;
2833   }
2834   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
2835     if (!xdr_guestfs_message_error (xdr, &state->err)) {
2836       error (g, "guestfs_lvcreate: failed to parse reply error");
2837       return;
2838     }
2839     goto done;
2840   }
2841  done:
2842   state->cb_state = 1;
2843   ml->main_loop_quit (ml, g);
2844 }
2845
2846 int guestfs_lvcreate (guestfs_h *g,
2847                 const char *logvol,
2848                 const char *volgroup,
2849                 int mbytes)
2850 {
2851   struct guestfs_lvcreate_args args;
2852   struct lvcreate_state state;
2853   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2854   int serial;
2855
2856   if (check_state (g, "guestfs_lvcreate") == -1) return -1;
2857
2858   memset (&state, 0, sizeof state);
2859
2860   args.logvol = (char *) logvol;
2861   args.volgroup = (char *) volgroup;
2862   args.mbytes = mbytes;
2863   serial = guestfs__send (g, GUESTFS_PROC_LVCREATE,
2864                      (xdrproc_t) xdr_guestfs_lvcreate_args, (char *) &args);
2865   if (serial == -1)
2866     return -1;
2867
2868   state.cb_state = 0;
2869   guestfs_set_reply_callback (g, lvcreate_cb, &state);
2870   (void) ml->main_loop_run (ml, g);
2871   guestfs_set_reply_callback (g, NULL, NULL);
2872   if (!state.cb_state) {
2873     error (g, "guestfs_lvcreate failed, see earlier error messages");
2874     return -1;
2875   }
2876
2877   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_LVCREATE, serial) == -1)
2878     return -1;
2879
2880   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
2881     error (g, "%s", state.err.error_message);
2882     return -1;
2883   }
2884
2885   return 0;
2886 }
2887
2888 struct mkfs_state {
2889   int cb_state;
2890   struct guestfs_message_header hdr;
2891   struct guestfs_message_error err;
2892 };
2893
2894 static void mkfs_cb (guestfs_h *g, void *data, XDR *xdr)
2895 {
2896   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2897   struct mkfs_state *state = (struct mkfs_state *) data;
2898
2899   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
2900     error (g, "guestfs_mkfs: failed to parse reply header");
2901     return;
2902   }
2903   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
2904     if (!xdr_guestfs_message_error (xdr, &state->err)) {
2905       error (g, "guestfs_mkfs: failed to parse reply error");
2906       return;
2907     }
2908     goto done;
2909   }
2910  done:
2911   state->cb_state = 1;
2912   ml->main_loop_quit (ml, g);
2913 }
2914
2915 int guestfs_mkfs (guestfs_h *g,
2916                 const char *fstype,
2917                 const char *device)
2918 {
2919   struct guestfs_mkfs_args args;
2920   struct mkfs_state state;
2921   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2922   int serial;
2923
2924   if (check_state (g, "guestfs_mkfs") == -1) return -1;
2925
2926   memset (&state, 0, sizeof state);
2927
2928   args.fstype = (char *) fstype;
2929   args.device = (char *) device;
2930   serial = guestfs__send (g, GUESTFS_PROC_MKFS,
2931                      (xdrproc_t) xdr_guestfs_mkfs_args, (char *) &args);
2932   if (serial == -1)
2933     return -1;
2934
2935   state.cb_state = 0;
2936   guestfs_set_reply_callback (g, mkfs_cb, &state);
2937   (void) ml->main_loop_run (ml, g);
2938   guestfs_set_reply_callback (g, NULL, NULL);
2939   if (!state.cb_state) {
2940     error (g, "guestfs_mkfs failed, see earlier error messages");
2941     return -1;
2942   }
2943
2944   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_MKFS, serial) == -1)
2945     return -1;
2946
2947   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
2948     error (g, "%s", state.err.error_message);
2949     return -1;
2950   }
2951
2952   return 0;
2953 }
2954
2955 struct sfdisk_state {
2956   int cb_state;
2957   struct guestfs_message_header hdr;
2958   struct guestfs_message_error err;
2959 };
2960
2961 static void sfdisk_cb (guestfs_h *g, void *data, XDR *xdr)
2962 {
2963   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2964   struct sfdisk_state *state = (struct sfdisk_state *) data;
2965
2966   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
2967     error (g, "guestfs_sfdisk: failed to parse reply header");
2968     return;
2969   }
2970   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
2971     if (!xdr_guestfs_message_error (xdr, &state->err)) {
2972       error (g, "guestfs_sfdisk: failed to parse reply error");
2973       return;
2974     }
2975     goto done;
2976   }
2977  done:
2978   state->cb_state = 1;
2979   ml->main_loop_quit (ml, g);
2980 }
2981
2982 int guestfs_sfdisk (guestfs_h *g,
2983                 const char *device,
2984                 int cyls,
2985                 int heads,
2986                 int sectors,
2987                 char * const* const lines)
2988 {
2989   struct guestfs_sfdisk_args args;
2990   struct sfdisk_state state;
2991   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2992   int serial;
2993
2994   if (check_state (g, "guestfs_sfdisk") == -1) return -1;
2995
2996   memset (&state, 0, sizeof state);
2997
2998   args.device = (char *) device;
2999   args.cyls = cyls;
3000   args.heads = heads;
3001   args.sectors = sectors;
3002   args.lines.lines_val = (char **) lines;
3003   for (args.lines.lines_len = 0; lines[args.lines.lines_len]; args.lines.lines_len++) ;
3004   serial = guestfs__send (g, GUESTFS_PROC_SFDISK,
3005                      (xdrproc_t) xdr_guestfs_sfdisk_args, (char *) &args);
3006   if (serial == -1)
3007     return -1;
3008
3009   state.cb_state = 0;
3010   guestfs_set_reply_callback (g, sfdisk_cb, &state);
3011   (void) ml->main_loop_run (ml, g);
3012   guestfs_set_reply_callback (g, NULL, NULL);
3013   if (!state.cb_state) {
3014     error (g, "guestfs_sfdisk failed, see earlier error messages");
3015     return -1;
3016   }
3017
3018   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_SFDISK, serial) == -1)
3019     return -1;
3020
3021   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
3022     error (g, "%s", state.err.error_message);
3023     return -1;
3024   }
3025
3026   return 0;
3027 }
3028
3029 struct write_file_state {
3030   int cb_state;
3031   struct guestfs_message_header hdr;
3032   struct guestfs_message_error err;
3033 };
3034
3035 static void write_file_cb (guestfs_h *g, void *data, XDR *xdr)
3036 {
3037   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3038   struct write_file_state *state = (struct write_file_state *) data;
3039
3040   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
3041     error (g, "guestfs_write_file: failed to parse reply header");
3042     return;
3043   }
3044   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
3045     if (!xdr_guestfs_message_error (xdr, &state->err)) {
3046       error (g, "guestfs_write_file: failed to parse reply error");
3047       return;
3048     }
3049     goto done;
3050   }
3051  done:
3052   state->cb_state = 1;
3053   ml->main_loop_quit (ml, g);
3054 }
3055
3056 int guestfs_write_file (guestfs_h *g,
3057                 const char *path,
3058                 const char *content,
3059                 int size)
3060 {
3061   struct guestfs_write_file_args args;
3062   struct write_file_state state;
3063   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3064   int serial;
3065
3066   if (check_state (g, "guestfs_write_file") == -1) return -1;
3067
3068   memset (&state, 0, sizeof state);
3069
3070   args.path = (char *) path;
3071   args.content = (char *) content;
3072   args.size = size;
3073   serial = guestfs__send (g, GUESTFS_PROC_WRITE_FILE,
3074                      (xdrproc_t) xdr_guestfs_write_file_args, (char *) &args);
3075   if (serial == -1)
3076     return -1;
3077
3078   state.cb_state = 0;
3079   guestfs_set_reply_callback (g, write_file_cb, &state);
3080   (void) ml->main_loop_run (ml, g);
3081   guestfs_set_reply_callback (g, NULL, NULL);
3082   if (!state.cb_state) {
3083     error (g, "guestfs_write_file failed, see earlier error messages");
3084     return -1;
3085   }
3086
3087   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_WRITE_FILE, serial) == -1)
3088     return -1;
3089
3090   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
3091     error (g, "%s", state.err.error_message);
3092     return -1;
3093   }
3094
3095   return 0;
3096 }
3097
3098 struct umount_state {
3099   int cb_state;
3100   struct guestfs_message_header hdr;
3101   struct guestfs_message_error err;
3102 };
3103
3104 static void umount_cb (guestfs_h *g, void *data, XDR *xdr)
3105 {
3106   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3107   struct umount_state *state = (struct umount_state *) data;
3108
3109   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
3110     error (g, "guestfs_umount: failed to parse reply header");
3111     return;
3112   }
3113   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
3114     if (!xdr_guestfs_message_error (xdr, &state->err)) {
3115       error (g, "guestfs_umount: failed to parse reply error");
3116       return;
3117     }
3118     goto done;
3119   }
3120  done:
3121   state->cb_state = 1;
3122   ml->main_loop_quit (ml, g);
3123 }
3124
3125 int guestfs_umount (guestfs_h *g,
3126                 const char *pathordevice)
3127 {
3128   struct guestfs_umount_args args;
3129   struct umount_state state;
3130   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3131   int serial;
3132
3133   if (check_state (g, "guestfs_umount") == -1) return -1;
3134
3135   memset (&state, 0, sizeof state);
3136
3137   args.pathordevice = (char *) pathordevice;
3138   serial = guestfs__send (g, GUESTFS_PROC_UMOUNT,
3139                      (xdrproc_t) xdr_guestfs_umount_args, (char *) &args);
3140   if (serial == -1)
3141     return -1;
3142
3143   state.cb_state = 0;
3144   guestfs_set_reply_callback (g, umount_cb, &state);
3145   (void) ml->main_loop_run (ml, g);
3146   guestfs_set_reply_callback (g, NULL, NULL);
3147   if (!state.cb_state) {
3148     error (g, "guestfs_umount failed, see earlier error messages");
3149     return -1;
3150   }
3151
3152   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_UMOUNT, serial) == -1)
3153     return -1;
3154
3155   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
3156     error (g, "%s", state.err.error_message);
3157     return -1;
3158   }
3159
3160   return 0;
3161 }
3162
3163 struct mounts_state {
3164   int cb_state;
3165   struct guestfs_message_header hdr;
3166   struct guestfs_message_error err;
3167   struct guestfs_mounts_ret ret;
3168 };
3169
3170 static void mounts_cb (guestfs_h *g, void *data, XDR *xdr)
3171 {
3172   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3173   struct mounts_state *state = (struct mounts_state *) data;
3174
3175   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
3176     error (g, "guestfs_mounts: failed to parse reply header");
3177     return;
3178   }
3179   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
3180     if (!xdr_guestfs_message_error (xdr, &state->err)) {
3181       error (g, "guestfs_mounts: failed to parse reply error");
3182       return;
3183     }
3184     goto done;
3185   }
3186   if (!xdr_guestfs_mounts_ret (xdr, &state->ret)) {
3187     error (g, "guestfs_mounts: failed to parse reply");
3188     return;
3189   }
3190  done:
3191   state->cb_state = 1;
3192   ml->main_loop_quit (ml, g);
3193 }
3194
3195 char **guestfs_mounts (guestfs_h *g)
3196 {
3197   struct mounts_state state;
3198   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3199   int serial;
3200
3201   if (check_state (g, "guestfs_mounts") == -1) return NULL;
3202
3203   memset (&state, 0, sizeof state);
3204
3205   serial = guestfs__send (g, GUESTFS_PROC_MOUNTS, NULL, NULL);
3206   if (serial == -1)
3207     return NULL;
3208
3209   state.cb_state = 0;
3210   guestfs_set_reply_callback (g, mounts_cb, &state);
3211   (void) ml->main_loop_run (ml, g);
3212   guestfs_set_reply_callback (g, NULL, NULL);
3213   if (!state.cb_state) {
3214     error (g, "guestfs_mounts failed, see earlier error messages");
3215     return NULL;
3216   }
3217
3218   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_MOUNTS, serial) == -1)
3219     return NULL;
3220
3221   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
3222     error (g, "%s", state.err.error_message);
3223     return NULL;
3224   }
3225
3226   /* caller will free this, but we need to add a NULL entry */
3227   state.ret.devices.devices_val =
3228     safe_realloc (g, state.ret.devices.devices_val,
3229                   sizeof (char *) * (state.ret.devices.devices_len + 1));
3230   state.ret.devices.devices_val[state.ret.devices.devices_len] = NULL;
3231   return state.ret.devices.devices_val;
3232 }
3233
3234 struct umount_all_state {
3235   int cb_state;
3236   struct guestfs_message_header hdr;
3237   struct guestfs_message_error err;
3238 };
3239
3240 static void umount_all_cb (guestfs_h *g, void *data, XDR *xdr)
3241 {
3242   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3243   struct umount_all_state *state = (struct umount_all_state *) data;
3244
3245   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
3246     error (g, "guestfs_umount_all: failed to parse reply header");
3247     return;
3248   }
3249   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
3250     if (!xdr_guestfs_message_error (xdr, &state->err)) {
3251       error (g, "guestfs_umount_all: failed to parse reply error");
3252       return;
3253     }
3254     goto done;
3255   }
3256  done:
3257   state->cb_state = 1;
3258   ml->main_loop_quit (ml, g);
3259 }
3260
3261 int guestfs_umount_all (guestfs_h *g)
3262 {
3263   struct umount_all_state state;
3264   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3265   int serial;
3266
3267   if (check_state (g, "guestfs_umount_all") == -1) return -1;
3268
3269   memset (&state, 0, sizeof state);
3270
3271   serial = guestfs__send (g, GUESTFS_PROC_UMOUNT_ALL, NULL, NULL);
3272   if (serial == -1)
3273     return -1;
3274
3275   state.cb_state = 0;
3276   guestfs_set_reply_callback (g, umount_all_cb, &state);
3277   (void) ml->main_loop_run (ml, g);
3278   guestfs_set_reply_callback (g, NULL, NULL);
3279   if (!state.cb_state) {
3280     error (g, "guestfs_umount_all failed, see earlier error messages");
3281     return -1;
3282   }
3283
3284   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_UMOUNT_ALL, serial) == -1)
3285     return -1;
3286
3287   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
3288     error (g, "%s", state.err.error_message);
3289     return -1;
3290   }
3291
3292   return 0;
3293 }
3294
3295 struct lvm_remove_all_state {
3296   int cb_state;
3297   struct guestfs_message_header hdr;
3298   struct guestfs_message_error err;
3299 };
3300
3301 static void lvm_remove_all_cb (guestfs_h *g, void *data, XDR *xdr)
3302 {
3303   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3304   struct lvm_remove_all_state *state = (struct lvm_remove_all_state *) data;
3305
3306   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
3307     error (g, "guestfs_lvm_remove_all: failed to parse reply header");
3308     return;
3309   }
3310   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
3311     if (!xdr_guestfs_message_error (xdr, &state->err)) {
3312       error (g, "guestfs_lvm_remove_all: failed to parse reply error");
3313       return;
3314     }
3315     goto done;
3316   }
3317  done:
3318   state->cb_state = 1;
3319   ml->main_loop_quit (ml, g);
3320 }
3321
3322 int guestfs_lvm_remove_all (guestfs_h *g)
3323 {
3324   struct lvm_remove_all_state state;
3325   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3326   int serial;
3327
3328   if (check_state (g, "guestfs_lvm_remove_all") == -1) return -1;
3329
3330   memset (&state, 0, sizeof state);
3331
3332   serial = guestfs__send (g, GUESTFS_PROC_LVM_REMOVE_ALL, NULL, NULL);
3333   if (serial == -1)
3334     return -1;
3335
3336   state.cb_state = 0;
3337   guestfs_set_reply_callback (g, lvm_remove_all_cb, &state);
3338   (void) ml->main_loop_run (ml, g);
3339   guestfs_set_reply_callback (g, NULL, NULL);
3340   if (!state.cb_state) {
3341     error (g, "guestfs_lvm_remove_all failed, see earlier error messages");
3342     return -1;
3343   }
3344
3345   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_LVM_REMOVE_ALL, serial) == -1)
3346     return -1;
3347
3348   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
3349     error (g, "%s", state.err.error_message);
3350     return -1;
3351   }
3352
3353   return 0;
3354 }
3355
3356 struct file_state {
3357   int cb_state;
3358   struct guestfs_message_header hdr;
3359   struct guestfs_message_error err;
3360   struct guestfs_file_ret ret;
3361 };
3362
3363 static void file_cb (guestfs_h *g, void *data, XDR *xdr)
3364 {
3365   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3366   struct file_state *state = (struct file_state *) data;
3367
3368   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
3369     error (g, "guestfs_file: failed to parse reply header");
3370     return;
3371   }
3372   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
3373     if (!xdr_guestfs_message_error (xdr, &state->err)) {
3374       error (g, "guestfs_file: failed to parse reply error");
3375       return;
3376     }
3377     goto done;
3378   }
3379   if (!xdr_guestfs_file_ret (xdr, &state->ret)) {
3380     error (g, "guestfs_file: failed to parse reply");
3381     return;
3382   }
3383  done:
3384   state->cb_state = 1;
3385   ml->main_loop_quit (ml, g);
3386 }
3387
3388 char *guestfs_file (guestfs_h *g,
3389                 const char *path)
3390 {
3391   struct guestfs_file_args args;
3392   struct file_state state;
3393   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3394   int serial;
3395
3396   if (check_state (g, "guestfs_file") == -1) return NULL;
3397
3398   memset (&state, 0, sizeof state);
3399
3400   args.path = (char *) path;
3401   serial = guestfs__send (g, GUESTFS_PROC_FILE,
3402                      (xdrproc_t) xdr_guestfs_file_args, (char *) &args);
3403   if (serial == -1)
3404     return NULL;
3405
3406   state.cb_state = 0;
3407   guestfs_set_reply_callback (g, file_cb, &state);
3408   (void) ml->main_loop_run (ml, g);
3409   guestfs_set_reply_callback (g, NULL, NULL);
3410   if (!state.cb_state) {
3411     error (g, "guestfs_file failed, see earlier error messages");
3412     return NULL;
3413   }
3414
3415   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_FILE, serial) == -1)
3416     return NULL;
3417
3418   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
3419     error (g, "%s", state.err.error_message);
3420     return NULL;
3421   }
3422
3423   return state.ret.description; /* caller will free */
3424 }
3425
3426 struct command_state {
3427   int cb_state;
3428   struct guestfs_message_header hdr;
3429   struct guestfs_message_error err;
3430   struct guestfs_command_ret ret;
3431 };
3432
3433 static void command_cb (guestfs_h *g, void *data, XDR *xdr)
3434 {
3435   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3436   struct command_state *state = (struct command_state *) data;
3437
3438   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
3439     error (g, "guestfs_command: failed to parse reply header");
3440     return;
3441   }
3442   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
3443     if (!xdr_guestfs_message_error (xdr, &state->err)) {
3444       error (g, "guestfs_command: failed to parse reply error");
3445       return;
3446     }
3447     goto done;
3448   }
3449   if (!xdr_guestfs_command_ret (xdr, &state->ret)) {
3450     error (g, "guestfs_command: failed to parse reply");
3451     return;
3452   }
3453  done:
3454   state->cb_state = 1;
3455   ml->main_loop_quit (ml, g);
3456 }
3457
3458 char *guestfs_command (guestfs_h *g,
3459                 char * const* const arguments)
3460 {
3461   struct guestfs_command_args args;
3462   struct command_state state;
3463   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3464   int serial;
3465
3466   if (check_state (g, "guestfs_command") == -1) return NULL;
3467
3468   memset (&state, 0, sizeof state);
3469
3470   args.arguments.arguments_val = (char **) arguments;
3471   for (args.arguments.arguments_len = 0; arguments[args.arguments.arguments_len]; args.arguments.arguments_len++) ;
3472   serial = guestfs__send (g, GUESTFS_PROC_COMMAND,
3473                      (xdrproc_t) xdr_guestfs_command_args, (char *) &args);
3474   if (serial == -1)
3475     return NULL;
3476
3477   state.cb_state = 0;
3478   guestfs_set_reply_callback (g, command_cb, &state);
3479   (void) ml->main_loop_run (ml, g);
3480   guestfs_set_reply_callback (g, NULL, NULL);
3481   if (!state.cb_state) {
3482     error (g, "guestfs_command failed, see earlier error messages");
3483     return NULL;
3484   }
3485
3486   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_COMMAND, serial) == -1)
3487     return NULL;
3488
3489   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
3490     error (g, "%s", state.err.error_message);
3491     return NULL;
3492   }
3493
3494   return state.ret.output; /* caller will free */
3495 }
3496
3497 struct command_lines_state {
3498   int cb_state;
3499   struct guestfs_message_header hdr;
3500   struct guestfs_message_error err;
3501   struct guestfs_command_lines_ret ret;
3502 };
3503
3504 static void command_lines_cb (guestfs_h *g, void *data, XDR *xdr)
3505 {
3506   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3507   struct command_lines_state *state = (struct command_lines_state *) data;
3508
3509   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
3510     error (g, "guestfs_command_lines: failed to parse reply header");
3511     return;
3512   }
3513   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
3514     if (!xdr_guestfs_message_error (xdr, &state->err)) {
3515       error (g, "guestfs_command_lines: failed to parse reply error");
3516       return;
3517     }
3518     goto done;
3519   }
3520   if (!xdr_guestfs_command_lines_ret (xdr, &state->ret)) {
3521     error (g, "guestfs_command_lines: failed to parse reply");
3522     return;
3523   }
3524  done:
3525   state->cb_state = 1;
3526   ml->main_loop_quit (ml, g);
3527 }
3528
3529 char **guestfs_command_lines (guestfs_h *g,
3530                 char * const* const arguments)
3531 {
3532   struct guestfs_command_lines_args args;
3533   struct command_lines_state state;
3534   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3535   int serial;
3536
3537   if (check_state (g, "guestfs_command_lines") == -1) return NULL;
3538
3539   memset (&state, 0, sizeof state);
3540
3541   args.arguments.arguments_val = (char **) arguments;
3542   for (args.arguments.arguments_len = 0; arguments[args.arguments.arguments_len]; args.arguments.arguments_len++) ;
3543   serial = guestfs__send (g, GUESTFS_PROC_COMMAND_LINES,
3544                      (xdrproc_t) xdr_guestfs_command_lines_args, (char *) &args);
3545   if (serial == -1)
3546     return NULL;
3547
3548   state.cb_state = 0;
3549   guestfs_set_reply_callback (g, command_lines_cb, &state);
3550   (void) ml->main_loop_run (ml, g);
3551   guestfs_set_reply_callback (g, NULL, NULL);
3552   if (!state.cb_state) {
3553     error (g, "guestfs_command_lines failed, see earlier error messages");
3554     return NULL;
3555   }
3556
3557   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_COMMAND_LINES, serial) == -1)
3558     return NULL;
3559
3560   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
3561     error (g, "%s", state.err.error_message);
3562     return NULL;
3563   }
3564
3565   /* caller will free this, but we need to add a NULL entry */
3566   state.ret.lines.lines_val =
3567     safe_realloc (g, state.ret.lines.lines_val,
3568                   sizeof (char *) * (state.ret.lines.lines_len + 1));
3569   state.ret.lines.lines_val[state.ret.lines.lines_len] = NULL;
3570   return state.ret.lines.lines_val;
3571 }
3572
3573 struct stat_state {
3574   int cb_state;
3575   struct guestfs_message_header hdr;
3576   struct guestfs_message_error err;
3577   struct guestfs_stat_ret ret;
3578 };
3579
3580 static void stat_cb (guestfs_h *g, void *data, XDR *xdr)
3581 {
3582   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3583   struct stat_state *state = (struct stat_state *) data;
3584
3585   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
3586     error (g, "guestfs_stat: failed to parse reply header");
3587     return;
3588   }
3589   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
3590     if (!xdr_guestfs_message_error (xdr, &state->err)) {
3591       error (g, "guestfs_stat: failed to parse reply error");
3592       return;
3593     }
3594     goto done;
3595   }
3596   if (!xdr_guestfs_stat_ret (xdr, &state->ret)) {
3597     error (g, "guestfs_stat: failed to parse reply");
3598     return;
3599   }
3600  done:
3601   state->cb_state = 1;
3602   ml->main_loop_quit (ml, g);
3603 }
3604
3605 struct guestfs_stat *guestfs_stat (guestfs_h *g,
3606                 const char *path)
3607 {
3608   struct guestfs_stat_args args;
3609   struct stat_state state;
3610   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3611   int serial;
3612
3613   if (check_state (g, "guestfs_stat") == -1) return NULL;
3614
3615   memset (&state, 0, sizeof state);
3616
3617   args.path = (char *) path;
3618   serial = guestfs__send (g, GUESTFS_PROC_STAT,
3619                      (xdrproc_t) xdr_guestfs_stat_args, (char *) &args);
3620   if (serial == -1)
3621     return NULL;
3622
3623   state.cb_state = 0;
3624   guestfs_set_reply_callback (g, stat_cb, &state);
3625   (void) ml->main_loop_run (ml, g);
3626   guestfs_set_reply_callback (g, NULL, NULL);
3627   if (!state.cb_state) {
3628     error (g, "guestfs_stat failed, see earlier error messages");
3629     return NULL;
3630   }
3631
3632   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_STAT, serial) == -1)
3633     return NULL;
3634
3635   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
3636     error (g, "%s", state.err.error_message);
3637     return NULL;
3638   }
3639
3640   /* caller will free this */
3641   return safe_memdup (g, &state.ret.statbuf, sizeof (state.ret.statbuf));
3642 }
3643
3644 struct lstat_state {
3645   int cb_state;
3646   struct guestfs_message_header hdr;
3647   struct guestfs_message_error err;
3648   struct guestfs_lstat_ret ret;
3649 };
3650
3651 static void lstat_cb (guestfs_h *g, void *data, XDR *xdr)
3652 {
3653   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3654   struct lstat_state *state = (struct lstat_state *) data;
3655
3656   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
3657     error (g, "guestfs_lstat: failed to parse reply header");
3658     return;
3659   }
3660   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
3661     if (!xdr_guestfs_message_error (xdr, &state->err)) {
3662       error (g, "guestfs_lstat: failed to parse reply error");
3663       return;
3664     }
3665     goto done;
3666   }
3667   if (!xdr_guestfs_lstat_ret (xdr, &state->ret)) {
3668     error (g, "guestfs_lstat: failed to parse reply");
3669     return;
3670   }
3671  done:
3672   state->cb_state = 1;
3673   ml->main_loop_quit (ml, g);
3674 }
3675
3676 struct guestfs_stat *guestfs_lstat (guestfs_h *g,
3677                 const char *path)
3678 {
3679   struct guestfs_lstat_args args;
3680   struct lstat_state state;
3681   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3682   int serial;
3683
3684   if (check_state (g, "guestfs_lstat") == -1) return NULL;
3685
3686   memset (&state, 0, sizeof state);
3687
3688   args.path = (char *) path;
3689   serial = guestfs__send (g, GUESTFS_PROC_LSTAT,
3690                      (xdrproc_t) xdr_guestfs_lstat_args, (char *) &args);
3691   if (serial == -1)
3692     return NULL;
3693
3694   state.cb_state = 0;
3695   guestfs_set_reply_callback (g, lstat_cb, &state);
3696   (void) ml->main_loop_run (ml, g);
3697   guestfs_set_reply_callback (g, NULL, NULL);
3698   if (!state.cb_state) {
3699     error (g, "guestfs_lstat failed, see earlier error messages");
3700     return NULL;
3701   }
3702
3703   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_LSTAT, serial) == -1)
3704     return NULL;
3705
3706   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
3707     error (g, "%s", state.err.error_message);
3708     return NULL;
3709   }
3710
3711   /* caller will free this */
3712   return safe_memdup (g, &state.ret.statbuf, sizeof (state.ret.statbuf));
3713 }
3714
3715 struct statvfs_state {
3716   int cb_state;
3717   struct guestfs_message_header hdr;
3718   struct guestfs_message_error err;
3719   struct guestfs_statvfs_ret ret;
3720 };
3721
3722 static void statvfs_cb (guestfs_h *g, void *data, XDR *xdr)
3723 {
3724   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3725   struct statvfs_state *state = (struct statvfs_state *) data;
3726
3727   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
3728     error (g, "guestfs_statvfs: failed to parse reply header");
3729     return;
3730   }
3731   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
3732     if (!xdr_guestfs_message_error (xdr, &state->err)) {
3733       error (g, "guestfs_statvfs: failed to parse reply error");
3734       return;
3735     }
3736     goto done;
3737   }
3738   if (!xdr_guestfs_statvfs_ret (xdr, &state->ret)) {
3739     error (g, "guestfs_statvfs: failed to parse reply");
3740     return;
3741   }
3742  done:
3743   state->cb_state = 1;
3744   ml->main_loop_quit (ml, g);
3745 }
3746
3747 struct guestfs_statvfs *guestfs_statvfs (guestfs_h *g,
3748                 const char *path)
3749 {
3750   struct guestfs_statvfs_args args;
3751   struct statvfs_state state;
3752   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3753   int serial;
3754
3755   if (check_state (g, "guestfs_statvfs") == -1) return NULL;
3756
3757   memset (&state, 0, sizeof state);
3758
3759   args.path = (char *) path;
3760   serial = guestfs__send (g, GUESTFS_PROC_STATVFS,
3761                      (xdrproc_t) xdr_guestfs_statvfs_args, (char *) &args);
3762   if (serial == -1)
3763     return NULL;
3764
3765   state.cb_state = 0;
3766   guestfs_set_reply_callback (g, statvfs_cb, &state);
3767   (void) ml->main_loop_run (ml, g);
3768   guestfs_set_reply_callback (g, NULL, NULL);
3769   if (!state.cb_state) {
3770     error (g, "guestfs_statvfs failed, see earlier error messages");
3771     return NULL;
3772   }
3773
3774   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_STATVFS, serial) == -1)
3775     return NULL;
3776
3777   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
3778     error (g, "%s", state.err.error_message);
3779     return NULL;
3780   }
3781
3782   /* caller will free this */
3783   return safe_memdup (g, &state.ret.statbuf, sizeof (state.ret.statbuf));
3784 }
3785
3786 struct tune2fs_l_state {
3787   int cb_state;
3788   struct guestfs_message_header hdr;
3789   struct guestfs_message_error err;
3790   struct guestfs_tune2fs_l_ret ret;
3791 };
3792
3793 static void tune2fs_l_cb (guestfs_h *g, void *data, XDR *xdr)
3794 {
3795   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3796   struct tune2fs_l_state *state = (struct tune2fs_l_state *) data;
3797
3798   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
3799     error (g, "guestfs_tune2fs_l: failed to parse reply header");
3800     return;
3801   }
3802   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
3803     if (!xdr_guestfs_message_error (xdr, &state->err)) {
3804       error (g, "guestfs_tune2fs_l: failed to parse reply error");
3805       return;
3806     }
3807     goto done;
3808   }
3809   if (!xdr_guestfs_tune2fs_l_ret (xdr, &state->ret)) {
3810     error (g, "guestfs_tune2fs_l: failed to parse reply");
3811     return;
3812   }
3813  done:
3814   state->cb_state = 1;
3815   ml->main_loop_quit (ml, g);
3816 }
3817
3818 char **guestfs_tune2fs_l (guestfs_h *g,
3819                 const char *device)
3820 {
3821   struct guestfs_tune2fs_l_args args;
3822   struct tune2fs_l_state state;
3823   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3824   int serial;
3825
3826   if (check_state (g, "guestfs_tune2fs_l") == -1) return NULL;
3827
3828   memset (&state, 0, sizeof state);
3829
3830   args.device = (char *) device;
3831   serial = guestfs__send (g, GUESTFS_PROC_TUNE2FS_L,
3832                      (xdrproc_t) xdr_guestfs_tune2fs_l_args, (char *) &args);
3833   if (serial == -1)
3834     return NULL;
3835
3836   state.cb_state = 0;
3837   guestfs_set_reply_callback (g, tune2fs_l_cb, &state);
3838   (void) ml->main_loop_run (ml, g);
3839   guestfs_set_reply_callback (g, NULL, NULL);
3840   if (!state.cb_state) {
3841     error (g, "guestfs_tune2fs_l failed, see earlier error messages");
3842     return NULL;
3843   }
3844
3845   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_TUNE2FS_L, serial) == -1)
3846     return NULL;
3847
3848   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
3849     error (g, "%s", state.err.error_message);
3850     return NULL;
3851   }
3852
3853   /* caller will free this, but we need to add a NULL entry */
3854   state.ret.superblock.superblock_val =
3855     safe_realloc (g, state.ret.superblock.superblock_val,
3856                   sizeof (char *) * (state.ret.superblock.superblock_len + 1));
3857   state.ret.superblock.superblock_val[state.ret.superblock.superblock_len] = NULL;
3858   return state.ret.superblock.superblock_val;
3859 }
3860
3861 struct blockdev_setro_state {
3862   int cb_state;
3863   struct guestfs_message_header hdr;
3864   struct guestfs_message_error err;
3865 };
3866
3867 static void blockdev_setro_cb (guestfs_h *g, void *data, XDR *xdr)
3868 {
3869   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3870   struct blockdev_setro_state *state = (struct blockdev_setro_state *) data;
3871
3872   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
3873     error (g, "guestfs_blockdev_setro: failed to parse reply header");
3874     return;
3875   }
3876   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
3877     if (!xdr_guestfs_message_error (xdr, &state->err)) {
3878       error (g, "guestfs_blockdev_setro: failed to parse reply error");
3879       return;
3880     }
3881     goto done;
3882   }
3883  done:
3884   state->cb_state = 1;
3885   ml->main_loop_quit (ml, g);
3886 }
3887
3888 int guestfs_blockdev_setro (guestfs_h *g,
3889                 const char *device)
3890 {
3891   struct guestfs_blockdev_setro_args args;
3892   struct blockdev_setro_state state;
3893   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3894   int serial;
3895
3896   if (check_state (g, "guestfs_blockdev_setro") == -1) return -1;
3897
3898   memset (&state, 0, sizeof state);
3899
3900   args.device = (char *) device;
3901   serial = guestfs__send (g, GUESTFS_PROC_BLOCKDEV_SETRO,
3902                      (xdrproc_t) xdr_guestfs_blockdev_setro_args, (char *) &args);
3903   if (serial == -1)
3904     return -1;
3905
3906   state.cb_state = 0;
3907   guestfs_set_reply_callback (g, blockdev_setro_cb, &state);
3908   (void) ml->main_loop_run (ml, g);
3909   guestfs_set_reply_callback (g, NULL, NULL);
3910   if (!state.cb_state) {
3911     error (g, "guestfs_blockdev_setro failed, see earlier error messages");
3912     return -1;
3913   }
3914
3915   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_BLOCKDEV_SETRO, serial) == -1)
3916     return -1;
3917
3918   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
3919     error (g, "%s", state.err.error_message);
3920     return -1;
3921   }
3922
3923   return 0;
3924 }
3925
3926 struct blockdev_setrw_state {
3927   int cb_state;
3928   struct guestfs_message_header hdr;
3929   struct guestfs_message_error err;
3930 };
3931
3932 static void blockdev_setrw_cb (guestfs_h *g, void *data, XDR *xdr)
3933 {
3934   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3935   struct blockdev_setrw_state *state = (struct blockdev_setrw_state *) data;
3936
3937   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
3938     error (g, "guestfs_blockdev_setrw: failed to parse reply header");
3939     return;
3940   }
3941   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
3942     if (!xdr_guestfs_message_error (xdr, &state->err)) {
3943       error (g, "guestfs_blockdev_setrw: failed to parse reply error");
3944       return;
3945     }
3946     goto done;
3947   }
3948  done:
3949   state->cb_state = 1;
3950   ml->main_loop_quit (ml, g);
3951 }
3952
3953 int guestfs_blockdev_setrw (guestfs_h *g,
3954                 const char *device)
3955 {
3956   struct guestfs_blockdev_setrw_args args;
3957   struct blockdev_setrw_state state;
3958   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3959   int serial;
3960
3961   if (check_state (g, "guestfs_blockdev_setrw") == -1) return -1;
3962
3963   memset (&state, 0, sizeof state);
3964
3965   args.device = (char *) device;
3966   serial = guestfs__send (g, GUESTFS_PROC_BLOCKDEV_SETRW,
3967                      (xdrproc_t) xdr_guestfs_blockdev_setrw_args, (char *) &args);
3968   if (serial == -1)
3969     return -1;
3970
3971   state.cb_state = 0;
3972   guestfs_set_reply_callback (g, blockdev_setrw_cb, &state);
3973   (void) ml->main_loop_run (ml, g);
3974   guestfs_set_reply_callback (g, NULL, NULL);
3975   if (!state.cb_state) {
3976     error (g, "guestfs_blockdev_setrw failed, see earlier error messages");
3977     return -1;
3978   }
3979
3980   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_BLOCKDEV_SETRW, serial) == -1)
3981     return -1;
3982
3983   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
3984     error (g, "%s", state.err.error_message);
3985     return -1;
3986   }
3987
3988   return 0;
3989 }
3990
3991 struct blockdev_getro_state {
3992   int cb_state;
3993   struct guestfs_message_header hdr;
3994   struct guestfs_message_error err;
3995   struct guestfs_blockdev_getro_ret ret;
3996 };
3997
3998 static void blockdev_getro_cb (guestfs_h *g, void *data, XDR *xdr)
3999 {
4000   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4001   struct blockdev_getro_state *state = (struct blockdev_getro_state *) data;
4002
4003   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
4004     error (g, "guestfs_blockdev_getro: failed to parse reply header");
4005     return;
4006   }
4007   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
4008     if (!xdr_guestfs_message_error (xdr, &state->err)) {
4009       error (g, "guestfs_blockdev_getro: failed to parse reply error");
4010       return;
4011     }
4012     goto done;
4013   }
4014   if (!xdr_guestfs_blockdev_getro_ret (xdr, &state->ret)) {
4015     error (g, "guestfs_blockdev_getro: failed to parse reply");
4016     return;
4017   }
4018  done:
4019   state->cb_state = 1;
4020   ml->main_loop_quit (ml, g);
4021 }
4022
4023 int guestfs_blockdev_getro (guestfs_h *g,
4024                 const char *device)
4025 {
4026   struct guestfs_blockdev_getro_args args;
4027   struct blockdev_getro_state state;
4028   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4029   int serial;
4030
4031   if (check_state (g, "guestfs_blockdev_getro") == -1) return -1;
4032
4033   memset (&state, 0, sizeof state);
4034
4035   args.device = (char *) device;
4036   serial = guestfs__send (g, GUESTFS_PROC_BLOCKDEV_GETRO,
4037                      (xdrproc_t) xdr_guestfs_blockdev_getro_args, (char *) &args);
4038   if (serial == -1)
4039     return -1;
4040
4041   state.cb_state = 0;
4042   guestfs_set_reply_callback (g, blockdev_getro_cb, &state);
4043   (void) ml->main_loop_run (ml, g);
4044   guestfs_set_reply_callback (g, NULL, NULL);
4045   if (!state.cb_state) {
4046     error (g, "guestfs_blockdev_getro failed, see earlier error messages");
4047     return -1;
4048   }
4049
4050   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_BLOCKDEV_GETRO, serial) == -1)
4051     return -1;
4052
4053   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
4054     error (g, "%s", state.err.error_message);
4055     return -1;
4056   }
4057
4058   return state.ret.ro;
4059 }
4060
4061 struct blockdev_getss_state {
4062   int cb_state;
4063   struct guestfs_message_header hdr;
4064   struct guestfs_message_error err;
4065   struct guestfs_blockdev_getss_ret ret;
4066 };
4067
4068 static void blockdev_getss_cb (guestfs_h *g, void *data, XDR *xdr)
4069 {
4070   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4071   struct blockdev_getss_state *state = (struct blockdev_getss_state *) data;
4072
4073   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
4074     error (g, "guestfs_blockdev_getss: failed to parse reply header");
4075     return;
4076   }
4077   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
4078     if (!xdr_guestfs_message_error (xdr, &state->err)) {
4079       error (g, "guestfs_blockdev_getss: failed to parse reply error");
4080       return;
4081     }
4082     goto done;
4083   }
4084   if (!xdr_guestfs_blockdev_getss_ret (xdr, &state->ret)) {
4085     error (g, "guestfs_blockdev_getss: failed to parse reply");
4086     return;
4087   }
4088  done:
4089   state->cb_state = 1;
4090   ml->main_loop_quit (ml, g);
4091 }
4092
4093 int guestfs_blockdev_getss (guestfs_h *g,
4094                 const char *device)
4095 {
4096   struct guestfs_blockdev_getss_args args;
4097   struct blockdev_getss_state state;
4098   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4099   int serial;
4100
4101   if (check_state (g, "guestfs_blockdev_getss") == -1) return -1;
4102
4103   memset (&state, 0, sizeof state);
4104
4105   args.device = (char *) device;
4106   serial = guestfs__send (g, GUESTFS_PROC_BLOCKDEV_GETSS,
4107                      (xdrproc_t) xdr_guestfs_blockdev_getss_args, (char *) &args);
4108   if (serial == -1)
4109     return -1;
4110
4111   state.cb_state = 0;
4112   guestfs_set_reply_callback (g, blockdev_getss_cb, &state);
4113   (void) ml->main_loop_run (ml, g);
4114   guestfs_set_reply_callback (g, NULL, NULL);
4115   if (!state.cb_state) {
4116     error (g, "guestfs_blockdev_getss failed, see earlier error messages");
4117     return -1;
4118   }
4119
4120   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_BLOCKDEV_GETSS, serial) == -1)
4121     return -1;
4122
4123   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
4124     error (g, "%s", state.err.error_message);
4125     return -1;
4126   }
4127
4128   return state.ret.sectorsize;
4129 }
4130
4131 struct blockdev_getbsz_state {
4132   int cb_state;
4133   struct guestfs_message_header hdr;
4134   struct guestfs_message_error err;
4135   struct guestfs_blockdev_getbsz_ret ret;
4136 };
4137
4138 static void blockdev_getbsz_cb (guestfs_h *g, void *data, XDR *xdr)
4139 {
4140   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4141   struct blockdev_getbsz_state *state = (struct blockdev_getbsz_state *) data;
4142
4143   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
4144     error (g, "guestfs_blockdev_getbsz: failed to parse reply header");
4145     return;
4146   }
4147   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
4148     if (!xdr_guestfs_message_error (xdr, &state->err)) {
4149       error (g, "guestfs_blockdev_getbsz: failed to parse reply error");
4150       return;
4151     }
4152     goto done;
4153   }
4154   if (!xdr_guestfs_blockdev_getbsz_ret (xdr, &state->ret)) {
4155     error (g, "guestfs_blockdev_getbsz: failed to parse reply");
4156     return;
4157   }
4158  done:
4159   state->cb_state = 1;
4160   ml->main_loop_quit (ml, g);
4161 }
4162
4163 int guestfs_blockdev_getbsz (guestfs_h *g,
4164                 const char *device)
4165 {
4166   struct guestfs_blockdev_getbsz_args args;
4167   struct blockdev_getbsz_state state;
4168   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4169   int serial;
4170
4171   if (check_state (g, "guestfs_blockdev_getbsz") == -1) return -1;
4172
4173   memset (&state, 0, sizeof state);
4174
4175   args.device = (char *) device;
4176   serial = guestfs__send (g, GUESTFS_PROC_BLOCKDEV_GETBSZ,
4177                      (xdrproc_t) xdr_guestfs_blockdev_getbsz_args, (char *) &args);
4178   if (serial == -1)
4179     return -1;
4180
4181   state.cb_state = 0;
4182   guestfs_set_reply_callback (g, blockdev_getbsz_cb, &state);
4183   (void) ml->main_loop_run (ml, g);
4184   guestfs_set_reply_callback (g, NULL, NULL);
4185   if (!state.cb_state) {
4186     error (g, "guestfs_blockdev_getbsz failed, see earlier error messages");
4187     return -1;
4188   }
4189
4190   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_BLOCKDEV_GETBSZ, serial) == -1)
4191     return -1;
4192
4193   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
4194     error (g, "%s", state.err.error_message);
4195     return -1;
4196   }
4197
4198   return state.ret.blocksize;
4199 }
4200
4201 struct blockdev_setbsz_state {
4202   int cb_state;
4203   struct guestfs_message_header hdr;
4204   struct guestfs_message_error err;
4205 };
4206
4207 static void blockdev_setbsz_cb (guestfs_h *g, void *data, XDR *xdr)
4208 {
4209   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4210   struct blockdev_setbsz_state *state = (struct blockdev_setbsz_state *) data;
4211
4212   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
4213     error (g, "guestfs_blockdev_setbsz: failed to parse reply header");
4214     return;
4215   }
4216   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
4217     if (!xdr_guestfs_message_error (xdr, &state->err)) {
4218       error (g, "guestfs_blockdev_setbsz: failed to parse reply error");
4219       return;
4220     }
4221     goto done;
4222   }
4223  done:
4224   state->cb_state = 1;
4225   ml->main_loop_quit (ml, g);
4226 }
4227
4228 int guestfs_blockdev_setbsz (guestfs_h *g,
4229                 const char *device,
4230                 int blocksize)
4231 {
4232   struct guestfs_blockdev_setbsz_args args;
4233   struct blockdev_setbsz_state state;
4234   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4235   int serial;
4236
4237   if (check_state (g, "guestfs_blockdev_setbsz") == -1) return -1;
4238
4239   memset (&state, 0, sizeof state);
4240
4241   args.device = (char *) device;
4242   args.blocksize = blocksize;
4243   serial = guestfs__send (g, GUESTFS_PROC_BLOCKDEV_SETBSZ,
4244                      (xdrproc_t) xdr_guestfs_blockdev_setbsz_args, (char *) &args);
4245   if (serial == -1)
4246     return -1;
4247
4248   state.cb_state = 0;
4249   guestfs_set_reply_callback (g, blockdev_setbsz_cb, &state);
4250   (void) ml->main_loop_run (ml, g);
4251   guestfs_set_reply_callback (g, NULL, NULL);
4252   if (!state.cb_state) {
4253     error (g, "guestfs_blockdev_setbsz failed, see earlier error messages");
4254     return -1;
4255   }
4256
4257   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_BLOCKDEV_SETBSZ, serial) == -1)
4258     return -1;
4259
4260   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
4261     error (g, "%s", state.err.error_message);
4262     return -1;
4263   }
4264
4265   return 0;
4266 }
4267
4268 struct blockdev_getsz_state {
4269   int cb_state;
4270   struct guestfs_message_header hdr;
4271   struct guestfs_message_error err;
4272   struct guestfs_blockdev_getsz_ret ret;
4273 };
4274
4275 static void blockdev_getsz_cb (guestfs_h *g, void *data, XDR *xdr)
4276 {
4277   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4278   struct blockdev_getsz_state *state = (struct blockdev_getsz_state *) data;
4279
4280   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
4281     error (g, "guestfs_blockdev_getsz: failed to parse reply header");
4282     return;
4283   }
4284   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
4285     if (!xdr_guestfs_message_error (xdr, &state->err)) {
4286       error (g, "guestfs_blockdev_getsz: failed to parse reply error");
4287       return;
4288     }
4289     goto done;
4290   }
4291   if (!xdr_guestfs_blockdev_getsz_ret (xdr, &state->ret)) {
4292     error (g, "guestfs_blockdev_getsz: failed to parse reply");
4293     return;
4294   }
4295  done:
4296   state->cb_state = 1;
4297   ml->main_loop_quit (ml, g);
4298 }
4299
4300 int64_t guestfs_blockdev_getsz (guestfs_h *g,
4301                 const char *device)
4302 {
4303   struct guestfs_blockdev_getsz_args args;
4304   struct blockdev_getsz_state state;
4305   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4306   int serial;
4307
4308   if (check_state (g, "guestfs_blockdev_getsz") == -1) return -1;
4309
4310   memset (&state, 0, sizeof state);
4311
4312   args.device = (char *) device;
4313   serial = guestfs__send (g, GUESTFS_PROC_BLOCKDEV_GETSZ,
4314                      (xdrproc_t) xdr_guestfs_blockdev_getsz_args, (char *) &args);
4315   if (serial == -1)
4316     return -1;
4317
4318   state.cb_state = 0;
4319   guestfs_set_reply_callback (g, blockdev_getsz_cb, &state);
4320   (void) ml->main_loop_run (ml, g);
4321   guestfs_set_reply_callback (g, NULL, NULL);
4322   if (!state.cb_state) {
4323     error (g, "guestfs_blockdev_getsz failed, see earlier error messages");
4324     return -1;
4325   }
4326
4327   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_BLOCKDEV_GETSZ, serial) == -1)
4328     return -1;
4329
4330   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
4331     error (g, "%s", state.err.error_message);
4332     return -1;
4333   }
4334
4335   return state.ret.sizeinsectors;
4336 }
4337
4338 struct blockdev_getsize64_state {
4339   int cb_state;
4340   struct guestfs_message_header hdr;
4341   struct guestfs_message_error err;
4342   struct guestfs_blockdev_getsize64_ret ret;
4343 };
4344
4345 static void blockdev_getsize64_cb (guestfs_h *g, void *data, XDR *xdr)
4346 {
4347   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4348   struct blockdev_getsize64_state *state = (struct blockdev_getsize64_state *) data;
4349
4350   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
4351     error (g, "guestfs_blockdev_getsize64: failed to parse reply header");
4352     return;
4353   }
4354   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
4355     if (!xdr_guestfs_message_error (xdr, &state->err)) {
4356       error (g, "guestfs_blockdev_getsize64: failed to parse reply error");
4357       return;
4358     }
4359     goto done;
4360   }
4361   if (!xdr_guestfs_blockdev_getsize64_ret (xdr, &state->ret)) {
4362     error (g, "guestfs_blockdev_getsize64: failed to parse reply");
4363     return;
4364   }
4365  done:
4366   state->cb_state = 1;
4367   ml->main_loop_quit (ml, g);
4368 }
4369
4370 int64_t guestfs_blockdev_getsize64 (guestfs_h *g,
4371                 const char *device)
4372 {
4373   struct guestfs_blockdev_getsize64_args args;
4374   struct blockdev_getsize64_state state;
4375   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4376   int serial;
4377
4378   if (check_state (g, "guestfs_blockdev_getsize64") == -1) return -1;
4379
4380   memset (&state, 0, sizeof state);
4381
4382   args.device = (char *) device;
4383   serial = guestfs__send (g, GUESTFS_PROC_BLOCKDEV_GETSIZE64,
4384                      (xdrproc_t) xdr_guestfs_blockdev_getsize64_args, (char *) &args);
4385   if (serial == -1)
4386     return -1;
4387
4388   state.cb_state = 0;
4389   guestfs_set_reply_callback (g, blockdev_getsize64_cb, &state);
4390   (void) ml->main_loop_run (ml, g);
4391   guestfs_set_reply_callback (g, NULL, NULL);
4392   if (!state.cb_state) {
4393     error (g, "guestfs_blockdev_getsize64 failed, see earlier error messages");
4394     return -1;
4395   }
4396
4397   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_BLOCKDEV_GETSIZE64, serial) == -1)
4398     return -1;
4399
4400   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
4401     error (g, "%s", state.err.error_message);
4402     return -1;
4403   }
4404
4405   return state.ret.sizeinbytes;
4406 }
4407
4408 struct blockdev_flushbufs_state {
4409   int cb_state;
4410   struct guestfs_message_header hdr;
4411   struct guestfs_message_error err;
4412 };
4413
4414 static void blockdev_flushbufs_cb (guestfs_h *g, void *data, XDR *xdr)
4415 {
4416   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4417   struct blockdev_flushbufs_state *state = (struct blockdev_flushbufs_state *) data;
4418
4419   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
4420     error (g, "guestfs_blockdev_flushbufs: failed to parse reply header");
4421     return;
4422   }
4423   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
4424     if (!xdr_guestfs_message_error (xdr, &state->err)) {
4425       error (g, "guestfs_blockdev_flushbufs: failed to parse reply error");
4426       return;
4427     }
4428     goto done;
4429   }
4430  done:
4431   state->cb_state = 1;
4432   ml->main_loop_quit (ml, g);
4433 }
4434
4435 int guestfs_blockdev_flushbufs (guestfs_h *g,
4436                 const char *device)
4437 {
4438   struct guestfs_blockdev_flushbufs_args args;
4439   struct blockdev_flushbufs_state state;
4440   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4441   int serial;
4442
4443   if (check_state (g, "guestfs_blockdev_flushbufs") == -1) return -1;
4444
4445   memset (&state, 0, sizeof state);
4446
4447   args.device = (char *) device;
4448   serial = guestfs__send (g, GUESTFS_PROC_BLOCKDEV_FLUSHBUFS,
4449                      (xdrproc_t) xdr_guestfs_blockdev_flushbufs_args, (char *) &args);
4450   if (serial == -1)
4451     return -1;
4452
4453   state.cb_state = 0;
4454   guestfs_set_reply_callback (g, blockdev_flushbufs_cb, &state);
4455   (void) ml->main_loop_run (ml, g);
4456   guestfs_set_reply_callback (g, NULL, NULL);
4457   if (!state.cb_state) {
4458     error (g, "guestfs_blockdev_flushbufs failed, see earlier error messages");
4459     return -1;
4460   }
4461
4462   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_BLOCKDEV_FLUSHBUFS, serial) == -1)
4463     return -1;
4464
4465   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
4466     error (g, "%s", state.err.error_message);
4467     return -1;
4468   }
4469
4470   return 0;
4471 }
4472
4473 struct blockdev_rereadpt_state {
4474   int cb_state;
4475   struct guestfs_message_header hdr;
4476   struct guestfs_message_error err;
4477 };
4478
4479 static void blockdev_rereadpt_cb (guestfs_h *g, void *data, XDR *xdr)
4480 {
4481   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4482   struct blockdev_rereadpt_state *state = (struct blockdev_rereadpt_state *) data;
4483
4484   if (!xdr_guestfs_message_header (xdr, &state->hdr)) {
4485     error (g, "guestfs_blockdev_rereadpt: failed to parse reply header");
4486     return;
4487   }
4488   if (state->hdr.status == GUESTFS_STATUS_ERROR) {
4489     if (!xdr_guestfs_message_error (xdr, &state->err)) {
4490       error (g, "guestfs_blockdev_rereadpt: failed to parse reply error");
4491       return;
4492     }
4493     goto done;
4494   }
4495  done:
4496   state->cb_state = 1;
4497   ml->main_loop_quit (ml, g);
4498 }
4499
4500 int guestfs_blockdev_rereadpt (guestfs_h *g,
4501                 const char *device)
4502 {
4503   struct guestfs_blockdev_rereadpt_args args;
4504   struct blockdev_rereadpt_state state;
4505   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4506   int serial;
4507
4508   if (check_state (g, "guestfs_blockdev_rereadpt") == -1) return -1;
4509
4510   memset (&state, 0, sizeof state);
4511
4512   args.device = (char *) device;
4513   serial = guestfs__send (g, GUESTFS_PROC_BLOCKDEV_REREADPT,
4514                      (xdrproc_t) xdr_guestfs_blockdev_rereadpt_args, (char *) &args);
4515   if (serial == -1)
4516     return -1;
4517
4518   state.cb_state = 0;
4519   guestfs_set_reply_callback (g, blockdev_rereadpt_cb, &state);
4520   (void) ml->main_loop_run (ml, g);
4521   guestfs_set_reply_callback (g, NULL, NULL);
4522   if (!state.cb_state) {
4523     error (g, "guestfs_blockdev_rereadpt failed, see earlier error messages");
4524     return -1;
4525   }
4526
4527   if (check_reply_header (g, &state.hdr, GUESTFS_PROC_BLOCKDEV_REREADPT, serial) == -1)
4528     return -1;
4529
4530   if (state.hdr.status == GUESTFS_STATUS_ERROR) {
4531     error (g, "%s", state.err.error_message);
4532     return -1;
4533   }
4534
4535   return 0;
4536 }
4537