diff options
Diffstat (limited to 'lib/libalpm')
| -rw-r--r-- | lib/libalpm/add.c | 100 | ||||
| -rw-r--r-- | lib/libalpm/alpm.h | 18 | ||||
| -rw-r--r-- | lib/libalpm/be_files.c | 3 | ||||
| -rw-r--r-- | lib/libalpm/conflict.c | 2 | ||||
| -rw-r--r-- | lib/libalpm/package.c | 7 | ||||
| -rw-r--r-- | lib/libalpm/remove.c | 174 | ||||
| -rw-r--r-- | lib/libalpm/remove.h | 5 | ||||
| -rw-r--r-- | lib/libalpm/sync.c | 100 | ||||
| -rw-r--r-- | lib/libalpm/trans.c | 371 | ||||
| -rw-r--r-- | lib/libalpm/trans.h | 9 | 
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);  | 
