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