mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-22 07:03:38 +00:00
builder, edit, fish: use copy-attributes
Make use of the new copy-attributes command to properly copy all file attributes from a file to the new version of it.
This commit is contained in:
@@ -42,7 +42,7 @@ let rec edit_file ~debug (g : Guestfs.guestfs) file expr =
|
||||
g#upload tmpfile file;
|
||||
|
||||
(* However like virt-edit we do need to copy attributes. *)
|
||||
copy_attributes g file_old file;
|
||||
g#copy_attributes ~all:true file_old file;
|
||||
g#rm file_old
|
||||
|
||||
and do_perl_edit ~debug g file expr =
|
||||
@@ -76,30 +76,3 @@ and do_perl_edit ~debug g file expr =
|
||||
);
|
||||
|
||||
Unix.rename (file ^ ".out") file
|
||||
|
||||
and copy_attributes g src dest =
|
||||
let has_linuxxattrs = g#feature_available [|"linuxxattrs"|] in
|
||||
|
||||
(* Get the mode. *)
|
||||
let stat = g#stat src in
|
||||
|
||||
(* Get the SELinux context. XXX Should we copy over other extended
|
||||
* attributes too?
|
||||
*)
|
||||
let selinux_context =
|
||||
if has_linuxxattrs then (
|
||||
try Some (g#getxattr src "security.selinux") with _ -> None
|
||||
) else None in
|
||||
|
||||
(* Set the permissions (inc. sticky and set*id bits), UID, GID. *)
|
||||
let mode = Int64.to_int stat.G.mode
|
||||
and uid = Int64.to_int stat.G.uid and gid = Int64.to_int stat.G.gid in
|
||||
g#chmod (mode land 0o7777) dest;
|
||||
g#chown uid gid dest;
|
||||
|
||||
(* Set the SELinux context. *)
|
||||
match selinux_context with
|
||||
| None -> ()
|
||||
| Some selinux_context ->
|
||||
g#setxattr "security.selinux"
|
||||
selinux_context (String.length selinux_context) dest
|
||||
|
||||
49
edit/edit.c
49
edit/edit.c
@@ -56,7 +56,6 @@ static void edit_files (int argc, char *argv[]);
|
||||
static void edit (const char *filename, const char *root);
|
||||
static char *edit_interactively (const char *tmpfile);
|
||||
static char *edit_non_interactively (const char *tmpfile);
|
||||
static int copy_attributes (const char *src, const char *dest);
|
||||
static int is_windows (guestfs_h *g, const char *root);
|
||||
static char *windows_path (guestfs_h *g, const char *root, const char *filename);
|
||||
static char *generate_random_name (const char *filename);
|
||||
@@ -361,7 +360,8 @@ edit (const char *filename, const char *root)
|
||||
/* Set the permissions, UID, GID and SELinux context of the new
|
||||
* file to match the old file (RHBZ#788641).
|
||||
*/
|
||||
if (copy_attributes (filename, newname) == -1)
|
||||
if (guestfs_copy_attributes (g, filename, newname,
|
||||
GUESTFS_COPY_ATTRIBUTES_ALL, 1, -1) == -1)
|
||||
goto error;
|
||||
|
||||
/* Backup or overwrite the file. */
|
||||
@@ -509,51 +509,6 @@ edit_non_interactively (const char *tmpfile)
|
||||
return ret; /* caller will free */
|
||||
}
|
||||
|
||||
static int
|
||||
copy_attributes (const char *src, const char *dest)
|
||||
{
|
||||
CLEANUP_FREE_STAT struct guestfs_stat *stat = NULL;
|
||||
const char *linuxxattrs[] = { "linuxxattrs", NULL };
|
||||
int has_linuxxattrs;
|
||||
CLEANUP_FREE char *selinux_context = NULL;
|
||||
size_t selinux_context_size;
|
||||
|
||||
has_linuxxattrs = guestfs_feature_available (g, (char **) linuxxattrs);
|
||||
|
||||
/* Get the mode. */
|
||||
stat = guestfs_stat (g, src);
|
||||
if (stat == NULL)
|
||||
return -1;
|
||||
|
||||
/* Get the SELinux context. XXX Should we copy over other extended
|
||||
* attributes too?
|
||||
*/
|
||||
if (has_linuxxattrs) {
|
||||
guestfs_push_error_handler (g, NULL, NULL);
|
||||
|
||||
selinux_context = guestfs_getxattr (g, src, "security.selinux",
|
||||
&selinux_context_size);
|
||||
/* selinux_context could be NULL. This isn't an error. */
|
||||
|
||||
guestfs_pop_error_handler (g);
|
||||
}
|
||||
|
||||
/* Set the permissions (inc. sticky and set*id bits), UID, GID. */
|
||||
if (guestfs_chmod (g, stat->mode & 07777, dest) == -1)
|
||||
return -1;
|
||||
if (guestfs_chown (g, stat->uid, stat->gid, dest) == -1)
|
||||
return -1;
|
||||
|
||||
/* Set the SELinux context. */
|
||||
if (has_linuxxattrs && selinux_context) {
|
||||
if (guestfs_setxattr (g, "security.selinux", selinux_context,
|
||||
(int) selinux_context_size, dest) == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
is_windows (guestfs_h *g, const char *root)
|
||||
{
|
||||
|
||||
54
fish/edit.c
54
fish/edit.c
@@ -32,7 +32,6 @@
|
||||
#include "fish.h"
|
||||
|
||||
static char *generate_random_name (const char *filename);
|
||||
static int copy_attributes (const char *src, const char *dest);
|
||||
|
||||
/* guestfish edit command, suggested by Ján Ondrej, implemented by RWMJ */
|
||||
|
||||
@@ -135,7 +134,8 @@ run_edit (const char *cmd, size_t argc, char *argv[])
|
||||
/* Set the permissions, UID, GID and SELinux context of the new
|
||||
* file to match the old file (RHBZ#788641).
|
||||
*/
|
||||
if (copy_attributes (remotefilename, newname) == -1)
|
||||
if (guestfs_copy_attributes (g, remotefilename, newname,
|
||||
GUESTFS_COPY_ATTRIBUTES_ALL, 1, -1) == -1)
|
||||
return -1;
|
||||
|
||||
if (guestfs_mv (g, newname, remotefilename) == -1)
|
||||
@@ -177,53 +177,3 @@ generate_random_name (const char *filename)
|
||||
|
||||
return ret; /* caller will free */
|
||||
}
|
||||
|
||||
static int
|
||||
copy_attributes (const char *src, const char *dest)
|
||||
{
|
||||
struct guestfs_stat *stat;
|
||||
const char *linuxxattrs[] = { "linuxxattrs", NULL };
|
||||
int has_linuxxattrs;
|
||||
CLEANUP_FREE char *selinux_context = NULL;
|
||||
size_t selinux_context_size;
|
||||
|
||||
has_linuxxattrs = guestfs_feature_available (g, (char **) linuxxattrs);
|
||||
|
||||
/* Get the mode. */
|
||||
stat = guestfs_stat (g, src);
|
||||
if (stat == NULL)
|
||||
return -1;
|
||||
|
||||
/* Get the SELinux context. XXX Should we copy over other extended
|
||||
* attributes too?
|
||||
*/
|
||||
if (has_linuxxattrs) {
|
||||
guestfs_push_error_handler (g, NULL, NULL);
|
||||
|
||||
selinux_context = guestfs_getxattr (g, src, "security.selinux",
|
||||
&selinux_context_size);
|
||||
/* selinux_context could be NULL. This isn't an error. */
|
||||
|
||||
guestfs_pop_error_handler (g);
|
||||
}
|
||||
|
||||
/* Set the permissions (inc. sticky and set*id bits), UID, GID. */
|
||||
if (guestfs_chmod (g, stat->mode & 07777, dest) == -1) {
|
||||
guestfs_free_stat (stat);
|
||||
return -1;
|
||||
}
|
||||
if (guestfs_chown (g, stat->uid, stat->gid, dest) == -1) {
|
||||
guestfs_free_stat (stat);
|
||||
return -1;
|
||||
}
|
||||
guestfs_free_stat (stat);
|
||||
|
||||
/* Set the SELinux context. */
|
||||
if (has_linuxxattrs && selinux_context) {
|
||||
if (guestfs_setxattr (g, "security.selinux", selinux_context,
|
||||
(int) selinux_context_size, dest) == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user