summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Gregory <andrew.gregory.8@gmail.com>2015-03-25 10:53:07 +0100
committerAllan McRae <allan@archlinux.org>2015-03-26 05:44:13 +0100
commit721b785e73333bdbd1b4ba3b0505cc14918064ad (patch)
tree9336767b73f3469e6009d08f27f57a3a869c131b
parentedeafcc988012615dbbb1cc9ac02090ad2dd8dac (diff)
downloadpacman-721b785e73333bdbd1b4ba3b0505cc14918064ad.tar.gz
pacman-721b785e73333bdbd1b4ba3b0505cc14918064ad.tar.xz
be_package: fallback to standard filelist loading
In order to work properly, loading the filelist from an mtree file requires a libarchive patch that has not yet been included in an official release.[1] Under certain circumstances, an unpatched libarchive may refuse to read the mtree file due to inconsistencies between it and the user's file system. In order to allow alpm to recover in this situation, read the mtree data into a temporary filelist that is only copied over to the package if the entire read is successful. [1] https://github.com/libarchive/libarchive/commit/661684170b970ef7d6eff135b57e58a537e8bc53 Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com> Signed-off-by: Allan McRae <allan@archlinux.org>
-rw-r--r--lib/libalpm/be_package.c37
1 files changed, 22 insertions, 15 deletions
diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c
index 37aa428e..53399a30 100644
--- a/lib/libalpm/be_package.c
+++ b/lib/libalpm/be_package.c
@@ -445,17 +445,12 @@ static int build_filelist_from_mtree(alpm_handle_t *handle, alpm_pkg_t *pkg, str
char *mtree_data = NULL;
struct archive *mtree;
struct archive_entry *mtree_entry = NULL;
+ alpm_filelist_t filelist;
_alpm_log(handle, ALPM_LOG_DEBUG,
"found mtree for package %s, getting file list\n", pkg->filename);
- /* throw away any files we might have already found */
- for(i = 0; i < pkg->files.count; i++) {
- free(pkg->files.files[i].name);
- }
- free(pkg->files.files);
- pkg->files.files = NULL;
- pkg->files.count = 0;
+ memset(&filelist, 0, sizeof(alpm_filelist_t));
/* create a new archive to parse the mtree and load it from archive into memory */
/* TODO: split this into a function */
@@ -478,7 +473,7 @@ static int build_filelist_from_mtree(alpm_handle_t *handle, alpm_pkg_t *pkg, str
size = archive_read_data(archive, mtree_data + mtree_cursize, ALPM_BUFFER_SIZE);
if(size < 0) {
- _alpm_log(handle, ALPM_LOG_ERROR, _("error while reading package %s: %s\n"),
+ _alpm_log(handle, ALPM_LOG_DEBUG, _("error while reading package %s: %s\n"),
pkg->filename, archive_error_string(archive));
handle->pm_errno = ALPM_ERR_LIBARCHIVE;
goto error;
@@ -491,7 +486,7 @@ static int build_filelist_from_mtree(alpm_handle_t *handle, alpm_pkg_t *pkg, str
}
if(archive_read_open_memory(mtree, mtree_data, mtree_cursize)) {
- _alpm_log(handle, ALPM_LOG_ERROR,
+ _alpm_log(handle, ALPM_LOG_DEBUG,
_("error while reading mtree of package %s: %s\n"),
pkg->filename, archive_error_string(mtree));
handle->pm_errno = ALPM_ERR_LIBARCHIVE;
@@ -510,23 +505,38 @@ static int build_filelist_from_mtree(alpm_handle_t *handle, alpm_pkg_t *pkg, str
continue;
}
- if(add_entry_to_files_list(&pkg->files, &files_size, mtree_entry, path) < 0) {
+ if(add_entry_to_files_list(&filelist, &files_size, mtree_entry, path) < 0) {
goto error;
}
}
if(ret != ARCHIVE_EOF && ret != ARCHIVE_OK) { /* An error occurred */
- _alpm_log(handle, ALPM_LOG_ERROR, _("error while reading mtree of package %s: %s\n"),
+ _alpm_log(handle, ALPM_LOG_DEBUG, _("error while reading mtree of package %s: %s\n"),
pkg->filename, archive_error_string(mtree));
handle->pm_errno = ALPM_ERR_LIBARCHIVE;
goto error;
}
+ /* throw away any files we loaded directly from the archive */
+ for(i = 0; i < pkg->files.count; i++) {
+ free(pkg->files.files[i].name);
+ }
+ free(pkg->files.files);
+
+ /* copy over new filelist */
+ memcpy(&pkg->files, &filelist, sizeof(alpm_filelist_t));
+
free(mtree_data);
_alpm_archive_read_free(mtree);
_alpm_log(handle, ALPM_LOG_DEBUG, "finished mtree reading for %s\n", pkg->filename);
return 0;
error:
+ /* throw away any files we loaded from the mtree */
+ for(i = 0; i < filelist.count; i++) {
+ free(filelist.files[i].name);
+ }
+ free(filelist.files);
+
free(mtree_data);
_alpm_archive_read_free(mtree);
return -1;
@@ -609,10 +619,7 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle,
/* building the file list: cheap way
* get the filelist from the mtree file rather than scanning
* the whole archive */
- if(build_filelist_from_mtree(handle, newpkg, archive) < 0) {
- goto error;
- }
- hit_mtree = 1;
+ hit_mtree = build_filelist_from_mtree(handle, newpkg, archive) == 0;
continue;
} else if(handle_simple_path(newpkg, entry_name)) {
continue;