(main): Standardize on the diagnostics given when someone gives
[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   {"owner", required_argument, NULL, 'o'},
127   {"preserve-timestamps", no_argument, NULL, 'p'},
128   {"strip", no_argument, NULL, 's'},
129   {"suffix", required_argument, NULL, 'S'},
130   {"version-control", required_argument, NULL, 'V'}, /* Deprecated. FIXME. */
131   {"verbose", no_argument, NULL, 'v'},
132   {GETOPT_HELP_OPTION_DECL},
133   {GETOPT_VERSION_OPTION_DECL},
134   {NULL, 0, NULL, 0}
135 };
136
137 static void
138 cp_option_init (struct cp_options *x)
139 {
140   x->copy_as_regular = 1;
141   x->dereference = DEREF_ALWAYS;
142   x->unlink_dest_before_opening = 1;
143   x->unlink_dest_after_failed_open = 0;
144   x->hard_link = 0;
145   x->interactive = I_UNSPECIFIED;
146   x->move_mode = 0;
147   x->myeuid = geteuid ();
148   x->one_file_system = 0;
149   x->preserve_ownership = 0;
150   x->preserve_links = 0;
151   x->preserve_mode = 0;
152   x->preserve_timestamps = 0;
153   x->require_preserve = 0;
154   x->recursive = 0;
155   x->sparse_mode = SPARSE_AUTO;
156   x->symbolic_link = 0;
157   x->backup_type = none;
158
159   /* Create destination files initially writable so we can run strip on them.
160      Although GNU strip works fine on read-only files, some others
161      would fail.  */
162   x->set_mode = 1;
163   x->mode = S_IRUSR | S_IWUSR;
164   x->stdin_tty = 0;
165
166   x->umask_kill = 0;
167   x->update = 0;
168   x->verbose = 0;
169   x->dest_info = NULL;
170   x->src_info = NULL;
171 }
172
173 int
174 main (int argc, char **argv)
175 {
176   int optc;
177   int errors = 0;
178   const char *specified_mode = NULL;
179   int make_backups = 0;
180   char *backup_suffix_string;
181   char *version_control_string = NULL;
182   int mkdir_and_install = 0;
183   struct cp_options x;
184   int n_files;
185   char **file;
186
187   initialize_main (&argc, &argv);
188   program_name = argv[0];
189   setlocale (LC_ALL, "");
190   bindtextdomain (PACKAGE, LOCALEDIR);
191   textdomain (PACKAGE);
192
193   atexit (close_stdout);
194
195   cp_option_init (&x);
196
197   owner_name = NULL;
198   group_name = NULL;
199   strip_files = 0;
200   dir_arg = 0;
201   umask (0);
202
203   /* FIXME: consider not calling getenv for SIMPLE_BACKUP_SUFFIX unless
204      we'll actually use backup_suffix_string.  */
205   backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
206
207   while ((optc = getopt_long (argc, argv, "bcsDdg:m:o:pvV:S:", long_options,
208                               NULL)) != -1)
209     {
210       switch (optc)
211         {
212         case 0:
213           break;
214
215         case 'V':  /* FIXME: this is deprecated.  Remove it in 2001.  */
216           error (0, 0,
217                  _("warning: --version-control (-V) is obsolete;  support for\
218  it\nwill be removed in some future release.  Use --backup=%s instead."
219                    ), optarg);
220           /* Fall through.  */
221
222         case 'b':
223           make_backups = 1;
224           if (optarg)
225             version_control_string = optarg;
226           break;
227         case 'c':
228           break;
229         case 's':
230           strip_files = 1;
231 #ifdef SIGCHLD
232           /* System V fork+wait does not work if SIGCHLD is ignored.  */
233           signal (SIGCHLD, SIG_DFL);
234 #endif
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 (EXIT_FAILURE);
265         }
266     }
267
268   /* Check for invalid combinations of arguments. */
269   if (dir_arg && strip_files)
270     error (EXIT_FAILURE, 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 (argc <= optind || (n_files == 1 && !dir_arg))
285     {
286       if (argc <= optind)
287         error (0, 0, _("missing operand"));
288       else
289         error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
290       usage (EXIT_FAILURE);
291     }
292
293   if (specified_mode)
294     {
295       struct mode_change *change = mode_compile (specified_mode, 0);
296       if (change == MODE_INVALID)
297         error (EXIT_FAILURE, 0, _("invalid mode %s"), quote (specified_mode));
298       else if (change == MODE_MEMORY_EXHAUSTED)
299         xalloc_die ();
300       mode = mode_adjust (0, change);
301     }
302
303   get_ids ();
304
305   if (dir_arg)
306     {
307       int i;
308       for (i = 0; i < n_files; i++)
309         {
310           errors |=
311             make_path (file[i], mode, mode, owner_id, group_id, 0,
312                        (x.verbose ? _("creating directory %s") : NULL));
313         }
314     }
315   else
316     {
317       /* FIXME: it's a little gross that this initialization is
318          required by copy.c::copy. */
319       hash_init ();
320
321       if (n_files == 2)
322         {
323           if (mkdir_and_install)
324             errors = install_file_to_path (file[0], file[1], &x);
325           else if (!isdir (file[1]))
326             errors = install_file_in_file (file[0], file[1], &x);
327           else
328             errors = install_file_in_dir (file[0], file[1], &x);
329         }
330       else
331         {
332           int i;
333           const char *dest = file[n_files - 1];
334           if (!isdir (dest))
335             {
336               error (0, 0,
337                      _("installing multiple files, but last argument, %s \
338 is not a directory"),
339                      quote (dest));
340               usage (EXIT_FAILURE);
341             }
342
343           dest_info_init (&x);
344           for (i = 0; i < n_files - 1; i++)
345             {
346               errors |= install_file_in_dir (file[i], dest, &x);
347             }
348         }
349     }
350
351   exit (errors == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
352 }
353
354 /* Copy file FROM onto file TO, creating any missing parent directories of TO.
355    Return 0 if successful, 1 if an error occurs */
356
357 static int
358 install_file_to_path (const char *from, const char *to,
359                       const struct cp_options *x)
360 {
361   char *dest_dir;
362   int fail = 0;
363
364   dest_dir = dir_name (to);
365
366   /* check to make sure this is a path (not install a b ) */
367   if (!STREQ (dest_dir, ".")
368       && !isdir (dest_dir))
369     {
370       /* Someone will probably ask for a new option or three to specify
371          owner, group, and permissions for parent directories.  Remember
372          that this option is intended mainly to help installers when the
373          distribution doesn't provide proper install rules.  */
374 #define DIR_MODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
375       fail = make_path (dest_dir, DIR_MODE, DIR_MODE, owner_id, group_id, 0,
376                         (x->verbose ? _("creating directory %s") : NULL));
377     }
378
379   if (fail == 0)
380     fail = install_file_in_file (from, to, x);
381
382   free (dest_dir);
383
384   return fail;
385 }
386
387 /* Copy file FROM onto file TO and give TO the appropriate
388    attributes.
389    Return 0 if successful, 1 if an error occurs. */
390
391 static int
392 install_file_in_file (const char *from, const char *to,
393                       const struct cp_options *x)
394 {
395   if (copy_file (from, to, x))
396     return 1;
397   if (strip_files)
398     strip (to);
399   if (change_attributes (to))
400     return 1;
401   if (x->preserve_timestamps)
402     return change_timestamps (from, to);
403   return 0;
404 }
405
406 /* Copy file FROM into directory TO_DIR, keeping its same name,
407    and give the copy the appropriate attributes.
408    Return 0 if successful, 1 if not. */
409
410 static int
411 install_file_in_dir (const char *from, const char *to_dir,
412                      const struct cp_options *x)
413 {
414   const char *from_base;
415   char *to;
416   int ret;
417
418   from_base = base_name (from);
419   to = path_concat (to_dir, from_base, NULL);
420   ret = install_file_in_file (from, to, x);
421   free (to);
422   return ret;
423 }
424
425 /* Copy file FROM onto file TO, creating TO if necessary.
426    Return 0 if the copy is successful, 1 if not.  */
427
428 static int
429 copy_file (const char *from, const char *to, const struct cp_options *x)
430 {
431   int fail;
432   int nonexistent_dst = 0;
433   int copy_into_self;
434
435   /* Allow installing from non-regular files like /dev/null.
436      Charles Karney reported that some Sun version of install allows that
437      and that sendmail's installation process relies on the behavior.  */
438   if (isdir (from))
439     {
440       error (0, 0, _("%s is a directory"), quote (from));
441       return 1;
442     }
443
444   fail = copy (from, to, nonexistent_dst, x, &copy_into_self, NULL);
445
446   return fail;
447 }
448
449 /* Set the attributes of file or directory PATH.
450    Return 0 if successful, 1 if not. */
451
452 static int
453 change_attributes (const char *path)
454 {
455   int err = 0;
456
457   /* chown must precede chmod because on some systems,
458      chown clears the set[ug]id bits for non-superusers,
459      resulting in incorrect permissions.
460      On System V, users can give away files with chown and then not
461      be able to chmod them.  So don't give files away.
462
463      We don't normally ignore errors from chown because the idea of
464      the install command is that the file is supposed to end up with
465      precisely the attributes that the user specified (or defaulted).
466      If the file doesn't end up with the group they asked for, they'll
467      want to know.  But AFS returns EPERM when you try to change a
468      file's group; thus the kludge.  */
469
470   if (chown (path, owner_id, group_id)
471 #ifdef AFS
472       && errno != EPERM
473 #endif
474       )
475     {
476       error (0, errno, _("cannot change ownership of %s"), quote (path));
477       err = 1;
478     }
479
480   if (!err && chmod (path, mode))
481     {
482       error (0, errno, _("cannot change permissions of %s"), quote (path));
483       err = 1;
484     }
485
486   return err;
487 }
488
489 /* Set the timestamps of file TO to match those of file FROM.
490    Return 0 if successful, 1 if not. */
491
492 static int
493 change_timestamps (const char *from, const char *to)
494 {
495   struct stat stb;
496   struct timespec timespec[2];
497
498   if (stat (from, &stb))
499     {
500       error (0, errno, _("cannot obtain time stamps for %s"), quote (from));
501       return 1;
502     }
503
504   timespec[0].tv_sec = stb.st_atime;
505   timespec[0].tv_nsec = TIMESPEC_NS (stb.st_atim);
506   timespec[1].tv_sec = stb.st_mtime;
507   timespec[1].tv_nsec = TIMESPEC_NS (stb.st_mtim);
508   if (utimens (to, timespec))
509     {
510       error (0, errno, _("cannot set time stamps for %s"), quote (to));
511       return 1;
512     }
513   return 0;
514 }
515
516 /* Strip the symbol table from the file PATH.
517    We could dig the magic number out of the file first to
518    determine whether to strip it, but the header files and
519    magic numbers vary so much from system to system that making
520    it portable would be very difficult.  Not worth the effort. */
521
522 static void
523 strip (const char *path)
524 {
525   int status;
526   pid_t pid = fork ();
527
528   switch (pid)
529     {
530     case -1:
531       error (EXIT_FAILURE, errno, _("fork system call failed"));
532       break;
533     case 0:                     /* Child. */
534       execlp ("strip", "strip", path, NULL);
535       error (EXIT_FAILURE, errno, _("cannot run strip"));
536       break;
537     default:                    /* Parent. */
538       /* Parent process. */
539       while (pid != wait (&status))     /* Wait for kid to finish. */
540         /* Do nothing. */ ;
541       if (status)
542         error (EXIT_FAILURE, 0, _("strip failed"));
543       break;
544     }
545 }
546
547 /* Initialize the user and group ownership of the files to install. */
548
549 static void
550 get_ids (void)
551 {
552   struct passwd *pw;
553   struct group *gr;
554
555   if (owner_name)
556     {
557       pw = getpwnam (owner_name);
558       if (pw == NULL)
559         {
560           unsigned long int tmp;
561           if (xstrtoul (owner_name, NULL, 0, &tmp, NULL) != LONGINT_OK
562               || UID_T_MAX < tmp)
563             error (EXIT_FAILURE, 0, _("invalid user %s"), quote (owner_name));
564           owner_id = tmp;
565         }
566       else
567         owner_id = pw->pw_uid;
568       endpwent ();
569     }
570   else
571     owner_id = (uid_t) -1;
572
573   if (group_name)
574     {
575       gr = getgrnam (group_name);
576       if (gr == NULL)
577         {
578           unsigned long int tmp;
579           if (xstrtoul (group_name, NULL, 0, &tmp, NULL) != LONGINT_OK
580               || GID_T_MAX < tmp)
581             error (EXIT_FAILURE, 0, _("invalid group %s"), quote (group_name));
582           group_id = tmp;
583         }
584       else
585         group_id = gr->gr_gid;
586       endgrent ();
587     }
588   else
589     group_id = (gid_t) -1;
590 }
591
592 void
593 usage (int status)
594 {
595   if (status != EXIT_SUCCESS)
596     fprintf (stderr, _("Try `%s --help' for more information.\n"),
597              program_name);
598   else
599     {
600       printf (_("\
601 Usage: %s [OPTION]... SOURCE DEST           (1st format)\n\
602   or:  %s [OPTION]... SOURCE... DIRECTORY   (2nd format)\n\
603   or:  %s -d [OPTION]... DIRECTORY...       (3rd format)\n\
604 "),
605               program_name, program_name, program_name);
606       fputs (_("\
607 In the first two formats, copy SOURCE to DEST or multiple SOURCE(s) to\n\
608 the existing DIRECTORY, while setting permission modes and owner/group.\n\
609 In the third format, create all components of the given DIRECTORY(ies).\n\
610 \n\
611 "), stdout);
612       fputs (_("\
613 Mandatory arguments to long options are mandatory for short options too.\n\
614 "), stdout);
615       fputs (_("\
616       --backup[=CONTROL] make a backup of each existing destination file\n\
617   -b                  like --backup but does not accept an argument\n\
618   -c                  (ignored)\n\
619   -d, --directory     treat all arguments as directory names; create all\n\
620                         components of the specified directories\n\
621 "), stdout);
622       fputs (_("\
623   -D                  create all leading components of DEST except the last,\n\
624                         then copy SOURCE to DEST;  useful in the 1st format\n\
625   -g, --group=GROUP   set group ownership, instead of process' current group\n\
626   -m, --mode=MODE     set permission mode (as in chmod), instead of rwxr-xr-x\n\
627   -o, --owner=OWNER   set ownership (super-user only)\n\
628 "), stdout);
629       fputs (_("\
630   -p, --preserve-timestamps   apply access/modification times of SOURCE files\n\
631                         to corresponding destination files\n\
632   -s, --strip         strip symbol tables, only for 1st and 2nd formats\n\
633   -S, --suffix=SUFFIX override the usual backup suffix\n\
634   -v, --verbose       print the name of each directory as it is created\n\
635 "), stdout);
636       fputs (HELP_OPTION_DESCRIPTION, stdout);
637       fputs (VERSION_OPTION_DESCRIPTION, stdout);
638       fputs (_("\
639 \n\
640 The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
641 The version control method may be selected via the --backup option or through\n\
642 the VERSION_CONTROL environment variable.  Here are the values:\n\
643 \n\
644 "), stdout);
645       fputs (_("\
646   none, off       never make backups (even if --backup is given)\n\
647   numbered, t     make numbered backups\n\
648   existing, nil   numbered if numbered backups exist, simple otherwise\n\
649   simple, never   always make simple backups\n\
650 "), stdout);
651       printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
652     }
653   exit (status);
654 }