diff options
Diffstat (limited to 'libbb/appletlib.c')
-rw-r--r-- | libbb/appletlib.c | 187 |
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" |
61 | static const char packed_scripts[] ALIGN1 = { PACKED_SCRIPTS }; | 71 | static 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 | ||
108 | static const char packed_usage[] ALIGN1 = { PACKED_USAGE }; | 118 | static 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 | ||
705 | static const char usr_bin [] ALIGN1 = "/usr/bin/"; | 721 | static const char usr_bin [] ALIGN1 = "/usr/bin/"; |
706 | static const char usr_sbin[] ALIGN1 = "/usr/sbin/"; | 722 | static const char usr_sbin[] ALIGN1 = "/usr/sbin/"; |
707 | static const char *const install_dir[] = { | 723 | static 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 */ | ||
766 | static 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 |
750 | static void install_links(const char *busybox UNUSED_PARAM, | 790 | static 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 | ||
1072 | static int interp = 0; | ||
1073 | char bb_comm[COMM_LEN]; | ||
1074 | char bb_command_line[128]; | ||
1075 | # endif | ||
1076 | |||
965 | void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv) | 1077 | void 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) | |||
1061 | int main(int argc UNUSED_PARAM, char **argv) | 1197 | int 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" */ |