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
This commit is contained in:
morganamilo 2025-05-30 13:55:21 +01:00
parent 45c4eef61d
commit 67e3a7be36
No known key found for this signature in database
GPG key ID: E48D0A8326DE47C5

View file

@ -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;