global: convert indentation-TABs to spaces
[coreutils.git] / src / cp.c
blob7424f9b3cff4c8bcb51b6e7f28a92159ac7519ba
1 /* cp.c -- file copying (main routines)
2 Copyright (C) 89, 90, 91, 1995-2009 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. */
19 #include <config.h>
20 #include <stdio.h>
21 #include <sys/types.h>
22 #include <getopt.h>
23 #include <selinux/selinux.h>
25 #include "system.h"
26 #include "argmatch.h"
27 #include "backupfile.h"
28 #include "copy.h"
29 #include "cp-hash.h"
30 #include "error.h"
31 #include "filenamecat.h"
32 #include "ignore-value.h"
33 #include "quote.h"
34 #include "stat-time.h"
35 #include "utimens.h"
36 #include "acl.h"
38 #if ! HAVE_LCHOWN
39 # define lchown(name, uid, gid) chown (name, uid, gid)
40 #endif
42 #define ASSIGN_BASENAME_STRDUPA(Dest, File_name) \
43 do \
44 { \
45 char *tmp_abns_; \
46 ASSIGN_STRDUPA (tmp_abns_, (File_name)); \
47 Dest = last_component (tmp_abns_); \
48 strip_trailing_slashes (Dest); \
49 } \
50 while (0)
52 /* The official name of this program (e.g., no `g' prefix). */
53 #define PROGRAM_NAME "cp"
55 #define AUTHORS \
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. */
63 struct dir_attr
65 struct stat st;
66 bool restore_mode;
67 size_t slash_offset;
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. */
73 enum
75 COPY_CONTENTS_OPTION = CHAR_MAX + 1,
76 NO_PRESERVE_ATTRIBUTES_OPTION,
77 PARENTS_OPTION,
78 PRESERVE_ATTRIBUTES_OPTION,
79 REFLINK_OPTION,
80 SPARSE_OPTION,
81 STRIP_TRAILING_SLASHES_OPTION,
82 UNLINK_DEST_BEFORE_OPENING
85 /* True if the kernel is SELinux enabled. */
86 static bool selinux_enabled;
88 /* If true, the command "cp x/e_file e_dir" uses "e_dir/x/e_file"
89 as its destination instead of the usual "e_dir/e_file." */
90 static bool parents_option = false;
92 /* Remove any trailing slashes from each SOURCE argument. */
93 static bool remove_trailing_slashes;
95 static char const *const sparse_type_string[] =
97 "never", "auto", "always", NULL
99 static enum Sparse_type const sparse_type[] =
101 SPARSE_NEVER, SPARSE_AUTO, SPARSE_ALWAYS
103 ARGMATCH_VERIFY (sparse_type_string, sparse_type);
105 static struct option const long_opts[] =
107 {"archive", no_argument, NULL, 'a'},
108 {"backup", optional_argument, NULL, 'b'},
109 {"copy-contents", no_argument, NULL, COPY_CONTENTS_OPTION},
110 {"dereference", no_argument, NULL, 'L'},
111 {"force", no_argument, NULL, 'f'},
112 {"interactive", no_argument, NULL, 'i'},
113 {"link", no_argument, NULL, 'l'},
114 {"no-clobber", no_argument, NULL, 'n'},
115 {"no-dereference", no_argument, NULL, 'P'},
116 {"no-preserve", required_argument, NULL, NO_PRESERVE_ATTRIBUTES_OPTION},
117 {"no-target-directory", no_argument, NULL, 'T'},
118 {"one-file-system", no_argument, NULL, 'x'},
119 {"parents", no_argument, NULL, PARENTS_OPTION},
120 {"path", no_argument, NULL, PARENTS_OPTION}, /* Deprecated. */
121 {"preserve", optional_argument, NULL, PRESERVE_ATTRIBUTES_OPTION},
122 {"recursive", no_argument, NULL, 'R'},
123 {"remove-destination", no_argument, NULL, UNLINK_DEST_BEFORE_OPENING},
124 {"sparse", required_argument, NULL, SPARSE_OPTION},
125 {"reflink", no_argument, NULL, REFLINK_OPTION},
126 {"strip-trailing-slashes", no_argument, NULL, STRIP_TRAILING_SLASHES_OPTION},
127 {"suffix", required_argument, NULL, 'S'},
128 {"symbolic-link", no_argument, NULL, 's'},
129 {"target-directory", required_argument, NULL, 't'},
130 {"update", no_argument, NULL, 'u'},
131 {"verbose", no_argument, NULL, 'v'},
132 {GETOPT_HELP_OPTION_DECL},
133 {GETOPT_VERSION_OPTION_DECL},
134 {NULL, 0, NULL, 0}
137 void
138 usage (int status)
140 if (status != EXIT_SUCCESS)
141 fprintf (stderr, _("Try `%s --help' for more information.\n"),
142 program_name);
143 else
145 printf (_("\
146 Usage: %s [OPTION]... [-T] SOURCE DEST\n\
147 or: %s [OPTION]... SOURCE... DIRECTORY\n\
148 or: %s [OPTION]... -t DIRECTORY SOURCE...\n\
150 program_name, program_name, program_name);
151 fputs (_("\
152 Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\
154 "), stdout);
155 fputs (_("\
156 Mandatory arguments to long options are mandatory for short options too.\n\
157 "), stdout);
158 fputs (_("\
159 -a, --archive same as -dR --preserve=all\n\
160 --backup[=CONTROL] make a backup of each existing destination file\n\
161 -b like --backup but does not accept an argument\n\
162 --copy-contents copy contents of special files when recursive\n\
163 -d same as --no-dereference --preserve=links\n\
164 "), stdout);
165 fputs (_("\
166 -f, --force if an existing destination file cannot be\n\
167 opened, remove it and try again (redundant if\n\
168 the -n option is used)\n\
169 -i, --interactive prompt before overwrite (overrides a previous -n\n\
170 option)\n\
171 -H follow command-line symbolic links in SOURCE\n\
172 "), stdout);
173 fputs (_("\
174 -l, --link link files instead of copying\n\
175 -L, --dereference always follow symbolic links in SOURCE\n\
176 "), stdout);
177 fputs (_("\
178 -n, --no-clobber do not overwrite an existing file (overrides\n\
179 a previous -i option)\n\
180 -P, --no-dereference never follow symbolic links in SOURCE\n\
181 "), stdout);
182 fputs (_("\
183 -p same as --preserve=mode,ownership,timestamps\n\
184 --preserve[=ATTR_LIST] preserve the specified attributes (default:\n\
185 mode,ownership,timestamps), if possible\n\
186 additional attributes: context, links, xattr,\n\
187 all\n\
188 "), stdout);
189 fputs (_("\
190 --no-preserve=ATTR_LIST don't preserve the specified attributes\n\
191 --parents use full source file name under DIRECTORY\n\
192 "), stdout);
193 fputs (_("\
194 -R, -r, --recursive copy directories recursively\n\
195 --reflink perform a lightweight (CoW/clone) copy\n\
196 --remove-destination remove each existing destination file before\n\
197 attempting to open it (contrast with --force)\n\
198 "), stdout);
199 fputs (_("\
200 --sparse=WHEN control creation of sparse files\n\
201 --strip-trailing-slashes remove any trailing slashes from each SOURCE\n\
202 argument\n\
203 "), stdout);
204 fputs (_("\
205 -s, --symbolic-link make symbolic links instead of copying\n\
206 -S, --suffix=SUFFIX override the usual backup suffix\n\
207 -t, --target-directory=DIRECTORY copy all SOURCE arguments into DIRECTORY\n\
208 -T, --no-target-directory treat DEST as a normal file\n\
209 "), stdout);
210 fputs (_("\
211 -u, --update copy only when the SOURCE file is newer\n\
212 than the destination file or when the\n\
213 destination file is missing\n\
214 -v, --verbose explain what is being done\n\
215 -x, --one-file-system stay on this file system\n\
216 "), stdout);
217 fputs (HELP_OPTION_DESCRIPTION, stdout);
218 fputs (VERSION_OPTION_DESCRIPTION, stdout);
219 fputs (_("\
221 By default, sparse SOURCE files are detected by a crude heuristic and the\n\
222 corresponding DEST file is made sparse as well. That is the behavior\n\
223 selected by --sparse=auto. Specify --sparse=always to create a sparse DEST\n\
224 file whenever the SOURCE file contains a long enough sequence of zero bytes.\n\
225 Use --sparse=never to inhibit creation of sparse files.\n\
226 "), stdout);
227 fputs (_("\
229 The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
230 The version control method may be selected via the --backup option or through\n\
231 the VERSION_CONTROL environment variable. Here are the values:\n\
233 "), stdout);
234 fputs (_("\
235 none, off never make backups (even if --backup is given)\n\
236 numbered, t make numbered backups\n\
237 existing, nil numbered if numbered backups exist, simple otherwise\n\
238 simple, never always make simple backups\n\
239 "), stdout);
240 fputs (_("\
242 As a special case, cp makes a backup of SOURCE when the force and backup\n\
243 options are given and SOURCE and DEST are the same name for an existing,\n\
244 regular file.\n\
245 "), stdout);
246 emit_bug_reporting_address ();
248 exit (status);
251 /* Ensure that the parent directories of CONST_DST_NAME have the
252 correct protections, for the --parents option. This is done
253 after all copying has been completed, to allow permissions
254 that don't include user write/execute.
256 SRC_OFFSET is the index in CONST_DST_NAME of the beginning of the
257 source directory name.
259 ATTR_LIST is a null-terminated linked list of structures that
260 indicates the end of the filename of each intermediate directory
261 in CONST_DST_NAME that may need to have its attributes changed.
262 The command `cp --parents --preserve a/b/c d/e_dir' changes the
263 attributes of the directories d/e_dir/a and d/e_dir/a/b to match
264 the corresponding source directories regardless of whether they
265 existed before the `cp' command was given.
267 Return true if the parent of CONST_DST_NAME and any intermediate
268 directories specified by ATTR_LIST have the proper permissions
269 when done. */
271 static bool
272 re_protect (char const *const_dst_name, size_t src_offset,
273 struct dir_attr *attr_list, const struct cp_options *x)
275 struct dir_attr *p;
276 char *dst_name; /* A copy of CONST_DST_NAME we can change. */
277 char *src_name; /* The source name in `dst_name'. */
279 ASSIGN_STRDUPA (dst_name, const_dst_name);
280 src_name = dst_name + src_offset;
282 for (p = attr_list; p; p = p->next)
284 dst_name[p->slash_offset] = '\0';
286 /* Adjust the times (and if possible, ownership) for the copy.
287 chown turns off set[ug]id bits for non-root,
288 so do the chmod last. */
290 if (x->preserve_timestamps)
292 struct timespec timespec[2];
294 timespec[0] = get_stat_atime (&p->st);
295 timespec[1] = get_stat_mtime (&p->st);
297 if (utimens (dst_name, timespec))
299 error (0, errno, _("failed to preserve times for %s"),
300 quote (dst_name));
301 return false;
305 if (x->preserve_ownership)
307 if (lchown (dst_name, p->st.st_uid, p->st.st_gid) != 0)
309 if (! chown_failure_ok (x))
311 error (0, errno, _("failed to preserve ownership for %s"),
312 quote (dst_name));
313 return false;
315 /* Failing to preserve ownership is OK. Still, try to preserve
316 the group, but ignore the possible error. */
317 ignore_value (lchown (dst_name, -1, p->st.st_gid));
321 if (x->preserve_mode)
323 if (copy_acl (src_name, -1, dst_name, -1, p->st.st_mode) != 0)
324 return false;
326 else if (p->restore_mode)
328 if (lchmod (dst_name, p->st.st_mode) != 0)
330 error (0, errno, _("failed to preserve permissions for %s"),
331 quote (dst_name));
332 return false;
336 dst_name[p->slash_offset] = '/';
338 return true;
341 /* Ensure that the parent directory of CONST_DIR exists, for
342 the --parents option.
344 SRC_OFFSET is the index in CONST_DIR (which is a destination
345 directory) of the beginning of the source directory name.
346 Create any leading directories that don't already exist.
347 If VERBOSE_FMT_STRING is nonzero, use it as a printf format
348 string for printing a message after successfully making a directory.
349 The format should take two string arguments: the names of the
350 source and destination directories.
351 Creates a linked list of attributes of intermediate directories,
352 *ATTR_LIST, for re_protect to use after calling copy.
353 Sets *NEW_DST if this function creates parent of CONST_DIR.
355 Return true if parent of CONST_DIR exists as a directory with the proper
356 permissions when done. */
358 /* FIXME: Synch this function with the one in ../lib/mkdir-p.c. */
360 static bool
361 make_dir_parents_private (char const *const_dir, size_t src_offset,
362 char const *verbose_fmt_string,
363 struct dir_attr **attr_list, bool *new_dst,
364 const struct cp_options *x)
366 struct stat stats;
367 char *dir; /* A copy of CONST_DIR we can change. */
368 char *src; /* Source name in DIR. */
369 char *dst_dir; /* Leading directory of DIR. */
370 size_t dirlen; /* Length of DIR. */
372 ASSIGN_STRDUPA (dir, const_dir);
374 src = dir + src_offset;
376 dirlen = dir_len (dir);
377 dst_dir = alloca (dirlen + 1);
378 memcpy (dst_dir, dir, dirlen);
379 dst_dir[dirlen] = '\0';
381 *attr_list = NULL;
383 if (stat (dst_dir, &stats) != 0)
385 /* A parent of CONST_DIR does not exist.
386 Make all missing intermediate directories. */
387 char *slash;
389 slash = src;
390 while (*slash == '/')
391 slash++;
392 while ((slash = strchr (slash, '/')))
394 struct dir_attr *new IF_LINT (= NULL);
395 bool missing_dir;
397 *slash = '\0';
398 missing_dir = (stat (dir, &stats) != 0);
400 if (missing_dir | x->preserve_ownership | x->preserve_mode
401 | x->preserve_timestamps)
403 /* Add this directory to the list of directories whose
404 modes might need fixing later. */
405 struct stat src_st;
406 int src_errno = (stat (src, &src_st) != 0
407 ? errno
408 : S_ISDIR (src_st.st_mode)
410 : ENOTDIR);
411 if (src_errno)
413 error (0, src_errno, _("failed to get attributes of %s"),
414 quote (src));
415 return false;
418 new = xmalloc (sizeof *new);
419 new->st = src_st;
420 new->slash_offset = slash - dir;
421 new->restore_mode = false;
422 new->next = *attr_list;
423 *attr_list = new;
426 if (missing_dir)
428 mode_t src_mode;
429 mode_t omitted_permissions;
430 mode_t mkdir_mode;
432 /* This component does not exist. We must set
433 *new_dst and new->st.st_mode inside this loop because,
434 for example, in the command `cp --parents ../a/../b/c e_dir',
435 make_dir_parents_private creates only e_dir/../a if
436 ./b already exists. */
437 *new_dst = true;
438 src_mode = new->st.st_mode;
440 /* If the ownership or special mode bits might change,
441 omit some permissions at first, so unauthorized users
442 cannot nip in before the file is ready. */
443 omitted_permissions = (src_mode
444 & (x->preserve_ownership
445 ? S_IRWXG | S_IRWXO
446 : x->preserve_mode
447 ? S_IWGRP | S_IWOTH
448 : 0));
450 /* POSIX says mkdir's behavior is implementation-defined when
451 (src_mode & ~S_IRWXUGO) != 0. However, common practice is
452 to ask mkdir to copy all the CHMOD_MODE_BITS, letting mkdir
453 decide what to do with S_ISUID | S_ISGID | S_ISVTX. */
454 mkdir_mode = src_mode & CHMOD_MODE_BITS & ~omitted_permissions;
455 if (mkdir (dir, mkdir_mode) != 0)
457 error (0, errno, _("cannot make directory %s"),
458 quote (dir));
459 return false;
461 else
463 if (verbose_fmt_string != NULL)
464 printf (verbose_fmt_string, src, dir);
467 /* We need search and write permissions to the new directory
468 for writing the directory's contents. Check if these
469 permissions are there. */
471 if (lstat (dir, &stats))
473 error (0, errno, _("failed to get attributes of %s"),
474 quote (dir));
475 return false;
479 if (! x->preserve_mode)
481 if (omitted_permissions & ~stats.st_mode)
482 omitted_permissions &= ~ cached_umask ();
483 if (omitted_permissions & ~stats.st_mode
484 || (stats.st_mode & S_IRWXU) != S_IRWXU)
486 new->st.st_mode = stats.st_mode | omitted_permissions;
487 new->restore_mode = true;
491 if ((stats.st_mode & S_IRWXU) != S_IRWXU)
493 /* Make the new directory searchable and writable.
494 The original permissions will be restored later. */
496 if (lchmod (dir, stats.st_mode | S_IRWXU) != 0)
498 error (0, errno, _("setting permissions for %s"),
499 quote (dir));
500 return false;
504 else if (!S_ISDIR (stats.st_mode))
506 error (0, 0, _("%s exists but is not a directory"),
507 quote (dir));
508 return false;
510 else
511 *new_dst = false;
512 *slash++ = '/';
514 /* Avoid unnecessary calls to `stat' when given
515 file names containing multiple adjacent slashes. */
516 while (*slash == '/')
517 slash++;
521 /* We get here if the parent of DIR already exists. */
523 else if (!S_ISDIR (stats.st_mode))
525 error (0, 0, _("%s exists but is not a directory"), quote (dst_dir));
526 return false;
528 else
530 *new_dst = false;
532 return true;
535 /* FILE is the last operand of this command.
536 Return true if FILE is a directory.
537 But report an error and exit if there is a problem accessing FILE,
538 or if FILE does not exist but would have to refer to an existing
539 directory if it referred to anything at all.
541 If the file exists, store the file's status into *ST.
542 Otherwise, set *NEW_DST. */
544 static bool
545 target_directory_operand (char const *file, struct stat *st, bool *new_dst)
547 int err = (stat (file, st) == 0 ? 0 : errno);
548 bool is_a_dir = !err && S_ISDIR (st->st_mode);
549 if (err)
551 if (err != ENOENT)
552 error (EXIT_FAILURE, err, _("accessing %s"), quote (file));
553 *new_dst = true;
555 return is_a_dir;
558 /* Scan the arguments, and copy each by calling copy.
559 Return true if successful. */
561 static bool
562 do_copy (int n_files, char **file, const char *target_directory,
563 bool no_target_directory, struct cp_options *x)
565 struct stat sb;
566 bool new_dst = false;
567 bool ok = true;
569 if (n_files <= !target_directory)
571 if (n_files <= 0)
572 error (0, 0, _("missing file operand"));
573 else
574 error (0, 0, _("missing destination file operand after %s"),
575 quote (file[0]));
576 usage (EXIT_FAILURE);
579 if (no_target_directory)
581 if (target_directory)
582 error (EXIT_FAILURE, 0,
583 _("cannot combine --target-directory (-t) "
584 "and --no-target-directory (-T)"));
585 if (2 < n_files)
587 error (0, 0, _("extra operand %s"), quote (file[2]));
588 usage (EXIT_FAILURE);
591 else if (!target_directory)
593 if (2 <= n_files
594 && target_directory_operand (file[n_files - 1], &sb, &new_dst))
595 target_directory = file[--n_files];
596 else if (2 < n_files)
597 error (EXIT_FAILURE, 0, _("target %s is not a directory"),
598 quote (file[n_files - 1]));
601 if (target_directory)
603 /* cp file1...filen edir
604 Copy the files `file1' through `filen'
605 to the existing directory `edir'. */
606 int i;
608 /* Initialize these hash tables only if we'll need them.
609 The problems they're used to detect can arise only if
610 there are two or more files to copy. */
611 if (2 <= n_files)
613 dest_info_init (x);
614 src_info_init (x);
617 for (i = 0; i < n_files; i++)
619 char *dst_name;
620 bool parent_exists = true; /* True if dir_name (dst_name) exists. */
621 struct dir_attr *attr_list;
622 char *arg_in_concat = NULL;
623 char *arg = file[i];
625 /* Trailing slashes are meaningful (i.e., maybe worth preserving)
626 only in the source file names. */
627 if (remove_trailing_slashes)
628 strip_trailing_slashes (arg);
630 if (parents_option)
632 char *arg_no_trailing_slash;
634 /* Use `arg' without trailing slashes in constructing destination
635 file names. Otherwise, we can end up trying to create a
636 directory via `mkdir ("dst/foo/"...', which is not portable.
637 It fails, due to the trailing slash, on at least
638 NetBSD 1.[34] systems. */
639 ASSIGN_STRDUPA (arg_no_trailing_slash, arg);
640 strip_trailing_slashes (arg_no_trailing_slash);
642 /* Append all of `arg' (minus any trailing slash) to `dest'. */
643 dst_name = file_name_concat (target_directory,
644 arg_no_trailing_slash,
645 &arg_in_concat);
647 /* For --parents, we have to make sure that the directory
648 dir_name (dst_name) exists. We may have to create a few
649 leading directories. */
650 parent_exists =
651 (make_dir_parents_private
652 (dst_name, arg_in_concat - dst_name,
653 (x->verbose ? "%s -> %s\n" : NULL),
654 &attr_list, &new_dst, x));
656 else
658 char *arg_base;
659 /* Append the last component of `arg' to `target_directory'. */
661 ASSIGN_BASENAME_STRDUPA (arg_base, arg);
662 /* For `cp -R source/.. dest', don't copy into `dest/..'. */
663 dst_name = (STREQ (arg_base, "..")
664 ? xstrdup (target_directory)
665 : file_name_concat (target_directory, arg_base,
666 NULL));
669 if (!parent_exists)
671 /* make_dir_parents_private failed, so don't even
672 attempt the copy. */
673 ok = false;
675 else
677 bool copy_into_self;
678 ok &= copy (arg, dst_name, new_dst, x, &copy_into_self, NULL);
680 if (parents_option)
681 ok &= re_protect (dst_name, arg_in_concat - dst_name,
682 attr_list, x);
685 if (parents_option)
687 while (attr_list)
689 struct dir_attr *p = attr_list;
690 attr_list = attr_list->next;
691 free (p);
695 free (dst_name);
698 else /* !target_directory */
700 char const *new_dest;
701 char const *source = file[0];
702 char const *dest = file[1];
703 bool unused;
705 if (parents_option)
707 error (0, 0,
708 _("with --parents, the destination must be a directory"));
709 usage (EXIT_FAILURE);
712 /* When the force and backup options have been specified and
713 the source and destination are the same name for an existing
714 regular file, convert the user's command, e.g.,
715 `cp --force --backup foo foo' to `cp --force foo fooSUFFIX'
716 where SUFFIX is determined by any version control options used. */
718 if (x->unlink_dest_after_failed_open
719 && x->backup_type != no_backups
720 && STREQ (source, dest)
721 && !new_dst && S_ISREG (sb.st_mode))
723 static struct cp_options x_tmp;
725 new_dest = find_backup_file_name (dest, x->backup_type);
726 /* Set x->backup_type to `no_backups' so that the normal backup
727 mechanism is not used when performing the actual copy.
728 backup_type must be set to `no_backups' only *after* the above
729 call to find_backup_file_name -- that function uses
730 backup_type to determine the suffix it applies. */
731 x_tmp = *x;
732 x_tmp.backup_type = no_backups;
733 x = &x_tmp;
735 else
737 new_dest = dest;
740 ok = copy (source, new_dest, 0, x, &unused, NULL);
743 return ok;
746 static void
747 cp_option_init (struct cp_options *x)
749 cp_options_default (x);
750 x->copy_as_regular = true;
751 x->dereference = DEREF_UNDEFINED;
752 x->unlink_dest_before_opening = false;
753 x->unlink_dest_after_failed_open = false;
754 x->hard_link = false;
755 x->interactive = I_UNSPECIFIED;
756 x->move_mode = false;
757 x->one_file_system = false;
758 x->reflink = false;
760 x->preserve_ownership = false;
761 x->preserve_links = false;
762 x->preserve_mode = false;
763 x->preserve_timestamps = false;
764 x->preserve_security_context = false;
765 x->require_preserve_context = false;
766 x->preserve_xattr = false;
767 x->reduce_diagnostics = false;
768 x->require_preserve_xattr = false;
770 x->require_preserve = false;
771 x->recursive = false;
772 x->sparse_mode = SPARSE_AUTO;
773 x->symbolic_link = false;
774 x->set_mode = false;
775 x->mode = 0;
777 /* Not used. */
778 x->stdin_tty = false;
780 x->update = false;
781 x->verbose = false;
783 /* By default, refuse to open a dangling destination symlink, because
784 in general one cannot do that safely, give the current semantics of
785 open's O_EXCL flag, (which POSIX doesn't even allow cp to use, btw).
786 But POSIX requires it. */
787 x->open_dangling_dest_symlink = getenv ("POSIXLY_CORRECT") != NULL;
789 x->dest_info = NULL;
790 x->src_info = NULL;
793 /* Given a string, ARG, containing a comma-separated list of arguments
794 to the --preserve option, set the appropriate fields of X to ON_OFF. */
795 static void
796 decode_preserve_arg (char const *arg, struct cp_options *x, bool on_off)
798 enum File_attribute
800 PRESERVE_MODE,
801 PRESERVE_TIMESTAMPS,
802 PRESERVE_OWNERSHIP,
803 PRESERVE_LINK,
804 PRESERVE_CONTEXT,
805 PRESERVE_XATTR,
806 PRESERVE_ALL
808 static enum File_attribute const preserve_vals[] =
810 PRESERVE_MODE, PRESERVE_TIMESTAMPS,
811 PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_CONTEXT, PRESERVE_XATTR,
812 PRESERVE_ALL
814 /* Valid arguments to the `--preserve' option. */
815 static char const* const preserve_args[] =
817 "mode", "timestamps",
818 "ownership", "links", "context", "xattr", "all", NULL
820 ARGMATCH_VERIFY (preserve_args, preserve_vals);
822 char *arg_writable = xstrdup (arg);
823 char *s = arg_writable;
826 /* find next comma */
827 char *comma = strchr (s, ',');
828 enum File_attribute val;
830 /* If we found a comma, put a NUL in its place and advance. */
831 if (comma)
832 *comma++ = 0;
834 /* process S. */
835 val = XARGMATCH ("--preserve", s, preserve_args, preserve_vals);
836 switch (val)
838 case PRESERVE_MODE:
839 x->preserve_mode = on_off;
840 break;
842 case PRESERVE_TIMESTAMPS:
843 x->preserve_timestamps = on_off;
844 break;
846 case PRESERVE_OWNERSHIP:
847 x->preserve_ownership = on_off;
848 break;
850 case PRESERVE_LINK:
851 x->preserve_links = on_off;
852 break;
854 case PRESERVE_CONTEXT:
855 x->preserve_security_context = on_off;
856 x->require_preserve_context = on_off;
857 break;
859 case PRESERVE_XATTR:
860 x->preserve_xattr = on_off;
861 x->require_preserve_xattr = on_off;
862 break;
864 case PRESERVE_ALL:
865 x->preserve_mode = on_off;
866 x->preserve_timestamps = on_off;
867 x->preserve_ownership = on_off;
868 x->preserve_links = on_off;
869 if (selinux_enabled)
870 x->preserve_security_context = on_off;
871 x->preserve_xattr = on_off;
872 break;
874 default:
875 abort ();
877 s = comma;
879 while (s);
881 free (arg_writable);
885 main (int argc, char **argv)
887 int c;
888 bool ok;
889 bool make_backups = false;
890 char *backup_suffix_string;
891 char *version_control_string = NULL;
892 struct cp_options x;
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 ());
906 cp_option_init (&x);
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, "abdfHilLnprst:uvxPRS:T",
913 long_opts, NULL))
914 != -1)
916 switch (c)
918 case SPARSE_OPTION:
919 x.sparse_mode = XARGMATCH ("--sparse", optarg,
920 sparse_type_string, sparse_type);
921 break;
923 case REFLINK_OPTION:
924 x.reflink = true;
925 break;
927 case 'a': /* Like -dR --preserve=all with reduced failure diagnostics. */
928 x.dereference = DEREF_NEVER;
929 x.preserve_links = true;
930 x.preserve_ownership = true;
931 x.preserve_mode = true;
932 x.preserve_timestamps = true;
933 x.require_preserve = true;
934 if (selinux_enabled)
935 x.preserve_security_context = true;
936 x.preserve_xattr = true;
937 x.reduce_diagnostics = true;
938 x.recursive = true;
939 break;
941 case 'b':
942 make_backups = true;
943 if (optarg)
944 version_control_string = optarg;
945 break;
947 case COPY_CONTENTS_OPTION:
948 copy_contents = true;
949 break;
951 case 'd':
952 x.preserve_links = true;
953 x.dereference = DEREF_NEVER;
954 break;
956 case 'f':
957 x.unlink_dest_after_failed_open = true;
958 break;
960 case 'H':
961 x.dereference = DEREF_COMMAND_LINE_ARGUMENTS;
962 break;
964 case 'i':
965 x.interactive = I_ASK_USER;
966 break;
968 case 'l':
969 x.hard_link = true;
970 break;
972 case 'L':
973 x.dereference = DEREF_ALWAYS;
974 break;
976 case 'n':
977 x.interactive = I_ALWAYS_NO;
978 break;
980 case 'P':
981 x.dereference = DEREF_NEVER;
982 break;
984 case NO_PRESERVE_ATTRIBUTES_OPTION:
985 decode_preserve_arg (optarg, &x, false);
986 break;
988 case PRESERVE_ATTRIBUTES_OPTION:
989 if (optarg == NULL)
991 /* Fall through to the case for `p' below. */
993 else
995 decode_preserve_arg (optarg, &x, true);
996 x.require_preserve = true;
997 break;
1000 case 'p':
1001 x.preserve_ownership = true;
1002 x.preserve_mode = true;
1003 x.preserve_timestamps = true;
1004 x.require_preserve = true;
1005 break;
1007 case PARENTS_OPTION:
1008 parents_option = true;
1009 break;
1011 case 'r':
1012 case 'R':
1013 x.recursive = true;
1014 break;
1016 case UNLINK_DEST_BEFORE_OPENING:
1017 x.unlink_dest_before_opening = true;
1018 break;
1020 case STRIP_TRAILING_SLASHES_OPTION:
1021 remove_trailing_slashes = true;
1022 break;
1024 case 's':
1025 x.symbolic_link = true;
1026 break;
1028 case 't':
1029 if (target_directory)
1030 error (EXIT_FAILURE, 0,
1031 _("multiple target directories specified"));
1032 else
1034 struct stat st;
1035 if (stat (optarg, &st) != 0)
1036 error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg));
1037 if (! S_ISDIR (st.st_mode))
1038 error (EXIT_FAILURE, 0, _("target %s is not a directory"),
1039 quote (optarg));
1041 target_directory = optarg;
1042 break;
1044 case 'T':
1045 no_target_directory = true;
1046 break;
1048 case 'u':
1049 x.update = true;
1050 break;
1052 case 'v':
1053 x.verbose = true;
1054 break;
1056 case 'x':
1057 x.one_file_system = true;
1058 break;
1060 case 'S':
1061 make_backups = true;
1062 backup_suffix_string = optarg;
1063 break;
1065 case_GETOPT_HELP_CHAR;
1067 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
1069 default:
1070 usage (EXIT_FAILURE);
1074 if (x.hard_link & x.symbolic_link)
1076 error (0, 0, _("cannot make both hard and symbolic links"));
1077 usage (EXIT_FAILURE);
1080 if (make_backups && x.interactive == I_ALWAYS_NO)
1082 error (0, 0,
1083 _("options --backup and --no-clobber are mutually exclusive"));
1084 usage (EXIT_FAILURE);
1087 if (x.reflink && x.sparse_mode != SPARSE_AUTO)
1089 error (0, 0, _("--reflink can be used only with --sparse=auto"));
1090 usage (EXIT_FAILURE);
1093 if (backup_suffix_string)
1094 simple_backup_suffix = xstrdup (backup_suffix_string);
1096 x.backup_type = (make_backups
1097 ? xget_version (_("backup type"),
1098 version_control_string)
1099 : no_backups);
1101 if (x.dereference == DEREF_UNDEFINED)
1103 if (x.recursive)
1104 /* This is compatible with FreeBSD. */
1105 x.dereference = DEREF_NEVER;
1106 else
1107 x.dereference = DEREF_ALWAYS;
1110 if (x.recursive)
1111 x.copy_as_regular = copy_contents;
1113 /* If --force (-f) was specified and we're in link-creation mode,
1114 first remove any existing destination file. */
1115 if (x.unlink_dest_after_failed_open & (x.hard_link | x.symbolic_link))
1116 x.unlink_dest_before_opening = true;
1118 if (x.preserve_security_context)
1120 if (!selinux_enabled)
1121 error (EXIT_FAILURE, 0,
1122 _("cannot preserve security context "
1123 "without an SELinux-enabled kernel"));
1126 #if !USE_XATTR
1127 if (x.require_preserve_xattr)
1128 error (EXIT_FAILURE, 0, _("cannot preserve extended attributes, cp is "
1129 "built without xattr support"));
1130 #endif
1132 /* Allocate space for remembering copied and created files. */
1134 hash_init ();
1136 ok = do_copy (argc - optind, argv + optind,
1137 target_directory, no_target_directory, &x);
1139 forget_all ();
1141 exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);