tests: exercise tests new "==" operator
[coreutils.git] / src / install.c
blobcebb64278fab1367bc2446dadc0e53dc21c6103c
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> */
19 #include <config.h>
20 #include <stdio.h>
21 #include <getopt.h>
22 #include <sys/types.h>
23 #include <signal.h>
24 #include <pwd.h>
25 #include <grp.h>
26 #include <selinux/selinux.h>
27 #include <sys/wait.h>
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 "full-read.h"
36 #include "mkancesdirs.h"
37 #include "mkdir-p.h"
38 #include "modechange.h"
39 #include "prog-fprintf.h"
40 #include "quote.h"
41 #include "quotearg.h"
42 #include "savewd.h"
43 #include "stat-time.h"
44 #include "utimens.h"
45 #include "xstrtol.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;
55 #if ! HAVE_ENDGRENT
56 # define endgrent() ((void) 0)
57 #endif
59 #if ! HAVE_ENDPWENT
60 # define endpwent() ((void) 0)
61 #endif
63 #if ! HAVE_LCHOWN
64 # define lchown(name, uid, gid) chown (name, uid, gid)
65 #endif
67 #if ! HAVE_MATCHPATHCON_INIT_PREFIX
68 # define matchpathcon_init_prefix(a, p) /* empty */
69 #endif
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,
85 void *options);
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
105 no effect. */
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
114 or S_ISGID bits. */
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. */
124 static bool dir_arg;
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. */
131 enum
133 PRESERVE_CONTEXT_OPTION = CHAR_MAX + 1,
134 PRESERVE_CONTEXT_OPTION_DEPRECATED,
135 STRIP_PROGRAM_OPTION
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},
160 {NULL, 0, NULL, 0}
163 /* Compare content of opened files using file descriptors A_FD and B_FD. Return
164 true if files are equal. */
165 static bool
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];
172 size_t 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))
175 return false;
177 if (memcmp (a_buff, b_buff, size) != 0)
178 return false;
181 return size == 0;
184 /* Return true for mode with non-permission bits. */
185 static bool
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. */
193 static bool
194 need_copy (const char *src_name, const char *dest_name,
195 const struct cp_options *x)
197 struct stat src_sb, dest_sb;
198 int src_fd, dest_fd;
199 bool content_match;
201 if (extra_mode (mode))
202 return true;
204 /* compare files using stat */
205 if (lstat (src_name, &src_sb) != 0)
206 return true;
208 if (lstat (dest_name, &dest_sb) != 0)
209 return true;
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))
213 return true;
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))
219 return true;
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;
226 bool scontext_match;
228 if (getfilecon (src_name, &file_scontext) == -1)
229 return true;
231 if (getfilecon (dest_name, &to_scontext) == -1)
233 freecon (file_scontext);
234 return true;
237 scontext_match = STREQ (file_scontext, to_scontext);
239 freecon (file_scontext);
240 freecon (to_scontext);
241 if (!scontext_match)
242 return true;
245 /* compare files content */
246 src_fd = open (src_name, O_RDONLY | O_BINARY);
247 if (src_fd < 0)
248 return true;
250 dest_fd = open (dest_name, O_RDONLY | O_BINARY);
251 if (dest_fd < 0)
253 close (src_fd);
254 return true;
257 content_match = have_same_content (src_fd, dest_fd);
259 close (src_fd);
260 close (dest_fd);
261 return !content_match;
264 static void
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
293 would fail. */
294 x->set_mode = true;
295 x->mode = S_IRUSR | S_IWUSR;
296 x->stdin_tty = false;
298 x->open_dangling_dest_symlink = false;
299 x->update = false;
300 x->preserve_security_context = false;
301 x->preserve_xattr = false;
302 x->verbose = false;
303 x->dest_info = NULL;
304 x->src_info = NULL;
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
310 context. */
311 static void
312 setdefaultfilecon (char const *file)
314 struct stat st;
315 security_context_t scontext = NULL;
316 static bool first_call = true;
318 if (selinux_enabled != 1)
320 /* Indicate no context found. */
321 return;
323 if (lstat (file, &st) != 0)
324 return;
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. */
335 char const *p0;
336 char const *p = file + 1;
337 while (ISSLASH (*p))
338 ++p;
340 /* Record final leading slash, for when FILE starts with two or more. */
341 p0 = p - 1;
343 if (*p)
345 char *prefix;
348 ++p;
350 while (*p && !ISSLASH (*p));
352 prefix = malloc (p - p0 + 2);
353 if (prefix)
355 stpcpy (stpncpy (prefix, p0, p - p0), "/");
356 matchpathcon_init_prefix (NULL, prefix);
357 free (prefix);
361 first_call = false;
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)
369 freecon (scontext);
370 return;
373 if (lsetfilecon (file, scontext) < 0 && errno != ENOTSUP)
374 error (0, errno,
375 _("warning: %s: failed to change context to %s"),
376 quotearg_colon (file), scontext);
378 freecon (scontext);
379 return;
381 #else
382 static void
383 setdefaultfilecon (char const *file)
385 (void) file;
387 #endif
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. */
394 static bool
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]));
400 struct stat st;
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));
407 return is_a_dir;
410 /* Process a command-line file name, for the -d option. */
411 static int
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)
418 ? EXIT_SUCCESS
419 : EXIT_FAILURE);
423 main (int argc, char **argv)
425 int optc;
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;
432 struct cp_options x;
433 char const *target_directory = NULL;
434 bool no_target_directory = false;
435 int n_files;
436 char **file;
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);
450 cp_option_init (&x);
452 owner_name = NULL;
453 group_name = NULL;
454 strip_files = false;
455 dir_arg = false;
456 umask (0);
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,
463 NULL)) != -1)
465 switch (optc)
467 case 'b':
468 make_backups = true;
469 if (optarg)
470 version_control_string = optarg;
471 break;
472 case 'c':
473 break;
474 case 'C':
475 copy_only_if_needed = true;
476 break;
477 case 's':
478 strip_files = true;
479 #ifdef SIGCHLD
480 /* System V fork+wait does not work if SIGCHLD is ignored. */
481 signal (SIGCHLD, SIG_DFL);
482 #endif
483 break;
484 case STRIP_PROGRAM_OPTION:
485 strip_program = xstrdup (optarg);
486 strip_program_specified = true;
487 break;
488 case 'd':
489 dir_arg = true;
490 break;
491 case 'D':
492 mkdir_and_install = true;
493 break;
494 case 'v':
495 x.verbose = true;
496 break;
497 case 'g':
498 group_name = optarg;
499 break;
500 case 'm':
501 specified_mode = optarg;
502 break;
503 case 'o':
504 owner_name = optarg;
505 break;
506 case 'p':
507 x.preserve_timestamps = true;
508 break;
509 case 'S':
510 make_backups = true;
511 backup_suffix_string = optarg;
512 break;
513 case 't':
514 if (target_directory)
515 error (EXIT_FAILURE, 0,
516 _("multiple target directories specified"));
517 else
519 struct stat st;
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"),
524 quote (optarg));
526 target_directory = optarg;
527 break;
528 case 'T':
529 no_target_directory = true;
530 break;
532 case PRESERVE_CONTEXT_OPTION_DEPRECATED:
533 error (0, 0, _("WARNING: --preserve_context is deprecated; "
534 "use --preserve-context instead"));
535 /* fall through */
536 case PRESERVE_CONTEXT_OPTION:
537 if ( ! selinux_enabled)
539 error (0, 0, _("WARNING: ignoring --preserve-context; "
540 "this kernel is not SELinux-enabled"));
541 break;
543 x.preserve_security_context = true;
544 use_default_selinux_context = false;
545 break;
546 case 'Z':
547 if ( ! selinux_enabled)
549 error (0, 0, _("WARNING: ignoring --context (-Z); "
550 "this kernel is not SELinux-enabled"));
551 break;
553 scontext = optarg;
554 use_default_selinux_context = false;
555 break;
556 case_GETOPT_HELP_CHAR;
557 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
558 default:
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"),
574 quote (scontext));
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)
582 : no_backups);
584 if (scontext && setfscreatecon (scontext) < 0)
585 error (EXIT_FAILURE, errno,
586 _("failed to set default file creation context to %s"),
587 quote (scontext));
589 n_files = argc - optind;
590 file = argv + optind;
592 if (n_files <= ! (dir_arg || target_directory))
594 if (n_files <= 0)
595 error (0, 0, _("missing file operand"));
596 else
597 error (0, 0, _("missing destination file operand after %s"),
598 quote (file[0]));
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)"));
608 if (2 < n_files)
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]));
623 if (specified_mode)
625 struct mode_change *change = mode_compile (specified_mode);
626 if (!change)
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);
630 free (change);
633 if (strip_program_specified && !strip_files)
634 error (0, 0, _("WARNING: ignoring --strip-program option as -s option was "
635 "not specified"));
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 "
647 "exclusive"));
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"));
655 get_ids ();
657 if (dir_arg)
658 exit_status = savewd_process_files (n_files, file, process_dir, &x);
659 else
661 /* FIXME: it's a little gross that this initialization is
662 required by copy.c::copy. */
663 hash_init ();
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;
672 else
674 int i;
675 dest_info_init (&x);
676 for (i = 0; i < n_files; i++)
677 if (! install_file_in_dir (file[i], target_directory, &x))
678 exit_status = EXIT_FAILURE;
682 exit (exit_status);
685 /* Copy file FROM onto file TO, creating any missing parent directories of TO.
686 Return true if successful. */
688 static bool
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;
696 struct savewd wd;
697 savewd_init (&wd);
698 if (! save_working_directory)
699 savewd_finish (&wd);
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;
711 savewd_finish (&wd);
712 if (EXIT_SUCCESS < restore_result)
713 return false;
714 if (restore_result < 0 && status == EXIT_SUCCESS)
716 error (0, restore_errno, _("cannot create directory %s"), to);
717 return false;
721 return (status == EXIT_SUCCESS && install_file_in_file (from, to, x));
724 /* Copy file FROM onto file TO and give TO the appropriate
725 attributes.
726 Return true if successful. */
728 static bool
729 install_file_in_file (const char *from, const char *to,
730 const struct cp_options *x)
732 struct stat from_sb;
733 if (x->preserve_timestamps && stat (from, &from_sb) != 0)
735 error (0, errno, _("cannot stat %s"), quote (from));
736 return false;
738 if (! copy_file (from, to, x))
739 return false;
740 if (strip_files)
741 strip (to);
742 if (x->preserve_timestamps && (strip_files || ! S_ISREG (from_sb.st_mode))
743 && ! change_timestamps (&from_sb, to))
744 return false;
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. */
752 static bool
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);
759 free (to);
760 return ret;
763 /* Copy file FROM onto file TO, creating TO if necessary.
764 Return true if successful. */
766 static bool
767 copy_file (const char *from, const char *to, const struct cp_options *x)
769 bool copy_into_self;
771 if (copy_only_if_needed && !need_copy (from, to, x))
772 return true;
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
778 is a directory. */
780 return copy (from, to, false, x, &copy_into_self, NULL);
783 /* Set the attributes of file or directory NAME.
784 Return true if successful. */
786 static bool
787 change_attributes (char const *name)
789 bool ok = false;
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
800 want to know. */
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));
807 else
808 ok = true;
810 if (use_default_selinux_context)
811 setdefaultfilecon (name);
813 return ok;
816 /* Set the timestamps of file TO to match those of file FROM.
817 Return true if successful. */
819 static bool
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));
829 return false;
831 return true;
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. */
840 static void
841 strip (char const *name)
843 int status;
844 pid_t pid = fork ();
846 switch (pid)
848 case -1:
849 error (EXIT_FAILURE, errno, _("fork system call failed"));
850 break;
851 case 0: /* Child. */
852 execlp (strip_program, strip_program, name, NULL);
853 error (EXIT_FAILURE, errno, _("cannot run %s"), strip_program);
854 break;
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"));
860 break;
864 /* Initialize the user and group ownership of the files to install. */
866 static void
867 get_ids (void)
869 struct passwd *pw;
870 struct group *gr;
872 if (owner_name)
874 pw = getpwnam (owner_name);
875 if (pw == NULL)
877 unsigned long int tmp;
878 if (xstrtoul (owner_name, NULL, 0, &tmp, NULL) != LONGINT_OK
879 || UID_T_MAX < tmp)
880 error (EXIT_FAILURE, 0, _("invalid user %s"), quote (owner_name));
881 owner_id = tmp;
883 else
884 owner_id = pw->pw_uid;
885 endpwent ();
887 else
888 owner_id = (uid_t) -1;
890 if (group_name)
892 gr = getgrnam (group_name);
893 if (gr == NULL)
895 unsigned long int tmp;
896 if (xstrtoul (group_name, NULL, 0, &tmp, NULL) != LONGINT_OK
897 || GID_T_MAX < tmp)
898 error (EXIT_FAILURE, 0, _("invalid group %s"), quote (group_name));
899 group_id = tmp;
901 else
902 group_id = gr->gr_gid;
903 endgrent ();
905 else
906 group_id = (gid_t) -1;
909 /* Report that directory DIR was made, if OPTIONS requests this. */
910 static void
911 announce_mkdir (char const *dir, void *options)
913 struct cp_options const *x = options;
914 if (x->verbose)
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. */
921 static int
922 make_ancestor (char const *dir, char const *component, void *options)
924 int r = mkdir (component, DEFAULT_MODE);
925 if (r == 0)
926 announce_mkdir (dir, options);
927 return r;
930 void
931 usage (int status)
933 if (status != EXIT_SUCCESS)
934 fprintf (stderr, _("Try `%s --help' for more information.\n"),
935 program_name);
936 else
938 printf (_("\
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);
945 fputs (_("\
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\
956 "), stdout);
957 fputs (_("\
958 Mandatory arguments to long options are mandatory for short options too.\n\
959 "), stdout);
960 fputs (_("\
961 --backup[=CONTROL] make a backup of each existing destination file\n\
962 -b like --backup but does not accept an argument\n\
963 -c (ignored)\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\
968 "), stdout);
969 fputs (_("\
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\
975 "), stdout);
976 fputs (_("\
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\
985 "), stdout);
986 fputs (_("\
987 --preserve-context preserve SELinux security context\n\
988 -Z, --context=CONTEXT set SELinux security context of files and directories\
990 "), stdout);
992 fputs (HELP_OPTION_DESCRIPTION, stdout);
993 fputs (VERSION_OPTION_DESCRIPTION, stdout);
994 fputs (_("\
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\
1000 "), stdout);
1001 fputs (_("\
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\
1006 "), stdout);
1007 emit_ancillary_info ();
1009 exit (status);