1 /* cp.c -- file copying (main routines)
2 Copyright (C) 1989-2024 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>.
17 Written by Torbjörn Granlund, David MacKenzie, and Jim Meyering. */
21 #include <sys/types.h>
23 #include <selinux/label.h>
28 #include "backupfile.h"
31 #include "filenamecat.h"
32 #include "ignore-value.h"
34 #include "stat-time.h"
35 #include "targetdir.h"
39 /* The official name of this program (e.g., no 'g' prefix). */
40 #define PROGRAM_NAME "cp"
43 proper_name_lite ("Torbjorn Granlund", "Torbj\303\266rn Granlund"), \
44 proper_name ("David MacKenzie"), \
45 proper_name ("Jim Meyering")
47 /* Used by do_copy, make_dir_parents_private, and re_protect
48 to keep a list of leading directories whose protections
49 need to be fixed after copying. */
55 struct dir_attr
*next
;
58 /* For long options that have no equivalent short option, use a
59 non-character as a pseudo short option, starting with CHAR_MAX + 1. */
62 ATTRIBUTES_ONLY_OPTION
= CHAR_MAX
+ 1,
65 NO_PRESERVE_ATTRIBUTES_OPTION
,
67 PRESERVE_ATTRIBUTES_OPTION
,
70 STRIP_TRAILING_SLASHES_OPTION
,
71 UNLINK_DEST_BEFORE_OPENING
,
72 KEEP_DIRECTORY_SYMLINK_OPTION
75 /* True if the kernel is SELinux enabled. */
76 static bool selinux_enabled
;
78 /* If true, the command "cp x/e_file e_dir" uses "e_dir/x/e_file"
79 as its destination instead of the usual "e_dir/e_file." */
80 static bool parents_option
= false;
82 /* Remove any trailing slashes from each SOURCE argument. */
83 static bool remove_trailing_slashes
;
85 static char const *const sparse_type_string
[] =
87 "never", "auto", "always", nullptr
89 static enum Sparse_type
const sparse_type
[] =
91 SPARSE_NEVER
, SPARSE_AUTO
, SPARSE_ALWAYS
93 ARGMATCH_VERIFY (sparse_type_string
, sparse_type
);
95 static char const *const reflink_type_string
[] =
97 "auto", "always", "never", nullptr
99 static enum Reflink_type
const reflink_type
[] =
101 REFLINK_AUTO
, REFLINK_ALWAYS
, REFLINK_NEVER
103 ARGMATCH_VERIFY (reflink_type_string
, reflink_type
);
105 static char const *const update_type_string
[] =
107 "all", "none", "older", nullptr
109 static enum Update_type
const update_type
[] =
111 UPDATE_ALL
, UPDATE_NONE
, UPDATE_OLDER
,
113 ARGMATCH_VERIFY (update_type_string
, update_type
);
115 static struct option
const long_opts
[] =
117 {"archive", no_argument
, nullptr, 'a'},
118 {"attributes-only", no_argument
, nullptr, ATTRIBUTES_ONLY_OPTION
},
119 {"backup", optional_argument
, nullptr, 'b'},
120 {"copy-contents", no_argument
, nullptr, COPY_CONTENTS_OPTION
},
121 {"debug", no_argument
, nullptr, DEBUG_OPTION
},
122 {"dereference", no_argument
, nullptr, 'L'},
123 {"force", no_argument
, nullptr, 'f'},
124 {"interactive", no_argument
, nullptr, 'i'},
125 {"link", no_argument
, nullptr, 'l'},
126 {"no-clobber", no_argument
, nullptr, 'n'}, /* Deprecated. */
127 {"no-dereference", no_argument
, nullptr, 'P'},
128 {"no-preserve", required_argument
, nullptr, NO_PRESERVE_ATTRIBUTES_OPTION
},
129 {"no-target-directory", no_argument
, nullptr, 'T'},
130 {"one-file-system", no_argument
, nullptr, 'x'},
131 {"parents", no_argument
, nullptr, PARENTS_OPTION
},
132 {"path", no_argument
, nullptr, PARENTS_OPTION
}, /* Deprecated. */
133 {"preserve", optional_argument
, nullptr, PRESERVE_ATTRIBUTES_OPTION
},
134 {"recursive", no_argument
, nullptr, 'R'},
135 {"remove-destination", no_argument
, nullptr, UNLINK_DEST_BEFORE_OPENING
},
136 {"sparse", required_argument
, nullptr, SPARSE_OPTION
},
137 {"reflink", optional_argument
, nullptr, REFLINK_OPTION
},
138 {"strip-trailing-slashes", no_argument
, nullptr,
139 STRIP_TRAILING_SLASHES_OPTION
},
140 {"suffix", required_argument
, nullptr, 'S'},
141 {"symbolic-link", no_argument
, nullptr, 's'},
142 {"target-directory", required_argument
, nullptr, 't'},
143 {"update", optional_argument
, nullptr, 'u'},
144 {"verbose", no_argument
, nullptr, 'v'},
145 {"keep-directory-symlink", no_argument
, nullptr,
146 KEEP_DIRECTORY_SYMLINK_OPTION
},
147 {GETOPT_SELINUX_CONTEXT_OPTION_DECL
},
148 {GETOPT_HELP_OPTION_DECL
},
149 {GETOPT_VERSION_OPTION_DECL
},
150 {nullptr, 0, nullptr, 0}
156 if (status
!= EXIT_SUCCESS
)
161 Usage: %s [OPTION]... [-T] SOURCE DEST\n\
162 or: %s [OPTION]... SOURCE... DIRECTORY\n\
163 or: %s [OPTION]... -t DIRECTORY SOURCE...\n\
165 program_name
, program_name
, program_name
);
167 Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\
170 emit_mandatory_arg_note ();
173 -a, --archive same as -dR --preserve=all\n\
174 --attributes-only don't copy the file data, just the attributes\n\
175 --backup[=CONTROL] make a backup of each existing destination file\
177 -b like --backup but does not accept an argument\n\
178 --copy-contents copy contents of special files when recursive\n\
179 -d same as --no-dereference --preserve=links\n\
182 --debug explain how a file is copied. Implies -v\n\
185 -f, --force if an existing destination file cannot be\n\
186 opened, remove it and try again (this option\n\
187 is ignored when the -n option is also used)\n\
188 -i, --interactive prompt before overwrite (overrides a previous -n\
191 -H follow command-line symbolic links in SOURCE\n\
194 -l, --link hard link files instead of copying\n\
195 -L, --dereference always follow symbolic links in SOURCE\n\
198 -n, --no-clobber (deprecated) silently skip existing files.\n\
202 -P, --no-dereference never follow symbolic links in SOURCE\n\
205 -p same as --preserve=mode,ownership,timestamps\n\
206 --preserve[=ATTR_LIST] preserve the specified attributes\n\
209 --no-preserve=ATTR_LIST don't preserve the specified attributes\n\
210 --parents use full source file name under DIRECTORY\n\
213 -R, -r, --recursive copy directories recursively\n\
214 --reflink[=WHEN] control clone/CoW copies. See below\n\
215 --remove-destination remove each existing destination file before\n\
216 attempting to open it (contrast with --force)\
219 --sparse=WHEN control creation of sparse files. See below\n\
220 --strip-trailing-slashes remove any trailing slashes from each SOURCE\n\
224 -s, --symbolic-link make symbolic links instead of copying\n\
225 -S, --suffix=SUFFIX override the usual backup suffix\n\
226 -t, --target-directory=DIRECTORY copy all SOURCE arguments into DIRECTORY\n\
227 -T, --no-target-directory treat DEST as a normal file\n\
230 --update[=UPDATE] control which existing files are updated;\n\
231 UPDATE={all,none,none-fail,older(default)}.\n\
232 -u equivalent to --update[=older]. See below\n\
235 -v, --verbose explain what is being done\n\
238 --keep-directory-symlink follow existing symlinks to directories\n\
241 -x, --one-file-system stay on this file system\n\
244 -Z set SELinux security context of destination\n\
245 file to default type\n\
246 --context[=CTX] like -Z, or if CTX is specified then set the\n\
247 SELinux or SMACK security context to CTX\n\
249 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
250 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
253 ATTR_LIST is a comma-separated list of attributes. Attributes are 'mode' for\n\
254 permissions (including any ACL and xattr permissions), 'ownership' for user\n\
255 and group, 'timestamps' for file timestamps, 'links' for hard links, 'context'\
256 \nfor security context, 'xattr' for extended attributes, and 'all' for all\n\
261 By default, sparse SOURCE files are detected by a crude heuristic and the\n\
262 corresponding DEST file is made sparse as well. That is the behavior\n\
263 selected by --sparse=auto. Specify --sparse=always to create a sparse DEST\n\
264 file whenever the SOURCE file contains a long enough sequence of zero bytes.\n\
265 Use --sparse=never to inhibit creation of sparse files.\n\
267 emit_update_parameters_note ();
270 When --reflink[=always] is specified, perform a lightweight copy, where the\n\
271 data blocks are copied only when modified. If this is not possible the copy\n\
272 fails, or if --reflink=auto is specified, fall back to a standard copy.\n\
273 Use --reflink=never to ensure a standard copy is performed.\n\
275 emit_backup_suffix_note ();
278 As a special case, cp makes a backup of SOURCE when the force and backup\n\
279 options are given and SOURCE and DEST are the same name for an existing,\n\
282 emit_ancillary_info (PROGRAM_NAME
);
287 /* Ensure that parents of CONST_DST_NAME have correct protections, for
288 the --parents option. This is done after all copying has been
289 completed, to allow permissions that don't include user write/execute.
291 DST_SRC_NAME is the suffix of CONST_DST_NAME that is the source file name,
292 DST_DIRFD+DST_RELNAME is equivalent to CONST_DST_NAME, and
293 DST_RELNAME equals DST_SRC_NAME after skipping any leading '/'s.
295 ATTR_LIST is a null-terminated linked list of structures that
296 indicates the end of the filename of each intermediate directory
297 in CONST_DST_NAME that may need to have its attributes changed.
298 The command 'cp --parents --preserve a/b/c d/e_dir' changes the
299 attributes of the directories d/e_dir/a and d/e_dir/a/b to match
300 the corresponding source directories regardless of whether they
301 existed before the 'cp' command was given.
303 Return true if the parent of CONST_DST_NAME and any intermediate
304 directories specified by ATTR_LIST have the proper permissions
308 re_protect (char const *const_dst_name
, char const *dst_src_name
,
309 int dst_dirfd
, char const *dst_relname
,
310 struct dir_attr
*attr_list
, const struct cp_options
*x
)
313 char *dst_name
; /* A copy of CONST_DST_NAME we can change. */
315 ASSIGN_STRDUPA (dst_name
, const_dst_name
);
317 /* The suffix of DST_NAME that is a copy of the source file name,
318 possibly truncated to name a parent directory. */
319 char const *src_name
= dst_name
+ (dst_src_name
- const_dst_name
);
321 /* Likewise, but with any leading '/'s skipped. */
322 char const *relname
= dst_name
+ (dst_relname
- const_dst_name
);
324 for (p
= attr_list
; p
; p
= p
->next
)
326 dst_name
[p
->slash_offset
] = '\0';
328 /* Adjust the times (and if possible, ownership) for the copy.
329 chown turns off set[ug]id bits for non-root,
330 so do the chmod last. */
332 if (x
->preserve_timestamps
)
334 struct timespec timespec
[2];
336 timespec
[0] = get_stat_atime (&p
->st
);
337 timespec
[1] = get_stat_mtime (&p
->st
);
339 if (utimensat (dst_dirfd
, relname
, timespec
, 0))
341 error (0, errno
, _("failed to preserve times for %s"),
347 if (x
->preserve_ownership
)
349 if (lchownat (dst_dirfd
, relname
, p
->st
.st_uid
, p
->st
.st_gid
)
352 if (! chown_failure_ok (x
))
354 error (0, errno
, _("failed to preserve ownership for %s"),
358 /* Failing to preserve ownership is OK. Still, try to preserve
359 the group, but ignore the possible error. */
360 ignore_value (lchownat (dst_dirfd
, relname
, -1, p
->st
.st_gid
));
364 if (x
->preserve_mode
)
366 if (copy_acl (src_name
, -1, dst_name
, -1, p
->st
.st_mode
) != 0)
369 else if (p
->restore_mode
)
371 if (lchmodat (dst_dirfd
, relname
, p
->st
.st_mode
) != 0)
373 error (0, errno
, _("failed to preserve permissions for %s"),
379 dst_name
[p
->slash_offset
] = '/';
384 /* Ensure that the parent directory of CONST_DIR exists, for
385 the --parents option.
387 SRC_OFFSET is the index in CONST_DIR (which is a destination
388 directory) of the beginning of the source directory name.
389 Create any leading directories that don't already exist.
390 DST_DIRFD is a file descriptor for the target directory.
391 If VERBOSE_FMT_STRING is nonzero, use it as a printf format
392 string for printing a message after successfully making a directory.
393 The format should take two string arguments: the names of the
394 source and destination directories.
395 Creates a linked list of attributes of intermediate directories,
396 *ATTR_LIST, for re_protect to use after calling copy.
397 Sets *NEW_DST if this function creates parent of CONST_DIR.
399 Return true if parent of CONST_DIR exists as a directory with the proper
400 permissions when done. */
402 /* FIXME: Synch this function with the one in ../lib/mkdir-p.c. */
405 make_dir_parents_private (char const *const_dir
, size_t src_offset
,
407 char const *verbose_fmt_string
,
408 struct dir_attr
**attr_list
, bool *new_dst
,
409 const struct cp_options
*x
)
412 char *dir
; /* A copy of CONST_DIR we can change. */
413 char *src
; /* Source name in DIR. */
414 char *dst_dir
; /* Leading directory of DIR. */
415 idx_t dirlen
= dir_len (const_dir
);
417 *attr_list
= nullptr;
419 /* Succeed immediately if the parent of CONST_DIR must already exist,
420 as the target directory has already been checked. */
421 if (dirlen
<= src_offset
)
424 ASSIGN_STRDUPA (dir
, const_dir
);
426 src
= dir
+ src_offset
;
428 dst_dir
= alloca (dirlen
+ 1);
429 memcpy (dst_dir
, dir
, dirlen
);
430 dst_dir
[dirlen
] = '\0';
431 char const *dst_reldir
= dst_dir
+ src_offset
;
432 while (*dst_reldir
== '/')
435 /* XXX: If all dirs are present at the destination,
436 no permissions or security contexts will be updated. */
437 if (fstatat (dst_dirfd
, dst_reldir
, &stats
, 0) != 0)
439 /* A parent of CONST_DIR does not exist.
440 Make all missing intermediate directories. */
444 while (*slash
== '/')
448 while ((slash
= strchr (slash
, '/')))
450 struct dir_attr
*new;
454 missing_dir
= fstatat (dst_dirfd
, dst_reldir
, &stats
, 0) != 0;
456 if (missing_dir
|| x
->preserve_ownership
|| x
->preserve_mode
457 || x
->preserve_timestamps
)
459 /* Add this directory to the list of directories whose
460 modes might need fixing later. */
462 int src_errno
= (stat (src
, &src_st
) != 0
464 : S_ISDIR (src_st
.st_mode
)
469 error (0, src_errno
, _("failed to get attributes of %s"),
474 new = xmalloc (sizeof *new);
476 new->slash_offset
= slash
- dir
;
477 new->restore_mode
= false;
478 new->next
= *attr_list
;
482 /* If required set the default context for created dirs. */
483 if (! set_process_security_ctx (src
, dir
,
484 missing_dir
? new->st
.st_mode
: 0,
491 mode_t omitted_permissions
;
494 /* This component does not exist. We must set
495 *new_dst and new->st.st_mode inside this loop because,
496 for example, in the command 'cp --parents ../a/../b/c e_dir',
497 make_dir_parents_private creates only e_dir/../a if
498 ./b already exists. */
500 src_mode
= new->st
.st_mode
;
502 /* If the ownership or special mode bits might change,
503 omit some permissions at first, so unauthorized users
504 cannot nip in before the file is ready. */
505 omitted_permissions
= (src_mode
506 & (x
->preserve_ownership
512 /* POSIX says mkdir's behavior is implementation-defined when
513 (src_mode & ~S_IRWXUGO) != 0. However, common practice is
514 to ask mkdir to copy all the CHMOD_MODE_BITS, letting mkdir
515 decide what to do with S_ISUID | S_ISGID | S_ISVTX. */
516 mkdir_mode
= x
->explicit_no_preserve_mode
? S_IRWXUGO
: src_mode
;
517 mkdir_mode
&= CHMOD_MODE_BITS
& ~omitted_permissions
;
518 if (mkdirat (dst_dirfd
, dst_reldir
, mkdir_mode
) != 0)
520 error (0, errno
, _("cannot make directory %s"),
526 if (verbose_fmt_string
!= nullptr)
527 printf (verbose_fmt_string
, src
, dir
);
530 /* We need search and write permissions to the new directory
531 for writing the directory's contents. Check if these
532 permissions are there. */
534 if (fstatat (dst_dirfd
, dst_reldir
, &stats
, AT_SYMLINK_NOFOLLOW
))
536 error (0, errno
, _("failed to get attributes of %s"),
542 if (! x
->preserve_mode
)
544 if (omitted_permissions
& ~stats
.st_mode
)
545 omitted_permissions
&= ~ cached_umask ();
546 if (omitted_permissions
& ~stats
.st_mode
547 || (stats
.st_mode
& S_IRWXU
) != S_IRWXU
)
549 new->st
.st_mode
= stats
.st_mode
| omitted_permissions
;
550 new->restore_mode
= true;
554 mode_t accessible
= stats
.st_mode
| S_IRWXU
;
555 if (stats
.st_mode
!= accessible
)
557 /* Make the new directory searchable and writable.
558 The original permissions will be restored later. */
560 if (lchmodat (dst_dirfd
, dst_reldir
, accessible
) != 0)
562 error (0, errno
, _("setting permissions for %s"),
568 else if (!S_ISDIR (stats
.st_mode
))
570 error (0, 0, _("%s exists but is not a directory"),
577 /* For existing dirs, set the security context as per that already
578 set for the process global context. */
580 && (x
->set_security_context
|| x
->preserve_security_context
))
582 if (! set_file_security_ctx (dir
, false, x
)
583 && x
->require_preserve_context
)
589 /* Avoid unnecessary calls to 'stat' when given
590 file names containing multiple adjacent slashes. */
591 while (*slash
== '/')
596 /* We get here if the parent of DIR already exists. */
598 else if (!S_ISDIR (stats
.st_mode
))
600 error (0, 0, _("%s exists but is not a directory"), quoteaf (dst_dir
));
610 /* Scan the arguments, and copy each by calling copy.
611 Return true if successful. */
614 do_copy (int n_files
, char **file
, char const *target_directory
,
615 bool no_target_directory
, struct cp_options
*x
)
618 bool new_dst
= false;
621 if (n_files
<= !target_directory
)
624 error (0, 0, _("missing file operand"));
626 error (0, 0, _("missing destination file operand after %s"),
628 usage (EXIT_FAILURE
);
632 int target_dirfd
= AT_FDCWD
;
633 if (no_target_directory
)
635 if (target_directory
)
636 error (EXIT_FAILURE
, 0,
637 _("cannot combine --target-directory (-t) "
638 "and --no-target-directory (-T)"));
641 error (0, 0, _("extra operand %s"), quoteaf (file
[2]));
642 usage (EXIT_FAILURE
);
645 else if (target_directory
)
647 target_dirfd
= target_directory_operand (target_directory
, &sb
);
648 if (! target_dirfd_valid (target_dirfd
))
649 error (EXIT_FAILURE
, errno
, _("target directory %s"),
650 quoteaf (target_directory
));
654 char const *lastfile
= file
[n_files
- 1];
655 int fd
= target_directory_operand (lastfile
, &sb
);
656 if (target_dirfd_valid (fd
))
659 target_directory
= lastfile
;
668 /* The last operand LASTFILE cannot be opened as a directory.
669 If there are more than two operands, report an error.
671 Also, report an error if LASTFILE is known to be a directory
672 even though it could not be opened, which can happen if
673 opening failed with EACCES on a platform lacking O_PATH.
674 In this case use stat to test whether LASTFILE is a
675 directory, in case opening a non-directory with (O_SEARCH
676 | O_DIRECTORY) failed with EACCES not ENOTDIR. */
678 || (O_PATHSEARCH
== O_SEARCH
&& err
== EACCES
679 && (sb
.st_mode
|| stat (lastfile
, &sb
) == 0)
680 && S_ISDIR (sb
.st_mode
)))
681 error (EXIT_FAILURE
, err
, _("target %s"), quoteaf (lastfile
));
685 if (target_directory
)
687 /* cp file1...filen edir
688 Copy the files 'file1' through 'filen'
689 to the existing directory 'edir'. */
691 /* Initialize these hash tables only if we'll need them.
692 The problems they're used to detect can arise only if
693 there are two or more files to copy. */
700 for (int i
= 0; i
< n_files
; i
++)
703 bool parent_exists
= true; /* True if dir_name (dst_name) exists. */
704 struct dir_attr
*attr_list
;
708 /* Trailing slashes are meaningful (i.e., maybe worth preserving)
709 only in the source file names. */
710 if (remove_trailing_slashes
)
711 strip_trailing_slashes (arg
);
715 char *arg_no_trailing_slash
;
717 /* Use 'arg' without trailing slashes in constructing destination
718 file names. Otherwise, we can end up trying to create a
719 directory using a name with trailing slash, which fails on
720 NetBSD 1.[34] systems. */
721 ASSIGN_STRDUPA (arg_no_trailing_slash
, arg
);
722 strip_trailing_slashes (arg_no_trailing_slash
);
724 /* Append all of 'arg' (minus any trailing slash) to 'dest'. */
725 dst_name
= file_name_concat (target_directory
,
726 arg_no_trailing_slash
,
729 /* For --parents, we have to make sure that the directory
730 dir_name (dst_name) exists. We may have to create a few
731 leading directories. */
733 (make_dir_parents_private
734 (dst_name
, arg_in_concat
- dst_name
, target_dirfd
,
735 (x
->verbose
? "%s -> %s\n" : nullptr),
736 &attr_list
, &new_dst
, x
));
741 /* Append the last component of 'arg' to 'target_directory'. */
742 ASSIGN_STRDUPA (arg_base
, last_component (arg
));
743 strip_trailing_slashes (arg_base
);
744 /* For 'cp -R source/.. dest', don't copy into 'dest/..'. */
745 arg_base
+= STREQ (arg_base
, "..");
746 dst_name
= file_name_concat (target_directory
, arg_base
,
752 /* make_dir_parents_private failed, so don't even
758 char const *dst_relname
= arg_in_concat
;
759 while (*dst_relname
== '/')
763 ok
&= copy (arg
, dst_name
, target_dirfd
, dst_relname
,
764 new_dst
, x
, ©_into_self
, nullptr);
767 ok
&= re_protect (dst_name
, arg_in_concat
, target_dirfd
,
768 dst_relname
, attr_list
, x
);
775 struct dir_attr
*p
= attr_list
;
776 attr_list
= attr_list
->next
;
784 else /* !target_directory */
786 char const *source
= file
[0];
787 char const *dest
= file
[1];
793 _("with --parents, the destination must be a directory"));
794 usage (EXIT_FAILURE
);
797 /* When the force and backup options have been specified and
798 the source and destination are the same name for an existing
799 regular file, convert the user's command, e.g.,
800 'cp --force --backup foo foo' to 'cp --force foo fooSUFFIX'
801 where SUFFIX is determined by any version control options used. */
803 if (x
->unlink_dest_after_failed_open
804 && x
->backup_type
!= no_backups
805 && STREQ (source
, dest
)
807 && (sb
.st_mode
!= 0 || stat (dest
, &sb
) == 0) && S_ISREG (sb
.st_mode
))
809 static struct cp_options x_tmp
;
811 dest
= find_backup_file_name (AT_FDCWD
, dest
, x
->backup_type
);
812 /* Set x->backup_type to 'no_backups' so that the normal backup
813 mechanism is not used when performing the actual copy.
814 backup_type must be set to 'no_backups' only *after* the above
815 call to find_backup_file_name -- that function uses
816 backup_type to determine the suffix it applies. */
818 x_tmp
.backup_type
= no_backups
;
822 ok
= copy (source
, dest
, AT_FDCWD
, dest
, -new_dst
, x
, &unused
, nullptr);
829 cp_option_init (struct cp_options
*x
)
831 cp_options_default (x
);
832 x
->copy_as_regular
= true;
833 x
->dereference
= DEREF_UNDEFINED
;
834 x
->unlink_dest_before_opening
= false;
835 x
->unlink_dest_after_failed_open
= false;
836 x
->hard_link
= false;
837 x
->interactive
= I_UNSPECIFIED
;
838 x
->move_mode
= false;
839 x
->install_mode
= false;
840 x
->one_file_system
= false;
841 x
->reflink_mode
= REFLINK_AUTO
;
843 x
->preserve_ownership
= false;
844 x
->preserve_links
= false;
845 x
->preserve_mode
= false;
846 x
->preserve_timestamps
= false;
847 x
->explicit_no_preserve_mode
= false;
848 x
->preserve_security_context
= false; /* -a or --preserve=context. */
849 x
->require_preserve_context
= false; /* --preserve=context. */
850 x
->set_security_context
= nullptr; /* -Z, set sys default context. */
851 x
->preserve_xattr
= false;
852 x
->reduce_diagnostics
= false;
853 x
->require_preserve_xattr
= false;
855 x
->data_copy_required
= true;
856 x
->require_preserve
= false;
857 x
->recursive
= false;
858 x
->sparse_mode
= SPARSE_AUTO
;
859 x
->symbolic_link
= false;
864 x
->stdin_tty
= false;
868 x
->keep_directory_symlink
= false;
870 /* By default, refuse to open a dangling destination symlink, because
871 in general one cannot do that safely, give the current semantics of
872 open's O_EXCL flag, (which POSIX doesn't even allow cp to use, btw).
873 But POSIX requires it. */
874 x
->open_dangling_dest_symlink
= getenv ("POSIXLY_CORRECT") != nullptr;
876 x
->dest_info
= nullptr;
877 x
->src_info
= nullptr;
880 /* Given a string, ARG, containing a comma-separated list of arguments
881 to the --preserve option, set the appropriate fields of X to ON_OFF. */
883 decode_preserve_arg (char const *arg
, struct cp_options
*x
, bool on_off
)
895 static enum File_attribute
const preserve_vals
[] =
897 PRESERVE_MODE
, PRESERVE_TIMESTAMPS
,
898 PRESERVE_OWNERSHIP
, PRESERVE_LINK
, PRESERVE_CONTEXT
, PRESERVE_XATTR
,
901 /* Valid arguments to the '--preserve' option. */
902 static char const *const preserve_args
[] =
904 "mode", "timestamps",
905 "ownership", "links", "context", "xattr", "all", nullptr
907 ARGMATCH_VERIFY (preserve_args
, preserve_vals
);
909 char *arg_writable
= xstrdup (arg
);
910 char *s
= arg_writable
;
913 /* find next comma */
914 char *comma
= strchr (s
, ',');
915 enum File_attribute val
;
917 /* If we found a comma, put a NUL in its place and advance. */
922 val
= XARGMATCH (on_off
? "--preserve" : "--no-preserve",
923 s
, preserve_args
, preserve_vals
);
927 x
->preserve_mode
= on_off
;
928 x
->explicit_no_preserve_mode
= !on_off
;
931 case PRESERVE_TIMESTAMPS
:
932 x
->preserve_timestamps
= on_off
;
935 case PRESERVE_OWNERSHIP
:
936 x
->preserve_ownership
= on_off
;
940 x
->preserve_links
= on_off
;
943 case PRESERVE_CONTEXT
:
944 x
->require_preserve_context
= on_off
;
945 x
->preserve_security_context
= on_off
;
949 x
->preserve_xattr
= on_off
;
950 x
->require_preserve_xattr
= on_off
;
954 x
->preserve_mode
= on_off
;
955 x
->preserve_timestamps
= on_off
;
956 x
->preserve_ownership
= on_off
;
957 x
->preserve_links
= on_off
;
958 x
->explicit_no_preserve_mode
= !on_off
;
960 x
->preserve_security_context
= on_off
;
961 x
->preserve_xattr
= on_off
;
975 main (int argc
, char **argv
)
979 bool make_backups
= false;
980 char const *backup_suffix
= nullptr;
981 char *version_control_string
= nullptr;
983 bool copy_contents
= false;
984 char *target_directory
= nullptr;
985 bool no_target_directory
= false;
986 char const *scontext
= nullptr;
987 bool no_clobber
= false;
989 initialize_main (&argc
, &argv
);
990 set_program_name (argv
[0]);
991 setlocale (LC_ALL
, "");
992 bindtextdomain (PACKAGE
, LOCALEDIR
);
993 textdomain (PACKAGE
);
995 atexit (close_stdin
);
997 selinux_enabled
= (0 < is_selinux_enabled ());
1000 while ((c
= getopt_long (argc
, argv
, "abdfHilLnprst:uvxPRS:TZ",
1001 long_opts
, nullptr))
1007 x
.sparse_mode
= XARGMATCH ("--sparse", optarg
,
1008 sparse_type_string
, sparse_type
);
1011 case REFLINK_OPTION
:
1012 if (optarg
== nullptr)
1013 x
.reflink_mode
= REFLINK_ALWAYS
;
1015 x
.reflink_mode
= XARGMATCH ("--reflink", optarg
,
1016 reflink_type_string
, reflink_type
);
1020 /* Like -dR --preserve=all with reduced failure diagnostics. */
1021 x
.dereference
= DEREF_NEVER
;
1022 x
.preserve_links
= true;
1023 x
.preserve_ownership
= true;
1024 x
.preserve_mode
= true;
1025 x
.preserve_timestamps
= true;
1026 x
.require_preserve
= true;
1027 if (selinux_enabled
)
1028 x
.preserve_security_context
= true;
1029 x
.preserve_xattr
= true;
1030 x
.reduce_diagnostics
= true;
1035 make_backups
= true;
1037 version_control_string
= optarg
;
1040 case ATTRIBUTES_ONLY_OPTION
:
1041 x
.data_copy_required
= false;
1045 x
.debug
= x
.verbose
= true;
1048 case COPY_CONTENTS_OPTION
:
1049 copy_contents
= true;
1053 x
.preserve_links
= true;
1054 x
.dereference
= DEREF_NEVER
;
1058 x
.unlink_dest_after_failed_open
= true;
1062 x
.dereference
= DEREF_COMMAND_LINE_ARGUMENTS
;
1066 x
.interactive
= I_ASK_USER
;
1074 x
.dereference
= DEREF_ALWAYS
;
1078 x
.interactive
= I_ALWAYS_SKIP
;
1084 x
.dereference
= DEREF_NEVER
;
1087 case NO_PRESERVE_ATTRIBUTES_OPTION
:
1088 decode_preserve_arg (optarg
, &x
, false);
1091 case PRESERVE_ATTRIBUTES_OPTION
:
1092 if (optarg
== nullptr)
1094 /* Fall through to the case for 'p' below. */
1098 decode_preserve_arg (optarg
, &x
, true);
1099 x
.require_preserve
= true;
1105 x
.preserve_ownership
= true;
1106 x
.preserve_mode
= true;
1107 x
.preserve_timestamps
= true;
1108 x
.require_preserve
= true;
1111 case PARENTS_OPTION
:
1112 parents_option
= true;
1120 case UNLINK_DEST_BEFORE_OPENING
:
1121 x
.unlink_dest_before_opening
= true;
1124 case STRIP_TRAILING_SLASHES_OPTION
:
1125 remove_trailing_slashes
= true;
1129 x
.symbolic_link
= true;
1133 if (target_directory
)
1134 error (EXIT_FAILURE
, 0,
1135 _("multiple target directories specified"));
1136 target_directory
= optarg
;
1140 no_target_directory
= true;
1144 if (! no_clobber
) /* -n > -u */
1146 enum Update_type update_opt
= UPDATE_OLDER
;
1148 update_opt
= XARGMATCH ("--update", optarg
,
1149 update_type_string
, update_type
);
1150 if (update_opt
== UPDATE_ALL
)
1152 /* Default cp operation. */
1154 x
.interactive
= I_UNSPECIFIED
;
1156 else if (update_opt
== UPDATE_NONE
)
1159 x
.interactive
= I_ALWAYS_SKIP
;
1161 else if (update_opt
== UPDATE_NONE_FAIL
)
1164 x
.interactive
= I_ALWAYS_NO
;
1166 else if (update_opt
== UPDATE_OLDER
)
1169 x
.interactive
= I_UNSPECIFIED
;
1178 case KEEP_DIRECTORY_SYMLINK_OPTION
:
1179 x
.keep_directory_symlink
= true;
1183 x
.one_file_system
= true;
1187 /* politely decline if we're not on a selinux-enabled kernel. */
1188 if (selinux_enabled
)
1194 x
.set_security_context
= selabel_open (SELABEL_CTX_FILE
,
1196 if (! x
.set_security_context
)
1197 error (0, errno
, _("warning: ignoring --context"));
1203 _("warning: ignoring --context; "
1204 "it requires an SELinux-enabled kernel"));
1209 make_backups
= true;
1210 backup_suffix
= optarg
;
1213 case_GETOPT_HELP_CHAR
;
1215 case_GETOPT_VERSION_CHAR (PROGRAM_NAME
, AUTHORS
);
1218 usage (EXIT_FAILURE
);
1222 /* With --sparse=never, disable reflinking so we create a non sparse copy.
1223 This will also have the effect of disabling copy offload as that may
1224 propagate holes. For e.g. FreeBSD documents that copy_file_range()
1225 will try to propagate holes. */
1226 if (x
.reflink_mode
== REFLINK_AUTO
&& x
.sparse_mode
== SPARSE_NEVER
)
1227 x
.reflink_mode
= REFLINK_NEVER
;
1229 if (x
.hard_link
&& x
.symbolic_link
)
1231 error (0, 0, _("cannot make both hard and symbolic links"));
1232 usage (EXIT_FAILURE
);
1236 && (x
.interactive
== I_ALWAYS_SKIP
1237 || x
.interactive
== I_ALWAYS_NO
))
1240 _("--backup is mutually exclusive with -n or --update=none-fail"));
1241 usage (EXIT_FAILURE
);
1244 if (x
.reflink_mode
== REFLINK_ALWAYS
&& x
.sparse_mode
!= SPARSE_AUTO
)
1246 error (0, 0, _("--reflink can be used only with --sparse=auto"));
1247 usage (EXIT_FAILURE
);
1250 x
.backup_type
= (make_backups
1251 ? xget_version (_("backup type"),
1252 version_control_string
)
1254 set_simple_backup_suffix (backup_suffix
);
1256 if (x
.dereference
== DEREF_UNDEFINED
)
1258 if (x
.recursive
&& ! x
.hard_link
)
1259 /* This is compatible with FreeBSD. */
1260 x
.dereference
= DEREF_NEVER
;
1262 x
.dereference
= DEREF_ALWAYS
;
1266 x
.copy_as_regular
= copy_contents
;
1268 /* Ensure -Z overrides -a. */
1269 if ((x
.set_security_context
|| scontext
)
1270 && ! x
.require_preserve_context
)
1271 x
.preserve_security_context
= false;
1273 if (x
.preserve_security_context
&& (x
.set_security_context
|| scontext
))
1274 error (EXIT_FAILURE
, 0,
1275 _("cannot set target context and preserve it"));
1277 if (x
.require_preserve_context
&& ! selinux_enabled
)
1278 error (EXIT_FAILURE
, 0,
1279 _("cannot preserve security context "
1280 "without an SELinux-enabled kernel"));
1282 /* FIXME: This handles new files. But what about existing files?
1283 I.e., if updating a tree, new files would have the specified context,
1284 but shouldn't existing files be updated for consistency like this?
1285 if (scontext && !restorecon (nullptr, dst_path, 0))
1288 if (scontext
&& setfscreatecon (scontext
) < 0)
1289 error (EXIT_FAILURE
, errno
,
1290 _("failed to set default file creation context to %s"),
1294 if (x
.require_preserve_xattr
)
1295 error (EXIT_FAILURE
, 0, _("cannot preserve extended attributes, cp is "
1296 "built without xattr support"));
1299 /* Allocate space for remembering copied and created files. */
1303 ok
= do_copy (argc
- optind
, argv
+ optind
,
1304 target_directory
, no_target_directory
, &x
);
1306 main_exit (ok
? EXIT_SUCCESS
: EXIT_FAILURE
);