aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2024-08-04 12:36:09 +0100
committerRon Yorston <rmy@pobox.com>2024-08-04 12:36:09 +0100
commit5eb14d55da843927f792e35dbf54079579f0d701 (patch)
tree98116bdbfbe3e990f98d06751d569d647979d040
parentfb959dd3f29c2d0655e01147f7b0b9bb2dab4223 (diff)
downloadbusybox-w32-5eb14d55da843927f792e35dbf54079579f0d701.tar.gz
busybox-w32-5eb14d55da843927f792e35dbf54079579f0d701.tar.bz2
busybox-w32-5eb14d55da843927f792e35dbf54079579f0d701.zip
su: allow an alternative shell to be selected
Add the '-s' option to allow an alternative shell to be given. No PATH search is performed for the shell, so an absolute or relative path to a suitable executable must be provided. Certain features are only available when the built-in shell is used: - The '-N' option, which allows the console window to remain open when the shell exits. - The fix which allows the current directory to be retained despite the efforts of ShellExecute() to change it. - The friendly message in the console title. Adds 128 bytes. (GitHub issue #438)
-rw-r--r--loginutils/suw32.c49
1 files changed, 30 insertions, 19 deletions
diff --git a/loginutils/suw32.c b/loginutils/suw32.c
index a0afe5bb7..cbe727969 100644
--- a/loginutils/suw32.c
+++ b/loginutils/suw32.c
@@ -16,22 +16,24 @@
16//kbuild:lib-$(CONFIG_SUW32) += suw32.o 16//kbuild:lib-$(CONFIG_SUW32) += suw32.o
17 17
18//usage:#define suw32_trivial_usage 18//usage:#define suw32_trivial_usage
19//usage: "[-NW] [root]\n" 19//usage: "[-W] [-N|-s SHELL] [root]\n"
20//usage: "or: su [-NW] -c CMD_STRING [[--] root [ARG0 [ARG...]]]\n" 20//usage: "or: su [-W] [-N|-s SHELL] -c CMD_STRING [[--] root [ARG0 [ARG...]]]\n"
21//usage: "or: su [-NW] [--] root [arbitrary sh arguments]" 21//usage: "or: su [-W] [-N|-s SHELL] [--] root [arbitrary sh arguments]"
22//usage:#define suw32_full_usage "\n\n" 22//usage:#define suw32_full_usage "\n\n"
23//usage: "Run shell with elevated privileges\n" 23//usage: "Run shell with elevated privileges\n"
24//usage: "\n -c CMD Command to pass to 'sh -c'" 24//usage: "\n -c CMD Command to pass to 'sh -c'"
25//usage: "\n -N Don't close console when shell exits" 25//usage: "\n -s SHELL Use specified shell"
26//usage: "\n -W Wait for shell exit code" 26//usage: "\n -N Don't close console when shell exits"
27//usage: "\n -W Wait for shell exit code"
27 28
28#include "libbb.h" 29#include "libbb.h"
29#include "lazyload.h" 30#include "lazyload.h"
30 31
31enum { 32enum {
32 OPT_c = (1 << 0), 33 OPT_c = (1 << 0),
33 OPT_N = (1 << 1), 34 OPT_s = (1 << 1),
34 OPT_W = (1 << 2) 35 OPT_N = (1 << 2),
36 OPT_W = (1 << 3)
35}; 37};
36 38
37int suw32_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 39int suw32_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
@@ -40,6 +42,7 @@ int suw32_main(int argc UNUSED_PARAM, char **argv)
40 int ret = 0; 42 int ret = 0;
41 unsigned opt; 43 unsigned opt;
42 char *opt_command = NULL; 44 char *opt_command = NULL;
45 char *opt_shell = NULL;
43 SHELLEXECUTEINFO info; 46 SHELLEXECUTEINFO info;
44 char *bb_path, *cwd, *realcwd, *q, *args; 47 char *bb_path, *cwd, *realcwd, *q, *args;
45 DECLARE_PROC_ADDR(BOOL, ShellExecuteExA, SHELLEXECUTEINFOA *); 48 DECLARE_PROC_ADDR(BOOL, ShellExecuteExA, SHELLEXECUTEINFOA *);
@@ -54,7 +57,7 @@ int suw32_main(int argc UNUSED_PARAM, char **argv)
54 } 57 }
55#endif 58#endif
56 59
57 opt = getopt32(argv, "c:NW", &opt_command); 60 opt = getopt32(argv, "^c:s:NW" "\0" "s--N:N--s", &opt_command, &opt_shell);
58 argv += optind; 61 argv += optind;
59 if (argv[0]) { 62 if (argv[0]) {
60 if (strcmp(argv[0], "root") != 0) { 63 if (strcmp(argv[0], "root") != 0) {
@@ -64,7 +67,15 @@ int suw32_main(int argc UNUSED_PARAM, char **argv)
64 } 67 }
65 68
66 /* ShellExecuteEx() needs backslash as separator in UNC paths. */ 69 /* ShellExecuteEx() needs backslash as separator in UNC paths. */
67 bb_path = xstrdup(bb_busybox_exec_path); 70 if (opt_shell) {
71 bb_path = file_is_win32_exe(opt_shell);
72 if (!bb_path)
73 bb_error_msg_and_die("%s: Not found", opt_shell);
74 args = NULL;
75 } else {
76 bb_path = xstrdup(bb_busybox_exec_path);
77 args = xasprintf("--busybox ash -t \"BusyBox ash (Admin)\"");
78 }
68 slash_to_bs(bb_path); 79 slash_to_bs(bb_path);
69 80
70 memset(&info, 0, sizeof(SHELLEXECUTEINFO)); 81 memset(&info, 0, sizeof(SHELLEXECUTEINFO));
@@ -85,15 +96,15 @@ int suw32_main(int argc UNUSED_PARAM, char **argv)
85 * a network share it may not be available once we have elevated 96 * a network share it may not be available once we have elevated
86 * privileges. 97 * privileges.
87 */ 98 */
88 args = xasprintf("--busybox ash -t \"BusyBox ash (Admin)\""); 99 if (opt_shell == NULL) {
89 100 cwd = getcwd(NULL, 0);
90 cwd = getcwd(NULL, 0); 101 realcwd = cwd ? xmalloc_realpath(cwd) : NULL;
91 realcwd = cwd ? xmalloc_realpath(cwd) : NULL; 102 if (realcwd || cwd) {
92 if (realcwd || cwd) { 103 args = xappendword(args, "-d");
93 args = xappendword(args, "-d"); 104 q = quote_arg(realcwd ?: cwd);
94 q = quote_arg(realcwd ?: cwd); 105 args = xappendword(args, q);
95 args = xappendword(args, q); 106 free(q);
96 free(q); 107 }
97 } 108 }
98 109
99 if (opt & OPT_N) 110 if (opt & OPT_N)