From 4fcec8f03ff790bfb23b826eee169bc9c0b00142 Mon Sep 17 00:00:00 2001 From: Aurelien Foret Date: Wed, 20 Apr 2005 20:50:49 +0000 Subject: first steps to support REPLACES feature --- lib/libalpm/sync.c | 158 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 111 insertions(+), 47 deletions(-) diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index 4df11eae..10f77ef4 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -56,12 +56,7 @@ pmsyncpkg_t *sync_new(int type, pmpkg_t *spkg, void *data) sync->type = type; sync->pkg = spkg; - - if(sync->type == PM_SYNC_TYPE_REPLACE) { - sync->data = pm_list_add(NULL, data); - } else { - sync->data = data; - } + sync->data = data; return(sync); } @@ -152,15 +147,36 @@ int sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync) if(pm_list_is_strin(lpkg->name, handle->ignorepkg)) { _alpm_log(PM_LOG_WARNING, "%s-%s: ignoring package upgrade (to be replaced by %s-%s)", lpkg->name, lpkg->version, spkg->name, spkg->version); - } else { - pmsyncpkg_t *sync = sync_new(PM_SYNC_TYPE_REPLACE, spkg, lpkg); - if(sync == NULL) { + } else /* ORE if(yesno(":: Replace %s with %s from \"%s\"? [Y/n] ", lpkg->name, spkg->name, ((pmdb_t *)i->data)->treename)) */ { + /* if confirmed, add this to the 'final' list, designating 'lpkg' as + * the package to replace. + */ + pmsyncpkg_t *sync; + pmpkg_t *dummy = pkg_new(); + if(dummy == NULL) { pm_errno = PM_ERR_MEMORY; goto error; } + STRNCPY(dummy->name, lpkg->name, PKG_NAME_LEN); + dummy->requiredby = _alpm_list_strdup(lpkg->requiredby); + /* check if spkg->name is already in the packages list. */ + sync = find_pkginsync(spkg->name, trans->packages); + if(sync) { + /* found it -- just append to the replaces list */ + sync->data = pm_list_add(sync->data, dummy); + } else { + /* none found -- enter pkg into the final sync list */ + sync = sync_new(PM_SYNC_TYPE_REPLACE, spkg, NULL); + if(sync == NULL) { + FREEPKG(dummy); + pm_errno = PM_ERR_MEMORY; + goto error; + } + sync->data = pm_list_add(sync->data, dummy); + trans->packages = pm_list_add(trans->packages, sync); + } _alpm_log(PM_LOG_DEBUG, "%s-%s elected for upgrade (to be replaced by %s-%s)", lpkg->name, lpkg->version, spkg->name, spkg->version); - trans->packages = pm_list_add(trans->packages, sync); } } } @@ -184,7 +200,7 @@ int sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync) } } if(spkg == NULL) { - /*fprintf(stderr, "%s: not found in sync db. skipping.", local->name);*/ + /*_alpm_logf(PM_LOG_ERROR, "%s: not found in sync db -- skipping.", local->name);*/ continue; } @@ -201,8 +217,12 @@ int sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync) _alpm_log(PM_LOG_FLOW1, "%s-%s: ignoring package upgrade (%s)", local->name, local->version, spkg->version); } else { - sync = sync_new(PM_SYNC_TYPE_UPGRADE, spkg, local); + pmpkg_t *dummy = pkg_new(); + STRNCPY(dummy->name, local->name, PKG_NAME_LEN); + STRNCPY(dummy->version, local->version, PKG_VERSION_LEN); + sync = sync_new(PM_SYNC_TYPE_UPGRADE, spkg, dummy); if(sync == NULL) { + FREEPKG(dummy); pm_errno = PM_ERR_MEMORY; goto error; } @@ -279,8 +299,18 @@ int sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, char *n /* add the package to the transaction */ if(!find_pkginsync(spkg->name, trans->packages)) { - sync = sync_new(PM_SYNC_TYPE_UPGRADE, spkg, local); + pmpkg_t *dummy = NULL; + if(local) { + dummy = pkg_new(); + if(dummy == NULL) { + RET_ERR(PM_ERR_MEMORY, -1); + } + STRNCPY(dummy->name, local->name, PKG_NAME_LEN); + STRNCPY(dummy->version, local->version, PKG_VERSION_LEN); + } + sync = sync_new(PM_SYNC_TYPE_UPGRADE, spkg, dummy); if(sync == NULL) { + FREEPKG(dummy); RET_ERR(PM_ERR_MEMORY, -1); } trans->packages = pm_list_add(trans->packages, sync); @@ -302,10 +332,6 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList ** *data = NULL; - if(trans->packages == NULL) { - return(0); - } - if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) { for(i = trans->packages; i; i = i->next) { pmsyncpkg_t *sync = i->data; @@ -342,6 +368,8 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList ** TRANS_CB(trans, PM_TRANS_EVT_INTERCONFLICTS_START, NULL, NULL); deps = checkdeps(db_local, PM_TRANS_TYPE_UPGRADE, list); if(deps) { + int found; + PMList *j, *k, *exfinal = NULL; int errorout = 0; _alpm_log(PM_LOG_FLOW1, "looking for unresolvable dependencies"); for(i = deps; i; i = i->next) { @@ -363,17 +391,40 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList ** FREELIST(deps); RET_ERR(PM_ERR_UNSATISFIED_DEPS, -1); } + /* no unresolvable deps, so look for conflicts */ - _alpm_log(PM_LOG_FLOW1, "looking for conflicts"); errorout = 0; + _alpm_log(PM_LOG_FLOW1, "looking for conflicts"); + for(i = deps; i && !errorout; i = i->next) { + pmdepmissing_t *miss = i->data; + if(miss->type != PM_DEP_TYPE_CONFLICT) { + continue; + } + /* make sure this package wasn't already removed from the final list */ + if(pm_list_is_ptrin(miss->target, exfinal)) { + continue; + } - /* ORE - * check if the conflicting package is one that's about to be removed/replaced. - * if so, then just ignore it - */ + /* check if the conflicting package is one that's about to be removed/replaced. + * if so, then just ignore it + */ + found = 0; + for(j = trans->packages; j && !found; j = j->next) { + pmsyncpkg_t *sync = j->data; + if(sync->type != PM_SYNC_TYPE_REPLACE) { + continue; + } + for(k = sync->data; k && !found; k = k->next) { + pmpkg_t *p = k->data; + if(!strcmp(p->name, miss->depend.name)) { + found = 1; + } + } + } - /* ORE - if we didn't find it in any sync->replaces lists, then it's a conflict */ + /* ORE + if we didn't find it in any sync->replaces lists, then it's a conflict */ + } if(errorout) { FREELIST(deps); @@ -420,34 +471,43 @@ int sync_commit(pmtrans_t *trans, pmdb_t *db_local) PMList *i; PMList *data; pmtrans_t *tr; - char ldir[PATH_MAX]; ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); - snprintf(ldir, PATH_MAX, "%s" PM_CACHEDIR, handle->root); - /* remove any conflicting packages (WITHOUT dep checks) */ /* ORE - alpm does not handle removal of conflicting pkgs for now */ /* remove to-be-replaced packages */ - _alpm_log(PM_LOG_FLOW1, "removing to-be-replaced packages"); tr = trans_new(PM_TRANS_TYPE_REMOVE, PM_TRANS_FLAG_NODEPS); /* ORE */ if(tr == NULL) { + _alpm_log(PM_LOG_ERROR, "could not create transaction"); + pm_errno = PM_ERR_XXX; goto error; } - /*for(i = trans->packages; i; i = i->next) { + for(i = trans->packages; i; i = i->next) { pmsyncpkg_t *sync = i->data; if(sync->type == PM_SYNC_TYPE_REPLACE) { - pmpkg_t *pkg = sync->lpkg; + pmpkg_t *pkg = sync->pkg; if(trans_addtarget(tr, pkg->name)) { goto error; } } } - trans_prepare(tr, &data); - trans_commit(tr);*/ + if(tr->packages) { + _alpm_log(PM_LOG_FLOW1, "removing to-be-replaced packages"); + if(trans_prepare(tr, &data) == -1) { + _alpm_log(PM_LOG_ERROR, "could not prepare transaction"); + pm_errno = PM_ERR_XXX; + goto error; + } + if(trans_commit(tr) == -1) { + _alpm_log(PM_LOG_ERROR, "could not commit transaction"); + pm_errno = PM_ERR_XXX; + goto error; + } + } trans_free(tr); /* install targets */ @@ -468,7 +528,7 @@ int sync_commit(pmtrans_t *trans, pmdb_t *db_local) if(sync->type != PM_SYNC_TYPE_REPLACE) { pmpkg_t *spkg = sync->pkg; char str[PATH_MAX]; - snprintf(str, PATH_MAX, "%s/%s-%s" PM_EXT_PKG, ldir, spkg->name, spkg->version); + snprintf(str, PATH_MAX, "%s" PM_CACHEDIR "/%s-%s" PM_EXT_PKG, handle->root, spkg->name, spkg->version); if(trans_addtarget(tr, str) == -1) { goto error; } @@ -487,36 +547,40 @@ int sync_commit(pmtrans_t *trans, pmdb_t *db_local) trans_free(tr); /* propagate replaced packages' requiredby fields to their new owners */ + /* ORE + won't work because if replaced packages are already removed, the sync(REPLACES) + structures data field will point to unexisting data... */ _alpm_log(PM_LOG_FLOW1, "updating database for replaced packages dependencies"); for(i = trans->packages; i; i = i->next) { - /*pmsyncpkg_t *sync = i->data; - if(sync->replaces) { + pmsyncpkg_t *sync = i->data; + if(sync->type == PM_SYNC_TYPE_REPLACE && sync->data) { PMList *j; - pkginfo_t *new = db_get_pkgfromcache(db_local, sync->pkg->name); - for(j = sync->replaces; j; j = j->next) { - pkginfo_t *old = j->data; - // merge lists + pmpkg_t *new = db_get_pkgfromcache(db_local, sync->pkg->name); + for(j = sync->data; j; j = j->next) { + PMList *k; + pmpkg_t *old = j->data; + /* merge lists */ for(k = old->requiredby; k; k = k->next) { - if(!list_is_strin(k->data, new->requiredby)) { - // replace old's name with new's name in the requiredby's dependency list + if(!pm_list_is_strin(k->data, new->requiredby)) { + /* replace old's name with new's name in the requiredby's dependency list */ PMList *m; - pkginfo_t *depender = db_get_pkgfromcache(db_local, k->data); + pmpkg_t *depender = db_get_pkgfromcache(db_local, k->data); for(m = depender->depends; m; m = m->next) { if(!strcmp(m->data, old->name)) { FREE(m->data); m->data = strdup(new->name); } } - db_write(db, depender, INFRQ_DEPENDS); + db_write(db_local, depender, INFRQ_DEPENDS); - // add the new requiredby - new->requiredby = list_add(new->requiredby, strdup(k->data)); + /* add the new requiredby */ + new->requiredby = pm_list_add(new->requiredby, strdup(k->data)); } } } - db_write(db, new, INFRQ_DEPENDS); + db_write(db_local, new, INFRQ_DEPENDS); FREEPKG(new); - }*/ + } } /* cache needs to be rebuilt */ -- cgit v1.2.3-70-g09d2