diff options
Diffstat (limited to 'lib/libalpm/package.c')
-rw-r--r-- | lib/libalpm/package.c | 468 |
1 files changed, 136 insertions, 332 deletions
diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c index becbc60f..241c41c0 100644 --- a/lib/libalpm/package.c +++ b/lib/libalpm/package.c @@ -1,7 +1,7 @@ /* * package.c * - * Copyright (c) 2006-2010 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> * Copyright (c) 2005, 2006 by Christian Hamar <krics@linuxforum.hu> @@ -25,24 +25,18 @@ #include <stdio.h> #include <stdlib.h> -#include <limits.h> #include <string.h> #include <ctype.h> #include <errno.h> #include <sys/types.h> #include <sys/stat.h> -/* libarchive */ -#include <archive.h> -#include <archive_entry.h> - /* libalpm */ #include "package.h" #include "alpm_list.h" #include "log.h" #include "util.h" #include "db.h" -#include "cache.h" #include "delta.h" #include "handle.h" #include "deps.h" @@ -63,7 +57,7 @@ int SYMEXPORT alpm_pkg_free(pmpkg_t *pkg) ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1)); /* Only free packages loaded in user space */ - if(pkg->origin != PKG_FROM_CACHE) { + if(pkg->origin == PKG_FROM_FILE) { _alpm_pkg_free(pkg); } @@ -83,8 +77,7 @@ int SYMEXPORT alpm_pkg_checkmd5sum(pmpkg_t *pkg) ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1)); /* We only inspect packages from sync repositories */ - ASSERT(pkg->origin == PKG_FROM_CACHE, RET_ERR(PM_ERR_PKG_INVALID, -1)); - ASSERT(pkg->origin_data.db != handle->db_local, RET_ERR(PM_ERR_PKG_INVALID, -1)); + ASSERT(pkg->origin == PKG_FROM_SYNCDB, RET_ERR(PM_ERR_PKG_INVALID, -1)); fpath = _alpm_filecache_find(alpm_pkg_get_filename(pkg)); @@ -100,334 +93,196 @@ int SYMEXPORT alpm_pkg_checkmd5sum(pmpkg_t *pkg) return(retval); } +/* Default package accessor functions. These will get overridden by any + * backend logic that needs lazy access, such as the local database through + * a lazy-load cache. However, the defaults will work just fine for fully- + * populated package structures. */ +static const char *_pkg_get_filename(pmpkg_t *pkg) { return pkg->filename; } +static const char *_pkg_get_name(pmpkg_t *pkg) { return pkg->name; } +static const char *_pkg_get_version(pmpkg_t *pkg) { return pkg->version; } +static const char *_pkg_get_desc(pmpkg_t *pkg) { return pkg->desc; } +static const char *_pkg_get_url(pmpkg_t *pkg) { return pkg->url; } +static time_t _pkg_get_builddate(pmpkg_t *pkg) { return pkg->builddate; } +static time_t _pkg_get_installdate(pmpkg_t *pkg) { return pkg->installdate; } +static const char *_pkg_get_packager(pmpkg_t *pkg) { return pkg->packager; } +static const char *_pkg_get_md5sum(pmpkg_t *pkg) { return pkg->md5sum; } +static const char *_pkg_get_arch(pmpkg_t *pkg) { return pkg->arch; } +static off_t _pkg_get_size(pmpkg_t *pkg) { return pkg->size; } +static off_t _pkg_get_isize(pmpkg_t *pkg) { return pkg->isize; } +static pmpkgreason_t _pkg_get_reason(pmpkg_t *pkg) { return pkg->reason; } +static int _pkg_get_epoch(pmpkg_t *pkg) { return pkg->epoch; } +static int _pkg_has_scriptlet(pmpkg_t *pkg) { return pkg->scriptlet; } + +static alpm_list_t *_pkg_get_licenses(pmpkg_t *pkg) { return pkg->licenses; } +static alpm_list_t *_pkg_get_groups(pmpkg_t *pkg) { return pkg->groups; } +static alpm_list_t *_pkg_get_depends(pmpkg_t *pkg) { return pkg->depends; } +static alpm_list_t *_pkg_get_optdepends(pmpkg_t *pkg) { return pkg->optdepends; } +static alpm_list_t *_pkg_get_conflicts(pmpkg_t *pkg) { return pkg->conflicts; } +static alpm_list_t *_pkg_get_provides(pmpkg_t *pkg) { return pkg->provides; } +static alpm_list_t *_pkg_get_replaces(pmpkg_t *pkg) { return pkg->replaces; } +static alpm_list_t *_pkg_get_deltas(pmpkg_t *pkg) { return pkg->deltas; } +static alpm_list_t *_pkg_get_files(pmpkg_t *pkg) { return pkg->files; } +static alpm_list_t *_pkg_get_backup(pmpkg_t *pkg) { return pkg->backup; } + +/** The standard package operations struct. Get fields directly from the + * struct itself with no abstraction layer or any type of lazy loading. + */ +struct pkg_operations default_pkg_ops = { + .get_filename = _pkg_get_filename, + .get_name = _pkg_get_name, + .get_version = _pkg_get_version, + .get_desc = _pkg_get_desc, + .get_url = _pkg_get_url, + .get_builddate = _pkg_get_builddate, + .get_installdate = _pkg_get_installdate, + .get_packager = _pkg_get_packager, + .get_md5sum = _pkg_get_md5sum, + .get_arch = _pkg_get_arch, + .get_size = _pkg_get_size, + .get_isize = _pkg_get_isize, + .get_reason = _pkg_get_reason, + .get_epoch = _pkg_get_epoch, + .has_scriptlet = _pkg_has_scriptlet, + .get_licenses = _pkg_get_licenses, + .get_groups = _pkg_get_groups, + .get_depends = _pkg_get_depends, + .get_optdepends = _pkg_get_optdepends, + .get_conflicts = _pkg_get_conflicts, + .get_provides = _pkg_get_provides, + .get_replaces = _pkg_get_replaces, + .get_deltas = _pkg_get_deltas, + .get_files = _pkg_get_files, + .get_backup = _pkg_get_backup, +}; + +/* Public functions for getting package information. These functions + * delegate the hard work to the function callbacks attached to each + * package, which depend on where the package was loaded from. */ const char SYMEXPORT *alpm_pkg_get_filename(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(pkg != NULL, return(NULL)); - - if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) { - _alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC); - } - - return pkg->filename; + return pkg->ops->get_filename(pkg); } const char SYMEXPORT *alpm_pkg_get_name(pmpkg_t *pkg) { - ASSERT(pkg != NULL, return(NULL)); - return pkg->name; + return pkg->ops->get_name(pkg); } const char SYMEXPORT *alpm_pkg_get_version(pmpkg_t *pkg) { - ASSERT(pkg != NULL, return(NULL)); - return pkg->version; + return pkg->ops->get_version(pkg); } const char SYMEXPORT *alpm_pkg_get_desc(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(pkg != NULL, return(NULL)); - - if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) { - _alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC); - } - return pkg->desc; + return pkg->ops->get_desc(pkg); } const char SYMEXPORT *alpm_pkg_get_url(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(pkg != NULL, return(NULL)); - - if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) { - _alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC); - } - return pkg->url; + return pkg->ops->get_url(pkg); } time_t SYMEXPORT alpm_pkg_get_builddate(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(0)); - ASSERT(pkg != NULL, return(0)); - - if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) { - _alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC); - } - return pkg->builddate; + return pkg->ops->get_builddate(pkg); } time_t SYMEXPORT alpm_pkg_get_installdate(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(0)); - ASSERT(pkg != NULL, return(0)); - - if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) { - _alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC); - } - return pkg->installdate; + return pkg->ops->get_installdate(pkg); } const char SYMEXPORT *alpm_pkg_get_packager(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(pkg != NULL, return(NULL)); - - if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) { - _alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC); - } - return pkg->packager; + return pkg->ops->get_packager(pkg); } const char SYMEXPORT *alpm_pkg_get_md5sum(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(pkg != NULL, return(NULL)); - - if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) { - _alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC); - } - return pkg->md5sum; + return pkg->ops->get_md5sum(pkg); } const char SYMEXPORT *alpm_pkg_get_arch(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(pkg != NULL, return(NULL)); - - if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) { - _alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC); - } - return pkg->arch; + return pkg->ops->get_arch(pkg); } off_t SYMEXPORT alpm_pkg_get_size(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(-1)); - ASSERT(pkg != NULL, return(-1)); - - if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) { - _alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC); - } - return pkg->size; + return pkg->ops->get_size(pkg); } off_t SYMEXPORT alpm_pkg_get_isize(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(-1)); - ASSERT(pkg != NULL, return(-1)); - - if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) { - _alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC); - } - return pkg->isize; + return pkg->ops->get_isize(pkg); } pmpkgreason_t SYMEXPORT alpm_pkg_get_reason(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(-1)); - ASSERT(pkg != NULL, return(-1)); + return pkg->ops->get_reason(pkg); +} - if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) { - _alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC); - } - return pkg->reason; +int SYMEXPORT alpm_pkg_get_epoch(pmpkg_t *pkg) +{ + return pkg->ops->get_epoch(pkg); } alpm_list_t SYMEXPORT *alpm_pkg_get_licenses(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(pkg != NULL, return(NULL)); - - if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) { - _alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC); - } - return pkg->licenses; + return pkg->ops->get_licenses(pkg); } alpm_list_t SYMEXPORT *alpm_pkg_get_groups(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(pkg != NULL, return(NULL)); - - if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) { - _alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC); - } - return pkg->groups; -} - -int SYMEXPORT alpm_pkg_has_force(pmpkg_t *pkg) -{ - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(-1)); - ASSERT(pkg != NULL, return(-1)); - - if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) { - _alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC); - } - return pkg->force; + return pkg->ops->get_groups(pkg); } alpm_list_t SYMEXPORT *alpm_pkg_get_depends(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(pkg != NULL, return(NULL)); - - if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DEPENDS)) { - _alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DEPENDS); - } - return pkg->depends; + return pkg->ops->get_depends(pkg); } alpm_list_t SYMEXPORT *alpm_pkg_get_optdepends(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(pkg != NULL, return(NULL)); - - if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DEPENDS)) { - _alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DEPENDS); - } - return pkg->optdepends; + return pkg->ops->get_optdepends(pkg); } alpm_list_t SYMEXPORT *alpm_pkg_get_conflicts(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(pkg != NULL, return(NULL)); - - if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DEPENDS)) { - _alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DEPENDS); - } - return pkg->conflicts; + return pkg->ops->get_conflicts(pkg); } alpm_list_t SYMEXPORT *alpm_pkg_get_provides(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(pkg != NULL, return(NULL)); - - if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DEPENDS)) { - _alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DEPENDS); - } - return pkg->provides; + return pkg->ops->get_provides(pkg); } -alpm_list_t SYMEXPORT *alpm_pkg_get_deltas(pmpkg_t *pkg) +alpm_list_t SYMEXPORT *alpm_pkg_get_replaces(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(pkg != NULL, return(NULL)); - - if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DELTAS)) { - _alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DELTAS); - } - return pkg->deltas; + return pkg->ops->get_replaces(pkg); } -alpm_list_t SYMEXPORT *alpm_pkg_get_replaces(pmpkg_t *pkg) +alpm_list_t SYMEXPORT *alpm_pkg_get_deltas(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(pkg != NULL, return(NULL)); - - if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) { - _alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC); - } - return pkg->replaces; + return pkg->ops->get_deltas(pkg); } alpm_list_t SYMEXPORT *alpm_pkg_get_files(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(pkg != NULL, return(NULL)); - - if(pkg->origin == PKG_FROM_CACHE && pkg->origin_data.db == handle->db_local - && !(pkg->infolevel & INFRQ_FILES)) { - _alpm_db_read(pkg->origin_data.db, pkg, INFRQ_FILES); - } - return pkg->files; + return pkg->ops->get_files(pkg); } alpm_list_t SYMEXPORT *alpm_pkg_get_backup(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(pkg != NULL, return(NULL)); - - if(pkg->origin == PKG_FROM_CACHE && pkg->origin_data.db == handle->db_local - && !(pkg->infolevel & INFRQ_FILES)) { - _alpm_db_read(pkg->origin_data.db, pkg, INFRQ_FILES); - } - return pkg->backup; + return pkg->ops->get_backup(pkg); } pmdb_t SYMEXPORT *alpm_pkg_get_db(pmpkg_t *pkg) { /* Sanity checks */ ASSERT(pkg != NULL, return(NULL)); - ASSERT(pkg->origin == PKG_FROM_CACHE, return(NULL)); + ASSERT(pkg->origin != PKG_FROM_FILE, return(NULL)); return(pkg->origin_data.db); } @@ -441,83 +296,31 @@ pmdb_t SYMEXPORT *alpm_pkg_get_db(pmpkg_t *pkg) */ void SYMEXPORT *alpm_pkg_changelog_open(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(pkg != NULL, return(NULL)); - - if(pkg->origin == PKG_FROM_CACHE) { - char clfile[PATH_MAX]; - snprintf(clfile, PATH_MAX, "%s/%s/%s-%s/changelog", - alpm_option_get_dbpath(), - alpm_db_get_name(handle->db_local), - alpm_pkg_get_name(pkg), - alpm_pkg_get_version(pkg)); - return fopen(clfile, "r"); - } else if(pkg->origin == PKG_FROM_FILE) { - struct archive *archive = NULL; - struct archive_entry *entry; - const char *pkgfile = pkg->origin_data.file; - - if((archive = archive_read_new()) == NULL) { - RET_ERR(PM_ERR_LIBARCHIVE, NULL); - } - - archive_read_support_compression_all(archive); - archive_read_support_format_all(archive); - - if (archive_read_open_filename(archive, pkgfile, - ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { - RET_ERR(PM_ERR_PKG_OPEN, NULL); - } - - while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) { - const char *entry_name = archive_entry_pathname(entry); - - if(strcmp(entry_name, ".CHANGELOG") == 0) { - return(archive); - } - } - /* we didn't find a changelog */ - archive_read_finish(archive); - errno = ENOENT; - } - return(NULL); + return pkg->ops->changelog_open(pkg); } /** * Read data from an open changelog 'file stream'. Similar to fread in - * functionality, this function takes a buffer and amount of data to read. + * functionality, this function takes a buffer and amount of data to read. If an + * error occurs pm_errno will be set. + * * @param ptr a buffer to fill with raw changelog data * @param size the size of the buffer * @param pkg the package that the changelog is being read from * @param fp a 'file stream' to the package changelog - * @return the number of characters read, or 0 if there is no more data + * @return the number of characters read, or 0 if there is no more data or an + * error occurred. */ size_t SYMEXPORT alpm_pkg_changelog_read(void *ptr, size_t size, const pmpkg_t *pkg, const void *fp) { - size_t ret = 0; - if(pkg->origin == PKG_FROM_CACHE) { - ret = fread(ptr, 1, size, (FILE*)fp); - } else if(pkg->origin == PKG_FROM_FILE) { - ret = archive_read_data((struct archive*)fp, ptr, size); - } - return(ret); + return pkg->ops->changelog_read(ptr, size, pkg, fp); } /* int SYMEXPORT alpm_pkg_changelog_feof(const pmpkg_t *pkg, void *fp) { - int ret = 0; - if(pkg->origin == PKG_FROM_CACHE) { - ret = feof((FILE*)fp); - } else if(pkg->origin == PKG_FROM_FILE) { - // note: this doesn't quite work, no feof in libarchive - ret = archive_read_data((struct archive*)fp, NULL, 0); - } - return(ret); + return pkg->ops->changelog_feof(pkg, fp); } */ @@ -531,28 +334,12 @@ int SYMEXPORT alpm_pkg_changelog_feof(const pmpkg_t *pkg, void *fp) */ int SYMEXPORT alpm_pkg_changelog_close(const pmpkg_t *pkg, void *fp) { - int ret = 0; - if(pkg->origin == PKG_FROM_CACHE) { - ret = fclose((FILE*)fp); - } else if(pkg->origin == PKG_FROM_FILE) { - ret = archive_read_finish((struct archive *)fp); - } - return(ret); + return pkg->ops->changelog_close(pkg, fp); } int SYMEXPORT alpm_pkg_has_scriptlet(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(-1)); - ASSERT(pkg != NULL, return(-1)); - - if(pkg->origin == PKG_FROM_CACHE && pkg->origin_data.db == handle->db_local - && !(pkg->infolevel & INFRQ_SCRIPTLET)) { - _alpm_db_read(pkg->origin_data.db, pkg, INFRQ_SCRIPTLET); - } - return pkg->scriptlet; + return pkg->ops->has_scriptlet(pkg); } static void find_requiredby(pmpkg_t *pkg, pmdb_t *db, alpm_list_t **reqs) @@ -626,6 +413,7 @@ pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg) CALLOC(newpkg, 1, sizeof(pmpkg_t), RET_ERR(PM_ERR_MEMORY, NULL)); + newpkg->name_hash = pkg->name_hash; STRDUP(newpkg->filename, pkg->filename, RET_ERR(PM_ERR_MEMORY, newpkg)); STRDUP(newpkg->name, pkg->name, RET_ERR(PM_ERR_MEMORY, newpkg)); STRDUP(newpkg->version, pkg->version, RET_ERR(PM_ERR_MEMORY, newpkg)); @@ -639,7 +427,7 @@ pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg) newpkg->size = pkg->size; newpkg->isize = pkg->isize; newpkg->scriptlet = pkg->scriptlet; - newpkg->force = pkg->force; + newpkg->epoch = pkg->epoch; newpkg->reason = pkg->reason; newpkg->licenses = alpm_list_strdup(pkg->licenses); @@ -657,6 +445,7 @@ pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg) /* internal */ newpkg->origin = pkg->origin; + newpkg->ops = pkg->ops; if(newpkg->origin == PKG_FROM_FILE) { newpkg->origin_data.file = strdup(pkg->origin_data.file); } else { @@ -726,21 +515,25 @@ void _alpm_pkg_free_trans(pmpkg_t *pkg) pkg->removes = NULL; } -/* Is spkg an upgrade for locapkg? */ +/* Is spkg an upgrade for localpkg? */ int _alpm_pkg_compare_versions(pmpkg_t *spkg, pmpkg_t *localpkg) { - int cmp = 0; + int spkg_epoch, localpkg_epoch; ALPM_LOG_FUNC; - cmp = alpm_pkg_vercmp(alpm_pkg_get_version(spkg), - alpm_pkg_get_version(localpkg)); + spkg_epoch = alpm_pkg_get_epoch(spkg); + localpkg_epoch = alpm_pkg_get_epoch(localpkg); - if(cmp < 0 && alpm_pkg_has_force(spkg)) { - cmp = 1; + if(spkg_epoch > localpkg_epoch) { + return(1); + } else if(spkg_epoch < localpkg_epoch) { + return(-1); } - return(cmp); + /* equal epoch values, move on to version comparison */ + return alpm_pkg_vercmp(alpm_pkg_get_version(spkg), + alpm_pkg_get_version(localpkg)); } /* Helper function for comparing packages @@ -749,7 +542,7 @@ int _alpm_pkg_cmp(const void *p1, const void *p2) { pmpkg_t *pkg1 = (pmpkg_t *)p1; pmpkg_t *pkg2 = (pmpkg_t *)p2; - return(strcmp(pkg1->name, pkg2->name)); + return(strcoll(pkg1->name, pkg2->name)); } /* Test for existence of a package in a alpm_list_t* @@ -758,6 +551,7 @@ int _alpm_pkg_cmp(const void *p1, const void *p2) pmpkg_t *_alpm_pkg_find(alpm_list_t *haystack, const char *needle) { alpm_list_t *lp; + unsigned long needle_hash; ALPM_LOG_FUNC; @@ -765,11 +559,21 @@ pmpkg_t *_alpm_pkg_find(alpm_list_t *haystack, const char *needle) return(NULL); } + needle_hash = _alpm_hash_sdbm(needle); + for(lp = haystack; lp; lp = lp->next) { pmpkg_t *info = lp->data; - if(info && strcmp(info->name, needle) == 0) { - return(info); + if(info) { + /* a zero hash will cause a fall-through just in case */ + if(info->name_hash && info->name_hash != needle_hash) { + continue; + } + + /* finally: we had hash match, verify string match */ + if(strcmp(info->name, needle) == 0) { + return(info); + } } } return(NULL); |