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