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 d2e5900b5..b1064d10a 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(); |
@@ -913,6 +1143,10 @@ int busybox_main(int argc UNUSED_PARAM, char **argv) | |||
913 | /* We support "busybox /a/path/to/applet args..." too. Allows for | 1143 | /* We support "busybox /a/path/to/applet args..." too. Allows for |
914 | * "#!/bin/busybox"-style wrappers | 1144 | * "#!/bin/busybox"-style wrappers |
915 | */ | 1145 | */ |
1146 | # if ENABLE_PLATFORM_MINGW32 | ||
1147 | if (interp) | ||
1148 | --interp; | ||
1149 | # endif | ||
916 | applet_name = bb_get_last_path_component_nostrip(argv[0]); | 1150 | applet_name = bb_get_last_path_component_nostrip(argv[0]); |
917 | } | 1151 | } |
918 | run_applet_and_exit(applet_name, argv); | 1152 | run_applet_and_exit(applet_name, argv); |
@@ -943,6 +1177,9 @@ void FAST_FUNC show_usage_if_dash_dash_help(int applet_no UNUSED_PARAM, char **a | |||
943 | # if ENABLE_TEST1 || ENABLE_TEST2 | 1177 | # if ENABLE_TEST1 || ENABLE_TEST2 |
944 | && argv[0][0] != '[' /* exclude [ --help ] and [[ --help ]] too */ | 1178 | && argv[0][0] != '[' /* exclude [ --help ] and [[ --help ]] too */ |
945 | # endif | 1179 | # endif |
1180 | # if ENABLE_PLATFORM_MINGW32 && defined APPLET_NO_busybox | ||
1181 | && applet_no != APPLET_NO_busybox | ||
1182 | # endif | ||
946 | ) { | 1183 | ) { |
947 | if (argv[1] && strcmp(argv[1], "--help") == 0) { | 1184 | if (argv[1] && strcmp(argv[1], "--help") == 0) { |
948 | /* Make "foo --help [...]" exit with 0: */ | 1185 | /* Make "foo --help [...]" exit with 0: */ |
@@ -954,7 +1191,14 @@ void FAST_FUNC show_usage_if_dash_dash_help(int applet_no UNUSED_PARAM, char **a | |||
954 | 1191 | ||
955 | void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv) | 1192 | void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv) |
956 | { | 1193 | { |
1194 | # if ENABLE_PLATFORM_MINGW32 | ||
1195 | int argc = string_array_len(argv); | ||
1196 | int i; | ||
1197 | const char *vmask; | ||
1198 | unsigned int mask; | ||
1199 | # else | ||
957 | int argc; | 1200 | int argc; |
1201 | # endif | ||
958 | 1202 | ||
959 | /* | 1203 | /* |
960 | * We do not use argv[0]: do not want to repeat massaging of | 1204 | * We do not use argv[0]: do not want to repeat massaging of |
@@ -967,7 +1211,23 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **ar | |||
967 | if (ENABLE_FEATURE_SUID) | 1211 | if (ENABLE_FEATURE_SUID) |
968 | check_suid(applet_no); | 1212 | check_suid(applet_no); |
969 | 1213 | ||
1214 | # if ENABLE_PLATFORM_MINGW32 | ||
1215 | safe_strncpy(bb_comm, | ||
1216 | interp ? bb_basename(argv[interp]) : applet_name, | ||
1217 | sizeof(bb_comm)); | ||
1218 | |||
1219 | safe_strncpy(bb_command_line, applet_name, sizeof(bb_command_line)); | ||
1220 | for (i=1; i < argc && argv[i] && | ||
1221 | strlen(bb_command_line) + strlen(argv[i]) + 2 < 128; ++i) { | ||
1222 | strcat(strcat(bb_command_line, " "), argv[i]); | ||
1223 | } | ||
1224 | |||
1225 | vmask = getenv("BB_UMASK"); | ||
1226 | if (vmask && sscanf(vmask, "%o", &mask) == 1) | ||
1227 | umask((mode_t)mask); | ||
1228 | # else | ||
970 | argc = string_array_len(argv); | 1229 | argc = string_array_len(argv); |
1230 | # endif | ||
971 | xfunc_error_retval = applet_main[applet_no](argc, argv); | 1231 | xfunc_error_retval = applet_main[applet_no](argc, argv); |
972 | 1232 | ||
973 | /* Note: applet_main() may also not return (die on a xfunc or such) */ | 1233 | /* Note: applet_main() may also not return (die on a xfunc or such) */ |
@@ -985,7 +1245,7 @@ static NORETURN void run_applet_and_exit(const char *name, char **argv) | |||
985 | # if NUM_APPLETS > 0 | 1245 | # if NUM_APPLETS > 0 |
986 | /* find_applet_by_name() search is more expensive, so goes second */ | 1246 | /* find_applet_by_name() search is more expensive, so goes second */ |
987 | { | 1247 | { |
988 | int applet = find_applet_by_name(name); | 1248 | int applet = find_applet_by_name_internal(name); |
989 | if (applet >= 0) | 1249 | if (applet >= 0) |
990 | run_applet_no_and_exit(applet, name, argv); | 1250 | run_applet_no_and_exit(applet, name, argv); |
991 | } | 1251 | } |
@@ -1077,6 +1337,44 @@ int main(int argc UNUSED_PARAM, char **argv) | |||
1077 | argv[0][0] &= 0x7f; | 1337 | argv[0][0] &= 0x7f; |
1078 | } | 1338 | } |
1079 | #endif | 1339 | #endif |
1340 | #if ENABLE_PLATFORM_MINGW32 | ||
1341 | # if ENABLE_FEATURE_UTF8_MANIFEST | ||
1342 | if (GetACP() != CP_UTF8) { | ||
1343 | full_write2_str(bb_basename(argv[0])); | ||
1344 | full_write2_str(": UTF8 manifest not supported\n"); | ||
1345 | return 1; | ||
1346 | } | ||
1347 | # endif | ||
1348 | |||
1349 | /* detect if we're running an interpreted script */ | ||
1350 | if (argv[0][1] == ':' && argv[0][2] == '/') { | ||
1351 | switch (argv[0][0]) { | ||
1352 | case '2': | ||
1353 | ++interp; | ||
1354 | /* fall through */ | ||
1355 | case '1': | ||
1356 | ++interp; | ||
1357 | argv[0] += 3; | ||
1358 | break; | ||
1359 | } | ||
1360 | } | ||
1361 | |||
1362 | /* Have this process handle critical errors itself: the default | ||
1363 | * system-generated error dialogs may be inconvenient. */ | ||
1364 | change_critical_error_dialogs(getenv(BB_CRITICAL_ERROR_DIALOGS)); | ||
1365 | #endif | ||
1366 | |||
1367 | #if defined(__MINGW64_VERSION_MAJOR) | ||
1368 | if ( stdin ) { | ||
1369 | _setmode(fileno(stdin), _O_BINARY); | ||
1370 | } | ||
1371 | if ( stdout ) { | ||
1372 | _setmode(fileno(stdout), _O_BINARY); | ||
1373 | } | ||
1374 | if ( stderr ) { | ||
1375 | _setmode(fileno(stderr), _O_BINARY); | ||
1376 | } | ||
1377 | #endif | ||
1080 | 1378 | ||
1081 | #if defined(SINGLE_APPLET_MAIN) | 1379 | #if defined(SINGLE_APPLET_MAIN) |
1082 | 1380 | ||
@@ -1101,6 +1399,10 @@ int main(int argc UNUSED_PARAM, char **argv) | |||
1101 | 1399 | ||
1102 | #else | 1400 | #else |
1103 | 1401 | ||
1402 | # if ENABLE_PLATFORM_MINGW32 | ||
1403 | if (argv[1] && argv[2] && strcmp(argv[1], "--busybox") == 0) | ||
1404 | argv += 2; | ||
1405 | # endif | ||
1104 | lbb_prepare("busybox" IF_FEATURE_INDIVIDUAL(, argv)); | 1406 | lbb_prepare("busybox" IF_FEATURE_INDIVIDUAL(, argv)); |
1105 | # if !ENABLE_BUSYBOX | 1407 | # if !ENABLE_BUSYBOX |
1106 | if (argv[1] && is_prefixed_with(bb_basename(argv[0]), "busybox")) | 1408 | if (argv[1] && is_prefixed_with(bb_basename(argv[0]), "busybox")) |
@@ -1109,6 +1411,27 @@ int main(int argc UNUSED_PARAM, char **argv) | |||
1109 | applet_name = argv[0]; | 1411 | applet_name = argv[0]; |
1110 | if (applet_name[0] == '-') | 1412 | if (applet_name[0] == '-') |
1111 | applet_name++; | 1413 | applet_name++; |
1414 | # if ENABLE_PLATFORM_MINGW32 | ||
1415 | str_tolower(argv[0]); | ||
1416 | bs_to_slash(argv[0]); | ||
1417 | if (has_exe_suffix_or_dot(argv[0])) { | ||
1418 | char *s = strrchr(argv[0], '.'); | ||
1419 | if (s) | ||
1420 | *s = '\0'; | ||
1421 | } | ||
1422 | |||
1423 | if (windows_env()) { | ||
1424 | /* remove single trailing separator from PATH */ | ||
1425 | for (char **envp = environ; envp && *envp; envp++) { | ||
1426 | if (is_prefixed_with_case(*envp, "PATH=")) { | ||
1427 | char *end = last_char_is(*envp, ';'); | ||
1428 | if (end && end[-1] != ';') | ||
1429 | *end = '\0'; | ||
1430 | break; | ||
1431 | } | ||
1432 | } | ||
1433 | } | ||
1434 | # endif | ||
1112 | applet_name = bb_basename(applet_name); | 1435 | applet_name = bb_basename(applet_name); |
1113 | 1436 | ||
1114 | /* If we are a result of execv("/proc/self/exe"), fix ugly comm of "exe" */ | 1437 | /* If we are a result of execv("/proc/self/exe"), fix ugly comm of "exe" */ |