summaryrefslogtreecommitdiffstats
path: root/lib/libalpm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libalpm')
-rw-r--r--lib/libalpm/alpm.c154
-rw-r--r--lib/libalpm/alpm.h2
-rw-r--r--lib/libalpm/package.c11
-rw-r--r--lib/libalpm/package.h2
-rw-r--r--lib/libalpm/sync.c15
5 files changed, 170 insertions, 14 deletions
diff --git a/lib/libalpm/alpm.c b/lib/libalpm/alpm.c
index de89fb21..62d46e6a 100644
--- a/lib/libalpm/alpm.c
+++ b/lib/libalpm/alpm.c
@@ -1078,4 +1078,158 @@ int SYMEXPORT alpm_parse_config(char *file, alpm_cb_db_register callback, const
/** @} */
+/* This function is mostly the same as sync.c find_replacements and sysupgrade
+ * functions, and we should be able to combine them - this is an interim
+ * solution made for -Qu operation */
+alpm_list_t *alpm_get_upgrades()
+{
+ int found = 0;
+ alpm_list_t *syncpkgs = NULL;
+ alpm_list_t *i, *j, *k;
+
+ ALPM_LOG_FUNC;
+
+ /* TODO holy nested loops, Batman! */
+ /* check for "recommended" package replacements */
+ _alpm_log(PM_LOG_DEBUG, _("checking for package replacements"));
+ for(i = handle->dbs_sync; i; i = i->next) {
+ for(j = _alpm_db_get_pkgcache(i->data, INFRQ_DESC); j; j = j->next) {
+ pmpkg_t *spkg = j->data;
+ for(k = spkg->replaces; k; k = k->next) {
+ alpm_list_t *m;
+ for(m = _alpm_db_get_pkgcache(handle->db_local, INFRQ_NONE); m; m = m->next) {
+ pmpkg_t *lpkg = m->data;
+ if(strcmp(k->data, lpkg->name) == 0) {
+ _alpm_log(PM_LOG_DEBUG, _("checking replacement '%s' for package '%s'"), k->data, spkg->name);
+ if(alpm_list_find_str(handle->ignorepkg, lpkg->name)) {
+ _alpm_log(PM_LOG_WARNING, _("%s-%s: ignoring package upgrade (to be replaced by %s-%s)"),
+ lpkg->name, lpkg->version, spkg->name, spkg->version);
+ } else {
+ /* assume all replaces=() packages are accepted */
+ pmsyncpkg_t *sync = NULL;
+ pmpkg_t *dummy = _alpm_pkg_new(lpkg->name, NULL);
+ if(dummy == NULL) {
+ pm_errno = PM_ERR_MEMORY;
+ goto error;
+ }
+ dummy->requiredby = alpm_list_strdup(lpkg->requiredby);
+ /* check if spkg->name is already in the packages list. */
+ alpm_list_t *s;
+ for(s = syncpkgs; s && !found; s = s->next) {
+ sync = i->data;
+ if(sync && !strcmp(sync->pkg->name, spkg->name)) {
+ found = 1;
+ }
+ }
+
+ if(found) {
+ /* found it -- just append to the replaces list */
+ sync->data = alpm_list_add(sync->data, dummy);
+ } else {
+ /* none found -- enter pkg into the final sync list */
+ sync = _alpm_sync_new(PM_SYNC_TYPE_REPLACE, spkg, NULL);
+ if(sync == NULL) {
+ FREEPKG(dummy);
+ pm_errno = PM_ERR_MEMORY;
+ goto error;
+ }
+ sync->data = alpm_list_add(NULL, dummy);
+ syncpkgs = alpm_list_add(syncpkgs, sync);
+ }
+ _alpm_log(PM_LOG_DEBUG, _("%s-%s elected for upgrade (to be replaced by %s-%s)"),
+ lpkg->name, lpkg->version, spkg->name, spkg->version);
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /* now do normal upgrades */
+ for(i = _alpm_db_get_pkgcache(handle->db_local, INFRQ_NONE); i; i = i->next) {
+ int cmp;
+ int replace=0;
+ pmpkg_t *local = i->data;
+ pmpkg_t *spkg = NULL;
+ pmsyncpkg_t *sync;
+
+ for(j = handle->dbs_sync; !spkg && j; j = j->next) {
+ spkg = _alpm_db_get_pkgfromcache(j->data, local->name);
+ }
+ if(spkg == NULL) {
+ _alpm_log(PM_LOG_DEBUG, _("'%s' not found in sync db -- skipping"), local->name);
+ continue;
+ }
+
+ /* we don't care about a to-be-replaced package's newer version */
+ for(j = syncpkgs; j && !replace; j=j->next) {
+ sync = j->data;
+ if(sync->type == PM_SYNC_TYPE_REPLACE) {
+ if(_alpm_pkg_isin(spkg->name, sync->data)) {
+ replace=1;
+ }
+ }
+ }
+ if(replace) {
+ _alpm_log(PM_LOG_DEBUG, _("'%s' is already elected for removal -- skipping"),
+ local->name);
+ continue;
+ }
+
+ /* compare versions and see if we need to upgrade */
+ cmp = alpm_versioncmp(local->version, spkg->version);
+ if(cmp > 0 && !spkg->force) {
+ /* local version is newer */
+ pmdb_t *db = spkg->data;
+ _alpm_log(PM_LOG_WARNING, _("%s: local (%s) is newer than %s (%s)"),
+ local->name, local->version, db->treename, spkg->version);
+ } else if(cmp == 0) {
+ /* versions are identical */
+ } else if(alpm_list_find_str(handle->ignorepkg, spkg->name)) {
+ /* package should be ignored (IgnorePkg) */
+ _alpm_log(PM_LOG_WARNING, _("%s-%s: ignoring package upgrade (%s)"),
+ local->name, local->version, spkg->version);
+ } else if(_alpm_pkg_istoonew(spkg)) {
+ /* package too new (UpgradeDelay) */
+ _alpm_log(PM_LOG_DEBUG, _("%s-%s: delaying upgrade of package (%s)"),
+ local->name, local->version, spkg->version);
+ /* check if spkg->name is already in the packages list. */
+ } else {
+ _alpm_log(PM_LOG_DEBUG, _("%s-%s elected for upgrade (%s => %s)"),
+ local->name, local->version, local->version, spkg->version);
+ alpm_list_t *s;
+ pmsyncpkg_t *sync = NULL;
+ found = 0;
+ for(s = syncpkgs; s && !found; s = s->next) {
+ sync = i->data;
+ if(sync && strcmp(sync->pkg->name, local->name) == 0) {
+ found = 1;
+ }
+ }
+
+ if(!found) {
+ pmpkg_t *dummy = _alpm_pkg_new(local->name, local->version);
+ if(dummy == NULL) {
+ goto error;
+ }
+ sync = _alpm_sync_new(PM_SYNC_TYPE_UPGRADE, spkg, dummy);
+ if(sync == NULL) {
+ FREEPKG(dummy);
+ goto error;
+ }
+ syncpkgs = alpm_list_add(syncpkgs, sync);
+ }
+ }
+ }
+
+ return(syncpkgs);
+error:
+ if(syncpkgs) {
+ alpm_list_free_inner(syncpkgs, _alpm_sync_free);
+ alpm_list_free(syncpkgs);
+ }
+ return(NULL);
+}
+
/* vim: set ts=2 sw=2 noet: */
diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index 15af82b1..3522604f 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -486,6 +486,8 @@ char *alpm_strerror(int err);
/* Version Compare */
int alpm_versioncmp(const char *a, const char *b);
+alpm_list_t *alpm_get_upgrades();
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c
index 4c78fdaf..e93da71e 100644
--- a/lib/libalpm/package.c
+++ b/lib/libalpm/package.c
@@ -834,4 +834,15 @@ unsigned short SYMEXPORT alpm_pkg_has_scriptlet(pmpkg_t *pkg)
return pkg->scriptlet;
}
+int _alpm_pkg_istoonew(pmpkg_t *pkg)
+{
+ time_t t;
+
+ ALPM_LOG_FUNC;
+
+ if (!handle->upgradedelay)
+ return 0;
+ time(&t);
+ return((pkg->date + handle->upgradedelay) > t);
+}
/* vim: set ts=2 sw=2 noet: */
diff --git a/lib/libalpm/package.h b/lib/libalpm/package.h
index 50052326..dfaec2a2 100644
--- a/lib/libalpm/package.h
+++ b/lib/libalpm/package.h
@@ -97,7 +97,7 @@ int _alpm_pkg_cmp(const void *p1, const void *p2);
pmpkg_t *_alpm_pkg_load(char *pkgfile);
pmpkg_t *_alpm_pkg_isin(char *needle, alpm_list_t *haystack);
int _alpm_pkg_splitname(char *target, char *name, char *version, int witharch);
-
+int _alpm_pkg_istoonew(pmpkg_t *pkg);
#endif /* _ALPM_PACKAGE_H */
diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c
index 329353a1..9cf973fa 100644
--- a/lib/libalpm/sync.c
+++ b/lib/libalpm/sync.c
@@ -115,18 +115,6 @@ static pmsyncpkg_t *find_pkginsync(char *needle, alpm_list_t *haystack)
return(sync);
}
-static int istoonew(pmpkg_t *pkg)
-{
- time_t t;
-
- ALPM_LOG_FUNC;
-
- if (!handle->upgradedelay)
- return 0;
- time(&t);
- return((pkg->date + handle->upgradedelay) > t);
-}
-
/* Find recommended replacements for packages during a sync.
* (refactored from _alpm_sync_prepare)
*/
@@ -198,6 +186,7 @@ error:
return(-1);
}
+/* TODO reimplement this in terms of alpm_get_upgrades */
int _alpm_sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync)
{
alpm_list_t *i, *j;
@@ -252,7 +241,7 @@ int _alpm_sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_s
/* package should be ignored (IgnorePkg) */
_alpm_log(PM_LOG_WARNING, _("%s-%s: ignoring package upgrade (%s)"),
local->name, local->version, spkg->version);
- } else if(istoonew(spkg)) {
+ } else if(_alpm_pkg_istoonew(spkg)) {
/* package too new (UpgradeDelay) */
_alpm_log(PM_LOG_DEBUG, _("%s-%s: delaying upgrade of package (%s)"),
local->name, local->version, spkg->version);