install: shrink a bit, fix two buglets
No binary (build failed)
—
(log yok)
| @@ -73,11 +73,14 @@ int install_main(int argc, char **argv) | |
| mode_t mode; | |
| uid_t uid; | |
| gid_t gid; | |
| + | char *arg, *last; |
| const char *gid_str; | |
| const char *uid_str; | |
| const char *mode_str; | |
| int copy_flags = FILEUTILS_DEREFERENCE | FILEUTILS_FORCE; | |
| - | int ret = EXIT_SUCCESS, flags, i, isdir; |
| + | int flags; |
| + | int ret = EXIT_SUCCESS; |
| + | int isdir; |
| #if ENABLE_SELINUX | |
| security_context_t scontext; | |
| #endif | |
| @@ -103,6 +106,8 @@ int install_main(int argc, char **argv) | |
| flags = getopt32(argv, "cdpsg:m:o:" USE_SELINUX("Z:"), | |
| &gid_str, &mode_str, &uid_str USE_SELINUX(, &scontext)); | |
| + | argc -= optind; |
| + | argv += optind; |
| #if ENABLE_SELINUX | |
| if (flags & OPT_PRESERVE_SECURITY_CONTEXT) { | |
| @@ -135,48 +140,50 @@ int install_main(int argc, char **argv) | |
| * perhaps bb_make_directory() should be improved. | |
| */ | |
| if (flags & OPT_DIRECTORY) { | |
| - | for (argv += optind; *argv; argv++) { |
| - | char *old_argv_ptr = *argv + 1; |
| - | char *argv_ptr; |
| - | do { |
| - | argv_ptr = strchr(old_argv_ptr, '/'); |
| - | old_argv_ptr = argv_ptr; |
| - | if (argv_ptr) { |
| - | *argv_ptr = '\0'; |
| - | old_argv_ptr++; |
| - | } |
| - | if (mkdir(*argv, mode | 0111) == -1) { |
| + | 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", *argv); |
| + | bb_perror_msg("cannot create %s", arg); |
| ret = EXIT_FAILURE; | |
| break; | |
| } | |
| - | } |
| - | if ((flags & (OPT_OWNER|OPT_GROUP)) |
| - | && lchown(*argv, uid, gid) == -1 |
| + | } /* dir was created, chown? */ |
| + | else if ((flags & (OPT_OWNER|OPT_GROUP)) |
| + | && lchown(arg, uid, gid) == -1 |
| ) { | |
| - | bb_perror_msg("cannot change ownership of %s", *argv); |
| + | bb_perror_msg("cannot change ownership of %s", arg); |
| ret = EXIT_FAILURE; | |
| break; | |
| } | |
| - | if (argv_ptr) { |
| - | *argv_ptr = '/'; |
| - | } |
| - | } while (old_argv_ptr); |
| + | if (!slash) |
| + | break; |
| + | *slash = '/'; |
| + | } |
| } | |
| return ret; | |
| } | |
| - | /* coreutils install resolves link in this case, don't use lstat */ |
| - | isdir = stat(argv[argc - 1], &statbuf) < 0 ? 0 : S_ISDIR(statbuf.st_mode); |
| + | if (argc < 2) |
| + | bb_show_usage(); |
| - | for (i = optind; i < argc - 1; i++) { |
| - | char *dest; |
| + | last = argv[argc - 1]; |
| + | /* coreutils install resolves link in this case, don't use lstat */ |
| + | isdir = stat(last, &statbuf) < 0 ? 0 : S_ISDIR(statbuf.st_mode); |
| - | dest = argv[argc - 1]; |
| + | while ((arg = *argv++) != NULL) { |
| + | char *dest = last; |
| if (isdir) | |
| - | dest = concat_path_file(argv[argc - 1], basename(argv[i])); |
| - | ret |= copy_file(argv[i], dest, copy_flags); |
| + | 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 */ | |
| if ((flags & OPT_MODE) && chmod(dest, mode) == -1) { | |
| @@ -204,7 +211,9 @@ int install_main(int argc, char **argv) | |
| ret = EXIT_FAILURE; | |
| } | |
| } | |
| - | if (ENABLE_FEATURE_CLEAN_UP && isdir) free(dest); |
| + | next: |
| + | if (ENABLE_FEATURE_CLEAN_UP && isdir) |
| + | free(dest); |
| } | |
| return ret; | |