Report — never delete — the updater script sitting next to the binary. * * install.sh/install.ps1 copies itself beside the executable so `update` has * something to hand off to. Uninstall does NOT remove it, deliberately: we * cannot prove we own that file. The user may have put their own copy there, it * may be a symlink into a checkout, or a package manager may manage it. Deleting * a file
| 11325 | * shouldn't. Telling the user the exact path costs one line and leaves the |
| 11326 | * decision with them. */ |
| 11327 | static void cli_uninstall_report_leftover_installer(const char *bin_path, bool dry_run) { |
| 11328 | if (!bin_path || !bin_path[0]) { |
| 11329 | return; |
| 11330 | } |
| 11331 | const char *slash = strrchr(bin_path, '/'); |
| 11332 | #ifdef _WIN32 |
| 11333 | const char *backslash = strrchr(bin_path, '\\'); |
| 11334 | if (backslash && (!slash || backslash > slash)) { |
| 11335 | slash = backslash; |
| 11336 | } |
| 11337 | static const char *const installer_names[] = {"install.ps1", "install.sh"}; |
| 11338 | #else |
| 11339 | static const char *const installer_names[] = {"install.sh"}; |
| 11340 | #endif |
| 11341 | if (!slash || slash == bin_path) { |
| 11342 | return; |
| 11343 | } |
| 11344 | size_t dir_len = (size_t)(slash - bin_path); |
| 11345 | for (size_t i = 0; i < sizeof(installer_names) / sizeof(installer_names[0]); i++) { |
| 11346 | char installer_path[CLI_BUF_1K]; |
| 11347 | int written = snprintf(installer_path, sizeof(installer_path), "%.*s/%s", (int)dir_len, |
| 11348 | bin_path, installer_names[i]); |
| 11349 | if (written <= 0 || (size_t)written >= sizeof(installer_path)) { |
| 11350 | continue; |
| 11351 | } |
| 11352 | struct stat installer_status; |
| 11353 | if (stat(installer_path, &installer_status) != 0) { |
| 11354 | continue; |
| 11355 | } |
| 11356 | if (dry_run) { |
| 11357 | printf("Would leave %s in place (remove it yourself if you want it gone).\n", |
| 11358 | installer_path); |
| 11359 | } else { |
| 11360 | printf("\nLeft in place: %s\n" |
| 11361 | " This is the updater; uninstall does not delete it because it cannot\n" |
| 11362 | " prove it owns it. To remove it as well:\n\n rm \"%s\"\n", |
| 11363 | installer_path, installer_path); |
| 11364 | } |
| 11365 | } |
| 11366 | } |
| 11367 | |
| 11368 | /* Uninstall is an activation too: removing the executable or its indexes |
| 11369 | * while a daemon generation is starting/running would leave live sessions on |
no test coverage detected