summaryrefslogtreecommitdiff
path: root/src/copy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/copy.c')
-rw-r--r--src/copy.c84
1 files changed, 37 insertions, 47 deletions
diff --git a/src/copy.c b/src/copy.c
index 171499c47..6d11ed868 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -177,11 +177,11 @@ static void
copy_attr_error (struct error_context *ctx ATTRIBUTE_UNUSED,
char const *fmt, ...)
{
- int err = errno;
- va_list ap;
-
if (!errno_unsupported (errno))
{
+ int err = errno;
+ va_list ap;
+
/* use verror module to print error message */
va_start (ap, fmt);
verror (0, err, fmt, ap);
@@ -214,51 +214,39 @@ copy_attr_free (struct error_context *ctx ATTRIBUTE_UNUSED,
{
}
-static bool
-copy_attr_by_fd (char const *src_path, int src_fd,
- char const *dst_path, int dst_fd, const struct cp_options *x)
-{
- struct error_context ctx =
- {
- .error = x->require_preserve_xattr ? copy_attr_allerror : copy_attr_error,
- .quote = copy_attr_quote,
- .quote_free = copy_attr_free
- };
- return 0 == attr_copy_fd (src_path, src_fd, dst_path, dst_fd, 0,
- (x->reduce_diagnostics
- && !x->require_preserve_xattr)? NULL : &ctx);
-}
+/* If positive SRC_FD and DST_FD descriptors are passed,
+ then copy by fd, otherwise copy by name. */
static bool
-copy_attr_by_name (char const *src_path, char const *dst_path,
- const struct cp_options *x)
+copy_attr (char const *src_path, int src_fd,
+ char const *dst_path, int dst_fd, struct cp_options const *x)
{
+ int ret;
+ bool all_errors = (!x->data_copy_required || x->require_preserve_xattr);
+ bool some_errors = (!all_errors && !x->reduce_diagnostics);
struct error_context ctx =
{
- .error = x->require_preserve_xattr ? copy_attr_allerror : copy_attr_error,
+ .error = all_errors ? copy_attr_allerror : copy_attr_error,
.quote = copy_attr_quote,
.quote_free = copy_attr_free
};
- return 0 == attr_copy_file (src_path, dst_path, 0,
- (x-> reduce_diagnostics
- && !x->require_preserve_xattr) ? NULL : &ctx);
-}
-#else /* USE_XATTR */
+ if (0 <= src_fd && 0 <= dst_fd)
+ ret = attr_copy_fd (src_path, src_fd, dst_path, dst_fd, 0,
+ (all_errors || some_errors ? &ctx : NULL));
+ else
+ ret = attr_copy_file (src_path, dst_path, 0,
+ (all_errors || some_errors ? &ctx : NULL));
-static bool
-copy_attr_by_fd (char const *src_path ATTRIBUTE_UNUSED,
- int src_fd ATTRIBUTE_UNUSED,
- char const *dst_path ATTRIBUTE_UNUSED,
- int dst_fd ATTRIBUTE_UNUSED,
- const struct cp_options *x ATTRIBUTE_UNUSED)
-{
- return true;
+ return ret == 0;
}
+#else /* USE_XATTR */
static bool
-copy_attr_by_name (char const *src_path ATTRIBUTE_UNUSED,
- char const *dst_path ATTRIBUTE_UNUSED,
- const struct cp_options *x ATTRIBUTE_UNUSED)
+copy_attr (char const *src_path ATTRIBUTE_UNUSED,
+ int src_fd ATTRIBUTE_UNUSED,
+ char const *dst_path ATTRIBUTE_UNUSED,
+ int dst_fd ATTRIBUTE_UNUSED,
+ struct cp_options const *x ATTRIBUTE_UNUSED)
{
return true;
}
@@ -483,7 +471,7 @@ copy_reg (char const *src_name, char const *dst_name,
struct stat sb;
struct stat src_open_sb;
bool return_val = true;
- bool data_copy_required = true;
+ bool data_copy_required = x->data_copy_required;
source_desc = open (src_name,
(O_RDONLY | O_BINARY
@@ -526,11 +514,14 @@ copy_reg (char const *src_name, char const *dst_name,
that is used when the destination file doesn't already exist. */
if (x->preserve_security_context && 0 <= dest_desc)
{
+ bool all_errors = (!x->data_copy_required
+ || x->require_preserve_context);
+ bool some_errors = !all_errors && !x->reduce_diagnostics;
security_context_t con = NULL;
+
if (getfscreatecon (&con) < 0)
{
- if (x->require_preserve_context ||
- (!x->reduce_diagnostics && !errno_unsupported (errno)))
+ if (all_errors || (some_errors && !errno_unsupported (errno)))
error (0, errno, _("failed to get file system create context"));
if (x->require_preserve_context)
{
@@ -543,8 +534,7 @@ copy_reg (char const *src_name, char const *dst_name,
{
if (fsetfilecon (dest_desc, con) < 0)
{
- if (x->require_preserve_context ||
- (!x->reduce_diagnostics && !errno_unsupported (errno)))
+ if (all_errors || (some_errors && !errno_unsupported (errno)))
error (0, errno,
_("failed to set the security context of %s to %s"),
quote_n (0, dst_name), quote_n (1, con));
@@ -850,7 +840,7 @@ copy_reg (char const *src_name, char const *dst_name,
if (!(sb.st_mode & S_IWUSR) && geteuid () != 0)
access_changed = fchmod_or_lchmod (dest_desc, dst_name, 0600) == 0;
- if (!copy_attr_by_fd (src_name, source_desc, dst_name, dest_desc, x)
+ if (!copy_attr (src_name, source_desc, dst_name, dest_desc, x)
&& x->require_preserve_xattr)
return_val = false;
@@ -1821,14 +1811,15 @@ copy_internal (char const *src_name, char const *dst_name,
if (x->preserve_security_context)
{
+ bool all_errors = !x->data_copy_required || x->require_preserve_context;
+ bool some_errors = !all_errors && !x->reduce_diagnostics;
security_context_t con;
if (0 <= lgetfilecon (src_name, &con))
{
if (setfscreatecon (con) < 0)
{
- if (x->require_preserve_context ||
- (!x->reduce_diagnostics && !errno_unsupported (errno)))
+ if (all_errors || (some_errors && !errno_unsupported (errno)))
error (0, errno,
_("failed to set default file creation context to %s"),
quote (con));
@@ -1842,8 +1833,7 @@ copy_internal (char const *src_name, char const *dst_name,
}
else
{
- if (x->require_preserve_context ||
- (!x->reduce_diagnostics && !errno_unsupported (errno)))
+ if (all_errors || (some_errors && !errno_unsupported (errno)))
{
error (0, errno,
_("failed to get security context of %s"),
@@ -2168,7 +2158,7 @@ copy_internal (char const *src_name, char const *dst_name,
set_author (dst_name, -1, &src_sb);
- if (x->preserve_xattr && ! copy_attr_by_name (src_name, dst_name, x)
+ if (x->preserve_xattr && ! copy_attr (src_name, -1, dst_name, -1, x)
&& x->require_preserve_xattr)
return false;