diff options
| author | Ron Yorston <rmy@pobox.com> | 2024-08-04 12:36:09 +0100 |
|---|---|---|
| committer | Ron Yorston <rmy@pobox.com> | 2024-08-04 12:36:09 +0100 |
| commit | 5eb14d55da843927f792e35dbf54079579f0d701 (patch) | |
| tree | 98116bdbfbe3e990f98d06751d569d647979d040 | |
| parent | fb959dd3f29c2d0655e01147f7b0b9bb2dab4223 (diff) | |
| download | busybox-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.c | 49 |
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 | ||
| 31 | enum { | 32 | enum { |
| 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 | ||
| 37 | int suw32_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 39 | int 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) |
