summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libalpm/add.c3
-rw-r--r--lib/libalpm/deps.c96
2 files changed, 53 insertions, 46 deletions
diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c
index 28e66354..a2d79eb4 100644
--- a/lib/libalpm/add.c
+++ b/lib/libalpm/add.c
@@ -441,6 +441,9 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db)
/* Add files in the NEW package's backup array to the noupgrade array
* so this removal operation doesn't kill them */
+ /* TODO if we add here, all backup=() entries for all targets, new and
+ * old, we cover all bases, including backup=() locations changing hands.
+ * But is this viable? */
alpm_list_t *old_noupgrade = alpm_list_strdup(handle->noupgrade);
for(b = newpkg->backup; b; b = b->next) {
_alpm_log(PM_LOG_DEBUG, _("adding %s to the NoUpgrade array temporarilly"), (char *)b->data);
diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c
index 7065efa7..99056071 100644
--- a/lib/libalpm/deps.c
+++ b/lib/libalpm/deps.c
@@ -138,9 +138,7 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, pmtranstype_t mode)
for(i = newtargs; i; i = i->next) {
pmpkg_t *p = (pmpkg_t*)i->data;
_alpm_log(PM_LOG_DEBUG, "sorting %s", p->name);
- /* TODO this may not always work if p->data is a fd, not db */
- _alpm_db_read(p->data, INFRQ_DEPENDS, p);
- for(j = p->depends; j; j = j->next) {
+ for(j = alpm_pkg_get_depends(p); j; j = j->next) {
pmdepend_t dep;
pmpkg_t *q = NULL;
if(_alpm_splitdep(j->data, &dep)) {
@@ -438,6 +436,35 @@ int _alpm_splitdep(char *depstr, pmdepend_t *depend)
return(0);
}
+/* These parameters are messy. We check if this package, given a list of
+ * targets (and a db), is safe to remove. We do NOT remove it if it is in the
+ * target list */
+static int can_remove_package(pmdb_t *db, pmpkg_t *pkg, alpm_list_t *targets)
+{
+ alpm_list_t *i;
+
+ if(_alpm_pkg_isin(pkg->name, targets)) {
+ return(0);
+ }
+
+ /* see if it was explicitly installed */
+ if(alpm_pkg_get_reason(pkg) == PM_PKG_REASON_EXPLICIT) {
+ _alpm_log(PM_LOG_DEBUG, _("excluding %s -- explicitly installed"), pkg->name);
+ return(0);
+ }
+
+ /* see if other packages need it */
+ for(i = alpm_pkg_get_requiredby(pkg); i; i = i->next) {
+ pmpkg_t *reqpkg = _alpm_db_get_pkgfromcache(db, i->data);
+ if(reqpkg && !_alpm_pkg_isin(reqpkg->name, targets)) {
+ return(0);
+ }
+ }
+
+ /* it's ok to remove */
+ return(1);
+}
+
/* return a new alpm_list_t target list containing all packages in the original
* target list, as well as all their un-needed dependencies. By un-needed,
* I mean dependencies that are *only* required for packages in the target
@@ -456,67 +483,44 @@ alpm_list_t *_alpm_removedeps(pmdb_t *db, alpm_list_t *targs)
for(i = targs; i; i = i->next) {
pmpkg_t *pkg = i->data;
- if(pkg) {
- _alpm_db_read(db, INFRQ_DEPENDS, pkg);
- } else {
- continue;
- }
- for(j = pkg->depends; j; j = j->next) {
+ for(j = alpm_pkg_get_depends(pkg); j; j = j->next) {
pmdepend_t depend;
pmpkg_t *dep;
- int needed = 0;
-
if(_alpm_splitdep(j->data, &depend)) {
continue;
}
dep = _alpm_db_get_pkgfromcache(db, depend.name);
if(dep == NULL) {
- /* package not found... look for a provisio instead */
- k = _alpm_db_whatprovides(db, depend.name);
- if(k == NULL) {
+ /* package not found... look for a provision instead */
+ alpm_list_t *provides = _alpm_db_whatprovides(db, depend.name);
+ if(!provides) {
/* Not found, that's fine, carry on */
_alpm_log(PM_LOG_DEBUG, _("cannot find package \"%s\" or anything that provides it!"), depend.name);
continue;
}
- dep = _alpm_db_get_pkgfromcache(db, ((pmpkg_t *)k->data)->name);
- if(dep == NULL) {
- _alpm_log(PM_LOG_ERROR, _("dep is NULL!"));
- /* wtf */
- continue;
- }
- FREELISTPTR(k);
- }
+ for(k = provides; k; k = k->next) {
+ pmpkg_t *provpkg = k->data;
+ if(can_remove_package(db, provpkg, newtargs)) {
+ pmpkg_t *pkg = _alpm_pkg_new(provpkg->name, provpkg->version);
+ _alpm_db_read(db, INFRQ_ALL, pkg);
- _alpm_db_read(db, INFRQ_DEPENDS, dep);
+ _alpm_log(PM_LOG_DEBUG, _("adding '%s' to the targets"), pkg->name);
- if(_alpm_pkg_isin(dep->name, targs)) {
- continue;
- }
-
- /* see if it was explicitly installed */
- if(dep->reason == PM_PKG_REASON_EXPLICIT) {
- _alpm_log(PM_LOG_DEBUG, _("excluding %s -- explicitly installed"), dep->name);
- needed = 1;
- }
-
- /* see if other packages need it */
- for(k = dep->requiredby; k && !needed; k = k->next) {
- pmpkg_t *dummy = _alpm_db_get_pkgfromcache(db, k->data);
- if(!_alpm_pkg_isin(dummy->name, targs)) {
- needed = 1;
+ /* add it to the target list */
+ newtargs = alpm_list_add(newtargs, pkg);
+ newtargs = _alpm_removedeps(db, newtargs);
+ }
}
- }
- if(!needed) {
+ FREELISTPTR(provides);
+ } else if(can_remove_package(db, dep, newtargs)) {
pmpkg_t *pkg = _alpm_pkg_new(dep->name, dep->version);
- if(pkg == NULL) {
- continue;
- }
- /* add it to the target list */
- _alpm_log(PM_LOG_DEBUG, _("loading ALL info for '%s'"), pkg->name);
_alpm_db_read(db, INFRQ_ALL, pkg);
- newtargs = alpm_list_add(newtargs, pkg);
+
_alpm_log(PM_LOG_DEBUG, _("adding '%s' to the targets"), pkg->name);
+
+ /* add it to the target list */
+ newtargs = alpm_list_add(newtargs, pkg);
newtargs = _alpm_removedeps(db, newtargs);
}
}