1 /* cp.c -- file copying (main routines)
2 Copyright (C) 89, 90, 91, 1995-2008 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 <http://www.gnu.org/licenses/>.
17 Written by Torbjorn Granlund, David MacKenzie, and Jim Meyering. */
21 #include <sys/types.h>
23 #include <selinux/selinux.h>
27 #include "backupfile.h"
31 #include "filenamecat.h"
34 #include "stat-time.h"
39 # define lchown(name, uid, gid) chown (name, uid, gid)
42 #define ASSIGN_BASENAME_STRDUPA(Dest, File_name) \
46 ASSIGN_STRDUPA (tmp_abns_, (File_name)); \
47 Dest = last_component (tmp_abns_); \
48 strip_trailing_slashes (Dest); \
52 /* The official name of this program (e.g., no `g' prefix). */
53 #define PROGRAM_NAME "cp"
56 proper_name_utf8 ("Torbjorn Granlund", "Torbj\303\266rn Granlund"), \
57 proper_name ("David MacKenzie"), \
58 proper_name ("Jim Meyering")
60 /* Used by do_copy, make_dir_parents_private, and re_protect
61 to keep a list of leading directories whose protections
62 need to be fixed after copying. */
68 struct dir_attr *next;
71 /* For long options that have no equivalent short option, use a
72 non-character as a pseudo short option, starting with CHAR_MAX + 1. */
75 COPY_CONTENTS_OPTION = CHAR_MAX + 1,
76 NO_PRESERVE_ATTRIBUTES_OPTION,
78 PRESERVE_ATTRIBUTES_OPTION,
81 STRIP_TRAILING_SLASHES_OPTION,
82 UNLINK_DEST_BEFORE_OPENING
85 /* Initial number of entries in each hash table entry's table of inodes. */
86 #define INITIAL_HASH_MODULE 100
88 /* Initial number of entries in the inode hash table. */
89 #define INITIAL_ENTRY_TAB_SIZE 70
91 /* True if the kernel is SELinux enabled. */
92 static bool selinux_enabled;
94 /* If true, the command "cp x/e_file e_dir" uses "e_dir/x/e_file"
95 as its destination instead of the usual "e_dir/e_file." */
96 static bool parents_option = false;
98 /* Remove any trailing slashes from each SOURCE argument. */
99 static bool remove_trailing_slashes;
101 static char const *const sparse_type_string[] =
103 "never", "auto", "always", NULL
105 static enum Sparse_type const sparse_type[] =
107 SPARSE_NEVER, SPARSE_AUTO, SPARSE_ALWAYS
109 ARGMATCH_VERIFY (sparse_type_string, sparse_type);
111 /* Valid arguments to the `--reply' option. */
112 static char const* const reply_args[] =
114 "yes", "no", "query", NULL
116 /* The values that correspond to the above strings. */
117 static int const reply_vals[] =
119 I_ALWAYS_YES, I_ALWAYS_NO, I_ASK_USER
121 ARGMATCH_VERIFY (reply_args, reply_vals);
123 static struct option const long_opts[] =
125 {"archive", no_argument, NULL, 'a'},
126 {"backup", optional_argument, NULL, 'b'},
127 {"copy-contents", no_argument, NULL, COPY_CONTENTS_OPTION},
128 {"dereference", no_argument, NULL, 'L'},
129 {"force", no_argument, NULL, 'f'},
130 {"interactive", no_argument, NULL, 'i'},
131 {"link", no_argument, NULL, 'l'},
132 {"no-dereference", no_argument, NULL, 'P'},
133 {"no-preserve", required_argument, NULL, NO_PRESERVE_ATTRIBUTES_OPTION},
134 {"no-target-directory", no_argument, NULL, 'T'},
135 {"one-file-system", no_argument, NULL, 'x'},
136 {"parents", no_argument, NULL, PARENTS_OPTION},
137 {"path", no_argument, NULL, PARENTS_OPTION}, /* Deprecated. */
138 {"preserve", optional_argument, NULL, PRESERVE_ATTRIBUTES_OPTION},
139 {"recursive", no_argument, NULL, 'R'},
140 {"remove-destination", no_argument, NULL, UNLINK_DEST_BEFORE_OPENING},
141 {"reply", required_argument, NULL, REPLY_OPTION}, /* Deprecated 2005-07-03,
143 {"sparse", required_argument, NULL, SPARSE_OPTION},
144 {"strip-trailing-slashes", no_argument, NULL, STRIP_TRAILING_SLASHES_OPTION},
145 {"suffix", required_argument, NULL, 'S'},
146 {"symbolic-link", no_argument, NULL, 's'},
147 {"target-directory", required_argument, NULL, 't'},
148 {"update", no_argument, NULL, 'u'},
149 {"verbose", no_argument, NULL, 'v'},
150 {GETOPT_HELP_OPTION_DECL},
151 {GETOPT_VERSION_OPTION_DECL},
158 if (status != EXIT_SUCCESS)
159 fprintf (stderr, _("Try `%s --help' for more information.\n"),
164 Usage: %s [OPTION]... [-T] SOURCE DEST\n\
165 or: %s [OPTION]... SOURCE... DIRECTORY\n\
166 or: %s [OPTION]... -t DIRECTORY SOURCE...\n\
168 program_name, program_name, program_name);
170 Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\
174 Mandatory arguments to long options are mandatory for short options too.\n\
177 -a, --archive same as -dpR\n\
178 --backup[=CONTROL] make a backup of each existing destination file\n\
179 -b like --backup but does not accept an argument\n\
180 --copy-contents copy contents of special files when recursive\n\
181 -d same as --no-dereference --preserve=links\n\
184 -f, --force if an existing destination file cannot be\n\
185 opened, remove it and try again\n\
186 -i, --interactive prompt before overwrite\n\
187 -H follow command-line symbolic links in SOURCE\n\
190 -l, --link link files instead of copying\n\
191 -L, --dereference always follow symbolic links in SOURCE\n\
194 -P, --no-dereference never follow symbolic links in SOURCE\n\
197 -p same as --preserve=mode,ownership,timestamps\n\
198 --preserve[=ATTR_LIST] preserve the specified attributes (default:\n\
199 mode,ownership,timestamps), if possible\n\
200 additional attributes: context, links, all\n\
203 --no-preserve=ATTR_LIST don't preserve the specified attributes\n\
204 --parents use full source file name under DIRECTORY\n\
207 -R, -r, --recursive copy directories recursively\n\
208 --remove-destination remove each existing destination file before\n\
209 attempting to open it (contrast with --force)\n\
212 --sparse=WHEN control creation of sparse files\n\
213 --strip-trailing-slashes remove any trailing slashes from each SOURCE\n\
217 -s, --symbolic-link make symbolic links instead of copying\n\
218 -S, --suffix=SUFFIX override the usual backup suffix\n\
219 -t, --target-directory=DIRECTORY copy all SOURCE arguments into DIRECTORY\n\
220 -T, --no-target-directory treat DEST as a normal file\n\
223 -u, --update copy only when the SOURCE file is newer\n\
224 than the destination file or when the\n\
225 destination file is missing\n\
226 -v, --verbose explain what is being done\n\
227 -x, --one-file-system stay on this file system\n\
229 fputs (HELP_OPTION_DESCRIPTION, stdout);
230 fputs (VERSION_OPTION_DESCRIPTION, stdout);
233 By default, sparse SOURCE files are detected by a crude heuristic and the\n\
234 corresponding DEST file is made sparse as well. That is the behavior\n\
235 selected by --sparse=auto. Specify --sparse=always to create a sparse DEST\n\
236 file whenever the SOURCE file contains a long enough sequence of zero bytes.\n\
237 Use --sparse=never to inhibit creation of sparse files.\n\
241 The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
242 The version control method may be selected via the --backup option or through\n\
243 the VERSION_CONTROL environment variable. Here are the values:\n\
247 none, off never make backups (even if --backup is given)\n\
248 numbered, t make numbered backups\n\
249 existing, nil numbered if numbered backups exist, simple otherwise\n\
250 simple, never always make simple backups\n\
254 As a special case, cp makes a backup of SOURCE when the force and backup\n\
255 options are given and SOURCE and DEST are the same name for an existing,\n\
258 emit_bug_reporting_address ();
263 /* Ensure that the parent directories of CONST_DST_NAME have the
264 correct protections, for the --parents option. This is done
265 after all copying has been completed, to allow permissions
266 that don't include user write/execute.
268 SRC_OFFSET is the index in CONST_DST_NAME of the beginning of the
269 source directory name.
271 ATTR_LIST is a null-terminated linked list of structures that
272 indicates the end of the filename of each intermediate directory
273 in CONST_DST_NAME that may need to have its attributes changed.
274 The command `cp --parents --preserve a/b/c d/e_dir' changes the
275 attributes of the directories d/e_dir/a and d/e_dir/a/b to match
276 the corresponding source directories regardless of whether they
277 existed before the `cp' command was given.
279 Return true if the parent of CONST_DST_NAME and any intermediate
280 directories specified by ATTR_LIST have the proper permissions
284 re_protect (char const *const_dst_name, size_t src_offset,
285 struct dir_attr *attr_list, const struct cp_options *x)
288 char *dst_name; /* A copy of CONST_DST_NAME we can change. */
289 char *src_name; /* The source name in `dst_name'. */
291 ASSIGN_STRDUPA (dst_name, const_dst_name);
292 src_name = dst_name + src_offset;
294 for (p = attr_list; p; p = p->next)
296 dst_name[p->slash_offset] = '\0';
298 /* Adjust the times (and if possible, ownership) for the copy.
299 chown turns off set[ug]id bits for non-root,
300 so do the chmod last. */
302 if (x->preserve_timestamps)
304 struct timespec timespec[2];
306 timespec[0] = get_stat_atime (&p->st);
307 timespec[1] = get_stat_mtime (&p->st);
309 if (utimens (dst_name, timespec))
311 error (0, errno, _("failed to preserve times for %s"),
317 if (x->preserve_ownership)
319 if (lchown (dst_name, p->st.st_uid, p->st.st_gid) != 0)
321 if (! chown_failure_ok (x))
323 error (0, errno, _("failed to preserve ownership for %s"),
327 /* Failing to preserve ownership is OK. Still, try to preserve
328 the group, but ignore the possible error. */
329 (void) lchown (dst_name, -1, p->st.st_gid);
333 if (x->preserve_mode)
335 if (copy_acl (src_name, -1, dst_name, -1, p->st.st_mode) != 0)
338 else if (p->restore_mode)
340 if (lchmod (dst_name, p->st.st_mode) != 0)
342 error (0, errno, _("failed to preserve permissions for %s"),
348 dst_name[p->slash_offset] = '/';
353 /* Ensure that the parent directory of CONST_DIR exists, for
354 the --parents option.
356 SRC_OFFSET is the index in CONST_DIR (which is a destination
357 directory) of the beginning of the source directory name.
358 Create any leading directories that don't already exist.
359 If VERBOSE_FMT_STRING is nonzero, use it as a printf format
360 string for printing a message after successfully making a directory.
361 The format should take two string arguments: the names of the
362 source and destination directories.
363 Creates a linked list of attributes of intermediate directories,
364 *ATTR_LIST, for re_protect to use after calling copy.
365 Sets *NEW_DST if this function creates parent of CONST_DIR.
367 Return true if parent of CONST_DIR exists as a directory with the proper
368 permissions when done. */
370 /* FIXME: Synch this function with the one in ../lib/mkdir-p.c. */
373 make_dir_parents_private (char const *const_dir, size_t src_offset,
374 char const *verbose_fmt_string,
375 struct dir_attr **attr_list, bool *new_dst,
376 const struct cp_options *x)
379 char *dir; /* A copy of CONST_DIR we can change. */
380 char *src; /* Source name in DIR. */
381 char *dst_dir; /* Leading directory of DIR. */
382 size_t dirlen; /* Length of DIR. */
384 ASSIGN_STRDUPA (dir, const_dir);
386 src = dir + src_offset;
388 dirlen = dir_len (dir);
389 dst_dir = alloca (dirlen + 1);
390 memcpy (dst_dir, dir, dirlen);
391 dst_dir[dirlen] = '\0';
395 if (stat (dst_dir, &stats) != 0)
397 /* A parent of CONST_DIR does not exist.
398 Make all missing intermediate directories. */
402 while (*slash == '/')
404 while ((slash = strchr (slash, '/')))
406 struct dir_attr *new IF_LINT (= NULL);
410 missing_dir = (stat (dir, &stats) != 0);
412 if (missing_dir | x->preserve_ownership | x->preserve_mode
413 | x->preserve_timestamps)
415 /* Add this directory to the list of directories whose
416 modes might need fixing later. */
418 int src_errno = (stat (src, &src_st) != 0
420 : S_ISDIR (src_st.st_mode)
425 error (0, src_errno, _("failed to get attributes of %s"),
430 new = xmalloc (sizeof *new);
432 new->slash_offset = slash - dir;
433 new->restore_mode = false;
434 new->next = *attr_list;
441 mode_t omitted_permissions;
444 /* This component does not exist. We must set
445 *new_dst and new->st.st_mode inside this loop because,
446 for example, in the command `cp --parents ../a/../b/c e_dir',
447 make_dir_parents_private creates only e_dir/../a if
448 ./b already exists. */
450 src_mode = new->st.st_mode;
452 /* If the ownership or special mode bits might change,
453 omit some permissions at first, so unauthorized users
454 cannot nip in before the file is ready. */
455 omitted_permissions = (src_mode
456 & (x->preserve_ownership
462 /* POSIX says mkdir's behavior is implementation-defined when
463 (src_mode & ~S_IRWXUGO) != 0. However, common practice is
464 to ask mkdir to copy all the CHMOD_MODE_BITS, letting mkdir
465 decide what to do with S_ISUID | S_ISGID | S_ISVTX. */
466 mkdir_mode = src_mode & CHMOD_MODE_BITS & ~omitted_permissions;
467 if (mkdir (dir, mkdir_mode) != 0)
469 error (0, errno, _("cannot make directory %s"),
475 if (verbose_fmt_string != NULL)
476 printf (verbose_fmt_string, src, dir);
479 /* We need search and write permissions to the new directory
480 for writing the directory's contents. Check if these
481 permissions are there. */
483 if (lstat (dir, &stats))
485 error (0, errno, _("failed to get attributes of %s"),
491 if (! x->preserve_mode)
493 if (omitted_permissions & ~stats.st_mode)
494 omitted_permissions &= ~ cached_umask ();
495 if (omitted_permissions & ~stats.st_mode
496 || (stats.st_mode & S_IRWXU) != S_IRWXU)
498 new->st.st_mode = stats.st_mode | omitted_permissions;
499 new->restore_mode = true;
503 if ((stats.st_mode & S_IRWXU) != S_IRWXU)
505 /* Make the new directory searchable and writable.
506 The original permissions will be restored later. */
508 if (lchmod (dir, stats.st_mode | S_IRWXU) != 0)
510 error (0, errno, _("setting permissions for %s"),
516 else if (!S_ISDIR (stats.st_mode))
518 error (0, 0, _("%s exists but is not a directory"),
526 /* Avoid unnecessary calls to `stat' when given
527 file names containing multiple adjacent slashes. */
528 while (*slash == '/')
533 /* We get here if the parent of DIR already exists. */
535 else if (!S_ISDIR (stats.st_mode))
537 error (0, 0, _("%s exists but is not a directory"), quote (dst_dir));
547 /* FILE is the last operand of this command.
548 Return true if FILE is a directory.
549 But report an error and exit if there is a problem accessing FILE,
550 or if FILE does not exist but would have to refer to an existing
551 directory if it referred to anything at all.
553 If the file exists, store the file's status into *ST.
554 Otherwise, set *NEW_DST. */
557 target_directory_operand (char const *file, struct stat *st, bool *new_dst)
559 int err = (stat (file, st) == 0 ? 0 : errno);
560 bool is_a_dir = !err && S_ISDIR (st->st_mode);
564 error (EXIT_FAILURE, err, _("accessing %s"), quote (file));
570 /* Scan the arguments, and copy each by calling copy.
571 Return true if successful. */
574 do_copy (int n_files, char **file, const char *target_directory,
575 bool no_target_directory, struct cp_options *x)
578 bool new_dst = false;
581 if (n_files <= !target_directory)
584 error (0, 0, _("missing file operand"));
586 error (0, 0, _("missing destination file operand after %s"),
588 usage (EXIT_FAILURE);
591 if (no_target_directory)
593 if (target_directory)
594 error (EXIT_FAILURE, 0,
595 _("cannot combine --target-directory (-t) "
596 "and --no-target-directory (-T)"));
599 error (0, 0, _("extra operand %s"), quote (file[2]));
600 usage (EXIT_FAILURE);
603 else if (!target_directory)
606 && target_directory_operand (file[n_files - 1], &sb, &new_dst))
607 target_directory = file[--n_files];
608 else if (2 < n_files)
609 error (EXIT_FAILURE, 0, _("target %s is not a directory"),
610 quote (file[n_files - 1]));
613 if (target_directory)
615 /* cp file1...filen edir
616 Copy the files `file1' through `filen'
617 to the existing directory `edir'. */
620 /* Initialize these hash tables only if we'll need them.
621 The problems they're used to detect can arise only if
622 there are two or more files to copy. */
629 for (i = 0; i < n_files; i++)
632 bool parent_exists = true; /* True if dir_name (dst_name) exists. */
633 struct dir_attr *attr_list;
634 char *arg_in_concat = NULL;
637 /* Trailing slashes are meaningful (i.e., maybe worth preserving)
638 only in the source file names. */
639 if (remove_trailing_slashes)
640 strip_trailing_slashes (arg);
644 char *arg_no_trailing_slash;
646 /* Use `arg' without trailing slashes in constructing destination
647 file names. Otherwise, we can end up trying to create a
648 directory via `mkdir ("dst/foo/"...', which is not portable.
649 It fails, due to the trailing slash, on at least
650 NetBSD 1.[34] systems. */
651 ASSIGN_STRDUPA (arg_no_trailing_slash, arg);
652 strip_trailing_slashes (arg_no_trailing_slash);
654 /* Append all of `arg' (minus any trailing slash) to `dest'. */
655 dst_name = file_name_concat (target_directory,
656 arg_no_trailing_slash,
659 /* For --parents, we have to make sure that the directory
660 dir_name (dst_name) exists. We may have to create a few
661 leading directories. */
663 (make_dir_parents_private
664 (dst_name, arg_in_concat - dst_name,
665 (x->verbose ? "%s -> %s\n" : NULL),
666 &attr_list, &new_dst, x));
671 /* Append the last component of `arg' to `target_directory'. */
673 ASSIGN_BASENAME_STRDUPA (arg_base, arg);
674 /* For `cp -R source/.. dest', don't copy into `dest/..'. */
675 dst_name = (STREQ (arg_base, "..")
676 ? xstrdup (target_directory)
677 : file_name_concat (target_directory, arg_base,
683 /* make_dir_parents_private failed, so don't even
690 ok &= copy (arg, dst_name, new_dst, x, ©_into_self, NULL);
693 ok &= re_protect (dst_name, arg_in_concat - dst_name,
701 struct dir_attr *p = attr_list;
702 attr_list = attr_list->next;
710 else /* !target_directory */
712 char const *new_dest;
713 char const *source = file[0];
714 char const *dest = file[1];
720 _("with --parents, the destination must be a directory"));
721 usage (EXIT_FAILURE);
724 /* When the force and backup options have been specified and
725 the source and destination are the same name for an existing
726 regular file, convert the user's command, e.g.,
727 `cp --force --backup foo foo' to `cp --force foo fooSUFFIX'
728 where SUFFIX is determined by any version control options used. */
730 if (x->unlink_dest_after_failed_open
731 && x->backup_type != no_backups
732 && STREQ (source, dest)
733 && !new_dst && S_ISREG (sb.st_mode))
735 static struct cp_options x_tmp;
737 new_dest = find_backup_file_name (dest, x->backup_type);
738 /* Set x->backup_type to `no_backups' so that the normal backup
739 mechanism is not used when performing the actual copy.
740 backup_type must be set to `no_backups' only *after* the above
741 call to find_backup_file_name -- that function uses
742 backup_type to determine the suffix it applies. */
744 x_tmp.backup_type = no_backups;
752 ok = copy (source, new_dest, 0, x, &unused, NULL);
759 cp_option_init (struct cp_options *x)
761 cp_options_default (x);
762 x->copy_as_regular = true;
763 x->dereference = DEREF_UNDEFINED;
764 x->unlink_dest_before_opening = false;
765 x->unlink_dest_after_failed_open = false;
766 x->hard_link = false;
767 x->interactive = I_UNSPECIFIED;
768 x->move_mode = false;
769 x->one_file_system = false;
771 x->preserve_ownership = false;
772 x->preserve_links = false;
773 x->preserve_mode = false;
774 x->preserve_timestamps = false;
775 x->preserve_security_context = false;
776 x->require_preserve_context = false;
778 x->require_preserve = false;
779 x->recursive = false;
780 x->sparse_mode = SPARSE_AUTO;
781 x->symbolic_link = false;
786 x->stdin_tty = false;
791 /* By default, refuse to open a dangling destination symlink, because
792 in general one cannot do that safely, give the current semantics of
793 open's O_EXCL flag, (which POSIX doesn't even allow cp to use, btw).
794 But POSIX requires it. */
795 x->open_dangling_dest_symlink = getenv ("POSIXLY_CORRECT") != NULL;
801 /* Given a string, ARG, containing a comma-separated list of arguments
802 to the --preserve option, set the appropriate fields of X to ON_OFF. */
804 decode_preserve_arg (char const *arg, struct cp_options *x, bool on_off)
815 static enum File_attribute const preserve_vals[] =
817 PRESERVE_MODE, PRESERVE_TIMESTAMPS,
818 PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_CONTEXT, PRESERVE_ALL
820 /* Valid arguments to the `--preserve' option. */
821 static char const* const preserve_args[] =
823 "mode", "timestamps",
824 "ownership", "links", "context", "all", NULL
826 ARGMATCH_VERIFY (preserve_args, preserve_vals);
828 char *arg_writable = xstrdup (arg);
829 char *s = arg_writable;
832 /* find next comma */
833 char *comma = strchr (s, ',');
834 enum File_attribute val;
836 /* If we found a comma, put a NUL in its place and advance. */
841 val = XARGMATCH ("--preserve", s, preserve_args, preserve_vals);
845 x->preserve_mode = on_off;
848 case PRESERVE_TIMESTAMPS:
849 x->preserve_timestamps = on_off;
852 case PRESERVE_OWNERSHIP:
853 x->preserve_ownership = on_off;
857 x->preserve_links = on_off;
860 case PRESERVE_CONTEXT:
861 x->preserve_security_context = on_off;
862 x->require_preserve_context = on_off;
866 x->preserve_mode = on_off;
867 x->preserve_timestamps = on_off;
868 x->preserve_ownership = on_off;
869 x->preserve_links = on_off;
871 x->preserve_security_context = on_off;
885 main (int argc, char **argv)
889 bool make_backups = false;
890 char *backup_suffix_string;
891 char *version_control_string = NULL;
893 bool copy_contents = false;
894 char *target_directory = NULL;
895 bool no_target_directory = false;
897 initialize_main (&argc, &argv);
898 set_program_name (argv[0]);
899 setlocale (LC_ALL, "");
900 bindtextdomain (PACKAGE, LOCALEDIR);
901 textdomain (PACKAGE);
903 atexit (close_stdin);
905 selinux_enabled = (0 < is_selinux_enabled ());
908 /* FIXME: consider not calling getenv for SIMPLE_BACKUP_SUFFIX unless
909 we'll actually use backup_suffix_string. */
910 backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
912 while ((c = getopt_long (argc, argv, "abdfHilLprst:uvxPRS:T",
919 x.sparse_mode = XARGMATCH ("--sparse", optarg,
920 sparse_type_string, sparse_type);
923 case 'a': /* Like -dpPR. */
924 x.dereference = DEREF_NEVER;
925 x.preserve_links = true;
926 x.preserve_ownership = true;
927 x.preserve_mode = true;
928 x.preserve_timestamps = true;
929 x.require_preserve = true;
936 version_control_string = optarg;
939 case COPY_CONTENTS_OPTION:
940 copy_contents = true;
944 x.preserve_links = true;
945 x.dereference = DEREF_NEVER;
949 x.unlink_dest_after_failed_open = true;
953 x.dereference = DEREF_COMMAND_LINE_ARGUMENTS;
957 x.interactive = I_ASK_USER;
965 x.dereference = DEREF_ALWAYS;
969 x.dereference = DEREF_NEVER;
972 case NO_PRESERVE_ATTRIBUTES_OPTION:
973 decode_preserve_arg (optarg, &x, false);
976 case PRESERVE_ATTRIBUTES_OPTION:
979 /* Fall through to the case for `p' below. */
983 decode_preserve_arg (optarg, &x, true);
984 x.require_preserve = true;
989 x.preserve_ownership = true;
990 x.preserve_mode = true;
991 x.preserve_timestamps = true;
992 x.require_preserve = true;
996 parents_option = true;
1004 case REPLY_OPTION: /* Deprecated */
1005 x.interactive = XARGMATCH ("--reply", optarg,
1006 reply_args, reply_vals);
1008 _("the --reply option is deprecated; use -i or -f instead"));
1011 case UNLINK_DEST_BEFORE_OPENING:
1012 x.unlink_dest_before_opening = true;
1015 case STRIP_TRAILING_SLASHES_OPTION:
1016 remove_trailing_slashes = true;
1020 x.symbolic_link = true;
1024 if (target_directory)
1025 error (EXIT_FAILURE, 0,
1026 _("multiple target directories specified"));
1030 if (stat (optarg, &st) != 0)
1031 error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg));
1032 if (! S_ISDIR (st.st_mode))
1033 error (EXIT_FAILURE, 0, _("target %s is not a directory"),
1036 target_directory = optarg;
1040 no_target_directory = true;
1052 x.one_file_system = true;
1056 make_backups = true;
1057 backup_suffix_string = optarg;
1060 case_GETOPT_HELP_CHAR;
1062 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
1065 usage (EXIT_FAILURE);
1069 if (x.hard_link & x.symbolic_link)
1071 error (0, 0, _("cannot make both hard and symbolic links"));
1072 usage (EXIT_FAILURE);
1075 if (backup_suffix_string)
1076 simple_backup_suffix = xstrdup (backup_suffix_string);
1078 x.backup_type = (make_backups
1079 ? xget_version (_("backup type"),
1080 version_control_string)
1083 if (x.dereference == DEREF_UNDEFINED)
1086 /* This is compatible with FreeBSD. */
1087 x.dereference = DEREF_NEVER;
1089 x.dereference = DEREF_ALWAYS;
1093 x.copy_as_regular = copy_contents;
1095 /* If --force (-f) was specified and we're in link-creation mode,
1096 first remove any existing destination file. */
1097 if (x.unlink_dest_after_failed_open & (x.hard_link | x.symbolic_link))
1098 x.unlink_dest_before_opening = true;
1100 if (x.preserve_security_context)
1102 if (!selinux_enabled)
1103 error (EXIT_FAILURE, 0,
1104 _("cannot preserve security context "
1105 "without an SELinux-enabled kernel"));
1108 /* Allocate space for remembering copied and created files. */
1112 ok = do_copy (argc - optind, argv + optind,
1113 target_directory, no_target_directory, &x);
1117 exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);