maint: avoid sc_tight_scope failure in sort.c
[coreutils.git] / src / cp.c
blob0355ed97f6f04c52a250e69c7b01648184828a41
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. */
19 #include <config.h>
20 #include <stdio.h>
21 #include <sys/types.h>
22 #include <getopt.h>
23 #include <selinux/label.h>
25 #include "system.h"
26 #include "argmatch.h"
27 #include "assure.h"
28 #include "backupfile.h"
29 #include "copy.h"
30 #include "cp-hash.h"
31 #include "filenamecat.h"
32 #include "ignore-value.h"
33 #include "quote.h"
34 #include "stat-time.h"
35 #include "targetdir.h"
36 #include "utimens.h"
37 #include "acl.h"
39 /* The official name of this program (e.g., no 'g' prefix). */
40 #define PROGRAM_NAME "cp"
42 #define AUTHORS \
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. */
50 struct dir_attr
52 struct stat st;
53 bool restore_mode;
54 size_t slash_offset;
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. */
60 enum
62 ATTRIBUTES_ONLY_OPTION = CHAR_MAX + 1,
63 COPY_CONTENTS_OPTION,
64 DEBUG_OPTION,
65 NO_PRESERVE_ATTRIBUTES_OPTION,
66 PARENTS_OPTION,
67 PRESERVE_ATTRIBUTES_OPTION,
68 REFLINK_OPTION,
69 SPARSE_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}
153 void
154 usage (int status)
156 if (status != EXIT_SUCCESS)
157 emit_try_help ();
158 else
160 printf (_("\
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);
166 fputs (_("\
167 Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\
168 "), stdout);
170 emit_mandatory_arg_note ();
172 fputs (_("\
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\
180 "), stdout);
181 fputs (_("\
182 --debug explain how a file is copied. Implies -v\n\
183 "), stdout);
184 fputs (_("\
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\
190 option)\n\
191 -H follow command-line symbolic links in SOURCE\n\
192 "), stdout);
193 fputs (_("\
194 -l, --link hard link files instead of copying\n\
195 -L, --dereference always follow symbolic links in SOURCE\n\
196 "), stdout);
197 fputs (_("\
198 -n, --no-clobber ensure no existing files overwritten, and fail\n\
199 silently instead. See also --update\n\
200 "), stdout);
201 fputs (_("\
202 -P, --no-dereference never follow symbolic links in SOURCE\n\
203 "), stdout);
204 fputs (_("\
205 -p same as --preserve=mode,ownership,timestamps\n\
206 --preserve[=ATTR_LIST] preserve the specified attributes\n\
207 "), stdout);
208 fputs (_("\
209 --no-preserve=ATTR_LIST don't preserve the specified attributes\n\
210 --parents use full source file name under DIRECTORY\n\
211 "), stdout);
212 fputs (_("\
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)\
217 \n"), stdout);
218 fputs (_("\
219 --sparse=WHEN control creation of sparse files. See below\n\
220 --strip-trailing-slashes remove any trailing slashes from each SOURCE\n\
221 argument\n\
222 "), stdout);
223 fputs (_("\
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\
228 "), stdout);
229 fputs (_("\
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\
233 "), stdout);
234 fputs (_("\
235 -v, --verbose explain what is being done\n\
236 "), stdout);
237 fputs (_("\
238 --keep-directory-symlink follow existing symlinks to directories\n\
239 "), stdout);
240 fputs (_("\
241 -x, --one-file-system stay on this file system\n\
242 "), stdout);
243 fputs (_("\
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\
248 "), stdout);
249 fputs (HELP_OPTION_DESCRIPTION, stdout);
250 fputs (VERSION_OPTION_DESCRIPTION, stdout);
251 fputs (_("\
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\
257 attributes.\n\
258 "), stdout);
259 fputs (_("\
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\
266 "), stdout);
267 emit_update_parameters_note ();
268 fputs (_("\
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\
274 "), stdout);
275 emit_backup_suffix_note ();
276 fputs (_("\
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\
280 regular file.\n\
281 "), stdout);
282 emit_ancillary_info (PROGRAM_NAME);
284 exit (status);
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
305 when done. */
307 static bool
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)
312 struct dir_attr *p;
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"),
342 quoteaf (dst_name));
343 return false;
347 if (x->preserve_ownership)
349 if (lchownat (dst_dirfd, relname, p->st.st_uid, p->st.st_gid)
350 != 0)
352 if (! chown_failure_ok (x))
354 error (0, errno, _("failed to preserve ownership for %s"),
355 quoteaf (dst_name));
356 return false;
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)
367 return false;
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"),
374 quoteaf (dst_name));
375 return false;
379 dst_name[p->slash_offset] = '/';
381 return true;
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. */
404 static bool
405 make_dir_parents_private (char const *const_dir, size_t src_offset,
406 int dst_dirfd,
407 char const *verbose_fmt_string,
408 struct dir_attr **attr_list, bool *new_dst,
409 const struct cp_options *x)
411 struct stat stats;
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)
422 return true;
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 == '/')
433 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. */
441 char *slash;
443 slash = src;
444 while (*slash == '/')
445 slash++;
446 dst_reldir = slash;
448 while ((slash = strchr (slash, '/')))
450 struct dir_attr *new;
451 bool missing_dir;
453 *slash = '\0';
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. */
461 struct stat src_st;
462 int src_errno = (stat (src, &src_st) != 0
463 ? errno
464 : S_ISDIR (src_st.st_mode)
466 : ENOTDIR);
467 if (src_errno)
469 error (0, src_errno, _("failed to get attributes of %s"),
470 quoteaf (src));
471 return false;
474 new = xmalloc (sizeof *new);
475 new->st = src_st;
476 new->slash_offset = slash - dir;
477 new->restore_mode = false;
478 new->next = *attr_list;
479 *attr_list = new;
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,
485 missing_dir, x))
486 return false;
488 if (missing_dir)
490 mode_t src_mode;
491 mode_t omitted_permissions;
492 mode_t mkdir_mode;
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. */
499 *new_dst = true;
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
507 ? S_IRWXG | S_IRWXO
508 : x->preserve_mode
509 ? S_IWGRP | S_IWOTH
510 : 0));
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"),
521 quoteaf (dir));
522 return false;
524 else
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"),
537 quoteaf (dir));
538 return false;
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"),
563 quoteaf (dir));
564 return false;
568 else if (!S_ISDIR (stats.st_mode))
570 error (0, 0, _("%s exists but is not a directory"),
571 quoteaf (dir));
572 return false;
574 else
575 *new_dst = false;
577 /* For existing dirs, set the security context as per that already
578 set for the process global context. */
579 if (! *new_dst
580 && (x->set_security_context || x->preserve_security_context))
582 if (! set_file_security_ctx (dir, false, x)
583 && x->require_preserve_context)
584 return false;
587 *slash++ = '/';
589 /* Avoid unnecessary calls to 'stat' when given
590 file names containing multiple adjacent slashes. */
591 while (*slash == '/')
592 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));
601 return false;
603 else
605 *new_dst = false;
607 return true;
610 /* Scan the arguments, and copy each by calling copy.
611 Return true if successful. */
613 static bool
614 do_copy (int n_files, char **file, char const *target_directory,
615 bool no_target_directory, struct cp_options *x)
617 struct stat sb;
618 bool new_dst = false;
619 bool ok = true;
621 if (n_files <= !target_directory)
623 if (n_files <= 0)
624 error (0, 0, _("missing file operand"));
625 else
626 error (0, 0, _("missing destination file operand after %s"),
627 quoteaf (file[0]));
628 usage (EXIT_FAILURE);
631 sb.st_mode = 0;
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)"));
639 if (2 < n_files)
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));
652 else
654 char const *lastfile = file[n_files - 1];
655 int fd = target_directory_operand (lastfile, &sb);
656 if (target_dirfd_valid (fd))
658 target_dirfd = fd;
659 target_directory = lastfile;
660 n_files--;
662 else
664 int err = errno;
665 if (err == ENOENT)
666 new_dst = true;
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. */
677 if (2 < n_files
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. */
694 if (2 <= n_files)
696 dest_info_init (x);
697 src_info_init (x);
700 for (int i = 0; i < n_files; i++)
702 char *dst_name;
703 bool parent_exists = true; /* True if dir_name (dst_name) exists. */
704 struct dir_attr *attr_list;
705 char *arg_in_concat;
706 char *arg = file[i];
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);
713 if (parents_option)
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,
727 &arg_in_concat);
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. */
732 parent_exists =
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));
738 else
740 char *arg_base;
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,
747 &arg_in_concat);
750 if (!parent_exists)
752 /* make_dir_parents_private failed, so don't even
753 attempt the copy. */
754 ok = false;
756 else
758 char const *dst_relname = arg_in_concat;
759 while (*dst_relname == '/')
760 dst_relname++;
762 bool copy_into_self;
763 ok &= copy (arg, dst_name, target_dirfd, dst_relname,
764 new_dst, x, &copy_into_self, nullptr);
766 if (parents_option)
767 ok &= re_protect (dst_name, arg_in_concat, target_dirfd,
768 dst_relname, attr_list, x);
771 if (parents_option)
773 while (attr_list)
775 struct dir_attr *p = attr_list;
776 attr_list = attr_list->next;
777 free (p);
781 free (dst_name);
784 else /* !target_directory */
786 char const *source = file[0];
787 char const *dest = file[1];
788 bool unused;
790 if (parents_option)
792 error (0, 0,
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)
806 && !new_dst
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. */
817 x_tmp = *x;
818 x_tmp.backup_type = no_backups;
819 x = &x_tmp;
822 ok = copy (source, dest, AT_FDCWD, dest, -new_dst, x, &unused, nullptr);
825 return ok;
828 static void
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;
860 x->set_mode = false;
861 x->mode = 0;
863 /* Not used. */
864 x->stdin_tty = false;
866 x->update = false;
867 x->verbose = 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. */
882 static void
883 decode_preserve_arg (char const *arg, struct cp_options *x, bool on_off)
885 enum File_attribute
887 PRESERVE_MODE,
888 PRESERVE_TIMESTAMPS,
889 PRESERVE_OWNERSHIP,
890 PRESERVE_LINK,
891 PRESERVE_CONTEXT,
892 PRESERVE_XATTR,
893 PRESERVE_ALL
895 static enum File_attribute const preserve_vals[] =
897 PRESERVE_MODE, PRESERVE_TIMESTAMPS,
898 PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_CONTEXT, PRESERVE_XATTR,
899 PRESERVE_ALL
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. */
918 if (comma)
919 *comma++ = 0;
921 /* process S. */
922 val = XARGMATCH (on_off ? "--preserve" : "--no-preserve",
923 s, preserve_args, preserve_vals);
924 switch (val)
926 case PRESERVE_MODE:
927 x->preserve_mode = on_off;
928 x->explicit_no_preserve_mode = !on_off;
929 break;
931 case PRESERVE_TIMESTAMPS:
932 x->preserve_timestamps = on_off;
933 break;
935 case PRESERVE_OWNERSHIP:
936 x->preserve_ownership = on_off;
937 break;
939 case PRESERVE_LINK:
940 x->preserve_links = on_off;
941 break;
943 case PRESERVE_CONTEXT:
944 x->require_preserve_context = on_off;
945 x->preserve_security_context = on_off;
946 break;
948 case PRESERVE_XATTR:
949 x->preserve_xattr = on_off;
950 x->require_preserve_xattr = on_off;
951 break;
953 case PRESERVE_ALL:
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;
959 if (selinux_enabled)
960 x->preserve_security_context = on_off;
961 x->preserve_xattr = on_off;
962 break;
964 default:
965 affirm (false);
967 s = comma;
969 while (s);
971 free (arg_writable);
975 main (int argc, char **argv)
977 int c;
978 bool ok;
979 bool make_backups = false;
980 char const *backup_suffix = nullptr;
981 char *version_control_string = nullptr;
982 struct cp_options x;
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 ());
997 cp_option_init (&x);
999 while ((c = getopt_long (argc, argv, "abdfHilLnprst:uvxPRS:TZ",
1000 long_opts, nullptr))
1001 != -1)
1003 switch (c)
1005 case SPARSE_OPTION:
1006 x.sparse_mode = XARGMATCH ("--sparse", optarg,
1007 sparse_type_string, sparse_type);
1008 break;
1010 case REFLINK_OPTION:
1011 if (optarg == nullptr)
1012 x.reflink_mode = REFLINK_ALWAYS;
1013 else
1014 x.reflink_mode = XARGMATCH ("--reflink", optarg,
1015 reflink_type_string, reflink_type);
1016 break;
1018 case 'a':
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;
1030 x.recursive = true;
1031 break;
1033 case 'b':
1034 make_backups = true;
1035 if (optarg)
1036 version_control_string = optarg;
1037 break;
1039 case ATTRIBUTES_ONLY_OPTION:
1040 x.data_copy_required = false;
1041 break;
1043 case DEBUG_OPTION:
1044 x.debug = x.verbose = true;
1045 break;
1047 case COPY_CONTENTS_OPTION:
1048 copy_contents = true;
1049 break;
1051 case 'd':
1052 x.preserve_links = true;
1053 x.dereference = DEREF_NEVER;
1054 break;
1056 case 'f':
1057 x.unlink_dest_after_failed_open = true;
1058 break;
1060 case 'H':
1061 x.dereference = DEREF_COMMAND_LINE_ARGUMENTS;
1062 break;
1064 case 'i':
1065 x.interactive = I_ASK_USER;
1066 break;
1068 case 'l':
1069 x.hard_link = true;
1070 break;
1072 case 'L':
1073 x.dereference = DEREF_ALWAYS;
1074 break;
1076 case 'n':
1077 x.interactive = I_ALWAYS_NO;
1078 break;
1080 case 'P':
1081 x.dereference = DEREF_NEVER;
1082 break;
1084 case NO_PRESERVE_ATTRIBUTES_OPTION:
1085 decode_preserve_arg (optarg, &x, false);
1086 break;
1088 case PRESERVE_ATTRIBUTES_OPTION:
1089 if (optarg == nullptr)
1091 /* Fall through to the case for 'p' below. */
1093 else
1095 decode_preserve_arg (optarg, &x, true);
1096 x.require_preserve = true;
1097 break;
1099 FALLTHROUGH;
1101 case 'p':
1102 x.preserve_ownership = true;
1103 x.preserve_mode = true;
1104 x.preserve_timestamps = true;
1105 x.require_preserve = true;
1106 break;
1108 case PARENTS_OPTION:
1109 parents_option = true;
1110 break;
1112 case 'r':
1113 case 'R':
1114 x.recursive = true;
1115 break;
1117 case UNLINK_DEST_BEFORE_OPENING:
1118 x.unlink_dest_before_opening = true;
1119 break;
1121 case STRIP_TRAILING_SLASHES_OPTION:
1122 remove_trailing_slashes = true;
1123 break;
1125 case 's':
1126 x.symbolic_link = true;
1127 break;
1129 case 't':
1130 if (target_directory)
1131 error (EXIT_FAILURE, 0,
1132 _("multiple target directories specified"));
1133 target_directory = optarg;
1134 break;
1136 case 'T':
1137 no_target_directory = true;
1138 break;
1140 case 'u':
1141 if (optarg == nullptr)
1142 x.update = true;
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. */
1151 x.update = false;
1152 x.interactive = I_UNSPECIFIED;
1154 else if (update_opt == UPDATE_NONE)
1156 x.update = false;
1157 x.interactive = I_ALWAYS_SKIP;
1159 else if (update_opt == UPDATE_OLDER)
1161 x.update = true;
1162 x.interactive = I_UNSPECIFIED;
1165 break;
1167 case 'v':
1168 x.verbose = true;
1169 break;
1171 case KEEP_DIRECTORY_SYMLINK_OPTION:
1172 x.keep_directory_symlink = true;
1173 break;
1175 case 'x':
1176 x.one_file_system = true;
1177 break;
1179 case 'Z':
1180 /* politely decline if we're not on a selinux-enabled kernel. */
1181 if (selinux_enabled)
1183 if (optarg)
1184 scontext = optarg;
1185 else
1187 x.set_security_context = selabel_open (SELABEL_CTX_FILE,
1188 nullptr, 0);
1189 if (! x.set_security_context)
1190 error (0, errno, _("warning: ignoring --context"));
1193 else if (optarg)
1195 error (0, 0,
1196 _("warning: ignoring --context; "
1197 "it requires an SELinux-enabled kernel"));
1199 break;
1201 case 'S':
1202 make_backups = true;
1203 backup_suffix = optarg;
1204 break;
1206 case_GETOPT_HELP_CHAR;
1208 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
1210 default:
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)
1229 x.update = false;
1231 if (make_backups && x.interactive == I_ALWAYS_NO)
1233 error (0, 0,
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)
1247 : no_backups);
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;
1255 else
1256 x.dereference = DEREF_ALWAYS;
1259 if (x.recursive)
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))
1280 error (...);
1282 if (scontext && setfscreatecon (scontext) < 0)
1283 error (EXIT_FAILURE, errno,
1284 _("failed to set default file creation context to %s"),
1285 quote (scontext));
1287 #if !USE_XATTR
1288 if (x.require_preserve_xattr)
1289 error (EXIT_FAILURE, 0, _("cannot preserve extended attributes, cp is "
1290 "built without xattr support"));
1291 #endif
1293 /* Allocate space for remembering copied and created files. */
1295 hash_init ();
1297 ok = do_copy (argc - optind, argv + optind,
1298 target_directory, no_target_directory, &x);
1300 main_exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);