diff options
Diffstat (limited to 'libbb/appletlib.c')
| -rw-r--r-- | libbb/appletlib.c | 335 |
1 files changed, 329 insertions, 6 deletions
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 17216baab..496d320cd 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
| @@ -53,6 +53,15 @@ static inline int *get_perrno(void) { return &errno; } | |||
| 53 | # define IF_FEATURE_INDIVIDUAL(...) __VA_ARGS__ | 53 | # define IF_FEATURE_INDIVIDUAL(...) __VA_ARGS__ |
| 54 | #endif | 54 | #endif |
| 55 | 55 | ||
| 56 | #if (ENABLE_FEATURE_INSTALLER && !ENABLE_PLATFORM_MINGW32) || \ | ||
| 57 | (ENABLE_PLATFORM_MINGW32 && (ENABLE_FEATURE_PREFER_APPLETS \ | ||
| 58 | || ENABLE_FEATURE_SH_STANDALONE \ | ||
| 59 | || ENABLE_FEATURE_SH_NOFORK)) | ||
| 60 | # define IF_FULL_LIST_OPTION(...) __VA_ARGS__ | ||
| 61 | #else | ||
| 62 | # define IF_FULL_LIST_OPTION(...) | ||
| 63 | #endif | ||
| 64 | |||
| 56 | #include "usage_compressed.h" | 65 | #include "usage_compressed.h" |
| 57 | 66 | ||
| 58 | #if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS | 67 | #if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS |
| @@ -62,6 +71,7 @@ static inline int *get_perrno(void) { return &errno; } | |||
| 62 | # define NUM_SCRIPTS 0 | 71 | # define NUM_SCRIPTS 0 |
| 63 | #endif | 72 | #endif |
| 64 | #if NUM_SCRIPTS > 0 | 73 | #if NUM_SCRIPTS > 0 |
| 74 | # define BB_ARCHIVE_PUBLIC | ||
| 65 | # include "bb_archive.h" | 75 | # include "bb_archive.h" |
| 66 | static const char packed_scripts[] ALIGN1 = { PACKED_SCRIPTS }; | 76 | static const char packed_scripts[] ALIGN1 = { PACKED_SCRIPTS }; |
| 67 | #endif | 77 | #endif |
| @@ -90,6 +100,12 @@ static const char packed_scripts[] ALIGN1 = { PACKED_SCRIPTS }; | |||
| 90 | # define ENABLE_FEATURE_COMPRESS_USAGE 0 | 100 | # define ENABLE_FEATURE_COMPRESS_USAGE 0 |
| 91 | #endif | 101 | #endif |
| 92 | 102 | ||
| 103 | #if ENABLE_PLATFORM_MINGW32 && NUM_APPLETS > 1 && \ | ||
| 104 | ENABLE_FEATURE_SH_STANDALONE | ||
| 105 | static int find_applet_by_name_internal(const char *name); | ||
| 106 | #else | ||
| 107 | # define find_applet_by_name_internal(n) find_applet_by_name(n) | ||
| 108 | #endif | ||
| 93 | 109 | ||
| 94 | unsigned FAST_FUNC string_array_len(char **argv) | 110 | unsigned FAST_FUNC string_array_len(char **argv) |
| 95 | { | 111 | { |
| @@ -111,6 +127,7 @@ static const char usage_messages[] ALIGN1 = UNPACKED_USAGE; | |||
| 111 | #if ENABLE_FEATURE_COMPRESS_USAGE | 127 | #if ENABLE_FEATURE_COMPRESS_USAGE |
| 112 | 128 | ||
| 113 | static const char packed_usage[] ALIGN1 = { PACKED_USAGE }; | 129 | static const char packed_usage[] ALIGN1 = { PACKED_USAGE }; |
| 130 | # define BB_ARCHIVE_PUBLIC | ||
| 114 | # include "bb_archive.h" | 131 | # include "bb_archive.h" |
| 115 | # define unpack_usage_messages() \ | 132 | # define unpack_usage_messages() \ |
| 116 | unpack_bz2_data(packed_usage, sizeof(packed_usage), sizeof(UNPACKED_USAGE)) | 133 | unpack_bz2_data(packed_usage, sizeof(packed_usage), sizeof(UNPACKED_USAGE)) |
| @@ -147,7 +164,7 @@ void FAST_FUNC bb_show_usage(void) | |||
| 147 | #else | 164 | #else |
| 148 | const char *p; | 165 | const char *p; |
| 149 | const char *usage_string = p = unpack_usage_messages(); | 166 | const char *usage_string = p = unpack_usage_messages(); |
| 150 | int ap = find_applet_by_name(applet_name); | 167 | int ap = find_applet_by_name_internal(applet_name); |
| 151 | 168 | ||
| 152 | if (ap < 0 || usage_string == NULL) | 169 | if (ap < 0 || usage_string == NULL) |
| 153 | xfunc_die(); | 170 | xfunc_die(); |
| @@ -156,7 +173,11 @@ void FAST_FUNC bb_show_usage(void) | |||
| 156 | ap--; | 173 | ap--; |
| 157 | } | 174 | } |
| 158 | full_write_fn(bb_banner); | 175 | full_write_fn(bb_banner); |
| 176 | #if ENABLE_PLATFORM_MINGW32 | ||
| 177 | full_write_fn("\n"); | ||
| 178 | #else | ||
| 159 | full_write_fn(" multi-call binary.\n"); /* common string */ | 179 | full_write_fn(" multi-call binary.\n"); /* common string */ |
| 180 | #endif | ||
| 160 | if (*p == '\b') | 181 | if (*p == '\b') |
| 161 | full_write_fn("\nNo help available\n"); | 182 | full_write_fn("\nNo help available\n"); |
| 162 | else { | 183 | else { |
| @@ -176,7 +197,12 @@ void FAST_FUNC bb_show_usage(void) | |||
| 176 | xfunc_die(); | 197 | xfunc_die(); |
| 177 | } | 198 | } |
| 178 | 199 | ||
| 200 | #if ENABLE_PLATFORM_MINGW32 && NUM_APPLETS > 1 && \ | ||
| 201 | ENABLE_FEATURE_SH_STANDALONE | ||
| 202 | static int find_applet_by_name_internal(const char *name) | ||
| 203 | #else | ||
| 179 | int FAST_FUNC find_applet_by_name(const char *name) | 204 | int FAST_FUNC find_applet_by_name(const char *name) |
| 205 | #endif | ||
| 180 | { | 206 | { |
| 181 | unsigned i; | 207 | unsigned i; |
| 182 | int j; | 208 | int j; |
| @@ -241,6 +267,83 @@ int FAST_FUNC find_applet_by_name(const char *name) | |||
| 241 | return -1; | 267 | return -1; |
| 242 | } | 268 | } |
| 243 | 269 | ||
| 270 | #if ENABLE_PLATFORM_MINGW32 && NUM_APPLETS > 1 | ||
| 271 | # if ENABLE_FEATURE_SH_STANDALONE | ||
| 272 | int FAST_FUNC find_applet_by_name_for_sh(const char *name, const char *path) | ||
| 273 | { | ||
| 274 | int applet_no = find_applet_by_name_internal(name); | ||
| 275 | return applet_no >= 0 && prefer_applet(name, path) ? applet_no : -1; | ||
| 276 | } | ||
| 277 | |||
| 278 | int FAST_FUNC find_applet_by_name(const char *name) | ||
| 279 | { | ||
| 280 | return find_applet_by_name_for_sh(name, NULL); | ||
| 281 | } | ||
| 282 | # endif | ||
| 283 | |||
| 284 | # if ENABLE_FEATURE_SH_STANDALONE || ENABLE_FEATURE_PREFER_APPLETS | ||
| 285 | static int external_exists(const char *name, const char *path) | ||
| 286 | { | ||
| 287 | const char *path0, *path1, *ret; | ||
| 288 | |||
| 289 | path0 = path1 = xstrdup(path ?: getenv("PATH")); | ||
| 290 | ret = find_executable(name, &path1); | ||
| 291 | free((void *)ret); | ||
| 292 | free((void *)path0); | ||
| 293 | return ret != NULL; | ||
| 294 | } | ||
| 295 | |||
| 296 | static int prefer_applet_internal(const char *name, const char *path, | ||
| 297 | const char *override) | ||
| 298 | { | ||
| 299 | const char *s, *sep; | ||
| 300 | size_t len; | ||
| 301 | |||
| 302 | if (override && *override) { | ||
| 303 | /* '-' disables all applets */ | ||
| 304 | if (override[0] == '-' && override[1] == '\0') | ||
| 305 | return FALSE; | ||
| 306 | |||
| 307 | /* '+' each applet is overridden if an external command exists */ | ||
| 308 | if (override[0] == '+' && override[1] == '\0') | ||
| 309 | return !external_exists(name, path); | ||
| 310 | |||
| 311 | /* Handle applets from a list separated by spaces, commas or | ||
| 312 | * semicolons. Applets before the first semicolon are disabled. | ||
| 313 | * Applets after the first semicolon are overridden if a | ||
| 314 | * corresponding external command exists. */ | ||
| 315 | sep = strchr(override, ';'); | ||
| 316 | len = strlen(name); | ||
| 317 | s = override - 1; | ||
| 318 | while (1) { | ||
| 319 | s = strstr(s + 1, name); | ||
| 320 | if (!s) | ||
| 321 | break; | ||
| 322 | /* neither "name.." nor "xxx,name.."? */ | ||
| 323 | if (s != override && !strchr(" ,;", s[-1])) | ||
| 324 | continue; | ||
| 325 | /* neither "..name" nor "..name,xxx"? */ | ||
| 326 | if (s[len] != '\0' && !strchr(" ,;", s[len])) | ||
| 327 | continue; | ||
| 328 | return (sep == NULL || s < sep) ? | ||
| 329 | FALSE : !external_exists(name, path); | ||
| 330 | } | ||
| 331 | } | ||
| 332 | return TRUE; | ||
| 333 | } | ||
| 334 | |||
| 335 | int FAST_FUNC prefer_applet(const char *name, const char *path) | ||
| 336 | { | ||
| 337 | int ret; | ||
| 338 | |||
| 339 | ret = prefer_applet_internal(name, path, getenv(BB_OVERRIDE_APPLETS)); | ||
| 340 | if (sizeof(CONFIG_OVERRIDE_APPLETS) > 1 && ret) | ||
| 341 | ret = prefer_applet_internal(name, path, CONFIG_OVERRIDE_APPLETS); | ||
| 342 | return ret; | ||
| 343 | } | ||
| 344 | # endif | ||
| 345 | #endif | ||
| 346 | |||
| 244 | 347 | ||
| 245 | void lbb_prepare(const char *applet | 348 | void lbb_prepare(const char *applet |
| 246 | IF_FEATURE_INDIVIDUAL(, char **argv)) | 349 | IF_FEATURE_INDIVIDUAL(, char **argv)) |
| @@ -291,6 +394,18 @@ const char *applet_name; | |||
| 291 | #if !BB_MMU | 394 | #if !BB_MMU |
| 292 | bool re_execed; | 395 | bool re_execed; |
| 293 | #endif | 396 | #endif |
| 397 | #if ENABLE_PLATFORM_MINGW32 | ||
| 398 | static int interp = 0; | ||
| 399 | char bb_comm[COMM_LEN]; | ||
| 400 | char bb_command_line[128]; | ||
| 401 | |||
| 402 | # if ENABLE_FEATURE_SH_STANDALONE | ||
| 403 | void FAST_FUNC set_interp(int i) | ||
| 404 | { | ||
| 405 | interp = i; | ||
| 406 | } | ||
| 407 | # endif | ||
| 408 | #endif | ||
| 294 | 409 | ||
| 295 | 410 | ||
| 296 | /* If not built as a single-applet executable... */ | 411 | /* If not built as a single-applet executable... */ |
| @@ -676,15 +791,36 @@ static void install_links(const char *busybox, int use_symbolic_links, | |||
| 676 | const char *appname = applet_names; | 791 | const char *appname = applet_names; |
| 677 | unsigned i; | 792 | unsigned i; |
| 678 | int rc; | 793 | int rc; |
| 794 | # if ENABLE_PLATFORM_MINGW32 | ||
| 795 | const char *sd = ""; | ||
| 796 | |||
| 797 | if (custom_install_dir != NULL) { | ||
| 798 | bb_make_directory(custom_install_dir, 0755, FILEUTILS_RECUR); | ||
| 799 | } | ||
| 800 | else { | ||
| 801 | sd = get_system_drive(); | ||
| 802 | for (i=1; i<ARRAY_SIZE(install_dir); ++i) { | ||
| 803 | fpc = concat_path_file(sd, install_dir[i]); | ||
| 804 | bb_make_directory(fpc, 0755, FILEUTILS_RECUR); | ||
| 805 | free(fpc); | ||
| 806 | } | ||
| 807 | } | ||
| 808 | # endif | ||
| 679 | 809 | ||
| 680 | lf = link; | 810 | lf = link; |
| 681 | if (use_symbolic_links) | 811 | if (use_symbolic_links) |
| 682 | lf = symlink; | 812 | lf = symlink; |
| 683 | 813 | ||
| 684 | for (i = 0; i < ARRAY_SIZE(applet_main); i++) { | 814 | for (i = 0; i < ARRAY_SIZE(applet_main); i++) { |
| 815 | # if ENABLE_PLATFORM_MINGW32 | ||
| 816 | fpc = xasprintf("%s%s/%s.exe", sd, | ||
| 817 | custom_install_dir ?: install_dir[APPLET_INSTALL_LOC(i)], | ||
| 818 | appname); | ||
| 819 | # else | ||
| 685 | fpc = concat_path_file( | 820 | fpc = concat_path_file( |
| 686 | custom_install_dir ? custom_install_dir : install_dir[APPLET_INSTALL_LOC(i)], | 821 | custom_install_dir ? custom_install_dir : install_dir[APPLET_INSTALL_LOC(i)], |
| 687 | appname); | 822 | appname); |
| 823 | # endif | ||
| 688 | // debug: bb_error_msg("%slinking %s to busybox", | 824 | // debug: bb_error_msg("%slinking %s to busybox", |
| 689 | // use_symbolic_links ? "sym" : "", fpc); | 825 | // use_symbolic_links ? "sym" : "", fpc); |
| 690 | rc = lf(busybox, fpc); | 826 | rc = lf(busybox, fpc); |
| @@ -781,20 +917,40 @@ int busybox_main(int argc UNUSED_PARAM, char **argv) | |||
| 781 | output_width = get_terminal_width(2); | 917 | output_width = get_terminal_width(2); |
| 782 | 918 | ||
| 783 | full_write1_str(bb_banner); /* reuse const string */ | 919 | full_write1_str(bb_banner); /* reuse const string */ |
| 920 | # if ENABLE_PLATFORM_MINGW32 | ||
| 921 | full_write1_str("\n("); | ||
| 922 | # if defined(MINGW_VER) | ||
| 923 | if (sizeof(MINGW_VER) > 5) { | ||
| 924 | full_write1_str(MINGW_VER "; "); | ||
| 925 | } | ||
| 926 | # endif | ||
| 927 | full_write1_str(ENABLE_GLOBBING ? "glob" : "noglob"); | ||
| 928 | # if ENABLE_FEATURE_UTF8_MANIFEST | ||
| 929 | full_write1_str("; Unicode"); | ||
| 930 | # endif | ||
| 931 | full_write1_str(")\n\n"); | ||
| 932 | # else | ||
| 784 | full_write1_str(" multi-call binary.\n"); /* reuse */ | 933 | full_write1_str(" multi-call binary.\n"); /* reuse */ |
| 934 | #endif | ||
| 785 | full_write1_str( | 935 | full_write1_str( |
| 786 | "BusyBox is copyrighted by many authors between 1998-2015.\n" | 936 | "BusyBox is copyrighted by many authors between 1998-2025.\n" |
| 787 | "Licensed under GPLv2. See source distribution for detailed\n" | 937 | "Licensed under GPLv2. See source distribution for detailed\n" |
| 788 | "copyright notices.\n" | 938 | "copyright notices.\n" |
| 789 | "\n" | 939 | "\n" |
| 790 | "Usage: busybox [function [arguments]...]\n" | 940 | "Usage: busybox [function [arguments]...]\n" |
| 791 | " or: busybox --list"IF_FEATURE_INSTALLER("[-full]")"\n" | 941 | " or: busybox --list"IF_FULL_LIST_OPTION("[-full]")"\n" |
| 792 | # if ENABLE_FEATURE_SHOW_SCRIPT && NUM_SCRIPTS > 0 | 942 | # if ENABLE_FEATURE_SHOW_SCRIPT && NUM_SCRIPTS > 0 |
| 793 | " or: busybox --show SCRIPT\n" | 943 | " or: busybox --show SCRIPT\n" |
| 794 | # endif | 944 | # endif |
| 795 | IF_FEATURE_INSTALLER( | 945 | IF_FEATURE_INSTALLER( |
| 946 | IF_NOT_PLATFORM_MINGW32( | ||
| 796 | " or: busybox --install [-s] [DIR]\n" | 947 | " or: busybox --install [-s] [DIR]\n" |
| 797 | ) | 948 | ) |
| 949 | IF_PLATFORM_MINGW32( | ||
| 950 | " or: busybox --install [-s] [-u|DIR]\n" | ||
| 951 | " or: busybox --uninstall [-n] file\n" | ||
| 952 | ) | ||
| 953 | ) | ||
| 798 | " or: function [arguments]...\n" | 954 | " or: function [arguments]...\n" |
| 799 | "\n" | 955 | "\n" |
| 800 | IF_NOT_FEATURE_SH_STANDALONE( | 956 | IF_NOT_FEATURE_SH_STANDALONE( |
| @@ -854,9 +1010,28 @@ int busybox_main(int argc UNUSED_PARAM, char **argv) | |||
| 854 | unsigned i = 0; | 1010 | unsigned i = 0; |
| 855 | const char *a = applet_names; | 1011 | const char *a = applet_names; |
| 856 | while (*a) { | 1012 | while (*a) { |
| 857 | # if ENABLE_FEATURE_INSTALLER | 1013 | # if ENABLE_FEATURE_INSTALLER && !ENABLE_PLATFORM_MINGW32 |
| 858 | if (argv[1][6]) /* --list-full? */ | 1014 | if (argv[1][6]) /* --list-full? */ |
| 859 | full_write1_str(install_dir[APPLET_INSTALL_LOC(i)] + 1); | 1015 | full_write1_str(install_dir[APPLET_INSTALL_LOC(i)] + 1); |
| 1016 | # elif ENABLE_PLATFORM_MINGW32 && (ENABLE_FEATURE_PREFER_APPLETS \ | ||
| 1017 | || ENABLE_FEATURE_SH_STANDALONE \ | ||
| 1018 | || ENABLE_FEATURE_SH_NOFORK) | ||
| 1019 | if (argv[1][6]) { /* --list-full? */ | ||
| 1020 | const char *str; | ||
| 1021 | |||
| 1022 | if (APPLET_IS_NOFORK(i)) | ||
| 1023 | str = "NOFORK "; | ||
| 1024 | else if (APPLET_IS_NOEXEC(i)) | ||
| 1025 | str = "noexec "; | ||
| 1026 | # if NUM_SCRIPTS > 0 | ||
| 1027 | else if (applet_main[i] == scripted_main) | ||
| 1028 | str = "script "; | ||
| 1029 | # endif | ||
| 1030 | else | ||
| 1031 | str = " "; | ||
| 1032 | full_write1_str(str); | ||
| 1033 | full_write1_str(install_dir[APPLET_INSTALL_LOC(i)] + 1); | ||
| 1034 | } | ||
| 860 | # endif | 1035 | # endif |
| 861 | full_write1_str(a); | 1036 | full_write1_str(a); |
| 862 | full_write1_str("\n"); | 1037 | full_write1_str("\n"); |
| @@ -869,6 +1044,7 @@ int busybox_main(int argc UNUSED_PARAM, char **argv) | |||
| 869 | 1044 | ||
| 870 | if (ENABLE_FEATURE_INSTALLER && strcmp(argv[1], "--install") == 0) { | 1045 | if (ENABLE_FEATURE_INSTALLER && strcmp(argv[1], "--install") == 0) { |
| 871 | int use_symbolic_links; | 1046 | int use_symbolic_links; |
| 1047 | #if !ENABLE_PLATFORM_MINGW32 | ||
| 872 | const char *busybox; | 1048 | const char *busybox; |
| 873 | 1049 | ||
| 874 | busybox = xmalloc_readlink(bb_busybox_exec_path); | 1050 | busybox = xmalloc_readlink(bb_busybox_exec_path); |
| @@ -888,8 +1064,62 @@ int busybox_main(int argc UNUSED_PARAM, char **argv) | |||
| 888 | */ | 1064 | */ |
| 889 | use_symbolic_links = (argv[2] && strcmp(argv[2], "-s") == 0 && ++argv); | 1065 | use_symbolic_links = (argv[2] && strcmp(argv[2], "-s") == 0 && ++argv); |
| 890 | install_links(busybox, use_symbolic_links, argv[2]); | 1066 | install_links(busybox, use_symbolic_links, argv[2]); |
| 1067 | #else | ||
| 1068 | char *target; | ||
| 1069 | uint32_t opt; | ||
| 1070 | enum { OPT_s = (1 << 0), OPT_u = (1 << 1) }; | ||
| 1071 | |||
| 1072 | /* busybox --install [-s] [-u|DIR] | ||
| 1073 | * -s: make symlinks | ||
| 1074 | * -u: install to Unix-style directories in system drive | ||
| 1075 | * DIR: directory to install links to | ||
| 1076 | * If no argument is provided put the links in the same directory | ||
| 1077 | * as busybox. | ||
| 1078 | */ | ||
| 1079 | argv += 1; | ||
| 1080 | opt = getopt32(argv, "!su"); | ||
| 1081 | argv += optind; | ||
| 1082 | |||
| 1083 | if (opt == (uint32_t)-1 || | ||
| 1084 | (*argv != NULL && (opt & OPT_u || *(argv + 1) != NULL))) | ||
| 1085 | bb_simple_error_msg_and_die("busybox --install [-s] [-u|DIR]"); | ||
| 1086 | |||
| 1087 | if (opt & OPT_u) | ||
| 1088 | target = NULL; | ||
| 1089 | else if (*argv != NULL) | ||
| 1090 | target = *argv; | ||
| 1091 | else | ||
| 1092 | target = dirname(xstrdup(bb_busybox_exec_path)); | ||
| 1093 | |||
| 1094 | use_symbolic_links = opt & OPT_s; | ||
| 1095 | /* NULL target -> install to Unix-style dirs */ | ||
| 1096 | install_links(bb_busybox_exec_path, use_symbolic_links, target); | ||
| 1097 | #endif | ||
| 1098 | return 0; | ||
| 1099 | } | ||
| 1100 | |||
| 1101 | #if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_INSTALLER | ||
| 1102 | if (strcmp(argv[1], "--uninstall") == 0) { | ||
| 1103 | char name[PATH_MAX]; | ||
| 1104 | int dry_run = (argv[2] && strcmp(argv[2], "-n") == 0 && ++argv); | ||
| 1105 | const char *file = argv[2]; | ||
| 1106 | |||
| 1107 | if (!argv[2]) | ||
| 1108 | bb_error_msg_and_die(bb_msg_requires_arg, "--uninstall"); | ||
| 1109 | |||
| 1110 | while (enumerate_links(file, name)) { | ||
| 1111 | if (dry_run) { | ||
| 1112 | full_write1_str(name); | ||
| 1113 | full_write1_str("\n"); | ||
| 1114 | } | ||
| 1115 | else if (unlink(name) != 0) { | ||
| 1116 | bb_simple_perror_msg(name); | ||
| 1117 | } | ||
| 1118 | file = NULL; | ||
| 1119 | } | ||
| 891 | return 0; | 1120 | return 0; |
| 892 | } | 1121 | } |
| 1122 | #endif | ||
| 893 | 1123 | ||
| 894 | if (strcmp(argv[1], "--help") == 0) { | 1124 | if (strcmp(argv[1], "--help") == 0) { |
| 895 | /* "busybox --help [APPLET]" */ | 1125 | /* "busybox --help [APPLET]" */ |
| @@ -902,7 +1132,7 @@ int busybox_main(int argc UNUSED_PARAM, char **argv) | |||
| 902 | /* convert to "APPLET --help" */ | 1132 | /* convert to "APPLET --help" */ |
| 903 | applet_name = argv[0] = argv[2]; | 1133 | applet_name = argv[0] = argv[2]; |
| 904 | argv[2] = NULL; | 1134 | argv[2] = NULL; |
| 905 | if (find_applet_by_name(applet_name) >= 0) { | 1135 | if (find_applet_by_name_internal(applet_name) >= 0) { |
| 906 | /* Make "--help foo" exit with 0: */ | 1136 | /* Make "--help foo" exit with 0: */ |
| 907 | xfunc_error_retval = 0; | 1137 | xfunc_error_retval = 0; |
| 908 | bb_show_usage(); | 1138 | bb_show_usage(); |
| @@ -921,6 +1151,10 @@ int busybox_main(int argc UNUSED_PARAM, char **argv) | |||
| 921 | /* We support "busybox /a/path/to/applet args..." too. Allows for | 1151 | /* We support "busybox /a/path/to/applet args..." too. Allows for |
| 922 | * "#!/bin/busybox"-style wrappers | 1152 | * "#!/bin/busybox"-style wrappers |
| 923 | */ | 1153 | */ |
| 1154 | # if ENABLE_PLATFORM_MINGW32 | ||
| 1155 | if (interp) | ||
| 1156 | --interp; | ||
| 1157 | # endif | ||
| 924 | applet_name = bb_get_last_path_component_nostrip(argv[0]); | 1158 | applet_name = bb_get_last_path_component_nostrip(argv[0]); |
| 925 | } | 1159 | } |
| 926 | run_applet_and_exit(applet_name, argv); | 1160 | run_applet_and_exit(applet_name, argv); |
| @@ -951,6 +1185,9 @@ void FAST_FUNC show_usage_if_dash_dash_help(int applet_no UNUSED_PARAM, char **a | |||
| 951 | # if ENABLE_TEST1 || ENABLE_TEST2 | 1185 | # if ENABLE_TEST1 || ENABLE_TEST2 |
| 952 | && argv[0][0] != '[' /* exclude [ --help ] and [[ --help ]] too */ | 1186 | && argv[0][0] != '[' /* exclude [ --help ] and [[ --help ]] too */ |
| 953 | # endif | 1187 | # endif |
| 1188 | # if ENABLE_PLATFORM_MINGW32 && defined APPLET_NO_busybox | ||
| 1189 | && applet_no != APPLET_NO_busybox | ||
| 1190 | # endif | ||
| 954 | ) { | 1191 | ) { |
| 955 | if (argv[1] && strcmp(argv[1], "--help") == 0) { | 1192 | if (argv[1] && strcmp(argv[1], "--help") == 0) { |
| 956 | /* Make "foo --help [...]" exit with 0: */ | 1193 | /* Make "foo --help [...]" exit with 0: */ |
| @@ -962,7 +1199,14 @@ void FAST_FUNC show_usage_if_dash_dash_help(int applet_no UNUSED_PARAM, char **a | |||
| 962 | 1199 | ||
| 963 | void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv) | 1200 | void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv) |
| 964 | { | 1201 | { |
| 1202 | # if ENABLE_PLATFORM_MINGW32 | ||
| 1203 | int argc = string_array_len(argv); | ||
| 1204 | int i; | ||
| 1205 | const char *vmask; | ||
| 1206 | unsigned int mask; | ||
| 1207 | # else | ||
| 965 | int argc; | 1208 | int argc; |
| 1209 | # endif | ||
| 966 | 1210 | ||
| 967 | /* | 1211 | /* |
| 968 | * We do not use argv[0]: do not want to repeat massaging of | 1212 | * We do not use argv[0]: do not want to repeat massaging of |
| @@ -975,7 +1219,23 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **ar | |||
| 975 | if (ENABLE_FEATURE_SUID) | 1219 | if (ENABLE_FEATURE_SUID) |
| 976 | check_suid(applet_no); | 1220 | check_suid(applet_no); |
| 977 | 1221 | ||
| 1222 | # if ENABLE_PLATFORM_MINGW32 | ||
| 1223 | safe_strncpy(bb_comm, | ||
| 1224 | interp ? bb_basename(argv[interp]) : applet_name, | ||
| 1225 | sizeof(bb_comm)); | ||
| 1226 | |||
| 1227 | safe_strncpy(bb_command_line, applet_name, sizeof(bb_command_line)); | ||
| 1228 | for (i=1; i < argc && argv[i] && | ||
| 1229 | strlen(bb_command_line) + strlen(argv[i]) + 2 < 128; ++i) { | ||
| 1230 | strcat(strcat(bb_command_line, " "), argv[i]); | ||
| 1231 | } | ||
| 1232 | |||
| 1233 | vmask = getenv("BB_UMASK"); | ||
| 1234 | if (vmask && sscanf(vmask, "%o", &mask) == 1) | ||
| 1235 | umask((mode_t)mask); | ||
| 1236 | # else | ||
| 978 | argc = string_array_len(argv); | 1237 | argc = string_array_len(argv); |
| 1238 | # endif | ||
| 979 | xfunc_error_retval = applet_main[applet_no](argc, argv); | 1239 | xfunc_error_retval = applet_main[applet_no](argc, argv); |
| 980 | 1240 | ||
| 981 | /* Note: applet_main() may also not return (die on a xfunc or such) */ | 1241 | /* Note: applet_main() may also not return (die on a xfunc or such) */ |
| @@ -993,7 +1253,7 @@ static NORETURN void run_applet_and_exit(const char *name, char **argv) | |||
| 993 | # if NUM_APPLETS > 0 | 1253 | # if NUM_APPLETS > 0 |
| 994 | /* find_applet_by_name() search is more expensive, so goes second */ | 1254 | /* find_applet_by_name() search is more expensive, so goes second */ |
| 995 | { | 1255 | { |
| 996 | int applet = find_applet_by_name(name); | 1256 | int applet = find_applet_by_name_internal(name); |
| 997 | if (applet >= 0) | 1257 | if (applet >= 0) |
| 998 | run_applet_no_and_exit(applet, name, argv); | 1258 | run_applet_no_and_exit(applet, name, argv); |
| 999 | } | 1259 | } |
| @@ -1085,6 +1345,44 @@ int main(int argc UNUSED_PARAM, char **argv) | |||
| 1085 | argv[0][0] &= 0x7f; | 1345 | argv[0][0] &= 0x7f; |
| 1086 | } | 1346 | } |
| 1087 | #endif | 1347 | #endif |
| 1348 | #if ENABLE_PLATFORM_MINGW32 | ||
| 1349 | # if ENABLE_FEATURE_UTF8_MANIFEST | ||
| 1350 | if (GetACP() != CP_UTF8) { | ||
| 1351 | full_write2_str(bb_basename(argv[0])); | ||
| 1352 | full_write2_str(": UTF8 manifest not supported\n"); | ||
| 1353 | return 1; | ||
| 1354 | } | ||
| 1355 | # endif | ||
| 1356 | |||
| 1357 | /* detect if we're running an interpreted script */ | ||
| 1358 | if (argv[0][1] == ':' && argv[0][2] == '/') { | ||
| 1359 | switch (argv[0][0]) { | ||
| 1360 | case '2': | ||
| 1361 | ++interp; | ||
| 1362 | /* fall through */ | ||
| 1363 | case '1': | ||
| 1364 | ++interp; | ||
| 1365 | argv[0] += 3; | ||
| 1366 | break; | ||
| 1367 | } | ||
| 1368 | } | ||
| 1369 | |||
| 1370 | /* Have this process handle critical errors itself: the default | ||
| 1371 | * system-generated error dialogs may be inconvenient. */ | ||
| 1372 | change_critical_error_dialogs(getenv(BB_CRITICAL_ERROR_DIALOGS)); | ||
| 1373 | #endif | ||
| 1374 | |||
| 1375 | #if defined(__MINGW64_VERSION_MAJOR) | ||
| 1376 | if ( stdin ) { | ||
| 1377 | _setmode(fileno(stdin), _O_BINARY); | ||
| 1378 | } | ||
| 1379 | if ( stdout ) { | ||
| 1380 | _setmode(fileno(stdout), _O_BINARY); | ||
| 1381 | } | ||
| 1382 | if ( stderr ) { | ||
| 1383 | _setmode(fileno(stderr), _O_BINARY); | ||
| 1384 | } | ||
| 1385 | #endif | ||
| 1088 | 1386 | ||
| 1089 | #if defined(SINGLE_APPLET_MAIN) | 1387 | #if defined(SINGLE_APPLET_MAIN) |
| 1090 | 1388 | ||
| @@ -1109,6 +1407,10 @@ int main(int argc UNUSED_PARAM, char **argv) | |||
| 1109 | 1407 | ||
| 1110 | #else | 1408 | #else |
| 1111 | 1409 | ||
| 1410 | # if ENABLE_PLATFORM_MINGW32 | ||
| 1411 | if (argv[1] && argv[2] && strcmp(argv[1], "--busybox") == 0) | ||
| 1412 | argv += 2; | ||
| 1413 | # endif | ||
| 1112 | lbb_prepare("busybox" IF_FEATURE_INDIVIDUAL(, argv)); | 1414 | lbb_prepare("busybox" IF_FEATURE_INDIVIDUAL(, argv)); |
| 1113 | # if !ENABLE_BUSYBOX | 1415 | # if !ENABLE_BUSYBOX |
| 1114 | if (argv[1] && is_prefixed_with(bb_basename(argv[0]), "busybox")) | 1416 | if (argv[1] && is_prefixed_with(bb_basename(argv[0]), "busybox")) |
| @@ -1117,6 +1419,27 @@ int main(int argc UNUSED_PARAM, char **argv) | |||
| 1117 | applet_name = argv[0]; | 1419 | applet_name = argv[0]; |
| 1118 | if (applet_name[0] == '-') | 1420 | if (applet_name[0] == '-') |
| 1119 | applet_name++; | 1421 | applet_name++; |
| 1422 | # if ENABLE_PLATFORM_MINGW32 | ||
| 1423 | str_tolower(argv[0]); | ||
| 1424 | bs_to_slash(argv[0]); | ||
| 1425 | if (has_exe_suffix_or_dot(argv[0])) { | ||
| 1426 | char *s = strrchr(argv[0], '.'); | ||
| 1427 | if (s) | ||
| 1428 | *s = '\0'; | ||
| 1429 | } | ||
| 1430 | |||
| 1431 | if (windows_env()) { | ||
| 1432 | /* remove single trailing separator from PATH */ | ||
| 1433 | for (char **envp = environ; envp && *envp; envp++) { | ||
| 1434 | if (is_prefixed_with_case(*envp, "PATH=")) { | ||
| 1435 | char *end = last_char_is(*envp, ';'); | ||
| 1436 | if (end && end[-1] != ';') | ||
| 1437 | *end = '\0'; | ||
| 1438 | break; | ||
| 1439 | } | ||
| 1440 | } | ||
| 1441 | } | ||
| 1442 | # endif | ||
| 1120 | applet_name = bb_basename(applet_name); | 1443 | applet_name = bb_basename(applet_name); |
| 1121 | 1444 | ||
| 1122 | /* If we are a result of execv("/proc/self/exe"), fix ugly comm of "exe" */ | 1445 | /* If we are a result of execv("/proc/self/exe"), fix ugly comm of "exe" */ |
