diff options
Diffstat (limited to 'lib/libalpm')
-rw-r--r-- | lib/libalpm/add.c | 48 | ||||
-rw-r--r-- | lib/libalpm/conflict.c | 29 | ||||
-rw-r--r-- | lib/libalpm/conflict.h | 2 |
3 files changed, 39 insertions, 40 deletions
diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c index 3b51110b..7a268048 100644 --- a/lib/libalpm/add.c +++ b/lib/libalpm/add.c @@ -126,7 +126,7 @@ error: int _alpm_add_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data) { - alpm_list_t *lp = NULL, *i = NULL; + alpm_list_t *lp = NULL; ALPM_LOG_FUNC; @@ -152,48 +152,26 @@ int _alpm_add_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data) /* no unsatisfied deps, so look for conflicts */ _alpm_log(PM_LOG_DEBUG, "looking for conflicts\n"); - lp = _alpm_checkconflicts(db, trans->packages); - for(i = lp; i; i = i->next) { - pmconflict_t *conflict = i->data; + alpm_list_t *inner = _alpm_innerconflicts(trans->packages); + alpm_list_t *outer = _alpm_outerconflicts(db, trans->packages); + lp = alpm_list_join(inner, outer); - _alpm_log(PM_LOG_ERROR, _("replacing packages with -A and -U is not supported yet\n")); - _alpm_log(PM_LOG_ERROR, _("please remove '%s' first, using -Rd\n"), conflict->package2); - RET_ERR(PM_ERR_CONFLICTING_DEPS, -1); + /* TODO : factorize the conflict resolving code from sync.c to use it here (FS#3492) */ - /* Attempt to resolve conflicts */ - /* - int skip_this = 0; - QUESTION(trans, PM_TRANS_CONV_CONFLICT_PKG, miss->target, miss->depend.name, NULL, &skip_this); - if(skip_this) { - pmdepmissing_t *pkg = NULL; - lp = alpm_list_remove(lp, (void *)miss, deppkg_cmp, (void*)&pkg); - */ - /* TODO: We remove the conflict from the list but never actually remove - * the package. Need to do this to fix FS #3492. The sync code should - * provide an example of how to do this, as it handles replaces and - * removes. We run into problems because we do a file conflict check - * below and it fails there. A force flag will skip that part, but - * still not remove the original package designated here for removal. - * Better yet, dump all this shitty duplicate code and somehow combine - * it with the sync code. */ - /* - FREE(pkg); - if(lp == NULL) { - break; - } - } - */ - } - /* Removal code should go here, as described above. Instead of simply - * removing items, perhaps throw them in another list to be removed, then - * proceed as sync.c would? I'm not sure because I'm not familiar enough - * with the codebase. */ if(lp != NULL) { if(data) { *data = lp; } else { FREELIST(lp); } + if(inner) { + _alpm_log(PM_LOG_ERROR, _("conflicting packages were found in the target list\n")); + _alpm_log(PM_LOG_ERROR, _("you cannot install two conflicting packages at the same time\n")); + } + if(outer) { + _alpm_log(PM_LOG_ERROR, _("replacing packages with -A and -U is not supported yet\n")); + _alpm_log(PM_LOG_ERROR, _("you can replace packages manually using -Rd and -U\n")); + } RET_ERR(PM_ERR_CONFLICTING_DEPS, -1); } diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c index 7268275e..7b21c38a 100644 --- a/lib/libalpm/conflict.c +++ b/lib/libalpm/conflict.c @@ -162,8 +162,24 @@ static void check_conflict(alpm_list_t *list1, alpm_list_t *list2, } } -/* Returns a alpm_list_t* of pmconflict_t pointers. */ -alpm_list_t *_alpm_checkconflicts(pmdb_t *db, alpm_list_t *packages) +/* Check for inter-conflicts */ +alpm_list_t *_alpm_innerconflicts(alpm_list_t *packages) +{ + alpm_list_t *baddeps = NULL; + + ALPM_LOG_FUNC; + + _alpm_log(PM_LOG_DEBUG, "check targets vs targets\n"); + check_conflict(packages, packages, &baddeps, 0); + + return(baddeps); +} + +/* Check for target vs (db - target) conflicts + * In case of conflict the package1 field of pmdepconflict_t contains + * the target package, package2 field contains the local package + */ +alpm_list_t *_alpm_outerconflicts(pmdb_t *db, alpm_list_t *packages) { alpm_list_t *baddeps = NULL; @@ -176,18 +192,21 @@ alpm_list_t *_alpm_checkconflicts(pmdb_t *db, alpm_list_t *packages) alpm_list_t *dblist = alpm_list_diff(_alpm_db_get_pkgcache(db), packages, _alpm_pkg_cmp); - /* three checks to be done here for conflicts */ + /* two checks to be done here for conflicts */ _alpm_log(PM_LOG_DEBUG, "check targets vs db\n"); check_conflict(packages, dblist, &baddeps, 1); _alpm_log(PM_LOG_DEBUG, "check db vs targets\n"); check_conflict(dblist, packages, &baddeps, -1); - _alpm_log(PM_LOG_DEBUG, "check targets vs targets\n"); - check_conflict(packages, packages, &baddeps, 0); alpm_list_free(dblist); return(baddeps); } +/* Check for transaction conflicts */ +alpm_list_t *_alpm_checkconflicts(pmdb_t *db, alpm_list_t *packages) { + return(alpm_list_join(_alpm_innerconflicts(packages), _alpm_outerconflicts(db, packages))); +} + /* Returns a alpm_list_t* of file conflicts. * Hooray for set-intersects! * Pre-condition: both lists are sorted! diff --git a/lib/libalpm/conflict.h b/lib/libalpm/conflict.h index 89695353..00a593e9 100644 --- a/lib/libalpm/conflict.h +++ b/lib/libalpm/conflict.h @@ -41,6 +41,8 @@ struct __pmfileconflict_t { pmconflict_t *_alpm_conflict_new(const char *package1, const char *package2); int _alpm_conflict_isin(pmconflict_t *needle, alpm_list_t *haystack); +alpm_list_t *_alpm_innerconflicts(alpm_list_t *packages); +alpm_list_t *_alpm_outerconflicts(pmdb_t *db, alpm_list_t *packages); alpm_list_t *_alpm_checkconflicts(pmdb_t *db, alpm_list_t *packages); alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans, char *root); |