install: do not chown intermediate directories with install -d; shrink
authorDenis Vlasenko <vda.linux@googlemail.com>
Wed, 16 Jul 2008 21:49:02 +0000 (21:49 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Wed, 16 Jul 2008 21:49:02 +0000 (21:49 -0000)
 (by Natanael Copa)

function                                             old     new   delta
.rodata                                           171528  171511     -17
install_main                                         841     697    -144
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-161)           Total: -161 bytes

coreutils/install.c

index 0b5eda0acdc42b47a26dab34801deb41e2a2613e..c5d7a0cc5d9ff2160f505397a96faf7a54ab656b 100644 (file)
@@ -76,8 +76,9 @@ int install_main(int argc, char **argv)
        const char *mode_str;
        int copy_flags = FILEUTILS_DEREFERENCE | FILEUTILS_FORCE;
        int flags;
+       int min_args = 1;
        int ret = EXIT_SUCCESS;
-       int isdir;
+       int isdir = 0;
 #if ENABLE_SELINUX
        security_context_t scontext;
        bool use_default_selinux_context = 1;
@@ -133,58 +134,38 @@ int install_main(int argc, char **argv)
                bb_parse_mode(mode_str, &mode);
        uid = (flags & OPT_OWNER) ? get_ug_id(uid_str, xuname2uid) : getuid();
        gid = (flags & OPT_GROUP) ? get_ug_id(gid_str, xgroup2gid) : getgid();
-       if (flags & (OPT_OWNER|OPT_GROUP))
-               umask(0);
-
-       /* Create directories
-        * don't use bb_make_directory() as it can't change uid or gid
-        * perhaps bb_make_directory() should be improved.
-        */
-       if (flags & OPT_DIRECTORY) {
-               while ((arg = *argv++) != NULL) {
-                       char *slash = arg;
-                       while (1) {
-                               slash = strchr(slash + 1, '/');
-                               if (slash)
-                                       *slash = '\0';
-                               if (mkdir(arg, mode | 0111) == -1) {
-                                       if (errno != EEXIST) {
-                                               bb_perror_msg("cannot create %s", arg);
-                                               ret = EXIT_FAILURE;
-                                               break;
-                                       }
-                               } /* dir was created, chown? */
-                               else if ((flags & (OPT_OWNER|OPT_GROUP))
-                                && lchown(arg, uid, gid) == -1
-                               ) {
-                                       bb_perror_msg("cannot change ownership of %s", arg);
-                                       ret = EXIT_FAILURE;
-                                       break;
-                               }
-                               if (!slash)
-                                       break;
-                               *slash = '/';
-                       }
-               }
-               return ret;
+
+       last = argv[argc - 1];
+       if (!(flags & OPT_DIRECTORY)) {
+               argv[argc - 1] = NULL;
+               min_args++;
+
+               /* coreutils install resolves link in this case, don't use lstat */
+               isdir = stat(last, &statbuf) < 0 ? 0 : S_ISDIR(statbuf.st_mode);
        }
 
-       if (argc < 2)
+       if (argc < min_args)
                bb_show_usage();
 
-       last = argv[argc - 1];
-       argv[argc - 1] = NULL;
-       /* coreutils install resolves link in this case, don't use lstat */
-       isdir = stat(last, &statbuf) < 0 ? 0 : S_ISDIR(statbuf.st_mode);
-
        while ((arg = *argv++) != NULL) {
                char *dest = last;
-               if (isdir)
-                       dest = concat_path_file(last, basename(arg));
-               if (copy_file(arg, dest, copy_flags)) {
-                       /* copy is not made */
-                       ret = EXIT_FAILURE;
-                       goto next;
+               if (flags & OPT_DIRECTORY) {
+                       dest = arg;
+                       /* GNU coreutils 6.9 does not set uid:gid
+                        * on intermediate created directories
+                        * (only on last one) */
+                       if (bb_make_directory(dest, 0755, FILEUTILS_RECUR)) {
+                               ret = EXIT_FAILURE;
+                               goto next;
+                       }
+               } else {
+                       if (isdir)
+                               dest = concat_path_file(last, basename(arg));
+                       if (copy_file(arg, dest, copy_flags)) {
+                               /* copy is not made */
+                               ret = EXIT_FAILURE;
+                               goto next;
+                       }
                }
 
                /* Set the file mode */