* tests/cp/cp-a-selinux: New file. Test for the bug reported in
[platform/upstream/coreutils.git] / src / install.c
1 /* install - copy files and set attributes
2    Copyright (C) 89, 90, 91, 1995-2007 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 2, or (at your option)
7    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, write to the Free Software Foundation,
16    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
17
18 /* Written by David MacKenzie <djm@gnu.ai.mit.edu> */
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <getopt.h>
23 #include <sys/types.h>
24 #include <signal.h>
25 #include <pwd.h>
26 #include <grp.h>
27 #include <selinux/selinux.h>
28
29 #include "system.h"
30 #include "backupfile.h"
31 #include "error.h"
32 #include "cp-hash.h"
33 #include "copy.h"
34 #include "filenamecat.h"
35 #include "mkancesdirs.h"
36 #include "mkdir-p.h"
37 #include "modechange.h"
38 #include "quote.h"
39 #include "quotearg.h"
40 #include "savewd.h"
41 #include "stat-time.h"
42 #include "utimens.h"
43 #include "xstrtol.h"
44
45 /* The official name of this program (e.g., no `g' prefix).  */
46 #define PROGRAM_NAME "install"
47
48 #define AUTHORS "David MacKenzie"
49
50 #if HAVE_SYS_WAIT_H
51 # include <sys/wait.h>
52 #endif
53
54 static int selinux_enabled = 0;
55 static bool use_default_selinux_context = true;
56
57 #if ! HAVE_ENDGRENT
58 # define endgrent() ((void) 0)
59 #endif
60
61 #if ! HAVE_ENDPWENT
62 # define endpwent() ((void) 0)
63 #endif
64
65 /* Initial number of entries in each hash table entry's table of inodes.  */
66 #define INITIAL_HASH_MODULE 100
67
68 /* Initial number of entries in the inode hash table.  */
69 #define INITIAL_ENTRY_TAB_SIZE 70
70
71 /* Number of bytes of a file to copy at a time. */
72 #define READ_SIZE (32 * 1024)
73
74 static bool change_timestamps (struct stat const *from_sb, char const *to);
75 static bool change_attributes (char const *name);
76 static bool copy_file (const char *from, const char *to,
77                        const struct cp_options *x);
78 static bool install_file_in_file_parents (char const *from, char *to,
79                                           struct cp_options *x);
80 static bool install_file_in_dir (const char *from, const char *to_dir,
81                                  const struct cp_options *x);
82 static bool install_file_in_file (const char *from, const char *to,
83                                   const struct cp_options *x);
84 static void get_ids (void);
85 static void strip (char const *name);
86 static void announce_mkdir (char const *dir, void *options);
87 static int make_ancestor (char const *dir, char const *component,
88                           void *options);
89 void usage (int status);
90
91 /* The name this program was run with, for error messages. */
92 char *program_name;
93
94 /* The user name that will own the files, or NULL to make the owner
95    the current user ID. */
96 static char *owner_name;
97
98 /* The user ID corresponding to `owner_name'. */
99 static uid_t owner_id;
100
101 /* The group name that will own the files, or NULL to make the group
102    the current group ID. */
103 static char *group_name;
104
105 /* The group ID corresponding to `group_name'. */
106 static gid_t group_id;
107
108 #define DEFAULT_MODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
109
110 /* The file mode bits to which non-directory files will be set.  The umask has
111    no effect. */
112 static mode_t mode = DEFAULT_MODE;
113
114 /* Similar, but for directories.  */
115 static mode_t dir_mode = DEFAULT_MODE;
116
117 /* The file mode bits that the user cares about.  This should be a
118    superset of DIR_MODE and a subset of CHMOD_MODE_BITS.  This matters
119    for directories, since otherwise directories may keep their S_ISUID
120    or S_ISGID bits.  */
121 static mode_t dir_mode_bits = CHMOD_MODE_BITS;
122
123 /* If true, strip executable files after copying them. */
124 static bool strip_files;
125
126 /* If true, install a directory instead of a regular file. */
127 static bool dir_arg;
128
129 /* For long options that have no equivalent short option, use a
130    non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
131 enum
132 {
133   PRESERVE_CONTEXT_OPTION = CHAR_MAX + 1
134 };
135
136 static struct option const long_options[] =
137 {
138   {"backup", optional_argument, NULL, 'b'},
139   {GETOPT_SELINUX_CONTEXT_OPTION_DECL},
140   {"directory", no_argument, NULL, 'd'},
141   {"group", required_argument, NULL, 'g'},
142   {"mode", required_argument, NULL, 'm'},
143   {"no-target-directory", no_argument, NULL, 'T'},
144   {"owner", required_argument, NULL, 'o'},
145   {"preserve-timestamps", no_argument, NULL, 'p'},
146   {"preserve-context", no_argument, NULL, PRESERVE_CONTEXT_OPTION},
147   /* Continue silent support for --preserve_context until Jan 2008. FIXME-obs
148      After that, FIXME-obs: warn in, say, late 2008, and disable altogether
149      a year or two later.  */
150   {"preserve_context", no_argument, NULL, PRESERVE_CONTEXT_OPTION},
151   {"strip", no_argument, NULL, 's'},
152   {"suffix", required_argument, NULL, 'S'},
153   {"target-directory", required_argument, NULL, 't'},
154   {"verbose", no_argument, NULL, 'v'},
155   {GETOPT_HELP_OPTION_DECL},
156   {GETOPT_VERSION_OPTION_DECL},
157   {NULL, 0, NULL, 0}
158 };
159
160 static void
161 cp_option_init (struct cp_options *x)
162 {
163   x->copy_as_regular = true;
164   x->dereference = DEREF_ALWAYS;
165   x->unlink_dest_before_opening = true;
166   x->unlink_dest_after_failed_open = false;
167   x->hard_link = false;
168   x->interactive = I_UNSPECIFIED;
169   x->move_mode = false;
170   x->chown_privileges = chown_privileges ();
171   x->one_file_system = false;
172   x->preserve_ownership = false;
173   x->preserve_links = false;
174   x->preserve_mode = false;
175   x->preserve_timestamps = false;
176   x->require_preserve = false;
177   x->require_preserve_context = false;
178   x->recursive = false;
179   x->sparse_mode = SPARSE_AUTO;
180   x->symbolic_link = false;
181   x->backup_type = no_backups;
182
183   /* Create destination files initially writable so we can run strip on them.
184      Although GNU strip works fine on read-only files, some others
185      would fail.  */
186   x->set_mode = true;
187   x->mode = S_IRUSR | S_IWUSR;
188   x->stdin_tty = false;
189
190   x->update = false;
191   x->preserve_security_context = false;
192   x->verbose = false;
193   x->dest_info = NULL;
194   x->src_info = NULL;
195 }
196
197 /* Modify file context to match the specified policy.
198    If an error occurs the file will remain with the default directory
199    context.  */
200 static void
201 setdefaultfilecon (char const *file)
202 {
203   struct stat st;
204   security_context_t scontext = NULL;
205   if (selinux_enabled != 1)
206     {
207       /* Indicate no context found. */
208       return;
209     }
210   if (lstat (file, &st) != 0)
211     return;
212
213   /* If there's an error determining the context, or it has none,
214      return to allow default context */
215   if ((matchpathcon (file, st.st_mode, &scontext) != 0) ||
216       (strcmp (scontext, "<<none>>") == 0))
217     {
218       if (scontext != NULL)
219         freecon (scontext);
220       return;
221     }
222
223   if (lsetfilecon (file, scontext) < 0 && errno != ENOTSUP)
224     error (0, errno,
225            _("warning: %s: failed to change context to %s"),
226            quotearg_colon (file), scontext);
227
228   freecon (scontext);
229   return;
230 }
231
232 /* FILE is the last operand of this command.  Return true if FILE is a
233    directory.  But report an error there is a problem accessing FILE,
234    or if FILE does not exist but would have to refer to an existing
235    directory if it referred to anything at all.  */
236
237 static bool
238 target_directory_operand (char const *file)
239 {
240   char const *b = last_component (file);
241   size_t blen = strlen (b);
242   bool looks_like_a_dir = (blen == 0 || ISSLASH (b[blen - 1]));
243   struct stat st;
244   int err = (stat (file, &st) == 0 ? 0 : errno);
245   bool is_a_dir = !err && S_ISDIR (st.st_mode);
246   if (err && err != ENOENT)
247     error (EXIT_FAILURE, err, _("accessing %s"), quote (file));
248   if (is_a_dir < looks_like_a_dir)
249     error (EXIT_FAILURE, err, _("target %s is not a directory"), quote (file));
250   return is_a_dir;
251 }
252
253 /* Process a command-line file name, for the -d option.  */
254 static int
255 process_dir (char *dir, struct savewd *wd, void *options)
256 {
257   return (make_dir_parents (dir, wd,
258                             make_ancestor, options,
259                             dir_mode, announce_mkdir,
260                             dir_mode_bits, owner_id, group_id, false)
261           ? EXIT_SUCCESS
262           : EXIT_FAILURE);
263 }
264
265 int
266 main (int argc, char **argv)
267 {
268   int optc;
269   int exit_status = EXIT_SUCCESS;
270   const char *specified_mode = NULL;
271   bool make_backups = false;
272   char *backup_suffix_string;
273   char *version_control_string = NULL;
274   bool mkdir_and_install = false;
275   struct cp_options x;
276   char const *target_directory = NULL;
277   bool no_target_directory = false;
278   int n_files;
279   char **file;
280   security_context_t scontext = NULL;
281   /* set iff kernel has extra selinux system calls */
282   selinux_enabled = (0 < is_selinux_enabled ());
283
284   initialize_main (&argc, &argv);
285   program_name = argv[0];
286   setlocale (LC_ALL, "");
287   bindtextdomain (PACKAGE, LOCALEDIR);
288   textdomain (PACKAGE);
289
290   atexit (close_stdout);
291
292   cp_option_init (&x);
293
294   owner_name = NULL;
295   group_name = NULL;
296   strip_files = false;
297   dir_arg = false;
298   umask (0);
299
300   /* FIXME: consider not calling getenv for SIMPLE_BACKUP_SUFFIX unless
301      we'll actually use backup_suffix_string.  */
302   backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
303
304   while ((optc = getopt_long (argc, argv, "bcsDdg:m:o:pt:TvS:Z:", long_options,
305                               NULL)) != -1)
306     {
307       switch (optc)
308         {
309         case 'b':
310           make_backups = true;
311           if (optarg)
312             version_control_string = optarg;
313           break;
314         case 'c':
315           break;
316         case 's':
317           strip_files = true;
318 #ifdef SIGCHLD
319           /* System V fork+wait does not work if SIGCHLD is ignored.  */
320           signal (SIGCHLD, SIG_DFL);
321 #endif
322           break;
323         case 'd':
324           dir_arg = true;
325           break;
326         case 'D':
327           mkdir_and_install = true;
328           break;
329         case 'v':
330           x.verbose = true;
331           break;
332         case 'g':
333           group_name = optarg;
334           break;
335         case 'm':
336           specified_mode = optarg;
337           break;
338         case 'o':
339           owner_name = optarg;
340           break;
341         case 'p':
342           x.preserve_timestamps = true;
343           break;
344         case 'S':
345           make_backups = true;
346           backup_suffix_string = optarg;
347           break;
348         case 't':
349           if (target_directory)
350             error (EXIT_FAILURE, 0,
351                    _("multiple target directories specified"));
352           else
353             {
354               struct stat st;
355               if (stat (optarg, &st) != 0)
356                 error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg));
357               if (! S_ISDIR (st.st_mode))
358                 error (EXIT_FAILURE, 0, _("target %s is not a directory"),
359                        quote (optarg));
360             }
361           target_directory = optarg;
362           break;
363         case 'T':
364           no_target_directory = true;
365           break;
366
367         case PRESERVE_CONTEXT_OPTION:
368           if ( ! selinux_enabled)
369             {
370               error (0, 0, _("Warning: ignoring --preserve-context; "
371                              "this kernel is not SELinux-enabled."));
372               break;
373             }
374           x.preserve_security_context = true;
375           use_default_selinux_context = false;
376           break;
377         case 'Z':
378           if ( ! selinux_enabled)
379             {
380               error (0, 0, _("Warning: ignoring --context (-Z); "
381                              "this kernel is not SELinux-enabled."));
382               break;
383             }
384           scontext = optarg;
385           use_default_selinux_context = false;
386           break;
387         case_GETOPT_HELP_CHAR;
388         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
389         default:
390           usage (EXIT_FAILURE);
391         }
392     }
393
394   /* Check for invalid combinations of arguments. */
395   if (dir_arg & strip_files)
396     error (EXIT_FAILURE, 0,
397            _("the strip option may not be used when installing a directory"));
398   if (dir_arg && target_directory)
399     error (EXIT_FAILURE, 0,
400            _("target directory not allowed when installing a directory"));
401
402   if (x.preserve_security_context && scontext != NULL)
403     error (EXIT_FAILURE, 0,
404            _("cannot force target context to %s and preserve it"),
405            quote (scontext));
406
407   if (backup_suffix_string)
408     simple_backup_suffix = xstrdup (backup_suffix_string);
409
410   x.backup_type = (make_backups
411                    ? xget_version (_("backup type"),
412                                    version_control_string)
413                    : no_backups);
414
415   if (scontext && setfscreatecon (scontext) < 0)
416     error (EXIT_FAILURE, errno,
417            _("failed to set default file creation context to %s"),
418            quote (scontext));
419
420   n_files = argc - optind;
421   file = argv + optind;
422
423   if (n_files <= ! (dir_arg || target_directory))
424     {
425       if (n_files <= 0)
426         error (0, 0, _("missing file operand"));
427       else
428         error (0, 0, _("missing destination file operand after %s"),
429                quote (file[0]));
430       usage (EXIT_FAILURE);
431     }
432
433   if (no_target_directory)
434     {
435       if (target_directory)
436         error (EXIT_FAILURE, 0,
437                _("Cannot combine --target-directory (-t) "
438                  "and --no-target-directory (-T)"));
439       if (2 < n_files)
440         {
441           error (0, 0, _("extra operand %s"), quote (file[2]));
442           usage (EXIT_FAILURE);
443         }
444     }
445   else if (! (dir_arg || target_directory))
446     {
447       if (2 <= n_files && target_directory_operand (file[n_files - 1]))
448         target_directory = file[--n_files];
449       else if (2 < n_files)
450         error (EXIT_FAILURE, 0, _("target %s is not a directory"),
451                quote (file[n_files - 1]));
452     }
453
454   if (specified_mode)
455     {
456       struct mode_change *change = mode_compile (specified_mode);
457       if (!change)
458         error (EXIT_FAILURE, 0, _("invalid mode %s"), quote (specified_mode));
459       mode = mode_adjust (0, false, 0, change, NULL);
460       dir_mode = mode_adjust (0, true, 0, change, &dir_mode_bits);
461       free (change);
462     }
463
464   get_ids ();
465
466   if (dir_arg)
467     exit_status = savewd_process_files (n_files, file, process_dir, &x);
468   else
469     {
470       /* FIXME: it's a little gross that this initialization is
471          required by copy.c::copy. */
472       hash_init ();
473
474       if (!target_directory)
475         {
476           if (! (mkdir_and_install
477                  ? install_file_in_file_parents (file[0], file[1], &x)
478                  : install_file_in_file (file[0], file[1], &x)))
479             exit_status = EXIT_FAILURE;
480         }
481       else
482         {
483           int i;
484           dest_info_init (&x);
485           for (i = 0; i < n_files; i++)
486             if (! install_file_in_dir (file[i], target_directory, &x))
487               exit_status = EXIT_FAILURE;
488         }
489     }
490
491   exit (exit_status);
492 }
493
494 /* Copy file FROM onto file TO, creating any missing parent directories of TO.
495    Return true if successful.  */
496
497 static bool
498 install_file_in_file_parents (char const *from, char *to,
499                               struct cp_options *x)
500 {
501   bool save_working_directory =
502     ! (IS_ABSOLUTE_FILE_NAME (from) && IS_ABSOLUTE_FILE_NAME (to));
503   int status = EXIT_SUCCESS;
504
505   struct savewd wd;
506   savewd_init (&wd);
507   if (! save_working_directory)
508     savewd_finish (&wd);
509
510   if (mkancesdirs (to, &wd, make_ancestor, x) == -1)
511     {
512       error (0, errno, _("cannot create directory %s"), to);
513       status = EXIT_FAILURE;
514     }
515
516   if (save_working_directory)
517     {
518       int restore_result = savewd_restore (&wd, status);
519       int restore_errno = errno;
520       savewd_finish (&wd);
521       if (EXIT_SUCCESS < restore_result)
522         return false;
523       if (restore_result < 0 && status == EXIT_SUCCESS)
524         {
525           error (0, restore_errno, _("cannot create directory %s"), to);
526           return false;
527         }
528     }
529
530   return (status == EXIT_SUCCESS && install_file_in_file (from, to, x));
531 }
532
533 /* Copy file FROM onto file TO and give TO the appropriate
534    attributes.
535    Return true if successful.  */
536
537 static bool
538 install_file_in_file (const char *from, const char *to,
539                       const struct cp_options *x)
540 {
541   struct stat from_sb;
542   if (x->preserve_timestamps && stat (from, &from_sb) != 0)
543     {
544       error (0, errno, _("cannot stat %s"), quote (from));
545       return false;
546     }
547   if (! copy_file (from, to, x))
548     return false;
549   if (strip_files)
550     strip (to);
551   if (x->preserve_timestamps && (strip_files || ! S_ISREG (from_sb.st_mode))
552       && ! change_timestamps (&from_sb, to))
553     return false;
554   return change_attributes (to);
555 }
556
557 /* Copy file FROM into directory TO_DIR, keeping its same name,
558    and give the copy the appropriate attributes.
559    Return true if successful.  */
560
561 static bool
562 install_file_in_dir (const char *from, const char *to_dir,
563                      const struct cp_options *x)
564 {
565   const char *from_base = last_component (from);
566   char *to = file_name_concat (to_dir, from_base, NULL);
567   bool ret = install_file_in_file (from, to, x);
568   free (to);
569   return ret;
570 }
571
572 /* Copy file FROM onto file TO, creating TO if necessary.
573    Return true if successful.  */
574
575 static bool
576 copy_file (const char *from, const char *to, const struct cp_options *x)
577 {
578   bool copy_into_self;
579
580   /* Allow installing from non-regular files like /dev/null.
581      Charles Karney reported that some Sun version of install allows that
582      and that sendmail's installation process relies on the behavior.
583      However, since !x->recursive, the call to "copy" will fail if FROM
584      is a directory.  */
585
586   return copy (from, to, false, x, &copy_into_self, NULL);
587 }
588
589 /* Set the attributes of file or directory NAME.
590    Return true if successful.  */
591
592 static bool
593 change_attributes (char const *name)
594 {
595   bool ok = false;
596   /* chown must precede chmod because on some systems,
597      chown clears the set[ug]id bits for non-superusers,
598      resulting in incorrect permissions.
599      On System V, users can give away files with chown and then not
600      be able to chmod them.  So don't give files away.
601
602      We don't normally ignore errors from chown because the idea of
603      the install command is that the file is supposed to end up with
604      precisely the attributes that the user specified (or defaulted).
605      If the file doesn't end up with the group they asked for, they'll
606      want to know.  */
607
608   if (! (owner_id == (uid_t) -1 && group_id == (gid_t) -1)
609       && chown (name, owner_id, group_id) != 0)
610     error (0, errno, _("cannot change ownership of %s"), quote (name));
611   else if (chmod (name, mode) != 0)
612     error (0, errno, _("cannot change permissions of %s"), quote (name));
613   else
614     ok = true;
615
616   if (use_default_selinux_context)
617     setdefaultfilecon (name);
618
619   return ok;
620 }
621
622 /* Set the timestamps of file TO to match those of file FROM.
623    Return true if successful.  */
624
625 static bool
626 change_timestamps (struct stat const *from_sb, char const *to)
627 {
628   struct timespec timespec[2];
629   timespec[0] = get_stat_atime (from_sb);
630   timespec[1] = get_stat_mtime (from_sb);
631
632   if (utimens (to, timespec))
633     {
634       error (0, errno, _("cannot set time stamps for %s"), quote (to));
635       return false;
636     }
637   return true;
638 }
639
640 /* Strip the symbol table from the file NAME.
641    We could dig the magic number out of the file first to
642    determine whether to strip it, but the header files and
643    magic numbers vary so much from system to system that making
644    it portable would be very difficult.  Not worth the effort. */
645
646 static void
647 strip (char const *name)
648 {
649   int status;
650   pid_t pid = fork ();
651
652   switch (pid)
653     {
654     case -1:
655       error (EXIT_FAILURE, errno, _("fork system call failed"));
656       break;
657     case 0:                     /* Child. */
658       execlp ("strip", "strip", name, NULL);
659       error (EXIT_FAILURE, errno, _("cannot run strip"));
660       break;
661     default:                    /* Parent. */
662       if (waitpid (pid, &status, 0) < 0)
663         error (EXIT_FAILURE, errno, _("waiting for strip"));
664       else if (! WIFEXITED (status) || WEXITSTATUS (status))
665         error (EXIT_FAILURE, 0, _("strip process terminated abnormally"));
666       break;
667     }
668 }
669
670 /* Initialize the user and group ownership of the files to install. */
671
672 static void
673 get_ids (void)
674 {
675   struct passwd *pw;
676   struct group *gr;
677
678   if (owner_name)
679     {
680       pw = getpwnam (owner_name);
681       if (pw == NULL)
682         {
683           unsigned long int tmp;
684           if (xstrtoul (owner_name, NULL, 0, &tmp, NULL) != LONGINT_OK
685               || UID_T_MAX < tmp)
686             error (EXIT_FAILURE, 0, _("invalid user %s"), quote (owner_name));
687           owner_id = tmp;
688         }
689       else
690         owner_id = pw->pw_uid;
691       endpwent ();
692     }
693   else
694     owner_id = (uid_t) -1;
695
696   if (group_name)
697     {
698       gr = getgrnam (group_name);
699       if (gr == NULL)
700         {
701           unsigned long int tmp;
702           if (xstrtoul (group_name, NULL, 0, &tmp, NULL) != LONGINT_OK
703               || GID_T_MAX < tmp)
704             error (EXIT_FAILURE, 0, _("invalid group %s"), quote (group_name));
705           group_id = tmp;
706         }
707       else
708         group_id = gr->gr_gid;
709       endgrent ();
710     }
711   else
712     group_id = (gid_t) -1;
713 }
714
715 /* Report that directory DIR was made, if OPTIONS requests this.  */
716 static void
717 announce_mkdir (char const *dir, void *options)
718 {
719   struct cp_options const *x = options;
720   if (x->verbose)
721     error (0, 0, _("creating directory %s"), quote (dir));
722 }
723
724 /* Make ancestor directory DIR, whose last file name component is
725    COMPONENT, with options OPTIONS.  Assume the working directory is
726    COMPONENT's parent.  */
727 static int
728 make_ancestor (char const *dir, char const *component, void *options)
729 {
730   int r = mkdir (component, DEFAULT_MODE);
731   if (r == 0)
732     announce_mkdir (dir, options);
733   return r;
734 }
735
736 void
737 usage (int status)
738 {
739   if (status != EXIT_SUCCESS)
740     fprintf (stderr, _("Try `%s --help' for more information.\n"),
741              program_name);
742   else
743     {
744       printf (_("\
745 Usage: %s [OPTION]... [-T] SOURCE DEST\n\
746   or:  %s [OPTION]... SOURCE... DIRECTORY\n\
747   or:  %s [OPTION]... -t DIRECTORY SOURCE...\n\
748   or:  %s [OPTION]... -d DIRECTORY...\n\
749 "),
750               program_name, program_name, program_name, program_name);
751       fputs (_("\
752 In the first three forms, copy SOURCE to DEST or multiple SOURCE(s) to\n\
753 the existing DIRECTORY, while setting permission modes and owner/group.\n\
754 In the 4th form, create all components of the given DIRECTORY(ies).\n\
755 \n\
756 "), stdout);
757       fputs (_("\
758 Mandatory arguments to long options are mandatory for short options too.\n\
759 "), stdout);
760       fputs (_("\
761       --backup[=CONTROL]  make a backup of each existing destination file\n\
762   -b                  like --backup but does not accept an argument\n\
763   -c                  (ignored)\n\
764   -d, --directory     treat all arguments as directory names; create all\n\
765                         components of the specified directories\n\
766 "), stdout);
767       fputs (_("\
768   -D                  create all leading components of DEST except the last,\n\
769                         then copy SOURCE to DEST\n\
770   -g, --group=GROUP   set group ownership, instead of process' current group\n\
771   -m, --mode=MODE     set permission mode (as in chmod), instead of rwxr-xr-x\n\
772   -o, --owner=OWNER   set ownership (super-user only)\n\
773 "), stdout);
774       fputs (_("\
775   -p, --preserve-timestamps   apply access/modification times of SOURCE files\n\
776                         to corresponding destination files\n\
777   -s, --strip         strip symbol tables\n\
778   -S, --suffix=SUFFIX  override the usual backup suffix\n\
779   -t, --target-directory=DIRECTORY  copy all SOURCE arguments into DIRECTORY\n\
780   -T, --no-target-directory  treat DEST as a normal file\n\
781   -v, --verbose       print the name of each directory as it is created\n\
782 "), stdout);
783       fputs (_("\
784       --preserve-context  preserve SELinux security context\n\
785   -Z, --context=CONTEXT  set SELinux security context of files and directories\n\
786 "), stdout);
787
788       fputs (HELP_OPTION_DESCRIPTION, stdout);
789       fputs (VERSION_OPTION_DESCRIPTION, stdout);
790       fputs (_("\
791 \n\
792 The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
793 The version control method may be selected via the --backup option or through\n\
794 the VERSION_CONTROL environment variable.  Here are the values:\n\
795 \n\
796 "), stdout);
797       fputs (_("\
798   none, off       never make backups (even if --backup is given)\n\
799   numbered, t     make numbered backups\n\
800   existing, nil   numbered if numbered backups exist, simple otherwise\n\
801   simple, never   always make simple backups\n\
802 "), stdout);
803       emit_bug_reporting_address ();
804     }
805   exit (status);
806 }