[pacman-dev] [PATCH 10/13] Move pm_errno onto the handle

Dan McGee dan at archlinux.org
Tue Jun 7 17:36:39 EDT 2011


This involves some serious changes and a very messy diff, unfortunately.

Signed-off-by: Dan McGee <dan at archlinux.org>
---
 lib/libalpm/add.c        |   31 ++++++++++--------
 lib/libalpm/alpm.c       |    6 ++--
 lib/libalpm/alpm.h       |   10 ++----
 lib/libalpm/be_local.c   |   28 +++++-----------
 lib/libalpm/be_package.c |   40 ++++++++++++------------
 lib/libalpm/be_sync.c    |   54 +++++++++++++++------------------
 lib/libalpm/conflict.c   |   65 ++++++++++++++++++++-------------------
 lib/libalpm/conflict.h   |    1 -
 lib/libalpm/db.c         |   75 ++++++++++++++++++++++-----------------------
 lib/libalpm/delta.c      |   14 +++++---
 lib/libalpm/deps.c       |   34 +++++++++++----------
 lib/libalpm/diskspace.c  |   14 ++++----
 lib/libalpm/dload.c      |   36 +++++++++++-----------
 lib/libalpm/dload.h      |    3 +-
 lib/libalpm/error.c      |   16 ++--------
 lib/libalpm/graph.c      |    2 +-
 lib/libalpm/group.c      |    4 +-
 lib/libalpm/handle.c     |   10 +++---
 lib/libalpm/handle.h     |    3 ++
 lib/libalpm/log.c        |   12 ++++----
 lib/libalpm/package.c    |   34 +++++++++++---------
 lib/libalpm/package.h    |    2 +-
 lib/libalpm/pkghash.c    |    8 +----
 lib/libalpm/remove.c     |   23 +++++++-------
 lib/libalpm/signing.c    |   25 ++++++++-------
 lib/libalpm/sync.c       |   60 +++++++++++++++++++------------------
 lib/libalpm/trans.c      |   70 +++++++++++++++++-------------------------
 lib/libalpm/trans.h      |    1 -
 lib/libalpm/util.c       |   54 +++++++++++++++++----------------
 lib/libalpm/util.h       |   15 +++++----
 src/pacman/conf.c        |   10 +++---
 src/pacman/database.c    |    2 +-
 src/pacman/remove.c      |   13 +++++---
 src/pacman/sync.c        |   28 ++++++++++-------
 src/pacman/upgrade.c     |   20 +++++++-----
 src/pacman/util.c        |    9 +++--
 src/util/cleanupdelta.c  |    2 +-
 src/util/pactree.c       |   30 +++++++-----------
 src/util/testdb.c        |    2 +-
 src/util/testpkg.c       |    5 ++-
 40 files changed, 426 insertions(+), 445 deletions(-)

diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c
index da2ecdc..20d6745 100644
--- a/lib/libalpm/add.c
+++ b/lib/libalpm/add.c
@@ -37,7 +37,9 @@
 
 /* libalpm */
 #include "add.h"
+#include "alpm.h"
 #include "alpm_list.h"
+#include "handle.h"
 #include "trans.h"
 #include "util.h"
 #include "log.h"
@@ -56,10 +58,11 @@ int SYMEXPORT alpm_add_pkg(pmpkg_t *pkg)
 	pmpkg_t *local;
 
 	/* Sanity checks */
-	ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
+	ASSERT(pkg != NULL, return -1);
 	trans = pkg->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 != NULL, RET_ERR(pkg->handle, PM_ERR_TRANS_NULL, -1));
+	ASSERT(trans->state == STATE_INITIALIZED,
+			RET_ERR(pkg->handle, PM_ERR_TRANS_NOT_INITIALIZED, -1));
 	db_local = pkg->handle->db_local;
 
 	pkgname = pkg->name;
@@ -68,7 +71,7 @@ int SYMEXPORT alpm_add_pkg(pmpkg_t *pkg)
 	_alpm_log(PM_LOG_DEBUG, "adding package '%s'\n", pkgname);
 
 	if(_alpm_pkg_find(trans->add, pkgname)) {
-		RET_ERR(PM_ERR_TRANS_DUP_TARGET, -1);
+		RET_ERR(pkg->handle, PM_ERR_TRANS_DUP_TARGET, -1);
 	}
 
 	local = _alpm_db_get_pkgfromcache(db_local, pkgname);
@@ -265,7 +268,7 @@ static int extract_single_file(pmhandle_t *handle, struct archive *archive,
 
 				/* if we force hash_orig to be non-NULL retroactive backup works */
 				if(needbackup && !hash_orig) {
-					STRDUP(hash_orig, "", RET_ERR(PM_ERR_MEMORY, -1));
+					STRDUP(hash_orig, "", RET_ERR(handle, PM_ERR_MEMORY, -1));
 				}
 			}
 		}
