summaryrefslogtreecommitdiffstats
path: root/lib/libalpm/sync.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libalpm/sync.c')
-rw-r--r--lib/libalpm/sync.c360
1 files changed, 193 insertions, 167 deletions
diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c
index 47639248..2cdcd47b 100644
--- a/lib/libalpm/sync.c
+++ b/lib/libalpm/sync.c
@@ -43,11 +43,13 @@
#include "deps.h"
#include "conflict.h"
#include "trans.h"
+#include "add.h"
#include "util.h"
#include "handle.h"
#include "alpm.h"
#include "dload.h"
#include "delta.h"
+#include "remove.h"
/** Check for new version of pkg in sync repos
* (only the first occurrence is considered in sync)
@@ -80,17 +82,30 @@ pmpkg_t SYMEXPORT *alpm_sync_newversion(pmpkg_t *pkg, alpm_list_t *dbs_sync)
return(NULL);
}
-int _alpm_sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync, int enable_downgrade)
+/** Search for packages to upgrade and add them to the transaction.
+ * @return 0 on success, -1 on error (pm_errno is set accordingly)
+ */
+int SYMEXPORT alpm_sync_sysupgrade(int enable_downgrade)
{
alpm_list_t *i, *j, *k;
+ pmtrans_t *trans;
+ pmdb_t *db_local;
+ alpm_list_t *dbs_sync;
ALPM_LOG_FUNC;
+ ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
+ trans = handle->trans;
+ db_local = handle->db_local;
+ dbs_sync = handle->dbs_sync;
+ ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
+ ASSERT(trans->state == STATE_INITIALIZED, RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1));
+
_alpm_log(PM_LOG_DEBUG, "checking for package upgrades\n");
for(i = _alpm_db_get_pkgcache(db_local); i; i = i->next) {
pmpkg_t *lpkg = i->data;
- if(_alpm_pkg_find(trans->packages, lpkg->name)) {
+ if(_alpm_pkg_find(trans->add, lpkg->name)) {
_alpm_log(PM_LOG_DEBUG, "%s is already in the target list -- skipping\n", lpkg->name);
continue;
}
@@ -113,7 +128,7 @@ int _alpm_sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_s
} else {
_alpm_log(PM_LOG_DEBUG, "adding package %s-%s to the transaction targets\n",
spkg->name, spkg->version);
- trans->packages = alpm_list_add(trans->packages, spkg);
+ trans->add = alpm_list_add(trans->add, spkg);
}
} else if(cmp < 0) {
if(enable_downgrade) {
@@ -124,7 +139,7 @@ int _alpm_sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_s
} else {
_alpm_log(PM_LOG_WARNING, _("%s: downgrading from version %s to version %s\n"),
lpkg->name, lpkg->version, spkg->version);
- trans->packages = alpm_list_add(trans->packages, spkg);
+ trans->add = alpm_list_add(trans->add, spkg);
}
} else {
_alpm_log(PM_LOG_WARNING, _("%s: local (%s) is newer than %s (%s)\n"),
@@ -152,7 +167,7 @@ int _alpm_sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_s
}
/* If spkg is already in the target list, we append lpkg to spkg's removes list */
- pmpkg_t *tpkg = _alpm_pkg_find(trans->packages, spkg->name);
+ pmpkg_t *tpkg = _alpm_pkg_find(trans->add, spkg->name);
if(tpkg) {
/* sanity check, multiple repos can contain spkg->name */
if(tpkg->origin_data.db != sdb) {
@@ -173,7 +188,7 @@ int _alpm_sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_s
spkg->removes = alpm_list_add(NULL, lpkg);
_alpm_log(PM_LOG_DEBUG, "adding package %s-%s to the transaction targets\n",
spkg->name, spkg->version);
- trans->packages = alpm_list_add(trans->packages, spkg);
+ trans->add = alpm_list_add(trans->add, spkg);
}
}
}
@@ -187,57 +202,18 @@ int _alpm_sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_s
return(0);
}
-int _alpm_sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync, char *name)
+int _alpm_sync_pkg(pmpkg_t *spkg)
{
- char *targline;
- char *targ;
- alpm_list_t *j;
- pmpkg_t *local, *spkg;
- pmdepend_t *dep; /* provisions and dependencies are also allowed */
+ pmtrans_t *trans;
+ pmdb_t *db_local;
+ pmpkg_t *local;
ALPM_LOG_FUNC;
- ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
- ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
- ASSERT(name != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
-
- STRDUP(targline, name, RET_ERR(PM_ERR_MEMORY, -1));
- targ = strchr(targline, '/');
- if(targ) {
- /* we are looking for a package in a specific database */
- alpm_list_t *dbs = NULL;
- *targ = '\0';
- targ++;
- _alpm_log(PM_LOG_DEBUG, "searching for target '%s' in repo '%s'\n", targ, targline);
- for(j = dbs_sync; j; j = j->next) {
- pmdb_t *db = j->data;
- if(strcmp(db->treename, targline) == 0) {
- dbs = alpm_list_add(NULL, db);
- break;
- }
- }
- if(dbs == NULL) {
- _alpm_log(PM_LOG_ERROR, _("repository '%s' not found\n"), targline);
- FREE(targline);
- RET_ERR(PM_ERR_PKG_REPO_NOT_FOUND, -1);
- }
- dep = _alpm_splitdep(targ);
- spkg = _alpm_resolvedep(dep, dbs, NULL, 1);
- _alpm_dep_free(dep);
- alpm_list_free(dbs);
- } else {
- dep = _alpm_splitdep(targline);
- spkg = _alpm_resolvedep(dep, dbs_sync, NULL, 1);
- _alpm_dep_free(dep);
- }
- FREE(targline);
-
- if(spkg == NULL) {
- /* pm_errno is set by _alpm_resolvedep */
- return(-1);
- }
+ trans = handle->trans;
+ db_local = handle->db_local;
- if(_alpm_pkg_find(trans->packages, alpm_pkg_get_name(spkg))) {
+ if(_alpm_pkg_find(trans->add, alpm_pkg_get_name(spkg))) {
RET_ERR(PM_ERR_TRANS_DUP_TARGET, -1);
}
@@ -267,11 +243,108 @@ int _alpm_sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sy
spkg->reason = PM_PKG_REASON_EXPLICIT;
_alpm_log(PM_LOG_DEBUG, "adding package %s-%s to the transaction targets\n",
alpm_pkg_get_name(spkg), alpm_pkg_get_version(spkg));
- trans->packages = alpm_list_add(trans->packages, spkg);
+ trans->add = alpm_list_add(trans->add, spkg);
+
+ return(0);
+}
+
+int _alpm_sync_target(alpm_list_t *dbs_sync, char *target)
+{
+ alpm_list_t *i, *j;
+ pmpkg_t *spkg;
+ pmdepend_t *dep; /* provisions and dependencies are also allowed */
+ pmgrp_t *grp;
+ int found = 0;
+
+ ALPM_LOG_FUNC;
+
+ /* Sanity checks */
+ ASSERT(target != NULL && strlen(target) != 0, RET_ERR(PM_ERR_WRONG_ARGS, -1));
+ ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
+
+ dep = _alpm_splitdep(target);
+ spkg = _alpm_resolvedep(dep, dbs_sync, NULL, 1);
+ _alpm_dep_free(dep);
+
+ if(spkg != NULL) {
+ return(_alpm_sync_pkg(spkg));
+ }
+
+ _alpm_log(PM_LOG_DEBUG, "%s package not found, searching for group...\n", target);
+ for(i = dbs_sync; i; i = i->next) {
+ pmdb_t *db = i->data;
+ grp = alpm_db_readgrp(db, target);
+ if(grp) {
+ found = 1;
+ for(j = alpm_grp_get_pkgs(grp); j; j = j->next) {
+ pmpkg_t *pkg = j->data;
+ if(_alpm_sync_pkg(pkg) == -1) {
+ if(pm_errno == PM_ERR_TRANS_DUP_TARGET || pm_errno == PM_ERR_PKG_IGNORED) {
+ /* just skip duplicate or ignored targets */
+ continue;
+ } else {
+ return(-1);
+ }
+ }
+ }
+ }
+ }
+
+ if(!found) {
+ RET_ERR(PM_ERR_PKG_NOT_FOUND, -1);
+ }
return(0);
}
+/** Add a sync target to the transaction.
+ * @param target the name of the sync target to add
+ * @return 0 on success, -1 on error (pm_errno is set accordingly)
+ */
+int SYMEXPORT alpm_sync_dbtarget(char *dbname, char *target)
+{
+ alpm_list_t *i;
+ alpm_list_t *dbs_sync;
+
+ ALPM_LOG_FUNC;
+
+ /* Sanity checks */
+ ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
+ dbs_sync = handle->dbs_sync;
+
+ /* we are looking for a package in a specific database */
+ alpm_list_t *dbs = NULL;
+ _alpm_log(PM_LOG_DEBUG, "searching for target '%s' in repo '%s'\n", target, dbname);
+ for(i = dbs_sync; i; i = i->next) {
+ pmdb_t *db = i->data;
+ if(strcmp(db->treename, dbname) == 0) {
+ dbs = alpm_list_add(NULL, db);
+ break;
+ }
+ }
+ if(dbs == NULL) {
+ RET_ERR(PM_ERR_PKG_REPO_NOT_FOUND, -1);
+ }
+ return(_alpm_sync_target(dbs, target));
+}
+
+/** Add a sync target to the transaction.
+ * @param target the name of the sync target to add
+ * @return 0 on success, -1 on error (pm_errno is set accordingly)
+ */
+int SYMEXPORT alpm_sync_target(char *target)
+{
+ alpm_list_t *dbs_sync;
+
+ ALPM_LOG_FUNC;
+
+ /* Sanity checks */
+ ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
+ dbs_sync = handle->dbs_sync;
+
+ return(_alpm_sync_target(dbs_sync,target));
+}
+
/** Compute the size of the files that will be downloaded to install a
* package.
* @param newpkg the new package to upgrade to
@@ -282,6 +355,11 @@ static int compute_download_size(pmpkg_t *newpkg)
char *fpath;
off_t size = 0;
+ if(newpkg->origin == PKG_FROM_FILE) {
+ newpkg->download_size = 0;
+ return(0);
+ }
+
fname = alpm_pkg_get_filename(newpkg);
ASSERT(fname != NULL, RET_ERR(PM_ERR_PKG_INVALID_NAME, -1));
fpath = _alpm_filecache_find(fname);
@@ -321,10 +399,9 @@ static int compute_download_size(pmpkg_t *newpkg)
int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync, alpm_list_t **data)
{
alpm_list_t *deps = NULL;
- alpm_list_t *preferred = NULL;
alpm_list_t *unresolvable = NULL;
- alpm_list_t *remove = NULL; /* allow checkdeps usage with trans->packages */
alpm_list_t *i, *j;
+ alpm_list_t *remove = NULL;
int ret = 0;
ALPM_LOG_FUNC;
@@ -344,32 +421,29 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_START, NULL, NULL);
_alpm_log(PM_LOG_DEBUG, "resolving target's dependencies\n");
- /* build remove list and preferred list for resolvedeps */
- for(i = trans->packages; i; i = i->next) {
+ /* build remove list for resolvedeps */
+ for(i = trans->add; i; i = i->next) {
pmpkg_t *spkg = i->data;
for(j = spkg->removes; j; j = j->next) {
remove = alpm_list_add(remove, j->data);
}
- preferred = alpm_list_add(preferred, spkg);
}
/* Resolve packages in the transaction one at a time, in addtion
building up a list of packages which could not be resolved. */
- for(i = trans->packages; i; i = i->next) {
+ for(i = trans->add; i; i = i->next) {
pmpkg_t *pkg = i->data;
- if(_alpm_resolvedeps(db_local, dbs_sync, pkg, preferred,
+ if(_alpm_resolvedeps(db_local, dbs_sync, pkg, trans->add,
&resolved, remove, data) == -1) {
unresolvable = alpm_list_add(unresolvable, pkg);
}
/* Else, [resolved] now additionally contains [pkg] and all of its
dependencies not already on the list */
}
- alpm_list_free(preferred);
/* If there were unresolvable top-level packages, prompt the user to
see if they'd like to ignore them rather than failing the sync */
if(unresolvable != NULL) {
- unresolvable = alpm_list_remove_dupes(unresolvable);
int remove_unresolvable = 0;
QUESTION(handle->trans, PM_TRANS_CONV_REMOVE_PKGS, unresolvable,
NULL, NULL, &remove_unresolvable);
@@ -392,21 +466,21 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
}
}
- /* Unresolvable packages will be removed from the target list, so
- we free the transaction specific fields */
- alpm_list_free_inner(unresolvable, (alpm_list_fn_free)_alpm_pkg_free_trans);
-
/* Set DEPEND reason for pulled packages */
for(i = resolved; i; i = i->next) {
pmpkg_t *pkg = i->data;
- if(!_alpm_pkg_find(trans->packages, pkg->name)) {
+ if(!_alpm_pkg_find(trans->add, pkg->name)) {
pkg->reason = PM_PKG_REASON_DEPEND;
}
}
+ /* Unresolvable packages will be removed from the target list, so
+ we free the transaction specific fields */
+ alpm_list_free_inner(unresolvable, (alpm_list_fn_free)_alpm_pkg_free_trans);
+
/* re-order w.r.t. dependencies */
- alpm_list_free(trans->packages);
- trans->packages = _alpm_sortbydeps(resolved, 0);
+ alpm_list_free(trans->add);
+ trans->add = _alpm_sortbydeps(resolved, 0);
alpm_list_free(resolved);
EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_DONE, NULL, NULL);
@@ -420,15 +494,15 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
/* 1. check for conflicts in the target list */
_alpm_log(PM_LOG_DEBUG, "check targets vs targets\n");
- deps = _alpm_innerconflicts(trans->packages);
+ deps = _alpm_innerconflicts(trans->add);
for(i = deps; i; i = i->next) {
pmconflict_t *conflict = i->data;
pmpkg_t *rsync, *sync, *sync1, *sync2;
/* have we already removed one of the conflicting targets? */
- sync1 = _alpm_pkg_find(trans->packages, conflict->package1);
- sync2 = _alpm_pkg_find(trans->packages, conflict->package2);
+ sync1 = _alpm_pkg_find(trans->add, conflict->package1);
+ sync2 = _alpm_pkg_find(trans->add, conflict->package2);
if(!sync1 || !sync2) {
continue;
}
@@ -468,8 +542,8 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
_alpm_log(PM_LOG_WARNING,
_("removing '%s' from target list because it conflicts with '%s'\n"),
rsync->name, sync->name);
+ trans->add = alpm_list_remove(trans->add, rsync, _alpm_pkg_cmp, NULL);
_alpm_pkg_free_trans(rsync); /* rsync is not transaction target anymore */
- trans->packages = alpm_list_remove(trans->packages, rsync, _alpm_pkg_cmp, NULL);
continue;
}
@@ -479,7 +553,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
/* 2. we check for target vs db conflicts (and resolve)*/
_alpm_log(PM_LOG_DEBUG, "check targets vs db and db vs targets\n");
- deps = _alpm_outerconflicts(db_local, trans->packages);
+ deps = _alpm_outerconflicts(db_local, trans->add);
for(i = deps; i; i = i->next) {
pmconflict_t *conflict = i->data;
@@ -487,7 +561,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
/* if conflict->package2 (the local package) is not elected for removal,
we ask the user */
int found = 0;
- for(j = trans->packages; j && !found; j = j->next) {
+ for(j = trans->add; j && !found; j = j->next) {
pmpkg_t *spkg = j->data;
if(_alpm_pkg_find(spkg->removes, conflict->package2)) {
found = 1;
@@ -500,11 +574,11 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
_alpm_log(PM_LOG_DEBUG, "package '%s' conflicts with '%s'\n",
conflict->package1, conflict->package2);
- pmpkg_t *sync = _alpm_pkg_find(trans->packages, conflict->package1);
+ pmpkg_t *sync = _alpm_pkg_find(trans->add, conflict->package1);
pmpkg_t *local = _alpm_db_get_pkgfromcache(db_local, conflict->package2);
int doremove = 0;
QUESTION(trans, PM_TRANS_CONV_CONFLICT_PKG, conflict->package1,
- conflict->package2, NULL, &doremove);
+ conflict->package2, conflict->reason, &doremove);
if(doremove) {
/* append to the removes list */
_alpm_log(PM_LOG_DEBUG, "electing '%s' for removal\n", conflict->package2);
@@ -529,19 +603,17 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
alpm_list_free(deps);
}
- if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) {
- /* rebuild remove list */
- alpm_list_free(remove);
- remove = NULL;
- for(i = trans->packages; i; i = i->next) {
- pmpkg_t *spkg = i->data;
- for(j = spkg->removes; j; j = j->next) {
- remove = alpm_list_add(remove, j->data);
- }
+ /* Build trans->remove list */
+ for(i = trans->add; i; i = i->next) {
+ pmpkg_t *spkg = i->data;
+ for(j = spkg->removes; j; j = j->next) {
+ trans->remove = alpm_list_add(trans->remove, _alpm_pkg_dup(j->data));
}
+ }
+ if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) {
_alpm_log(PM_LOG_DEBUG, "checking dependencies\n");
- deps = alpm_checkdeps(_alpm_db_get_pkgcache(db_local), 1, remove, trans->packages);
+ deps = alpm_checkdeps(_alpm_db_get_pkgcache(db_local), 1, trans->remove, trans->add);
if(deps) {
pm_errno = PM_ERR_UNSATISFIED_DEPS;
ret = -1;
@@ -554,7 +626,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
goto cleanup;
}
}
- for(i = trans->packages; i; i = i->next) {
+ for(i = trans->add; i; i = i->next) {
/* update download size field */
pmpkg_t *spkg = i->data;
if(compute_download_size(spkg) != 0) {
@@ -564,8 +636,8 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
}
cleanup:
- alpm_list_free(remove);
alpm_list_free(unresolvable);
+ alpm_list_free(remove);
return(ret);
}
@@ -601,7 +673,7 @@ static int apply_deltas(pmtrans_t *trans)
int ret = 0;
const char *cachedir = _alpm_filecache_setup();
- for(i = trans->packages; i; i = i->next) {
+ for(i = trans->add; i; i = i->next) {
pmpkg_t *spkg = i->data;
alpm_list_t *delta_path = spkg->delta_path;
alpm_list_t *dlts = NULL;
@@ -614,7 +686,7 @@ static int apply_deltas(pmtrans_t *trans)
pmdelta_t *d = dlts->data;
char *delta, *from, *to;
char command[PATH_MAX];
- int len = 0;
+ size_t len = 0;
delta = _alpm_filecache_find(d->delta);
/* the initial package might be in a different cachedir */
@@ -711,7 +783,6 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
{
alpm_list_t *i, *j, *files = NULL;
alpm_list_t *deltas = NULL;
- pmtrans_t *tr_remove = NULL, *tr_upgrade = NULL;
int replaces = 0;
int errors = 0;
const char *cachedir = NULL;
@@ -730,7 +801,7 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
if(handle->totaldlcb) {
off_t total_size = (off_t)0;
/* sum up the download size for each package and store total */
- for(i = trans->packages; i; i = i->next) {
+ for(i = trans->add; i; i = i->next) {
pmpkg_t *spkg = i->data;
total_size += spkg->download_size;
}
@@ -741,11 +812,10 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
for(i = handle->dbs_sync; i; i = i->next) {
pmdb_t *current = i->data;
- for(j = trans->packages; j; j = j->next) {
+ for(j = trans->add; j; j = j->next) {
pmpkg_t *spkg = j->data;
- pmdb_t *dbs = spkg->origin_data.db;
- if(current == dbs) {
+ if(spkg->origin == PKG_FROM_CACHE && current == spkg->origin_data.db) {
const char *fname = NULL;
fname = alpm_pkg_get_filename(spkg);
@@ -835,15 +905,36 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
EVENT(trans, PM_TRANS_EVT_INTEGRITY_START, NULL, NULL);
errors = 0;
- for(i = trans->packages; i; i = i->next) {
+ for(i = trans->add; i; i = i->next) {
pmpkg_t *spkg = i->data;
+ if(spkg->origin == PKG_FROM_FILE) {
+ continue; /* pkg_load() has been already called, this package is valid */
+ }
+
const char *filename = alpm_pkg_get_filename(spkg);
const char *md5sum = alpm_pkg_get_md5sum(spkg);
if(test_md5sum(trans, filename, md5sum) != 0) {
errors++;
*data = alpm_list_add(*data, strdup(filename));
+ continue;
+ }
+ /* load the package file and replace pkgcache entry with it in the target list */
+ /* TODO: alpm_pkg_get_db() will not work on this target anymore */
+ _alpm_log(PM_LOG_DEBUG, "replacing pkgcache entry with package file for target %s\n", spkg->name);
+ char *filepath = _alpm_filecache_find(filename);
+ pmpkg_t *pkgfile;
+ if(alpm_pkg_load(filepath, 1, &pkgfile) != 0) {
+ _alpm_pkg_free(pkgfile);
+ errors++;
+ *data = alpm_list_add(*data, strdup(filename));
+ FREE(filepath);
+ continue;
}
+ FREE(filepath);
+ pkgfile->reason = spkg->reason; /* copy over install reason */
+ i->data = pkgfile;
+ _alpm_pkg_free_trans(spkg); /* spkg has been removed from the target list */
}
if(errors) {
pm_errno = PM_ERR_PKG_INVALID;
@@ -856,71 +947,15 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
trans->state = STATE_COMMITING;
- /* Create remove and upgrade transactions */
- tr_remove = _alpm_trans_new();
- if(tr_remove == NULL) {
- _alpm_log(PM_LOG_ERROR, _("could not create removal transaction\n"));
- goto error;
- }
- tr_upgrade = _alpm_trans_new();
- if(tr_upgrade == NULL) {
- _alpm_log(PM_LOG_ERROR, _("could not create transaction\n"));
- goto error;
- }
-
- if(_alpm_trans_init(tr_remove, PM_TRANS_TYPE_REMOVE, PM_TRANS_FLAG_NODEPS, NULL, NULL, NULL) == -1) {
- _alpm_log(PM_LOG_ERROR, _("could not initialize the removal transaction\n"));
- goto error;
- }
- if(_alpm_trans_init(tr_upgrade, PM_TRANS_TYPE_UPGRADE, trans->flags, trans->cb_event, trans->cb_conv, trans->cb_progress) == -1) {
- _alpm_log(PM_LOG_ERROR, _("could not initialize transaction\n"));
- goto error;
- }
-
- /* adding targets */
- for(i = trans->packages; i; i = i->next) {
- pmpkg_t *spkg = i->data;
- alpm_list_t *j;
- /* remove transaction */
- for(j = spkg->removes; j; j = j->next) {
- pmpkg_t *pkg = j->data;
- if(!_alpm_pkg_find(tr_remove->packages, pkg->name)) {
- if(_alpm_trans_addtarget(tr_remove, pkg->name) == -1) {
- goto error;
- }
- replaces++;
- }
- }
- /* upgrade transaction */
- const char *fname;
- char *fpath;
-
- fname = alpm_pkg_get_filename(spkg);
- if(fname == NULL) {
- goto error;
- }
- /* Loop through the cache dirs until we find a matching file */
- fpath = _alpm_filecache_find(fname);
-
- if(_alpm_trans_addtarget(tr_upgrade, fpath) == -1) {
- FREE(fpath);
- goto error;
- }
- FREE(fpath);
-
- /* using alpm_list_last() is ok because addtarget() adds the new target at the
- * end of the tr->packages list */
- pmpkg_t *ipkg = alpm_list_last(tr_upgrade->packages)->data;
- ipkg->reason = spkg->reason;
- }
+ replaces = alpm_list_count(trans->remove);
/* fileconflict check */
if(!(trans->flags & PM_TRANS_FLAG_FORCE)) {
EVENT(trans, PM_TRANS_EVT_FILECONFLICTS_START, NULL, NULL);
_alpm_log(PM_LOG_DEBUG, "looking for file conflicts\n");
- alpm_list_t *conflict = _alpm_db_find_fileconflicts(db_local, tr_upgrade,
- tr_upgrade->packages, tr_remove->packages);
+ alpm_list_t *conflict = _alpm_db_find_fileconflicts(db_local, trans,
+ trans->add, trans->remove);
if(conflict) {
pm_errno = PM_ERR_FILE_CONFLICTS;
if(data) {
@@ -938,14 +973,8 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
/* remove conflicting and to-be-replaced packages */
if(replaces) {
_alpm_log(PM_LOG_DEBUG, "removing conflicting and to-be-replaced packages\n");
- if(_alpm_trans_prepare(tr_remove, data) == -1) {
- _alpm_log(PM_LOG_ERROR, _("could not prepare removal transaction\n"));
- goto error;
- }
/* we want the frontend to be aware of commit details */
- tr_remove->cb_event = trans->cb_event;
- tr_remove->cb_progress = trans->cb_progress;
- if(_alpm_trans_commit(tr_remove, NULL) == -1) {
+ if(_alpm_remove_packages(trans, handle->db_local) == -1) {
_alpm_log(PM_LOG_ERROR, _("could not commit removal transaction\n"));
goto error;
}
@@ -953,8 +982,7 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
/* install targets */
_alpm_log(PM_LOG_DEBUG, "installing packages\n");
- /* add_prepare is not needed */
- if(_alpm_trans_commit(tr_upgrade, NULL) == -1) {
+ if(_alpm_upgrade_packages(trans, handle->db_local) == -1) {
_alpm_log(PM_LOG_ERROR, _("could not commit transaction\n"));
goto error;
}
@@ -963,8 +991,6 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
error:
FREELIST(files);
alpm_list_free(deltas);
- _alpm_trans_free(tr_remove);
- _alpm_trans_free(tr_upgrade);
return(ret);
}