1 /* install - copy files and set attributes
2 Copyright (C) 89, 90, 91, 1995-2008 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>
29 #include "backupfile.h"
33 #include "filenamecat.h"
34 #include "mkancesdirs.h"
36 #include "modechange.h"
37 #include "prog-fprintf.h"
41 #include "stat-time.h"
45 /* The official name of this program (e.g., no `g' prefix). */
46 #define PROGRAM_NAME "install"
48 #define AUTHORS proper_name ("David MacKenzie")
51 # include <sys/wait.h>
54 static int selinux_enabled = 0;
55 static bool use_default_selinux_context = true;
58 # define endgrent() ((void) 0)
62 # define endpwent() ((void) 0)
66 # define lchown(name, uid, gid) chown (name, uid, gid)
69 #if ! HAVE_MATCHPATHCON_INIT_PREFIX
70 # define matchpathcon_init_prefix(a, p) /* empty */
73 /* Initial number of entries in each hash table entry's table of inodes. */
74 #define INITIAL_HASH_MODULE 100
76 /* Initial number of entries in the inode hash table. */
77 #define INITIAL_ENTRY_TAB_SIZE 70
79 /* Number of bytes of a file to copy at a time. */
80 #define READ_SIZE (32 * 1024)
82 static bool change_timestamps (struct stat const *from_sb, char const *to);
83 static bool change_attributes (char const *name);
84 static bool copy_file (const char *from, const char *to,
85 const struct cp_options *x);
86 static bool install_file_in_file_parents (char const *from, char *to,
87 struct cp_options *x);
88 static bool install_file_in_dir (const char *from, const char *to_dir,
89 const struct cp_options *x);
90 static bool install_file_in_file (const char *from, const char *to,
91 const struct cp_options *x);
92 static void get_ids (void);
93 static void strip (char const *name);
94 static void announce_mkdir (char const *dir, void *options);
95 static int make_ancestor (char const *dir, char const *component,
97 void usage (int status);
99 /* The user name that will own the files, or NULL to make the owner
100 the current user ID. */
101 static char *owner_name;
103 /* The user ID corresponding to `owner_name'. */
104 static uid_t owner_id;
106 /* The group name that will own the files, or NULL to make the group
107 the current group ID. */
108 static char *group_name;
110 /* The group ID corresponding to `group_name'. */
111 static gid_t group_id;
113 #define DEFAULT_MODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
115 /* The file mode bits to which non-directory files will be set. The umask has
117 static mode_t mode = DEFAULT_MODE;
119 /* Similar, but for directories. */
120 static mode_t dir_mode = DEFAULT_MODE;
122 /* The file mode bits that the user cares about. This should be a
123 superset of DIR_MODE and a subset of CHMOD_MODE_BITS. This matters
124 for directories, since otherwise directories may keep their S_ISUID
126 static mode_t dir_mode_bits = CHMOD_MODE_BITS;
128 /* If true, strip executable files after copying them. */
129 static bool strip_files;
131 /* If true, install a directory instead of a regular file. */
134 /* For long options that have no equivalent short option, use a
135 non-character as a pseudo short option, starting with CHAR_MAX + 1. */
138 PRESERVE_CONTEXT_OPTION = CHAR_MAX + 1
141 static struct option const long_options[] =
143 {"backup", optional_argument, NULL, 'b'},
144 {GETOPT_SELINUX_CONTEXT_OPTION_DECL},
145 {"directory", no_argument, NULL, 'd'},
146 {"group", required_argument, NULL, 'g'},
147 {"mode", required_argument, NULL, 'm'},
148 {"no-target-directory", no_argument, NULL, 'T'},
149 {"owner", required_argument, NULL, 'o'},
150 {"preserve-timestamps", no_argument, NULL, 'p'},
151 {"preserve-context", no_argument, NULL, PRESERVE_CONTEXT_OPTION},
152 /* Continue silent support for --preserve_context until Jan 2008. FIXME-obs
153 After that, FIXME-obs: warn in, say, late 2008, and disable altogether
154 a year or two later. */
155 {"preserve_context", no_argument, NULL, PRESERVE_CONTEXT_OPTION},
156 {"strip", no_argument, NULL, 's'},
157 {"suffix", required_argument, NULL, 'S'},
158 {"target-directory", required_argument, NULL, 't'},
159 {"verbose", no_argument, NULL, 'v'},
160 {GETOPT_HELP_OPTION_DECL},
161 {GETOPT_VERSION_OPTION_DECL},
166 cp_option_init (struct cp_options *x)
168 cp_options_default (x);
169 x->copy_as_regular = true;
170 x->dereference = DEREF_ALWAYS;
171 x->unlink_dest_before_opening = true;
172 x->unlink_dest_after_failed_open = false;
173 x->hard_link = false;
174 x->interactive = I_UNSPECIFIED;
175 x->move_mode = false;
176 x->one_file_system = false;
177 x->preserve_ownership = false;
178 x->preserve_links = false;
179 x->preserve_mode = false;
180 x->preserve_timestamps = false;
181 x->require_preserve = false;
182 x->require_preserve_context = false;
183 x->recursive = false;
184 x->sparse_mode = SPARSE_AUTO;
185 x->symbolic_link = false;
186 x->backup_type = no_backups;
188 /* Create destination files initially writable so we can run strip on them.
189 Although GNU strip works fine on read-only files, some others
192 x->mode = S_IRUSR | S_IWUSR;
193 x->stdin_tty = false;
195 x->open_dangling_dest_symlink = false;
197 x->preserve_security_context = false;
203 #ifdef ENABLE_MATCHPATHCON
204 /* Modify file context to match the specified policy.
205 If an error occurs the file will remain with the default directory
208 setdefaultfilecon (char const *file)
211 security_context_t scontext = NULL;
212 static bool first_call = true;
214 if (selinux_enabled != 1)
216 /* Indicate no context found. */
219 if (lstat (file, &st) != 0)
222 if (first_call && IS_ABSOLUTE_FILE_NAME (file))
224 /* Calling matchpathcon_init_prefix (NULL, "/first_component/")
225 is an optimization to minimize the expense of the following
226 matchpathcon call. Do it only once, just before the first
227 matchpathcon call. We *could* call matchpathcon_fini after
228 the final matchpathcon call, but that's not necessary, since
229 by then we're about to exit, and besides, the buffers it
230 would free are still reachable. */
232 char const *p = file + 1;
236 /* Record final leading slash, for when FILE starts with two or more. */
246 while (*p && !ISSLASH (*p));
248 prefix = malloc (p - p0 + 2);
251 stpcpy (stpncpy (prefix, p0, p - p0), "/");
252 matchpathcon_init_prefix (NULL, prefix);
259 /* If there's an error determining the context, or it has none,
260 return to allow default context */
261 if ((matchpathcon (file, st.st_mode, &scontext) != 0) ||
262 STREQ (scontext, "<<none>>"))
264 if (scontext != NULL)
269 if (lsetfilecon (file, scontext) < 0 && errno != ENOTSUP)
271 _("warning: %s: failed to change context to %s"),
272 quotearg_colon (file), scontext);
279 setdefaultfilecon (char const *file)
285 /* FILE is the last operand of this command. Return true if FILE is a
286 directory. But report an error there is a problem accessing FILE,
287 or if FILE does not exist but would have to refer to an existing
288 directory if it referred to anything at all. */
291 target_directory_operand (char const *file)
293 char const *b = last_component (file);
294 size_t blen = strlen (b);
295 bool looks_like_a_dir = (blen == 0 || ISSLASH (b[blen - 1]));
297 int err = (stat (file, &st) == 0 ? 0 : errno);
298 bool is_a_dir = !err && S_ISDIR (st.st_mode);
299 if (err && err != ENOENT)
300 error (EXIT_FAILURE, err, _("accessing %s"), quote (file));
301 if (is_a_dir < looks_like_a_dir)
302 error (EXIT_FAILURE, err, _("target %s is not a directory"), quote (file));
306 /* Process a command-line file name, for the -d option. */
308 process_dir (char *dir, struct savewd *wd, void *options)
310 return (make_dir_parents (dir, wd,
311 make_ancestor, options,
312 dir_mode, announce_mkdir,
313 dir_mode_bits, owner_id, group_id, false)
319 main (int argc, char **argv)
322 int exit_status = EXIT_SUCCESS;
323 const char *specified_mode = NULL;
324 bool make_backups = false;
325 char *backup_suffix_string;
326 char *version_control_string = NULL;
327 bool mkdir_and_install = false;
329 char const *target_directory = NULL;
330 bool no_target_directory = false;
333 security_context_t scontext = NULL;
334 /* set iff kernel has extra selinux system calls */
335 selinux_enabled = (0 < is_selinux_enabled ());
337 initialize_main (&argc, &argv);
338 set_program_name (argv[0]);
339 setlocale (LC_ALL, "");
340 bindtextdomain (PACKAGE, LOCALEDIR);
341 textdomain (PACKAGE);
343 atexit (close_stdin);
353 /* FIXME: consider not calling getenv for SIMPLE_BACKUP_SUFFIX unless
354 we'll actually use backup_suffix_string. */
355 backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
357 while ((optc = getopt_long (argc, argv, "bcsDdg:m:o:pt:TvS:Z:", long_options,
365 version_control_string = optarg;
372 /* System V fork+wait does not work if SIGCHLD is ignored. */
373 signal (SIGCHLD, SIG_DFL);
380 mkdir_and_install = true;
389 specified_mode = optarg;
395 x.preserve_timestamps = true;
399 backup_suffix_string = optarg;
402 if (target_directory)
403 error (EXIT_FAILURE, 0,
404 _("multiple target directories specified"));
408 if (stat (optarg, &st) != 0)
409 error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg));
410 if (! S_ISDIR (st.st_mode))
411 error (EXIT_FAILURE, 0, _("target %s is not a directory"),
414 target_directory = optarg;
417 no_target_directory = true;
420 case PRESERVE_CONTEXT_OPTION:
421 if ( ! selinux_enabled)
423 error (0, 0, _("WARNING: ignoring --preserve-context; "
424 "this kernel is not SELinux-enabled"));
427 x.preserve_security_context = true;
428 use_default_selinux_context = false;
431 if ( ! selinux_enabled)
433 error (0, 0, _("WARNING: ignoring --context (-Z); "
434 "this kernel is not SELinux-enabled"));
438 use_default_selinux_context = false;
440 case_GETOPT_HELP_CHAR;
441 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
443 usage (EXIT_FAILURE);
447 /* Check for invalid combinations of arguments. */
448 if (dir_arg & strip_files)
449 error (EXIT_FAILURE, 0,
450 _("the strip option may not be used when installing a directory"));
451 if (dir_arg && target_directory)
452 error (EXIT_FAILURE, 0,
453 _("target directory not allowed when installing a directory"));
455 if (x.preserve_security_context && scontext != NULL)
456 error (EXIT_FAILURE, 0,
457 _("cannot force target context to %s and preserve it"),
460 if (backup_suffix_string)
461 simple_backup_suffix = xstrdup (backup_suffix_string);
463 x.backup_type = (make_backups
464 ? xget_version (_("backup type"),
465 version_control_string)
468 if (scontext && setfscreatecon (scontext) < 0)
469 error (EXIT_FAILURE, errno,
470 _("failed to set default file creation context to %s"),
473 n_files = argc - optind;
474 file = argv + optind;
476 if (n_files <= ! (dir_arg || target_directory))
479 error (0, 0, _("missing file operand"));
481 error (0, 0, _("missing destination file operand after %s"),
483 usage (EXIT_FAILURE);
486 if (no_target_directory)
488 if (target_directory)
489 error (EXIT_FAILURE, 0,
490 _("cannot combine --target-directory (-t) "
491 "and --no-target-directory (-T)"));
494 error (0, 0, _("extra operand %s"), quote (file[2]));
495 usage (EXIT_FAILURE);
498 else if (! (dir_arg || target_directory))
500 if (2 <= n_files && target_directory_operand (file[n_files - 1]))
501 target_directory = file[--n_files];
502 else if (2 < n_files)
503 error (EXIT_FAILURE, 0, _("target %s is not a directory"),
504 quote (file[n_files - 1]));
509 struct mode_change *change = mode_compile (specified_mode);
511 error (EXIT_FAILURE, 0, _("invalid mode %s"), quote (specified_mode));
512 mode = mode_adjust (0, false, 0, change, NULL);
513 dir_mode = mode_adjust (0, true, 0, change, &dir_mode_bits);
520 exit_status = savewd_process_files (n_files, file, process_dir, &x);
523 /* FIXME: it's a little gross that this initialization is
524 required by copy.c::copy. */
527 if (!target_directory)
529 if (! (mkdir_and_install
530 ? install_file_in_file_parents (file[0], file[1], &x)
531 : install_file_in_file (file[0], file[1], &x)))
532 exit_status = EXIT_FAILURE;
538 for (i = 0; i < n_files; i++)
539 if (! install_file_in_dir (file[i], target_directory, &x))
540 exit_status = EXIT_FAILURE;
547 /* Copy file FROM onto file TO, creating any missing parent directories of TO.
548 Return true if successful. */
551 install_file_in_file_parents (char const *from, char *to,
552 struct cp_options *x)
554 bool save_working_directory =
555 ! (IS_ABSOLUTE_FILE_NAME (from) && IS_ABSOLUTE_FILE_NAME (to));
556 int status = EXIT_SUCCESS;
560 if (! save_working_directory)
563 if (mkancesdirs (to, &wd, make_ancestor, x) == -1)
565 error (0, errno, _("cannot create directory %s"), to);
566 status = EXIT_FAILURE;
569 if (save_working_directory)
571 int restore_result = savewd_restore (&wd, status);
572 int restore_errno = errno;
574 if (EXIT_SUCCESS < restore_result)
576 if (restore_result < 0 && status == EXIT_SUCCESS)
578 error (0, restore_errno, _("cannot create directory %s"), to);
583 return (status == EXIT_SUCCESS && install_file_in_file (from, to, x));
586 /* Copy file FROM onto file TO and give TO the appropriate
588 Return true if successful. */
591 install_file_in_file (const char *from, const char *to,
592 const struct cp_options *x)
595 if (x->preserve_timestamps && stat (from, &from_sb) != 0)
597 error (0, errno, _("cannot stat %s"), quote (from));
600 if (! copy_file (from, to, x))
604 if (x->preserve_timestamps && (strip_files || ! S_ISREG (from_sb.st_mode))
605 && ! change_timestamps (&from_sb, to))
607 return change_attributes (to);
610 /* Copy file FROM into directory TO_DIR, keeping its same name,
611 and give the copy the appropriate attributes.
612 Return true if successful. */
615 install_file_in_dir (const char *from, const char *to_dir,
616 const struct cp_options *x)
618 const char *from_base = last_component (from);
619 char *to = file_name_concat (to_dir, from_base, NULL);
620 bool ret = install_file_in_file (from, to, x);
625 /* Copy file FROM onto file TO, creating TO if necessary.
626 Return true if successful. */
629 copy_file (const char *from, const char *to, const struct cp_options *x)
633 /* Allow installing from non-regular files like /dev/null.
634 Charles Karney reported that some Sun version of install allows that
635 and that sendmail's installation process relies on the behavior.
636 However, since !x->recursive, the call to "copy" will fail if FROM
639 return copy (from, to, false, x, ©_into_self, NULL);
642 /* Set the attributes of file or directory NAME.
643 Return true if successful. */
646 change_attributes (char const *name)
649 /* chown must precede chmod because on some systems,
650 chown clears the set[ug]id bits for non-superusers,
651 resulting in incorrect permissions.
652 On System V, users can give away files with chown and then not
653 be able to chmod them. So don't give files away.
655 We don't normally ignore errors from chown because the idea of
656 the install command is that the file is supposed to end up with
657 precisely the attributes that the user specified (or defaulted).
658 If the file doesn't end up with the group they asked for, they'll
661 if (! (owner_id == (uid_t) -1 && group_id == (gid_t) -1)
662 && lchown (name, owner_id, group_id) != 0)
663 error (0, errno, _("cannot change ownership of %s"), quote (name));
664 else if (chmod (name, mode) != 0)
665 error (0, errno, _("cannot change permissions of %s"), quote (name));
669 if (use_default_selinux_context)
670 setdefaultfilecon (name);
675 /* Set the timestamps of file TO to match those of file FROM.
676 Return true if successful. */
679 change_timestamps (struct stat const *from_sb, char const *to)
681 struct timespec timespec[2];
682 timespec[0] = get_stat_atime (from_sb);
683 timespec[1] = get_stat_mtime (from_sb);
685 if (utimens (to, timespec))
687 error (0, errno, _("cannot set time stamps for %s"), quote (to));
693 /* Strip the symbol table from the file NAME.
694 We could dig the magic number out of the file first to
695 determine whether to strip it, but the header files and
696 magic numbers vary so much from system to system that making
697 it portable would be very difficult. Not worth the effort. */
700 strip (char const *name)
708 error (EXIT_FAILURE, errno, _("fork system call failed"));
711 execlp ("strip", "strip", name, NULL);
712 error (EXIT_FAILURE, errno, _("cannot run strip"));
714 default: /* Parent. */
715 if (waitpid (pid, &status, 0) < 0)
716 error (EXIT_FAILURE, errno, _("waiting for strip"));
717 else if (! WIFEXITED (status) || WEXITSTATUS (status))
718 error (EXIT_FAILURE, 0, _("strip process terminated abnormally"));
723 /* Initialize the user and group ownership of the files to install. */
733 pw = getpwnam (owner_name);
736 unsigned long int tmp;
737 if (xstrtoul (owner_name, NULL, 0, &tmp, NULL) != LONGINT_OK
739 error (EXIT_FAILURE, 0, _("invalid user %s"), quote (owner_name));
743 owner_id = pw->pw_uid;
747 owner_id = (uid_t) -1;
751 gr = getgrnam (group_name);
754 unsigned long int tmp;
755 if (xstrtoul (group_name, NULL, 0, &tmp, NULL) != LONGINT_OK
757 error (EXIT_FAILURE, 0, _("invalid group %s"), quote (group_name));
761 group_id = gr->gr_gid;
765 group_id = (gid_t) -1;
768 /* Report that directory DIR was made, if OPTIONS requests this. */
770 announce_mkdir (char const *dir, void *options)
772 struct cp_options const *x = options;
774 prog_fprintf (stdout, _("creating directory %s"), quote (dir));
777 /* Make ancestor directory DIR, whose last file name component is
778 COMPONENT, with options OPTIONS. Assume the working directory is
779 COMPONENT's parent. */
781 make_ancestor (char const *dir, char const *component, void *options)
783 int r = mkdir (component, DEFAULT_MODE);
785 announce_mkdir (dir, options);
792 if (status != EXIT_SUCCESS)
793 fprintf (stderr, _("Try `%s --help' for more information.\n"),
798 Usage: %s [OPTION]... [-T] SOURCE DEST\n\
799 or: %s [OPTION]... SOURCE... DIRECTORY\n\
800 or: %s [OPTION]... -t DIRECTORY SOURCE...\n\
801 or: %s [OPTION]... -d DIRECTORY...\n\
803 program_name, program_name, program_name, program_name);
805 In the first three forms, copy SOURCE to DEST or multiple SOURCE(s) to\n\
806 the existing DIRECTORY, while setting permission modes and owner/group.\n\
807 In the 4th form, create all components of the given DIRECTORY(ies).\n\
811 Mandatory arguments to long options are mandatory for short options too.\n\
814 --backup[=CONTROL] make a backup of each existing destination file\n\
815 -b like --backup but does not accept an argument\n\
817 -d, --directory treat all arguments as directory names; create all\n\
818 components of the specified directories\n\
821 -D create all leading components of DEST except the last,\n\
822 then copy SOURCE to DEST\n\
823 -g, --group=GROUP set group ownership, instead of process' current group\n\
824 -m, --mode=MODE set permission mode (as in chmod), instead of rwxr-xr-x\n\
825 -o, --owner=OWNER set ownership (super-user only)\n\
828 -p, --preserve-timestamps apply access/modification times of SOURCE files\n\
829 to corresponding destination files\n\
830 -s, --strip strip symbol tables\n\
831 -S, --suffix=SUFFIX override the usual backup suffix\n\
832 -t, --target-directory=DIRECTORY copy all SOURCE arguments into DIRECTORY\n\
833 -T, --no-target-directory treat DEST as a normal file\n\
834 -v, --verbose print the name of each directory as it is created\n\
837 --preserve-context preserve SELinux security context\n\
838 -Z, --context=CONTEXT set SELinux security context of files and directories\n\
841 fputs (HELP_OPTION_DESCRIPTION, stdout);
842 fputs (VERSION_OPTION_DESCRIPTION, stdout);
845 The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
846 The version control method may be selected via the --backup option or through\n\
847 the VERSION_CONTROL environment variable. Here are the values:\n\
851 none, off never make backups (even if --backup is given)\n\
852 numbered, t make numbered backups\n\
853 existing, nil numbered if numbered backups exist, simple otherwise\n\
854 simple, never always make simple backups\n\
856 emit_bug_reporting_address ();