diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c index 442b3180..47a885ec 100644 --- a/lib/libalpm/add.c +++ b/lib/libalpm/add.c @@ -65,7 +65,7 @@ int _alpm_add_loadtarget(pmtrans_t *trans, pmdb_t *db, char *name) _alpm_log(PM_LOG_DEBUG, "loading target '%s'\n", name); - if(alpm_pkg_load(name, &pkg) != 0) { + if(alpm_pkg_load(name, 1, &pkg) != 0) { goto error; } pkgname = alpm_pkg_get_name(pkg); @@ -97,7 +97,7 @@ int _alpm_add_loadtarget(pmtrans_t *trans, pmdb_t *db, char *name) pmpkg_t *newpkg; _alpm_log(PM_LOG_WARNING, _("replacing older version %s-%s by %s in target list\n"), pkg->name, pkg->version, pkgver); - if((newpkg = _alpm_pkg_load(name)) == NULL) { + if((newpkg = _alpm_pkg_load(name, 1)) == NULL) { /* pm_errno is already set by pkg_load() */ goto error; } diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 53bbaaa0..f208398d 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -180,7 +180,7 @@ typedef enum _pmpkgreason_t { PM_PKG_REASON_DEPEND = 1 /* installed as a dependency for another package */ } pmpkgreason_t; -int alpm_pkg_load(const char *filename, pmpkg_t **pkg); +int alpm_pkg_load(const char *filename, unsigned short full, pmpkg_t **pkg); int alpm_pkg_free(pmpkg_t *pkg); int alpm_pkg_checkmd5sum(pmpkg_t *pkg); char *alpm_fetch_pkgurl(const char *url); diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c index 30d77a74..96c264ac 100644 --- a/lib/libalpm/package.c +++ b/lib/libalpm/package.c @@ -57,10 +57,13 @@ /** Create a package from a file. * @param filename location of the package tarball + * @param full whether to stop the load after metadata is read or continue + * through the full archive * @param pkg address of the package pointer * @return 0 on success, -1 on error (pm_errno is set accordingly) */ -int SYMEXPORT alpm_pkg_load(const char *filename, pmpkg_t **pkg) +int SYMEXPORT alpm_pkg_load(const char *filename, unsigned short full, + pmpkg_t **pkg) { _alpm_log(PM_LOG_FUNCTION, "enter alpm_pkg_load\n"); @@ -69,7 +72,7 @@ int SYMEXPORT alpm_pkg_load(const char *filename, pmpkg_t **pkg) RET_ERR(PM_ERR_WRONG_ARGS, -1)); ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1)); - *pkg = _alpm_pkg_load(filename); + *pkg = _alpm_pkg_load(filename, full); if(*pkg == NULL) { /* pm_errno is set by pkg_load */ return(-1); @@ -870,13 +873,19 @@ static int parse_descfile(const char *descfile, pmpkg_t *info) return(0); } -pmpkg_t *_alpm_pkg_load(const char *pkgfile) + +/** + * Load a package and create the corresponding pmpkg_t struct. + * @param pkgfile path to the package file + * @param full whether to stop the load after metadata is read or continue + * through the full archive + * @return An information filled pmpkg_t struct + */ +pmpkg_t *_alpm_pkg_load(const char *pkgfile, unsigned short full) { - char *expath; int ret = ARCHIVE_OK; int config = 0; int filelist = 0; - int scriptcheck = 0; struct archive *archive; struct archive_entry *entry; pmpkg_t *info = NULL; @@ -920,9 +929,9 @@ pmpkg_t *_alpm_pkg_load(const char *pkgfile) * requires changes 'parse_descfile' as well * */ - /* Read through the entire archive for metadata. We will continue reading - * even if all metadata is found, to verify the integrity of the archive in - * full */ + /* If full is false, only read through the archive until we find our needed + * metadata. If it is true, read through the entire archive, which serves + * as a verfication of integrity. */ while((ret = archive_read_next_header (archive, &entry)) == ARCHIVE_OK) { const char *entry_name = archive_entry_pathname(entry); @@ -951,7 +960,6 @@ pmpkg_t *_alpm_pkg_load(const char *pkgfile) continue; } else if(strcmp(entry_name, ".INSTALL") == 0) { info->scriptlet = 1; - scriptcheck = 1; } else if(strcmp(entry_name, ".FILELIST") == 0) { /* Build info->files from the filelist */ FILE *fp; @@ -983,10 +991,9 @@ pmpkg_t *_alpm_pkg_load(const char *pkgfile) filelist = 1; continue; } else if(*entry_name == '.') { - /* for now, ignore all files starting with '.' that haven't - * already been handled (for future possibilities) */ + /* for now, ignore all files starting with '.' that haven't + * already been handled (for future possibilities) */ } else { - scriptcheck = 1; /* Keep track of all files so we can generate a filelist later if missing */ all_files = alpm_list_add(all_files, strdup(entry_name)); } @@ -996,9 +1003,14 @@ pmpkg_t *_alpm_pkg_load(const char *pkgfile) pm_errno = PM_ERR_LIBARCHIVE_ERROR; goto error; } - expath = NULL; + + /* if we are not doing a full read, see if we have all we need */ + if(!full && config && filelist) { + break; + } } - if(ret != ARCHIVE_EOF) { /* An error occured */ + + if(ret != ARCHIVE_EOF && ret != ARCHIVE_OK) { /* An error occured */ _alpm_log(PM_LOG_ERROR, _("error while reading package: %s\n"), archive_error_string(archive)); pm_errno = PM_ERR_LIBARCHIVE_ERROR; goto error; diff --git a/lib/libalpm/package.h b/lib/libalpm/package.h index 30dd3961..47d384b6 100644 --- a/lib/libalpm/package.h +++ b/lib/libalpm/package.h @@ -94,7 +94,7 @@ pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg); void _alpm_pkg_free(pmpkg_t *pkg); int _alpm_pkg_cmp(const void *p1, const void *p2); int alpm_pkg_compare_versions(pmpkg_t *local_pkg, pmpkg_t *pkg); -pmpkg_t *_alpm_pkg_load(const char *pkgfile); +pmpkg_t *_alpm_pkg_load(const char *pkgfile, unsigned short full); pmpkg_t *_alpm_pkg_find(const char *needle, alpm_list_t *haystack); int _alpm_pkg_istoonew(pmpkg_t *pkg); void _alpm_pkg_update_requiredby(pmpkg_t *pkg); diff --git a/src/pacman/query.c b/src/pacman/query.c index 26a1bd8f..4e4002cf 100644 --- a/src/pacman/query.c +++ b/src/pacman/query.c @@ -369,7 +369,7 @@ int pacman_query(alpm_list_t *targets) pmpkg_t *pkg = NULL; if(config->op_q_isfile) { - alpm_pkg_load(strname, &pkg); + alpm_pkg_load(strname, 1, &pkg); } else { pkg = alpm_db_get_pkg(db_local, strname); } diff --git a/src/pacman/sync.c b/src/pacman/sync.c index bb4926e2..11941eb3 100644 --- a/src/pacman/sync.c +++ b/src/pacman/sync.c @@ -82,8 +82,9 @@ static int sync_cleancache(int level) snprintf(path, PATH_MAX, "%s/%s", cachedir, ent->d_name); /* attempt to load the package, skip file on failures as we may have - * files here that aren't valid packages */ - if(alpm_pkg_load(path, &localpkg) != 0 || localpkg == NULL) { + * files here that aren't valid packages. we also don't need a full + * load of the package, just the metadata. */ + if(alpm_pkg_load(path, 0, &localpkg) != 0 || localpkg == NULL) { continue; } /* check if this package is in the local DB */ diff --git a/src/util/testpkg.c b/src/util/testpkg.c index 7da18ca6..7d844e85 100644 --- a/src/util/testpkg.c +++ b/src/util/testpkg.c @@ -57,7 +57,7 @@ int main(int argc, char **argv) /* let us get log messages from libalpm */ alpm_option_set_logcb(output_cb); - if(alpm_pkg_load(argv[1], &pkg) == -1 || pkg == NULL) { + if(alpm_pkg_load(argv[1], 1, &pkg) == -1 || pkg == NULL) { retval = 1; } else { alpm_pkg_free(pkg);