(cp_option_init): Initialize to DEREF_ALWAYS, not `1'.
[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->force = 1;
193
194   /* If unlink fails, try to proceed anyway.  */
195   x->failed_unlink_is_fatal = 0;
196
197   x->hard_link = 0;
198   x->interactive = 0;
199   x->move_mode = 0;
200   x->myeuid = geteuid ();
201   x->one_file_system = 0;
202   x->preserve_owner_and_group = 0;
203   x->preserve_chmod_bits = 0;
204   x->preserve_timestamps = 0;
205   x->require_preserve = 0;
206   x->recursive = 0;
207   x->sparse_mode = SPARSE_AUTO;
208   x->symbolic_link = 0;
209   x->backup_type = none;
210
211   /* Create destination files initially writable so we can run strip on them.
212      Although GNU strip works fine on read-only files, some others
213      would fail.  */
214   x->set_mode = 1;
215   x->mode = S_IRUSR | S_IWUSR;
216
217   x->umask_kill = 0;
218   x->update = 0;
219   x->verbose = 0;
220   x->xstat = stat;
221 }
222
223 int
224 main (int argc, char **argv)
225 {
226   int optc;
227   int errors = 0;
228   const char *symbolic_mode = NULL;
229   int make_backups = 0;
230   char *backup_suffix_string;
231   char *version_control_string = NULL;
232   int mkdir_and_install = 0;
233   struct cp_options x;
234   int n_files;
235   char **file;
236
237   program_name = argv[0];
238   setlocale (LC_ALL, "");
239   bindtextdomain (PACKAGE, LOCALEDIR);
240   textdomain (PACKAGE);
241
242   atexit (close_stdout);
243
244   cp_option_init (&x);
245
246   owner_name = NULL;
247   group_name = NULL;
248   strip_files = 0;
249   dir_arg = 0;
250   umask (0);
251
252   /* FIXME: consider not calling getenv for SIMPLE_BACKUP_SUFFIX unless
253      we'll actually use backup_suffix_string.  */
254   backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
255
256   while ((optc = getopt_long (argc, argv, "bcsDdg:m:o:pvV:S:", long_options,
257                               NULL)) != -1)
258     {
259       switch (optc)
260         {
261         case 0:
262           break;
263
264         case 'V':  /* FIXME: this is deprecated.  Remove it in 2001.  */
265           error (0, 0,
266                  _("warning: --version-control (-V) is obsolete;  support for\
267  it\nwill be removed in some future release.  Use --backup=%s instead."
268                    ), optarg);
269           /* Fall through.  */
270
271         case 'b':
272           make_backups = 1;
273           if (optarg)
274             version_control_string = optarg;
275           break;
276         case 'c':
277           break;
278         case 's':
279           strip_files = 1;
280           break;
281         case 'd':
282           dir_arg = 1;
283           break;
284         case 'D':
285           mkdir_and_install = 1;
286           break;
287         case 'v':
288           x.verbose = 1;
289           break;
290         case 'g':
291           group_name = optarg;
292           break;
293         case 'm':
294           symbolic_mode = optarg;
295           break;
296         case 'o':
297           owner_name = optarg;
298           break;
299         case 'p':
300           x.preserve_timestamps = 1;
301           break;
302         case 'S':
303           make_backups = 1;
304           backup_suffix_string = optarg;
305           break;
306         case_GETOPT_HELP_CHAR;
307         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
308         default:
309           usage (1);
310         }
311     }
312
313   /* Check for invalid combinations of arguments. */
314   if (dir_arg && strip_files)
315     error (1, 0,
316            _("the strip option may not be used when installing a directory"));
317
318   if (make_backups)
319     x.backup_type = xget_version ("backup type", version_control_string);
320
321   n_files = argc - optind;
322   file = argv + optind;
323
324   if (n_files == 0 || (n_files == 1 && !dir_arg))
325     {
326       error (0, 0, _("too few arguments"));
327       usage (1);
328     }
329
330   if (symbolic_mode)
331     {
332       struct mode_change *change = mode_compile (symbolic_mode, 0);
333       if (change == MODE_INVALID)
334         error (1, 0, _("invalid mode %s"), quote (symbolic_mode));
335       else if (change == MODE_MEMORY_EXHAUSTED)
336         xalloc_die ();
337       mode = mode_adjust (0, change);
338     }
339
340   get_ids ();
341
342   if (dir_arg)
343     {
344       int i;
345       for (i = 0; i < n_files; i++)
346         {
347           errors |=
348             make_path (file[i], mode, mode, owner_id, group_id, 0,
349                        (x.verbose ? _("creating directory %s") : NULL));
350         }
351     }
352   else
353     {
354       /* FIXME: it's a little gross that this initialization is
355          required by copy.c::copy. */
356       hash_init (INITIAL_HASH_MODULE, INITIAL_ENTRY_TAB_SIZE);
357
358       if (n_files == 2)
359         {
360           if (mkdir_and_install)
361             errors = install_file_to_path (file[0], file[1], &x);
362           else if (!isdir (file[1]))
363             errors = install_file_in_file (file[0], file[1], &x);
364           else
365             errors = install_file_in_dir (file[0], file[1], &x);
366         }
367       else
368         {
369           int i;
370           const char *dest = file[n_files - 1];
371           if (!isdir (dest))
372             {
373               error (0, 0,
374                      _("installing multiple files, but last argument, %s \
375 is not a directory"),
376                      quote (dest));
377               usage (1);
378             }
379           for (i = 0; i < n_files - 1; i++)
380             {
381               errors |= install_file_in_dir (file[i], dest, &x);
382             }
383         }
384     }
385
386   exit (errors);
387 }
388
389 /* Copy file FROM onto file TO, creating any missing parent directories of TO.
390    Return 0 if successful, 1 if an error occurs */
391
392 static int
393 install_file_to_path (const char *from, const char *to,
394                       const struct cp_options *x)
395 {
396   char *dest_dir;
397   int fail = 0;
398
399   dest_dir = dir_name (to);
400
401   /* check to make sure this is a path (not install a b ) */
402   if (!STREQ (dest_dir, ".")
403       && !isdir (dest_dir))
404     {
405       /* Someone will probably ask for a new option or three to specify
406          owner, group, and permissions for parent directories.  Remember
407          that this option is intended mainly to help installers when the
408          distribution doesn't provide proper install rules.  */
409 #define DIR_MODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
410       fail = make_path (dest_dir, DIR_MODE, DIR_MODE, owner_id, group_id, 0,
411                         (x->verbose ? _("creating directory %s") : NULL));
412     }
413
414   if (fail == 0)
415     fail = install_file_in_file (from, to, x);
416
417   free (dest_dir);
418
419   return fail;
420 }
421
422 /* Copy file FROM onto file TO and give TO the appropriate
423    attributes.
424    Return 0 if successful, 1 if an error occurs. */
425
426 static int
427 install_file_in_file (const char *from, const char *to,
428                       const struct cp_options *x)
429 {
430   if (copy_file (from, to, x))
431     return 1;
432   if (strip_files)
433     strip (to);
434   if (change_attributes (to))
435     return 1;
436   if (x->preserve_timestamps)
437     return change_timestamps (from, to);
438   return 0;
439 }
440
441 /* Copy file FROM into directory TO_DIR, keeping its same name,
442    and give the copy the appropriate attributes.
443    Return 0 if successful, 1 if not. */
444
445 static int
446 install_file_in_dir (const char *from, const char *to_dir,
447                      const struct cp_options *x)
448 {
449   const char *from_base;
450   char *to;
451   int ret;
452
453   from_base = base_name (from);
454   to = path_concat (to_dir, from_base, NULL);
455   ret = install_file_in_file (from, to, x);
456   free (to);
457   return ret;
458 }
459
460 /* Copy file FROM onto file TO, creating TO if necessary.
461    Return 0 if the copy is successful, 1 if not.  */
462
463 static int
464 copy_file (const char *from, const char *to, const struct cp_options *x)
465 {
466   int fail;
467   int nonexistent_dst = 0;
468   int copy_into_self;
469
470   /* Allow installing from non-regular files like /dev/null.
471      Charles Karney reported that some Sun version of install allows that
472      and that sendmail's installation process relies on the behavior.  */
473   if (isdir (from))
474     {
475       error (0, 0, _("%s is a directory"), quote (from));
476       return 1;
477     }
478
479   fail = copy (from, to, nonexistent_dst, x, &copy_into_self, NULL);
480
481   return fail;
482 }
483
484 /* Set the attributes of file or directory PATH.
485    Return 0 if successful, 1 if not. */
486
487 static int
488 change_attributes (const char *path)
489 {
490   int err = 0;
491
492   /* chown must precede chmod because on some systems,
493      chown clears the set[ug]id bits for non-superusers,
494      resulting in incorrect permissions.
495      On System V, users can give away files with chown and then not
496      be able to chmod them.  So don't give files away.
497
498      We don't normally ignore errors from chown because the idea of
499      the install command is that the file is supposed to end up with
500      precisely the attributes that the user specified (or defaulted).
501      If the file doesn't end up with the group they asked for, they'll
502      want to know.  But AFS returns EPERM when you try to change a
503      file's group; thus the kludge.  */
504
505   if (chown (path, owner_id, group_id)
506 #ifdef AFS
507       && errno != EPERM
508 #endif
509       )
510     {
511       error (0, errno, "cannot change ownership of %s", quote (path));
512       err = 1;
513     }
514
515   if (!err && chmod (path, mode))
516     {
517       error (0, errno, "cannot change permissions of %s", quote (path));
518       err = 1;
519     }
520
521   return err;
522 }
523
524 /* Set the timestamps of file TO to match those of file FROM.
525    Return 0 if successful, 1 if not. */
526
527 static int
528 change_timestamps (const char *from, const char *to)
529 {
530   struct stat stb;
531   struct utimbuf utb;
532
533   if (stat (from, &stb))
534     {
535       error (0, errno, _("cannot obtain time stamps for %s"), quote (from));
536       return 1;
537     }
538
539   /* There's currently no interface to set file timestamps with
540      better than 1-second resolution, so discard any fractional
541      part of the source timestamp.  */
542
543   utb.actime = stb.st_atime;
544   utb.modtime = stb.st_mtime;
545   if (utime (to, &utb))
546     {
547       error (0, errno, _("cannot set time stamps for %s"), quote (to));
548       return 1;
549     }
550   return 0;
551 }
552
553 /* Strip the symbol table from the file PATH.
554    We could dig the magic number out of the file first to
555    determine whether to strip it, but the header files and
556    magic numbers vary so much from system to system that making
557    it portable would be very difficult.  Not worth the effort. */
558
559 static void
560 strip (const char *path)
561 {
562   int status;
563   pid_t pid = fork ();
564
565   switch (pid)
566     {
567     case -1:
568       error (1, errno, _("cannot fork"));
569       break;
570     case 0:                     /* Child. */
571       execlp ("strip", "strip", path, NULL);
572       error (1, errno, _("cannot run strip"));
573       break;
574     default:                    /* Parent. */
575       /* Parent process. */
576       while (pid != wait (&status))     /* Wait for kid to finish. */
577         /* Do nothing. */ ;
578       if (status)
579         error (1, 0, _("strip failed"));
580       break;
581     }
582 }
583
584 /* Initialize the user and group ownership of the files to install. */
585
586 static void
587 get_ids (void)
588 {
589   struct passwd *pw;
590   struct group *gr;
591
592   if (owner_name)
593     {
594       pw = getpwnam (owner_name);
595       if (pw == NULL)
596         {
597           long int tmp_long;
598           if (xstrtol (owner_name, NULL, 0, &tmp_long, NULL) != LONGINT_OK
599               || tmp_long < 0 || tmp_long > UID_T_MAX)
600             error (1, 0, _("invalid user %s"), quote (owner_name));
601           owner_id = (uid_t) tmp_long;
602         }
603       else
604         owner_id = pw->pw_uid;
605       endpwent ();
606     }
607   else
608     owner_id = (uid_t) -1;
609
610   if (group_name)
611     {
612       gr = getgrnam (group_name);
613       if (gr == NULL)
614         {
615           long int tmp_long;
616           if (xstrtol (group_name, NULL, 0, &tmp_long, NULL) != LONGINT_OK
617               || tmp_long < 0 || tmp_long > GID_T_MAX)
618             error (1, 0, _("invalid group %s"), quote (group_name));
619           group_id = (gid_t) tmp_long;
620         }
621       else
622         group_id = gr->gr_gid;
623       endgrent ();
624     }
625   else
626     group_id = (gid_t) -1;
627 }
628
629 void
630 usage (int status)
631 {
632   if (status != 0)
633     fprintf (stderr, _("Try `%s --help' for more information.\n"),
634              program_name);
635   else
636     {
637       printf (_("\
638 Usage: %s [OPTION]... SOURCE DEST           (1st format)\n\
639   or:  %s [OPTION]... SOURCE... DIRECTORY   (2nd format)\n\
640   or:  %s -d [OPTION]... DIRECTORY...       (3rd format)\n\
641 "),
642               program_name, program_name, program_name);
643       printf (_("\
644 In the first two formats, copy SOURCE to DEST or multiple SOURCE(s) to\n\
645 the existing DIRECTORY, while setting permission modes and owner/group.\n\
646 In the third format, create all components of the given DIRECTORY(ies).\n\
647 \n\
648       --backup[=CONTROL] make a backup of each existing destination file\n\
649   -b                  like --backup but does not accept an argument\n\
650   -c                  (ignored)\n\
651   -d, --directory     treat all arguments as directory names; create all\n\
652                         components of the specified directories\n\
653   -D                  create all leading components of DEST except the last,\n\
654                         then copy SOURCE to DEST;  useful in the 1st format\n\
655   -g, --group=GROUP   set group ownership, instead of process' current group\n\
656   -m, --mode=MODE     set permission mode (as in chmod), instead of rwxr-xr-x\n\
657   -o, --owner=OWNER   set ownership (super-user only)\n\
658   -p, --preserve-timestamps   apply access/modification times of SOURCE files\n\
659                         to corresponding destination files\n\
660   -s, --strip         strip symbol tables, only for 1st and 2nd formats\n\
661   -S, --suffix=SUFFIX override the usual backup suffix\n\
662   -v, --verbose       print the name of each directory as it is created\n\
663       --help          display this help and exit\n\
664       --version       output version information and exit\n\
665 \n\
666 "));
667       printf (_("\
668 The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
669 The version control method may be selected via the --backup option or through\n\
670 the VERSION_CONTROL environment variable.  Here are the values:\n\
671 \n\
672   none, off       never make backups (even if --backup is given)\n\
673   numbered, t     make numbered backups\n\
674   existing, nil   numbered if numbered backups exist, simple otherwise\n\
675   simple, never   always make simple backups\n\
676 "));
677       puts (_("\nReport bugs to <bug-fileutils@gnu.org>."));
678     }
679   exit (status);
680 }