From 01c26253a12ed1e6b1199f8c85f049a7fc4aef28 Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Thu, 9 Apr 2009 19:36:07 +0100 Subject: [PATCH] Added aug-ls (generated code). --- daemon/actions.h | 1 + daemon/stubs.c | 29 ++++++++++++++++++ fish/cmds.c | 24 +++++++++++++++ guestfish-actions.pod | 7 +++++ guestfs-actions.pod | 12 ++++++++ ocaml/guestfs.ml | 1 + ocaml/guestfs.mli | 3 ++ ocaml/guestfs_c_actions.c | 26 ++++++++++++++++ perl/Guestfs.xs | 19 ++++++++++++ perl/lib/Sys/Guestfs.pm | 5 +++ src/guestfs-actions.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++ src/guestfs-actions.h | 1 + src/guestfs_protocol.c | 21 +++++++++++++ src/guestfs_protocol.h | 20 +++++++++++- src/guestfs_protocol.x | 9 ++++++ 15 files changed, 255 insertions(+), 1 deletion(-) diff --git a/daemon/actions.h b/daemon/actions.h index 6a41c7d..a2edc76 100644 --- a/daemon/actions.h +++ b/daemon/actions.h @@ -48,3 +48,4 @@ extern int do_aug_mv (const char *src, const char *dest); extern char **do_aug_match (const char *path); extern int do_aug_save (void); extern int do_aug_load (void); +extern char **do_aug_ls (const char *path); diff --git a/daemon/stubs.c b/daemon/stubs.c index 38aea33..eb39828 100644 --- a/daemon/stubs.c +++ b/daemon/stubs.c @@ -580,6 +580,32 @@ static void aug_load_stub (XDR *xdr_in) reply (NULL, NULL); } +static void aug_ls_stub (XDR *xdr_in) +{ + char **r; + struct guestfs_aug_ls_args args; + const char *path; + + memset (&args, 0, sizeof args); + + if (!xdr_guestfs_aug_ls_args (xdr_in, &args)) { + reply_with_error ("%s: daemon failed to decode procedure arguments", "aug_ls"); + return; + } + path = args.path; + + r = do_aug_ls (path); + if (r == NULL) + /* do_aug_ls has already called reply_with_error, so just return */ + return; + + struct guestfs_aug_ls_ret ret; + ret.matches.matches_len = count_strings (r); + ret.matches.matches_val = r; + reply ((xdrproc_t) &xdr_guestfs_aug_ls_ret, (char *) &ret); + free_strings (r); +} + void dispatch_incoming_message (XDR *xdr_in) { switch (proc_nr) { @@ -664,6 +690,9 @@ void dispatch_incoming_message (XDR *xdr_in) case GUESTFS_PROC_AUG_LOAD: aug_load_stub (xdr_in); break; + case GUESTFS_PROC_AUG_LS: + aug_ls_stub (xdr_in); + break; default: reply_with_error ("dispatch_incoming_message: unknown procedure number %d", proc_nr); } diff --git a/fish/cmds.c b/fish/cmds.c index 12c2c1e..e9ef208 100644 --- a/fish/cmds.c +++ b/fish/cmds.c @@ -40,6 +40,7 @@ void list_commands (void) printf ("%-20s %s\n", "aug-init", "create a new Augeas handle"); printf ("%-20s %s\n", "aug-insert", "insert a sibling Augeas node"); printf ("%-20s %s\n", "aug-load", "load files into the tree"); + printf ("%-20s %s\n", "aug-ls", "list Augeas nodes under a path"); printf ("%-20s %s\n", "aug-match", "return Augeas nodes which match path"); printf ("%-20s %s\n", "aug-mv", "move Augeas node"); printf ("%-20s %s\n", "aug-rm", "remove an Augeas path"); @@ -188,6 +189,9 @@ void display_command (const char *cmd) if (strcasecmp (cmd, "aug_load") == 0 || strcasecmp (cmd, "aug-load") == 0) pod2text ("aug-load - load files into the tree", " aug-load\n\nLoad files into the tree.\n\nSee C in the Augeas documentation for the full gory\ndetails."); else + if (strcasecmp (cmd, "aug_ls") == 0 || strcasecmp (cmd, "aug-ls") == 0) + pod2text ("aug-ls - list Augeas nodes under a path", " aug-ls \n\nThis is just a shortcut for listing C\nC and sorting the files into alphabetical order."); + else display_builtin_command (cmd); } @@ -867,6 +871,23 @@ static int run_aug_load (const char *cmd, int argc, char *argv[]) return r; } +static int run_aug_ls (const char *cmd, int argc, char *argv[]) +{ + char **r; + const char *path; + if (argc != 1) { + fprintf (stderr, "%s should have 1 parameter(s)\n", cmd); + fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd); + return -1; + } + path = argv[0]; + r = guestfs_aug_ls (g, path); + if (r == NULL) return -1; + print_strings (r); + free_strings (r); + return 0; +} + int run_action (const char *cmd, int argc, char *argv[]) { if (strcasecmp (cmd, "launch") == 0 || strcasecmp (cmd, "run") == 0) @@ -983,6 +1004,9 @@ int run_action (const char *cmd, int argc, char *argv[]) if (strcasecmp (cmd, "aug_load") == 0 || strcasecmp (cmd, "aug-load") == 0) return run_aug_load (cmd, argc, argv); else + if (strcasecmp (cmd, "aug_ls") == 0 || strcasecmp (cmd, "aug-ls") == 0) + return run_aug_ls (cmd, argc, argv); + else { fprintf (stderr, "%s: unknown command\n", cmd); return -1; diff --git a/guestfish-actions.pod b/guestfish-actions.pod index d218e0e..c8ebfc5 100644 --- a/guestfish-actions.pod +++ b/guestfish-actions.pod @@ -137,6 +137,13 @@ Load files into the tree. See C in the Augeas documentation for the full gory details. +=head2 aug-ls + + aug-ls path + +This is just a shortcut for listing C +C and sorting the files into alphabetical order. + =head2 aug-match aug-match path diff --git a/guestfs-actions.pod b/guestfs-actions.pod index 29f8538..89aa968 100644 --- a/guestfs-actions.pod +++ b/guestfs-actions.pod @@ -170,6 +170,18 @@ details. This function returns 0 on success or -1 on error. +=head2 guestfs_aug_ls + + char **guestfs_aug_ls (guestfs_h *handle, + const char *path); + +This is just a shortcut for listing C +C and sorting the files into alphabetical order. + +This function returns a NULL-terminated array of strings +(like L), or NULL if there was an error. +I. + =head2 guestfs_aug_match char **guestfs_aug_match (guestfs_h *handle, diff --git a/ocaml/guestfs.ml b/ocaml/guestfs.ml index 6487861..fba005f 100644 --- a/ocaml/guestfs.ml +++ b/ocaml/guestfs.ml @@ -124,3 +124,4 @@ external aug_mv : t -> string -> string -> unit = "ocaml_guestfs_aug_mv" external aug_match : t -> string -> string array = "ocaml_guestfs_aug_match" external aug_save : t -> unit = "ocaml_guestfs_aug_save" external aug_load : t -> unit = "ocaml_guestfs_aug_load" +external aug_ls : t -> string -> string array = "ocaml_guestfs_aug_ls" diff --git a/ocaml/guestfs.mli b/ocaml/guestfs.mli index b1452ab..4981eb1 100644 --- a/ocaml/guestfs.mli +++ b/ocaml/guestfs.mli @@ -211,3 +211,6 @@ val aug_save : t -> unit val aug_load : t -> unit (** load files into the tree *) +val aug_ls : t -> string -> string array +(** list Augeas nodes under a path *) + diff --git a/ocaml/guestfs_c_actions.c b/ocaml/guestfs_c_actions.c index f21d63e..f26226c 100644 --- a/ocaml/guestfs_c_actions.c +++ b/ocaml/guestfs_c_actions.c @@ -1157,3 +1157,29 @@ ocaml_guestfs_aug_load (value gv) CAMLreturn (rv); } +CAMLprim value +ocaml_guestfs_aug_ls (value gv, value pathv) +{ + CAMLparam2 (gv, pathv); + CAMLlocal1 (rv); + + guestfs_h *g = Guestfs_val (gv); + if (g == NULL) + caml_failwith ("aug_ls: used handle after closing it"); + + const char *path = String_val (pathv); + int i; + char **r; + + caml_enter_blocking_section (); + r = guestfs_aug_ls (g, path); + caml_leave_blocking_section (); + if (r == NULL) + ocaml_guestfs_raise_error (g, "aug_ls"); + + rv = caml_copy_string_array ((const char **) r); + for (i = 0; r[i] != NULL; ++i) free (r[i]); + free (r); + CAMLreturn (rv); +} + diff --git a/perl/Guestfs.xs b/perl/Guestfs.xs index 99eb319..954d7e2 100644 --- a/perl/Guestfs.xs +++ b/perl/Guestfs.xs @@ -623,3 +623,22 @@ aug_load (g) if (guestfs_aug_load (g) == -1) croak ("aug_load: %s", last_error); +void +aug_ls (g, path) + guestfs_h *g; + char *path; +PREINIT: + char **matches; + int i, n; + PPCODE: + matches = guestfs_aug_ls (g, path); + if (matches == NULL) + croak ("aug_ls: %s", last_error); + for (n = 0; matches[n] != NULL; ++n) /**/; + EXTEND (SP, n); + for (i = 0; i < n; ++i) { + PUSHs (sv_2mortal (newSVpv (matches[i], 0))); + free (matches[i]); + } + free (matches); + diff --git a/perl/lib/Sys/Guestfs.pm b/perl/lib/Sys/Guestfs.pm index 9fefb9a..9f3dd5e 100644 --- a/perl/lib/Sys/Guestfs.pm +++ b/perl/lib/Sys/Guestfs.pm @@ -212,6 +212,11 @@ Load files into the tree. See C in the Augeas documentation for the full gory details. +=item @matches = $h->aug_ls (path); + +This is just a shortcut for listing C<$h-Eaug_match> +C and sorting the files into alphabetical order. + =item @matches = $h->aug_match (path); Returns a list of paths which match the path expression C. diff --git a/src/guestfs-actions.c b/src/guestfs-actions.c index 0bb868c..9b9749a 100644 --- a/src/guestfs-actions.c +++ b/src/guestfs-actions.c @@ -1973,3 +1973,81 @@ int guestfs_aug_load (guestfs_h *g) return 0; } +struct aug_ls_rv { + int cb_done; /* flag to indicate callback was called */ + struct guestfs_message_header hdr; + struct guestfs_message_error err; + struct guestfs_aug_ls_ret ret; +}; + +static void aug_ls_cb (guestfs_h *g, void *data, XDR *xdr) +{ + struct aug_ls_rv *rv = (struct aug_ls_rv *) data; + + if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + error (g, "guestfs_aug_ls: failed to parse reply header"); + return; + } + if (rv->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &rv->err)) { + error (g, "guestfs_aug_ls: failed to parse reply error"); + return; + } + goto done; + } + if (!xdr_guestfs_aug_ls_ret (xdr, &rv->ret)) { + error (g, "guestfs_aug_ls: failed to parse reply"); + return; + } + done: + rv->cb_done = 1; + main_loop.main_loop_quit (g); +} + +char **guestfs_aug_ls (guestfs_h *g, + const char *path) +{ + struct guestfs_aug_ls_args args; + struct aug_ls_rv rv; + int serial; + + if (g->state != READY) { + error (g, "guestfs_aug_ls called from the wrong state, %d != READY", + g->state); + return NULL; + } + + memset (&rv, 0, sizeof rv); + + args.path = (char *) path; + serial = dispatch (g, GUESTFS_PROC_AUG_LS, + (xdrproc_t) xdr_guestfs_aug_ls_args, (char *) &args); + if (serial == -1) + return NULL; + + rv.cb_done = 0; + g->reply_cb_internal = aug_ls_cb; + g->reply_cb_internal_data = &rv; + main_loop.main_loop_run (g); + g->reply_cb_internal = NULL; + g->reply_cb_internal_data = NULL; + if (!rv.cb_done) { + error (g, "guestfs_aug_ls failed, see earlier error messages"); + return NULL; + } + + if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_AUG_LS, serial) == -1) + return NULL; + + if (rv.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", rv.err.error); + return NULL; + } + + /* caller will free this, but we need to add a NULL entry */ + rv.ret.matches.matches_val = safe_realloc (g, rv.ret.matches.matches_val, + sizeof (char *) * (rv.ret.matches.matches_len + 1)); + rv.ret.matches.matches_val[rv.ret.matches.matches_len] = NULL; + return rv.ret.matches.matches_val; +} + diff --git a/src/guestfs-actions.h b/src/guestfs-actions.h index eeb6903..497e36b 100644 --- a/src/guestfs-actions.h +++ b/src/guestfs-actions.h @@ -58,3 +58,4 @@ extern int guestfs_aug_mv (guestfs_h *handle, const char *src, const char *dest) extern char **guestfs_aug_match (guestfs_h *handle, const char *path); extern int guestfs_aug_save (guestfs_h *handle); extern int guestfs_aug_load (guestfs_h *handle); +extern char **guestfs_aug_ls (guestfs_h *handle, const char *path); diff --git a/src/guestfs_protocol.c b/src/guestfs_protocol.c index a573728..ed38a8d 100644 --- a/src/guestfs_protocol.c +++ b/src/guestfs_protocol.c @@ -522,6 +522,27 @@ xdr_guestfs_aug_match_ret (XDR *xdrs, guestfs_aug_match_ret *objp) } bool_t +xdr_guestfs_aug_ls_args (XDR *xdrs, guestfs_aug_ls_args *objp) +{ + register int32_t *buf; + + if (!xdr_string (xdrs, &objp->path, ~0)) + return FALSE; + return TRUE; +} + +bool_t +xdr_guestfs_aug_ls_ret (XDR *xdrs, guestfs_aug_ls_ret *objp) +{ + register int32_t *buf; + + if (!xdr_array (xdrs, (char **)&objp->matches.matches_val, (u_int *) &objp->matches.matches_len, ~0, + sizeof (str), (xdrproc_t) xdr_str)) + return FALSE; + return TRUE; +} + +bool_t xdr_guestfs_procedure (XDR *xdrs, guestfs_procedure *objp) { register int32_t *buf; diff --git a/src/guestfs_protocol.h b/src/guestfs_protocol.h index 9412986..a094355 100644 --- a/src/guestfs_protocol.h +++ b/src/guestfs_protocol.h @@ -286,6 +286,19 @@ struct guestfs_aug_match_ret { }; typedef struct guestfs_aug_match_ret guestfs_aug_match_ret; +struct guestfs_aug_ls_args { + char *path; +}; +typedef struct guestfs_aug_ls_args guestfs_aug_ls_args; + +struct guestfs_aug_ls_ret { + struct { + u_int matches_len; + str *matches_val; + } matches; +}; +typedef struct guestfs_aug_ls_ret guestfs_aug_ls_ret; + enum guestfs_procedure { GUESTFS_PROC_MOUNT = 1, GUESTFS_PROC_SYNC = 2, @@ -314,7 +327,8 @@ enum guestfs_procedure { GUESTFS_PROC_AUG_MATCH = 24, GUESTFS_PROC_AUG_SAVE = 25, GUESTFS_PROC_AUG_LOAD = 27, - GUESTFS_PROC_dummy = 27 + 1, + GUESTFS_PROC_AUG_LS = 28, + GUESTFS_PROC_dummy = 28 + 1, }; typedef enum guestfs_procedure guestfs_procedure; #define GUESTFS_MESSAGE_MAX 4194304 @@ -391,6 +405,8 @@ extern bool_t xdr_guestfs_aug_rm_ret (XDR *, guestfs_aug_rm_ret*); extern bool_t xdr_guestfs_aug_mv_args (XDR *, guestfs_aug_mv_args*); extern bool_t xdr_guestfs_aug_match_args (XDR *, guestfs_aug_match_args*); extern bool_t xdr_guestfs_aug_match_ret (XDR *, guestfs_aug_match_ret*); +extern bool_t xdr_guestfs_aug_ls_args (XDR *, guestfs_aug_ls_args*); +extern bool_t xdr_guestfs_aug_ls_ret (XDR *, guestfs_aug_ls_ret*); extern bool_t xdr_guestfs_procedure (XDR *, guestfs_procedure*); extern bool_t xdr_guestfs_message_direction (XDR *, guestfs_message_direction*); extern bool_t xdr_guestfs_message_status (XDR *, guestfs_message_status*); @@ -437,6 +453,8 @@ extern bool_t xdr_guestfs_aug_rm_ret (); extern bool_t xdr_guestfs_aug_mv_args (); extern bool_t xdr_guestfs_aug_match_args (); extern bool_t xdr_guestfs_aug_match_ret (); +extern bool_t xdr_guestfs_aug_ls_args (); +extern bool_t xdr_guestfs_aug_ls_ret (); extern bool_t xdr_guestfs_procedure (); extern bool_t xdr_guestfs_message_direction (); extern bool_t xdr_guestfs_message_status (); diff --git a/src/guestfs_protocol.x b/src/guestfs_protocol.x index eb3045e..8e3d2a9 100644 --- a/src/guestfs_protocol.x +++ b/src/guestfs_protocol.x @@ -223,6 +223,14 @@ struct guestfs_aug_match_ret { str matches<>; }; +struct guestfs_aug_ls_args { + string path<>; +}; + +struct guestfs_aug_ls_ret { + str matches<>; +}; + enum guestfs_procedure { GUESTFS_PROC_MOUNT = 1, GUESTFS_PROC_SYNC = 2, @@ -251,6 +259,7 @@ enum guestfs_procedure { GUESTFS_PROC_AUG_MATCH = 24, GUESTFS_PROC_AUG_SAVE = 25, GUESTFS_PROC_AUG_LOAD = 27, + GUESTFS_PROC_AUG_LS = 28, GUESTFS_PROC_dummy }; -- 1.8.3.1