diff options
author | Christian Hesse <mail@eworm.de> | 2013-09-05 16:08:23 +0200 |
---|---|---|
committer | Allan McRae <allan@archlinux.org> | 2013-09-18 14:28:03 +1000 |
commit | 3b3152fc501a1561d733c33557ff2f7be8376067 (patch) | |
tree | ff07d48eca9c4ee6a7703466423c7f0d685b13f2 | |
parent | 3f99cfba1b6ef1c5665488b651a3d6409730fa98 (diff) | |
download | pacman-3b3152fc501a1561d733c33557ff2f7be8376067.tar.xz |
dload: avoid renaming files downloaded via sync operations
If the server redirects from ${repo}.db to ${repo}.db.tar.gz pacman gets
this wrong: It saves to new filename and fails when accessing
${repo}.db.
We need the remote filename only when downloading remote files with
pacman's -U operation. This introduces a new field 'trust_remote_name'
to payload. If set pacman downloads to the filename given by the server.
The field trust_remote_name is set in alpm_fetch_pkgurl().
Fixes FS#36791 ([pacman] downloads to wrong filename with redirect).
[dave: remove redundant assignment leading to memory leak]
Signed-off-by: Allan McRae <allan@archlinux.org>
-rw-r--r-- | lib/libalpm/dload.c | 38 | ||||
-rw-r--r-- | lib/libalpm/dload.h | 1 |
2 files changed, 22 insertions, 17 deletions
diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c index 8537b3db..7782f8dc 100644 --- a/lib/libalpm/dload.c +++ b/lib/libalpm/dload.c @@ -547,23 +547,25 @@ static int curl_download_internal(struct dload_payload *payload, goto cleanup; } - if(payload->content_disp_name) { - /* content-disposition header has a better name for our file */ - free(payload->destfile_name); - payload->destfile_name = get_fullpath(localpath, payload->content_disp_name, ""); - } else { - const char *effective_filename = strrchr(effective_url, '/'); - if(effective_filename && strlen(effective_filename) > 2) { - effective_filename++; - - /* if destfile was never set, we wrote to a tempfile. even if destfile is - * set, we may have followed some redirects and the effective url may - * have a better suggestion as to what to name our file. in either case, - * refactor destfile to this newly derived name. */ - if(!payload->destfile_name || strcmp(effective_filename, - strrchr(payload->destfile_name, '/') + 1) != 0) { - free(payload->destfile_name); - payload->destfile_name = get_fullpath(localpath, effective_filename, ""); + if (payload->trust_remote_name) { + if(payload->content_disp_name) { + /* content-disposition header has a better name for our file */ + free(payload->destfile_name); + payload->destfile_name = get_fullpath(localpath, payload->content_disp_name, ""); + } else { + const char *effective_filename = strrchr(effective_url, '/'); + if(effective_filename && strlen(effective_filename) > 2) { + effective_filename++; + + /* if destfile was never set, we wrote to a tempfile. even if destfile is + * set, we may have followed some redirects and the effective url may + * have a better suggestion as to what to name our file. in either case, + * refactor destfile to this newly derived name. */ + if(!payload->destfile_name || strcmp(effective_filename, + strrchr(payload->destfile_name, '/') + 1) != 0) { + free(payload->destfile_name); + payload->destfile_name = get_fullpath(localpath, effective_filename, ""); + } } } } @@ -678,6 +680,7 @@ char SYMEXPORT *alpm_fetch_pkgurl(alpm_handle_t *handle, const char *url) STRDUP(payload.fileurl, url, RET_ERR(handle, ALPM_ERR_MEMORY, NULL)); payload.allow_resume = 1; payload.handle = handle; + payload.trust_remote_name = 1; /* download the file */ ret = _alpm_download(&payload, cachedir, &final_file, &final_pkg_url); @@ -702,6 +705,7 @@ char SYMEXPORT *alpm_fetch_pkgurl(alpm_handle_t *handle, const char *url) sig_filepath = filecache_find_url(handle, payload.fileurl); if(sig_filepath == NULL) { payload.handle = handle; + payload.trust_remote_name = 1; payload.force = 1; payload.errors_ok = (handle->siglevel & ALPM_SIG_PACKAGE_OPTIONAL); diff --git a/lib/libalpm/dload.h b/lib/libalpm/dload.h index 95bb91a3..6c9f7a74 100644 --- a/lib/libalpm/dload.h +++ b/lib/libalpm/dload.h @@ -38,6 +38,7 @@ struct dload_payload { int allow_resume; int errors_ok; int unlink_on_fail; + int trust_remote_name; alpm_list_t *servers; #ifdef HAVE_LIBCURL CURLcode curlerr; /* last error produced by curl */ |