mirror of
https://github.com/moparisthebest/pacman
synced 2024-12-22 15:58:50 -05:00
Add 'full' parameter to alpm_pkg_load
In most cases, we want to fully scan a package when we load it, which serves as a integrity verification check. However, there are times when it is only desired to read the metadata and nothing else, so allow the caller of pkg_load to choose the behavior they need. This pays big dividends in speeding up pacman cache cleaning functionality. Old (729 packages): real 1m43.717s user 1m20.785s sys 0m2.993s New (729 packages): real 0m25.607s user 0m19.389s sys 0m0.543s Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
parent
d2edcb58e2
commit
219808714f
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user