Download, verify checksum, kill old instances, and install binary. Returns 0 on success. */
| 4239 | |
| 4240 | /* Download, verify checksum, kill old instances, and install binary. Returns 0 on success. */ |
| 4241 | static int download_verify_install(const char *url, const char *ext, const char *os, |
| 4242 | const char *arch, bool want_ui, const char *bin_dest) { |
| 4243 | char tmp_archive[CLI_BUF_256]; |
| 4244 | snprintf(tmp_archive, sizeof(tmp_archive), "%s/cbm-update.%s", cbm_tmpdir(), ext); |
| 4245 | |
| 4246 | int rc = cbm_download_to_file(url, tmp_archive); |
| 4247 | if (rc != 0) { |
| 4248 | (void)fprintf(stderr, "error: download failed (exit %d)\n", rc); |
| 4249 | cbm_unlink(tmp_archive); |
| 4250 | return CLI_TRUE; |
| 4251 | } |
| 4252 | |
| 4253 | char archive_name[CLI_BUF_256]; |
| 4254 | /* Must match build_update_url: linux uses the static "-portable" asset. */ |
| 4255 | const char *portable = (strcmp(os, "linux") == 0) ? "-portable" : ""; |
| 4256 | snprintf(archive_name, sizeof(archive_name), "codebase-memory-mcp-%s%s-%s%s.%s", |
| 4257 | want_ui ? "ui-" : "", os, arch, portable, ext); |
| 4258 | /* Fail closed: install only a positively-verified download. A mismatch, |
| 4259 | * a missing checksum entry, or an unavailable hash tool (crc != 0) all |
| 4260 | * abort rather than install an unverified binary. */ |
| 4261 | int crc = verify_download_checksum(tmp_archive, archive_name); |
| 4262 | if (crc != 0) { |
| 4263 | (void)fprintf(stderr, "error: refusing to install an unverified download\n"); |
| 4264 | cbm_unlink(tmp_archive); |
| 4265 | return CLI_TRUE; |
| 4266 | } |
| 4267 | |
| 4268 | int killed = cbm_kill_other_instances(); |
| 4269 | if (killed > 0) { |
| 4270 | printf("Stopped %d running MCP server instance(s).\n", killed); |
| 4271 | } |
| 4272 | |
| 4273 | if (extract_and_install_binary((extract_install_args_t){tmp_archive, ext, bin_dest}) != 0) { |
| 4274 | return CLI_TRUE; |
| 4275 | } |
| 4276 | return 0; |
| 4277 | } |
| 4278 | |
| 4279 | /* Select update variant. Returns 0=standard, 1=ui, -1=error. */ |
| 4280 | static int select_update_variant(int variant_flag) { |
no test coverage detected