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

Reply via email to