diff options
-rw-r--r-- | daemon/actions.h | 7 | ||||
-rw-r--r-- | daemon/stubs.c | 181 | ||||
-rw-r--r-- | fish/cmds.c | 153 | ||||
-rw-r--r-- | guestfish-actions.pod | 50 | ||||
-rw-r--r-- | guestfs-actions.pod | 74 | ||||
-rw-r--r-- | ocaml/guestfs.ml | 7 | ||||
-rw-r--r-- | ocaml/guestfs.mli | 21 | ||||
-rw-r--r-- | ocaml/guestfs_c_actions.c | 164 | ||||
-rw-r--r-- | perl/Guestfs.xs | 59 | ||||
-rw-r--r-- | perl/lib/Sys/Guestfs.pm | 36 | ||||
-rw-r--r-- | src/guestfs-actions.c | 489 | ||||
-rw-r--r-- | src/guestfs-actions.h | 7 | ||||
-rw-r--r-- | src/guestfs_protocol.c | 76 | ||||
-rw-r--r-- | src/guestfs_protocol.h | 61 | ||||
-rw-r--r-- | src/guestfs_protocol.x | 38 |
15 files changed, 1422 insertions, 1 deletions
diff --git a/daemon/actions.h b/daemon/actions.h index a2edc762..1b35cad1 100644 --- a/daemon/actions.h +++ b/daemon/actions.h @@ -49,3 +49,10 @@ 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); +extern int do_rm (const char *path); +extern int do_rmdir (const char *path); +extern int do_rm_rf (const char *path); +extern int do_mkdir (const char *path); +extern int do_mkdir_p (const char *path); +extern int do_chmod (int mode, const char *path); +extern int do_chown (int owner, int group, const char *path); diff --git a/daemon/stubs.c b/daemon/stubs.c index eb398281..1227fa88 100644 --- a/daemon/stubs.c +++ b/daemon/stubs.c @@ -606,6 +606,166 @@ static void aug_ls_stub (XDR *xdr_in) free_strings (r); } +static void rm_stub (XDR *xdr_in) +{ + int r; + struct guestfs_rm_args args; + const char *path; + + memset (&args, 0, sizeof args); + + if (!xdr_guestfs_rm_args (xdr_in, &args)) { + reply_with_error ("%s: daemon failed to decode procedure arguments", "rm"); + return; + } + path = args.path; + + r = do_rm (path); + if (r == -1) + /* do_rm has already called reply_with_error, so just return */ + return; + + reply (NULL, NULL); +} + +static void rmdir_stub (XDR *xdr_in) +{ + int r; + struct guestfs_rmdir_args args; + const char *path; + + memset (&args, 0, sizeof args); + + if (!xdr_guestfs_rmdir_args (xdr_in, &args)) { + reply_with_error ("%s: daemon failed to decode procedure arguments", "rmdir"); + return; + } + path = args.path; + + r = do_rmdir (path); + if (r == -1) + /* do_rmdir has already called reply_with_error, so just return */ + return; + + reply (NULL, NULL); +} + +static void rm_rf_stub (XDR *xdr_in) +{ + int r; + struct guestfs_rm_rf_args args; + const char *path; + + memset (&args, 0, sizeof args); + + if (!xdr_guestfs_rm_rf_args (xdr_in, &args)) { + reply_with_error ("%s: daemon failed to decode procedure arguments", "rm_rf"); + return; + } + path = args.path; + + r = do_rm_rf (path); + if (r == -1) + /* do_rm_rf has already called reply_with_error, so just return */ + return; + + reply (NULL, NULL); +} + +static void mkdir_stub (XDR *xdr_in) +{ + int r; + struct guestfs_mkdir_args args; + const char *path; + + memset (&args, 0, sizeof args); + + if (!xdr_guestfs_mkdir_args (xdr_in, &args)) { + reply_with_error ("%s: daemon failed to decode procedure arguments", "mkdir"); + return; + } + path = args.path; + + r = do_mkdir (path); + if (r == -1) + /* do_mkdir has already called reply_with_error, so just return */ + return; + + reply (NULL, NULL); +} + +static void mkdir_p_stub (XDR *xdr_in) +{ + int r; + struct guestfs_mkdir_p_args args; + const char *path; + + memset (&args, 0, sizeof args); + + if (!xdr_guestfs_mkdir_p_args (xdr_in, &args)) { + reply_with_error ("%s: daemon failed to decode procedure arguments", "mkdir_p"); + return; + } + path = args.path; + + r = do_mkdir_p (path); + if (r == -1) + /* do_mkdir_p has already called reply_with_error, so just return */ + return; + + reply (NULL, NULL); +} + +static void chmod_stub (XDR *xdr_in) +{ + int r; + struct guestfs_chmod_args args; + int mode; + const char *path; + + memset (&args, 0, sizeof args); + + if (!xdr_guestfs_chmod_args (xdr_in, &args)) { + reply_with_error ("%s: daemon failed to decode procedure arguments", "chmod"); + return; + } + mode = args.mode; + path = args.path; + + r = do_chmod (mode, path); + if (r == -1) + /* do_chmod has already called reply_with_error, so just return */ + return; + + reply (NULL, NULL); +} + +static void chown_stub (XDR *xdr_in) +{ + int r; + struct guestfs_chown_args args; + int owner; + int group; + const char *path; + + memset (&args, 0, sizeof args); + + if (!xdr_guestfs_chown_args (xdr_in, &args)) { + reply_with_error ("%s: daemon failed to decode procedure arguments", "chown"); + return; + } + owner = args.owner; + group = args.group; + path = args.path; + + r = do_chown (owner, group, path); + if (r == -1) + /* do_chown has already called reply_with_error, so just return */ + return; + + reply (NULL, NULL); +} + void dispatch_incoming_message (XDR *xdr_in) { switch (proc_nr) { @@ -693,6 +853,27 @@ void dispatch_incoming_message (XDR *xdr_in) case GUESTFS_PROC_AUG_LS: aug_ls_stub (xdr_in); break; + case GUESTFS_PROC_RM: + rm_stub (xdr_in); + break; + case GUESTFS_PROC_RMDIR: + rmdir_stub (xdr_in); + break; + case GUESTFS_PROC_RM_RF: + rm_rf_stub (xdr_in); + break; + case GUESTFS_PROC_MKDIR: + mkdir_stub (xdr_in); + break; + case GUESTFS_PROC_MKDIR_P: + mkdir_p_stub (xdr_in); + break; + case GUESTFS_PROC_CHMOD: + chmod_stub (xdr_in); + break; + case GUESTFS_PROC_CHOWN: + chown_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 f0c0458e..cef38ccc 100644 --- a/fish/cmds.c +++ b/fish/cmds.c @@ -47,6 +47,8 @@ void list_commands (void) printf ("%-20s %s\n", "aug-save", "write all pending Augeas changes to disk"); printf ("%-20s %s\n", "aug-set", "set Augeas path to value"); printf ("%-20s %s\n", "cat", "list the contents of a file"); + printf ("%-20s %s\n", "chmod", "change file mode"); + printf ("%-20s %s\n", "chown", "change file owner and group"); printf ("%-20s %s\n", "config", "add qemu parameters"); printf ("%-20s %s\n", "get-autosync", "get autosync mode"); printf ("%-20s %s\n", "get-path", "get the search path"); @@ -59,10 +61,15 @@ void list_commands (void) printf ("%-20s %s\n", "ls", "list the files in a directory"); printf ("%-20s %s\n", "lvs", "list the LVM logical volumes (LVs)"); printf ("%-20s %s\n", "lvs-full", "list the LVM logical volumes (LVs)"); + printf ("%-20s %s\n", "mkdir", "create a directory"); + printf ("%-20s %s\n", "mkdir-p", "create a directory and parents"); printf ("%-20s %s\n", "mount", "mount a guest disk at a position in the filesystem"); printf ("%-20s %s\n", "pvs", "list the LVM physical volumes (PVs)"); printf ("%-20s %s\n", "pvs-full", "list the LVM physical volumes (PVs)"); printf ("%-20s %s\n", "read-lines", "read file as lines"); + printf ("%-20s %s\n", "rm", "remove a file"); + printf ("%-20s %s\n", "rm-rf", "remove a file or directory recursively"); + printf ("%-20s %s\n", "rmdir", "remove a directory"); printf ("%-20s %s\n", "set-autosync", "set autosync mode"); printf ("%-20s %s\n", "set-path", "set the search path"); printf ("%-20s %s\n", "set-verbose", "set verbose mode"); @@ -192,6 +199,27 @@ void display_command (const char *cmd) if (strcasecmp (cmd, "aug_ls") == 0 || strcasecmp (cmd, "aug-ls") == 0) pod2text ("aug-ls - list Augeas nodes under a path", " aug-ls <path>\n\nThis is just a shortcut for listing C<aug_match>\nC<path/*> and sorting the resulting nodes into alphabetical order."); else + if (strcasecmp (cmd, "rm") == 0) + pod2text ("rm - remove a file", " rm <path>\n\nRemove the single file C<path>."); + else + if (strcasecmp (cmd, "rmdir") == 0) + pod2text ("rmdir - remove a directory", " rmdir <path>\n\nRemove the single directory C<path>."); + else + if (strcasecmp (cmd, "rm_rf") == 0 || strcasecmp (cmd, "rm-rf") == 0) + pod2text ("rm-rf - remove a file or directory recursively", " rm-rf <path>\n\nRemove the file or directory C<path>, recursively removing the\ncontents if its a directory. This is like the C<rm -rf> shell\ncommand."); + else + if (strcasecmp (cmd, "mkdir") == 0) + pod2text ("mkdir - create a directory", " mkdir <path>\n\nCreate a directory named C<path>."); + else + if (strcasecmp (cmd, "mkdir_p") == 0 || strcasecmp (cmd, "mkdir-p") == 0) + pod2text ("mkdir-p - create a directory and parents", " mkdir-p <path>\n\nCreate a directory named C<path>, creating any parent directories\nas necessary. This is like the C<mkdir -p> shell command."); + else + if (strcasecmp (cmd, "chmod") == 0) + pod2text ("chmod - change file mode", " chmod <mode> <path>\n\nChange the mode (permissions) of C<path> to C<mode>. Only\nnumeric modes are supported."); + else + if (strcasecmp (cmd, "chown") == 0) + pod2text ("chown - change file owner and group", " chown <owner> <group> <path>\n\nChange the file owner to C<owner> and group to C<group>.\n\nOnly numeric uid and gid are supported. If you want to use\nnames, you will need to locate and parse the password file\nyourself (Augeas support makes this relatively easy)."); + else display_builtin_command (cmd); } @@ -888,6 +916,110 @@ static int run_aug_ls (const char *cmd, int argc, char *argv[]) return 0; } +static int run_rm (const char *cmd, int argc, char *argv[]) +{ + int 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_rm (g, path); + return r; +} + +static int run_rmdir (const char *cmd, int argc, char *argv[]) +{ + int 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_rmdir (g, path); + return r; +} + +static int run_rm_rf (const char *cmd, int argc, char *argv[]) +{ + int 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_rm_rf (g, path); + return r; +} + +static int run_mkdir (const char *cmd, int argc, char *argv[]) +{ + int 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_mkdir (g, path); + return r; +} + +static int run_mkdir_p (const char *cmd, int argc, char *argv[]) +{ + int 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_mkdir_p (g, path); + return r; +} + +static int run_chmod (const char *cmd, int argc, char *argv[]) +{ + int r; + int mode; + const char *path; + if (argc != 2) { + fprintf (stderr, "%s should have 2 parameter(s)\n", cmd); + fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd); + return -1; + } + mode = atoi (argv[0]); + path = argv[1]; + r = guestfs_chmod (g, mode, path); + return r; +} + +static int run_chown (const char *cmd, int argc, char *argv[]) +{ + int r; + int owner; + int group; + const char *path; + if (argc != 3) { + fprintf (stderr, "%s should have 3 parameter(s)\n", cmd); + fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd); + return -1; + } + owner = atoi (argv[0]); + group = atoi (argv[1]); + path = argv[2]; + r = guestfs_chown (g, owner, group, path); + return r; +} + int run_action (const char *cmd, int argc, char *argv[]) { if (strcasecmp (cmd, "launch") == 0 || strcasecmp (cmd, "run") == 0) @@ -1007,6 +1139,27 @@ int run_action (const char *cmd, int argc, char *argv[]) if (strcasecmp (cmd, "aug_ls") == 0 || strcasecmp (cmd, "aug-ls") == 0) return run_aug_ls (cmd, argc, argv); else + if (strcasecmp (cmd, "rm") == 0) + return run_rm (cmd, argc, argv); + else + if (strcasecmp (cmd, "rmdir") == 0) + return run_rmdir (cmd, argc, argv); + else + if (strcasecmp (cmd, "rm_rf") == 0 || strcasecmp (cmd, "rm-rf") == 0) + return run_rm_rf (cmd, argc, argv); + else + if (strcasecmp (cmd, "mkdir") == 0) + return run_mkdir (cmd, argc, argv); + else + if (strcasecmp (cmd, "mkdir_p") == 0 || strcasecmp (cmd, "mkdir-p") == 0) + return run_mkdir_p (cmd, argc, argv); + else + if (strcasecmp (cmd, "chmod") == 0) + return run_chmod (cmd, argc, argv); + else + if (strcasecmp (cmd, "chown") == 0) + return run_chown (cmd, argc, argv); + else { fprintf (stderr, "%s: unknown command\n", cmd); return -1; diff --git a/guestfish-actions.pod b/guestfish-actions.pod index 63122886..d47e9bf9 100644 --- a/guestfish-actions.pod +++ b/guestfish-actions.pod @@ -193,6 +193,23 @@ Note that this function cannot correctly handle binary files as end of string). For those you need to use the C<read_file> function which has a more complex interface. +=head2 chmod + + chmod mode path + +Change the mode (permissions) of C<path> to C<mode>. Only +numeric modes are supported. + +=head2 chown + + chown owner group path + +Change the file owner to C<owner> and group to C<group>. + +Only numeric uid and gid are supported. If you want to use +names, you will need to locate and parse the password file +yourself (Augeas support makes this relatively easy). + =head2 config config qemuparam qemuvalue @@ -302,6 +319,19 @@ See also C<lvs_full>. List all the logical volumes detected. This is the equivalent of the L<lvs(8)> command. The "full" version includes all fields. +=head2 mkdir + + mkdir path + +Create a directory named C<path>. + +=head2 mkdir-p + + mkdir-p path + +Create a directory named C<path>, creating any parent directories +as necessary. This is like the C<mkdir -p> shell command. + =head2 mount mount device mountpoint @@ -356,6 +386,26 @@ Note that this function cannot correctly handle binary files as end of line). For those you need to use the C<read_file> function which has a more complex interface. +=head2 rm + + rm path + +Remove the single file C<path>. + +=head2 rm-rf + + rm-rf path + +Remove the file or directory C<path>, recursively removing the +contents if its a directory. This is like the C<rm -rf> shell +command. + +=head2 rmdir + + rmdir path + +Remove the single directory C<path>. + =head2 set-autosync | autosync set-autosync true|false diff --git a/guestfs-actions.pod b/guestfs-actions.pod index 4b1ad4b6..069ea8f7 100644 --- a/guestfs-actions.pod +++ b/guestfs-actions.pod @@ -257,6 +257,32 @@ Because of the message protocol, there is a transfer limit of somewhere between 2MB and 4MB. To transfer large files you should use FTP. +=head2 guestfs_chmod + + int guestfs_chmod (guestfs_h *handle, + int mode, + const char *path); + +Change the mode (permissions) of C<path> to C<mode>. Only +numeric modes are supported. + +This function returns 0 on success or -1 on error. + +=head2 guestfs_chown + + int guestfs_chown (guestfs_h *handle, + int owner, + int group, + const char *path); + +Change the file owner to C<owner> and group to C<group>. + +Only numeric uid and gid are supported. If you want to use +names, you will need to locate and parse the password file +yourself (Augeas support makes this relatively easy). + +This function returns 0 on success or -1 on error. + =head2 guestfs_config int guestfs_config (guestfs_h *handle, @@ -405,6 +431,25 @@ of the L<lvs(8)> command. The "full" version includes all fields. This function returns a C<struct guestfs_lvm_lv_list *>. I<The caller must call C<guestfs_free_lvm_lv_list> after use>. +=head2 guestfs_mkdir + + int guestfs_mkdir (guestfs_h *handle, + const char *path); + +Create a directory named C<path>. + +This function returns 0 on success or -1 on error. + +=head2 guestfs_mkdir_p + + int guestfs_mkdir_p (guestfs_h *handle, + const char *path); + +Create a directory named C<path>, creating any parent directories +as necessary. This is like the C<mkdir -p> shell command. + +This function returns 0 on success or -1 on error. + =head2 guestfs_mount int guestfs_mount (guestfs_h *handle, @@ -475,6 +520,35 @@ This function returns a NULL-terminated array of strings (like L<environ(3)>), or NULL if there was an error. I<The caller must free the strings and the array after use>. +=head2 guestfs_rm + + int guestfs_rm (guestfs_h *handle, + const char *path); + +Remove the single file C<path>. + +This function returns 0 on success or -1 on error. + +=head2 guestfs_rm_rf + + int guestfs_rm_rf (guestfs_h *handle, + const char *path); + +Remove the file or directory C<path>, recursively removing the +contents if its a directory. This is like the C<rm -rf> shell +command. + +This function returns 0 on success or -1 on error. + +=head2 guestfs_rmdir + + int guestfs_rmdir (guestfs_h *handle, + const char *path); + +Remove the single directory C<path>. + +This function returns 0 on success or -1 on error. + =head2 guestfs_set_autosync int guestfs_set_autosync (guestfs_h *handle, diff --git a/ocaml/guestfs.ml b/ocaml/guestfs.ml index fba005f6..32a6b82a 100644 --- a/ocaml/guestfs.ml +++ b/ocaml/guestfs.ml @@ -125,3 +125,10 @@ 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" +external rm : t -> string -> unit = "ocaml_guestfs_rm" +external rmdir : t -> string -> unit = "ocaml_guestfs_rmdir" +external rm_rf : t -> string -> unit = "ocaml_guestfs_rm_rf" +external mkdir : t -> string -> unit = "ocaml_guestfs_mkdir" +external mkdir_p : t -> string -> unit = "ocaml_guestfs_mkdir_p" +external chmod : t -> int -> string -> unit = "ocaml_guestfs_chmod" +external chown : t -> int -> int -> string -> unit = "ocaml_guestfs_chown" diff --git a/ocaml/guestfs.mli b/ocaml/guestfs.mli index 4981eb1e..ecf86f11 100644 --- a/ocaml/guestfs.mli +++ b/ocaml/guestfs.mli @@ -214,3 +214,24 @@ val aug_load : t -> unit val aug_ls : t -> string -> string array (** list Augeas nodes under a path *) +val rm : t -> string -> unit +(** remove a file *) + +val rmdir : t -> string -> unit +(** remove a directory *) + +val rm_rf : t -> string -> unit +(** remove a file or directory recursively *) + +val mkdir : t -> string -> unit +(** create a directory *) + +val mkdir_p : t -> string -> unit +(** create a directory and parents *) + +val chmod : t -> int -> string -> unit +(** change file mode *) + +val chown : t -> int -> int -> string -> unit +(** change file owner and group *) + diff --git a/ocaml/guestfs_c_actions.c b/ocaml/guestfs_c_actions.c index f26226c0..6675cf8c 100644 --- a/ocaml/guestfs_c_actions.c +++ b/ocaml/guestfs_c_actions.c @@ -1183,3 +1183,167 @@ ocaml_guestfs_aug_ls (value gv, value pathv) CAMLreturn (rv); } +CAMLprim value +ocaml_guestfs_rm (value gv, value pathv) +{ + CAMLparam2 (gv, pathv); + CAMLlocal1 (rv); + + guestfs_h *g = Guestfs_val (gv); + if (g == NULL) + caml_failwith ("rm: used handle after closing it"); + + const char *path = String_val (pathv); + int r; + + caml_enter_blocking_section (); + r = guestfs_rm (g, path); + caml_leave_blocking_section (); + if (r == -1) + ocaml_guestfs_raise_error (g, "rm"); + + rv = Val_unit; + CAMLreturn (rv); +} + +CAMLprim value +ocaml_guestfs_rmdir (value gv, value pathv) +{ + CAMLparam2 (gv, pathv); + CAMLlocal1 (rv); + + guestfs_h *g = Guestfs_val (gv); + if (g == NULL) + caml_failwith ("rmdir: used handle after closing it"); + + const char *path = String_val (pathv); + int r; + + caml_enter_blocking_section (); + r = guestfs_rmdir (g, path); + caml_leave_blocking_section (); + if (r == -1) + ocaml_guestfs_raise_error (g, "rmdir"); + + rv = Val_unit; + CAMLreturn (rv); +} + +CAMLprim value +ocaml_guestfs_rm_rf (value gv, value pathv) +{ + CAMLparam2 (gv, pathv); + CAMLlocal1 (rv); + + guestfs_h *g = Guestfs_val (gv); + if (g == NULL) + caml_failwith ("rm_rf: used handle after closing it"); + + const char *path = String_val (pathv); + int r; + + caml_enter_blocking_section (); + r = guestfs_rm_rf (g, path); + caml_leave_blocking_section (); + if (r == -1) + ocaml_guestfs_raise_error (g, "rm_rf"); + + rv = Val_unit; + CAMLreturn (rv); +} + +CAMLprim value +ocaml_guestfs_mkdir (value gv, value pathv) +{ + CAMLparam2 (gv, pathv); + CAMLlocal1 (rv); + + guestfs_h *g = Guestfs_val (gv); + if (g == NULL) + caml_failwith ("mkdir: used handle after closing it"); + + const char *path = String_val (pathv); + int r; + + caml_enter_blocking_section (); + r = guestfs_mkdir (g, path); + caml_leave_blocking_section (); + if (r == -1) + ocaml_guestfs_raise_error (g, "mkdir"); + + rv = Val_unit; + CAMLreturn (rv); +} + +CAMLprim value +ocaml_guestfs_mkdir_p (value gv, value pathv) +{ + CAMLparam2 (gv, pathv); + CAMLlocal1 (rv); + + guestfs_h *g = Guestfs_val (gv); + if (g == NULL) + caml_failwith ("mkdir_p: used handle after closing it"); + + const char *path = String_val (pathv); + int r; + + caml_enter_blocking_section (); + r = guestfs_mkdir_p (g, path); + caml_leave_blocking_section (); + if (r == -1) + ocaml_guestfs_raise_error (g, "mkdir_p"); + + rv = Val_unit; + CAMLreturn (rv); +} + +CAMLprim value +ocaml_guestfs_chmod (value gv, value modev, value pathv) +{ + CAMLparam3 (gv, modev, pathv); + CAMLlocal1 (rv); + + guestfs_h *g = Guestfs_val (gv); + if (g == NULL) + caml_failwith ("chmod: used handle after closing it"); + + int mode = Int_val (modev); + const char *path = String_val (pathv); + int r; + + caml_enter_blocking_section (); + r = guestfs_chmod (g, mode, path); + caml_leave_blocking_section (); + if (r == -1) + ocaml_guestfs_raise_error (g, "chmod"); + + rv = Val_unit; + CAMLreturn (rv); +} + +CAMLprim value +ocaml_guestfs_chown (value gv, value ownerv, value groupv, value pathv) +{ + CAMLparam4 (gv, ownerv, groupv, pathv); + CAMLlocal1 (rv); + + guestfs_h *g = Guestfs_val (gv); + if (g == NULL) + caml_failwith ("chown: used handle after closing it"); + + int owner = Int_val (ownerv); + int group = Int_val (groupv); + const char *path = String_val (pathv); + int r; + + caml_enter_blocking_section (); + r = guestfs_chown (g, owner, group, path); + caml_leave_blocking_section (); + if (r == -1) + ocaml_guestfs_raise_error (g, "chown"); + + rv = Val_unit; + CAMLreturn (rv); +} + diff --git a/perl/Guestfs.xs b/perl/Guestfs.xs index 954d7e2e..d5f1da6b 100644 --- a/perl/Guestfs.xs +++ b/perl/Guestfs.xs @@ -642,3 +642,62 @@ PREINIT: } free (matches); +void +rm (g, path) + guestfs_h *g; + char *path; + PPCODE: + if (guestfs_rm (g, path) == -1) + croak ("rm: %s", last_error); + +void +rmdir (g, path) + guestfs_h *g; + char *path; + PPCODE: + if (guestfs_rmdir (g, path) == -1) + croak ("rmdir: %s", last_error); + +void +rm_rf (g, path) + guestfs_h *g; + char *path; + PPCODE: + if (guestfs_rm_rf (g, path) == -1) + croak ("rm_rf: %s", last_error); + +void +mkdir (g, path) + guestfs_h *g; + char *path; + PPCODE: + if (guestfs_mkdir (g, path) == -1) + croak ("mkdir: %s", last_error); + +void +mkdir_p (g, path) + guestfs_h *g; + char *path; + PPCODE: + if (guestfs_mkdir_p (g, path) == -1) + croak ("mkdir_p: %s", last_error); + +void +chmod (g, mode, path) + guestfs_h *g; + int mode; + char *path; + PPCODE: + if (guestfs_chmod (g, mode, path) == -1) + croak ("chmod: %s", last_error); + +void +chown (g, owner, group, path) + guestfs_h *g; + int owner; + int group; + char *path; + PPCODE: + if (guestfs_chown (g, owner, group, path) == -1) + croak ("chown: %s", last_error); + diff --git a/perl/lib/Sys/Guestfs.pm b/perl/lib/Sys/Guestfs.pm index d3027f35..50f5d750 100644 --- a/perl/lib/Sys/Guestfs.pm +++ b/perl/lib/Sys/Guestfs.pm @@ -258,6 +258,19 @@ Because of the message protocol, there is a transfer limit of somewhere between 2MB and 4MB. To transfer large files you should use FTP. +=item $h->chmod (mode, path); + +Change the mode (permissions) of C<path> to C<mode>. Only +numeric modes are supported. + +=item $h->chown (owner, group, path); + +Change the file owner to C<owner> and group to C<group>. + +Only numeric uid and gid are supported. If you want to use +names, you will need to locate and parse the password file +yourself (Augeas support makes this relatively easy). + =item $h->config (qemuparam, qemuvalue); This can be used to add arbitrary qemu command line parameters @@ -343,6 +356,15 @@ See also C<$h-E<gt>lvs_full>. List all the logical volumes detected. This is the equivalent of the L<lvs(8)> command. The "full" version includes all fields. +=item $h->mkdir (path); + +Create a directory named C<path>. + +=item $h->mkdir_p (path); + +Create a directory named C<path>, creating any parent directories +as necessary. This is like the C<mkdir -p> shell command. + =item $h->mount (device, mountpoint); Mount a guest disk at a position in the filesystem. Block devices @@ -389,6 +411,20 @@ Note that this function cannot correctly handle binary files as end of line). For those you need to use the C<$h-E<gt>read_file> function which has a more complex interface. +=item $h->rm (path); + +Remove the single file C<path>. + +=item $h->rm_rf (path); + +Remove the file or directory C<path>, recursively removing the +contents if its a directory. This is like the C<rm -rf> shell +command. + +=item $h->rmdir (path); + +Remove the single directory C<path>. + =item $h->set_autosync (autosync); If C<autosync> is true, this enables autosync. Libguestfs will make a diff --git a/src/guestfs-actions.c b/src/guestfs-actions.c index 9b9749a1..25892cd0 100644 --- a/src/guestfs-actions.c +++ b/src/guestfs-actions.c @@ -2051,3 +2051,492 @@ char **guestfs_aug_ls (guestfs_h *g, return rv.ret.matches.matches_val; } +struct rm_rv { + int cb_done; /* flag to indicate callback was called */ + struct guestfs_message_header hdr; + struct guestfs_message_error err; +}; + +static void rm_cb (guestfs_h *g, void *data, XDR *xdr) +{ + struct rm_rv *rv = (struct rm_rv *) data; + + if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + error (g, "guestfs_rm: failed to parse reply header"); + return; + } + if (rv->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &rv->err)) { + error (g, "guestfs_rm: failed to parse reply error"); + return; + } + goto done; + } + done: + rv->cb_done = 1; + main_loop.main_loop_quit (g); +} + +int guestfs_rm (guestfs_h *g, + const char *path) +{ + struct guestfs_rm_args args; + struct rm_rv rv; + int serial; + + if (g->state != READY) { + error (g, "guestfs_rm called from the wrong state, %d != READY", + g->state); + return -1; + } + + memset (&rv, 0, sizeof rv); + + args.path = (char *) path; + serial = dispatch (g, GUESTFS_PROC_RM, + (xdrproc_t) xdr_guestfs_rm_args, (char *) &args); + if (serial == -1) + return -1; + + rv.cb_done = 0; + g->reply_cb_internal = rm_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_rm failed, see earlier error messages"); + return -1; + } + + if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_RM, serial) == -1) + return -1; + + if (rv.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", rv.err.error); + return -1; + } + + return 0; +} + +struct rmdir_rv { + int cb_done; /* flag to indicate callback was called */ + struct guestfs_message_header hdr; + struct guestfs_message_error err; +}; + +static void rmdir_cb (guestfs_h *g, void *data, XDR *xdr) +{ + struct rmdir_rv *rv = (struct rmdir_rv *) data; + + if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + error (g, "guestfs_rmdir: failed to parse reply header"); + return; + } + if (rv->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &rv->err)) { + error (g, "guestfs_rmdir: failed to parse reply error"); + return; + } + goto done; + } + done: + rv->cb_done = 1; + main_loop.main_loop_quit (g); +} + +int guestfs_rmdir (guestfs_h *g, + const char *path) +{ + struct guestfs_rmdir_args args; + struct rmdir_rv rv; + int serial; + + if (g->state != READY) { + error (g, "guestfs_rmdir called from the wrong state, %d != READY", + g->state); + return -1; + } + + memset (&rv, 0, sizeof rv); + + args.path = (char *) path; + serial = dispatch (g, GUESTFS_PROC_RMDIR, + (xdrproc_t) xdr_guestfs_rmdir_args, (char *) &args); + if (serial == -1) + return -1; + + rv.cb_done = 0; + g->reply_cb_internal = rmdir_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_rmdir failed, see earlier error messages"); + return -1; + } + + if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_RMDIR, serial) == -1) + return -1; + + if (rv.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", rv.err.error); + return -1; + } + + return 0; +} + +struct rm_rf_rv { + int cb_done; /* flag to indicate callback was called */ + struct guestfs_message_header hdr; + struct guestfs_message_error err; +}; + +static void rm_rf_cb (guestfs_h *g, void *data, XDR *xdr) +{ + struct rm_rf_rv *rv = (struct rm_rf_rv *) data; + + if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + error (g, "guestfs_rm_rf: failed to parse reply header"); + return; + } + if (rv->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &rv->err)) { + error (g, "guestfs_rm_rf: failed to parse reply error"); + return; + } + goto done; + } + done: + rv->cb_done = 1; + main_loop.main_loop_quit (g); +} + +int guestfs_rm_rf (guestfs_h *g, + const char *path) +{ + struct guestfs_rm_rf_args args; + struct rm_rf_rv rv; + int serial; + + if (g->state != READY) { + error (g, "guestfs_rm_rf called from the wrong state, %d != READY", + g->state); + return -1; + } + + memset (&rv, 0, sizeof rv); + + args.path = (char *) path; + serial = dispatch (g, GUESTFS_PROC_RM_RF, + (xdrproc_t) xdr_guestfs_rm_rf_args, (char *) &args); + if (serial == -1) + return -1; + + rv.cb_done = 0; + g->reply_cb_internal = rm_rf_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_rm_rf failed, see earlier error messages"); + return -1; + } + + if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_RM_RF, serial) == -1) + return -1; + + if (rv.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", rv.err.error); + return -1; + } + + return 0; +} + +struct mkdir_rv { + int cb_done; /* flag to indicate callback was called */ + struct guestfs_message_header hdr; + struct guestfs_message_error err; +}; + +static void mkdir_cb (guestfs_h *g, void *data, XDR *xdr) +{ + struct mkdir_rv *rv = (struct mkdir_rv *) data; + + if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + error (g, "guestfs_mkdir: failed to parse reply header"); + return; + } + if (rv->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &rv->err)) { + error (g, "guestfs_mkdir: failed to parse reply error"); + return; + } + goto done; + } + done: + rv->cb_done = 1; + main_loop.main_loop_quit (g); +} + +int guestfs_mkdir (guestfs_h *g, + const char *path) +{ + struct guestfs_mkdir_args args; + struct mkdir_rv rv; + int serial; + + if (g->state != READY) { + error (g, "guestfs_mkdir called from the wrong state, %d != READY", + g->state); + return -1; + } + + memset (&rv, 0, sizeof rv); + + args.path = (char *) path; + serial = dispatch (g, GUESTFS_PROC_MKDIR, + (xdrproc_t) xdr_guestfs_mkdir_args, (char *) &args); + if (serial == -1) + return -1; + + rv.cb_done = 0; + g->reply_cb_internal = mkdir_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_mkdir failed, see earlier error messages"); + return -1; + } + + if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_MKDIR, serial) == -1) + return -1; + + if (rv.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", rv.err.error); + return -1; + } + + return 0; +} + +struct mkdir_p_rv { + int cb_done; /* flag to indicate callback was called */ + struct guestfs_message_header hdr; + struct guestfs_message_error err; +}; + +static void mkdir_p_cb (guestfs_h *g, void *data, XDR *xdr) +{ + struct mkdir_p_rv *rv = (struct mkdir_p_rv *) data; + + if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + error (g, "guestfs_mkdir_p: failed to parse reply header"); + return; + } + if (rv->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &rv->err)) { + error (g, "guestfs_mkdir_p: failed to parse reply error"); + return; + } + goto done; + } + done: + rv->cb_done = 1; + main_loop.main_loop_quit (g); +} + +int guestfs_mkdir_p (guestfs_h *g, + const char *path) +{ + struct guestfs_mkdir_p_args args; + struct mkdir_p_rv rv; + int serial; + + if (g->state != READY) { + error (g, "guestfs_mkdir_p called from the wrong state, %d != READY", + g->state); + return -1; + } + + memset (&rv, 0, sizeof rv); + + args.path = (char *) path; + serial = dispatch (g, GUESTFS_PROC_MKDIR_P, + (xdrproc_t) xdr_guestfs_mkdir_p_args, (char *) &args); + if (serial == -1) + return -1; + + rv.cb_done = 0; + g->reply_cb_internal = mkdir_p_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_mkdir_p failed, see earlier error messages"); + return -1; + } + + if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_MKDIR_P, serial) == -1) + return -1; + + if (rv.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", rv.err.error); + return -1; + } + + return 0; +} + +struct chmod_rv { + int cb_done; /* flag to indicate callback was called */ + struct guestfs_message_header hdr; + struct guestfs_message_error err; +}; + +static void chmod_cb (guestfs_h *g, void *data, XDR *xdr) +{ + struct chmod_rv *rv = (struct chmod_rv *) data; + + if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + error (g, "guestfs_chmod: failed to parse reply header"); + return; + } + if (rv->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &rv->err)) { + error (g, "guestfs_chmod: failed to parse reply error"); + return; + } + goto done; + } + done: + rv->cb_done = 1; + main_loop.main_loop_quit (g); +} + +int guestfs_chmod (guestfs_h *g, + int mode, + const char *path) +{ + struct guestfs_chmod_args args; + struct chmod_rv rv; + int serial; + + if (g->state != READY) { + error (g, "guestfs_chmod called from the wrong state, %d != READY", + g->state); + return -1; + } + + memset (&rv, 0, sizeof rv); + + args.mode = mode; + args.path = (char *) path; + serial = dispatch (g, GUESTFS_PROC_CHMOD, + (xdrproc_t) xdr_guestfs_chmod_args, (char *) &args); + if (serial == -1) + return -1; + + rv.cb_done = 0; + g->reply_cb_internal = chmod_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_chmod failed, see earlier error messages"); + return -1; + } + + if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_CHMOD, serial) == -1) + return -1; + + if (rv.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", rv.err.error); + return -1; + } + + return 0; +} + +struct chown_rv { + int cb_done; /* flag to indicate callback was called */ + struct guestfs_message_header hdr; + struct guestfs_message_error err; +}; + +static void chown_cb (guestfs_h *g, void *data, XDR *xdr) +{ + struct chown_rv *rv = (struct chown_rv *) data; + + if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + error (g, "guestfs_chown: failed to parse reply header"); + return; + } + if (rv->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &rv->err)) { + error (g, "guestfs_chown: failed to parse reply error"); + return; + } + goto done; + } + done: + rv->cb_done = 1; + main_loop.main_loop_quit (g); +} + +int guestfs_chown (guestfs_h *g, + int owner, + int group, + const char *path) +{ + struct guestfs_chown_args args; + struct chown_rv rv; + int serial; + + if (g->state != READY) { + error (g, "guestfs_chown called from the wrong state, %d != READY", + g->state); + return -1; + } + + memset (&rv, 0, sizeof rv); + + args.owner = owner; + args.group = group; + args.path = (char *) path; + serial = dispatch (g, GUESTFS_PROC_CHOWN, + (xdrproc_t) xdr_guestfs_chown_args, (char *) &args); + if (serial == -1) + return -1; + + rv.cb_done = 0; + g->reply_cb_internal = chown_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_chown failed, see earlier error messages"); + return -1; + } + + if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_CHOWN, serial) == -1) + return -1; + + if (rv.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", rv.err.error); + return -1; + } + + return 0; +} + diff --git a/src/guestfs-actions.h b/src/guestfs-actions.h index 497e36bb..06f1485b 100644 --- a/src/guestfs-actions.h +++ b/src/guestfs-actions.h @@ -59,3 +59,10 @@ 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); +extern int guestfs_rm (guestfs_h *handle, const char *path); +extern int guestfs_rmdir (guestfs_h *handle, const char *path); +extern int guestfs_rm_rf (guestfs_h *handle, const char *path); +extern int guestfs_mkdir (guestfs_h *handle, const char *path); +extern int guestfs_mkdir_p (guestfs_h *handle, const char *path); +extern int guestfs_chmod (guestfs_h *handle, int mode, const char *path); +extern int guestfs_chown (guestfs_h *handle, int owner, int group, const char *path); diff --git a/src/guestfs_protocol.c b/src/guestfs_protocol.c index ed38a8d2..781c2daf 100644 --- a/src/guestfs_protocol.c +++ b/src/guestfs_protocol.c @@ -543,6 +543,82 @@ xdr_guestfs_aug_ls_ret (XDR *xdrs, guestfs_aug_ls_ret *objp) } bool_t +xdr_guestfs_rm_args (XDR *xdrs, guestfs_rm_args *objp) +{ + register int32_t *buf; + + if (!xdr_string (xdrs, &objp->path, ~0)) + return FALSE; + return TRUE; +} + +bool_t +xdr_guestfs_rmdir_args (XDR *xdrs, guestfs_rmdir_args *objp) +{ + register int32_t *buf; + + if (!xdr_string (xdrs, &objp->path, ~0)) + return FALSE; + return TRUE; +} + +bool_t +xdr_guestfs_rm_rf_args (XDR *xdrs, guestfs_rm_rf_args *objp) +{ + register int32_t *buf; + + if (!xdr_string (xdrs, &objp->path, ~0)) + return FALSE; + return TRUE; +} + +bool_t +xdr_guestfs_mkdir_args (XDR *xdrs, guestfs_mkdir_args *objp) +{ + register int32_t *buf; + + if (!xdr_string (xdrs, &objp->path, ~0)) + return FALSE; + return TRUE; +} + +bool_t +xdr_guestfs_mkdir_p_args (XDR *xdrs, guestfs_mkdir_p_args *objp) +{ + register int32_t *buf; + + if (!xdr_string (xdrs, &objp->path, ~0)) + return FALSE; + return TRUE; +} + +bool_t +xdr_guestfs_chmod_args (XDR *xdrs, guestfs_chmod_args *objp) +{ + register int32_t *buf; + + if (!xdr_int (xdrs, &objp->mode)) + return FALSE; + if (!xdr_string (xdrs, &objp->path, ~0)) + return FALSE; + return TRUE; +} + +bool_t +xdr_guestfs_chown_args (XDR *xdrs, guestfs_chown_args *objp) +{ + register int32_t *buf; + + if (!xdr_int (xdrs, &objp->owner)) + return FALSE; + if (!xdr_int (xdrs, &objp->group)) + return FALSE; + if (!xdr_string (xdrs, &objp->path, ~0)) + 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 a0943554..508bc4e3 100644 --- a/src/guestfs_protocol.h +++ b/src/guestfs_protocol.h @@ -299,6 +299,44 @@ struct guestfs_aug_ls_ret { }; typedef struct guestfs_aug_ls_ret guestfs_aug_ls_ret; +struct guestfs_rm_args { + char *path; +}; +typedef struct guestfs_rm_args guestfs_rm_args; + +struct guestfs_rmdir_args { + char *path; +}; +typedef struct guestfs_rmdir_args guestfs_rmdir_args; + +struct guestfs_rm_rf_args { + char *path; +}; +typedef struct guestfs_rm_rf_args guestfs_rm_rf_args; + +struct guestfs_mkdir_args { + char *path; +}; +typedef struct guestfs_mkdir_args guestfs_mkdir_args; + +struct guestfs_mkdir_p_args { + char *path; +}; +typedef struct guestfs_mkdir_p_args guestfs_mkdir_p_args; + +struct guestfs_chmod_args { + int mode; + char *path; +}; +typedef struct guestfs_chmod_args guestfs_chmod_args; + +struct guestfs_chown_args { + int owner; + int group; + char *path; +}; +typedef struct guestfs_chown_args guestfs_chown_args; + enum guestfs_procedure { GUESTFS_PROC_MOUNT = 1, GUESTFS_PROC_SYNC = 2, @@ -328,7 +366,14 @@ enum guestfs_procedure { GUESTFS_PROC_AUG_SAVE = 25, GUESTFS_PROC_AUG_LOAD = 27, GUESTFS_PROC_AUG_LS = 28, - GUESTFS_PROC_dummy = 28 + 1, + GUESTFS_PROC_RM = 29, + GUESTFS_PROC_RMDIR = 30, + GUESTFS_PROC_RM_RF = 31, + GUESTFS_PROC_MKDIR = 32, + GUESTFS_PROC_MKDIR_P = 33, + GUESTFS_PROC_CHMOD = 34, + GUESTFS_PROC_CHOWN = 35, + GUESTFS_PROC_dummy = 35 + 1, }; typedef enum guestfs_procedure guestfs_procedure; #define GUESTFS_MESSAGE_MAX 4194304 @@ -407,6 +452,13 @@ 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_rm_args (XDR *, guestfs_rm_args*); +extern bool_t xdr_guestfs_rmdir_args (XDR *, guestfs_rmdir_args*); +extern bool_t xdr_guestfs_rm_rf_args (XDR *, guestfs_rm_rf_args*); +extern bool_t xdr_guestfs_mkdir_args (XDR *, guestfs_mkdir_args*); +extern bool_t xdr_guestfs_mkdir_p_args (XDR *, guestfs_mkdir_p_args*); +extern bool_t xdr_guestfs_chmod_args (XDR *, guestfs_chmod_args*); +extern bool_t xdr_guestfs_chown_args (XDR *, guestfs_chown_args*); 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*); @@ -455,6 +507,13 @@ 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_rm_args (); +extern bool_t xdr_guestfs_rmdir_args (); +extern bool_t xdr_guestfs_rm_rf_args (); +extern bool_t xdr_guestfs_mkdir_args (); +extern bool_t xdr_guestfs_mkdir_p_args (); +extern bool_t xdr_guestfs_chmod_args (); +extern bool_t xdr_guestfs_chown_args (); 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 8e3d2a95..41116b53 100644 --- a/src/guestfs_protocol.x +++ b/src/guestfs_protocol.x @@ -231,6 +231,37 @@ struct guestfs_aug_ls_ret { str matches<>; }; +struct guestfs_rm_args { + string path<>; +}; + +struct guestfs_rmdir_args { + string path<>; +}; + +struct guestfs_rm_rf_args { + string path<>; +}; + +struct guestfs_mkdir_args { + string path<>; +}; + +struct guestfs_mkdir_p_args { + string path<>; +}; + +struct guestfs_chmod_args { + int mode; + string path<>; +}; + +struct guestfs_chown_args { + int owner; + int group; + string path<>; +}; + enum guestfs_procedure { GUESTFS_PROC_MOUNT = 1, GUESTFS_PROC_SYNC = 2, @@ -260,6 +291,13 @@ enum guestfs_procedure { GUESTFS_PROC_AUG_SAVE = 25, GUESTFS_PROC_AUG_LOAD = 27, GUESTFS_PROC_AUG_LS = 28, + GUESTFS_PROC_RM = 29, + GUESTFS_PROC_RMDIR = 30, + GUESTFS_PROC_RM_RF = 31, + GUESTFS_PROC_MKDIR = 32, + GUESTFS_PROC_MKDIR_P = 33, + GUESTFS_PROC_CHMOD = 34, + GUESTFS_PROC_CHOWN = 35, GUESTFS_PROC_dummy }; |