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