diff --git a/lib/libpacman/add.c b/lib/libpacman/add.c
index 8b77a73..23322e1 100644
--- a/lib/libpacman/add.c
+++ b/lib/libpacman/add.c
@@ -105,13 +105,14 @@ static int add_faketarget(pmtrans_t *trans, const char *name)
 	return(0);
 }
 
-int _pacman_add_loadtarget(pmtrans_t *trans, pmdb_t *db, const char *name)
+int _pacman_add_addtarget(pmtrans_t *trans, const char *name)
 {
 	pmpkg_t *info = NULL;
 	pmpkg_t *dummy;
 	pmlist_t *i;
 	pmpkg_t *local;
 	struct stat buf;
+	pmdb_t *db = handle->db_local;
 
 	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
 	ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
@@ -201,12 +202,13 @@ error:
 	return(-1);
 }
 
-int _pacman_add_prepare(pmtrans_t *trans, pmdb_t *db, pmlist_t **data)
+int _pacman_add_prepare(pmtrans_t *trans, pmlist_t **data)
 {
 	pmlist_t *lp;
 	pmlist_t *rmlist = NULL;
 	char rm_fname[PATH_MAX];
 	pmpkg_t *info = NULL;
+	pmdb_t *db = handle->db_local;
 
 	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
 	ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
@@ -298,7 +300,7 @@ int _pacman_add_prepare(pmtrans_t *trans, pmdb_t *db, pmlist_t **data)
 	return(0);
 }
 
-int _pacman_add_commit(pmtrans_t *trans, pmdb_t *db)
+int _pacman_add_commit(pmtrans_t *trans, pmlist_t **data)
 {
 	int i, ret = 0, errors = 0, needdisp = 0;
 	int remain, howmany, archive_ret;
@@ -309,6 +311,7 @@ int _pacman_add_commit(pmtrans_t *trans, pmdb_t *db)
 	unsigned char cb_state;
 	time_t t;
 	pmlist_t *targ, *lp;
+	pmdb_t *db = handle->db_local;
 
 	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
 	ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
@@ -373,13 +376,13 @@ int _pacman_add_commit(pmtrans_t *trans, pmdb_t *db)
 						FREETRANS(tr);
 						RET_ERR(PM_ERR_TRANS_ABORT, -1);
 					}
-					if(_pacman_remove_loadtarget(tr, db, info->name) == -1) {
+					if(_pacman_remove_addtarget(tr, info->name) == -1) {
 						FREETRANS(tr);
 						RET_ERR(PM_ERR_TRANS_ABORT, -1);
 					}
 					/* copy the skiplist over */
 					tr->skiplist = _pacman_list_strdup(trans->skiplist);
-					if(_pacman_remove_commit(tr, db) == -1) {
+					if(_pacman_remove_commit(tr, NULL) == -1) {
 						FREETRANS(tr);
 						RET_ERR(PM_ERR_TRANS_ABORT, -1);
 					}
@@ -835,4 +838,10 @@ int _pacman_add_commit(pmtrans_t *trans, pmdb_t *db)
 	return(0);
 }
 
+const pmtrans_ops_t _pacman_add_pmtrans_opts = {
+	.addtarget = _pacman_add_addtarget,
+	.prepare = _pacman_add_prepare,
+	.commit = _pacman_add_commit
+};
+
 /* vim: set ts=2 sw=2 noet: */
diff --git a/lib/libpacman/add.h b/lib/libpacman/add.h
index e59a32a..e717973 100644
--- a/lib/libpacman/add.h
+++ b/lib/libpacman/add.h
@@ -21,13 +21,11 @@
 #ifndef _PACMAN_ADD_H
 #define _PACMAN_ADD_H
 
-#include "list.h"
-#include "db.h"
+//#include "list.h"
+//#include "db.h"
 #include "trans.h"
 
-int _pacman_add_loadtarget(pmtrans_t *trans, pmdb_t *db, const char *name);
-int _pacman_add_prepare(pmtrans_t *trans, pmdb_t *db, pmlist_t **data);
-int _pacman_add_commit(pmtrans_t *trans, pmdb_t *db);
+const pmtrans_ops_t _pacman_add_pmtrans_opts;
 
 #endif /* _PACMAN_ADD_H */
 
diff --git a/lib/libpacman/error.h b/lib/libpacman/error.h
index 9d874f4..d016005 100644
--- a/lib/libpacman/error.h
+++ b/lib/libpacman/error.h
@@ -21,6 +21,9 @@
 #ifndef _PACMAN_ERROR_H
 #define _PACMAN_ERROR_H
 
+#include "log.h"
+#include "pacman.h"
+
 #define RET_ERR(err, ret) do { pm_errno = (err); \
 	_pacman_log(PM_LOG_ERROR, _("returning error %d: %s\n"), err, pacman_strerror(err)); \
 	return(ret); } while(0)
