Ejemplo n.º 1
0
/** 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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
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;
}