aboutsummaryrefslogtreecommitdiff
path: root/libbb/appletlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbb/appletlib.c')
-rw-r--r--libbb/appletlib.c253
1 files changed, 250 insertions, 3 deletions
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index d8ab2a450..99f0cb89c 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,10 +71,18 @@ 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"
66static const char packed_scripts[] ALIGN1 = { PACKED_SCRIPTS }; 76static const char packed_scripts[] ALIGN1 = { PACKED_SCRIPTS };
67#endif 77#endif
68 78
79#if defined(find_applet_by_name)
80# undef find_applet_by_name
81#endif
82#if defined(is_applet_preferred)
83# undef is_applet_preferred
84#endif
85
69/* "Do not compress usage text if uncompressed text is small 86/* "Do not compress usage text if uncompressed text is small
70 * and we don't include bunzip2 code for other reasons" 87 * and we don't include bunzip2 code for other reasons"
71 * 88 *
@@ -111,6 +128,7 @@ static const char usage_messages[] ALIGN1 = UNPACKED_USAGE;
111#if ENABLE_FEATURE_COMPRESS_USAGE 128#if ENABLE_FEATURE_COMPRESS_USAGE
112 129
113static const char packed_usage[] ALIGN1 = { PACKED_USAGE }; 130static const char packed_usage[] ALIGN1 = { PACKED_USAGE };
131# define BB_ARCHIVE_PUBLIC
114# include "bb_archive.h" 132# include "bb_archive.h"
115# define unpack_usage_messages() \ 133# define unpack_usage_messages() \
116 unpack_bz2_data(packed_usage, sizeof(packed_usage), sizeof(UNPACKED_USAGE)) 134 unpack_bz2_data(packed_usage, sizeof(packed_usage), sizeof(UNPACKED_USAGE))
@@ -154,7 +172,11 @@ void FAST_FUNC bb_show_usage(void)
154 ap--; 172 ap--;
155 } 173 }
156 full_write2_str(bb_banner); 174 full_write2_str(bb_banner);
175#if ENABLE_PLATFORM_MINGW32
176 full_write2_str("\n");
177#else
157 full_write2_str(" multi-call binary.\n"); /* common string */ 178 full_write2_str(" multi-call binary.\n"); /* common string */
179#endif
158 if (*p == '\b') 180 if (*p == '\b')
159 full_write2_str("\nNo help available\n"); 181 full_write2_str("\nNo help available\n");
160 else { 182 else {
@@ -239,6 +261,45 @@ int FAST_FUNC find_applet_by_name(const char *name)
239 return -1; 261 return -1;
240} 262}
241 263
264#if ENABLE_PLATFORM_MINGW32 && NUM_APPLETS > 1 && \
265 (ENABLE_FEATURE_PREFER_APPLETS || ENABLE_FEATURE_SH_STANDALONE)
266int FAST_FUNC is_applet_preferred(const char *name)
267{
268 const char *var, *s;
269 size_t len;
270
271 var = getenv(BB_OVERRIDE_APPLETS);
272 if (var && *var) {
273 /* '-' overrides all applets */
274 if (var[0] == '-' && var[1] == '\0')
275 return FALSE;
276
277 /* Override applets from a space-separated list */
278 len = strlen(name);
279 s = var - 1;
280 while (1) {
281 s = strstr(s + 1, name);
282 if (!s)
283 break;
284 /* neither "name.." nor "xxx,name.."? */
285 if (s != var && s[-1] != ' ')
286 continue;
287 /* neither "..name" nor "..name,xxx"? */
288 if (s[len] != '\0' && s[len] != ' ')
289 continue;
290 return FALSE;
291 }
292 }
293 return TRUE;
294}
295
296int FAST_FUNC find_preferred_applet_by_name(const char *name)
297{
298 int applet_no = find_applet_by_name(name);
299 return applet_no >= 0 && is_applet_preferred(name) ? applet_no : -1;
300}
301#endif
302
242 303
243void lbb_prepare(const char *applet 304void lbb_prepare(const char *applet
244 IF_FEATURE_INDIVIDUAL(, char **argv)) 305 IF_FEATURE_INDIVIDUAL(, char **argv))
@@ -288,6 +349,11 @@ const char *applet_name;
288#if !BB_MMU 349#if !BB_MMU
289bool re_execed; 350bool re_execed;
290#endif 351#endif
352#if ENABLE_PLATFORM_MINGW32
353static int interp = 0;
354char bb_comm[COMM_LEN];
355char bb_command_line[128];
356#endif
291 357
292 358
293/* If not built as a single-applet executable... */ 359/* If not built as a single-applet executable... */
@@ -673,15 +739,36 @@ static void install_links(const char *busybox, int use_symbolic_links,
673 const char *appname = applet_names; 739 const char *appname = applet_names;
674 unsigned i; 740 unsigned i;
675 int rc; 741 int rc;
742# if ENABLE_PLATFORM_MINGW32
743 const char *sd = NULL;
744
745 if (custom_install_dir != NULL) {
746 bb_make_directory(custom_install_dir, 0755, FILEUTILS_RECUR);
747 }
748 else {
749 sd = get_system_drive();
750 for (i=1; i<ARRAY_SIZE(install_dir); ++i) {
751 fpc = xasprintf("%s%s", sd ?: "", install_dir[i]);
752 bb_make_directory(fpc, 0755, FILEUTILS_RECUR);
753 free(fpc);
754 }
755 }
756# endif
676 757
677 lf = link; 758 lf = link;
678 if (use_symbolic_links) 759 if (use_symbolic_links)
679 lf = symlink; 760 lf = symlink;
680 761
681 for (i = 0; i < ARRAY_SIZE(applet_main); i++) { 762 for (i = 0; i < ARRAY_SIZE(applet_main); i++) {
763# if ENABLE_PLATFORM_MINGW32
764 fpc = xasprintf("%s%s/%s.exe", sd ?: "",
765 custom_install_dir ?: install_dir[APPLET_INSTALL_LOC(i)],
766 appname);
767# else
682 fpc = concat_path_file( 768 fpc = concat_path_file(
683 custom_install_dir ? custom_install_dir : install_dir[APPLET_INSTALL_LOC(i)], 769 custom_install_dir ? custom_install_dir : install_dir[APPLET_INSTALL_LOC(i)],
684 appname); 770 appname);
771# endif
685 // debug: bb_error_msg("%slinking %s to busybox", 772 // debug: bb_error_msg("%slinking %s to busybox",
686 // use_symbolic_links ? "sym" : "", fpc); 773 // use_symbolic_links ? "sym" : "", fpc);
687 rc = lf(busybox, fpc); 774 rc = lf(busybox, fpc);
@@ -779,20 +866,35 @@ int busybox_main(int argc UNUSED_PARAM, char **argv)
779 866
780 dup2(1, 2); 867 dup2(1, 2);
781 full_write2_str(bb_banner); /* reuse const string */ 868 full_write2_str(bb_banner); /* reuse const string */
869#if ENABLE_PLATFORM_MINGW32
870 full_write2_str("\n");
871#else
782 full_write2_str(" multi-call binary.\n"); /* reuse */ 872 full_write2_str(" multi-call binary.\n"); /* reuse */
873#endif
874#if defined(MINGW_VER)
875 if (sizeof(MINGW_VER) > 5) {
876 full_write2_str(MINGW_VER "\n\n");
877 }
878#endif
783 full_write2_str( 879 full_write2_str(
784 "BusyBox is copyrighted by many authors between 1998-2015.\n" 880 "BusyBox is copyrighted by many authors between 1998-2022.\n"
785 "Licensed under GPLv2. See source distribution for detailed\n" 881 "Licensed under GPLv2. See source distribution for detailed\n"
786 "copyright notices.\n" 882 "copyright notices.\n"
787 "\n" 883 "\n"
788 "Usage: busybox [function [arguments]...]\n" 884 "Usage: busybox [function [arguments]...]\n"
789 " or: busybox --list"IF_FEATURE_INSTALLER("[-full]")"\n" 885 " or: busybox --list"IF_FULL_LIST_OPTION("[-full]")"\n"
790# if ENABLE_FEATURE_SHOW_SCRIPT && NUM_SCRIPTS > 0 886# if ENABLE_FEATURE_SHOW_SCRIPT && NUM_SCRIPTS > 0
791 " or: busybox --show SCRIPT\n" 887 " or: busybox --show SCRIPT\n"
792# endif 888# endif
793 IF_FEATURE_INSTALLER( 889 IF_FEATURE_INSTALLER(
890 IF_NOT_PLATFORM_MINGW32(
794 " or: busybox --install [-s] [DIR]\n" 891 " or: busybox --install [-s] [DIR]\n"
795 ) 892 )
893 IF_PLATFORM_MINGW32(
894 " or: busybox --install [-s] [-u|DIR]\n"
895 " or: busybox --uninstall [-n] file\n"
896 )
897 )
796 " or: function [arguments]...\n" 898 " or: function [arguments]...\n"
797 "\n" 899 "\n"
798 IF_NOT_FEATURE_SH_STANDALONE( 900 IF_NOT_FEATURE_SH_STANDALONE(
@@ -853,9 +955,28 @@ int busybox_main(int argc UNUSED_PARAM, char **argv)
853 const char *a = applet_names; 955 const char *a = applet_names;
854 dup2(1, 2); 956 dup2(1, 2);
855 while (*a) { 957 while (*a) {
856# if ENABLE_FEATURE_INSTALLER 958# if ENABLE_FEATURE_INSTALLER && !ENABLE_PLATFORM_MINGW32
857 if (argv[1][6]) /* --list-full? */ 959 if (argv[1][6]) /* --list-full? */
858 full_write2_str(install_dir[APPLET_INSTALL_LOC(i)] + 1); 960 full_write2_str(install_dir[APPLET_INSTALL_LOC(i)] + 1);
961# elif ENABLE_PLATFORM_MINGW32 && (ENABLE_FEATURE_PREFER_APPLETS \
962 || ENABLE_FEATURE_SH_STANDALONE \
963 || ENABLE_FEATURE_SH_NOFORK)
964 if (argv[1][6]) { /* --list-full? */
965 const char *str;
966
967 if (APPLET_IS_NOFORK(i))
968 str = "NOFORK ";
969 else if (APPLET_IS_NOEXEC(i))
970 str = "noexec ";
971# if NUM_SCRIPTS > 0
972 else if (applet_main[i] == scripted_main)
973 str = "script ";
974# endif
975 else
976 str = " ";
977 full_write2_str(str);
978 full_write2_str(install_dir[APPLET_INSTALL_LOC(i)] + 1);
979 }
859# endif 980# endif
860 full_write2_str(a); 981 full_write2_str(a);
861 full_write2_str("\n"); 982 full_write2_str("\n");
@@ -868,6 +989,7 @@ int busybox_main(int argc UNUSED_PARAM, char **argv)
868 989
869 if (ENABLE_FEATURE_INSTALLER && strcmp(argv[1], "--install") == 0) { 990 if (ENABLE_FEATURE_INSTALLER && strcmp(argv[1], "--install") == 0) {
870 int use_symbolic_links; 991 int use_symbolic_links;
992#if !ENABLE_PLATFORM_MINGW32
871 const char *busybox; 993 const char *busybox;
872 994
873 busybox = xmalloc_readlink(bb_busybox_exec_path); 995 busybox = xmalloc_readlink(bb_busybox_exec_path);
@@ -887,9 +1009,63 @@ int busybox_main(int argc UNUSED_PARAM, char **argv)
887 */ 1009 */
888 use_symbolic_links = (argv[2] && strcmp(argv[2], "-s") == 0 && ++argv); 1010 use_symbolic_links = (argv[2] && strcmp(argv[2], "-s") == 0 && ++argv);
889 install_links(busybox, use_symbolic_links, argv[2]); 1011 install_links(busybox, use_symbolic_links, argv[2]);
1012#else
1013 char *target;
1014 uint32_t opt;
1015 enum { OPT_s = (1 << 0), OPT_u = (1 << 1) };
1016
1017 /* busybox --install [-s] [-u|DIR]
1018 * -s: make symlinks
1019 * -u: install to Unix-style directories in system drive
1020 * DIR: directory to install links to
1021 * If no argument is provided put the links in the same directory
1022 * as busybox.
1023 */
1024 argv += 1;
1025 opt = getopt32(argv, "!su");
1026 argv += optind;
1027
1028 if (opt == (uint32_t)-1 ||
1029 (*argv != NULL && (opt & OPT_u || *(argv + 1) != NULL)))
1030 bb_simple_error_msg_and_die("busybox --install [-s] [-u|DIR]");
1031
1032 if (opt & OPT_u)
1033 target = NULL;
1034 else if (*argv != NULL)
1035 target = *argv;
1036 else
1037 target = dirname(xstrdup(bb_busybox_exec_path));
1038
1039 use_symbolic_links = opt & OPT_s;
1040 /* NULL target -> install to Unix-style dirs */
1041 install_links(bb_busybox_exec_path, use_symbolic_links, target);
1042#endif
890 return 0; 1043 return 0;
891 } 1044 }
892 1045
1046#if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_INSTALLER
1047 if (strcmp(argv[1], "--uninstall") == 0) {
1048 char name[PATH_MAX];
1049 int dry_run = (argv[2] && strcmp(argv[2], "-n") == 0 && ++argv);
1050 const char *file = argv[2];
1051
1052 if (!argv[2])
1053 bb_error_msg_and_die(bb_msg_requires_arg, "--uninstall");
1054
1055 while (enumerate_links(file, name)) {
1056 if (dry_run) {
1057 full_write1_str(name);
1058 full_write1_str("\n");
1059 }
1060 else if (unlink(name) != 0) {
1061 bb_simple_perror_msg(name);
1062 }
1063 file = NULL;
1064 }
1065 return 0;
1066 }
1067#endif
1068
893 if (strcmp(argv[1], "--help") == 0) { 1069 if (strcmp(argv[1], "--help") == 0) {
894 /* "busybox --help [<applet>]" */ 1070 /* "busybox --help [<applet>]" */
895 if (!argv[2] 1071 if (!argv[2]
@@ -939,6 +1115,9 @@ void FAST_FUNC show_usage_if_dash_dash_help(int applet_no, char **argv)
939# if defined APPLET_NO_echo 1115# if defined APPLET_NO_echo
940 && applet_no != APPLET_NO_echo 1116 && applet_no != APPLET_NO_echo
941# endif 1117# endif
1118# if ENABLE_PLATFORM_MINGW32 && defined APPLET_NO_busybox
1119 && applet_no != APPLET_NO_busybox
1120# endif
942 ) { 1121 ) {
943 if (argv[1] && !argv[2] && strcmp(argv[1], "--help") == 0) { 1122 if (argv[1] && !argv[2] && strcmp(argv[1], "--help") == 0) {
944 /* Make "foo --help" exit with 0: */ 1123 /* Make "foo --help" exit with 0: */
@@ -950,7 +1129,14 @@ void FAST_FUNC show_usage_if_dash_dash_help(int applet_no, char **argv)
950 1129
951void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv) 1130void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv)
952{ 1131{
1132# if ENABLE_PLATFORM_MINGW32
1133 int argc = string_array_len(argv);
1134 int i;
1135 const char *vmask;
1136 unsigned int mask;
1137# else
953 int argc; 1138 int argc;
1139# endif
954 1140
955 /* 1141 /*
956 * We do not use argv[0]: do not want to repeat massaging of 1142 * We do not use argv[0]: do not want to repeat massaging of
@@ -963,7 +1149,23 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **ar
963 if (ENABLE_FEATURE_SUID) 1149 if (ENABLE_FEATURE_SUID)
964 check_suid(applet_no); 1150 check_suid(applet_no);
965 1151
1152# if ENABLE_PLATFORM_MINGW32
1153 safe_strncpy(bb_comm,
1154 interp ? bb_basename(argv[interp]) : applet_name,
1155 sizeof(bb_comm));
1156
1157 safe_strncpy(bb_command_line, applet_name, sizeof(bb_command_line));
1158 for (i=1; i < argc && argv[i] &&
1159 strlen(bb_command_line) + strlen(argv[i]) + 2 < 128; ++i) {
1160 strcat(strcat(bb_command_line, " "), argv[i]);
1161 }
1162
1163 vmask = getenv("BB_UMASK");
1164 if (vmask && sscanf(vmask, "%o", &mask) == 1)
1165 umask((mode_t)mask);
1166# else
966 argc = string_array_len(argv); 1167 argc = string_array_len(argv);
1168# endif
967 xfunc_error_retval = applet_main[applet_no](argc, argv); 1169 xfunc_error_retval = applet_main[applet_no](argc, argv);
968 1170
969 /* Note: applet_main() may also not return (die on a xfunc or such) */ 1171 /* Note: applet_main() may also not return (die on a xfunc or such) */
@@ -1073,6 +1275,38 @@ int main(int argc UNUSED_PARAM, char **argv)
1073 argv[0][0] &= 0x7f; 1275 argv[0][0] &= 0x7f;
1074 } 1276 }
1075#endif 1277#endif
1278#if ENABLE_PLATFORM_MINGW32
1279 /* detect if we're running an interpreted script */
1280 if (argv[0][1] == ':' && argv[0][2] == '/') {
1281 switch (argv[0][0]) {
1282 case '2':
1283 ++interp;
1284 /* fall through */
1285 case '1':
1286 ++interp;
1287 argv[0] += 3;
1288 break;
1289 }
1290 }
1291# if ENABLE_FEATURE_EURO
1292 init_codepage();
1293# endif
1294 /* Ignore critical errors, such as calling GetVolumeInformation() on
1295 * a floppy or CDROM drive with no media. */
1296 SetErrorMode(SEM_FAILCRITICALERRORS);
1297#endif
1298
1299#if defined(__MINGW64_VERSION_MAJOR)
1300 if ( stdin ) {
1301 _setmode(fileno(stdin), _O_BINARY);
1302 }
1303 if ( stdout ) {
1304 _setmode(fileno(stdout), _O_BINARY);
1305 }
1306 if ( stderr ) {
1307 _setmode(fileno(stderr), _O_BINARY);
1308 }
1309#endif
1076 1310
1077#if defined(SINGLE_APPLET_MAIN) 1311#if defined(SINGLE_APPLET_MAIN)
1078 1312
@@ -1097,6 +1331,10 @@ int main(int argc UNUSED_PARAM, char **argv)
1097 1331
1098#else 1332#else
1099 1333
1334# if ENABLE_PLATFORM_MINGW32
1335 if (argv[1] && argv[2] && strcmp(argv[1], "--busybox") == 0)
1336 argv += 2;
1337# endif
1100 lbb_prepare("busybox" IF_FEATURE_INDIVIDUAL(, argv)); 1338 lbb_prepare("busybox" IF_FEATURE_INDIVIDUAL(, argv));
1101# if !ENABLE_BUSYBOX 1339# if !ENABLE_BUSYBOX
1102 if (argv[1] && is_prefixed_with(bb_basename(argv[0]), "busybox")) 1340 if (argv[1] && is_prefixed_with(bb_basename(argv[0]), "busybox"))
@@ -1105,6 +1343,15 @@ int main(int argc UNUSED_PARAM, char **argv)
1105 applet_name = argv[0]; 1343 applet_name = argv[0];
1106 if (applet_name[0] == '-') 1344 if (applet_name[0] == '-')
1107 applet_name++; 1345 applet_name++;
1346# if ENABLE_PLATFORM_MINGW32
1347 str_tolower(argv[0]);
1348 bs_to_slash(argv[0]);
1349 if (has_exe_suffix_or_dot(argv[0])) {
1350 char *s = strrchr(argv[0], '.');
1351 if (s)
1352 *s = '\0';
1353 }
1354# endif
1108 applet_name = bb_basename(applet_name); 1355 applet_name = bb_basename(applet_name);
1109 1356
1110 /* If we are a result of execv("/proc/self/exe"), fix ugly comm of "exe" */ 1357 /* If we are a result of execv("/proc/self/exe"), fix ugly comm of "exe" */