[pacman-dev] [PATCH 1/2] add_entry_to_files_list: pass filelist directly
Allows entries to be added to arbitrary filelists not connected to a package. Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com> --- lib/libalpm/be_package.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c index e284254..37aa428 100644 --- a/lib/libalpm/be_package.c +++ b/lib/libalpm/be_package.c @@ -384,15 +384,16 @@ static int handle_simple_path(alpm_pkg_t *pkg, const char *path) * @param path path of the file to be added * @return <0 on error, 0 on success */ -static int add_entry_to_files_list(alpm_pkg_t *pkg, size_t *files_size, - struct archive_entry *entry, const char *path) +static int add_entry_to_files_list(alpm_filelist_t *filelist, + size_t *files_size, struct archive_entry *entry, const char *path) { - const size_t files_count = pkg->files.count; + const size_t files_count = filelist->count; alpm_file_t *current_file; mode_t type; size_t pathlen; - if(!_alpm_greedy_grow((void **)&pkg->files.files, files_size, (files_count + 1) * sizeof(alpm_file_t))) { + if(!_alpm_greedy_grow((void **)&filelist->files, + files_size, (files_count + 1) * sizeof(alpm_file_t))) { return -1; } @@ -400,7 +401,7 @@ static int add_entry_to_files_list(alpm_pkg_t *pkg, size_t *files_size, pathlen = strlen(path); - current_file = pkg->files.files + files_count; + current_file = filelist->files + files_count; /* mtree paths don't contain a tailing slash, those we get from * the archive directly do (expensive way) @@ -418,7 +419,7 @@ static int add_entry_to_files_list(alpm_pkg_t *pkg, size_t *files_size, } current_file->size = archive_entry_size(entry); current_file->mode = archive_entry_mode(entry); - pkg->files.count++; + filelist->count++; return 0; } @@ -509,7 +510,7 @@ static int build_filelist_from_mtree(alpm_handle_t *handle, alpm_pkg_t *pkg, str continue; } - if(add_entry_to_files_list(pkg, &files_size, mtree_entry, path) < 0) { + if(add_entry_to_files_list(&pkg->files, &files_size, mtree_entry, path) < 0) { goto error; } } @@ -617,7 +618,7 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle, continue; } else if(full && !hit_mtree) { /* building the file list: expensive way */ - if(add_entry_to_files_list(newpkg, &files_size, entry, entry_name) < 0) { + if(add_entry_to_files_list(&newpkg->files, &files_size, entry, entry_name) < 0) { goto error; } } -- 2.3.4
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/661684170b970ef7d6eff135b57e... Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com> --- https://bbs.archlinux.org/viewtopic.php?id=194771 lib/libalpm/be_package.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c index 37aa428..53399a3 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; -- 2.3.4
On 25/03/15 19:53, Andrew Gregory wrote:
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/661684170b970ef7d6eff135b57e...
Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com> ---
Good catch! I could not tell what was wrong on that forum post. And where is that libarchive release!
participants (2)
-
Allan McRae
-
Andrew Gregory