/** Commit a transaction. */ int SYMEXPORT alpm_trans_commit(alpm_handle_t *handle, alpm_list_t **data) { alpm_trans_t *trans; /* Sanity checks */ CHECK_HANDLE(handle, return -1); trans = handle->trans; ASSERT(trans != NULL, RET_ERR(handle, ALPM_ERR_TRANS_NULL, -1)); ASSERT(trans->state == STATE_PREPARED, RET_ERR(handle, ALPM_ERR_TRANS_NOT_PREPARED, -1)); ASSERT(!(trans->flags & ALPM_TRANS_FLAG_NOLOCK), RET_ERR(handle, ALPM_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(handle) == -1) { /* pm_errno is set by _alpm_remove_commit() */ return -1; } } else { if(_alpm_sync_commit(handle, data) == -1) { /* pm_errno is set by _alpm_sync_commit() */ return -1; } } trans->state = STATE_COMMITED; return 0; }
/** Commit a transaction. */ int SYMEXPORT alpm_trans_commit(alpm_handle_t *handle, alpm_list_t **data) { alpm_trans_t *trans; alpm_event_any_t event; /* Sanity checks */ CHECK_HANDLE(handle, return -1); trans = handle->trans; ASSERT(trans != NULL, RET_ERR(handle, ALPM_ERR_TRANS_NULL, -1)); ASSERT(trans->state == STATE_PREPARED, RET_ERR(handle, ALPM_ERR_TRANS_NOT_PREPARED, -1)); ASSERT(!(trans->flags & ALPM_TRANS_FLAG_NOLOCK), RET_ERR(handle, ALPM_ERR_TRANS_NOT_LOCKED, -1)); /* If there's nothing to do, return without complaining */ if(trans->add == NULL && trans->remove == NULL) { return 0; } if(trans->add) { if(_alpm_sync_load(handle, data) != 0) { /* pm_errno is set by _alpm_sync_load() */ return -1; } if(trans->flags & ALPM_TRANS_FLAG_DOWNLOADONLY) { return 0; } if(_alpm_sync_check(handle, data) != 0) { /* pm_errno is set by _alpm_sync_check() */ return -1; } } if(_alpm_hook_run(handle, ALPM_HOOK_PRE_TRANSACTION) != 0) { RET_ERR(handle, ALPM_ERR_TRANS_HOOK_FAILED, -1); } trans->state = STATE_COMMITING; alpm_logaction(handle, ALPM_CALLER_PREFIX, "transaction started\n"); event.type = ALPM_EVENT_TRANSACTION_START; EVENT(handle, (void *)&event); if(trans->add == NULL) { if(_alpm_remove_packages(handle, 1) == -1) { /* pm_errno is set by _alpm_remove_packages() */ alpm_errno_t save = handle->pm_errno; alpm_logaction(handle, ALPM_CALLER_PREFIX, "transaction failed\n"); handle->pm_errno = save; return -1; } } else { if(_alpm_sync_commit(handle) == -1) { /* pm_errno is set by _alpm_sync_commit() */ alpm_errno_t save = handle->pm_errno; alpm_logaction(handle, ALPM_CALLER_PREFIX, "transaction failed\n"); handle->pm_errno = save; return -1; } } if(trans->state == STATE_INTERRUPTED) { alpm_logaction(handle, ALPM_CALLER_PREFIX, "transaction interrupted\n"); } else { event.type = ALPM_EVENT_TRANSACTION_DONE; EVENT(handle, (void *)&event); alpm_logaction(handle, ALPM_CALLER_PREFIX, "transaction completed\n"); _alpm_hook_run(handle, ALPM_HOOK_POST_TRANSACTION); } trans->state = STATE_COMMITED; return 0; }
int _alpm_sync_commit(alpm_handle_t *handle, alpm_list_t **data) { alpm_list_t *i; alpm_list_t *deltas = NULL; size_t numtargs, current = 0, replaces = 0; int errors; alpm_trans_t *trans = handle->trans; if(download_files(handle, &deltas)) { alpm_list_free(deltas); return -1; } if(validate_deltas(handle, deltas, data)) { alpm_list_free(deltas); return -1; } alpm_list_free(deltas); /* Check integrity of packages */ numtargs = alpm_list_count(trans->add); EVENT(trans, ALPM_TRANS_EVT_INTEGRITY_START, NULL, NULL); errors = 0; for(i = trans->add; i; i = i->next, current++) { alpm_pkg_t *spkg = i->data; int percent = (current * 100) / numtargs; const char *filename; char *filepath; alpm_siglevel_t level; PROGRESS(trans, ALPM_TRANS_PROGRESS_INTEGRITY_START, "", percent, numtargs, current); if(spkg->origin == PKG_FROM_FILE) { continue; /* pkg_load() has been already called, this package is valid */ } filename = alpm_pkg_get_filename(spkg); filepath = _alpm_filecache_find(handle, filename); alpm_db_t *sdb = alpm_pkg_get_db(spkg); level = alpm_db_get_siglevel(sdb); /* load the package file and replace pkgcache entry with it in the target list */ /* TODO: alpm_pkg_get_db() will not work on this target anymore */ _alpm_log(handle, ALPM_LOG_DEBUG, "replacing pkgcache entry with package file for target %s\n", spkg->name); alpm_pkg_t *pkgfile =_alpm_pkg_load_internal(handle, filepath, 1, spkg->md5sum, spkg->base64_sig, level); if(!pkgfile) { errors++; *data = alpm_list_add(*data, strdup(filename)); FREE(filepath); continue; } FREE(filepath); pkgfile->reason = spkg->reason; /* copy over install reason */ i->data = pkgfile; _alpm_pkg_free_trans(spkg); /* spkg has been removed from the target list */ } PROGRESS(trans, ALPM_TRANS_PROGRESS_INTEGRITY_START, "", 100, numtargs, current); EVENT(trans, ALPM_TRANS_EVT_INTEGRITY_DONE, NULL, NULL); if(errors) { RET_ERR(handle, ALPM_ERR_PKG_INVALID, -1); } if(trans->flags & ALPM_TRANS_FLAG_DOWNLOADONLY) { return 0; } trans->state = STATE_COMMITING; replaces = alpm_list_count(trans->remove); /* fileconflict check */ if(!(trans->flags & ALPM_TRANS_FLAG_FORCE)) { EVENT(trans, ALPM_TRANS_EVT_FILECONFLICTS_START, NULL, NULL); _alpm_log(handle, ALPM_LOG_DEBUG, "looking for file conflicts\n"); alpm_list_t *conflict = _alpm_db_find_fileconflicts(handle, trans->add, trans->remove); if(conflict) { if(data) { *data = conflict; } else { alpm_list_free_inner(conflict, (alpm_list_fn_free)_alpm_fileconflict_free); alpm_list_free(conflict); } RET_ERR(handle, ALPM_ERR_FILE_CONFLICTS, -1); } EVENT(trans, ALPM_TRANS_EVT_FILECONFLICTS_DONE, NULL, NULL); } /* check available disk space */ if(handle->checkspace) { EVENT(trans, ALPM_TRANS_EVT_DISKSPACE_START, NULL, NULL); _alpm_log(handle, ALPM_LOG_DEBUG, "checking available disk space\n"); if(_alpm_check_diskspace(handle) == -1) { _alpm_log(handle, ALPM_LOG_ERROR, "%s\n", _("not enough free disk space")); return -1; } EVENT(trans, ALPM_TRANS_EVT_DISKSPACE_DONE, NULL, NULL); } /* remove conflicting and to-be-replaced packages */ if(replaces) { _alpm_log(handle, ALPM_LOG_DEBUG, "removing conflicting and to-be-replaced packages\n"); /* we want the frontend to be aware of commit details */ if(_alpm_remove_packages(handle) == -1) { _alpm_log(handle, ALPM_LOG_ERROR, _("could not commit removal transaction\n")); return -1; } } /* install targets */ _alpm_log(handle, ALPM_LOG_DEBUG, "installing packages\n"); if(_alpm_upgrade_packages(handle) == -1) { _alpm_log(handle, ALPM_LOG_ERROR, _("could not commit transaction\n")); return -1; } return 0; }