diff --git a/lib/libpacman/package.c b/lib/libpacman/package.c
index 5d2efc0..ab0380b 100644
--- a/lib/libpacman/package.c
+++ b/lib/libpacman/package.c
@@ -82,6 +82,7 @@ pmpkg_t *_pacman_pkg_new(const char *name, const char *version)
 	pkg->files          = NULL;
 	pkg->backup         = NULL;
 	pkg->depends        = NULL;
+	pkg->rodepends      = NULL;
 	pkg->removes        = NULL;
 	pkg->groups         = NULL;
 	pkg->provides       = NULL;
@@ -128,6 +129,7 @@ pmpkg_t *_pacman_pkg_dup(pmpkg_t *pkg)
 	newpkg->files      = _pacman_list_strdup(pkg->files);
 	newpkg->backup     = _pacman_list_strdup(pkg->backup);
 	newpkg->depends    = _pacman_list_strdup(pkg->depends);
+	newpkg->rodepends    = _pacman_list_strdup(pkg->rodepends);
 	newpkg->removes    = _pacman_list_strdup(pkg->removes);
 	newpkg->groups     = _pacman_list_strdup(pkg->groups);
 	newpkg->provides   = _pacman_list_strdup(pkg->provides);
@@ -153,6 +155,7 @@ void _pacman_pkg_free(void *data)
 	FREELIST(pkg->files);
 	FREELIST(pkg->backup);
 	FREELIST(pkg->depends);
+	FREELIST(pkg->rodepends);
 	FREELIST(pkg->removes);
 	FREELIST(pkg->conflicts);
 	FREELIST(pkg->requiredby);
