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