diff options
| author | Ron Yorston <rmy@pobox.com> | 2024-10-08 11:54:51 +0100 |
|---|---|---|
| committer | Ron Yorston <rmy@pobox.com> | 2024-10-08 12:09:30 +0100 |
| commit | ded78ca2656fd41f130d65345b0eb4d39b1fcbdf (patch) | |
| tree | ec6a2dfab77f2a49a9629d29df371a3d93256929 /shell | |
| parent | 054f494916093715bc1d2d25a7a452a036d41add (diff) | |
| parent | 75ca8d074bacb6896d770993b93161c40aa31b9f (diff) | |
| download | busybox-w32-ded78ca2656fd41f130d65345b0eb4d39b1fcbdf.tar.gz busybox-w32-ded78ca2656fd41f130d65345b0eb4d39b1fcbdf.tar.bz2 busybox-w32-ded78ca2656fd41f130d65345b0eb4d39b1fcbdf.zip | |
Merge branch 'busybox' into merge
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/hush.c | 86 |
1 files changed, 57 insertions, 29 deletions
diff --git a/shell/hush.c b/shell/hush.c index 6b6ec7c6b..04dda0734 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
| @@ -1022,6 +1022,13 @@ struct globals { | |||
| 1022 | #if HUSH_DEBUG >= 2 | 1022 | #if HUSH_DEBUG >= 2 |
| 1023 | int debug_indent; | 1023 | int debug_indent; |
| 1024 | #endif | 1024 | #endif |
| 1025 | #if ENABLE_HUSH_TEST || BASH_TEST2 | ||
| 1026 | /* Cached supplementary group array (for testing executable'ity of files) */ | ||
| 1027 | struct cached_groupinfo groupinfo; | ||
| 1028 | # define GROUPINFO_INIT { G.groupinfo.euid = -1; G.groupinfo.egid = -1; } | ||
| 1029 | #else | ||
| 1030 | # define GROUPINFO_INIT /* nothing */ | ||
| 1031 | #endif | ||
| 1025 | struct sigaction sa; | 1032 | struct sigaction sa; |
| 1026 | char optstring_buf[sizeof("eixcs")]; | 1033 | char optstring_buf[sizeof("eixcs")]; |
| 1027 | #if BASH_EPOCH_VARS | 1034 | #if BASH_EPOCH_VARS |
| @@ -1040,6 +1047,7 @@ struct globals { | |||
| 1040 | /* memset(&G.sa, 0, sizeof(G.sa)); */ \ | 1047 | /* memset(&G.sa, 0, sizeof(G.sa)); */ \ |
| 1041 | sigfillset(&G.sa.sa_mask); \ | 1048 | sigfillset(&G.sa.sa_mask); \ |
| 1042 | G.sa.sa_flags = SA_RESTART; \ | 1049 | G.sa.sa_flags = SA_RESTART; \ |
| 1050 | GROUPINFO_INIT; \ | ||
| 1043 | } while (0) | 1051 | } while (0) |
| 1044 | 1052 | ||
| 1045 | /* Function prototypes for builtins */ | 1053 | /* Function prototypes for builtins */ |
| @@ -8193,38 +8201,53 @@ static int setup_redirects(struct command *prog, struct squirrel **sqp) | |||
| 8193 | return 0; | 8201 | return 0; |
| 8194 | } | 8202 | } |
| 8195 | 8203 | ||
| 8196 | static char *find_in_path(const char *arg) | 8204 | /* Find a file in PATH, not necessarily executable |
| 8205 | * Name is known to not contain '/'. | ||
| 8206 | */ | ||
| 8207 | //TODO: shares code with find_executable() in libbb, factor out? | ||
| 8208 | static char *find_in_PATH(const char *name) | ||
| 8197 | { | 8209 | { |
| 8198 | char *ret = NULL; | 8210 | char *p = (char*) get_local_var_value("PATH"); |
| 8199 | const char *PATH = get_local_var_value("PATH"); | ||
| 8200 | 8211 | ||
| 8201 | if (!PATH) | 8212 | if (!p) |
| 8202 | return NULL; | 8213 | return NULL; |
| 8203 | |||
| 8204 | while (1) { | 8214 | while (1) { |
| 8205 | const char *end = strchrnul(PATH, ':'); | 8215 | const char *end = strchrnul(p, ':'); |
| 8206 | int sz = end - PATH; /* must be int! */ | 8216 | int sz = end - p; /* must be int! */ |
| 8207 | 8217 | ||
| 8208 | free(ret); | ||
| 8209 | if (sz != 0) { | 8218 | if (sz != 0) { |
| 8210 | ret = xasprintf("%.*s/%s", sz, PATH, arg); | 8219 | p = xasprintf("%.*s/%s", sz, p, name); |
| 8211 | } else { | 8220 | } else { |
| 8212 | /* We have xxx::yyyy in $PATH, | 8221 | /* We have xxx::yyy in $PATH, |
| 8213 | * it means "use current dir" */ | 8222 | * it means "use current dir" */ |
| 8214 | ret = xstrdup(arg); | 8223 | p = xstrdup(name); |
| 8215 | } | 8224 | } |
| 8216 | if (access(ret, F_OK) == 0) | 8225 | if (access(p, F_OK) == 0) |
| 8217 | break; | 8226 | return p; |
| 8218 | 8227 | free(p); | |
| 8219 | if (*end == '\0') { | 8228 | if (*end == '\0') |
| 8220 | free(ret); | ||
| 8221 | return NULL; | 8229 | return NULL; |
| 8222 | } | 8230 | p = (char *) end + 1; |
| 8223 | PATH = end + 1; | ||
| 8224 | } | 8231 | } |
| 8232 | } | ||
| 8225 | 8233 | ||
| 8226 | return ret; | 8234 | #if ENABLE_HUSH_TYPE || ENABLE_HUSH_COMMAND |
| 8235 | static char *find_executable_in_PATH(const char *name) | ||
| 8236 | { | ||
| 8237 | const char *PATH; | ||
| 8238 | if (strchr(name, '/')) { | ||
| 8239 | /* Name with '/' is tested verbatim, with no PATH traversal: | ||
| 8240 | * "cd /bin; type ./cat" should print "./cat is ./cat", | ||
| 8241 | * NOT "./cat is /bin/./cat" | ||
| 8242 | */ | ||
| 8243 | if (file_is_executable(name)) | ||
| 8244 | return xstrdup(name); | ||
| 8245 | return NULL; | ||
| 8246 | } | ||
| 8247 | PATH = get_local_var_value("PATH"); | ||
| 8248 | return find_executable(name, &PATH); /* path == NULL is ok */ | ||
| 8227 | } | 8249 | } |
| 8250 | #endif | ||
| 8228 | 8251 | ||
| 8229 | static const struct built_in_command *find_builtin_helper(const char *name, | 8252 | static const struct built_in_command *find_builtin_helper(const char *name, |
| 8230 | const struct built_in_command *x, | 8253 | const struct built_in_command *x, |
| @@ -8635,10 +8658,11 @@ static void if_command_vV_print_and_exit(char opt_vV, char *cmd, const char *exp | |||
| 8635 | 8658 | ||
| 8636 | to_free = NULL; | 8659 | to_free = NULL; |
| 8637 | if (!explanation) { | 8660 | if (!explanation) { |
| 8638 | char *path = getenv("PATH"); | 8661 | explanation = to_free = find_executable_in_PATH(cmd); |
| 8639 | explanation = to_free = find_executable(cmd, &path); /* path == NULL is ok */ | 8662 | if (!explanation) { |
| 8640 | if (!explanation) | 8663 | bb_error_msg("%s: %s: not found", "command", cmd); |
| 8641 | _exit(1); /* PROG was not found */ | 8664 | _exit(1); /* PROG was not found */ |
| 8665 | } | ||
| 8642 | if (opt_vV != 'V') | 8666 | if (opt_vV != 'V') |
| 8643 | cmd = to_free; /* -v PROG prints "/path/to/PROG" */ | 8667 | cmd = to_free; /* -v PROG prints "/path/to/PROG" */ |
| 8644 | } | 8668 | } |
| @@ -10870,7 +10894,8 @@ static NOINLINE int run_applet_main(char **argv, int (*applet_main_func)(int arg | |||
| 10870 | #if ENABLE_HUSH_TEST || BASH_TEST2 | 10894 | #if ENABLE_HUSH_TEST || BASH_TEST2 |
| 10871 | static int FAST_FUNC builtin_test(char **argv) | 10895 | static int FAST_FUNC builtin_test(char **argv) |
| 10872 | { | 10896 | { |
| 10873 | return run_applet_main(argv, test_main); | 10897 | int argc = string_array_len(argv); |
| 10898 | return test_main2(&G.groupinfo, argc, argv); | ||
| 10874 | } | 10899 | } |
| 10875 | #endif | 10900 | #endif |
| 10876 | #if ENABLE_HUSH_ECHO | 10901 | #if ENABLE_HUSH_ECHO |
| @@ -11063,12 +11088,15 @@ static int FAST_FUNC builtin_type(char **argv) | |||
| 11063 | # endif | 11088 | # endif |
| 11064 | else if (find_builtin(*argv)) | 11089 | else if (find_builtin(*argv)) |
| 11065 | type = "a shell builtin"; | 11090 | type = "a shell builtin"; |
| 11066 | else if ((path = find_in_path(*argv)) != NULL) | ||
| 11067 | type = path; | ||
| 11068 | else { | 11091 | else { |
| 11069 | bb_error_msg("type: %s: not found", *argv); | 11092 | path = find_executable_in_PATH(*argv); |
| 11070 | ret = EXIT_FAILURE; | 11093 | if (path) |
| 11071 | continue; | 11094 | type = path; |
| 11095 | else { | ||
| 11096 | bb_error_msg("%s: %s: not found", "type", *argv); | ||
| 11097 | ret = EXIT_FAILURE; | ||
| 11098 | continue; | ||
| 11099 | } | ||
| 11072 | } | 11100 | } |
| 11073 | 11101 | ||
| 11074 | printf("%s is %s\n", *argv, type); | 11102 | printf("%s is %s\n", *argv, type); |
| @@ -11695,7 +11723,7 @@ static int FAST_FUNC builtin_source(char **argv) | |||
| 11695 | } | 11723 | } |
| 11696 | arg_path = NULL; | 11724 | arg_path = NULL; |
| 11697 | if (!strchr(filename, '/')) { | 11725 | if (!strchr(filename, '/')) { |
| 11698 | arg_path = find_in_path(filename); | 11726 | arg_path = find_in_PATH(filename); |
| 11699 | if (arg_path) | 11727 | if (arg_path) |
| 11700 | filename = arg_path; | 11728 | filename = arg_path; |
| 11701 | else if (!ENABLE_HUSH_BASH_SOURCE_CURDIR) { | 11729 | else if (!ENABLE_HUSH_BASH_SOURCE_CURDIR) { |
