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