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