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