aboutsummaryrefslogtreecommitdiff
path: root/libbb/appletlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbb/appletlib.c')
-rw-r--r--libbb/appletlib.c187
1 files changed, 184 insertions, 3 deletions
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index a515c3fe3..d2f98567e 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -48,6 +48,15 @@
48# define IF_FEATURE_INDIVIDUAL(...) __VA_ARGS__ 48# define IF_FEATURE_INDIVIDUAL(...) __VA_ARGS__
49#endif 49#endif
50 50
51#if (ENABLE_FEATURE_INSTALLER && !ENABLE_PLATFORM_MINGW32) || \
52 (ENABLE_PLATFORM_MINGW32 && (ENABLE_FEATURE_PREFER_APPLETS \
53 || ENABLE_FEATURE_SH_STANDALONE \
54 || ENABLE_FEATURE_SH_NOFORK))
55# define IF_FULL_LIST_OPTION(...) __VA_ARGS__
56#else
57# define IF_FULL_LIST_OPTION(...)
58#endif
59
51#include "usage_compressed.h" 60#include "usage_compressed.h"
52 61
53#if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS 62#if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS
@@ -57,6 +66,7 @@
57# define NUM_SCRIPTS 0 66# define NUM_SCRIPTS 0
58#endif 67#endif
59#if NUM_SCRIPTS > 0 68#if NUM_SCRIPTS > 0
69# define BB_ARCHIVE_PUBLIC
60# include "bb_archive.h" 70# include "bb_archive.h"
61static const char packed_scripts[] ALIGN1 = { PACKED_SCRIPTS }; 71static const char packed_scripts[] ALIGN1 = { PACKED_SCRIPTS };
62#endif 72#endif
@@ -106,6 +116,7 @@ static const char usage_messages[] ALIGN1 = UNPACKED_USAGE;
106#if ENABLE_FEATURE_COMPRESS_USAGE 116#if ENABLE_FEATURE_COMPRESS_USAGE
107 117
108static const char packed_usage[] ALIGN1 = { PACKED_USAGE }; 118static const char packed_usage[] ALIGN1 = { PACKED_USAGE };
119# define BB_ARCHIVE_PUBLIC
109# include "bb_archive.h" 120# include "bb_archive.h"
110# define unpack_usage_messages() \ 121# define unpack_usage_messages() \
111 unpack_bz2_data(packed_usage, sizeof(packed_usage), sizeof(UNPACKED_USAGE)) 122 unpack_bz2_data(packed_usage, sizeof(packed_usage), sizeof(UNPACKED_USAGE))
@@ -149,7 +160,11 @@ void FAST_FUNC bb_show_usage(void)
149 ap--; 160 ap--;
150 } 161 }
151 full_write2_str(bb_banner); 162 full_write2_str(bb_banner);
163#if ENABLE_PLATFORM_MINGW32
164 full_write2_str(" multi-call binary\n");
165#else
152 full_write2_str(" multi-call binary.\n"); /* common string */ 166 full_write2_str(" multi-call binary.\n"); /* common string */
167#endif
153 if (*p == '\b') 168 if (*p == '\b')
154 full_write2_str("\nNo help available\n"); 169 full_write2_str("\nNo help available\n");
155 else { 170 else {
@@ -702,6 +717,7 @@ static void check_suid(int applet_no)
702 717
703 718
704# if ENABLE_FEATURE_INSTALLER 719# if ENABLE_FEATURE_INSTALLER
720# if !ENABLE_PLATFORM_MINGW32
705static const char usr_bin [] ALIGN1 = "/usr/bin/"; 721static const char usr_bin [] ALIGN1 = "/usr/bin/";
706static const char usr_sbin[] ALIGN1 = "/usr/sbin/"; 722static const char usr_sbin[] ALIGN1 = "/usr/sbin/";
707static const char *const install_dir[] = { 723static const char *const install_dir[] = {
@@ -746,6 +762,30 @@ static void install_links(const char *busybox, int use_symbolic_links,
746 continue; 762 continue;
747 } 763 }
748} 764}
765# else /* ENABLE_PLATFORM_MINGW32 */
766static void install_links(const char *busybox,
767 int use_symbolic_links UNUSED_PARAM, char *custom_install_dir)
768{
769 char *fpc;
770 const char *appname = applet_names;
771 int rc;
772
773 if (!is_directory(custom_install_dir, FALSE))
774 bb_error_msg_and_die("'%s' is not a directory", custom_install_dir);
775
776 while (*appname) {
777 fpc = xasprintf("%s/%s.exe", custom_install_dir, appname);
778 rc = link(busybox, fpc);
779 if (rc != 0 && (errno != EEXIST ||
780 strcmp("busybox.exe", bb_basename(fpc)) != 0)) {
781 bb_simple_perror_msg(fpc);
782 }
783 free(fpc);
784 while (*appname++ != '\0')
785 continue;
786 }
787}
788# endif
749# elif ENABLE_BUSYBOX 789# elif ENABLE_BUSYBOX
750static void install_links(const char *busybox UNUSED_PARAM, 790static void install_links(const char *busybox UNUSED_PARAM,
751 int use_symbolic_links UNUSED_PARAM, 791 int use_symbolic_links UNUSED_PARAM,
@@ -832,20 +872,35 @@ int busybox_main(int argc UNUSED_PARAM, char **argv)
832 872
833 dup2(1, 2); 873 dup2(1, 2);
834 full_write2_str(bb_banner); /* reuse const string */ 874 full_write2_str(bb_banner); /* reuse const string */
875#if ENABLE_PLATFORM_MINGW32
876 full_write2_str(" multi-call binary\n"); /* reuse */
877#else
835 full_write2_str(" multi-call binary.\n"); /* reuse */ 878 full_write2_str(" multi-call binary.\n"); /* reuse */
879#endif
880#if defined(MINGW_VER)
881 if (sizeof(MINGW_VER) > 5) {
882 full_write2_str(MINGW_VER "\n\n");
883 }
884#endif
836 full_write2_str( 885 full_write2_str(
837 "BusyBox is copyrighted by many authors between 1998-2015.\n" 886 "BusyBox is copyrighted by many authors between 1998-2020.\n"
838 "Licensed under GPLv2. See source distribution for detailed\n" 887 "Licensed under GPLv2. See source distribution for detailed\n"
839 "copyright notices.\n" 888 "copyright notices.\n"
840 "\n" 889 "\n"
841 "Usage: busybox [function [arguments]...]\n" 890 "Usage: busybox [function [arguments]...]\n"
842 " or: busybox --list"IF_FEATURE_INSTALLER("[-full]")"\n" 891 " or: busybox --list"IF_FULL_LIST_OPTION("[-full]")"\n"
843# if ENABLE_FEATURE_SHOW_SCRIPT && NUM_SCRIPTS > 0 892# if ENABLE_FEATURE_SHOW_SCRIPT && NUM_SCRIPTS > 0
844 " or: busybox --show SCRIPT\n" 893 " or: busybox --show SCRIPT\n"
845# endif 894# endif
846 IF_FEATURE_INSTALLER( 895 IF_FEATURE_INSTALLER(
896 IF_NOT_PLATFORM_MINGW32(
847 " or: busybox --install [-s] [DIR]\n" 897 " or: busybox --install [-s] [DIR]\n"
848 ) 898 )
899 IF_PLATFORM_MINGW32(
900 " or: busybox --install [DIR]\n"
901 " or: busybox --uninstall [-n] file\n"
902 )
903 )
849 " or: function [arguments]...\n" 904 " or: function [arguments]...\n"
850 "\n" 905 "\n"
851 IF_NOT_FEATURE_SH_STANDALONE( 906 IF_NOT_FEATURE_SH_STANDALONE(
@@ -906,9 +961,27 @@ int busybox_main(int argc UNUSED_PARAM, char **argv)
906 const char *a = applet_names; 961 const char *a = applet_names;
907 dup2(1, 2); 962 dup2(1, 2);
908 while (*a) { 963 while (*a) {
909# if ENABLE_FEATURE_INSTALLER 964# if ENABLE_FEATURE_INSTALLER && !ENABLE_PLATFORM_MINGW32
910 if (argv[1][6]) /* --list-full? */ 965 if (argv[1][6]) /* --list-full? */
911 full_write2_str(install_dir[APPLET_INSTALL_LOC(i)] + 1); 966 full_write2_str(install_dir[APPLET_INSTALL_LOC(i)] + 1);
967# elif ENABLE_PLATFORM_MINGW32 && (ENABLE_FEATURE_PREFER_APPLETS \
968 || ENABLE_FEATURE_SH_STANDALONE \
969 || ENABLE_FEATURE_SH_NOFORK)
970 if (argv[1][6]) { /* --list-full? */
971 const char *str;
972
973 if (APPLET_IS_NOFORK(i))
974 str = "NOFORK ";
975 else if (APPLET_IS_NOEXEC(i))
976 str = "noexec ";
977# if NUM_SCRIPTS > 0
978 else if (applet_main[i] == scripted_main)
979 str = "script ";
980# endif
981 else
982 str = " ";
983 full_write2_str(str);
984 }
912# endif 985# endif
913 full_write2_str(a); 986 full_write2_str(a);
914 full_write2_str("\n"); 987 full_write2_str("\n");
@@ -920,6 +993,7 @@ int busybox_main(int argc UNUSED_PARAM, char **argv)
920 } 993 }
921 994
922 if (ENABLE_FEATURE_INSTALLER && strcmp(argv[1], "--install") == 0) { 995 if (ENABLE_FEATURE_INSTALLER && strcmp(argv[1], "--install") == 0) {
996#if !ENABLE_PLATFORM_MINGW32
923 int use_symbolic_links; 997 int use_symbolic_links;
924 const char *busybox; 998 const char *busybox;
925 999
@@ -940,9 +1014,40 @@ int busybox_main(int argc UNUSED_PARAM, char **argv)
940 */ 1014 */
941 use_symbolic_links = (argv[2] && strcmp(argv[2], "-s") == 0 && ++argv); 1015 use_symbolic_links = (argv[2] && strcmp(argv[2], "-s") == 0 && ++argv);
942 install_links(busybox, use_symbolic_links, argv[2]); 1016 install_links(busybox, use_symbolic_links, argv[2]);
1017#else
1018 /* busybox --install [DIR]
1019 * where DIR is the directory to install to. If DIR is not
1020 * provided put the links in the same directory as busybox.
1021 */
1022 install_links(bb_busybox_exec_path, FALSE, argv[2] ? argv[2] :
1023 dirname(xstrdup(bb_busybox_exec_path)));
1024#endif
943 return 0; 1025 return 0;
944 } 1026 }
945 1027
1028#if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_INSTALLER
1029 if (strcmp(argv[1], "--uninstall") == 0) {
1030 char name[PATH_MAX];
1031 int dry_run = (argv[2] && strcmp(argv[2], "-n") == 0 && ++argv);
1032 const char *file = argv[2];
1033
1034 if (!argv[2])
1035 bb_error_msg_and_die(bb_msg_requires_arg, "--uninstall");
1036
1037 while (enumerate_links(file, name)) {
1038 if (dry_run) {
1039 full_write1_str(name);
1040 full_write1_str("\n");
1041 }
1042 else if (unlink(name) != 0) {
1043 bb_simple_perror_msg(name);
1044 }
1045 file = NULL;
1046 }
1047 return 0;
1048 }
1049#endif
1050
946 if (strcmp(argv[1], "--help") == 0) { 1051 if (strcmp(argv[1], "--help") == 0) {
947 /* "busybox --help [<applet>]" */ 1052 /* "busybox --help [<applet>]" */
948 if (!argv[2]) 1053 if (!argv[2])
@@ -962,15 +1067,42 @@ int busybox_main(int argc UNUSED_PARAM, char **argv)
962# endif 1067# endif
963 1068
964# if NUM_APPLETS > 0 1069# if NUM_APPLETS > 0
1070
1071# if ENABLE_PLATFORM_MINGW32
1072static int interp = 0;
1073char bb_comm[COMM_LEN];
1074char bb_command_line[128];
1075# endif
1076
965void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv) 1077void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv)
966{ 1078{
967 int argc = string_array_len(argv); 1079 int argc = string_array_len(argv);
1080# if ENABLE_PLATFORM_MINGW32
1081 int i;
1082 const char *vmask;
1083 unsigned int mask;
1084# endif
968 1085
969 /* 1086 /*
970 * We do not use argv[0]: do not want to repeat massaging of 1087 * We do not use argv[0]: do not want to repeat massaging of
971 * "-/sbin/halt" -> "halt", for example. 1088 * "-/sbin/halt" -> "halt", for example.
972 */ 1089 */
973 applet_name = name; 1090 applet_name = name;
1091# if ENABLE_PLATFORM_MINGW32
1092 safe_strncpy(bb_comm,
1093 interp ? bb_basename(argv[interp]) : applet_name,
1094 sizeof(bb_comm));
1095
1096 safe_strncpy(bb_command_line, applet_name, sizeof(bb_command_line));
1097 for (i=1; i < argc && argv[i] &&
1098 strlen(bb_command_line) + strlen(argv[i]) + 2 < 128; ++i) {
1099 strcat(strcat(bb_command_line, " "), argv[i]);
1100 }
1101
1102 vmask = getenv("BB_UMASK");
1103 if (vmask && sscanf(vmask, "%o", &mask) == 1)
1104 umask((mode_t)(mask&0777));
1105# endif
974 1106
975 /* Special case. POSIX says "test --help" 1107 /* Special case. POSIX says "test --help"
976 * should be no different from e.g. "test --foo". 1108 * should be no different from e.g. "test --foo".
@@ -987,6 +1119,9 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **ar
987# if defined APPLET_NO_false 1119# if defined APPLET_NO_false
988 && applet_no != APPLET_NO_false 1120 && applet_no != APPLET_NO_false
989# endif 1121# endif
1122# if defined APPLET_NO_busybox
1123 && applet_no != APPLET_NO_busybox
1124# endif
990 ) { 1125 ) {
991 if (argc == 2 && strcmp(argv[1], "--help") == 0) { 1126 if (argc == 2 && strcmp(argv[1], "--help") == 0) {
992 /* Make "foo --help" exit with 0: */ 1127 /* Make "foo --help" exit with 0: */
@@ -996,6 +1131,7 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **ar
996 } 1131 }
997 if (ENABLE_FEATURE_SUID) 1132 if (ENABLE_FEATURE_SUID)
998 check_suid(applet_no); 1133 check_suid(applet_no);
1134
999 xfunc_error_retval = applet_main[applet_no](argc, argv); 1135 xfunc_error_retval = applet_main[applet_no](argc, argv);
1000 /* Note: applet_main() may also not return (die on a xfunc or such) */ 1136 /* Note: applet_main() may also not return (die on a xfunc or such) */
1001 xfunc_die(); 1137 xfunc_die();
@@ -1061,6 +1197,9 @@ int lbb_main(char **argv)
1061int main(int argc UNUSED_PARAM, char **argv) 1197int main(int argc UNUSED_PARAM, char **argv)
1062#endif 1198#endif
1063{ 1199{
1200#if ENABLE_PLATFORM_MINGW32
1201 char *s;
1202#endif
1064#if 0 1203#if 0
1065 /* TODO: find a use for a block of memory between end of .bss 1204 /* TODO: find a use for a block of memory between end of .bss
1066 * and end of page. For example, I'm getting "_end:0x812e698 2408 bytes" 1205 * and end of page. For example, I'm getting "_end:0x812e698 2408 bytes"
@@ -1104,6 +1243,38 @@ int main(int argc UNUSED_PARAM, char **argv)
1104 argv[0][0] &= 0x7f; 1243 argv[0][0] &= 0x7f;
1105 } 1244 }
1106#endif 1245#endif
1246#if ENABLE_PLATFORM_MINGW32
1247 /* detect if we're running an interpreted script */
1248 if (argv[0][1] == ':' && argv[0][2] == '/') {
1249 switch (argv[0][0]) {
1250 case '2':
1251 ++interp;
1252 /* fall through */
1253 case '1':
1254 ++interp;
1255 argv[0] += 3;
1256 break;
1257 }
1258 }
1259# if ENABLE_FEATURE_EURO
1260 init_codepage();
1261# endif
1262 /* Ignore critical errors, such as calling GetVolumeInformation() on
1263 * a floppy or CDROM drive with no media. */
1264 SetErrorMode(SEM_FAILCRITICALERRORS);
1265#endif
1266
1267#if defined(__MINGW64_VERSION_MAJOR)
1268 if ( stdin ) {
1269 _setmode(fileno(stdin), _O_BINARY);
1270 }
1271 if ( stdout ) {
1272 _setmode(fileno(stdout), _O_BINARY);
1273 }
1274 if ( stderr ) {
1275 _setmode(fileno(stderr), _O_BINARY);
1276 }
1277#endif
1107 1278
1108#if defined(SINGLE_APPLET_MAIN) 1279#if defined(SINGLE_APPLET_MAIN)
1109 1280
@@ -1128,6 +1299,10 @@ int main(int argc UNUSED_PARAM, char **argv)
1128 1299
1129#else 1300#else
1130 1301
1302# if ENABLE_PLATFORM_MINGW32
1303 if (argv[1] && argv[2] && strcmp(argv[1], "--busybox") == 0)
1304 argv += 2;
1305# endif
1131 lbb_prepare("busybox" IF_FEATURE_INDIVIDUAL(, argv)); 1306 lbb_prepare("busybox" IF_FEATURE_INDIVIDUAL(, argv));
1132# if !ENABLE_BUSYBOX 1307# if !ENABLE_BUSYBOX
1133 if (argv[1] && is_prefixed_with(bb_basename(argv[0]), "busybox")) 1308 if (argv[1] && is_prefixed_with(bb_basename(argv[0]), "busybox"))
@@ -1136,6 +1311,12 @@ int main(int argc UNUSED_PARAM, char **argv)
1136 applet_name = argv[0]; 1311 applet_name = argv[0];
1137 if (applet_name[0] == '-') 1312 if (applet_name[0] == '-')
1138 applet_name++; 1313 applet_name++;
1314# if ENABLE_PLATFORM_MINGW32
1315 str_tolower(argv[0]);
1316 bs_to_slash(argv[0]);
1317 if (has_exe_suffix_or_dot(argv[0]) && (s=strrchr(argv[0], '.')))
1318 *s = '\0';
1319# endif
1139 applet_name = bb_basename(applet_name); 1320 applet_name = bb_basename(applet_name);
1140 1321
1141 /* If we are a result of execv("/proc/self/exe"), fix ugly comm of "exe" */ 1322 /* If we are a result of execv("/proc/self/exe"), fix ugly comm of "exe" */