@@ -248,6 +251,8 @@ static int parse_descfile(char *descfile, pmpkg_t *info, int output)
 				info->usize = atol(tmp);
 			} else if(!strcmp(key, "DEPEND")) {
 				info->depends = _pacman_list_add(info->depends, strdup(ptr));
+			} else if(!strcmp(key, "RODEPEND")) {
+				info->rodepends = _pacman_list_add(info->rodepends, strdup(ptr));
 			} else if(!strcmp(key, "REMOVE")) {
 				info->removes = _pacman_list_add(info->removes, strdup(ptr));
 			} else if(!strcmp(key, "CONFLICT")) {
@@ -585,6 +590,7 @@ void *_pacman_pkg_getinfo(pmpkg_t *pkg, unsigned char parm)
 		case PM_PKG_MD5SUM:      data = pkg->md5sum; break;
 		case PM_PKG_SHA1SUM:     data = pkg->sha1sum; break;
 		case PM_PKG_DEPENDS:     data = pkg->depends; break;
+		case PM_PKG_RODEPENDS:   data = pkg->rodepends; break;
 		case PM_PKG_REMOVES:     data = pkg->removes; break;
 		case PM_PKG_REQUIREDBY:  data = pkg->requiredby; break;
 		case PM_PKG_PROVIDES:    data = pkg->provides; break;
diff --git a/lib/libpacman/package.h b/lib/libpacman/package.h
index b41aa13..3cef3f8 100644
--- a/lib/libpacman/package.h
+++ b/lib/libpacman/package.h
@@ -73,6 +73,7 @@ typedef struct __pmpkg_t {
 	pmlist_t *files;
 	pmlist_t *backup;
 	pmlist_t *depends;
+	pmlist_t *rodepends;
 	pmlist_t *removes;
 	pmlist_t *requiredby;
 	pmlist_t *conflicts;
diff --git a/lib/libpacman/pacman.h b/lib/libpacman/pacman.h
index 9624383..efac2d8 100644
--- a/lib/libpacman/pacman.h
+++ b/lib/libpacman/pacman.h
@@ -198,7 +198,9 @@ enum {
 	/* Misc */
 	PM_PKG_DATA,
 	PM_PKG_FORCE,
-	PM_PKG_STICK
+	PM_PKG_STICK,
+	/* New Depends entry */
+	PM_PKG_RODEPENDS
 };
 
 /* reasons -- ie, why the package was installed */
diff --git a/lib/libpacman/remove.c b/lib/libpacman/remove.c
index 3168bdc..77eb0ab 100644
--- a/lib/libpacman/remove.c
+++ b/lib/libpacman/remove.c
@@ -58,9 +58,10 @@
 #include "handle.h"
 #include "pacman.h"
 
-int _pacman_remove_loadtarget(pmtrans_t *trans, pmdb_t *db, const char *name)
+int _pacman_remove_addtarget(pmtrans_t *trans, const char *name)
 {
 	pmpkg_t *info;
+	pmdb_t *db = handle->db_local;
 
 	ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
 	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
@@ -90,9 +91,10 @@ int _pacman_remove_loadtarget(pmtrans_t *trans, pmdb_t *db, const char *name)
 	return(0);
 }
 
-int _pacman_remove_prepare(pmtrans_t *trans, pmdb_t *db, pmlist_t **data)
+int _pacman_remove_prepare(pmtrans_t *trans, pmlist_t **data)
 {
 	pmlist_t *lp;
+	pmdb_t *db = handle->db_local;
 
 	ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
 	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
@@ -155,13 +157,14 @@ static int str_cmp(const void *s1, const void *s2)
 	return(strcmp(s1, s2));
 }
 
-int _pacman_remove_commit(pmtrans_t *trans, pmdb_t *db)
+int _pacman_remove_commit(pmtrans_t *trans, pmlist_t **data)
 {
 	pmpkg_t *info;
 	struct stat buf;
 	pmlist_t *targ, *lp;
 	char line[PATH_MAX+1];
 	int howmany, remain;
+	pmdb_t *db = handle->db_local;
 
 	ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
 	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
@@ -352,4 +355,10 @@ int _pacman_remove_commit(pmtrans_t *trans, pmdb_t *db)
 	return(0);
 }
 
+const pmtrans_ops_t _pacman_remove_pmtrans_opts = {
+	.addtarget = _pacman_remove_addtarget,
+	.prepare = _pacman_remove_prepare,
+	.commit = _pacman_remove_commit
+};
+
 /* vim: set ts=2 sw=2 noet: */
diff --git a/lib/libpacman/remove.h b/lib/libpacman/remove.h
index cd18282..5c5a363 100644
--- a/lib/libpacman/remove.h
+++ b/lib/libpacman/remove.h
@@ -21,13 +21,14 @@
 #ifndef _PACMAN_REMOVE_H
 #define _PACMAN_REMOVE_H
 
-#include "list.h"
-#include "db.h"
+//#include "list.h"
+//#include "db.h"
 #include "trans.h"
 
-int _pacman_remove_loadtarget(pmtrans_t *trans, pmdb_t *db, const char *name);
-int _pacman_remove_prepare(pmtrans_t *trans, pmdb_t *db, pmlist_t **data);
-int _pacman_remove_commit(pmtrans_t *trans, pmdb_t *db);
+int _pacman_remove_addtarget(pmtrans_t *trans, const char *name);
+
+const pmtrans_ops_t _pacman_remove_pmtrans_opts;
+
 
 #endif /* _PACMAN_REMOVE_H */
 
diff --git a/lib/libpacman/sync.c b/lib/libpacman/sync.c
index 6381d97..2c9d9b8 100644
--- a/lib/libpacman/sync.c
+++ b/lib/libpacman/sync.c
@@ -52,7 +52,6 @@
 #include "pacman.h"
 #include "md5.h"
 #include "sha1.h"
-#include "handle.h"
 #include "server.h"
 
 pmsyncpkg_t *_pacman_sync_new(int type, pmpkg_t *spkg, void *data)
@@ -260,7 +259,7 @@ error:
 	return(-1);
 }
 
-int _pacman_sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, pmlist_t *dbs_sync, const char *name)
+int _pacman_sync_addtarget(pmtrans_t *trans, const char *name)
 {
 	char targline[PKG_FULLNAME_LEN];
 	char *targ;
@@ -269,6 +268,8 @@ int _pacman_sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, pmlist_t *dbs_syn
 	pmpkg_t *spkg = NULL;
 	pmsyncpkg_t *ps;
 	int cmp;
+  pmdb_t *db_local = handle->db_local;
+	pmlist_t *dbs_sync = handle->dbs_sync;
 
 	ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
 	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
@@ -401,7 +402,7 @@ static int check_olddelay(void)
 	return(0);
 }
 
