diff options
| author | Ron Yorston <rmy@pobox.com> | 2019-01-05 14:16:50 +0000 |
|---|---|---|
| committer | Ron Yorston <rmy@pobox.com> | 2019-01-05 14:16:50 +0000 |
| commit | fa96aa8d70eb1dfd7b3550fab417a43b3a507a6d (patch) | |
| tree | 2b7d4c0a4a56175018f28e7e116a3dcdfb78e06a | |
| parent | da7d205446459dfa1ba7bb46206955383dc6a420 (diff) | |
| download | busybox-w32-fa96aa8d70eb1dfd7b3550fab417a43b3a507a6d.tar.gz busybox-w32-fa96aa8d70eb1dfd7b3550fab417a43b3a507a6d.tar.bz2 busybox-w32-fa96aa8d70eb1dfd7b3550fab417a43b3a507a6d.zip | |
busybox: add --uninstall option
Add an option to allow hard links to be removed.
busybox --uninstall file
removes all hard links to the given file (including the file itself.)
Since Microsoft Windows refuses to delete a running executable a
BusyBox binary is unable to remove links to itself.
busybox --uninstall -n file
displays the names of all hard links to the given file.
Although this feature is couched in terms of uninstalling BusyBox
it's actually quite general: it can be used to delete or display
hard links to any file.
| -rw-r--r-- | include/mingw.h | 1 | ||||
| -rw-r--r-- | libbb/appletlib.c | 34 | ||||
| -rw-r--r-- | win32/mingw.c | 39 |
3 files changed, 72 insertions, 2 deletions
diff --git a/include/mingw.h b/include/mingw.h index cef53a7c9..b712e4ec0 100644 --- a/include/mingw.h +++ b/include/mingw.h | |||
| @@ -482,3 +482,4 @@ ULONGLONG CompatGetTickCount64(void); | |||
| 482 | #define GetTickCount64 CompatGetTickCount64 | 482 | #define GetTickCount64 CompatGetTickCount64 |
| 483 | 483 | ||
| 484 | ssize_t get_random_bytes(void *buf, ssize_t count); | 484 | ssize_t get_random_bytes(void *buf, ssize_t count); |
| 485 | int enumerate_links(const char *file, char *name); | ||
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 11136de11..8a66b3303 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
| @@ -776,7 +776,8 @@ static void install_links(const char *busybox, | |||
| 776 | while (*appname) { | 776 | while (*appname) { |
| 777 | fpc = xasprintf("%s/%s.exe", custom_install_dir, appname); | 777 | fpc = xasprintf("%s/%s.exe", custom_install_dir, appname); |
| 778 | rc = link(busybox, fpc); | 778 | rc = link(busybox, fpc); |
| 779 | if (rc != 0 && errno != EEXIST) { | 779 | if (rc != 0 && (errno != EEXIST || |
| 780 | strcmp("busybox.exe", bb_basename(fpc)) != 0)) { | ||
| 780 | bb_simple_perror_msg(fpc); | 781 | bb_simple_perror_msg(fpc); |
| 781 | } | 782 | } |
| 782 | free(fpc); | 783 | free(fpc); |
| @@ -885,7 +886,13 @@ int busybox_main(int argc UNUSED_PARAM, char **argv) | |||
| 885 | " or: busybox --show SCRIPT\n" | 886 | " or: busybox --show SCRIPT\n" |
| 886 | # endif | 887 | # endif |
| 887 | IF_FEATURE_INSTALLER( | 888 | IF_FEATURE_INSTALLER( |
| 888 | " or: busybox --install "IF_NOT_PLATFORM_MINGW32("[-s] ")"[DIR]\n" | 889 | IF_NOT_PLATFORM_MINGW32( |
| 890 | " or: busybox --install [-s] [DIR]\n" | ||
| 891 | ) | ||
| 892 | IF_PLATFORM_MINGW32( | ||
| 893 | " or: busybox --install [DIR]\n" | ||
| 894 | " or: busybox --uninstall [-n] file\n" | ||
| 895 | ) | ||
| 889 | ) | 896 | ) |
| 890 | " or: function [arguments]...\n" | 897 | " or: function [arguments]...\n" |
| 891 | "\n" | 898 | "\n" |
| @@ -1016,6 +1023,29 @@ int busybox_main(int argc UNUSED_PARAM, char **argv) | |||
| 1016 | return 0; | 1023 | return 0; |
| 1017 | } | 1024 | } |
| 1018 | 1025 | ||
| 1026 | #if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_INSTALLER | ||
| 1027 | if (strcmp(argv[1], "--uninstall") == 0) { | ||
| 1028 | char name[PATH_MAX]; | ||
| 1029 | int dry_run = (argv[2] && strcmp(argv[2], "-n") == 0 && ++argv); | ||
| 1030 | const char *file = argv[2]; | ||
| 1031 | |||
| 1032 | if (!argv[2]) | ||
| 1033 | bb_error_msg_and_die(bb_msg_requires_arg, "--uninstall"); | ||
| 1034 | |||
| 1035 | while (enumerate_links(file, name)) { | ||
| 1036 | if (dry_run) { | ||
| 1037 | full_write1_str(name); | ||
| 1038 | full_write1_str("\n"); | ||
| 1039 | } | ||
| 1040 | else if (unlink(name) != 0) { | ||
| 1041 | bb_simple_perror_msg(name); | ||
| 1042 | } | ||
| 1043 | file = NULL; | ||
| 1044 | } | ||
| 1045 | return 0; | ||
| 1046 | } | ||
| 1047 | #endif | ||
| 1048 | |||
| 1019 | if (strcmp(argv[1], "--help") == 0) { | 1049 | if (strcmp(argv[1], "--help") == 0) { |
| 1020 | /* "busybox --help [<applet>]" */ | 1050 | /* "busybox --help [<applet>]" */ |
| 1021 | if (!argv[2]) | 1051 | if (!argv[2]) |
diff --git a/win32/mingw.c b/win32/mingw.c index c420992d5..8d1da5199 100644 --- a/win32/mingw.c +++ b/win32/mingw.c | |||
| @@ -1289,3 +1289,42 @@ ULONGLONG CompatGetTickCount64(void) | |||
| 1289 | return GetTickCount64(); | 1289 | return GetTickCount64(); |
| 1290 | } | 1290 | } |
| 1291 | #endif | 1291 | #endif |
| 1292 | |||
| 1293 | #if ENABLE_FEATURE_INSTALLER | ||
| 1294 | /* | ||
| 1295 | * Enumerate the names of all hard links to a file. The first call | ||
| 1296 | * provides the file name as the first argument; subsequent calls must | ||
| 1297 | * set the first argument to NULL. Returns 0 on error or when there are | ||
| 1298 | * no more links. | ||
| 1299 | */ | ||
| 1300 | int enumerate_links(const char *file, char *name) | ||
| 1301 | { | ||
| 1302 | static HANDLE h = INVALID_HANDLE_VALUE; | ||
| 1303 | char aname[PATH_MAX]; | ||
| 1304 | wchar_t wname[PATH_MAX]; | ||
| 1305 | DWORD length = PATH_MAX; | ||
| 1306 | DECLARE_PROC_ADDR(HANDLE, FindFirstFileNameW, LPCWSTR, DWORD, LPDWORD, | ||
| 1307 | PWSTR); | ||
| 1308 | DECLARE_PROC_ADDR(BOOL, FindNextFileNameW, HANDLE, LPDWORD, PWSTR); | ||
| 1309 | |||
| 1310 | if (!INIT_PROC_ADDR(kernel32.dll, FindFirstFileNameW) || | ||
| 1311 | !INIT_PROC_ADDR(kernel32.dll, FindNextFileNameW)) | ||
| 1312 | return 0; | ||
| 1313 | |||
| 1314 | if (file != NULL) { | ||
| 1315 | wchar_t wfile[PATH_MAX]; | ||
| 1316 | MultiByteToWideChar(CP_ACP, 0, file, -1, wfile, PATH_MAX); | ||
| 1317 | h = FindFirstFileNameW(wfile, 0, &length, wname); | ||
| 1318 | if (h == INVALID_HANDLE_VALUE) | ||
| 1319 | return 0; | ||
| 1320 | } | ||
| 1321 | else if (!FindNextFileNameW(h, &length, wname)) { | ||
| 1322 | FindClose(h); | ||
| 1323 | h = INVALID_HANDLE_VALUE; | ||
| 1324 | return 0; | ||
| 1325 | } | ||
| 1326 | WideCharToMultiByte(CP_ACP, 0, wname, -1, aname, PATH_MAX, NULL, NULL); | ||
| 1327 | realpath(aname, name); | ||
| 1328 | return 1; | ||
| 1329 | } | ||
| 1330 | #endif | ||
