1 /* cp.c -- file copying (main routines)
2 Copyright (C) 1989-2023 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 Torbjorn Granlund, David MacKenzie, and Jim Meyering. */
21 #include <sys/types.h>
23 #include <selinux/label.h>
27 #include "backupfile.h"
32 #include "filenamecat.h"
33 #include "ignore-value.h"
35 #include "stat-time.h"
36 #include "targetdir.h"
40 /* The official name of this program (e.g., no 'g' prefix). */
41 #define PROGRAM_NAME "cp"
44 proper_name ("Torbjorn Granlund"), \
45 proper_name ("David MacKenzie"), \
46 proper_name ("Jim Meyering")
48 /* Used by do_copy, make_dir_parents_private, and re_protect
49 to keep a list of leading directories whose protections
50 need to be fixed after copying. */
56 struct dir_attr
*next
;
59 /* For long options that have no equivalent short option, use a
60 non-character as a pseudo short option, starting with CHAR_MAX + 1. */
63 ATTRIBUTES_ONLY_OPTION
= CHAR_MAX
+ 1,
66 NO_PRESERVE_ATTRIBUTES_OPTION
,
68 PRESERVE_ATTRIBUTES_OPTION
,
71 STRIP_TRAILING_SLASHES_OPTION
,
72 UNLINK_DEST_BEFORE_OPENING
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", NULL
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", NULL
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", NULL
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
, NULL
, 'a'},
118 {"attributes-only", no_argument
, NULL
, ATTRIBUTES_ONLY_OPTION
},
119 {"backup", optional_argument
, NULL
, 'b'},
120 {"copy-contents", no_argument
, NULL
, COPY_CONTENTS_OPTION
},
121 {"debug", no_argument
, NULL
, DEBUG_OPTION
},
122 {"dereference", no_argument
, NULL
, 'L'},
123 {"force", no_argument
, NULL
, 'f'},
124 {"interactive", no_argument
, NULL
, 'i'},
125 {"link", no_argument
, NULL
, 'l'},
126 {"no-clobber", no_argument
, NULL
, 'n'},
127 {"no-dereference", no_argument
, NULL
, 'P'},
128 {"no-preserve", required_argument
, NULL
, NO_PRESERVE_ATTRIBUTES_OPTION
},
129 {"no-target-directory", no_argument
, NULL
, 'T'},
130 {"one-file-system", no_argument
, NULL
, 'x'},
131 {"parents", no_argument
, NULL
, PARENTS_OPTION
},
132 {"path", no_argument
, NULL
, PARENTS_OPTION
}, /* Deprecated. */
133 {"preserve", optional_argument
, NULL
, PRESERVE_ATTRIBUTES_OPTION
},
134 {"recursive", no_argument
, NULL
, 'R'},
135 {"remove-destination", no_argument
, NULL
, UNLINK_DEST_BEFORE_OPENING
},
136 {"sparse", required_argument
, NULL
, SPARSE_OPTION
},
137 {"reflink", optional_argument
, NULL
, REFLINK_OPTION
},
138 {"strip-trailing-slashes", no_argument
, NULL
, STRIP_TRAILING_SLASHES_OPTION
},
139 {"suffix", required_argument
, NULL
, 'S'},
140 {"symbolic-link", no_argument
, NULL
, 's'},
141 {"target-directory", required_argument
, NULL
, 't'},
142 {"update", optional_argument
, NULL
, 'u'},
143 {"verbose", no_argument
, NULL
, 'v'},
144 {GETOPT_SELINUX_CONTEXT_OPTION_DECL
},
145 {GETOPT_HELP_OPTION_DECL
},
146 {GETOPT_VERSION_OPTION_DECL
},
153 if (status
!= EXIT_SUCCESS
)
158 Usage: %s [OPTION]... [-T] SOURCE DEST\n\
159 or: %s [OPTION]... SOURCE... DIRECTORY\n\
160 or: %s [OPTION]... -t DIRECTORY SOURCE...\n\
162 program_name
, program_name
, program_name
);
164 Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\
167 emit_mandatory_arg_note ();
170 -a, --archive same as -dR --preserve=all\n\
171 --attributes-only don't copy the file data, just the attributes\n\
172 --backup[=CONTROL] make a backup of each existing destination file\
174 -b like --backup but does not accept an argument\n\
175 --copy-contents copy contents of special files when recursive\n\
176 -d same as --no-dereference --preserve=links\n\
179 --debug explain how a file is copied. Implies -v\n\
182 -f, --force if an existing destination file cannot be\n\
183 opened, remove it and try again (this option\n\
184 is ignored when the -n option is also used)\n\
185 -i, --interactive prompt before overwrite (overrides a previous -n\
188 -H follow command-line symbolic links in SOURCE\n\
191 -l, --link hard link files instead of copying\n\
192 -L, --dereference always follow symbolic links in SOURCE\n\
195 -n, --no-clobber do not overwrite an existing file (overrides a\n\
196 -u or previous -i option). See also --update\n\
199 -P, --no-dereference never follow symbolic links in SOURCE\n\
202 -p same as --preserve=mode,ownership,timestamps\n\
203 --preserve[=ATTR_LIST] preserve the specified attributes\n\
206 --no-preserve=ATTR_LIST don't preserve the specified attributes\n\
207 --parents use full source file name under DIRECTORY\n\
210 -R, -r, --recursive copy directories recursively\n\
211 --reflink[=WHEN] control clone/CoW copies. See below\n\
212 --remove-destination remove each existing destination file before\n\
213 attempting to open it (contrast with --force)\
216 --sparse=WHEN control creation of sparse files. See below\n\
217 --strip-trailing-slashes remove any trailing slashes from each SOURCE\n\
221 -s, --symbolic-link make symbolic links instead of copying\n\
222 -S, --suffix=SUFFIX override the usual backup suffix\n\
223 -t, --target-directory=DIRECTORY copy all SOURCE arguments into DIRECTORY\n\
224 -T, --no-target-directory treat DEST as a normal file\n\
227 --update[=UPDATE] control which existing files are updated;\n\
228 UPDATE={all,none,older(default)}. See below\n\
229 -u equivalent to --update[=older]\n\
232 -v, --verbose explain what is being done\n\
235 -x, --one-file-system stay on this file system\n\
238 -Z set SELinux security context of destination\n\
239 file to default type\n\
240 --context[=CTX] like -Z, or if CTX is specified then set the\n\
241 SELinux or SMACK security context to CTX\n\
243 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
244 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
247 ATTR_LIST is a comma-separated list of attributes. Attributes are 'mode' for\n\
248 permissions (including any ACL and xattr permissions), 'ownership' for user\n\
249 and group, 'timestamps' for file timestamps, 'links' for hard links, 'context'\
250 \nfor security context, 'xattr' for extended attributes, and 'all' for all\n\
255 By default, sparse SOURCE files are detected by a crude heuristic and the\n\
256 corresponding DEST file is made sparse as well. That is the behavior\n\
257 selected by --sparse=auto. Specify --sparse=always to create a sparse DEST\n\
258 file whenever the SOURCE file contains a long enough sequence of zero bytes.\n\
259 Use --sparse=never to inhibit creation of sparse files.\n\
261 emit_update_parameters_note ();
264 When --reflink[=always] is specified, perform a lightweight copy, where the\n\
265 data blocks are copied only when modified. If this is not possible the copy\n\
266 fails, or if --reflink=auto is specified, fall back to a standard copy.\n\
267 Use --reflink=never to ensure a standard copy is performed.\n\
269 emit_backup_suffix_note ();
272 As a special case, cp makes a backup of SOURCE when the force and backup\n\
273 options are given and SOURCE and DEST are the same name for an existing,\n\
276 emit_ancillary_info (PROGRAM_NAME
);
281 /* Ensure that parents of CONST_DST_NAME have correct protections, for
282 the --parents option. This is done after all copying has been
283 completed, to allow permissions that don't include user write/execute.
285 DST_SRC_NAME is the suffix of CONST_DST_NAME that is the source file name,
286 DST_DIRFD+DST_RELNAME is equivalent to CONST_DST_NAME, and
287 DST_RELNAME equals DST_SRC_NAME after skipping any leading '/'s.
289 ATTR_LIST is a null-terminated linked list of structures that
290 indicates the end of the filename of each intermediate directory
291 in CONST_DST_NAME that may need to have its attributes changed.
292 The command 'cp --parents --preserve a/b/c d/e_dir' changes the
293 attributes of the directories d/e_dir/a and d/e_dir/a/b to match
294 the corresponding source directories regardless of whether they
295 existed before the 'cp' command was given.
297 Return true if the parent of CONST_DST_NAME and any intermediate
298 directories specified by ATTR_LIST have the proper permissions
302 re_protect (char const *const_dst_name
, char const *dst_src_name
,
303 int dst_dirfd
, char const *dst_relname
,
304 struct dir_attr
*attr_list
, const struct cp_options
*x
)
307 char *dst_name
; /* A copy of CONST_DST_NAME we can change. */
309 ASSIGN_STRDUPA (dst_name
, const_dst_name
);
311 /* The suffix of DST_NAME that is a copy of the source file name,
312 possibly truncated to name a parent directory. */
313 char const *src_name
= dst_name
+ (dst_src_name
- const_dst_name
);
315 /* Likewise, but with any leading '/'s skipped. */
316 char const *relname
= dst_name
+ (dst_relname
- const_dst_name
);
318 for (p
= attr_list
; p
; p
= p
->next
)
320 dst_name
[p
->slash_offset
] = '\0';
322 /* Adjust the times (and if possible, ownership) for the copy.
323 chown turns off set[ug]id bits for non-root,
324 so do the chmod last. */
326 if (x
->preserve_timestamps
)
328 struct timespec timespec
[2];
330 timespec
[0] = get_stat_atime (&p
->st
);
331 timespec
[1] = get_stat_mtime (&p
->st
);
333 if (utimensat (dst_dirfd
, relname
, timespec
, 0))
335 error (0, errno
, _("failed to preserve times for %s"),
341 if (x
->preserve_ownership
)
343 if (lchownat (dst_dirfd
, relname
, p
->st
.st_uid
, p
->st
.st_gid
)
346 if (! chown_failure_ok (x
))
348 error (0, errno
, _("failed to preserve ownership for %s"),
352 /* Failing to preserve ownership is OK. Still, try to preserve
353 the group, but ignore the possible error. */
354 ignore_value (lchownat (dst_dirfd
, relname
, -1, p
->st
.st_gid
));
358 if (x
->preserve_mode
)
360 if (copy_acl (src_name
, -1, dst_name
, -1, p
->st
.st_mode
) != 0)
363 else if (p
->restore_mode
)
365 if (lchmodat (dst_dirfd
, relname
, p
->st
.st_mode
) != 0)
367 error (0, errno
, _("failed to preserve permissions for %s"),
373 dst_name
[p
->slash_offset
] = '/';
378 /* Ensure that the parent directory of CONST_DIR exists, for
379 the --parents option.
381 SRC_OFFSET is the index in CONST_DIR (which is a destination
382 directory) of the beginning of the source directory name.
383 Create any leading directories that don't already exist.
384 DST_DIRFD is a file descriptor for the target directory.
385 If VERBOSE_FMT_STRING is nonzero, use it as a printf format
386 string for printing a message after successfully making a directory.
387 The format should take two string arguments: the names of the
388 source and destination directories.
389 Creates a linked list of attributes of intermediate directories,
390 *ATTR_LIST, for re_protect to use after calling copy.
391 Sets *NEW_DST if this function creates parent of CONST_DIR.
393 Return true if parent of CONST_DIR exists as a directory with the proper
394 permissions when done. */
396 /* FIXME: Synch this function with the one in ../lib/mkdir-p.c. */
399 make_dir_parents_private (char const *const_dir
, size_t src_offset
,
401 char const *verbose_fmt_string
,
402 struct dir_attr
**attr_list
, bool *new_dst
,
403 const struct cp_options
*x
)
406 char *dir
; /* A copy of CONST_DIR we can change. */
407 char *src
; /* Source name in DIR. */
408 char *dst_dir
; /* Leading directory of DIR. */
409 idx_t dirlen
= dir_len (const_dir
);
413 /* Succeed immediately if the parent of CONST_DIR must already exist,
414 as the target directory has already been checked. */
415 if (dirlen
<= src_offset
)
418 ASSIGN_STRDUPA (dir
, const_dir
);
420 src
= dir
+ src_offset
;
422 dst_dir
= alloca (dirlen
+ 1);
423 memcpy (dst_dir
, dir
, dirlen
);
424 dst_dir
[dirlen
] = '\0';
425 char const *dst_reldir
= dst_dir
+ src_offset
;
426 while (*dst_reldir
== '/')
429 /* XXX: If all dirs are present at the destination,
430 no permissions or security contexts will be updated. */
431 if (fstatat (dst_dirfd
, dst_reldir
, &stats
, 0) != 0)
433 /* A parent of CONST_DIR does not exist.
434 Make all missing intermediate directories. */
438 while (*slash
== '/')
442 while ((slash
= strchr (slash
, '/')))
444 struct dir_attr
*new;
448 missing_dir
= fstatat (dst_dirfd
, dst_reldir
, &stats
, 0) != 0;
450 if (missing_dir
|| x
->preserve_ownership
|| x
->preserve_mode
451 || x
->preserve_timestamps
)
453 /* Add this directory to the list of directories whose
454 modes might need fixing later. */
456 int src_errno
= (stat (src
, &src_st
) != 0
458 : S_ISDIR (src_st
.st_mode
)
463 error (0, src_errno
, _("failed to get attributes of %s"),
468 new = xmalloc (sizeof *new);
470 new->slash_offset
= slash
- dir
;
471 new->restore_mode
= false;
472 new->next
= *attr_list
;
476 /* If required set the default context for created dirs. */
477 if (! set_process_security_ctx (src
, dir
,
478 missing_dir
? new->st
.st_mode
: 0,
485 mode_t omitted_permissions
;
488 /* This component does not exist. We must set
489 *new_dst and new->st.st_mode inside this loop because,
490 for example, in the command 'cp --parents ../a/../b/c e_dir',
491 make_dir_parents_private creates only e_dir/../a if
492 ./b already exists. */
494 src_mode
= new->st
.st_mode
;
496 /* If the ownership or special mode bits might change,
497 omit some permissions at first, so unauthorized users
498 cannot nip in before the file is ready. */
499 omitted_permissions
= (src_mode
500 & (x
->preserve_ownership
506 /* POSIX says mkdir's behavior is implementation-defined when
507 (src_mode & ~S_IRWXUGO) != 0. However, common practice is
508 to ask mkdir to copy all the CHMOD_MODE_BITS, letting mkdir
509 decide what to do with S_ISUID | S_ISGID | S_ISVTX. */
510 mkdir_mode
= x
->explicit_no_preserve_mode
? S_IRWXUGO
: src_mode
;
511 mkdir_mode
&= CHMOD_MODE_BITS
& ~omitted_permissions
;
512 if (mkdirat (dst_dirfd
, dst_reldir
, mkdir_mode
) != 0)
514 error (0, errno
, _("cannot make directory %s"),
520 if (verbose_fmt_string
!= NULL
)
521 printf (verbose_fmt_string
, src
, dir
);
524 /* We need search and write permissions to the new directory
525 for writing the directory's contents. Check if these
526 permissions are there. */
528 if (fstatat (dst_dirfd
, dst_reldir
, &stats
, AT_SYMLINK_NOFOLLOW
))
530 error (0, errno
, _("failed to get attributes of %s"),
536 if (! x
->preserve_mode
)
538 if (omitted_permissions
& ~stats
.st_mode
)
539 omitted_permissions
&= ~ cached_umask ();
540 if (omitted_permissions
& ~stats
.st_mode
541 || (stats
.st_mode
& S_IRWXU
) != S_IRWXU
)
543 new->st
.st_mode
= stats
.st_mode
| omitted_permissions
;
544 new->restore_mode
= true;
548 mode_t accessible
= stats
.st_mode
| S_IRWXU
;
549 if (stats
.st_mode
!= accessible
)
551 /* Make the new directory searchable and writable.
552 The original permissions will be restored later. */
554 if (lchmodat (dst_dirfd
, dst_reldir
, accessible
) != 0)
556 error (0, errno
, _("setting permissions for %s"),
562 else if (!S_ISDIR (stats
.st_mode
))
564 error (0, 0, _("%s exists but is not a directory"),
571 /* For existing dirs, set the security context as per that already
572 set for the process global context. */
574 && (x
->set_security_context
|| x
->preserve_security_context
))
576 if (! set_file_security_ctx (dir
, false, x
)
577 && x
->require_preserve_context
)
583 /* Avoid unnecessary calls to 'stat' when given
584 file names containing multiple adjacent slashes. */
585 while (*slash
== '/')
590 /* We get here if the parent of DIR already exists. */
592 else if (!S_ISDIR (stats
.st_mode
))
594 error (0, 0, _("%s exists but is not a directory"), quoteaf (dst_dir
));
604 /* Scan the arguments, and copy each by calling copy.
605 Return true if successful. */
608 do_copy (int n_files
, char **file
, char const *target_directory
,
609 bool no_target_directory
, struct cp_options
*x
)
612 bool new_dst
= false;
615 if (n_files
<= !target_directory
)
618 error (0, 0, _("missing file operand"));
620 error (0, 0, _("missing destination file operand after %s"),
622 usage (EXIT_FAILURE
);
626 int target_dirfd
= AT_FDCWD
;
627 if (no_target_directory
)
629 if (target_directory
)
630 die (EXIT_FAILURE
, 0,
631 _("cannot combine --target-directory (-t) "
632 "and --no-target-directory (-T)"));
635 error (0, 0, _("extra operand %s"), quoteaf (file
[2]));
636 usage (EXIT_FAILURE
);
639 else if (target_directory
)
641 target_dirfd
= target_directory_operand (target_directory
, &sb
);
642 if (! target_dirfd_valid (target_dirfd
))
643 die (EXIT_FAILURE
, errno
, _("target directory %s"),
644 quoteaf (target_directory
));
648 char const *lastfile
= file
[n_files
- 1];
649 int fd
= target_directory_operand (lastfile
, &sb
);
650 if (target_dirfd_valid (fd
))
653 target_directory
= lastfile
;
662 /* The last operand LASTFILE cannot be opened as a directory.
663 If there are more than two operands, report an error.
665 Also, report an error if LASTFILE is known to be a directory
666 even though it could not be opened, which can happen if
667 opening failed with EACCES on a platform lacking O_PATH.
668 In this case use stat to test whether LASTFILE is a
669 directory, in case opening a non-directory with (O_SEARCH
670 | O_DIRECTORY) failed with EACCES not ENOTDIR. */
672 || (O_PATHSEARCH
== O_SEARCH
&& err
== EACCES
673 && (sb
.st_mode
|| stat (lastfile
, &sb
) == 0)
674 && S_ISDIR (sb
.st_mode
)))
675 die (EXIT_FAILURE
, err
, _("target %s"), quoteaf (lastfile
));
679 if (target_directory
)
681 /* cp file1...filen edir
682 Copy the files 'file1' through 'filen'
683 to the existing directory 'edir'. */
685 /* Initialize these hash tables only if we'll need them.
686 The problems they're used to detect can arise only if
687 there are two or more files to copy. */
694 for (int i
= 0; i
< n_files
; i
++)
697 bool parent_exists
= true; /* True if dir_name (dst_name) exists. */
698 struct dir_attr
*attr_list
;
702 /* Trailing slashes are meaningful (i.e., maybe worth preserving)
703 only in the source file names. */
704 if (remove_trailing_slashes
)
705 strip_trailing_slashes (arg
);
709 char *arg_no_trailing_slash
;
711 /* Use 'arg' without trailing slashes in constructing destination
712 file names. Otherwise, we can end up trying to create a
713 directory using a name with trailing slash, which fails on
714 NetBSD 1.[34] systems. */
715 ASSIGN_STRDUPA (arg_no_trailing_slash
, arg
);
716 strip_trailing_slashes (arg_no_trailing_slash
);
718 /* Append all of 'arg' (minus any trailing slash) to 'dest'. */
719 dst_name
= file_name_concat (target_directory
,
720 arg_no_trailing_slash
,
723 /* For --parents, we have to make sure that the directory
724 dir_name (dst_name) exists. We may have to create a few
725 leading directories. */
727 (make_dir_parents_private
728 (dst_name
, arg_in_concat
- dst_name
, target_dirfd
,
729 (x
->verbose
? "%s -> %s\n" : NULL
),
730 &attr_list
, &new_dst
, x
));
735 /* Append the last component of 'arg' to 'target_directory'. */
736 ASSIGN_STRDUPA (arg_base
, last_component (arg
));
737 strip_trailing_slashes (arg_base
);
738 /* For 'cp -R source/.. dest', don't copy into 'dest/..'. */
739 arg_base
+= STREQ (arg_base
, "..");
740 dst_name
= file_name_concat (target_directory
, arg_base
,
746 /* make_dir_parents_private failed, so don't even
752 char const *dst_relname
= arg_in_concat
;
753 while (*dst_relname
== '/')
757 ok
&= copy (arg
, dst_name
, target_dirfd
, dst_relname
,
758 new_dst
, x
, ©_into_self
, NULL
);
761 ok
&= re_protect (dst_name
, arg_in_concat
, target_dirfd
,
762 dst_relname
, attr_list
, x
);
769 struct dir_attr
*p
= attr_list
;
770 attr_list
= attr_list
->next
;
778 else /* !target_directory */
780 char const *source
= file
[0];
781 char const *dest
= file
[1];
787 _("with --parents, the destination must be a directory"));
788 usage (EXIT_FAILURE
);
791 /* When the force and backup options have been specified and
792 the source and destination are the same name for an existing
793 regular file, convert the user's command, e.g.,
794 'cp --force --backup foo foo' to 'cp --force foo fooSUFFIX'
795 where SUFFIX is determined by any version control options used. */
797 if (x
->unlink_dest_after_failed_open
798 && x
->backup_type
!= no_backups
799 && STREQ (source
, dest
)
801 && (sb
.st_mode
!= 0 || stat (dest
, &sb
) == 0) && S_ISREG (sb
.st_mode
))
803 static struct cp_options x_tmp
;
805 dest
= find_backup_file_name (AT_FDCWD
, dest
, x
->backup_type
);
806 /* Set x->backup_type to 'no_backups' so that the normal backup
807 mechanism is not used when performing the actual copy.
808 backup_type must be set to 'no_backups' only *after* the above
809 call to find_backup_file_name -- that function uses
810 backup_type to determine the suffix it applies. */
812 x_tmp
.backup_type
= no_backups
;
816 ok
= copy (source
, dest
, AT_FDCWD
, dest
, -new_dst
, x
, &unused
, NULL
);
823 cp_option_init (struct cp_options
*x
)
825 cp_options_default (x
);
826 x
->copy_as_regular
= true;
827 x
->dereference
= DEREF_UNDEFINED
;
828 x
->unlink_dest_before_opening
= false;
829 x
->unlink_dest_after_failed_open
= false;
830 x
->hard_link
= false;
831 x
->interactive
= I_UNSPECIFIED
;
832 x
->move_mode
= false;
833 x
->install_mode
= false;
834 x
->one_file_system
= false;
835 x
->reflink_mode
= REFLINK_AUTO
;
837 x
->preserve_ownership
= false;
838 x
->preserve_links
= false;
839 x
->preserve_mode
= false;
840 x
->preserve_timestamps
= false;
841 x
->explicit_no_preserve_mode
= false;
842 x
->preserve_security_context
= false; /* -a or --preserve=context. */
843 x
->require_preserve_context
= false; /* --preserve=context. */
844 x
->set_security_context
= NULL
; /* -Z, set sys default context. */
845 x
->preserve_xattr
= false;
846 x
->reduce_diagnostics
= false;
847 x
->require_preserve_xattr
= false;
849 x
->data_copy_required
= true;
850 x
->require_preserve
= false;
851 x
->recursive
= false;
852 x
->sparse_mode
= SPARSE_AUTO
;
853 x
->symbolic_link
= false;
858 x
->stdin_tty
= false;
863 /* By default, refuse to open a dangling destination symlink, because
864 in general one cannot do that safely, give the current semantics of
865 open's O_EXCL flag, (which POSIX doesn't even allow cp to use, btw).
866 But POSIX requires it. */
867 x
->open_dangling_dest_symlink
= getenv ("POSIXLY_CORRECT") != NULL
;
873 /* Given a string, ARG, containing a comma-separated list of arguments
874 to the --preserve option, set the appropriate fields of X to ON_OFF. */
876 decode_preserve_arg (char const *arg
, struct cp_options
*x
, bool on_off
)
888 static enum File_attribute
const preserve_vals
[] =
890 PRESERVE_MODE
, PRESERVE_TIMESTAMPS
,
891 PRESERVE_OWNERSHIP
, PRESERVE_LINK
, PRESERVE_CONTEXT
, PRESERVE_XATTR
,
894 /* Valid arguments to the '--preserve' option. */
895 static char const *const preserve_args
[] =
897 "mode", "timestamps",
898 "ownership", "links", "context", "xattr", "all", NULL
900 ARGMATCH_VERIFY (preserve_args
, preserve_vals
);
902 char *arg_writable
= xstrdup (arg
);
903 char *s
= arg_writable
;
906 /* find next comma */
907 char *comma
= strchr (s
, ',');
908 enum File_attribute val
;
910 /* If we found a comma, put a NUL in its place and advance. */
915 val
= XARGMATCH (on_off
? "--preserve" : "--no-preserve",
916 s
, preserve_args
, preserve_vals
);
920 x
->preserve_mode
= on_off
;
921 x
->explicit_no_preserve_mode
= !on_off
;
924 case PRESERVE_TIMESTAMPS
:
925 x
->preserve_timestamps
= on_off
;
928 case PRESERVE_OWNERSHIP
:
929 x
->preserve_ownership
= on_off
;
933 x
->preserve_links
= on_off
;
936 case PRESERVE_CONTEXT
:
937 x
->require_preserve_context
= on_off
;
938 x
->preserve_security_context
= on_off
;
942 x
->preserve_xattr
= on_off
;
943 x
->require_preserve_xattr
= on_off
;
947 x
->preserve_mode
= on_off
;
948 x
->preserve_timestamps
= on_off
;
949 x
->preserve_ownership
= on_off
;
950 x
->preserve_links
= on_off
;
951 x
->explicit_no_preserve_mode
= !on_off
;
953 x
->preserve_security_context
= on_off
;
954 x
->preserve_xattr
= on_off
;
968 main (int argc
, char **argv
)
972 bool make_backups
= false;
973 char const *backup_suffix
= NULL
;
974 char *version_control_string
= NULL
;
976 bool copy_contents
= false;
977 char *target_directory
= NULL
;
978 bool no_target_directory
= false;
979 char const *scontext
= NULL
;
981 initialize_main (&argc
, &argv
);
982 set_program_name (argv
[0]);
983 setlocale (LC_ALL
, "");
984 bindtextdomain (PACKAGE
, LOCALEDIR
);
985 textdomain (PACKAGE
);
987 atexit (close_stdin
);
989 selinux_enabled
= (0 < is_selinux_enabled ());
992 while ((c
= getopt_long (argc
, argv
, "abdfHilLnprst:uvxPRS:TZ",
999 x
.sparse_mode
= XARGMATCH ("--sparse", optarg
,
1000 sparse_type_string
, sparse_type
);
1003 case REFLINK_OPTION
:
1005 x
.reflink_mode
= REFLINK_ALWAYS
;
1007 x
.reflink_mode
= XARGMATCH ("--reflink", optarg
,
1008 reflink_type_string
, reflink_type
);
1012 /* Like -dR --preserve=all with reduced failure diagnostics. */
1013 x
.dereference
= DEREF_NEVER
;
1014 x
.preserve_links
= true;
1015 x
.preserve_ownership
= true;
1016 x
.preserve_mode
= true;
1017 x
.preserve_timestamps
= true;
1018 x
.require_preserve
= true;
1019 if (selinux_enabled
)
1020 x
.preserve_security_context
= true;
1021 x
.preserve_xattr
= true;
1022 x
.reduce_diagnostics
= true;
1027 make_backups
= true;
1029 version_control_string
= optarg
;
1032 case ATTRIBUTES_ONLY_OPTION
:
1033 x
.data_copy_required
= false;
1037 x
.debug
= x
.verbose
= true;
1040 case COPY_CONTENTS_OPTION
:
1041 copy_contents
= true;
1045 x
.preserve_links
= true;
1046 x
.dereference
= DEREF_NEVER
;
1050 x
.unlink_dest_after_failed_open
= true;
1054 x
.dereference
= DEREF_COMMAND_LINE_ARGUMENTS
;
1058 x
.interactive
= I_ASK_USER
;
1066 x
.dereference
= DEREF_ALWAYS
;
1070 x
.interactive
= I_ALWAYS_NO
;
1074 x
.dereference
= DEREF_NEVER
;
1077 case NO_PRESERVE_ATTRIBUTES_OPTION
:
1078 decode_preserve_arg (optarg
, &x
, false);
1081 case PRESERVE_ATTRIBUTES_OPTION
:
1084 /* Fall through to the case for 'p' below. */
1088 decode_preserve_arg (optarg
, &x
, true);
1089 x
.require_preserve
= true;
1095 x
.preserve_ownership
= true;
1096 x
.preserve_mode
= true;
1097 x
.preserve_timestamps
= true;
1098 x
.require_preserve
= true;
1101 case PARENTS_OPTION
:
1102 parents_option
= true;
1110 case UNLINK_DEST_BEFORE_OPENING
:
1111 x
.unlink_dest_before_opening
= true;
1114 case STRIP_TRAILING_SLASHES_OPTION
:
1115 remove_trailing_slashes
= true;
1119 x
.symbolic_link
= true;
1123 if (target_directory
)
1124 die (EXIT_FAILURE
, 0,
1125 _("multiple target directories specified"));
1126 target_directory
= optarg
;
1130 no_target_directory
= true;
1136 else if (x
.interactive
!= I_ALWAYS_NO
) /* -n takes precedence. */
1138 enum Update_type update_opt
;
1139 update_opt
= XARGMATCH ("--update", optarg
,
1140 update_type_string
, update_type
);
1141 if (update_opt
== UPDATE_ALL
)
1143 /* Default cp operation. */
1145 x
.interactive
= I_UNSPECIFIED
;
1147 else if (update_opt
== UPDATE_NONE
)
1150 x
.interactive
= I_ALWAYS_SKIP
;
1152 else if (update_opt
== UPDATE_OLDER
)
1155 x
.interactive
= I_UNSPECIFIED
;
1165 x
.one_file_system
= true;
1169 /* politely decline if we're not on a selinux-enabled kernel. */
1170 if (selinux_enabled
)
1176 x
.set_security_context
= selabel_open (SELABEL_CTX_FILE
,
1178 if (! x
.set_security_context
)
1179 error (0, errno
, _("warning: ignoring --context"));
1185 _("warning: ignoring --context; "
1186 "it requires an SELinux-enabled kernel"));
1191 make_backups
= true;
1192 backup_suffix
= optarg
;
1195 case_GETOPT_HELP_CHAR
;
1197 case_GETOPT_VERSION_CHAR (PROGRAM_NAME
, AUTHORS
);
1200 usage (EXIT_FAILURE
);
1204 if (x
.hard_link
&& x
.symbolic_link
)
1206 error (0, 0, _("cannot make both hard and symbolic links"));
1207 usage (EXIT_FAILURE
);
1210 if (x
.interactive
== I_ALWAYS_NO
)
1213 if (make_backups
&& x
.interactive
== I_ALWAYS_NO
)
1216 _("options --backup and --no-clobber are mutually exclusive"));
1217 usage (EXIT_FAILURE
);
1220 if (x
.reflink_mode
== REFLINK_ALWAYS
&& x
.sparse_mode
!= SPARSE_AUTO
)
1222 error (0, 0, _("--reflink can be used only with --sparse=auto"));
1223 usage (EXIT_FAILURE
);
1226 x
.backup_type
= (make_backups
1227 ? xget_version (_("backup type"),
1228 version_control_string
)
1230 set_simple_backup_suffix (backup_suffix
);
1232 if (x
.dereference
== DEREF_UNDEFINED
)
1234 if (x
.recursive
&& ! x
.hard_link
)
1235 /* This is compatible with FreeBSD. */
1236 x
.dereference
= DEREF_NEVER
;
1238 x
.dereference
= DEREF_ALWAYS
;
1242 x
.copy_as_regular
= copy_contents
;
1244 /* Ensure -Z overrides -a. */
1245 if ((x
.set_security_context
|| scontext
)
1246 && ! x
.require_preserve_context
)
1247 x
.preserve_security_context
= false;
1249 if (x
.preserve_security_context
&& (x
.set_security_context
|| scontext
))
1250 die (EXIT_FAILURE
, 0,
1251 _("cannot set target context and preserve it"));
1253 if (x
.require_preserve_context
&& ! selinux_enabled
)
1254 die (EXIT_FAILURE
, 0,
1255 _("cannot preserve security context "
1256 "without an SELinux-enabled kernel"));
1258 /* FIXME: This handles new files. But what about existing files?
1259 I.e., if updating a tree, new files would have the specified context,
1260 but shouldn't existing files be updated for consistency like this?
1261 if (scontext && !restorecon (NULL, dst_path, 0))
1264 if (scontext
&& setfscreatecon (scontext
) < 0)
1265 die (EXIT_FAILURE
, errno
,
1266 _("failed to set default file creation context to %s"),
1270 if (x
.require_preserve_xattr
)
1271 die (EXIT_FAILURE
, 0, _("cannot preserve extended attributes, cp is "
1272 "built without xattr support"));
1275 /* Allocate space for remembering copied and created files. */
1279 ok
= do_copy (argc
- optind
, argv
+ optind
,
1280 target_directory
, no_target_directory
, &x
);
1282 main_exit (ok
? EXIT_SUCCESS
: EXIT_FAILURE
);