@@ -275,7 +278,7 @@ static int extract_single_file(pmhandle_t *handle, struct archive *archive,
 
 	/* we need access to the original entryname later after calls to
 	 * archive_entry_set_pathname(), so we need to dupe it and free() later */
-	STRDUP(entryname_orig, entryname, RET_ERR(PM_ERR_MEMORY, -1));
+	STRDUP(entryname_orig, entryname, RET_ERR(handle, PM_ERR_MEMORY, -1));
 
 	if(needbackup) {
 		char checkfile[PATH_MAX];
@@ -307,7 +310,7 @@ static int extract_single_file(pmhandle_t *handle, struct archive *archive,
 			char *backup = NULL;
 			/* length is tab char, null byte and MD5 (32 char) */
 			size_t backup_len = strlen(oldbackup) + 34;
-			MALLOC(backup, backup_len, RET_ERR(PM_ERR_MEMORY, -1));
+			MALLOC(backup, backup_len, RET_ERR(handle, PM_ERR_MEMORY, -1));
 
 			sprintf(backup, "%s\t%s", oldbackup, hash_pkg);
 			backup[backup_len-1] = '\0';
@@ -449,7 +452,7 @@ static int extract_single_file(pmhandle_t *handle, struct archive *archive,
 			_alpm_log(PM_LOG_DEBUG, "appending backup entry for %s\n", filename);
 
 			hash = alpm_compute_md5sum(filename);
-			MALLOC(backup, backup_len, RET_ERR(PM_ERR_MEMORY, -1));
+			MALLOC(backup, backup_len, RET_ERR(handle, PM_ERR_MEMORY, -1));
 
 			sprintf(backup, "%s\t%s", oldbackup, hash);
 			backup[backup_len-1] = '\0';
@@ -523,7 +526,7 @@ static int commit_single_pkg(pmhandle_t *handle, pmpkg_t *newpkg,
 	if(oldpkg) {
 		/* set up fake remove transaction */
 		if(_alpm_upgraderemove_package(newpkg->handle, oldpkg, newpkg) == -1) {
-			pm_errno = PM_ERR_TRANS_ABORT;
+			handle->pm_errno = PM_ERR_TRANS_ABORT;
 			ret = -1;
 			goto cleanup;
 		}
@@ -534,7 +537,7 @@ static int commit_single_pkg(pmhandle_t *handle, pmpkg_t *newpkg,
 	if(_alpm_local_db_prepare(db, newpkg)) {
 		alpm_logaction(handle, "error: could not create database entry %s-%s\n",
 				alpm_pkg_get_name(newpkg), alpm_pkg_get_version(newpkg));
-		pm_errno = PM_ERR_DB_WRITE;
+		handle->pm_errno = PM_ERR_DB_WRITE;
 		ret = -1;
 		goto cleanup;
 	}
@@ -548,7 +551,7 @@ static int commit_single_pkg(pmhandle_t *handle, pmpkg_t *newpkg,
 		_alpm_log(PM_LOG_DEBUG, "extracting files\n");
 
 		if((archive = archive_read_new()) == NULL) {
-			pm_errno = PM_ERR_LIBARCHIVE;
+			handle->pm_errno = PM_ERR_LIBARCHIVE;
 			ret = -1;
 			goto cleanup;
 		}
@@ -559,7 +562,7 @@ static int commit_single_pkg(pmhandle_t *handle, pmpkg_t *newpkg,
 		_alpm_log(PM_LOG_DEBUG, "archive: %s\n", newpkg->origin_data.file);
 		if(archive_read_open_filename(archive, newpkg->origin_data.file,
 					ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
-			pm_errno = PM_ERR_PKG_OPEN;
+			handle->pm_errno = PM_ERR_PKG_OPEN;
 			ret = -1;
 			goto cleanup;
 		}
@@ -654,7 +657,7 @@ static int commit_single_pkg(pmhandle_t *handle, pmpkg_t *newpkg,
 				alpm_pkg_get_name(newpkg), alpm_pkg_get_version(newpkg));
 		alpm_logaction(handle, "error: could not update database entry %s-%s\n",
 				alpm_pkg_get_name(newpkg), alpm_pkg_get_version(newpkg));
-		pm_errno = PM_ERR_DB_WRITE;
+		handle->pm_errno = PM_ERR_DB_WRITE;
 		ret = -1;
 		goto cleanup;
 	}
@@ -720,7 +723,7 @@ int _alpm_upgrade_packages(pmhandle_t *handle)
 		if(commit_single_pkg(handle, newpkg, pkg_current, pkg_count)) {
 			/* something screwed up on the commit, abort the trans */
 			trans->state = STATE_INTERRUPTED;
-			pm_errno = PM_ERR_TRANS_ABORT;
+			handle->pm_errno = PM_ERR_TRANS_ABORT;
 			/* running ldconfig at this point could possibly screw system */
 			skip_ldconfig = 1;
 			ret = -1;
diff --git a/lib/libalpm/alpm.c b/lib/libalpm/alpm.c
index d516870..86b1619 100644
--- a/lib/libalpm/alpm.c
+++ b/lib/libalpm/alpm.c
@@ -35,7 +35,6 @@
 #include "util.h"
 
 /* Globals */
-enum _pmerrno_t pm_errno SYMEXPORT;
 extern pmhandle_t *handle;
 
 /** \addtogroup alpm_interface Interface Functions
@@ -107,6 +106,7 @@ cleanup:
  */
 int SYMEXPORT alpm_release(pmhandle_t *myhandle)
 {
+	int ret = 0;
 	pmdb_t *db;
 
 	ASSERT(myhandle != NULL, return -1);
@@ -119,7 +119,7 @@ int SYMEXPORT alpm_release(pmhandle_t *myhandle)
 	}
 
 	if(alpm_db_unregister_all(myhandle) == -1) {
-		return -1;
+		ret = -1;
 	}
 
 	_alpm_handle_free(myhandle);
@@ -131,7 +131,7 @@ int SYMEXPORT alpm_release(pmhandle_t *myhandle)
 	curl_global_cleanup();
 #endif
 
-	return 0;
+	return ret;
 }
 
 /** @} */
diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index c493245..742a343 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -1031,7 +1031,6 @@ enum _pmerrno_t {
 	PM_ERR_FILE_CONFLICTS,
 	/* Misc */
 	PM_ERR_RETRIEVE,
-	PM_ERR_WRITE,
 	PM_ERR_INVALID_REGEX,
 	/* External library errors */
 	PM_ERR_LIBARCHIVE,
@@ -1040,14 +1039,11 @@ enum _pmerrno_t {
 	PM_ERR_GPGME
 };
 
-/** The number of the last error that occurred. */
-extern enum _pmerrno_t pm_errno;
+/** Returns the current error code from the handle. */
+enum _pmerrno_t alpm_errno(pmhandle_t *handle);
 
 /** Returns the string corresponding to an error number. */
-const char *alpm_strerror(int err);
-
-/** Returns the string corresponding to pm_errno. */
-const char *alpm_strerrorlast(void);
+const char *alpm_strerror(enum _pmerrno_t err);
 
 /* End of alpm_api_errors */
 /** @} */
diff --git a/lib/libalpm/be_local.c b/lib/libalpm/be_local.c
index 42ddaf5..d7d1812 100644
--- a/lib/libalpm/be_local.c
+++ b/lib/libalpm/be_local.c
@@ -282,12 +282,12 @@ static int checkdbdir(pmdb_t *db)
 		_alpm_log(PM_LOG_DEBUG, "database dir '%s' does not exist, creating it\n",
 				path);
 		if(_alpm_makepath(path) != 0) {
-			RET_ERR(PM_ERR_SYSTEM, -1);
+			RET_ERR(db->handle, PM_ERR_SYSTEM, -1);
 		}
 	} else if(!S_ISDIR(buf.st_mode)) {
 		_alpm_log(PM_LOG_WARNING, _("removing invalid database: %s\n"), path);
 		if(unlink(path) != 0 || _alpm_makepath(path) != 0) {
-			RET_ERR(PM_ERR_SYSTEM, -1);
+			RET_ERR(db->handle, PM_ERR_SYSTEM, -1);
 		}
 	}
 	return 0;
@@ -323,8 +323,6 @@ static int local_db_populate(pmdb_t *db)
 	const char *dbpath;
 	DIR *dbdir;
 
-	ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
-
 	dbpath = _alpm_db_path(db);
 	if(dbpath == NULL) {
 		/* pm_errno set in _alpm_db_path() */
@@ -336,10 +334,10 @@ static int local_db_populate(pmdb_t *db)
 			/* no database existing yet is not an error */
 			return 0;
 		}
-		RET_ERR(PM_ERR_DB_OPEN, -1);
+		RET_ERR(db->handle, PM_ERR_DB_OPEN, -1);
 	}
 	if(fstat(dirfd(dbdir), &buf) != 0) {
-		RET_ERR(PM_ERR_DB_OPEN, -1);
+		RET_ERR(db->handle, PM_ERR_DB_OPEN, -1);
 	}
 	if(buf.st_nlink >= 2) {
 		est_count = buf.st_nlink;
@@ -363,7 +361,7 @@ static int local_db_populate(pmdb_t *db)
 	db->pkgcache = _alpm_pkghash_create(est_count * 2);
 	if(db->pkgcache == NULL){
 		closedir(dbdir);
-		RET_ERR(PM_ERR_MEMORY, -1);
+		RET_ERR(db->handle, PM_ERR_MEMORY, -1);
 	}
 
 	while((ent = readdir(dbdir)) != NULL) {
@@ -381,7 +379,7 @@ static int local_db_populate(pmdb_t *db)
 		pkg = _alpm_pkg_new();
 		if(pkg == NULL) {
 			closedir(dbdir);
-			RET_ERR(PM_ERR_MEMORY, -1);
+			RET_ERR(db->handle, PM_ERR_MEMORY, -1);
 		}
 		/* split the db entry name */
 		if(_alpm_splitname(name, pkg) != 0) {
@@ -436,7 +434,7 @@ static char *get_pkgpath(pmdb_t *db, pmpkg_t *info)
 
 	dbpath = _alpm_db_path(db);
 	len = strlen(dbpath) + strlen(info->name) + strlen(info->version) + 3;
-	MALLOC(pkgpath, len, RET_ERR(PM_ERR_MEMORY, NULL));
+	MALLOC(pkgpath, len, RET_ERR(db->handle, PM_ERR_MEMORY, NULL));
 	sprintf(pkgpath, "%s%s-%s/", dbpath, info->name, info->version);
 	return pkgpath;
 }
@@ -449,10 +447,6 @@ int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
 	char line[1024];
 	char *pkgpath = NULL;
 
-	if(db == NULL) {
-		RET_ERR(PM_ERR_DB_NULL, -1);
-	}
-
 	if(info == NULL || info->name == NULL || info->version == NULL) {
 		_alpm_log(PM_LOG_DEBUG, "invalid package entry provided to _alpm_local_db_read, skipping\n");
 		return -1;
@@ -856,10 +850,6 @@ int _alpm_local_db_remove(pmdb_t *db, pmpkg_t *info)
 	int ret = 0;
 	char *pkgpath = NULL;
 
-	if(db == NULL || info == NULL) {
-		RET_ERR(PM_ERR_DB_NULL, -1);
-	}
-
 	pkgpath = get_pkgpath(db, info);
 
 	ret = _alpm_rmrf(pkgpath);
@@ -879,7 +869,7 @@ static int local_db_version(pmdb_t *db)
 
 	dbpath = _alpm_db_path(db);
 	if(dbpath == NULL) {
-		RET_ERR(PM_ERR_DB_OPEN, -1);
+		RET_ERR(db->handle, PM_ERR_DB_OPEN, -1);
 	}
 	dbdir = opendir(dbpath);
 	if(dbdir == NULL) {
@@ -888,7 +878,7 @@ static int local_db_version(pmdb_t *db)
 			version = 2;
 			goto done;
 		} else {
-			RET_ERR(PM_ERR_DB_OPEN, -1);
+			RET_ERR(db->handle, PM_ERR_DB_OPEN, -1);
 		}
 	}
 
diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c
index 5b8cd81..20b9f52 100644
--- a/lib/libalpm/be_package.c
+++ b/lib/libalpm/be_package.c
@@ -52,7 +52,7 @@ static void *_package_changelog_open(pmpkg_t *pkg)
 	const char *pkgfile = pkg->origin_data.file;
 
 	if((archive = archive_read_new()) == NULL) {
-		RET_ERR(PM_ERR_LIBARCHIVE, NULL);
+		RET_ERR(pkg->handle, PM_ERR_LIBARCHIVE, NULL);
 	}
 
 	archive_read_support_compression_all(archive);
@@ -60,7 +60,7 @@ static void *_package_changelog_open(pmpkg_t *pkg)
 
 	if(archive_read_open_filename(archive, pkgfile,
 				ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
-		RET_ERR(PM_ERR_PKG_OPEN, NULL);
+		RET_ERR(pkg->handle, PM_ERR_PKG_OPEN, NULL);
 	}
 
 	while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) {
@@ -92,7 +92,7 @@ static size_t _package_changelog_read(void *ptr, size_t size,
 	ssize_t sret = archive_read_data((struct archive *)fp, ptr, size);
 	/* Report error (negative values) */
 	if(sret < 0) {
-		pm_errno = PM_ERR_LIBARCHIVE;
+		pkg->handle->pm_errno = PM_ERR_LIBARCHIVE;
 		return 0;
 	} else {
 		return (size_t)sret;
@@ -166,26 +166,26 @@ static int parse_descfile(struct archive *a, pmpkg_t *newpkg)
 			while(*ptr == ' ') ptr++;
 			ptr = _alpm_strtrim(ptr);
 			if(strcmp(key, "pkgname") == 0) {
-				STRDUP(newpkg->name, ptr, RET_ERR(PM_ERR_MEMORY, -1));
+				STRDUP(newpkg->name, ptr, return -1);
 				newpkg->name_hash = _alpm_hash_sdbm(newpkg->name);
 			} else if(strcmp(key, "pkgbase") == 0) {
 				/* not used atm */
 			} else if(strcmp(key, "pkgver") == 0) {
-				STRDUP(newpkg->version, ptr, RET_ERR(PM_ERR_MEMORY, -1));
+				STRDUP(newpkg->version, ptr, return -1);
 			} else if(strcmp(key, "pkgdesc") == 0) {
-				STRDUP(newpkg->desc, ptr, RET_ERR(PM_ERR_MEMORY, -1));
+				STRDUP(newpkg->desc, ptr, return -1);
 			} else if(strcmp(key, "group") == 0) {
 				newpkg->groups = alpm_list_add(newpkg->groups, strdup(ptr));
 			} else if(strcmp(key, "url") == 0) {
-				STRDUP(newpkg->url, ptr, RET_ERR(PM_ERR_MEMORY, -1));
+				STRDUP(newpkg->url, ptr, return -1);
 			} else if(strcmp(key, "license") == 0) {
 				newpkg->licenses = alpm_list_add(newpkg->licenses, strdup(ptr));
 			} else if(strcmp(key, "builddate") == 0) {
 				newpkg->builddate = _alpm_parsedate(ptr);
 			} else if(strcmp(key, "packager") == 0) {
-				STRDUP(newpkg->packager, ptr, RET_ERR(PM_ERR_MEMORY, -1));
+				STRDUP(newpkg->packager, ptr, return -1);
 			} else if(strcmp(key, "arch") == 0) {
-				STRDUP(newpkg->arch, ptr, RET_ERR(PM_ERR_MEMORY, -1));
+				STRDUP(newpkg->arch, ptr, return -1);
 			} else if(strcmp(key, "size") == 0) {
 				/* size in the raw package is uncompressed (installed) size */
 				newpkg->isize = atol(ptr);
@@ -241,20 +241,20 @@ pmpkg_t *_alpm_pkg_load_internal(pmhandle_t *handle, const char *pkgfile,
 	struct stat st;
 
 	if(pkgfile == NULL || strlen(pkgfile) == 0) {
-		RET_ERR(PM_ERR_WRONG_ARGS, NULL);
+		RET_ERR(handle, PM_ERR_WRONG_ARGS, NULL);
 	}
 
 	/* attempt to stat the package file, ensure it exists */
 	if(stat(pkgfile, &st) == 0) {
 		newpkg = _alpm_pkg_new();
 		if(newpkg == NULL) {
-			RET_ERR(PM_ERR_MEMORY, NULL);
+			RET_ERR(handle, PM_ERR_MEMORY, NULL);
 		}
 		newpkg->filename = strdup(pkgfile);
 		newpkg->size = st.st_size;
 	} else {
 		/* couldn't stat the pkgfile, return an error */
-		RET_ERR(PM_ERR_PKG_OPEN, NULL);
+		RET_ERR(handle, PM_ERR_PKG_OPEN, NULL);
 	}
 
 	/* first steps- validate the package file */
@@ -263,7 +263,7 @@ pmpkg_t *_alpm_pkg_load_internal(pmhandle_t *handle, const char *pkgfile,
 		_alpm_log(PM_LOG_DEBUG, "checking md5sum for %s\n", pkgfile);
 		if(_alpm_test_md5sum(pkgfile, md5sum) != 0) {
 			alpm_pkg_free(newpkg);
-			RET_ERR(PM_ERR_PKG_INVALID, NULL);
+			RET_ERR(handle, PM_ERR_PKG_INVALID, NULL);
 		}
 	}
 
@@ -273,14 +273,14 @@ pmpkg_t *_alpm_pkg_load_internal(pmhandle_t *handle, const char *pkgfile,
 		ret = _alpm_gpgme_checksig(handle, pkgfile, base64_sig);
 		if((check_sig == PM_PGP_VERIFY_ALWAYS && ret != 0) ||
 				(check_sig == PM_PGP_VERIFY_OPTIONAL && ret == 1)) {
-			RET_ERR(PM_ERR_SIG_INVALID, NULL);
+			RET_ERR(handle, PM_ERR_SIG_INVALID, NULL);
 		}
 	}
 
 	/* next- try to create an archive object to read in the package */
 	if((archive = archive_read_new()) == NULL) {
 		alpm_pkg_free(newpkg);
-		RET_ERR(PM_ERR_LIBARCHIVE, NULL);
+		RET_ERR(handle, PM_ERR_LIBARCHIVE, NULL);
 	}
 
 	archive_read_support_compression_all(archive);
@@ -289,7 +289,7 @@ pmpkg_t *_alpm_pkg_load_internal(pmhandle_t *handle, const char *pkgfile,
 	if(archive_read_open_filename(archive, pkgfile,
 				ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
 		alpm_pkg_free(newpkg);
-		RET_ERR(PM_ERR_PKG_OPEN, NULL);
+		RET_ERR(handle, PM_ERR_PKG_OPEN, NULL);
 	}
 
 	_alpm_log(PM_LOG_DEBUG, "starting package load for %s\n", pkgfile);
@@ -330,7 +330,7 @@ pmpkg_t *_alpm_pkg_load_internal(pmhandle_t *handle, const char *pkgfile,
 		if(archive_read_data_skip(archive)) {
 			_alpm_log(PM_LOG_ERROR, _("error while reading package %s: %s\n"),
 					pkgfile, archive_error_string(archive));
-			pm_errno = PM_ERR_LIBARCHIVE;
+			handle->pm_errno = PM_ERR_LIBARCHIVE;
 			goto error;
 		}
 
@@ -343,7 +343,7 @@ pmpkg_t *_alpm_pkg_load_internal(pmhandle_t *handle, const char *pkgfile,
 	if(ret != ARCHIVE_EOF && ret != ARCHIVE_OK) { /* An error occured */
 		_alpm_log(PM_LOG_ERROR, _("error while reading package %s: %s\n"),
 				pkgfile, archive_error_string(archive));
-		pm_errno = PM_ERR_LIBARCHIVE;
+		handle->pm_errno = PM_ERR_LIBARCHIVE;
 		goto error;
 	}
 
@@ -375,7 +375,7 @@ pmpkg_t *_alpm_pkg_load_internal(pmhandle_t *handle, const char *pkgfile,
 	return newpkg;
 
 pkg_invalid:
-	pm_errno = PM_ERR_PKG_INVALID;
+	handle->pm_errno = PM_ERR_PKG_INVALID;
 error:
 	_alpm_pkg_free(newpkg);
 	archive_read_finish(archive);
@@ -387,7 +387,7 @@ int SYMEXPORT alpm_pkg_load(pmhandle_t *handle, const char *filename, int full,
 		pgp_verify_t check_sig, pmpkg_t **pkg)
 {
 	ASSERT(handle != NULL, return -1);
-	ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
+	ASSERT(pkg != NULL, RET_ERR(handle, PM_ERR_WRONG_ARGS, -1));
 
 	*pkg = _alpm_pkg_load_internal(handle, filename, full, NULL, NULL, check_sig);
 	if(*pkg == NULL) {
diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c
index c8d3758..ecef7a5 100644
--- a/lib/libalpm/be_sync.c
+++ b/lib/libalpm/be_sync.c
@@ -85,15 +85,18 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
 	size_t len;
 	int ret = -1;
 	mode_t oldmask;
+	pmhandle_t *handle;
 	pgp_verify_t check_sig;
 
 	/* Sanity checks */
-	ASSERT(db != NULL && db != db->handle->db_local, RET_ERR(PM_ERR_WRONG_ARGS, -1));
-	ASSERT(db->servers != NULL, RET_ERR(PM_ERR_SERVER_NONE, -1));
+	ASSERT(db != NULL, return -1);
+	handle = db->handle;
+	ASSERT(db != handle->db_local, RET_ERR(handle, PM_ERR_WRONG_ARGS, -1));
+	ASSERT(db->servers != NULL, RET_ERR(handle, PM_ERR_SERVER_NONE, -1));
 
-	dbpath = alpm_option_get_dbpath(db->handle);
+	dbpath = alpm_option_get_dbpath(handle);
 	len = strlen(dbpath) + 6;
-	MALLOC(syncpath, len, RET_ERR(PM_ERR_MEMORY, -1));
+	MALLOC(syncpath, len, RET_ERR(handle, PM_ERR_MEMORY, -1));
 	sprintf(syncpath, "%s%s", dbpath, "sync/");
 
 	/* make sure we have a sane umask */
@@ -104,13 +107,13 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
 				syncpath);
 		if(_alpm_makepath(syncpath) != 0) {
 			free(syncpath);
-			RET_ERR(PM_ERR_SYSTEM, -1);
+			RET_ERR(handle, PM_ERR_SYSTEM, -1);
 		}
 	} else if(!S_ISDIR(buf.st_mode)) {
 		_alpm_log(PM_LOG_WARNING, _("removing invalid file: %s\n"), syncpath);
 		if(unlink(syncpath) != 0 || _alpm_makepath(syncpath) != 0) {
 			free(syncpath);
-			RET_ERR(PM_ERR_SYSTEM, -1);
+			RET_ERR(handle, PM_ERR_SYSTEM, -1);
 		}
 	}
 
@@ -124,10 +127,10 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
 
 		/* print server + filename into a buffer (leave space for .sig) */
 		len = strlen(server) + strlen(db->treename) + 9;
-		CALLOC(fileurl, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, -1));
+		CALLOC(fileurl, len, sizeof(char), RET_ERR(handle, PM_ERR_MEMORY, -1));
 		snprintf(fileurl, len, "%s/%s.db", server, db->treename);
 
-		ret = _alpm_download(fileurl, syncpath, force, 0, 0);
+		ret = _alpm_download(handle, fileurl, syncpath, force, 0, 0);
 
 		if(ret == 0 && (check_sig == PM_PGP_VERIFY_ALWAYS ||
 					check_sig == PM_PGP_VERIFY_OPTIONAL)) {
@@ -135,7 +138,7 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
 			/* if we downloaded a DB, we want the .sig from the same server */
 			snprintf(fileurl, len, "%s/%s.db.sig", server, db->treename);
 
-			sig_ret = _alpm_download(fileurl, syncpath, 1, 0, errors_ok);
+			sig_ret = _alpm_download(handle, fileurl, syncpath, 1, 0, errors_ok);
 			/* errors_ok suppresses error messages, but not the return code */
 			sig_ret = errors_ok ? 0 : sig_ret;
 		}
@@ -148,11 +151,11 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
 
 	if(ret == 1) {
 		/* files match, do nothing */
-		pm_errno = 0;
+		handle->pm_errno = 0;
 		goto cleanup;
 	} else if(ret == -1) {
 		/* pm_errno was set by the download code */
-		_alpm_log(PM_LOG_DEBUG, "failed to sync db: %s\n", alpm_strerrorlast());
+		_alpm_log(PM_LOG_DEBUG, "failed to sync db: %s\n", alpm_strerror(handle->pm_errno));
 		goto cleanup;
 	}
 
@@ -239,10 +242,8 @@ static int sync_db_populate(pmdb_t *db)
 	struct archive_entry *entry;
 	pmpkg_t *pkg = NULL;
 
-	ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
-
 	if((archive = archive_read_new()) == NULL) {
-		RET_ERR(PM_ERR_LIBARCHIVE, -1);
+		RET_ERR(db->handle, PM_ERR_LIBARCHIVE, -1);
 	}
 
 	archive_read_support_compression_all(archive);
@@ -261,17 +262,17 @@ static int sync_db_populate(pmdb_t *db)
 		_alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), dbpath,
 				archive_error_string(archive));
 		archive_read_finish(archive);
-		RET_ERR(PM_ERR_DB_OPEN, -1);
+		RET_ERR(db->handle, PM_ERR_DB_OPEN, -1);
 	}
 	if(stat(dbpath, &buf) != 0) {
-		RET_ERR(PM_ERR_DB_OPEN, -1);
+		RET_ERR(db->handle, PM_ERR_DB_OPEN, -1);
 	}
 	est_count = estimate_package_count(&buf, archive);
 
 	/* initialize hash at 66% full */
 	db->pkgcache = _alpm_pkghash_create(est_count * 3 / 2);
 	if(db->pkgcache == NULL) {
-		RET_ERR(PM_ERR_MEMORY, -1);
+		RET_ERR(db->handle, PM_ERR_MEMORY, -1);
 	}
 
 	while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) {
@@ -285,7 +286,7 @@ static int sync_db_populate(pmdb_t *db)
 			pkg = _alpm_pkg_new();
 			if(pkg == NULL) {
 				archive_read_finish(archive);
-				RET_ERR(PM_ERR_MEMORY, -1);
+				RET_ERR(db->handle, PM_ERR_MEMORY, -1);
 			}
 
 			name = archive_entry_pathname(entry);
@@ -360,18 +361,12 @@ static int sync_db_populate(pmdb_t *db)
 static int sync_db_read(pmdb_t *db, struct archive *archive,
 		struct archive_entry *entry, pmpkg_t *likely_pkg)
 {
-	const char *entryname = NULL, *filename;
+	const char *entryname, *filename;
 	char *pkgname, *p, *q;
 	pmpkg_t *pkg;
 	struct archive_read_buffer buf;
 
-	if(db == NULL) {
-		RET_ERR(PM_ERR_DB_NULL, -1);
-	}
-
-	if(entry != NULL) {
-		entryname = archive_entry_pathname(entry);
-	}
+	entryname = archive_entry_pathname(entry);
 	if(entryname == NULL) {
 		_alpm_log(PM_LOG_DEBUG, "invalid archive entry provided to _alpm_sync_db_read, skipping\n");
 		return -1;
@@ -385,7 +380,7 @@ static int sync_db_read(pmdb_t *db, struct archive *archive,
 	buf.max_line_size = 512 * 1024;
 
 	/* get package and db file names */
-	STRDUP(pkgname, entryname, RET_ERR(PM_ERR_MEMORY, -1));
+	STRDUP(pkgname, entryname, RET_ERR(db->handle, PM_ERR_MEMORY, -1));
 	p = pkgname + strlen(pkgname);
 	for(q = --p; *q && *q != '/'; q--);
 	filename = q + 1;
@@ -398,7 +393,7 @@ static int sync_db_read(pmdb_t *db, struct archive *archive,
 		pkg = likely_pkg;
 	} else {
 		if(db->pkgcache == NULL) {
-			RET_ERR(PM_ERR_MEMORY, -1);
+			RET_ERR(db->handle, PM_ERR_MEMORY, -1);
 		}
 		pkg = _alpm_pkghash_find(db->pkgcache, pkgname);
 	}
@@ -501,6 +496,7 @@ static int sync_db_read(pmdb_t *db, struct archive *archive,
 	return 0;
 
 error:
+	_alpm_log(PM_LOG_DEBUG, "error parsing database file: %s\n", filename);
 	FREE(pkgname);
 	return -1;
 }
@@ -524,7 +520,7 @@ pmdb_t *_alpm_db_register_sync(pmhandle_t *handle, const char *treename)
 
 	db = _alpm_db_new(treename, 0);
 	if(db == NULL) {
-		RET_ERR(PM_ERR_DB_CREATE, NULL);
+		RET_ERR(handle, PM_ERR_DB_CREATE, NULL);
 	}
 	db->ops = &sync_db_ops;
 	db->handle = handle;
diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c
index 28f8cc6..1d3f0e7 100644
--- a/lib/libalpm/conflict.c
+++ b/lib/libalpm/conflict.c
@@ -40,16 +40,16 @@
 #include "log.h"
 #include "deps.h"
 
-pmconflict_t *_alpm_conflict_new(const char *package1, const char *package2,
+static pmconflict_t *conflict_new(const char *package1, const char *package2,
 		const char *reason)
 {
 	pmconflict_t *conflict;
 
-	MALLOC(conflict, sizeof(pmconflict_t), RET_ERR(PM_ERR_MEMORY, NULL));
+	MALLOC(conflict, sizeof(pmconflict_t), return NULL);
 
-	STRDUP(conflict->package1, package1, RET_ERR(PM_ERR_MEMORY, NULL));
-	STRDUP(conflict->package2, package2, RET_ERR(PM_ERR_MEMORY, NULL));
-	STRDUP(conflict->reason, reason, RET_ERR(PM_ERR_MEMORY, NULL));
+	STRDUP(conflict->package1, package1, return NULL);
+	STRDUP(conflict->package2, package2, return NULL);
+	STRDUP(conflict->reason, reason, return NULL);
 
 	return conflict;
 }
@@ -65,11 +65,11 @@ void _alpm_conflict_free(pmconflict_t *conflict)
 pmconflict_t *_alpm_conflict_dup(const pmconflict_t *conflict)
 {
 	pmconflict_t *newconflict;
-	CALLOC(newconflict, 1, sizeof(pmconflict_t), RET_ERR(PM_ERR_MEMORY, NULL));
+	CALLOC(newconflict, 1, sizeof(pmconflict_t), );
 
-	STRDUP(newconflict->package1, conflict->package1, RET_ERR(PM_ERR_MEMORY, NULL));
-	STRDUP(newconflict->package2, conflict->package2, RET_ERR(PM_ERR_MEMORY, NULL));
-	STRDUP(newconflict->reason, conflict->reason, RET_ERR(PM_ERR_MEMORY, NULL));
+	STRDUP(newconflict->package1, conflict->package1, return NULL);
+	STRDUP(newconflict->package2, conflict->package2, return NULL);
+	STRDUP(newconflict->reason, conflict->reason, return NULL);
 
 	return newconflict;
 }
@@ -98,17 +98,21 @@ static int conflict_isin(pmconflict_t *needle, alpm_list_t *haystack)
  * @param pkg1 first package
  * @param pkg2 package causing conflict
  */
-static void add_conflict(alpm_list_t **baddeps, const char *pkg1,
+static int add_conflict(alpm_list_t **baddeps, const char *pkg1,
 		const char *pkg2, const char *reason)
 {
-	pmconflict_t *conflict = _alpm_conflict_new(pkg1, pkg2, reason);
+	pmconflict_t *conflict = conflict_new(pkg1, pkg2, reason);
+	if(!conflict) {
+		return -1;
+	}
 	_alpm_log(PM_LOG_DEBUG, "package %s conflicts with %s (by %s)\n",
 			pkg1, pkg2, reason);
-	if(conflict && !conflict_isin(conflict, *baddeps)) {
+	if(!conflict_isin(conflict, *baddeps)) {
 		*baddeps = alpm_list_add(*baddeps, conflict);
 	} else {
 		_alpm_conflict_free(conflict);
 	}
+	return 0;
 }
 
 /** Check if packages from list1 conflict with packages from list2.
@@ -273,15 +277,15 @@ static alpm_list_t *add_fileconflict(alpm_list_t *conflicts,
                     const char* name1, const char* name2)
 {
 	pmfileconflict_t *conflict;
-	MALLOC(conflict, sizeof(pmfileconflict_t), RET_ERR(PM_ERR_MEMORY, NULL));
+	MALLOC(conflict, sizeof(pmfileconflict_t), return NULL);
 
 	conflict->type = type;
-	STRDUP(conflict->target, name1, RET_ERR(PM_ERR_MEMORY, NULL));
-	STRDUP(conflict->file, filestr, RET_ERR(PM_ERR_MEMORY, NULL));
+	STRDUP(conflict->target, name1, return NULL);
+	STRDUP(conflict->file, filestr, return NULL);
 	if(name2) {
-		STRDUP(conflict->ctarget, name2, RET_ERR(PM_ERR_MEMORY, NULL));
+		STRDUP(conflict->ctarget, name2, return NULL);
 	} else {
-		STRDUP(conflict->ctarget, "", RET_ERR(PM_ERR_MEMORY, NULL));
+		STRDUP(conflict->ctarget, "", return NULL);
 	}
 
 	conflicts = alpm_list_add(conflicts, conflict);
@@ -392,6 +396,11 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmhandle_t *handle,
 					snprintf(path, PATH_MAX, "%s%s", handle->root, (char *)k->data);
 					conflicts = add_fileconflict(conflicts, PM_FILECONFLICT_TARGET, path,
 							alpm_pkg_get_name(p1), alpm_pkg_get_name(p2));
+					if(!conflicts) {
+						FREELIST(conflicts);
+						FREELIST(tmpfiles);
+						RET_ERR(handle, PM_ERR_MEMORY, NULL);
+					}
 				}
 				FREELIST(tmpfiles);
 			}
@@ -464,7 +473,8 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmhandle_t *handle,
 					/* 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(filestr));
+					handle->trans->skip_remove =
+						alpm_list_add(handle->trans->skip_remove, strdup(filestr));
 					_alpm_log(PM_LOG_DEBUG, "file changed packages, adding to remove skiplist: %s\n", filestr);
 					resolved_conflict = 1;
 				}
@@ -499,6 +509,11 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmhandle_t *handle,
 				_alpm_log(PM_LOG_DEBUG, "file found in conflict: %s\n", path);
 				conflicts = add_fileconflict(conflicts, PM_FILECONFLICT_FILESYSTEM,
 						path, p1->name, NULL);
+				if(!conflicts) {
+					FREELIST(conflicts);
+					FREELIST(tmpfiles);
+					RET_ERR(handle, PM_ERR_MEMORY, NULL);
+				}
 			}
 		}
 		FREELIST(tmpfiles);
@@ -511,57 +526,43 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmhandle_t *handle,
 
 const char SYMEXPORT *alpm_conflict_get_package1(pmconflict_t *conflict)
 {
-	/* Sanity checks */
 	ASSERT(conflict != NULL, return NULL);
-
 	return conflict->package1;
 }
 
 const char SYMEXPORT *alpm_conflict_get_package2(pmconflict_t *conflict)
 {
-	/* Sanity checks */
 	ASSERT(conflict != NULL, return NULL);
-
 	return conflict->package2;
 }
 
 const char SYMEXPORT *alpm_conflict_get_reason(pmconflict_t *conflict)
 {
-	/* Sanity checks */
 	ASSERT(conflict != NULL, return NULL);
-
 	return conflict->reason;
 }
 
 const char SYMEXPORT *alpm_fileconflict_get_target(pmfileconflict_t *conflict)
 {
-	/* Sanity checks */
 	ASSERT(conflict != NULL, return NULL);
-
 	return conflict->target;
 }
 
 pmfileconflicttype_t SYMEXPORT alpm_fileconflict_get_type(pmfileconflict_t *conflict)
 {
-	/* Sanity checks */
 	ASSERT(conflict != NULL, return -1);
-
 	return conflict->type;
 }
 
 const char SYMEXPORT *alpm_fileconflict_get_file(pmfileconflict_t *conflict)
 {
-	/* Sanity checks */
 	ASSERT(conflict != NULL, return NULL);
-
 	return conflict->file;
 }
 
 const char SYMEXPORT *alpm_fileconflict_get_ctarget(pmfileconflict_t *conflict)
 {
-	/* Sanity checks */
 	ASSERT(conflict != NULL, return NULL);
-
 	return conflict->ctarget;
 }
 
diff --git a/lib/libalpm/conflict.h b/lib/libalpm/conflict.h
index 2101170..7a3784a 100644
--- a/lib/libalpm/conflict.h
+++ b/lib/libalpm/conflict.h
@@ -37,7 +37,6 @@ struct __pmfileconflict_t {
 	char *ctarget;
 };
 
-pmconflict_t *_alpm_conflict_new(const char *package1, const char *package2, const char *reason);
 pmconflict_t *_alpm_conflict_dup(const pmconflict_t *conflict);
 void _alpm_conflict_free(pmconflict_t *conflict);
 alpm_list_t *_alpm_innerconflicts(pmhandle_t *handle, alpm_list_t *packages);
diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c
index 8156f2a..17dde95 100644
--- a/lib/libalpm/db.c
+++ b/lib/libalpm/db.c
@@ -48,10 +48,11 @@
 pmdb_t SYMEXPORT *alpm_db_register_sync(pmhandle_t *handle, const char *treename)
 {
 	/* Sanity checks */
-	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, NULL));
-	ASSERT(treename != NULL && strlen(treename) != 0, RET_ERR(PM_ERR_WRONG_ARGS, NULL));
+	ASSERT(handle != NULL, return NULL);
+	ASSERT(treename != NULL && strlen(treename) != 0,
+			RET_ERR(handle, PM_ERR_WRONG_ARGS, NULL));
 	/* Do not register a database if a transaction is on-going */
-	ASSERT(handle->trans == NULL, RET_ERR(PM_ERR_TRANS_NOT_NULL, NULL));
+	ASSERT(handle->trans == NULL, RET_ERR(handle, PM_ERR_TRANS_NOT_NULL, NULL));
 
 	return _alpm_db_register_sync(handle, treename);
 }
@@ -74,9 +75,9 @@ int SYMEXPORT alpm_db_unregister_all(pmhandle_t *handle)
 	pmdb_t *db;
 
 	/* Sanity checks */
-	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
+	ASSERT(handle != NULL, return -1);
 	/* Do not unregister a database if a transaction is on-going */
-	ASSERT(handle->trans == NULL, RET_ERR(PM_ERR_TRANS_NOT_NULL, -1));
+	ASSERT(handle->trans == NULL, RET_ERR(handle, PM_ERR_TRANS_NOT_NULL, -1));
 
 	/* unregister all sync dbs */
 	for(i = handle->dbs_sync; i; i = i->next) {
@@ -92,14 +93,16 @@ int SYMEXPORT alpm_db_unregister_all(pmhandle_t *handle)
 int SYMEXPORT alpm_db_unregister(pmdb_t *db)
 {
 	int found = 0;
+	pmhandle_t *handle;
 
 	/* Sanity checks */
-	ASSERT(db != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
+	ASSERT(db != NULL, return -1);
 	/* Do not unregister a database if a transaction is on-going */
-	ASSERT(db->handle->trans == NULL, RET_ERR(PM_ERR_TRANS_NOT_NULL, -1));
+	handle = db->handle;
+	ASSERT(handle->trans == NULL, RET_ERR(handle, PM_ERR_TRANS_NOT_NULL, -1));
 
-	if(db == db->handle->db_local) {
-		db->handle->db_local = NULL;
+	if(db == handle->db_local) {
+		handle->db_local = NULL;
 		found = 1;
 	} else {
 		/* Warning : this function shouldn't be used to unregister all sync
@@ -107,7 +110,7 @@ int SYMEXPORT alpm_db_unregister(pmdb_t *db)
 		 * alpm_option_get_syncdbs, because the db is removed from that list here.
 		 */
 		void *data;
-		db->handle->dbs_sync = alpm_list_remove(db->handle->dbs_sync,
+		handle->dbs_sync = alpm_list_remove(handle->dbs_sync,
 				db, _alpm_db_cmp, &data);
 		if(data) {
 			found = 1;
@@ -115,7 +118,7 @@ int SYMEXPORT alpm_db_unregister(pmdb_t *db)
 	}
 
 	if(!found) {
-		RET_ERR(PM_ERR_DB_NOT_FOUND, -1);
+		RET_ERR(handle, PM_ERR_DB_NOT_FOUND, -1);
 	}
 
 	db->ops->unregister(db);
@@ -126,7 +129,7 @@ int SYMEXPORT alpm_db_unregister(pmdb_t *db)
 alpm_list_t SYMEXPORT *alpm_db_get_servers(const pmdb_t *db)
 {
 	/* Sanity checks */
-	ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, NULL));
+	ASSERT(db != NULL, return NULL);
 
 	return(db->servers);
 }
@@ -135,7 +138,7 @@ alpm_list_t SYMEXPORT *alpm_db_get_servers(const pmdb_t *db)
 int SYMEXPORT alpm_db_set_servers(pmdb_t *db, alpm_list_t *servers)
 {
 	/* Sanity checks */
-	ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
+	ASSERT(db != NULL, return -1);
 
 	if(db->servers) FREELIST(db->servers);
 	db->servers = servers;
@@ -147,7 +150,7 @@ static char *sanitize_url(const char *url)
 	char *newurl;
 	size_t len = strlen(url);
 
-	STRDUP(newurl, url, RET_ERR(PM_ERR_MEMORY, NULL));
+	STRDUP(newurl, url, return NULL);
 	/* strip the trailing slash if one exists */
 	if(newurl[len - 1] == '/') {
 		newurl[len - 1] = '\0';
@@ -165,8 +168,8 @@ int SYMEXPORT alpm_db_add_server(pmdb_t *db, const char *url)
 	char *newurl;
 
 	/* Sanity checks */
-	ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
-	ASSERT(url != NULL && strlen(url) != 0, RET_ERR(PM_ERR_WRONG_ARGS, -1));
+	ASSERT(db != NULL, return -1);
+	ASSERT(url != NULL && strlen(url) != 0, RET_ERR(db->handle, PM_ERR_WRONG_ARGS, -1));
 
 	newurl = sanitize_url(url);
 	if(!newurl) {
@@ -190,8 +193,8 @@ int SYMEXPORT alpm_db_remove_server(pmdb_t *db, const char *url)
 	char *newurl, *vdata = NULL;
 
 	/* Sanity checks */
-	ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
-	ASSERT(url != NULL && strlen(url) != 0, RET_ERR(PM_ERR_WRONG_ARGS, -1));
+	ASSERT(db != NULL, return -1);
+	ASSERT(url != NULL && strlen(url) != 0, RET_ERR(db->handle, PM_ERR_WRONG_ARGS, -1));
 
 	newurl = sanitize_url(url);
 	if(!newurl) {
@@ -216,7 +219,7 @@ int SYMEXPORT alpm_db_remove_server(pmdb_t *db, const char *url)
 int SYMEXPORT alpm_db_set_pgp_verify(pmdb_t *db, pgp_verify_t verify)
 {
 	/* Sanity checks */
-	ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
+	ASSERT(db != NULL, return -1);
 
 	db->pgp_verify = verify;
 	_alpm_log(PM_LOG_DEBUG, "adding VerifySig option to database '%s': %d\n",
@@ -228,9 +231,7 @@ int SYMEXPORT alpm_db_set_pgp_verify(pmdb_t *db, pgp_verify_t verify)
 /** Get the name of a package database. */
 const char SYMEXPORT *alpm_db_get_name(const pmdb_t *db)
 {
-	/* Sanity checks */
 	ASSERT(db != NULL, return NULL);
-
 	return db->treename;
 }
 
@@ -239,7 +240,6 @@ const char SYMEXPORT *alpm_db_get_url(const pmdb_t *db)
 {
 	char *url;
 
-	/* Sanity checks */
 	ASSERT(db != NULL, return NULL);
 	ASSERT(db->servers != NULL, return NULL);
 
@@ -252,7 +252,6 @@ const char SYMEXPORT *alpm_db_get_url(const pmdb_t *db)
 /** Get a package entry from a package database. */
 pmpkg_t SYMEXPORT *alpm_db_get_pkg(pmdb_t *db, const char *name)
 {
-	/* Sanity checks */
 	ASSERT(db != NULL, return NULL);
 	ASSERT(name != NULL && strlen(name) != 0, return NULL);
 
@@ -262,16 +261,13 @@ pmpkg_t SYMEXPORT *alpm_db_get_pkg(pmdb_t *db, const char *name)
 /** Get the package cache of a package database. */
 alpm_list_t SYMEXPORT *alpm_db_get_pkgcache(pmdb_t *db)
 {
-	/* Sanity checks */
 	ASSERT(db != NULL, return NULL);
-
 	return _alpm_db_get_pkgcache(db);
 }
 
 /** Get a group entry from a package database. */
 pmgrp_t SYMEXPORT *alpm_db_readgrp(pmdb_t *db, const char *name)
 {
-	/* Sanity checks */
 	ASSERT(db != NULL, return NULL);
 	ASSERT(name != NULL && strlen(name) != 0, return NULL);
 
@@ -281,7 +277,6 @@ pmgrp_t SYMEXPORT *alpm_db_readgrp(pmdb_t *db, const char *name)
 /** Get the group cache of a package database. */
 alpm_list_t SYMEXPORT *alpm_db_get_grpcache(pmdb_t *db)
 {
-	/* Sanity checks */
 	ASSERT(db != NULL, return NULL);
 
 	return _alpm_db_get_grpcache(db);
@@ -290,7 +285,6 @@ alpm_list_t SYMEXPORT *alpm_db_get_grpcache(pmdb_t *db)
 /** Searches a database. */
 alpm_list_t SYMEXPORT *alpm_db_search(pmdb_t *db, const alpm_list_t* needles)
 {
-	/* Sanity checks */
 	ASSERT(db != NULL, return NULL);
 
 	return _alpm_db_search(db, needles);
@@ -299,12 +293,13 @@ alpm_list_t SYMEXPORT *alpm_db_search(pmdb_t *db, const alpm_list_t* needles)
 /** Set install reason for a package in db. */
 int SYMEXPORT alpm_db_set_pkgreason(pmdb_t *db, const char *name, pmpkgreason_t reason)
 {
-	/* Sanity checks */
-	ASSERT(db != NULL && name != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
+	ASSERT(db != NULL, return -1);
+	/* TODO assert db == db_local ? shouldn't need a db param at all here... */
+	ASSERT(name != NULL, RET_ERR(db->handle, PM_ERR_WRONG_ARGS, -1));
 
 	pmpkg_t *pkg = _alpm_db_get_pkgfromcache(db, name);
 	if(pkg == NULL) {
-		RET_ERR(PM_ERR_PKG_NOT_FOUND, -1);
+		RET_ERR(db->handle, PM_ERR_PKG_NOT_FOUND, -1);
 	}
 
 	_alpm_log(PM_LOG_DEBUG, "setting install reason %u for %s/%s\n", reason, db->treename, name);
@@ -316,7 +311,7 @@ int SYMEXPORT alpm_db_set_pkgreason(pmdb_t *db, const char *name, pmpkgreason_t
 	pkg->reason = reason;
 	/* write DESC */
 	if(_alpm_local_db_write(db, pkg, INFRQ_DESC)) {
-		RET_ERR(PM_ERR_DB_WRITE, -1);
+		RET_ERR(db->handle, PM_ERR_DB_WRITE, -1);
 	}
 
 	return 0;
@@ -328,8 +323,8 @@ pmdb_t *_alpm_db_new(const char *treename, int is_local)
 {
 	pmdb_t *db;
 
-	CALLOC(db, 1, sizeof(pmdb_t), RET_ERR(PM_ERR_MEMORY, NULL));
-	STRDUP(db->treename, treename, RET_ERR(PM_ERR_MEMORY, NULL));
+	CALLOC(db, 1, sizeof(pmdb_t), return NULL);
+	STRDUP(db->treename, treename, return NULL);
 	db->is_local = is_local;
 
 	return db;
@@ -360,16 +355,16 @@ const char *_alpm_db_path(pmdb_t *db)
 		dbpath = alpm_option_get_dbpath(db->handle);
 		if(!dbpath) {
 			_alpm_log(PM_LOG_ERROR, _("database path is undefined\n"));
-			RET_ERR(PM_ERR_DB_OPEN, NULL);
+			RET_ERR(db->handle, PM_ERR_DB_OPEN, NULL);
 		}
 
 		if(db->is_local) {
 			pathsize = strlen(dbpath) + strlen(db->treename) + 2;
-			CALLOC(db->_path, 1, pathsize, RET_ERR(PM_ERR_MEMORY, NULL));
+			CALLOC(db->_path, 1, pathsize, RET_ERR(db->handle, PM_ERR_MEMORY, NULL));
 			sprintf(db->_path, "%s%s/", dbpath, db->treename);
 		} else {
 			pathsize = strlen(dbpath) + 5 + strlen(db->treename) + 4;
-			CALLOC(db->_path, 1, pathsize, RET_ERR(PM_ERR_MEMORY, NULL));
+			CALLOC(db->_path, 1, pathsize, RET_ERR(db->handle, PM_ERR_MEMORY, NULL));
 			/* all sync DBs now reside in the sync/ subdir of the dbpath */
 			sprintf(db->_path, "%ssync/%s.db", dbpath, db->treename);
 		}
@@ -413,7 +408,7 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles)
 		_alpm_log(PM_LOG_DEBUG, "searching for target '%s'\n", targ);
 
 		if(regcomp(&reg, targ, REG_EXTENDED | REG_NOSUB | REG_ICASE | REG_NEWLINE) != 0) {
-			RET_ERR(PM_ERR_INVALID_REGEX, NULL);
+			RET_ERR(db->handle, PM_ERR_INVALID_REGEX, NULL);
 		}
 
 		for(j = list; j; j = j->next) {
@@ -640,6 +635,10 @@ int _alpm_db_load_grpcache(pmdb_t *db)
 			}
 			/* we didn't find the group, so create a new one with this name */
 			grp = _alpm_grp_new(grpname);
+			if(!grp) {
+				_alpm_db_free_grpcache(db);
+				return -1;
+			}
 			grp->packages = alpm_list_add(grp->packages, pkg);
 			db->grpcache = alpm_list_add(db->grpcache, grp);
 		}
diff --git a/lib/libalpm/delta.c b/lib/libalpm/delta.c
index 645c7ba..ad2be77 100644
--- a/lib/libalpm/delta.c
+++ b/lib/libalpm/delta.c
@@ -78,6 +78,10 @@ static alpm_list_t *graph_init(alpm_list_t *deltas, int reverse)
 	/* create the vertices */
 	for(i = deltas; i; i = i->next) {
 		pmgraph_t *v = _alpm_graph_new();
+		if(!v) {
+			alpm_list_free(vertices);
+			return NULL;
+		}
 		pmdelta_t *vdelta = i->data;
 		vdelta->download_size = vdelta->delta_size;
 		v->weight = LONG_MAX;
@@ -311,17 +315,17 @@ pmdelta_t *_alpm_delta_parse(char *line)
 	}
 	regfree(&reg);
 
-	CALLOC(delta, 1, sizeof(pmdelta_t), RET_ERR(PM_ERR_MEMORY, NULL));
+	CALLOC(delta, 1, sizeof(pmdelta_t), return NULL);
 
 	tmp2 = tmp;
 	tmp = strchr(tmp, ' ');
 	*(tmp++) = '\0';
-	STRDUP(delta->delta, tmp2, RET_ERR(PM_ERR_MEMORY, NULL));
+	STRDUP(delta->delta, tmp2, return NULL);
 
 	tmp2 = tmp;
 	tmp = strchr(tmp, ' ');
 	*(tmp++) = '\0';
-	STRDUP(delta->delta_md5, tmp2, RET_ERR(PM_ERR_MEMORY, NULL));
+	STRDUP(delta->delta_md5, tmp2, return NULL);
 
 	tmp2 = tmp;
 	tmp = strchr(tmp, ' ');
@@ -331,10 +335,10 @@ pmdelta_t *_alpm_delta_parse(char *line)
 	tmp2 = tmp;
 	tmp = strchr(tmp, ' ');
 	*(tmp++) = '\0';
-	STRDUP(delta->from, tmp2, RET_ERR(PM_ERR_MEMORY, NULL));
+	STRDUP(delta->from, tmp2, return NULL);
 
 	tmp2 = tmp;
-	STRDUP(delta->to, tmp2, RET_ERR(PM_ERR_MEMORY, NULL));
+	STRDUP(delta->to, tmp2, return NULL);
 
 	_alpm_log(PM_LOG_DEBUG, "delta : %s %s '%jd'\n", delta->from, delta->to, (intmax_t)delta->delta_size);
 
diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c
index 1ebf45a..bcec8c7 100644
--- a/lib/libalpm/deps.c
+++ b/lib/libalpm/deps.c
@@ -49,11 +49,11 @@ static pmdepmissing_t *depmiss_new(const char *target, pmdepend_t *dep,
 {
 	pmdepmissing_t *miss;
 
-	MALLOC(miss, sizeof(pmdepmissing_t), RET_ERR(PM_ERR_MEMORY, NULL));
+	MALLOC(miss, sizeof(pmdepmissing_t), return NULL);
 
-	STRDUP(miss->target, target, RET_ERR(PM_ERR_MEMORY, NULL));
+	STRDUP(miss->target, target, return NULL);
 	miss->depend = _alpm_dep_dup(dep);
-	STRDUP(miss->causingpkg, causingpkg, RET_ERR(PM_ERR_MEMORY, NULL));
+	STRDUP(miss->causingpkg, causingpkg, return NULL);
 
 	return miss;
 }
@@ -247,6 +247,9 @@ static pmpkg_t *find_dep_satisfier(alpm_list_t *pkgs, pmdepend_t *dep)
 pmpkg_t SYMEXPORT *alpm_find_satisfier(alpm_list_t *pkgs, const char *depstring)
 {
 	pmdepend_t *dep = _alpm_splitdep(depstring);
+	if(!dep) {
+		return NULL;
+	}
 	pmpkg_t *pkg = find_dep_satisfier(pkgs, dep);
 	_alpm_dep_free(dep);
 	return pkg;
@@ -414,7 +417,7 @@ pmdepend_t *_alpm_splitdep(const char *depstring)
 		return NULL;
 	}
 
-	CALLOC(depend, 1, sizeof(pmdepend_t), RET_ERR(PM_ERR_MEMORY, NULL));
+	CALLOC(depend, 1, sizeof(pmdepend_t), return NULL);
 
 	/* Find a version comparator if one exists. If it does, set the type and
 	 * increment the ptr accordingly so we can copy the right strings. */
@@ -440,11 +443,10 @@ pmdepend_t *_alpm_splitdep(const char *depstring)
 	}
 
 	/* copy the right parts to the right places */
-	STRNDUP(depend->name, depstring, ptr - depstring,
-			RET_ERR(PM_ERR_MEMORY, NULL));
+	STRNDUP(depend->name, depstring, ptr - depstring, return NULL);
 	depend->name_hash = _alpm_hash_sdbm(depend->name);
 	if(version) {
-		STRDUP(depend->version, version, RET_ERR(PM_ERR_MEMORY, NULL));
+		STRDUP(depend->version, version, return NULL);
 	}
 
 	return depend;
@@ -453,11 +455,11 @@ pmdepend_t *_alpm_splitdep(const char *depstring)
 pmdepend_t *_alpm_dep_dup(const pmdepend_t *dep)
 {
 	pmdepend_t *newdep;
-	CALLOC(newdep, 1, sizeof(pmdepend_t), RET_ERR(PM_ERR_MEMORY, NULL));
+	CALLOC(newdep, 1, sizeof(pmdepend_t), return NULL);
 
-	STRDUP(newdep->name, dep->name, RET_ERR(PM_ERR_MEMORY, NULL));
+	STRDUP(newdep->name, dep->name, return NULL);
 	newdep->name_hash = dep->name_hash;
-	STRDUP(newdep->version, dep->version, RET_ERR(PM_ERR_MEMORY, NULL));
+	STRDUP(newdep->version, dep->version, return NULL);
 	newdep->mod = dep->mod;
 
 	return newdep;
@@ -562,7 +564,7 @@ static pmpkg_t *resolvedep(pmhandle_t *handle, pmdepend_t *dep,
 	for(i = dbs; i; i = i->next) {
 		pmpkg_t *pkg = _alpm_db_get_pkgfromcache(i->data, dep->name);
 		if(pkg && _alpm_depcmp(pkg, dep) && !_alpm_pkg_find(excluding, pkg->name)) {
-			if(_alpm_pkg_should_ignore(pkg)) {
+			if(_alpm_pkg_should_ignore(handle, pkg)) {
 				int install = 0;
 				if(prompt) {
 					QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg,
@@ -584,7 +586,7 @@ static pmpkg_t *resolvedep(pmhandle_t *handle, pmdepend_t *dep,
 			pmpkg_t *pkg = j->data;
 			if(_alpm_depcmp(pkg, dep) && strcmp(pkg->name, dep->name) != 0 &&
 			             !_alpm_pkg_find(excluding, pkg->name)) {
-				if(_alpm_pkg_should_ignore(pkg)) {
+				if(_alpm_pkg_should_ignore(handle, pkg)) {
 					int install = 0;
 					if(prompt) {
 						QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG,
@@ -632,9 +634,9 @@ static pmpkg_t *resolvedep(pmhandle_t *handle, pmdepend_t *dep,
 	}
 
 	if(ignored) { /* resolvedeps will override these */
-		pm_errno = PM_ERR_PKG_IGNORED;
+		handle->pm_errno = PM_ERR_PKG_IGNORED;
 	} else {
-		pm_errno = PM_ERR_PKG_NOT_FOUND;
+		handle->pm_errno = PM_ERR_PKG_NOT_FOUND;
 	}
 	return NULL;
 }
@@ -728,7 +730,7 @@ int _alpm_resolvedeps(pmhandle_t *handle, alpm_list_t *localpkgs, pmpkg_t *pkg,
 				spkg = resolvedep(handle, missdep, handle->dbs_sync, *packages, 0);
 			}
 			if(!spkg) {
-				pm_errno = PM_ERR_UNSATISFIED_DEPS;
+				handle->pm_errno = PM_ERR_UNSATISFIED_DEPS;
 				char *missdepstring = alpm_dep_compute_string(missdep);
 				_alpm_log(PM_LOG_WARNING,
 						_("cannot resolve \"%s\", a dependency of \"%s\"\n"),
@@ -860,7 +862,7 @@ char SYMEXPORT *alpm_dep_compute_string(const pmdepend_t *dep)
 	 * and ver will be empty when PM_DEP_MOD_ANY is the depend type. the
 	 * reassignments above also ensure we do not do a strlen(NULL). */
 	len = strlen(name) + strlen(opr) + strlen(ver) + 1;
-	MALLOC(str, len, RET_ERR(PM_ERR_MEMORY, NULL));
+	MALLOC(str, len, return NULL);
 	snprintf(str, len, "%s%s%s", name, opr, ver);
 
 	return str;
diff --git a/lib/libalpm/diskspace.c b/lib/libalpm/diskspace.c
index 7be5464..c24b65d 100644
--- a/lib/libalpm/diskspace.c
+++ b/lib/libalpm/diskspace.c
@@ -59,7 +59,7 @@ static int mount_point_cmp(const void *p1, const void *p2)
 	return -strcmp(mp1->mount_dir, mp2->mount_dir);
 }
 
-static alpm_list_t *mount_point_list(void)
+static alpm_list_t *mount_point_list(pmhandle_t *handle)
 {
 	alpm_list_t *mount_points = NULL, *ptr;
 	alpm_mountpoint_t *mp;
@@ -87,7 +87,7 @@ static alpm_list_t *mount_point_list(void)
 			continue;
 		}
 
-		CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(PM_ERR_MEMORY, NULL));
+		CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(handle, PM_ERR_MEMORY, NULL));
 		mp->mount_dir = strdup(mnt->mnt_dir);
 		mp->mount_dir_len = strlen(mp->mount_dir);
 		memcpy(&(mp->fsp), &fsp, sizeof(struct statvfs));
@@ -193,7 +193,7 @@ static int calculate_installed_size(pmhandle_t *handle,
 	struct archive_entry *entry;
 
 	if((archive = archive_read_new()) == NULL) {
-		pm_errno = PM_ERR_LIBARCHIVE;
+		handle->pm_errno = PM_ERR_LIBARCHIVE;
 		ret = -1;
 		goto cleanup;
 	}
@@ -203,7 +203,7 @@ static int calculate_installed_size(pmhandle_t *handle,
 
 	if(archive_read_open_filename(archive, pkg->origin_data.file,
 				ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
-		pm_errno = PM_ERR_PKG_OPEN;
+		handle->pm_errno = PM_ERR_PKG_OPEN;
 		ret = -1;
 		goto cleanup;
 	}
@@ -246,7 +246,7 @@ static int calculate_installed_size(pmhandle_t *handle,
 		if(archive_read_data_skip(archive)) {
 			_alpm_log(PM_LOG_ERROR, _("error while reading package %s: %s\n"),
 					pkg->name, archive_error_string(archive));
-			pm_errno = PM_ERR_LIBARCHIVE;
+			handle->pm_errno = PM_ERR_LIBARCHIVE;
 			break;
 		}
 	}
@@ -267,7 +267,7 @@ int _alpm_check_diskspace(pmhandle_t *handle)
 	pmtrans_t *trans = handle->trans;
 
 	numtargs = alpm_list_count(trans->add);
-	mount_points = mount_point_list();
+	mount_points = mount_point_list(handle);
 	if(mount_points == NULL) {
 		_alpm_log(PM_LOG_ERROR, _("could not determine filesystem mount points\n"));
 		return -1;
@@ -350,7 +350,7 @@ int _alpm_check_diskspace(pmhandle_t *handle)
 	FREELIST(mount_points);
 
 	if(abort) {
-		RET_ERR(PM_ERR_DISK_SPACE, -1);
+		RET_ERR(handle, PM_ERR_DISK_SPACE, -1);
 	}
 
 	return 0;
diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c
index 0ba3bc1..fee5a98 100644
--- a/lib/libalpm/dload.c
+++ b/lib/libalpm/dload.c
@@ -42,9 +42,6 @@
 #include "util.h"
 #include "handle.h"
 
-/* global handle variable */
-extern pmhandle_t *handle;
-
 #ifdef HAVE_LIBCURL
 static double prevprogress; /* last download amount */
 #endif
@@ -65,7 +62,7 @@ static char *get_fullpath(const char *path, const char *filename,
 	char *filepath;
 	/* len = localpath len + filename len + suffix len + null */
 	size_t len = strlen(path) + strlen(filename) + strlen(suffix) + 1;
-	CALLOC(filepath, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, NULL));
+	CALLOC(filepath, len, sizeof(char), return NULL);
 	snprintf(filepath, len, "%s%s%s", path, filename, suffix);
 
 	return filepath;
@@ -92,7 +89,7 @@ static int curl_progress(void *file, double dltotal, double dlnow,
 	}
 
 	/* none of what follows matters if the front end has no callback */
-	if(handle->dlcb == NULL) {
+	if(dlfile->handle->dlcb == NULL) {
 		return 0;
 	}
 
@@ -106,10 +103,10 @@ static int curl_progress(void *file, double dltotal, double dlnow,
 	/* initialize the progress bar here to avoid displaying it when
 	 * a repo is up to date and nothing gets downloaded */
 	if(DOUBLE_EQ(prevprogress, 0)) {
-		handle->dlcb(dlfile->filename, 0, (long)dltotal);
+		dlfile->handle->dlcb(dlfile->filename, 0, (long)dltotal);
 	}
 
-	handle->dlcb(dlfile->filename, (long)current_size, (long)total_size);
+	dlfile->handle->dlcb(dlfile->filename, (long)current_size, (long)total_size);
 
 	prevprogress = current_size;
 
@@ -153,7 +150,8 @@ static int utimes_long(const char *path, long time)
 }
 
 
-static int curl_download_internal(const char *url, const char *localpath,
+static int curl_download_internal(pmhandle_t *handle,
+		const char *url, const char *localpath,
 		int force, int allow_resume, int errors_ok)
 {
 	int ret = -1;
@@ -170,11 +168,12 @@ static int curl_download_internal(const char *url, const char *localpath,
 	struct sigaction sig_pipe[2], sig_int[2];
 	struct fileinfo dlfile;
 
+	dlfile.handle = handle;
 	dlfile.initial_size = 0.0;
 	dlfile.filename = get_filename(url);
 	if(!dlfile.filename || curl_gethost(url, hostname) != 0) {
 		_alpm_log(PM_LOG_ERROR, _("url '%s' is invalid\n"), url);
-		RET_ERR(PM_ERR_SERVER_BAD_URL, -1);
+		RET_ERR(handle, PM_ERR_SERVER_BAD_URL, -1);
 	}
 
 	destfile = get_fullpath(localpath, dlfile.filename, "");
@@ -250,7 +249,7 @@ static int curl_download_internal(const char *url, const char *localpath,
 		goto cleanup;
 	} else if(handle->curlerr != CURLE_OK) {
 		if(!errors_ok) {
-			pm_errno = PM_ERR_LIBCURL;
+			handle->pm_errno = PM_ERR_LIBCURL;
 			_alpm_log(PM_LOG_ERROR, _("failed retrieving file '%s' from %s : %s\n"),
 					dlfile.filename, hostname, error_buffer);
 		} else {
@@ -280,7 +279,7 @@ static int curl_download_internal(const char *url, const char *localpath,
 	 * as actually being transferred during curl_easy_perform() */
 	if(!DOUBLE_EQ(remote_size, -1) && !DOUBLE_EQ(bytes_dl, -1) &&
 			!DOUBLE_EQ(bytes_dl, remote_size)) {
-		pm_errno = PM_ERR_RETRIEVE;
+		handle->pm_errno = PM_ERR_RETRIEVE;
 		_alpm_log(PM_LOG_ERROR, _("%s appears to be truncated: %jd/%jd bytes\n"),
 				dlfile.filename, (intmax_t)bytes_dl, (intmax_t)remote_size);
 		goto cleanup;
@@ -313,19 +312,20 @@ cleanup:
 }
 #endif
 
-int _alpm_download(const char *url, const char *localpath,
+int _alpm_download(pmhandle_t *handle, const char *url, const char *localpath,
 		int force, int allow_resume, int errors_ok)
 {
 	if(handle->fetchcb == NULL) {
 #ifdef HAVE_LIBCURL
-		return curl_download_internal(url, localpath, force, allow_resume, errors_ok);
+		return curl_download_internal(handle, url, localpath,
+				force, allow_resume, errors_ok);
 #else
-		RET_ERR(PM_ERR_EXTERNAL_DOWNLOAD, -1);
+		RET_ERR(handle, PM_ERR_EXTERNAL_DOWNLOAD, -1);
 #endif
 	} else {
 		int ret = handle->fetchcb(url, localpath, force);
 		if(ret == -1 && !errors_ok) {
-			RET_ERR(PM_ERR_EXTERNAL_DOWNLOAD, -1);
+			RET_ERR(handle, PM_ERR_EXTERNAL_DOWNLOAD, -1);
 		}
 		return ret;
 	}
@@ -344,7 +344,7 @@ char SYMEXPORT *alpm_fetch_pkgurl(pmhandle_t *handle, const char *url)
 	cachedir = _alpm_filecache_setup(handle);
 
 	/* download the file */
-	ret = _alpm_download(url, cachedir, 0, 1, 0);
+	ret = _alpm_download(handle, url, cachedir, 0, 1, 0);
 	if(ret == -1) {
 		_alpm_log(PM_LOG_WARNING, _("failed to download %s\n"), url);
 		return NULL;
@@ -359,10 +359,10 @@ char SYMEXPORT *alpm_fetch_pkgurl(pmhandle_t *handle, const char *url)
 		int errors_ok = (handle->sigverify == PM_PGP_VERIFY_OPTIONAL);
 
 		len = strlen(url) + 5;
-		CALLOC(sig_url, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, NULL));
+		CALLOC(sig_url, len, sizeof(char), RET_ERR(handle, PM_ERR_MEMORY, NULL));
 		snprintf(sig_url, len, "%s.sig", url);
 
-		ret = _alpm_download(sig_url, cachedir, 1, 0, errors_ok);
+		ret = _alpm_download(handle, sig_url, cachedir, 1, 0, errors_ok);
 		if(ret == -1 && !errors_ok) {
 			_alpm_log(PM_LOG_WARNING, _("failed to download %s\n"), sig_url);
 			/* Warn now, but don't return NULL. We will fail later during package
diff --git a/lib/libalpm/dload.h b/lib/libalpm/dload.h
index f4fd14c..e409c32 100644
--- a/lib/libalpm/dload.h
+++ b/lib/libalpm/dload.h
@@ -27,11 +27,12 @@
 
 /* internal structure for communicating with curl progress callback */
 struct fileinfo {
+	pmhandle_t *handle;
 	const char *filename;
 	double initial_size;
 };
 
-int _alpm_download(const char *url, const char *localpath,
+int _alpm_download(pmhandle_t *handle, const char *url, const char *localpath,
 		int force, int allow_resume, int errors_ok);
 
 #endif /* _ALPM_DLOAD_H */
diff --git a/lib/libalpm/error.c b/lib/libalpm/error.c
index 294ec21..d893f86 100644
--- a/lib/libalpm/error.c
+++ b/lib/libalpm/error.c
@@ -29,15 +29,12 @@
 #include "alpm.h"
 #include "handle.h"
 
-/* global handle variable */
-extern pmhandle_t *handle;
-
-const char SYMEXPORT *alpm_strerrorlast(void)
+enum _pmerrno_t SYMEXPORT alpm_errno(pmhandle_t *handle)
 {
-	return alpm_strerror(pm_errno);
+	return handle->pm_errno;
 }
 
-const char SYMEXPORT *alpm_strerror(int err)
+const char SYMEXPORT *alpm_strerror(enum _pmerrno_t err)
 {
 	switch(err) {
 		/* System */
@@ -140,8 +137,6 @@ const char SYMEXPORT *alpm_strerror(int err)
 		/* Miscellaenous */
 		case PM_ERR_RETRIEVE:
 			return _("failed to retrieve some files");
-		case PM_ERR_WRITE:
-			return _("failed to copy some file");
 		case PM_ERR_INVALID_REGEX:
 			return _("invalid regular expression");
 		/* Errors from external libraries- our own wrapper error */
@@ -151,12 +146,7 @@ const char SYMEXPORT *alpm_strerror(int err)
 			 * error string instead. */
 			return _("libarchive error");
 		case PM_ERR_LIBCURL:
-#ifdef HAVE_LIBCURL
-			return curl_easy_strerror(handle->curlerr);
-#else
-			/* obviously shouldn't get here... */
 			return _("download library error");
-#endif
 		case PM_ERR_GPGME:
 			return _("gpgme error");
 		case PM_ERR_EXTERNAL_DOWNLOAD:
diff --git a/lib/libalpm/graph.c b/lib/libalpm/graph.c
index 2e2ba23..29bf86a 100644
--- a/lib/libalpm/graph.c
+++ b/lib/libalpm/graph.c
@@ -27,7 +27,7 @@ pmgraph_t *_alpm_graph_new(void)
 {
 	pmgraph_t *graph = NULL;
 
-	CALLOC(graph, 1, sizeof(pmgraph_t), RET_ERR(PM_ERR_MEMORY, NULL));
+	CALLOC(graph, 1, sizeof(pmgraph_t), return NULL);
 	return graph;
 }
 
diff --git a/lib/libalpm/group.c b/lib/libalpm/group.c
index 383d016..1d77382 100644
--- a/lib/libalpm/group.c
+++ b/lib/libalpm/group.c
@@ -34,8 +34,8 @@ pmgrp_t *_alpm_grp_new(const char *name)
 {
 	pmgrp_t* grp;
 
-	CALLOC(grp, 1, sizeof(pmgrp_t), RET_ERR(PM_ERR_MEMORY, NULL));
-	STRDUP(grp->name, name, RET_ERR(PM_ERR_MEMORY, NULL));
+	CALLOC(grp, 1, sizeof(pmgrp_t), return NULL);
+	STRDUP(grp->name, name, free(grp); return NULL);
 
 	return grp;
 }
diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c
index 0e50cbd..888eae8 100644
--- a/lib/libalpm/handle.c
+++ b/lib/libalpm/handle.c
@@ -44,7 +44,7 @@ pmhandle_t *_alpm_handle_new()
 {
 	pmhandle_t *handle;
 
-	CALLOC(handle, 1, sizeof(pmhandle_t), RET_ERR(PM_ERR_MEMORY, NULL));
+	CALLOC(handle, 1, sizeof(pmhandle_t), return NULL);
 
 	handle->sigverify = PM_PGP_VERIFY_OPTIONAL;
 
@@ -290,7 +290,7 @@ int SYMEXPORT alpm_option_add_cachedir(pmhandle_t *handle, const char *cachedir)
 
 	ASSERT(handle != NULL, return -1);
 	if(!cachedir) {
-		pm_errno = PM_ERR_WRONG_ARGS;
+		handle->pm_errno = PM_ERR_WRONG_ARGS;
 		return -1;
 	}
 	/* don't stat the cachedir yet, as it may not even be needed. we can
@@ -347,7 +347,7 @@ int SYMEXPORT alpm_option_set_logfile(pmhandle_t *handle, const char *logfile)
 
 	ASSERT(handle != NULL, return -1);
 	if(!logfile) {
-		pm_errno = PM_ERR_WRONG_ARGS;
+		handle->pm_errno = PM_ERR_WRONG_ARGS;
 		return -1;
 	}
 
@@ -370,7 +370,7 @@ int SYMEXPORT alpm_option_set_signaturedir(pmhandle_t *handle, const char *signa
 {
 	ASSERT(handle != NULL, return -1);
 	if(!signaturedir) {
-		pm_errno = PM_ERR_WRONG_ARGS;
+		handle->pm_errno = PM_ERR_WRONG_ARGS;
 		return -1;
 	}
 
@@ -527,7 +527,7 @@ int SYMEXPORT alpm_option_set_checkspace(pmhandle_t *handle, int checkspace)
 int SYMEXPORT alpm_option_set_default_sigverify(pmhandle_t *handle, pgp_verify_t level)
 {
 	ASSERT(handle != NULL, return -1);
-	ASSERT(level != PM_PGP_VERIFY_UNKNOWN, RET_ERR(PM_ERR_WRONG_ARGS, -1));
+	ASSERT(level != PM_PGP_VERIFY_UNKNOWN, RET_ERR(handle, PM_ERR_WRONG_ARGS, -1));
 	handle->sigverify = level;
 	return 0;
 }
diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h
index ecfefcc..bace805 100644
--- a/lib/libalpm/handle.h
+++ b/lib/libalpm/handle.h
@@ -70,6 +70,9 @@ struct __pmhandle_t {
 	int usedelta;            /* Download deltas if possible */
 	int checkspace;          /* Check disk space before installing */
 	pgp_verify_t sigverify;  /* Default signature verification level */
+
+	/* error code */
+	enum _pmerrno_t pm_errno;
 };
 
 pmhandle_t *_alpm_handle_new(void);
diff --git a/lib/libalpm/log.c b/lib/libalpm/log.c
index 023bfc9..2b6385b 100644
--- a/lib/libalpm/log.c
+++ b/lib/libalpm/log.c
@@ -39,6 +39,7 @@ extern pmhandle_t *handle;
  */
 
 /** A printf-like function for logging.
+ * @param handle the context handle
  * @param fmt output format
  * @return 0 on success, -1 on error (pm_errno is set accordingly)
  */
@@ -47,8 +48,7 @@ int SYMEXPORT alpm_logaction(pmhandle_t *handle, const char *fmt, ...)
 	int ret;
 	va_list args;
 
-	/* Sanity checks */
-	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
+	ASSERT(handle != NULL, return -1);
 
 	/* check if the logstream is open already, opening it if needed */
 	if(handle->logstream == NULL) {
@@ -56,13 +56,13 @@ int SYMEXPORT alpm_logaction(pmhandle_t *handle, const char *fmt, ...)
 		/* if we couldn't open it, we have an issue */
 		if(handle->logstream == NULL) {
 			if(errno == EACCES) {
-				pm_errno = PM_ERR_BADPERMS;
+				handle->pm_errno = PM_ERR_BADPERMS;
 			} else if(errno == ENOENT) {
-				pm_errno = PM_ERR_NOT_A_DIR;
+				handle->pm_errno = PM_ERR_NOT_A_DIR;
 			} else {
-				pm_errno = PM_ERR_SYSTEM;
+				handle->pm_errno = PM_ERR_SYSTEM;
 			}
-		return -1;
+			return -1;
 		}
 	}
 
diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c
index 67d31c3..7071e89 100644
--- a/lib/libalpm/package.c
+++ b/lib/libalpm/package.c
@@ -45,7 +45,7 @@
 /** Free a package. */
 int SYMEXPORT alpm_pkg_free(pmpkg_t *pkg)
 {
-	ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
+	ASSERT(pkg != NULL, return -1);
 
 	/* Only free packages loaded in user space */
 	if(pkg->origin == PKG_FROM_FILE) {
@@ -61,9 +61,9 @@ int SYMEXPORT alpm_pkg_checkmd5sum(pmpkg_t *pkg)
 	char *fpath;
 	int retval;
 
-	ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
+	ASSERT(pkg != NULL, return -1);
 	/* We only inspect packages from sync repositories */
-	ASSERT(pkg->origin == PKG_FROM_SYNCDB, RET_ERR(PM_ERR_PKG_INVALID, -1));
+	ASSERT(pkg->origin == PKG_FROM_SYNCDB, return -1);
 
 	fpath = _alpm_filecache_find(pkg->handle, alpm_pkg_get_filename(pkg));
 
@@ -72,7 +72,7 @@ int SYMEXPORT alpm_pkg_checkmd5sum(pmpkg_t *pkg)
 	if(retval == 0) {
 		return 0;
 	} else if(retval == 1) {
-		pm_errno = PM_ERR_PKG_INVALID;
+		pkg->handle->pm_errno = PM_ERR_PKG_INVALID;
 		retval = -1;
 	}
 
@@ -366,7 +366,7 @@ pmpkg_t *_alpm_pkg_new(void)
 {
 	pmpkg_t* pkg;
 
-	CALLOC(pkg, 1, sizeof(pmpkg_t), RET_ERR(PM_ERR_MEMORY, NULL));
+	CALLOC(pkg, 1, sizeof(pmpkg_t), return NULL);
 
 	return pkg;
 }
@@ -376,19 +376,19 @@ pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg)
 	pmpkg_t *newpkg;
 	alpm_list_t *i;
 
-	CALLOC(newpkg, 1, sizeof(pmpkg_t), RET_ERR(PM_ERR_MEMORY, NULL));
+	CALLOC(newpkg, 1, sizeof(pmpkg_t), goto cleanup);
 
 	newpkg->name_hash = pkg->name_hash;
-	STRDUP(newpkg->filename, pkg->filename, RET_ERR(PM_ERR_MEMORY, newpkg));
-	STRDUP(newpkg->name, pkg->name, RET_ERR(PM_ERR_MEMORY, newpkg));
-	STRDUP(newpkg->version, pkg->version, RET_ERR(PM_ERR_MEMORY, newpkg));
-	STRDUP(newpkg->desc, pkg->desc, RET_ERR(PM_ERR_MEMORY, newpkg));
-	STRDUP(newpkg->url, pkg->url, RET_ERR(PM_ERR_MEMORY, newpkg));
+	STRDUP(newpkg->filename, pkg->filename, goto cleanup);
+	STRDUP(newpkg->name, pkg->name, goto cleanup);
+	STRDUP(newpkg->version, pkg->version, goto cleanup);
+	STRDUP(newpkg->desc, pkg->desc, goto cleanup);
+	STRDUP(newpkg->url, pkg->url, goto cleanup);
 	newpkg->builddate = pkg->builddate;
 	newpkg->installdate = pkg->installdate;
-	STRDUP(newpkg->packager, pkg->packager, RET_ERR(PM_ERR_MEMORY, newpkg));
-	STRDUP(newpkg->md5sum, pkg->md5sum, RET_ERR(PM_ERR_MEMORY, newpkg));
-	STRDUP(newpkg->arch, pkg->arch, RET_ERR(PM_ERR_MEMORY, newpkg));
+	STRDUP(newpkg->packager, pkg->packager, goto cleanup);
+	STRDUP(newpkg->md5sum, pkg->md5sum, goto cleanup);
+	STRDUP(newpkg->arch, pkg->arch, goto cleanup);
 	newpkg->size = pkg->size;
 	newpkg->isize = pkg->isize;
 	newpkg->scriptlet = pkg->scriptlet;
@@ -419,6 +419,10 @@ pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg)
 	newpkg->handle = pkg->handle;
 
 	return newpkg;
+
+cleanup:
+	_alpm_pkg_free(newpkg);
+	return NULL;
 }
 
 void _alpm_pkg_free(pmpkg_t *pkg)
@@ -534,7 +538,7 @@ pmpkg_t *_alpm_pkg_find(alpm_list_t *haystack, const char *needle)
  *
  * @return 1 if the package should be ignored, 0 otherwise
  */
-int _alpm_pkg_should_ignore(pmpkg_t *pkg)
+int _alpm_pkg_should_ignore(pmhandle_t *handle, pmpkg_t *pkg)
 {
 	alpm_list_t *groups = NULL;
 
diff --git a/lib/libalpm/package.h b/lib/libalpm/package.h
index b5d8f73..bc5b267 100644
--- a/lib/libalpm/package.h
+++ b/lib/libalpm/package.h
@@ -149,7 +149,7 @@ pmpkg_t *_alpm_pkg_load_internal(pmhandle_t *handle, const char *pkgfile,
 int _alpm_pkg_cmp(const void *p1, const void *p2);
 int _alpm_pkg_compare_versions(pmpkg_t *local_pkg, pmpkg_t *pkg);
 pmpkg_t *_alpm_pkg_find(alpm_list_t *haystack, const char *needle);
-int _alpm_pkg_should_ignore(pmpkg_t *pkg);
+int _alpm_pkg_should_ignore(pmhandle_t *handle, pmpkg_t *pkg);
 
 #endif /* _ALPM_PACKAGE_H */
 
diff --git a/lib/libalpm/pkghash.c b/lib/libalpm/pkghash.c
index 7e5e1fc..a22e6b5 100644
--- a/lib/libalpm/pkghash.c
+++ b/lib/libalpm/pkghash.c
@@ -55,11 +55,7 @@ pmpkghash_t *_alpm_pkghash_create(size_t size)
 	pmpkghash_t *hash = NULL;
 	size_t i, loopsize;
 
-	MALLOC(hash, sizeof(pmpkghash_t), RET_ERR(PM_ERR_MEMORY, NULL));
-
-	hash->list = NULL;
-	hash->entries = 0;
-	hash->buckets = 0;
+	CALLOC(hash, 1, sizeof(pmpkghash_t), return NULL);
 
 	loopsize = sizeof(prime_list) / sizeof(*prime_list);
 	for(i = 0; i < loopsize; i++) {
@@ -76,7 +72,7 @@ pmpkghash_t *_alpm_pkghash_create(size_t size)
 	}
 
 	CALLOC(hash->hash_table, hash->buckets, sizeof(alpm_list_t *), \
-				free(hash); RET_ERR(PM_ERR_MEMORY, NULL));
+				free(hash); return NULL);
 
 	return hash;
 }
diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c
index 5f09930..e1c78c4 100644
--- a/lib/libalpm/remove.c
+++ b/lib/libalpm/remove.c
@@ -50,16 +50,16 @@ int SYMEXPORT alpm_remove_pkg(pmpkg_t *pkg)
 	const char *pkgname;
 
 	/* Sanity checks */
-	ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
+	ASSERT(pkg != NULL, return -1);
 	trans = pkg->handle->trans;
-	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
+	ASSERT(trans != NULL, RET_ERR(pkg->handle, PM_ERR_TRANS_NULL, -1));
 	ASSERT(trans->state == STATE_INITIALIZED,
-			RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1));
+			RET_ERR(pkg->handle, PM_ERR_TRANS_NOT_INITIALIZED, -1));
 
 	pkgname = pkg->name;
 
 	if(_alpm_pkg_find(trans->remove, pkgname)) {
-		RET_ERR(PM_ERR_TRANS_DUP_TARGET, -1);
+		RET_ERR(pkg->handle, PM_ERR_TRANS_DUP_TARGET, -1);
 	}
 
 	_alpm_log(PM_LOG_DEBUG, "adding package %s to the transaction remove list\n",
@@ -164,7 +164,7 @@ int _alpm_remove_prepare(pmhandle_t *handle, alpm_list_t **data)
 					alpm_list_free_inner(lp, (alpm_list_fn_free)_alpm_depmiss_free);
 					alpm_list_free(lp);
 				}
-				RET_ERR(PM_ERR_UNSATISFIED_DEPS, -1);
+				RET_ERR(handle, PM_ERR_UNSATISFIED_DEPS, -1);
 			}
 		}
 	}
@@ -189,11 +189,12 @@ int _alpm_remove_prepare(pmhandle_t *handle, alpm_list_t **data)
 	return 0;
 }
 
-static int can_remove_file(pmhandle_t *handle, const char *path, alpm_list_t *skip)
+static int can_remove_file(const char *root, const char *path,
+		alpm_list_t *skip)
 {
 	char file[PATH_MAX+1];
 
-	snprintf(file, PATH_MAX, "%s%s", handle->root, path);
+	snprintf(file, PATH_MAX, "%s%s", root, path);
 
 	if(alpm_list_find_str(skip, file)) {
 		/* return success because we will never actually remove this file */
@@ -317,10 +318,10 @@ int _alpm_upgraderemove_package(pmhandle_t *handle,
 	}
 
 	for(lp = files; lp; lp = lp->next) {
-		if(!can_remove_file(handle, lp->data, skip_remove)) {
+		if(!can_remove_file(handle->root, 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);
+			RET_ERR(handle, PM_ERR_PKG_CANT_REMOVE, -1);
 		}
 	}
 
@@ -393,10 +394,10 @@ int _alpm_remove_packages(pmhandle_t *handle)
 			size_t filenum;
 
 			for(lp = files; lp; lp = lp->next) {
-				if(!can_remove_file(handle, lp->data, NULL)) {
+				if(!can_remove_file(handle->root, 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);
+					RET_ERR(handle, PM_ERR_PKG_CANT_REMOVE, -1);
 				}
 			}
 
diff --git a/lib/libalpm/signing.c b/lib/libalpm/signing.c
index 6ce56e5..ec465e7 100644
--- a/lib/libalpm/signing.c
+++ b/lib/libalpm/signing.c
@@ -35,6 +35,7 @@
 #include "util.h"
 #include "log.h"
 #include "alpm.h"
+#include "handle.h"
 
 #if HAVE_LIBGPGME
 #define CHECK_ERR(void) do { \
@@ -117,7 +118,7 @@ static int gpgme_init(pmhandle_t *handle)
 	}
 
 	if(!alpm_option_get_signaturedir(handle)) {
-		RET_ERR(PM_ERR_SIG_MISSINGDIR, 1);
+		RET_ERR(handle, PM_ERR_SIG_MISSINGDIR, 1);
 	}
 
 	/* calling gpgme_check_version() returns the current version and runs
@@ -154,7 +155,7 @@ static int gpgme_init(pmhandle_t *handle)
 
 error:
 	_alpm_log(PM_LOG_ERROR, _("GPGME error: %s\n"), gpgme_strerror(err));
-	RET_ERR(PM_ERR_GPGME, 1);
+	RET_ERR(handle, PM_ERR_GPGME, 1);
 }
 
 /**
@@ -214,17 +215,17 @@ int _alpm_gpgme_checksig(pmhandle_t *handle, const char *path,
 	FILE *file = NULL, *sigfile = NULL;
 
 	if(!path || access(path, R_OK) != 0) {
-		RET_ERR(PM_ERR_NOT_A_FILE, -1);
+		RET_ERR(handle, PM_ERR_NOT_A_FILE, -1);
 	}
 
 	if(!base64_sig) {
 		size_t len = strlen(path) + 5;
-		CALLOC(sigpath, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, -1));
+		CALLOC(sigpath, len, sizeof(char), RET_ERR(handle, PM_ERR_MEMORY, -1));
 		snprintf(sigpath, len, "%s.sig", path);
 
 		if(!access(sigpath, R_OK) == 0) {
 			FREE(sigpath);
-			RET_ERR(PM_ERR_SIG_UNKNOWN, -1);
+			RET_ERR(handle, PM_ERR_SIG_UNKNOWN, -1);
 		}
 	}
 
@@ -245,7 +246,7 @@ int _alpm_gpgme_checksig(pmhandle_t *handle, const char *path,
 	/* create our necessary data objects to verify the signature */
 	file = fopen(path, "rb");
 	if(file == NULL) {
-		pm_errno = PM_ERR_NOT_A_FILE;
+		handle->pm_errno = PM_ERR_NOT_A_FILE;
 		ret = -1;
 		goto error;
 	}
@@ -268,7 +269,7 @@ int _alpm_gpgme_checksig(pmhandle_t *handle, const char *path,
 		/* file-based, it is on disk */
 		sigfile = fopen(sigpath, "rb");
 		if(sigfile == NULL) {
-			pm_errno = PM_ERR_NOT_A_FILE;
+			handle->pm_errno = PM_ERR_NOT_A_FILE;
 			ret = -1;
 			goto error;
 		}
@@ -324,13 +325,13 @@ int _alpm_gpgme_checksig(pmhandle_t *handle, const char *path,
 		_alpm_log(PM_LOG_WARNING, _("File %s has a green signature.\n"),
 				path);
 	} else if(gpgsig->summary & GPGME_SIGSUM_KEY_MISSING) {
-		pm_errno = PM_ERR_SIG_UNKNOWN;
+		handle->pm_errno = PM_ERR_SIG_UNKNOWN;
 		_alpm_log(PM_LOG_WARNING, _("File %s has a signature from an unknown key.\n"),
 				path);
 		ret = -1;
 	} else {
 		/* we'll capture everything else here */
-		pm_errno = PM_ERR_SIG_INVALID;
+		handle->pm_errno = PM_ERR_SIG_INVALID;
 		_alpm_log(PM_LOG_ERROR, _("File %s has an invalid signature.\n"),
 				path);
 		ret = 1;
@@ -350,12 +351,13 @@ error:
 	FREE(decoded_sigdata);
 	if(err != GPG_ERR_NO_ERROR) {
 		_alpm_log(PM_LOG_ERROR, _("GPGME error: %s\n"), gpgme_strerror(err));
-		RET_ERR(PM_ERR_GPGME, -1);
+		RET_ERR(handle, PM_ERR_GPGME, -1);
 	}
 	return ret;
 }
 #else
-int _alpm_gpgme_checksig(const char *path, const char *base64_sig)
+int _alpm_gpgme_checksig(pmhandle_t *handle, const char *path,
+		const char *base64_sig)
 {
 	return -1;
 }
@@ -369,7 +371,6 @@ int _alpm_gpgme_checksig(const char *path, const char *base64_sig)
  */
 pgp_verify_t _alpm_db_get_sigverify_level(pmdb_t *db)
 {
-	ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, PM_PGP_VERIFY_UNKNOWN));
 
 	if(db->pgp_verify != PM_PGP_VERIFY_UNKNOWN) {
 		return db->pgp_verify;
diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c
index b525efa..f8b93f1 100644
--- a/lib/libalpm/sync.c
+++ b/lib/libalpm/sync.c
@@ -89,12 +89,12 @@ int SYMEXPORT alpm_sync_sysupgrade(pmhandle_t *handle, int enable_downgrade)
 	pmdb_t *db_local;
 	alpm_list_t *dbs_sync;
 
-	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
+	ASSERT(handle != NULL, return -1);
 	trans = handle->trans;
 	db_local = handle->db_local;
 	dbs_sync = handle->dbs_sync;
-	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 != NULL, RET_ERR(handle, PM_ERR_TRANS_NULL, -1));
+	ASSERT(trans->state == STATE_INITIALIZED, RET_ERR(handle, PM_ERR_TRANS_NOT_INITIALIZED, -1));
 
 	_alpm_log(PM_LOG_DEBUG, "checking for package upgrades\n");
 	for(i = _alpm_db_get_pkgcache(db_local); i; i = i->next) {
@@ -118,7 +118,8 @@ int SYMEXPORT alpm_sync_sysupgrade(pmhandle_t *handle, int enable_downgrade)
 					_alpm_log(PM_LOG_DEBUG, "new version of '%s' found (%s => %s)\n",
 								lpkg->name, lpkg->version, spkg->version);
 					/* check IgnorePkg/IgnoreGroup */
-					if(_alpm_pkg_should_ignore(spkg) || _alpm_pkg_should_ignore(lpkg)) {
+					if(_alpm_pkg_should_ignore(spkg->handle, spkg)
+							|| _alpm_pkg_should_ignore(lpkg->handle, lpkg)) {
 						_alpm_log(PM_LOG_WARNING, _("%s: ignoring package upgrade (%s => %s)\n"),
 										lpkg->name, lpkg->version, spkg->version);
 					} else {
@@ -129,7 +130,8 @@ int SYMEXPORT alpm_sync_sysupgrade(pmhandle_t *handle, int enable_downgrade)
 				} else if(cmp < 0) {
 					if(enable_downgrade) {
 						/* check IgnorePkg/IgnoreGroup */
-						if(_alpm_pkg_should_ignore(spkg) || _alpm_pkg_should_ignore(lpkg)) {
+						if(_alpm_pkg_should_ignore(spkg->handle, spkg)
+								|| _alpm_pkg_should_ignore(lpkg->handle, lpkg)) {
 							_alpm_log(PM_LOG_WARNING, _("%s: ignoring package downgrade (%s => %s)\n"),
 											lpkg->name, lpkg->version, spkg->version);
 						} else {
@@ -152,7 +154,8 @@ int SYMEXPORT alpm_sync_sysupgrade(pmhandle_t *handle, int enable_downgrade)
 					if(alpm_list_find_str(alpm_pkg_get_replaces(spkg), lpkg->name)) {
 						found = 1;
 						/* check IgnorePkg/IgnoreGroup */
-						if(_alpm_pkg_should_ignore(spkg) || _alpm_pkg_should_ignore(lpkg)) {
+						if(_alpm_pkg_should_ignore(spkg->handle, spkg)
+								|| _alpm_pkg_should_ignore(lpkg->handle, lpkg)) {
 							_alpm_log(PM_LOG_WARNING, _("ignoring package replacement (%s-%s => %s-%s)\n"),
 										lpkg->name, lpkg->version, spkg->name, spkg->version);
 							continue;
@@ -228,7 +231,7 @@ alpm_list_t SYMEXPORT *alpm_find_grp_pkgs(pmhandle_t *handle, alpm_list_t *dbs,
 			if(_alpm_pkg_find(ignorelist, alpm_pkg_get_name(pkg))) {
 				continue;
 			}
-			if(_alpm_pkg_should_ignore(pkg)) {
+			if(_alpm_pkg_should_ignore(pkg->handle, pkg)) {
 				ignorelist = alpm_list_add(ignorelist, pkg);
 				int install = 0;
 				QUESTION(db->handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg,
@@ -262,7 +265,7 @@ static int compute_download_size(pmpkg_t *newpkg)
 	}
 
 	fname = alpm_pkg_get_filename(newpkg);
-	ASSERT(fname != NULL, RET_ERR(PM_ERR_PKG_INVALID_NAME, -1));
+	ASSERT(fname != NULL, RET_ERR(newpkg->handle, PM_ERR_PKG_INVALID_NAME, -1));
 	fpath = _alpm_filecache_find(newpkg->handle, fname);
 
 	if(fpath) {
@@ -300,13 +303,12 @@ static int compute_download_size(pmpkg_t *newpkg)
 
 int _alpm_sync_prepare(pmhandle_t *handle, alpm_list_t **data)
 {
+	alpm_list_t *i, *j;
 	alpm_list_t *deps = NULL;
 	alpm_list_t *unresolvable = NULL;
-	alpm_list_t *i, *j;
 	alpm_list_t *remove = NULL;
 	int ret = 0;
 	pmtrans_t *trans = handle->trans;
-	pmdb_t *db_local = handle->db_local;
 
 	if(data) {
 		*data = NULL;
@@ -330,7 +332,7 @@ int _alpm_sync_prepare(pmhandle_t *handle, alpm_list_t **data)
 
 		/* Compute the fake local database for resolvedeps (partial fix for the
 		 * phonon/qt issue) */
-		alpm_list_t *localpkgs = alpm_list_diff(_alpm_db_get_pkgcache(db_local),
+		alpm_list_t *localpkgs = alpm_list_diff(_alpm_db_get_pkgcache(handle->db_local),
 				trans->add, _alpm_pkg_cmp);
 
 		/* Resolve packages in the transaction one at a time, in addition
@@ -350,14 +352,14 @@ int _alpm_sync_prepare(pmhandle_t *handle, alpm_list_t **data)
 		   see if they'd like to ignore them rather than failing the sync */
 		if(unresolvable != NULL) {
 			int remove_unresolvable = 0;
-			QUESTION(handle->trans, PM_TRANS_CONV_REMOVE_PKGS, unresolvable,
+			QUESTION(trans, PM_TRANS_CONV_REMOVE_PKGS, unresolvable,
 					NULL, NULL, &remove_unresolvable);
 			if(remove_unresolvable) {
 				/* User wants to remove the unresolvable packages from the
 				   transaction. The packages will be removed from the actual
 				   transaction when the transaction packages are replaced with a
 				   dependency-reordered list below */
-				pm_errno = 0; /* pm_errno was set by resolvedeps */
+				handle->pm_errno = 0; /* pm_errno was set by resolvedeps */
 				if(data) {
 					alpm_list_free_inner(*data, (alpm_list_fn_free)_alpm_depmiss_free);
 					alpm_list_free(*data);
@@ -426,7 +428,7 @@ int _alpm_sync_prepare(pmhandle_t *handle, alpm_list_t **data)
 				sync = sync2;
 			} else {
 				_alpm_log(PM_LOG_ERROR, _("unresolvable package conflicts detected\n"));
-				pm_errno = PM_ERR_CONFLICTING_DEPS;
+				handle->pm_errno = PM_ERR_CONFLICTING_DEPS;
 				ret = -1;
 				if(data) {
 					pmconflict_t *newconflict = _alpm_conflict_dup(conflict);
@@ -458,7 +460,7 @@ int _alpm_sync_prepare(pmhandle_t *handle, alpm_list_t **data)
 
 		/* 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->add);
+		deps = _alpm_outerconflicts(handle->db_local, trans->add);
 
 		for(i = deps; i; i = i->next) {
 			pmconflict_t *conflict = i->data;
@@ -480,7 +482,7 @@ int _alpm_sync_prepare(pmhandle_t *handle, alpm_list_t **data)
 					conflict->package1, conflict->package2);
 
 			pmpkg_t *sync = _alpm_pkg_find(trans->add, conflict->package1);
-			pmpkg_t *local = _alpm_db_get_pkgfromcache(db_local, conflict->package2);
+			pmpkg_t *local = _alpm_db_get_pkgfromcache(handle->db_local, conflict->package2);
 			int doremove = 0;
 			QUESTION(trans, PM_TRANS_CONV_CONFLICT_PKG, conflict->package1,
 							conflict->package2, conflict->reason, &doremove);
@@ -490,7 +492,7 @@ int _alpm_sync_prepare(pmhandle_t *handle, alpm_list_t **data)
 				sync->removes = alpm_list_add(sync->removes, local);
 			} else { /* abort */
 				_alpm_log(PM_LOG_ERROR, _("unresolvable package conflicts detected\n"));
-				pm_errno = PM_ERR_CONFLICTING_DEPS;
+				handle->pm_errno = PM_ERR_CONFLICTING_DEPS;
 				ret = -1;
 				if(data) {
 					pmconflict_t *newconflict = _alpm_conflict_dup(conflict);
@@ -525,7 +527,7 @@ int _alpm_sync_prepare(pmhandle_t *handle, alpm_list_t **data)
 		deps = alpm_checkdeps(handle, _alpm_db_get_pkgcache(handle->db_local),
 				trans->remove, trans->add, 1);
 		if(deps) {
-			pm_errno = PM_ERR_UNSATISFIED_DEPS;
+			handle->pm_errno = PM_ERR_UNSATISFIED_DEPS;
 			ret = -1;
 			if(data) {
 				*data = deps;
@@ -609,11 +611,11 @@ static int apply_deltas(pmhandle_t *handle)
 			} else {
 				/* len = cachedir len + from len + '/' + null */
 				len = strlen(cachedir) + strlen(d->from) + 2;
-				CALLOC(from, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, 1));
+				CALLOC(from, len, sizeof(char), RET_ERR(handle, PM_ERR_MEMORY, 1));
 				snprintf(from, len, "%s/%s", cachedir, d->from);
 			}
 			len = strlen(cachedir) + strlen(d->to) + 2;
-			CALLOC(to, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, 1));
+			CALLOC(to, len, sizeof(char), RET_ERR(handle, PM_ERR_MEMORY, 1));
 			snprintf(to, len, "%s/%s", cachedir, d->to);
 
 			/* build the patch command */
@@ -649,7 +651,7 @@ static int apply_deltas(pmhandle_t *handle)
 			if(retval != 0) {
 				/* one delta failed for this package, cancel the remaining ones */
 				EVENT(trans, PM_TRANS_EVT_DELTA_PATCH_FAILED, NULL, NULL);
-				pm_errno = PM_ERR_DLT_PATCHFAILED;
+				handle->pm_errno = PM_ERR_DLT_PATCHFAILED;
 				ret = 1;
 				break;
 			}
@@ -713,7 +715,7 @@ static int validate_deltas(pmhandle_t *handle, alpm_list_t *deltas,
 		FREE(filepath);
 	}
 	if(errors) {
-		pm_errno = PM_ERR_DLT_INVALID;
+		handle->pm_errno = PM_ERR_DLT_INVALID;
 		return -1;
 	}
 	EVENT(trans, PM_TRANS_EVT_DELTA_INTEGRITY_DONE, NULL, NULL);
@@ -759,7 +761,7 @@ static int download_files(pmhandle_t *handle, alpm_list_t **deltas)
 				const char *fname = NULL;
 
 				fname = alpm_pkg_get_filename(spkg);
-				ASSERT(fname != NULL, RET_ERR(PM_ERR_PKG_INVALID_NAME, -1));
+				ASSERT(fname != NULL, RET_ERR(handle, PM_ERR_PKG_INVALID_NAME, -1));
 				alpm_list_t *delta_path = spkg->delta_path;
 				if(delta_path) {
 					/* using deltas */
@@ -793,10 +795,10 @@ static int download_files(pmhandle_t *handle, alpm_list_t **deltas)
 
 					/* print server + filename into a buffer */
 					len = strlen(server_url) + strlen(filename) + 2;
-					CALLOC(fileurl, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, -1));
+					CALLOC(fileurl, len, sizeof(char), RET_ERR(handle, PM_ERR_MEMORY, -1));
 					snprintf(fileurl, len, "%s/%s", server_url, filename);
 
-					ret = _alpm_download(fileurl, cachedir, 0, 1, 0);
+					ret = _alpm_download(handle, fileurl, cachedir, 0, 1, 0);
 					FREE(fileurl);
 					if(ret != -1) {
 						break;
@@ -811,8 +813,8 @@ static int download_files(pmhandle_t *handle, alpm_list_t **deltas)
 			if(errors) {
 				_alpm_log(PM_LOG_WARNING, _("failed to retrieve some files from %s\n"),
 						current->treename);
-				if(pm_errno == 0) {
-					pm_errno = PM_ERR_RETRIEVE;
+				if(handle->pm_errno == 0) {
+					handle->pm_errno = PM_ERR_RETRIEVE;
 				}
 				return -1;
 			}
@@ -898,7 +900,7 @@ int _alpm_sync_commit(pmhandle_t *handle, alpm_list_t **data)
 
 
 	if(errors) {
-		RET_ERR(PM_ERR_PKG_INVALID, -1);
+		RET_ERR(handle, PM_ERR_PKG_INVALID, -1);
 	}
 
 	if(trans->flags & PM_TRANS_FLAG_DOWNLOADONLY) {
@@ -923,7 +925,7 @@ int _alpm_sync_commit(pmhandle_t *handle, alpm_list_t **data)
 				alpm_list_free_inner(conflict, (alpm_list_fn_free)_alpm_fileconflict_free);
 				alpm_list_free(conflict);
 			}
-			RET_ERR(PM_ERR_FILE_CONFLICTS, -1);
+			RET_ERR(handle, PM_ERR_FILE_CONFLICTS, -1);
 		}
 
 		EVENT(trans, PM_TRANS_EVT_FILECONFLICTS_DONE, NULL, NULL);
diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c
index f7fbd2b..564b06e 100644
--- a/lib/libalpm/trans.c
+++ b/lib/libalpm/trans.c
@@ -105,29 +105,23 @@ int SYMEXPORT alpm_trans_init(pmhandle_t *handle, pmtransflag_t flags,
 	int db_version;
 
 	/* Sanity checks */
-	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
-	ASSERT(handle->trans == NULL, RET_ERR(PM_ERR_TRANS_NOT_NULL, -1));
+	ASSERT(handle != NULL, return -1);
+	ASSERT(handle->trans == NULL, RET_ERR(handle, PM_ERR_TRANS_NOT_NULL, -1));
 
 	/* lock db */
 	if(!(flags & PM_TRANS_FLAG_NOLOCK)) {
 		if(make_lock(handle)) {
-			RET_ERR(PM_ERR_HANDLE_LOCK, -1);
+			RET_ERR(handle, PM_ERR_HANDLE_LOCK, -1);
 		}
 	}
 
-	trans = _alpm_trans_new();
-	if(trans == NULL) {
-		RET_ERR(PM_ERR_MEMORY, -1);
-	}
-
+	CALLOC(trans, 1, sizeof(pmtrans_t), RET_ERR(handle, PM_ERR_MEMORY, -1));
 	trans->flags = flags;
 	trans->cb_event = event;
 	trans->cb_conv = conv;
 	trans->cb_progress = progress;
 	trans->state = STATE_INITIALIZED;
 
-	handle->trans = trans;
-
 	/* check database version */
 	db_version = _alpm_db_version(handle->db_local);
 	if(db_version < required_db_version) {
@@ -135,9 +129,11 @@ int SYMEXPORT alpm_trans_init(pmhandle_t *handle, pmtransflag_t flags,
 				_("%s database version is too old\n"), handle->db_local->treename);
 		remove_lock(handle);
 		_alpm_trans_free(trans);
-		RET_ERR(PM_ERR_DB_VERSION, -1);
+		RET_ERR(handle, PM_ERR_DB_VERSION, -1);
 	}
 
+	handle->trans = trans;
+
 	return 0;
 }
 
@@ -158,7 +154,7 @@ static alpm_list_t *check_arch(pmhandle_t *handle, alpm_list_t *pkgs)
 			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));
+			MALLOC(string, len, RET_ERR(handle, PM_ERR_MEMORY, invalid));
 			sprintf(string, "%s-%s-%s", pkgname, pkgver, pkgarch);
 			invalid = alpm_list_add(invalid, string);
 		}
@@ -172,13 +168,13 @@ int SYMEXPORT alpm_trans_prepare(pmhandle_t *handle, alpm_list_t **data)
 	pmtrans_t *trans;
 
 	/* Sanity checks */
-	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
-	ASSERT(data != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
+	ASSERT(handle != NULL, return -1);
+	ASSERT(data != NULL, RET_ERR(handle, 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));
+	ASSERT(trans != NULL, RET_ERR(handle, PM_ERR_TRANS_NULL, -1));
+	ASSERT(trans->state == STATE_INITIALIZED, RET_ERR(handle, PM_ERR_TRANS_NOT_INITIALIZED, -1));
 
 	/* If there's nothing to do, return without complaining */
 	if(trans->add == NULL && trans->remove == NULL) {
@@ -190,7 +186,7 @@ int SYMEXPORT alpm_trans_prepare(pmhandle_t *handle, alpm_list_t **data)
 		if(data) {
 			*data = invalid;
 		}
-		RET_ERR(PM_ERR_PKG_INVALID_ARCH, -1);
+		RET_ERR(handle, PM_ERR_PKG_INVALID_ARCH, -1);
 	}
 
 	if(trans->add == NULL) {
@@ -216,14 +212,14 @@ int SYMEXPORT alpm_trans_commit(pmhandle_t *handle, alpm_list_t **data)
 	pmtrans_t *trans;
 
 	/* Sanity checks */
-	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
+	ASSERT(handle != NULL, return -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 != NULL, RET_ERR(handle, PM_ERR_TRANS_NULL, -1));
+	ASSERT(trans->state == STATE_PREPARED, RET_ERR(handle, PM_ERR_TRANS_NOT_PREPARED, -1));
 
-	ASSERT(!(trans->flags & PM_TRANS_FLAG_NOLOCK), RET_ERR(PM_ERR_TRANS_NOT_LOCKED, -1));
+	ASSERT(!(trans->flags & PM_TRANS_FLAG_NOLOCK), RET_ERR(handle, PM_ERR_TRANS_NOT_LOCKED, -1));
 
 	/* If there's nothing to do, return without complaining */
 	if(trans->add == NULL && trans->remove == NULL) {
@@ -255,12 +251,12 @@ int SYMEXPORT alpm_trans_interrupt(pmhandle_t *handle)
 	pmtrans_t *trans;
 
 	/* Sanity checks */
-	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
+	ASSERT(handle != NULL, return -1);
 
 	trans = handle->trans;
-	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
+	ASSERT(trans != NULL, RET_ERR(handle, PM_ERR_TRANS_NULL, -1));
 	ASSERT(trans->state == STATE_COMMITING || trans->state == STATE_INTERRUPTED,
-			RET_ERR(PM_ERR_TRANS_TYPE, -1));
+			RET_ERR(handle, PM_ERR_TRANS_TYPE, -1));
 
 	trans->state = STATE_INTERRUPTED;
 
@@ -273,11 +269,11 @@ int SYMEXPORT alpm_trans_release(pmhandle_t *handle)
 	pmtrans_t *trans;
 
 	/* Sanity checks */
-	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
+	ASSERT(handle != NULL, return -1);
 
 	trans = handle->trans;
-	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
-	ASSERT(trans->state != STATE_IDLE, RET_ERR(PM_ERR_TRANS_NULL, -1));
+	ASSERT(trans != NULL, RET_ERR(handle, PM_ERR_TRANS_NULL, -1));
+	ASSERT(trans->state != STATE_IDLE, RET_ERR(handle, PM_ERR_TRANS_NULL, -1));
 
 	int nolock_flag = trans->flags & PM_TRANS_FLAG_NOLOCK;
 
@@ -299,16 +295,6 @@ int SYMEXPORT alpm_trans_release(pmhandle_t *handle)
 
 /** @} */
 
-pmtrans_t *_alpm_trans_new(void)
-{
-	pmtrans_t *trans;
-
-	CALLOC(trans, 1, sizeof(pmtrans_t), RET_ERR(PM_ERR_MEMORY, NULL));
-	trans->state = STATE_IDLE;
-
-	return trans;
-}
-
 void _alpm_trans_free(pmtrans_t *trans)
 {
 	if(trans == NULL) {
@@ -384,7 +370,7 @@ int _alpm_runscriptlet(pmhandle_t *handle, const char *installfn,
 	/* either extract or copy the scriptlet */
 	snprintf(scriptfn, PATH_MAX, "%s/.INSTALL", tmpdir);
 	if(strcmp(script, "pre_upgrade") == 0 || strcmp(script, "pre_install") == 0) {
-		if(_alpm_unpack_single(installfn, tmpdir, ".INSTALL")) {
+		if(_alpm_unpack_single(handle, installfn, tmpdir, ".INSTALL")) {
 			retval = 1;
 		}
 	} else {
@@ -428,8 +414,8 @@ cleanup:
 pmtransflag_t SYMEXPORT alpm_trans_get_flags(pmhandle_t *handle)
 {
 	/* 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 != NULL, return -1);
+	ASSERT(handle->trans != NULL, RET_ERR(handle, PM_ERR_TRANS_NULL, -1));
 
 	return handle->trans->flags;
 }
@@ -438,7 +424,7 @@ alpm_list_t SYMEXPORT *alpm_trans_get_add(pmhandle_t *handle)
 {
 	/* Sanity checks */
 	ASSERT(handle != NULL, return NULL);
-	ASSERT(handle->trans != NULL, return NULL);
+	ASSERT(handle->trans != NULL, RET_ERR(handle, PM_ERR_TRANS_NULL, NULL));
 
 	return handle->trans->add;
 }
@@ -447,7 +433,7 @@ alpm_list_t SYMEXPORT *alpm_trans_get_remove(pmhandle_t *handle)
 {
 	/* Sanity checks */
 	ASSERT(handle != NULL, return NULL);
-	ASSERT(handle->trans != NULL, return NULL);
+	ASSERT(handle->trans != NULL, RET_ERR(handle, PM_ERR_TRANS_NULL, NULL));
 
 	return handle->trans->remove;
 }
diff --git a/lib/libalpm/trans.h b/lib/libalpm/trans.h
index 8c9e7fa..e858715 100644
--- a/lib/libalpm/trans.h
+++ b/lib/libalpm/trans.h
@@ -66,7 +66,6 @@ do { \
 	} \
 } while(0)
 
-pmtrans_t *_alpm_trans_new(void);
 void _alpm_trans_free(pmtrans_t *trans);
 int _alpm_trans_init(pmtrans_t *trans, pmtransflag_t flags,
                      alpm_trans_cb_event event, alpm_trans_cb_conv conv,
diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c
index 174af8c..2ad0833 100644
--- a/lib/libalpm/util.c
+++ b/lib/libalpm/util.c
@@ -152,9 +152,6 @@ int _alpm_copyfile(const char *src, const char *dest)
 		size_t nwritten = 0;
 		nwritten = fwrite(buf, 1, len, out);
 		if((nwritten != len) || ferror(out)) {
-			pm_errno = PM_ERR_WRITE;
-			_alpm_log(PM_LOG_ERROR, _("error writing to file '%s': %s\n"),
-					dest, strerror(errno));
 			ret = -1;
 			goto cleanup;
 		}
@@ -215,20 +212,22 @@ char *_alpm_strtrim(char *str)
 /**
  * @brief Unpack a specific file in an archive.
  *
- * @param archive  the archive to unpack
- * @param prefix   where to extract the files
- * @param fn       a file within the archive to unpack
+ * @param handle the context handle
+ * @param archive the archive to unpack
+ * @param prefix where to extract the files
+ * @param filename a file within the archive to unpack
  * @return 0 on success, 1 on failure
  */
-int _alpm_unpack_single(const char *archive, const char *prefix, const char *fn)
+int _alpm_unpack_single(pmhandle_t *handle, const char *archive,
+		const char *prefix, const char *filename)
 {
 	alpm_list_t *list = NULL;
 	int ret = 0;
-	if(fn == NULL) {
+	if(filename == NULL) {
 		return 1;
 	}
-	list = alpm_list_add(list, (void *)fn);
-	ret = _alpm_unpack(archive, prefix, list, 1);
+	list = alpm_list_add(list, (void *)filename);
+	ret = _alpm_unpack(handle, archive, prefix, list, 1);
 	alpm_list_free(list);
 	return ret;
 }
@@ -236,15 +235,16 @@ int _alpm_unpack_single(const char *archive, const char *prefix, const char *fn)
 /**
  * @brief Unpack a list of files in an archive.
  *
- * @param archive  the archive to unpack
- * @param prefix   where to extract the files
- * @param list     a list of files within the archive to unpack or
- * NULL for all
+ * @param handle the context handle
+ * @param archive the archive to unpack
+ * @param prefix where to extract the files
+ * @param list a list of files within the archive to unpack or NULL for all
  * @param breakfirst break after the first entry found
  *
  * @return 0 on success, 1 on failure
  */
-int _alpm_unpack(const char *archive, const char *prefix, alpm_list_t *list, int breakfirst)
+int _alpm_unpack(pmhandle_t *handle, const char *archive, const char *prefix,
+		alpm_list_t *list, int breakfirst)
 {
 	int ret = 0;
 	mode_t oldmask;
@@ -253,8 +253,9 @@ int _alpm_unpack(const char *archive, const char *prefix, alpm_list_t *list, int
 	char cwd[PATH_MAX];
 	int restore_cwd = 0;
 
-	if((_archive = archive_read_new()) == NULL)
-		RET_ERR(PM_ERR_LIBARCHIVE, 1);
+	if((_archive = archive_read_new()) == NULL) {
+		RET_ERR(handle, PM_ERR_LIBARCHIVE, 1);
+	}
 
 	archive_read_support_compression_all(_archive);
 	archive_read_support_format_all(_archive);
@@ -263,7 +264,7 @@ int _alpm_unpack(const char *archive, const char *prefix, alpm_list_t *list, int
 				ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
 		_alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), archive,
 				archive_error_string(_archive));
-		RET_ERR(PM_ERR_PKG_OPEN, 1);
+		RET_ERR(handle, PM_ERR_PKG_OPEN, 1);
 	}
 
 	oldmask = umask(0022);
@@ -277,7 +278,8 @@ int _alpm_unpack(const char *archive, const char *prefix, alpm_list_t *list, int
 
 	/* just in case our cwd was removed in the upgrade operation */
 	if(chdir(prefix) != 0) {
-		_alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), prefix, strerror(errno));
+		_alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"),
+				prefix, strerror(errno));
 		ret = 1;
 		goto cleanup;
 	}
@@ -337,7 +339,8 @@ cleanup:
 	umask(oldmask);
 	archive_read_finish(_archive);
 	if(restore_cwd && chdir(cwd) != 0) {
-		_alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), cwd, strerror(errno));
+		_alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"),
+				cwd, strerror(errno));
 	}
 	return ret;
 }
@@ -581,7 +584,7 @@ char *_alpm_filecache_find(pmhandle_t *handle, const char *filename)
 		}
 	}
 	/* package wasn't found in any cachedir */
-	RET_ERR(PM_ERR_PKG_NOT_FOUND, NULL);
+	return NULL;
 }
 
 /** Check the alpm cachedirs for existance and find a writable one.
@@ -655,7 +658,7 @@ static int md5_file(const char *path, unsigned char output[16])
 	MD5_CTX ctx;
 	unsigned char *buf;
 
-	CALLOC(buf, 8192, sizeof(unsigned char), RET_ERR(PM_ERR_MEMORY, 1));
+	CALLOC(buf, 8192, sizeof(unsigned char), return 1);
 
 	if((f = fopen(path, "rb")) == NULL) {
 		free(buf);
@@ -702,7 +705,7 @@ char SYMEXPORT *alpm_compute_md5sum(const char *filename)
 	ret = md5_file(filename, output);
 
 	if(ret > 0) {
-		RET_ERR(PM_ERR_NOT_A_FILE, NULL);
+		return NULL;
 	}
 
 	/* Convert the result to something readable */
@@ -856,13 +859,12 @@ int _alpm_splitname(const char *target, pmpkg_t *pkg)
 	}
 	/* version actually points to the dash, so need to increment 1 and account
 	 * for potential end character */
-	STRNDUP(pkg->version, version + 1, end - version - 1,
-			RET_ERR(PM_ERR_MEMORY, -1));
+	STRNDUP(pkg->version, version + 1, end - version - 1, return -1);
 
 	if(pkg->name) {
 		FREE(pkg->name);
 	}
-	STRNDUP(pkg->name, target, version - target, RET_ERR(PM_ERR_MEMORY, -1));
+	STRNDUP(pkg->name, target, version - target, return -1);
 	pkg->name_hash = _alpm_hash_sdbm(pkg->name);
 
 	return 0;
diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h
index 839b802..b289531 100644
--- a/lib/libalpm/util.h
+++ b/lib/libalpm/util.h
@@ -29,6 +29,7 @@
 #include "alpm_list.h"
 #include "alpm.h"
 #include "package.h" /* pmpkg_t */
+#include "handle.h" /* pmhandle_t */
 
 #include <stdio.h>
 #include <string.h>
@@ -60,12 +61,12 @@
 
 #define ASSERT(cond, action) do { if(!(cond)) { action; } } while(0)
 
-#define RET_ERR_VOID(err) do { pm_errno = (err); \
-	_alpm_log(PM_LOG_DEBUG, "returning error %d from %s : %s\n", err, __func__, alpm_strerrorlast()); \
+#define RET_ERR_VOID(handle, err) do { (handle)->pm_errno = (err); \
+	_alpm_log(PM_LOG_DEBUG, "returning error %d from %s : %s\n", err, __func__, alpm_strerror(err)); \
 	return; } while(0)
 
-#define RET_ERR(err, ret) do { pm_errno = (err); \
-	_alpm_log(PM_LOG_DEBUG, "returning error %d from %s : %s\n", err, __func__, alpm_strerrorlast()); \
+#define RET_ERR(handle, err, ret) do { (handle)->pm_errno = (err); \
+	_alpm_log(PM_LOG_DEBUG, "returning error %d from %s : %s\n", err, __func__, alpm_strerror(err)); \
 	return (ret); } while(0)
 
 #define DOUBLE_EQ(x, y) (fabs((x) - (y)) < DBL_EPSILON)
@@ -90,8 +91,10 @@ int _alpm_makepath(const char *path);
 int _alpm_makepath_mode(const char *path, mode_t mode);
 int _alpm_copyfile(const char *src, const char *dest);
 char *_alpm_strtrim(char *str);
-int _alpm_unpack_single(const char *archive, const char *prefix, const char *fn);
-int _alpm_unpack(const char *archive, const char *prefix, alpm_list_t *list, int breakfirst);
+int _alpm_unpack_single(pmhandle_t *handle, const char *archive,
+		const char *prefix, const char *filename);
+int _alpm_unpack(pmhandle_t *handle, const char *archive, const char *prefix,
+		alpm_list_t *list, int breakfirst);
 int _alpm_rmrf(const char *path);
 int _alpm_logaction(pmhandle_t *handle, const char *fmt, va_list args);
 int _alpm_run_chroot(pmhandle_t *handle, const char *path, char *const argv[]);
diff --git a/src/pacman/conf.c b/src/pacman/conf.c
index 6686f73..97e6497 100644
--- a/src/pacman/conf.c
+++ b/src/pacman/conf.c
@@ -402,7 +402,7 @@ static int _add_mirror(pmdb_t *db, char *value)
 	if(alpm_db_add_server(db, server) != 0) {
 		/* pm_errno is set by alpm_db_setserver */
 		pm_printf(PM_LOG_ERROR, _("could not add server URL to database '%s': %s (%s)\n"),
-				dbname, server, alpm_strerrorlast());
+				dbname, server, alpm_strerror(alpm_errno(config->handle)));
 		free(server);
 		return 1;
 	}
@@ -460,7 +460,7 @@ static int setup_libalpm(void)
 	ret = alpm_option_set_logfile(handle, config->logfile);
 	if(ret != 0) {
 		pm_printf(PM_LOG_ERROR, _("problem setting logfile '%s' (%s)\n"),
-				config->logfile, alpm_strerrorlast());
+				config->logfile, alpm_strerror(alpm_errno(config->handle)));
 		return ret;
 	}
 
@@ -470,7 +470,7 @@ static int setup_libalpm(void)
 	ret = alpm_option_set_signaturedir(handle, config->gpgdir);
 	if(ret != 0) {
 		pm_printf(PM_LOG_ERROR, _("problem setting gpgdir '%s' (%s)\n"),
-				config->gpgdir, alpm_strerrorlast());
+				config->gpgdir, alpm_strerror(alpm_errno(config->handle)));
 		return ret;
 	}
 
@@ -567,7 +567,7 @@ static int _parseconfig(const char *file, int parse_options,
 				db = alpm_db_register_sync(config->handle, name);
 				if(db == NULL) {
 					pm_printf(PM_LOG_ERROR, _("could not register '%s' database (%s)\n"),
-							name, alpm_strerrorlast());
+							name, alpm_strerror(alpm_errno(config->handle)));
 					ret = 1;
 					goto cleanup;
 				}
@@ -665,7 +665,7 @@ static int _parseconfig(const char *file, int parse_options,
 					ret = alpm_db_set_pgp_verify(db, level);
 					if(ret != 0) {
 						pm_printf(PM_LOG_ERROR, _("could not add set verify option for database '%s': %s (%s)\n"),
-								alpm_db_get_name(db), value, alpm_strerrorlast());
+								alpm_db_get_name(db), value, alpm_strerror(alpm_errno(config->handle)));
 						goto cleanup;
 					}
 				} else {
diff --git a/src/pacman/database.c b/src/pacman/database.c
index 33cd49e..292fa54 100644
--- a/src/pacman/database.c
+++ b/src/pacman/database.c
@@ -68,7 +68,7 @@ int pacman_database(alpm_list_t *targets)
 		char *pkgname = i->data;
 		if(alpm_db_set_pkgreason(db_local, pkgname, reason) == -1) {
 			pm_printf(PM_LOG_ERROR, _("could not set install reason for package %s (%s)\n"),
-							pkgname, alpm_strerrorlast());
+							pkgname, alpm_strerror(alpm_errno(config->handle)));
 			retval = 1;
 		} else {
 			if(reason == PM_PKG_REASON_DEPEND) {
diff --git a/src/pacman/remove.c b/src/pacman/remove.c
index b96687a..5993ab3 100644
--- a/src/pacman/remove.c
+++ b/src/pacman/remove.c
@@ -39,7 +39,8 @@ static int remove_target(const char *target)
 
 	if((info = alpm_db_get_pkg(db_local, target)) != NULL) {
 		if(alpm_remove_pkg(info) == -1) {
-			pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n", target, alpm_strerrorlast());
+			pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n", target,
+					alpm_strerror(alpm_errno(config->handle)));
 			return -1;
 		}
 		return 0;
@@ -54,7 +55,8 @@ static int remove_target(const char *target)
 	for(p = alpm_grp_get_pkgs(grp); p; p = alpm_list_next(p)) {
 		pmpkg_t *pkg = alpm_list_getdata(p);
 		if(alpm_remove_pkg(pkg) == -1) {
-			pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n", target, alpm_strerrorlast());
+			pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n", target,
+					alpm_strerror(alpm_errno(config->handle)));
 			return -1;
 		}
 	}
@@ -100,9 +102,10 @@ int pacman_remove(alpm_list_t *targets)
 
 	/* Step 2: prepare the transaction based on its type, targets and flags */
 	if(alpm_trans_prepare(config->handle, &data) == -1) {
+		enum _pmerrno_t err = alpm_errno(config->handle);
 		pm_fprintf(stderr, PM_LOG_ERROR, _("failed to prepare transaction (%s)\n"),
-		        alpm_strerrorlast());
-		switch(pm_errno) {
+		        alpm_strerror(err));
+		switch(err) {
 			case PM_ERR_PKG_INVALID_ARCH:
 				for(i = data; i; i = alpm_list_next(i)) {
 					char *pkg = alpm_list_getdata(i);
@@ -164,7 +167,7 @@ int pacman_remove(alpm_list_t *targets)
 
 	if(alpm_trans_commit(config->handle, NULL) == -1) {
 		pm_fprintf(stderr, PM_LOG_ERROR, _("failed to commit transaction (%s)\n"),
-		        alpm_strerrorlast());
+		        alpm_strerror(alpm_errno(config->handle)));
 		retval = 1;
 	}
 
diff --git a/src/pacman/sync.c b/src/pacman/sync.c
index 87b321f..dae828d 100644
--- a/src/pacman/sync.c
+++ b/src/pacman/sync.c
@@ -293,7 +293,7 @@ static int sync_synctree(int level, alpm_list_t *syncs)
 		ret = alpm_db_update((level < 2 ? 0 : 1), db);
 		if(ret < 0) {
 			pm_fprintf(stderr, PM_LOG_ERROR, _("failed to update %s (%s)\n"),
-					alpm_db_get_name(db), alpm_strerrorlast());
+					alpm_db_get_name(db), alpm_strerror(alpm_errno(config->handle)));
 		} else if(ret == 1) {
 			printf(_(" %s is up to date\n"), alpm_db_get_name(db));
 			success++;
@@ -623,14 +623,15 @@ static int process_pkg(pmpkg_t *pkg)
 	int ret = alpm_add_pkg(pkg);
 
 	if(ret == -1) {
-		if(pm_errno == PM_ERR_TRANS_DUP_TARGET
-				|| pm_errno == PM_ERR_PKG_IGNORED) {
+		enum _pmerrno_t err = alpm_errno(config->handle);
+		if(err == PM_ERR_TRANS_DUP_TARGET
+				|| err == PM_ERR_PKG_IGNORED) {
 			/* just skip duplicate or ignored targets */
 			pm_printf(PM_LOG_WARNING, _("skipping target: %s\n"), alpm_pkg_get_name(pkg));
 			return 0;
 		} else {
 			pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n", alpm_pkg_get_name(pkg),
-					alpm_strerrorlast());
+					alpm_strerror(err));
 			return 1;
 		}
 	}
@@ -687,10 +688,11 @@ static int process_targname(alpm_list_t *dblist, char *targname)
 {
 	pmpkg_t *pkg = alpm_find_dbs_satisfier(config->handle, dblist, targname);
 
-	/* #FS23342 - skip ignored packages when user says no */
-	if(pm_errno == PM_ERR_PKG_IGNORED) {
+	/* #FS#23342 - skip ignored packages when user says no */
+	if(alpm_errno(config->handle) == PM_ERR_PKG_IGNORED) {
 			pm_printf(PM_LOG_WARNING, _("skipping target: %s\n"), targname);
-			pm_errno = 0;
+			/* TODO how to do this, we shouldn't be fucking with it from the frontend */
+			/* pm_errno = 0; */
 			return 0;
 	}
 
@@ -761,7 +763,7 @@ static int sync_trans(alpm_list_t *targets)
 		printf(_(":: Starting full system upgrade...\n"));
 		alpm_logaction(config->handle, "starting full system upgrade\n");
 		if(alpm_sync_sysupgrade(config->handle, config->op_s_upgrade >= 2) == -1) {
-			pm_fprintf(stderr, PM_LOG_ERROR, "%s\n", alpm_strerrorlast());
+			pm_fprintf(stderr, PM_LOG_ERROR, "%s\n", alpm_strerror(alpm_errno(config->handle)));
 			retval = 1;
 			goto cleanup;
 		}
@@ -769,9 +771,10 @@ static int sync_trans(alpm_list_t *targets)
 
 	/* Step 2: "compute" the transaction based on targets and flags */
 	if(alpm_trans_prepare(config->handle, &data) == -1) {
+		enum _pmerrno_t err = alpm_errno(config->handle);
 		pm_fprintf(stderr, PM_LOG_ERROR, _("failed to prepare transaction (%s)\n"),
-		        alpm_strerrorlast());
-		switch(pm_errno) {
+		        alpm_strerror(err));
+		switch(err) {
 			alpm_list_t *i;
 			case PM_ERR_PKG_INVALID_ARCH:
 				for(i = data; i; i = alpm_list_next(i)) {
@@ -838,9 +841,10 @@ static int sync_trans(alpm_list_t *targets)
 	}
 
 	if(alpm_trans_commit(config->handle, &data) == -1) {
+		enum _pmerrno_t err = alpm_errno(config->handle);
 		pm_fprintf(stderr, PM_LOG_ERROR, _("failed to commit transaction (%s)\n"),
-		        alpm_strerrorlast());
-		switch(pm_errno) {
+		        alpm_strerror(err));
+		switch(err) {
 			alpm_list_t *i;
 			case PM_ERR_FILE_CONFLICTS:
 				for(i = data; i; i = alpm_list_next(i)) {
diff --git a/src/pacman/upgrade.c b/src/pacman/upgrade.c
index deea1ee..cdbbffe 100644
--- a/src/pacman/upgrade.c
+++ b/src/pacman/upgrade.c
@@ -57,7 +57,7 @@ int pacman_upgrade(alpm_list_t *targets)
 			char *str = alpm_fetch_pkgurl(config->handle, i->data);
 			if(str == NULL) {
 				pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n",
-						(char *)i->data, alpm_strerrorlast());
+						(char *)i->data, alpm_strerror(alpm_errno(config->handle)));
 				return 1;
 			} else {
 				free(i->data);
@@ -78,13 +78,13 @@ int pacman_upgrade(alpm_list_t *targets)
 
 		if(alpm_pkg_load(config->handle, targ, 1, check_sig, &pkg) != 0) {
 			pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n",
-					targ, alpm_strerrorlast());
+					targ, alpm_strerror(alpm_errno(config->handle)));
 			trans_release();
 			return 1;
 		}
 		if(alpm_add_pkg(pkg) == -1) {
 			pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n",
-					targ, alpm_strerrorlast());
+					targ, alpm_strerror(alpm_errno(config->handle)));
 			alpm_pkg_free(pkg);
 			trans_release();
 			return 1;
@@ -94,9 +94,10 @@ int pacman_upgrade(alpm_list_t *targets)
 	/* Step 2: "compute" the transaction based on targets and flags */
 	/* TODO: No, compute nothing. This is stupid. */
 	if(alpm_trans_prepare(config->handle, &data) == -1) {
+		enum _pmerrno_t err = alpm_errno(config->handle);
 		pm_fprintf(stderr, PM_LOG_ERROR, _("failed to prepare transaction (%s)\n"),
-		        alpm_strerrorlast());
-		switch(pm_errno) {
+		        alpm_strerror(err));
+		switch(err) {
 			case PM_ERR_PKG_INVALID_ARCH:
 				for(i = data; i; i = alpm_list_next(i)) {
 					char *pkg = alpm_list_getdata(i);
@@ -140,15 +141,15 @@ int pacman_upgrade(alpm_list_t *targets)
 	}
 
 	/* Step 3: perform the installation */
+	alpm_list_t *packages = alpm_trans_get_add(config->handle);
 
 	if(config->print) {
-		print_packages(alpm_trans_get_add(config->handle));
+		print_packages(packages);
 		trans_release();
 		return 0;
 	}
 
 	/* print targets and ask user confirmation */
-	alpm_list_t *packages = alpm_trans_get_add(config->handle);
 	if(packages == NULL) { /* we are done */
 		printf(_(" there is nothing to do\n"));
 		trans_release();
@@ -164,9 +165,10 @@ int pacman_upgrade(alpm_list_t *targets)
 	}
 
 	if(alpm_trans_commit(config->handle, &data) == -1) {
+		enum _pmerrno_t err = alpm_errno(config->handle);
 		pm_fprintf(stderr, PM_LOG_ERROR, _("failed to commit transaction (%s)\n"),
-				alpm_strerrorlast());
-		switch(pm_errno) {
+				alpm_strerror(err));
+		switch(err) {
 			alpm_list_t *i;
 			case PM_ERR_FILE_CONFLICTS:
 				for(i = data; i; i = alpm_list_next(i)) {
diff --git a/src/pacman/util.c b/src/pacman/util.c
index 043b9d6..71acd6f 100644
--- a/src/pacman/util.c
+++ b/src/pacman/util.c
@@ -60,14 +60,15 @@ int trans_init(pmtransflag_t flags)
 	}
 
 	if(ret == -1) {
+		enum _pmerrno_t err = alpm_errno(config->handle);
 		pm_fprintf(stderr, PM_LOG_ERROR, _("failed to init transaction (%s)\n"),
-				alpm_strerrorlast());
-		if(pm_errno == PM_ERR_HANDLE_LOCK) {
+				alpm_strerror(err));
+		if(err == PM_ERR_HANDLE_LOCK) {
 			fprintf(stderr, _("  if you're sure a package manager is not already\n"
 						"  running, you can remove %s\n"),
 					alpm_option_get_lockfile(config->handle));
 		}
-		else if(pm_errno == PM_ERR_DB_VERSION) {
+		else if(err == PM_ERR_DB_VERSION) {
 			fprintf(stderr, _("  try running pacman-db-upgrade\n"));
 		}
 
@@ -80,7 +81,7 @@ int trans_release(void)
 {
 	if(alpm_trans_release(config->handle) == -1) {
 		pm_fprintf(stderr, PM_LOG_ERROR, _("failed to release transaction (%s)\n"),
-				alpm_strerrorlast());
+				alpm_strerror(alpm_errno(config->handle)));
 		return -1;
 	}
 	return 0;
diff --git a/src/util/cleanupdelta.c b/src/util/cleanupdelta.c
index 5112b1a..9829170 100644
--- a/src/util/cleanupdelta.c
+++ b/src/util/cleanupdelta.c
@@ -78,7 +78,7 @@ static void checkdbs(const char *dbpath, alpm_list_t *dbnames) {
 		db = alpm_db_register_sync(handle, dbname);
 		if(db == NULL) {
 			fprintf(stderr, "error: could not register sync database (%s)\n",
-					alpm_strerrorlast());
+					alpm_strerror(alpm_errno(handle)));
 			return;
 		}
 		checkpkgs(alpm_db_get_pkgcache(db));
diff --git a/src/util/pactree.c b/src/util/pactree.c
index 6c86942..1dee61b 100644
--- a/src/util/pactree.c
+++ b/src/util/pactree.c
@@ -88,19 +88,6 @@ int reverse = 0;
 int unique = 0;
 const char *dbpath = DBPATH;
 
-static int alpm_local_init(void)
-{
-	enum _pmerrno_t err;
-
-	handle = alpm_initialize(ROOTDIR, dbpath, &err);
-	if(!handle) {
-		return -1;
-	}
-
-	db_local = alpm_option_get_localdb(handle);
-	return 0;
-}
-
 static int parse_options(int argc, char *argv[])
 {
 	int opt, option_index = 0;
@@ -327,22 +314,27 @@ static void walk_deps(pmpkg_t *pkg, int depth)
 
 int main(int argc, char *argv[])
 {
-	int ret;
+	int ret = 0;
+	enum _pmerrno_t err;
 	const char *target_name;
 	pmpkg_t *pkg;
 
-	ret = parse_options(argc, argv);
-	if(ret != 0) {
+	if(parse_options(argc, argv) != 0) {
 		usage();
+		ret = 1;
 		goto finish;
 	}
 
-	ret = alpm_local_init();
-	if(ret != 0) {
-		fprintf(stderr, "error: cannot initialize alpm: %s\n", alpm_strerrorlast());
+	handle = alpm_initialize(ROOTDIR, dbpath, &err);
+	if(!handle) {
+		fprintf(stderr, "error: cannot initialize alpm: %s\n",
+				alpm_strerror(err));
+		ret = 1;
 		goto finish;
 	}
 
+	db_local = alpm_option_get_localdb(handle);
+
 	/* we only care about the first non option arg for walking */
 	target_name = argv[optind];
 
diff --git a/src/util/testdb.c b/src/util/testdb.c
index bda67d5..0bd7820 100644
--- a/src/util/testdb.c
+++ b/src/util/testdb.c
@@ -155,7 +155,7 @@ static int check_syncdbs(alpm_list_t *dbnames) {
 		db = alpm_db_register_sync(handle, dbname);
 		if(db == NULL) {
 			fprintf(stderr, "error: could not register sync database (%s)\n",
-					alpm_strerrorlast());
+					alpm_strerror(alpm_errno(handle)));
 			ret = 1;
 			goto cleanup;
 		}
diff --git a/src/util/testpkg.c b/src/util/testpkg.c
index 5b8831d..c6f02e3 100644
--- a/src/util/testpkg.c
+++ b/src/util/testpkg.c
@@ -60,7 +60,8 @@ int main(int argc, char *argv[])
 
 	if(alpm_pkg_load(handle, argv[1], 1, PM_PGP_VERIFY_OPTIONAL, &pkg) == -1
 			|| pkg == NULL) {
-		switch(pm_errno) {
+		enum _pmerrno_t err = alpm_errno(handle);
+		switch(err) {
 			case PM_ERR_PKG_OPEN:
 				printf("Cannot open the given file.\n");
 				break;
@@ -69,7 +70,7 @@ int main(int argc, char *argv[])
 				printf("Package is invalid.\n");
 				break;
 			default:
-				printf("libalpm error: %s\n", alpm_strerrorlast());
+				printf("libalpm error: %s\n", alpm_strerror(err));
 				break;
 		}
 		retval = 1;
-- 
1.7.5.2



More information about the pacman-dev mailing list