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