1/* cp.c  -- file copying (main routines)
2   Copyright (C) 1989-1991, 1995-2010 Free Software Foundation, Inc.
3
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.
8
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.
13
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/>.
16
17   Written by Torbjorn Granlund, David MacKenzie, and Jim Meyering. */
18
19#include <config.h>
20#include <stdio.h>
21#include <sys/types.h>
22#include <getopt.h>
23#include <selinux/selinux.h>
24
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"
37
38#if ! HAVE_LCHOWN
39# define lchown(name, uid, gid) chown (name, uid, gid)
40#endif
41
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)
51
52/* The official name of this program (e.g., no `g' prefix).  */
53#define PROGRAM_NAME "cp"
54
55#define AUTHORS \
56  proper_name_utf8 ("Torbjorn Granlund", "Torbj\303\266rn Granlund"), \
57  proper_name ("David MacKenzie"), \
58  proper_name ("Jim Meyering")
59
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. */
63struct dir_attr
64{
65  struct stat st;
66  bool restore_mode;
67  size_t slash_offset;
68  struct dir_attr *next;
69};
70
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.  */
73enum
74{
75  COPY_CONTENTS_OPTION = CHAR_MAX + 1,
76  IGNORE_ATTRIBUTES,
77  NO_PRESERVE_ATTRIBUTES_OPTION,
78  PARENTS_OPTION,
79  PRESERVE_ATTRIBUTES_OPTION,
80  REFLINK_OPTION,
81  SPARSE_OPTION,
82  STRIP_TRAILING_SLASHES_OPTION,
83  UNLINK_DEST_BEFORE_OPENING
84};
85
86/* True if the kernel is SELinux enabled.  */
87static bool selinux_enabled;
88
89/* If true, the command "cp x/e_file e_dir" uses "e_dir/x/e_file"
90   as its destination instead of the usual "e_dir/e_file." */
91static bool parents_option = false;
92
93/* Remove any trailing slashes from each SOURCE argument.  */
94static bool remove_trailing_slashes;
95
96static char const *const sparse_type_string[] =
97{
98  "never", "auto", "always", NULL
99};
100static enum Sparse_type const sparse_type[] =
101{
102  SPARSE_NEVER, SPARSE_AUTO, SPARSE_ALWAYS
103};
104ARGMATCH_VERIFY (sparse_type_string, sparse_type);
105
106static char const *const reflink_type_string[] =
107{
108  "auto", "always", NULL
109};
110static enum Reflink_type const reflink_type[] =
111{
112  REFLINK_AUTO, REFLINK_ALWAYS
113};
114ARGMATCH_VERIFY (reflink_type_string, reflink_type);
115
116static struct option const long_opts[] =
117{
118  {"archive", no_argument, NULL, 'a'},
119  {"backup", optional_argument, NULL, 'b'},
120  {"copy-contents", no_argument, NULL, COPY_CONTENTS_OPTION},
121  {"dereference", no_argument, NULL, 'L'},
122  {"force", no_argument, NULL, 'f'},
123  {"ignore-attributes", no_argument, NULL, IGNORE_ATTRIBUTES},
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", no_argument, NULL, 'u'},
143  {"verbose", no_argument, NULL, 'v'},
144  {GETOPT_HELP_OPTION_DECL},
145  {GETOPT_VERSION_OPTION_DECL},
146  {NULL, 0, NULL, 0}
147};
148
149void
150usage (int status)
151{
152  if (status != EXIT_SUCCESS)
153    fprintf (stderr, _("Try `%s --help' for more information.\n"),
154             program_name);
155  else
156    {
157      printf (_("\
158Usage: %s [OPTION]... [-T] SOURCE DEST\n\
159  or:  %s [OPTION]... SOURCE... DIRECTORY\n\
160  or:  %s [OPTION]... -t DIRECTORY SOURCE...\n\
161"),
162              program_name, program_name, program_name);
163      fputs (_("\
164Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\
165\n\
166"), stdout);
167      fputs (_("\
168Mandatory arguments to long options are mandatory for short options too.\n\
169"), stdout);
170      fputs (_("\
171  -a, --archive                same as -dR --preserve=all\n\
172      --backup[=CONTROL]       make a backup of each existing destination file\n\
173  -b                           like --backup but does not accept an argument\n\
174      --copy-contents          copy contents of special files when recursive\n\
175  -d                           same as --no-dereference --preserve=links\n\
176"), stdout);
177      fputs (_("\
178  -f, --force                  if an existing destination file cannot be\n\
179                                 opened, remove it and try again (redundant if\n\
180                                 the -n option is used)\n\
181      --ignore-attributes      do not copy attributes\n\
182  -i, --interactive            prompt before overwrite (overrides a previous -n\n\
183                                  option)\n\
184  -H                           follow command-line symbolic links in SOURCE\n\
185"), stdout);
186      fputs (_("\
187  -l, --link                   link files instead of copying\n\
188  -L, --dereference            always follow symbolic links in SOURCE\n\
189"), stdout);
190      fputs (_("\
191  -n, --no-clobber             do not overwrite an existing file (overrides\n\
192                                 a previous -i option)\n\
193  -P, --no-dereference         never follow symbolic links in SOURCE\n\
194"), stdout);
195      fputs (_("\
196  -p                           same as --preserve=mode,ownership,timestamps\n\
197      --preserve[=ATTR_LIST]   preserve the specified attributes (default:\n\
198                                 mode,ownership,timestamps), if possible\n\
199                                 additional attributes: context, links, xattr,\n\
200                                 all\n\
201"), stdout);
202      fputs (_("\
203      --no-preserve=ATTR_LIST  don't preserve the specified attributes\n\
204      --parents                use full source file name under DIRECTORY\n\
205"), stdout);
206      fputs (_("\
207  -R, -r, --recursive          copy directories recursively\n\
208      --reflink[=WHEN]         control clone/CoW copies. See below.\n\
209      --remove-destination     remove each existing destination file before\n\
210                                 attempting to open it (contrast with --force)\n\
211"), stdout);
212      fputs (_("\
213      --sparse=WHEN            control creation of sparse files. See below.\n\
214      --strip-trailing-slashes  remove any trailing slashes from each SOURCE\n\
215                                 argument\n\
216"), stdout);
217      fputs (_("\
218  -s, --symbolic-link          make symbolic links instead of copying\n\
219  -S, --suffix=SUFFIX          override the usual backup suffix\n\
220  -t, --target-directory=DIRECTORY  copy all SOURCE arguments into DIRECTORY\n\
221  -T, --no-target-directory    treat DEST as a normal file\n\
222"), stdout);
223      fputs (_("\
224  -u, --update                 copy only when the SOURCE file is newer\n\
225                                 than the destination file or when the\n\
226                                 destination file is missing\n\
227  -v, --verbose                explain what is being done\n\
228  -x, --one-file-system        stay on this file system\n\
229"), stdout);
230      fputs (HELP_OPTION_DESCRIPTION, stdout);
231      fputs (VERSION_OPTION_DESCRIPTION, stdout);
232      fputs (_("\
233\n\
234By default, sparse SOURCE files are detected by a crude heuristic and the\n\
235corresponding DEST file is made sparse as well.  That is the behavior\n\
236selected by --sparse=auto.  Specify --sparse=always to create a sparse DEST\n\
237file whenever the SOURCE file contains a long enough sequence of zero bytes.\n\
238Use --sparse=never to inhibit creation of sparse files.\n\
239\n\
240When --reflink[=always] is specified, perform a lightweight copy, where the\n\
241data blocks are copied only when modified.  If this is not possible the copy\n\
242fails, or if --reflink=auto is specified, fall back to a standard copy.\n\
243"), stdout);
244      fputs (_("\
245\n\
246The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
247The version control method may be selected via the --backup option or through\n\
248the VERSION_CONTROL environment variable.  Here are the values:\n\
249\n\
250"), stdout);
251      fputs (_("\
252  none, off       never make backups (even if --backup is given)\n\
253  numbered, t     make numbered backups\n\
254  existing, nil   numbered if numbered backups exist, simple otherwise\n\
255  simple, never   always make simple backups\n\
256"), stdout);
257      fputs (_("\
258\n\
259As a special case, cp makes a backup of SOURCE when the force and backup\n\
260options are given and SOURCE and DEST are the same name for an existing,\n\
261regular file.\n\
262"), stdout);
263      emit_ancillary_info ();
264    }
265  exit (status);
266}
267
268/* Ensure that the parent directories of CONST_DST_NAME have the
269   correct protections, for the --parents option.  This is done
270   after all copying has been completed, to allow permissions
271   that don't include user write/execute.
272
273   SRC_OFFSET is the index in CONST_DST_NAME of the beginning of the
274   source directory name.
275
276   ATTR_LIST is a null-terminated linked list of structures that
277   indicates the end of the filename of each intermediate directory
278   in CONST_DST_NAME that may need to have its attributes changed.
279   The command `cp --parents --preserve a/b/c d/e_dir' changes the
280   attributes of the directories d/e_dir/a and d/e_dir/a/b to match
281   the corresponding source directories regardless of whether they
282   existed before the `cp' command was given.
283
284   Return true if the parent of CONST_DST_NAME and any intermediate
285   directories specified by ATTR_LIST have the proper permissions
286   when done.  */
287
288static bool
289re_protect (char const *const_dst_name, size_t src_offset,
290            struct dir_attr *attr_list, const struct cp_options *x)
291{
292  struct dir_attr *p;
293  char *dst_name;		/* A copy of CONST_DST_NAME we can change. */
294  char *src_name;		/* The source name in `dst_name'. */
295
296  ASSIGN_STRDUPA (dst_name, const_dst_name);
297  src_name = dst_name + src_offset;
298
299  for (p = attr_list; p; p = p->next)
300    {
301      dst_name[p->slash_offset] = '\0';
302
303      /* Adjust the times (and if possible, ownership) for the copy.
304         chown turns off set[ug]id bits for non-root,
305         so do the chmod last.  */
306
307      if (x->preserve_timestamps)
308        {
309          struct timespec timespec[2];
310
311          timespec[0] = get_stat_atime (&p->st);
312          timespec[1] = get_stat_mtime (&p->st);
313
314          if (utimens (dst_name, timespec))
315            {
316              error (0, errno, _("failed to preserve times for %s"),
317                     quote (dst_name));
318              return false;
319            }
320        }
321
322      if (x->preserve_ownership)
323        {
324          if (lchown (dst_name, p->st.st_uid, p->st.st_gid) != 0)
325            {
326              if (! chown_failure_ok (x))
327                {
328                  error (0, errno, _("failed to preserve ownership for %s"),
329                         quote (dst_name));
330                  return false;
331                }
332              /* Failing to preserve ownership is OK. Still, try to preserve
333                 the group, but ignore the possible error. */
334              ignore_value (lchown (dst_name, -1, p->st.st_gid));
335            }
336        }
337
338      if (x->preserve_mode)
339        {
340          if (copy_acl (src_name, -1, dst_name, -1, p->st.st_mode) != 0)
341            return false;
342        }
343      else if (p->restore_mode)
344        {
345          if (lchmod (dst_name, p->st.st_mode) != 0)
346            {
347              error (0, errno, _("failed to preserve permissions for %s"),
348                     quote (dst_name));
349              return false;
350            }
351        }
352
353      dst_name[p->slash_offset] = '/';
354    }
355  return true;
356}
357
358/* Ensure that the parent directory of CONST_DIR exists, for
359   the --parents option.
360
361   SRC_OFFSET is the index in CONST_DIR (which is a destination
362   directory) of the beginning of the source directory name.
363   Create any leading directories that don't already exist.
364   If VERBOSE_FMT_STRING is nonzero, use it as a printf format
365   string for printing a message after successfully making a directory.
366   The format should take two string arguments: the names of the
367   source and destination directories.
368   Creates a linked list of attributes of intermediate directories,
369   *ATTR_LIST, for re_protect to use after calling copy.
370   Sets *NEW_DST if this function creates parent of CONST_DIR.
371
372   Return true if parent of CONST_DIR exists as a directory with the proper
373   permissions when done.  */
374
375/* FIXME: Synch this function with the one in ../lib/mkdir-p.c.  */
376
377static bool
378make_dir_parents_private (char const *const_dir, size_t src_offset,
379                          char const *verbose_fmt_string,
380                          struct dir_attr **attr_list, bool *new_dst,
381                          const struct cp_options *x)
382{
383  struct stat stats;
384  char *dir;		/* A copy of CONST_DIR we can change.  */
385  char *src;		/* Source name in DIR.  */
386  char *dst_dir;	/* Leading directory of DIR.  */
387  size_t dirlen;	/* Length of DIR.  */
388
389  ASSIGN_STRDUPA (dir, const_dir);
390
391  src = dir + src_offset;
392
393  dirlen = dir_len (dir);
394  dst_dir = alloca (dirlen + 1);
395  memcpy (dst_dir, dir, dirlen);
396  dst_dir[dirlen] = '\0';
397
398  *attr_list = NULL;
399
400  if (stat (dst_dir, &stats) != 0)
401    {
402      /* A parent of CONST_DIR does not exist.
403         Make all missing intermediate directories. */
404      char *slash;
405
406      slash = src;
407      while (*slash == '/')
408        slash++;
409      while ((slash = strchr (slash, '/')))
410        {
411          struct dir_attr *new IF_LINT (= NULL);
412          bool missing_dir;
413
414          *slash = '\0';
415          missing_dir = (stat (dir, &stats) != 0);
416
417          if (missing_dir || x->preserve_ownership || x->preserve_mode
418              || x->preserve_timestamps)
419            {
420              /* Add this directory to the list of directories whose
421                 modes might need fixing later. */
422              struct stat src_st;
423              int src_errno = (stat (src, &src_st) != 0
424                               ? errno
425                               : S_ISDIR (src_st.st_mode)
426                               ? 0
427                               : ENOTDIR);
428              if (src_errno)
429                {
430                  error (0, src_errno, _("failed to get attributes of %s"),
431                         quote (src));
432                  return false;
433                }
434
435              new = xmalloc (sizeof *new);
436              new->st = src_st;
437              new->slash_offset = slash - dir;
438              new->restore_mode = false;
439              new->next = *attr_list;
440              *attr_list = new;
441            }
442
443          if (missing_dir)
444            {
445              mode_t src_mode;
446              mode_t omitted_permissions;
447              mode_t mkdir_mode;
448
449              /* This component does not exist.  We must set
450                 *new_dst and new->st.st_mode inside this loop because,
451                 for example, in the command `cp --parents ../a/../b/c e_dir',
452                 make_dir_parents_private creates only e_dir/../a if
453                 ./b already exists. */
454              *new_dst = true;
455              src_mode = new->st.st_mode;
456
457              /* If the ownership or special mode bits might change,
458                 omit some permissions at first, so unauthorized users
459                 cannot nip in before the file is ready.  */
460              omitted_permissions = (src_mode
461                                     & (x->preserve_ownership
462                                        ? S_IRWXG | S_IRWXO
463                                        : x->preserve_mode
464                                        ? S_IWGRP | S_IWOTH
465                                        : 0));
466
467              /* POSIX says mkdir's behavior is implementation-defined when
468                 (src_mode & ~S_IRWXUGO) != 0.  However, common practice is
469                 to ask mkdir to copy all the CHMOD_MODE_BITS, letting mkdir
470                 decide what to do with S_ISUID | S_ISGID | S_ISVTX.  */
471              mkdir_mode = src_mode & CHMOD_MODE_BITS & ~omitted_permissions;
472              if (mkdir (dir, mkdir_mode) != 0)
473                {
474                  error (0, errno, _("cannot make directory %s"),
475                         quote (dir));
476                  return false;
477                }
478              else
479                {
480                  if (verbose_fmt_string != NULL)
481                    printf (verbose_fmt_string, src, dir);
482                }
483
484              /* We need search and write permissions to the new directory
485                 for writing the directory's contents. Check if these
486                 permissions are there.  */
487
488              if (lstat (dir, &stats))
489                {
490                  error (0, errno, _("failed to get attributes of %s"),
491                         quote (dir));
492                  return false;
493                }
494
495
496              if (! x->preserve_mode)
497                {
498                  if (omitted_permissions & ~stats.st_mode)
499                    omitted_permissions &= ~ cached_umask ();
500                  if (omitted_permissions & ~stats.st_mode
501                      || (stats.st_mode & S_IRWXU) != S_IRWXU)
502                    {
503                      new->st.st_mode = stats.st_mode | omitted_permissions;
504                      new->restore_mode = true;
505                    }
506                }
507
508              if ((stats.st_mode & S_IRWXU) != S_IRWXU)
509                {
510                  /* Make the new directory searchable and writable.
511                     The original permissions will be restored later.  */
512
513                  if (lchmod (dir, stats.st_mode | S_IRWXU) != 0)
514                    {
515                      error (0, errno, _("setting permissions for %s"),
516                             quote (dir));
517                      return false;
518                    }
519                }
520            }
521          else if (!S_ISDIR (stats.st_mode))
522            {
523              error (0, 0, _("%s exists but is not a directory"),
524                     quote (dir));
525              return false;
526            }
527          else
528            *new_dst = false;
529          *slash++ = '/';
530
531          /* Avoid unnecessary calls to `stat' when given
532             file names containing multiple adjacent slashes.  */
533          while (*slash == '/')
534            slash++;
535        }
536    }
537
538  /* We get here if the parent of DIR already exists.  */
539
540  else if (!S_ISDIR (stats.st_mode))
541    {
542      error (0, 0, _("%s exists but is not a directory"), quote (dst_dir));
543      return false;
544    }
545  else
546    {
547      *new_dst = false;
548    }
549  return true;
550}
551
552/* FILE is the last operand of this command.
553   Return true if FILE is a directory.
554   But report an error and exit if there is a problem accessing FILE,
555   or if FILE does not exist but would have to refer to an existing
556   directory if it referred to anything at all.
557
558   If the file exists, store the file's status into *ST.
559   Otherwise, set *NEW_DST.  */
560
561static bool
562target_directory_operand (char const *file, struct stat *st, bool *new_dst)
563{
564  int err = (stat (file, st) == 0 ? 0 : errno);
565  bool is_a_dir = !err && S_ISDIR (st->st_mode);
566  if (err)
567    {
568      if (err != ENOENT)
569        error (EXIT_FAILURE, err, _("accessing %s"), quote (file));
570      *new_dst = true;
571    }
572  return is_a_dir;
573}
574
575/* Scan the arguments, and copy each by calling copy.
576   Return true if successful.  */
577
578static bool
579do_copy (int n_files, char **file, const char *target_directory,
580         bool no_target_directory, struct cp_options *x)
581{
582  struct stat sb;
583  bool new_dst = false;
584  bool ok = true;
585
586  if (n_files <= !target_directory)
587    {
588      if (n_files <= 0)
589        error (0, 0, _("missing file operand"));
590      else
591        error (0, 0, _("missing destination file operand after %s"),
592               quote (file[0]));
593      usage (EXIT_FAILURE);
594    }
595
596  if (no_target_directory)
597    {
598      if (target_directory)
599        error (EXIT_FAILURE, 0,
600               _("cannot combine --target-directory (-t) "
601                 "and --no-target-directory (-T)"));
602      if (2 < n_files)
603        {
604          error (0, 0, _("extra operand %s"), quote (file[2]));
605          usage (EXIT_FAILURE);
606        }
607    }
608  else if (!target_directory)
609    {
610      if (2 <= n_files
611          && target_directory_operand (file[n_files - 1], &sb, &new_dst))
612        target_directory = file[--n_files];
613      else if (2 < n_files)
614        error (EXIT_FAILURE, 0, _("target %s is not a directory"),
615               quote (file[n_files - 1]));
616    }
617
618  if (target_directory)
619    {
620      /* cp file1...filen edir
621         Copy the files `file1' through `filen'
622         to the existing directory `edir'. */
623      int i;
624
625      /* Initialize these hash tables only if we'll need them.
626         The problems they're used to detect can arise only if
627         there are two or more files to copy.  */
628      if (2 <= n_files)
629        {
630          dest_info_init (x);
631          src_info_init (x);
632        }
633
634      for (i = 0; i < n_files; i++)
635        {
636          char *dst_name;
637          bool parent_exists = true;  /* True if dir_name (dst_name) exists. */
638          struct dir_attr *attr_list;
639          char *arg_in_concat = NULL;
640          char *arg = file[i];
641
642          /* Trailing slashes are meaningful (i.e., maybe worth preserving)
643             only in the source file names.  */
644          if (remove_trailing_slashes)
645            strip_trailing_slashes (arg);
646
647          if (parents_option)
648            {
649              char *arg_no_trailing_slash;
650
651              /* Use `arg' without trailing slashes in constructing destination
652                 file names.  Otherwise, we can end up trying to create a
653                 directory via `mkdir ("dst/foo/"...', which is not portable.
654                 It fails, due to the trailing slash, on at least
655                 NetBSD 1.[34] systems.  */
656              ASSIGN_STRDUPA (arg_no_trailing_slash, arg);
657              strip_trailing_slashes (arg_no_trailing_slash);
658
659              /* Append all of `arg' (minus any trailing slash) to `dest'.  */
660              dst_name = file_name_concat (target_directory,
661                                           arg_no_trailing_slash,
662                                           &arg_in_concat);
663
664              /* For --parents, we have to make sure that the directory
665                 dir_name (dst_name) exists.  We may have to create a few
666                 leading directories. */
667              parent_exists =
668                (make_dir_parents_private
669                 (dst_name, arg_in_concat - dst_name,
670                  (x->verbose ? "%s -> %s\n" : NULL),
671                  &attr_list, &new_dst, x));
672            }
673          else
674            {
675              char *arg_base;
676              /* Append the last component of `arg' to `target_directory'.  */
677
678              ASSIGN_BASENAME_STRDUPA (arg_base, arg);
679              /* For `cp -R source/.. dest', don't copy into `dest/..'. */
680              dst_name = (STREQ (arg_base, "..")
681                          ? xstrdup (target_directory)
682                          : file_name_concat (target_directory, arg_base,
683                                              NULL));
684            }
685
686          if (!parent_exists)
687            {
688              /* make_dir_parents_private failed, so don't even
689                 attempt the copy.  */
690              ok = false;
691            }
692          else
693            {
694              bool copy_into_self;
695              ok &= copy (arg, dst_name, new_dst, x, &copy_into_self, NULL);
696
697              if (parents_option)
698                ok &= re_protect (dst_name, arg_in_concat - dst_name,
699                                  attr_list, x);
700            }
701
702          if (parents_option)
703            {
704              while (attr_list)
705                {
706                  struct dir_attr *p = attr_list;
707                  attr_list = attr_list->next;
708                  free (p);
709                }
710            }
711
712          free (dst_name);
713        }
714    }
715  else /* !target_directory */
716    {
717      char const *new_dest;
718      char const *source = file[0];
719      char const *dest = file[1];
720      bool unused;
721
722      if (parents_option)
723        {
724          error (0, 0,
725                 _("with --parents, the destination must be a directory"));
726          usage (EXIT_FAILURE);
727        }
728
729      /* When the force and backup options have been specified and
730         the source and destination are the same name for an existing
731         regular file, convert the user's command, e.g.,
732         `cp --force --backup foo foo' to `cp --force foo fooSUFFIX'
733         where SUFFIX is determined by any version control options used.  */
734
735      if (x->unlink_dest_after_failed_open
736          && x->backup_type != no_backups
737          && STREQ (source, dest)
738          && !new_dst && S_ISREG (sb.st_mode))
739        {
740          static struct cp_options x_tmp;
741
742          new_dest = find_backup_file_name (dest, x->backup_type);
743          /* Set x->backup_type to `no_backups' so that the normal backup
744             mechanism is not used when performing the actual copy.
745             backup_type must be set to `no_backups' only *after* the above
746             call to find_backup_file_name -- that function uses
747             backup_type to determine the suffix it applies.  */
748          x_tmp = *x;
749          x_tmp.backup_type = no_backups;
750          x = &x_tmp;
751        }
752      else
753        {
754          new_dest = dest;
755        }
756
757      ok = copy (source, new_dest, 0, x, &unused, NULL);
758    }
759
760  return ok;
761}
762
763static void
764cp_option_init (struct cp_options *x)
765{
766  cp_options_default (x);
767  x->copy_as_regular = true;
768  x->dereference = DEREF_UNDEFINED;
769  x->unlink_dest_before_opening = false;
770  x->unlink_dest_after_failed_open = false;
771  x->hard_link = false;
772  x->interactive = I_UNSPECIFIED;
773  x->move_mode = false;
774  x->one_file_system = false;
775  x->reflink_mode = REFLINK_NEVER;
776
777  x->preserve_ownership = false;
778  x->preserve_links = false;
779  x->preserve_mode = false;
780  x->preserve_timestamps = false;
781  x->preserve_security_context = false;
782  x->require_preserve_context = false;
783  x->preserve_xattr = false;
784  x->reduce_diagnostics = false;
785  x->require_preserve_xattr = false;
786
787  x->require_preserve = false;
788  x->ignore_attributes = false;
789  x->recursive = false;
790  x->sparse_mode = SPARSE_AUTO;
791  x->symbolic_link = false;
792  x->set_mode = false;
793  x->mode = 0;
794
795  /* Not used.  */
796  x->stdin_tty = false;
797
798  x->update = false;
799  x->verbose = false;
800
801  /* By default, refuse to open a dangling destination symlink, because
802     in general one cannot do that safely, give the current semantics of
803     open's O_EXCL flag, (which POSIX doesn't even allow cp to use, btw).
804     But POSIX requires it.  */
805  x->open_dangling_dest_symlink = getenv ("POSIXLY_CORRECT") != NULL;
806
807  x->dest_info = NULL;
808  x->src_info = NULL;
809}
810
811/* Given a string, ARG, containing a comma-separated list of arguments
812   to the --preserve option, set the appropriate fields of X to ON_OFF.  */
813static void
814decode_preserve_arg (char const *arg, struct cp_options *x, bool on_off)
815{
816  enum File_attribute
817    {
818      PRESERVE_MODE,
819      PRESERVE_TIMESTAMPS,
820      PRESERVE_OWNERSHIP,
821      PRESERVE_LINK,
822      PRESERVE_CONTEXT,
823      PRESERVE_XATTR,
824      PRESERVE_ALL
825    };
826  static enum File_attribute const preserve_vals[] =
827    {
828      PRESERVE_MODE, PRESERVE_TIMESTAMPS,
829      PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_CONTEXT, PRESERVE_XATTR,
830      PRESERVE_ALL
831    };
832  /* Valid arguments to the `--preserve' option. */
833  static char const* const preserve_args[] =
834    {
835      "mode", "timestamps",
836      "ownership", "links", "context", "xattr", "all", NULL
837    };
838  ARGMATCH_VERIFY (preserve_args, preserve_vals);
839
840  char *arg_writable = xstrdup (arg);
841  char *s = arg_writable;
842  do
843    {
844      /* find next comma */
845      char *comma = strchr (s, ',');
846      enum File_attribute val;
847
848      /* If we found a comma, put a NUL in its place and advance.  */
849      if (comma)
850        *comma++ = 0;
851
852      /* process S.  */
853      val = XARGMATCH ("--preserve", s, preserve_args, preserve_vals);
854      switch (val)
855        {
856        case PRESERVE_MODE:
857          x->preserve_mode = on_off;
858          break;
859
860        case PRESERVE_TIMESTAMPS:
861          x->preserve_timestamps = on_off;
862          break;
863
864        case PRESERVE_OWNERSHIP:
865          x->preserve_ownership = on_off;
866          break;
867
868        case PRESERVE_LINK:
869          x->preserve_links = on_off;
870          break;
871
872        case PRESERVE_CONTEXT:
873          x->preserve_security_context = on_off;
874          x->require_preserve_context = on_off;
875          break;
876
877        case PRESERVE_XATTR:
878          x->preserve_xattr = on_off;
879          x->require_preserve_xattr = on_off;
880          break;
881
882        case PRESERVE_ALL:
883          x->preserve_mode = on_off;
884          x->preserve_timestamps = on_off;
885          x->preserve_ownership = on_off;
886          x->preserve_links = on_off;
887          if (selinux_enabled)
888            x->preserve_security_context = on_off;
889          x->preserve_xattr = on_off;
890          break;
891
892        default:
893          abort ();
894        }
895      s = comma;
896    }
897  while (s);
898
899  free (arg_writable);
900}
901
902int
903main (int argc, char **argv)
904{
905  int c;
906  bool ok;
907  bool make_backups = false;
908  char *backup_suffix_string;
909  char *version_control_string = NULL;
910  struct cp_options x;
911  bool copy_contents = false;
912  char *target_directory = NULL;
913  bool no_target_directory = false;
914
915  initialize_main (&argc, &argv);
916  set_program_name (argv[0]);
917  setlocale (LC_ALL, "");
918  bindtextdomain (PACKAGE, LOCALEDIR);
919  textdomain (PACKAGE);
920
921  atexit (close_stdin);
922
923  selinux_enabled = (0 < is_selinux_enabled ());
924  cp_option_init (&x);
925
926  /* FIXME: consider not calling getenv for SIMPLE_BACKUP_SUFFIX unless
927     we'll actually use backup_suffix_string.  */
928  backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
929
930  while ((c = getopt_long (argc, argv, "abdfHilLnprst:uvxPRS:T",
931                           long_opts, NULL))
932         != -1)
933    {
934      switch (c)
935        {
936        case SPARSE_OPTION:
937          x.sparse_mode = XARGMATCH ("--sparse", optarg,
938                                     sparse_type_string, sparse_type);
939          break;
940
941        case REFLINK_OPTION:
942          if (optarg == NULL)
943            x.reflink_mode = REFLINK_ALWAYS;
944          else
945            x.reflink_mode = XARGMATCH ("--reflink", optarg,
946                                       reflink_type_string, reflink_type);
947          break;
948
949        case 'a':		/* Like -dR --preserve=all with reduced failure diagnostics. */
950          x.dereference = DEREF_NEVER;
951          x.preserve_links = true;
952          x.preserve_ownership = true;
953          x.preserve_mode = true;
954          x.preserve_timestamps = true;
955          x.require_preserve = true;
956          if (selinux_enabled)
957             x.preserve_security_context = true;
958          x.preserve_xattr = true;
959          x.reduce_diagnostics = true;
960          x.recursive = true;
961          break;
962
963        case 'b':
964          make_backups = true;
965          if (optarg)
966            version_control_string = optarg;
967          break;
968
969        case COPY_CONTENTS_OPTION:
970          copy_contents = true;
971          break;
972
973        case 'd':
974          x.preserve_links = true;
975          x.dereference = DEREF_NEVER;
976          break;
977
978        case 'f':
979          x.unlink_dest_after_failed_open = true;
980          break;
981
982        case 'H':
983          x.dereference = DEREF_COMMAND_LINE_ARGUMENTS;
984          break;
985
986        case IGNORE_ATTRIBUTES:
987          x.ignore_attributes = true;
988          break;
989
990        case 'i':
991          x.interactive = I_ASK_USER;
992          break;
993
994        case 'l':
995          x.hard_link = true;
996          break;
997
998        case 'L':
999          x.dereference = DEREF_ALWAYS;
1000          break;
1001
1002        case 'n':
1003          x.interactive = I_ALWAYS_NO;
1004          break;
1005
1006        case 'P':
1007          x.dereference = DEREF_NEVER;
1008          break;
1009
1010        case NO_PRESERVE_ATTRIBUTES_OPTION:
1011          decode_preserve_arg (optarg, &x, false);
1012          break;
1013
1014        case PRESERVE_ATTRIBUTES_OPTION:
1015          if (optarg == NULL)
1016            {
1017              /* Fall through to the case for `p' below.  */
1018            }
1019          else
1020            {
1021              decode_preserve_arg (optarg, &x, true);
1022              x.require_preserve = true;
1023              break;
1024            }
1025
1026        case 'p':
1027          x.preserve_ownership = true;
1028          x.preserve_mode = true;
1029          x.preserve_timestamps = true;
1030          x.require_preserve = true;
1031          break;
1032
1033        case PARENTS_OPTION:
1034          parents_option = true;
1035          break;
1036
1037        case 'r':
1038        case 'R':
1039          x.recursive = true;
1040          break;
1041
1042        case UNLINK_DEST_BEFORE_OPENING:
1043          x.unlink_dest_before_opening = true;
1044          break;
1045
1046        case STRIP_TRAILING_SLASHES_OPTION:
1047          remove_trailing_slashes = true;
1048          break;
1049
1050        case 's':
1051          x.symbolic_link = true;
1052          break;
1053
1054        case 't':
1055          if (target_directory)
1056            error (EXIT_FAILURE, 0,
1057                   _("multiple target directories specified"));
1058          else
1059            {
1060              struct stat st;
1061              if (stat (optarg, &st) != 0)
1062                error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg));
1063              if (! S_ISDIR (st.st_mode))
1064                error (EXIT_FAILURE, 0, _("target %s is not a directory"),
1065                       quote (optarg));
1066            }
1067          target_directory = optarg;
1068          break;
1069
1070        case 'T':
1071          no_target_directory = true;
1072          break;
1073
1074        case 'u':
1075          x.update = true;
1076          break;
1077
1078        case 'v':
1079          x.verbose = true;
1080          break;
1081
1082        case 'x':
1083          x.one_file_system = true;
1084          break;
1085
1086        case 'S':
1087          make_backups = true;
1088          backup_suffix_string = optarg;
1089          break;
1090
1091        case_GETOPT_HELP_CHAR;
1092
1093        case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
1094
1095        default:
1096          usage (EXIT_FAILURE);
1097        }
1098    }
1099
1100  if (x.hard_link && x.symbolic_link)
1101    {
1102      error (0, 0, _("cannot make both hard and symbolic links"));
1103      usage (EXIT_FAILURE);
1104    }
1105
1106  if (make_backups && x.interactive == I_ALWAYS_NO)
1107    {
1108      error (0, 0,
1109             _("options --backup and --no-clobber are mutually exclusive"));
1110      usage (EXIT_FAILURE);
1111    }
1112
1113  if (x.reflink_mode == REFLINK_ALWAYS && x.sparse_mode != SPARSE_AUTO)
1114    {
1115      error (0, 0, _("--reflink can be used only with --sparse=auto"));
1116      usage (EXIT_FAILURE);
1117    }
1118
1119  if (backup_suffix_string)
1120    simple_backup_suffix = xstrdup (backup_suffix_string);
1121
1122  x.backup_type = (make_backups
1123                   ? xget_version (_("backup type"),
1124                                   version_control_string)
1125                   : no_backups);
1126
1127  if (x.dereference == DEREF_UNDEFINED)
1128    {
1129      if (x.recursive)
1130        /* This is compatible with FreeBSD.  */
1131        x.dereference = DEREF_NEVER;
1132      else
1133        x.dereference = DEREF_ALWAYS;
1134    }
1135
1136  if (x.recursive)
1137    x.copy_as_regular = copy_contents;
1138
1139  /* If --force (-f) was specified and we're in link-creation mode,
1140     first remove any existing destination file.  */
1141  if (x.unlink_dest_after_failed_open && (x.hard_link || x.symbolic_link))
1142    x.unlink_dest_before_opening = true;
1143
1144  if (x.preserve_security_context)
1145    {
1146      if (!selinux_enabled)
1147        error (EXIT_FAILURE, 0,
1148               _("cannot preserve security context "
1149                 "without an SELinux-enabled kernel"));
1150    }
1151
1152#if !USE_XATTR
1153  if (x.require_preserve_xattr)
1154    error (EXIT_FAILURE, 0, _("cannot preserve extended attributes, cp is "
1155                              "built without xattr support"));
1156#endif
1157
1158  /* Allocate space for remembering copied and created files.  */
1159
1160  hash_init ();
1161
1162  ok = do_copy (argc - optind, argv + optind,
1163                target_directory, no_target_directory, &x);
1164
1165  forget_all ();
1166
1167  exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
1168}
1169