From 7858f4c9b4d4c4a478f27952c0beb34b58d0679f Mon Sep 17 00:00:00 2001 From: Aurelien Foret Date: Thu, 5 Jan 2006 20:53:41 +0000 Subject: - fix for sync conflicts (patch from VMiklos ) - sync code cleanup - added the deps check for targets to be removed in sync_prepare() --- lib/libalpm/sync.c | 96 +++++++++++++++++++++++++++--------------------------- 1 file changed, 48 insertions(+), 48 deletions(-) (limited to 'lib/libalpm/sync.c') 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; -- cgit v1.2.3-54-g00ecf