cp: add an option to only copy the file attributes
[platform/upstream/coreutils.git] / src / install.c
1 /* install - copy files and set attributes
2    Copyright (C) 1989-1991, 1995-2010 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
16
17 /* Written by David MacKenzie <djm@gnu.ai.mit.edu> */
18
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
28 #include "system.h"
29 #include "backupfile.h"
30 #include "error.h"
31 #include "cp-hash.h"
32 #include "copy.h"
33 #include "filenamecat.h"
34 #include "full-read.h"
35 #include "mkancesdirs.h"
36 #include "mkdir-p.h"
37 #include "modechange.h"
38 #include "prog-fprintf.h"
39 #include "quote.h"
40 #include "quotearg.h"
41 #include "savewd.h"
42 #include "stat-time.h"
43 #include "utimens.h"
44 #include "xstrtol.h"
45
46 /* The official name of this program (e.g., no `g' prefix).  */
47 #define PROGRAM_NAME "install"
48
49 #define AUTHORS proper_name ("David MacKenzie")
50
51 #include <sys/wait.h>
52
53 static int selinux_enabled = 0;
54 static bool use_default_selinux_context = true;
55
56 #if ! HAVE_ENDGRENT
57 # define endgrent() ((void) 0)
58 #endif
59
60 #if ! HAVE_ENDPWENT
61 # define endpwent() ((void) 0)
62 #endif
63
64 #if ! HAVE_LCHOWN
65 # define lchown(name, uid, gid) chown (name, uid, gid)
66 #endif
67
68 #if ! HAVE_MATCHPATHCON_INIT_PREFIX
69 # define matchpathcon_init_prefix(a, p) /* empty */
70 #endif
71
72 static bool change_timestamps (struct stat const *from_sb, char const *to);
73 static bool change_attributes (char const *name);
74 static bool copy_file (const char *from, const char *to,
75                        const struct cp_options *x);
76 static bool install_file_in_file_parents (char const *from, char *to,
77                                           struct cp_options *x);
78 static bool install_file_in_dir (const char *from, const char *to_dir,
79                                  const struct cp_options *x);
80 static bool install_file_in_file (const char *from, const char *to,
81                                   const struct cp_options *x);
82 static void get_ids (void);
83 static void strip (char const *name);
84 static void announce_mkdir (char const *dir, void *options);
85 static int make_ancestor (char const *dir, char const *component,
86                           void *options);
87 void usage (int status);
88
89 /* The user name that will own the files, or NULL to make the owner
90    the current user ID. */
91 static char *owner_name;
92
93 /* The user ID corresponding to `owner_name'. */
94 static uid_t owner_id;
95
96 /* The group name that will own the files, or NULL to make the group
97    the current group ID. */
98 static char *group_name;
99
100 /* The group ID corresponding to `group_name'. */
101 static gid_t group_id;
102
103 #define DEFAULT_MODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
104
105 /* The file mode bits to which non-directory files will be set.  The umask has
106    no effect. */
107 static mode_t mode = DEFAULT_MODE;
108
109 /* Similar, but for directories.  */
110 static mode_t dir_mode = DEFAULT_MODE;
111
112 /* The file mode bits that the user cares about.  This should be a
113    superset of DIR_MODE and a subset of CHMOD_MODE_BITS.  This matters
114    for directories, since otherwise directories may keep their S_ISUID
115    or S_ISGID bits.  */
116 static mode_t dir_mode_bits = CHMOD_MODE_BITS;
117
118 /* Compare files before installing (-C) */
119 static bool copy_only_if_needed;
120
121 /* If true, strip executable files after copying them. */
122 static bool strip_files;
123
124 /* If true, install a directory instead of a regular file. */
125 static bool dir_arg;
126
127 /* Program used to strip binaries, "strip" is default */
128 static char const *strip_program = "strip";
129
130 /* For long options that have no equivalent short option, use a
131    non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
132 enum
133 {
134   PRESERVE_CONTEXT_OPTION = CHAR_MAX + 1,
135   PRESERVE_CONTEXT_OPTION_DEPRECATED,
136   STRIP_PROGRAM_OPTION
137 };
138
139 static struct option const long_options[] =
140 {
141   {"backup", optional_argument, NULL, 'b'},
142   {"compare", no_argument, NULL, 'C'},
143   {GETOPT_SELINUX_CONTEXT_OPTION_DECL},
144   {"directory", no_argument, NULL, 'd'},
145   {"group", required_argument, NULL, 'g'},
146   {"mode", required_argument, NULL, 'm'},
147   {"no-target-directory", no_argument, NULL, 'T'},
148   {"owner", required_argument, NULL, 'o'},
149   {"preserve-timestamps", no_argument, NULL, 'p'},
150   {"preserve-context", no_argument, NULL, PRESERVE_CONTEXT_OPTION},
151   /* --preserve_context was silently supported until Apr 2009.
152      FIXME: disable altogether in a year or so.  */
153   {"preserve_context", no_argument, NULL, PRESERVE_CONTEXT_OPTION_DEPRECATED},
154   {"strip", no_argument, NULL, 's'},
155   {"strip-program", required_argument, NULL, STRIP_PROGRAM_OPTION},
156   {"suffix", required_argument, NULL, 'S'},
157   {"target-directory", required_argument, NULL, 't'},
158   {"verbose", no_argument, NULL, 'v'},
159   {GETOPT_HELP_OPTION_DECL},
160   {GETOPT_VERSION_OPTION_DECL},
161   {NULL, 0, NULL, 0}
162 };
163
164 /* Compare content of opened files using file descriptors A_FD and B_FD. Return
165    true if files are equal. */
166 static bool
167 have_same_content (int a_fd, int b_fd)
168 {
169   enum { CMP_BLOCK_SIZE = 4096 };
170   static char a_buff[CMP_BLOCK_SIZE];
171   static char b_buff[CMP_BLOCK_SIZE];
172
173   size_t size;
174   while (0 < (size = full_read (a_fd, a_buff, sizeof a_buff))) {
175     if (size != full_read (b_fd, b_buff, sizeof b_buff))
176       return false;
177
178     if (memcmp (a_buff, b_buff, size) != 0)
179       return false;
180   }
181
182   return size == 0;
183 }
184
185 /* Return true for mode with non-permission bits. */
186 static bool
187 extra_mode (mode_t input)
188 {
189   const mode_t mask = ~S_IRWXUGO & ~S_IFMT;
190   return !! (input & mask);
191 }
192
193 /* Return true if copy of file SRC_NAME to file DEST_NAME is necessary. */
194 static bool
195 need_copy (const char *src_name, const char *dest_name,
196            const struct cp_options *x)
197 {
198   struct stat src_sb, dest_sb;
199   int src_fd, dest_fd;
200   bool content_match;
201
202   if (extra_mode (mode))
203     return true;
204
205   /* compare files using stat */
206   if (lstat (src_name, &src_sb) != 0)
207     return true;
208
209   if (lstat (dest_name, &dest_sb) != 0)
210     return true;
211
212   if (!S_ISREG (src_sb.st_mode) || !S_ISREG (dest_sb.st_mode)
213       || extra_mode (src_sb.st_mode) || extra_mode (dest_sb.st_mode))
214     return true;
215
216   if (src_sb.st_size != dest_sb.st_size
217       || (dest_sb.st_mode & CHMOD_MODE_BITS) != mode
218       || dest_sb.st_uid != (owner_id == (uid_t) -1 ? getuid () : owner_id)
219       || dest_sb.st_gid != (group_id == (gid_t) -1 ? getgid () : group_id))
220     return true;
221
222   /* compare SELinux context if preserving */
223   if (selinux_enabled && x->preserve_security_context)
224     {
225       security_context_t file_scontext = NULL;
226       security_context_t to_scontext = NULL;
227       bool scontext_match;
228
229       if (getfilecon (src_name, &file_scontext) == -1)
230         return true;
231
232       if (getfilecon (dest_name, &to_scontext) == -1)
233         {
234           freecon (file_scontext);
235           return true;
236         }
237
238       scontext_match = STREQ (file_scontext, to_scontext);
239
240       freecon (file_scontext);
241       freecon (to_scontext);
242       if (!scontext_match)
243         return true;
244     }
245
246   /* compare files content */
247   src_fd = open (src_name, O_RDONLY | O_BINARY);
248   if (src_fd < 0)
249     return true;
250
251   dest_fd = open (dest_name, O_RDONLY | O_BINARY);
252   if (dest_fd < 0)
253     {
254       close (src_fd);
255       return true;
256     }
257
258   content_match = have_same_content (src_fd, dest_fd);
259
260   close (src_fd);
261   close (dest_fd);
262   return !content_match;
263 }
264
265 static void
266 cp_option_init (struct cp_options *x)
267 {
268   cp_options_default (x);
269   x->copy_as_regular = true;
270   x->reflink_mode = REFLINK_NEVER;
271   x->dereference = DEREF_ALWAYS;
272   x->unlink_dest_before_opening = true;
273   x->unlink_dest_after_failed_open = false;
274   x->hard_link = false;
275   x->interactive = I_UNSPECIFIED;
276   x->move_mode = false;
277   x->one_file_system = false;
278   x->preserve_ownership = false;
279   x->preserve_links = false;
280   x->preserve_mode = false;
281   x->preserve_timestamps = false;
282   x->reduce_diagnostics=false;
283   x->data_copy_required = true;
284   x->require_preserve = false;
285   x->require_preserve_context = false;
286   x->require_preserve_xattr = false;
287   x->recursive = false;
288   x->sparse_mode = SPARSE_AUTO;
289   x->symbolic_link = false;
290   x->backup_type = no_backups;
291
292   /* Create destination files initially writable so we can run strip on them.
293      Although GNU strip works fine on read-only files, some others
294      would fail.  */
295   x->set_mode = true;
296   x->mode = S_IRUSR | S_IWUSR;
297   x->stdin_tty = false;
298
299   x->open_dangling_dest_symlink = false;
300   x->update = false;
301   x->preserve_security_context = false;
302   x->preserve_xattr = false;
303   x->verbose = false;
304   x->dest_info = NULL;
305   x->src_info = NULL;
306 }
307
308 #ifdef ENABLE_MATCHPATHCON
309 /* Modify file context to match the specified policy.
310    If an error occurs the file will remain with the default directory
311    context.  */
312 static void
313 setdefaultfilecon (char const *file)
314 {
315   struct stat st;
316   security_context_t scontext = NULL;
317   static bool first_call = true;
318
319   if (selinux_enabled != 1)
320     {
321       /* Indicate no context found. */
322       return;
323     }
324   if (lstat (file, &st) != 0)
325     return;
326
327   if (first_call && IS_ABSOLUTE_FILE_NAME (file))
328     {
329       /* Calling matchpathcon_init_prefix (NULL, "/first_component/")
330          is an optimization to minimize the expense of the following
331          matchpathcon call.  Do it only once, just before the first
332          matchpathcon call.  We *could* call matchpathcon_fini after
333          the final matchpathcon call, but that's not necessary, since
334          by then we're about to exit, and besides, the buffers it
335          would free are still reachable.  */
336       char const *p0;
337       char const *p = file + 1;
338       while (ISSLASH (*p))
339         ++p;
340
341       /* Record final leading slash, for when FILE starts with two or more.  */
342       p0 = p - 1;
343
344       if (*p)
345         {
346           char *prefix;
347           do
348             {
349               ++p;
350             }
351           while (*p && !ISSLASH (*p));
352
353           prefix = malloc (p - p0 + 2);
354           if (prefix)
355             {
356               stpcpy (stpncpy (prefix, p0, p - p0), "/");
357               matchpathcon_init_prefix (NULL, prefix);
358               free (prefix);
359             }
360         }
361     }
362   first_call = false;
363
364   /* If there's an error determining the context, or it has none,
365      return to allow default context */
366   if ((matchpathcon (file, st.st_mode, &scontext) != 0) ||
367       STREQ (scontext, "<<none>>"))
368     {
369       if (scontext != NULL)
370         freecon (scontext);
371       return;
372     }
373
374   if (lsetfilecon (file, scontext) < 0 && errno != ENOTSUP)
375     error (0, errno,
376            _("warning: %s: failed to change context to %s"),
377            quotearg_colon (file), scontext);
378
379   freecon (scontext);
380   return;
381 }
382 #else
383 static void
384 setdefaultfilecon (char const *file)
385 {
386   (void) file;
387 }
388 #endif
389
390 /* FILE is the last operand of this command.  Return true if FILE is a
391    directory.  But report an error there is a problem accessing FILE,
392    or if FILE does not exist but would have to refer to an existing
393    directory if it referred to anything at all.  */
394
395 static bool
396 target_directory_operand (char const *file)
397 {
398   char const *b = last_component (file);
399   size_t blen = strlen (b);
400   bool looks_like_a_dir = (blen == 0 || ISSLASH (b[blen - 1]));
401   struct stat st;
402   int err = (stat (file, &st) == 0 ? 0 : errno);
403   bool is_a_dir = !err && S_ISDIR (st.st_mode);
404   if (err && err != ENOENT)
405     error (EXIT_FAILURE, err, _("accessing %s"), quote (file));
406   if (is_a_dir < looks_like_a_dir)
407     error (EXIT_FAILURE, err, _("target %s is not a directory"), quote (file));
408   return is_a_dir;
409 }
410
411 /* Process a command-line file name, for the -d option.  */
412 static int
413 process_dir (char *dir, struct savewd *wd, void *options)
414 {
415   return (make_dir_parents (dir, wd,
416                             make_ancestor, options,
417                             dir_mode, announce_mkdir,
418                             dir_mode_bits, owner_id, group_id, false)
419           ? EXIT_SUCCESS
420           : EXIT_FAILURE);
421 }
422
423 int
424 main (int argc, char **argv)
425 {
426   int optc;
427   int exit_status = EXIT_SUCCESS;
428   const char *specified_mode = NULL;
429   bool make_backups = false;
430   char *backup_suffix_string;
431   char *version_control_string = NULL;
432   bool mkdir_and_install = false;
433   struct cp_options x;
434   char const *target_directory = NULL;
435   bool no_target_directory = false;
436   int n_files;
437   char **file;
438   bool strip_program_specified = false;
439   security_context_t scontext = NULL;
440   /* set iff kernel has extra selinux system calls */
441   selinux_enabled = (0 < is_selinux_enabled ());
442
443   initialize_main (&argc, &argv);
444   set_program_name (argv[0]);
445   setlocale (LC_ALL, "");
446   bindtextdomain (PACKAGE, LOCALEDIR);
447   textdomain (PACKAGE);
448
449   atexit (close_stdin);
450
451   cp_option_init (&x);
452
453   owner_name = NULL;
454   group_name = NULL;
455   strip_files = false;
456   dir_arg = false;
457   umask (0);
458
459   /* FIXME: consider not calling getenv for SIMPLE_BACKUP_SUFFIX unless
460      we'll actually use backup_suffix_string.  */
461   backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
462
463   while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pt:TvS:Z:", long_options,
464                               NULL)) != -1)
465     {
466       switch (optc)
467         {
468         case 'b':
469           make_backups = true;
470           if (optarg)
471             version_control_string = optarg;
472           break;
473         case 'c':
474           break;
475         case 'C':
476           copy_only_if_needed = true;
477           break;
478         case 's':
479           strip_files = true;
480 #ifdef SIGCHLD
481           /* System V fork+wait does not work if SIGCHLD is ignored.  */
482           signal (SIGCHLD, SIG_DFL);
483 #endif
484           break;
485         case STRIP_PROGRAM_OPTION:
486           strip_program = xstrdup (optarg);
487           strip_program_specified = true;
488           break;
489         case 'd':
490           dir_arg = true;
491           break;
492         case 'D':
493           mkdir_and_install = true;
494           break;
495         case 'v':
496           x.verbose = true;
497           break;
498         case 'g':
499           group_name = optarg;
500           break;
501         case 'm':
502           specified_mode = optarg;
503           break;
504         case 'o':
505           owner_name = optarg;
506           break;
507         case 'p':
508           x.preserve_timestamps = true;
509           break;
510         case 'S':
511           make_backups = true;
512           backup_suffix_string = optarg;
513           break;
514         case 't':
515           if (target_directory)
516             error (EXIT_FAILURE, 0,
517                    _("multiple target directories specified"));
518           else
519             {
520               struct stat st;
521               if (stat (optarg, &st) != 0)
522                 error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg));
523               if (! S_ISDIR (st.st_mode))
524                 error (EXIT_FAILURE, 0, _("target %s is not a directory"),
525                        quote (optarg));
526             }
527           target_directory = optarg;
528           break;
529         case 'T':
530           no_target_directory = true;
531           break;
532
533         case PRESERVE_CONTEXT_OPTION_DEPRECATED:
534           error (0, 0, _("WARNING: --preserve_context is deprecated; "
535                          "use --preserve-context instead"));
536           /* fall through */
537         case PRESERVE_CONTEXT_OPTION:
538           if ( ! selinux_enabled)
539             {
540               error (0, 0, _("WARNING: ignoring --preserve-context; "
541                              "this kernel is not SELinux-enabled"));
542               break;
543             }
544           x.preserve_security_context = true;
545           use_default_selinux_context = false;
546           break;
547         case 'Z':
548           if ( ! selinux_enabled)
549             {
550               error (0, 0, _("WARNING: ignoring --context (-Z); "
551                              "this kernel is not SELinux-enabled"));
552               break;
553             }
554           scontext = optarg;
555           use_default_selinux_context = false;
556           break;
557         case_GETOPT_HELP_CHAR;
558         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
559         default:
560           usage (EXIT_FAILURE);
561         }
562     }
563
564   /* Check for invalid combinations of arguments. */
565   if (dir_arg && strip_files)
566     error (EXIT_FAILURE, 0,
567            _("the strip option may not be used when installing a directory"));
568   if (dir_arg && target_directory)
569     error (EXIT_FAILURE, 0,
570            _("target directory not allowed when installing a directory"));
571
572   if (x.preserve_security_context && scontext != NULL)
573     error (EXIT_FAILURE, 0,
574            _("cannot force target context to %s and preserve it"),
575            quote (scontext));
576
577   if (backup_suffix_string)
578     simple_backup_suffix = xstrdup (backup_suffix_string);
579
580   x.backup_type = (make_backups
581                    ? xget_version (_("backup type"),
582                                    version_control_string)
583                    : no_backups);
584
585   if (scontext && setfscreatecon (scontext) < 0)
586     error (EXIT_FAILURE, errno,
587            _("failed to set default file creation context to %s"),
588            quote (scontext));
589
590   n_files = argc - optind;
591   file = argv + optind;
592
593   if (n_files <= ! (dir_arg || target_directory))
594     {
595       if (n_files <= 0)
596         error (0, 0, _("missing file operand"));
597       else
598         error (0, 0, _("missing destination file operand after %s"),
599                quote (file[0]));
600       usage (EXIT_FAILURE);
601     }
602
603   if (no_target_directory)
604     {
605       if (target_directory)
606         error (EXIT_FAILURE, 0,
607                _("cannot combine --target-directory (-t) "
608                  "and --no-target-directory (-T)"));
609       if (2 < n_files)
610         {
611           error (0, 0, _("extra operand %s"), quote (file[2]));
612           usage (EXIT_FAILURE);
613         }
614     }
615   else if (! (dir_arg || target_directory))
616     {
617       if (2 <= n_files && target_directory_operand (file[n_files - 1]))
618         target_directory = file[--n_files];
619       else if (2 < n_files)
620         error (EXIT_FAILURE, 0, _("target %s is not a directory"),
621                quote (file[n_files - 1]));
622     }
623
624   if (specified_mode)
625     {
626       struct mode_change *change = mode_compile (specified_mode);
627       if (!change)
628         error (EXIT_FAILURE, 0, _("invalid mode %s"), quote (specified_mode));
629       mode = mode_adjust (0, false, 0, change, NULL);
630       dir_mode = mode_adjust (0, true, 0, change, &dir_mode_bits);
631       free (change);
632     }
633
634   if (strip_program_specified && !strip_files)
635     error (0, 0, _("WARNING: ignoring --strip-program option as -s option was "
636                    "not specified"));
637
638   if (copy_only_if_needed && x.preserve_timestamps)
639     {
640       error (0, 0, _("options --compare (-C) and --preserve-timestamps are "
641                      "mutually exclusive"));
642       usage (EXIT_FAILURE);
643     }
644
645   if (copy_only_if_needed && strip_files)
646     {
647       error (0, 0, _("options --compare (-C) and --strip are mutually "
648                      "exclusive"));
649       usage (EXIT_FAILURE);
650     }
651
652   if (copy_only_if_needed && extra_mode (mode))
653     error (0, 0, _("the --compare (-C) option is ignored when you"
654                    " specify a mode with non-permission bits"));
655
656   get_ids ();
657
658   if (dir_arg)
659     exit_status = savewd_process_files (n_files, file, process_dir, &x);
660   else
661     {
662       /* FIXME: it's a little gross that this initialization is
663          required by copy.c::copy. */
664       hash_init ();
665
666       if (!target_directory)
667         {
668           if (! (mkdir_and_install
669                  ? install_file_in_file_parents (file[0], file[1], &x)
670                  : install_file_in_file (file[0], file[1], &x)))
671             exit_status = EXIT_FAILURE;
672         }
673       else
674         {
675           int i;
676           dest_info_init (&x);
677           for (i = 0; i < n_files; i++)
678             if (! install_file_in_dir (file[i], target_directory, &x))
679               exit_status = EXIT_FAILURE;
680         }
681     }
682
683   exit (exit_status);
684 }
685
686 /* Copy file FROM onto file TO, creating any missing parent directories of TO.
687    Return true if successful.  */
688
689 static bool
690 install_file_in_file_parents (char const *from, char *to,
691                               struct cp_options *x)
692 {
693   bool save_working_directory =
694     ! (IS_ABSOLUTE_FILE_NAME (from) && IS_ABSOLUTE_FILE_NAME (to));
695   int status = EXIT_SUCCESS;
696
697   struct savewd wd;
698   savewd_init (&wd);
699   if (! save_working_directory)
700     savewd_finish (&wd);
701
702   if (mkancesdirs (to, &wd, make_ancestor, x) == -1)
703     {
704       error (0, errno, _("cannot create directory %s"), to);
705       status = EXIT_FAILURE;
706     }
707
708   if (save_working_directory)
709     {
710       int restore_result = savewd_restore (&wd, status);
711       int restore_errno = errno;
712       savewd_finish (&wd);
713       if (EXIT_SUCCESS < restore_result)
714         return false;
715       if (restore_result < 0 && status == EXIT_SUCCESS)
716         {
717           error (0, restore_errno, _("cannot create directory %s"), to);
718           return false;
719         }
720     }
721
722   return (status == EXIT_SUCCESS && install_file_in_file (from, to, x));
723 }
724
725 /* Copy file FROM onto file TO and give TO the appropriate
726    attributes.
727    Return true if successful.  */
728
729 static bool
730 install_file_in_file (const char *from, const char *to,
731                       const struct cp_options *x)
732 {
733   struct stat from_sb;
734   if (x->preserve_timestamps && stat (from, &from_sb) != 0)
735     {
736       error (0, errno, _("cannot stat %s"), quote (from));
737       return false;
738     }
739   if (! copy_file (from, to, x))
740     return false;
741   if (strip_files)
742     strip (to);
743   if (x->preserve_timestamps && (strip_files || ! S_ISREG (from_sb.st_mode))
744       && ! change_timestamps (&from_sb, to))
745     return false;
746   return change_attributes (to);
747 }
748
749 /* Copy file FROM into directory TO_DIR, keeping its same name,
750    and give the copy the appropriate attributes.
751    Return true if successful.  */
752
753 static bool
754 install_file_in_dir (const char *from, const char *to_dir,
755                      const struct cp_options *x)
756 {
757   const char *from_base = last_component (from);
758   char *to = file_name_concat (to_dir, from_base, NULL);
759   bool ret = install_file_in_file (from, to, x);
760   free (to);
761   return ret;
762 }
763
764 /* Copy file FROM onto file TO, creating TO if necessary.
765    Return true if successful.  */
766
767 static bool
768 copy_file (const char *from, const char *to, const struct cp_options *x)
769 {
770   bool copy_into_self;
771
772   if (copy_only_if_needed && !need_copy (from, to, x))
773     return true;
774
775   /* Allow installing from non-regular files like /dev/null.
776      Charles Karney reported that some Sun version of install allows that
777      and that sendmail's installation process relies on the behavior.
778      However, since !x->recursive, the call to "copy" will fail if FROM
779      is a directory.  */
780
781   return copy (from, to, false, x, &copy_into_self, NULL);
782 }
783
784 /* Set the attributes of file or directory NAME.
785    Return true if successful.  */
786
787 static bool
788 change_attributes (char const *name)
789 {
790   bool ok = false;
791   /* chown must precede chmod because on some systems,
792      chown clears the set[ug]id bits for non-superusers,
793      resulting in incorrect permissions.
794      On System V, users can give away files with chown and then not
795      be able to chmod them.  So don't give files away.
796
797      We don't normally ignore errors from chown because the idea of
798      the install command is that the file is supposed to end up with
799      precisely the attributes that the user specified (or defaulted).
800      If the file doesn't end up with the group they asked for, they'll
801      want to know.  */
802
803   if (! (owner_id == (uid_t) -1 && group_id == (gid_t) -1)
804       && lchown (name, owner_id, group_id) != 0)
805     error (0, errno, _("cannot change ownership of %s"), quote (name));
806   else if (chmod (name, mode) != 0)
807     error (0, errno, _("cannot change permissions of %s"), quote (name));
808   else
809     ok = true;
810
811   if (use_default_selinux_context)
812     setdefaultfilecon (name);
813
814   return ok;
815 }
816
817 /* Set the timestamps of file TO to match those of file FROM.
818    Return true if successful.  */
819
820 static bool
821 change_timestamps (struct stat const *from_sb, char const *to)
822 {
823   struct timespec timespec[2];
824   timespec[0] = get_stat_atime (from_sb);
825   timespec[1] = get_stat_mtime (from_sb);
826
827   if (utimens (to, timespec))
828     {
829       error (0, errno, _("cannot set time stamps for %s"), quote (to));
830       return false;
831     }
832   return true;
833 }
834
835 /* Strip the symbol table from the file NAME.
836    We could dig the magic number out of the file first to
837    determine whether to strip it, but the header files and
838    magic numbers vary so much from system to system that making
839    it portable would be very difficult.  Not worth the effort. */
840
841 static void
842 strip (char const *name)
843 {
844   int status;
845   pid_t pid = fork ();
846
847   switch (pid)
848     {
849     case -1:
850       error (EXIT_FAILURE, errno, _("fork system call failed"));
851       break;
852     case 0:                     /* Child. */
853       execlp (strip_program, strip_program, name, NULL);
854       error (EXIT_FAILURE, errno, _("cannot run %s"), strip_program);
855       break;
856     default:                    /* Parent. */
857       if (waitpid (pid, &status, 0) < 0)
858         error (EXIT_FAILURE, errno, _("waiting for strip"));
859       else if (! WIFEXITED (status) || WEXITSTATUS (status))
860         error (EXIT_FAILURE, 0, _("strip process terminated abnormally"));
861       break;
862     }
863 }
864
865 /* Initialize the user and group ownership of the files to install. */
866
867 static void
868 get_ids (void)
869 {
870   struct passwd *pw;
871   struct group *gr;
872
873   if (owner_name)
874     {
875       pw = getpwnam (owner_name);
876       if (pw == NULL)
877         {
878           unsigned long int tmp;
879           if (xstrtoul (owner_name, NULL, 0, &tmp, NULL) != LONGINT_OK
880               || UID_T_MAX < tmp)
881             error (EXIT_FAILURE, 0, _("invalid user %s"), quote (owner_name));
882           owner_id = tmp;
883         }
884       else
885         owner_id = pw->pw_uid;
886       endpwent ();
887     }
888   else
889     owner_id = (uid_t) -1;
890
891   if (group_name)
892     {
893       gr = getgrnam (group_name);
894       if (gr == NULL)
895         {
896           unsigned long int tmp;
897           if (xstrtoul (group_name, NULL, 0, &tmp, NULL) != LONGINT_OK
898               || GID_T_MAX < tmp)
899             error (EXIT_FAILURE, 0, _("invalid group %s"), quote (group_name));
900           group_id = tmp;
901         }
902       else
903         group_id = gr->gr_gid;
904       endgrent ();
905     }
906   else
907     group_id = (gid_t) -1;
908 }
909
910 /* Report that directory DIR was made, if OPTIONS requests this.  */
911 static void
912 announce_mkdir (char const *dir, void *options)
913 {
914   struct cp_options const *x = options;
915   if (x->verbose)
916     prog_fprintf (stdout, _("creating directory %s"), quote (dir));
917 }
918
919 /* Make ancestor directory DIR, whose last file name component is
920    COMPONENT, with options OPTIONS.  Assume the working directory is
921    COMPONENT's parent.  */
922 static int
923 make_ancestor (char const *dir, char const *component, void *options)
924 {
925   int r = mkdir (component, DEFAULT_MODE);
926   if (r == 0)
927     announce_mkdir (dir, options);
928   return r;
929 }
930
931 void
932 usage (int status)
933 {
934   if (status != EXIT_SUCCESS)
935     fprintf (stderr, _("Try `%s --help' for more information.\n"),
936              program_name);
937   else
938     {
939       printf (_("\
940 Usage: %s [OPTION]... [-T] SOURCE DEST\n\
941   or:  %s [OPTION]... SOURCE... DIRECTORY\n\
942   or:  %s [OPTION]... -t DIRECTORY SOURCE...\n\
943   or:  %s [OPTION]... -d DIRECTORY...\n\
944 "),
945               program_name, program_name, program_name, program_name);
946       fputs (_("\
947 \n\
948 This install program copies files (often just compiled) into destination\n\
949 locations you choose.  If you want to download and install a ready-to-use\n\
950 package on a GNU/Linux system, you should instead be using a package manager\n\
951 like yum(1) or apt-get(1).\n\
952 \n\
953 In the first three forms, copy SOURCE to DEST or multiple SOURCE(s) to\n\
954 the existing DIRECTORY, while setting permission modes and owner/group.\n\
955 In the 4th form, create all components of the given DIRECTORY(ies).\n\
956 \n\
957 "), stdout);
958       fputs (_("\
959 Mandatory arguments to long options are mandatory for short options too.\n\
960 "), stdout);
961       fputs (_("\
962       --backup[=CONTROL]  make a backup of each existing destination file\n\
963   -b                  like --backup but does not accept an argument\n\
964   -c                  (ignored)\n\
965   -C, --compare       compare each pair of source and destination files, and\n\
966                         in some cases, do not modify the destination at all\n\
967   -d, --directory     treat all arguments as directory names; create all\n\
968                         components of the specified directories\n\
969 "), stdout);
970       fputs (_("\
971   -D                  create all leading components of DEST except the last,\n\
972                         then copy SOURCE to DEST\n\
973   -g, --group=GROUP   set group ownership, instead of process' current group\n\
974   -m, --mode=MODE     set permission mode (as in chmod), instead of rwxr-xr-x\n\
975   -o, --owner=OWNER   set ownership (super-user only)\n\
976 "), stdout);
977       fputs (_("\
978   -p, --preserve-timestamps   apply access/modification times of SOURCE files\n\
979                         to corresponding destination files\n\
980   -s, --strip         strip symbol tables\n\
981       --strip-program=PROGRAM  program used to strip binaries\n\
982   -S, --suffix=SUFFIX  override the usual backup suffix\n\
983   -t, --target-directory=DIRECTORY  copy all SOURCE arguments into DIRECTORY\n\
984   -T, --no-target-directory  treat DEST as a normal file\n\
985   -v, --verbose       print the name of each directory as it is created\n\
986 "), stdout);
987       fputs (_("\
988       --preserve-context  preserve SELinux security context\n\
989   -Z, --context=CONTEXT  set SELinux security context of files and directories\n\
990 "), stdout);
991
992       fputs (HELP_OPTION_DESCRIPTION, stdout);
993       fputs (VERSION_OPTION_DESCRIPTION, stdout);
994       fputs (_("\
995 \n\
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\
999 \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 ();
1008     }
1009   exit (status);
1010 }