summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/libalpm/add.c100
-rw-r--r--lib/libalpm/alpm.h18
-rw-r--r--lib/libalpm/be_files.c3
-rw-r--r--lib/libalpm/conflict.c2
-rw-r--r--lib/libalpm/package.c7
-rw-r--r--lib/libalpm/remove.c174
-rw-r--r--lib/libalpm/remove.h5
-rw-r--r--lib/libalpm/sync.c100
-rw-r--r--lib/libalpm/trans.c371
-rw-r--r--lib/libalpm/trans.h9
10 files changed, 335 insertions, 454 deletions
diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c
index 86355007..1609c5c3 100644
--- a/lib/libalpm/add.c
+++ b/lib/libalpm/add.c
@@ -72,7 +72,7 @@ int _alpm_add_loadtarget(pmtrans_t *trans, pmdb_t *db, char *name)
/* check if an older version of said package is already in transaction
* packages. if so, replace it in the list */
- for(i = trans->packages; i; i = i->next) {
+ for(i = trans->add; i; i = i->next) {
pmpkg_t *transpkg = i->data;
if(strcmp(transpkg->name, pkgname) == 0) {
if(alpm_pkg_vercmp(transpkg->version, pkgver) < 0) {
@@ -90,7 +90,7 @@ int _alpm_add_loadtarget(pmtrans_t *trans, pmdb_t *db, char *name)
}
/* add the package to the transaction */
- trans->packages = alpm_list_add(trans->packages, pkg);
+ trans->add = alpm_list_add(trans->add, pkg);
return(0);
@@ -99,91 +99,6 @@ error:
return(-1);
}
-static int upgrade_remove(pmpkg_t *oldpkg, pmpkg_t *newpkg, pmtrans_t *trans, pmdb_t *db) {
- /* this is kinda odd. If the old package exists, at this point we make a
- * NEW transaction, unrelated to handle->trans, and instantiate a "remove"
- * with the type PM_TRANS_TYPE_REMOVEUPGRADE. TODO: kill this weird
- * behavior. */
- pmtrans_t *tr = _alpm_trans_new();
-
- ALPM_LOG_FUNC;
-
- _alpm_log(PM_LOG_DEBUG, "removing old package first (%s-%s)\n",
- oldpkg->name, oldpkg->version);
-
- if(!tr) {
- RET_ERR(PM_ERR_TRANS_ABORT, -1);
- }
-
- if(_alpm_trans_init(tr, PM_TRANS_TYPE_REMOVEUPGRADE, trans->flags,
- NULL, NULL, NULL) == -1) {
- _alpm_trans_free(tr);
- tr = NULL;
- RET_ERR(PM_ERR_TRANS_ABORT, -1);
- }
-
- if(_alpm_remove_loadtarget(tr, db, newpkg->name) == -1) {
- _alpm_trans_free(tr);
- tr = NULL;
- RET_ERR(PM_ERR_TRANS_ABORT, -1);
- }
-
- /* copy the remove skiplist over */
- tr->skip_remove = alpm_list_strdup(trans->skip_remove);
- const alpm_list_t *b;
-
- /* Add files in the NEW backup array to the NoUpgrade array
- * so this removal operation doesn't kill them */
- alpm_list_t *old_noupgrade = alpm_list_strdup(handle->noupgrade);
- /* old package backup list */
- alpm_list_t *filelist = alpm_pkg_get_files(newpkg);
- for(b = alpm_pkg_get_backup(newpkg); b; b = b->next) {
- char *backup = _alpm_backup_file(b->data);
- /* safety check (fix the upgrade026 pactest) */
- if(!alpm_list_find_str(filelist, backup)) {
- FREE(backup);
- continue;
- }
- _alpm_log(PM_LOG_DEBUG, "adding %s to the NoUpgrade array temporarily\n",
- backup);
- handle->noupgrade = alpm_list_add(handle->noupgrade,
- backup);
- }
-
- /* TODO: we could also add files in the OLD backup array, but this would
- * change the backup handling behavior, and break several pactests, and we
- * can't do this just before 3.1 release.
- * The unlink_file function in remove.c would also need to be reviewed. */
-#if 0
- /* new package backup list */
- for(b = alpm_pkg_get_backup(oldpkg); b; b = b->next) {
- char *backup = _alpm_backup_file(b->data);
- /* make sure we don't add duplicate entries */
- if(!alpm_list_find_ptr(handle->noupgrade, backup)) {
- _alpm_log(PM_LOG_DEBUG, "adding %s to the NoUpgrade array temporarily\n",
- backup);
- handle->noupgrade = alpm_list_add(handle->noupgrade,
- backup);
- }
- }
-#endif
-
- int ret = _alpm_remove_commit(tr, db);
-
- _alpm_trans_free(tr);
- tr = NULL;
-
- /* restore our "NoUpgrade" list to previous state */
- FREELIST(handle->noupgrade);
- handle->noupgrade = old_noupgrade;
-
- if(ret == -1) {
- RET_ERR(PM_ERR_TRANS_ABORT, -1);
- }
-
- return(0);
-}
-
static int extract_single_file(struct archive *archive,
struct archive_entry *entry, pmpkg_t *newpkg, pmpkg_t *oldpkg,
pmtrans_t *trans, pmdb_t *db)
@@ -606,8 +521,9 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count,
if(oldpkg) {
/* set up fake remove transaction */
- int ret = upgrade_remove(oldpkg, newpkg, trans, db);
- if(ret != 0) {
+ if(_alpm_upgraderemove_package(oldpkg, newpkg, trans) == -1) {
+ pm_errno = PM_ERR_TRANS_ABORT;
+ ret = -1;
goto cleanup;
}
}
@@ -783,15 +699,15 @@ int _alpm_upgrade_packages(pmtrans_t *trans, pmdb_t *db)
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
- if(trans->packages == NULL) {
+ if(trans->add == NULL) {
return(0);
}
- pkg_count = alpm_list_count(trans->packages);
+ pkg_count = alpm_list_count(trans->add);
pkg_current = 1;
/* loop through our package list adding/upgrading one at a time */
- for(targ = trans->packages; targ; targ = targ->next) {
+ for(targ = trans->add; targ; targ = targ->next) {
if(handle->trans->state == STATE_INTERRUPTED) {
return(0);
}
diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index a08e2247..661df453 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -225,7 +225,6 @@ alpm_list_t *alpm_pkg_get_deltas(pmpkg_t *pkg);
alpm_list_t *alpm_pkg_get_replaces(pmpkg_t *pkg);
alpm_list_t *alpm_pkg_get_files(pmpkg_t *pkg);
alpm_list_t *alpm_pkg_get_backup(pmpkg_t *pkg);
-alpm_list_t *alpm_pkg_get_removes(pmpkg_t *pkg);
pmdb_t *alpm_pkg_get_db(pmpkg_t *pkg);
void *alpm_pkg_changelog_open(pmpkg_t *pkg);
size_t alpm_pkg_changelog_read(void *ptr, size_t size,
@@ -263,13 +262,6 @@ pmpkg_t *alpm_sync_newversion(pmpkg_t *pkg, alpm_list_t *dbs_sync);
* Transactions
*/
-/* Types */
-typedef enum _pmtranstype_t {
- PM_TRANS_TYPE_UPGRADE = 1,
- PM_TRANS_TYPE_REMOVE,
- PM_TRANS_TYPE_REMOVEUPGRADE,
- PM_TRANS_TYPE_SYNC
-} pmtranstype_t;
/* Flags */
typedef enum _pmtransflag_t {
@@ -403,14 +395,16 @@ typedef void (*alpm_trans_cb_conv)(pmtransconv_t, void *, void *,
/* Transaction Progress callback */
typedef void (*alpm_trans_cb_progress)(pmtransprog_t, const char *, int, int, int);
-pmtranstype_t alpm_trans_get_type();
unsigned int alpm_trans_get_flags();
-alpm_list_t * alpm_trans_get_pkgs();
-int alpm_trans_init(pmtranstype_t type, pmtransflag_t flags,
+alpm_list_t * alpm_trans_get_add();
+alpm_list_t * alpm_trans_get_remove();
+int alpm_trans_init(pmtransflag_t flags,
alpm_trans_cb_event cb_event, alpm_trans_cb_conv conv,
alpm_trans_cb_progress cb_progress);
int alpm_trans_sysupgrade(int enable_downgrade);
-int alpm_trans_addtarget(char *target);
+int alpm_trans_sync(char *target);
+int alpm_trans_add(char *target);
+int alpm_trans_remove(char *target);
int alpm_trans_prepare(alpm_list_t **data);
int alpm_trans_commit(alpm_list_t **data);
int alpm_trans_interrupt(void);
diff --git a/lib/libalpm/be_files.c b/lib/libalpm/be_files.c
index 9bb7b3dc..03a14637 100644
--- a/lib/libalpm/be_files.c
+++ b/lib/libalpm/be_files.c
@@ -148,7 +148,7 @@ static int checkdbdir(pmdb_t *db)
* pmdb_t *db;
* int result;
* db = alpm_list_getdata(alpm_option_get_syncdbs());
- * if(alpm_trans_init(PM_TRANS_TYPE_SYNC, 0, NULL, NULL, NULL) == 0) {
+ * if(alpm_trans_init(0, NULL, NULL, NULL) == 0) {
* result = alpm_db_update(0, db);
* alpm_trans_release();
*
@@ -191,7 +191,6 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
*/
ASSERT(handle->trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
ASSERT(handle->trans->state == STATE_INITIALIZED, RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1));
- ASSERT(handle->trans->type == PM_TRANS_TYPE_SYNC, RET_ERR(PM_ERR_TRANS_TYPE, -1));
if(!alpm_list_find_ptr(handle->dbs_sync, db)) {
RET_ERR(PM_ERR_DB_NOT_FOUND, -1);
diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c
index be97f004..e934c01e 100644
--- a/lib/libalpm/conflict.c
+++ b/lib/libalpm/conflict.c
@@ -516,7 +516,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans,
/* skip removal of file, but not add. this will prevent a second
* package from removing the file when it was already installed
* by its new owner (whether the file is in backup array or not */
- trans->skip_remove = alpm_list_add(trans->skip_remove, strdup(path));
+ trans->skip_remove = alpm_list_add(trans->skip_remove, strdup(filestr));
_alpm_log(PM_LOG_DEBUG, "file changed packages, adding to remove skiplist: %s\n", filestr);
resolved_conflict = 1;
}
diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c
index 2e0d0dfd..de171661 100644
--- a/lib/libalpm/package.c
+++ b/lib/libalpm/package.c
@@ -423,13 +423,6 @@ alpm_list_t SYMEXPORT *alpm_pkg_get_backup(pmpkg_t *pkg)
return pkg->backup;
}
-alpm_list_t SYMEXPORT *alpm_pkg_get_removes(pmpkg_t *pkg)
-{
- ASSERT(pkg != NULL, return(NULL));
-
- return(pkg->removes);
-}
-
pmdb_t SYMEXPORT *alpm_pkg_get_db(pmpkg_t *pkg)
{
/* Sanity checks */
diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c
index aa6a5cc7..4bebe3e5 100644
--- a/lib/libalpm/remove.c
+++ b/lib/libalpm/remove.c
@@ -65,7 +65,7 @@ int _alpm_remove_loadtarget(pmtrans_t *trans, pmdb_t *db, char *name)
targ = name;
}
- if(_alpm_pkg_find(trans->packages, targ)) {
+ if(_alpm_pkg_find(trans->remove, targ)) {
RET_ERR(PM_ERR_TRANS_DUP_TARGET, -1);
}
@@ -75,7 +75,7 @@ int _alpm_remove_loadtarget(pmtrans_t *trans, pmdb_t *db, char *name)
}
_alpm_log(PM_LOG_DEBUG, "adding %s in the targets list\n", info->name);
- trans->packages = alpm_list_add(trans->packages, _alpm_pkg_dup(info));
+ trans->remove = alpm_list_add(trans->remove, _alpm_pkg_dup(info));
return(0);
}
@@ -91,10 +91,10 @@ static void remove_prepare_cascade(pmtrans_t *trans, pmdb_t *db,
pmdepmissing_t *miss = (pmdepmissing_t *)i->data;
pmpkg_t *info = _alpm_db_get_pkgfromcache(db, miss->target);
if(info) {
- if(!_alpm_pkg_find(trans->packages, alpm_pkg_get_name(info))) {
+ if(!_alpm_pkg_find(trans->remove, alpm_pkg_get_name(info))) {
_alpm_log(PM_LOG_DEBUG, "pulling %s in the targets list\n",
alpm_pkg_get_name(info));
- trans->packages = alpm_list_add(trans->packages, _alpm_pkg_dup(info));
+ trans->remove = alpm_list_add(trans->remove, _alpm_pkg_dup(info));
}
} else {
_alpm_log(PM_LOG_ERROR, _("could not find %s in database -- skipping\n"),
@@ -103,7 +103,7 @@ static void remove_prepare_cascade(pmtrans_t *trans, pmdb_t *db,
}
alpm_list_free_inner(lp, (alpm_list_fn_free)_alpm_depmiss_free);
alpm_list_free(lp);
- lp = alpm_checkdeps(_alpm_db_get_pkgcache(db), 1, trans->packages, NULL);
+ lp = alpm_checkdeps(_alpm_db_get_pkgcache(db), 1, trans->remove, NULL);
}
}
@@ -118,11 +118,11 @@ static void remove_prepare_keep_needed(pmtrans_t *trans, pmdb_t *db,
for(i = lp; i; i = i->next) {
pmdepmissing_t *miss = (pmdepmissing_t *)i->data;
void *vpkg;
- pmpkg_t *pkg = _alpm_pkg_find(trans->packages, miss->causingpkg);
+ pmpkg_t *pkg = _alpm_pkg_find(trans->remove, miss->causingpkg);
if(pkg == NULL) {
continue;
}
- trans->packages = alpm_list_remove(trans->packages, pkg, _alpm_pkg_cmp,
+ trans->remove = alpm_list_remove(trans->remove, pkg, _alpm_pkg_cmp,
&vpkg);
pkg = vpkg;
if(pkg) {
@@ -133,7 +133,7 @@ static void remove_prepare_keep_needed(pmtrans_t *trans, pmdb_t *db,
}
alpm_list_free_inner(lp, (alpm_list_fn_free)_alpm_depmiss_free);
alpm_list_free(lp);
- lp = alpm_checkdeps(_alpm_db_get_pkgcache(db), 1, trans->packages, NULL);
+ lp = alpm_checkdeps(_alpm_db_get_pkgcache(db), 1, trans->remove, NULL);
}
}
@@ -146,21 +146,16 @@ int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data)
ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
- /* skip all checks if we are doing this removal as part of an upgrade */
- if(trans->type == PM_TRANS_TYPE_REMOVEUPGRADE) {
- return(0);
- }
-
if((trans->flags & PM_TRANS_FLAG_RECURSE) && !(trans->flags & PM_TRANS_FLAG_CASCADE)) {
_alpm_log(PM_LOG_DEBUG, "finding removable dependencies\n");
- _alpm_recursedeps(db, trans->packages, trans->flags & PM_TRANS_FLAG_RECURSEALL);
+ _alpm_recursedeps(db, trans->remove, trans->flags & PM_TRANS_FLAG_RECURSEALL);
}
if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) {
EVENT(trans, PM_TRANS_EVT_CHECKDEPS_START, NULL, NULL);
_alpm_log(PM_LOG_DEBUG, "looking for unsatisfied dependencies\n");
- lp = alpm_checkdeps(_alpm_db_get_pkgcache(db), 1, trans->packages, NULL);
+ lp = alpm_checkdeps(_alpm_db_get_pkgcache(db), 1, trans->remove, NULL);
if(lp != NULL) {
if(trans->flags & PM_TRANS_FLAG_CASCADE) {
@@ -183,15 +178,15 @@ int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data)
/* re-order w.r.t. dependencies */
_alpm_log(PM_LOG_DEBUG, "sorting by dependencies\n");
- lp = _alpm_sortbydeps(trans->packages, 1);
+ lp = _alpm_sortbydeps(trans->remove, 1);
/* free the old alltargs */
- alpm_list_free(trans->packages);
- trans->packages = lp;
+ alpm_list_free(trans->remove);
+ trans->remove = lp;
/* -Rcs == -Rc then -Rs */
if((trans->flags & PM_TRANS_FLAG_CASCADE) && (trans->flags & PM_TRANS_FLAG_RECURSE)) {
_alpm_log(PM_LOG_DEBUG, "finding removable dependencies\n");
- _alpm_recursedeps(db, trans->packages, trans->flags & PM_TRANS_FLAG_RECURSEALL);
+ _alpm_recursedeps(db, trans->remove, trans->flags & PM_TRANS_FLAG_RECURSEALL);
}
if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) {
@@ -201,13 +196,13 @@ int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data)
return(0);
}
-static int can_remove_file(pmtrans_t *trans, const char *path)
+static int can_remove_file(const char *path, alpm_list_t *skip)
{
char file[PATH_MAX+1];
snprintf(file, PATH_MAX, "%s%s", handle->root, path);
- if(alpm_list_find_str(trans->skip_remove, file)) {
+ if(alpm_list_find_str(skip, file)) {
/* return success because we will never actually remove this file */
return(1);
}
@@ -228,7 +223,7 @@ static int can_remove_file(pmtrans_t *trans, const char *path)
/* Helper function for iterating through a package's file and deleting them
* Used by _alpm_remove_commit. */
-static void unlink_file(pmpkg_t *info, char *filename, pmtrans_t *trans)
+static void unlink_file(pmpkg_t *info, char *filename, alpm_list_t *skip_remove, int nosave)
{
struct stat buf;
char file[PATH_MAX+1];
@@ -237,13 +232,13 @@ static void unlink_file(pmpkg_t *info, char *filename, pmtrans_t *trans)
snprintf(file, PATH_MAX, "%s%s", handle->root, filename);
- if(trans->type == PM_TRANS_TYPE_REMOVEUPGRADE) {
- /* check noupgrade */
- if(alpm_list_find_str(handle->noupgrade, filename)) {
- _alpm_log(PM_LOG_DEBUG, "Skipping removal of '%s' due to NoUpgrade\n",
- file);
- return;
- }
+ /* check the remove skip list before removing the file.
+ * see the big comment block in db_find_fileconflicts() for an
+ * explanation. */
+ if(alpm_list_find_str(skip_remove, filename)) {
+ _alpm_log(PM_LOG_DEBUG, "%s is in skip_remove, skipping removal\n",
+ file);
+ return;
}
/* we want to do a lstat here, and not a _alpm_lstat.
@@ -263,19 +258,10 @@ static void unlink_file(pmpkg_t *info, char *filename, pmtrans_t *trans)
_alpm_log(PM_LOG_DEBUG, "removing directory %s\n", file);
}
} else {
- /* check the remove skip list before removing the file.
- * see the big comment block in db_find_fileconflicts() for an
- * explanation. */
- if(alpm_list_find_str(trans->skip_remove, file)) {
- _alpm_log(PM_LOG_DEBUG, "%s is in trans->skip_remove, skipping removal\n",
- file);
- return;
- }
-
/* if the file needs backup and has been modified, back it up to .pacsave */
char *pkghash = _alpm_needbackup(filename, alpm_pkg_get_backup(info));
if(pkghash) {
- if(trans->flags & PM_TRANS_FLAG_NOSAVE) {
+ if(nosave) {
_alpm_log(PM_LOG_DEBUG, "transaction is set to NOSAVE, not backing up '%s'\n", file);
FREE(pkghash);
} else {
@@ -303,7 +289,69 @@ static void unlink_file(pmpkg_t *info, char *filename, pmtrans_t *trans)
}
}
-int _alpm_remove_commit(pmtrans_t *trans, pmdb_t *db)
+int _alpm_upgraderemove_package(pmpkg_t *oldpkg, pmpkg_t *newpkg, pmtrans_t *trans)
+{
+ alpm_list_t *skip_remove, *b;
+ alpm_list_t *newfiles, *lp;
+ alpm_list_t *files = alpm_pkg_get_files(oldpkg);
+ const char *pkgname = alpm_pkg_get_name(oldpkg);
+
+ ALPM_LOG_FUNC;
+
+ _alpm_log(PM_LOG_DEBUG, "removing old package first (%s-%s)\n",
+ oldpkg->name, oldpkg->version);
+
+ /* copy the remove skiplist over */
+ skip_remove =
+ alpm_list_join(alpm_list_strdup(trans->skip_remove),alpm_list_strdup(handle->noupgrade));
+ /* Add files in the NEW backup array to the skip_remove array
+ * so this removal operation doesn't kill them */
+ /* old package backup list */
+ alpm_list_t *filelist = alpm_pkg_get_files(newpkg);
+ for(b = alpm_pkg_get_backup(newpkg); b; b = b->next) {
+ char *backup = _alpm_backup_file(b->data);
+ /* safety check (fix the upgrade026 pactest) */
+ if(!alpm_list_find_str(filelist, backup)) {
+ FREE(backup);
+ continue;
+ }
+ _alpm_log(PM_LOG_DEBUG, "adding %s to the skip_remove array\n", backup);
+ skip_remove = alpm_list_add(skip_remove, backup);
+ }
+
+ for(lp = files; lp; lp = lp->next) {
+ if(!can_remove_file(lp->data, skip_remove)) {
+ _alpm_log(PM_LOG_DEBUG, "not removing package '%s', can't remove all files\n",
+ pkgname);
+ RET_ERR(PM_ERR_PKG_CANT_REMOVE, -1);
+ }
+ }
+
+ /* iterate through the list backwards, unlinking files */
+ newfiles = alpm_list_reverse(files);
+ for(lp = newfiles; lp; lp = alpm_list_next(lp)) {
+ unlink_file(oldpkg, lp->data, skip_remove, 0);
+ }
+ alpm_list_free(newfiles);
+ FREELIST(skip_remove);
+
+ /* remove the package from the database */
+ _alpm_log(PM_LOG_DEBUG, "updating database\n");
+ _alpm_log(PM_LOG_DEBUG, "removing database entry '%s'\n", pkgname);
+ if(_alpm_db_remove(handle->db_local, oldpkg) == -1) {
+ _alpm_log(PM_LOG_ERROR, _("could not remove database entry %s-%s\n"),
+ pkgname, alpm_pkg_get_version(oldpkg));
+ }
+ /* remove the package from the cache */
+ if(_alpm_db_remove_pkgfromcache(handle->db_local, oldpkg) == -1) {
+ _alpm_log(PM_LOG_ERROR, _("could not remove entry '%s' from cache\n"),
+ pkgname);
+ }
+
+ return(0);
+}
+
+int _alpm_remove_packages(pmtrans_t *trans, pmdb_t *db)
{
pmpkg_t *info;
alpm_list_t *targ, *lp;
@@ -314,12 +362,11 @@ int _alpm_remove_commit(pmtrans_t *trans, pmdb_t *db)
ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
- pkg_count = alpm_list_count(trans->packages);
+ pkg_count = alpm_list_count(trans->remove);
- for(targ = trans->packages; targ; targ = targ->next) {
+ for(targ = trans->remove; targ; targ = targ->next) {
int position = 0;
char scriptlet[PATH_MAX];
- alpm_list_t *files;
info = (pmpkg_t*)targ->data;
const char *pkgname = NULL;
@@ -332,23 +379,21 @@ int _alpm_remove_commit(pmtrans_t *trans, pmdb_t *db)
snprintf(scriptlet, PATH_MAX, "%s%s-%s/install", db->path,
pkgname, alpm_pkg_get_version(info));
- if(trans->type != PM_TRANS_TYPE_REMOVEUPGRADE) {
- EVENT(trans, PM_TRANS_EVT_REMOVE_START, info, NULL);
- _alpm_log(PM_LOG_DEBUG, "removing package %s-%s\n",
- pkgname, alpm_pkg_get_version(info));
+ EVENT(trans, PM_TRANS_EVT_REMOVE_START, info, NULL);
+ _alpm_log(PM_LOG_DEBUG, "removing package %s-%s\n",
+ pkgname, alpm_pkg_get_version(info));
- /* run the pre-remove scriptlet if it exists */
- if(alpm_pkg_has_scriptlet(info) && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) {
- _alpm_runscriptlet(handle->root, scriptlet, "pre_remove",
- alpm_pkg_get_version(info), NULL, trans);
- }
+ /* run the pre-remove scriptlet if it exists */
+ if(alpm_pkg_has_scriptlet(info) && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) {
+ _alpm_runscriptlet(handle->root, scriptlet, "pre_remove",
+ alpm_pkg_get_version(info), NULL, trans);
}
- files = alpm_pkg_get_files(info);
if(!(trans->flags & PM_TRANS_FLAG_DBONLY)) {
+ alpm_list_t *files = alpm_pkg_get_files(info);
for(lp = files; lp; lp = lp->next) {
- if(!can_remove_file(trans, lp->data)) {
+ if(!can_remove_file(lp->data, NULL)) {
_alpm_log(PM_LOG_DEBUG, "not removing package '%s', can't remove all files\n",
pkgname);
RET_ERR(PM_ERR_PKG_CANT_REMOVE, -1);
@@ -363,7 +408,7 @@ int _alpm_remove_commit(pmtrans_t *trans, pmdb_t *db)
/* iterate through the list backwards, unlinking files */
newfiles = alpm_list_reverse(files);
for(lp = newfiles; lp; lp = alpm_list_next(lp)) {
- unlink_file(info, lp->data, trans);
+ unlink_file(info, lp->data, NULL, trans->flags & PM_TRANS_FLAG_NOSAVE);
/* update progress bar after each file */
percent = (double)position / (double)filenum;
@@ -379,12 +424,10 @@ int _alpm_remove_commit(pmtrans_t *trans, pmdb_t *db)
PROGRESS(trans, PM_TRANS_PROGRESS_REMOVE_START, pkgname, 100,
pkg_count, (pkg_count - alpm_list_count(targ) + 1));
- if(trans->type != PM_TRANS_TYPE_REMOVEUPGRADE) {
- /* run the post-remove script if it exists */
- if(alpm_pkg_has_scriptlet(info) && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) {
- _alpm_runscriptlet(handle->root, scriptlet, "post_remove",
- alpm_pkg_get_version(info), NULL, trans);
- }
+ /* run the post-remove script if it exists */
+ if(alpm_pkg_has_scriptlet(info) && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) {
+ _alpm_runscriptlet(handle->root, scriptlet, "post_remove",
+ alpm_pkg_get_version(info), NULL, trans);
}
/* remove the package from the database */
@@ -400,16 +443,11 @@ int _alpm_remove_commit(pmtrans_t *trans, pmdb_t *db)
pkgname);
}
- /* call a done event if this isn't an upgrade */
- if(trans->type != PM_TRANS_TYPE_REMOVEUPGRADE) {
- EVENT(trans, PM_TRANS_EVT_REMOVE_DONE, info, NULL);
- }
+ EVENT(trans, PM_TRANS_EVT_REMOVE_DONE, info, NULL);
}
/* run ldconfig if it exists */
- if(trans->type != PM_TRANS_TYPE_REMOVEUPGRADE) {
- _alpm_ldconfig(handle->root);
- }
+ _alpm_ldconfig(handle->root);
return(0);
}
diff --git a/lib/libalpm/remove.h b/lib/libalpm/remove.h
index 716fbf72..9697f8c3 100644
--- a/lib/libalpm/remove.h
+++ b/lib/libalpm/remove.h
@@ -26,7 +26,10 @@
int _alpm_remove_loadtarget(pmtrans_t *trans, pmdb_t *db, char *name);
int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data);
-int _alpm_remove_commit(pmtrans_t *trans, pmdb_t *db);
+int _alpm_remove_packages(pmtrans_t *trans, pmdb_t *db);
+
+int _alpm_upgraderemove_package(pmpkg_t *oldpkg, pmpkg_t *newpkg, pmtrans_t *trans);
+
#endif /* _ALPM_REMOVE_H */
diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c
index a738d1b8..d676778b 100644
--- a/lib/libalpm/sync.c
+++ b/lib/libalpm/sync.c
@@ -49,6 +49,7 @@
#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)
@@ -91,7 +92,7 @@ int _alpm_sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_s
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;
}
@@ -114,7 +115,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) {
@@ -125,7 +126,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"),
@@ -153,7 +154,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) {
@@ -174,7 +175,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);
}
}
}
@@ -238,7 +239,7 @@ int _alpm_sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sy
return(-1);
}
- 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);
}
@@ -268,7 +269,7 @@ 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);
}
@@ -329,8 +330,8 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
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;
@@ -351,7 +352,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
_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) {
+ 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);
@@ -361,7 +362,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
/* 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,
&resolved, remove, data) == -1) {
@@ -401,7 +402,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
/* 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;
}
}
@@ -411,8 +412,8 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
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);
@@ -426,15 +427,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;
}
@@ -474,7 +475,7 @@ 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->packages = alpm_list_remove(trans->packages, rsync, _alpm_pkg_cmp, NULL);
+ trans->add = alpm_list_remove(trans->add, rsync, _alpm_pkg_cmp, NULL);
_alpm_pkg_free_trans(rsync); /* rsync is not transaction target anymore */
continue;
}
@@ -485,7 +486,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;
@@ -493,7 +494,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;
@@ -506,7 +507,7 @@ 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,
@@ -538,16 +539,16 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) {
/* rebuild remove list */
alpm_list_free(remove);
- remove = NULL;
- for(i = trans->packages; i; i = i->next) {
+ trans->remove = NULL;
+ 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);
+ trans->remove = alpm_list_add(trans->remove, _alpm_pkg_dup(j->data));
}
}
_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;
@@ -560,7 +561,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) {
@@ -570,7 +571,6 @@ 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);
return(ret);
@@ -607,7 +607,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;
@@ -717,7 +717,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;
int replaces = 0;
int errors = 0;
const char *cachedir = NULL;
@@ -736,7 +735,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;
}
@@ -747,7 +746,7 @@ 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;
if(spkg->origin == PKG_FROM_CACHE && current == spkg->origin_data.db) {
@@ -840,7 +839,7 @@ 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 */
@@ -868,7 +867,6 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
}
FREE(filepath);
pkgfile->reason = spkg->reason; /* copy over install reason */
- pkgfile->removes = alpm_list_copy(spkg->removes); /* copy over removes list */
i->data = pkgfile;
_alpm_pkg_free_trans(spkg); /* spkg has been removed from the target list */
}
@@ -883,32 +881,7 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
trans->state = STATE_COMMITING;
- /* Create remove transaction */
- tr_remove = _alpm_trans_new();
- if(tr_remove == NULL) {
- _alpm_log(PM_LOG_ERROR, _("could not create removal 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;
- }
-
- /* adding targets to the remove transaction */
- for(i = trans->packages; i; i = i->next) {
- pmpkg_t *spkg = i->data;
- alpm_list_t *j;
- 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++;
- }
- }
- }
+ replaces = alpm_list_count(trans->remove);
/* fileconflict check */
if(!(trans->flags & PM_TRANS_FLAG_FORCE)) {
@@ -916,7 +889,7 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
_alpm_log(PM_LOG_DEBUG, "looking for file conflicts\n");
alpm_list_t *conflict = _alpm_db_find_fileconflicts(db_local, trans,
- trans->packages, tr_remove->packages);
+ trans->add, trans->remove);
if(conflict) {
pm_errno = PM_ERR_FILE_CONFLICTS;
if(data) {
@@ -934,14 +907,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;
}
@@ -958,7 +925,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);
return(ret);
}
diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c
index f913ba9e..74ce418a 100644
--- a/lib/libalpm/trans.c
+++ b/lib/libalpm/trans.c
@@ -52,17 +52,18 @@
*/
/** Initialize the transaction.
- * @param type type of the transaction
* @param flags flags of the transaction (like nodeps, etc)
* @param event event callback function pointer
* @param conv question callback function pointer
* @param progress progress callback function pointer
* @return 0 on success, -1 on error (pm_errno is set accordingly)
*/
-int SYMEXPORT alpm_trans_init(pmtranstype_t type, pmtransflag_t flags,
+int SYMEXPORT alpm_trans_init(pmtransflag_t flags,
alpm_trans_cb_event event, alpm_trans_cb_conv conv,
alpm_trans_cb_progress progress)
{
+ pmtrans_t *trans;
+
ALPM_LOG_FUNC;
/* Sanity checks */
@@ -78,12 +79,20 @@ int SYMEXPORT alpm_trans_init(pmtranstype_t type, pmtransflag_t flags,
}
}
- handle->trans = _alpm_trans_new();
- if(handle->trans == NULL) {
+ trans = _alpm_trans_new();
+ if(trans == NULL) {
RET_ERR(PM_ERR_MEMORY, -1);
}
- return(_alpm_trans_init(handle->trans, type, flags, event, conv, progress));
+ trans->flags = flags;
+ trans->cb_event = event;
+ trans->cb_conv = conv;
+ trans->cb_progress = progress;
+ trans->state = STATE_INITIALIZED;
+
+ handle->trans = trans;
+
+ return(0);
}
/** Search for packages to upgrade and add them to the transaction.
@@ -100,16 +109,41 @@ int SYMEXPORT alpm_trans_sysupgrade(int enable_downgrade)
trans = handle->trans;
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
ASSERT(trans->state == STATE_INITIALIZED, RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1));
- ASSERT(trans->type == PM_TRANS_TYPE_SYNC, RET_ERR(PM_ERR_TRANS_TYPE, -1));
return(_alpm_sync_sysupgrade(trans, handle->db_local, handle->dbs_sync, enable_downgrade));
}
-/** Add a target to the transaction.
- * @param target the name of the target to add
+/** Add a file target to the transaction.
+ * @param target the name of the file target to add
+ * @return 0 on success, -1 on error (pm_errno is set accordingly)
+ */
+int SYMEXPORT alpm_trans_add(char *target)
+{
+ pmtrans_t *trans;
+
+ ALPM_LOG_FUNC;
+
+ /* Sanity checks */
+ ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
+ ASSERT(target != NULL && strlen(target) != 0, RET_ERR(PM_ERR_WRONG_ARGS, -1));
+
+ trans = handle->trans;
+ ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
+ ASSERT(trans->state == STATE_INITIALIZED, RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1));
+
+ if(_alpm_add_loadtarget(trans, handle->db_local, target) == -1) {
+ /* pm_errno is set by _alpm_add_loadtarget() */
+ return(-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_trans_addtarget(char *target)
+int SYMEXPORT alpm_trans_sync(char *target)
{
pmtrans_t *trans;
@@ -123,7 +157,61 @@ int SYMEXPORT alpm_trans_addtarget(char *target)
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
ASSERT(trans->state == STATE_INITIALIZED, RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1));
- return(_alpm_trans_addtarget(trans, target));
+ if(_alpm_sync_addtarget(trans, handle->db_local, handle->dbs_sync, target) == -1) {
+ /* pm_errno is set by _alpm_sync_loadtarget() */
+ return(-1);
+ }
+
+ return(0);
+}
+
+int SYMEXPORT alpm_trans_remove(char *target)
+{
+ ALPM_LOG_FUNC;
+
+ pmtrans_t *trans;
+
+ ALPM_LOG_FUNC;
+
+ /* Sanity checks */
+ ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
+ ASSERT(target != NULL && strlen(target) != 0, RET_ERR(PM_ERR_WRONG_ARGS, -1));
+
+ trans = handle->trans;
+ ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
+ ASSERT(trans->state == STATE_INITIALIZED, RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1));
+
+ if(_alpm_remove_loadtarget(trans, handle->db_local, target) == -1) {
+ /* pm_errno is set by _alpm_remove_loadtarget() */
+ return(-1);
+ }
+
+ return(0);
+}
+
+static alpm_list_t *check_arch(alpm_list_t *pkgs)
+{
+ alpm_list_t *i;
+ alpm_list_t *invalid = NULL;
+
+ const char *arch = alpm_option_get_arch();
+ if(!arch) {
+ return(NULL);
+ }
+ for(i = pkgs; i; i = i->next) {
+ pmpkg_t *pkg = i->data;
+ const char *pkgarch = alpm_pkg_get_arch(pkg);
+ if(strcmp(pkgarch,arch) && strcmp(pkgarch,"any")) {
+ char *string;
+ const char *pkgname = alpm_pkg_get_name(pkg);
+ const char *pkgver = alpm_pkg_get_version(pkg);
+ size_t len = strlen(pkgname) + strlen(pkgver) + strlen(pkgarch) + 3;
+ MALLOC(string, len, RET_ERR(PM_ERR_MEMORY, invalid));
+ sprintf(string, "%s-%s-%s", pkgname, pkgver, pkgarch);
+ invalid = alpm_list_add(invalid, string);
+ }
+ }
+ return(invalid);
}
/** Prepare a transaction.
@@ -133,16 +221,47 @@ int SYMEXPORT alpm_trans_addtarget(char *target)
*/
int SYMEXPORT alpm_trans_prepare(alpm_list_t **data)
{
+ pmtrans_t *trans;
+
ALPM_LOG_FUNC;
/* Sanity checks */
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
ASSERT(data != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
- ASSERT(handle->trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
- ASSERT(handle->trans->state == STATE_INITIALIZED, RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1));
+ trans = handle->trans;
- return(_alpm_trans_prepare(handle->trans, data));
+ ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
+ ASSERT(trans->state == STATE_INITIALIZED, RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1));
+
+ /* If there's nothing to do, return without complaining */
+ if(trans->add == NULL && trans->remove == NULL) {
+ return(0);
+ }
+
+ alpm_list_t *invalid = check_arch(trans->add);
+ if(invalid) {
+ if(data) {
+ *data = invalid;
+ }
+ RET_ERR(PM_ERR_PKG_INVALID_ARCH, -1);
+ }
+
+ if(trans->add == NULL) {
+ if(_alpm_remove_prepare(trans, handle->db_local, data) == -1) {
+ /* pm_errno is set by _alpm_remove_prepare() */
+ return(-1);
+ }
+ } else {
+ if(_alpm_sync_prepare(trans, handle->db_local, handle->dbs_sync, data) == -1) {
+ /* pm_errno is set by _alpm_sync_prepare() */
+ return(-1);
+ }
+ }
+
+ trans->state = STATE_PREPARED;
+
+ return(0);
}
/** Commit a transaction.
@@ -152,17 +271,42 @@ int SYMEXPORT alpm_trans_prepare(alpm_list_t **data)
*/
int SYMEXPORT alpm_trans_commit(alpm_list_t **data)
{
+ pmtrans_t *trans;
+
ALPM_LOG_FUNC;
/* Sanity checks */
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
- ASSERT(handle->trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
- ASSERT(handle->trans->state == STATE_PREPARED, RET_ERR(PM_ERR_TRANS_NOT_PREPARED, -1));
+ trans = handle->trans;
+
+ ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
+ ASSERT(trans->state == STATE_PREPARED, RET_ERR(PM_ERR_TRANS_NOT_PREPARED, -1));
+
+ ASSERT(!(trans->flags & PM_TRANS_FLAG_NOLOCK), RET_ERR(PM_ERR_TRANS_NOT_LOCKED, -1));
+
+ /* If there's nothing to do, return without complaining */
+ if(trans->add == NULL && trans->remove == NULL) {
+ return(0);
+ }
+
+ trans->state = STATE_COMMITING;
+
+ if(trans->add == NULL) {
+ if(_alpm_remove_packages(trans, handle->db_local) == -1) {
+ /* pm_errno is set by _alpm_remove_commit() */
+ return(-1);
+ }
+ } else {
+ if(_alpm_sync_commit(trans, handle->db_local, data) == -1) {
+ /* pm_errno is set by _alpm_sync_commit() */
+ return(-1);
+ }
+ }
- ASSERT(!(handle->trans->flags & PM_TRANS_FLAG_NOLOCK), RET_ERR(PM_ERR_TRANS_NOT_LOCKED, -1));
+ trans->state = STATE_COMMITED;
- return(_alpm_trans_commit(handle->trans, data));
+ return(0);
}
/** Interrupt a transaction.
@@ -247,12 +391,10 @@ void _alpm_trans_free(pmtrans_t *trans)
return;
}
- if(trans->type == PM_TRANS_TYPE_SYNC || trans->type == PM_TRANS_TYPE_UPGRADE) {
- alpm_list_free_inner(trans->packages, (alpm_list_fn_free)_alpm_pkg_free_trans);
- } else {
- alpm_list_free_inner(trans->packages, (alpm_list_fn_free)_alpm_pkg_free);
- }
- alpm_list_free(trans->packages);
+ alpm_list_free_inner(trans->add, (alpm_list_fn_free)_alpm_pkg_free_trans);
+ alpm_list_free(trans->add);
+ alpm_list_free_inner(trans->remove, (alpm_list_fn_free)_alpm_pkg_free);
+ alpm_list_free(trans->remove);
FREELIST(trans->skip_add);
FREELIST(trans->skip_remove);
@@ -260,173 +402,6 @@ void _alpm_trans_free(pmtrans_t *trans)
FREE(trans);
}
-int _alpm_trans_init(pmtrans_t *trans, pmtranstype_t type, pmtransflag_t flags,
- alpm_trans_cb_event event, alpm_trans_cb_conv conv,
- alpm_trans_cb_progress progress)
-{
- ALPM_LOG_FUNC;
-
- /* Sanity checks */
- ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
-
- trans->type = type;
- trans->flags = flags;
- trans->cb_event = event;
- trans->cb_conv = conv;
- trans->cb_progress = progress;
- trans->state = STATE_INITIALIZED;
-
- return(0);
-}
-
-/** Add a target to the transaction.
- * @param trans the current transaction
- * @param target the name of the target to add
- * @return 0 on success, -1 on error (pm_errno is set accordingly)
- */
-int _alpm_trans_addtarget(pmtrans_t *trans, char *target)
-{
- ALPM_LOG_FUNC;
-
- /* Sanity checks */
- ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
- ASSERT(target != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
-
- switch(trans->type) {
- case PM_TRANS_TYPE_UPGRADE:
- if(_alpm_add_loadtarget(trans, handle->db_local, target) == -1) {
- /* pm_errno is set by _alpm_add_loadtarget() */
- return(-1);
- }
- break;
- case PM_TRANS_TYPE_REMOVE:
- case PM_TRANS_TYPE_REMOVEUPGRADE:
- if(_alpm_remove_loadtarget(trans, handle->db_local, target) == -1) {
- /* pm_errno is set by _alpm_remove_loadtarget() */
- return(-1);
- }
- break;
- case PM_TRANS_TYPE_SYNC:
- if(_alpm_sync_addtarget(trans, handle->db_local, handle->dbs_sync, target) == -1) {
- /* pm_errno is set by _alpm_sync_loadtarget() */
- return(-1);
- }
- break;
- }
-
- return(0);
-}
-
-static alpm_list_t *check_arch(alpm_list_t *pkgs)
-{
- alpm_list_t *i;
- alpm_list_t *invalid = NULL;
-
- const char *arch = alpm_option_get_arch();
- if(!arch) {
- return(NULL);
- }
- for(i = pkgs; i; i = i->next) {
- pmpkg_t *pkg = i->data;
- const char *pkgarch = alpm_pkg_get_arch(pkg);
- if(strcmp(pkgarch,arch) && strcmp(pkgarch,"any")) {
- char *string;
- const char *pkgname = alpm_pkg_get_name(pkg);
- const char *pkgver = alpm_pkg_get_version(pkg);
- size_t len = strlen(pkgname) + strlen(pkgver) + strlen(pkgarch) + 3;
- MALLOC(string, len, RET_ERR(PM_ERR_MEMORY, invalid));
- sprintf(string, "%s-%s-%s", pkgname, pkgver, pkgarch);
- invalid = alpm_list_add(invalid, string);
- }
- }
- return(invalid);
-}
-
-int _alpm_trans_prepare(pmtrans_t *trans, alpm_list_t **data)
-{
- if(data) {
- *data = NULL;
- }
-
- ALPM_LOG_FUNC;
-
- /* Sanity checks */
- ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
-
- /* If there's nothing to do, return without complaining */
- if(trans->packages == NULL) {
- return(0);
- }
-
- alpm_list_t *invalid = check_arch(trans->packages);
- if(invalid) {
- if(data) {
- *data = invalid;
- }
- RET_ERR(PM_ERR_PKG_INVALID_ARCH, -1);
- }
-
- switch(trans->type) {
- case PM_TRANS_TYPE_REMOVE:
- case PM_TRANS_TYPE_REMOVEUPGRADE:
- if(_alpm_remove_prepare(trans, handle->db_local, data) == -1) {
- /* pm_errno is set by _alpm_remove_prepare() */
- return(-1);
- }
- break;
- case PM_TRANS_TYPE_UPGRADE:
- case PM_TRANS_TYPE_SYNC:
- if(_alpm_sync_prepare(trans, handle->db_local, handle->dbs_sync, data) == -1) {
- /* pm_errno is set by _alpm_sync_prepare() */
- return(-1);
- }
- break;
- }
-
- trans->state = STATE_PREPARED;
-
- return(0);
-}
-
-int _alpm_trans_commit(pmtrans_t *trans, alpm_list_t **data)
-{
- ALPM_LOG_FUNC;
-
- if(data!=NULL)
- *data = NULL;
-
- /* Sanity checks */
- ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
-
- /* If there's nothing to do, return without complaining */
- if(trans->packages == NULL) {
- return(0);
- }
-
- trans->state = STATE_COMMITING;
-
- switch(trans->type) {
- case PM_TRANS_TYPE_REMOVE:
- case PM_TRANS_TYPE_REMOVEUPGRADE:
- if(_alpm_remove_commit(trans, handle->db_local) == -1) {
- /* pm_errno is set by _alpm_remove_commit() */
- return(-1);
- }
- break;
- case PM_TRANS_TYPE_UPGRADE:
- case PM_TRANS_TYPE_SYNC:
- if(_alpm_sync_commit(trans, handle->db_local, data) == -1) {
- /* pm_errno is set by _alpm_sync_commit() */
- return(-1);
- }
- break;
- }
-
- trans->state = STATE_COMMITED;
-
- return(0);
-}
-
/* A cheap grep for text files, returns 1 if a substring
* was found in the text file fn, 0 if it wasn't
*/
@@ -526,30 +501,30 @@ cleanup:
return(retval);
}
-pmtranstype_t SYMEXPORT alpm_trans_get_type()
+unsigned int SYMEXPORT alpm_trans_get_flags()
{
/* Sanity checks */
ASSERT(handle != NULL, return(-1));
ASSERT(handle->trans != NULL, return(-1));
- return handle->trans->type;
+ return handle->trans->flags;
}
-unsigned int SYMEXPORT alpm_trans_get_flags()
+alpm_list_t SYMEXPORT * alpm_trans_get_add()
{
/* Sanity checks */
- ASSERT(handle != NULL, return(-1));
- ASSERT(handle->trans != NULL, return(-1));
+ ASSERT(handle != NULL, return(NULL));
+ ASSERT(handle->trans != NULL, return(NULL));
- return handle->trans->flags;
+ return handle->trans->add;
}
-alpm_list_t SYMEXPORT * alpm_trans_get_pkgs()
+alpm_list_t SYMEXPORT * alpm_trans_get_remove()
{
/* Sanity checks */
ASSERT(handle != NULL, return(NULL));
ASSERT(handle->trans != NULL, return(NULL));
- return handle->trans->packages;
+ return handle->trans->remove;
}
/* vim: set ts=2 sw=2 noet: */
diff --git a/lib/libalpm/trans.h b/lib/libalpm/trans.h
index 0537bc72..ca1e141a 100644
--- a/lib/libalpm/trans.h
+++ b/lib/libalpm/trans.h
@@ -37,10 +37,10 @@ typedef enum _pmtransstate_t {
/* Transaction */
struct __pmtrans_t {
- pmtranstype_t type;
pmtransflag_t flags;
pmtransstate_t state;
- alpm_list_t *packages; /* list of (pmpkg_t *) */
+ alpm_list_t *add; /* list of (pmpkg_t *) */
+ alpm_list_t *remove; /* list of (pmpkg_t *) */
alpm_list_t *skip_add; /* list of (char *) */
alpm_list_t *skip_remove; /* list of (char *) */
alpm_trans_cb_event cb_event;
@@ -69,12 +69,9 @@ do { \
pmtrans_t *_alpm_trans_new(void);
void _alpm_trans_free(pmtrans_t *trans);
-int _alpm_trans_init(pmtrans_t *trans, pmtranstype_t type, pmtransflag_t flags,
+int _alpm_trans_init(pmtrans_t *trans, pmtransflag_t flags,
alpm_trans_cb_event event, alpm_trans_cb_conv conv,
alpm_trans_cb_progress progress);
-int _alpm_trans_addtarget(pmtrans_t *trans, char *target);
-int _alpm_trans_prepare(pmtrans_t *trans, alpm_list_t **data);
-int _alpm_trans_commit(pmtrans_t *trans, alpm_list_t **data);
int _alpm_runscriptlet(const char *root, const char *installfn,
const char *script, const char *ver,
const char *oldver, pmtrans_t *trans);