aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2019-01-05 14:16:50 +0000
committerRon Yorston <rmy@pobox.com>2019-01-05 14:16:50 +0000
commitfa96aa8d70eb1dfd7b3550fab417a43b3a507a6d (patch)
tree2b7d4c0a4a56175018f28e7e116a3dcdfb78e06a
parentda7d205446459dfa1ba7bb46206955383dc6a420 (diff)
downloadbusybox-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.h1
-rw-r--r--libbb/appletlib.c34
-rw-r--r--win32/mingw.c39
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
484ssize_t get_random_bytes(void *buf, ssize_t count); 484ssize_t get_random_bytes(void *buf, ssize_t count);
485int 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 */
1300int 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