diff options
Diffstat (limited to 'libbb/appletlib.c')
-rw-r--r-- | libbb/appletlib.c | 211 |
1 files changed, 208 insertions, 3 deletions
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 542211255..320cb5b13 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 |
@@ -111,6 +121,7 @@ static const char usage_messages[] ALIGN1 = UNPACKED_USAGE; | |||
111 | #if ENABLE_FEATURE_COMPRESS_USAGE | 121 | #if ENABLE_FEATURE_COMPRESS_USAGE |
112 | 122 | ||
113 | static const char packed_usage[] ALIGN1 = { PACKED_USAGE }; | 123 | static const char packed_usage[] ALIGN1 = { PACKED_USAGE }; |
124 | # define BB_ARCHIVE_PUBLIC | ||
114 | # include "bb_archive.h" | 125 | # include "bb_archive.h" |
115 | # define unpack_usage_messages() \ | 126 | # define unpack_usage_messages() \ |
116 | unpack_bz2_data(packed_usage, sizeof(packed_usage), sizeof(UNPACKED_USAGE)) | 127 | unpack_bz2_data(packed_usage, sizeof(packed_usage), sizeof(UNPACKED_USAGE)) |
@@ -154,7 +165,11 @@ void FAST_FUNC bb_show_usage(void) | |||
154 | ap--; | 165 | ap--; |
155 | } | 166 | } |
156 | full_write2_str(bb_banner); | 167 | full_write2_str(bb_banner); |
168 | #if ENABLE_PLATFORM_MINGW32 | ||
169 | full_write2_str(" multi-call binary\n"); | ||
170 | #else | ||
157 | full_write2_str(" multi-call binary.\n"); /* common string */ | 171 | full_write2_str(" multi-call binary.\n"); /* common string */ |
172 | #endif | ||
158 | if (*p == '\b') | 173 | if (*p == '\b') |
159 | full_write2_str("\nNo help available\n"); | 174 | full_write2_str("\nNo help available\n"); |
160 | else { | 175 | else { |
@@ -657,6 +672,7 @@ static const char *const install_dir[] = { | |||
657 | # endif | 672 | # endif |
658 | }; | 673 | }; |
659 | 674 | ||
675 | # if !ENABLE_PLATFORM_MINGW32 | ||
660 | /* create (sym)links for each applet */ | 676 | /* create (sym)links for each applet */ |
661 | static void install_links(const char *busybox, int use_symbolic_links, | 677 | static void install_links(const char *busybox, int use_symbolic_links, |
662 | char *custom_install_dir) | 678 | char *custom_install_dir) |
@@ -689,6 +705,42 @@ static void install_links(const char *busybox, int use_symbolic_links, | |||
689 | continue; | 705 | continue; |
690 | } | 706 | } |
691 | } | 707 | } |
708 | # else /* ENABLE_PLATFORM_MINGW32 */ | ||
709 | static void install_links(const char *busybox, | ||
710 | int use_symbolic_links UNUSED_PARAM, char *custom_install_dir) | ||
711 | { | ||
712 | char *fpc; | ||
713 | const char *appname = applet_names; | ||
714 | const char *sd = NULL; | ||
715 | int i, rc; | ||
716 | |||
717 | if (custom_install_dir != NULL) { | ||
718 | bb_make_directory(custom_install_dir, 0755, FILEUTILS_RECUR); | ||
719 | } | ||
720 | else { | ||
721 | sd = get_system_drive(); | ||
722 | for (i=1; i<ARRAY_SIZE(install_dir); ++i) { | ||
723 | fpc = xasprintf("%s%s", sd ?: "", install_dir[i]); | ||
724 | bb_make_directory(fpc, 0755, FILEUTILS_RECUR); | ||
725 | free(fpc); | ||
726 | } | ||
727 | } | ||
728 | |||
729 | for (i = 0; i < ARRAY_SIZE(applet_main); i++) { | ||
730 | fpc = xasprintf("%s%s/%s.exe", sd ?: "", | ||
731 | custom_install_dir ?: install_dir[APPLET_INSTALL_LOC(i)], | ||
732 | appname); | ||
733 | rc = link(busybox, fpc); | ||
734 | if (rc != 0 && (errno != EEXIST || | ||
735 | strcmp("busybox.exe", bb_basename(fpc)) != 0)) { | ||
736 | bb_simple_perror_msg(fpc); | ||
737 | } | ||
738 | free(fpc); | ||
739 | while (*appname++ != '\0') | ||
740 | continue; | ||
741 | } | ||
742 | } | ||
743 | # endif | ||
692 | # elif ENABLE_BUSYBOX | 744 | # elif ENABLE_BUSYBOX |
693 | static void install_links(const char *busybox UNUSED_PARAM, | 745 | static void install_links(const char *busybox UNUSED_PARAM, |
694 | int use_symbolic_links UNUSED_PARAM, | 746 | int use_symbolic_links UNUSED_PARAM, |
@@ -775,20 +827,35 @@ int busybox_main(int argc UNUSED_PARAM, char **argv) | |||
775 | 827 | ||
776 | dup2(1, 2); | 828 | dup2(1, 2); |
777 | full_write2_str(bb_banner); /* reuse const string */ | 829 | full_write2_str(bb_banner); /* reuse const string */ |
830 | #if ENABLE_PLATFORM_MINGW32 | ||
831 | full_write2_str(" multi-call binary\n"); /* reuse */ | ||
832 | #else | ||
778 | full_write2_str(" multi-call binary.\n"); /* reuse */ | 833 | full_write2_str(" multi-call binary.\n"); /* reuse */ |
834 | #endif | ||
835 | #if defined(MINGW_VER) | ||
836 | if (sizeof(MINGW_VER) > 5) { | ||
837 | full_write2_str(MINGW_VER "\n\n"); | ||
838 | } | ||
839 | #endif | ||
779 | full_write2_str( | 840 | full_write2_str( |
780 | "BusyBox is copyrighted by many authors between 1998-2015.\n" | 841 | "BusyBox is copyrighted by many authors between 1998-2021.\n" |
781 | "Licensed under GPLv2. See source distribution for detailed\n" | 842 | "Licensed under GPLv2. See source distribution for detailed\n" |
782 | "copyright notices.\n" | 843 | "copyright notices.\n" |
783 | "\n" | 844 | "\n" |
784 | "Usage: busybox [function [arguments]...]\n" | 845 | "Usage: busybox [function [arguments]...]\n" |
785 | " or: busybox --list"IF_FEATURE_INSTALLER("[-full]")"\n" | 846 | " or: busybox --list"IF_FULL_LIST_OPTION("[-full]")"\n" |
786 | # if ENABLE_FEATURE_SHOW_SCRIPT && NUM_SCRIPTS > 0 | 847 | # if ENABLE_FEATURE_SHOW_SCRIPT && NUM_SCRIPTS > 0 |
787 | " or: busybox --show SCRIPT\n" | 848 | " or: busybox --show SCRIPT\n" |
788 | # endif | 849 | # endif |
789 | IF_FEATURE_INSTALLER( | 850 | IF_FEATURE_INSTALLER( |
851 | IF_NOT_PLATFORM_MINGW32( | ||
790 | " or: busybox --install [-s] [DIR]\n" | 852 | " or: busybox --install [-s] [DIR]\n" |
791 | ) | 853 | ) |
854 | IF_PLATFORM_MINGW32( | ||
855 | " or: busybox --install [-u|DIR]\n" | ||
856 | " or: busybox --uninstall [-n] file\n" | ||
857 | ) | ||
858 | ) | ||
792 | " or: function [arguments]...\n" | 859 | " or: function [arguments]...\n" |
793 | "\n" | 860 | "\n" |
794 | IF_NOT_FEATURE_SH_STANDALONE( | 861 | IF_NOT_FEATURE_SH_STANDALONE( |
@@ -849,9 +916,28 @@ int busybox_main(int argc UNUSED_PARAM, char **argv) | |||
849 | const char *a = applet_names; | 916 | const char *a = applet_names; |
850 | dup2(1, 2); | 917 | dup2(1, 2); |
851 | while (*a) { | 918 | while (*a) { |
852 | # if ENABLE_FEATURE_INSTALLER | 919 | # if ENABLE_FEATURE_INSTALLER && !ENABLE_PLATFORM_MINGW32 |
853 | if (argv[1][6]) /* --list-full? */ | 920 | if (argv[1][6]) /* --list-full? */ |
854 | full_write2_str(install_dir[APPLET_INSTALL_LOC(i)] + 1); | 921 | full_write2_str(install_dir[APPLET_INSTALL_LOC(i)] + 1); |
922 | # elif ENABLE_PLATFORM_MINGW32 && (ENABLE_FEATURE_PREFER_APPLETS \ | ||
923 | || ENABLE_FEATURE_SH_STANDALONE \ | ||
924 | || ENABLE_FEATURE_SH_NOFORK) | ||
925 | if (argv[1][6]) { /* --list-full? */ | ||
926 | const char *str; | ||
927 | |||
928 | if (APPLET_IS_NOFORK(i)) | ||
929 | str = "NOFORK "; | ||
930 | else if (APPLET_IS_NOEXEC(i)) | ||
931 | str = "noexec "; | ||
932 | # if NUM_SCRIPTS > 0 | ||
933 | else if (applet_main[i] == scripted_main) | ||
934 | str = "script "; | ||
935 | # endif | ||
936 | else | ||
937 | str = " "; | ||
938 | full_write2_str(str); | ||
939 | full_write2_str(install_dir[APPLET_INSTALL_LOC(i)] + 1); | ||
940 | } | ||
855 | # endif | 941 | # endif |
856 | full_write2_str(a); | 942 | full_write2_str(a); |
857 | full_write2_str("\n"); | 943 | full_write2_str("\n"); |
@@ -863,6 +949,7 @@ int busybox_main(int argc UNUSED_PARAM, char **argv) | |||
863 | } | 949 | } |
864 | 950 | ||
865 | if (ENABLE_FEATURE_INSTALLER && strcmp(argv[1], "--install") == 0) { | 951 | if (ENABLE_FEATURE_INSTALLER && strcmp(argv[1], "--install") == 0) { |
952 | #if !ENABLE_PLATFORM_MINGW32 | ||
866 | int use_symbolic_links; | 953 | int use_symbolic_links; |
867 | const char *busybox; | 954 | const char *busybox; |
868 | 955 | ||
@@ -883,8 +970,50 @@ int busybox_main(int argc UNUSED_PARAM, char **argv) | |||
883 | */ | 970 | */ |
884 | use_symbolic_links = (argv[2] && strcmp(argv[2], "-s") == 0 && ++argv); | 971 | use_symbolic_links = (argv[2] && strcmp(argv[2], "-s") == 0 && ++argv); |
885 | install_links(busybox, use_symbolic_links, argv[2]); | 972 | install_links(busybox, use_symbolic_links, argv[2]); |
973 | #else | ||
974 | char *target = NULL; | ||
975 | |||
976 | /* busybox --install [-u|DIR] | ||
977 | * -u: install to Unix-style directories in system drive | ||
978 | * DIR: directory to install links to | ||
979 | * If no argument is provided put the links in the same directory | ||
980 | * as busybox. | ||
981 | */ | ||
982 | if (argv[2]) { | ||
983 | if (strcmp(argv[2], "-u") != 0) | ||
984 | target = argv[2]; | ||
985 | } | ||
986 | else { | ||
987 | target = dirname(xstrdup(bb_busybox_exec_path)); | ||
988 | } | ||
989 | /* NULL target -> install to Unix-style dirs */ | ||
990 | install_links(bb_busybox_exec_path, FALSE, target); | ||
991 | #endif | ||
992 | return 0; | ||
993 | } | ||
994 | |||
995 | #if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_INSTALLER | ||
996 | if (strcmp(argv[1], "--uninstall") == 0) { | ||
997 | char name[PATH_MAX]; | ||
998 | int dry_run = (argv[2] && strcmp(argv[2], "-n") == 0 && ++argv); | ||
999 | const char *file = argv[2]; | ||
1000 | |||
1001 | if (!argv[2]) | ||
1002 | bb_error_msg_and_die(bb_msg_requires_arg, "--uninstall"); | ||
1003 | |||
1004 | while (enumerate_links(file, name)) { | ||
1005 | if (dry_run) { | ||
1006 | full_write1_str(name); | ||
1007 | full_write1_str("\n"); | ||
1008 | } | ||
1009 | else if (unlink(name) != 0) { | ||
1010 | bb_simple_perror_msg(name); | ||
1011 | } | ||
1012 | file = NULL; | ||
1013 | } | ||
886 | return 0; | 1014 | return 0; |
887 | } | 1015 | } |
1016 | #endif | ||
888 | 1017 | ||
889 | if (strcmp(argv[1], "--help") == 0) { | 1018 | if (strcmp(argv[1], "--help") == 0) { |
890 | /* "busybox --help [<applet>]" */ | 1019 | /* "busybox --help [<applet>]" */ |
@@ -905,15 +1034,42 @@ int busybox_main(int argc UNUSED_PARAM, char **argv) | |||
905 | # endif | 1034 | # endif |
906 | 1035 | ||
907 | # if NUM_APPLETS > 0 | 1036 | # if NUM_APPLETS > 0 |
1037 | |||
1038 | # if ENABLE_PLATFORM_MINGW32 | ||
1039 | static int interp = 0; | ||
1040 | char bb_comm[COMM_LEN]; | ||
1041 | char bb_command_line[128]; | ||
1042 | # endif | ||
1043 | |||
908 | void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv) | 1044 | void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv) |
909 | { | 1045 | { |
910 | int argc = string_array_len(argv); | 1046 | int argc = string_array_len(argv); |
1047 | # if ENABLE_PLATFORM_MINGW32 | ||
1048 | int i; | ||
1049 | const char *vmask; | ||
1050 | unsigned int mask; | ||
1051 | # endif | ||
911 | 1052 | ||
912 | /* | 1053 | /* |
913 | * We do not use argv[0]: do not want to repeat massaging of | 1054 | * We do not use argv[0]: do not want to repeat massaging of |
914 | * "-/sbin/halt" -> "halt", for example. | 1055 | * "-/sbin/halt" -> "halt", for example. |
915 | */ | 1056 | */ |
916 | applet_name = name; | 1057 | applet_name = name; |
1058 | # if ENABLE_PLATFORM_MINGW32 | ||
1059 | safe_strncpy(bb_comm, | ||
1060 | interp ? bb_basename(argv[interp]) : applet_name, | ||
1061 | sizeof(bb_comm)); | ||
1062 | |||
1063 | safe_strncpy(bb_command_line, applet_name, sizeof(bb_command_line)); | ||
1064 | for (i=1; i < argc && argv[i] && | ||
1065 | strlen(bb_command_line) + strlen(argv[i]) + 2 < 128; ++i) { | ||
1066 | strcat(strcat(bb_command_line, " "), argv[i]); | ||
1067 | } | ||
1068 | |||
1069 | vmask = getenv("BB_UMASK"); | ||
1070 | if (vmask && sscanf(vmask, "%o", &mask) == 1) | ||
1071 | umask((mode_t)(mask&0777)); | ||
1072 | # endif | ||
917 | 1073 | ||
918 | /* Special case. POSIX says "test --help" | 1074 | /* Special case. POSIX says "test --help" |
919 | * should be no different from e.g. "test --foo". | 1075 | * should be no different from e.g. "test --foo". |
@@ -930,6 +1086,9 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **ar | |||
930 | # if defined APPLET_NO_false | 1086 | # if defined APPLET_NO_false |
931 | && applet_no != APPLET_NO_false | 1087 | && applet_no != APPLET_NO_false |
932 | # endif | 1088 | # endif |
1089 | # if defined APPLET_NO_busybox | ||
1090 | && applet_no != APPLET_NO_busybox | ||
1091 | # endif | ||
933 | ) { | 1092 | ) { |
934 | if (argc == 2 && strcmp(argv[1], "--help") == 0) { | 1093 | if (argc == 2 && strcmp(argv[1], "--help") == 0) { |
935 | /* Make "foo --help" exit with 0: */ | 1094 | /* Make "foo --help" exit with 0: */ |
@@ -939,6 +1098,7 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **ar | |||
939 | } | 1098 | } |
940 | if (ENABLE_FEATURE_SUID) | 1099 | if (ENABLE_FEATURE_SUID) |
941 | check_suid(applet_no); | 1100 | check_suid(applet_no); |
1101 | |||
942 | xfunc_error_retval = applet_main[applet_no](argc, argv); | 1102 | xfunc_error_retval = applet_main[applet_no](argc, argv); |
943 | /* Note: applet_main() may also not return (die on a xfunc or such) */ | 1103 | /* Note: applet_main() may also not return (die on a xfunc or such) */ |
944 | xfunc_die(); | 1104 | xfunc_die(); |
@@ -1004,6 +1164,9 @@ int lbb_main(char **argv) | |||
1004 | int main(int argc UNUSED_PARAM, char **argv) | 1164 | int main(int argc UNUSED_PARAM, char **argv) |
1005 | #endif | 1165 | #endif |
1006 | { | 1166 | { |
1167 | #if ENABLE_PLATFORM_MINGW32 | ||
1168 | char *s; | ||
1169 | #endif | ||
1007 | #if 0 | 1170 | #if 0 |
1008 | /* TODO: find a use for a block of memory between end of .bss | 1171 | /* TODO: find a use for a block of memory between end of .bss |
1009 | * and end of page. For example, I'm getting "_end:0x812e698 2408 bytes" | 1172 | * and end of page. For example, I'm getting "_end:0x812e698 2408 bytes" |
@@ -1047,6 +1210,38 @@ int main(int argc UNUSED_PARAM, char **argv) | |||
1047 | argv[0][0] &= 0x7f; | 1210 | argv[0][0] &= 0x7f; |
1048 | } | 1211 | } |
1049 | #endif | 1212 | #endif |
1213 | #if ENABLE_PLATFORM_MINGW32 | ||
1214 | /* detect if we're running an interpreted script */ | ||
1215 | if (argv[0][1] == ':' && argv[0][2] == '/') { | ||
1216 | switch (argv[0][0]) { | ||
1217 | case '2': | ||
1218 | ++interp; | ||
1219 | /* fall through */ | ||
1220 | case '1': | ||
1221 | ++interp; | ||
1222 | argv[0] += 3; | ||
1223 | break; | ||
1224 | } | ||
1225 | } | ||
1226 | # if ENABLE_FEATURE_EURO | ||
1227 | init_codepage(); | ||
1228 | # endif | ||
1229 | /* Ignore critical errors, such as calling GetVolumeInformation() on | ||
1230 | * a floppy or CDROM drive with no media. */ | ||
1231 | SetErrorMode(SEM_FAILCRITICALERRORS); | ||
1232 | #endif | ||
1233 | |||
1234 | #if defined(__MINGW64_VERSION_MAJOR) | ||
1235 | if ( stdin ) { | ||
1236 | _setmode(fileno(stdin), _O_BINARY); | ||
1237 | } | ||
1238 | if ( stdout ) { | ||
1239 | _setmode(fileno(stdout), _O_BINARY); | ||
1240 | } | ||
1241 | if ( stderr ) { | ||
1242 | _setmode(fileno(stderr), _O_BINARY); | ||
1243 | } | ||
1244 | #endif | ||
1050 | 1245 | ||
1051 | #if defined(SINGLE_APPLET_MAIN) | 1246 | #if defined(SINGLE_APPLET_MAIN) |
1052 | 1247 | ||
@@ -1071,6 +1266,10 @@ int main(int argc UNUSED_PARAM, char **argv) | |||
1071 | 1266 | ||
1072 | #else | 1267 | #else |
1073 | 1268 | ||
1269 | # if ENABLE_PLATFORM_MINGW32 | ||
1270 | if (argv[1] && argv[2] && strcmp(argv[1], "--busybox") == 0) | ||
1271 | argv += 2; | ||
1272 | # endif | ||
1074 | lbb_prepare("busybox" IF_FEATURE_INDIVIDUAL(, argv)); | 1273 | lbb_prepare("busybox" IF_FEATURE_INDIVIDUAL(, argv)); |
1075 | # if !ENABLE_BUSYBOX | 1274 | # if !ENABLE_BUSYBOX |
1076 | if (argv[1] && is_prefixed_with(bb_basename(argv[0]), "busybox")) | 1275 | if (argv[1] && is_prefixed_with(bb_basename(argv[0]), "busybox")) |
@@ -1079,6 +1278,12 @@ int main(int argc UNUSED_PARAM, char **argv) | |||
1079 | applet_name = argv[0]; | 1278 | applet_name = argv[0]; |
1080 | if (applet_name[0] == '-') | 1279 | if (applet_name[0] == '-') |
1081 | applet_name++; | 1280 | applet_name++; |
1281 | # if ENABLE_PLATFORM_MINGW32 | ||
1282 | str_tolower(argv[0]); | ||
1283 | bs_to_slash(argv[0]); | ||
1284 | if (has_exe_suffix_or_dot(argv[0]) && (s=strrchr(argv[0], '.'))) | ||
1285 | *s = '\0'; | ||
1286 | # endif | ||
1082 | applet_name = bb_basename(applet_name); | 1287 | applet_name = bb_basename(applet_name); |
1083 | 1288 | ||
1084 | /* If we are a result of execv("/proc/self/exe"), fix ugly comm of "exe" */ | 1289 | /* If we are a result of execv("/proc/self/exe"), fix ugly comm of "exe" */ |