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