From e46dd09127c3e01715a550a7fa9c20a21374696a Mon Sep 17 00:00:00 2001 From: Juan RP Date: Wed, 9 Nov 2011 21:01:25 +0100 Subject: [PATCH] Faster binary package unpacking, see the NEWS file for info. --- NEWS | 8 +++ include/xbps_api.h | 2 +- lib/package_unpack.c | 134 +++++++++++++++++++++++++------------------ 3 files changed, 87 insertions(+), 57 deletions(-) diff --git a/NEWS b/NEWS index d1188a2b..9557c8b3 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,13 @@ xbps-0.11.0 (???): + * Faster binary package unpacking. Only files and symlinks are now + extracted from binary packages, thus directories are not extracted + anymore. The package builder is responsible to create required + directories where appropiate and set correct permissions. + While being here, some stuff is skipped now if a package uses the + "preserve" keyword or package is being installed, resulting in a + faster operation. + * Implemented "New repository scheme and configuration file" from issue 16. The plist index file has been renamed to "index.plist", version bumped to 1.3. The configuration file (repositories.plist) now expect the full diff --git a/include/xbps_api.h b/include/xbps_api.h index be90a102..6141e52d 100644 --- a/include/xbps_api.h +++ b/include/xbps_api.h @@ -55,7 +55,7 @@ */ #define XBPS_PKGINDEX_VERSION "1.3" -#define XBPS_API_VERSION "20111107" +#define XBPS_API_VERSION "20111109" #define XBPS_VERSION "0.11.0" /** diff --git a/lib/package_unpack.c b/lib/package_unpack.c index ee3237e5..c198a0e7 100644 --- a/lib/package_unpack.c +++ b/lib/package_unpack.c @@ -161,7 +161,7 @@ unpack_archive(prop_dictionary_t pkg_repod, struct archive_entry *entry; size_t nmetadata = 0, entry_idx = 0; const char *entry_pname, *transact; - char *buf; + char *buf = NULL, *pkgfilesd = NULL; int rv, flags; bool preserve, update, replace; @@ -204,14 +204,22 @@ unpack_archive(prop_dictionary_t pkg_repod, entry_statp = archive_entry_stat(entry); entry_pname = archive_entry_pathname(entry); flags = set_extract_flags(); - + /* + * Ignore directories from archive. + */ + if (S_ISDIR(entry_statp->st_mode)) { + archive_read_data_skip(ar); + continue; + } + /* + * Prepare unpack callback ops. + */ if (xhp->xbps_unpack_cb != NULL) { xhp->xucd->entry = entry_pname; xhp->xucd->entry_size = archive_entry_size(entry); xhp->xucd->entry_is_metadata = false; xhp->xucd->entry_is_conf = false; } - if (strcmp("./INSTALL", entry_pname) == 0) { /* * Extract the INSTALL script first to execute @@ -409,67 +417,81 @@ unpack_archive(prop_dictionary_t pkg_repod, pkgname, version, strerror(rv)); goto out; } else { - if (xhp->flags & XBPS_FLAG_VERBOSE) - xbps_warn_printf("ignoring existing " - "entry: %s\n", entry_pname); - continue; + xbps_warn_printf("ignoring existing " + "entry: %s\n", entry_pname); } } xhp->xucd->entry_extract_count++; RUN_PROGRESS_CB(); } - - if ((rv = archive_errno(ar)) == 0) { - buf = xbps_xasprintf(".%s/metadata/%s/%s", - XBPS_META_PATH, pkgname, XBPS_PKGFILES); - if (buf == NULL) { - rv = ENOMEM; - goto out; - } - /* - * Check if files.plist exists and pkg is NOT marked as - * preserve, in that case we need to check for obsolete files - * and remove them if necessary. - */ - if (!preserve) { - old_filesd = - prop_dictionary_internalize_from_zfile(buf); - if (old_filesd) { - rv = xbps_remove_obsoletes(old_filesd, filesd); - if (rv != 0) { - prop_object_release(old_filesd); - free(buf); - rv = errno; - goto out; - } - prop_object_release(old_filesd); - - } else if (errno && errno != ENOENT) { - free(buf); - rv = errno; - goto out; - } - } - /* - * Now that all files were successfully unpacked, we - * can safely externalize files.plist because the path - * is reachable. - */ - if (!prop_dictionary_externalize_to_zfile(filesd, buf)) { - rv = errno; - xbps_error_printf("failed to extract metadata %s file" - "for `%s-%s': %s\n", XBPS_PKGFILES, pkgname, - version, strerror(rv)); - free(buf); - goto out; - } - free(buf); + /* + * If there was any error extracting files from archive, error out. + */ + if ((rv = archive_errno(ar)) != 0) { + xbps_dbg_printf("%s-%s: error extracting pkg files: %s\n", + pkgname, version, archive_errno(ar)); + goto out; + } + /* + * On pkgs that set the preserve keyword or while installing + * new packages, do not check for obsolete files. + */ + pkgfilesd = xbps_xasprintf(".%s/metadata/%s/%s", + XBPS_META_PATH, pkgname, XBPS_PKGFILES); + if (pkgfilesd == NULL) { + rv = ENOMEM; + goto out; + } + if (preserve || !update) + goto out1; + /* + * Check for obsolete files. + */ + old_filesd = prop_dictionary_internalize_from_zfile(pkgfilesd); + if (prop_object_type(old_filesd) == PROP_TYPE_DICTIONARY) { + if ((rv = xbps_remove_obsoletes(old_filesd, filesd)) != 0) { + prop_object_release(old_filesd); + rv = errno; + goto out; + } + prop_object_release(old_filesd); + } else if (errno && errno != ENOENT) { + rv = errno; + goto out; + } +out1: + /* + * Create pkg metadata directory. + */ + buf = xbps_xasprintf(".%s/metadata/%s", XBPS_META_PATH, pkgname); + if (buf == NULL) { + rv = ENOMEM; + goto out; + } + if (xbps_mkpath(buf, 0755) == -1) { + xbps_dbg_printf("%s-%s: failed to create pkg metadir: %s\n", + pkgname, version, strerror(errno)); + rv = errno; + goto out; + } + /* + * Externalize XBPS_PKGFILES into pkg metadata directory. + */ + if (!prop_dictionary_externalize_to_zfile(filesd, pkgfilesd)) { + rv = errno; + xbps_error_printf("failed to extract metadata %s file" + "for `%s-%s': %s\n", XBPS_PKGFILES, pkgname, + version, strerror(rv)); + goto out; } - out: - if (filesd) + if (pkgfilesd != NULL) + free(pkgfilesd); + if (buf != NULL) + free(buf); + if (prop_object_type(filesd) == PROP_TYPE_DICTIONARY) prop_object_release(filesd); - if (propsd) + if (prop_object_type(propsd) == PROP_TYPE_DICTIONARY) prop_object_release(propsd); return rv;