From 8ff3b87066d35d3518a3cd0bef27b86c3a85e983 Mon Sep 17 00:00:00 2001 From: Xavier Chantry Date: Wed, 15 Jul 2009 19:14:01 +0200 Subject: Remove transaction type This basically started with this change : /* 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 *) */ And then I have to modify all the code accordingly. --- lib/libalpm/add.c | 100 ++----------- lib/libalpm/alpm.h | 18 +-- lib/libalpm/be_files.c | 3 +- lib/libalpm/conflict.c | 2 +- lib/libalpm/package.c | 7 - lib/libalpm/remove.c | 174 ++++++++++++++--------- lib/libalpm/remove.h | 5 +- lib/libalpm/sync.c | 100 +++++-------- lib/libalpm/trans.c | 371 +++++++++++++++++++++++-------------------------- lib/libalpm/trans.h | 9 +- 10 files changed, 335 insertions(+), 454 deletions(-) (limited to 'lib') 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); -- cgit v1.2.3-70-g09d2