diff options
Diffstat (limited to 'lib/libalpm/remove.c')
-rw-r--r-- | lib/libalpm/remove.c | 97 |
1 files changed, 72 insertions, 25 deletions
diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c index a0f9963a..625abe67 100644 --- a/lib/libalpm/remove.c +++ b/lib/libalpm/remove.c @@ -37,7 +37,6 @@ #include "alpm_list.h" #include "trans.h" #include "util.h" -#include "error.h" #include "log.h" #include "backup.h" #include "package.h" @@ -57,7 +56,7 @@ int _alpm_remove_loadtarget(pmtrans_t *trans, pmdb_t *db, char *name) ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); ASSERT(name != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1)); - if(_alpm_pkg_find(name, trans->packages)) { + if(_alpm_pkg_find(trans->packages, name)) { RET_ERR(PM_ERR_TRANS_DUP_TARGET, -1); } @@ -82,6 +81,60 @@ int _alpm_remove_loadtarget(pmtrans_t *trans, pmdb_t *db, char *name) return(0); } +static void remove_prepare_cascade(pmtrans_t *trans, pmdb_t *db, + alpm_list_t *lp) +{ + ALPM_LOG_FUNC; + + while(lp) { + alpm_list_t *i; + for(i = lp; i; i = i->next) { + pmdepmissing_t *miss = (pmdepmissing_t *)i->data; + pmpkg_t *info = _alpm_db_get_pkgfromcache(db, miss->target); + if(info) { + if(!_alpm_pkg_find(trans->packages, alpm_pkg_get_name(info))) { + _alpm_log(PM_LOG_DEBUG, "pulling %s in the targets list\n", + alpm_pkg_get_name(info)); + trans->packages = alpm_list_add(trans->packages, _alpm_pkg_dup(info)); + } + } else { + _alpm_log(PM_LOG_ERROR, _("could not find %s in database -- skipping\n"), + miss->target); + } + } + alpm_list_free_inner(lp, (alpm_list_fn_free)_alpm_depmiss_free); + alpm_list_free(lp); + lp = alpm_checkdeps(db, 1, trans->packages, NULL); + } +} + +static void remove_prepare_keep_needed(pmtrans_t *trans, pmdb_t *db, + alpm_list_t *lp) +{ + ALPM_LOG_FUNC; + + /* Remove needed packages (which break dependencies) from the target list */ + while(lp != NULL) { + alpm_list_t *i; + for(i = lp; i; i = i->next) { + pmdepmissing_t *miss = (pmdepmissing_t *)i->data; + void *vpkg; + pmpkg_t *pkg = _alpm_pkg_find(trans->packages, miss->causingpkg); + trans->packages = alpm_list_remove(trans->packages, pkg, _alpm_pkg_cmp, + &vpkg); + pkg = vpkg; + if(pkg) { + _alpm_log(PM_LOG_WARNING, "removing %s from the target-list\n", + alpm_pkg_get_name(pkg)); + _alpm_pkg_free(pkg); + } + } + alpm_list_free_inner(lp, (alpm_list_fn_free)_alpm_depmiss_free); + alpm_list_free(lp); + lp = alpm_checkdeps(db, 1, trans->packages, NULL); + } +} + int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data) { alpm_list_t *lp; @@ -96,37 +149,30 @@ int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data) return(0); } + if((trans->flags & PM_TRANS_FLAG_RECURSE) && !(trans->flags & PM_TRANS_FLAG_CASCADE)) { + _alpm_log(PM_LOG_DEBUG, "finding removable dependencies\n"); + _alpm_recursedeps(db, trans->packages, trans->flags & PM_TRANS_FLAG_RECURSEALL); + } + if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) { EVENT(trans, PM_TRANS_EVT_CHECKDEPS_START, NULL, NULL); _alpm_log(PM_LOG_DEBUG, "looking for unsatisfied dependencies\n"); lp = alpm_checkdeps(db, 1, trans->packages, NULL); if(lp != NULL) { + if(trans->flags & PM_TRANS_FLAG_CASCADE) { - while(lp) { - alpm_list_t *i; - for(i = lp; i; i = i->next) { - pmdepmissing_t *miss = (pmdepmissing_t *)i->data; - pmpkg_t *info = _alpm_db_get_pkgfromcache(db, miss->target); - if(info) { - if(!_alpm_pkg_find(alpm_pkg_get_name(info), trans->packages)) { - _alpm_log(PM_LOG_DEBUG, "pulling %s in the targets list\n", - alpm_pkg_get_name(info)); - trans->packages = alpm_list_add(trans->packages, _alpm_pkg_dup(info)); - } - } else { - _alpm_log(PM_LOG_ERROR, _("could not find %s in database -- skipping\n"), - miss->target); - } - } - FREELIST(lp); - lp = alpm_checkdeps(db, 1, trans->packages, NULL); - } + remove_prepare_cascade(trans, db, lp); + } else if (trans->flags & PM_TRANS_FLAG_UNNEEDED) { + /* Remove needed packages (which would break dependencies) + * from the target list */ + remove_prepare_keep_needed(trans, db, lp); } else { if(data) { *data = lp; } else { - FREELIST(lp); + alpm_list_free_inner(lp, (alpm_list_fn_free)_alpm_depmiss_free); + alpm_list_free(lp); } RET_ERR(PM_ERR_UNSATISFIED_DEPS, -1); } @@ -135,14 +181,15 @@ int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data) /* re-order w.r.t. dependencies */ _alpm_log(PM_LOG_DEBUG, "sorting by dependencies\n"); - lp = _alpm_sortbydeps(trans->packages, PM_TRANS_TYPE_REMOVE); + lp = _alpm_sortbydeps(trans->packages, 1); /* free the old alltargs */ alpm_list_free(trans->packages); trans->packages = lp; - if(trans->flags & PM_TRANS_FLAG_RECURSE) { + /* -Rcs == -Rc then -Rs */ + if((trans->flags & PM_TRANS_FLAG_CASCADE) && (trans->flags & PM_TRANS_FLAG_RECURSE)) { _alpm_log(PM_LOG_DEBUG, "finding removable dependencies\n"); - _alpm_recursedeps(db, trans->packages, 0); + _alpm_recursedeps(db, trans->packages, trans->flags & PM_TRANS_FLAG_RECURSEALL); } if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) { |