aboutsummaryrefslogtreecommitdiff
path: root/libbb/appletlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbb/appletlib.c')
-rw-r--r--libbb/appletlib.c211
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"
66static const char packed_scripts[] ALIGN1 = { PACKED_SCRIPTS }; 76static 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
113static const char packed_usage[] ALIGN1 = { PACKED_USAGE }; 123static 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 */
661static void install_links(const char *busybox, int use_symbolic_links, 677static 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 */
709static 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
693static void install_links(const char *busybox UNUSED_PARAM, 745static 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
1039static int interp = 0;
1040char bb_comm[COMM_LEN];
1041char bb_command_line[128];
1042# endif
1043
908void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv) 1044void 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)
1004int main(int argc UNUSED_PARAM, char **argv) 1164int 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" */