049d7ab4b0067528cb50ab8c79a7d0b5571c9b10
[platform/upstream/coreutils.git] / src / install.c
1 /* install - copy files and set attributes
2    Copyright (C) 89, 90, 91, 1995-2005 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 2, or (at your option)
7    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, write to the Free Software Foundation,
16    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
17
18 /* Written by David MacKenzie <djm@gnu.ai.mit.edu> */
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <getopt.h>
23 #include <sys/types.h>
24 #include <signal.h>
25 #include <pwd.h>
26 #include <grp.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 "dirname.h"
34 #include "filenamecat.h"
35 #include "mkdir-p.h"
36 #include "modechange.h"
37 #include "quote.h"
38 #include "utimens.h"
39 #include "xstrtol.h"
40
41 /* The official name of this program (e.g., no `g' prefix).  */
42 #define PROGRAM_NAME "install"
43
44 #define AUTHORS "David MacKenzie"
45
46 #if HAVE_SYS_WAIT_H
47 # include <sys/wait.h>
48 #endif
49
50 #if ! HAVE_ENDGRENT
51 # define endgrent() ((void) 0)
52 #endif
53
54 #if ! HAVE_ENDPWENT
55 # define endpwent() ((void) 0)
56 #endif
57
58 /* Initial number of entries in each hash table entry's table of inodes.  */
59 #define INITIAL_HASH_MODULE 100
60
61 /* Initial number of entries in the inode hash table.  */
62 #define INITIAL_ENTRY_TAB_SIZE 70
63
64 /* Number of bytes of a file to copy at a time. */
65 #define READ_SIZE (32 * 1024)
66
67 static bool change_timestamps (const char *from, const char *to);
68 static bool change_attributes (char const *name);
69 static bool copy_file (const char *from, const char *to,
70                        const struct cp_options *x);
71 static bool install_file_in_file_parents (char const *from, char const *to,
72                                           struct cp_options const *x);
73 static bool install_file_in_dir (const char *from, const char *to_dir,
74                                  const struct cp_options *x);
75 static bool install_file_in_file (const char *from, const char *to,
76                                   const struct cp_options *x);
77 static void get_ids (void);
78 static void strip (char const *name);
79 void usage (int status);
80
81 /* The name this program was run with, for error messages. */
82 char *program_name;
83
84 /* The user name that will own the files, or NULL to make the owner
85    the current user ID. */
86 static char *owner_name;
87
88 /* The user ID corresponding to `owner_name'. */
89 static uid_t owner_id;
90
91 /* The group name that will own the files, or NULL to make the group
92    the current group ID. */
93 static char *group_name;
94
95 /* The group ID corresponding to `group_name'. */
96 static gid_t group_id;
97
98 /* The permissions to which the files will be set.  The umask has
99    no effect. */
100 static mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
101
102 /* If true, strip executable files after copying them. */
103 static bool strip_files;
104
105 /* If true, install a directory instead of a regular file. */
106 static bool dir_arg;
107
108 static struct option const long_options[] =
109 {
110   {"backup", optional_argument, NULL, 'b'},
111   {"directory", no_argument, NULL, 'd'},
112   {"group", required_argument, NULL, 'g'},
113   {"mode", required_argument, NULL, 'm'},
114   {"no-target-directory", no_argument, NULL, 'T'},
115   {"owner", required_argument, NULL, 'o'},
116   {"preserve-timestamps", no_argument, NULL, 'p'},
117   {"strip", no_argument, NULL, 's'},
118   {"suffix", required_argument, NULL, 'S'},
119   {"target-directory", required_argument, NULL, 't'},
120   {"version-control", required_argument, NULL, 'V'}, /* Deprecated. FIXME. */
121   {"verbose", no_argument, NULL, 'v'},
122   {GETOPT_HELP_OPTION_DECL},
123   {GETOPT_VERSION_OPTION_DECL},
124   {NULL, 0, NULL, 0}
125 };
126
127 static void
128 cp_option_init (struct cp_options *x)
129 {
130   x->copy_as_regular = true;
131   x->dereference = DEREF_ALWAYS;
132   x->unlink_dest_before_opening = true;
133   x->unlink_dest_after_failed_open = false;
134   x->hard_link = false;
135   x->interactive = I_UNSPECIFIED;
136   x->move_mode = false;
137   x->chown_privileges = chown_privileges ();
138   x->one_file_system = false;
139   x->preserve_ownership = false;
140   x->preserve_links = false;
141   x->preserve_mode = false;
142   x->preserve_timestamps = false;
143   x->require_preserve = false;
144   x->recursive = false;
145   x->sparse_mode = SPARSE_AUTO;
146   x->symbolic_link = false;
147   x->backup_type = no_backups;
148
149   /* Create destination files initially writable so we can run strip on them.
150      Although GNU strip works fine on read-only files, some others
151      would fail.  */
152   x->set_mode = true;
153   x->mode = S_IRUSR | S_IWUSR;
154   x->stdin_tty = false;
155
156   x->umask_kill = 0;
157   x->update = false;
158   x->verbose = false;
159   x->dest_info = NULL;
160   x->src_info = NULL;
161 }
162
163 /* FILE is the last operand of this command.  Return true if FILE is a
164    directory.  But report an error there is a problem accessing FILE,
165    or if FILE does not exist but would have to refer to an existing
166    directory if it referred to anything at all.  */
167
168 static bool
169 target_directory_operand (char const *file)
170 {
171   char const *b = base_name (file);
172   size_t blen = strlen (b);
173   bool looks_like_a_dir = (blen == 0 || ISSLASH (b[blen - 1]));
174   struct stat st;
175   int err = (stat (file, &st) == 0 ? 0 : errno);
176   bool is_a_dir = !err && S_ISDIR (st.st_mode);
177   if (err && err != ENOENT)
178     error (EXIT_FAILURE, err, _("accessing %s"), quote (file));
179   if (is_a_dir < looks_like_a_dir)
180     error (EXIT_FAILURE, err, _("target %s is not a directory"), quote (file));
181   return is_a_dir;
182 }
183
184 int
185 main (int argc, char **argv)
186 {
187   int optc;
188   bool ok = true;
189   const char *specified_mode = NULL;
190   bool make_backups = false;
191   char *backup_suffix_string;
192   char *version_control_string = NULL;
193   bool mkdir_and_install = false;
194   struct cp_options x;
195   char const *target_directory = NULL;
196   bool no_target_directory = false;
197   int n_files;
198   char **file;
199
200   initialize_main (&argc, &argv);
201   program_name = argv[0];
202   setlocale (LC_ALL, "");
203   bindtextdomain (PACKAGE, LOCALEDIR);
204   textdomain (PACKAGE);
205
206   atexit (close_stdout);
207
208   cp_option_init (&x);
209
210   owner_name = NULL;
211   group_name = NULL;
212   strip_files = false;
213   dir_arg = false;
214   umask (0);
215
216   /* FIXME: consider not calling getenv for SIMPLE_BACKUP_SUFFIX unless
217      we'll actually use backup_suffix_string.  */
218   backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
219
220   while ((optc = getopt_long (argc, argv, "bcsDdg:m:o:pt:TvV:S:", long_options,
221                               NULL)) != -1)
222     {
223       switch (optc)
224         {
225         case 'V':  /* FIXME: this is deprecated.  Remove it in 2001.  */
226           error (0, 0,
227                  _("warning: --version-control (-V) is obsolete;  support for\
228  it\nwill be removed in some future release.  Use --backup=%s instead."
229                    ), optarg);
230           /* Fall through.  */
231
232         case 'b':
233           make_backups = true;
234           if (optarg)
235             version_control_string = optarg;
236           break;
237         case 'c':
238           break;
239         case 's':
240           strip_files = true;
241 #ifdef SIGCHLD
242           /* System V fork+wait does not work if SIGCHLD is ignored.  */
243           signal (SIGCHLD, SIG_DFL);
244 #endif
245           break;
246         case 'd':
247           dir_arg = true;
248           break;
249         case 'D':
250           mkdir_and_install = true;
251           break;
252         case 'v':
253           x.verbose = true;
254           break;
255         case 'g':
256           group_name = optarg;
257           break;
258         case 'm':
259           specified_mode = optarg;
260           break;
261         case 'o':
262           owner_name = optarg;
263           break;
264         case 'p':
265           x.preserve_timestamps = true;
266           break;
267         case 'S':
268           make_backups = true;
269           backup_suffix_string = optarg;
270           break;
271         case 't':
272           if (target_directory)
273             error (EXIT_FAILURE, 0,
274                    _("multiple target directories specified"));
275           else
276             {
277               struct stat st;
278               if (stat (optarg, &st) != 0)
279                 error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg));
280               if (! S_ISDIR (st.st_mode))
281                 error (EXIT_FAILURE, 0, _("target %s is not a directory"),
282                        quote (optarg));
283             }
284           target_directory = optarg;
285           break;
286         case 'T':
287           no_target_directory = true;
288           break;
289         case_GETOPT_HELP_CHAR;
290         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
291         default:
292           usage (EXIT_FAILURE);
293         }
294     }
295
296   /* Check for invalid combinations of arguments. */
297   if (dir_arg & strip_files)
298     error (EXIT_FAILURE, 0,
299            _("the strip option may not be used when installing a directory"));
300   if (dir_arg && target_directory)
301     error (EXIT_FAILURE, 0,
302            _("target directory not allowed when installing a directory"));
303
304   if (backup_suffix_string)
305     simple_backup_suffix = xstrdup (backup_suffix_string);
306
307   x.backup_type = (make_backups
308                    ? xget_version (_("backup type"),
309                                    version_control_string)
310                    : no_backups);
311
312   n_files = argc - optind;
313   file = argv + optind;
314
315   if (n_files <= ! (dir_arg || target_directory))
316     {
317       if (n_files <= 0)
318         error (0, 0, _("missing file operand"));
319       else
320         error (0, 0, _("missing destination file operand after %s"),
321                quote (file[0]));
322       usage (EXIT_FAILURE);
323     }
324
325   if (no_target_directory)
326     {
327       if (target_directory)
328         error (EXIT_FAILURE, 0,
329                _("Cannot combine --target-directory (-t) "
330                  "and --no-target-directory (-T)"));
331       if (2 < n_files)
332         {
333           error (0, 0, _("extra operand %s"), quote (file[2]));
334           usage (EXIT_FAILURE);
335         }
336     }
337   else if (! (dir_arg || target_directory))
338     {
339       if (2 <= n_files && target_directory_operand (file[n_files - 1]))
340         target_directory = file[--n_files];
341       else if (2 < n_files)
342         error (EXIT_FAILURE, 0, _("target %s is not a directory"),
343                quote (file[n_files - 1]));
344     }
345
346   if (specified_mode)
347     {
348       struct mode_change *change = mode_compile (specified_mode);
349       if (!change)
350         error (EXIT_FAILURE, 0, _("invalid mode %s"), quote (specified_mode));
351       mode = mode_adjust (0, change, 0);
352       free (change);
353     }
354
355   get_ids ();
356
357   if (dir_arg)
358     {
359       int i;
360       bool cwd_not_restored = false;
361       for (i = 0; i < n_files; i++)
362         {
363           bool different_cwd;
364           if (cwd_not_restored && IS_RELATIVE_FILE_NAME (argv[optind]))
365             {
366               error (0, 0,
367                      _("unable to create relative-named directory, %s,"
368                        " due to prior failure to restore working directory"),
369                      quote (argv[optind]));
370               ok = false;;
371               continue;
372             }
373
374           ok &=
375             make_dir_parents (file[i], mode, mode, owner_id, group_id, false,
376                               (x.verbose ? _("creating directory %s") : NULL),
377                               &different_cwd);
378           cwd_not_restored |= different_cwd;
379         }
380     }
381   else
382     {
383       /* FIXME: it's a little gross that this initialization is
384          required by copy.c::copy. */
385       hash_init ();
386
387       if (!target_directory)
388         {
389           if (mkdir_and_install)
390             ok = install_file_in_file_parents (file[0], file[1], &x);
391           else
392             ok = install_file_in_file (file[0], file[1], &x);
393         }
394       else
395         {
396           int i;
397           dest_info_init (&x);
398           for (i = 0; i < n_files; i++)
399             {
400               ok &= install_file_in_dir (file[i], target_directory, &x);
401             }
402         }
403     }
404
405   exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
406 }
407
408 /* Copy file FROM onto file TO, creating any missing parent directories of TO.
409    Return true if successful.  */
410
411 static bool
412 install_file_in_file_parents (char const *from, char const *to,
413                               struct cp_options const *x)
414 {
415   char *dest_dir = dir_name (to);
416   bool ok = true;
417
418   /* Make sure that the parent of the destination is a directory.  */
419   if (! STREQ (dest_dir, "."))
420     {
421       /* Someone will probably ask for a new option or three to specify
422          owner, group, and permissions for parent directories.  Remember
423          that this option is intended mainly to help installers when the
424          distribution doesn't provide proper install rules.  */
425       mode_t dir_mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
426       bool different_cwd;
427       ok = make_dir_parents (dest_dir, dir_mode, dir_mode,
428                              owner_id, group_id, true,
429                              (x->verbose ? _("creating directory %s") : NULL),
430                              &different_cwd);
431       /* Ignore different_cwd, since this function is called at most once.  */
432     }
433
434   free (dest_dir);
435
436   if (ok)
437     ok = install_file_in_file (from, to, x);
438
439   return ok;
440 }
441
442 /* Copy file FROM onto file TO and give TO the appropriate
443    attributes.
444    Return true if successful.  */
445
446 static bool
447 install_file_in_file (const char *from, const char *to,
448                       const struct cp_options *x)
449 {
450   if (! copy_file (from, to, x))
451     return false;
452   if (strip_files)
453     strip (to);
454   if (! change_attributes (to))
455     return false;
456   if (x->preserve_timestamps)
457     return change_timestamps (from, to);
458   return true;
459 }
460
461 /* Copy file FROM into directory TO_DIR, keeping its same name,
462    and give the copy the appropriate attributes.
463    Return true if successful.  */
464
465 static bool
466 install_file_in_dir (const char *from, const char *to_dir,
467                      const struct cp_options *x)
468 {
469   const char *from_base = base_name (from);
470   char *to = file_name_concat (to_dir, from_base, NULL);
471   bool ret = install_file_in_file (from, to, x);
472   free (to);
473   return ret;
474 }
475
476 /* Copy file FROM onto file TO, creating TO if necessary.
477    Return true if successful.  */
478
479 static bool
480 copy_file (const char *from, const char *to, const struct cp_options *x)
481 {
482   bool copy_into_self;
483
484   /* Allow installing from non-regular files like /dev/null.
485      Charles Karney reported that some Sun version of install allows that
486      and that sendmail's installation process relies on the behavior.
487      However, since !x->recursive, the call to "copy" will fail if FROM
488      is a directory.  */
489
490   return copy (from, to, false, x, &copy_into_self, NULL);
491 }
492
493 /* Set the attributes of file or directory NAME.
494    Return true if successful.  */
495
496 static bool
497 change_attributes (char const *name)
498 {
499   bool ok = true;
500
501   /* chown must precede chmod because on some systems,
502      chown clears the set[ug]id bits for non-superusers,
503      resulting in incorrect permissions.
504      On System V, users can give away files with chown and then not
505      be able to chmod them.  So don't give files away.
506
507      We don't normally ignore errors from chown because the idea of
508      the install command is that the file is supposed to end up with
509      precisely the attributes that the user specified (or defaulted).
510      If the file doesn't end up with the group they asked for, they'll
511      want to know.  But AFS returns EPERM when you try to change a
512      file's group; thus the kludge.  */
513
514   if (chown (name, owner_id, group_id) != 0
515 #ifdef AFS
516       && errno != EPERM
517 #endif
518       )
519     {
520       error (0, errno, _("cannot change ownership of %s"), quote (name));
521       ok = false;
522     }
523
524   if (ok && chmod (name, mode) != 0)
525     {
526       error (0, errno, _("cannot change permissions of %s"), quote (name));
527       ok = false;
528     }
529
530   return ok;
531 }
532
533 /* Set the timestamps of file TO to match those of file FROM.
534    Return true if successful.  */
535
536 static bool
537 change_timestamps (const char *from, const char *to)
538 {
539   struct stat stb;
540   struct timespec timespec[2];
541
542   if (stat (from, &stb))
543     {
544       error (0, errno, _("cannot obtain time stamps for %s"), quote (from));
545       return false;
546     }
547
548   timespec[0].tv_sec = stb.st_atime;
549   timespec[0].tv_nsec = TIMESPEC_NS (stb.st_atim);
550   timespec[1].tv_sec = stb.st_mtime;
551   timespec[1].tv_nsec = TIMESPEC_NS (stb.st_mtim);
552   if (utimens (to, timespec))
553     {
554       error (0, errno, _("cannot set time stamps for %s"), quote (to));
555       return false;
556     }
557   return true;
558 }
559
560 /* Strip the symbol table from the file NAME.
561    We could dig the magic number out of the file first to
562    determine whether to strip it, but the header files and
563    magic numbers vary so much from system to system that making
564    it portable would be very difficult.  Not worth the effort. */
565
566 static void
567 strip (char const *name)
568 {
569   int status;
570   pid_t pid = fork ();
571
572   switch (pid)
573     {
574     case -1:
575       error (EXIT_FAILURE, errno, _("fork system call failed"));
576       break;
577     case 0:                     /* Child. */
578       execlp ("strip", "strip", name, NULL);
579       error (EXIT_FAILURE, errno, _("cannot run strip"));
580       break;
581     default:                    /* Parent. */
582       /* Parent process. */
583       while (pid != wait (&status))     /* Wait for kid to finish. */
584         /* Do nothing. */ ;
585       if (status)
586         error (EXIT_FAILURE, 0, _("strip failed"));
587       break;
588     }
589 }
590
591 /* Initialize the user and group ownership of the files to install. */
592
593 static void
594 get_ids (void)
595 {
596   struct passwd *pw;
597   struct group *gr;
598
599   if (owner_name)
600     {
601       pw = getpwnam (owner_name);
602       if (pw == NULL)
603         {
604           unsigned long int tmp;
605           if (xstrtoul (owner_name, NULL, 0, &tmp, NULL) != LONGINT_OK
606               || UID_T_MAX < tmp)
607             error (EXIT_FAILURE, 0, _("invalid user %s"), quote (owner_name));
608           owner_id = tmp;
609         }
610       else
611         owner_id = pw->pw_uid;
612       endpwent ();
613     }
614   else
615     owner_id = (uid_t) -1;
616
617   if (group_name)
618     {
619       gr = getgrnam (group_name);
620       if (gr == NULL)
621         {
622           unsigned long int tmp;
623           if (xstrtoul (group_name, NULL, 0, &tmp, NULL) != LONGINT_OK
624               || GID_T_MAX < tmp)
625             error (EXIT_FAILURE, 0, _("invalid group %s"), quote (group_name));
626           group_id = tmp;
627         }
628       else
629         group_id = gr->gr_gid;
630       endgrent ();
631     }
632   else
633     group_id = (gid_t) -1;
634 }
635
636 void
637 usage (int status)
638 {
639   if (status != EXIT_SUCCESS)
640     fprintf (stderr, _("Try `%s --help' for more information.\n"),
641              program_name);
642   else
643     {
644       printf (_("\
645 Usage: %s [OPTION]... [-T] SOURCE DEST\n\
646   or:  %s [OPTION]... SOURCE... DIRECTORY\n\
647   or:  %s [OPTION]... -t DIRECTORY SOURCE...\n\
648   or:  %s [OPTION]... -d DIRECTORY...\n\
649 "),
650               program_name, program_name, program_name, program_name);
651       fputs (_("\
652 In the first three forms, copy SOURCE to DEST or multiple SOURCE(s) to\n\
653 the existing DIRECTORY, while setting permission modes and owner/group.\n\
654 In the 4th form, create all components of the given DIRECTORY(ies).\n\
655 \n\
656 "), stdout);
657       fputs (_("\
658 Mandatory arguments to long options are mandatory for short options too.\n\
659 "), stdout);
660       fputs (_("\
661       --backup[=CONTROL] make a backup of each existing destination file\n\
662   -b                  like --backup but does not accept an argument\n\
663   -c                  (ignored)\n\
664   -d, --directory     treat all arguments as directory names; create all\n\
665                         components of the specified directories\n\
666 "), stdout);
667       fputs (_("\
668   -D                  create all leading components of DEST except the last,\n\
669                         then copy SOURCE to DEST\n\
670   -g, --group=GROUP   set group ownership, instead of process' current group\n\
671   -m, --mode=MODE     set permission mode (as in chmod), instead of rwxr-xr-x\n\
672   -o, --owner=OWNER   set ownership (super-user only)\n\
673 "), stdout);
674       fputs (_("\
675   -p, --preserve-timestamps   apply access/modification times of SOURCE files\n\
676                         to corresponding destination files\n\
677   -s, --strip         strip symbol tables\n\
678   -S, --suffix=SUFFIX override the usual backup suffix\n\
679   -t, --target-directory=DIRECTORY  copy all SOURCE arguments into DIRECTORY\n\
680   -T, --no-target-directory  treat DEST as a normal file\n\
681   -v, --verbose       print the name of each directory as it is created\n\
682 "), stdout);
683       fputs (HELP_OPTION_DESCRIPTION, stdout);
684       fputs (VERSION_OPTION_DESCRIPTION, stdout);
685       fputs (_("\
686 \n\
687 The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
688 The version control method may be selected via the --backup option or through\n\
689 the VERSION_CONTROL environment variable.  Here are the values:\n\
690 \n\
691 "), stdout);
692       fputs (_("\
693   none, off       never make backups (even if --backup is given)\n\
694   numbered, t     make numbered backups\n\
695   existing, nil   numbered if numbered backups exist, simple otherwise\n\
696   simple, never   always make simple backups\n\
697 "), stdout);
698       printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
699     }
700   exit (status);
701 }