tests: add fold(1) test for --bytes option
[coreutils.git] / src / cp.c
blob1c4fd5c20cc65e89a1e59466bfcfb5be2a78c90b
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", "none-fail", "older", nullptr
109 static enum Update_type const update_type[] =
111 UPDATE_ALL, UPDATE_NONE, UPDATE_NONE_FAIL, 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}
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 (deprecated) silently skip existing files.\n\
199 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,none-fail,older(default)}\n\
232 -u equivalent to --update[=older]. See below\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 (xcopy_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;
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 ());
998 cp_option_init (&x);
1000 while ((c = getopt_long (argc, argv, "abdfHilLnprst:uvxPRS:TZ",
1001 long_opts, nullptr))
1002 != -1)
1004 switch (c)
1006 case SPARSE_OPTION:
1007 x.sparse_mode = XARGMATCH ("--sparse", optarg,
1008 sparse_type_string, sparse_type);
1009 break;
1011 case REFLINK_OPTION:
1012 if (optarg == nullptr)
1013 x.reflink_mode = REFLINK_ALWAYS;
1014 else
1015 x.reflink_mode = XARGMATCH ("--reflink", optarg,
1016 reflink_type_string, reflink_type);
1017 break;
1019 case 'a':
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;
1031 x.recursive = true;
1032 break;
1034 case 'b':
1035 make_backups = true;
1036 if (optarg)
1037 version_control_string = optarg;
1038 break;
1040 case ATTRIBUTES_ONLY_OPTION:
1041 x.data_copy_required = false;
1042 break;
1044 case DEBUG_OPTION:
1045 x.debug = x.verbose = true;
1046 break;
1048 case COPY_CONTENTS_OPTION:
1049 copy_contents = true;
1050 break;
1052 case 'd':
1053 x.preserve_links = true;
1054 x.dereference = DEREF_NEVER;
1055 break;
1057 case 'f':
1058 x.unlink_dest_after_failed_open = true;
1059 break;
1061 case 'H':
1062 x.dereference = DEREF_COMMAND_LINE_ARGUMENTS;
1063 break;
1065 case 'i':
1066 x.interactive = I_ASK_USER;
1067 break;
1069 case 'l':
1070 x.hard_link = true;
1071 break;
1073 case 'L':
1074 x.dereference = DEREF_ALWAYS;
1075 break;
1077 case 'n':
1078 x.interactive = I_ALWAYS_SKIP;
1079 no_clobber = true;
1080 x.update = false;
1081 break;
1083 case 'P':
1084 x.dereference = DEREF_NEVER;
1085 break;
1087 case NO_PRESERVE_ATTRIBUTES_OPTION:
1088 decode_preserve_arg (optarg, &x, false);
1089 break;
1091 case PRESERVE_ATTRIBUTES_OPTION:
1092 if (optarg == nullptr)
1094 /* Fall through to the case for 'p' below. */
1096 else
1098 decode_preserve_arg (optarg, &x, true);
1099 x.require_preserve = true;
1100 break;
1102 FALLTHROUGH;
1104 case 'p':
1105 x.preserve_ownership = true;
1106 x.preserve_mode = true;
1107 x.preserve_timestamps = true;
1108 x.require_preserve = true;
1109 break;
1111 case PARENTS_OPTION:
1112 parents_option = true;
1113 break;
1115 case 'r':
1116 case 'R':
1117 x.recursive = true;
1118 break;
1120 case UNLINK_DEST_BEFORE_OPENING:
1121 x.unlink_dest_before_opening = true;
1122 break;
1124 case STRIP_TRAILING_SLASHES_OPTION:
1125 remove_trailing_slashes = true;
1126 break;
1128 case 's':
1129 x.symbolic_link = true;
1130 break;
1132 case 't':
1133 if (target_directory)
1134 error (EXIT_FAILURE, 0,
1135 _("multiple target directories specified"));
1136 target_directory = optarg;
1137 break;
1139 case 'T':
1140 no_target_directory = true;
1141 break;
1143 case 'u':
1144 if (! no_clobber) /* -n > -u */
1146 enum Update_type update_opt = UPDATE_OLDER;
1147 if (optarg)
1148 update_opt = XARGMATCH ("--update", optarg,
1149 update_type_string, update_type);
1150 if (update_opt == UPDATE_ALL)
1152 /* Default cp operation. */
1153 x.update = false;
1154 x.interactive = I_UNSPECIFIED;
1156 else if (update_opt == UPDATE_NONE)
1158 x.update = false;
1159 x.interactive = I_ALWAYS_SKIP;
1161 else if (update_opt == UPDATE_NONE_FAIL)
1163 x.update = false;
1164 x.interactive = I_ALWAYS_NO;
1166 else if (update_opt == UPDATE_OLDER)
1168 x.update = true;
1169 x.interactive = I_UNSPECIFIED;
1172 break;
1174 case 'v':
1175 x.verbose = true;
1176 break;
1178 case KEEP_DIRECTORY_SYMLINK_OPTION:
1179 x.keep_directory_symlink = true;
1180 break;
1182 case 'x':
1183 x.one_file_system = true;
1184 break;
1186 case 'Z':
1187 /* politely decline if we're not on a selinux-enabled kernel. */
1188 if (selinux_enabled)
1190 if (optarg)
1191 scontext = optarg;
1192 else
1194 x.set_security_context = selabel_open (SELABEL_CTX_FILE,
1195 nullptr, 0);
1196 if (! x.set_security_context)
1197 error (0, errno, _("warning: ignoring --context"));
1200 else if (optarg)
1202 error (0, 0,
1203 _("warning: ignoring --context; "
1204 "it requires an SELinux-enabled kernel"));
1206 break;
1208 case 'S':
1209 make_backups = true;
1210 backup_suffix = optarg;
1211 break;
1213 case_GETOPT_HELP_CHAR;
1215 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
1217 default:
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);
1235 if (make_backups
1236 && (x.interactive == I_ALWAYS_SKIP
1237 || x.interactive == I_ALWAYS_NO))
1239 error (0, 0,
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)
1253 : no_backups);
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;
1261 else
1262 x.dereference = DEREF_ALWAYS;
1265 if (x.recursive)
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))
1286 error (...);
1288 if (scontext && setfscreatecon (scontext) < 0)
1289 error (EXIT_FAILURE, errno,
1290 _("failed to set default file creation context to %s"),
1291 quote (scontext));
1293 #if !USE_XATTR
1294 if (x.require_preserve_xattr)
1295 error (EXIT_FAILURE, 0, _("cannot preserve extended attributes, cp is "
1296 "built without xattr support"));
1297 #endif
1299 /* Allocate space for remembering copied and created files. */
1301 hash_init ();
1303 ok = do_copy (argc - optind, argv + optind,
1304 target_directory, no_target_directory, &x);
1306 main_exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);