1 /* install - copy files and set attributes
2 Copyright (C) 1989-1991, 1995-2011 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 /* Written by David MacKenzie <djm@gnu.ai.mit.edu> */
22 #include <sys/types.h>
26 #include <selinux/selinux.h>
30 #include "backupfile.h"
34 #include "filenamecat.h"
35 #include "full-read.h"
36 #include "mkancesdirs.h"
38 #include "modechange.h"
39 #include "prog-fprintf.h"
43 #include "stat-time.h"
47 /* The official name of this program (e.g., no `g' prefix). */
48 #define PROGRAM_NAME "install"
50 #define AUTHORS proper_name ("David MacKenzie")
52 static int selinux_enabled
= 0;
53 static bool use_default_selinux_context
= true;
56 # define endgrent() ((void) 0)
60 # define endpwent() ((void) 0)
64 # define lchown(name, uid, gid) chown (name, uid, gid)
67 #if ! HAVE_MATCHPATHCON_INIT_PREFIX
68 # define matchpathcon_init_prefix(a, p) /* empty */
71 static bool change_timestamps (struct stat
const *from_sb
, char const *to
);
72 static bool change_attributes (char const *name
);
73 static bool copy_file (const char *from
, const char *to
,
74 const struct cp_options
*x
);
75 static bool install_file_in_file_parents (char const *from
, char *to
,
76 struct cp_options
*x
);
77 static bool install_file_in_dir (const char *from
, const char *to_dir
,
78 const struct cp_options
*x
);
79 static bool install_file_in_file (const char *from
, const char *to
,
80 const struct cp_options
*x
);
81 static void get_ids (void);
82 static void strip (char const *name
);
83 static void announce_mkdir (char const *dir
, void *options
);
84 static int make_ancestor (char const *dir
, char const *component
,
86 void usage (int status
);
88 /* The user name that will own the files, or NULL to make the owner
89 the current user ID. */
90 static char *owner_name
;
92 /* The user ID corresponding to `owner_name'. */
93 static uid_t owner_id
;
95 /* The group name that will own the files, or NULL to make the group
96 the current group ID. */
97 static char *group_name
;
99 /* The group ID corresponding to `group_name'. */
100 static gid_t group_id
;
102 #define DEFAULT_MODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
104 /* The file mode bits to which non-directory files will be set. The umask has
106 static mode_t mode
= DEFAULT_MODE
;
108 /* Similar, but for directories. */
109 static mode_t dir_mode
= DEFAULT_MODE
;
111 /* The file mode bits that the user cares about. This should be a
112 superset of DIR_MODE and a subset of CHMOD_MODE_BITS. This matters
113 for directories, since otherwise directories may keep their S_ISUID
115 static mode_t dir_mode_bits
= CHMOD_MODE_BITS
;
117 /* Compare files before installing (-C) */
118 static bool copy_only_if_needed
;
120 /* If true, strip executable files after copying them. */
121 static bool strip_files
;
123 /* If true, install a directory instead of a regular file. */
126 /* Program used to strip binaries, "strip" is default */
127 static char const *strip_program
= "strip";
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. */
133 PRESERVE_CONTEXT_OPTION
= CHAR_MAX
+ 1,
134 PRESERVE_CONTEXT_OPTION_DEPRECATED
,
138 static struct option
const long_options
[] =
140 {"backup", optional_argument
, NULL
, 'b'},
141 {"compare", no_argument
, NULL
, 'C'},
142 {GETOPT_SELINUX_CONTEXT_OPTION_DECL
},
143 {"directory", no_argument
, NULL
, 'd'},
144 {"group", required_argument
, NULL
, 'g'},
145 {"mode", required_argument
, NULL
, 'm'},
146 {"no-target-directory", no_argument
, NULL
, 'T'},
147 {"owner", required_argument
, NULL
, 'o'},
148 {"preserve-timestamps", no_argument
, NULL
, 'p'},
149 {"preserve-context", no_argument
, NULL
, PRESERVE_CONTEXT_OPTION
},
150 /* --preserve_context was silently supported until Apr 2009.
151 FIXME: disable altogether in a year or so. */
152 {"preserve_context", no_argument
, NULL
, PRESERVE_CONTEXT_OPTION_DEPRECATED
},
153 {"strip", no_argument
, NULL
, 's'},
154 {"strip-program", required_argument
, NULL
, STRIP_PROGRAM_OPTION
},
155 {"suffix", required_argument
, NULL
, 'S'},
156 {"target-directory", required_argument
, NULL
, 't'},
157 {"verbose", no_argument
, NULL
, 'v'},
158 {GETOPT_HELP_OPTION_DECL
},
159 {GETOPT_VERSION_OPTION_DECL
},
163 /* Compare content of opened files using file descriptors A_FD and B_FD. Return
164 true if files are equal. */
166 have_same_content (int a_fd
, int b_fd
)
168 enum { CMP_BLOCK_SIZE
= 4096 };
169 static char a_buff
[CMP_BLOCK_SIZE
];
170 static char b_buff
[CMP_BLOCK_SIZE
];
173 while (0 < (size
= full_read (a_fd
, a_buff
, sizeof a_buff
))) {
174 if (size
!= full_read (b_fd
, b_buff
, sizeof b_buff
))
177 if (memcmp (a_buff
, b_buff
, size
) != 0)
184 /* Return true for mode with non-permission bits. */
186 extra_mode (mode_t input
)
188 mode_t mask
= S_IRWXUGO
| S_IFMT
;
189 return !! (input
& ~ mask
);
192 /* Return true if copy of file SRC_NAME to file DEST_NAME is necessary. */
194 need_copy (const char *src_name
, const char *dest_name
,
195 const struct cp_options
*x
)
197 struct stat src_sb
, dest_sb
;
201 if (extra_mode (mode
))
204 /* compare files using stat */
205 if (lstat (src_name
, &src_sb
) != 0)
208 if (lstat (dest_name
, &dest_sb
) != 0)
211 if (!S_ISREG (src_sb
.st_mode
) || !S_ISREG (dest_sb
.st_mode
)
212 || extra_mode (src_sb
.st_mode
) || extra_mode (dest_sb
.st_mode
))
215 if (src_sb
.st_size
!= dest_sb
.st_size
216 || (dest_sb
.st_mode
& CHMOD_MODE_BITS
) != mode
217 || dest_sb
.st_uid
!= (owner_id
== (uid_t
) -1 ? getuid () : owner_id
)
218 || dest_sb
.st_gid
!= (group_id
== (gid_t
) -1 ? getgid () : group_id
))
221 /* compare SELinux context if preserving */
222 if (selinux_enabled
&& x
->preserve_security_context
)
224 security_context_t file_scontext
= NULL
;
225 security_context_t to_scontext
= NULL
;
228 if (getfilecon (src_name
, &file_scontext
) == -1)
231 if (getfilecon (dest_name
, &to_scontext
) == -1)
233 freecon (file_scontext
);
237 scontext_match
= STREQ (file_scontext
, to_scontext
);
239 freecon (file_scontext
);
240 freecon (to_scontext
);
245 /* compare files content */
246 src_fd
= open (src_name
, O_RDONLY
| O_BINARY
);
250 dest_fd
= open (dest_name
, O_RDONLY
| O_BINARY
);
257 content_match
= have_same_content (src_fd
, dest_fd
);
261 return !content_match
;
265 cp_option_init (struct cp_options
*x
)
267 cp_options_default (x
);
268 x
->copy_as_regular
= true;
269 x
->reflink_mode
= REFLINK_NEVER
;
270 x
->dereference
= DEREF_ALWAYS
;
271 x
->unlink_dest_before_opening
= true;
272 x
->unlink_dest_after_failed_open
= false;
273 x
->hard_link
= false;
274 x
->interactive
= I_UNSPECIFIED
;
275 x
->move_mode
= false;
276 x
->one_file_system
= false;
277 x
->preserve_ownership
= false;
278 x
->preserve_links
= false;
279 x
->preserve_mode
= false;
280 x
->preserve_timestamps
= false;
281 x
->reduce_diagnostics
=false;
282 x
->data_copy_required
= true;
283 x
->require_preserve
= false;
284 x
->require_preserve_context
= false;
285 x
->require_preserve_xattr
= false;
286 x
->recursive
= false;
287 x
->sparse_mode
= SPARSE_AUTO
;
288 x
->symbolic_link
= false;
289 x
->backup_type
= no_backups
;
291 /* Create destination files initially writable so we can run strip on them.
292 Although GNU strip works fine on read-only files, some others
295 x
->mode
= S_IRUSR
| S_IWUSR
;
296 x
->stdin_tty
= false;
298 x
->open_dangling_dest_symlink
= false;
300 x
->preserve_security_context
= false;
301 x
->preserve_xattr
= false;
307 #ifdef ENABLE_MATCHPATHCON
308 /* Modify file context to match the specified policy.
309 If an error occurs the file will remain with the default directory
312 setdefaultfilecon (char const *file
)
315 security_context_t scontext
= NULL
;
316 static bool first_call
= true;
318 if (selinux_enabled
!= 1)
320 /* Indicate no context found. */
323 if (lstat (file
, &st
) != 0)
326 if (first_call
&& IS_ABSOLUTE_FILE_NAME (file
))
328 /* Calling matchpathcon_init_prefix (NULL, "/first_component/")
329 is an optimization to minimize the expense of the following
330 matchpathcon call. Do it only once, just before the first
331 matchpathcon call. We *could* call matchpathcon_fini after
332 the final matchpathcon call, but that's not necessary, since
333 by then we're about to exit, and besides, the buffers it
334 would free are still reachable. */
336 char const *p
= file
+ 1;
340 /* Record final leading slash, for when FILE starts with two or more. */
350 while (*p
&& !ISSLASH (*p
));
352 prefix
= malloc (p
- p0
+ 2);
355 stpcpy (stpncpy (prefix
, p0
, p
- p0
), "/");
356 matchpathcon_init_prefix (NULL
, prefix
);
363 /* If there's an error determining the context, or it has none,
364 return to allow default context */
365 if ((matchpathcon (file
, st
.st_mode
, &scontext
) != 0) ||
366 STREQ (scontext
, "<<none>>"))
368 if (scontext
!= NULL
)
373 if (lsetfilecon (file
, scontext
) < 0 && errno
!= ENOTSUP
)
375 _("warning: %s: failed to change context to %s"),
376 quotearg_colon (file
), scontext
);
383 setdefaultfilecon (char const *file
)
389 /* FILE is the last operand of this command. Return true if FILE is a
390 directory. But report an error there is a problem accessing FILE,
391 or if FILE does not exist but would have to refer to an existing
392 directory if it referred to anything at all. */
395 target_directory_operand (char const *file
)
397 char const *b
= last_component (file
);
398 size_t blen
= strlen (b
);
399 bool looks_like_a_dir
= (blen
== 0 || ISSLASH (b
[blen
- 1]));
401 int err
= (stat (file
, &st
) == 0 ? 0 : errno
);
402 bool is_a_dir
= !err
&& S_ISDIR (st
.st_mode
);
403 if (err
&& err
!= ENOENT
)
404 error (EXIT_FAILURE
, err
, _("accessing %s"), quote (file
));
405 if (is_a_dir
< looks_like_a_dir
)
406 error (EXIT_FAILURE
, err
, _("target %s is not a directory"), quote (file
));
410 /* Process a command-line file name, for the -d option. */
412 process_dir (char *dir
, struct savewd
*wd
, void *options
)
414 return (make_dir_parents (dir
, wd
,
415 make_ancestor
, options
,
416 dir_mode
, announce_mkdir
,
417 dir_mode_bits
, owner_id
, group_id
, false)
423 main (int argc
, char **argv
)
426 int exit_status
= EXIT_SUCCESS
;
427 const char *specified_mode
= NULL
;
428 bool make_backups
= false;
429 char *backup_suffix_string
;
430 char *version_control_string
= NULL
;
431 bool mkdir_and_install
= false;
433 char const *target_directory
= NULL
;
434 bool no_target_directory
= false;
437 bool strip_program_specified
= false;
438 security_context_t scontext
= NULL
;
439 /* set iff kernel has extra selinux system calls */
440 selinux_enabled
= (0 < is_selinux_enabled ());
442 initialize_main (&argc
, &argv
);
443 set_program_name (argv
[0]);
444 setlocale (LC_ALL
, "");
445 bindtextdomain (PACKAGE
, LOCALEDIR
);
446 textdomain (PACKAGE
);
448 atexit (close_stdin
);
458 /* FIXME: consider not calling getenv for SIMPLE_BACKUP_SUFFIX unless
459 we'll actually use backup_suffix_string. */
460 backup_suffix_string
= getenv ("SIMPLE_BACKUP_SUFFIX");
462 while ((optc
= getopt_long (argc
, argv
, "bcCsDdg:m:o:pt:TvS:Z:", long_options
,
470 version_control_string
= optarg
;
475 copy_only_if_needed
= true;
480 /* System V fork+wait does not work if SIGCHLD is ignored. */
481 signal (SIGCHLD
, SIG_DFL
);
484 case STRIP_PROGRAM_OPTION
:
485 strip_program
= xstrdup (optarg
);
486 strip_program_specified
= true;
492 mkdir_and_install
= true;
501 specified_mode
= optarg
;
507 x
.preserve_timestamps
= true;
511 backup_suffix_string
= optarg
;
514 if (target_directory
)
515 error (EXIT_FAILURE
, 0,
516 _("multiple target directories specified"));
520 if (stat (optarg
, &st
) != 0)
521 error (EXIT_FAILURE
, errno
, _("accessing %s"), quote (optarg
));
522 if (! S_ISDIR (st
.st_mode
))
523 error (EXIT_FAILURE
, 0, _("target %s is not a directory"),
526 target_directory
= optarg
;
529 no_target_directory
= true;
532 case PRESERVE_CONTEXT_OPTION_DEPRECATED
:
533 error (0, 0, _("WARNING: --preserve_context is deprecated; "
534 "use --preserve-context instead"));
536 case PRESERVE_CONTEXT_OPTION
:
537 if ( ! selinux_enabled
)
539 error (0, 0, _("WARNING: ignoring --preserve-context; "
540 "this kernel is not SELinux-enabled"));
543 x
.preserve_security_context
= true;
544 use_default_selinux_context
= false;
547 if ( ! selinux_enabled
)
549 error (0, 0, _("WARNING: ignoring --context (-Z); "
550 "this kernel is not SELinux-enabled"));
554 use_default_selinux_context
= false;
556 case_GETOPT_HELP_CHAR
;
557 case_GETOPT_VERSION_CHAR (PROGRAM_NAME
, AUTHORS
);
559 usage (EXIT_FAILURE
);
563 /* Check for invalid combinations of arguments. */
564 if (dir_arg
&& strip_files
)
565 error (EXIT_FAILURE
, 0,
566 _("the strip option may not be used when installing a directory"));
567 if (dir_arg
&& target_directory
)
568 error (EXIT_FAILURE
, 0,
569 _("target directory not allowed when installing a directory"));
571 if (x
.preserve_security_context
&& scontext
!= NULL
)
572 error (EXIT_FAILURE
, 0,
573 _("cannot force target context to %s and preserve it"),
576 if (backup_suffix_string
)
577 simple_backup_suffix
= xstrdup (backup_suffix_string
);
579 x
.backup_type
= (make_backups
580 ? xget_version (_("backup type"),
581 version_control_string
)
584 if (scontext
&& setfscreatecon (scontext
) < 0)
585 error (EXIT_FAILURE
, errno
,
586 _("failed to set default file creation context to %s"),
589 n_files
= argc
- optind
;
590 file
= argv
+ optind
;
592 if (n_files
<= ! (dir_arg
|| target_directory
))
595 error (0, 0, _("missing file operand"));
597 error (0, 0, _("missing destination file operand after %s"),
599 usage (EXIT_FAILURE
);
602 if (no_target_directory
)
604 if (target_directory
)
605 error (EXIT_FAILURE
, 0,
606 _("cannot combine --target-directory (-t) "
607 "and --no-target-directory (-T)"));
610 error (0, 0, _("extra operand %s"), quote (file
[2]));
611 usage (EXIT_FAILURE
);
614 else if (! (dir_arg
|| target_directory
))
616 if (2 <= n_files
&& target_directory_operand (file
[n_files
- 1]))
617 target_directory
= file
[--n_files
];
618 else if (2 < n_files
)
619 error (EXIT_FAILURE
, 0, _("target %s is not a directory"),
620 quote (file
[n_files
- 1]));
625 struct mode_change
*change
= mode_compile (specified_mode
);
627 error (EXIT_FAILURE
, 0, _("invalid mode %s"), quote (specified_mode
));
628 mode
= mode_adjust (0, false, 0, change
, NULL
);
629 dir_mode
= mode_adjust (0, true, 0, change
, &dir_mode_bits
);
633 if (strip_program_specified
&& !strip_files
)
634 error (0, 0, _("WARNING: ignoring --strip-program option as -s option was "
637 if (copy_only_if_needed
&& x
.preserve_timestamps
)
639 error (0, 0, _("options --compare (-C) and --preserve-timestamps are "
640 "mutually exclusive"));
641 usage (EXIT_FAILURE
);
644 if (copy_only_if_needed
&& strip_files
)
646 error (0, 0, _("options --compare (-C) and --strip are mutually "
648 usage (EXIT_FAILURE
);
651 if (copy_only_if_needed
&& extra_mode (mode
))
652 error (0, 0, _("the --compare (-C) option is ignored when you"
653 " specify a mode with non-permission bits"));
658 exit_status
= savewd_process_files (n_files
, file
, process_dir
, &x
);
661 /* FIXME: it's a little gross that this initialization is
662 required by copy.c::copy. */
665 if (!target_directory
)
667 if (! (mkdir_and_install
668 ? install_file_in_file_parents (file
[0], file
[1], &x
)
669 : install_file_in_file (file
[0], file
[1], &x
)))
670 exit_status
= EXIT_FAILURE
;
676 for (i
= 0; i
< n_files
; i
++)
677 if (! install_file_in_dir (file
[i
], target_directory
, &x
))
678 exit_status
= EXIT_FAILURE
;
685 /* Copy file FROM onto file TO, creating any missing parent directories of TO.
686 Return true if successful. */
689 install_file_in_file_parents (char const *from
, char *to
,
690 struct cp_options
*x
)
692 bool save_working_directory
=
693 ! (IS_ABSOLUTE_FILE_NAME (from
) && IS_ABSOLUTE_FILE_NAME (to
));
694 int status
= EXIT_SUCCESS
;
698 if (! save_working_directory
)
701 if (mkancesdirs (to
, &wd
, make_ancestor
, x
) == -1)
703 error (0, errno
, _("cannot create directory %s"), to
);
704 status
= EXIT_FAILURE
;
707 if (save_working_directory
)
709 int restore_result
= savewd_restore (&wd
, status
);
710 int restore_errno
= errno
;
712 if (EXIT_SUCCESS
< restore_result
)
714 if (restore_result
< 0 && status
== EXIT_SUCCESS
)
716 error (0, restore_errno
, _("cannot create directory %s"), to
);
721 return (status
== EXIT_SUCCESS
&& install_file_in_file (from
, to
, x
));
724 /* Copy file FROM onto file TO and give TO the appropriate
726 Return true if successful. */
729 install_file_in_file (const char *from
, const char *to
,
730 const struct cp_options
*x
)
733 if (x
->preserve_timestamps
&& stat (from
, &from_sb
) != 0)
735 error (0, errno
, _("cannot stat %s"), quote (from
));
738 if (! copy_file (from
, to
, x
))
742 if (x
->preserve_timestamps
&& (strip_files
|| ! S_ISREG (from_sb
.st_mode
))
743 && ! change_timestamps (&from_sb
, to
))
745 return change_attributes (to
);
748 /* Copy file FROM into directory TO_DIR, keeping its same name,
749 and give the copy the appropriate attributes.
750 Return true if successful. */
753 install_file_in_dir (const char *from
, const char *to_dir
,
754 const struct cp_options
*x
)
756 const char *from_base
= last_component (from
);
757 char *to
= file_name_concat (to_dir
, from_base
, NULL
);
758 bool ret
= install_file_in_file (from
, to
, x
);
763 /* Copy file FROM onto file TO, creating TO if necessary.
764 Return true if successful. */
767 copy_file (const char *from
, const char *to
, const struct cp_options
*x
)
771 if (copy_only_if_needed
&& !need_copy (from
, to
, x
))
774 /* Allow installing from non-regular files like /dev/null.
775 Charles Karney reported that some Sun version of install allows that
776 and that sendmail's installation process relies on the behavior.
777 However, since !x->recursive, the call to "copy" will fail if FROM
780 return copy (from
, to
, false, x
, ©_into_self
, NULL
);
783 /* Set the attributes of file or directory NAME.
784 Return true if successful. */
787 change_attributes (char const *name
)
790 /* chown must precede chmod because on some systems,
791 chown clears the set[ug]id bits for non-superusers,
792 resulting in incorrect permissions.
793 On System V, users can give away files with chown and then not
794 be able to chmod them. So don't give files away.
796 We don't normally ignore errors from chown because the idea of
797 the install command is that the file is supposed to end up with
798 precisely the attributes that the user specified (or defaulted).
799 If the file doesn't end up with the group they asked for, they'll
802 if (! (owner_id
== (uid_t
) -1 && group_id
== (gid_t
) -1)
803 && lchown (name
, owner_id
, group_id
) != 0)
804 error (0, errno
, _("cannot change ownership of %s"), quote (name
));
805 else if (chmod (name
, mode
) != 0)
806 error (0, errno
, _("cannot change permissions of %s"), quote (name
));
810 if (use_default_selinux_context
)
811 setdefaultfilecon (name
);
816 /* Set the timestamps of file TO to match those of file FROM.
817 Return true if successful. */
820 change_timestamps (struct stat
const *from_sb
, char const *to
)
822 struct timespec timespec
[2];
823 timespec
[0] = get_stat_atime (from_sb
);
824 timespec
[1] = get_stat_mtime (from_sb
);
826 if (utimens (to
, timespec
))
828 error (0, errno
, _("cannot set time stamps for %s"), quote (to
));
834 /* Strip the symbol table from the file NAME.
835 We could dig the magic number out of the file first to
836 determine whether to strip it, but the header files and
837 magic numbers vary so much from system to system that making
838 it portable would be very difficult. Not worth the effort. */
841 strip (char const *name
)
849 error (EXIT_FAILURE
, errno
, _("fork system call failed"));
852 execlp (strip_program
, strip_program
, name
, NULL
);
853 error (EXIT_FAILURE
, errno
, _("cannot run %s"), strip_program
);
855 default: /* Parent. */
856 if (waitpid (pid
, &status
, 0) < 0)
857 error (EXIT_FAILURE
, errno
, _("waiting for strip"));
858 else if (! WIFEXITED (status
) || WEXITSTATUS (status
))
859 error (EXIT_FAILURE
, 0, _("strip process terminated abnormally"));
864 /* Initialize the user and group ownership of the files to install. */
874 pw
= getpwnam (owner_name
);
877 unsigned long int tmp
;
878 if (xstrtoul (owner_name
, NULL
, 0, &tmp
, NULL
) != LONGINT_OK
880 error (EXIT_FAILURE
, 0, _("invalid user %s"), quote (owner_name
));
884 owner_id
= pw
->pw_uid
;
888 owner_id
= (uid_t
) -1;
892 gr
= getgrnam (group_name
);
895 unsigned long int tmp
;
896 if (xstrtoul (group_name
, NULL
, 0, &tmp
, NULL
) != LONGINT_OK
898 error (EXIT_FAILURE
, 0, _("invalid group %s"), quote (group_name
));
902 group_id
= gr
->gr_gid
;
906 group_id
= (gid_t
) -1;
909 /* Report that directory DIR was made, if OPTIONS requests this. */
911 announce_mkdir (char const *dir
, void *options
)
913 struct cp_options
const *x
= options
;
915 prog_fprintf (stdout
, _("creating directory %s"), quote (dir
));
918 /* Make ancestor directory DIR, whose last file name component is
919 COMPONENT, with options OPTIONS. Assume the working directory is
920 COMPONENT's parent. */
922 make_ancestor (char const *dir
, char const *component
, void *options
)
924 int r
= mkdir (component
, DEFAULT_MODE
);
926 announce_mkdir (dir
, options
);
933 if (status
!= EXIT_SUCCESS
)
934 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
939 Usage: %s [OPTION]... [-T] SOURCE DEST\n\
940 or: %s [OPTION]... SOURCE... DIRECTORY\n\
941 or: %s [OPTION]... -t DIRECTORY SOURCE...\n\
942 or: %s [OPTION]... -d DIRECTORY...\n\
944 program_name
, program_name
, program_name
, program_name
);
947 This install program copies files (often just compiled) into destination\n\
948 locations you choose. If you want to download and install a ready-to-use\n\
949 package on a GNU/Linux system, you should instead be using a package manager\n\
950 like yum(1) or apt-get(1).\n\
952 In the first three forms, copy SOURCE to DEST or multiple SOURCE(s) to\n\
953 the existing DIRECTORY, while setting permission modes and owner/group.\n\
954 In the 4th form, create all components of the given DIRECTORY(ies).\n\
958 Mandatory arguments to long options are mandatory for short options too.\n\
961 --backup[=CONTROL] make a backup of each existing destination file\n\
962 -b like --backup but does not accept an argument\n\
964 -C, --compare compare each pair of source and destination files, and\n\
965 in some cases, do not modify the destination at all\n\
966 -d, --directory treat all arguments as directory names; create all\n\
967 components of the specified directories\n\
970 -D create all leading components of DEST except the last,\n\
971 then copy SOURCE to DEST\n\
972 -g, --group=GROUP set group ownership, instead of process' current group\n\
973 -m, --mode=MODE set permission mode (as in chmod), instead of rwxr-xr-x\n\
974 -o, --owner=OWNER set ownership (super-user only)\n\
977 -p, --preserve-timestamps apply access/modification times of SOURCE files\n\
978 to corresponding destination files\n\
979 -s, --strip strip symbol tables\n\
980 --strip-program=PROGRAM program used to strip binaries\n\
981 -S, --suffix=SUFFIX override the usual backup suffix\n\
982 -t, --target-directory=DIRECTORY copy all SOURCE arguments into DIRECTORY\n\
983 -T, --no-target-directory treat DEST as a normal file\n\
984 -v, --verbose print the name of each directory as it is created\n\
987 --preserve-context preserve SELinux security context\n\
988 -Z, --context=CONTEXT set SELinux security context of files and directories\
992 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
993 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
996 The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
997 The version control method may be selected via the --backup option or through\n\
998 the VERSION_CONTROL environment variable. Here are the values:\n\
1002 none, off never make backups (even if --backup is given)\n\
1003 numbered, t make numbered backups\n\
1004 existing, nil numbered if numbered backups exist, simple otherwise\n\
1005 simple, never always make simple backups\n\
1007 emit_ancillary_info ();