-int _pacman_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, pmlist_t *dbs_sync, pmlist_t **data)
+int _pacman_sync_prepare(pmtrans_t *trans, pmlist_t **data)
 {
 	pmlist_t *deps = NULL;
 	pmlist_t *list = NULL; /* list allowing checkdeps usage with data from trans->packages */
@@ -409,6 +410,8 @@ int _pacman_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, pmlist_t *dbs_sync,
 	pmlist_t *asked = NULL;
 	pmlist_t *i, *j, *k, *l;
 	int ret = 0;
+	pmdb_t *db_local = handle->db_local;
+	pmlist_t *dbs_sync = handle->dbs_sync;
 
 	ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
 	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
@@ -784,7 +787,7 @@ cleanup:
 	return(ret);
 }
 
-int _pacman_sync_commit(pmtrans_t *trans, pmdb_t *db_local, pmlist_t **data)
+int _pacman_sync_commit(pmtrans_t *trans, pmlist_t **data)
 {
 	pmlist_t *i, *j, *files = NULL;
 	pmtrans_t *tr = NULL;
@@ -792,6 +795,7 @@ int _pacman_sync_commit(pmtrans_t *trans, pmdb_t *db_local, pmlist_t **data)
 	char ldir[PATH_MAX];
 	int varcache = 1;
 	int tries = 0, doremove;
+	pmdb_t *db_local = handle->db_local;
 
 	ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
 	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
@@ -1110,4 +1114,10 @@ error:
 	return(-1);
 }
 
+const pmtrans_ops_t _pacman_sync_pmtrans_opts = {
+	.addtarget = _pacman_sync_addtarget,
+	.prepare = _pacman_sync_prepare,
+	.commit = _pacman_sync_commit
+};
+
 /* vim: set ts=2 sw=2 noet: */
diff --git a/lib/libpacman/sync.h b/lib/libpacman/sync.h
index 4e7a8ce..cd28992 100644
--- a/lib/libpacman/sync.h
+++ b/lib/libpacman/sync.h
@@ -39,9 +39,8 @@ pmsyncpkg_t *_pacman_sync_new(int type, pmpkg_t *spkg, void *data);
 void _pacman_sync_free(void *data);
 
 int _pacman_sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, pmlist_t *dbs_sync);
-int _pacman_sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, pmlist_t *dbs_sync, const char *name);
-int _pacman_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, pmlist_t *dbs_sync, pmlist_t **data);
-int _pacman_sync_commit(pmtrans_t *trans, pmdb_t *db_local, pmlist_t **data);
+
+const pmtrans_ops_t _pacman_sync_pmtrans_opts;
 
 #endif /* _PACMAN_SYNC_H */
 
diff --git a/lib/libpacman/trans.c b/lib/libpacman/trans.c
index e68173e..46141af 100644
--- a/lib/libpacman/trans.c
+++ b/lib/libpacman/trans.c
@@ -71,6 +71,7 @@ pmtrans_t *_pacman_trans_new()
 	trans->skiplist = NULL;
 	trans->type = 0;
 	trans->flags = 0;
+	trans->ops = NULL;
 	trans->cb_event = NULL;
 	trans->cb_conv = NULL;
 	trans->cb_progress = NULL;
