Git-Url: http://git.frugalware.org/gitweb/gitweb.cgi?p=pacman-g2.git;a=commitdiff;h=38ddceadb92fbcfed1b982a4b48a58f1195fb593
commit 38ddceadb92fbcfed1b982a4b48a58f1195fb593 Author: Michel Hermier <[email protected]> Date: Wed May 1 16:55:43 2013 +0200 libpacman: Move _pacman_sync_prepare to trans.c diff --git a/lib/libpacman/sync.c b/lib/libpacman/sync.c index 3aa549a..1cc5952 100644 --- a/lib/libpacman/sync.c +++ b/lib/libpacman/sync.c @@ -59,417 +59,6 @@ #include "fstringlist.h" -static int pkg_cmp(const void *p1, const void *p2) -{ - return(strcmp(((pmpkg_t *)p1)->name, ((pmsyncpkg_t *)p2)->pkg_new->name)); -} - -static int check_olddelay(void) -{ - pmlist_t *i; - char lastupdate[16] = ""; - struct tm tm; - - if(!handle->olddelay) { - return(0); - } - - memset(&tm,0,sizeof(struct tm)); - - for(i = handle->dbs_sync; i; i= i->next) { - pmdb_t *db = i->data; - if(_pacman_db_getlastupdate(db, lastupdate) == -1) { - continue; - } - if(strptime(lastupdate, "%Y%m%d%H%M%S", &tm) == NULL) { - continue; - } - if((time(NULL)-mktime(&tm)) > handle->olddelay) { - _pacman_log(PM_LOG_WARNING, _("local copy of '%s' repo is too old"), db->treename); - } - } - return(0); -} - -int _pacman_sync_prepare(pmtrans_t *trans, pmlist_t **data) -{ - pmlist_t *deps = NULL; - pmlist_t *list = NULL; /* list allowing checkdeps usage with data from trans->packages */ - pmlist_t *trail = NULL; /* breadcrum list to avoid running into circles */ - pmlist_t *asked = NULL; - pmlist_t *i, *j, *k, *l, *m; - int ret = 0; - pmdb_t *db_local = trans->handle->db_local; - pmlist_t *dbs_sync = trans->handle->dbs_sync; - - ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); - ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); - - if(data) { - *data = NULL; - } - - for(i = trans->packages; i; i = i->next) { - pmsyncpkg_t *ps = i->data; - list = _pacman_list_add(list, ps->pkg_new); - } - - if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) { - trail = f_list_new(); - - /* Resolve targets dependencies */ - EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_START, NULL, NULL); - _pacman_log(PM_LOG_FLOW1, _("resolving targets dependencies")); - for(i = trans->packages; i; i = i->next) { - pmpkg_t *spkg = ((pmsyncpkg_t *)i->data)->pkg_new; - if(_pacman_resolvedeps(trans, spkg, list, trail, data) == -1) { - /* pm_errno is set by resolvedeps */ - ret = -1; - goto cleanup; - } - } - - for(i = list; i; i = i->next) { - /* add the dependencies found by resolvedeps to the transaction set */ - pmpkg_t *spkg = i->data; - if(!__pacman_trans_get_trans_pkg(trans, spkg->name)) { - pmsyncpkg_t *ps = __pacman_trans_pkg_new(PM_TRANS_TYPE_ADD, spkg); - if(ps == NULL) { - ret = -1; - goto cleanup; - } - trans->packages = _pacman_list_add(trans->packages, ps); - _pacman_log(PM_LOG_FLOW2, _("adding package %s-%s to the transaction targets"), - spkg->name, spkg->version); - } else { - /* remove the original targets from the list if requested */ - if((trans->flags & PM_TRANS_FLAG_DEPENDSONLY)) { - /* they are just pointers so we don't have to free them */ - trans->packages = _pacman_list_remove(trans->packages, spkg, pkg_cmp, NULL); - } - } - } - - /* re-order w.r.t. dependencies */ - k = l = NULL; - for(i=trans->packages; i; i=i->next) { - pmsyncpkg_t *s = (pmsyncpkg_t*)i->data; - k = _pacman_list_add(k, s->pkg_new); - } - m = _pacman_sortbydeps(k, PM_TRANS_TYPE_ADD); - for(i=m; i; i=i->next) { - for(j=trans->packages; j; j=j->next) { - pmsyncpkg_t *s = (pmsyncpkg_t*)j->data; - if(s->pkg_new==i->data) { - l = _pacman_list_add(l, s); - } - } - } - FREELISTPTR(k); - FREELISTPTR(m); - FREELISTPTR(trans->packages); - trans->packages = l; - - EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_DONE, NULL, NULL); - - _pacman_log(PM_LOG_FLOW1, _("looking for unresolvable dependencies")); - deps = _pacman_checkdeps(trans, PM_TRANS_TYPE_UPGRADE, list); - if(deps) { - if(data) { - *data = deps; - deps = NULL; - } - pm_errno = PM_ERR_UNSATISFIED_DEPS; - ret = -1; - goto cleanup; - } - - FREELISTPTR(trail); - } - - if(!(trans->flags & PM_TRANS_FLAG_NOCONFLICTS)) { - /* check for inter-conflicts and whatnot */ - EVENT(trans, PM_TRANS_EVT_INTERCONFLICTS_START, NULL, NULL); - - _pacman_log(PM_LOG_FLOW1, _("looking for conflicts")); - deps = _pacman_checkconflicts(trans, list); - if(deps) { - int errorout = 0; - - for(i = deps; i && !errorout; i = i->next) { - pmdepmissing_t *miss = i->data; - int found = 0; - pmsyncpkg_t *ps; - pmpkg_t *local; - - _pacman_log(PM_LOG_FLOW2, _("package '%s' is conflicting with '%s'"), - miss->target, miss->depend.name); - - /* check if the conflicting package is one that's about to be removed/replaced. - * if so, then just ignore it - */ - for(j = trans->packages; j && !found; j = j->next) { - ps = j->data; - if(_pacman_pkg_isin(miss->depend.name, ps->replaces)) { - found = 1; - } - } - if(found) { - _pacman_log(PM_LOG_DEBUG, _("'%s' is already elected for removal -- skipping"), - miss->depend.name); - continue; - } - - ps = __pacman_trans_get_trans_pkg(trans, miss->target); - if(ps == NULL) { - _pacman_log(PM_LOG_DEBUG, _("'%s' not found in transaction set -- skipping"), - miss->target); - continue; - } - local = _pacman_db_get_pkgfromcache(db_local, miss->depend.name); - /* check if this package also "provides" the package it's conflicting with - */ - if(f_stringlist_find (ps->pkg_new->provides, miss->depend.name)) { - /* so just treat it like a "replaces" item so the REQUIREDBY - * fields are inherited properly. - */ - _pacman_log(PM_LOG_DEBUG, _("package '%s' provides its own conflict"), miss->target); - if(local) { - /* nothing to do for now: it will be handled later - * (not the same behavior as in pacman) */ - } else { - char *rmpkg = NULL; - int target, depend; - /* hmmm, depend.name isn't installed, so it must be conflicting - * with another package in our final list. For example: - * - * pacman-g2 -S blackbox xfree86 - * - * If no x-servers are installed and blackbox pulls in xorg, then - * xorg and xfree86 will conflict with each other. In this case, - * we should follow the user's preference and rip xorg out of final, - * opting for xfree86 instead. - */ - - /* figure out which one was requested in targets. If they both were, - * then it's still an unresolvable conflict. */ - target = f_stringlist_find (trans->targets, miss->target); - depend = f_stringlist_find (trans->targets, miss->depend.name); - if(depend && !target) { - _pacman_log(PM_LOG_DEBUG, _("'%s' is in the target list -- keeping it"), - miss->depend.name); - /* remove miss->target */ - rmpkg = miss->target; - } else if(target && !depend) { - _pacman_log(PM_LOG_DEBUG, _("'%s' is in the target list -- keeping it"), - miss->target); - /* remove miss->depend.name */ - rmpkg = miss->depend.name; - } else { - /* miss->depend.name is not needed, miss->target already provides - * it, let's resolve the conflict */ - rmpkg = miss->depend.name; - } - if(rmpkg) { - pmsyncpkg_t *rsync = __pacman_trans_get_trans_pkg(trans, rmpkg); - pmsyncpkg_t *spkg = NULL; - _pacman_log(PM_LOG_FLOW2, _("removing '%s' from target list"), rmpkg); - trans->packages = _pacman_list_remove(trans->packages, rsync, __pacman_transpkg_cmp, (void **)&spkg); - __pacman_trans_pkg_delete (spkg); - spkg = NULL; - continue; - } - } - } - /* It's a conflict -- see if they want to remove it - */ - _pacman_log(PM_LOG_DEBUG, _("resolving package '%s' conflict"), miss->target); - if(local) { - int doremove = 0; - if(!f_stringlist_find (asked, miss->depend.name)) { - QUESTION(trans, PM_TRANS_CONV_CONFLICT_PKG, miss->target, miss->depend.name, NULL, &doremove); - asked = f_stringlist_append (asked, miss->depend.name); - if(doremove) { - pmsyncpkg_t *rsync = __pacman_trans_get_trans_pkg(trans, miss->depend.name); - pmpkg_t *q = _pacman_pkg_new(miss->depend.name, NULL); - if(q == NULL) { - if(data) { - FREELIST(*data); - } - ret = -1; - goto cleanup; - } - q->requiredby = f_stringlist_deep_copy(local->requiredby); - if(ps->type != PM_TRANS_TYPE_ADD) { - /* switch this sync type to REPLACE */ - ps->type = PM_TRANS_TYPE_ADD; - //FREEPKG(ps->data); - } - /* append to the replaces list */ - _pacman_log(PM_LOG_FLOW2, _("electing '%s' for removal"), miss->depend.name); - ps->replaces = _pacman_list_add(ps->replaces, q); - if(rsync) { - /* remove it from the target list */ - pmsyncpkg_t *spkg = NULL; - _pacman_log(PM_LOG_FLOW2, _("removing '%s' from target list"), miss->depend.name); - trans->packages = _pacman_list_remove(trans->packages, rsync, __pacman_transpkg_cmp, (void **)&spkg); - __pacman_trans_pkg_delete (spkg); - spkg = NULL; - } - } else { - /* abort */ - _pacman_log(PM_LOG_ERROR, _("unresolvable package conflicts detected")); - errorout = 1; - if(data) { - if((miss = _pacman_malloc(sizeof(pmdepmissing_t))) == NULL) { - FREELIST(*data); - ret = -1; - goto cleanup; - } - *miss = *(pmdepmissing_t *)i->data; - *data = _pacman_list_add(*data, miss); - } - } - } - } else { - _pacman_log(PM_LOG_ERROR, _("unresolvable package conflicts detected")); - errorout = 1; - if(data) { - if((miss = _pacman_malloc(sizeof(pmdepmissing_t))) == NULL) { - FREELIST(*data); - ret = -1; - goto cleanup; - } - *miss = *(pmdepmissing_t *)i->data; - *data = _pacman_list_add(*data, miss); - } - } - } - if(errorout) { - pm_errno = PM_ERR_CONFLICTING_DEPS; - ret = -1; - goto cleanup; - } - FREELIST(deps); - FREELIST(asked); - } - EVENT(trans, PM_TRANS_EVT_INTERCONFLICTS_DONE, NULL, NULL); - } - - FREELISTPTR(list); - - /* 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... - */ - - if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) { - /* 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 *ps = i->data; - for(j = ps->replaces; j; j = j->next) { - list = _pacman_list_add(list, j->data); - } - } - if(list) { - _pacman_log(PM_LOG_FLOW1, _("checking dependencies of packages designated for removal")); - deps = _pacman_checkdeps(trans, PM_TRANS_TYPE_REMOVE, list); - if(deps) { - int errorout = 0; - for(i = deps; i; i = i->next) { - pmdepmissing_t *miss = i->data; - if(!__pacman_trans_get_trans_pkg(trans, miss->depend.name)) { - int pfound = 0; - /* If miss->depend.name depends on something that miss->target and a - * package in final both provide, then it's okay... */ - pmpkg_t *leavingp = _pacman_db_get_pkgfromcache(db_local, miss->target); - pmpkg_t *conflictp = _pacman_db_get_pkgfromcache(db_local, miss->depend.name); - if(!leavingp || !conflictp) { - _pacman_log(PM_LOG_ERROR, _("something has gone horribly wrong")); - ret = -1; - goto cleanup; - } - /* Look through the upset package's dependencies and try to match one up - * to a provisio from the package we want to remove */ - for(k = conflictp->depends; k && !pfound; k = k->next) { - pmlist_t *m; - for(m = leavingp->provides; m && !pfound; m = m->next) { - if(!strcmp(k->data, m->data)) { - /* Found a match -- now look through final for a package that - * provides the same thing. If none are found, then it truly - * is an unresolvable conflict. */ - pmlist_t *n, *o; - for(n = trans->packages; n && !pfound; n = n->next) { - pmsyncpkg_t *sp = n->data; - for(o = sp->pkg_new->provides; o && !pfound; o = o->next) { - if(!strcmp(m->data, o->data)) { - /* found matching provisio -- we're good to go */ - _pacman_log(PM_LOG_FLOW2, _("found '%s' as a provision for '%s' -- conflict aborted"), - sp->pkg_new->name, (char *)o->data); - pfound = 1; - } - } - } - } - } - } - if(!pfound) { - if(!errorout) { - errorout = 1; - } - if(data) { - if((miss = _pacman_malloc(sizeof(pmdepmissing_t))) == NULL) { - FREELIST(*data); - ret = -1; - goto cleanup; - } - *miss = *(pmdepmissing_t *)i->data; - *data = _pacman_list_add(*data, miss); - } - } - } - } - if(errorout) { - pm_errno = PM_ERR_UNSATISFIED_DEPS; - ret = -1; - goto cleanup; - } - FREELIST(deps); - } - } - /*EVENT(trans, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL);*/ - } - -#ifndef __sun__ - /* check for free space only in case the packages will be extracted */ - if(!(trans->flags & PM_TRANS_FLAG_NOCONFLICTS)) { - if(_pacman_check_freespace(trans, data) == -1) { - /* pm_errno is set by check_freespace */ - ret = -1; - goto cleanup; - } - } -#endif - - /* issue warning if the local db is too old */ - check_olddelay(); - -cleanup: - FREELISTPTR(list); - FREELISTPTR(trail); - FREELIST(asked); - - return(ret); -} - int _pacman_sync_commit(pmtrans_t *trans, pmlist_t **data) { pmlist_t *i, *j; @@ -806,7 +395,6 @@ error: } const pmtrans_ops_t _pacman_sync_pmtrans_opts = { - .prepare = _pacman_sync_prepare, .commit = _pacman_trans_download_commit }; diff --git a/lib/libpacman/trans.c b/lib/libpacman/trans.c index 12d9aac..2cc6032 100644 --- a/lib/libpacman/trans.c +++ b/lib/libpacman/trans.c @@ -511,6 +511,420 @@ int _pacman_trans_set_state(pmtrans_t *trans, int new_state) return(0); } +static +int pkg_cmp(const void *p1, const void *p2) +{ + return(strcmp(((pmpkg_t *)p1)->name, ((pmsyncpkg_t *)p2)->pkg_new->name)); +} + +static +int check_olddelay(void) +{ + pmlist_t *i; + char lastupdate[16] = ""; + struct tm tm; + + if(!handle->olddelay) { + return(0); + } + + memset(&tm,0,sizeof(struct tm)); + + for(i = handle->dbs_sync; i; i= i->next) { + pmdb_t *db = i->data; + if(_pacman_db_getlastupdate(db, lastupdate) == -1) { + continue; + } + if(strptime(lastupdate, "%Y%m%d%H%M%S", &tm) == NULL) { + continue; + } + if((time(NULL)-mktime(&tm)) > handle->olddelay) { + _pacman_log(PM_LOG_WARNING, _("local copy of '%s' repo is too old"), db->treename); + } + } + return(0); +} + +static +int _pacman_sync_prepare (pmtrans_t *trans, pmlist_t **data) +{ + pmlist_t *deps = NULL; + pmlist_t *list = NULL; /* list allowing checkdeps usage with data from trans->packages */ + pmlist_t *trail = NULL; /* breadcrum list to avoid running into circles */ + pmlist_t *asked = NULL; + pmlist_t *i, *j, *k, *l, *m; + int ret = 0; + pmdb_t *db_local = trans->handle->db_local; + pmlist_t *dbs_sync = trans->handle->dbs_sync; + + ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); + ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); + + if(data) { + *data = NULL; + } + + for(i = trans->packages; i; i = i->next) { + pmsyncpkg_t *ps = i->data; + list = _pacman_list_add(list, ps->pkg_new); + } + + if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) { + trail = f_list_new(); + + /* Resolve targets dependencies */ + EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_START, NULL, NULL); + _pacman_log(PM_LOG_FLOW1, _("resolving targets dependencies")); + for(i = trans->packages; i; i = i->next) { + pmpkg_t *spkg = ((pmsyncpkg_t *)i->data)->pkg_new; + if(_pacman_resolvedeps(trans, spkg, list, trail, data) == -1) { + /* pm_errno is set by resolvedeps */ + ret = -1; + goto cleanup; + } + } + + for(i = list; i; i = i->next) { + /* add the dependencies found by resolvedeps to the transaction set */ + pmpkg_t *spkg = i->data; + if(!__pacman_trans_get_trans_pkg(trans, spkg->name)) { + pmsyncpkg_t *ps = __pacman_trans_pkg_new(PM_TRANS_TYPE_ADD, spkg); + if(ps == NULL) { + ret = -1; + goto cleanup; + } + trans->packages = _pacman_list_add(trans->packages, ps); + _pacman_log(PM_LOG_FLOW2, _("adding package %s-%s to the transaction targets"), + spkg->name, spkg->version); + } else { + /* remove the original targets from the list if requested */ + if((trans->flags & PM_TRANS_FLAG_DEPENDSONLY)) { + /* they are just pointers so we don't have to free them */ + trans->packages = _pacman_list_remove(trans->packages, spkg, pkg_cmp, NULL); + } + } + } + + /* re-order w.r.t. dependencies */ + k = l = NULL; + for(i=trans->packages; i; i=i->next) { + pmsyncpkg_t *s = (pmsyncpkg_t*)i->data; + k = _pacman_list_add(k, s->pkg_new); + } + m = _pacman_sortbydeps(k, PM_TRANS_TYPE_ADD); + for(i=m; i; i=i->next) { + for(j=trans->packages; j; j=j->next) { + pmsyncpkg_t *s = (pmsyncpkg_t*)j->data; + if(s->pkg_new==i->data) { + l = _pacman_list_add(l, s); + } + } + } + FREELISTPTR(k); + FREELISTPTR(m); + FREELISTPTR(trans->packages); + trans->packages = l; + + EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_DONE, NULL, NULL); + + _pacman_log(PM_LOG_FLOW1, _("looking for unresolvable dependencies")); + deps = _pacman_checkdeps(trans, PM_TRANS_TYPE_UPGRADE, list); + if(deps) { + if(data) { + *data = deps; + deps = NULL; + } + pm_errno = PM_ERR_UNSATISFIED_DEPS; + ret = -1; + goto cleanup; + } + + FREELISTPTR(trail); + } + + if(!(trans->flags & PM_TRANS_FLAG_NOCONFLICTS)) { + /* check for inter-conflicts and whatnot */ + EVENT(trans, PM_TRANS_EVT_INTERCONFLICTS_START, NULL, NULL); + + _pacman_log(PM_LOG_FLOW1, _("looking for conflicts")); + deps = _pacman_checkconflicts(trans, list); + if(deps) { + int errorout = 0; + + for(i = deps; i && !errorout; i = i->next) { + pmdepmissing_t *miss = i->data; + int found = 0; + pmsyncpkg_t *ps; + pmpkg_t *local; + + _pacman_log(PM_LOG_FLOW2, _("package '%s' is conflicting with '%s'"), + miss->target, miss->depend.name); + + /* check if the conflicting package is one that's about to be removed/replaced. + * if so, then just ignore it + */ + for(j = trans->packages; j && !found; j = j->next) { + ps = j->data; + if(_pacman_pkg_isin(miss->depend.name, ps->replaces)) { + found = 1; + } + } + if(found) { + _pacman_log(PM_LOG_DEBUG, _("'%s' is already elected for removal -- skipping"), + miss->depend.name); + continue; + } + + ps = __pacman_trans_get_trans_pkg(trans, miss->target); + if(ps == NULL) { + _pacman_log(PM_LOG_DEBUG, _("'%s' not found in transaction set -- skipping"), + miss->target); + continue; + } + local = _pacman_db_get_pkgfromcache(db_local, miss->depend.name); + /* check if this package also "provides" the package it's conflicting with + */ + if(f_stringlist_find (ps->pkg_new->provides, miss->depend.name)) { + /* so just treat it like a "replaces" item so the REQUIREDBY + * fields are inherited properly. + */ + _pacman_log(PM_LOG_DEBUG, _("package '%s' provides its own conflict"), miss->target); + if(local) { + /* nothing to do for now: it will be handled later + * (not the same behavior as in pacman) */ + } else { + char *rmpkg = NULL; + int target, depend; + /* hmmm, depend.name isn't installed, so it must be conflicting + * with another package in our final list. For example: + * + * pacman-g2 -S blackbox xfree86 + * + * If no x-servers are installed and blackbox pulls in xorg, then + * xorg and xfree86 will conflict with each other. In this case, + * we should follow the user's preference and rip xorg out of final, + * opting for xfree86 instead. + */ + + /* figure out which one was requested in targets. If they both were, + * then it's still an unresolvable conflict. */ + target = f_stringlist_find (trans->targets, miss->target); + depend = f_stringlist_find (trans->targets, miss->depend.name); + if(depend && !target) { + _pacman_log(PM_LOG_DEBUG, _("'%s' is in the target list -- keeping it"), + miss->depend.name); + /* remove miss->target */ + rmpkg = miss->target; + } else if(target && !depend) { + _pacman_log(PM_LOG_DEBUG, _("'%s' is in the target list -- keeping it"), + miss->target); + /* remove miss->depend.name */ + rmpkg = miss->depend.name; + } else { + /* miss->depend.name is not needed, miss->target already provides + * it, let's resolve the conflict */ + rmpkg = miss->depend.name; + } + if(rmpkg) { + pmsyncpkg_t *rsync = __pacman_trans_get_trans_pkg(trans, rmpkg); + pmsyncpkg_t *spkg = NULL; + _pacman_log(PM_LOG_FLOW2, _("removing '%s' from target list"), rmpkg); + trans->packages = _pacman_list_remove(trans->packages, rsync, __pacman_transpkg_cmp, (void **)&spkg); + __pacman_trans_pkg_delete (spkg); + spkg = NULL; + continue; + } + } + } + /* It's a conflict -- see if they want to remove it + */ + _pacman_log(PM_LOG_DEBUG, _("resolving package '%s' conflict"), miss->target); + if(local) { + int doremove = 0; + if(!f_stringlist_find (asked, miss->depend.name)) { + QUESTION(trans, PM_TRANS_CONV_CONFLICT_PKG, miss->target, miss->depend.name, NULL, &doremove); + asked = f_stringlist_append (asked, miss->depend.name); + if(doremove) { + pmsyncpkg_t *rsync = __pacman_trans_get_trans_pkg(trans, miss->depend.name); + pmpkg_t *q = _pacman_pkg_new(miss->depend.name, NULL); + if(q == NULL) { + if(data) { + FREELIST(*data); + } + ret = -1; + goto cleanup; + } + q->requiredby = f_stringlist_deep_copy(local->requiredby); + if(ps->type != PM_TRANS_TYPE_ADD) { + /* switch this sync type to REPLACE */ + ps->type = PM_TRANS_TYPE_ADD; + //FREEPKG(ps->data); + } + /* append to the replaces list */ + _pacman_log(PM_LOG_FLOW2, _("electing '%s' for removal"), miss->depend.name); + ps->replaces = _pacman_list_add(ps->replaces, q); + if(rsync) { + /* remove it from the target list */ + pmsyncpkg_t *spkg = NULL; + _pacman_log(PM_LOG_FLOW2, _("removing '%s' from target list"), miss->depend.name); + trans->packages = _pacman_list_remove(trans->packages, rsync, __pacman_transpkg_cmp, (void **)&spkg); + __pacman_trans_pkg_delete (spkg); + spkg = NULL; + } + } else { + /* abort */ + _pacman_log(PM_LOG_ERROR, _("unresolvable package conflicts detected")); + errorout = 1; + if(data) { + if((miss = _pacman_malloc(sizeof(pmdepmissing_t))) == NULL) { + FREELIST(*data); + ret = -1; + goto cleanup; + } + *miss = *(pmdepmissing_t *)i->data; + *data = _pacman_list_add(*data, miss); + } + } + } + } else { + _pacman_log(PM_LOG_ERROR, _("unresolvable package conflicts detected")); + errorout = 1; + if(data) { + if((miss = _pacman_malloc(sizeof(pmdepmissing_t))) == NULL) { + FREELIST(*data); + ret = -1; + goto cleanup; + } + *miss = *(pmdepmissing_t *)i->data; + *data = _pacman_list_add(*data, miss); + } + } + } + if(errorout) { + pm_errno = PM_ERR_CONFLICTING_DEPS; + ret = -1; + goto cleanup; + } + FREELIST(deps); + FREELIST(asked); + } + EVENT(trans, PM_TRANS_EVT_INTERCONFLICTS_DONE, NULL, NULL); + } + + FREELISTPTR(list); + + /* 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... + */ + + if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) { + /* 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 *ps = i->data; + for(j = ps->replaces; j; j = j->next) { + list = _pacman_list_add(list, j->data); + } + } + if(list) { + _pacman_log(PM_LOG_FLOW1, _("checking dependencies of packages designated for removal")); + deps = _pacman_checkdeps(trans, PM_TRANS_TYPE_REMOVE, list); + if(deps) { + int errorout = 0; + for(i = deps; i; i = i->next) { + pmdepmissing_t *miss = i->data; + if(!__pacman_trans_get_trans_pkg(trans, miss->depend.name)) { + int pfound = 0; + /* If miss->depend.name depends on something that miss->target and a + * package in final both provide, then it's okay... */ + pmpkg_t *leavingp = _pacman_db_get_pkgfromcache(db_local, miss->target); + pmpkg_t *conflictp = _pacman_db_get_pkgfromcache(db_local, miss->depend.name); + if(!leavingp || !conflictp) { + _pacman_log(PM_LOG_ERROR, _("something has gone horribly wrong")); + ret = -1; + goto cleanup; + } + /* Look through the upset package's dependencies and try to match one up + * to a provisio from the package we want to remove */ + for(k = conflictp->depends; k && !pfound; k = k->next) { + pmlist_t *m; + for(m = leavingp->provides; m && !pfound; m = m->next) { + if(!strcmp(k->data, m->data)) { + /* Found a match -- now look through final for a package that + * provides the same thing. If none are found, then it truly + * is an unresolvable conflict. */ + pmlist_t *n, *o; + for(n = trans->packages; n && !pfound; n = n->next) { + pmsyncpkg_t *sp = n->data; + for(o = sp->pkg_new->provides; o && !pfound; o = o->next) { + if(!strcmp(m->data, o->data)) { + /* found matching provisio -- we're good to go */ + _pacman_log(PM_LOG_FLOW2, _("found '%s' as a provision for '%s' -- conflict aborted"), + sp->pkg_new->name, (char *)o->data); + pfound = 1; + } + } + } + } + } + } + if(!pfound) { + if(!errorout) { + errorout = 1; + } + if(data) { + if((miss = _pacman_malloc(sizeof(pmdepmissing_t))) == NULL) { + FREELIST(*data); + ret = -1; + goto cleanup; + } + *miss = *(pmdepmissing_t *)i->data; + *data = _pacman_list_add(*data, miss); + } + } + } + } + if(errorout) { + pm_errno = PM_ERR_UNSATISFIED_DEPS; + ret = -1; + goto cleanup; + } + FREELIST(deps); + } + } + /*EVENT(trans, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL);*/ + } + +#ifndef __sun__ + /* check for free space only in case the packages will be extracted */ + if(!(trans->flags & PM_TRANS_FLAG_NOCONFLICTS)) { + if(_pacman_check_freespace(trans, data) == -1) { + /* pm_errno is set by check_freespace */ + ret = -1; + goto cleanup; + } + } +#endif + + /* issue warning if the local db is too old */ + check_olddelay(); + +cleanup: + FREELISTPTR(list); + FREELISTPTR(trail); + FREELIST(asked); + + return(ret); +} + int _pacman_trans_prepare(pmtrans_t *trans, pmlist_t **data) { pmdb_t *db_local; @@ -529,8 +943,8 @@ int _pacman_trans_prepare(pmtrans_t *trans, pmlist_t **data) return(0); } - if(trans->ops != NULL && trans->ops->prepare != NULL) { - if(trans->ops->prepare(trans, data) == -1) { + if(trans->type == PM_TRANS_TYPE_SYNC) { + if(_pacman_sync_prepare (trans, data) == -1) { /* pm_errno is set by trans->ops->prepare() */ return(-1); } _______________________________________________ Frugalware-git mailing list [email protected] http://frugalware.org/mailman/listinfo/frugalware-git
