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'},
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 ensure no existing files overwritten, and fail\n\
199 silently instead. See also --update\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,older(default)}. See below\n\
232 -u equivalent to --update[=older]\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;
988 initialize_main (&argc
, &argv
);
989 set_program_name (argv
[0]);
990 setlocale (LC_ALL
, "");
991 bindtextdomain (PACKAGE
, LOCALEDIR
);
992 textdomain (PACKAGE
);
994 atexit (close_stdin
);
996 selinux_enabled
= (0 < is_selinux_enabled ());
999 while ((c
= getopt_long (argc
, argv
, "abdfHilLnprst:uvxPRS:TZ",
1000 long_opts
, nullptr))
1006 x
.sparse_mode
= XARGMATCH ("--sparse", optarg
,
1007 sparse_type_string
, sparse_type
);
1010 case REFLINK_OPTION
:
1011 if (optarg
== nullptr)
1012 x
.reflink_mode
= REFLINK_ALWAYS
;
1014 x
.reflink_mode
= XARGMATCH ("--reflink", optarg
,
1015 reflink_type_string
, reflink_type
);
1019 /* Like -dR --preserve=all with reduced failure diagnostics. */
1020 x
.dereference
= DEREF_NEVER
;
1021 x
.preserve_links
= true;
1022 x
.preserve_ownership
= true;
1023 x
.preserve_mode
= true;
1024 x
.preserve_timestamps
= true;
1025 x
.require_preserve
= true;
1026 if (selinux_enabled
)
1027 x
.preserve_security_context
= true;
1028 x
.preserve_xattr
= true;
1029 x
.reduce_diagnostics
= true;
1034 make_backups
= true;
1036 version_control_string
= optarg
;
1039 case ATTRIBUTES_ONLY_OPTION
:
1040 x
.data_copy_required
= false;
1044 x
.debug
= x
.verbose
= true;
1047 case COPY_CONTENTS_OPTION
:
1048 copy_contents
= true;
1052 x
.preserve_links
= true;
1053 x
.dereference
= DEREF_NEVER
;
1057 x
.unlink_dest_after_failed_open
= true;
1061 x
.dereference
= DEREF_COMMAND_LINE_ARGUMENTS
;
1065 x
.interactive
= I_ASK_USER
;
1073 x
.dereference
= DEREF_ALWAYS
;
1077 x
.interactive
= I_ALWAYS_NO
;
1081 x
.dereference
= DEREF_NEVER
;
1084 case NO_PRESERVE_ATTRIBUTES_OPTION
:
1085 decode_preserve_arg (optarg
, &x
, false);
1088 case PRESERVE_ATTRIBUTES_OPTION
:
1089 if (optarg
== nullptr)
1091 /* Fall through to the case for 'p' below. */
1095 decode_preserve_arg (optarg
, &x
, true);
1096 x
.require_preserve
= true;
1102 x
.preserve_ownership
= true;
1103 x
.preserve_mode
= true;
1104 x
.preserve_timestamps
= true;
1105 x
.require_preserve
= true;
1108 case PARENTS_OPTION
:
1109 parents_option
= true;
1117 case UNLINK_DEST_BEFORE_OPENING
:
1118 x
.unlink_dest_before_opening
= true;
1121 case STRIP_TRAILING_SLASHES_OPTION
:
1122 remove_trailing_slashes
= true;
1126 x
.symbolic_link
= true;
1130 if (target_directory
)
1131 error (EXIT_FAILURE
, 0,
1132 _("multiple target directories specified"));
1133 target_directory
= optarg
;
1137 no_target_directory
= true;
1141 if (optarg
== nullptr)
1143 else if (x
.interactive
!= I_ALWAYS_NO
) /* -n takes precedence. */
1145 enum Update_type update_opt
;
1146 update_opt
= XARGMATCH ("--update", optarg
,
1147 update_type_string
, update_type
);
1148 if (update_opt
== UPDATE_ALL
)
1150 /* Default cp operation. */
1152 x
.interactive
= I_UNSPECIFIED
;
1154 else if (update_opt
== UPDATE_NONE
)
1157 x
.interactive
= I_ALWAYS_SKIP
;
1159 else if (update_opt
== UPDATE_OLDER
)
1162 x
.interactive
= I_UNSPECIFIED
;
1171 case KEEP_DIRECTORY_SYMLINK_OPTION
:
1172 x
.keep_directory_symlink
= true;
1176 x
.one_file_system
= true;
1180 /* politely decline if we're not on a selinux-enabled kernel. */
1181 if (selinux_enabled
)
1187 x
.set_security_context
= selabel_open (SELABEL_CTX_FILE
,
1189 if (! x
.set_security_context
)
1190 error (0, errno
, _("warning: ignoring --context"));
1196 _("warning: ignoring --context; "
1197 "it requires an SELinux-enabled kernel"));
1202 make_backups
= true;
1203 backup_suffix
= optarg
;
1206 case_GETOPT_HELP_CHAR
;
1208 case_GETOPT_VERSION_CHAR (PROGRAM_NAME
, AUTHORS
);
1211 usage (EXIT_FAILURE
);
1215 /* With --sparse=never, disable reflinking so we create a non sparse copy.
1216 This will also have the effect of disabling copy offload as that may
1217 propagate holes. For e.g. FreeBSD documents that copy_file_range()
1218 will try to propagate holes. */
1219 if (x
.reflink_mode
== REFLINK_AUTO
&& x
.sparse_mode
== SPARSE_NEVER
)
1220 x
.reflink_mode
= REFLINK_NEVER
;
1222 if (x
.hard_link
&& x
.symbolic_link
)
1224 error (0, 0, _("cannot make both hard and symbolic links"));
1225 usage (EXIT_FAILURE
);
1228 if (x
.interactive
== I_ALWAYS_NO
)
1231 if (make_backups
&& x
.interactive
== I_ALWAYS_NO
)
1234 _("options --backup and --no-clobber are mutually exclusive"));
1235 usage (EXIT_FAILURE
);
1238 if (x
.reflink_mode
== REFLINK_ALWAYS
&& x
.sparse_mode
!= SPARSE_AUTO
)
1240 error (0, 0, _("--reflink can be used only with --sparse=auto"));
1241 usage (EXIT_FAILURE
);
1244 x
.backup_type
= (make_backups
1245 ? xget_version (_("backup type"),
1246 version_control_string
)
1248 set_simple_backup_suffix (backup_suffix
);
1250 if (x
.dereference
== DEREF_UNDEFINED
)
1252 if (x
.recursive
&& ! x
.hard_link
)
1253 /* This is compatible with FreeBSD. */
1254 x
.dereference
= DEREF_NEVER
;
1256 x
.dereference
= DEREF_ALWAYS
;
1260 x
.copy_as_regular
= copy_contents
;
1262 /* Ensure -Z overrides -a. */
1263 if ((x
.set_security_context
|| scontext
)
1264 && ! x
.require_preserve_context
)
1265 x
.preserve_security_context
= false;
1267 if (x
.preserve_security_context
&& (x
.set_security_context
|| scontext
))
1268 error (EXIT_FAILURE
, 0,
1269 _("cannot set target context and preserve it"));
1271 if (x
.require_preserve_context
&& ! selinux_enabled
)
1272 error (EXIT_FAILURE
, 0,
1273 _("cannot preserve security context "
1274 "without an SELinux-enabled kernel"));
1276 /* FIXME: This handles new files. But what about existing files?
1277 I.e., if updating a tree, new files would have the specified context,
1278 but shouldn't existing files be updated for consistency like this?
1279 if (scontext && !restorecon (nullptr, dst_path, 0))
1282 if (scontext
&& setfscreatecon (scontext
) < 0)
1283 error (EXIT_FAILURE
, errno
,
1284 _("failed to set default file creation context to %s"),
1288 if (x
.require_preserve_xattr
)
1289 error (EXIT_FAILURE
, 0, _("cannot preserve extended attributes, cp is "
1290 "built without xattr support"));
1293 /* Allocate space for remembering copied and created files. */
1297 ok
= do_copy (argc
- optind
, argv
+ optind
,
1298 target_directory
, no_target_directory
, &x
);
1300 main_exit (ok
? EXIT_SUCCESS
: EXIT_FAILURE
);