(usage): Tweak spacing
[platform/upstream/coreutils.git] / src / install.c
1 /* install - copy files and set attributes
2    Copyright (C) 89, 90, 91, 95, 96, 97, 1998 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 0755).
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 "modechange.h"
77 #include "makepath.h"
78 #include "closeout.h"
79 #include "error.h"
80 #include "xstrtol.h"
81
82 #if HAVE_SYS_WAIT_H
83 # include <sys/wait.h>
84 #endif
85
86 #if HAVE_VALUES_H
87 # include <values.h>
88 #endif
89
90 struct passwd *getpwnam ();
91 struct group *getgrnam ();
92
93 #ifndef _POSIX_VERSION
94 uid_t getuid ();
95 gid_t getgid ();
96 #endif
97
98 #ifndef HAVE_ENDGRENT
99 # define endgrent() ((void) 0)
100 #endif
101
102 #ifndef HAVE_ENDPWENT
103 # define endpwent() ((void) 0)
104 #endif
105
106 /* True if C is an ASCII octal digit. */
107 #define isodigit(c) ((c) >= '0' && c <= '7')
108
109 /* Number of bytes of a file to copy at a time. */
110 #define READ_SIZE (32 * 1024)
111
112 #ifndef UID_T_MAX
113 # define UID_T_MAX TYPE_MAXIMUM (uid_t)
114 #endif
115
116 #ifndef GID_T_MAX
117 # define GID_T_MAX TYPE_MAXIMUM (gid_t)
118 #endif
119
120 char *base_name ();
121 char *dirname ();
122 int safe_read ();
123 int full_write ();
124 int isdir ();
125 enum backup_type get_version ();
126
127 static int change_timestamps PARAMS ((const char *from, const char *to));
128 static int change_attributes PARAMS ((const char *path, int no_need_to_chown));
129 static int copy_file PARAMS ((const char *from, const char *to,
130                               int *to_created));
131 static int install_file_to_path PARAMS ((const char *from, const char *to));
132 static int install_file_in_dir PARAMS ((const char *from, const char *to_dir));
133 static int install_file_in_file PARAMS ((const char *from, const char *to));
134 static void get_ids PARAMS ((void));
135 static void strip PARAMS ((const char *path));
136 static void usage PARAMS ((int status));
137
138 /* The name this program was run with, for error messages. */
139 char *program_name;
140
141 /* FIXME: document */
142 enum backup_type backup_type;
143
144 /* The user name that will own the files, or NULL to make the owner
145    the current user ID. */
146 static char *owner_name;
147
148 /* The user ID corresponding to `owner_name'. */
149 static uid_t owner_id;
150
151 /* The group name that will own the files, or NULL to make the group
152    the current group ID. */
153 static char *group_name;
154
155 /* The group ID corresponding to `group_name'. */
156 static gid_t group_id;
157
158 /* The permissions to which the files will be set.  The umask has
159    no effect. */
160 static int mode;
161
162 /* If nonzero, strip executable files after copying them. */
163 static int strip_files;
164
165 /* If nonzero, preserve timestamps when installing files. */
166 static int preserve_timestamps;
167
168 /* If nonzero, install a directory instead of a regular file. */
169 static int dir_arg;
170
171 /* If nonzero, show what we are doing.  */
172 static int verbose;
173
174 /* If nonzero, display usage information and exit.  */
175 static int show_help;
176
177 /* If nonzero, print the version on standard output and exit.  */
178 static int show_version;
179
180 static struct option const long_options[] =
181 {
182   {"strip", no_argument, NULL, 's'},
183   {"directory", no_argument, NULL, 'd'},
184   {"group", required_argument, NULL, 'g'},
185   {"mode", required_argument, NULL, 'm'},
186   {"owner", required_argument, NULL, 'o'},
187   {"preserve-timestamps", no_argument, NULL, 'p'},
188   {"backup", no_argument, NULL, 'b'},
189   {"version-control", required_argument, NULL, 'V'},
190   {"verbose", no_argument, NULL, 'v'},
191   {"help", no_argument, &show_help, 1},
192   {"version", no_argument, &show_version, 1},
193   {NULL, 0, NULL, 0}
194 };
195
196 int
197 main (int argc, char **argv)
198 {
199   int optc;
200   int errors = 0;
201   char *symbolic_mode = NULL;
202   int make_backups = 0;
203   char *version;
204   int mkdir_and_install = 0;
205
206   program_name = argv[0];
207   setlocale (LC_ALL, "");
208   bindtextdomain (PACKAGE, LOCALEDIR);
209   textdomain (PACKAGE);
210
211   owner_name = NULL;
212   group_name = NULL;
213   mode = 0755;
214   strip_files = 0;
215   preserve_timestamps = 0;
216   dir_arg = 0;
217   verbose = 0;
218   umask (0);
219
220   version = getenv ("SIMPLE_BACKUP_SUFFIX");
221   if (version)
222     simple_backup_suffix = version;
223   version = getenv ("VERSION_CONTROL");
224
225   while ((optc = getopt_long (argc, argv, "bcsDdg:m:o:pvV:S:", long_options,
226                               NULL)) != -1)
227     {
228       switch (optc)
229         {
230         case 0:
231           break;
232         case 'b':
233           make_backups = 1;
234           break;
235         case 'c':
236           break;
237         case 's':
238           strip_files = 1;
239           break;
240         case 'd':
241           dir_arg = 1;
242           break;
243         case 'D':
244           mkdir_and_install = 1;
245           break;
246         case 'v':
247           verbose = 1;
248           break;
249         case 'g':
250           group_name = optarg;
251           break;
252         case 'm':
253           symbolic_mode = optarg;
254           break;
255         case 'o':
256           owner_name = optarg;
257           break;
258         case 'p':
259           preserve_timestamps = 1;
260           break;
261         case 'S':
262           simple_backup_suffix = optarg;
263           break;
264         case 'V':
265           version = optarg;
266           break;
267         default:
268           usage (1);
269         }
270     }
271
272   if (show_version)
273     {
274       printf ("install (%s) %s\n", GNU_PACKAGE, VERSION);
275       close_stdout ();
276       exit (0);
277     }
278
279   if (show_help)
280     usage (0);
281
282   /* Check for invalid combinations of arguments. */
283   if (dir_arg && strip_files)
284     error (1, 0,
285            _("the strip option may not be used when installing a directory"));
286
287   backup_type = (make_backups ? get_version (version) : none);
288
289   if (optind == argc || (optind == argc - 1 && !dir_arg))
290     {
291       error (0, 0, _("too few arguments"));
292       usage (1);
293     }
294
295   if (symbolic_mode)
296     {
297       struct mode_change *change = mode_compile (symbolic_mode, 0);
298       if (change == MODE_INVALID)
299         error (1, 0, _("invalid mode `%s'"), symbolic_mode);
300       else if (change == MODE_MEMORY_EXHAUSTED)
301         error (1, 0, _("virtual memory exhausted"));
302       mode = mode_adjust (0, change);
303     }
304
305   get_ids ();
306
307   if (dir_arg)
308     {
309       for (; optind < argc; ++optind)
310         {
311           errors |=
312             make_path (argv[optind], mode, mode, owner_id, group_id, 0,
313                        (verbose ? "creating directory `%s'" : NULL));
314         }
315     }
316   else
317     {
318       if (optind == argc - 2)
319         {
320           if (mkdir_and_install)
321             errors = install_file_to_path (argv[argc - 2], argv[argc - 1]);
322           else if (!isdir (argv[argc - 1]))
323             errors = install_file_in_file (argv[argc - 2], argv[argc - 1]);
324           else
325             errors = install_file_in_dir (argv[argc - 2], argv[argc - 1]);
326         }
327       else
328         {
329           if (!isdir (argv[argc - 1]))
330             usage (1);
331           for (; optind < argc - 1; ++optind)
332             {
333               errors |= install_file_in_dir (argv[optind], argv[argc - 1]);
334             }
335         }
336     }
337
338   if (verbose)
339     close_stdout ();
340   exit (errors);
341 }
342
343 /* Copy file FROM onto file TO, creating any missing parent directories of TO.
344    Return 0 if successful, 1 if an error occurs */
345
346 static int
347 install_file_to_path (const char *from, const char *to)
348 {
349   char *dest_dir;
350   int fail;
351
352   dest_dir = dirname (to);
353
354   /* check to make sure this is a path (not install a b ) */
355   if (!STREQ (dest_dir, ".")
356       && !isdir (dest_dir))
357     {
358       /* FIXME: Note that it's a little kludgey (even dangerous) that we
359          derive the permissions for parent directories from the permissions
360          specfied for the file, but since this option is intended mainly to
361          help installers when the distribution doesn't provide proper install
362          rules, it's not so bad.  Maybe use something like this instead:
363          int parent_dir_mode = (mode | (S_IRUGO | S_IXUGO)) & (~SPECIAL_BITS);
364          */
365       fail = make_path (dest_dir, mode, mode, owner_id, group_id, 0,
366                         (verbose ? _("creating directory `%s'") : NULL));
367     }
368   else
369     {
370       fail = install_file_in_file (from, to);
371     }
372
373   free (dest_dir);
374
375   return fail;
376 }
377
378 /* Copy file FROM onto file TO and give TO the appropriate
379    attributes.
380    Return 0 if successful, 1 if an error occurs. */
381
382 static int
383 install_file_in_file (const char *from, const char *to)
384 {
385   int to_created;
386   int no_need_to_chown;
387
388   if (copy_file (from, to, &to_created))
389     return 1;
390   if (strip_files)
391     strip (to);
392   no_need_to_chown = (to_created
393                       && owner_name == NULL
394                       && group_name == NULL);
395   if (change_attributes (to, no_need_to_chown))
396     return 1;
397   if (preserve_timestamps)
398     return change_timestamps (from, to);
399   return 0;
400 }
401
402 /* Copy file FROM into directory TO_DIR, keeping its same name,
403    and give the copy the appropriate attributes.
404    Return 0 if successful, 1 if not. */
405
406 static int
407 install_file_in_dir (const char *from, const char *to_dir)
408 {
409   char *from_base;
410   char *to;
411   int ret;
412
413   from_base = base_name (from);
414   to = xmalloc ((unsigned) (strlen (to_dir) + strlen (from_base) + 2));
415   stpcpy (stpcpy (stpcpy (to, to_dir), "/"), from_base);
416   ret = install_file_in_file (from, to);
417   free (to);
418   return ret;
419 }
420
421 /* A chunk of a file being copied. */
422 static char buffer[READ_SIZE];
423
424 /* Copy file FROM onto file TO, creating TO if necessary.
425    Return 0 if the copy is successful, 1 if not.  If the copy is
426    successful, set *TO_CREATED to nonzero if TO was created (if it did
427    not exist or did, but was unlinked) and to zero otherwise.  If the
428    copy fails, don't modify *TO_CREATED.  */
429
430 static int
431 copy_file (const char *from, const char *to, int *to_created)
432 {
433   int fromfd, tofd;
434   int bytes;
435   int ret = 0;
436   struct stat from_stats, to_stats;
437   int target_created = 1;
438
439   if (stat (from, &from_stats))
440     {
441       error (0, errno, "%s", from);
442       return 1;
443     }
444
445   /* Allow installing from non-regular files like /dev/null.
446      Charles Karney reported that some Sun version of install allows that
447      and that sendmail's installation process relies on the behavior.  */
448   if (S_ISDIR (from_stats.st_mode))
449     {
450       error (0, 0, _("`%s' is a directory"), from);
451       return 1;
452     }
453   if (stat (to, &to_stats) == 0)
454     {
455       if (!S_ISREG (to_stats.st_mode))
456         {
457           error (0, 0, _("`%s' is not a regular file"), to);
458           return 1;
459         }
460       if (from_stats.st_dev == to_stats.st_dev
461           && from_stats.st_ino == to_stats.st_ino)
462         {
463           error (0, 0, _("`%s' and `%s' are the same file"), from, to);
464           return 1;
465         }
466
467       /* The destination file exists.  Try to back it up if required.  */
468       if (backup_type != none)
469         {
470           char *tmp_backup = find_backup_file_name (to, backup_type);
471           char *dst_backup;
472
473           if (tmp_backup == NULL)
474             error (1, 0, "virtual memory exhausted");
475           dst_backup = (char *) alloca (strlen (tmp_backup) + 1);
476           strcpy (dst_backup, tmp_backup);
477           free (tmp_backup);
478           if (rename (to, dst_backup))
479             {
480               if (errno != ENOENT)
481                 {
482                   error (0, errno, "cannot backup `%s'", to);
483                   return 1;
484                 }
485             }
486         }
487
488       /* If unlink fails, try to proceed anyway.  */
489       if (unlink (to))
490         target_created = 0;
491     }
492
493   /* Now it's the time to give some feedback if requested.  */
494   if (verbose)
495     printf ("copying `%s' to `%s'\n", from, to);
496
497   fromfd = open (from, O_RDONLY, 0);
498   if (fromfd == -1)
499     {
500       error (0, errno, "%s", from);
501       return 1;
502     }
503
504   /* Make sure to open the file in a mode that allows writing. */
505   tofd = open (to, O_WRONLY | O_CREAT | O_TRUNC, 0600);
506   if (tofd == -1)
507     {
508       error (0, errno, "%s", to);
509       close (fromfd);
510       return 1;
511     }
512
513   while ((bytes = safe_read (fromfd, buffer, READ_SIZE)) > 0)
514     if (full_write (tofd, buffer, bytes) < 0)
515       {
516         error (0, errno, "%s", to);
517         goto copy_error;
518       }
519
520   if (bytes == -1)
521     {
522       error (0, errno, "%s", from);
523       goto copy_error;
524     }
525
526   if (close (fromfd) < 0)
527     {
528       error (0, errno, "%s", from);
529       ret = 1;
530     }
531   if (close (tofd) < 0)
532     {
533       error (0, errno, "%s", to);
534       ret = 1;
535     }
536   if (ret == 0)
537     *to_created = target_created;
538   return ret;
539
540  copy_error:
541   close (fromfd);
542   close (tofd);
543   return 1;
544 }
545
546 /* Set the attributes of file or directory PATH.
547    If NO_NEED_TO_CHOWN is nonzero, don't call chown.
548    Return 0 if successful, 1 if not. */
549
550 static int
551 change_attributes (const char *path, int no_need_to_chown)
552 {
553   int err = 0;
554
555   /* chown must precede chmod because on some systems,
556      chown clears the set[ug]id bits for non-superusers,
557      resulting in incorrect permissions.
558      On System V, users can give away files with chown and then not
559      be able to chmod them.  So don't give files away.
560
561      We don't pass -1 to chown to mean "don't change the value"
562      because SVR3 and earlier non-BSD systems don't support that.
563
564      We don't normally ignore errors from chown because the idea of
565      the install command is that the file is supposed to end up with
566      precisely the attributes that the user specified (or defaulted).
567      If the file doesn't end up with the group they asked for, they'll
568      want to know.  But AFS returns EPERM when you try to change a
569      file's group; thus the kludge.  */
570
571   if (!no_need_to_chown && chown (path, owner_id, group_id)
572 #ifdef AFS
573       && errno != EPERM
574 #endif
575       )
576     err = errno;
577   if (chmod (path, mode))
578     err = errno;
579   if (err)
580     {
581       error (0, err, "%s", path);
582       return 1;
583     }
584   return 0;
585 }
586
587 /* Set the timestamps of file TO to match those of file FROM.
588    Return 0 if successful, 1 if not. */
589
590 static int
591 change_timestamps (const char *from, const char *to)
592 {
593   struct stat stb;
594   struct utimbuf utb;
595
596   if (stat (from, &stb))
597     {
598       error (0, errno, "%s", from);
599       return 1;
600     }
601   utb.actime = stb.st_atime;
602   utb.modtime = stb.st_mtime;
603   if (utime (to, &utb))
604     {
605       error (0, errno, "%s", to);
606       return 1;
607     }
608   return 0;
609 }
610
611 /* Strip the symbol table from the file PATH.
612    We could dig the magic number out of the file first to
613    determine whether to strip it, but the header files and
614    magic numbers vary so much from system to system that making
615    it portable would be very difficult.  Not worth the effort. */
616
617 static void
618 strip (const char *path)
619 {
620   int pid, status;
621
622   pid = fork ();
623   switch (pid)
624     {
625     case -1:
626       error (1, errno, _("fork system call failed"));
627       break;
628     case 0:                     /* Child. */
629       execlp ("strip", "strip", path, NULL);
630       error (1, errno, _("cannot run strip"));
631       break;
632     default:                    /* Parent. */
633       /* Parent process. */
634       while (pid != wait (&status))     /* Wait for kid to finish. */
635         /* Do nothing. */ ;
636       break;
637     }
638 }
639
640 /* Initialize the user and group ownership of the files to install. */
641
642 static void
643 get_ids (void)
644 {
645   struct passwd *pw;
646   struct group *gr;
647
648   if (owner_name)
649     {
650       pw = getpwnam (owner_name);
651       if (pw == NULL)
652         {
653           long int tmp_long;
654           if (xstrtol (owner_name, NULL, 0, &tmp_long, NULL) != LONGINT_OK
655               || tmp_long < 0 || tmp_long > UID_T_MAX)
656             error (1, 0, _("invalid user `%s'"), owner_name);
657           owner_id = (uid_t) tmp_long;
658         }
659       else
660         owner_id = pw->pw_uid;
661       endpwent ();
662     }
663   else
664     owner_id = (uid_t) -1;
665
666   if (group_name)
667     {
668       gr = getgrnam (group_name);
669       if (gr == NULL)
670         {
671           long int tmp_long;
672           if (xstrtol (group_name, NULL, 0, &tmp_long, NULL) != LONGINT_OK
673               || tmp_long < 0 || tmp_long > GID_T_MAX)
674             error (1, 0, _("invalid group `%s'"), group_name);
675           group_id = (gid_t) tmp_long;
676         }
677       else
678         group_id = gr->gr_gid;
679       endgrent ();
680     }
681   else
682     group_id = (gid_t) -1;
683 }
684
685 static void
686 usage (int status)
687 {
688   if (status != 0)
689     fprintf (stderr, _("Try `%s --help' for more information.\n"),
690              program_name);
691   else
692     {
693       printf (_("\
694 Usage: %s [OPTION]... SOURCE DEST           (1st format)\n\
695   or:  %s [OPTION]... SOURCE... DIRECTORY   (2nd format)\n\
696   or:  %s -d [OPTION]... DIRECTORY...       (3rd format)\n\
697 "),
698               program_name, program_name, program_name);
699       printf (_("\
700 In the first two formats, copy SOURCE to DEST or multiple SOURCE(s) to\n\
701 the existing DIRECTORY, while setting permission modes and owner/group.\n\
702 In the third format, create all components of the given DIRECTORY(ies).\n\
703 \n\
704   -b, --backup        make backup before removal\n\
705   -c                  (ignored)\n\
706   -d, --directory     treat all arguments as directory names; create all\n\
707                         components of the specified directories\n\
708   -D                  create all leading components of DEST except the last,\n\
709                         then copy SOURCE to DEST;  useful in the 1st format\n\
710   -g, --group=GROUP   set group ownership, instead of process' current group\n\
711   -m, --mode=MODE     set permission mode (as in chmod), instead of rwxr-xr-x\n\
712   -o, --owner=OWNER   set ownership (super-user only)\n\
713   -p, --preserve-timestamps   apply access/modification times of SOURCE files\n\
714                         to corresponding destination files\n\
715   -s, --strip         strip symbol tables, only for 1st and 2nd formats\n\
716   -S, --suffix=SUFFIX override the usual backup suffix\n\
717       --verbose       print the name of each directory as it is created\n\
718   -V, --version-control=WORD   override the usual version control\n\
719       --help          display this help and exit\n\
720       --version       output version information and exit\n\
721 \n\
722 "));
723       printf (_("\
724 The backup suffix is ~, unless set with SIMPLE_BACKUP_SUFFIX.  The\n\
725 version control may be set with VERSION_CONTROL, values are:\n\
726 \n\
727   t, numbered     make numbered backups\n\
728   nil, existing   numbered if numbered backups exist, simple otherwise\n\
729   never, simple   always make simple backups\n\
730 "));
731       puts (_("\nReport bugs to <fileutils-bugs@gnu.org>."));
732       close_stdout ();
733     }
734   exit (status);
735 }