When lstat returns an error (such as file not found), the value of
authorlandley <landley@69ca8d6d-28ef-0310-b511-8ec308f3f277>
Sun, 9 Oct 2005 11:16:01 +0000 (11:16 +0000)
committerlandley <landley@69ca8d6d-28ef-0310-b511-8ec308f3f277>
Sun, 9 Oct 2005 11:16:01 +0000 (11:16 +0000)
st_mode is random garbage (under uClibc), leading to random triggering
of the S_ISDIR() case when the destination will be a normal file which
doesn't exist yet.  I.E. checking the return value of lstat is not optional.

git-svn-id: svn://busybox.net/trunk/busybox@11815 69ca8d6d-28ef-0310-b511-8ec308f3f277

coreutils/install.c

index d046041..9fcb754 100644 (file)
@@ -51,7 +51,6 @@ static const struct option install_long_options[] = {
 
 extern int install_main(int argc, char **argv)
 {
-       struct stat statbuf;
        mode_t mode;
        uid_t uid;
        gid_t gid;
@@ -59,9 +58,7 @@ extern int install_main(int argc, char **argv)
        char *uid_str = "-1";
        char *mode_str = "0755";
        int copy_flags = FILEUTILS_DEREFERENCE | FILEUTILS_FORCE;
-       int ret = EXIT_SUCCESS;
-       int flags;
-       int i;
+       int ret = EXIT_SUCCESS, flags, i, isdir;
 
        bb_applet_long_options = install_long_options;
        bb_opt_complementally = "!s~d:d~s";
@@ -112,15 +109,16 @@ extern int install_main(int argc, char **argv)
                return(ret);
        }
 
-       cp_mv_stat2(argv[argc - 1], &statbuf, lstat);
+       {
+               struct stat statbuf;
+               isdir = lstat(argv[argc - 1], &statbuf)<0
+                                       ? 0 : S_ISDIR(statbuf.st_mode);
+       }
        for (i = optind; i < argc - 1; i++) {
                unsigned char *dest;
 
-               if (S_ISDIR(statbuf.st_mode)) {
-                       dest = concat_path_file(argv[argc - 1], basename(argv[i]));
-               } else {
-                       dest = argv[argc - 1];
-               }
+               dest = argv[argc - 1];
+               if (isdir) dest = concat_path_file(argv[argc - 1], basename(argv[i]));
                ret |= copy_file(argv[i], dest, copy_flags);
 
                /* Set the file mode */
@@ -140,6 +138,7 @@ extern int install_main(int argc, char **argv)
                                ret = EXIT_FAILURE;
                        }
                }
+               if(ENABLE_FEATURE_CLEAN_UP && isdir) free(dest);
        }
 
        return(ret);