Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/lib/libalpm/trans.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libalpm/trans.c')
-rw-r--r--lib/libalpm/trans.c320
1 files changed, 114 insertions, 206 deletions
diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c
index 6e847e64..4879d236 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,38 +79,53 @@ 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));
-}
-
-/** Search for packages to upgrade and add them to the transaction.
- * @return 0 on success, -1 on error (pm_errno is set accordingly)
- */
-int SYMEXPORT alpm_trans_sysupgrade(int enable_downgrade)
-{
- pmtrans_t *trans;
+ trans->flags = flags;
+ trans->cb_event = event;
+ trans->cb_conv = conv;
+ trans->cb_progress = progress;
+ trans->state = STATE_INITIALIZED;
- ALPM_LOG_FUNC;
+ handle->trans = trans;
- ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
+ return(0);
+}
- 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));
+static alpm_list_t *check_arch(alpm_list_t *pkgs)
+{
+ alpm_list_t *i;
+ alpm_list_t *invalid = NULL;
- return(_alpm_sync_sysupgrade(trans, handle->db_local, handle->dbs_sync, enable_downgrade));
+ 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);
}
-/** Add a target to the transaction.
- * @param target the name of the target to add
+/** Prepare a transaction.
+ * @param data the address of an alpm_list where detailed description
+ * of an error can be dumped (ie. list of conflicting files)
* @return 0 on success, -1 on error (pm_errno is set accordingly)
*/
-int SYMEXPORT alpm_trans_addtarget(char *target)
+int SYMEXPORT alpm_trans_prepare(alpm_list_t **data)
{
pmtrans_t *trans;
@@ -117,32 +133,41 @@ int SYMEXPORT alpm_trans_addtarget(char *target)
/* 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));
+ ASSERT(data != NULL, 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));
- return(_alpm_trans_addtarget(trans, target));
-}
+ /* If there's nothing to do, return without complaining */
+ if(trans->add == NULL && trans->remove == NULL) {
+ return(0);
+ }
-/** Prepare a transaction.
- * @param data the address of an alpm_list where detailed description
- * of an error can be dumped (ie. list of conflicting files)
- * @return 0 on success, -1 on error (pm_errno is set accordingly)
- */
-int SYMEXPORT alpm_trans_prepare(alpm_list_t **data)
-{
- ALPM_LOG_FUNC;
+ alpm_list_t *invalid = check_arch(trans->add);
+ if(invalid) {
+ if(data) {
+ *data = invalid;
+ }
+ RET_ERR(PM_ERR_PKG_INVALID_ARCH, -1);
+ }
- /* Sanity checks */
- ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
- ASSERT(data != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -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);
+ }
+ }
- 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->state = STATE_PREPARED;
- return(_alpm_trans_prepare(handle->trans, data));
+ return(0);
}
/** Commit a transaction.
@@ -152,17 +177,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;
- ASSERT(!(handle->trans->flags & PM_TRANS_FLAG_NOLOCK), RET_ERR(PM_ERR_TRANS_NOT_LOCKED, -1));
+ 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);
+ }
+ }
- return(_alpm_trans_commit(handle->trans, data));
+ trans->state = STATE_COMMITED;
+
+ return(0);
}
/** Interrupt a transaction.
@@ -203,7 +253,7 @@ int SYMEXPORT alpm_trans_release()
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
ASSERT(trans->state != STATE_IDLE, RET_ERR(PM_ERR_TRANS_NULL, -1));
- unsigned int nolock_flag = trans->flags & PM_TRANS_FLAG_NOLOCK;
+ int nolock_flag = trans->flags & PM_TRANS_FLAG_NOLOCK;
_alpm_trans_free(trans);
handle->trans = NULL;
@@ -211,7 +261,10 @@ int SYMEXPORT alpm_trans_release()
/* unlock db */
if(!nolock_flag) {
if(handle->lckfd != -1) {
- while(close(handle->lckfd) == -1 && errno == EINTR);
+ int fd;
+ do {
+ fd = close(handle->lckfd);
+ } while(fd == -1 && errno == EINTR);
handle->lckfd = -1;
}
if(_alpm_lckrm()) {
@@ -247,12 +300,10 @@ void _alpm_trans_free(pmtrans_t *trans)
return;
}
- if(trans->type == PM_TRANS_TYPE_SYNC) {
- 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,150 +311,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);
-}
-
-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);
- }
-
- switch(trans->type) {
- case PM_TRANS_TYPE_UPGRADE:
- if(_alpm_add_prepare(trans, handle->db_local, data) == -1) {
- /* pm_errno is set by _alpm_add_prepare() */
- return(-1);
- }
- break;
- 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_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_UPGRADE:
- if(_alpm_add_commit(trans, handle->db_local) == -1) {
- /* pm_errno is set by _alpm_add_commit() */
- return(-1);
- }
- break;
- 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_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
*/
@@ -416,7 +323,8 @@ static int grep(const char *fn, const char *needle)
}
while(!feof(fp)) {
char line[1024];
- fgets(line, 1024, fp);
+ int sline = sizeof(line)-1;
+ fgets(line, sline, fp);
if(feof(fp)) {
continue;
}
@@ -464,7 +372,7 @@ int _alpm_runscriptlet(const char *root, const char *installfn,
/* either extract or copy the scriptlet */
snprintf(scriptfn, PATH_MAX, "%s/.INSTALL", tmpdir);
if(!strcmp(script, "pre_upgrade") || !strcmp(script, "pre_install")) {
- if(_alpm_unpack(installfn, tmpdir, ".INSTALL")) {
+ if(_alpm_unpack_single(installfn, tmpdir, ".INSTALL")) {
retval = 1;
}
} else {
@@ -503,30 +411,30 @@ cleanup:
return(retval);
}
-pmtranstype_t SYMEXPORT alpm_trans_get_type()
+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: */