summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAurelien Foret <aurelien@archlinux.org>2006-01-05 20:53:41 +0000
committerAurelien Foret <aurelien@archlinux.org>2006-01-05 20:53:41 +0000
commit7858f4c9b4d4c4a478f27952c0beb34b58d0679f (patch)
tree84b3597ad3312eebebccc39b2e116d25afb9e3d6 /lib
parenta6923f9aae5465be45b4e716bd337eb40544f6cd (diff)
downloadpacman-7858f4c9b4d4c4a478f27952c0beb34b58d0679f.tar.xz
- fix for sync conflicts (patch from VMiklos <vmiklos@frugalware.org>)
- sync code cleanup - added the deps check for targets to be removed in sync_prepare()
Diffstat (limited to 'lib')
-rw-r--r--lib/libalpm/sync.c96
1 files changed, 48 insertions, 48 deletions
diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c
index 7b3cafae..25ac6dff 100644
--- a/lib/libalpm/sync.c
+++ b/lib/libalpm/sync.c
@@ -338,10 +338,10 @@ static int ptr_cmp(const void *s1, const void *s2)
int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **data)
{
PMList *deps = NULL;
- PMList *list = NULL;
- PMList *trail = NULL;
+ PMList *list = NULL; /* list allowing checkdeps usage with data from trans->packages */
+ PMList *trail = NULL; /* breadcrum list to avoid running into circles */
PMList *asked = NULL;
- PMList *i;
+ PMList *i, *j;
ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
@@ -383,7 +383,6 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **
deps = checkdeps(db_local, PM_TRANS_TYPE_UPGRADE, list);
if(deps) {
int found = 0;
- PMList *j, *k;
int errorout = 0;
_alpm_log(PM_LOG_FLOW1, "looking for unresolvable dependencies");
@@ -411,6 +410,7 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **
_alpm_log(PM_LOG_FLOW1, "looking for conflicts");
for(i = deps; i && !errorout; i = i->next) {
pmdepmissing_t *miss = i->data;
+ PMList *k;
if(miss->type != PM_DEP_TYPE_CONFLICT) {
continue;
}
@@ -420,7 +420,7 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **
*/
for(j = trans->packages; j && !found; j = j->next) {
pmsyncpkg_t *sync = j->data;
- if(sync->type == PM_SYNC_TYPE_REPLACE || sync->type == PM_SYNC_TYPE_REMOVE) {
+ if(sync->type == PM_SYNC_TYPE_REPLACE) {
for(k = sync->data; k && !found; k = k->next) {
pmpkg_t *p = k->data;
if(!strcmp(p->name, miss->depend.name)) {
@@ -441,16 +441,7 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **
* fields are inherited properly.
*/
- /* we save the dependency info so we can move p's requiredby stuff
- * over to the replacing package
- */
- pmpkg_t *q = db_scan(db_local, miss->depend.name, INFRQ_DESC | INFRQ_DEPENDS);
- if(q) {
- /* append to the replaces list */
- pmsyncpkg_t *spkg = sync_new(PM_SYNC_TYPE_REPLACE, q, NULL);
- trans->packages = pm_list_add(trans->packages, spkg);
- solved = 1;
- } else {
+ if(db_get_pkgfromcache(db_local, miss->depend.name) == NULL) {
char *rmpkg = NULL;
/* hmmm, depend.name isn't installed, so it must be conflicting
* with another package in our final list. For example:
@@ -492,16 +483,7 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **
if(!solved) {
/* It's a conflict -- see if they want to remove it
*/
- pmpkg_t *p,*q = NULL;
- int pkgfound = 0;
- for(k = db_get_pkgcache(db_local); k; k = k->next) {
- p = k->data;
- if(!strcmp(p->name, miss->depend.name)) {
- pkgfound = 1;
- break;
- }
- }
- if(pkgfound) {
+ if(db_get_pkgfromcache(db_local, miss->depend.name)) {
int doremove = 0;
if(!pm_list_is_strin(miss->depend.name, asked)) {
QUESTION(trans, PM_TRANS_CONV_CONFLICT_PKG, miss->target, miss->depend.name, NULL, &doremove);
@@ -512,8 +494,8 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **
for(l = trans->packages; l; l = l->next) {
pmsyncpkg_t *s = l->data;
if(!strcmp(s->pkg->name, miss->target)) {
- q = pkg_new();
- strcpy(q->name, miss->depend.name);
+ pmpkg_t *q = pkg_new();
+ STRNCPY(q->name, miss->depend.name, PKG_NAME_LEN);
if(s->type == PM_SYNC_TYPE_REPLACE) {
/* append to the replaces list */
s->data = pm_list_add(s->data, q);
@@ -550,26 +532,41 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **
FREELISTPTR(list);
FREELISTPTR(trail);
FREELIST(asked);
- }
- /* any packages in rmtargs need to be removed from final. */
- /* rather than ripping out nodes from final, we just copy over */
- /* our "good" nodes to a new list and reassign. */
-
- /* XXX: this fails for cases where a requested package wants
- * a dependency that conflicts with an older version of
- * the package. It will be removed from final, and the user
- * has to re-request it to get it installed properly.
- *
- * Not gonna happen very often, but should be dealt with...
- */
-
- /* ORE
- Check dependencies of packages in rmtargs and make sure
- we won't be breaking anything by removing them.
- If a broken dep is detected, make sure it's not from a
- package that's in our final (upgrade) list. */
- /*_alpm_log(PM_LOG_DEBUG, "checking dependencies of packages designated for removal");*/
+ /* XXX: this fails for cases where a requested package wants
+ * a dependency that conflicts with an older version of
+ * the package. It will be removed from final, and the user
+ * has to re-request it to get it installed properly.
+ *
+ * Not gonna happen very often, but should be dealt with...
+ */
+
+ /* Check dependencies of packages in rmtargs and make sure
+ * we won't be breaking anything by removing them.
+ * If a broken dep is detected, make sure it's not from a
+ * package that's in our final (upgrade) list.
+ */
+ /*EVENT(trans, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL);*/
+ for(i = trans->packages; i; i = i->next) {
+ pmsyncpkg_t *sync = i->data;
+ if(sync->type == PM_SYNC_TYPE_REPLACE) {
+ for(j = sync->data; j; j = j->next) {
+ list = pm_list_add(list, j->data);
+ }
+ }
+ }
+
+ _alpm_log(PM_LOG_DEBUG, "checking dependencies of packages designated for removal");
+ deps = checkdeps(db_local, PM_TRANS_TYPE_REMOVE, list);
+ if(deps) {
+ *data = deps;
+ pm_errno = PM_ERR_UNSATISFIED_DEPS;
+ goto error;
+ }
+
+ FREELISTPTR(list);
+ /*EVENT(trans, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL);*/
+ }
return(0);
@@ -596,11 +593,14 @@ int sync_commit(pmtrans_t *trans, pmdb_t *db_local)
tr = trans_new();
if(tr == NULL) {
_alpm_log(PM_LOG_ERROR, "could not create removal transaction");
- pm_errno = PM_ERR_XXX;
+ pm_errno = PM_ERR_MEMORY;
goto error;
}
- trans_init(tr, PM_TRANS_TYPE_REMOVE, PM_TRANS_FLAG_NODEPS, NULL, NULL);
+ if(trans_init(tr, PM_TRANS_TYPE_REMOVE, PM_TRANS_FLAG_NODEPS, NULL, NULL) == -1) {
+ _alpm_log(PM_LOG_ERROR, "could not initialize the removal transaction");
+ goto error;
+ }
for(i = trans->packages; i; i = i->next) {
pmsyncpkg_t *sync = i->data;