@@ -108,6 +109,21 @@ int _pacman_trans_init(pmtrans_t *trans, pmtranstype_t type, unsigned int flags,
 
 	trans->type = type;
 	trans->flags = flags;
+	switch(trans->type) {
+		case PM_TRANS_TYPE_ADD:
+		case PM_TRANS_TYPE_UPGRADE:
+			trans->ops = &_pacman_add_pmtrans_opts;
+		break;
+		case PM_TRANS_TYPE_REMOVE:
+			trans->ops = &_pacman_remove_pmtrans_opts;
+		break;
+		case PM_TRANS_TYPE_SYNC:
+			trans->ops = &_pacman_sync_pmtrans_opts;
+		break;
+		default:
+			trans->ops = NULL;
+			return(-1);
+	}
 	trans->cb_event = event;
 	trans->cb_conv = conv;
 	trans->cb_progress = progress;
@@ -130,32 +146,17 @@ int _pacman_trans_addtarget(pmtrans_t *trans, const char *target)
 {
 	/* Sanity checks */
 	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
+	ASSERT(trans->ops != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
+	ASSERT(trans->ops->addtarget != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
 	ASSERT(target != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
 
 	if(_pacman_list_is_strin(target, trans->targets)) {
 		RET_ERR(PM_ERR_TRANS_DUP_TARGET, -1);
 	}
 
-	switch(trans->type) {
-		case PM_TRANS_TYPE_ADD:
-		case PM_TRANS_TYPE_UPGRADE:
-			if(_pacman_add_loadtarget(trans, handle->db_local, target) == -1) {
-				/* pm_errno is set by _pacman_add_loadtarget() */
-				return(-1);
-			}
-		break;
-		case PM_TRANS_TYPE_REMOVE:
-			if(_pacman_remove_loadtarget(trans, handle->db_local, target) == -1) {
-				/* pm_errno is set by remove_loadtarget() */
-				return(-1);
-			}
-		break;
-		case PM_TRANS_TYPE_SYNC:
-			if(_pacman_sync_addtarget(trans, handle->db_local, handle->dbs_sync, target) == -1) {
-				/* pm_errno is set by sync_loadtarget() */
-				return(-1);
-			}
-		break;
+	if(trans->ops->addtarget(trans, target) == -1) {
+		/* pm_errno is set by trans->ops->addtarget() */
+		return(-1);
 	}
 
 	trans->targets = _pacman_list_add(trans->targets, strdup(target));
@@ -165,36 +166,22 @@ int _pacman_trans_addtarget(pmtrans_t *trans, const char *target)
 
 int _pacman_trans_prepare(pmtrans_t *trans, pmlist_t **data)
 {
-	*data = NULL;
-
 	/* Sanity checks */
 	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
+	ASSERT(trans->ops != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
+	ASSERT(trans->ops->prepare != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
+	ASSERT(data != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
+
+	*data = NULL;
 
 	/* If there's nothing to do, return without complaining */
 	if(trans->packages == NULL) {
 		return(0);
 	}
 
-	switch(trans->type) {
-		case PM_TRANS_TYPE_ADD:
-		case PM_TRANS_TYPE_UPGRADE:
-			if(_pacman_add_prepare(trans, handle->db_local, data) == -1) {
-				/* pm_errno is set by _pacman_add_prepare() */
-				return(-1);
-			}
-		break;
-		case PM_TRANS_TYPE_REMOVE:
-			if(_pacman_remove_prepare(trans, handle->db_local, data) == -1) {
-				/* pm_errno is set by _pacman_remove_prepare() */
-				return(-1);
-			}
-		break;
-		case PM_TRANS_TYPE_SYNC:
-			if(_pacman_sync_prepare(trans, handle->db_local, handle->dbs_sync, data) == -1) {
-				/* pm_errno is set by _pacman_sync_prepare() */
-				return(-1);
-			}
-		break;
+	if(trans->ops->prepare(trans, data) == -1) {
+		/* pm_errno is set by trans->ops->prepare() */
+		return(-1);
 	}
 
 	trans->state = STATE_PREPARED;
@@ -204,11 +191,13 @@ int _pacman_trans_prepare(pmtrans_t *trans, pmlist_t **data)
 
 int _pacman_trans_commit(pmtrans_t *trans, pmlist_t **data)
 {
-	if(data!=NULL)
-		*data = NULL;
-
 	/* Sanity checks */
 	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
+	ASSERT(trans->ops != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
+	ASSERT(trans->ops->prepare != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
+
+	if(data!=NULL)
+		*data = NULL;
 
 	/* If there's nothing to do, return without complaining */
 	if(trans->packages == NULL) {
@@ -217,26 +206,9 @@ int _pacman_trans_commit(pmtrans_t *trans, pmlist_t **data)
 
 	trans->state = STATE_COMMITING;
 
-	switch(trans->type) {
-		case PM_TRANS_TYPE_ADD:
-		case PM_TRANS_TYPE_UPGRADE:
-			if(_pacman_add_commit(trans, handle->db_local) == -1) {
-				/* pm_errno is set by _pacman_add_prepare() */
-				return(-1);
-			}
-		break;
-		case PM_TRANS_TYPE_REMOVE:
-			if(_pacman_remove_commit(trans, handle->db_local) == -1) {
-				/* pm_errno is set by _pacman_remove_prepare() */
-				return(-1);
-			}
-		break;
-		case PM_TRANS_TYPE_SYNC:
-			if(_pacman_sync_commit(trans, handle->db_local, data) == -1) {
-				/* pm_errno is set by _pacman_sync_commit() */
-				return(-1);
-			}
-		break;
+	if(trans->ops->commit(trans, data) == -1) {
+		/* pm_errno is set by trans->ops->commit() */
+		return(-1);
 	}
 
 	trans->state = STATE_COMMITED;
diff --git a/lib/libpacman/trans.h b/lib/libpacman/trans.h
index fef6ee2..53359c6 100644
--- a/lib/libpacman/trans.h
+++ b/lib/libpacman/trans.h
@@ -24,6 +24,9 @@
 #ifndef _PACMAN_TRANS_H
 #define _PACMAN_TRANS_H
 
+#include "db.h"
+#include "pacman.h"
+
 enum {
 	STATE_IDLE = 0,
 	STATE_INITIALIZED,
@@ -34,10 +37,18 @@ enum {
 	STATE_INTERRUPTED
 };
 
-#include "pacman.h"
+typedef struct __pmtrans_t pmtrans_t;
 
-typedef struct __pmtrans_t {
+typedef struct __pmtrans_ops_t {
+	int (*addtarget)(pmtrans_t *trans, const char *name);
+	int (*prepare)(pmtrans_t *trans, pmlist_t **data);
+	int (*commit)(pmtrans_t *trans, pmlist_t **data);
+} pmtrans_ops_t;
+
+struct __pmtrans_t {
+	/* pmhandle_t *handle; */
 	pmtranstype_t type;
+	const pmtrans_ops_t *ops;
 	unsigned int flags;
 	unsigned char state;
 	pmlist_t *targets;     /* pmlist_t of (char *) */
@@ -46,7 +57,7 @@ typedef struct __pmtrans_t {
 	pacman_trans_cb_event cb_event;
 	pacman_trans_cb_conv cb_conv;
 	pacman_trans_cb_progress cb_progress;
-} pmtrans_t;
+};
 
 #define FREETRANS(p) \
 do { \
diff --git a/lib/libpacman/util.h b/lib/libpacman/util.h
index 7ff4a02..38ddb68 100644
--- a/lib/libpacman/util.h
+++ b/lib/libpacman/util.h
@@ -26,6 +26,8 @@
 #define _PACMAN_UTIL_H
 
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #if defined(__OpenBSD__)
 #include "/usr/local/include/archive.h"
 #include "/usr/local/include/archive_entry.h"
@@ -34,6 +36,10 @@
 #include <archive_entry.h>
 #endif
 
+#include "error.h"
+#include "log.h"
+#include "pacman.h"
+
 #define FREE(p) do { if (p) { free(p); p = NULL; } } while(0)
 
 #define ASSERT(cond, action) do { if(!(cond)) { action; } } while(0)
@@ -78,6 +84,32 @@ char* mkdtemp(char *template);
 #endif
 char *_pacman_archive_fgets(char *line, size_t size, struct archive *a);
 
+static __inline__ void *_pacman_malloc(size_t size)
+{
+	void *ptr = malloc(size);
+	if(ptr == NULL) {
+		_pacman_log(PM_LOG_ERROR, _("malloc failure: could not allocate %d bytes"), size);
+		RET_ERR(PM_ERR_MEMORY, NULL);
+	}
+	return ptr;
+}
+
+static __inline__ void *_pacman_zalloc(size_t size)
+{
+	void *ptr = _pacman_malloc(size);
+	if(ptr != NULL)
+		memset(ptr, 0, size);
+	return ptr;
+}
+
+static __inline__ void _pacman_free(void **ptr)
+{
+	if((ptr != NULL) && ((*ptr) != NULL)) {
+		free(*ptr);
+		*ptr = NULL;
+	}
+}
+
 #endif /* _PACMAN_UTIL_H */
 
 /* vim: set ts=2 sw=2 noet: */
