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