maint: rename variables for clarity...
[platform/upstream/coreutils.git] / src / install.c
1 /* install - copy files and set attributes
2    Copyright (C) 1989-1991, 1995-2011 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 #include <sys/wait.h>
28
29 #include "system.h"
30 #include "backupfile.h"
31 #include "error.h"
32 #include "cp-hash.h"
33 #include "copy.h"
34 #include "filenamecat.h"
35 #include "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"
46
47 /* The official name of this program (e.g., no `g' prefix).  */
48 #define PROGRAM_NAME "install"
49
50 #define AUTHORS proper_name ("David MacKenzie")
51
52 static int selinux_enabled = 0;
53 static bool use_default_selinux_context = true;
54
55 #if ! HAVE_ENDGRENT
56 # define endgrent() ((void) 0)
57 #endif
58
59 #if ! HAVE_ENDPWENT
60 # define endpwent() ((void) 0)
61 #endif
62
63 #if ! HAVE_LCHOWN
64 # define lchown(name, uid, gid) chown (name, uid, gid)
65 #endif
66
67 #if ! HAVE_MATCHPATHCON_INIT_PREFIX
68 # define matchpathcon_init_prefix(a, p) /* empty */
69 #endif
70
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);
87
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;
91
92 /* The user ID corresponding to `owner_name'. */
93 static uid_t owner_id;
94
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;
98
99 /* The group ID corresponding to `group_name'. */
100 static gid_t group_id;
101
102 #define DEFAULT_MODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
103
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;
107
108 /* Similar, but for directories.  */
109 static mode_t dir_mode = DEFAULT_MODE;
110
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;
116
117 /* Compare files before installing (-C) */
118 static bool copy_only_if_needed;
119
120 /* If true, strip executable files after copying them. */
121 static bool strip_files;
122
123 /* If true, install a directory instead of a regular file. */
124 static bool dir_arg;
125
126 /* Program used to strip binaries, "strip" is default */
127 static char const *strip_program = "strip";
128
129 /* For long options that have no equivalent short option, use a
130    non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
131 enum
132 {
133   PRESERVE_CONTEXT_OPTION = CHAR_MAX + 1,
134   PRESERVE_CONTEXT_OPTION_DEPRECATED,
135   STRIP_PROGRAM_OPTION
136 };
137
138 static struct option const long_options[] =
139 {
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}
161 };
162
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)
167 {
168   enum { CMP_BLOCK_SIZE = 4096 };
169   static char a_buff[CMP_BLOCK_SIZE];
170   static char b_buff[CMP_BLOCK_SIZE];
171
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;
176
177     if (memcmp (a_buff, b_buff, size) != 0)
178       return false;
179   }
180
181   return size == 0;
182 }
183
184 /* Return true for mode with non-permission bits. */
185 static bool
186 extra_mode (mode_t input)
187 {
188   mode_t mask = S_IRWXUGO | S_IFMT;
189   return !! (input & ~ mask);
190 }
191
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)
196 {
197   struct stat src_sb, dest_sb;
198   int src_fd, dest_fd;
199   bool content_match;
200
201   if (extra_mode (mode))
202     return true;
203
204   /* compare files using stat */
205   if (lstat (src_name, &src_sb) != 0)
206     return true;
207
208   if (lstat (dest_name, &dest_sb) != 0)
209     return true;
210
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;
214
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;
220
221   /* compare SELinux context if preserving */
222   if (selinux_enabled && x->preserve_security_context)
223     {
224       security_context_t file_scontext = NULL;
225       security_context_t to_scontext = NULL;
226       bool scontext_match;
227
228       if (getfilecon (src_name, &file_scontext) == -1)
229         return true;
230
231       if (getfilecon (dest_name, &to_scontext) == -1)
232         {
233           freecon (file_scontext);
234           return true;
235         }
236
237       scontext_match = STREQ (file_scontext, to_scontext);
238
239       freecon (file_scontext);
240       freecon (to_scontext);
241       if (!scontext_match)
242         return true;
243     }
244
245   /* compare files content */
246   src_fd = open (src_name, O_RDONLY | O_BINARY);
247   if (src_fd < 0)
248     return true;
249
250   dest_fd = open (dest_name, O_RDONLY | O_BINARY);
251   if (dest_fd < 0)
252     {
253       close (src_fd);
254       return true;
255     }
256
257   content_match = have_same_content (src_fd, dest_fd);
258
259   close (src_fd);
260   close (dest_fd);
261   return !content_match;
262 }
263
264 static void
265 cp_option_init (struct cp_options *x)
266 {
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;
290
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;
297
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;
305 }
306
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)
313 {
314   struct stat st;
315   security_context_t scontext = NULL;
316   static bool first_call = true;
317
318   if (selinux_enabled != 1)
319     {
320       /* Indicate no context found. */
321       return;
322     }
323   if (lstat (file, &st) != 0)
324     return;
325
326   if (first_call && IS_ABSOLUTE_FILE_NAME (file))
327     {
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;
339
340       /* Record final leading slash, for when FILE starts with two or more.  */
341       p0 = p - 1;
342
343       if (*p)
344         {
345           char *prefix;
346           do
347             {
348               ++p;
349             }
350           while (*p && !ISSLASH (*p));
351
352           prefix = malloc (p - p0 + 2);
353           if (prefix)
354             {
355               stpcpy (stpncpy (prefix, p0, p - p0), "/");
356               matchpathcon_init_prefix (NULL, prefix);
357               free (prefix);
358             }
359         }
360     }
361   first_call = false;
362
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>>"))
367     {
368       if (scontext != NULL)
369         freecon (scontext);
370       return;
371     }
372
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);
377
378   freecon (scontext);
379   return;
380 }
381 #else
382 static void
383 setdefaultfilecon (char const *file)
384 {
385   (void) file;
386 }
387 #endif
388
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.  */
393
394 static bool
395 target_directory_operand (char const *file)
396 {
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;
408 }
409
410 /* Process a command-line file name, for the -d option.  */
411 static int
412 process_dir (char *dir, struct savewd *wd, void *options)
413 {
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);
420 }
421
422 int
423 main (int argc, char **argv)
424 {
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 ());
441
442   initialize_main (&argc, &argv);
443   set_program_name (argv[0]);
444   setlocale (LC_ALL, "");
445   bindtextdomain (PACKAGE, LOCALEDIR);
446   textdomain (PACKAGE);
447
448   atexit (close_stdin);
449
450   cp_option_init (&x);
451
452   owner_name = NULL;
453   group_name = NULL;
454   strip_files = false;
455   dir_arg = false;
456   umask (0);
457
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");
461
462   while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pt:TvS:Z:", long_options,
463                               NULL)) != -1)
464     {
465       switch (optc)
466         {
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
518             {
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));
525             }
526           target_directory = optarg;
527           break;
528         case 'T':
529           no_target_directory = true;
530           break;
531
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)
538             {
539               error (0, 0, _("WARNING: ignoring --preserve-context; "
540                              "this kernel is not SELinux-enabled"));
541               break;
542             }
543           x.preserve_security_context = true;
544           use_default_selinux_context = false;
545           break;
546         case 'Z':
547           if ( ! selinux_enabled)
548             {
549               error (0, 0, _("WARNING: ignoring --context (-Z); "
550                              "this kernel is not SELinux-enabled"));
551               break;
552             }
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);
560         }
561     }
562
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"));
570
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));
575
576   if (backup_suffix_string)
577     simple_backup_suffix = xstrdup (backup_suffix_string);
578
579   x.backup_type = (make_backups
580                    ? xget_version (_("backup type"),
581                                    version_control_string)
582                    : no_backups);
583
584   if (scontext && setfscreatecon (scontext) < 0)
585     error (EXIT_FAILURE, errno,
586            _("failed to set default file creation context to %s"),
587            quote (scontext));
588
589   n_files = argc - optind;
590   file = argv + optind;
591
592   if (n_files <= ! (dir_arg || target_directory))
593     {
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);
600     }
601
602   if (no_target_directory)
603     {
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)
609         {
610           error (0, 0, _("extra operand %s"), quote (file[2]));
611           usage (EXIT_FAILURE);
612         }
613     }
614   else if (! (dir_arg || target_directory))
615     {
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]));
621     }
622
623   if (specified_mode)
624     {
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);
631     }
632
633   if (strip_program_specified && !strip_files)
634     error (0, 0, _("WARNING: ignoring --strip-program option as -s option was "
635                    "not specified"));
636
637   if (copy_only_if_needed && x.preserve_timestamps)
638     {
639       error (0, 0, _("options --compare (-C) and --preserve-timestamps are "
640                      "mutually exclusive"));
641       usage (EXIT_FAILURE);
642     }
643
644   if (copy_only_if_needed && strip_files)
645     {
646       error (0, 0, _("options --compare (-C) and --strip are mutually "
647                      "exclusive"));
648       usage (EXIT_FAILURE);
649     }
650
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"));
654
655   get_ids ();
656
657   if (dir_arg)
658     exit_status = savewd_process_files (n_files, file, process_dir, &x);
659   else
660     {
661       /* FIXME: it's a little gross that this initialization is
662          required by copy.c::copy. */
663       hash_init ();
664
665       if (!target_directory)
666         {
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;
671         }
672       else
673         {
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;
679         }
680     }
681
682   exit (exit_status);
683 }
684
685 /* Copy file FROM onto file TO, creating any missing parent directories of TO.
686    Return true if successful.  */
687
688 static bool
689 install_file_in_file_parents (char const *from, char *to,
690                               struct cp_options *x)
691 {
692   bool save_working_directory =
693     ! (IS_ABSOLUTE_FILE_NAME (from) && IS_ABSOLUTE_FILE_NAME (to));
694   int status = EXIT_SUCCESS;
695
696   struct savewd wd;
697   savewd_init (&wd);
698   if (! save_working_directory)
699     savewd_finish (&wd);
700
701   if (mkancesdirs (to, &wd, make_ancestor, x) == -1)
702     {
703       error (0, errno, _("cannot create directory %s"), to);
704       status = EXIT_FAILURE;
705     }
706
707   if (save_working_directory)
708     {
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)
715         {
716           error (0, restore_errno, _("cannot create directory %s"), to);
717           return false;
718         }
719     }
720
721   return (status == EXIT_SUCCESS && install_file_in_file (from, to, x));
722 }
723
724 /* Copy file FROM onto file TO and give TO the appropriate
725    attributes.
726    Return true if successful.  */
727
728 static bool
729 install_file_in_file (const char *from, const char *to,
730                       const struct cp_options *x)
731 {
732   struct stat from_sb;
733   if (x->preserve_timestamps && stat (from, &from_sb) != 0)
734     {
735       error (0, errno, _("cannot stat %s"), quote (from));
736       return false;
737     }
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);
746 }
747
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.  */
751
752 static bool
753 install_file_in_dir (const char *from, const char *to_dir,
754                      const struct cp_options *x)
755 {
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;
761 }
762
763 /* Copy file FROM onto file TO, creating TO if necessary.
764    Return true if successful.  */
765
766 static bool
767 copy_file (const char *from, const char *to, const struct cp_options *x)
768 {
769   bool copy_into_self;
770
771   if (copy_only_if_needed && !need_copy (from, to, x))
772     return true;
773
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.  */
779
780   return copy (from, to, false, x, &copy_into_self, NULL);
781 }
782
783 /* Set the attributes of file or directory NAME.
784    Return true if successful.  */
785
786 static bool
787 change_attributes (char const *name)
788 {
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.
795
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.  */
801
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;
809
810   if (use_default_selinux_context)
811     setdefaultfilecon (name);
812
813   return ok;
814 }
815
816 /* Set the timestamps of file DEST to match those of SRC_SB.
817    Return true if successful.  */
818
819 static bool
820 change_timestamps (struct stat const *src_sb, char const *dest)
821 {
822   struct timespec timespec[2];
823   timespec[0] = get_stat_atime (src_sb);
824   timespec[1] = get_stat_mtime (src_sb);
825
826   if (utimens (dest, timespec))
827     {
828       error (0, errno, _("cannot set time stamps for %s"), quote (dest));
829       return false;
830     }
831   return true;
832 }
833
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. */
839
840 static void
841 strip (char const *name)
842 {
843   int status;
844   pid_t pid = fork ();
845
846   switch (pid)
847     {
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;
861     }
862 }
863
864 /* Initialize the user and group ownership of the files to install. */
865
866 static void
867 get_ids (void)
868 {
869   struct passwd *pw;
870   struct group *gr;
871
872   if (owner_name)
873     {
874       pw = getpwnam (owner_name);
875       if (pw == NULL)
876         {
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;
882         }
883       else
884         owner_id = pw->pw_uid;
885       endpwent ();
886     }
887   else
888     owner_id = (uid_t) -1;
889
890   if (group_name)
891     {
892       gr = getgrnam (group_name);
893       if (gr == NULL)
894         {
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;
900         }
901       else
902         group_id = gr->gr_gid;
903       endgrent ();
904     }
905   else
906     group_id = (gid_t) -1;
907 }
908
909 /* Report that directory DIR was made, if OPTIONS requests this.  */
910 static void
911 announce_mkdir (char const *dir, void *options)
912 {
913   struct cp_options const *x = options;
914   if (x->verbose)
915     prog_fprintf (stdout, _("creating directory %s"), quote (dir));
916 }
917
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)
923 {
924   int r = mkdir (component, DEFAULT_MODE);
925   if (r == 0)
926     announce_mkdir (dir, options);
927   return r;
928 }
929
930 void
931 usage (int status)
932 {
933   if (status != EXIT_SUCCESS)
934     fprintf (stderr, _("Try `%s --help' for more information.\n"),
935              program_name);
936   else
937     {
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\
943 "),
944               program_name, program_name, program_name, program_name);
945       fputs (_("\
946 \n\
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\
951 \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\
955 \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\
989 \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 }