TODO: add an item for a chmod optimization
[platform/upstream/coreutils.git] / src / cp.c
1 /* cp.c  -- file copying (main routines)
2    Copyright (C) 89, 90, 91, 1995-2008 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 "lchmod.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. */
63 struct 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.  */
73 enum
74 {
75   COPY_CONTENTS_OPTION = CHAR_MAX + 1,
76   NO_PRESERVE_ATTRIBUTES_OPTION,
77   PARENTS_OPTION,
78   PRESERVE_ATTRIBUTES_OPTION,
79   REPLY_OPTION,
80   SPARSE_OPTION,
81   STRIP_TRAILING_SLASHES_OPTION,
82   UNLINK_DEST_BEFORE_OPENING
83 };
84
85 /* Initial number of entries in each hash table entry's table of inodes.  */
86 #define INITIAL_HASH_MODULE 100
87
88 /* Initial number of entries in the inode hash table.  */
89 #define INITIAL_ENTRY_TAB_SIZE 70
90
91 /* True if the kernel is SELinux enabled.  */
92 static bool selinux_enabled;
93
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;
97
98 /* Remove any trailing slashes from each SOURCE argument.  */
99 static bool remove_trailing_slashes;
100
101 static char const *const sparse_type_string[] =
102 {
103   "never", "auto", "always", NULL
104 };
105 static enum Sparse_type const sparse_type[] =
106 {
107   SPARSE_NEVER, SPARSE_AUTO, SPARSE_ALWAYS
108 };
109 ARGMATCH_VERIFY (sparse_type_string, sparse_type);
110
111 /* Valid arguments to the `--reply' option. */
112 static char const* const reply_args[] =
113 {
114   "yes", "no", "query", NULL
115 };
116 /* The values that correspond to the above strings. */
117 static int const reply_vals[] =
118 {
119   I_ALWAYS_YES, I_ALWAYS_NO, I_ASK_USER
120 };
121 ARGMATCH_VERIFY (reply_args, reply_vals);
122
123 static struct option const long_opts[] =
124 {
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,
142                                                        remove in 2008. */
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},
152   {NULL, 0, NULL, 0}
153 };
154
155 void
156 usage (int status)
157 {
158   if (status != EXIT_SUCCESS)
159     fprintf (stderr, _("Try `%s --help' for more information.\n"),
160              program_name);
161   else
162     {
163       printf (_("\
164 Usage: %s [OPTION]... [-T] SOURCE DEST\n\
165   or:  %s [OPTION]... SOURCE... DIRECTORY\n\
166   or:  %s [OPTION]... -t DIRECTORY SOURCE...\n\
167 "),
168               program_name, program_name, program_name);
169       fputs (_("\
170 Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\
171 \n\
172 "), stdout);
173       fputs (_("\
174 Mandatory arguments to long options are mandatory for short options too.\n\
175 "), stdout);
176       fputs (_("\
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\
182 "), stdout);
183       fputs (_("\
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\
188 "), stdout);
189       fputs (_("\
190   -l, --link                   link files instead of copying\n\
191   -L, --dereference            always follow symbolic links in SOURCE\n\
192 "), stdout);
193       fputs (_("\
194   -P, --no-dereference         never follow symbolic links in SOURCE\n\
195 "), stdout);
196       fputs (_("\
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\
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       --remove-destination     remove each existing destination file before\n\
209                                  attempting to open it (contrast with --force)\n\
210 "), stdout);
211       fputs (_("\
212       --sparse=WHEN            control creation of sparse files\n\
213       --strip-trailing-slashes  remove any trailing slashes from each SOURCE\n\
214                                  argument\n\
215 "), stdout);
216       fputs (_("\
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\
221 "), stdout);
222       fputs (_("\
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\
228 "), stdout);
229       fputs (HELP_OPTION_DESCRIPTION, stdout);
230       fputs (VERSION_OPTION_DESCRIPTION, stdout);
231       fputs (_("\
232 \n\
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\
238 "), stdout);
239       fputs (_("\
240 \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\
244 \n\
245 "), stdout);
246       fputs (_("\
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\
251 "), stdout);
252       fputs (_("\
253 \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\
256 regular file.\n\
257 "), stdout);
258       emit_bug_reporting_address ();
259     }
260   exit (status);
261 }
262
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.
267
268    SRC_OFFSET is the index in CONST_DST_NAME of the beginning of the
269    source directory name.
270
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.
278
279    Return true if the parent of CONST_DST_NAME and any intermediate
280    directories specified by ATTR_LIST have the proper permissions
281    when done.  */
282
283 static bool
284 re_protect (char const *const_dst_name, size_t src_offset,
285             struct dir_attr *attr_list, const struct cp_options *x)
286 {
287   struct dir_attr *p;
288   char *dst_name;               /* A copy of CONST_DST_NAME we can change. */
289   char *src_name;               /* The source name in `dst_name'. */
290
291   ASSIGN_STRDUPA (dst_name, const_dst_name);
292   src_name = dst_name + src_offset;
293
294   for (p = attr_list; p; p = p->next)
295     {
296       dst_name[p->slash_offset] = '\0';
297
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.  */
301
302       if (x->preserve_timestamps)
303         {
304           struct timespec timespec[2];
305
306           timespec[0] = get_stat_atime (&p->st);
307           timespec[1] = get_stat_mtime (&p->st);
308
309           if (utimens (dst_name, timespec))
310             {
311               error (0, errno, _("failed to preserve times for %s"),
312                      quote (dst_name));
313               return false;
314             }
315         }
316
317       if (x->preserve_ownership)
318         {
319           if (lchown (dst_name, p->st.st_uid, p->st.st_gid) != 0)
320             {
321               if (! chown_failure_ok (x))
322                 {
323                   error (0, errno, _("failed to preserve ownership for %s"),
324                          quote (dst_name));
325                   return false;
326                 }
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);
330             }
331         }
332
333       if (x->preserve_mode)
334         {
335           if (copy_acl (src_name, -1, dst_name, -1, p->st.st_mode) != 0)
336             return false;
337         }
338       else if (p->restore_mode)
339         {
340           if (lchmod (dst_name, p->st.st_mode) != 0)
341             {
342               error (0, errno, _("failed to preserve permissions for %s"),
343                      quote (dst_name));
344               return false;
345             }
346         }
347
348       dst_name[p->slash_offset] = '/';
349     }
350   return true;
351 }
352
353 /* Ensure that the parent directory of CONST_DIR exists, for
354    the --parents option.
355
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.
366
367    Return true if parent of CONST_DIR exists as a directory with the proper
368    permissions when done.  */
369
370 /* FIXME: Synch this function with the one in ../lib/mkdir-p.c.  */
371
372 static bool
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)
377 {
378   struct stat stats;
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.  */
383
384   ASSIGN_STRDUPA (dir, const_dir);
385
386   src = dir + src_offset;
387
388   dirlen = dir_len (dir);
389   dst_dir = alloca (dirlen + 1);
390   memcpy (dst_dir, dir, dirlen);
391   dst_dir[dirlen] = '\0';
392
393   *attr_list = NULL;
394
395   if (stat (dst_dir, &stats) != 0)
396     {
397       /* A parent of CONST_DIR does not exist.
398          Make all missing intermediate directories. */
399       char *slash;
400
401       slash = src;
402       while (*slash == '/')
403         slash++;
404       while ((slash = strchr (slash, '/')))
405         {
406           struct dir_attr *new IF_LINT (= NULL);
407           bool missing_dir;
408
409           *slash = '\0';
410           missing_dir = (stat (dir, &stats) != 0);
411
412           if (missing_dir | x->preserve_ownership | x->preserve_mode
413               | x->preserve_timestamps)
414             {
415               /* Add this directory to the list of directories whose
416                  modes might need fixing later. */
417               struct stat src_st;
418               int src_errno = (stat (src, &src_st) != 0
419                                ? errno
420                                : S_ISDIR (src_st.st_mode)
421                                ? 0
422                                : ENOTDIR);
423               if (src_errno)
424                 {
425                   error (0, src_errno, _("failed to get attributes of %s"),
426                          quote (src));
427                   return false;
428                 }
429
430               new = xmalloc (sizeof *new);
431               new->st = src_st;
432               new->slash_offset = slash - dir;
433               new->restore_mode = false;
434               new->next = *attr_list;
435               *attr_list = new;
436             }
437
438           if (missing_dir)
439             {
440               mode_t src_mode;
441               mode_t omitted_permissions;
442               mode_t mkdir_mode;
443
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. */
449               *new_dst = true;
450               src_mode = new->st.st_mode;
451
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
457                                         ? S_IRWXG | S_IRWXO
458                                         : x->preserve_mode
459                                         ? S_IWGRP | S_IWOTH
460                                         : 0));
461
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)
468                 {
469                   error (0, errno, _("cannot make directory %s"),
470                          quote (dir));
471                   return false;
472                 }
473               else
474                 {
475                   if (verbose_fmt_string != NULL)
476                     printf (verbose_fmt_string, src, dir);
477                 }
478
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.  */
482
483               if (lstat (dir, &stats))
484                 {
485                   error (0, errno, _("failed to get attributes of %s"),
486                          quote (dir));
487                   return false;
488                 }
489
490
491               if (! x->preserve_mode)
492                 {
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)
497                     {
498                       new->st.st_mode = stats.st_mode | omitted_permissions;
499                       new->restore_mode = true;
500                     }
501                 }
502
503               if ((stats.st_mode & S_IRWXU) != S_IRWXU)
504                 {
505                   /* Make the new directory searchable and writable.
506                      The original permissions will be restored later.  */
507
508                   if (lchmod (dir, stats.st_mode | S_IRWXU) != 0)
509                     {
510                       error (0, errno, _("setting permissions for %s"),
511                              quote (dir));
512                       return false;
513                     }
514                 }
515             }
516           else if (!S_ISDIR (stats.st_mode))
517             {
518               error (0, 0, _("%s exists but is not a directory"),
519                      quote (dir));
520               return false;
521             }
522           else
523             *new_dst = false;
524           *slash++ = '/';
525
526           /* Avoid unnecessary calls to `stat' when given
527              file names containing multiple adjacent slashes.  */
528           while (*slash == '/')
529             slash++;
530         }
531     }
532
533   /* We get here if the parent of DIR already exists.  */
534
535   else if (!S_ISDIR (stats.st_mode))
536     {
537       error (0, 0, _("%s exists but is not a directory"), quote (dst_dir));
538       return false;
539     }
540   else
541     {
542       *new_dst = false;
543     }
544   return true;
545 }
546
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.
552
553    If the file exists, store the file's status into *ST.
554    Otherwise, set *NEW_DST.  */
555
556 static bool
557 target_directory_operand (char const *file, struct stat *st, bool *new_dst)
558 {
559   int err = (stat (file, st) == 0 ? 0 : errno);
560   bool is_a_dir = !err && S_ISDIR (st->st_mode);
561   if (err)
562     {
563       if (err != ENOENT)
564         error (EXIT_FAILURE, err, _("accessing %s"), quote (file));
565       *new_dst = true;
566     }
567   return is_a_dir;
568 }
569
570 /* Scan the arguments, and copy each by calling copy.
571    Return true if successful.  */
572
573 static bool
574 do_copy (int n_files, char **file, const char *target_directory,
575          bool no_target_directory, struct cp_options *x)
576 {
577   struct stat sb;
578   bool new_dst = false;
579   bool ok = true;
580
581   if (n_files <= !target_directory)
582     {
583       if (n_files <= 0)
584         error (0, 0, _("missing file operand"));
585       else
586         error (0, 0, _("missing destination file operand after %s"),
587                quote (file[0]));
588       usage (EXIT_FAILURE);
589     }
590
591   if (no_target_directory)
592     {
593       if (target_directory)
594         error (EXIT_FAILURE, 0,
595                _("cannot combine --target-directory (-t) "
596                  "and --no-target-directory (-T)"));
597       if (2 < n_files)
598         {
599           error (0, 0, _("extra operand %s"), quote (file[2]));
600           usage (EXIT_FAILURE);
601         }
602     }
603   else if (!target_directory)
604     {
605       if (2 <= n_files
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]));
611     }
612
613   if (target_directory)
614     {
615       /* cp file1...filen edir
616          Copy the files `file1' through `filen'
617          to the existing directory `edir'. */
618       int i;
619
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.  */
623       if (2 <= n_files)
624         {
625           dest_info_init (x);
626           src_info_init (x);
627         }
628
629       for (i = 0; i < n_files; i++)
630         {
631           char *dst_name;
632           bool parent_exists = true;  /* True if dir_name (dst_name) exists. */
633           struct dir_attr *attr_list;
634           char *arg_in_concat = NULL;
635           char *arg = file[i];
636
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);
641
642           if (parents_option)
643             {
644               char *arg_no_trailing_slash;
645
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);
653
654               /* Append all of `arg' (minus any trailing slash) to `dest'.  */
655               dst_name = file_name_concat (target_directory,
656                                            arg_no_trailing_slash,
657                                            &arg_in_concat);
658
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. */
662               parent_exists =
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));
667             }
668           else
669             {
670               char *arg_base;
671               /* Append the last component of `arg' to `target_directory'.  */
672
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,
678                                               NULL));
679             }
680
681           if (!parent_exists)
682             {
683               /* make_dir_parents_private failed, so don't even
684                  attempt the copy.  */
685               ok = false;
686             }
687           else
688             {
689               bool copy_into_self;
690               ok &= copy (arg, dst_name, new_dst, x, &copy_into_self, NULL);
691
692               if (parents_option)
693                 ok &= re_protect (dst_name, arg_in_concat - dst_name,
694                                   attr_list, x);
695             }
696
697           if (parents_option)
698             {
699               while (attr_list)
700                 {
701                   struct dir_attr *p = attr_list;
702                   attr_list = attr_list->next;
703                   free (p);
704                 }
705             }
706
707           free (dst_name);
708         }
709     }
710   else /* !target_directory */
711     {
712       char const *new_dest;
713       char const *source = file[0];
714       char const *dest = file[1];
715       bool unused;
716
717       if (parents_option)
718         {
719           error (0, 0,
720                  _("with --parents, the destination must be a directory"));
721           usage (EXIT_FAILURE);
722         }
723
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.  */
729
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))
734         {
735           static struct cp_options x_tmp;
736
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.  */
743           x_tmp = *x;
744           x_tmp.backup_type = no_backups;
745           x = &x_tmp;
746         }
747       else
748         {
749           new_dest = dest;
750         }
751
752       ok = copy (source, new_dest, 0, x, &unused, NULL);
753     }
754
755   return ok;
756 }
757
758 static void
759 cp_option_init (struct cp_options *x)
760 {
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;
770
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;
777
778   x->require_preserve = false;
779   x->recursive = false;
780   x->sparse_mode = SPARSE_AUTO;
781   x->symbolic_link = false;
782   x->set_mode = false;
783   x->mode = 0;
784
785   /* Not used.  */
786   x->stdin_tty = false;
787
788   x->update = false;
789   x->verbose = false;
790
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;
796
797   x->dest_info = NULL;
798   x->src_info = NULL;
799 }
800
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.  */
803 static void
804 decode_preserve_arg (char const *arg, struct cp_options *x, bool on_off)
805 {
806   enum File_attribute
807     {
808       PRESERVE_MODE,
809       PRESERVE_TIMESTAMPS,
810       PRESERVE_OWNERSHIP,
811       PRESERVE_LINK,
812       PRESERVE_CONTEXT,
813       PRESERVE_ALL
814     };
815   static enum File_attribute const preserve_vals[] =
816     {
817       PRESERVE_MODE, PRESERVE_TIMESTAMPS,
818       PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_CONTEXT, PRESERVE_ALL
819     };
820   /* Valid arguments to the `--preserve' option. */
821   static char const* const preserve_args[] =
822     {
823       "mode", "timestamps",
824       "ownership", "links", "context", "all", NULL
825     };
826   ARGMATCH_VERIFY (preserve_args, preserve_vals);
827
828   char *arg_writable = xstrdup (arg);
829   char *s = arg_writable;
830   do
831     {
832       /* find next comma */
833       char *comma = strchr (s, ',');
834       enum File_attribute val;
835
836       /* If we found a comma, put a NUL in its place and advance.  */
837       if (comma)
838         *comma++ = 0;
839
840       /* process S.  */
841       val = XARGMATCH ("--preserve", s, preserve_args, preserve_vals);
842       switch (val)
843         {
844         case PRESERVE_MODE:
845           x->preserve_mode = on_off;
846           break;
847
848         case PRESERVE_TIMESTAMPS:
849           x->preserve_timestamps = on_off;
850           break;
851
852         case PRESERVE_OWNERSHIP:
853           x->preserve_ownership = on_off;
854           break;
855
856         case PRESERVE_LINK:
857           x->preserve_links = on_off;
858           break;
859
860         case PRESERVE_CONTEXT:
861           x->preserve_security_context = on_off;
862           x->require_preserve_context = on_off;
863           break;
864
865         case PRESERVE_ALL:
866           x->preserve_mode = on_off;
867           x->preserve_timestamps = on_off;
868           x->preserve_ownership = on_off;
869           x->preserve_links = on_off;
870           if (selinux_enabled)
871             x->preserve_security_context = on_off;
872           break;
873
874         default:
875           abort ();
876         }
877       s = comma;
878     }
879   while (s);
880
881   free (arg_writable);
882 }
883
884 int
885 main (int argc, char **argv)
886 {
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;
896
897   initialize_main (&argc, &argv);
898   set_program_name (argv[0]);
899   setlocale (LC_ALL, "");
900   bindtextdomain (PACKAGE, LOCALEDIR);
901   textdomain (PACKAGE);
902
903   atexit (close_stdin);
904
905   selinux_enabled = (0 < is_selinux_enabled ());
906   cp_option_init (&x);
907
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");
911
912   while ((c = getopt_long (argc, argv, "abdfHilLprst:uvxPRS:T",
913                            long_opts, NULL))
914          != -1)
915     {
916       switch (c)
917         {
918         case SPARSE_OPTION:
919           x.sparse_mode = XARGMATCH ("--sparse", optarg,
920                                      sparse_type_string, sparse_type);
921           break;
922
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;
930           x.recursive = true;
931           break;
932
933         case 'b':
934           make_backups = true;
935           if (optarg)
936             version_control_string = optarg;
937           break;
938
939         case COPY_CONTENTS_OPTION:
940           copy_contents = true;
941           break;
942
943         case 'd':
944           x.preserve_links = true;
945           x.dereference = DEREF_NEVER;
946           break;
947
948         case 'f':
949           x.unlink_dest_after_failed_open = true;
950           break;
951
952         case 'H':
953           x.dereference = DEREF_COMMAND_LINE_ARGUMENTS;
954           break;
955
956         case 'i':
957           x.interactive = I_ASK_USER;
958           break;
959
960         case 'l':
961           x.hard_link = true;
962           break;
963
964         case 'L':
965           x.dereference = DEREF_ALWAYS;
966           break;
967
968         case 'P':
969           x.dereference = DEREF_NEVER;
970           break;
971
972         case NO_PRESERVE_ATTRIBUTES_OPTION:
973           decode_preserve_arg (optarg, &x, false);
974           break;
975
976         case PRESERVE_ATTRIBUTES_OPTION:
977           if (optarg == NULL)
978             {
979               /* Fall through to the case for `p' below.  */
980             }
981           else
982             {
983               decode_preserve_arg (optarg, &x, true);
984               x.require_preserve = true;
985               break;
986             }
987
988         case 'p':
989           x.preserve_ownership = true;
990           x.preserve_mode = true;
991           x.preserve_timestamps = true;
992           x.require_preserve = true;
993           break;
994
995         case PARENTS_OPTION:
996           parents_option = true;
997           break;
998
999         case 'r':
1000         case 'R':
1001           x.recursive = true;
1002           break;
1003
1004         case REPLY_OPTION: /* Deprecated */
1005           x.interactive = XARGMATCH ("--reply", optarg,
1006                                      reply_args, reply_vals);
1007           error (0, 0,
1008                  _("the --reply option is deprecated; use -i or -f instead"));
1009           break;
1010
1011         case UNLINK_DEST_BEFORE_OPENING:
1012           x.unlink_dest_before_opening = true;
1013           break;
1014
1015         case STRIP_TRAILING_SLASHES_OPTION:
1016           remove_trailing_slashes = true;
1017           break;
1018
1019         case 's':
1020           x.symbolic_link = true;
1021           break;
1022
1023         case 't':
1024           if (target_directory)
1025             error (EXIT_FAILURE, 0,
1026                    _("multiple target directories specified"));
1027           else
1028             {
1029               struct stat st;
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"),
1034                        quote (optarg));
1035             }
1036           target_directory = optarg;
1037           break;
1038
1039         case 'T':
1040           no_target_directory = true;
1041           break;
1042
1043         case 'u':
1044           x.update = true;
1045           break;
1046
1047         case 'v':
1048           x.verbose = true;
1049           break;
1050
1051         case 'x':
1052           x.one_file_system = true;
1053           break;
1054
1055         case 'S':
1056           make_backups = true;
1057           backup_suffix_string = optarg;
1058           break;
1059
1060         case_GETOPT_HELP_CHAR;
1061
1062         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
1063
1064         default:
1065           usage (EXIT_FAILURE);
1066         }
1067     }
1068
1069   if (x.hard_link & x.symbolic_link)
1070     {
1071       error (0, 0, _("cannot make both hard and symbolic links"));
1072       usage (EXIT_FAILURE);
1073     }
1074
1075   if (backup_suffix_string)
1076     simple_backup_suffix = xstrdup (backup_suffix_string);
1077
1078   x.backup_type = (make_backups
1079                    ? xget_version (_("backup type"),
1080                                    version_control_string)
1081                    : no_backups);
1082
1083   if (x.dereference == DEREF_UNDEFINED)
1084     {
1085       if (x.recursive)
1086         /* This is compatible with FreeBSD.  */
1087         x.dereference = DEREF_NEVER;
1088       else
1089         x.dereference = DEREF_ALWAYS;
1090     }
1091
1092   if (x.recursive)
1093     x.copy_as_regular = copy_contents;
1094
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;
1099
1100   if (x.preserve_security_context)
1101     {
1102       if (!selinux_enabled)
1103         error (EXIT_FAILURE, 0,
1104                _("cannot preserve security context "
1105                  "without an SELinux-enabled kernel"));
1106     }
1107
1108   /* Allocate space for remembering copied and created files.  */
1109
1110   hash_init ();
1111
1112   ok = do_copy (argc - optind, argv + optind,
1113                 target_directory, no_target_directory, &x);
1114
1115   forget_all ();
1116
1117   exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
1118 }