From 67e3a7be36643b37568d071d95583bb4ca094e24 Mon Sep 17 00:00:00 2001 From: morganamilo Date: Fri, 30 May 2025 13:55:21 +0100 Subject: [PATCH] libalpm: fix regression in downloader Fixes failure to finalize download path if the package file already exists but the .sig file does not. This patch also moves .sig.part files which should be done for completeness although it's probably rare/inconsequential for them to exist. Hopefully this is now the right approach now. The logic is as follows: Check if dest_name or temp_name exists and try to move whichever does. If neither exist assume we're just downloading sig files and don't error. Figure out the .sig base filename. Try to move the .sig file if one was needed and if that fails try move the .sig.part file. The patch leaves the logging as is. Maybe we should check if moves fail for reasons other than non existence and log it properly. Though this is probably rare and pacman will error out later anyway. Fixes #256 --- lib/libalpm/dload.c | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c index 9a70810a..cac2f9b2 100644 --- a/lib/libalpm/dload.c +++ b/lib/libalpm/dload.c @@ -1118,31 +1118,34 @@ static int finalize_download_locations(alpm_list_t *payloads, const char *localp filename = payload->tempfile_name; } - /* if neither file exists then the download failed and logged an error for us */ - if(!filename) { - returnvalue = -1; - continue; - } + if(filename) { + int ret = move_file(filename, localpath); - int ret = move_file(filename, localpath); - - if(ret == -1) { - /* ignore error if the file already existed - only signature file was downloaded */ - if(payload->mtime_existing_file == 0) { - _alpm_log(payload->handle, ALPM_LOG_ERROR, _("could not move %s into %s (%s)\n"), - filename, localpath, strerror(errno)); - returnvalue = -1; + if(ret == -1) { + if(payload->mtime_existing_file == 0) { + _alpm_log(payload->handle, ALPM_LOG_ERROR, _("could not move %s into %s (%s)\n"), + filename, localpath, strerror(errno)); + returnvalue = -1; + } } } if (payload->download_signature) { - const char sig_suffix[] = ".sig"; - char *sig_filename = NULL; - size_t sig_filename_len = strlen(filename) + sizeof(sig_suffix); - MALLOC(sig_filename, sig_filename_len, continue); - snprintf(sig_filename, sig_filename_len, "%s%s", filename, sig_suffix); - move_file(sig_filename, localpath); - FREE(sig_filename); + char *sig_filename; + int ret; + + filename = payload->destfile_name ? payload->destfile_name : payload->tempfile_name; + sig_filename = _alpm_get_fullpath("", filename, ".sig"); + ASSERT(sig_filename, RET_ERR(payload->handle, ALPM_ERR_MEMORY, -1)); + ret = move_file(sig_filename, localpath); + free(sig_filename); + + if(ret == -1) { + sig_filename = _alpm_get_fullpath("", filename, ".sig.part"); + ASSERT(sig_filename, RET_ERR(payload->handle, ALPM_ERR_MEMORY, -1)); + move_file(sig_filename, localpath); + free(sig_filename); + } } } return returnvalue;