Git-Url: 
http://git.frugalware.org/gitweb/gitweb.cgi?p=pacman-g2.git;a=commitdiff;h=88739f90bae097f0de0702be341ab3264d40fabf

commit 88739f90bae097f0de0702be341ab3264d40fabf
Author: Michel Hermier <[email protected]>
Date:   Mon May 12 08:16:44 2014 +0200

libpacman: Merge all _pacman_*_prepare in __pmtrans_t::prepare.

diff --git a/lib/libpacman/trans.cpp b/lib/libpacman/trans.cpp
index c206dcd..e18f0a0 100644
--- a/lib/libpacman/trans.cpp
+++ b/lib/libpacman/trans.cpp
@@ -374,389 +374,6 @@ static int check_olddelay(void)
}

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;
-       Database *db_local = trans->handle->db_local;
-
-       ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
-       ASSERT(trans->packages == NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
-
-       if(data) {
-               *data = NULL;
-       }
-
-       for(i = trans->syncpkgs; i; i = i->next) {
-               pmsyncpkg_t *ps = i->data;
-               list = _pacman_list_add(list, ps->pkg);
-       }
-
-       if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) {
-               trail = _pacman_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->syncpkgs; i; i = i->next) {
-                       Package *spkg = ((pmsyncpkg_t *)i->data)->pkg;
-                       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 */
-                       Package *spkg = i->data;
-                       if(!trans->find(spkg->name())) {
-                               pmsyncpkg_t *ps = new 
__pmsyncpkg_t(PM_SYNC_TYPE_DEPEND, spkg, NULL);
-                               if(ps == NULL) {
-                                       ret = -1;
-                                       goto cleanup;
-                               }
-                               trans->syncpkgs = 
_pacman_list_add(trans->syncpkgs, 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->syncpkgs = 
_pacman_list_remove(trans->syncpkgs, spkg, pkg_cmp, NULL);
-                               }
-                       }
-               }
-
-               /* re-order w.r.t. dependencies */
-               k = l = NULL;
-               for(i=trans->syncpkgs; i; i=i->next) {
-                       pmsyncpkg_t *s = (pmsyncpkg_t*)i->data;
-                       k = _pacman_list_add(k, s->pkg);
-               }
-               m = _pacman_sortbydeps(k, PM_TRANS_TYPE_ADD);
-               for(i=m; i; i=i->next) {
-                       for(j=trans->syncpkgs; j; j=j->next) {
-                               pmsyncpkg_t *s = (pmsyncpkg_t*)j->data;
-                               if(s->pkg==i->data) {
-                                       l = _pacman_list_add(l, s);
-                               }
-                       }
-               }
-               FREELISTPTR(k);
-               FREELISTPTR(m);
-               FREELISTPTR(trans->syncpkgs);
-               trans->syncpkgs = 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(!f_ptrlist_empty(deps)) {
-                       if(data) {
-                               *data = deps;
-                       }
-                       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(!f_ptrlist_empty(deps)) {
-                       int errorout = 0;
-
-                       for(i = deps; i && !errorout; i = i->next) {
-                               pmdepmissing_t *miss = i->data;
-                               int found = 0;
-                               pmsyncpkg_t *ps;
-                               Package *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->syncpkgs; j && !found; j = 
j->next) {
-                                       ps = j->data;
-                                       if(ps->type == PM_SYNC_TYPE_REPLACE) {
-                                               
if(_pacman_pkg_isin(miss->depend.name, ps->data)) {
-                                                       found = 1;
-                                               }
-                                       }
-                               }
-                               if(found) {
-                                       _pacman_log(PM_LOG_DEBUG, _("'%s' is 
already elected for removal -- skipping"),
-                                                       miss->depend.name);
-                                       continue;
-                               }
-
-                               ps = trans->find(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(ps->pkg->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 = 
_pacman_list_is_strin(miss->target, trans->targets);
-                                               depend = 
_pacman_list_is_strin(miss->depend.name, trans->targets);
-                                               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 = 
trans->find(rmpkg);
-                                                       pmsyncpkg_t *spkg = 
NULL;
-
-                                                       
_pacman_log(PM_LOG_FLOW2, _("removing '%s' from target list"), rmpkg);
-                                                       trans->syncpkgs = 
_pacman_list_remove(trans->syncpkgs, rsync, _pacman_syncpkg_cmp, (void 
**)&spkg);
-                                                       delete spkg;
-                                                       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(!_pacman_list_is_strin(miss->depend.name, asked)) {
-                                               QUESTION(trans, 
PM_TRANS_CONV_CONFLICT_PKG, miss->target, miss->depend.name, NULL, &doremove);
-                                               asked = 
_pacman_stringlist_append(asked, miss->depend.name);
-                                               if(doremove) {
-                                                       pmsyncpkg_t *rsync = 
trans->find(miss->depend.name);
-                                                       Package *q = new 
Package(miss->depend.name, NULL);
-                                                       if(q == NULL) {
-                                                               if(data) {
-                                                                       
FREELIST(*data);
-                                                               }
-                                                               ret = -1;
-                                                               goto cleanup;
-                                                       }
-                                                       q->m_requiredby = 
_pacman_list_strdup(local->requiredby());
-                                                       if(ps->type != 
PM_SYNC_TYPE_REPLACE) {
-                                                               /* switch this 
sync type to REPLACE */
-                                                               ps->type = 
PM_SYNC_TYPE_REPLACE;
-                                                               delete ps->data;
-                                                               ps->data = NULL;
-                                                       }
-                                                       /* append to the 
replaces list */
-                                                       
_pacman_log(PM_LOG_FLOW2, _("electing '%s' for removal"), miss->depend.name);
-                                                       ps->data = 
_pacman_list_add(ps->data, 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->syncpkgs 
= _pacman_list_remove(trans->syncpkgs, rsync, _pacman_syncpkg_cmp, (void 
**)&spkg);
-                                                               delete spkg;
-                                                       }
-                                               } 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->syncpkgs; i; i = i->next) {
-                       pmsyncpkg_t *ps = i->data;
-                       if(ps->type == PM_SYNC_TYPE_REPLACE) {
-                               for(j = ps->data; 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(!trans->find(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...  */
-                                               Package *leavingp  = 
_pacman_db_get_pkgfromcache(db_local, miss->target);
-                                               Package *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->syncpkgs; n && !pfound; n = n->next) {
-                                                                               
pmsyncpkg_t *sp = n->data;
-                                                                               
for(o = sp->pkg->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->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);
-}
-
-static
int _pacman_sync_commit(pmtrans_t *trans, pmlist_t **data)
{
pmlist_t *i, *j;
@@ -1195,88 +812,482 @@ int __pmtrans_t::add(const char *target)
goto error;
}

-       pkg_local = _pacman_db_get_pkgfromcache(db_local, pkg_new->name());
-       if(type != PM_TRANS_TYPE_UPGRADE) {
-               /* only install this package if it is not already installed */
-               if(pkg_local != NULL) {
-                       pm_errno = PM_ERR_PKG_INSTALLED;
-                       goto error;
-               }
-       } else {
-               if(flags & PM_TRANS_FLAG_FRESHEN) {
-                       /* only upgrade/install this package if it is already 
installed and at a lesser version */
-                       if(pkg_local == NULL || 
_pacman_versioncmp(pkg_local->version(), pkg_new->version()) >= 0) {
-                               pm_errno = PM_ERR_PKG_CANT_FRESH;
-                               goto error;
+       pkg_local = _pacman_db_get_pkgfromcache(db_local, pkg_new->name());
+       if(type != PM_TRANS_TYPE_UPGRADE) {
+               /* only install this package if it is not already installed */
+               if(pkg_local != NULL) {
+                       pm_errno = PM_ERR_PKG_INSTALLED;
+                       goto error;
+               }
+       } else {
+               if(flags & PM_TRANS_FLAG_FRESHEN) {
+                       /* only upgrade/install this package if it is already 
installed and at a lesser version */
+                       if(pkg_local == NULL || 
_pacman_versioncmp(pkg_local->version(), pkg_new->version()) >= 0) {
+                               pm_errno = PM_ERR_PKG_CANT_FRESH;
+                               goto error;
+                       }
+               }
+       }
+
+       if(flags & PM_TRANS_FLAG_ALLDEPS) {
+               pkg_new->m_reason = PM_PKG_REASON_DEPEND;
+       }
+
+       /* copy over the install reason */
+       if(pkg_local) {
+               pkg_new->m_reason = pkg_local->reason();
+       }
+
+       /* check if an older version of said package is already in transaction 
packages.
+        * if so, replace it in the list */
+       for(i = packages; i; i = i->next) {
+               Package *pkg = i->data;
+               if(strcmp(pkg->name(), pkg_new->name()) == 0) {
+                       pkg_queued = pkg;
+                       break;
+               }
+       }
+
+       if(pkg_queued != NULL) {
+               if(_pacman_versioncmp(pkg_queued->version(), 
pkg_new->version()) < 0) {
+                       _pacman_log(PM_LOG_WARNING, _("replacing older version 
%s-%s by %s in target list"),
+                                 pkg_queued->name(), pkg_queued->version(), 
pkg_new->version());
+                       f_ptrswap(&i->data, (void **)&pkg_new);
+               } else {
+                       _pacman_log(PM_LOG_WARNING, _("newer version %s-%s is 
in the target list -- skipping"),
+                                 pkg_queued->name(), pkg_queued->version(), 
pkg_new->version());
+               }
+               delete pkg_new;
+       } else {
+               add(pkg_new, type, 0);
+       }
+       }
+       if(type == PM_TRANS_TYPE_REMOVE) {
+               if(_pacman_remove_addtarget(this, target) == -1) {
+                       return -1;
+               }
+       }
+       }
+
+       targets = _pacman_stringlist_append(targets, target);
+
+       return(0);
+
+error:
+       delete pkg_new;
+       return(-1);
+}
+
+int __pmtrans_t::prepare(pmlist_t **data)
+{
+       /* Sanity checks */
+       ASSERT(data != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
+
+       *data = NULL;
+
+       /* If there's nothing to do, return without complaining */
+       if(_pacman_list_empty(packages) &&
+               _pacman_list_empty(syncpkgs)) {
+               return(0);
+       }
+
+       _pacman_trans_compute_triggers(this);
+
+       if(type == PM_TRANS_TYPE_SYNC) {
+       pmlist_t *deps = NULL;
+       pmlist_t *list = NULL; /* list allowing checkdeps usage with data from 
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;
+       Database *db_local = handle->db_local;
+
+       ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
+
+       if(data) {
+               *data = NULL;
+       }
+
+       for(i = syncpkgs; i; i = i->next) {
+               pmsyncpkg_t *ps = i->data;
+               list = _pacman_list_add(list, ps->pkg);
+       }
+
+       if(!(flags & PM_TRANS_FLAG_NODEPS)) {
+               trail = _pacman_list_new();
+
+               /* Resolve targets dependencies */
+               EVENT(this, PM_TRANS_EVT_RESOLVEDEPS_START, NULL, NULL);
+               _pacman_log(PM_LOG_FLOW1, _("resolving targets dependencies"));
+               for(i = syncpkgs; i; i = i->next) {
+                       Package *spkg = ((pmsyncpkg_t *)i->data)->pkg;
+                       if(_pacman_resolvedeps(this, 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 */
+                       Package *spkg = i->data;
+                       if(!find(spkg->name())) {
+                               pmsyncpkg_t *ps = new 
__pmsyncpkg_t(PM_SYNC_TYPE_DEPEND, spkg, NULL);
+                               if(ps == NULL) {
+                                       ret = -1;
+                                       goto cleanup;
+                               }
+                               syncpkgs = _pacman_list_add(syncpkgs, 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((flags & PM_TRANS_FLAG_DEPENDSONLY)) {
+                                       /* they are just pointers so we don't 
have to free them */
+                                       syncpkgs = 
_pacman_list_remove(syncpkgs, spkg, pkg_cmp, NULL);
+                               }
+                       }
+               }
+
+               /* re-order w.r.t. dependencies */
+               k = l = NULL;
+               for(i=syncpkgs; i; i=i->next) {
+                       pmsyncpkg_t *s = (pmsyncpkg_t*)i->data;
+                       k = _pacman_list_add(k, s->pkg);
+               }
+               m = _pacman_sortbydeps(k, PM_TRANS_TYPE_ADD);
+               for(i=m; i; i=i->next) {
+                       for(j=syncpkgs; j; j=j->next) {
+                               pmsyncpkg_t *s = (pmsyncpkg_t*)j->data;
+                               if(s->pkg==i->data) {
+                                       l = _pacman_list_add(l, s);
+                               }
+                       }
+               }
+               FREELISTPTR(k);
+               FREELISTPTR(m);
+               FREELISTPTR(syncpkgs);
+               syncpkgs = l;
+
+               EVENT(this, PM_TRANS_EVT_RESOLVEDEPS_DONE, NULL, NULL);
+
+               _pacman_log(PM_LOG_FLOW1, _("looking for unresolvable 
dependencies"));
+               deps = _pacman_checkdeps(this, PM_TRANS_TYPE_UPGRADE, list);
+               if(!f_ptrlist_empty(deps)) {
+                       if(data) {
+                               *data = deps;
+                       }
+                       pm_errno = PM_ERR_UNSATISFIED_DEPS;
+                       ret = -1;
+                       goto cleanup;
+               }
+
+               FREELISTPTR(trail);
+       }
+
+       if(!(flags & PM_TRANS_FLAG_NOCONFLICTS)) {
+               /* check for inter-conflicts and whatnot */
+               EVENT(this, PM_TRANS_EVT_INTERCONFLICTS_START, NULL, NULL);
+
+               _pacman_log(PM_LOG_FLOW1, _("looking for conflicts"));
+               deps = _pacman_checkconflicts(this, list);
+               if(!f_ptrlist_empty(deps)) {
+                       int errorout = 0;
+
+                       for(i = deps; i && !errorout; i = i->next) {
+                               pmdepmissing_t *miss = i->data;
+                               int found = 0;
+                               pmsyncpkg_t *ps;
+                               Package *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 = syncpkgs; j && !found; j = j->next) {
+                                       ps = j->data;
+                                       if(ps->type == PM_SYNC_TYPE_REPLACE) {
+                                               
if(_pacman_pkg_isin(miss->depend.name, ps->data)) {
+                                                       found = 1;
+                                               }
+                                       }
+                               }
+                               if(found) {
+                                       _pacman_log(PM_LOG_DEBUG, _("'%s' is 
already elected for removal -- skipping"),
+                                                       miss->depend.name);
+                                       continue;
+                               }
+
+                               ps = find(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(ps->pkg->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 = 
_pacman_list_is_strin(miss->target, targets);
+                                               depend = 
_pacman_list_is_strin(miss->depend.name, targets);
+                                               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 = 
find(rmpkg);
+                                                       pmsyncpkg_t *spkg = 
NULL;
+
+                                                       
_pacman_log(PM_LOG_FLOW2, _("removing '%s' from target list"), rmpkg);
+                                                       syncpkgs = 
_pacman_list_remove(syncpkgs, rsync, _pacman_syncpkg_cmp, (void **)&spkg);
+                                                       delete spkg;
+                                                       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(!_pacman_list_is_strin(miss->depend.name, asked)) {
+                                               QUESTION(this, 
PM_TRANS_CONV_CONFLICT_PKG, miss->target, miss->depend.name, NULL, &doremove);
+                                               asked = 
_pacman_stringlist_append(asked, miss->depend.name);
+                                               if(doremove) {
+                                                       pmsyncpkg_t *rsync = 
find(miss->depend.name);
+                                                       Package *q = new 
Package(miss->depend.name, NULL);
+                                                       if(q == NULL) {
+                                                               if(data) {
+                                                                       
FREELIST(*data);
+                                                               }
+                                                               ret = -1;
+                                                               goto cleanup;
+                                                       }
+                                                       q->m_requiredby = 
_pacman_list_strdup(local->requiredby());
+                                                       if(ps->type != 
PM_SYNC_TYPE_REPLACE) {
+                                                               /* switch this 
sync type to REPLACE */
+                                                               ps->type = 
PM_SYNC_TYPE_REPLACE;
+                                                               delete ps->data;
+                                                               ps->data = NULL;
+                                                       }
+                                                       /* append to the 
replaces list */
+                                                       
_pacman_log(PM_LOG_FLOW2, _("electing '%s' for removal"), miss->depend.name);
+                                                       ps->data = 
_pacman_list_add(ps->data, 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);
+                                                               syncpkgs = 
_pacman_list_remove(syncpkgs, rsync, _pacman_syncpkg_cmp, (void **)&spkg);
+                                                               delete spkg;
+                                                       }
+                                               } 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(this, PM_TRANS_EVT_INTERCONFLICTS_DONE, NULL, NULL);
}

-       if(flags & PM_TRANS_FLAG_ALLDEPS) {
-               pkg_new->m_reason = PM_PKG_REASON_DEPEND;
-       }
+       FREELISTPTR(list);

-       /* copy over the install reason */
-       if(pkg_local) {
-               pkg_new->m_reason = pkg_local->reason();
-       }
+       /* 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 if an older version of said package is already in transaction 
packages.
-        * if so, replace it in the list */
-       for(i = packages; i; i = i->next) {
-               Package *pkg = i->data;
-               if(strcmp(pkg->name(), pkg_new->name()) == 0) {
-                       pkg_queued = pkg;
-                       break;
+       if(!(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(this, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL);*/
+               for(i = syncpkgs; i; i = i->next) {
+                       pmsyncpkg_t *ps = i->data;
+                       if(ps->type == PM_SYNC_TYPE_REPLACE) {
+                               for(j = ps->data; j; j = j->next) {
+                                       list = _pacman_list_add(list, j->data);
+                               }
+                       }
}
-       }
-
-       if(pkg_queued != NULL) {
-               if(_pacman_versioncmp(pkg_queued->version(), 
pkg_new->version()) < 0) {
-                       _pacman_log(PM_LOG_WARNING, _("replacing older version 
%s-%s by %s in target list"),
-                                 pkg_queued->name(), pkg_queued->version(), 
pkg_new->version());
-                       f_ptrswap(&i->data, (void **)&pkg_new);
-               } else {
-                       _pacman_log(PM_LOG_WARNING, _("newer version %s-%s is 
in the target list -- skipping"),
-                                 pkg_queued->name(), pkg_queued->version(), 
pkg_new->version());
+               if(list) {
+                       _pacman_log(PM_LOG_FLOW1, _("checking dependencies of 
packages designated for removal"));
+                       deps = _pacman_checkdeps(this, PM_TRANS_TYPE_REMOVE, 
list);
+                       if(deps) {
+                               int errorout = 0;
+                               for(i = deps; i; i = i->next) {
+                                       pmdepmissing_t *miss = i->data;
+                                       if(!find(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...  */
+                                               Package *leavingp  = 
_pacman_db_get_pkgfromcache(db_local, miss->target);
+                                               Package *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 = 
syncpkgs; n && !pfound; n = n->next) {
+                                                                               
pmsyncpkg_t *sp = n->data;
+                                                                               
for(o = sp->pkg->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->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);
+                       }
}
-               delete pkg_new;
-       } else {
-               add(pkg_new, type, 0);
+               /*EVENT(this, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL);*/
}
-       }
-       if(type == PM_TRANS_TYPE_REMOVE) {
-               if(_pacman_remove_addtarget(this, target) == -1) {
-                       return -1;
+
+#ifndef __sun__
+       /* check for free space only in case the packages will be extracted */
+       if(!(flags & PM_TRANS_FLAG_NOCONFLICTS)) {
+               if(_pacman_check_freespace(this, data) == -1) {
+                               /* pm_errno is set by check_freespace */
+                               ret = -1;
+                               goto cleanup;
}
}
-       }
-
-       targets = _pacman_stringlist_append(targets, target);
+#endif

-       return(0);
+       /* issue warning if the local db is too old */
+       check_olddelay();

-error:
-       delete pkg_new;
-       return(-1);
-}
+cleanup:
+       FREELISTPTR(list);
+       FREELISTPTR(trail);
+       FREELIST(asked);

-static
-int _pacman_add_prepare(pmtrans_t *trans, pmlist_t **data)
-{
+       if(ret != 0) {
+               return ret;
+       }
+       } else {
+       if(type & PM_TRANS_TYPE_ADD) {
pmlist_t *lp;
-       Database *db_local = trans->handle->db_local;
+       Database *db_local = handle->db_local;

ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1));

/* Check dependencies
*/
-       if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) {
-               EVENT(trans, PM_TRANS_EVT_CHECKDEPS_START, NULL, NULL);
+       if(!(flags & PM_TRANS_FLAG_NODEPS)) {
+               EVENT(this, PM_TRANS_EVT_CHECKDEPS_START, NULL, NULL);

/* look for unsatisfied dependencies */
_pacman_log(PM_LOG_FLOW1, _("looking for unsatisfied dependencies"));
-               lp = _pacman_checkdeps(trans, trans->type, trans->packages);
+               lp = _pacman_checkdeps(this, type, packages);
if(lp != NULL) {
if(data) {
*data = lp;
@@ -1288,7 +1299,7 @@ int _pacman_add_prepare(pmtrans_t *trans, pmlist_t **data)

/* no unsatisfied deps, so look for conflicts */
_pacman_log(PM_LOG_FLOW1, _("looking for conflicts"));
-               lp = _pacman_checkconflicts(trans, trans->packages);
+               lp = _pacman_checkconflicts(this, packages);
if(lp != NULL) {
if(data) {
*data = lp;
@@ -1300,19 +1311,19 @@ int _pacman_add_prepare(pmtrans_t *trans, pmlist_t 
**data)

/* re-order w.r.t. dependencies */
_pacman_log(PM_LOG_FLOW1, _("sorting by dependencies"));
-               lp = _pacman_sortbydeps(trans->packages, PM_TRANS_TYPE_ADD);
+               lp = _pacman_sortbydeps(packages, PM_TRANS_TYPE_ADD);
/* free the old alltargs */
-               FREELISTPTR(trans->packages);
-               trans->packages = lp;
+               FREELISTPTR(packages);
+               packages = lp;

-               EVENT(trans, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL);
+               EVENT(this, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL);
}

/* Cleaning up
*/
-       EVENT(trans, PM_TRANS_EVT_CLEANUP_START, NULL, NULL);
+       EVENT(this, PM_TRANS_EVT_CLEANUP_START, NULL, NULL);
_pacman_log(PM_LOG_FLOW1, _("cleaning up"));
-       for (lp=trans->packages; lp!=NULL; lp=lp->next) {
+       for (lp = packages; lp!=NULL; lp=lp->next) {
Package *pkg_new=(Package *)lp->data;
pmlist_t *rmlist;

@@ -1323,17 +1334,17 @@ int _pacman_add_prepare(pmtrans_t *trans, pmlist_t 
**data)
remove(rm_fname);
}
}
-       EVENT(trans, PM_TRANS_EVT_CLEANUP_DONE, NULL, NULL);
+       EVENT(this, PM_TRANS_EVT_CLEANUP_DONE, NULL, NULL);

/* Check for file conflicts
*/
-       if(!(trans->flags & PM_TRANS_FLAG_FORCE)) {
+       if(!(flags & PM_TRANS_FLAG_FORCE)) {
pmlist_t *skiplist = NULL;

-               EVENT(trans, PM_TRANS_EVT_FILECONFLICTS_START, NULL, NULL);
+               EVENT(this, PM_TRANS_EVT_FILECONFLICTS_START, NULL, NULL);

_pacman_log(PM_LOG_FLOW1, _("looking for file conflicts"));
-               lp = _pacman_db_find_conflicts(trans, handle->root, &skiplist);
+               lp = _pacman_db_find_conflicts(this, handle->root, &skiplist);
if(lp != NULL) {
if(data) {
*data = lp;
@@ -1345,36 +1356,31 @@ int _pacman_add_prepare(pmtrans_t *trans, pmlist_t 
**data)
}

/* copy the file skiplist into the transaction */
-               trans->skiplist = skiplist;
+               skiplist = skiplist;

-               EVENT(trans, PM_TRANS_EVT_FILECONFLICTS_DONE, NULL, NULL);
+               EVENT(this, PM_TRANS_EVT_FILECONFLICTS_DONE, NULL, NULL);
}

#ifndef __sun__
-       if(_pacman_check_freespace(trans, data) == -1) {
+       if(_pacman_check_freespace(this, data) == -1) {
/* pm_errno is set by check_freespace */
return(-1);
}
#endif
-
-       return(0);
-}
-
-static
-int _pacman_remove_prepare(pmtrans_t *trans, pmlist_t **data)
-{
+       }
+       if(type == PM_TRANS_TYPE_REMOVE) {
pmlist_t *lp;
-       Database *db_local = trans->handle->db_local;
+       Database *db_local = handle->db_local;

ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1));

-       if(!(trans->flags & (PM_TRANS_FLAG_NODEPS)) && (trans->type != 
PM_TRANS_TYPE_UPGRADE)) {
-               EVENT(trans, PM_TRANS_EVT_CHECKDEPS_START, NULL, NULL);
+       if(!(flags & (PM_TRANS_FLAG_NODEPS)) && (type != 
PM_TRANS_TYPE_UPGRADE)) {
+               EVENT(this, PM_TRANS_EVT_CHECKDEPS_START, NULL, NULL);

_pacman_log(PM_LOG_FLOW1, _("looking for unsatisfied dependencies"));
-               lp = _pacman_checkdeps(trans, trans->type, trans->packages);
+               lp = _pacman_checkdeps(this, type, packages);
if(lp != NULL) {
-                       if(trans->flags & PM_TRANS_FLAG_CASCADE) {
+                       if(flags & PM_TRANS_FLAG_CASCADE) {
while(lp) {
pmlist_t *i;
for(i = lp; i; i = i->next) {
@@ -1382,14 +1388,14 @@ int _pacman_remove_prepare(pmtrans_t *trans, pmlist_t 
**data)
Package *pkg_local = db_local->scan(miss->depend.name, INFRQ_ALL);
if(pkg_local) {
_pacman_log(PM_LOG_FLOW2, _("pulling %s in the targets list"), 
pkg_local->name());
-                                                       trans->packages = 
_pacman_list_add(trans->packages, pkg_local);
+                                                       packages = 
_pacman_list_add(packages, pkg_local);
} else {
_pacman_log(PM_LOG_ERROR, _("could not find %s in database -- skipping"),
miss->depend.name);
}
}
FREELIST(lp);
-                                       lp = _pacman_checkdeps(trans, 
trans->type, trans->packages);
+                                       lp = _pacman_checkdeps(this, type, 
packages);
}
} else {
if(data) {
@@ -1401,53 +1407,20 @@ int _pacman_remove_prepare(pmtrans_t *trans, pmlist_t 
**data)
}
}

-               if(trans->flags & PM_TRANS_FLAG_RECURSE) {
+               if(flags & PM_TRANS_FLAG_RECURSE) {
_pacman_log(PM_LOG_FLOW1, _("finding removable dependencies"));
-                       trans->packages = _pacman_removedeps(db_local, 
trans->packages);
+                       packages = _pacman_removedeps(db_local, packages);
}

/* re-order w.r.t. dependencies */
_pacman_log(PM_LOG_FLOW1, _("sorting by dependencies"));
-               lp = _pacman_sortbydeps(trans->packages, PM_TRANS_TYPE_REMOVE);
+               lp = _pacman_sortbydeps(packages, PM_TRANS_TYPE_REMOVE);
/* free the old alltargs */
-               FREELISTPTR(trans->packages);
-               trans->packages = lp;
-
-               EVENT(trans, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL);
-       }
-
-       return(0);
-}
-
-int __pmtrans_t::prepare(pmlist_t **data)
-{
-       /* Sanity checks */
-       ASSERT(data != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
-
-       *data = NULL;
-
-       /* If there's nothing to do, return without complaining */
-       if(_pacman_list_empty(packages) &&
-               _pacman_list_empty(syncpkgs)) {
-               return(0);
-       }
+               FREELISTPTR(packages);
+               packages = lp;

-       _pacman_trans_compute_triggers(this);
-
-       if(type == PM_TRANS_TYPE_SYNC) {
-               if(_pacman_sync_prepare(this, data) == -1) {
-                       return(-1);
-               }
-       } else {
-       if(type & PM_TRANS_TYPE_ADD) {
-               if(_pacman_add_prepare(this, data) == -1) {
-                       return -1;
-               }
+               EVENT(this, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL);
}
-       if(type == PM_TRANS_TYPE_REMOVE) {
-               if(_pacman_remove_prepare(this, data) == -1) {
-                       return -1;
-               }
}
}
_______________________________________________
Frugalware-git mailing list
[email protected]
http://frugalware.org/mailman/listinfo/frugalware-git

Reply via email to