[PackageKit-commit] packagekit: Branch 'master' - 56 commits

Richard Hughes hughsient at kemper.freedesktop.org
Mon Oct 4 10:27:50 PDT 2010


 NEWS                                             |   57 +
 backends/alpm/pk-backend-alpm.c                  |    4 
 backends/apt/pk-backend-apt.c                    |    4 
 backends/aptcc/apt-utils.cpp                     |    2 
 backends/aptcc/apt.cpp                           |    5 
 backends/aptcc/pk-backend-aptcc.cpp              |   12 
 backends/box/pk-backend-box.c                    |    4 
 backends/conary/pk-backend-conary.c              |    4 
 backends/dummy/pk-backend-dummy.c                |  353 +++---
 backends/entropy/entropyBackend.py               |   42 
 backends/entropy/pk-backend-entropy.c            |    4 
 backends/opkg/pk-backend-opkg.c                  |    4 
 backends/pacman/backend-pacman.c                 |    4 
 backends/pisi/pk-backend-pisi.c                  |    4 
 backends/poldek/pk-backend-poldek.c              |    4 
 backends/portage/pk-backend-portage.c            |    4 
 backends/ports/pk-backend-ports.c                |    4 
 backends/razor/pk-backend-razor.c                |    4 
 backends/slapt/pk-backend-slapt.c                |    4 
 backends/smart/pk-backend-smart.c                |    4 
 backends/test/pk-backend-test-fail.c             |  191 +--
 backends/test/pk-backend-test-nop.c              |   51 -
 backends/test/pk-backend-test-spawn.c            |   62 -
 backends/test/pk-backend-test-succeed.c          |  270 ++---
 backends/test/pk-backend-test-thread.c           |   86 -
 backends/urpmi/pk-backend-urpmi.c                |    4 
 backends/yum/Yum.conf                            |   12 
 backends/yum/pk-backend-yum.c                    | 1167 +++++++++++------------
 backends/yum/yumBackend.py                       |   80 -
 backends/yum/yumFilter.py                        |   11 
 backends/zypp/pk-backend-zypp.cpp                |   58 +
 backends/zypp/zypp-utils.cpp                     |   18 
 client/pk-console.c                              |   18 
 client/pk-generate-pack.c                        |    2 
 configure.ac                                     |    4 
 contrib/PackageKit.spec.in                       |    4 
 contrib/browser-plugin/pk-plugin-install.c       |   30 
 contrib/command-not-found/pk-command-not-found.c |   19 
 docs/html/img/users-anjuta.png                   |binary
 docs/html/pk-download.html                       |    1 
 docs/html/pk-users.html                          |   17 
 etc/Makefile.am                                  |    7 
 etc/README                                       |   11 
 lib/packagekit-glib2/Makefile.am                 |    3 
 lib/packagekit-glib2/pk-catalog.c                |   11 
 lib/packagekit-glib2/pk-client.c                 |  422 ++++++++
 lib/packagekit-glib2/pk-common.c                 |  201 +++
 lib/packagekit-glib2/pk-common.h                 |    1 
 lib/packagekit-glib2/pk-control.c                |   99 +
 lib/packagekit-glib2/pk-self-test.c              |   20 
 lib/packagekit-glib2/pk-service-pack.c           |   45 
 lib/packagekit-glib2/pk-task.c                   |   37 
 lib/packagekit-qt/src/transaction.cpp            |    1 
 src/Makefile.am                                  |    1 
 src/pk-backend-internal.h                        |  172 ---
 src/pk-backend-spawn.c                           |   12 
 src/pk-backend.c                                 |  205 +++-
 src/pk-backend.h                                 |  155 ++-
 src/pk-engine.c                                  |  201 ---
 src/pk-main.c                                    |    2 
 src/pk-network-stack-connman.c                   |   11 
 src/pk-self-test.c                               |    1 
 src/pk-transaction-extra.c                       |    2 
 src/pk-transaction.c                             |  110 ++
 64 files changed, 2583 insertions(+), 1779 deletions(-)

New commits:
commit b00a9ebfc26376e2848bc03cc7ae9b18b8fcd07d
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Oct 4 18:27:56 2010 +0100

    Release version 0.6.9

diff --git a/NEWS b/NEWS
index a1d8487..90fb4e6 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,60 @@
+Version 0.6.9
+~~~~~~~~~~~~~
+Released: 2010-10-04
+
+Libraries:
+ - glib: Check the GCancellable is not already cancelled at startup in PkClient and PkControl (Richard Hughes)
+ - glib: Do not crash the client if a catalog file has both file and package sections (Richard Hughes)
+ - glib: Do not return simulation failures as critical errors (Richard Hughes)
+ - glib: Only return packages for catalogs that are _not_ installed (Richard Hughes)
+ - qt: Use setHints() on new constructor (Daniel Nicoletti)
+
+Backends:
+ - aptcc: Added Fonts group (Daniel Nicoletti)
+ - aptcc: Updated calls not to use deprecated apt code (Daniel Nicoletti)
+ - dummy: Remove the table-of-vfuncs from the dummy backend (Richard Hughes)
+ - entropy: Add forward compatibility, use EntropyRepositoryBase.listPackageIdsInCategory() if available. (Fabio Erculiani)
+ - portage: Add compatibility with latest Portage 2.2 rc snapshots (Fabio Erculiani)
+ - test: Remove the table-of-vfuncs from the test backends (Richard Hughes)
+ - yum: Allow SearchFiles and GetUpdateDetail to be processed using zif (Richard Hughes)
+ - yum: Change the configuration value UseZif to a bitfield of roles (Richard Hughes)
+ - yum: Don't assume yb.pkgSack.searchNevra() only returns one result to fix service pack generation (Richard Hughes)
+ - yum: Fix the split media handling in PackageKit yum backend (Hedayat Vatankhah)
+ - yum: For some reason yum needs to download the packagelists at init, so mark the download as cancellable. Fixes fd#30276 (Richard Hughes)
+ - yum: Get the changelog text using zif if it is available (Richard Hughes)
+ - yum: Only cancel the GCancellable if we are using ZIF (Richard Hughes)
+ - yum: Remove RepoSetData, it's a NOOP (Richard Hughes)
+ - yum: Remove the set-proxy from get_distro_upgrades(), it's already done in transaction_start() (Richard Hughes)
+ - yum: Remove the table-of-vfuncs from the yum backend (Richard Hughes)
+ - yum: Select the repository with the higher priority when a package exists in serveral repositories (Hedayat Vatankhah)
+ - yum: Switch to using transaction_start() and transaction_stop() to reduce backend complexity (Richard Hughes)
+ - yum: Use GetCategories also for using a zif GetGroups, as GetGroups does not have a role enum (Richard Hughes)
+ - yum: When prompting for media, include the disc number (Hedayat Vatankhah)
+ - zypp: Add development package support to filtering (Michael Meeks)
+ - zypp: Calculate sizes for patches correctly: bmo#2281, bnc#559802 (Michael Meeks)
+ - zypp: Enable proxy for zypp backend (Zhang Qiang)
+ - zypp: Include patches in 'resolve' results. bmc#2059 (Michael Meeks)
+ - zypp: Refresh cache and sat solv pool data if necessary (Zhang Qiang)
+ - zypp: Refresh cache before geting upgrade and installing (Zhang Qiang)
+ - zypp: Refresh system rpmdb while refresh cache (Zhang Qiang)
+ - zypp: Remove premature require_restart emission in update_packages_thread (Michael Meeks)
+
+New Features:
+ - Add transaction_start() and transaction_stop() vfuncs to make backends simpler (Richard Hughes)
+ - Add a feature that allows external scripts to be run after certain transactions (Richard Hughes)
+ - Allow backends to omit the table-of-vfuncs and use GModule functionality to resolve backend functions (Richard Hughes)
+
+Bugfixes:
+ - Add a nicer translated error when UpdatePackages has no packages to update. Fixes fd#30459 (Richard Hughes)
+ - browser-plugin: Do not query PkDesktop by default (Richard Hughes)
+ - browser-plugin: Fix up 2 small memory leaks in error paths (Richard Hughes)
+ - cnf: Add a proper error message when the transaction was cancelled (Richard Hughes)
+ - Don't call back into the daemon (from the daemon) when checking service packs. Fixes rh#634628 (Richard Hughes)
+ - Ensure we set an error if the spawned backend gets cancelled (Richard Hughes)
+ - Fix build with newer gobject-introspection (Matthias Clasen)
+ - Fix generating an updates service pack using pkgenpack (Richard Hughes)
+ - Use the correct network state for connman (Zhang Qiang)
+
 Version 0.6.8
 ~~~~~~~~~~~~~
 Released: 2010-09-06
diff --git a/configure.ac b/configure.ac
index f2a39f5..ecd585a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -37,7 +37,7 @@ AC_SUBST(PK_VERSION)
 # AGE		If libpackagekit can be linked into executables which can be
 # 		built with previous versions of this library. Don't use.
 LT_CURRENT=14
-LT_REVISION=3
+LT_REVISION=4
 LT_AGE=0
 AC_SUBST(LT_CURRENT)
 AC_SUBST(LT_REVISION)
diff --git a/docs/html/pk-download.html b/docs/html/pk-download.html
index e28ed3b..2d1fdd6 100644
--- a/docs/html/pk-download.html
+++ b/docs/html/pk-download.html
@@ -68,6 +68,7 @@ Releases are normally on the first working Monday of each month.
 </p>
 <table>
 <tr><td><b>Version</b></td><td>&nbsp;&nbsp;</td><td><b>Date</b></td></tr>
+<tr><td>0.6.9</td><td></td><td>2010-10-04</td></tr>
 <tr><td>0.6.8</td><td></td><td>2010-09-06</td></tr>
 <tr><td>0.6.7</td><td></td><td>2010-08-04</td></tr>
 <tr><td>0.6.6</td><td></td><td>2010-07-01</td></tr>
commit 24ae9f186a3a63004b01c00dde85ee7407ac3f50
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Oct 4 16:28:56 2010 +0100

    trivial: require zif 0.1.1 for the new API we introduced

diff --git a/configure.ac b/configure.ac
index 9c8ed98..f2a39f5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -666,7 +666,7 @@ if test x$enable_yum = xyes; then
 	AC_ARG_ENABLE(zif, AS_HELP_STRING([--enable-zif],[Build ZIF experimental code]),
 		      enable_zif=$enableval,enable_zif=yes)
 	if test x$enable_zif = xyes; then
-		PKG_CHECK_MODULES(ZIF, zif,
+		PKG_CHECK_MODULES(ZIF, zif >= 0.1.1,
 			          build_zif=yes, build_zif=no)
 	fi
 	if test "x$build_zif" = "xyes"; then
commit 00582c937543a749689f889526a330f69887306a
Author: Matthias Clasen <mclasen at redhat.com>
Date:   Mon Oct 4 09:10:21 2010 +0100

    Fix build with newer gobject-introspection
    
    I had to experiment a bit to come up with the fix below, which lets PackageKit
    0.6.8 build against current gobject-introspection.
    
    Signed-off-by: Richard Hughes <richard at hughsie.com>

diff --git a/lib/packagekit-glib2/Makefile.am b/lib/packagekit-glib2/Makefile.am
index 8fdce5e..25c67d7 100644
--- a/lib/packagekit-glib2/Makefile.am
+++ b/lib/packagekit-glib2/Makefile.am
@@ -237,8 +237,9 @@ introspection_sources = $(libpackagekit_glib2_la_SOURCES)
 PackageKitGlib-1.0.gir: libpackagekit-glib2.la
 PackageKitGlib_1_0_gir_INCLUDES = GObject-2.0 Gio-2.0
 PackageKitGlib_1_0_gir_CFLAGS = $(INCLUDES) -DI_KNOW_THE_PACKAGEKIT_GLIB2_API_IS_SUBJECT_TO_CHANGE
+PackageKitGlib_1_0_gir_SCANNERFLAGS = --identifier-prefix=Pk --warn-all --add-include-path=$(srcdir)
 PackageKitGlib_1_0_gir_LIBS = libpackagekit-glib2.la
-PackageKitGlib_1_0_gir_FILES = $(addprefix $(srcdir)/,$(introspection_sources))
+PackageKitGlib_1_0_gir_FILES = $(introspection_sources)
 INTROSPECTION_GIRS += PackageKitGlib-1.0.gir
 
 girdir = $(datadir)/gir-1.0
commit dad233a3384aa24220b0415dcfd480d8c3dd1d27
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Oct 4 09:19:35 2010 +0100

    Revert "glib: Fix build of introspection with gobject-introspection 0.9.9"
    
    This reverts commit a04286d4a9b66703fc4c1a4a122251419f3bbbfc.

diff --git a/lib/packagekit-glib2/Makefile.am b/lib/packagekit-glib2/Makefile.am
index d8b2b71..8fdce5e 100644
--- a/lib/packagekit-glib2/Makefile.am
+++ b/lib/packagekit-glib2/Makefile.am
@@ -238,7 +238,6 @@ PackageKitGlib-1.0.gir: libpackagekit-glib2.la
 PackageKitGlib_1_0_gir_INCLUDES = GObject-2.0 Gio-2.0
 PackageKitGlib_1_0_gir_CFLAGS = $(INCLUDES) -DI_KNOW_THE_PACKAGEKIT_GLIB2_API_IS_SUBJECT_TO_CHANGE
 PackageKitGlib_1_0_gir_LIBS = libpackagekit-glib2.la
-PackageKitGlib_1_0_gir_SCANNERFLAGS = --strip-prefix=Pk
 PackageKitGlib_1_0_gir_FILES = $(addprefix $(srcdir)/,$(introspection_sources))
 INTROSPECTION_GIRS += PackageKitGlib-1.0.gir
 
commit ec10c22846bc75203bc59df783f97a5a3c1c7677
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Sat Oct 2 10:19:04 2010 +0200

    entropy: add forward compatibility, use EntropyRepositoryBase.listPackageIdsInCategory() if available.

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index fe5f6ef..b06b550 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -1598,20 +1598,36 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
             self.percentage(percent)
             repo_all_cats = repo_db.listAllCategories()
-            if selected_categories:
-                etp_cat_ids = set([cat_id for cat_id, cat_name in \
-                    repo_all_cats if cat_name in selected_categories])
+
+            if hasattr(repo_db, "listPackageIdsInCategory"):
+                if selected_categories:
+                    etp_cats = set((x for x in repo_all_cats \
+                         if x in selected_categories))
+                else:
+                    # get all etp categories excluding all_matched_categories
+                    etp_cats = set((x for x in repo_all_cats \
+                         if x not in all_matched_categories))
+
+                for category in etp_cats:
+                    pkg_ids = repo_db.listPackageIdsInCategory(category)
+                    pkgs.update((repo, x, repo_db,) for x in pkg_ids)
+
             else:
-                # get all etp category ids excluding all_matched_categories
-                etp_cat_ids = set([cat_id for cat_id, cat_name in \
-                     repo_all_cats if cat_name not in all_matched_categories])
-
-            for cat_id in etp_cat_ids:
-                try:
-                    pkg_ids = repo_db.listIdPackagesInIdcategory(cat_id)
-                except AttributeError:
-                    pkg_ids = repo_db.listPackageIdsInCategoryId(cat_id)
-                pkgs.update((repo, x, repo_db,) for x in pkg_ids)
+                # backward compatibility
+                if selected_categories:
+                    etp_cat_ids = set([cat_id for cat_id, cat_name in \
+                        repo_all_cats if cat_name in selected_categories])
+                else:
+                    # get all etp category ids excluding all_matched_categories
+                    etp_cat_ids = set([cat_id for cat_id, cat_name in \
+                        repo_all_cats if cat_name not in all_matched_categories])
+
+                for cat_id in etp_cat_ids:
+                    try:
+                        pkg_ids = repo_db.listIdPackagesInIdcategory(cat_id)
+                    except AttributeError:
+                        pkg_ids = repo_db.listPackageIdsInCategoryId(cat_id)
+                    pkgs.update((repo, x, repo_db,) for x in pkg_ids)
 
         # now filter
         pkgs = self._pk_filter_pkgs(pkgs, filters)
commit a04286d4a9b66703fc4c1a4a122251419f3bbbfc
Author: Vincent Untz <vuntz at gnome.org>
Date:   Fri Oct 1 19:48:55 2010 +0200

    glib: Fix build of introspection with gobject-introspection 0.9.9
    
    We need to tell g-it-scanner what prefix is used by the library.

diff --git a/lib/packagekit-glib2/Makefile.am b/lib/packagekit-glib2/Makefile.am
index 8fdce5e..d8b2b71 100644
--- a/lib/packagekit-glib2/Makefile.am
+++ b/lib/packagekit-glib2/Makefile.am
@@ -238,6 +238,7 @@ PackageKitGlib-1.0.gir: libpackagekit-glib2.la
 PackageKitGlib_1_0_gir_INCLUDES = GObject-2.0 Gio-2.0
 PackageKitGlib_1_0_gir_CFLAGS = $(INCLUDES) -DI_KNOW_THE_PACKAGEKIT_GLIB2_API_IS_SUBJECT_TO_CHANGE
 PackageKitGlib_1_0_gir_LIBS = libpackagekit-glib2.la
+PackageKitGlib_1_0_gir_SCANNERFLAGS = --strip-prefix=Pk
 PackageKitGlib_1_0_gir_FILES = $(addprefix $(srcdir)/,$(introspection_sources))
 INTROSPECTION_GIRS += PackageKitGlib-1.0.gir
 
commit 9bacc0ea36a5c526193f455fdf3d413a8360a59a
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Oct 1 18:33:38 2010 +0100

    yum: use GetCategories also for using a zif GetGroups, as GetGroups does not have a role enum

diff --git a/backends/yum/pk-backend-yum.c b/backends/yum/pk-backend-yum.c
index 2cc12b4..90fc8f3 100644
--- a/backends/yum/pk-backend-yum.c
+++ b/backends/yum/pk-backend-yum.c
@@ -964,7 +964,7 @@ pk_backend_get_groups (PkBackend *backend)
 	PkBitfield groups = 0;
 
 	/* it seems some people are not ready for the awesomeness */
-	if (!pk_bitfield_contain (priv->use_zif, pk_backend_get_role (backend))) {
+	if (!pk_bitfield_contain (priv->use_zif, PK_ROLE_ENUM_GET_CATEGORIES)) {
 		groups = pk_bitfield_from_enums (
 			PK_GROUP_ENUM_COLLECTIONS,
 			PK_GROUP_ENUM_NEWEST,
commit b0e629d6d9b5c9e537f2804af2bf492bb25c0a57
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Oct 1 18:07:22 2010 +0100

    yum: remove RepoSetData, it's a NOOP

diff --git a/backends/yum/pk-backend-yum.c b/backends/yum/pk-backend-yum.c
index 63ebd64..2cc12b4 100644
--- a/backends/yum/pk-backend-yum.c
+++ b/backends/yum/pk-backend-yum.c
@@ -2755,16 +2755,6 @@ pk_backend_repo_enable (PkBackend *backend, const gchar *repo_id, gboolean enabl
 }
 
 /**
- * pk_backend_repo_set_data:
- */
-void
-pk_backend_repo_set_data (PkBackend *backend, const gchar *repo_id, const gchar *parameter, const gchar *value)
-{
-	/* no operation */
-	pk_backend_finished (backend);
-}
-
-/**
  * pk_backend_what_provides:
  */
 void
commit 0665ac256ad4df06447afc605188264b963f7efd
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Oct 1 17:45:41 2010 +0100

    yum: allow SearchFiles and GetUpdateDetail to be processed using zif

diff --git a/backends/yum/pk-backend-yum.c b/backends/yum/pk-backend-yum.c
index 5105206..63ebd64 100644
--- a/backends/yum/pk-backend-yum.c
+++ b/backends/yum/pk-backend-yum.c
@@ -1869,16 +1869,14 @@ pk_backend_get_files (PkBackend *backend, gchar **package_ids)
 {
 	gchar *package_ids_temp;
 
-	/* check if we can use zif */
-	if (priv->use_zif) {
-		pk_backend_thread_create (backend, pk_backend_get_files_thread);
+	/* it seems some people are not ready for the awesomeness */
+	if (!pk_bitfield_contain (priv->use_zif, pk_backend_get_role (backend))) {
+		package_ids_temp = pk_package_ids_to_string (package_ids);
+		pk_backend_spawn_helper (priv->spawn,  "yumBackend.py", "get-files", package_ids_temp, NULL);
+		g_free (package_ids_temp);
 		return;
 	}
-
-	/* fall back to spawning */
-	package_ids_temp = pk_package_ids_to_string (package_ids);
-	pk_backend_spawn_helper (priv->spawn,  "yumBackend.py", "get-files", package_ids_temp, NULL);
-	g_free (package_ids_temp);
+	pk_backend_thread_create (backend, pk_backend_get_files_thread);
 }
 
 /**
@@ -2264,7 +2262,7 @@ void
 pk_backend_get_update_detail (PkBackend *backend, gchar **package_ids)
 {
 	/* it seems some people are not ready for the awesomeness */
-	if (TRUE || !pk_bitfield_contain (priv->use_zif, pk_backend_get_role (backend))) {
+	if (!pk_bitfield_contain (priv->use_zif, pk_backend_get_role (backend))) {
 		gchar *package_ids_temp;
 		package_ids_temp = pk_package_ids_to_string (package_ids);
 		pk_backend_spawn_helper (priv->spawn, "yumBackend.py", "get-update-detail", package_ids_temp, NULL);
commit 3d55e6b226d0ff90f58ad758b7bbce635b581a34
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Oct 1 17:40:56 2010 +0100

    yum: Remove the set-proxy from get_distro_upgrades(), it's already done in transaction_start()

diff --git a/backends/yum/pk-backend-yum.c b/backends/yum/pk-backend-yum.c
index 740ba67..5105206 100644
--- a/backends/yum/pk-backend-yum.c
+++ b/backends/yum/pk-backend-yum.c
@@ -1638,7 +1638,6 @@ pk_backend_get_distro_upgrades_thread (PkBackend *backend)
 	gchar *filename = NULL;
 	gchar **groups = NULL;
 	gchar *name = NULL;
-	gchar *proxy = NULL;
 	gchar **split = NULL;
 	guint i;
 	guint last_version = 0;
@@ -1652,15 +1651,6 @@ pk_backend_get_distro_upgrades_thread (PkBackend *backend)
 	zif_state_reset (priv->state);
 	zif_state_set_number_steps (priv->state, 2);
 
-	/* set proxy */
-	proxy = pk_backend_get_proxy_http (backend);
-	ret = zif_download_set_proxy (priv->download, proxy, &error);
-	if (!ret) {
-		pk_backend_error_code (backend, PK_ERROR_ENUM_TRANSACTION_ERROR, "failed to set proxy: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
 	/* download new file */
 	filename = g_build_filename ("/var/cache/PackageKit", "releases.txt", NULL);
 	child = zif_state_get_child (priv->state);
@@ -1735,7 +1725,6 @@ out:
 	g_free (distro_id);
 	g_free (filename);
 	g_free (name);
-	g_free (proxy);
 	if (file != NULL)
 		g_key_file_free (file);
 	g_strfreev (groups);
commit 4c5e7732520039cfbddd9424c622f5a89e571e7a
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Oct 1 15:53:14 2010 +0100

    yum: change the configuration value UseZif to a bitfield of roles

diff --git a/backends/yum/Yum.conf b/backends/yum/Yum.conf
index ac6b080..8884138 100644
--- a/backends/yum/Yum.conf
+++ b/backends/yum/Yum.conf
@@ -39,12 +39,14 @@ InfrastructurePackages=PackageKit;yum;rpm;gnome-packagekit;kpackagekit;selinux-p
 
 # Yum is slow, and we can use Zif to accelerate some simple transactions
 #
-# Yum is written in python, and we therefor have to execute a new process and
+# Yum is written in python, and we have to execute a new process and
 # communicate with it. This is much slower than just acessing the repo files
-# and rpmdb in a C thread. Zif is a pretty new project, and is not well tested
+# and rpmdb in a thread. Zif is a pretty new project, and is not well tested
 # at this time. It is however up to an order of magnitude faster in some
 # benchmark tests.
 #
-# default=true
-UseZif=true
-
+# Zif probably still has bugs. This key provides a way for the admin
+# to still use the awesomeness of Zif for some operations, but not others.
+#
+# default=repo-list;repo-enable
+UseZif=get-repo-list;repo-enable
diff --git a/backends/yum/pk-backend-yum.c b/backends/yum/pk-backend-yum.c
index 195a37e..740ba67 100644
--- a/backends/yum/pk-backend-yum.c
+++ b/backends/yum/pk-backend-yum.c
@@ -39,7 +39,7 @@ typedef struct {
 	PkBackendSpawn	*spawn;
 	GFileMonitor	*monitor;
 	GCancellable	*cancellable;
-	gboolean	 use_zif;
+	PkBitfield	 use_zif;
 	guint		 signal_finished;
 	guint		 signal_status;
 #ifdef HAVE_ZIF
@@ -779,6 +779,7 @@ pk_backend_initialize (PkBackend *backend)
 	GKeyFile *key_file = NULL;
 	gchar *config_file = NULL;
 	GList *mounts;
+	gchar *use_zif = NULL;
 
 	/* create private area */
 	priv = g_new0 (PkBackendYumPrivate, 1);
@@ -826,11 +827,15 @@ pk_backend_initialize (PkBackend *backend)
 		goto out;
 	}
 
-#ifdef HAVE_ZIF
+	#ifdef HAVE_ZIF
 	/* it seems some people are not ready for the awesomeness */
-	priv->use_zif = g_key_file_get_boolean (key_file, "Backend", "UseZif", NULL);
-	if (!priv->use_zif)
-		goto out;
+	use_zif = g_key_file_get_string (key_file, "Backend", "UseZif", NULL);
+	if (use_zif != NULL) {
+		priv->use_zif = pk_role_bitfield_from_string (use_zif);
+		if (priv->use_zif == 0)
+			egg_warning ("failed to parse UseZif '%s'", use_zif);
+	}
+	egg_debug ("UseZif=%s (%i)", use_zif, (gint)priv->use_zif);
 
 	/* use a timer for profiling */
 	priv->timer = g_timer_new ();
@@ -900,6 +905,7 @@ pk_backend_initialize (PkBackend *backend)
 	priv->use_zif = FALSE;
 #endif
 out:
+	g_free (use_zif);
 	g_free (config_file);
 	if (key_file != NULL)
 		g_key_file_free (key_file);
@@ -958,7 +964,7 @@ pk_backend_get_groups (PkBackend *backend)
 	PkBitfield groups = 0;
 
 	/* it seems some people are not ready for the awesomeness */
-	if (!priv->use_zif) {
+	if (!pk_bitfield_contain (priv->use_zif, pk_backend_get_role (backend))) {
 		groups = pk_bitfield_from_enums (
 			PK_GROUP_ENUM_COLLECTIONS,
 			PK_GROUP_ENUM_NEWEST,
@@ -1235,7 +1241,7 @@ void
 pk_backend_download_packages (PkBackend *backend, gchar **package_ids, const gchar *directory)
 {
 	/* it seems some people are not ready for the awesomeness */
-	if (!priv->use_zif) {
+	if (!pk_bitfield_contain (priv->use_zif, pk_backend_get_role (backend))) {
 		gchar *package_ids_temp;
 
 		/* send the complete list as stdin */
@@ -1422,7 +1428,7 @@ void
 pk_backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	/* it seems some people are not ready for the awesomeness */
-	if (!priv->use_zif) {
+	if (!pk_bitfield_contain (priv->use_zif, pk_backend_get_role (backend))) {
 		gchar *filters_text;
 		gchar *package_ids_temp;
 		package_ids_temp = pk_package_ids_to_string (package_ids);
@@ -1610,7 +1616,7 @@ void
 pk_backend_get_details (PkBackend *backend, gchar **package_ids)
 {
 	/* check if we can use zif */
-	if (!priv->use_zif) {
+	if (!pk_bitfield_contain (priv->use_zif, pk_backend_get_role (backend))) {
 		gchar *package_ids_temp;
 		package_ids_temp = pk_package_ids_to_string (package_ids);
 		pk_backend_spawn_helper (priv->spawn, "yumBackend.py", "get-details", package_ids_temp, NULL);
@@ -1745,7 +1751,7 @@ void
 pk_backend_get_distro_upgrades (PkBackend *backend)
 {
 	/* it seems some people are not ready for the awesomeness */
-	if (!priv->use_zif) {
+	if (!pk_bitfield_contain (priv->use_zif, pk_backend_get_role (backend))) {
 		pk_backend_spawn_helper (priv->spawn, "yumBackend.py", "get-distro-upgrades", NULL);
 		return;
 	}
@@ -2092,7 +2098,7 @@ void
 pk_backend_get_updates (PkBackend *backend, PkBitfield filters)
 {
 	/* it seems some people are not ready for the awesomeness */
-	if (!priv->use_zif) {
+	if (!pk_bitfield_contain (priv->use_zif, pk_backend_get_role (backend))) {
 		gchar *filters_text;
 		filters_text = pk_filter_bitfield_to_string (filters);
 		pk_backend_spawn_helper (priv->spawn,  "yumBackend.py", "get-updates", filters_text, NULL);
@@ -2109,7 +2115,7 @@ void
 pk_backend_get_packages (PkBackend *backend, PkBitfield filters)
 {
 	/* it seems some people are not ready for the awesomeness */
-	if (!priv->use_zif) {
+	if (!pk_bitfield_contain (priv->use_zif, pk_backend_get_role (backend))) {
 		gchar *filters_text;
 		filters_text = pk_filter_bitfield_to_string (filters);
 		pk_backend_spawn_helper (priv->spawn, "yumBackend.py", "get-packages", filters_text, NULL);
@@ -2269,7 +2275,7 @@ void
 pk_backend_get_update_detail (PkBackend *backend, gchar **package_ids)
 {
 	/* it seems some people are not ready for the awesomeness */
-	if (TRUE || !priv->use_zif) {
+	if (TRUE || !pk_bitfield_contain (priv->use_zif, pk_backend_get_role (backend))) {
 		gchar *package_ids_temp;
 		package_ids_temp = pk_package_ids_to_string (package_ids);
 		pk_backend_spawn_helper (priv->spawn, "yumBackend.py", "get-update-detail", package_ids_temp, NULL);
@@ -2435,7 +2441,7 @@ pk_backend_refresh_cache (PkBackend *backend, gboolean force)
 	}
 
 	/* it seems some people are not ready for the awesomeness */
-	if (!priv->use_zif) {
+	if (!pk_bitfield_contain (priv->use_zif, pk_backend_get_role (backend))) {
 		pk_backend_spawn_helper (priv->spawn, "yumBackend.py", "refresh-cache", pk_backend_bool_to_string (force), NULL);
 		return;
 	}
@@ -2463,7 +2469,7 @@ void
 pk_backend_search_details (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	/* it seems some people are not ready for the awesomeness */
-	if (!priv->use_zif) {
+	if (!pk_bitfield_contain (priv->use_zif, pk_backend_get_role (backend))) {
 		gchar *filters_text;
 		gchar *search;
 		filters_text = pk_filter_bitfield_to_string (filters);
@@ -2483,7 +2489,7 @@ void
 pk_backend_search_files (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	/* it seems some people are not ready for the awesomeness */
-	if (!priv->use_zif) {
+	if (!pk_bitfield_contain (priv->use_zif, pk_backend_get_role (backend))) {
 		gchar *filters_text;
 		gchar *search;
 		filters_text = pk_filter_bitfield_to_string (filters);
@@ -2503,7 +2509,7 @@ void
 pk_backend_search_groups (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	/* it seems some people are not ready for the awesomeness */
-	if (!priv->use_zif) {
+	if (!pk_bitfield_contain (priv->use_zif, pk_backend_get_role (backend))) {
 		gchar *filters_text;
 		gchar *search;
 		filters_text = pk_filter_bitfield_to_string (filters);
@@ -2523,7 +2529,7 @@ void
 pk_backend_search_names (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	/* it seems some people are not ready for the awesomeness */
-	if (!priv->use_zif) {
+	if (!pk_bitfield_contain (priv->use_zif, pk_backend_get_role (backend))) {
 		gchar *filters_text;
 		gchar *search;
 		filters_text = pk_filter_bitfield_to_string (filters);
@@ -2566,7 +2572,7 @@ void
 pk_backend_resolve (PkBackend *backend, PkBitfield filters, gchar **packages)
 {
 	/* it seems some people are not ready for the awesomeness */
-	if (!priv->use_zif) {
+	if (!pk_bitfield_contain (priv->use_zif, pk_backend_get_role (backend))) {
 		gchar *filters_text;
 		gchar *package_ids_temp;
 		filters_text = pk_filter_bitfield_to_string (filters);
@@ -2678,7 +2684,7 @@ void
 pk_backend_get_repo_list (PkBackend *backend, PkBitfield filters)
 {
 	/* it seems some people are not ready for the awesomeness */
-	if (!priv->use_zif) {
+	if (!pk_bitfield_contain (priv->use_zif, pk_backend_get_role (backend))) {
 		gchar *filters_text;
 		filters_text = pk_filter_bitfield_to_string (filters);
 		pk_backend_spawn_helper (priv->spawn, "yumBackend.py", "get-repo-list", filters_text, NULL);
@@ -2750,7 +2756,7 @@ void
 pk_backend_repo_enable (PkBackend *backend, const gchar *repo_id, gboolean enabled)
 {
 	/* it seems some people are not ready for the awesomeness */
-	if (!priv->use_zif) {
+	if (!pk_bitfield_contain (priv->use_zif, pk_backend_get_role (backend))) {
 		if (enabled == TRUE) {
 			pk_backend_spawn_helper (priv->spawn, "yumBackend.py", "repo-enable", repo_id, "true", NULL);
 		} else {
@@ -2784,7 +2790,7 @@ pk_backend_what_provides (PkBackend *backend, PkBitfield filters, PkProvidesEnum
 	gchar *search_tmp;
 
 	/* it seems some people are not ready for the awesomeness */
-	if (!priv->use_zif) {
+	if (!pk_bitfield_contain (priv->use_zif, pk_backend_get_role (backend))) {
 		gchar *filters_text;
 		const gchar *provides_text;
 		provides_text = pk_provides_enum_to_string (provides);
@@ -2928,7 +2934,7 @@ void
 pk_backend_get_categories (PkBackend *backend)
 {
 	/* it seems some people are not ready for the awesomeness */
-	if (!priv->use_zif) {
+	if (!pk_bitfield_contain (priv->use_zif, pk_backend_get_role (backend))) {
 		pk_backend_spawn_helper (priv->spawn, "yumBackend.py", "get-categories", NULL);
 		return;
 	}
commit 605edd826fa71cf75b2f41c939e54d2e8be6653d
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Oct 1 15:25:52 2010 +0100

    trivial: fix the yum backend compile if we are using zif, my sed apologies

diff --git a/backends/yum/pk-backend-yum.c b/backends/yum/pk-backend-yum.c
index 7e441ef..195a37e 100644
--- a/backends/yum/pk-backend-yum.c
+++ b/backends/yum/pk-backend-yum.c
@@ -518,7 +518,7 @@ pk_backend_search_thread (PkBackend *backend)
 
 	/* get default store_array */
 	state_local = zif_state_get_child (priv->state);
-	store_array = backend_get_default_store_array_for_filter (backend, filters, state_local, &error);
+	store_array = pk_backend_get_default_store_array_for_filter (backend, filters, state_local, &error);
 	if (store_array == NULL) {
 		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, "failed to get stores: %s", error->message);
 		g_error_free (error);
@@ -532,7 +532,7 @@ pk_backend_search_thread (PkBackend *backend)
 		g_error_free (error);
 		goto out;
 	}
-	zif_state_set_error_handler (priv->state, (ZifStateErrorHandlerCb) backend_error_handler_cb, backend);
+	zif_state_set_error_handler (priv->state, (ZifStateErrorHandlerCb) pk_backend_error_handler_cb, backend);
 
 	/* do get action */
 	if (role == PK_ROLE_ENUM_GET_PACKAGES) {
@@ -599,7 +599,7 @@ pk_backend_search_thread (PkBackend *backend)
 	}
 
 	/* filter */
-	result = backend_filter_package_array (array, filters);
+	result = pk_backend_filter_package_array (array, filters);
 
 	/* this section done */
 	ret = zif_state_done (priv->state, &error);
@@ -1124,7 +1124,7 @@ pk_backend_download_packages_thread (PkBackend *backend)
 	/* find all the packages */
 	packages = g_ptr_array_new ();
 	state_local = zif_state_get_child (priv->state);
-	store_array = backend_get_default_store_array_for_filter (backend, pk_bitfield_value (PK_FILTER_ENUM_NOT_INSTALLED), state_local, &error);
+	store_array = pk_backend_get_default_store_array_for_filter (backend, pk_bitfield_value (PK_FILTER_ENUM_NOT_INSTALLED), state_local, &error);
 	if (store_array == NULL) {
 		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, "failed to get stores: %s", error->message);
 		g_error_free (error);
@@ -1280,7 +1280,7 @@ pk_backend_get_depends_thread (PkBackend *backend)
 
 	/* find all the packages */
 	state_local = zif_state_get_child (priv->state);
-	store_array = backend_get_default_store_array_for_filter (backend, 0, state_local, &error);
+	store_array = pk_backend_get_default_store_array_for_filter (backend, 0, state_local, &error);
 	if (store_array == NULL) {
 		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, "failed to get stores: %s", error->message);
 		g_error_free (error);
@@ -1381,7 +1381,7 @@ pk_backend_get_depends_thread (PkBackend *backend)
 	}
 
 	/* filter */
-	result = backend_filter_package_array (array, filters);
+	result = pk_backend_filter_package_array (array, filters);
 
 	/* this section done */
 	ret = zif_state_done (priv->state, &error);
@@ -1466,9 +1466,9 @@ pk_backend_get_details_thread (PkBackend *backend)
 
 	/* find all the packages */
 	state_local = zif_state_get_child (priv->state);
-	if (backend_is_all_installed (package_ids))
+	if (pk_backend_is_all_installed (package_ids))
 		pk_bitfield_add (filters, PK_FILTER_ENUM_INSTALLED);
-	store_array = backend_get_default_store_array_for_filter (backend, filters, state_local, &error);
+	store_array = pk_backend_get_default_store_array_for_filter (backend, filters, state_local, &error);
 	if (store_array == NULL) {
 		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, "failed to get stores: %s", error->message);
 		g_error_free (error);
@@ -1783,9 +1783,9 @@ pk_backend_get_files_thread (PkBackend *backend)
 
 	/* find all the packages */
 	state_local = zif_state_get_child (priv->state);
-	if (backend_is_all_installed (package_ids))
+	if (pk_backend_is_all_installed (package_ids))
 		pk_bitfield_add (filters, PK_FILTER_ENUM_INSTALLED);
-	store_array = backend_get_default_store_array_for_filter (backend, filters, state_local, &error);
+	store_array = pk_backend_get_default_store_array_for_filter (backend, filters, state_local, &error);
 	if (store_array == NULL) {
 		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, "failed to get stores: %s", error->message);
 		g_error_free (error);
@@ -1987,7 +1987,7 @@ pk_backend_get_updates_thread (PkBackend *backend)
 
 	/* get updates */
 	state_local = zif_state_get_child (priv->state);
-	zif_state_set_error_handler (priv->state, (ZifStateErrorHandlerCb) backend_error_handler_cb, backend);
+	zif_state_set_error_handler (priv->state, (ZifStateErrorHandlerCb) pk_backend_error_handler_cb, backend);
 	array = zif_store_array_get_updates (store_array, packages, state_local, &error);
 	if (array == NULL) {
 		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, "failed to get updates: %s\n", error->message);
@@ -2059,7 +2059,7 @@ pk_backend_get_updates_thread (PkBackend *backend)
 	pk_backend_profile ("get updateinfo");
 
 	/* filter */
-	result = backend_filter_package_array (array, filters);
+	result = pk_backend_filter_package_array (array, filters);
 
 	/* done */
 	pk_backend_set_percentage (backend, 100);
@@ -2225,7 +2225,7 @@ pk_backend_get_update_detail_thread (PkBackend *backend)
 			/* format changelog */
 			changesets = zif_update_get_changelog (update);
 			if (changesets != NULL)
-				changelog_text = backend_get_changelog_text (changesets);
+				changelog_text = pk_backend_get_changelog_text (changesets);
 			pk_backend_update_detail (backend, package_ids[i],
 						  NULL, //updates,
 						  NULL, //obsoletes,
@@ -2406,7 +2406,7 @@ pk_backend_refresh_cache_thread (PkBackend *backend)
 
 	/* clean all the repos */
 	state_local = zif_state_get_child (priv->state);
-	zif_state_set_error_handler (priv->state, (ZifStateErrorHandlerCb) backend_error_handler_cb, backend);
+	zif_state_set_error_handler (priv->state, (ZifStateErrorHandlerCb) pk_backend_error_handler_cb, backend);
 	ret = zif_store_array_clean (store_array, state_local, &error);
 	if (!ret) {
 		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, "failed to clean: %s\n", error->message);
@@ -2871,7 +2871,7 @@ pk_backend_get_categories_thread (PkBackend *backend)
 
 	/* get sorted list of unique categories */
 	state_local = zif_state_get_child (priv->state);
-	zif_state_set_error_handler (priv->state, (ZifStateErrorHandlerCb) backend_error_handler_cb, backend);
+	zif_state_set_error_handler (priv->state, (ZifStateErrorHandlerCb) pk_backend_error_handler_cb, backend);
 	array = zif_store_array_get_categories (stores, state_local, &error);
 	if (array == NULL) {
 		pk_backend_error_code (backend, PK_ERROR_ENUM_GROUP_LIST_INVALID, "failed to add get categories: %s", error->message);
commit 2474054245b21459084b2c9ee098538cf55c0fa3
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Sep 29 13:54:02 2010 +0100

    Add a nicer translated error when UpdatePackages has no packages to update. Fixes fd#30459

diff --git a/client/pk-console.c b/client/pk-console.c
index c7913cb..0ad3190 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -689,11 +689,22 @@ pk_console_finished_cb (GObject *object, GAsyncResult *res, gpointer data)
 		goto out;
 	}
 
+	/* get the role */
+	g_object_get (G_OBJECT(results), "role", &role, NULL);
+
 	/* check error code */
 	error_code = pk_results_get_error_code (results);
 	if (error_code != NULL) {
-		/* TRANSLATORS: the transaction failed in a way we could not expect */
-		g_print ("%s: %s, %s\n", _("The transaction failed"), pk_error_enum_to_string (pk_error_get_code (error_code)), pk_error_get_details (error_code));
+
+		/* print an error */
+		if (role == PK_ROLE_ENUM_UPDATE_PACKAGES &&
+		    pk_error_get_code (error_code) == PK_ERROR_ENUM_NO_PACKAGES_TO_UPDATE) {
+			/* TRANSLATORS: the user asked to update everything, but there is nothing that can be updated */
+			g_print ("%s\n", _("There are no packages to update."));
+		} else {
+			/* TRANSLATORS: the transaction failed in a way we could not expect */
+			g_print ("%s: %s, %s\n", _("The transaction failed"), pk_error_enum_to_string (pk_error_get_code (error_code)), pk_error_get_details (error_code));
+		}
 
 		/* special case */
 		if (pk_error_get_code (error_code) == PK_ERROR_ENUM_NO_PACKAGES_TO_UPDATE)
@@ -701,9 +712,6 @@ pk_console_finished_cb (GObject *object, GAsyncResult *res, gpointer data)
 		goto out;
 	}
 
-	/* get the role */
-	g_object_get (G_OBJECT(results), "role", &role, NULL);
-
 	/* get the sack */
 	sack = pk_results_get_package_sack (results);
 	pk_package_sack_sort (sack, PK_PACKAGE_SACK_SORT_TYPE_NAME);
commit 9b89cefedb86d4f9ebd633ed1602768c51003993
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 28 17:24:31 2010 +0100

    trivial: add Anjuta to the list of PK users

diff --git a/docs/html/img/users-anjuta.png b/docs/html/img/users-anjuta.png
new file mode 100644
index 0000000..fa41560
Binary files /dev/null and b/docs/html/img/users-anjuta.png differ
diff --git a/docs/html/pk-users.html b/docs/html/pk-users.html
index 3ccc1dc..ec699a3 100644
--- a/docs/html/pk-users.html
+++ b/docs/html/pk-users.html
@@ -293,6 +293,23 @@
   </p>
  </td>
 </tr>
+<tr>
+ <td>
+  <a href="http://projects.gnome.org/anjuta/"><img src="img/users-anjuta.png" alt=""/></a>
+ </td>
+ <td>
+  <h2>Anjuta</h2>
+  <p>
+   Anjuta is an integrated development environment for GNOME supported
+   various programming languages such as C/C++, Python, Vala and
+   Javascript.
+  </p>
+  <p>
+   PackageKit is used to install missing packages when creating a new
+   project.
+  </p>
+ </td>
+</tr>
 <!--
 <tr>
  <td>
commit 6b81039fac1f51b33f1e74d1bbc298ba70b92cf3
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 28 15:36:28 2010 +0100

    Add a feature that allows external scripts to be run after certain transactions

diff --git a/contrib/PackageKit.spec.in b/contrib/PackageKit.spec.in
index 073beb3..28bb44b 100644
--- a/contrib/PackageKit.spec.in
+++ b/contrib/PackageKit.spec.in
@@ -294,6 +294,10 @@ update-mime-database %{_datadir}/mime &> /dev/null || :
 %dir %{_datadir}/PackageKit
 %dir %{_datadir}/PackageKit/helpers
 %dir %{_sysconfdir}/PackageKit
+%dir %{_sysconfdir}/PackageKit/events
+%dir %{_sysconfdir}/PackageKit/events/post-transaction.d
+%dir %{_sysconfdir}/PackageKit/events/pre-transaction.d
+%{_sysconfdir}/PackageKit/events/*.d/README
 %dir %{_localstatedir}/lib/PackageKit
 %dir %{python_sitelib}/packagekit
 %dir %{_localstatedir}/cache/PackageKit
diff --git a/etc/Makefile.am b/etc/Makefile.am
index 352f802..a37b789 100644
--- a/etc/Makefile.am
+++ b/etc/Makefile.am
@@ -10,9 +10,16 @@ $(conf_DATA): $(conf_in_files) Makefile
 vendordir = $(PK_CONF_DIR)
 vendor_DATA = Vendor.conf
 
+eventspostransdir = $(PK_CONF_DIR)/events/post-transaction.d
+eventspostrans_DATA = README
+
+eventspretransdir = $(PK_CONF_DIR)/events/pre-transaction.d
+eventspretrans_DATA = README
+
 EXTRA_DIST =						\
 	$(conf_in_files)				\
 	$(vendor_DATA)					\
+	$(eventspostrans_DATA)				\
 	$(NULL)
 
 DISTCLEANFILES =					\
diff --git a/etc/README b/etc/README
new file mode 100644
index 0000000..6a7aa4d
--- /dev/null
+++ b/etc/README
@@ -0,0 +1,11 @@
+README
+
+Executable scripts can be installed in this directory and will be run
+before or after each transaction. The transaction type will be the first
+parameter to the script, e.g. "search-name" or "refresh-cache".
+
+*** THESE SCRIPTS ARE RUN AS ROOT AND ARE SECURITY SENSITIVE ***
+
+Be sure to ensure that files here have the correct permissions
+(owned by root, and not writable by users), or they will not be run by
+the daemon.
diff --git a/src/pk-transaction.c b/src/pk-transaction.c
index c72706f..949aee0 100644
--- a/src/pk-transaction.c
+++ b/src/pk-transaction.c
@@ -680,6 +680,109 @@ pk_transaction_package_list_to_string (GPtrArray *array)
 }
 
 /**
+ * pk_transaction_process_script:
+ **/
+static void
+pk_transaction_process_script (PkTransaction *transaction, const gchar *filename)
+{
+	GFile *file = NULL;
+	GFileInfo *info = NULL;
+	guint file_uid;
+	gchar *command;
+	gint exit_status = 0;
+	gboolean ret;
+	GError *error = NULL;
+
+	/* get content type for file */
+	file = g_file_new_for_path (filename);
+	info = g_file_query_info (file,
+				  G_FILE_ATTRIBUTE_UNIX_UID ","
+				  G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE,
+				  G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error);
+	if (info == NULL) {
+		egg_warning ("failed to get info: %s", error->message);
+		goto out;
+	}
+
+	/* check is executable */
+	ret = g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE);
+	if (!ret) {
+		egg_warning ("%s is not executable", filename);
+		goto out;
+	}
+
+	/* check is owned by the correct user */
+	file_uid = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_UID);
+	if (file_uid != 0) {
+		egg_warning ("%s is not owned by the root user", filename);
+		goto out;
+	}
+
+	/* format the argument list */
+	command = g_strdup_printf ("%s %s NOTAPISTABLE",
+				   filename,
+				   pk_role_enum_to_string (transaction->priv->role));
+
+	/* run the command, but don't exit if fails */
+	ret = g_spawn_command_line_sync (command, NULL, NULL, &exit_status, &error);
+	if (!ret) {
+		egg_warning ("failed to spawn %s [%i]: %s", command, exit_status, error->message);
+		g_error_free (error);
+	} else {
+		egg_debug ("ran %s", command);
+	}
+
+out:
+	g_free (command);
+	if (info != NULL)
+		g_object_unref (info);
+	if (file != NULL)
+		g_object_unref (file);
+}
+
+/**
+ * pk_transaction_process_scripts:
+ *
+ * Run all scripts in a given directory
+ **/
+static void
+pk_transaction_process_scripts (PkTransaction *transaction, const gchar *location)
+{
+	GError *error = NULL;
+	gchar *filename;
+	gchar *dirname;
+	const gchar *file;
+	GDir *dir;
+
+	/* get location to search */
+	dirname = g_build_filename (SYSCONFDIR, "PackageKit", "events", location, NULL);
+	dir = g_dir_open (dirname, 0, &error);
+	if (dir == NULL) {
+		egg_warning ("Failed to open %s: %s", dirname, error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* run scripts */
+	file = g_dir_read_name (dir);
+	while (file != NULL) {
+		filename = g_build_filename (dirname, file, NULL);
+
+		/* we put this here */
+		if (g_strcmp0 (file, "README") != 0) {
+			pk_transaction_process_script (transaction, filename);
+		}
+
+		g_free (filename);
+		file = g_dir_read_name (dir);
+	}
+out:
+	if (dir != NULL)
+		g_dir_close (dir);
+	g_free (dirname);
+}
+
+/**
  * pk_transaction_finished_cb:
  **/
 static void
@@ -845,6 +948,9 @@ pk_transaction_finished_cb (PkBackend *backend, PkExitEnum exit_enum, PkTransact
 		pk_transaction_extra_clear_firmware_requests (transaction->priv->transaction_extra);
 	}
 
+	/* do the post-transaction.d scripts */
+	pk_transaction_process_scripts (transaction, "post-transaction.d");
+
 	/* save this so we know if the cache is valid */
 	pk_results_set_exit_code (transaction->priv->results, exit_enum);
 
@@ -1861,6 +1967,9 @@ pk_transaction_run (PkTransaction *transaction)
 	g_return_val_if_fail (PK_IS_TRANSACTION (transaction), FALSE);
 	g_return_val_if_fail (transaction->priv->tid != NULL, FALSE);
 
+	/* do the pre-transaction.d scripts */
+	pk_transaction_process_scripts (transaction, "pre-transaction.d");
+
 	ret = pk_transaction_set_running (transaction);
 	return ret;
 }
commit ec903806d6e98bf50c64a63fb72ff0755feaea4d
Author: Jonathan Conder <jonno dot conder at gmail dot com>
Date:   Fri Sep 17 20:13:01 2010 +1200

    trivial: pacman: fix build with new backend API

diff --git a/backends/pacman/backend-pacman.c b/backends/pacman/backend-pacman.c
index 14147c6..09612e8 100644
--- a/backends/pacman/backend-pacman.c
+++ b/backends/pacman/backend-pacman.c
@@ -250,5 +250,7 @@ PK_BACKEND_OPTIONS (
 	backend_simulate_install_files,		/* simulate_install_files */
 	backend_simulate_install_packages,	/* simulate_install_packages */
 	backend_simulate_remove_packages,	/* simulate_remove_packages */
-	backend_simulate_update_packages	/* simulate_update_packages */
+	backend_simulate_update_packages,	/* simulate_update_packages */
+	NULL,					/* transaction_start */
+	NULL					/* transaction_stop */
 );
commit a1227392324437f59869ef312dff8017daed07db
Author: Hedayat Vatankhah <hedayat at grad.com>
Date:   Fri Sep 24 12:46:59 2010 +0330

    yum: select the repository with the higher priority when a package exists in serveral repositories

diff --git a/backends/yum/yumFilter.py b/backends/yum/yumFilter.py
index 11e48b6..94a4114 100644
--- a/backends/yum/yumFilter.py
+++ b/backends/yum/yumFilter.py
@@ -103,11 +103,16 @@ class YumFilter(PackagekitFilter):
             # we've already come across this package
             if key in newest:
 
-                # the current package is older (or the same) than the one we have stored
-                if pkg <= newest[key][0]:
+                # the current package is older version than the one we have stored
+                if pkg.verCMP(newest[key][0]) < 0:
                     continue
 
-                # the current package is newer than what we have stored, so nuke the old package
+                # the current package is the same version, but the repository has a lower priority
+                if pkg.verCMP(newest[key][0]) == 0 and \
+                   pkg.repo >= newest[key][0].repo:
+                    continue
+
+                # the current package is newer than what we have stored or the repository has a higher priority, so nuke the old package
                 del newest[key]
 
             newest[key] = (pkg, state)
commit 7c0620a32d83f3af2d73b409863b77917d1a3938
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 21 17:16:20 2010 +0100

    trivial: ensure we include gmodule.h for backends that don't depend on it explicitly

diff --git a/src/pk-backend.h b/src/pk-backend.h
index f5f720c..7c939b0 100644
--- a/src/pk-backend.h
+++ b/src/pk-backend.h
@@ -24,6 +24,7 @@
 
 #include <glib.h>
 #include <glib-object.h>
+#include <gmodule.h>
 
 /* these include the includes the backends should be using */
 #include <packagekit-glib2/pk-enum.h>
commit 10ab03423c892c06cd341e9629a5efb5050a7493
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 21 17:04:51 2010 +0100

    yum: Remove the table-of-vfuncs from the yum backend

diff --git a/backends/yum/pk-backend-yum.c b/backends/yum/pk-backend-yum.c
index 84ec83f..7e441ef 100644
--- a/backends/yum/pk-backend-yum.c
+++ b/backends/yum/pk-backend-yum.c
@@ -58,10 +58,29 @@ typedef struct {
 static PkBackendYumPrivate *priv;
 
 /**
- * backend_stderr_cb:
+ * pk_backend_get_description:
+ */
+gchar *
+pk_backend_get_description (PkBackend *backend)
+{
+	return g_strdup ("YUM (and optionally ZIF)");
+}
+
+/**
+ * pk_backend_get_author:
+ */
+gchar *
+pk_backend_get_author (PkBackend *backend)
+{
+	return g_strdup ("Tim Lauridsen <timlau at fedoraproject.org>, "
+			 "Richard Hughes <richard at hughsie.com>");
+}
+
+/**
+ * pk_backend_stderr_cb:
  */
 static gboolean
-backend_stderr_cb (PkBackend *backend, const gchar *output)
+pk_backend_stderr_cb (PkBackend *backend, const gchar *output)
 {
 	/* unsigned rpm, this will be picked up by yum and and exception will be thrown */
 	if (strstr (output, "NOKEY") != NULL)
@@ -74,19 +93,19 @@ backend_stderr_cb (PkBackend *backend, const gchar *output)
 }
 
 /**
- * backend_stdout_cb:
+ * pk_backend_stdout_cb:
  */
 static gboolean
-backend_stdout_cb (PkBackend *backend, const gchar *output)
+pk_backend_stdout_cb (PkBackend *backend, const gchar *output)
 {
 	return TRUE;
 }
 
 /**
- * backend_yum_repos_changed_cb:
+ * pk_backend_yum_repos_changed_cb:
  **/
 static void
-backend_yum_repos_changed_cb (GFileMonitor *monitor_, GFile *file, GFile *other_file, GFileMonitorEvent event_type, PkBackend *backend)
+pk_backend_yum_repos_changed_cb (GFileMonitor *monitor_, GFile *file, GFile *other_file, GFileMonitorEvent event_type, PkBackend *backend)
 {
 	gchar *filename;
 
@@ -104,22 +123,22 @@ out:
 #ifdef HAVE_ZIF
 
 static void
-backend_state_percentage_changed_cb (ZifState *state, guint percentage, PkBackend *backend)
+pk_backend_state_percentage_changed_cb (ZifState *state, guint percentage, PkBackend *backend)
 {
 	pk_backend_set_percentage (backend, percentage);
 }
 
 static void
-backend_state_subpercentage_changed_cb (ZifState *state, guint subpercentage, PkBackend *backend)
+pk_backend_state_subpercentage_changed_cb (ZifState *state, guint subpercentage, PkBackend *backend)
 {
 	pk_backend_set_sub_percentage (backend, subpercentage);
 }
 
 /**
- * backend_profile:
+ * pk_backend_profile:
  */
 static void
-backend_profile (const gchar *title)
+pk_backend_profile (const gchar *title)
 {
 	gdouble elapsed;
 
@@ -133,10 +152,10 @@ out:
 }
 
 /**
- * backend_is_all_installed:
+ * pk_backend_is_all_installed:
  */
 static gboolean
-backend_is_all_installed (gchar **package_ids)
+pk_backend_is_all_installed (gchar **package_ids)
 {
 	guint i;
 	gboolean ret = TRUE;
@@ -153,10 +172,10 @@ backend_is_all_installed (gchar **package_ids)
 #endif
 
 /**
- * backend_transaction_start:
+ * pk_backend_transaction_start:
  */
-static void
-backend_transaction_start (PkBackend *backend)
+void
+pk_backend_transaction_start (PkBackend *backend)
 {
 #ifdef HAVE_ZIF
 	gboolean ret = FALSE;
@@ -231,10 +250,10 @@ out:
 }
 
 /**
- * backend_transaction_stop:
+ * pk_backend_transaction_stop:
  */
-static void
-backend_transaction_stop (PkBackend *backend)
+void
+pk_backend_transaction_stop (PkBackend *backend)
 {
 #ifdef HAVE_ZIF
 	gboolean ret;
@@ -254,14 +273,14 @@ out:
 
 #ifdef HAVE_ZIF
 /**
- * backend_filter_package_array_newest:
+ * pk_backend_filter_package_array_newest:
  *
  * This function needs to scale well, and be fast to process 50,000 packages in
  * less than one second. If it looks overcomplicated, it's because it needs to
  * be O(n) not O(n*n).
  **/
 static gboolean
-backend_filter_package_array_newest (GPtrArray *array)
+pk_backend_filter_package_array_newest (GPtrArray *array)
 {
 	gchar **split;
 	const gchar *package_id;
@@ -315,10 +334,10 @@ backend_filter_package_array_newest (GPtrArray *array)
 }
 
 /**
- * backend_filter_package_array:
+ * pk_backend_filter_package_array:
  **/
 static GPtrArray *
-backend_filter_package_array (GPtrArray *array, PkBitfield filters)
+pk_backend_filter_package_array (GPtrArray *array, PkBitfield filters)
 {
 	guint i;
 	ZifPackage *package;
@@ -381,16 +400,16 @@ backend_filter_package_array (GPtrArray *array, PkBitfield filters)
 
 	/* do newest filtering */
 	if (pk_bitfield_contain (filters, PK_FILTER_ENUM_NEWEST))
-		backend_filter_package_array_newest (result);
+		pk_backend_filter_package_array_newest (result);
 
 	return result;
 }
 
 /**
- * backend_emit_package_array:
+ * pk_backend_emit_package_array:
  **/
 static gboolean
-backend_emit_package_array (PkBackend *backend, GPtrArray *array, ZifState *state)
+pk_backend_emit_package_array (PkBackend *backend, GPtrArray *array, ZifState *state)
 {
 	guint i;
 	gboolean installed;
@@ -425,10 +444,10 @@ backend_emit_package_array (PkBackend *backend, GPtrArray *array, ZifState *stat
 }
 
 /**
- * backend_error_handler_cb:
+ * pk_backend_error_handler_cb:
  */
 static gboolean
-backend_error_handler_cb (const GError *error, PkBackend *backend)
+pk_backend_error_handler_cb (const GError *error, PkBackend *backend)
 {
 	/* emit a warning, this isn't fatal */
 	pk_backend_message (backend, PK_MESSAGE_ENUM_BROKEN_MIRROR, "%s", error->message);
@@ -436,10 +455,10 @@ backend_error_handler_cb (const GError *error, PkBackend *backend)
 }
 
 /**
- * backend_get_default_store_array_for_filter:
+ * pk_backend_get_default_store_array_for_filter:
  */
 static GPtrArray *
-backend_get_default_store_array_for_filter (PkBackend *backend, PkBitfield filters, ZifState *state, GError **error)
+pk_backend_get_default_store_array_for_filter (PkBackend *backend, PkBitfield filters, ZifState *state, GError **error)
 {
 	GPtrArray *store_array;
 	ZifStore *store;
@@ -474,10 +493,10 @@ out:
 #endif
 
 /**
- * backend_search_thread:
+ * pk_backend_search_thread:
  */
 static gboolean
-backend_search_thread (PkBackend *backend)
+pk_backend_search_thread (PkBackend *backend)
 {
 #ifdef HAVE_ZIF
 	gboolean ret;
@@ -595,7 +614,7 @@ backend_search_thread (PkBackend *backend)
 
 	/* emit */
 	state_local = zif_state_get_child (priv->state);
-	backend_emit_package_array (backend, result, state_local);
+	pk_backend_emit_package_array (backend, result, state_local);
 
 	/* this section done */
 	ret = zif_state_done (priv->state, &error);
@@ -615,10 +634,10 @@ out:
 }
 
 /**
- * backend_enable_media_repo:
+ * pk_backend_enable_media_repo:
  */
 static void
-backend_enable_media_repo (gboolean enabled)
+pk_backend_enable_media_repo (gboolean enabled)
 {
 #ifdef HAVE_ZIF
 	ZifStoreRemote *repo = NULL;
@@ -684,10 +703,10 @@ out:
 }
 
 /**
- * backend_mount_add:
+ * pk_backend_mount_add:
  */
 static void
-backend_mount_add (GMount *mount, gpointer user_data)
+pk_backend_mount_add (GMount *mount, gpointer user_data)
 {
 	GFile *root;
 	GFile *repo;
@@ -725,34 +744,34 @@ out:
 }
 
 /**
- * backend_finished_cb:
+ * pk_backend_finished_cb:
  **/
 static void
-backend_finished_cb (PkBackend *backend, PkExitEnum exit_enum, gpointer user_data)
+pk_backend_finished_cb (PkBackend *backend, PkExitEnum exit_enum, gpointer user_data)
 {
 	/* disable media repo */
-	backend_enable_media_repo (FALSE);
+	pk_backend_enable_media_repo (FALSE);
 }
 
 /**
- * backend_status_changed_cb:
+ * pk_backend_status_changed_cb:
  **/
 static void
-backend_status_changed_cb (PkBackend *backend, PkStatusEnum status, gpointer user_data)
+pk_backend_status_changed_cb (PkBackend *backend, PkStatusEnum status, gpointer user_data)
 {
 	if (status != PK_STATUS_ENUM_WAIT)
 		return;
 
 	/* enable media repo */
-	backend_enable_media_repo (TRUE);
+	pk_backend_enable_media_repo (TRUE);
 }
 
 /**
- * backend_initialize:
+ * pk_backend_initialize:
  * This should only be run once per backend load, i.e. not every transaction
  */
-static void
-backend_initialize (PkBackend *backend)
+void
+pk_backend_initialize (PkBackend *backend)
 {
 	gboolean ret;
 	GFile *file = NULL;
@@ -767,22 +786,22 @@ backend_initialize (PkBackend *backend)
 	/* connect to finished, so we can clean up */
 	priv->signal_finished =
 		g_signal_connect (backend, "finished",
-				  G_CALLBACK (backend_finished_cb), NULL);
+				  G_CALLBACK (pk_backend_finished_cb), NULL);
 	priv->signal_status =
 		g_signal_connect (backend, "status-changed",
-				  G_CALLBACK (backend_status_changed_cb), NULL);
+				  G_CALLBACK (pk_backend_status_changed_cb), NULL);
 
 	egg_debug ("backend: initialize");
 	priv->spawn = pk_backend_spawn_new ();
-	pk_backend_spawn_set_filter_stderr (priv->spawn, backend_stderr_cb);
-	pk_backend_spawn_set_filter_stdout (priv->spawn, backend_stdout_cb);
+	pk_backend_spawn_set_filter_stderr (priv->spawn, pk_backend_stderr_cb);
+	pk_backend_spawn_set_filter_stdout (priv->spawn, pk_backend_stdout_cb);
 	pk_backend_spawn_set_name (priv->spawn, "yum");
 	pk_backend_spawn_set_allow_sigkill (priv->spawn, FALSE);
 
 	/* coldplug the mounts */
 	priv->volume_monitor = g_volume_monitor_get ();
 	mounts = g_volume_monitor_get_mounts (priv->volume_monitor);
-	g_list_foreach (mounts, (GFunc) backend_mount_add, NULL);
+	g_list_foreach (mounts, (GFunc) pk_backend_mount_add, NULL);
 	g_list_foreach (mounts, (GFunc) g_object_unref, NULL);
 	g_list_free (mounts);
 
@@ -790,7 +809,7 @@ backend_initialize (PkBackend *backend)
 	file = g_file_new_for_path (YUM_REPOS_DIRECTORY);
 	priv->monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, &error);
 	if (priv->monitor != NULL) {
-		g_signal_connect (priv->monitor, "changed", G_CALLBACK (backend_yum_repos_changed_cb), backend);
+		g_signal_connect (priv->monitor, "changed", G_CALLBACK (pk_backend_yum_repos_changed_cb), backend);
 	} else {
 		egg_warning ("failed to setup monitor: %s", error->message);
 		g_error_free (error);
@@ -820,15 +839,15 @@ backend_initialize (PkBackend *backend)
 	zif_init ();
 
 	/* profile */
-	backend_profile ("zif init");
+	pk_backend_profile ("zif init");
 
 	/* TODO: hook up errors */
 	priv->cancellable = g_cancellable_new ();
 
 	/* ZifState */
 	priv->state = zif_state_new ();
-	g_signal_connect (priv->state, "percentage-changed", G_CALLBACK (backend_state_percentage_changed_cb), backend);
-	g_signal_connect (priv->state, "subpercentage-changed", G_CALLBACK (backend_state_subpercentage_changed_cb), backend);
+	g_signal_connect (priv->state, "percentage-changed", G_CALLBACK (pk_backend_state_percentage_changed_cb), backend);
+	g_signal_connect (priv->state, "subpercentage-changed", G_CALLBACK (pk_backend_state_subpercentage_changed_cb), backend);
 
 	/* ZifConfig */
 	priv->config = zif_config_new ();
@@ -840,7 +859,7 @@ backend_initialize (PkBackend *backend)
 	}
 
 	/* profile */
-	backend_profile ("read config_file");
+	pk_backend_profile ("read config_file");
 
 	/* ZifDownload */
 	priv->download = zif_download_new ();
@@ -852,7 +871,7 @@ backend_initialize (PkBackend *backend)
 	priv->store_local = zif_store_local_new ();
 
 	/* profile */
-	backend_profile ("read local store");
+	pk_backend_profile ("read local store");
 
 	/* ZifRepos */
 	priv->repos = zif_repos_new ();
@@ -864,7 +883,7 @@ backend_initialize (PkBackend *backend)
 	}
 
 	/* profile */
-	backend_profile ("read repos");
+	pk_backend_profile ("read repos");
 
 	/* ZifGroups */
 	priv->groups = zif_groups_new ();
@@ -876,7 +895,7 @@ backend_initialize (PkBackend *backend)
 	}
 
 	/* profile */
-	backend_profile ("read groups");
+	pk_backend_profile ("read groups");
 #else
 	priv->use_zif = FALSE;
 #endif
@@ -889,11 +908,11 @@ out:
 }
 
 /**
- * backend_destroy:
+ * pk_backend_destroy:
  * This should only be run once per backend load, i.e. not every transaction
  */
-static void
-backend_destroy (PkBackend *backend)
+void
+pk_backend_destroy (PkBackend *backend)
 {
 	egg_debug ("backend: destroy");
 	g_object_unref (priv->spawn);
@@ -925,10 +944,10 @@ backend_destroy (PkBackend *backend)
 }
 
 /**
- * backend_get_groups:
+ * pk_backend_get_groups:
  */
-static PkBitfield
-backend_get_groups (PkBackend *backend)
+PkBitfield
+pk_backend_get_groups (PkBackend *backend)
 {
 #ifdef HAVE_ZIF
 	GError *error = NULL;
@@ -991,10 +1010,10 @@ out:
 }
 
 /**
- * backend_get_filters:
+ * pk_backend_get_filters:
  */
-static PkBitfield
-backend_get_filters (PkBackend *backend)
+PkBitfield
+pk_backend_get_filters (PkBackend *backend)
 {
 	return pk_bitfield_from_enums (
 		PK_FILTER_ENUM_GUI,
@@ -1008,10 +1027,10 @@ backend_get_filters (PkBackend *backend)
 }
 
 /**
- * backend_get_roles:
+ * pk_backend_get_roles:
  */
-static PkBitfield
-backend_get_roles (PkBackend *backend)
+PkBitfield
+pk_backend_get_roles (PkBackend *backend)
 {
 	PkBitfield roles;
 	roles = pk_bitfield_from_enums (
@@ -1055,10 +1074,10 @@ backend_get_roles (PkBackend *backend)
 }
 
 /**
- * backend_get_mime_types:
+ * pk_backend_get_mime_types:
  */
-static gchar *
-backend_get_mime_types (PkBackend *backend)
+gchar *
+pk_backend_get_mime_types (PkBackend *backend)
 {
 	return g_strdup ("application/x-rpm;application/x-servicepack");
 }
@@ -1066,8 +1085,8 @@ backend_get_mime_types (PkBackend *backend)
 /**
  * pk_backend_cancel:
  */
-static void
-backend_cancel (PkBackend *backend)
+void
+pk_backend_cancel (PkBackend *backend)
 {
 #ifdef HAVE_ZIF
 	/* try to cancel the thread first */
@@ -1078,10 +1097,10 @@ backend_cancel (PkBackend *backend)
 }
 
 /**
- * backend_download_packages_thread:
+ * pk_backend_download_packages_thread:
  */
 static gboolean
-backend_download_packages_thread (PkBackend *backend)
+pk_backend_download_packages_thread (PkBackend *backend)
 {
 #ifdef HAVE_ZIF
 	gchar **package_ids = pk_backend_get_strv (backend, "package_ids");
@@ -1210,10 +1229,10 @@ out:
 }
 
 /**
- * backend_download_packages:
+ * pk_backend_download_packages:
  */
-static void
-backend_download_packages (PkBackend *backend, gchar **package_ids, const gchar *directory)
+void
+pk_backend_download_packages (PkBackend *backend, gchar **package_ids, const gchar *directory)
 {
 	/* it seems some people are not ready for the awesomeness */
 	if (!priv->use_zif) {
@@ -1225,14 +1244,14 @@ backend_download_packages (PkBackend *backend, gchar **package_ids, const gchar
 		g_free (package_ids_temp);
 		return;
 	}
-	pk_backend_thread_create (backend, backend_download_packages_thread);
+	pk_backend_thread_create (backend, pk_backend_download_packages_thread);
 }
 
 /**
- * backend_get_depends_thread:
+ * pk_backend_get_depends_thread:
  */
 static gboolean
-backend_get_depends_thread (PkBackend *backend)
+pk_backend_get_depends_thread (PkBackend *backend)
 {
 #ifdef HAVE_ZIF
 	gboolean ret;
@@ -1377,7 +1396,7 @@ backend_get_depends_thread (PkBackend *backend)
 
 	/* emit */
 	state_local = zif_state_get_child (priv->state);
-	backend_emit_package_array (backend, result, state_local);
+	pk_backend_emit_package_array (backend, result, state_local);
 
 	/* this section done */
 	ret = zif_state_done (priv->state, &error);
@@ -1397,10 +1416,10 @@ out:
 }
 
 /**
- * backend_get_depends:
+ * pk_backend_get_depends:
  */
-static void
-backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
+void
+pk_backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	/* it seems some people are not ready for the awesomeness */
 	if (!priv->use_zif) {
@@ -1413,14 +1432,14 @@ backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids
 		g_free (package_ids_temp);
 		return;
 	}
-	pk_backend_thread_create (backend, backend_get_depends_thread);
+	pk_backend_thread_create (backend, pk_backend_get_depends_thread);
 }
 
 /**
- * backend_get_details_thread:
+ * pk_backend_get_details_thread:
  */
 static gboolean
-backend_get_details_thread (PkBackend *backend)
+pk_backend_get_details_thread (PkBackend *backend)
 {
 #ifdef HAVE_ZIF
 	gboolean ret;
@@ -1585,10 +1604,10 @@ out:
 }
 
 /**
- * backend_get_details:
+ * pk_backend_get_details:
  */
-static void
-backend_get_details (PkBackend *backend, gchar **package_ids)
+void
+pk_backend_get_details (PkBackend *backend, gchar **package_ids)
 {
 	/* check if we can use zif */
 	if (!priv->use_zif) {
@@ -1598,14 +1617,14 @@ backend_get_details (PkBackend *backend, gchar **package_ids)
 		g_free (package_ids_temp);
 		return;
 	}
-	pk_backend_thread_create (backend, backend_get_details_thread);
+	pk_backend_thread_create (backend, pk_backend_get_details_thread);
 }
 
 /**
-  * backend_get_distro_upgrades_thread:
+  * pk_backend_get_distro_upgrades_thread:
   */
 static gboolean
-backend_get_distro_upgrades_thread (PkBackend *backend)
+pk_backend_get_distro_upgrades_thread (PkBackend *backend)
 {
 #ifdef HAVE_ZIF
 	gboolean ret;
@@ -1720,10 +1739,10 @@ out:
 }
 
 /**
- * backend_get_distro_upgrades:
+ * pk_backend_get_distro_upgrades:
  */
-static void
-backend_get_distro_upgrades (PkBackend *backend)
+void
+pk_backend_get_distro_upgrades (PkBackend *backend)
 {
 	/* it seems some people are not ready for the awesomeness */
 	if (!priv->use_zif) {
@@ -1731,14 +1750,14 @@ backend_get_distro_upgrades (PkBackend *backend)
 		return;
 	}
 
-	pk_backend_thread_create (backend, backend_get_distro_upgrades_thread);
+	pk_backend_thread_create (backend, pk_backend_get_distro_upgrades_thread);
 }
 
 /**
- * backend_get_files_thread:
+ * pk_backend_get_files_thread:
  */
 static gboolean
-backend_get_files_thread (PkBackend *backend)
+pk_backend_get_files_thread (PkBackend *backend)
 {
 #ifdef HAVE_ZIF
 	gboolean ret;
@@ -1756,7 +1775,7 @@ backend_get_files_thread (PkBackend *backend)
 	PkBitfield filters = PK_FILTER_ENUM_UNKNOWN;
 
 	/* reset */
-	backend_profile (NULL);
+	pk_backend_profile (NULL);
 
 	len = g_strv_length (package_ids);
 
@@ -1774,7 +1793,7 @@ backend_get_files_thread (PkBackend *backend)
 	}
 
 	/* profile */
-	backend_profile ("add local");
+	pk_backend_profile ("add local");
 
 	/* this section done */
 	ret = zif_state_done (priv->state, &error);
@@ -1796,7 +1815,7 @@ backend_get_files_thread (PkBackend *backend)
 		}
 
 		/* profile */
-		backend_profile ("find package");
+		pk_backend_profile ("find package");
 
 		/* this section done */
 		ret = zif_state_done (priv->state, &error);
@@ -1816,7 +1835,7 @@ backend_get_files_thread (PkBackend *backend)
 		}
 
 		/* profile */
-		backend_profile ("get files");
+		pk_backend_profile ("get files");
 
 		files_str = g_string_new ("");
 		for (j=0; j<files->len; j++) {
@@ -1826,7 +1845,7 @@ backend_get_files_thread (PkBackend *backend)
 		pk_backend_files (backend, package_ids[i], files_str->str);
 
 		/* profile */
-		backend_profile ("emit files");
+		pk_backend_profile ("emit files");
 
 		/* this section done */
 		ret = zif_state_done (priv->state, &error);
@@ -1848,16 +1867,16 @@ out:
 }
 
 /**
- * backend_get_files:
+ * pk_backend_get_files:
  */
-static void
-backend_get_files (PkBackend *backend, gchar **package_ids)
+void
+pk_backend_get_files (PkBackend *backend, gchar **package_ids)
 {
 	gchar *package_ids_temp;
 
 	/* check if we can use zif */
 	if (priv->use_zif) {
-		pk_backend_thread_create (backend, backend_get_files_thread);
+		pk_backend_thread_create (backend, pk_backend_get_files_thread);
 		return;
 	}
 
@@ -1868,10 +1887,10 @@ backend_get_files (PkBackend *backend, gchar **package_ids)
 }
 
 /**
- * backend_get_requires:
+ * pk_backend_get_requires:
  */
-static void
-backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
+void
+pk_backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	gchar *package_ids_temp;
 	gchar *filters_text;
@@ -1883,10 +1902,10 @@ backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_id
 }
 
 /**
- * backend_get_updates_thread:
+ * pk_backend_get_updates_thread:
  */
 static gboolean
-backend_get_updates_thread (PkBackend *backend)
+pk_backend_get_updates_thread (PkBackend *backend)
 {
 #ifdef HAVE_ZIF
 	PkBitfield filters = (PkBitfield) pk_backend_get_uint (backend, "filters");
@@ -1906,7 +1925,7 @@ backend_get_updates_thread (PkBackend *backend)
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 
 	/* reset */
-	backend_profile (NULL);
+	pk_backend_profile (NULL);
 
 	zif_state_set_number_steps (priv->state, 5);
 
@@ -1929,7 +1948,7 @@ backend_get_updates_thread (PkBackend *backend)
 	}
 
 	/* profile */
-	backend_profile ("get remote stores");
+	pk_backend_profile ("get remote stores");
 
 	/* get all the installed packages */
 	state_local = zif_state_get_child (priv->state);
@@ -1950,7 +1969,7 @@ backend_get_updates_thread (PkBackend *backend)
 	}
 
 	/* profile */
-	backend_profile ("get installed packages");
+	pk_backend_profile ("get installed packages");
 
 	/* remove any packages that are not newest (think kernel) */
 	zif_package_array_filter_newest (packages);
@@ -1964,7 +1983,7 @@ backend_get_updates_thread (PkBackend *backend)
 	}
 
 	/* profile */
-	backend_profile ("filter installed newest");
+	pk_backend_profile ("filter installed newest");
 
 	/* get updates */
 	state_local = zif_state_get_child (priv->state);
@@ -1985,7 +2004,7 @@ backend_get_updates_thread (PkBackend *backend)
 	}
 
 	/* profile */
-	backend_profile ("get updates of packages");
+	pk_backend_profile ("get updates of packages");
 
 	/* setup steps on updatinfo state */
 	state_local = zif_state_get_child (priv->state);
@@ -2037,7 +2056,7 @@ backend_get_updates_thread (PkBackend *backend)
 	}
 
 	/* profile */
-	backend_profile ("get updateinfo");
+	pk_backend_profile ("get updateinfo");
 
 	/* filter */
 	result = backend_filter_package_array (array, filters);
@@ -2047,10 +2066,10 @@ backend_get_updates_thread (PkBackend *backend)
 
 	/* emit */
 	state_local = zif_state_get_child (priv->state);
-	backend_emit_package_array (backend, result, state_local);
+	pk_backend_emit_package_array (backend, result, state_local);
 
 	/* profile */
-	backend_profile ("filter and emit");
+	pk_backend_profile ("filter and emit");
 
 out:
 	pk_backend_finished (backend);
@@ -2067,10 +2086,10 @@ out:
 }
 
 /**
- * backend_get_updates:
+ * pk_backend_get_updates:
  */
-static void
-backend_get_updates (PkBackend *backend, PkBitfield filters)
+void
+pk_backend_get_updates (PkBackend *backend, PkBitfield filters)
 {
 	/* it seems some people are not ready for the awesomeness */
 	if (!priv->use_zif) {
@@ -2080,14 +2099,14 @@ backend_get_updates (PkBackend *backend, PkBitfield filters)
 		g_free (filters_text);
 		return;
 	}
-	pk_backend_thread_create (backend, backend_get_updates_thread);
+	pk_backend_thread_create (backend, pk_backend_get_updates_thread);
 }
 
 /**
- * backend_get_packages:
+ * pk_backend_get_packages:
  */
-static void
-backend_get_packages (PkBackend *backend, PkBitfield filters)
+void
+pk_backend_get_packages (PkBackend *backend, PkBitfield filters)
 {
 	/* it seems some people are not ready for the awesomeness */
 	if (!priv->use_zif) {
@@ -2097,15 +2116,15 @@ backend_get_packages (PkBackend *backend, PkBitfield filters)
 		g_free (filters_text);
 		return;
 	}
-	pk_backend_thread_create (backend, backend_search_thread);
+	pk_backend_thread_create (backend, pk_backend_search_thread);
 }
 
 #ifdef HAVE_ZIF
 /**
- * backend_get_changelog_text:
+ * pk_backend_get_changelog_text:
  */
 static gchar *
-backend_get_changelog_text (GPtrArray *changesets)
+pk_backend_get_changelog_text (GPtrArray *changesets)
 {
 	guint i;
 	ZifChangeset *changeset;
@@ -2136,10 +2155,10 @@ backend_get_changelog_text (GPtrArray *changesets)
 #endif
 
 /**
- * backend_get_update_detail_thread:
+ * pk_backend_get_update_detail_thread:
  */
 static gboolean
-backend_get_update_detail_thread (PkBackend *backend)
+pk_backend_get_update_detail_thread (PkBackend *backend)
 {
 #ifdef HAVE_ZIF
 	gchar **package_ids;
@@ -2152,7 +2171,7 @@ backend_get_update_detail_thread (PkBackend *backend)
 	GError *error = NULL;
 
 	/* reset */
-	backend_profile (NULL);
+	pk_backend_profile (NULL);
 
 	/* get the data */
 	package_ids = pk_backend_get_strv (backend, "package_ids");
@@ -2244,10 +2263,10 @@ out:
 }
 
 /**
- * backend_get_update_detail:
+ * pk_backend_get_update_detail:
  */
-static void
-backend_get_update_detail (PkBackend *backend, gchar **package_ids)
+void
+pk_backend_get_update_detail (PkBackend *backend, gchar **package_ids)
 {
 	/* it seems some people are not ready for the awesomeness */
 	if (TRUE || !priv->use_zif) {
@@ -2257,14 +2276,14 @@ backend_get_update_detail (PkBackend *backend, gchar **package_ids)
 		g_free (package_ids_temp);
 		return;
 	}
-	pk_backend_thread_create (backend, backend_get_update_detail_thread);
+	pk_backend_thread_create (backend, pk_backend_get_update_detail_thread);
 }
 
 /**
- * backend_install_packages:
+ * pk_backend_install_packages:
  */
-static void
-backend_install_packages (PkBackend *backend, gboolean only_trusted, gchar **package_ids)
+void
+pk_backend_install_packages (PkBackend *backend, gboolean only_trusted, gchar **package_ids)
 {
 	gchar *package_ids_temp;
 
@@ -2275,10 +2294,10 @@ backend_install_packages (PkBackend *backend, gboolean only_trusted, gchar **pac
 }
 
 /**
- * backend_simulate_remove_packages:
+ * pk_backend_simulate_remove_packages:
  */
-static void
-backend_simulate_remove_packages (PkBackend *backend, gchar **package_ids, gboolean autoremove)
+void
+pk_backend_simulate_remove_packages (PkBackend *backend, gchar **package_ids, gboolean autoremove)
 {
 	gchar *package_ids_temp;
 
@@ -2289,10 +2308,10 @@ backend_simulate_remove_packages (PkBackend *backend, gchar **package_ids, gbool
 }
 
 /**
- * backend_simulate_update_packages:
+ * pk_backend_simulate_update_packages:
  */
-static void
-backend_simulate_update_packages (PkBackend *backend, gchar **package_ids)
+void
+pk_backend_simulate_update_packages (PkBackend *backend, gchar **package_ids)
 {
 	gchar *package_ids_temp;
 
@@ -2303,10 +2322,10 @@ backend_simulate_update_packages (PkBackend *backend, gchar **package_ids)
 }
 
 /**
- * backend_simulate_install_packages:
+ * pk_backend_simulate_install_packages:
  */
-static void
-backend_simulate_install_packages (PkBackend *backend, gchar **package_ids)
+void
+pk_backend_simulate_install_packages (PkBackend *backend, gchar **package_ids)
 {
 	gchar *package_ids_temp;
 
@@ -2317,10 +2336,10 @@ backend_simulate_install_packages (PkBackend *backend, gchar **package_ids)
 }
 
 /**
- * backend_install_files:
+ * pk_backend_install_files:
  */
-static void
-backend_install_files (PkBackend *backend, gboolean only_trusted, gchar **full_paths)
+void
+pk_backend_install_files (PkBackend *backend, gboolean only_trusted, gchar **full_paths)
 {
 	gchar *package_ids_temp;
 
@@ -2331,10 +2350,10 @@ backend_install_files (PkBackend *backend, gboolean only_trusted, gchar **full_p
 }
 
 /**
- * backend_install_signature:
+ * pk_backend_install_signature:
  */
-static void
-backend_install_signature (PkBackend *backend, PkSigTypeEnum type,
+void
+pk_backend_install_signature (PkBackend *backend, PkSigTypeEnum type,
 			   const gchar *key_id, const gchar *package_id)
 {
 	const gchar *type_text;
@@ -2344,10 +2363,10 @@ backend_install_signature (PkBackend *backend, PkSigTypeEnum type,
 }
 
 /**
- * backend_refresh_cache_thread:
+ * pk_backend_refresh_cache_thread:
  */
 static gboolean
-backend_refresh_cache_thread (PkBackend *backend)
+pk_backend_refresh_cache_thread (PkBackend *backend)
 {
 #ifdef HAVE_ZIF
 	GPtrArray *store_array = NULL;
@@ -2403,10 +2422,10 @@ out:
 }
 
 /**
- * backend_refresh_cache:
+ * pk_backend_refresh_cache:
  */
-static void
-backend_refresh_cache (PkBackend *backend, gboolean force)
+void
+pk_backend_refresh_cache (PkBackend *backend, gboolean force)
 {
 	/* check network state */
 	if (!pk_backend_is_online (backend)) {
@@ -2420,14 +2439,14 @@ backend_refresh_cache (PkBackend *backend, gboolean force)
 		pk_backend_spawn_helper (priv->spawn, "yumBackend.py", "refresh-cache", pk_backend_bool_to_string (force), NULL);
 		return;
 	}
-	pk_backend_thread_create (backend, backend_refresh_cache_thread);
+	pk_backend_thread_create (backend, pk_backend_refresh_cache_thread);
 }
 
 /**
  * pk_backend_remove_packages:
  */
-static void
-backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow_deps, gboolean autoremove)
+void
+pk_backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow_deps, gboolean autoremove)
 {
 	gchar *package_ids_temp;
 
@@ -2440,8 +2459,8 @@ backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow
 /**
  * pk_backend_search_details:
  */
-static void
-backend_search_details (PkBackend *backend, PkBitfield filters, gchar **values)
+void
+pk_backend_search_details (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	/* it seems some people are not ready for the awesomeness */
 	if (!priv->use_zif) {
@@ -2454,14 +2473,14 @@ backend_search_details (PkBackend *backend, PkBitfield filters, gchar **values)
 		g_free (search);
 		return;
 	}
-	pk_backend_thread_create (backend, backend_search_thread);
+	pk_backend_thread_create (backend, pk_backend_search_thread);
 }
 
 /**
  * pk_backend_search_files:
  */
-static void
-backend_search_files (PkBackend *backend, PkBitfield filters, gchar **values)
+void
+pk_backend_search_files (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	/* it seems some people are not ready for the awesomeness */
 	if (!priv->use_zif) {
@@ -2474,14 +2493,14 @@ backend_search_files (PkBackend *backend, PkBitfield filters, gchar **values)
 		g_free (search);
 		return;
 	}
-	pk_backend_thread_create (backend, backend_search_thread);
+	pk_backend_thread_create (backend, pk_backend_search_thread);
 }
 
 /**
  * pk_backend_search_groups:
  */
-static void
-backend_search_groups (PkBackend *backend, PkBitfield filters, gchar **values)
+void
+pk_backend_search_groups (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	/* it seems some people are not ready for the awesomeness */
 	if (!priv->use_zif) {
@@ -2494,14 +2513,14 @@ backend_search_groups (PkBackend *backend, PkBitfield filters, gchar **values)
 		g_free (search);
 		return;
 	}
-	pk_backend_thread_create (backend, backend_search_thread);
+	pk_backend_thread_create (backend, pk_backend_search_thread);
 }
 
 /**
  * pk_backend_search_names:
  */
-static void
-backend_search_names (PkBackend *backend, PkBitfield filters, gchar **values)
+void
+pk_backend_search_names (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	/* it seems some people are not ready for the awesomeness */
 	if (!priv->use_zif) {
@@ -2514,14 +2533,14 @@ backend_search_names (PkBackend *backend, PkBitfield filters, gchar **values)
 		g_free (search);
 		return;
 	}
-	pk_backend_thread_create (backend, backend_search_thread);
+	pk_backend_thread_create (backend, pk_backend_search_thread);
 }
 
 /**
  * pk_backend_update_packages:
  */
-static void
-backend_update_packages (PkBackend *backend, gboolean only_trusted, gchar **package_ids)
+void
+pk_backend_update_packages (PkBackend *backend, gboolean only_trusted, gchar **package_ids)
 {
 	gchar *package_ids_temp;
 
@@ -2534,8 +2553,8 @@ backend_update_packages (PkBackend *backend, gboolean only_trusted, gchar **pack
 /**
  * pk_backend_update_system:
  */
-static void
-backend_update_system (PkBackend *backend, gboolean only_trusted)
+void
+pk_backend_update_system (PkBackend *backend, gboolean only_trusted)
 {
 	pk_backend_spawn_helper (priv->spawn, "yumBackend.py", "update-system", pk_backend_bool_to_string (only_trusted), NULL);
 }
@@ -2543,8 +2562,8 @@ backend_update_system (PkBackend *backend, gboolean only_trusted)
 /**
  * pk_backend_resolve:
  */
-static void
-backend_resolve (PkBackend *backend, PkBitfield filters, gchar **packages)
+void
+pk_backend_resolve (PkBackend *backend, PkBitfield filters, gchar **packages)
 {
 	/* it seems some people are not ready for the awesomeness */
 	if (!priv->use_zif) {
@@ -2558,14 +2577,14 @@ backend_resolve (PkBackend *backend, PkBitfield filters, gchar **packages)
 		return;
 	}
 	pk_backend_set_strv (backend, "search", packages);
-	pk_backend_thread_create (backend, backend_search_thread);
+	pk_backend_thread_create (backend, pk_backend_search_thread);
 }
 
 /**
- * backend_get_repo_list_thread:
+ * pk_backend_get_repo_list_thread:
  */
 static gboolean
-backend_get_repo_list_thread (PkBackend *backend)
+pk_backend_get_repo_list_thread (PkBackend *backend)
 {
 #ifdef HAVE_ZIF
 	gboolean ret;
@@ -2655,8 +2674,8 @@ out:
 /**
  * pk_backend_get_repo_list:
  */
-static void
-backend_get_repo_list (PkBackend *backend, PkBitfield filters)
+void
+pk_backend_get_repo_list (PkBackend *backend, PkBitfield filters)
 {
 	/* it seems some people are not ready for the awesomeness */
 	if (!priv->use_zif) {
@@ -2667,14 +2686,14 @@ backend_get_repo_list (PkBackend *backend, PkBitfield filters)
 		return;
 	}
 
-	pk_backend_thread_create (backend, backend_get_repo_list_thread);
+	pk_backend_thread_create (backend, pk_backend_get_repo_list_thread);
 }
 
 /**
- * backend_repo_enable_thread:
+ * pk_backend_repo_enable_thread:
  */
 static gboolean
-backend_repo_enable_thread (PkBackend *backend)
+pk_backend_repo_enable_thread (PkBackend *backend)
 {
 #ifdef HAVE_ZIF
 	ZifStoreRemote *repo = NULL;
@@ -2727,8 +2746,8 @@ out:
 /**
  * pk_backend_repo_enable:
  */
-static void
-backend_repo_enable (PkBackend *backend, const gchar *repo_id, gboolean enabled)
+void
+pk_backend_repo_enable (PkBackend *backend, const gchar *repo_id, gboolean enabled)
 {
 	/* it seems some people are not ready for the awesomeness */
 	if (!priv->use_zif) {
@@ -2739,24 +2758,24 @@ backend_repo_enable (PkBackend *backend, const gchar *repo_id, gboolean enabled)
 		}
 		return;
 	}
-	pk_backend_thread_create (backend, backend_repo_enable_thread);
+	pk_backend_thread_create (backend, pk_backend_repo_enable_thread);
 }
 
 /**
  * pk_backend_repo_set_data:
  */
-static void
-backend_repo_set_data (PkBackend *backend, const gchar *repo_id, const gchar *parameter, const gchar *value)
+void
+pk_backend_repo_set_data (PkBackend *backend, const gchar *repo_id, const gchar *parameter, const gchar *value)
 {
 	/* no operation */
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_what_provides:
+ * pk_backend_what_provides:
  */
-static void
-backend_what_provides (PkBackend *backend, PkBitfield filters, PkProvidesEnum provides, gchar **values)
+void
+pk_backend_what_provides (PkBackend *backend, PkBitfield filters, PkProvidesEnum provides, gchar **values)
 {
 	guint i;
 	guint len;
@@ -2806,16 +2825,16 @@ backend_what_provides (PkBackend *backend, PkBitfield filters, PkProvidesEnum pr
 	/* set the search terms and run */
 	search = pk_ptr_array_to_strv (array);
 	pk_backend_set_strv (backend, "search", search);
-	pk_backend_thread_create (backend, backend_search_thread);
+	pk_backend_thread_create (backend, pk_backend_search_thread);
 	g_strfreev (search);
 	g_ptr_array_unref (array);
 }
 
 /**
- * backend_get_categories_thread:
+ * pk_backend_get_categories_thread:
  */
 static gboolean
-backend_get_categories_thread (PkBackend *backend)
+pk_backend_get_categories_thread (PkBackend *backend)
 {
 #ifdef HAVE_ZIF
 	gboolean ret;
@@ -2905,22 +2924,22 @@ out:
 /**
  * pk_backend_get_categories:
  */
-static void
-backend_get_categories (PkBackend *backend)
+void
+pk_backend_get_categories (PkBackend *backend)
 {
 	/* it seems some people are not ready for the awesomeness */
 	if (!priv->use_zif) {
 		pk_backend_spawn_helper (priv->spawn, "yumBackend.py", "get-categories", NULL);
 		return;
 	}
-	pk_backend_thread_create (backend, backend_get_categories_thread);
+	pk_backend_thread_create (backend, pk_backend_get_categories_thread);
 }
 
 /**
- * backend_simulate_install_files:
+ * pk_backend_simulate_install_files:
  */
-static void
-backend_simulate_install_files (PkBackend *backend, gchar **full_paths)
+void
+pk_backend_simulate_install_files (PkBackend *backend, gchar **full_paths)
 {
 	gchar *package_ids_temp;
 
@@ -2929,50 +2948,3 @@ backend_simulate_install_files (PkBackend *backend, gchar **full_paths)
 	pk_backend_spawn_helper (priv->spawn, "yumBackend.py", "simulate-install-files", package_ids_temp, NULL);
 	g_free (package_ids_temp);
 }
-
-PK_BACKEND_OPTIONS (
-	"YUM",					/* description */
-	"Tim Lauridsen <timlau at fedoraproject.org>, "
-	"Richard Hughes <richard at hughsie.com>",	/* author */
-	backend_initialize,			/* initalize */
-	backend_destroy,			/* destroy */
-	backend_get_groups,			/* get_groups */
-	backend_get_filters,			/* get_filters */
-	backend_get_roles,			/* get_roles */
-	backend_get_mime_types,			/* get_mime_types */
-	backend_cancel,				/* cancel */
-	backend_download_packages,		/* download_packages */
-	backend_get_categories,			/* get_categories */
-	backend_get_depends,			/* get_depends */
-	backend_get_details,			/* get_details */
-	backend_get_distro_upgrades,		/* get_distro_upgrades */
-	backend_get_files,			/* get_files */
-	backend_get_packages,			/* get_packages */
-	backend_get_repo_list,			/* get_repo_list */
-	backend_get_requires,			/* get_requires */
-	backend_get_update_detail,		/* get_update_detail */
-	backend_get_updates,			/* get_updates */
-	backend_install_files,			/* install_files */
-	backend_install_packages,		/* install_packages */
-	backend_install_signature,		/* install_signature */
-	backend_refresh_cache,			/* refresh_cache */
-	backend_remove_packages,		/* remove_packages */
-	backend_repo_enable,			/* repo_enable */
-	backend_repo_set_data,			/* repo_set_data */
-	backend_resolve,			/* resolve */
-	NULL,					/* rollback */
-	backend_search_details,			/* search_details */
-	backend_search_files,			/* search_files */
-	backend_search_groups,			/* search_groups */
-	backend_search_names,			/* search_names */
-	backend_update_packages,		/* update_packages */
-	backend_update_system,			/* update_system */
-	backend_what_provides,			/* what_provides */
-	backend_simulate_install_files,		/* simulate_install_files */
-	backend_simulate_install_packages,	/* simulate_install_packages */
-	backend_simulate_remove_packages,	/* simulate_remove_packages */
-	backend_simulate_update_packages,	/* simulate_update_packages */
-	backend_transaction_start,		/* transaction_start */
-	backend_transaction_stop		/* transaction_stop */
-);
-
commit d3b1558ef1ce71068ac57638c55a1932c31c3cb9
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 21 17:04:04 2010 +0100

    dummy: Remove the table-of-vfuncs from the dummy backend

diff --git a/backends/dummy/pk-backend-dummy.c b/backends/dummy/pk-backend-dummy.c
index 3dc827c..bc7243d 100644
--- a/backends/dummy/pk-backend-dummy.c
+++ b/backends/dummy/pk-backend-dummy.c
@@ -49,27 +49,27 @@ static gboolean _use_distro_upgrade = FALSE;
 static PkBitfield _filters = 0;
 
 /**
- * backend_initialize:
+ * pk_backend_initialize:
  */
-static void
-backend_initialize (PkBackend *backend)
+void
+pk_backend_initialize (PkBackend *backend)
 {
 	_progress_percentage = 0;
 }
 
 /**
- * backend_destroy:
+ * pk_backend_destroy:
  */
-static void
-backend_destroy (PkBackend *backend)
+void
+pk_backend_destroy (PkBackend *backend)
 {
 }
 
 /**
- * backend_get_groups:
+ * pk_backend_get_groups:
  */
-static PkBitfield
-backend_get_groups (PkBackend *backend)
+PkBitfield
+pk_backend_get_groups (PkBackend *backend)
 {
 	return pk_bitfield_from_enums (PK_GROUP_ENUM_ACCESSIBILITY,
 		PK_GROUP_ENUM_GAMES,
@@ -78,10 +78,10 @@ backend_get_groups (PkBackend *backend)
 }
 
 /**
- * backend_get_filters:
+ * pk_backend_get_filters:
  */
-static PkBitfield
-backend_get_filters (PkBackend *backend)
+PkBitfield
+pk_backend_get_filters (PkBackend *backend)
 {
 	return pk_bitfield_from_enums (PK_FILTER_ENUM_GUI,
 		PK_FILTER_ENUM_INSTALLED,
@@ -90,19 +90,19 @@ backend_get_filters (PkBackend *backend)
 }
 
 /**
- * backend_get_mime_types:
+ * pk_backend_get_mime_types:
  */
-static gchar *
-backend_get_mime_types (PkBackend *backend)
+gchar *
+pk_backend_get_mime_types (PkBackend *backend)
 {
 	return g_strdup ("application/x-rpm;application/x-deb");
 }
 
 /**
- * backend_cancel_timeout:
+ * pk_backend_cancel_timeout:
  */
 static gboolean
-backend_cancel_timeout (gpointer data)
+pk_backend_cancel_timeout (gpointer data)
 {
 	PkBackend *backend = (PkBackend *) data;
 
@@ -117,25 +117,25 @@ backend_cancel_timeout (gpointer data)
 }
 
 /**
- * backend_cancel:
+ * pk_backend_cancel:
  */
-static void
-backend_cancel (PkBackend *backend)
+void
+pk_backend_cancel (PkBackend *backend)
 {
 	/* cancel the timeout */
 	if (_signal_timeout != 0) {
 		g_source_remove (_signal_timeout);
 
 		/* emulate that it takes us a few ms to cancel */
-		g_timeout_add (1500, backend_cancel_timeout, backend);
+		g_timeout_add (1500, pk_backend_cancel_timeout, backend);
 	}
 }
 
 /**
- * backend_get_depends:
+ * pk_backend_get_depends:
  */
-static void
-backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
+void
+pk_backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 
@@ -152,10 +152,10 @@ backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids
 }
 
 /**
- * backend_get_details:
+ * pk_backend_get_details:
  */
-static void
-backend_get_details (PkBackend *backend, gchar **package_ids)
+void
+pk_backend_get_details (PkBackend *backend, gchar **package_ids)
 {
 	guint i;
 	guint len;
@@ -210,10 +210,10 @@ backend_get_details (PkBackend *backend, gchar **package_ids)
 }
 
 /**
- * backend_get_distro_upgrades:
+ * pk_backend_get_distro_upgrades:
  */
-static void
-backend_get_distro_upgrades (PkBackend *backend)
+void
+pk_backend_get_distro_upgrades (PkBackend *backend)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	if (!_use_distro_upgrade)
@@ -227,10 +227,10 @@ out:
 }
 
 /**
- * backend_get_files:
+ * pk_backend_get_files:
  */
-static void
-backend_get_files (PkBackend *backend, gchar **package_ids)
+void
+pk_backend_get_files (PkBackend *backend, gchar **package_ids)
 {
 	guint i;
 	guint len;
@@ -254,10 +254,10 @@ backend_get_files (PkBackend *backend, gchar **package_ids)
 }
 
 /**
- * backend_get_requires:
+ * pk_backend_get_requires:
  */
-static void
-backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
+void
+pk_backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pk_backend_package (backend, PK_INFO_ENUM_INSTALLED,
@@ -268,10 +268,10 @@ backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_id
 }
 
 /**
- * backend_get_update_detail_timeout:
+ * pk_backend_get_update_detail_timeout:
  **/
 static gboolean
-backend_get_update_detail_timeout (gpointer data)
+pk_backend_get_update_detail_timeout (gpointer data)
 {
 	guint i;
 	guint len;
@@ -354,21 +354,21 @@ backend_get_update_detail_timeout (gpointer data)
 }
 
 /**
- * backend_get_update_detail:
+ * pk_backend_get_update_detail:
  */
-static void
-backend_get_update_detail (PkBackend *backend, gchar **package_ids)
+void
+pk_backend_get_update_detail (PkBackend *backend, gchar **package_ids)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	_package_ids = package_ids;
-	_signal_timeout = g_timeout_add (500, backend_get_update_detail_timeout, backend);
+	_signal_timeout = g_timeout_add (500, pk_backend_get_update_detail_timeout, backend);
 }
 
 /**
- * backend_get_updates_timeout:
+ * pk_backend_get_updates_timeout:
  **/
 static gboolean
-backend_get_updates_timeout (gpointer data)
+pk_backend_get_updates_timeout (gpointer data)
 {
 	PkBackend *backend = (PkBackend *) data;
 
@@ -400,10 +400,10 @@ backend_get_updates_timeout (gpointer data)
 }
 
 /**
- * backend_get_updates:
+ * pk_backend_get_updates:
  */
-static void
-backend_get_updates (PkBackend *backend, PkBitfield filters)
+void
+pk_backend_get_updates (PkBackend *backend, PkBitfield filters)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
@@ -413,11 +413,11 @@ backend_get_updates (PkBackend *backend, PkBitfield filters)
 		pk_backend_finished (backend);
 		return;
 	}
-	_signal_timeout = g_timeout_add (1000, backend_get_updates_timeout, backend);
+	_signal_timeout = g_timeout_add (1000, pk_backend_get_updates_timeout, backend);
 }
 
 static gboolean
-backend_install_timeout (gpointer data)
+pk_backend_install_timeout (gpointer data)
 {
 	PkBackend *backend = (PkBackend *) data;
 	guint sub_percent;
@@ -454,10 +454,10 @@ backend_install_timeout (gpointer data)
 }
 
 /**
- * backend_install_packages:
+ * pk_backend_install_packages:
  */
-static void
-backend_install_packages (PkBackend *backend, gboolean only_trusted, gchar **package_ids)
+void
+pk_backend_install_packages (PkBackend *backend, gboolean only_trusted, gchar **package_ids)
 {
 	const gchar *license_agreement;
 	const gchar *eula_id;
@@ -528,14 +528,14 @@ backend_install_packages (PkBackend *backend, gboolean only_trusted, gchar **pac
 	pk_backend_package (backend, PK_INFO_ENUM_DOWNLOADING,
 			    "gtkhtml2;2.19.1-4.fc8;i386;fedora",
 			    "An HTML widget for GTK+ 2.0");
-	_signal_timeout = g_timeout_add (100, backend_install_timeout, backend);
+	_signal_timeout = g_timeout_add (100, pk_backend_install_timeout, backend);
 }
 
 /**
- * backend_install_signature:
+ * pk_backend_install_signature:
  */
-static void
-backend_install_signature (PkBackend *backend, PkSigTypeEnum type,
+void
+pk_backend_install_signature (PkBackend *backend, PkSigTypeEnum type,
 			   const gchar *key_id, const gchar *package_id)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_INSTALL);
@@ -553,10 +553,10 @@ backend_install_signature (PkBackend *backend, PkSigTypeEnum type,
 }
 
 /**
- * backend_refresh_cache_timeout:
+ * pk_backend_refresh_cache_timeout:
  */
 static gboolean
-backend_install_files_timeout (gpointer data)
+pk_backend_install_files_timeout (gpointer data)
 {
 	PkBackend *backend = (PkBackend *) data;
 	pk_backend_finished (backend);
@@ -564,21 +564,21 @@ backend_install_files_timeout (gpointer data)
 }
 
 /**
- * backend_install_files:
+ * pk_backend_install_files:
  */
-static void
-backend_install_files (PkBackend *backend, gboolean only_trusted, gchar **full_paths)
+void
+pk_backend_install_files (PkBackend *backend, gboolean only_trusted, gchar **full_paths)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_INSTALL);
 	pk_backend_set_percentage (backend, 101);
-	_signal_timeout = g_timeout_add (2000, backend_install_files_timeout, backend);
+	_signal_timeout = g_timeout_add (2000, pk_backend_install_files_timeout, backend);
 }
 
 /**
- * backend_refresh_cache_timeout:
+ * pk_backend_refresh_cache_timeout:
  */
 static gboolean
-backend_refresh_cache_timeout (gpointer data)
+pk_backend_refresh_cache_timeout (gpointer data)
 {
 	PkBackend *backend = (PkBackend *) data;
 	if (_progress_percentage == 100) {
@@ -593,10 +593,10 @@ backend_refresh_cache_timeout (gpointer data)
 }
 
 /**
- * backend_refresh_cache:
+ * pk_backend_refresh_cache:
  */
-static void
-backend_refresh_cache (PkBackend *backend, gboolean force)
+void
+pk_backend_refresh_cache (PkBackend *backend, gboolean force)
 {
 	_progress_percentage = 0;
 
@@ -607,14 +607,14 @@ backend_refresh_cache (PkBackend *backend, gboolean force)
 
 	pk_backend_set_allow_cancel (backend, TRUE);
 	pk_backend_set_status (backend, PK_STATUS_ENUM_REFRESH_CACHE);
-	_signal_timeout = g_timeout_add (500, backend_refresh_cache_timeout, backend);
+	_signal_timeout = g_timeout_add (500, pk_backend_refresh_cache_timeout, backend);
 }
 
 /**
- * backend_resolve_timeout:
+ * pk_backend_resolve_timeout:
  */
 static gboolean
-backend_resolve_timeout (gpointer data)
+pk_backend_resolve_timeout (gpointer data)
 {
 	PkBackend *backend = (PkBackend *) data;
 	guint i;
@@ -655,21 +655,21 @@ backend_resolve_timeout (gpointer data)
 }
 
 /**
- * backend_resolve:
+ * pk_backend_resolve:
  */
-static void
-backend_resolve (PkBackend *backend, PkBitfield filters, gchar **packages)
+void
+pk_backend_resolve (PkBackend *backend, PkBitfield filters, gchar **packages)
 {
 	_filters = filters;
 	_package_ids = packages;
-	_signal_timeout = g_timeout_add (20, backend_resolve_timeout, backend);
+	_signal_timeout = g_timeout_add (20, pk_backend_resolve_timeout, backend);
 }
 
 /**
- * backend_rollback_timeout:
+ * pk_backend_rollback_timeout:
  */
 static gboolean
-backend_rollback_timeout (gpointer data)
+pk_backend_rollback_timeout (gpointer data)
 {
 	PkBackend *backend = (PkBackend *) data;
 	if (_progress_percentage == 0) {
@@ -691,10 +691,10 @@ backend_rollback_timeout (gpointer data)
 
 
 /**
- * backend_rollback:
+ * pk_backend_rollback:
  */
-static void
-backend_rollback (PkBackend *backend, const gchar *transaction_id)
+void
+pk_backend_rollback (PkBackend *backend, const gchar *transaction_id)
 {
 	/* allow testing error condition */
 	if (g_strcmp0 (transaction_id, "/397_eeecadad_data") == 0) {
@@ -706,14 +706,14 @@ backend_rollback (PkBackend *backend, const gchar *transaction_id)
 	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 	pk_backend_set_allow_cancel (backend, TRUE);
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
-	_signal_timeout = g_timeout_add (2000, backend_rollback_timeout, backend);
+	_signal_timeout = g_timeout_add (2000, pk_backend_rollback_timeout, backend);
 }
 
 /**
- * backend_remove_packages:
+ * pk_backend_remove_packages:
  */
-static void
-backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow_deps, gboolean autoremove)
+void
+pk_backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow_deps, gboolean autoremove)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_REMOVE);
 	pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "No network connection available");
@@ -721,10 +721,10 @@ backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow
 }
 
 /**
- * backend_search_details:
+ * pk_backend_search_details:
  */
-static void
-backend_search_details (PkBackend *backend, PkBitfield filters, gchar **values)
+void
+pk_backend_search_details (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pk_backend_set_allow_cancel (backend, TRUE);
@@ -735,10 +735,10 @@ backend_search_details (PkBackend *backend, PkBitfield filters, gchar **values)
 }
 
 /**
- * backend_search_files:
+ * pk_backend_search_files:
  */
-static void
-backend_search_files (PkBackend *backend, PkBitfield filters, gchar **values)
+void
+pk_backend_search_files (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pk_backend_set_allow_cancel (backend, TRUE);
@@ -754,10 +754,10 @@ backend_search_files (PkBackend *backend, PkBitfield filters, gchar **values)
 }
 
 /**
- * backend_search_groups:
+ * pk_backend_search_groups:
  */
-static void
-backend_search_groups (PkBackend *backend, PkBitfield filters, gchar **values)
+void
+pk_backend_search_groups (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pk_backend_set_allow_cancel (backend, TRUE);
@@ -771,10 +771,10 @@ backend_search_groups (PkBackend *backend, PkBitfield filters, gchar **values)
 }
 
 /**
- * backend_search_name_timeout:
+ * pk_backend_search_name_timeout:
  **/
 static gboolean
-backend_search_name_timeout (gpointer data)
+pk_backend_search_name_timeout (gpointer data)
 {
 	gchar *locale;
 	PkBackend *backend = (PkBackend *) data;
@@ -804,22 +804,22 @@ backend_search_name_timeout (gpointer data)
 }
 
 /**
- * backend_search_names:
+ * pk_backend_search_names:
  */
-static void
-backend_search_names (PkBackend *backend, PkBitfield filters, gchar **values)
+void
+pk_backend_search_names (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 	pk_backend_set_allow_cancel (backend, TRUE);
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
-	_signal_timeout = g_timeout_add (2000, backend_search_name_timeout, backend);
+	_signal_timeout = g_timeout_add (2000, pk_backend_search_name_timeout, backend);
 }
 
 /**
- * backend_update_packages_download_timeout:
+ * pk_backend_update_packages_download_timeout:
  **/
 static gboolean
-backend_update_packages_download_timeout (gpointer data)
+pk_backend_update_packages_download_timeout (gpointer data)
 {
 	PkBackend *backend = (PkBackend *) data;
 	guint sub;
@@ -897,10 +897,10 @@ backend_update_packages_download_timeout (gpointer data)
 }
 
 /**
- * backend_update_packages:
+ * pk_backend_update_packages:
  */
-static void
-backend_update_packages (PkBackend *backend, gboolean only_trusted, gchar **package_ids)
+void
+pk_backend_update_packages (PkBackend *backend, gboolean only_trusted, gchar **package_ids)
 {
 	const gchar *eula_id;
 	const gchar *license_agreement;
@@ -955,11 +955,11 @@ backend_update_packages (PkBackend *backend, gboolean only_trusted, gchar **pack
 	pk_backend_set_allow_cancel (backend, TRUE);
 	pk_backend_set_percentage (backend, 0);
 	pk_backend_set_status (backend, PK_STATUS_ENUM_DOWNLOAD);
-	_signal_timeout = g_timeout_add (200, backend_update_packages_download_timeout, backend);
+	_signal_timeout = g_timeout_add (200, pk_backend_update_packages_download_timeout, backend);
 }
 
 static gboolean
-backend_update_system_timeout (gpointer data)
+pk_backend_update_system_timeout (gpointer data)
 {
 	PkBackend *backend = (PkBackend *) data;
 	if (_progress_percentage == 100) {
@@ -1020,10 +1020,10 @@ backend_update_system_timeout (gpointer data)
 }
 
 /**
- * backend_update_system:
+ * pk_backend_update_system:
  */
-static void
-backend_update_system (PkBackend *backend, gboolean only_trusted)
+void
+pk_backend_update_system (PkBackend *backend, gboolean only_trusted)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_DOWNLOAD);
 	pk_backend_set_allow_cancel (backend, TRUE);
@@ -1032,14 +1032,14 @@ backend_update_system (PkBackend *backend, gboolean only_trusted)
 	/* FIXME: support only_trusted */
 
 	pk_backend_require_restart (backend, PK_RESTART_ENUM_SYSTEM, "kernel;2.6.23-0.115.rc3.git1.fc8;i386;installed");
-	_signal_timeout = g_timeout_add (100, backend_update_system_timeout, backend);
+	_signal_timeout = g_timeout_add (100, pk_backend_update_system_timeout, backend);
 }
 
 /**
- * backend_get_repo_list:
+ * pk_backend_get_repo_list:
  */
-static void
-backend_get_repo_list (PkBackend *backend, PkBitfield filters)
+void
+pk_backend_get_repo_list (PkBackend *backend, PkBitfield filters)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pk_backend_repo_detail (backend, "fedora",
@@ -1054,10 +1054,10 @@ backend_get_repo_list (PkBackend *backend, PkBitfield filters)
 }
 
 /**
- * backend_repo_enable:
+ * pk_backend_repo_enable:
  */
-static void
-backend_repo_enable (PkBackend *backend, const gchar *rid, gboolean enabled)
+void
+pk_backend_repo_enable (PkBackend *backend, const gchar *rid, gboolean enabled)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_REQUEST);
 
@@ -1080,10 +1080,10 @@ backend_repo_enable (PkBackend *backend, const gchar *rid, gboolean enabled)
 }
 
 /**
- * backend_repo_set_data:
+ * pk_backend_repo_set_data:
  */
-static void
-backend_repo_set_data (PkBackend *backend, const gchar *rid, const gchar *parameter, const gchar *value)
+void
+pk_backend_repo_set_data (PkBackend *backend, const gchar *rid, const gchar *parameter, const gchar *value)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_REQUEST);
 	egg_warning ("REPO '%s' PARAMETER '%s' TO '%s'", rid, parameter, value);
@@ -1106,10 +1106,10 @@ backend_repo_set_data (PkBackend *backend, const gchar *rid, const gchar *parame
 }
 
 /**
- * backend_what_provides_timeout:
+ * pk_backend_what_provides_timeout:
  */
 static gboolean
-backend_what_provides_timeout (gpointer data)
+pk_backend_what_provides_timeout (gpointer data)
 {
 	PkBackend *backend = (PkBackend *) data;
 	if (_progress_percentage == 100) {
@@ -1145,14 +1145,14 @@ backend_what_provides_timeout (gpointer data)
 }
 
 /**
- * backend_what_provides:
+ * pk_backend_what_provides:
  */
-static void
-backend_what_provides (PkBackend *backend, PkBitfield filters, PkProvidesEnum provides, gchar **values)
+void
+pk_backend_what_provides (PkBackend *backend, PkBitfield filters, PkProvidesEnum provides, gchar **values)
 {
 	_progress_percentage = 0;
 	_values = values;
-	_signal_timeout = g_timeout_add (200, backend_what_provides_timeout, backend);
+	_signal_timeout = g_timeout_add (200, pk_backend_what_provides_timeout, backend);
 	_filters = filters;
 	pk_backend_set_status (backend, PK_STATUS_ENUM_REQUEST);
 	pk_backend_set_allow_cancel (backend, TRUE);
@@ -1160,10 +1160,10 @@ backend_what_provides (PkBackend *backend, PkBitfield filters, PkProvidesEnum pr
 }
 
 /**
- * backend_get_packages:
+ * pk_backend_get_packages:
  */
-static void
-backend_get_packages (PkBackend *backend, PkBitfield filters)
+void
+pk_backend_get_packages (PkBackend *backend, PkBitfield filters)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_REQUEST);
 	pk_backend_package (backend, PK_INFO_ENUM_INSTALLED,
@@ -1173,10 +1173,10 @@ backend_get_packages (PkBackend *backend, PkBitfield filters)
 }
 
 /**
- * backend_download_packages:
+ * pk_backend_download_packages:
  */
-static void
-backend_download_packages (PkBackend *backend, gchar **package_ids, const gchar *directory)
+void
+pk_backend_download_packages (PkBackend *backend, gchar **package_ids, const gchar *directory)
 {
 	gchar *filename;
 
@@ -1202,10 +1202,10 @@ backend_download_packages (PkBackend *backend, gchar **package_ids, const gchar
 }
 
 /**
- * backend_simulate_install_packages:
+ * pk_backend_simulate_install_packages:
  */
-static void
-backend_simulate_install_packages (PkBackend *backend, gchar **package_ids)
+void
+pk_backend_simulate_install_packages (PkBackend *backend, gchar **package_ids)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_DEP_RESOLVE);
 
@@ -1237,10 +1237,10 @@ backend_simulate_install_packages (PkBackend *backend, gchar **package_ids)
 }
 
 /**
- * backend_transaction_start:
+ * pk_backend_transaction_start:
  */
-static void
-backend_transaction_start (PkBackend *backend)
+void
+pk_backend_transaction_start (PkBackend *backend)
 {
 	/* here you would lock the backend */
 	pk_backend_message (backend, PK_MESSAGE_ENUM_AUTOREMOVE_IGNORED, "backend is crap");
@@ -1249,10 +1249,10 @@ backend_transaction_start (PkBackend *backend)
 }
 
 /**
- * backend_transaction_stop:
+ * pk_backend_transaction_stop:
  */
-static void
-backend_transaction_stop (PkBackend *backend)
+void
+pk_backend_transaction_stop (PkBackend *backend)
 {
 	/* here you would unlock the backend */
 	pk_backend_message (backend, PK_MESSAGE_ENUM_CONFIG_FILES_CHANGED, "backend is crap");
@@ -1265,48 +1265,20 @@ backend_transaction_stop (PkBackend *backend)
 	 * needed to fire the transaction_stop() vfunc */
 }
 
-PK_BACKEND_OPTIONS (
-	"Dummy",				/* description */
-	"Richard Hughes <richard at hughsie.com>",	/* author */
-	backend_initialize,			/* initalize */
-	backend_destroy,			/* destroy */
-	backend_get_groups,			/* get_groups */
-	backend_get_filters,			/* get_filters */
-	NULL,					/* get_roles */
-	backend_get_mime_types,			/* get_mime_types */
-	backend_cancel,				/* cancel */
-	backend_download_packages,		/* download_packages */
-	NULL,					/* get_categories */
-	backend_get_depends,			/* get_depends */
-	backend_get_details,			/* get_details */
-	backend_get_distro_upgrades,		/* get_distro_upgrades */
-	backend_get_files,			/* get_files */
-	backend_get_packages,			/* get_packages */
-	backend_get_repo_list,			/* get_repo_list */
-	backend_get_requires,			/* get_requires */
-	backend_get_update_detail,		/* get_update_detail */
-	backend_get_updates,			/* get_updates */
-	backend_install_files,			/* install_files */
-	backend_install_packages,		/* install_packages */
-	backend_install_signature,		/* install_signature */
-	backend_refresh_cache,			/* refresh_cache */
-	backend_remove_packages,		/* remove_packages */
-	backend_repo_enable,			/* repo_enable */
-	backend_repo_set_data,			/* repo_set_data */
-	backend_resolve,			/* resolve */
-	backend_rollback,			/* rollback */
-	backend_search_details,			/* search_details */
-	backend_search_files,			/* search_files */
-	backend_search_groups,			/* search_groups */
-	backend_search_names,			/* search_names */
-	backend_update_packages,		/* update_packages */
-	backend_update_system,			/* update_system */
-	backend_what_provides,			/* what_provides */
-	NULL,					/* simulate_install_files */
-	backend_simulate_install_packages,	/* simulate_install_packages */
-	NULL,					/* simulate_remove_packages */
-	NULL,					/* simulate_update_packages */
-	backend_transaction_start,		/* transaction_start */
-	backend_transaction_stop		/* transaction_stop */
-);
+/**
+ * pk_backend_get_description:
+ */
+gchar *
+pk_backend_get_description (PkBackend *backend)
+{
+	return g_strdup ("Dummy");
+}
 
+/**
+ * pk_backend_get_author:
+ */
+gchar *
+pk_backend_get_author (PkBackend *backend)
+{
+	return g_strdup ("Richard Hughes <richard at hughsie.com>");
+}
commit 03f623c7608eedbd948664af205d1a0eab2a8ead
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 21 17:03:02 2010 +0100

    test: Remove the table-of-vfuncs from the test backends

diff --git a/backends/test/pk-backend-test-fail.c b/backends/test/pk-backend-test-fail.c
index 6085a0d..fb4ee2c 100644
--- a/backends/test/pk-backend-test-fail.c
+++ b/backends/test/pk-backend-test-fail.c
@@ -25,30 +25,39 @@
 #include <pk-backend.h>
 
 /**
- * backend_initialize:
+ * pk_backend_get_description:
  */
-static void
-backend_initialize (PkBackend *backend)
+gchar *
+pk_backend_get_description (PkBackend *backend)
+{
+	return g_strdup ("Test Fail");
+}
+
+/**
+ * pk_backend_initialize:
+ */
+void
+pk_backend_initialize (PkBackend *backend)
 {
 	pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR,
 			       "Failed to initialize package manager");
 }
 
 /**
- * backend_destroy:
+ * pk_backend_destroy:
  */
-static void
-backend_destroy (PkBackend *backend)
+void
+pk_backend_destroy (PkBackend *backend)
 {
 	pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR,
 			       "Failed to release control");
 }
 
 /**
- * backend_get_groups:
+ * pk_backend_get_groups:
  */
-static PkBitfield
-backend_get_groups (PkBackend *backend)
+PkBitfield
+pk_backend_get_groups (PkBackend *backend)
 {
 	return pk_bitfield_from_enums (
 		PK_GROUP_ENUM_ACCESSIBILITY,
@@ -58,10 +67,10 @@ backend_get_groups (PkBackend *backend)
 }
 
 /**
- * backend_get_filters:
+ * pk_backend_get_filters:
  */
-static PkBitfield
-backend_get_filters (PkBackend *backend)
+PkBitfield
+pk_backend_get_filters (PkBackend *backend)
 {
 	return pk_bitfield_from_enums (
 		PK_FILTER_ENUM_GUI,
@@ -71,136 +80,136 @@ backend_get_filters (PkBackend *backend)
 }
 
 /**
- * backend_cancel:
+ * pk_backend_cancel:
  */
-static void
-backend_cancel (PkBackend *backend)
+void
+pk_backend_cancel (PkBackend *backend)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_get_depends:
+ * pk_backend_get_depends:
  */
-static void
-backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
+void
+pk_backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_get_details:
+ * pk_backend_get_details:
  */
-static void
-backend_get_details (PkBackend *backend, gchar **package_ids)
+void
+pk_backend_get_details (PkBackend *backend, gchar **package_ids)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_get_files:
+ * pk_backend_get_files:
  */
-static void
-backend_get_files (PkBackend *backend, gchar **package_ids)
+void
+pk_backend_get_files (PkBackend *backend, gchar **package_ids)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_get_requires:
+ * pk_backend_get_requires:
  */
-static void
-backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
+void
+pk_backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_get_update_detail:
+ * pk_backend_get_update_detail:
  */
-static void
-backend_get_update_detail (PkBackend *backend, gchar **package_ids)
+void
+pk_backend_get_update_detail (PkBackend *backend, gchar **package_ids)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_get_updates:
+ * pk_backend_get_updates:
  */
-static void
-backend_get_updates (PkBackend *backend, PkBitfield filters)
+void
+pk_backend_get_updates (PkBackend *backend, PkBitfield filters)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_install_packages:
+ * pk_backend_install_packages:
  */
-static void
-backend_install_packages (PkBackend *backend, gboolean only_trusted, gchar **package_ids)
+void
+pk_backend_install_packages (PkBackend *backend, gboolean only_trusted, gchar **package_ids)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_install_files:
+ * pk_backend_install_files:
  */
-static void
-backend_install_files (PkBackend *backend, gboolean only_trusted, gchar **full_paths)
+void
+pk_backend_install_files (PkBackend *backend, gboolean only_trusted, gchar **full_paths)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_refresh_cache:
+ * pk_backend_refresh_cache:
  */
-static void
-backend_refresh_cache (PkBackend *backend, gboolean force)
+void
+pk_backend_refresh_cache (PkBackend *backend, gboolean force)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_remove_packages:
+ * pk_backend_remove_packages:
  */
-static void
-backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow_deps, gboolean autoremove)
+void
+pk_backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow_deps, gboolean autoremove)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_resolve:
+ * pk_backend_resolve:
  */
-static void
-backend_resolve (PkBackend *backend, PkBitfield filters, gchar **package_ids)
+void
+pk_backend_resolve (PkBackend *backend, PkBitfield filters, gchar **package_ids)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_rollback:
+ * pk_backend_rollback:
  */
-static void
-backend_rollback (PkBackend *backend, const gchar *transaction_id)
+void
+pk_backend_rollback (PkBackend *backend, const gchar *transaction_id)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_search_details:
+ * pk_backend_search_details:
  */
-static void
-backend_search_details (PkBackend *backend, PkBitfield filters, gchar **values)
+void
+pk_backend_search_details (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_search_files:
+ * pk_backend_search_files:
  */
-static void
-backend_search_files (PkBackend *backend, PkBitfield filters, gchar **values)
+void
+pk_backend_search_files (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR,
 			       "Error number 1");
@@ -210,19 +219,19 @@ backend_search_files (PkBackend *backend, PkBitfield filters, gchar **values)
 }
 
 /**
- * backend_search_groups:
+ * pk_backend_search_groups:
  */
-static void
-backend_search_groups (PkBackend *backend, PkBitfield filters, gchar **values)
+void
+pk_backend_search_groups (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_search_names:
+ * pk_backend_search_names:
  */
-static void
-backend_search_names (PkBackend *backend, PkBitfield filters, gchar **values)
+void
+pk_backend_search_names (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR,
 			       "Error number 1");
@@ -230,65 +239,19 @@ backend_search_names (PkBackend *backend, PkBitfield filters, gchar **values)
 }
 
 /**
- * backend_update_packages:
+ * pk_backend_update_packages:
  */
-static void
-backend_update_packages (PkBackend *backend, gboolean only_trusted, gchar **package_ids)
+void
+pk_backend_update_packages (PkBackend *backend, gboolean only_trusted, gchar **package_ids)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_update_system:
+ * pk_backend_update_system:
  */
-static void
-backend_update_system (PkBackend *backend, gboolean only_trusted)
+void
+pk_backend_update_system (PkBackend *backend, gboolean only_trusted)
 {
 	pk_backend_finished (backend);
 }
-
-PK_BACKEND_OPTIONS (
-	"Test Fail",				/* description */
-	"Richard Hughes <richard at hughsie.com>",	/* author */
-	backend_initialize,			/* initialize */
-	backend_destroy,			/* destroy */
-	backend_get_groups,			/* get_groups */
-	backend_get_filters,			/* get_filters */
-	NULL,					/* get_roles */
-	NULL,					/* get_mime_types */
-	backend_cancel,				/* cancel */
-	NULL,					/* download_packages */
-	NULL,					/* get_categories */
-	backend_get_depends,			/* get_depends */
-	backend_get_details,			/* get_details */
-	NULL,					/* get_distro_upgrades */
-	backend_get_files,			/* get_files */
-	NULL,					/* get_packages */
-	NULL,					/* get_repo_list */
-	backend_get_requires,			/* get_requires */
-	backend_get_update_detail,		/* get_update_detail */
-	backend_get_updates,			/* get_updates */
-	backend_install_files,			/* install_files */
-	backend_install_packages,		/* install_packages */
-	NULL,					/* install_signature */
-	backend_refresh_cache,			/* refresh_cache */
-	backend_remove_packages,		/* remove_packages */
-	NULL,					/* repo_enable */
-	NULL,					/* repo_set_data */
-	backend_resolve,			/* resolve */
-	backend_rollback,			/* rollback */
-	backend_search_details,			/* search_details */
-	backend_search_files,			/* search_files */
-	backend_search_groups,			/* search_groups */
-	backend_search_names,			/* search_names */
-	backend_update_packages,		/* update_packages */
-	backend_update_system,			/* update_system */
-	NULL,					/* what_provides */
-	NULL,					/* simulate_install_files */
-	NULL,					/* simulate_install_packages */
-	NULL,					/* simulate_remove_packages */
-	NULL,					/* simulate_update_packages */
-	NULL,					/* transaction_start */
-	NULL					/* transaction_stop */
-);
-
diff --git a/backends/test/pk-backend-test-nop.c b/backends/test/pk-backend-test-nop.c
index b822529..a5b0c7a 100644
--- a/backends/test/pk-backend-test-nop.c
+++ b/backends/test/pk-backend-test-nop.c
@@ -23,48 +23,11 @@
 #include <glib.h>
 #include <pk-backend.h>
 
-PK_BACKEND_OPTIONS (
-	"Test NOP",				/* description */
-	"Richard Hughes <richard at hughsie.com>",	/* author */
-	NULL,					/* initialize */
-	NULL,					/* destroy */
-	NULL,					/* get_groups */
-	NULL,					/* get_filters */
-	NULL,					/* get_roles */
-	NULL,					/* get_mime_types */
-	NULL,					/* cancel */
-	NULL,					/* download_packages */
-	NULL,					/* get_categories */
-	NULL,					/* get_depends */
-	NULL,					/* get_details */
-	NULL,					/* get_distro_upgrades */
-	NULL,					/* get_files */
-	NULL,					/* get_packages */
-	NULL,					/* get_repo_list */
-	NULL,					/* get_requires */
-	NULL,					/* get_update_detail */
-	NULL,					/* get_updates */
-	NULL,					/* install_files */
-	NULL,					/* install_packages */
-	NULL,					/* install_signature */
-	NULL,					/* refresh_cache */
-	NULL,					/* remove_packages */
-	NULL,					/* repo_enable */
-	NULL,					/* repo_set_data */
-	NULL,					/* resolve */
-	NULL,					/* rollback */
-	NULL,					/* search_details */
-	NULL,					/* search_files */
-	NULL,					/* search_groups */
-	NULL,					/* search_names */
-	NULL,					/* update_package */
-	NULL,					/* update_system */
-	NULL,					/* what_provides */
-	NULL,					/* simulate_install_files */
-	NULL,					/* simulate_install_packages */
-	NULL,					/* simulate_remove_packages */
-	NULL,					/* simulate_update_packages */
-	NULL,					/* transaction_start */
-	NULL					/* transaction_stop */
-);
-
+/**
+ * pk_backend_get_description:
+ */
+gchar *
+pk_backend_get_description (PkBackend *backend)
+{
+	return g_strdup ("Test NOP");
+}
diff --git a/backends/test/pk-backend-test-spawn.c b/backends/test/pk-backend-test-spawn.c
index 676e385..0501e67 100644
--- a/backends/test/pk-backend-test-spawn.c
+++ b/backends/test/pk-backend-test-spawn.c
@@ -28,10 +28,10 @@
 static PkBackendSpawn *spawn;
 
 /**
- * backend_search_names:
+ * pk_backend_search_names:
  */
-static void
-backend_search_names (PkBackend *backend, PkBitfield filters, gchar **values)
+void
+pk_backend_search_names (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	gchar *filters_text;
 	gchar *search;
@@ -45,11 +45,11 @@ backend_search_names (PkBackend *backend, PkBitfield filters, gchar **values)
 }
 
 /**
- * backend_initialize:
+ * pk_backend_initialize:
  * This should only be run once per backend load, i.e. not every transaction
  */
-static void
-backend_initialize (PkBackend *backend)
+void
+pk_backend_initialize (PkBackend *backend)
 {
 	egg_debug ("backend: initialize");
 	spawn = pk_backend_spawn_new ();
@@ -57,58 +57,12 @@ backend_initialize (PkBackend *backend)
 }
 
 /**
- * backend_destroy:
+ * pk_backend_destroy:
  * This should only be run once per backend load, i.e. not every transaction
  */
-static void
-backend_destroy (PkBackend *backend)
+void
+pk_backend_destroy (PkBackend *backend)
 {
 	egg_debug ("backend: destroy");
 	g_object_unref (spawn);
 }
-
-PK_BACKEND_OPTIONS (
-	"Test Spawn",				/* description */
-	"Richard Hughes <richard at hughsie.com>",	/* author */
-	backend_initialize,			/* initalize */
-	backend_destroy,			/* destroy */
-	NULL,					/* get_groups */
-	NULL,					/* get_filters */
-	NULL,					/* get_roles */
-	NULL,					/* get_mime_types */
-	NULL,					/* cancel */
-	NULL,					/* download_packages */
-	NULL,					/* get_categories */
-	NULL,					/* get_depends */
-	NULL,					/* get_details */
-	NULL,					/* get_distro_upgrades */
-	NULL,					/* get_files */
-	NULL,					/* get_packages */
-	NULL,					/* get_repo_list */
-	NULL,					/* get_requires */
-	NULL,					/* get_update_detail */
-	NULL,					/* get_updates */
-	NULL,					/* install_files */
-	NULL,					/* install_packages */
-	NULL,					/* install_signature */
-	NULL,					/* refresh_cache */
-	NULL,					/* remove_packages */
-	NULL,					/* repo_enable */
-	NULL,					/* repo_set_data */
-	NULL,					/* resolve */
-	NULL,					/* rollback */
-	NULL,					/* search_details */
-	NULL,					/* search_files */
-	NULL,					/* search_groups */
-	backend_search_names,			/* search_names */
-	NULL,					/* update_package */
-	NULL,					/* update_system */
-	NULL,					/* what_provides */
-	NULL,					/* simulate_install_files */
-	NULL,					/* simulate_install_packages */
-	NULL,					/* simulate_remove_packages */
-	NULL,					/* simulate_update_packages */
-	NULL,					/* transaction_start */
-	NULL					/* transaction_stop */
-);
-
diff --git a/backends/test/pk-backend-test-succeed.c b/backends/test/pk-backend-test-succeed.c
index 97ad0d0..dc19459 100644
--- a/backends/test/pk-backend-test-succeed.c
+++ b/backends/test/pk-backend-test-succeed.c
@@ -25,26 +25,26 @@
 #include <pk-backend.h>
 
 /**
- * backend_initialize:
+ * pk_backend_initialize:
  */
-static void
-backend_initialize (PkBackend *backend)
+void
+pk_backend_initialize (PkBackend *backend)
 {
 }
 
 /**
- * backend_destroy:
+ * pk_backend_destroy:
  */
-static void
-backend_destroy (PkBackend *backend)
+void
+pk_backend_destroy (PkBackend *backend)
 {
 }
 
 /**
- * backend_get_groups:
+ * pk_backend_get_groups:
  */
-static PkBitfield
-backend_get_groups (PkBackend *backend)
+PkBitfield
+pk_backend_get_groups (PkBackend *backend)
 {
 	return pk_bitfield_from_enums (
 		PK_GROUP_ENUM_ACCESSIBILITY,
@@ -54,10 +54,10 @@ backend_get_groups (PkBackend *backend)
 }
 
 /**
- * backend_get_filters:
+ * pk_backend_get_filters:
  */
-static PkBitfield
-backend_get_filters (PkBackend *backend)
+PkBitfield
+pk_backend_get_filters (PkBackend *backend)
 {
 	return pk_bitfield_from_enums (
 		PK_FILTER_ENUM_GUI,
@@ -68,28 +68,28 @@ backend_get_filters (PkBackend *backend)
 }
 
 /**
- * backend_get_mime_types:
+ * pk_backend_get_mime_types:
  */
-static gchar *
-backend_get_mime_types (PkBackend *backend)
+gchar *
+pk_backend_get_mime_types (PkBackend *backend)
 {
 	return g_strdup ("");
 }
 
 /**
- * backend_cancel:
+ * pk_backend_cancel:
  */
-static void
-backend_cancel (PkBackend *backend)
+void
+pk_backend_cancel (PkBackend *backend)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_download_packages:
+ * pk_backend_download_packages:
  */
-static void
-backend_download_packages (PkBackend *backend, gchar **package_ids, const gchar *directory)
+void
+pk_backend_download_packages (PkBackend *backend, gchar **package_ids, const gchar *directory)
 {
 	pk_backend_finished (backend);
 }
@@ -97,171 +97,171 @@ backend_download_packages (PkBackend *backend, gchar **package_ids, const gchar
 /**
  * pk_backend_get_categories:
  */
-static void
-backend_get_categories (PkBackend *backend)
+void
+pk_backend_get_categories (PkBackend *backend)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_get_depends:
+ * pk_backend_get_depends:
  */
-static void
-backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
+void
+pk_backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_get_details:
+ * pk_backend_get_details:
  */
-static void
-backend_get_details (PkBackend *backend, gchar **package_ids)
+void
+pk_backend_get_details (PkBackend *backend, gchar **package_ids)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_get_distro_upgrades:
+ * pk_backend_get_distro_upgrades:
  */
-static void
-backend_get_distro_upgrades (PkBackend *backend)
+void
+pk_backend_get_distro_upgrades (PkBackend *backend)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_get_files:
+ * pk_backend_get_files:
  */
-static void
-backend_get_files (PkBackend *backend, gchar **package_ids)
+void
+pk_backend_get_files (PkBackend *backend, gchar **package_ids)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_get_requires:
+ * pk_backend_get_requires:
  */
-static void
-backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
+void
+pk_backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_get_update_detail:
+ * pk_backend_get_update_detail:
  */
-static void
-backend_get_update_detail (PkBackend *backend, gchar **package_ids)
+void
+pk_backend_get_update_detail (PkBackend *backend, gchar **package_ids)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_get_updates:
+ * pk_backend_get_updates:
  */
-static void
-backend_get_updates (PkBackend *backend, PkBitfield filters)
+void
+pk_backend_get_updates (PkBackend *backend, PkBitfield filters)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_install_packages:
+ * pk_backend_install_packages:
  */
-static void
-backend_install_packages (PkBackend *backend, gboolean only_trusted, gchar **package_ids)
+void
+pk_backend_install_packages (PkBackend *backend, gboolean only_trusted, gchar **package_ids)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_install_signature:
+ * pk_backend_install_signature:
  */
-static void
-backend_install_signature (PkBackend *backend, PkSigTypeEnum type,
+void
+pk_backend_install_signature (PkBackend *backend, PkSigTypeEnum type,
 			   const gchar *key_id, const gchar *package_id)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_install_files:
+ * pk_backend_install_files:
  */
-static void
-backend_install_files (PkBackend *backend, gboolean only_trusted, gchar **full_paths)
+void
+pk_backend_install_files (PkBackend *backend, gboolean only_trusted, gchar **full_paths)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_refresh_cache:
+ * pk_backend_refresh_cache:
  */
-static void
-backend_refresh_cache (PkBackend *backend, gboolean force)
+void
+pk_backend_refresh_cache (PkBackend *backend, gboolean force)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_remove_packages:
+ * pk_backend_remove_packages:
  */
-static void
-backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow_deps, gboolean autoremove)
+void
+pk_backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow_deps, gboolean autoremove)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_resolve:
+ * pk_backend_resolve:
  */
-static void
-backend_resolve (PkBackend *backend, PkBitfield filters, gchar **package_ids)
+void
+pk_backend_resolve (PkBackend *backend, PkBitfield filters, gchar **package_ids)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_rollback:
+ * pk_backend_rollback:
  */
-static void
-backend_rollback (PkBackend *backend, const gchar *transaction_id)
+void
+pk_backend_rollback (PkBackend *backend, const gchar *transaction_id)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_search_details:
+ * pk_backend_search_details:
  */
-static void
-backend_search_details (PkBackend *backend, PkBitfield filters, gchar **values)
+void
+pk_backend_search_details (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_search_file:
+ * pk_backend_search_files:
  */
-static void
-backend_search_file (PkBackend *backend, PkBitfield filters, gchar **values)
+void
+pk_backend_search_files (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_search_group:
+ * pk_backend_search_groups:
  */
-static void
-backend_search_group (PkBackend *backend, PkBitfield filters, gchar **values)
+void
+pk_backend_search_groups (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_search_name_timeout:
+ * pk_backend_search_name_timeout:
  **/
 static gboolean
-backend_search_name_timeout (gpointer data)
+pk_backend_search_name_timeout (gpointer data)
 {
 	PkBackend *backend = (PkBackend *) data;
 	pk_backend_finished (backend);
@@ -269,158 +269,112 @@ backend_search_name_timeout (gpointer data)
 }
 
 /**
- * backend_search_name:
+ * pk_backend_search_names:
  *
  * A really long wait........
  */
-static void
-backend_search_name (PkBackend *backend, PkBitfield filters, gchar **values)
+void
+pk_backend_search_names (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
-	g_timeout_add (200, backend_search_name_timeout, backend);
+	g_timeout_add (200, pk_backend_search_name_timeout, backend);
 }
 
 /**
- * backend_update_packages:
+ * pk_backend_update_packages:
  */
-static void
-backend_update_packages (PkBackend *backend, gboolean only_trusted, gchar **package_ids)
+void
+pk_backend_update_packages (PkBackend *backend, gboolean only_trusted, gchar **package_ids)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_update_system:
+ * pk_backend_update_system:
  */
-static void
-backend_update_system (PkBackend *backend, gboolean only_trusted)
+void
+pk_backend_update_system (PkBackend *backend, gboolean only_trusted)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_get_repo_list:
+ * pk_backend_get_repo_list:
  */
-static void
-backend_get_repo_list (PkBackend *backend, PkBitfield filters)
+void
+pk_backend_get_repo_list (PkBackend *backend, PkBitfield filters)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_repo_enable:
+ * pk_backend_repo_enable:
  */
-static void
-backend_repo_enable (PkBackend *backend, const gchar *rid, gboolean enabled)
+void
+pk_backend_repo_enable (PkBackend *backend, const gchar *rid, gboolean enabled)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_repo_set_data:
+ * pk_backend_repo_set_data:
  */
-static void
-backend_repo_set_data (PkBackend *backend, const gchar *rid, const gchar *parameter, const gchar *value)
+void
+pk_backend_repo_set_data (PkBackend *backend, const gchar *rid, const gchar *parameter, const gchar *value)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_what_provides:
+ * pk_backend_what_provides:
  */
-static void
-backend_what_provides (PkBackend *backend, PkBitfield filters, PkProvidesEnum provides, gchar **values)
+void
+pk_backend_what_provides (PkBackend *backend, PkBitfield filters, PkProvidesEnum provides, gchar **values)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_get_packages:
+ * pk_backend_get_packages:
  */
-static void
-backend_get_packages (PkBackend *backend, PkBitfield filters)
+void
+pk_backend_get_packages (PkBackend *backend, PkBitfield filters)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_simulate_install_files:
+ * pk_backend_simulate_install_files:
  */
-static void
-backend_simulate_install_files (PkBackend *backend, gchar **full_paths)
+void
+pk_backend_simulate_install_files (PkBackend *backend, gchar **full_paths)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_simulate_install_packages:
+ * pk_backend_simulate_install_packages:
  */
-static void
-backend_simulate_install_packages (PkBackend *backend, gchar **package_ids)
+void
+pk_backend_simulate_install_packages (PkBackend *backend, gchar **package_ids)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_simulate_remove_packages:
+ * pk_backend_simulate_remove_packages:
  */
-static void
-backend_simulate_remove_packages (PkBackend *backend, gchar **package_ids, gboolean autoremove)
+void
+pk_backend_simulate_remove_packages (PkBackend *backend, gchar **package_ids, gboolean autoremove)
 {
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_simulate_update_packages:
+ * pk_backend_simulate_update_packages:
  */
-static void
-backend_simulate_update_packages (PkBackend *backend, gchar **package_ids)
+void
+pk_backend_simulate_update_packages (PkBackend *backend, gchar **package_ids)
 {
 	pk_backend_finished (backend);
 }
-
-PK_BACKEND_OPTIONS (
-	"Test Succeed",				/* description */
-	"Richard Hughes <richard at hughsie.com>",	/* author */
-	backend_initialize,			/* initalize */
-	backend_destroy,			/* destroy */
-	backend_get_groups,			/* get_groups */
-	backend_get_filters,			/* get_filters */
-	NULL,					/* get_roles */
-	backend_get_mime_types,			/* get_mime_types */
-	backend_cancel,				/* cancel */
-	backend_download_packages,		/* download_packages */
-	backend_get_categories,			/* get_categories */
-	backend_get_depends,			/* get_depends */
-	backend_get_details,			/* get_details */
-	backend_get_distro_upgrades,		/* get_distro_upgrades */
-	backend_get_files,			/* get_files */
-	backend_get_packages,			/* get_packages */
-	backend_get_repo_list,			/* get_repo_list */
-	backend_get_requires,			/* get_requires */
-	backend_get_update_detail,		/* get_update_detail */
-	backend_get_updates,			/* get_updates */
-	backend_install_files,			/* install_files */
-	backend_install_packages,		/* install_packages */
-	backend_install_signature,		/* install_signature */
-	backend_refresh_cache,			/* refresh_cache */
-	backend_remove_packages,		/* remove_packages */
-	backend_repo_enable,			/* repo_enable */
-	backend_repo_set_data,			/* repo_set_data */
-	backend_resolve,			/* resolve */
-	backend_rollback,			/* rollback */
-	backend_search_details,			/* search_details */
-	backend_search_file,			/* search_files */
-	backend_search_group,			/* search_groups */
-	backend_search_name,			/* search_names */
-	backend_update_packages,		/* update_packages */
-	backend_update_system,			/* update_system */
-	backend_what_provides,			/* what_provides */
-	backend_simulate_install_files,		/* simulate_install_files */
-	backend_simulate_install_packages,	/* simulate_install_packages */
-	backend_simulate_remove_packages,	/* simulate_remove_packages */
-	backend_simulate_update_packages,	/* simulate_update_packages */
-	NULL,					/* transaction_start */
-	NULL					/* transaction_stop */
-);
-
diff --git a/backends/test/pk-backend-test-thread.c b/backends/test/pk-backend-test-thread.c
index a3117ce..48d7e56 100644
--- a/backends/test/pk-backend-test-thread.c
+++ b/backends/test/pk-backend-test-thread.c
@@ -27,30 +27,30 @@
 static gboolean is_cancelled = FALSE;
 
 /**
- * backend_initialize:
+ * pk_backend_initialize:
  * This should only be run once per backend load, i.e. not every transaction
  */
-static void
-backend_initialize (PkBackend *backend)
+ void
+pk_backend_initialize (PkBackend *backend)
 {
 	egg_debug ("backend: initialize");
 }
 
 /**
- * backend_destroy:
+ * pk_backend_destroy:
  * This should only be run once per backend load, i.e. not every transaction
  */
-static void
-backend_destroy (PkBackend *backend)
+void
+pk_backend_destroy (PkBackend *backend)
 {
 	egg_debug ("backend: destroy");
 }
 
 /**
- * backend_search_group_thread:
+ * pk_backend_search_groups_thread:
  */
 static gboolean
-backend_search_group_thread (PkBackend *backend)
+pk_backend_search_groups_thread (PkBackend *backend)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 
@@ -64,19 +64,19 @@ backend_search_group_thread (PkBackend *backend)
 }
 
 /**
- * backend_search_group:
+ * pk_backend_search_groups:
  */
-static void
-backend_search_group (PkBackend *backend, PkBitfield filters, gchar **values)
+void
+pk_backend_search_groups (PkBackend *backend, PkBitfield filters, gchar **values)
 {
-	pk_backend_thread_create (backend, backend_search_group_thread);
+	pk_backend_thread_create (backend, pk_backend_search_groups_thread);
 }
 
 /**
- * backend_search_name_thread:
+ * pk_backend_search_names_thread:
  */
 static gboolean
-backend_search_name_thread (PkBackend *backend)
+pk_backend_search_names_thread (PkBackend *backend)
 {
 	GTimer *timer;
 	guint percentage;
@@ -118,66 +118,20 @@ backend_search_name_thread (PkBackend *backend)
 }
 
 /**
- * backend_search_name:
+ * pk_backend_search_names:
  */
-static void
-backend_search_name (PkBackend *backend, PkBitfield filters, gchar **values)
+void
+pk_backend_search_names (PkBackend *backend, PkBitfield filters, gchar **values)
 {
-	pk_backend_thread_create (backend, backend_search_name_thread);
+	pk_backend_thread_create (backend, pk_backend_search_names_thread);
 }
 
 /**
- * backend_cancel:
+ * pk_backend_cancel:
  */
-static void
-backend_cancel (PkBackend *backend)
+void
+pk_backend_cancel (PkBackend *backend)
 {
 	egg_debug ("cancelling %p", backend);
 	is_cancelled = TRUE;
 }
-
-PK_BACKEND_OPTIONS (
-	"Test Thread",				/* description */
-	"Richard Hughes <richard at hughsie.com>",	/* author */
-	backend_initialize,			/* initalize */
-	backend_destroy,			/* destroy */
-	NULL,					/* get_groups */
-	NULL,					/* get_filters */
-	NULL,					/* get_roles */
-	NULL,					/* get_mime_types */
-	backend_cancel,				/* cancel */
-	NULL,					/* download_packages */
-	NULL,					/* get_categories */
-	NULL,					/* get_depends */
-	NULL,					/* get_details */
-	NULL,					/* get_distro_upgrades */
-	NULL,					/* get_files */
-	NULL,					/* get_packages */
-	NULL,					/* get_repo_list */
-	NULL,					/* get_requires */
-	NULL,					/* get_update_detail */
-	NULL,					/* get_updates */
-	NULL,					/* install_files */
-	NULL,					/* install_packages */
-	NULL,					/* install_signature */
-	NULL,					/* refresh_cache */
-	NULL,					/* remove_packages */
-	NULL,					/* repo_enable */
-	NULL,					/* repo_set_data */
-	NULL,					/* resolve */
-	NULL,					/* rollback */
-	NULL,					/* search_details */
-	NULL,					/* search_files */
-	backend_search_group,			/* search_groups */
-	backend_search_name,			/* search_names */
-	NULL,					/* update_package */
-	NULL,					/* update_system */
-	NULL,					/* what_provides */
-	NULL,					/* simulate_install_files */
-	NULL,					/* simulate_install_packages */
-	NULL,					/* simulate_remove_packages */
-	NULL,					/* simulate_update_packages */
-	NULL,					/* transaction_start */
-	NULL					/* transaction_stop */
-);
-
commit d9121d9192bc6347354bfd623cf0b24bbac3c582
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 21 17:02:10 2010 +0100

    Allow backends to omit the table-of-vfuncs and use GModule functionality to resolve backend functions

diff --git a/src/pk-backend.c b/src/pk-backend.c
index 5840431..2c3a870 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -501,6 +501,7 @@ pk_backend_set_name (PkBackend *backend, const gchar *backend_name)
 	GModule *handle;
 	gchar *path = NULL;
 	gboolean ret = TRUE;
+	gpointer func = NULL;
 
 	g_return_val_if_fail (PK_IS_BACKEND (backend), FALSE);
 	g_return_val_if_fail (backend_name != NULL, FALSE);
@@ -522,8 +523,72 @@ pk_backend_set_name (PkBackend *backend, const gchar *backend_name)
 		goto out;
 	}
 
-	/* is is correctly formed? */
-	if (!g_module_symbol (handle, "pk_backend_desc", (gpointer) &backend->priv->desc)) {
+	/* first check for the table of vfuncs */
+	ret = g_module_symbol (handle, "pk_backend_desc", (gpointer) &func);
+	if (ret) {
+		egg_warning ("using table-of-vfuncs compatibility mode");
+		backend->priv->desc = func;
+	} else {
+		/* then check for the new style exported functions */
+		ret = g_module_symbol (handle, "pk_backend_get_description", (gpointer *)&func);
+		if (ret) {
+			PkBackendDesc *desc;
+			PkBackendGetCompatStringFunc backend_vfunc;
+			desc = g_new0 (PkBackendDesc, 1);
+
+			/* connect up exported methods */
+			g_module_symbol (handle, "pk_backend_cancel", (gpointer *)&desc->cancel);
+			g_module_symbol (handle, "pk_backend_destroy", (gpointer *)&desc->destroy);
+			g_module_symbol (handle, "pk_backend_download_packages", (gpointer *)&desc->download_packages);
+			g_module_symbol (handle, "pk_backend_get_categories", (gpointer *)&desc->get_categories);
+			g_module_symbol (handle, "pk_backend_get_depends", (gpointer *)&desc->get_depends);
+			g_module_symbol (handle, "pk_backend_get_details", (gpointer *)&desc->get_details);
+			g_module_symbol (handle, "pk_backend_get_distro_upgrades", (gpointer *)&desc->get_distro_upgrades);
+			g_module_symbol (handle, "pk_backend_get_files", (gpointer *)&desc->get_files);
+			g_module_symbol (handle, "pk_backend_get_filters", (gpointer *)&desc->get_filters);
+			g_module_symbol (handle, "pk_backend_get_groups", (gpointer *)&desc->get_groups);
+			g_module_symbol (handle, "pk_backend_get_mime_types", (gpointer *)&desc->get_mime_types);
+			g_module_symbol (handle, "pk_backend_get_packages", (gpointer *)&desc->get_packages);
+			g_module_symbol (handle, "pk_backend_get_repo_list", (gpointer *)&desc->get_repo_list);
+			g_module_symbol (handle, "pk_backend_get_requires", (gpointer *)&desc->get_requires);
+			g_module_symbol (handle, "pk_backend_get_roles", (gpointer *)&desc->get_roles);
+			g_module_symbol (handle, "pk_backend_get_update_detail", (gpointer *)&desc->get_update_detail);
+			g_module_symbol (handle, "pk_backend_get_updates", (gpointer *)&desc->get_updates);
+			g_module_symbol (handle, "pk_backend_initialize", (gpointer *)&desc->initialize);
+			g_module_symbol (handle, "pk_backend_install_files", (gpointer *)&desc->install_files);
+			g_module_symbol (handle, "pk_backend_install_packages", (gpointer *)&desc->install_packages);
+			g_module_symbol (handle, "pk_backend_install_signature", (gpointer *)&desc->install_signature);
+			g_module_symbol (handle, "pk_backend_refresh_cache", (gpointer *)&desc->refresh_cache);
+			g_module_symbol (handle, "pk_backend_remove_packages", (gpointer *)&desc->remove_packages);
+			g_module_symbol (handle, "pk_backend_repo_enable", (gpointer *)&desc->repo_enable);
+			g_module_symbol (handle, "pk_backend_repo_set_data", (gpointer *)&desc->repo_set_data);
+			g_module_symbol (handle, "pk_backend_resolve", (gpointer *)&desc->resolve);
+			g_module_symbol (handle, "pk_backend_rollback", (gpointer *)&desc->rollback);
+			g_module_symbol (handle, "pk_backend_search_details", (gpointer *)&desc->search_details);
+			g_module_symbol (handle, "pk_backend_search_files", (gpointer *)&desc->search_files);
+			g_module_symbol (handle, "pk_backend_search_groups", (gpointer *)&desc->search_groups);
+			g_module_symbol (handle, "pk_backend_search_names", (gpointer *)&desc->search_names);
+			g_module_symbol (handle, "pk_backend_simulate_install_files", (gpointer *)&desc->simulate_install_files);
+			g_module_symbol (handle, "pk_backend_simulate_install_packages", (gpointer *)&desc->simulate_install_packages);
+			g_module_symbol (handle, "pk_backend_simulate_remove_packages", (gpointer *)&desc->simulate_remove_packages);
+			g_module_symbol (handle, "pk_backend_simulate_update_packages", (gpointer *)&desc->simulate_update_packages);
+			g_module_symbol (handle, "pk_backend_transaction_start", (gpointer *)&desc->transaction_start);
+			g_module_symbol (handle, "pk_backend_transaction_stop", (gpointer *)&desc->transaction_stop);
+			g_module_symbol (handle, "pk_backend_update_packages", (gpointer *)&desc->update_packages);
+			g_module_symbol (handle, "pk_backend_update_system", (gpointer *)&desc->update_system);
+			g_module_symbol (handle, "pk_backend_what_provides", (gpointer *)&desc->what_provides);
+
+			/* get old static string data */
+			g_module_symbol (handle, "pk_backend_get_author", (gpointer *)&backend_vfunc);
+			desc->author = backend_vfunc (backend);
+			g_module_symbol (handle, "pk_backend_get_description", (gpointer *)&backend_vfunc);
+			desc->description = backend_vfunc (backend);
+
+			/* make available */
+			backend->priv->desc = desc;
+		}
+	}
+	if (!ret) {
 		g_module_close (handle);
 		egg_warning ("could not find description in plugin %s, not loading", backend_name);
 		ret = FALSE;
@@ -2085,27 +2150,20 @@ pk_backend_set_exit_code (PkBackend *backend, PkExitEnum exit_enum)
  *
  * It is *not* called for non-threaded backends, as multiple processes
  * would be inherently racy.
- *
- * Return value: %TRUE for success.
  */
-static gboolean
+void
 pk_backend_transaction_start (PkBackend *backend)
 {
-	gboolean ret = TRUE;
-
-	g_return_val_if_fail (PK_IS_BACKEND (backend), FALSE);
+	g_return_if_fail (PK_IS_BACKEND (backend));
 
 	/* no transaction setup is perfectly fine */
 	if (backend->priv->desc->transaction_start == NULL) {
 		egg_debug ("no transaction start vfunc");
-		goto out;
+		return;
 	}
 
 	/* run the transaction setup */
 	backend->priv->desc->transaction_start (backend);
-	ret = !pk_backend_has_set_error_code (backend);
-out:
-	return ret;
 }
 
 /**
@@ -2117,7 +2175,7 @@ out:
  * This method has no return value as the ErrorCode should have already
  * been set.
  */
-static void
+void
 pk_backend_transaction_stop (PkBackend *backend)
 {
 	g_return_if_fail (PK_IS_BACKEND (backend));
@@ -2435,7 +2493,6 @@ gchar *
 pk_backend_get_name (PkBackend *backend)
 {
 	g_return_val_if_fail (PK_IS_BACKEND (backend), NULL);
-	g_return_val_if_fail (backend->priv->desc != NULL, NULL);
 	g_return_val_if_fail (backend->priv->locked != FALSE, NULL);
 	return g_strdup (backend->priv->name);
 }
diff --git a/src/pk-backend.h b/src/pk-backend.h
index 7071274..f5f720c 100644
--- a/src/pk-backend.h
+++ b/src/pk-backend.h
@@ -91,6 +91,7 @@ gchar		*pk_backend_get_description		(PkBackend	*backend)
 							 G_GNUC_WARN_UNUSED_RESULT;
 gchar		*pk_backend_get_author			(PkBackend	*backend)
 							 G_GNUC_WARN_UNUSED_RESULT;
+typedef gchar	*(*PkBackendGetCompatStringFunc)	(PkBackend	*backend);
 PkBitfield	 pk_backend_get_groups			(PkBackend	*backend);
 PkBitfield	 pk_backend_get_filters			(PkBackend	*backend);
 PkBitfield	 pk_backend_get_roles			(PkBackend	*backend);
@@ -103,6 +104,10 @@ void		pk_backend_cancel			(PkBackend	*backend);
 void		pk_backend_download_packages		(PkBackend	*backend,
 							 gchar		**package_ids,
 							 const gchar	*directory);
+void		pk_backend_initialize			(PkBackend	*backend);
+void		pk_backend_destroy			(PkBackend	*backend);
+void		pk_backend_transaction_start		(PkBackend	*backend);
+void		pk_backend_transaction_stop		(PkBackend	*backend);
 void		pk_backend_get_categories		(PkBackend	*backend);
 void		pk_backend_get_depends			(PkBackend	*backend,
 							 PkBitfield	 filters,
@@ -455,6 +460,7 @@ typedef struct {
 	gpointer	padding[8];
 } PkBackendDesc;
 
+/* this is deprecated */
 #define PK_BACKEND_OPTIONS(description, author, initialize, destroy, get_groups, get_filters, get_roles, \
 			   get_mime_types, cancel, download_packages, get_categories, get_depends,	\
 			   get_details, get_distro_upgrades, get_files, get_packages, get_repo_list,	\
commit 628a918c44a2a83bd25db25a339a17a643c1ab58
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 21 16:52:54 2010 +0100

    Merge pk-backend-internal.h back into pk-backend.h

diff --git a/src/Makefile.am b/src/Makefile.am
index 501a3a0..d81e175 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -62,7 +62,6 @@ shared_SOURCES =					\
 	pk-transaction-extra.h				\
 	pk-backend.c					\
 	pk-backend.h					\
-	pk-backend-internal.h				\
 	pk-network.c					\
 	pk-network.h					\
 	pk-shared.c					\
diff --git a/src/pk-backend-internal.h b/src/pk-backend-internal.h
deleted file mode 100644
index bb7df4e..0000000
--- a/src/pk-backend-internal.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2007-2008 Richard Hughes <richard at hughsie.com>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef __PK_BACKEND_INTERNAL_H
-#define __PK_BACKEND_INTERNAL_H
-
-#include <glib-object.h>
-#include <packagekit-glib2/pk-bitfield.h>
-
-#include "pk-store.h"
-#include "pk-backend.h"
-
-G_BEGIN_DECLS
-
-#define PK_TYPE_BACKEND		(pk_backend_get_type ())
-#define PK_BACKEND(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), PK_TYPE_BACKEND, PkBackend))
-#define PK_BACKEND_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), PK_TYPE_BACKEND, PkBackendClass))
-#define PK_IS_BACKEND(o)	(G_TYPE_CHECK_INSTANCE_TYPE ((o), PK_TYPE_BACKEND))
-#define PK_IS_BACKEND_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), PK_TYPE_BACKEND))
-#define PK_BACKEND_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), PK_TYPE_BACKEND, PkBackendClass))
-
-typedef struct _PkBackendPrivate PkBackendPrivate;
-typedef struct _PkBackendClass PkBackendClass;
-
-struct _PkBackend
-{
-	GObject			 parent;
-	PkBackendPrivate	*priv;
-};
-
-struct _PkBackendClass
-{
-	GObjectClass	parent_class;
-};
-
-GType		 pk_backend_get_type			(void);
-PkBackend	*pk_backend_new				(void);
-gboolean	 pk_backend_lock			(PkBackend	*backend)
-							 G_GNUC_WARN_UNUSED_RESULT;
-gboolean	 pk_backend_unlock			(PkBackend	*backend)
-							 G_GNUC_WARN_UNUSED_RESULT;
-gboolean	 pk_backend_reset			(PkBackend	*backend);
-gboolean	 pk_backend_set_name			(PkBackend	*backend,
-							 const gchar	*name)
-							 G_GNUC_WARN_UNUSED_RESULT;
-gboolean	 pk_backend_set_proxy			(PkBackend	*backend,
-							 const gchar	*proxy_http,
-							 const gchar	*proxy_ftp);
-gboolean	 pk_backend_set_root			(PkBackend	*backend,
-							 const gchar	*root);
-gchar		*pk_backend_get_name			(PkBackend	*backend)
-							 G_GNUC_WARN_UNUSED_RESULT;
-gboolean	 pk_backend_get_is_finished		(PkBackend	*backend);
-gchar		*pk_backend_get_description		(PkBackend	*backend)
-							 G_GNUC_WARN_UNUSED_RESULT;
-gchar		*pk_backend_get_author			(PkBackend	*backend)
-							 G_GNUC_WARN_UNUSED_RESULT;
-PkBitfield	 pk_backend_get_groups			(PkBackend	*backend);
-PkBitfield	 pk_backend_get_filters			(PkBackend	*backend);
-PkBitfield	 pk_backend_get_roles			(PkBackend	*backend);
-gchar		*pk_backend_get_mime_types		(PkBackend	*backend);
-gboolean	 pk_backend_has_set_error_code		(PkBackend	*backend);
-gboolean	 pk_backend_is_implemented		(PkBackend	*backend,
-							 PkRoleEnum	 role);
-gchar		*pk_backend_get_accepted_eula_string	(PkBackend	*backend);
-void		pk_backend_cancel			(PkBackend	*backend);
-void		pk_backend_download_packages		(PkBackend	*backend,
-							 gchar		**package_ids,
-							 const gchar	*directory);
-void		pk_backend_get_categories		(PkBackend	*backend);
-void		pk_backend_get_depends			(PkBackend	*backend,
-							 PkBitfield	 filters,
-							 gchar		**package_ids,
-							 gboolean	 recursive);
-void		pk_backend_get_details			(PkBackend	*backend,
-							 gchar		**package_ids);
-void		pk_backend_get_distro_upgrades		(PkBackend	*backend);
-void		pk_backend_get_files			(PkBackend	*backend,
-							 gchar		**package_ids);
-void		pk_backend_get_requires			(PkBackend	*backend,
-							 PkBitfield	 filters,
-							 gchar		**package_ids,
-							 gboolean	 recursive);
-void		pk_backend_get_update_detail		(PkBackend	*backend,
-							 gchar		**package_ids);
-void		pk_backend_get_updates			(PkBackend	*backend,
-							 PkBitfield	 filters);
-void		pk_backend_install_packages		(PkBackend	*backend,
-							 gboolean	 only_trusted,
-							 gchar		**package_ids);
-void		pk_backend_install_signature		(PkBackend	*backend,
-							 PkSigTypeEnum	 type,
-							 const gchar	*key_id,
-							 const gchar	*package_id);
-void		pk_backend_install_files		(PkBackend	*backend,
-							 gboolean	 only_trusted,
-							 gchar		**full_paths);
-void		pk_backend_refresh_cache		(PkBackend	*backend,
-							 gboolean	 force);
-void		pk_backend_remove_packages		(PkBackend	*backend,
-							 gchar		**package_ids,
-							 gboolean	 allow_deps,
-							 gboolean	 autoremove);
-void		pk_backend_resolve			(PkBackend	*backend,
-							 PkBitfield	 filters,
-							 gchar		**packages);
-void		pk_backend_rollback			(PkBackend	*backend,
-							 const gchar	*transaction_id);
-void		pk_backend_search_details		(PkBackend	*backend,
-							 PkBitfield	 filters,
-							 gchar		**search);
-void		pk_backend_search_files			(PkBackend	*backend,
-							 PkBitfield	 filters,
-							 gchar		**search);
-void		pk_backend_search_groups		(PkBackend	*backend,
-							 PkBitfield	 filters,
-							 gchar		**search);
-void		pk_backend_search_names			(PkBackend	*backend,
-							 PkBitfield	 filters,
-							 gchar		**search);
-void		pk_backend_update_packages		(PkBackend	*backend,
-							 gboolean	 only_trusted,
-							 gchar		**package_ids);
-void		pk_backend_update_system		(PkBackend	*backend,
-							 gboolean	 only_trusted);
-void		pk_backend_get_repo_list		(PkBackend	*backend,
-							 PkBitfield	 filters);
-void		pk_backend_repo_enable			(PkBackend	*backend,
-							 const gchar	*repo_id,
-							 gboolean	 enabled);
-void		pk_backend_repo_set_data		(PkBackend	*backend,
-							 const gchar	*repo_id,
-							 const gchar	*parameter,
-							 const gchar	*value);
-void		pk_backend_what_provides		(PkBackend	*backend,
-							 PkBitfield	 filters,
-							 PkProvidesEnum provides,
-							 gchar		**search);
-void		pk_backend_get_packages			(PkBackend	*backend,
-							 PkBitfield	 filters);
-void		pk_backend_simulate_install_files	(PkBackend	*backend,
-							 gchar		**full_paths);
-void		pk_backend_simulate_install_packages	(PkBackend	*backend,
-							 gchar		**package_ids);
-void		pk_backend_simulate_remove_packages	(PkBackend	*backend,
-							 gchar		**package_ids,
-							 gboolean	 autoremove);
-void		pk_backend_simulate_update_packages	(PkBackend	*backend,
-							 gchar		**package_ids);
-
-G_END_DECLS
-
-#endif /* __PK_BACKEND_INTERNAL_H */
-
diff --git a/src/pk-backend-spawn.c b/src/pk-backend-spawn.c
index b5c90d7..f70db0e 100644
--- a/src/pk-backend-spawn.c
+++ b/src/pk-backend-spawn.c
@@ -45,7 +45,7 @@
 #include "egg-debug.h"
 #include "egg-string.h"
 
-#include "pk-backend-internal.h"
+#include "pk-backend.h"
 #include "pk-backend-spawn.h"
 #include "pk-marshal.h"
 #include "pk-spawn.h"
diff --git a/src/pk-backend.c b/src/pk-backend.c
index c902d0f..5840431 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -41,7 +41,6 @@
 #include "pk-conf.h"
 #include "pk-network.h"
 #include "pk-marshal.h"
-#include "pk-backend-internal.h"
 #include "pk-backend.h"
 #include "pk-conf.h"
 #include "pk-store.h"
@@ -89,7 +88,7 @@
  */
 #define PK_BACKEND_CANCEL_ACTION_TIMEOUT	2000 /* ms */
 
-struct _PkBackendPrivate
+struct PkBackendPrivate
 {
 	gboolean		 during_initialize;
 	gboolean		 finished;
diff --git a/src/pk-backend.h b/src/pk-backend.h
index 6a7bc25..7071274 100644
--- a/src/pk-backend.h
+++ b/src/pk-backend.h
@@ -23,7 +23,7 @@
 #define __PK_BACKEND_H
 
 #include <glib.h>
-#include <gmodule.h>
+#include <glib-object.h>
 
 /* these include the includes the backends should be using */
 #include <packagekit-glib2/pk-enum.h>
@@ -31,12 +31,36 @@
 #include <packagekit-glib2/pk-bitfield.h>
 #include <packagekit-glib2/pk-package-id.h>
 #include <packagekit-glib2/pk-package-ids.h>
+#include <packagekit-glib2/pk-bitfield.h>
+
+#include "pk-store.h"
+#include "pk-backend.h"
 
 #include "egg-debug.h"
 #include "egg-string.h"
 
 G_BEGIN_DECLS
 
+#define PK_TYPE_BACKEND		(pk_backend_get_type ())
+#define PK_BACKEND(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), PK_TYPE_BACKEND, PkBackend))
+#define PK_BACKEND_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), PK_TYPE_BACKEND, PkBackendClass))
+#define PK_IS_BACKEND(o)	(G_TYPE_CHECK_INSTANCE_TYPE ((o), PK_TYPE_BACKEND))
+#define PK_IS_BACKEND_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), PK_TYPE_BACKEND))
+#define PK_BACKEND_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), PK_TYPE_BACKEND, PkBackendClass))
+
+typedef struct PkBackendPrivate PkBackendPrivate;
+
+typedef struct
+{
+	 GObject		 parent;
+	 PkBackendPrivate	*priv;
+} PkBackend;
+
+typedef struct
+{
+	GObjectClass		 parent_class;
+} PkBackendClass;
+
 /**
  * PK_BACKEND_PERCENTAGE_INVALID:
  *
@@ -44,7 +68,121 @@ G_BEGIN_DECLS
  */
 #define PK_BACKEND_PERCENTAGE_INVALID		101
 
-typedef struct _PkBackend PkBackend;
+GType		 pk_backend_get_type			(void);
+PkBackend	*pk_backend_new				(void);
+gboolean	 pk_backend_lock			(PkBackend	*backend)
+							 G_GNUC_WARN_UNUSED_RESULT;
+gboolean	 pk_backend_unlock			(PkBackend	*backend)
+							 G_GNUC_WARN_UNUSED_RESULT;
+gboolean	 pk_backend_reset			(PkBackend	*backend);
+gboolean	 pk_backend_set_name			(PkBackend	*backend,
+							 const gchar	*name)
+							 G_GNUC_WARN_UNUSED_RESULT;
+gboolean	 pk_backend_set_proxy			(PkBackend	*backend,
+							 const gchar	*proxy_http,
+							 const gchar	*proxy_ftp);
+gboolean	 pk_backend_set_root			(PkBackend	*backend,
+							 const gchar	*root);
+gchar		*pk_backend_get_name			(PkBackend	*backend)
+							 G_GNUC_WARN_UNUSED_RESULT;
+gboolean	 pk_backend_get_is_finished		(PkBackend	*backend);
+
+gchar		*pk_backend_get_description		(PkBackend	*backend)
+							 G_GNUC_WARN_UNUSED_RESULT;
+gchar		*pk_backend_get_author			(PkBackend	*backend)
+							 G_GNUC_WARN_UNUSED_RESULT;
+PkBitfield	 pk_backend_get_groups			(PkBackend	*backend);
+PkBitfield	 pk_backend_get_filters			(PkBackend	*backend);
+PkBitfield	 pk_backend_get_roles			(PkBackend	*backend);
+gchar		*pk_backend_get_mime_types		(PkBackend	*backend);
+gboolean	 pk_backend_has_set_error_code		(PkBackend	*backend);
+gboolean	 pk_backend_is_implemented		(PkBackend	*backend,
+							 PkRoleEnum	 role);
+gchar		*pk_backend_get_accepted_eula_string	(PkBackend	*backend);
+void		pk_backend_cancel			(PkBackend	*backend);
+void		pk_backend_download_packages		(PkBackend	*backend,
+							 gchar		**package_ids,
+							 const gchar	*directory);
+void		pk_backend_get_categories		(PkBackend	*backend);
+void		pk_backend_get_depends			(PkBackend	*backend,
+							 PkBitfield	 filters,
+							 gchar		**package_ids,
+							 gboolean	 recursive);
+void		pk_backend_get_details			(PkBackend	*backend,
+							 gchar		**package_ids);
+void		pk_backend_get_distro_upgrades		(PkBackend	*backend);
+void		pk_backend_get_files			(PkBackend	*backend,
+							 gchar		**package_ids);
+void		pk_backend_get_requires			(PkBackend	*backend,
+							 PkBitfield	 filters,
+							 gchar		**package_ids,
+							 gboolean	 recursive);
+void		pk_backend_get_update_detail		(PkBackend	*backend,
+							 gchar		**package_ids);
+void		pk_backend_get_updates			(PkBackend	*backend,
+							 PkBitfield	 filters);
+void		pk_backend_install_packages		(PkBackend	*backend,
+							 gboolean	 only_trusted,
+							 gchar		**package_ids);
+void		pk_backend_install_signature		(PkBackend	*backend,
+							 PkSigTypeEnum	 type,
+							 const gchar	*key_id,
+							 const gchar	*package_id);
+void		pk_backend_install_files		(PkBackend	*backend,
+							 gboolean	 only_trusted,
+							 gchar		**full_paths);
+void		pk_backend_refresh_cache		(PkBackend	*backend,
+							 gboolean	 force);
+void		pk_backend_remove_packages		(PkBackend	*backend,
+							 gchar		**package_ids,
+							 gboolean	 allow_deps,
+							 gboolean	 autoremove);
+void		pk_backend_resolve			(PkBackend	*backend,
+							 PkBitfield	 filters,
+							 gchar		**packages);
+void		pk_backend_rollback			(PkBackend	*backend,
+							 const gchar	*transaction_id);
+void		pk_backend_search_details		(PkBackend	*backend,
+							 PkBitfield	 filters,
+							 gchar		**search);
+void		pk_backend_search_files			(PkBackend	*backend,
+							 PkBitfield	 filters,
+							 gchar		**search);
+void		pk_backend_search_groups		(PkBackend	*backend,
+							 PkBitfield	 filters,
+							 gchar		**search);
+void		pk_backend_search_names			(PkBackend	*backend,
+							 PkBitfield	 filters,
+							 gchar		**search);
+void		pk_backend_update_packages		(PkBackend	*backend,
+							 gboolean	 only_trusted,
+							 gchar		**package_ids);
+void		pk_backend_update_system		(PkBackend	*backend,
+							 gboolean	 only_trusted);
+void		pk_backend_get_repo_list		(PkBackend	*backend,
+							 PkBitfield	 filters);
+void		pk_backend_repo_enable			(PkBackend	*backend,
+							 const gchar	*repo_id,
+							 gboolean	 enabled);
+void		pk_backend_repo_set_data		(PkBackend	*backend,
+							 const gchar	*repo_id,
+							 const gchar	*parameter,
+							 const gchar	*value);
+void		pk_backend_what_provides		(PkBackend	*backend,
+							 PkBitfield	 filters,
+							 PkProvidesEnum provides,
+							 gchar		**search);
+void		pk_backend_get_packages			(PkBackend	*backend,
+							 PkBitfield	 filters);
+void		pk_backend_simulate_install_files	(PkBackend	*backend,
+							 gchar		**full_paths);
+void		pk_backend_simulate_install_packages	(PkBackend	*backend,
+							 gchar		**package_ids);
+void		pk_backend_simulate_remove_packages	(PkBackend	*backend,
+							 gchar		**package_ids,
+							 gboolean	 autoremove);
+void		pk_backend_simulate_update_packages	(PkBackend	*backend,
+							 gchar		**package_ids);
 
 /* set the state */
 gboolean	 pk_backend_accept_eula			(PkBackend	*backend,
diff --git a/src/pk-engine.c b/src/pk-engine.c
index d9d6d51..19c67fe 100644
--- a/src/pk-engine.c
+++ b/src/pk-engine.c
@@ -51,7 +51,6 @@
 #include "pk-cache.h"
 #include "pk-shared.h"
 #include "pk-backend.h"
-#include "pk-backend-internal.h"
 #include "pk-engine.h"
 #include "pk-transaction.h"
 #include "pk-transaction-db.h"
diff --git a/src/pk-main.c b/src/pk-main.c
index 55f1ca6..a2c55bb 100644
--- a/src/pk-main.c
+++ b/src/pk-main.c
@@ -39,7 +39,7 @@
 #include "pk-engine.h"
 #include "pk-syslog.h"
 #include "pk-transaction.h"
-#include "pk-backend-internal.h"
+#include "pk-backend.h"
 #include "org.freedesktop.PackageKit.h"
 
 static guint exit_idle_time;
diff --git a/src/pk-self-test.c b/src/pk-self-test.c
index c6c29c4..7d45b2a 100644
--- a/src/pk-self-test.c
+++ b/src/pk-self-test.c
@@ -26,7 +26,6 @@
 #include <glib/gstdio.h>
 
 #include "pk-backend.h"
-#include "pk-backend-internal.h"
 #include "pk-backend-spawn.h"
 #include "pk-cache.h"
 #include "pk-conf.h"
diff --git a/src/pk-transaction-extra.c b/src/pk-transaction-extra.c
index c18f5be..8b7e735 100644
--- a/src/pk-transaction-extra.c
+++ b/src/pk-transaction-extra.c
@@ -41,7 +41,7 @@
 #include "pk-transaction-extra.h"
 #include "pk-shared.h"
 #include "pk-marshal.h"
-#include "pk-backend-internal.h"
+#include "pk-backend.h"
 #include "pk-lsof.h"
 #include "pk-proc.h"
 #include "pk-conf.h"
diff --git a/src/pk-transaction.c b/src/pk-transaction.c
index 503bb9d..c72706f 100644
--- a/src/pk-transaction.c
+++ b/src/pk-transaction.c
@@ -60,7 +60,6 @@
 #include "pk-transaction-db.h"
 #include "pk-marshal.h"
 #include "pk-backend.h"
-#include "pk-backend-internal.h"
 #include "pk-inhibit.h"
 #include "pk-conf.h"
 #include "pk-shared.h"
commit d576b3a6a12114aeead568023ceb247fd341d86b
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 21 11:56:02 2010 +0100

    cnf: add a proper error message when the transaction was cancelled

diff --git a/contrib/command-not-found/pk-command-not-found.c b/contrib/command-not-found/pk-command-not-found.c
index 92305dd..c07094f 100644
--- a/contrib/command-not-found/pk-command-not-found.c
+++ b/contrib/command-not-found/pk-command-not-found.c
@@ -450,9 +450,22 @@ pk_cnf_find_available (const gchar *cmd, guint max_search_time)
 	/* check error code */
 	error_code = pk_results_get_error_code (results);
 	if (error_code != NULL) {
-		/* TRANSLATORS: the transaction failed in a way we could not expect */
-		g_printerr ("%s: %s, %s\n", _("The transaction failed"), pk_error_enum_to_string (pk_error_get_code (error_code)), pk_error_get_details (error_code));
-		goto out;
+		if (pk_error_get_code (error_code) == PK_ERROR_ENUM_TRANSACTION_CANCELLED) {
+			/* TRANSLATORS: the transaction took too long to process */
+			g_printerr ("%s\n", _("The search was cancelled as it was taking too long to complete."));
+
+			/* TRANSLATORS: tell the user what to do --
+			 * the first %s is the keyname, e.g. "MaxSearchTime"
+			 * the second %s is the config file location, e.g. "/etc/PackageKit/CommandNotFound.conf" */
+			g_printerr (_("You can increase the value of '%s' in %s to change the timeout."),
+				    "MaxSearchTime", SYSCONFDIR "/PackageKit/CommandNotFound.conf");
+		} else {
+			/* TRANSLATORS: the transaction failed in a way we could not expect */
+			g_printerr ("%s: %s, %s\n", _("The transaction failed"),
+				    pk_error_enum_to_string (pk_error_get_code (error_code)),
+				    pk_error_get_details (error_code));
+			goto out;
+		}
 	}
 
 	/* get the packages returned */
commit 05aa3f19090c1488071f79a4f6e16f4b20863ee8
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 21 11:25:23 2010 +0100

    glib: Check the GCancellable is not already cancelled at startup in PkClient and PkControl

diff --git a/lib/packagekit-glib2/pk-client.c b/lib/packagekit-glib2/pk-client.c
index d30bd28..93d13d7 100644
--- a/lib/packagekit-glib2/pk-client.c
+++ b/lib/packagekit-glib2/pk-client.c
@@ -1919,6 +1919,7 @@ pk_client_resolve_async (PkClient *client, PkBitfield filters, gchar **packages,
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -1940,10 +1941,20 @@ pk_client_resolve_async (PkClient *client, PkBitfield filters, gchar **packages,
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -1970,6 +1981,7 @@ pk_client_search_names_async (PkClient *client, PkBitfield filters, gchar **valu
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -1991,10 +2003,20 @@ pk_client_search_names_async (PkClient *client, PkBitfield filters, gchar **valu
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -2022,6 +2044,7 @@ pk_client_search_details_async (PkClient *client, PkBitfield filters, gchar **va
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -2043,10 +2066,20 @@ pk_client_search_details_async (PkClient *client, PkBitfield filters, gchar **va
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -2072,6 +2105,7 @@ pk_client_search_groups_async (PkClient *client, PkBitfield filters, gchar **val
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -2093,10 +2127,20 @@ pk_client_search_groups_async (PkClient *client, PkBitfield filters, gchar **val
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -2122,6 +2166,7 @@ pk_client_search_files_async (PkClient *client, PkBitfield filters, gchar **valu
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -2143,10 +2188,20 @@ pk_client_search_files_async (PkClient *client, PkBitfield filters, gchar **valu
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -2172,6 +2227,7 @@ pk_client_get_details_async (PkClient *client, gchar **package_ids, GCancellable
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -2193,10 +2249,20 @@ pk_client_get_details_async (PkClient *client, gchar **package_ids, GCancellable
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -2222,6 +2288,7 @@ pk_client_get_update_detail_async (PkClient *client, gchar **package_ids, GCance
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -2243,10 +2310,20 @@ pk_client_get_update_detail_async (PkClient *client, gchar **package_ids, GCance
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -2272,6 +2349,7 @@ pk_client_download_packages_async (PkClient *client, gchar **package_ids, const
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -2294,10 +2372,20 @@ pk_client_download_packages_async (PkClient *client, gchar **package_ids, const
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -2322,6 +2410,7 @@ pk_client_get_updates_async (PkClient *client, PkBitfield filters, GCancellable
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -2342,10 +2431,20 @@ pk_client_get_updates_async (PkClient *client, PkBitfield filters, GCancellable
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -2370,6 +2469,7 @@ pk_client_get_old_transactions_async (PkClient *client, guint number, GCancellab
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -2390,10 +2490,20 @@ pk_client_get_old_transactions_async (PkClient *client, guint number, GCancellab
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -2423,6 +2533,7 @@ pk_client_update_system_async (PkClient *client, gboolean only_trusted, GCancell
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -2443,10 +2554,20 @@ pk_client_update_system_async (PkClient *client, gboolean only_trusted, GCancell
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -2473,6 +2594,7 @@ pk_client_get_depends_async (PkClient *client, PkBitfield filters, gchar **packa
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -2496,10 +2618,20 @@ pk_client_get_depends_async (PkClient *client, PkBitfield filters, gchar **packa
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -2524,6 +2656,7 @@ pk_client_get_packages_async (PkClient *client, PkBitfield filters, GCancellable
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -2544,10 +2677,20 @@ pk_client_get_packages_async (PkClient *client, PkBitfield filters, GCancellable
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -2574,6 +2717,7 @@ pk_client_get_requires_async (PkClient *client, PkBitfield filters, gchar **pack
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -2597,10 +2741,20 @@ pk_client_get_requires_async (PkClient *client, PkBitfield filters, gchar **pack
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -2629,6 +2783,7 @@ pk_client_what_provides_async (PkClient *client, PkBitfield filters, PkProvidesE
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -2651,10 +2806,20 @@ pk_client_what_provides_async (PkClient *client, PkBitfield filters, PkProvidesE
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -2679,6 +2844,7 @@ pk_client_get_distro_upgrades_async (PkClient *client, GCancellable *cancellable
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -2698,10 +2864,20 @@ pk_client_get_distro_upgrades_async (PkClient *client, GCancellable *cancellable
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -2726,6 +2902,7 @@ pk_client_get_files_async (PkClient *client, gchar **package_ids, GCancellable *
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -2747,10 +2924,20 @@ pk_client_get_files_async (PkClient *client, gchar **package_ids, GCancellable *
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -2774,6 +2961,7 @@ pk_client_get_categories_async (PkClient *client, GCancellable *cancellable,
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -2793,10 +2981,20 @@ pk_client_get_categories_async (PkClient *client, GCancellable *cancellable,
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -2825,6 +3023,7 @@ pk_client_remove_packages_async (PkClient *client, gchar **package_ids, gboolean
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -2848,10 +3047,20 @@ pk_client_remove_packages_async (PkClient *client, gchar **package_ids, gboolean
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -2879,6 +3088,7 @@ pk_client_refresh_cache_async (PkClient *client, gboolean force, GCancellable *c
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -2899,10 +3109,20 @@ pk_client_refresh_cache_async (PkClient *client, gboolean force, GCancellable *c
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -2928,6 +3148,7 @@ pk_client_install_packages_async (PkClient *client, gboolean only_trusted, gchar
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -2950,10 +3171,20 @@ pk_client_install_packages_async (PkClient *client, gboolean only_trusted, gchar
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -2980,6 +3211,7 @@ pk_client_install_signature_async (PkClient *client, PkSigTypeEnum type, const g
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -3002,10 +3234,20 @@ pk_client_install_signature_async (PkClient *client, PkSigTypeEnum type, const g
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -3031,6 +3273,7 @@ pk_client_update_packages_async (PkClient *client, gboolean only_trusted, gchar
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -3053,10 +3296,20 @@ pk_client_update_packages_async (PkClient *client, gboolean only_trusted, gchar
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -3167,9 +3420,9 @@ pk_client_install_files_async (PkClient *client, gboolean only_trusted, gchar **
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 	gboolean ret;
 	guint i;
-	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -3191,6 +3444,15 @@ pk_client_install_files_async (PkClient *client, gboolean only_trusted, gchar **
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* check files are valid */
@@ -3243,6 +3505,7 @@ pk_client_accept_eula_async (PkClient *client, const gchar *eula_id, GCancellabl
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -3263,10 +3526,20 @@ pk_client_accept_eula_async (PkClient *client, const gchar *eula_id, GCancellabl
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -3291,6 +3564,7 @@ pk_client_rollback_async (PkClient *client, const gchar *transaction_id, GCancel
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -3311,10 +3585,20 @@ pk_client_rollback_async (PkClient *client, const gchar *transaction_id, GCancel
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -3339,6 +3623,7 @@ pk_client_get_repo_list_async (PkClient *client, PkBitfield filters, GCancellabl
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -3359,10 +3644,20 @@ pk_client_get_repo_list_async (PkClient *client, PkBitfield filters, GCancellabl
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -3388,6 +3683,7 @@ pk_client_repo_enable_async (PkClient *client, const gchar *repo_id, gboolean en
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -3409,10 +3705,20 @@ pk_client_repo_enable_async (PkClient *client, const gchar *repo_id, gboolean en
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -3440,6 +3746,7 @@ pk_client_repo_set_data_async (PkClient *client, const gchar *repo_id, const gch
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -3462,10 +3769,20 @@ pk_client_repo_set_data_async (PkClient *client, const gchar *repo_id, const gch
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -3490,9 +3807,9 @@ pk_client_simulate_install_files_async (PkClient *client, gchar **files, GCancel
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 	gboolean ret;
 	guint i;
-	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -3514,6 +3831,15 @@ pk_client_simulate_install_files_async (PkClient *client, gchar **files, GCancel
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* check files are valid */
@@ -3566,6 +3892,7 @@ pk_client_simulate_install_packages_async (PkClient *client, gchar **package_ids
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -3587,10 +3914,20 @@ pk_client_simulate_install_packages_async (PkClient *client, gchar **package_ids
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -3616,6 +3953,7 @@ pk_client_simulate_remove_packages_async (PkClient *client, gchar **package_ids,
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -3638,10 +3976,20 @@ pk_client_simulate_remove_packages_async (PkClient *client, gchar **package_ids,
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -3666,6 +4014,7 @@ pk_client_simulate_update_packages_async (PkClient *client, gchar **package_ids,
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -3687,10 +4036,20 @@ pk_client_simulate_update_packages_async (PkClient *client, gchar **package_ids,
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 
 	/* get tid */
 	pk_control_get_tid_async (client->priv->control, cancellable, (GAsyncReadyCallback) pk_client_get_tid_cb, state);
+out:
 	g_object_unref (res);
 }
 
@@ -3763,6 +4122,7 @@ pk_client_adopt_async (PkClient *client, const gchar *transaction_id, GCancellab
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -3783,6 +4143,15 @@ pk_client_adopt_async (PkClient *client, const gchar *transaction_id, GCancellab
 	state->progress_callback = progress_callback;
 	state->progress_user_data = progress_user_data;
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_client_set_role (state, state->role);
 	pk_progress_set_transaction_id (state->progress, state->tid);
 
@@ -3820,7 +4189,7 @@ pk_client_adopt_async (PkClient *client, const gchar *transaction_id, GCancellab
 
 	/* track state */
 	pk_client_state_add (client, state);
-
+out:
 	g_object_unref (res);
 }
 
@@ -3944,6 +4313,7 @@ pk_client_get_progress_async (PkClient *client, const gchar *transaction_id, GCa
 {
 	GSimpleAsyncResult *res;
 	PkClientState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
@@ -3961,6 +4331,15 @@ pk_client_get_progress_async (PkClient *client, const gchar *transaction_id, GCa
 	}
 	state->tid = g_strdup (transaction_id);
 	state->progress = pk_progress_new ();
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_client_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* identify */
 	pk_progress_set_transaction_id (state->progress, state->tid);
 
 	/* get a connection to the transaction interface */
@@ -3993,7 +4372,7 @@ pk_client_get_progress_async (PkClient *client, const gchar *transaction_id, GCa
 
 	/* track state */
 	pk_client_state_add (client, state);
-
+out:
 	g_object_unref (res);
 }
 
diff --git a/lib/packagekit-glib2/pk-control.c b/lib/packagekit-glib2/pk-control.c
index 4dddc1c..11f648c 100644
--- a/lib/packagekit-glib2/pk-control.c
+++ b/lib/packagekit-glib2/pk-control.c
@@ -274,6 +274,7 @@ pk_control_get_tid_async (PkControl *control, GCancellable *cancellable, GAsyncR
 {
 	GSimpleAsyncResult *res;
 	PkControlState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CONTROL (control));
 	g_return_if_fail (callback != NULL);
@@ -290,6 +291,13 @@ pk_control_get_tid_async (PkControl *control, GCancellable *cancellable, GAsyncR
 		state->cancellable_id = g_cancellable_connect (cancellable, G_CALLBACK (pk_control_cancellable_cancel_cb), state, NULL);
 	}
 
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_control_get_tid_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
 	/* call D-Bus method async */
 	state->call = dbus_g_proxy_begin_call (control->priv->proxy, "GetTid",
 					       (DBusGProxyCallNotify) pk_control_get_tid_cb, state,
@@ -300,7 +308,7 @@ pk_control_get_tid_async (PkControl *control, GCancellable *cancellable, GAsyncR
 	/* track state */
 	g_ptr_array_add (control->priv->calls, state);
 	egg_debug ("state array add %p (%p)", state, state->call);
-
+out:
 	g_object_unref (res);
 }
 
@@ -420,6 +428,7 @@ pk_control_suggest_daemon_quit_async (PkControl *control, GCancellable *cancella
 {
 	GSimpleAsyncResult *res;
 	PkControlState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CONTROL (control));
 	g_return_if_fail (callback != NULL);
@@ -436,6 +445,13 @@ pk_control_suggest_daemon_quit_async (PkControl *control, GCancellable *cancella
 		state->cancellable_id = g_cancellable_connect (cancellable, G_CALLBACK (pk_control_cancellable_cancel_cb), state, NULL);
 	}
 
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_control_suggest_daemon_quit_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
 	/* call D-Bus method async */
 	state->call = dbus_g_proxy_begin_call (control->priv->proxy, "SuggestDaemonQuit",
 					       (DBusGProxyCallNotify) pk_control_suggest_daemon_quit_cb, state,
@@ -446,7 +462,7 @@ pk_control_suggest_daemon_quit_async (PkControl *control, GCancellable *cancella
 	/* track state */
 	g_ptr_array_add (control->priv->calls, state);
 	egg_debug ("state array add %p (%p)", state, state->call);
-
+out:
 	g_object_unref (res);
 }
 
@@ -570,6 +586,7 @@ pk_control_get_daemon_state_async (PkControl *control, GCancellable *cancellable
 {
 	GSimpleAsyncResult *res;
 	PkControlState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CONTROL (control));
 	g_return_if_fail (callback != NULL);
@@ -586,6 +603,13 @@ pk_control_get_daemon_state_async (PkControl *control, GCancellable *cancellable
 		state->cancellable_id = g_cancellable_connect (cancellable, G_CALLBACK (pk_control_cancellable_cancel_cb), state, NULL);
 	}
 
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_control_get_daemon_state_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
 	/* call D-Bus method async */
 	state->call = dbus_g_proxy_begin_call (control->priv->proxy, "GetDaemonState",
 					       (DBusGProxyCallNotify) pk_control_get_daemon_state_cb, state,
@@ -596,7 +620,7 @@ pk_control_get_daemon_state_async (PkControl *control, GCancellable *cancellable
 	/* track state */
 	g_ptr_array_add (control->priv->calls, state);
 	egg_debug ("state array add %p (%p)", state, state->call);
-
+out:
 	g_object_unref (res);
 }
 
@@ -719,6 +743,7 @@ pk_control_set_proxy_async (PkControl *control, const gchar *proxy_http, const g
 {
 	GSimpleAsyncResult *res;
 	PkControlState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CONTROL (control));
 	g_return_if_fail (callback != NULL);
@@ -735,6 +760,13 @@ pk_control_set_proxy_async (PkControl *control, const gchar *proxy_http, const g
 		state->cancellable_id = g_cancellable_connect (cancellable, G_CALLBACK (pk_control_cancellable_cancel_cb), state, NULL);
 	}
 
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_control_set_proxy_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
 	/* call D-Bus set_proxy async */
 	state->call = dbus_g_proxy_begin_call (control->priv->proxy, "SetProxy",
 					       (DBusGProxyCallNotify) pk_control_set_proxy_cb, state, NULL,
@@ -747,7 +779,7 @@ pk_control_set_proxy_async (PkControl *control, const gchar *proxy_http, const g
 	/* track state */
 	g_ptr_array_add (control->priv->calls, state);
 	egg_debug ("state array add %p (%p)", state, state->call);
-
+out:
 	g_object_unref (res);
 }
 
@@ -869,6 +901,7 @@ pk_control_set_root_async (PkControl *control, const gchar *root, GCancellable *
 {
 	GSimpleAsyncResult *res;
 	PkControlState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CONTROL (control));
 	g_return_if_fail (callback != NULL);
@@ -885,6 +918,13 @@ pk_control_set_root_async (PkControl *control, const gchar *root, GCancellable *
 		state->cancellable_id = g_cancellable_connect (cancellable, G_CALLBACK (pk_control_cancellable_cancel_cb), state, NULL);
 	}
 
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_control_set_root_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
 	/* call D-Bus set_root async */
 	state->call = dbus_g_proxy_begin_call (control->priv->proxy, "SetRoot",
 					       (DBusGProxyCallNotify) pk_control_set_root_cb, state, NULL,
@@ -896,7 +936,7 @@ pk_control_set_root_async (PkControl *control, const gchar *root, GCancellable *
 	/* track state */
 	g_ptr_array_add (control->priv->calls, state);
 	egg_debug ("state array add %p (%p)", state, state->call);
-
+out:
 	g_object_unref (res);
 }
 
@@ -1020,6 +1060,7 @@ pk_control_get_transaction_list_async (PkControl *control, GCancellable *cancell
 {
 	GSimpleAsyncResult *res;
 	PkControlState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CONTROL (control));
 	g_return_if_fail (callback != NULL);
@@ -1036,6 +1077,13 @@ pk_control_get_transaction_list_async (PkControl *control, GCancellable *cancell
 		state->cancellable_id = g_cancellable_connect (cancellable, G_CALLBACK (pk_control_cancellable_cancel_cb), state, NULL);
 	}
 
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_control_get_transaction_list_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
 	/* call D-Bus get_transaction_list async */
 	state->call = dbus_g_proxy_begin_call (control->priv->proxy, "GetTransactionList",
 					       (DBusGProxyCallNotify) pk_control_get_transaction_list_cb, state,
@@ -1046,7 +1094,7 @@ pk_control_get_transaction_list_async (PkControl *control, GCancellable *cancell
 	/* track state */
 	g_ptr_array_add (control->priv->calls, state);
 	egg_debug ("state array add %p (%p)", state, state->call);
-
+out:
 	g_object_unref (res);
 }
 
@@ -1177,6 +1225,7 @@ pk_control_get_time_since_action_async (PkControl *control, PkRoleEnum role, GCa
 {
 	GSimpleAsyncResult *res;
 	PkControlState *state;
+	GError *error = NULL;
 	const gchar *role_text;
 
 	g_return_if_fail (PK_IS_CONTROL (control));
@@ -1194,6 +1243,13 @@ pk_control_get_time_since_action_async (PkControl *control, PkRoleEnum role, GCa
 		state->cancellable_id = g_cancellable_connect (cancellable, G_CALLBACK (pk_control_cancellable_cancel_cb), state, NULL);
 	}
 
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_control_get_time_since_action_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
 	/* call D-Bus get_time_since_action async */
 	role_text = pk_role_enum_to_string (role);
 	state->call = dbus_g_proxy_begin_call (control->priv->proxy, "GetTimeSinceAction",
@@ -1206,7 +1262,7 @@ pk_control_get_time_since_action_async (PkControl *control, PkRoleEnum role, GCa
 	/* track state */
 	g_ptr_array_add (control->priv->calls, state);
 	egg_debug ("state array add %p (%p)", state, state->call);
-
+out:
 	g_object_unref (res);
 }
 
@@ -1338,6 +1394,7 @@ pk_control_can_authorize_async (PkControl *control, const gchar *action_id, GCan
 {
 	GSimpleAsyncResult *res;
 	PkControlState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CONTROL (control));
 	g_return_if_fail (callback != NULL);
@@ -1353,6 +1410,13 @@ pk_control_can_authorize_async (PkControl *control, const gchar *action_id, GCan
 		state->cancellable = g_object_ref (cancellable);
 		state->cancellable_id = g_cancellable_connect (cancellable, G_CALLBACK (pk_control_cancellable_cancel_cb), state, NULL);
 	}
+
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_control_can_authorize_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
 	state->authorize = PK_AUTHORIZE_ENUM_UNKNOWN;
 
 	/* call D-Bus async */
@@ -1366,7 +1430,7 @@ pk_control_can_authorize_async (PkControl *control, const gchar *action_id, GCan
 	/* track state */
 	g_ptr_array_add (control->priv->calls, state);
 	egg_debug ("state array add %p (%p)", state, state->call);
-
+out:
 	g_object_unref (res);
 }
 
@@ -1745,6 +1809,7 @@ pk_control_get_properties_async (PkControl *control, GCancellable *cancellable,
 {
 	GSimpleAsyncResult *res;
 	PkControlState *state;
+	GError *error = NULL;
 
 	g_return_if_fail (PK_IS_CONTROL (control));
 	g_return_if_fail (callback != NULL);
@@ -1761,6 +1826,13 @@ pk_control_get_properties_async (PkControl *control, GCancellable *cancellable,
 		state->cancellable_id = g_cancellable_connect (cancellable, G_CALLBACK (pk_control_cancellable_cancel_cb), state, NULL);
 	}
 
+	/* check not already cancelled */
+	if (cancellable != NULL && g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+		pk_control_get_properties_state_finish (state, error);
+		g_error_free (error);
+		goto out;
+	}
+
 	/* call D-Bus get_properties async */
 	state->call = dbus_g_proxy_begin_call (control->priv->proxy_props, "GetAll",
 					       (DBusGProxyCallNotify) pk_control_get_properties_cb, state, NULL,
@@ -1772,7 +1844,7 @@ pk_control_get_properties_async (PkControl *control, GCancellable *cancellable,
 	/* track state */
 	g_ptr_array_add (control->priv->calls, state);
 	egg_debug ("state array add %p (%p)", state, state->call);
-
+out:
 	g_object_unref (res);
 }
 
diff --git a/lib/packagekit-glib2/pk-self-test.c b/lib/packagekit-glib2/pk-self-test.c
index 07c31c4..08fd7f3 100644
--- a/lib/packagekit-glib2/pk-self-test.c
+++ b/lib/packagekit-glib2/pk-self-test.c
@@ -420,6 +420,18 @@ pk_test_client_search_name_cb (GObject *object, GAsyncResult *res, gpointer user
 	_g_test_loop_quit ();
 }
 
+static void
+pk_test_client_search_name_cancellable_cancelled_cb (GObject *object, GAsyncResult *res, gpointer user_data)
+{
+	PkClient *client = PK_CLIENT (object);
+	GError *error = NULL;
+	PkResults *results = NULL;
+	results = pk_client_generic_finish (client, res, &error);
+	g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
+	g_assert (results == NULL);
+	_g_test_loop_quit ();
+}
+
 static guint _progress_cb = 0;
 static guint _status_cb = 0;
 static guint _package_cb = 0;
@@ -652,7 +664,15 @@ pk_test_client_func (void)
 	_g_test_loop_run_with_timeout (15000);
 	egg_debug ("cancelled in %f", g_test_timer_elapsed ());
 
+	/* ensure we abort with error if we cancel */
+	pk_client_search_names_async (client, pk_bitfield_value (PK_FILTER_ENUM_NONE), values, cancellable,
+		     (PkProgressCallback) pk_test_client_progress_cb, NULL,
+		     (GAsyncReadyCallback) pk_test_client_search_name_cancellable_cancelled_cb, NULL);
+	_g_test_loop_run_with_timeout (15000);
+
 	g_strfreev (values);
+
+	/* okay now */
 	g_cancellable_reset (cancellable);
 
 	/* do downloads */
commit a519245b228d330c57719f4b52148877f94ae233
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 21 11:17:31 2010 +0100

    yum: only cancel the GCancellable if we are using ZIF

diff --git a/backends/yum/pk-backend-yum.c b/backends/yum/pk-backend-yum.c
index 19658a0..84ec83f 100644
--- a/backends/yum/pk-backend-yum.c
+++ b/backends/yum/pk-backend-yum.c
@@ -1069,9 +1069,10 @@ backend_get_mime_types (PkBackend *backend)
 static void
 backend_cancel (PkBackend *backend)
 {
+#ifdef HAVE_ZIF
 	/* try to cancel the thread first */
 	g_cancellable_cancel (priv->cancellable);
-
+#endif
 	/* this feels bad... */
 	pk_backend_spawn_kill (priv->spawn);
 }
commit 2b3c13110a448ab1535716c0944e43a7e945ac98
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 21 11:06:58 2010 +0100

    Ensure we set an error if the spawned backend gets cancelled
    
    We can't assume the spawned backend gets a chance to set an error when we SIGQUIT it
    and so set a generic transaction cancelled error code when before we send the signal.
    
    This means we don't trigger the obnoxious internal error when sometimes cancelling
    tranasctions, e.g. '...This is a serious error as the spawned backend did not...' and
    we don't scare the user when there's nothing actually wrong.

diff --git a/src/pk-backend-spawn.c b/src/pk-backend-spawn.c
index f43e489..b5c90d7 100644
--- a/src/pk-backend-spawn.c
+++ b/src/pk-backend-spawn.c
@@ -589,10 +589,11 @@ pk_backend_spawn_exit_cb (PkSpawn *spawn, PkSpawnExitType exit_enum, PkBackendSp
 
 	/* only emit if not finished */
 	if (!backend_spawn->priv->finished) {
-		egg_warning ("script exited without doing finished");
+		egg_debug ("script exited without doing finished, tidying up");
 		ret = pk_backend_has_set_error_code (backend_spawn->priv->backend);
 		if (!ret) {
-			pk_backend_error_code (backend_spawn->priv->backend, PK_ERROR_ENUM_INTERNAL_ERROR,
+			pk_backend_error_code (backend_spawn->priv->backend,
+					       PK_ERROR_ENUM_INTERNAL_ERROR,
 					       "The backend exited unexpectedly. "
 					       "This is a serious error as the spawned backend did not complete the pending transaction.");
 		}
@@ -937,6 +938,11 @@ gboolean
 pk_backend_spawn_kill (PkBackendSpawn *backend_spawn)
 {
 	g_return_val_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn), FALSE);
+
+	/* set an error as the script will just exit without doing finished */
+	pk_backend_error_code (backend_spawn->priv->backend,
+			       PK_ERROR_ENUM_TRANSACTION_CANCELLED,
+			       "the script was killed as the action was cancelled");
 	pk_spawn_kill (backend_spawn->priv->spawn);
 	return TRUE;
 }
commit b708fca56bcd88642da9e38ad3cddbaba7782fa3
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 21 08:48:32 2010 +0100

    glib: ensure GCancellable values are valid, or NULL

diff --git a/lib/packagekit-glib2/pk-client.c b/lib/packagekit-glib2/pk-client.c
index 25cb19d..d30bd28 100644
--- a/lib/packagekit-glib2/pk-client.c
+++ b/lib/packagekit-glib2/pk-client.c
@@ -1922,6 +1922,7 @@ pk_client_resolve_async (PkClient *client, PkBitfield filters, gchar **packages,
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_resolve_async);
 
@@ -1972,6 +1973,7 @@ pk_client_search_names_async (PkClient *client, PkBitfield filters, gchar **valu
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_search_names_async);
 
@@ -2023,6 +2025,7 @@ pk_client_search_details_async (PkClient *client, PkBitfield filters, gchar **va
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_search_details_async);
 
@@ -2072,6 +2075,7 @@ pk_client_search_groups_async (PkClient *client, PkBitfield filters, gchar **val
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_search_groups_async);
 
@@ -2121,6 +2125,7 @@ pk_client_search_files_async (PkClient *client, PkBitfield filters, gchar **valu
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_search_files_async);
 
@@ -2170,6 +2175,7 @@ pk_client_get_details_async (PkClient *client, gchar **package_ids, GCancellable
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 	g_return_if_fail (package_ids != NULL);
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_get_details_async);
@@ -2219,6 +2225,7 @@ pk_client_get_update_detail_async (PkClient *client, gchar **package_ids, GCance
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 	g_return_if_fail (package_ids != NULL);
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_get_update_detail_async);
@@ -2268,6 +2275,7 @@ pk_client_download_packages_async (PkClient *client, gchar **package_ids, const
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 	g_return_if_fail (package_ids != NULL);
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_download_packages_async);
@@ -2317,6 +2325,7 @@ pk_client_get_updates_async (PkClient *client, PkBitfield filters, GCancellable
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_get_updates_async);
 
@@ -2364,6 +2373,7 @@ pk_client_get_old_transactions_async (PkClient *client, guint number, GCancellab
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_get_old_transactions_async);
 
@@ -2416,6 +2426,7 @@ pk_client_update_system_async (PkClient *client, gboolean only_trusted, GCancell
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_update_system_async);
 
@@ -2465,6 +2476,7 @@ pk_client_get_depends_async (PkClient *client, PkBitfield filters, gchar **packa
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 	g_return_if_fail (package_ids != NULL);
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_get_depends_async);
@@ -2515,6 +2527,7 @@ pk_client_get_packages_async (PkClient *client, PkBitfield filters, GCancellable
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_get_packages_async);
 
@@ -2564,6 +2577,7 @@ pk_client_get_requires_async (PkClient *client, PkBitfield filters, gchar **pack
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 	g_return_if_fail (package_ids != NULL);
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_get_requires_async);
@@ -2618,6 +2632,7 @@ pk_client_what_provides_async (PkClient *client, PkBitfield filters, PkProvidesE
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_what_provides_async);
 
@@ -2667,6 +2682,7 @@ pk_client_get_distro_upgrades_async (PkClient *client, GCancellable *cancellable
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_get_distro_upgrades_async);
 
@@ -2713,6 +2729,7 @@ pk_client_get_files_async (PkClient *client, gchar **package_ids, GCancellable *
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 	g_return_if_fail (package_ids != NULL);
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_get_files_async);
@@ -2760,6 +2777,7 @@ pk_client_get_categories_async (PkClient *client, GCancellable *cancellable,
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_get_categories_async);
 
@@ -2810,6 +2828,7 @@ pk_client_remove_packages_async (PkClient *client, gchar **package_ids, gboolean
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 	g_return_if_fail (package_ids != NULL);
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_remove_packages_async);
@@ -2863,6 +2882,7 @@ pk_client_refresh_cache_async (PkClient *client, gboolean force, GCancellable *c
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_refresh_cache_async);
 
@@ -2911,6 +2931,7 @@ pk_client_install_packages_async (PkClient *client, gboolean only_trusted, gchar
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 	g_return_if_fail (package_ids != NULL);
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_install_packages_async);
@@ -2962,6 +2983,7 @@ pk_client_install_signature_async (PkClient *client, PkSigTypeEnum type, const g
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_install_signature_async);
 
@@ -3012,6 +3034,7 @@ pk_client_update_packages_async (PkClient *client, gboolean only_trusted, gchar
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 	g_return_if_fail (package_ids != NULL);
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_update_packages_async);
@@ -3150,6 +3173,7 @@ pk_client_install_files_async (PkClient *client, gboolean only_trusted, gchar **
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 	g_return_if_fail (files != NULL);
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_install_files_async);
@@ -3222,6 +3246,7 @@ pk_client_accept_eula_async (PkClient *client, const gchar *eula_id, GCancellabl
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_accept_eula_async);
 
@@ -3269,6 +3294,7 @@ pk_client_rollback_async (PkClient *client, const gchar *transaction_id, GCancel
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_accept_eula_async);
 
@@ -3316,6 +3342,7 @@ pk_client_get_repo_list_async (PkClient *client, PkBitfield filters, GCancellabl
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_get_repo_list_async);
 
@@ -3364,6 +3391,7 @@ pk_client_repo_enable_async (PkClient *client, const gchar *repo_id, gboolean en
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_repo_enable_async);
 
@@ -3415,6 +3443,7 @@ pk_client_repo_set_data_async (PkClient *client, const gchar *repo_id, const gch
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_repo_set_data_async);
 
@@ -3467,6 +3496,7 @@ pk_client_simulate_install_files_async (PkClient *client, gchar **files, GCancel
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 	g_return_if_fail (files != NULL);
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_simulate_install_files_async);
@@ -3539,6 +3569,7 @@ pk_client_simulate_install_packages_async (PkClient *client, gchar **package_ids
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 	g_return_if_fail (package_ids != NULL);
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_simulate_install_packages_async);
@@ -3588,6 +3619,7 @@ pk_client_simulate_remove_packages_async (PkClient *client, gchar **package_ids,
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 	g_return_if_fail (package_ids != NULL);
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_simulate_remove_packages_async);
@@ -3637,6 +3669,7 @@ pk_client_simulate_update_packages_async (PkClient *client, gchar **package_ids,
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 	g_return_if_fail (package_ids != NULL);
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_simulate_update_packages_async);
@@ -3733,6 +3766,7 @@ pk_client_adopt_async (PkClient *client, const gchar *transaction_id, GCancellab
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_adopt_async);
 
@@ -3913,6 +3947,7 @@ pk_client_get_progress_async (PkClient *client, const gchar *transaction_id, GCa
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (client), callback_ready, user_data, pk_client_get_progress_async);
 
diff --git a/lib/packagekit-glib2/pk-control.c b/lib/packagekit-glib2/pk-control.c
index 170c967..4dddc1c 100644
--- a/lib/packagekit-glib2/pk-control.c
+++ b/lib/packagekit-glib2/pk-control.c
@@ -277,6 +277,7 @@ pk_control_get_tid_async (PkControl *control, GCancellable *cancellable, GAsyncR
 
 	g_return_if_fail (PK_IS_CONTROL (control));
 	g_return_if_fail (callback != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (control), callback, user_data, pk_control_get_tid_async);
 
@@ -422,6 +423,7 @@ pk_control_suggest_daemon_quit_async (PkControl *control, GCancellable *cancella
 
 	g_return_if_fail (PK_IS_CONTROL (control));
 	g_return_if_fail (callback != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (control), callback, user_data, pk_control_suggest_daemon_quit_async);
 
@@ -571,6 +573,7 @@ pk_control_get_daemon_state_async (PkControl *control, GCancellable *cancellable
 
 	g_return_if_fail (PK_IS_CONTROL (control));
 	g_return_if_fail (callback != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (control), callback, user_data, pk_control_get_daemon_state_async);
 
@@ -719,6 +722,7 @@ pk_control_set_proxy_async (PkControl *control, const gchar *proxy_http, const g
 
 	g_return_if_fail (PK_IS_CONTROL (control));
 	g_return_if_fail (callback != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (control), callback, user_data, pk_control_set_proxy_async);
 
@@ -868,6 +872,7 @@ pk_control_set_root_async (PkControl *control, const gchar *root, GCancellable *
 
 	g_return_if_fail (PK_IS_CONTROL (control));
 	g_return_if_fail (callback != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (control), callback, user_data, pk_control_set_root_async);
 
@@ -1018,6 +1023,7 @@ pk_control_get_transaction_list_async (PkControl *control, GCancellable *cancell
 
 	g_return_if_fail (PK_IS_CONTROL (control));
 	g_return_if_fail (callback != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (control), callback, user_data, pk_control_get_transaction_list_async);
 
@@ -1175,6 +1181,7 @@ pk_control_get_time_since_action_async (PkControl *control, PkRoleEnum role, GCa
 
 	g_return_if_fail (PK_IS_CONTROL (control));
 	g_return_if_fail (callback != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (control), callback, user_data, pk_control_get_time_since_action_async);
 
@@ -1334,6 +1341,7 @@ pk_control_can_authorize_async (PkControl *control, const gchar *action_id, GCan
 
 	g_return_if_fail (PK_IS_CONTROL (control));
 	g_return_if_fail (callback != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (control), callback, user_data, pk_control_can_authorize_async);
 
@@ -1740,6 +1748,7 @@ pk_control_get_properties_async (PkControl *control, GCancellable *cancellable,
 
 	g_return_if_fail (PK_IS_CONTROL (control));
 	g_return_if_fail (callback != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (control), callback, user_data, pk_control_get_properties_async);
 
diff --git a/lib/packagekit-glib2/pk-task.c b/lib/packagekit-glib2/pk-task.c
index 12cddf8..dccaec8 100644
--- a/lib/packagekit-glib2/pk-task.c
+++ b/lib/packagekit-glib2/pk-task.c
@@ -938,6 +938,7 @@ pk_task_install_packages_async (PkTask *task, gchar **package_ids, GCancellable
 
 	g_return_if_fail (PK_IS_TASK (task));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async);
 
@@ -992,6 +993,7 @@ pk_task_update_packages_async (PkTask *task, gchar **package_ids, GCancellable *
 
 	g_return_if_fail (PK_IS_CLIENT (task));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_update_packages_async);
 
@@ -1049,6 +1051,7 @@ pk_task_remove_packages_async (PkTask *task, gchar **package_ids, gboolean allow
 
 	g_return_if_fail (PK_IS_CLIENT (task));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_remove_packages_async);
 
@@ -1104,6 +1107,7 @@ pk_task_install_files_async (PkTask *task, gchar **files, GCancellable *cancella
 
 	g_return_if_fail (PK_IS_CLIENT (task));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_files_async);
 
@@ -1160,6 +1164,7 @@ pk_task_update_system_async (PkTask *task, GCancellable *cancellable,
 
 	g_return_if_fail (PK_IS_CLIENT (task));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_update_system_async);
 
@@ -1209,6 +1214,7 @@ pk_task_resolve_async (PkTask *task, PkBitfield filters, gchar **packages, GCanc
 
 	g_return_if_fail (PK_IS_TASK (task));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async);
 
@@ -1261,6 +1267,7 @@ pk_task_search_names_async (PkTask *task, PkBitfield filters, gchar **values, GC
 
 	g_return_if_fail (PK_IS_TASK (task));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async);
 
@@ -1313,6 +1320,7 @@ pk_task_search_details_async (PkTask *task, PkBitfield filters, gchar **values,
 
 	g_return_if_fail (PK_IS_TASK (task));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async);
 
@@ -1365,6 +1373,7 @@ pk_task_search_groups_async (PkTask *task, PkBitfield filters, gchar **values, G
 
 	g_return_if_fail (PK_IS_TASK (task));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async);
 
@@ -1417,6 +1426,7 @@ pk_task_search_files_async (PkTask *task, PkBitfield filters, gchar **values, GC
 
 	g_return_if_fail (PK_IS_TASK (task));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async);
 
@@ -1468,6 +1478,7 @@ pk_task_get_details_async (PkTask *task, gchar **package_ids, GCancellable *canc
 
 	g_return_if_fail (PK_IS_TASK (task));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async);
 
@@ -1518,6 +1529,7 @@ pk_task_get_update_detail_async (PkTask *task, gchar **package_ids, GCancellable
 
 	g_return_if_fail (PK_IS_TASK (task));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async);
 
@@ -1569,6 +1581,7 @@ pk_task_download_packages_async (PkTask *task, gchar **package_ids, const gchar
 
 	g_return_if_fail (PK_IS_TASK (task));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async);
 
@@ -1620,6 +1633,7 @@ pk_task_get_updates_async (PkTask *task, PkBitfield filters, GCancellable *cance
 
 	g_return_if_fail (PK_IS_TASK (task));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async);
 
@@ -1672,6 +1686,7 @@ pk_task_get_depends_async (PkTask *task, PkBitfield filters, gchar **package_ids
 
 	g_return_if_fail (PK_IS_TASK (task));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async);
 
@@ -1724,6 +1739,7 @@ pk_task_get_packages_async (PkTask *task, PkBitfield filters, GCancellable *canc
 
 	g_return_if_fail (PK_IS_TASK (task));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async);
 
@@ -1776,6 +1792,7 @@ pk_task_get_requires_async (PkTask *task, PkBitfield filters, gchar **package_id
 
 	g_return_if_fail (PK_IS_TASK (task));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async);
 
@@ -1830,6 +1847,7 @@ pk_task_what_provides_async (PkTask *task, PkBitfield filters, PkProvidesEnum pr
 
 	g_return_if_fail (PK_IS_TASK (task));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async);
 
@@ -1882,6 +1900,7 @@ pk_task_get_files_async (PkTask *task, gchar **package_ids, GCancellable *cancel
 
 	g_return_if_fail (PK_IS_TASK (task));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async);
 
@@ -1931,6 +1950,7 @@ pk_task_get_categories_async (PkTask *task, GCancellable *cancellable,
 
 	g_return_if_fail (PK_IS_TASK (task));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async);
 
@@ -1980,6 +2000,7 @@ pk_task_refresh_cache_async (PkTask *task, gboolean force, GCancellable *cancell
 
 	g_return_if_fail (PK_IS_TASK (task));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async);
 
@@ -2030,6 +2051,7 @@ pk_task_rollback_async (PkTask *task, const gchar *transaction_id, GCancellable
 
 	g_return_if_fail (PK_IS_TASK (task));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async);
 
@@ -2080,6 +2102,7 @@ pk_task_get_repo_list_async (PkTask *task, PkBitfield filters, GCancellable *can
 
 	g_return_if_fail (PK_IS_TASK (task));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async);
 
@@ -2131,6 +2154,7 @@ pk_task_repo_enable_async (PkTask *task, const gchar *repo_id, gboolean enabled,
 
 	g_return_if_fail (PK_IS_TASK (task));
 	g_return_if_fail (callback_ready != NULL);
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
 	res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async);
 
commit 8ad945da5819a967b926510ce1c960036d3c4342
Author: Zhang Qiang <qiang.z.zhang at intel.com>
Date:   Tue Sep 21 15:33:31 2010 +0800

    Send correct network state for connman end
    
    Currently, packagekitd accept a bool type of connman network state, and
    this patch transfer the correct connman network state (offline/online)
    to packagekitd. Without this patch packagekitd/application will get the
    incorrect network state notification.

diff --git a/src/pk-network-stack-connman.c b/src/pk-network-stack-connman.c
index a05b1d8..f28150c 100644
--- a/src/pk-network-stack-connman.c
+++ b/src/pk-network-stack-connman.c
@@ -179,7 +179,7 @@ static void
 pk_network_stack_connman_state_changed (DBusGProxy *proxy, const char *property,
 					GValue *value, gpointer user_data)
 {
-	gboolean ret;
+	PkNetworkEnum network_state;
 	PkNetworkStackConnman *nstack_connman = (PkNetworkStackConnman *) user_data;
 
 	g_return_if_fail (PK_IS_NETWORK_STACK_CONNMAN (nstack_connman));
@@ -189,12 +189,11 @@ pk_network_stack_connman_state_changed (DBusGProxy *proxy, const char *property,
 
 		state = g_value_dup_string (value);
 		if (g_str_equal (state, "online") == TRUE)
-			ret = TRUE;
+			network_state = PK_NETWORK_ENUM_ONLINE;
 		else
-			ret = FALSE;
-		/* TODO: this is a PkNetworkState, not a gboolean */
-		egg_debug ("emitting network-state-changed: %s", pk_network_enum_to_string (ret));
-		g_signal_emit_by_name (PK_NETWORK_STACK (nstack_connman), "state-changed", ret);
+			network_state = PK_NETWORK_ENUM_OFFLINE;
+		egg_debug ("emitting network-state-changed: %s", pk_network_enum_to_string (network_state));
+		g_signal_emit_by_name (PK_NETWORK_STACK (nstack_connman), "state-changed", network_state);
 	}
 
 }
commit da4e08f88e97c3663dc1a186b435af905ee25704
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Sep 20 16:40:31 2010 +0100

    yum: for some reason yum needs to download the packagelists at init, so mark the download as cancellable. Fixes fd#30276

diff --git a/backends/yum/yumBackend.py b/backends/yum/yumBackend.py
index 7490644..92f9095 100755
--- a/backends/yum/yumBackend.py
+++ b/backends/yum/yumBackend.py
@@ -2951,6 +2951,9 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
     def _check_init(self, lazy_cache=False):
         '''Just does the caching tweaks'''
 
+        # this entire section can be cancelled
+        self.allow_cancel(True)
+
         # clear previous transaction data
         self.yumbase._tsInfo = None
 
commit 0c134d971b8d93ad8c768f706affab280bcbbde2
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Sep 20 16:16:07 2010 +0100

    glib: Do not return simulation failures as critical errors

diff --git a/lib/packagekit-glib2/pk-task.c b/lib/packagekit-glib2/pk-task.c
index 53d36a3..12cddf8 100644
--- a/lib/packagekit-glib2/pk-task.c
+++ b/lib/packagekit-glib2/pk-task.c
@@ -304,7 +304,6 @@ pk_task_simulate_ready_cb (GObject *source_object, GAsyncResult *res, PkTaskStat
 	PkResults *results;
 	PkPackageSack *sack = NULL;
 	guint length;
-	PkError *error_code;
 	guint idx = 0;
 	guint i;
 	GPtrArray *array = NULL;
@@ -343,13 +342,11 @@ pk_task_simulate_ready_cb (GObject *source_object, GAsyncResult *res, PkTaskStat
 	/* get exit code */
 	state->exit_enum = pk_results_get_exit_code (state->results);
 	if (state->exit_enum != PK_EXIT_ENUM_SUCCESS) {
-		error_code = pk_results_get_error_code (state->results);
-		/* TODO: convert the PkErrorEnum to a PK_CLIENT_ERROR_* enum */
-		error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED,
-				     "could not do simulate: %s", pk_error_get_details (error_code));
-		pk_task_generic_state_finish (state, error);
-		g_error_free (error);
-		g_object_unref (error_code);
+		/* we 'fail' with success so the appication gets a
+		 * chance to process the PackageKit-specific
+		 * ErrorCode enumerated value and detail. */
+		state->ret = TRUE;
+		pk_task_generic_state_finish (state, NULL);
 		goto out;
 	}
 
commit 39e15a5484af8ae110a72db6936675c6c7513d41
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Sep 20 16:13:52 2010 +0100

    glib: only return packages for catalogs that are _not_ installed

diff --git a/lib/packagekit-glib2/pk-catalog.c b/lib/packagekit-glib2/pk-catalog.c
index 61d4922..feaaf3c 100644
--- a/lib/packagekit-glib2/pk-catalog.c
+++ b/lib/packagekit-glib2/pk-catalog.c
@@ -455,7 +455,10 @@ pk_catalog_do_resolve (PkCatalogState *state)
 	data = pk_ptr_array_to_strv (state->array_packages);
 	dbg = g_strjoinv ("&", data);
 	egg_debug ("searching for %s", dbg);
-	pk_client_resolve_async (state->catalog->priv->client, pk_bitfield_from_enums (PK_FILTER_ENUM_ARCH, PK_FILTER_ENUM_NEWEST, -1), data,
+	pk_client_resolve_async (state->catalog->priv->client,
+				 pk_bitfield_from_enums (PK_FILTER_ENUM_ARCH,
+							 PK_FILTER_ENUM_NOT_INSTALLED,
+							 PK_FILTER_ENUM_NEWEST, -1), data,
 				 state->cancellable, state->progress_callback, state->progress_user_data,
 				 (GAsyncReadyCallback) pk_catalog_resolve_ready_cb, state);
 	g_free (dbg);
commit e258ac2b920efb3d9aab14548907541711c30f68
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Sep 20 16:13:20 2010 +0100

    glib: do not crash the client if a catalog file has both file and package sections

diff --git a/lib/packagekit-glib2/pk-catalog.c b/lib/packagekit-glib2/pk-catalog.c
index 64a311b..61d4922 100644
--- a/lib/packagekit-glib2/pk-catalog.c
+++ b/lib/packagekit-glib2/pk-catalog.c
@@ -530,12 +530,10 @@ pk_catalog_lookup_async (PkCatalog *catalog, const gchar *filename, GCancellable
 	if (state->array_packages->len > 0) {
 		pk_catalog_do_resolve (state);
 		goto out;
-	}
-	if (state->array_files->len > 0) {
+	} else if (state->array_files->len > 0) {
 		pk_catalog_do_search_files (state);
 		goto out;
-	}
-	if (state->array_provides->len > 0) {
+	} else if (state->array_provides->len > 0) {
 		pk_catalog_do_what_provides (state);
 		goto out;
 	}
commit dcb3369660a926f69f48ffa288163ae1505db11a
Author: Hedayat Vatankhah <hedayat at grad.com>
Date:   Mon Sep 20 11:50:08 2010 +0100

    yum: Fix the split media handling in PackageKit yum backend
    
    Signed-off-by: Richard Hughes <richard at hughsie.com>

diff --git a/backends/yum/yumBackend.py b/backends/yum/yumBackend.py
index 14a022d..7490644 100755
--- a/backends/yum/yumBackend.py
+++ b/backends/yum/yumBackend.py
@@ -3292,7 +3292,7 @@ class PackageKitYumBase(yum.YumBase):
             else:
                 raise PkError(ERROR_INTERNAL_ERROR, _format_str(traceback.format_exc()))
 
-    def _media_find_root(self, media_id, disc_number=1):
+    def _media_find_root(self, media_id, disc_number=-1):
         """ returns the root "/media/Fedora Extras" or None """
 
         # search all the disks
@@ -3322,13 +3322,14 @@ class PackageKitYumBase(yum.YumBase):
                 continue
 
             # disc number can be random things like 'ALL'
-            disc_number_tmp = 1
-            try:
-                disc_number_tmp = int(lines[3].strip())
-            except ValueError, e:
-                pass
-            if disc_number_tmp != disc_number:
-                continue
+            if disc_number != -1:
+                disc_number_tmp = 1
+                try:
+                    disc_number_tmp = int(lines[3].strip())
+                except ValueError, e:
+                    pass
+                if disc_number_tmp != disc_number:
+                    continue
             return root
 
         # nothing remaining
commit facb22c96a2dd6afa1bc80fbb5984affa3efb9be
Author: Hedayat Vatankhah <hedayat at grad.com>
Date:   Mon Sep 20 11:49:28 2010 +0100

    When prompting for media, include the disc number
    
    Signed-off-by: Richard Hughes <richard at hughsie.com>

diff --git a/backends/yum/yumBackend.py b/backends/yum/yumBackend.py
index b261308..14a022d 100755
--- a/backends/yum/yumBackend.py
+++ b/backends/yum/yumBackend.py
@@ -3351,7 +3351,7 @@ class PackageKitYumBase(yum.YumBase):
 
         # we have to send a message to the client
         if not root:
-            name = kwargs["name"]
+            name = "%s Volume #%s" %(kwargs["name"], kwargs["discnum"])
             self.backend.media_change_required(MEDIA_TYPE_DISC, name, name)
             self.backend.error(ERROR_MEDIA_CHANGE_REQUIRED,
                                "Insert media labeled '%s' or disable media repos" % name,
commit 1aea94019e010586aa4b39ad07f7f7fd8331a59b
Author: Zhang Qiang <qiang.z.zhang at intel.com>
Date:   Fri Sep 17 16:20:49 2010 +0800

    Enable proxy for zypp backend
    
    Implement 'backend_transaction_start' and 'backend_transaction_stop' for
    zypp backend, where proxy info is set/unset for individual transaction.
    This proxy info can be used in zypp-backend->curl.

diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp
index 6cd6888..5189f8d 100644
--- a/backends/zypp/pk-backend-zypp.cpp
+++ b/backends/zypp/pk-backend-zypp.cpp
@@ -22,6 +22,7 @@
 #include <gmodule.h>
 #include <glib.h>
 #include <pk-backend.h>
+#include <pk-backend-spawn.h>
 #include <unistd.h>
 #include <egg-debug.h>
 #include <string>
@@ -1878,6 +1879,47 @@ backend_get_mime_types (PkBackend *backend)
 	return g_strdup ("application/x-rpm");
 }
 
+/**
+ * backend_transaction_start:
+ */
+static void
+backend_transaction_start (PkBackend *backend)
+{
+	gchar *proxy_http;
+	gchar *proxy_ftp;
+	gchar *uri;
+
+	/* http_proxy */
+	proxy_http = pk_backend_get_proxy_http (backend);
+	if (!egg_strzero (proxy_http)) {
+		uri = pk_backend_spawn_convert_uri (proxy_http);
+		g_setenv ("http_proxy", uri, TRUE);
+		g_free (uri);
+	}
+
+	/* ftp_proxy */
+	proxy_ftp = pk_backend_get_proxy_ftp (backend);
+	if (!egg_strzero (proxy_ftp)) {
+		uri = pk_backend_spawn_convert_uri (proxy_ftp);
+		g_setenv ("ftp_proxy", uri, TRUE);
+		g_free (uri);
+	}
+
+	g_free (proxy_http);
+	g_free (proxy_ftp);
+}
+
+/**
+ * backend_transaction_stop:
+ */
+static void
+backend_transaction_stop (PkBackend *backend)
+{
+	/* unset proxy info for this transaction */
+	g_unsetenv ("http_proxy");
+	g_unsetenv ("ftp_proxy");
+}
+
 extern "C" PK_BACKEND_OPTIONS (
 	"Zypp",					/* description */
 	"Boyd Timothy <btimothy at gmail.com>, "
@@ -1921,7 +1963,7 @@ extern "C" PK_BACKEND_OPTIONS (
 	backend_simulate_install_packages,	/* simulate_install_packages */
 	backend_simulate_remove_packages,	/* simulate_remove_packages */
 	backend_simulate_update_packages,	/* simulate_update_packages */
-	NULL,					/* transaction_start */
-	NULL					/* transaction_stop */
+	backend_transaction_start,		/* transaction_start */
+	backend_transaction_stop		/* transaction_stop */
 );
 
commit 68eb126106c26d324645fe0a3d0f1d982ba661e5
Author: Daniel Nicoletti <dantti85-pk at yahoo.com.br>
Date:   Fri Sep 17 01:40:58 2010 -0300

    packagekit-qt: Forgot to setHints() on new constructor

diff --git a/lib/packagekit-qt/src/transaction.cpp b/lib/packagekit-qt/src/transaction.cpp
index 3868c2c..568ddd7 100644
--- a/lib/packagekit-qt/src/transaction.cpp
+++ b/lib/packagekit-qt/src/transaction.cpp
@@ -87,6 +87,7 @@ Transaction::Transaction(const QString &tid, QObject *parent)
     } else {
         d->error = Client::NoError;
         Client::instance()->d_ptr->runningTransactions.insert(d->tid, this);
+        setHints(Client::instance()->d_ptr->hints);
     }
 
     connect(d->p, SIGNAL(Changed()),
commit c79e2f6f705d45379c6fab9939681a3aa34daaa5
Author: Daniel Nicoletti <dantti85-pk at yahoo.com.br>
Date:   Fri Sep 17 00:52:14 2010 -0300

    aptcc: Updated calls not to use deprecated apt code

diff --git a/backends/aptcc/apt.cpp b/backends/aptcc/apt.cpp
index a36145f..c4089de 100644
--- a/backends/aptcc/apt.cpp
+++ b/backends/aptcc/apt.cpp
@@ -1450,7 +1450,7 @@ bool aptcc::runTransaction(vector<pair<pkgCache::PkgIterator, pkgCache::VerItera
 	OpTextProgress Prog(*_config);
 	int timeout = 10;
 	// TODO test this
-	while (Cache.Open(Prog, WithLock) == false) {
+	while (Cache.Open(&Prog, WithLock) == false) {
 		// failed to open cache, try checkDeps then..
 		// || Cache.CheckDeps(CmdL.FileSize() != 1) == false
 		if (WithLock == false || (timeout <= 0)) {
@@ -1601,7 +1601,8 @@ bool aptcc::installPackages(pkgCacheFile &Cache)
 	AcqPackageKitStatus Stat(this, m_backend, _cancel);
 
 	// get a fetcher
-	pkgAcquire fetcher(&Stat);
+	pkgAcquire fetcher;
+	fetcher.Setup(&Stat);
 
 	// Create the package manager and prepare to download
 	SPtr<pkgPackageManager> PM= _system->CreatePM(Cache);
diff --git a/backends/aptcc/pk-backend-aptcc.cpp b/backends/aptcc/pk-backend-aptcc.cpp
index 60c1274..f4f80d5 100644
--- a/backends/aptcc/pk-backend-aptcc.cpp
+++ b/backends/aptcc/pk-backend-aptcc.cpp
@@ -402,7 +402,7 @@ backend_get_or_update_system_thread (PkBackend *backend)
 	OpTextProgress Prog(*_config);
 	int timeout = 10;
 	// TODO test this
-	while (Cache.Open(Prog, !getUpdates) == false) {
+	while (Cache.Open(&Prog, !getUpdates) == false) {
 		// failed to open cache, try checkDeps then..
 		// || Cache.CheckDeps(CmdL.FileSize() != 1) == false
 		if (getUpdates == true || (timeout <= 0)) {
@@ -607,7 +607,8 @@ backend_download_packages_thread (PkBackend *backend)
 	AcqPackageKitStatus Stat(m_apt, backend, _cancel);
 
 	// get a fetcher
-	pkgAcquire fetcher(&Stat);
+	pkgAcquire fetcher;
+	fetcher.Setup(&Stat);
 	string filelist;
 	gchar *pi;
 
@@ -747,7 +748,7 @@ backend_refresh_cache_thread (PkBackend *backend)
 	// Rebuild the cache.
 	pkgCacheFile Cache;
 	OpTextProgress Prog(*_config);
-	if (Cache.BuildCaches(Prog, true) == false) {
+	if (Cache.BuildCaches(&Prog, true) == false) {
 		if (_error->PendingError() == true) {
 			show_errors(backend, PK_ERROR_ENUM_CANNOT_GET_LOCK);
 		}
commit d923f027e0f6c03de49887c9bdec5dad12def73c
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu Sep 16 16:45:14 2010 +0100

    Don't call back into the daemon (from the daemon) when checking service packs. Fixes rh#634628
    
    This fixes a deadlock when the user tries to install a service pack.

diff --git a/lib/packagekit-glib2/pk-common.c b/lib/packagekit-glib2/pk-common.c
index 1e9de6e..71c3d60 100644
--- a/lib/packagekit-glib2/pk-common.c
+++ b/lib/packagekit-glib2/pk-common.c
@@ -32,6 +32,7 @@
 #include <stdio.h>
 
 #include <string.h>
+#include <sys/utsname.h>
 
 #include <glib.h>
 #include <packagekit-glib2/pk-common.h>
@@ -163,3 +164,201 @@ pk_ptr_array_to_strv (GPtrArray *array)
 
 	return value;
 }
+
+/**
+ * pk_get_os_release:
+ *
+ * Return value: The current OS release, e.g. "7.2-RELEASE"
+ * Note: Don't use this function if you can get this data from /etc/foo
+ **/
+static gchar *
+pk_get_distro_id_os_release (void)
+{
+	gint retval;
+	struct utsname buf;
+
+	retval = uname (&buf);
+	if (retval != 0)
+		return g_strdup ("unknown");
+	return g_strdup (buf.release);
+}
+
+/**
+ * pk_get_machine_type:
+ *
+ * Return value: The current machine ID, e.g. "i386"
+ * Note: Don't use this function if you can get this data from /etc/foo
+ **/
+static gchar *
+pk_get_distro_id_machine_type (void)
+{
+	gint retval;
+	struct utsname buf;
+
+	retval = uname (&buf);
+	if (retval != 0)
+		return g_strdup ("unknown");
+	return g_strdup (buf.machine);
+}
+
+/**
+ * pk_get_distro_id:
+ *
+ * Return value: the distro-id, typically "distro;version;arch"
+ **/
+gchar *
+pk_get_distro_id (void)
+{
+	guint i;
+	gboolean ret;
+	gchar *contents = NULL;
+	gchar *arch = NULL;
+	gchar *version = NULL;
+	gchar **split = NULL;
+	gchar *distro = NULL;
+	gchar *distro_id = NULL;
+
+	/* The distro id property should have the
+	   format "distro;version;arch" as this is
+	   used to determine if a specific package
+	   can be installed on a certain machine.
+	   For instance, x86_64 packages cannot be
+	   installed on a i386 machine.
+	*/
+
+	/* we can't get arch from /etc */
+	arch = pk_get_distro_id_machine_type ();
+
+	/* check for fedora */
+	ret = g_file_get_contents ("/etc/fedora-release", &contents, NULL, NULL);
+	if (ret) {
+		/* Fedora release 8.92 (Rawhide) */
+		split = g_strsplit (contents, " ", 0);
+		if (split == NULL)
+			goto out;
+
+		/* complete! */
+		distro_id = g_strdup_printf ("fedora;%s;%s", split[2], arch);
+		goto out;
+	}
+
+	/* check for suse */
+	ret = g_file_get_contents ("/etc/SuSE-release", &contents, NULL, NULL);
+	if (ret) {
+		/* replace with spaces: openSUSE 11.0 (i586) Alpha3\nVERSION = 11.0 */
+		g_strdelimit (contents, "()\n", ' ');
+
+		/* openSUSE 11.0  i586  Alpha3 VERSION = 11.0 */
+		split = g_strsplit (contents, " ", 0);
+		if (split == NULL)
+			goto out;
+
+		/* complete! */
+		distro_id = g_strdup_printf ("suse;%s-%s;%s", split[1], split[3], arch);
+		goto out;
+	}
+
+	/* check for meego */
+	ret = g_file_get_contents ("/etc/meego-release", &contents, NULL, NULL);
+	if (ret) {
+		/* Meego release 1.0 (MeeGo) */
+		split = g_strsplit (contents, " ", 0);
+		if (split == NULL)
+			goto out;
+
+		/* complete! */
+		distro_id = g_strdup_printf ("meego;%s;%s", split[2], arch);
+		goto out;
+	}
+
+	/* check for foresight or foresight derivatives */
+	ret = g_file_get_contents ("/etc/distro-release", &contents, NULL, NULL);
+	if (ret) {
+		/* Foresight Linux 2 */
+		split = g_strsplit (contents, " ", 0);
+		if (split == NULL)
+			goto out;
+
+		/* complete! */
+		distro_id = g_strdup_printf ("foresight;%s;%s", split[2], arch);
+		goto out;
+	}
+
+	/* check for PLD */
+	ret = g_file_get_contents ("/etc/pld-release", &contents, NULL, NULL);
+	if (ret) {
+		/* 2.99 PLD Linux (Th) */
+		split = g_strsplit (contents, " ", 0);
+		if (split == NULL)
+			goto out;
+
+		/* complete! */
+		distro_id = g_strdup_printf ("pld;%s;%s", split[0], arch);
+		goto out;
+	}
+
+	/* check for Arch */
+	ret = g_file_test ("/etc/arch-release", G_FILE_TEST_EXISTS);
+	if (ret) {
+		/* complete! */
+		distro_id = g_strdup_printf ("arch;current;%s", arch);
+		goto out;
+	}
+
+	/* check for LSB */
+	ret = g_file_get_contents ("/etc/lsb-release", &contents, NULL, NULL);
+	if (ret) {
+		/* split by lines */
+		split = g_strsplit (contents, "\n", -1);
+		for (i=0; split[i] != NULL; i++) {
+			if (g_str_has_prefix (split[i], "DISTRIB_ID="))
+				distro = g_ascii_strdown (&split[i][11], -1);
+			if (g_str_has_prefix (split[i], "DISTRIB_RELEASE="))
+				version = g_ascii_strdown (&split[i][16], -1);
+		}
+
+		/* complete! */
+		distro_id = g_strdup_printf ("%s;%s;%s", distro, version, arch);
+		goto out;
+	}
+
+	/* check for Debian or Debian derivatives */
+	ret = g_file_get_contents ("/etc/debian_version", &contents, NULL, NULL);
+	if (ret) {
+		/* remove "\n": "squeeze/sid\n" */
+		g_strdelimit (contents, "\n", '\0');
+		/* removes leading and trailing whitespace */
+		g_strstrip (contents);
+
+		/* complete! */
+		distro_id = g_strdup_printf ("debian;%s;%s", contents, arch);
+		goto out;
+	}
+
+#ifdef __FreeBSD__
+	ret = TRUE;
+#endif
+	/* FreeBSD */
+	if (ret) {
+		/* we can't get version from /etc */
+		version = pk_get_distro_id_os_release ();
+		if (version == NULL)
+			goto out;
+
+		/* 7.2-RELEASE */
+		split = g_strsplit (version, "-", 0);
+		if (split == NULL)
+			goto out;
+
+		/* complete! */
+		distro_id = g_strdup_printf ("freebsd;%s;%s", split[0], arch);
+		goto out;
+	}
+out:
+	g_strfreev (split);
+	g_free (version);
+	g_free (distro);
+	g_free (arch);
+	g_free (contents);
+	return distro_id;
+}
diff --git a/lib/packagekit-glib2/pk-common.h b/lib/packagekit-glib2/pk-common.h
index 2a9668d..1f0800b 100644
--- a/lib/packagekit-glib2/pk-common.h
+++ b/lib/packagekit-glib2/pk-common.h
@@ -81,6 +81,7 @@ gchar		*pk_iso8601_present			(void)
 							 G_GNUC_WARN_UNUSED_RESULT;
 gchar		*pk_iso8601_from_date			(const GDate	*date);
 GDate		*pk_iso8601_to_date			(const gchar	*iso_date);
+gchar		*pk_get_distro_id			(void);
 
 G_END_DECLS
 
diff --git a/lib/packagekit-glib2/pk-service-pack.c b/lib/packagekit-glib2/pk-service-pack.c
index d6c3a40..72e27e6 100644
--- a/lib/packagekit-glib2/pk-service-pack.c
+++ b/lib/packagekit-glib2/pk-service-pack.c
@@ -49,7 +49,6 @@
 #include <packagekit-glib2/pk-client.h>
 #include <packagekit-glib2/pk-package-id.h>
 #include <packagekit-glib2/pk-package-ids.h>
-#include <packagekit-glib2/pk-control-sync.h>
 
 #include "egg-debug.h"
 #include "egg-string.h"
@@ -147,7 +146,6 @@ pk_service_pack_check_metadata_file (const gchar *full_path, GError **error)
 	gchar *type = NULL;
 	gchar *distro_id = NULL;
 	gchar *distro_id_us = NULL;
-	PkControl *control = NULL;
 
 	/* load the file */
 	file = g_key_file_new ();
@@ -183,28 +181,13 @@ pk_service_pack_check_metadata_file (const gchar *full_path, GError **error)
 		goto out;
 	}
 
-	/* get this system id */
-	control = pk_control_new ();
-	ret = pk_control_get_properties (control, NULL, &error_local);
-	if (!ret) {
-		egg_error ("Failed to contact PackageKit: %s", error_local->message);
-		g_error_free (error_local);
-		goto out;
-	}
-
-	/* get data */
-	g_object_get (control,
-		      "distro-id", &distro_id_us,
-		      NULL);
-
 	/* do we match? */
+	distro_id_us = pk_get_distro_id ();
 	ret = (g_strcmp0 (distro_id_us, distro_id) == 0);
 	if (!ret)
 		g_set_error (error, 1, 0, "distro id did not match %s == %s", distro_id_us, distro_id);
 
 out:
-	if (control != NULL)
-		g_object_unref (control);
 	g_key_file_free (file);
 	g_free (type);
 	g_free (distro_id);
@@ -467,8 +450,6 @@ pk_service_pack_create_metadata_file (PkServicePackState *state, const gchar *fi
 	GError *error = NULL;
 	GKeyFile *file = NULL;
 	gchar *data = NULL;
-	PkControl *control;
-	GError *error_local = NULL;
 
 	g_return_val_if_fail (state->filename != NULL, FALSE);
 	g_return_val_if_fail (state->type != PK_SERVICE_PACK_TYPE_UNKNOWN, FALSE);
@@ -476,18 +457,7 @@ pk_service_pack_create_metadata_file (PkServicePackState *state, const gchar *fi
 	file = g_key_file_new ();
 
 	/* get this system id */
-	control = pk_control_new ();
-	ret = pk_control_get_properties (control, NULL, &error_local);
-	if (!ret) {
-		egg_error ("Failed to contact PackageKit: %s", error_local->message);
-		g_error_free (error_local);
-		goto out;
-	}
-
-	/* get needed data */
-	g_object_get (control,
-		      "distro-id", &distro_id,
-		      NULL);
+	distro_id = pk_get_distro_id ();
 	if (distro_id == NULL)
 		goto out;
 	iso_time = pk_iso8601_present ();
@@ -518,7 +488,6 @@ pk_service_pack_create_metadata_file (PkServicePackState *state, const gchar *fi
 		goto out;
 	}
 out:
-	g_object_unref (control);
 	g_key_file_free (file);
 	g_free (data);
 	g_free (distro_id);
diff --git a/src/pk-engine.c b/src/pk-engine.c
index 0f7c410..d9d6d51 100644
--- a/src/pk-engine.c
+++ b/src/pk-engine.c
@@ -298,204 +298,6 @@ out:
 }
 
 /**
- * pk_get_os_release:
- *
- * Return value: The current OS release, e.g. "7.2-RELEASE"
- * Note: Don't use this function if you can get this data from /etc/foo
- **/
-static gchar *
-pk_engine_get_os_release (void)
-{
-	gint retval;
-	struct utsname buf;
-
-	retval = uname (&buf);
-	if (retval != 0)
-		return g_strdup ("unknown");
-	return g_strdup (buf.release);
-}
-
-/**
- * pk_get_machine_type:
- *
- * Return value: The current machine ID, e.g. "i386"
- * Note: Don't use this function if you can get this data from /etc/foo
- **/
-static gchar *
-pk_engine_get_machine_type (void)
-{
-	gint retval;
-	struct utsname buf;
-
-	retval = uname (&buf);
-	if (retval != 0)
-		return g_strdup ("unknown");
-	return g_strdup (buf.machine);
-}
-
-/**
- * pk_engine_get_distro_id:
- **/
-static gchar *
-pk_engine_get_distro_id (PkEngine *engine)
-{
-	guint i;
-	gboolean ret;
-	gchar *contents = NULL;
-	gchar *arch = NULL;
-	gchar *version = NULL;
-	gchar **split = NULL;
-	gchar *distro = NULL;
-	gchar *distro_id = NULL;
-
-	g_return_val_if_fail (PK_IS_ENGINE (engine), NULL);
-
-	/* The distro id property should have the
-	   format "distro;version;arch" as this is
-	   used to determine if a specific package
-	   can be installed on a certain machine.
-	   For instance, x86_64 packages cannot be
-	   installed on a i386 machine.
-	*/
-
-	/* we can't get arch from /etc */
-	arch = pk_engine_get_machine_type ();
-
-	/* check for fedora */
-	ret = g_file_get_contents ("/etc/fedora-release", &contents, NULL, NULL);
-	if (ret) {
-		/* Fedora release 8.92 (Rawhide) */
-		split = g_strsplit (contents, " ", 0);
-		if (split == NULL)
-			goto out;
-
-		/* complete! */
-		distro_id = g_strdup_printf ("fedora;%s;%s", split[2], arch);
-		goto out;
-	}
-
-	/* check for suse */
-	ret = g_file_get_contents ("/etc/SuSE-release", &contents, NULL, NULL);
-	if (ret) {
-		/* replace with spaces: openSUSE 11.0 (i586) Alpha3\nVERSION = 11.0 */
-		g_strdelimit (contents, "()\n", ' ');
-
-		/* openSUSE 11.0  i586  Alpha3 VERSION = 11.0 */
-		split = g_strsplit (contents, " ", 0);
-		if (split == NULL)
-			goto out;
-
-		/* complete! */
-		distro_id = g_strdup_printf ("suse;%s-%s;%s", split[1], split[3], arch);
-		goto out;
-	}
-
-	/* check for meego */
-	ret = g_file_get_contents ("/etc/meego-release", &contents, NULL, NULL);
-	if (ret) {
-		/* Meego release 1.0 (MeeGo) */
-		split = g_strsplit (contents, " ", 0);
-		if (split == NULL)
-			goto out;
-
-		/* complete! */
-		distro_id = g_strdup_printf ("meego;%s;%s", split[2], arch);
-		goto out;
-	}
-
-	/* check for foresight or foresight derivatives */
-	ret = g_file_get_contents ("/etc/distro-release", &contents, NULL, NULL);
-	if (ret) {
-		/* Foresight Linux 2 */
-		split = g_strsplit (contents, " ", 0);
-		if (split == NULL)
-			goto out;
-
-		/* complete! */
-		distro_id = g_strdup_printf ("foresight;%s;%s", split[2], arch);
-		goto out;
-	}
-
-	/* check for PLD */
-	ret = g_file_get_contents ("/etc/pld-release", &contents, NULL, NULL);
-	if (ret) {
-		/* 2.99 PLD Linux (Th) */
-		split = g_strsplit (contents, " ", 0);
-		if (split == NULL)
-			goto out;
-
-		/* complete! */
-		distro_id = g_strdup_printf ("pld;%s;%s", split[0], arch);
-		goto out;
-	}
-
-	/* check for Arch */
-	ret = g_file_test ("/etc/arch-release", G_FILE_TEST_EXISTS);
-	if (ret) {
-		/* complete! */
-		distro_id = g_strdup_printf ("arch;current;%s", arch);
-		goto out;
-	}
-
-	/* check for LSB */
-	ret = g_file_get_contents ("/etc/lsb-release", &contents, NULL, NULL);
-	if (ret) {
-		/* split by lines */
-		split = g_strsplit (contents, "\n", -1);
-		for (i=0; split[i] != NULL; i++) {
-			if (g_str_has_prefix (split[i], "DISTRIB_ID="))
-				distro = g_ascii_strdown (&split[i][11], -1);
-			if (g_str_has_prefix (split[i], "DISTRIB_RELEASE="))
-				version = g_ascii_strdown (&split[i][16], -1);
-		}
-
-		/* complete! */
-		distro_id = g_strdup_printf ("%s;%s;%s", distro, version, arch);
-		goto out;
-	}
-
-	/* check for Debian or Debian derivatives */
-	ret = g_file_get_contents ("/etc/debian_version", &contents, NULL, NULL);
-	if (ret) {
-		/* remove "\n": "squeeze/sid\n" */
-		g_strdelimit (contents, "\n", '\0');
-		/* removes leading and trailing whitespace */
-		g_strstrip (contents);
-
-		/* complete! */
-		distro_id = g_strdup_printf ("debian;%s;%s", contents, arch);
-		goto out;
-	}
-
-#ifdef __FreeBSD__
-	ret = TRUE;
-#endif
-	/* FreeBSD */
-	if (ret) {
-		/* we can't get version from /etc */
-		version = pk_engine_get_os_release ();
-		if (version == NULL)
-			goto out;
-
-		/* 7.2-RELEASE */
-		split = g_strsplit (version, "-", 0);
-		if (split == NULL)
-			goto out;
-
-		/* complete! */
-		distro_id = g_strdup_printf ("freebsd;%s;%s", split[0], arch);
-		goto out;
-	}
-out:
-	g_strfreev (split);
-	g_free (version);
-	g_free (distro);
-	g_free (arch);
-	g_free (contents);
-	return distro_id;
-}
-
-/**
  * pk_engine_get_daemon_state:
  **/
 gboolean
@@ -1645,7 +1447,7 @@ pk_engine_init (PkEngine *engine)
 	engine->priv->backend_author = pk_backend_get_author (engine->priv->backend);
 
 	/* try to get the distro id */
-	engine->priv->distro_id = pk_engine_get_distro_id (engine);
+	engine->priv->distro_id = pk_get_distro_id ();
 
 	/* we allow fallback to these legacy methods */
 	if (pk_bitfield_contain (engine->priv->roles, PK_ROLE_ENUM_GET_DEPENDS))
commit c0c417526f1cd3552971d41aecbc08b1317c41c3
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu Sep 16 16:42:21 2010 +0100

    yum: don't assume yb.pkgSack.searchNevra() only returns one result to fix service pack generation

diff --git a/backends/yum/yumBackend.py b/backends/yum/yumBackend.py
index 8eaa89f..b261308 100755
--- a/backends/yum/yumBackend.py
+++ b/backends/yum/yumBackend.py
@@ -969,37 +969,37 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
                 self.message(MESSAGE_COULD_NOT_FIND_PACKAGE, "Could not find a match for package %s" % package_id)
                 continue
 
-            # should have only one...
-            for pkg_download in packs:
-                self._show_package(pkg_download, INFO_DOWNLOADING)
-                try:
-                    repo = self.yumbase.repos.getRepo(pkg_download.repoid)
-                except exceptions.IOError, e:
-                    self.error(ERROR_NO_SPACE_ON_DEVICE, "Disk error: %s" % _to_unicode(e))
-                except Exception, e:
-                    self.error(ERROR_INTERNAL_ERROR, _format_str(traceback.format_exc()))
-                remote = pkg_download.returnSimple('relativepath')
-                local = os.path.basename(remote)
-                if not os.path.exists(directory):
-                    self.error(ERROR_PACKAGE_DOWNLOAD_FAILED, "No destination directory exists", exit=False)
-                    return
-                local = os.path.join(directory, local)
-                if (os.path.exists(local) and os.path.getsize(local) == int(pkg_download.returnSimple('packagesize'))):
-                    self.error(ERROR_PACKAGE_DOWNLOAD_FAILED, "Package already exists", exit=False)
-                    return
-                # Disable cache otherwise things won't download
-                repo.cache = 0
-                pkg_download.localpath = local #Hack:To set the localpath we want
-                try:
-                    path = repo.getPackage(pkg_download)
+            # choose the first entry, as the same NEVRA package in multiple repos is fine
+            pkg_download = packs[0]
+            self._show_package(pkg_download, INFO_DOWNLOADING)
+            try:
+                repo = self.yumbase.repos.getRepo(pkg_download.repoid)
+            except exceptions.IOError, e:
+                self.error(ERROR_NO_SPACE_ON_DEVICE, "Disk error: %s" % _to_unicode(e))
+            except Exception, e:
+                self.error(ERROR_INTERNAL_ERROR, _format_str(traceback.format_exc()))
+            remote = pkg_download.returnSimple('relativepath')
+            local = os.path.basename(remote)
+            if not os.path.exists(directory):
+                self.error(ERROR_PACKAGE_DOWNLOAD_FAILED, "No destination directory exists", exit=False)
+                return
+            local = os.path.join(directory, local)
+            if (os.path.exists(local) and os.path.getsize(local) == int(pkg_download.returnSimple('packagesize'))):
+                self.error(ERROR_PACKAGE_DOWNLOAD_FAILED, "Package already exists as %s" % local, exit=False)
+                return
+            # Disable cache otherwise things won't download
+            repo.cache = 0
+            pkg_download.localpath = local #Hack:To set the localpath we want
+            try:
+                path = repo.getPackage(pkg_download)
 
-                    # emit the file we downloaded
-                    package_id_tmp = self._pkg_to_id(pkg_download)
-                    self.files(package_id_tmp, path)
+                # emit the file we downloaded
+                package_id_tmp = self._pkg_to_id(pkg_download)
+                self.files(package_id_tmp, path)
 
-                except IOError, e:
-                    self.error(ERROR_PACKAGE_DOWNLOAD_FAILED, "Cannot write to file", exit=False)
-                    return
+            except IOError, e:
+                self.error(ERROR_PACKAGE_DOWNLOAD_FAILED, "Cannot write to file", exit=False)
+                return
             percentage += bump
 
         # in case we don't sum to 100
commit 03a8d4bbf30361142043d3efd1ea95b1547e1ecb
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu Sep 16 15:26:59 2010 +0100

    yum: get the changelog text using zif if it is available

diff --git a/backends/yum/pk-backend-yum.c b/backends/yum/pk-backend-yum.c
index a96490d..19658a0 100644
--- a/backends/yum/pk-backend-yum.c
+++ b/backends/yum/pk-backend-yum.c
@@ -150,6 +150,7 @@ backend_is_all_installed (gchar **package_ids)
 	}
 	return ret;
 }
+#endif
 
 /**
  * backend_transaction_start:
@@ -251,6 +252,7 @@ out:
 	return;
 }
 
+#ifdef HAVE_ZIF
 /**
  * backend_filter_package_array_newest:
  *
@@ -2097,6 +2099,41 @@ backend_get_packages (PkBackend *backend, PkBitfield filters)
 	pk_backend_thread_create (backend, backend_search_thread);
 }
 
+#ifdef HAVE_ZIF
+/**
+ * backend_get_changelog_text:
+ */
+static gchar *
+backend_get_changelog_text (GPtrArray *changesets)
+{
+	guint i;
+	ZifChangeset *changeset;
+	GString *text;
+	gchar date_str[128];
+	GDate *date;
+
+	/* create output string */
+	text = g_string_new ("");
+	date = g_date_new ();
+
+	/* go through each one */
+	for (i=0; i<changesets->len; i++) {
+		changeset = g_ptr_array_index (changesets, i);
+
+		/* format the indervidual changeset */
+		g_date_set_time_t (date, zif_changeset_get_date (changeset));
+		g_date_strftime (date_str, 128, "%F", date);
+		g_string_append_printf (text, "**%s** %s - %s\n%s\n\n",
+					date_str,
+					zif_changeset_get_author (changeset),
+					zif_changeset_get_version (changeset),
+					zif_changeset_get_description (changeset));
+	}
+	g_date_free (date);
+	return g_string_free (text, FALSE);
+}
+#endif
+
 /**
  * backend_get_update_detail_thread:
  */
@@ -2118,7 +2155,6 @@ backend_get_update_detail_thread (PkBackend *backend)
 
 	/* get the data */
 	package_ids = pk_backend_get_strv (backend, "package_ids");
-
 	zif_state_set_number_steps (priv->state, g_strv_length (package_ids));
 
 	/* get the update info */
@@ -2139,7 +2175,9 @@ backend_get_update_detail_thread (PkBackend *backend)
 			egg_debug ("failed to get updateinfo for %s", zif_package_get_id (package));
 			g_clear_error (&error);
 		} else {
+			gchar *changelog_text = NULL;
 			GPtrArray *array;
+			GPtrArray *changesets;
 			GString *string_cve;
 			GString *string_bugzilla;
 			ZifUpdateInfo *info;
@@ -2163,6 +2201,11 @@ backend_get_update_detail_thread (PkBackend *backend)
 					break;
 				}
 			}
+
+			/* format changelog */
+			changesets = zif_update_get_changelog (update);
+			if (changesets != NULL)
+				changelog_text = backend_get_changelog_text (changesets);
 			pk_backend_update_detail (backend, package_ids[i],
 						  NULL, //updates,
 						  NULL, //obsoletes,
@@ -2171,13 +2214,16 @@ backend_get_update_detail_thread (PkBackend *backend)
 						  string_cve->str,
 						  PK_RESTART_ENUM_NONE,
 						  zif_update_get_description (update),
-						  NULL, //changelog,
+						  changelog_text,
 						  zif_update_get_state (update),
 						  zif_update_get_issued (update),
 						  NULL);
+			if (changesets != NULL)
+				g_ptr_array_unref (changesets);
 			g_ptr_array_unref (array);
 			g_string_free (string_cve, TRUE);
 			g_string_free (string_bugzilla, TRUE);
+			g_free (changelog_text);
 		}
 
 		g_object_unref (package);
commit 28a3c08f4b8ee264710452f6a12bf3b442edc10c
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu Sep 16 15:13:07 2010 +0100

    Fix generating an updates service pack using pkgenpack

diff --git a/client/pk-generate-pack.c b/client/pk-generate-pack.c
index 1b2da1d..ae9c18e 100644
--- a/client/pk-generate-pack.c
+++ b/client/pk-generate-pack.c
@@ -428,7 +428,7 @@ main (int argc, char *argv[])
 	if (!updates) {
 		/* TRANSLATORS: The package name is being matched up to available packages */
 		g_print ("%s\n", _("Finding package name."));
-		package_id = pk_console_resolve_package (client, PK_FILTER_ENUM_NONE, package, &error);
+		package_id = pk_console_resolve_package (client, pk_bitfield_value (PK_FILTER_ENUM_NONE), package, &error);
 		if (package_id == NULL) {
 			/* TRANSLATORS: This is when the package cannot be found in any software source. The detailed error follows */
 			g_print (_("Failed to find package '%s': %s"), package, error->message);
diff --git a/lib/packagekit-glib2/pk-service-pack.c b/lib/packagekit-glib2/pk-service-pack.c
index b2ee394..d6c3a40 100644
--- a/lib/packagekit-glib2/pk-service-pack.c
+++ b/lib/packagekit-glib2/pk-service-pack.c
@@ -905,7 +905,9 @@ pk_service_pack_create_for_package_ids_async (PkServicePack *pack, const gchar *
 	state->type = PK_SERVICE_PACK_TYPE_INSTALL;
 
 	/* get deps */
-	pk_client_get_depends_async (pack->priv->client, pk_bitfield_from_enums (PK_FILTER_ENUM_ARCH, PK_FILTER_ENUM_NEWEST, -1), state->package_ids, TRUE,
+	pk_client_get_depends_async (pack->priv->client,
+				     pk_bitfield_from_enums (PK_FILTER_ENUM_ARCH, PK_FILTER_ENUM_NEWEST, -1),
+				     state->package_ids, TRUE,
 				     state->cancellable, state->progress_callback, state->progress_user_data,
 				     (GAsyncReadyCallback) pk_service_pack_get_depends_ready_cb, state);
 
@@ -952,7 +954,9 @@ pk_service_pack_get_updates_ready_cb (GObject *source_object, GAsyncResult *res,
 	}
 
 	/* get deps, TODO: use NEWEST? */
-	pk_client_get_depends_async (state->pack->priv->client, PK_FILTER_ENUM_NONE, state->package_ids, TRUE,
+	pk_client_get_depends_async (state->pack->priv->client,
+				     pk_bitfield_value (PK_FILTER_ENUM_NONE),
+				     state->package_ids, TRUE,
 				     state->cancellable, state->progress_callback, state->progress_user_data,
 				     (GAsyncReadyCallback) pk_service_pack_get_depends_ready_cb, state);
 out:
@@ -1007,7 +1011,7 @@ pk_service_pack_create_for_updates_async (PkServicePack *pack, const gchar *file
 	state->package_ids_exclude = g_strdupv (package_ids_exclude);
 
 	/* get deps, TODO: use NEWEST? */
-	pk_client_get_updates_async (pack->priv->client, PK_FILTER_ENUM_NONE,
+	pk_client_get_updates_async (pack->priv->client, pk_bitfield_value (PK_FILTER_ENUM_NONE),
 				     state->cancellable, state->progress_callback, state->progress_user_data,
 				     (GAsyncReadyCallback) pk_service_pack_get_updates_ready_cb, state);
 
commit 70730d16b711782a51d5f6c06a635c4879a066ce
Author: Zhang Qiang <qiang.z.zhang at intel.com>
Date:   Thu Sep 16 16:44:10 2010 +0800

    Refresh cache and sat solv pool data if necessary
    
    In the original implementation, pkcon refresh only refresh/build
    metadata, while solv file have not been refreshed properly. this patch
    refresh solv data in solv pool while execute refresh operation.
    
    Reference zypper's implementation, changed refreshMetadata flag from
    RefreshIfNeeded to RefreshIfNeededIgnoreDelay, or refresh will not
    work properly. This patch also check if the cache is up to date, which
    reduce some unnecessay operations.

diff --git a/backends/zypp/zypp-utils.cpp b/backends/zypp/zypp-utils.cpp
index 8c299b4..2fd39a2 100644
--- a/backends/zypp/zypp-utils.cpp
+++ b/backends/zypp/zypp-utils.cpp
@@ -455,12 +455,21 @@ gboolean
 zypp_refresh_meta_and_cache (zypp::RepoManager &manager, zypp::RepoInfo &repo, bool force)
 {
 	try {
+		if (manager.checkIfToRefreshMetadata (repo, repo.url(), 
+					zypp::RepoManager::RefreshIfNeededIgnoreDelay)
+					!= zypp::RepoManager::REFRESH_NEEDED)
+			return TRUE;
+
+		zypp::sat::Pool pool = zypp::sat::Pool::instance ();
+		// Erase old solv file
+		pool.reposErase (repo.alias ());
 		manager.refreshMetadata (repo, force ?
 					 zypp::RepoManager::RefreshForced :
-					 zypp::RepoManager::RefreshIfNeeded);
+					 zypp::RepoManager::RefreshIfNeededIgnoreDelay);
 		manager.buildCache (repo, force ?
 				    zypp::RepoManager::BuildForced :
 				    zypp::RepoManager::BuildIfNeeded);
+		manager.loadFromCache (repo);
 		return TRUE;
 	} catch (const AbortTransactionException &ex) {
 		return FALSE;
commit 9794bc1f6dbdaa4297f77ec673939cb11665affd
Author: Zhang Qiang <qiang.z.zhang at intel.com>
Date:   Thu Sep 16 09:53:24 2010 +0800

    Refresh cache before geting upgrade and installing
    
    Refresh cache is necessary before executing get-updates and install
    operations. With out this patch, pkcon get-updates/install would not
    work after modifying rpmdb using rpm or changing repo.
    
    Related bug: http://bugs.meego.com/show_bug.cgi?id=2434

diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp
index 3989aed..6cd6888 100644
--- a/backends/zypp/pk-backend-zypp.cpp
+++ b/backends/zypp/pk-backend-zypp.cpp
@@ -546,6 +546,12 @@ backend_get_distro_upgrades_thread(PkBackend *backend)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 
+	// refresh the repos before checking for updates
+	if (!zypp_refresh_cache (backend, FALSE)) {
+		pk_backend_finished (backend);
+		return FALSE;
+	}
+
 	std::vector<zypp::parser::ProductFileData> result;
 	if (!zypp::parser::ProductFileReader::scanDir (zypp::functor::getAll (std::back_inserter (result)), "/etc/products.d")) {
 		return zypp_backend_finished_error (
@@ -978,6 +984,12 @@ backend_install_packages_thread (PkBackend *backend)
 {
 	gchar **package_ids;
 
+	// refresh the repos before installing packages
+	if (!zypp_refresh_cache (backend, FALSE)) {
+		pk_backend_finished (backend);
+		return FALSE;
+	}
+
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pk_backend_set_percentage (backend, 0);
 
commit 1b39a57b9f61270e057829a4c3654be1d9337939
Author: Zhang Qiang <qiang.z.zhang at intel.com>
Date:   Thu Sep 16 09:52:36 2010 +0800

    Refresh system rpmdb while refresh cache
    
    Refreshing rpmdb is necessary, which can let packagekitd get the
    correct status of packages, even if you use rpm command to change the
    status of rpmdb while packagekit is running.

diff --git a/backends/zypp/zypp-utils.cpp b/backends/zypp/zypp-utils.cpp
index 0b2dc89..8c299b4 100644
--- a/backends/zypp/zypp-utils.cpp
+++ b/backends/zypp/zypp-utils.cpp
@@ -1054,7 +1054,12 @@ gboolean
 zypp_refresh_cache (PkBackend *backend, gboolean force)
 {
 	// This call is needed as it calls initializeTarget which appears to properly setup the keyring
-	get_zypp (backend);
+	zypp::ZYpp::Ptr zypp = get_zypp (backend);
+	zypp::filesystem::Pathname pathname(pk_backend_get_root (backend));
+	// This call is needed to refresh system rpmdb status while refresh cache
+	zypp->finishTarget ();
+	zypp->initializeTarget (pathname);
+
 	if (!pk_backend_is_online (backend)) {
 		pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot refresh cache whilst offline");
 		return FALSE;
commit 4be060ff28ea226dd13a133666f7f3bc53c7fbd3
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 14 18:02:36 2010 +0100

    Fix g_time_val_from_iso8601() call in pk_iso8601_to_date()
    
    It appears the semantics of g_time_val_from_iso8601() has changed in
    new versions of GLib. Work around this until we can depend on GDateTime
    and remove a lot of the date/time insanity.

diff --git a/lib/packagekit-glib2/pk-common.c b/lib/packagekit-glib2/pk-common.c
index 0a4ea00..1e9de6e 100644
--- a/lib/packagekit-glib2/pk-common.c
+++ b/lib/packagekit-glib2/pk-common.c
@@ -106,7 +106,7 @@ pk_iso8601_to_date (const gchar *iso_date)
 
 	/* try to parse complete ISO8601 date */
 	ret = g_time_val_from_iso8601 (iso_date, &time_val);
-	if (ret) {
+	if (ret && time_val.tv_sec != 0) {
 		date = g_date_new ();
 		g_date_set_time_val (date, &time_val);
 		goto out;
commit fa6d8045d2fbe347da3986246c8fda7a2766830d
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 14 18:01:13 2010 +0100

    trivial: pk_iso8601_to_date() is less strict than g_time_val_from_iso8601() so relax the warning a little

diff --git a/src/pk-backend.c b/src/pk-backend.c
index a944015..c902d0f 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -1138,17 +1138,13 @@ pk_backend_update_detail (PkBackend *backend, const gchar *package_id,
 	/* check the issued dates are valid */
 	if (issued_text != NULL) {
 		ret = g_time_val_from_iso8601 (issued_text, &timeval);
-		if (!ret) {
-			egg_warning ("failed to parse '%s'", issued_text);
-			goto out;
-		}
+		if (!ret)
+			egg_warning ("failed to parse issued '%s'", issued_text);
 	}
 	if (updated_text != NULL) {
 		ret = g_time_val_from_iso8601 (updated_text, &timeval);
-		if (!ret) {
-			egg_warning ("failed to parse '%s'", updated_text);
-			goto out;
-		}
+		if (!ret)
+			egg_warning ("failed to parse updated '%s'", updated_text);
 	}
 
 	/* replace unsafe chars */
commit dd9e7d1fcac2783d0add807863e78766da63e1a6
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 14 15:45:10 2010 +0100

    yum: switch to using transaction_start() and transaction_stop() to reduce backend complexity

diff --git a/backends/yum/pk-backend-yum.c b/backends/yum/pk-backend-yum.c
index edbc6f8..a96490d 100644
--- a/backends/yum/pk-backend-yum.c
+++ b/backends/yum/pk-backend-yum.c
@@ -116,34 +116,6 @@ backend_state_subpercentage_changed_cb (ZifState *state, guint subpercentage, Pk
 }
 
 /**
- * backend_set_root:
- */
-static gboolean
-backend_set_root (PkBackend *backend)
-{
-	gboolean ret = FALSE;
-	GError *error = NULL;
-	const gchar *root;
-
-	/* this backend does not support a relocatable root... yet */
-	root = pk_backend_get_root (backend);
-	if (g_strcmp0 (root, "/") != 0) {
-		pk_backend_error_code (backend, PK_ERROR_ENUM_INSTALL_ROOT_INVALID, "backend does not support this root: '%s'", root);
-		goto out;
-	}
-
-	/* try to set, or re-set root */
-	ret = zif_store_local_set_prefix (priv->store_local, root, &error);
-	if (!ret) {
-		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, "failed to set prefix: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-out:
-	return ret;
-}
-
-/**
  * backend_profile:
  */
 static void
@@ -161,45 +133,42 @@ out:
 }
 
 /**
- * backend_setup_network:
+ * backend_is_all_installed:
  */
-static void
-backend_setup_network (PkBackend *backend)
+static gboolean
+backend_is_all_installed (gchar **package_ids)
 {
-	gboolean ret;
-	gchar *http_proxy = NULL;
+	guint i;
+	gboolean ret = TRUE;
 
-	/* get network state */
-	ret = pk_backend_is_online (backend);
-	if (!ret) {
-		zif_config_set_local (priv->config, "network", "false", NULL);
-		goto out;
+	/* check if we can use zif */
+	for (i=0; package_ids[i] != NULL; i++) {
+		if (!g_str_has_suffix (package_ids[i], ";installed")) {
+			ret = FALSE;
+			break;
+		}
 	}
-
-	/* tell ZifConfig it's okay to contact the network */
-	zif_config_set_local (priv->config, "network", "true", NULL);
-
-	/* set the proxy */
-	http_proxy = pk_backend_get_proxy_http (backend);
-	zif_download_set_proxy (priv->download, http_proxy, NULL);
-out:
-	g_free (http_proxy);
+	return ret;
 }
 
 /**
- * backend_get_lock:
+ * backend_transaction_start:
  */
-static gboolean
-backend_get_lock (PkBackend *backend)
+static void
+backend_transaction_start (PkBackend *backend)
 {
-	guint i;
-	guint pid;
+#ifdef HAVE_ZIF
 	gboolean ret = FALSE;
 	GError *error = NULL;
+	const gchar *root;
+	guint i;
+	guint pid;
+	gchar *http_proxy = NULL;
 
 	/* quit the spawned backend rather than waiting for it to time out */
 	pk_backend_spawn_exit (priv->spawn);
 
+	/* only try a finite number of times */
 	for (i=0; i<YUM_BACKEND_LOCKING_RETRIES; i++) {
 
 		/* try to lock */
@@ -217,38 +186,56 @@ backend_get_lock (PkBackend *backend)
 		g_usleep (YUM_BACKEND_LOCKING_DELAY * G_USEC_PER_SEC);
 	}
 
-	/* we failed */
-	if (!ret)
+	/* we failed to lock */
+	if (!ret) {
 		pk_backend_error_code (backend, PK_ERROR_ENUM_CANNOT_GET_LOCK, "failed to get lock, held by PID: %i", pid);
+		goto out;
+	}
 
-	return ret;
-}
+	/* this backend does not support a relocatable root... yet */
+	root = pk_backend_get_root (backend);
+	if (g_strcmp0 (root, "/") != 0) {
+		pk_backend_error_code (backend, PK_ERROR_ENUM_INSTALL_ROOT_INVALID, "backend does not support this root: '%s'", root);
+		goto out;
+	}
 
-/**
- * backend_is_all_installed:
- */
-static gboolean
-backend_is_all_installed (gchar **package_ids)
-{
-	guint i;
-	gboolean ret = TRUE;
+	/* try to set, or re-set install root */
+	ret = zif_store_local_set_prefix (priv->store_local, root, &error);
+	if (!ret) {
+		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, "failed to set prefix: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
 
-	/* check if we can use zif */
-	for (i=0; package_ids[i] != NULL; i++) {
-		if (!g_str_has_suffix (package_ids[i], ";installed")) {
-			ret = FALSE;
-			break;
-		}
+	/* get network state */
+	ret = pk_backend_is_online (backend);
+	if (!ret) {
+		zif_config_set_local (priv->config, "network", "false", NULL);
+		goto out;
 	}
-	return ret;
+
+	/* tell ZifConfig it's okay to contact the network */
+	zif_config_set_local (priv->config, "network", "true", NULL);
+
+	/* set the proxy */
+	http_proxy = pk_backend_get_proxy_http (backend);
+	zif_download_set_proxy (priv->download, http_proxy, NULL);
+
+	/* setup state */
+	zif_state_reset (priv->state);
+out:
+	g_free (http_proxy);
+#endif
+	return;
 }
 
 /**
- * backend_unlock:
+ * backend_transaction_stop:
  */
-static gboolean
-backend_unlock (PkBackend *backend)
+static void
+backend_transaction_stop (PkBackend *backend)
 {
+#ifdef HAVE_ZIF
 	gboolean ret;
 	GError *error = NULL;
 
@@ -257,8 +244,11 @@ backend_unlock (PkBackend *backend)
 	if (!ret) {
 		egg_warning ("failed to unlock: %s", error->message);
 		g_error_free (error);
+		goto out;
 	}
-	return ret;
+out:
+#endif
+	return;
 }
 
 /**
@@ -500,28 +490,9 @@ backend_search_thread (PkBackend *backend)
 	filters = (PkBitfield) pk_backend_get_uint (backend, "filters");
 	role = pk_backend_get_role (backend);
 
-	/* get lock */
-	ret = backend_get_lock (backend);
-	if (!ret) {
-		egg_warning ("failed to get lock");
-		goto out;
-	}
-
-	/* set correct install root */
-	ret = backend_set_root (backend);
-	if (!ret) {
-		egg_warning ("failed to set root");
-		goto out;
-	}
-
-	/* set the network state */
-	backend_setup_network (backend);
-
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pk_backend_set_percentage (backend, 0);
 
-	/* setup state */
-	zif_state_reset (priv->state);
 	zif_state_set_number_steps (priv->state, 4);
 
 	/* get default store_array */
@@ -636,7 +607,6 @@ out:
 		g_ptr_array_unref (store_array);
 	if (array != NULL)
 		g_ptr_array_unref (array);
-	backend_unlock (backend);
 	pk_backend_finished (backend);
 #endif
 	return TRUE;
@@ -1126,25 +1096,6 @@ backend_download_packages_thread (PkBackend *backend)
 	gchar *basename;
 	gchar *path;
 
-	/* get lock */
-	ret = backend_get_lock (backend);
-	if (!ret) {
-		egg_warning ("failed to get lock");
-		goto out;
-	}
-
-	/* set correct install root */
-	ret = backend_set_root (backend);
-	if (!ret) {
-		egg_warning ("failed to set root");
-		goto out;
-	}
-
-	/* set the network state */
-	backend_setup_network (backend);
-
-	/* setup state */
-	zif_state_reset (priv->state);
 	len = g_strv_length (package_ids);
 	zif_state_set_number_steps (priv->state, (len * 4) + 1);
 
@@ -1246,7 +1197,6 @@ backend_download_packages_thread (PkBackend *backend)
 		}
 	}
 out:
-	backend_unlock (backend);
 	pk_backend_finished (backend);
 	if (packages != NULL)
 		g_ptr_array_unref (packages);
@@ -1302,27 +1252,8 @@ backend_get_depends_thread (PkBackend *backend)
 	GPtrArray *provides;
 	const gchar *to_array[] = { NULL, NULL };
 
-	/* get lock */
-	ret = backend_get_lock (backend);
-	if (!ret) {
-		egg_warning ("failed to get lock");
-		goto out;
-	}
-
-	/* set correct install root */
-	ret = backend_set_root (backend);
-	if (!ret) {
-		egg_warning ("failed to set root");
-		goto out;
-	}
-
-	/* set the network state */
-	backend_setup_network (backend);
-
 	len = g_strv_length (package_ids);
 
-	/* setup state */
-	zif_state_reset (priv->state);
 	zif_state_set_number_steps (priv->state, len + 3);
 
 	/* find all the packages */
@@ -1455,7 +1386,6 @@ backend_get_depends_thread (PkBackend *backend)
 out:
 	if (array != NULL)
 		g_ptr_array_unref (array);
-	backend_unlock (backend);
 	pk_backend_finished (backend);
 	if (store_array != NULL)
 		g_ptr_array_unref (store_array);
@@ -1508,27 +1438,8 @@ backend_get_details_thread (PkBackend *backend)
 	guint64 size;
 	PkBitfield filters = PK_FILTER_ENUM_UNKNOWN;
 
-	/* get lock */
-	ret = backend_get_lock (backend);
-	if (!ret) {
-		egg_warning ("failed to get lock");
-		goto out;
-	}
-
-	/* set correct install root */
-	ret = backend_set_root (backend);
-	if (!ret) {
-		egg_warning ("failed to set root");
-		goto out;
-	}
-
-	/* set the network state */
-	backend_setup_network (backend);
-
 	len = g_strv_length (package_ids);
 
-	/* setup state */
-	zif_state_reset (priv->state);
 	zif_state_set_number_steps (priv->state, len + 1);
 
 	/* find all the packages */
@@ -1663,7 +1574,6 @@ backend_get_details_thread (PkBackend *backend)
 		g_object_unref (package);
 	}
 out:
-	backend_unlock (backend);
 	pk_backend_finished (backend);
 	if (store_array != NULL)
 		g_ptr_array_unref (store_array);
@@ -1845,30 +1755,8 @@ backend_get_files_thread (PkBackend *backend)
 	/* reset */
 	backend_profile (NULL);
 
-	/* get lock */
-	ret = backend_get_lock (backend);
-	if (!ret) {
-		egg_warning ("failed to get lock");
-		goto out;
-	}
-
-	/* set correct install root */
-	ret = backend_set_root (backend);
-	if (!ret) {
-		egg_warning ("failed to set root");
-		goto out;
-	}
-
-	/* set the network state */
-	backend_setup_network (backend);
-
-	/* profile */
-	backend_profile ("get lock");
-
 	len = g_strv_length (package_ids);
 
-	/* setup state */
-	zif_state_reset (priv->state);
 	zif_state_set_number_steps (priv->state, (len * 2) + 1);
 
 	/* find all the packages */
@@ -1949,7 +1837,6 @@ backend_get_files_thread (PkBackend *backend)
 		g_object_unref (package);
 	}
 out:
-	backend_unlock (backend);
 	pk_backend_finished (backend);
 	if (store_array != NULL)
 		g_ptr_array_unref (store_array);
@@ -2018,28 +1905,6 @@ backend_get_updates_thread (PkBackend *backend)
 	/* reset */
 	backend_profile (NULL);
 
-	/* get lock */
-	ret = backend_get_lock (backend);
-	if (!ret) {
-		egg_warning ("failed to get lock");
-		goto out;
-	}
-
-	/* set correct install root */
-	ret = backend_set_root (backend);
-	if (!ret) {
-		egg_warning ("failed to set root");
-		goto out;
-	}
-
-	/* profile */
-	backend_profile ("get lock");
-
-	/* set the network state */
-	backend_setup_network (backend);
-
-	/* setup state */
-	zif_state_reset (priv->state);
 	zif_state_set_number_steps (priv->state, 5);
 
 	/* get a store_array of remote stores */
@@ -2185,7 +2050,6 @@ backend_get_updates_thread (PkBackend *backend)
 	backend_profile ("filter and emit");
 
 out:
-	backend_unlock (backend);
 	pk_backend_finished (backend);
 	if (packages != NULL)
 		g_ptr_array_unref (packages);
@@ -2252,31 +2116,9 @@ backend_get_update_detail_thread (PkBackend *backend)
 	/* reset */
 	backend_profile (NULL);
 
-	/* get lock */
-	ret = backend_get_lock (backend);
-	if (!ret) {
-		egg_warning ("failed to get lock");
-		goto out;
-	}
-
-	/* set correct install root */
-	ret = backend_set_root (backend);
-	if (!ret) {
-		egg_warning ("failed to set root");
-		goto out;
-	}
-
 	/* get the data */
 	package_ids = pk_backend_get_strv (backend, "package_ids");
 
-	/* profile */
-	backend_profile ("get lock");
-
-	/* set the network state */
-	backend_setup_network (backend);
-
-	/* setup state */
-	zif_state_reset (priv->state);
 	zif_state_set_number_steps (priv->state, g_strv_length (package_ids));
 
 	/* get the update info */
@@ -2349,7 +2191,6 @@ backend_get_update_detail_thread (PkBackend *backend)
 		}
 	}
 out:
-	backend_unlock (backend);
 	pk_backend_finished (backend);
 #endif
 	return TRUE;
@@ -2468,25 +2309,6 @@ backend_refresh_cache_thread (PkBackend *backend)
 	ZifState *state_local;
 	gboolean force = pk_backend_get_bool (backend, "force");
 
-	/* get lock */
-	ret = backend_get_lock (backend);
-	if (!ret) {
-		egg_warning ("failed to get lock");
-		goto out;
-	}
-
-	/* set correct install root */
-	ret = backend_set_root (backend);
-	if (!ret) {
-		egg_warning ("failed to set root");
-		goto out;
-	}
-
-	/* set the network state */
-	backend_setup_network (backend);
-
-	/* setup state */
-	zif_state_reset (priv->state);
 	zif_state_set_number_steps (priv->state, 2);
 
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
@@ -2526,7 +2348,6 @@ backend_refresh_cache_thread (PkBackend *backend)
 		goto out;
 	}
 out:
-	backend_unlock (backend);
 	pk_backend_finished (backend);
 	if (store_array != NULL)
 		g_ptr_array_unref (store_array);
@@ -2712,28 +2533,9 @@ backend_get_repo_list_thread (PkBackend *backend)
 	gboolean devel;
 	GError *error = NULL;
 
-	/* get lock */
-	ret = backend_get_lock (backend);
-	if (!ret) {
-		egg_warning ("failed to get lock");
-		goto out;
-	}
-
-	/* set correct install root */
-	ret = backend_set_root (backend);
-	if (!ret) {
-		egg_warning ("failed to set root");
-		goto out;
-	}
-
-	/* set the network state */
-	backend_setup_network (backend);
-
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pk_backend_set_percentage (backend, 0);
 
-	/* setup state */
-	zif_state_reset (priv->state);
 	zif_state_set_number_steps (priv->state, 2);
 
 	state_local = zif_state_get_child (priv->state);
@@ -2796,7 +2598,6 @@ skip:
 		goto out;
 	}
 out:
-	backend_unlock (backend);
 	pk_backend_finished (backend);
 	if (array != NULL)
 		g_ptr_array_unref (array);
@@ -2836,23 +2637,6 @@ backend_repo_enable_thread (PkBackend *backend)
 	gboolean enabled = pk_backend_get_bool (backend, "enabled");
 	const gchar *repo_id = pk_backend_get_string (backend, "repo_id");
 
-	/* get lock */
-	ret = backend_get_lock (backend);
-	if (!ret) {
-		egg_warning ("failed to get lock");
-		goto out;
-	}
-
-	/* set correct install root */
-	ret = backend_set_root (backend);
-	if (!ret) {
-		egg_warning ("failed to set root");
-		goto out;
-	}
-
-	/* set the network state */
-	backend_setup_network (backend);
-
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pk_backend_set_percentage (backend, 0);
 
@@ -2885,7 +2669,6 @@ backend_repo_enable_thread (PkBackend *backend)
 		pk_backend_message (backend, PK_MESSAGE_ENUM_REPO_FOR_DEVELOPERS_ONLY, warning);
 	}
 out:
-	backend_unlock (backend);
 	pk_backend_finished (backend);
 	g_free (warning);
 	if (repo != NULL)
@@ -2998,25 +2781,6 @@ backend_get_categories_thread (PkBackend *backend)
 	ZifState *state_local;
 	GError *error = NULL;
 
-	/* get lock */
-	ret = backend_get_lock (backend);
-	if (!ret) {
-		egg_warning ("failed to get lock");
-		goto out;
-	}
-
-	/* set correct install root */
-	ret = backend_set_root (backend);
-	if (!ret) {
-		egg_warning ("failed to set root");
-		goto out;
-	}
-
-	/* set the network state */
-	backend_setup_network (backend);
-
-	/* setup state */
-	zif_state_reset (priv->state);
 	zif_state_set_number_steps (priv->state, 3);
 
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
@@ -3082,7 +2846,6 @@ backend_get_categories_thread (PkBackend *backend)
 		goto out;
 	}
 out:
-	backend_unlock (backend);
 	pk_backend_finished (backend);
 	if (array != NULL)
 		g_ptr_array_unref (array);
@@ -3122,7 +2885,8 @@ backend_simulate_install_files (PkBackend *backend, gchar **full_paths)
 
 PK_BACKEND_OPTIONS (
 	"YUM",					/* description */
-	"Tim Lauridsen <timlau at fedoraproject.org>, Richard Hughes <richard at hughsie.com>",	/* author */
+	"Tim Lauridsen <timlau at fedoraproject.org>, "
+	"Richard Hughes <richard at hughsie.com>",	/* author */
 	backend_initialize,			/* initalize */
 	backend_destroy,			/* destroy */
 	backend_get_groups,			/* get_groups */
@@ -3161,7 +2925,7 @@ PK_BACKEND_OPTIONS (
 	backend_simulate_install_packages,	/* simulate_install_packages */
 	backend_simulate_remove_packages,	/* simulate_remove_packages */
 	backend_simulate_update_packages,	/* simulate_update_packages */
-	NULL,					/* transaction_start */
-	NULL					/* transaction_stop */
+	backend_transaction_start,		/* transaction_start */
+	backend_transaction_stop		/* transaction_stop */
 );
 
commit b4fec94949739667a2a81b5c2e829f02cc34354d
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 14 15:42:08 2010 +0100

    trivial: fix up compile error with the last patch, cause by a lack of ctrl-s

diff --git a/src/pk-backend.c b/src/pk-backend.c
index 198430f..a944015 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -2382,7 +2382,7 @@ pk_backend_thread_setup (gpointer thread_data)
 	ret = helper->func (helper->backend);
 	if (!ret) {
 		egg_warning ("transaction setup failed, going straight to finished");
-		pk_backend_transaction_stop (backend);
+		pk_backend_transaction_stop (helper->backend);
 	}
 
 	/* destroy helper */
commit eb00ffb63672bb35dd4ad6ca486fb6e39b61c85c
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 14 15:14:27 2010 +0100

    Add transaction_start() and transaction_stop() vfuncs to make backends simpler
    
    For threaded backends, there is a lot of copy and paste code in
    just setting up and tearing down the packaging system for each
    transaction. By making this common code we can make our lives
    much easier.
    
    The new vfuncs are optional, and nothing uses them yet.

diff --git a/backends/alpm/pk-backend-alpm.c b/backends/alpm/pk-backend-alpm.c
index 33f111e..e7f4160 100644
--- a/backends/alpm/pk-backend-alpm.c
+++ b/backends/alpm/pk-backend-alpm.c
@@ -1690,5 +1690,7 @@ PK_BACKEND_OPTIONS (
 	NULL,						/* simulate_install_files */
 	NULL,						/* simulate_install_packages */
 	NULL,						/* simulate_remove_packages */
-	NULL						/* simulate_update_packages */
+	NULL,						/* simulate_update_packages */
+	NULL,						/* transaction_start */
+	NULL						/* transaction_stop */
 );
diff --git a/backends/apt/pk-backend-apt.c b/backends/apt/pk-backend-apt.c
index 79ec435..2e84422 100644
--- a/backends/apt/pk-backend-apt.c
+++ b/backends/apt/pk-backend-apt.c
@@ -589,7 +589,9 @@ PK_BACKEND_OPTIONS (
 	backend_simulate_install_files,		/* simulate_install_files */
 	backend_simulate_install_packages,	/* simulate_install_packages */
 	backend_simulate_remove_packages,	/* simulate_remove_packages */
-	backend_simulate_update_packages	/* simulate_update_packages */
+	backend_simulate_update_packages,	/* simulate_update_packages */
+	NULL,					/* transaction_start */
+	NULL					/* transaction_stop */
 );
 
 
diff --git a/backends/aptcc/pk-backend-aptcc.cpp b/backends/aptcc/pk-backend-aptcc.cpp
index 082574a..60c1274 100644
--- a/backends/aptcc/pk-backend-aptcc.cpp
+++ b/backends/aptcc/pk-backend-aptcc.cpp
@@ -1500,5 +1500,7 @@ extern "C" PK_BACKEND_OPTIONS (
 	NULL,						/* simulate_install_files */
 	backend_simulate_install_update_packages,	/* simulate_install_packages */
 	backend_simulate_remove_packages,		/* simulate_remove_packages */
-	backend_simulate_install_update_packages	/* simulate_update_packages */
+	backend_simulate_install_update_packages,	/* simulate_update_packages */
+	NULL,						/* transaction_start */
+	NULL						/* transaction_stop */
 );
diff --git a/backends/box/pk-backend-box.c b/backends/box/pk-backend-box.c
index 5d2f507..bcd5fba 100644
--- a/backends/box/pk-backend-box.c
+++ b/backends/box/pk-backend-box.c
@@ -738,5 +738,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* simulate_install_files */
 	NULL,					/* simulate_install_packages */
 	NULL,					/* simulate_remove_packages */
-	NULL					/* simulate_update_packages */
+	NULL,					/* simulate_update_packages */
+	NULL,					/* transaction_start */
+	NULL					/* transaction_stop */
 );
diff --git a/backends/conary/pk-backend-conary.c b/backends/conary/pk-backend-conary.c
index 2a33858..a7617cd 100644
--- a/backends/conary/pk-backend-conary.c
+++ b/backends/conary/pk-backend-conary.c
@@ -461,6 +461,8 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* simulate_install_files */
 	backend_simulate_install_packages,	/* simulate_install_packages */
 	backend_simulate_remove_packages,	/* simulate_remove_packages */
-	backend_simulate_update_packages	/* simulate_update_packages */
+	backend_simulate_update_packages,	/* simulate_update_packages */
+	NULL,					/* transaction_start */
+	NULL					/* transaction_stop */
 );
 
diff --git a/backends/dummy/pk-backend-dummy.c b/backends/dummy/pk-backend-dummy.c
index 439923d..3dc827c 100644
--- a/backends/dummy/pk-backend-dummy.c
+++ b/backends/dummy/pk-backend-dummy.c
@@ -1236,6 +1236,35 @@ backend_simulate_install_packages (PkBackend *backend, gchar **package_ids)
 	pk_backend_finished (backend);
 }
 
+/**
+ * backend_transaction_start:
+ */
+static void
+backend_transaction_start (PkBackend *backend)
+{
+	/* here you would lock the backend */
+	pk_backend_message (backend, PK_MESSAGE_ENUM_AUTOREMOVE_IGNORED, "backend is crap");
+
+	/* you can use pk_backend_error_code() here too */
+}
+
+/**
+ * backend_transaction_stop:
+ */
+static void
+backend_transaction_stop (PkBackend *backend)
+{
+	/* here you would unlock the backend */
+	pk_backend_message (backend, PK_MESSAGE_ENUM_CONFIG_FILES_CHANGED, "backend is crap");
+
+	/* you *cannot* use pk_backend_error_code() here,
+	 * unless pk_backend_get_is_error_set() returns FALSE, and
+	 * even then it's probably just best to clean up silently */
+
+	/* you cannot do pk_backend_finished() here as well as this is
+	 * needed to fire the transaction_stop() vfunc */
+}
+
 PK_BACKEND_OPTIONS (
 	"Dummy",				/* description */
 	"Richard Hughes <richard at hughsie.com>",	/* author */
@@ -1276,6 +1305,8 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* simulate_install_files */
 	backend_simulate_install_packages,	/* simulate_install_packages */
 	NULL,					/* simulate_remove_packages */
-	NULL					/* simulate_update_packages */
+	NULL,					/* simulate_update_packages */
+	backend_transaction_start,		/* transaction_start */
+	backend_transaction_stop		/* transaction_stop */
 );
 
diff --git a/backends/entropy/pk-backend-entropy.c b/backends/entropy/pk-backend-entropy.c
index 7399a58..5d8ae87 100644
--- a/backends/entropy/pk-backend-entropy.c
+++ b/backends/entropy/pk-backend-entropy.c
@@ -595,6 +595,8 @@ PK_BACKEND_OPTIONS (
 	backend_simulate_install_files,	    /* simulate_install_files */
 	backend_simulate_install_packages,  /* simulate_install_packages */
 	backend_simulate_remove_packages,   /* simulate_remove_packages */
-	backend_simulate_update_packages    /* simulate_update_packages */
+	backend_simulate_update_packages,   /* simulate_update_packages */
+	NULL,					/* transaction_start */
+	NULL					/* transaction_stop */
 );
 
diff --git a/backends/opkg/pk-backend-opkg.c b/backends/opkg/pk-backend-opkg.c
index 6318457..d3c1800 100644
--- a/backends/opkg/pk-backend-opkg.c
+++ b/backends/opkg/pk-backend-opkg.c
@@ -760,6 +760,8 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* simulate_install_files */
 	NULL,					/* simulate_install_packages */
 	NULL,					/* simulate_remove_packages */
-	NULL					/* simulate_update_packages */
+	NULL,					/* simulate_update_packages */
+	NULL,					/* transaction_start */
+	NULL					/* transaction_stop */
 );
 
diff --git a/backends/pisi/pk-backend-pisi.c b/backends/pisi/pk-backend-pisi.c
index 89e5ff2..b871292 100644
--- a/backends/pisi/pk-backend-pisi.c
+++ b/backends/pisi/pk-backend-pisi.c
@@ -397,6 +397,8 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* simulate_install_files */
 	NULL,					/* simulate_install_packages */
 	NULL,					/* simulate_remove_packages */
-	NULL					/* simulate_update_packages */
+	NULL,					/* simulate_update_packages */
+	NULL,					/* transaction_start */
+	NULL					/* transaction_stop */
 );
 
diff --git a/backends/poldek/pk-backend-poldek.c b/backends/poldek/pk-backend-poldek.c
index 131d780..df3222a 100644
--- a/backends/poldek/pk-backend-poldek.c
+++ b/backends/poldek/pk-backend-poldek.c
@@ -3437,6 +3437,8 @@ PK_BACKEND_OPTIONS (
 	NULL,						/* simulate_install_files */
 	backend_simulate_install_packages,		/* simulate_install_packages */
 	backend_simulate_remove_packages,		/* simulate_remove_packages */
-	backend_simulate_update_packages		/* simulate_update_packages */
+	backend_simulate_update_packages,		/* simulate_update_packages */
+	NULL,						/* transaction_start */
+	NULL						/* transaction_stop */
 );
 
diff --git a/backends/portage/pk-backend-portage.c b/backends/portage/pk-backend-portage.c
index 3ba1b64..c00040d 100644
--- a/backends/portage/pk-backend-portage.c
+++ b/backends/portage/pk-backend-portage.c
@@ -528,6 +528,8 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* simulate_install_files */
     backend_simulate_install_packages,  /* simulate_install_packages */
     backend_simulate_remove_packages,   /* simulate_remove_packages */
-    backend_simulate_update_packages    /* simulate_update_packages */
+    backend_simulate_update_packages,   /* simulate_update_packages */
+	NULL,					/* transaction_start */
+	NULL					/* transaction_stop */
 );
 
diff --git a/backends/ports/pk-backend-ports.c b/backends/ports/pk-backend-ports.c
index 11e2973..e442f06 100644
--- a/backends/ports/pk-backend-ports.c
+++ b/backends/ports/pk-backend-ports.c
@@ -449,6 +449,8 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* simulate_install_files */
 	NULL,					/* simulate_install_packages */
 	NULL,					/* simulate_remove_packages */
-	NULL					/* simulate_update_packages */
+	NULL,					/* simulate_update_packages */
+	NULL,					/* transaction_start */
+	NULL					/* transaction_stop */
 );
 
diff --git a/backends/razor/pk-backend-razor.c b/backends/razor/pk-backend-razor.c
index 24bf07b..e20fe31 100644
--- a/backends/razor/pk-backend-razor.c
+++ b/backends/razor/pk-backend-razor.c
@@ -431,6 +431,8 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* simulate_install_files */
 	NULL,					/* simulate_install_packages */
 	NULL,					/* simulate_remove_packages */
-	NULL					/* simulate_update_packages */
+	NULL,					/* simulate_update_packages */
+	NULL,					/* transaction_start */
+	NULL					/* transaction_stop */
 );
 
diff --git a/backends/slapt/pk-backend-slapt.c b/backends/slapt/pk-backend-slapt.c
index 490a8ad..4e16ccd 100644
--- a/backends/slapt/pk-backend-slapt.c
+++ b/backends/slapt/pk-backend-slapt.c
@@ -1368,6 +1368,8 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* simulate_install_files */
 	NULL,					/* simulate_install_packages */
 	NULL,					/* simulate_remove_packages */
-	NULL					/* simulate_update_packages */
+	NULL,					/* simulate_update_packages */
+	NULL,					/* transaction_start */
+	NULL					/* transaction_stop */
 );
 
diff --git a/backends/smart/pk-backend-smart.c b/backends/smart/pk-backend-smart.c
index 45a4c4f..2cea306 100644
--- a/backends/smart/pk-backend-smart.c
+++ b/backends/smart/pk-backend-smart.c
@@ -481,5 +481,7 @@ PK_BACKEND_OPTIONS (
 	NULL,						/* simulate_install_files */
 	NULL,						/* simulate_install_packages */
 	NULL,						/* simulate_remove_packages */
-	NULL						/* simulate_update_packages */
+	NULL,						/* simulate_update_packages */
+	NULL,						/* transaction_start */
+	NULL						/* transaction_stop */
 );
diff --git a/backends/test/pk-backend-test-fail.c b/backends/test/pk-backend-test-fail.c
index ff85b65..6085a0d 100644
--- a/backends/test/pk-backend-test-fail.c
+++ b/backends/test/pk-backend-test-fail.c
@@ -287,6 +287,8 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* simulate_install_files */
 	NULL,					/* simulate_install_packages */
 	NULL,					/* simulate_remove_packages */
-	NULL					/* simulate_update_packages */
+	NULL,					/* simulate_update_packages */
+	NULL,					/* transaction_start */
+	NULL					/* transaction_stop */
 );
 
diff --git a/backends/test/pk-backend-test-nop.c b/backends/test/pk-backend-test-nop.c
index d0167e0..b822529 100644
--- a/backends/test/pk-backend-test-nop.c
+++ b/backends/test/pk-backend-test-nop.c
@@ -63,6 +63,8 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* simulate_install_files */
 	NULL,					/* simulate_install_packages */
 	NULL,					/* simulate_remove_packages */
-	NULL					/* simulate_update_packages */
+	NULL,					/* simulate_update_packages */
+	NULL,					/* transaction_start */
+	NULL					/* transaction_stop */
 );
 
diff --git a/backends/test/pk-backend-test-spawn.c b/backends/test/pk-backend-test-spawn.c
index 82444ee..676e385 100644
--- a/backends/test/pk-backend-test-spawn.c
+++ b/backends/test/pk-backend-test-spawn.c
@@ -107,6 +107,8 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* simulate_install_files */
 	NULL,					/* simulate_install_packages */
 	NULL,					/* simulate_remove_packages */
-	NULL					/* simulate_update_packages */
+	NULL,					/* simulate_update_packages */
+	NULL,					/* transaction_start */
+	NULL					/* transaction_stop */
 );
 
diff --git a/backends/test/pk-backend-test-succeed.c b/backends/test/pk-backend-test-succeed.c
index 52c4f3f..97ad0d0 100644
--- a/backends/test/pk-backend-test-succeed.c
+++ b/backends/test/pk-backend-test-succeed.c
@@ -419,6 +419,8 @@ PK_BACKEND_OPTIONS (
 	backend_simulate_install_files,		/* simulate_install_files */
 	backend_simulate_install_packages,	/* simulate_install_packages */
 	backend_simulate_remove_packages,	/* simulate_remove_packages */
-	backend_simulate_update_packages	/* simulate_update_packages */
+	backend_simulate_update_packages,	/* simulate_update_packages */
+	NULL,					/* transaction_start */
+	NULL					/* transaction_stop */
 );
 
diff --git a/backends/test/pk-backend-test-thread.c b/backends/test/pk-backend-test-thread.c
index 01ff437..a3117ce 100644
--- a/backends/test/pk-backend-test-thread.c
+++ b/backends/test/pk-backend-test-thread.c
@@ -176,6 +176,8 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* simulate_install_files */
 	NULL,					/* simulate_install_packages */
 	NULL,					/* simulate_remove_packages */
-	NULL					/* simulate_update_packages */
+	NULL,					/* simulate_update_packages */
+	NULL,					/* transaction_start */
+	NULL					/* transaction_stop */
 );
 
diff --git a/backends/urpmi/pk-backend-urpmi.c b/backends/urpmi/pk-backend-urpmi.c
index 0a1cfa3..387aa3b 100644
--- a/backends/urpmi/pk-backend-urpmi.c
+++ b/backends/urpmi/pk-backend-urpmi.c
@@ -400,6 +400,8 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* simulate_install_files */
 	NULL,					/* simulate_install_packages */
 	NULL,					/* simulate_remove_packages */
-	NULL					/* simulate_update_packages */
+	NULL,					/* simulate_update_packages */
+	NULL,					/* transaction_start */
+	NULL					/* transaction_stop */
 );
 
diff --git a/backends/yum/pk-backend-yum.c b/backends/yum/pk-backend-yum.c
index 4062656..edbc6f8 100644
--- a/backends/yum/pk-backend-yum.c
+++ b/backends/yum/pk-backend-yum.c
@@ -3160,6 +3160,8 @@ PK_BACKEND_OPTIONS (
 	backend_simulate_install_files,		/* simulate_install_files */
 	backend_simulate_install_packages,	/* simulate_install_packages */
 	backend_simulate_remove_packages,	/* simulate_remove_packages */
-	backend_simulate_update_packages	/* simulate_update_packages */
+	backend_simulate_update_packages,	/* simulate_update_packages */
+	NULL,					/* transaction_start */
+	NULL					/* transaction_stop */
 );
 
diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp
index c2ca1b4..3989aed 100644
--- a/backends/zypp/pk-backend-zypp.cpp
+++ b/backends/zypp/pk-backend-zypp.cpp
@@ -1908,6 +1908,8 @@ extern "C" PK_BACKEND_OPTIONS (
 	backend_simulate_install_files,		/* simulate_install_files */
 	backend_simulate_install_packages,	/* simulate_install_packages */
 	backend_simulate_remove_packages,	/* simulate_remove_packages */
-	backend_simulate_update_packages	/* simulate_update_packages */
+	backend_simulate_update_packages,	/* simulate_update_packages */
+	NULL,					/* transaction_start */
+	NULL					/* transaction_stop */
 );
 
diff --git a/src/pk-backend.c b/src/pk-backend.c
index 9c2b660..198430f 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -2059,6 +2059,87 @@ pk_backend_set_exit_code (PkBackend *backend, PkExitEnum exit_enum)
 }
 
 /**
+ * pk_backend_transaction_start:
+ *
+ * This is called just before the threaded transaction method, and in
+ * the newly created thread context. e.g.
+ *
+ * >>> desc->transaction_start(backend)
+ *     (locked backend)
+ * >>> desc->backend_method_we_want_to_run(backend)
+ * <<< ::Package(PK_INFO_ENUM_INSTALLING,"hal;0.1.1;i386;fedora","Hardware Stuff")
+ * >>> desc->transaction_stop(backend)
+ *     (unlocked backend)
+ * <<< ::Finished()
+ *
+ * or in the case of backend_method_we_want_to_run() failure:
+ * >>> desc->transaction_start(backend)
+ *     (locked backend)
+ * >>> desc->backend_method_we_want_to_run(backend)
+ * <<< ::ErrorCode(PK_ERROR_ENUM_FAILED_TO_FIND,"no package")
+ * >>> desc->transaction_stop(backend)
+ *     (unlocked backend)
+ * <<< ::Finished()
+ *
+ * or in the case of transaction_start() failure:
+ * >>> desc->transaction_start(backend)
+ *     (failed to lock backend)
+ * <<< ::ErrorCode(PK_ERROR_ENUM_FAILED_TO_LOCK,"no pid file")
+ * >>> desc->transaction_stop(backend)
+ * <<< ::Finished()
+ *
+ * It is *not* called for non-threaded backends, as multiple processes
+ * would be inherently racy.
+ *
+ * Return value: %TRUE for success.
+ */
+static gboolean
+pk_backend_transaction_start (PkBackend *backend)
+{
+	gboolean ret = TRUE;
+
+	g_return_val_if_fail (PK_IS_BACKEND (backend), FALSE);
+
+	/* no transaction setup is perfectly fine */
+	if (backend->priv->desc->transaction_start == NULL) {
+		egg_debug ("no transaction start vfunc");
+		goto out;
+	}
+
+	/* run the transaction setup */
+	backend->priv->desc->transaction_start (backend);
+	ret = !pk_backend_has_set_error_code (backend);
+out:
+	return ret;
+}
+
+/**
+ * pk_backend_transaction_stop:
+ *
+ * Always run for each transaction, *even* when the transaction_start()
+ * vfunc fails.
+ *
+ * This method has no return value as the ErrorCode should have already
+ * been set.
+ */
+static void
+pk_backend_transaction_stop (PkBackend *backend)
+{
+	g_return_if_fail (PK_IS_BACKEND (backend));
+
+	/* no transaction setup is perfectly fine */
+	if (backend->priv->desc->transaction_stop == NULL) {
+		egg_debug ("no transaction stop vfunc");
+		goto out;
+	}
+
+	/* run the transaction setup */
+	backend->priv->desc->transaction_stop (backend);
+out:
+	return;
+}
+
+/**
  * pk_backend_finished_delay:
  *
  * We can call into this function if we *know* it's safe.
@@ -2120,6 +2201,10 @@ pk_backend_finished (PkBackend *backend)
 		return FALSE;
 	}
 
+	/* ensure threaded backends get stop vfuncs fired */
+	if (backend->priv->thread != NULL)
+		pk_backend_transaction_stop (backend);
+
 	/* check we got a Package() else the UI will suck */
 	if (!backend->priv->set_error &&
 	    !backend->priv->has_sent_package &&
@@ -2275,6 +2360,39 @@ pk_backend_use_background (PkBackend *backend)
 	return FALSE;
 }
 
+/* simple helper to work around the GThread one pointer limit */
+typedef struct {
+	PkBackend		*backend;
+	PkBackendThreadFunc	 func;
+} PkBackendThreadHelper;
+
+/**
+ * pk_backend_thread_setup:
+ **/
+static gpointer
+pk_backend_thread_setup (gpointer thread_data)
+{
+	gboolean ret;
+	PkBackendThreadHelper *helper = (PkBackendThreadHelper *) thread_data;
+
+	/* call setup */
+	pk_backend_transaction_start (helper->backend);
+
+	/* run original function */
+	ret = helper->func (helper->backend);
+	if (!ret) {
+		egg_warning ("transaction setup failed, going straight to finished");
+		pk_backend_transaction_stop (backend);
+	}
+
+	/* destroy helper */
+	g_object_unref (helper->backend);
+	g_free (helper);
+
+	/* no return value */
+	return NULL;
+}
+
 /**
  * pk_backend_thread_create:
  **/
@@ -2282,6 +2400,7 @@ gboolean
 pk_backend_thread_create (PkBackend *backend, PkBackendThreadFunc func)
 {
 	gboolean ret = TRUE;
+	PkBackendThreadHelper *helper = NULL;
 
 	g_return_val_if_fail (PK_IS_BACKEND (backend), FALSE);
 	g_return_val_if_fail (func != NULL, FALSE);
@@ -2298,8 +2417,13 @@ pk_backend_thread_create (PkBackend *backend, PkBackendThreadFunc func)
 		goto out;
 	}
 
+	/* create a helper object to allow us to call a _setup() function */
+	helper = g_new0 (PkBackendThreadHelper, 1);
+	helper->backend = g_object_ref (backend);
+	helper->func = func;
+
 	/* create a thread */
-	backend->priv->thread = g_thread_create ((GThreadFunc) func, backend, FALSE, NULL);
+	backend->priv->thread = g_thread_create (pk_backend_thread_setup, helper, FALSE, NULL);
 	if (backend->priv->thread == NULL) {
 		egg_warning ("failed to create thread");
 		ret = FALSE;
diff --git a/src/pk-backend.h b/src/pk-backend.h
index c9b6171..6a7bc25 100644
--- a/src/pk-backend.h
+++ b/src/pk-backend.h
@@ -312,7 +312,9 @@ typedef struct {
 							 gboolean	 autoremove);
 	void		(*simulate_update_packages)	(PkBackend	*backend,
 							 gchar		**package_ids);
-	gpointer	padding[10];
+	void		(*transaction_start)		(PkBackend	*backend);
+	void		(*transaction_stop)		(PkBackend	*backend);
+	gpointer	padding[8];
 } PkBackendDesc;
 
 #define PK_BACKEND_OPTIONS(description, author, initialize, destroy, get_groups, get_filters, get_roles, \
@@ -323,7 +325,7 @@ typedef struct {
 			   repo_enable, repo_set_data, resolve, rollback, search_details, search_file,	\
 			   search_group, search_name, update_packages, update_system, what_provides,	\
 			   simulate_install_files, simulate_install_packages, simulate_remove_packages,	\
-			   simulate_update_packages )							\
+			   simulate_update_packages, transaction_start, transaction_stop )		\
 	G_MODULE_EXPORT const PkBackendDesc pk_backend_desc = { 					\
 		description,			\
 		author,				\
@@ -365,6 +367,8 @@ typedef struct {
 		simulate_install_packages,	\
 		simulate_remove_packages,	\
 		simulate_update_packages,	\
+		transaction_start,		\
+		transaction_stop,		\
 		{0} 				\
 	}
 
commit fd0f734b8cc7a53c738acc891c801c08a910095d
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 14 13:23:09 2010 +0100

    trivial: remove console warning that isn't valid anymore

diff --git a/src/pk-backend.c b/src/pk-backend.c
index 4264715..9c2b660 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -2299,7 +2299,6 @@ pk_backend_thread_create (PkBackend *backend, PkBackendThreadFunc func)
 	}
 
 	/* create a thread */
-	egg_warning ("using threads, so daemon may crash");
 	backend->priv->thread = g_thread_create ((GThreadFunc) func, backend, FALSE, NULL);
 	if (backend->priv->thread == NULL) {
 		egg_warning ("failed to create thread");
commit a3aa63fc548511a670ac20533158b0a35ea5805d
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 14 13:21:38 2010 +0100

    yum: Add an initial rough cut of zif compatible GetDepends()

diff --git a/backends/yum/pk-backend-yum.c b/backends/yum/pk-backend-yum.c
index b5a989b..4062656 100644
--- a/backends/yum/pk-backend-yum.c
+++ b/backends/yum/pk-backend-yum.c
@@ -1276,18 +1276,211 @@ backend_download_packages (PkBackend *backend, gchar **package_ids, const gchar
 }
 
 /**
+ * backend_get_depends_thread:
+ */
+static gboolean
+backend_get_depends_thread (PkBackend *backend)
+{
+#ifdef HAVE_ZIF
+	gboolean ret;
+	gchar **package_ids = pk_backend_get_strv (backend, "package_ids");
+	PkBitfield filters = (PkBitfield) pk_backend_get_uint (backend, "filters");
+	GPtrArray *store_array = NULL;
+	ZifPackage *package;
+	ZifPackage *package_provide;
+	ZifState *state_local;
+	ZifState *state_loop;
+	ZifState *state_loop_inner;
+	const ZifDepend *require;
+	const gchar *id;
+	guint i, j, k;
+	guint len;
+	GError *error = NULL;
+	GPtrArray *array = NULL;
+	GPtrArray *result;
+	GPtrArray *requires;
+	GPtrArray *provides;
+	const gchar *to_array[] = { NULL, NULL };
+
+	/* get lock */
+	ret = backend_get_lock (backend);
+	if (!ret) {
+		egg_warning ("failed to get lock");
+		goto out;
+	}
+
+	/* set correct install root */
+	ret = backend_set_root (backend);
+	if (!ret) {
+		egg_warning ("failed to set root");
+		goto out;
+	}
+
+	/* set the network state */
+	backend_setup_network (backend);
+
+	len = g_strv_length (package_ids);
+
+	/* setup state */
+	zif_state_reset (priv->state);
+	zif_state_set_number_steps (priv->state, len + 3);
+
+	/* find all the packages */
+	state_local = zif_state_get_child (priv->state);
+	store_array = backend_get_default_store_array_for_filter (backend, 0, state_local, &error);
+	if (store_array == NULL) {
+		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, "failed to get stores: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* this section done */
+	ret = zif_state_done (priv->state, &error);
+	if (!ret) {
+		pk_backend_error_code (backend, PK_ERROR_ENUM_TRANSACTION_CANCELLED, "cancelled: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* new output array */
+	array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
+
+	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
+	for (i=0; package_ids[i] != NULL; i++) {
+		id = package_ids[i];
+
+		/* set up state */
+		state_local = zif_state_get_child (priv->state);
+		zif_state_set_number_steps (state_local, 2);
+
+		/* find package */
+		state_loop = zif_state_get_child (state_local);
+		package = zif_store_array_find_package (store_array, id, state_loop, &error);
+		if (package == NULL) {
+			pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, "failed to find %s: %s", package_ids[i], error->message);
+			g_error_free (error);
+			goto out;
+		}
+
+		/* this section done */
+		ret = zif_state_done (state_local, &error);
+		if (!ret) {
+			pk_backend_error_code (backend, PK_ERROR_ENUM_TRANSACTION_CANCELLED, "cancelled: %s", error->message);
+			g_error_free (error);
+			goto out;
+		}
+
+		/* get requires */
+		state_loop = zif_state_get_child (state_local);
+		requires = zif_package_get_requires (package, state_loop, &error);
+		if (requires == NULL) {
+			pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_FOUND,
+					       "failed to get requires for %s: %s",
+					       package_ids[i], error->message);
+			g_error_free (error);
+			goto out;
+		}
+
+		/* this section done */
+		ret = zif_state_done (state_local, &error);
+		if (!ret) {
+			pk_backend_error_code (backend, PK_ERROR_ENUM_TRANSACTION_CANCELLED, "cancelled: %s", error->message);
+			g_error_free (error);
+			goto out;
+		}
+
+		/* match a package to each require */
+		state_loop = zif_state_get_child (state_local);
+		zif_state_set_number_steps (state_loop, requires->len);
+		for (k=0; k<requires->len; k++) {
+
+			/* setup deeper state */
+			state_loop_inner = zif_state_get_child (state_loop);
+
+			require = g_ptr_array_index (requires, k);
+
+			/* find the package providing the depend */
+			to_array[0] = require->name;
+			provides = zif_store_array_what_provides (store_array, (gchar**)to_array, state_loop_inner, &error);
+			if (provides == NULL) {
+				pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_FOUND,
+						       "failed to find provide for %s: %s",
+						       require->name, error->message);
+				g_error_free (error);
+				goto out;
+			}
+
+			/* print all of them */
+			for (j=0;j<provides->len;j++) {
+				package_provide = g_ptr_array_index (provides, j);
+				g_ptr_array_add (array, g_object_ref (package_provide));
+			}
+			g_ptr_array_unref (provides);
+
+			/* this section done */
+			ret = zif_state_done (state_loop, &error);
+			if (!ret)
+				goto out;
+		}
+
+		/* free */
+		g_object_unref (package);
+	}
+
+	/* filter */
+	result = backend_filter_package_array (array, filters);
+
+	/* this section done */
+	ret = zif_state_done (priv->state, &error);
+	if (!ret) {
+		pk_backend_error_code (backend, PK_ERROR_ENUM_TRANSACTION_CANCELLED, "cancelled: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* done */
+	pk_backend_set_percentage (backend, 100);
+
+	/* emit */
+	state_local = zif_state_get_child (priv->state);
+	backend_emit_package_array (backend, result, state_local);
+
+	/* this section done */
+	ret = zif_state_done (priv->state, &error);
+	if (!ret) {
+		pk_backend_error_code (backend, PK_ERROR_ENUM_TRANSACTION_CANCELLED, "cancelled: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+out:
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	backend_unlock (backend);
+	pk_backend_finished (backend);
+	if (store_array != NULL)
+		g_ptr_array_unref (store_array);
+#endif
+	return TRUE;
+}
+
+/**
  * backend_get_depends:
  */
 static void
 backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
-	gchar *filters_text;
-	gchar *package_ids_temp;
-	package_ids_temp = pk_package_ids_to_string (package_ids);
-	filters_text = pk_filter_bitfield_to_string (filters);
-	pk_backend_spawn_helper (priv->spawn, "yumBackend.py", "get-depends", filters_text, package_ids_temp, pk_backend_bool_to_string (recursive), NULL);
-	g_free (filters_text);
-	g_free (package_ids_temp);
+	/* it seems some people are not ready for the awesomeness */
+	if (!priv->use_zif) {
+		gchar *filters_text;
+		gchar *package_ids_temp;
+		package_ids_temp = pk_package_ids_to_string (package_ids);
+		filters_text = pk_filter_bitfield_to_string (filters);
+		pk_backend_spawn_helper (priv->spawn, "yumBackend.py", "get-depends", filters_text, package_ids_temp, pk_backend_bool_to_string (recursive), NULL);
+		g_free (filters_text);
+		g_free (package_ids_temp);
+		return;
+	}
+	pk_backend_thread_create (backend, backend_get_depends_thread);
 }
 
 /**
commit 2a68a6cd3ce8c24a18773da888411d0f135798c6
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Sep 13 15:32:42 2010 +0100

    browser-plugin: Do not query PkDesktop by default
    
    By default, firefox is compiled with an internal version of sqlite
    and when packagekit-glib sucks its own copy into the running
    process, hilarity ensues. Icons are less important than a crashed
    browser.

diff --git a/contrib/browser-plugin/pk-plugin-install.c b/contrib/browser-plugin/pk-plugin-install.c
index f940639..f854f28 100644
--- a/contrib/browser-plugin/pk-plugin-install.c
+++ b/contrib/browser-plugin/pk-plugin-install.c
@@ -38,6 +38,8 @@
 #include "pk-main.h"
 #include "pk-plugin-install.h"
 
+//#define PK_PLUGIN_INSTALL_USE_DESKTOP_FOR_INSTALLED
+
 #define PK_PLUGIN_INSTALL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_PLUGIN_INSTALL, PkPluginInstallPrivate))
 
 typedef enum {
@@ -189,11 +191,12 @@ pk_plugin_install_set_installed_version (PkPluginInstall *self, const gchar *ver
 static gchar *
 pk_plugin_install_get_best_desktop_file (PkPluginInstall *self)
 {
+	gchar *data = NULL;
+#ifdef PK_PLUGIN_INSTALL_USE_DESKTOP_FOR_INSTALLED
 	GPtrArray *array = NULL;
 	PkDesktop *desktop;
 	GError *error = NULL;
 	gboolean ret;
-	gchar *data = NULL;
 	const gchar *package;
 
 	/* open desktop database */
@@ -230,6 +233,7 @@ out:
 		g_ptr_array_free (array, TRUE);
 	}
 	g_object_unref (desktop);
+#endif
 	return data;
 }
 
@@ -328,9 +332,7 @@ pk_plugin_install_finished_cb (GObject *object, GAsyncResult *res, PkPluginInsta
 #endif
 		}
 
-		if (self->priv->app_info != 0)
-			pk_plugin_install_set_status (self, INSTALLED);
-
+		pk_plugin_install_set_status (self, INSTALLED);
 		pk_plugin_install_clear_layout (self);
 		pk_plugin_install_refresh (self);
 	}
commit ff71dc0bbfda8071ef4fb6a86251dc67fda4c1c1
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Sep 13 15:29:59 2010 +0100

    browser-plugin: Fix up 2 small memory leaks in error paths

diff --git a/contrib/browser-plugin/pk-plugin-install.c b/contrib/browser-plugin/pk-plugin-install.c
index aeb9c2d..f940639 100644
--- a/contrib/browser-plugin/pk-plugin-install.c
+++ b/contrib/browser-plugin/pk-plugin-install.c
@@ -244,7 +244,7 @@ pk_plugin_install_finished_cb (GObject *object, GAsyncResult *res, PkPluginInsta
 	PkResults *results = NULL;
 	GPtrArray *packages = NULL;
 	PkPackage *item;
-	gchar *filename;
+	gchar *filename = NULL;
 	gchar **split = NULL;
 	PkError *error_code = NULL;
 	PkInfoEnum info;
@@ -327,7 +327,6 @@ pk_plugin_install_finished_cb (GObject *object, GAsyncResult *res, PkPluginInsta
 			self->priv->display_name = g_strdup (g_app_info_get_name (self->priv->app_info));
 #endif
 		}
-		g_free (filename);
 
 		if (self->priv->app_info != 0)
 			pk_plugin_install_set_status (self, INSTALLED);
@@ -336,6 +335,7 @@ pk_plugin_install_finished_cb (GObject *object, GAsyncResult *res, PkPluginInsta
 		pk_plugin_install_refresh (self);
 	}
 out:
+	g_free (filename);
 	g_free (package_id);
 	g_free (summary);
 
@@ -560,7 +560,7 @@ static gchar *
 pk_plugin_install_get_package_icon (PkPluginInstall *self)
 {
 	gboolean ret;
-	GKeyFile *file;
+	GKeyFile *file = NULL;
 	gchar *data = NULL;
 	const gchar *filename;
 
@@ -583,8 +583,9 @@ pk_plugin_install_get_package_icon (PkPluginInstall *self)
 		goto out;
 	}
 	data = g_key_file_get_string (file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_ICON, NULL);
-	g_key_file_free (file);
 out:
+	if (file != NULL)
+		g_key_file_free (file);
 	return data;
 }
 
@@ -689,9 +690,9 @@ pk_plugin_install_draw (PkPlugin *plugin, cairo_t *cr)
 	guint width;
 	guint height;
 	guint radius;
-	const gchar *filename;
+	gchar *filename = NULL;
 	GtkIconTheme *theme;
-	GdkPixbuf *pixbuf;
+	GdkPixbuf *pixbuf = NULL;
 	PangoRectangle rect;
 	PkPluginInstall *self = PK_PLUGIN_INSTALL (plugin);
 	guint sep;
@@ -750,7 +751,7 @@ pk_plugin_install_draw (PkPlugin *plugin, cairo_t *cr)
 	/* get themed icon */
 	filename = pk_plugin_install_get_package_icon (self);
 	if (filename == NULL)
-		filename = "package-x-generic";
+		filename = g_strdup ("package-x-generic");
 	theme = gtk_icon_theme_get_default ();
 	pixbuf = gtk_icon_theme_load_icon (theme, filename, 48, GTK_ICON_LOOKUP_FORCE_SIZE, NULL);
 	if (pixbuf == NULL)
@@ -759,7 +760,6 @@ pk_plugin_install_draw (PkPlugin *plugin, cairo_t *cr)
 	gdk_cairo_set_source_pixbuf (cr, pixbuf, x + sep, y + (height - 48) / 2);
 	cairo_rectangle (cr, x + sep, y + (height - 48) / 2, 48, 48);
 	cairo_fill (cr);
-	g_object_unref (pixbuf);
 
 skip:
 	/* write text */
@@ -787,7 +787,9 @@ update_spinner:
 						x + sep + 48 + sep + rect.width + 2 * sep,
 						y + (height - SPINNER_SIZE) / 2);
 	}
-
+	if (pixbuf != NULL)
+		g_object_unref (pixbuf);
+	g_free (filename);
 	return TRUE;
 }
 
commit 58e5b2b56250d1a7580831ea17d6161f84b00ef7
Author: Daniel Nicoletti <dantti85-pk at yahoo.com.br>
Date:   Mon Sep 13 11:10:58 2010 -0300

    aptcc: Added Fonts group

diff --git a/backends/aptcc/apt-utils.cpp b/backends/aptcc/apt-utils.cpp
index 09f71ba..f2ed478 100644
--- a/backends/aptcc/apt-utils.cpp
+++ b/backends/aptcc/apt-utils.cpp
@@ -177,6 +177,8 @@ get_enum_group (string group)
 		return PK_GROUP_ENUM_ELECTRONICS;
 	} else if (group.compare ("embedded") == 0) {
 		return PK_GROUP_ENUM_SYSTEM;
+	} else if (group.compare ("fonts") == 0) {
+		return PK_GROUP_ENUM_FONTS;
 	} else if (group.compare ("games") == 0) {
 		return PK_GROUP_ENUM_GAMES;
 	} else if (group.compare ("gnome") == 0) {
diff --git a/backends/aptcc/pk-backend-aptcc.cpp b/backends/aptcc/pk-backend-aptcc.cpp
index 7fa8264..082574a 100644
--- a/backends/aptcc/pk-backend-aptcc.cpp
+++ b/backends/aptcc/pk-backend-aptcc.cpp
@@ -83,6 +83,7 @@ backend_get_groups (PkBackend *backend)
 		PK_GROUP_ENUM_DESKTOP_KDE,
 		PK_GROUP_ENUM_DESKTOP_OTHER,
 		PK_GROUP_ENUM_ELECTRONICS,
+		PK_GROUP_ENUM_FONTS,
 		PK_GROUP_ENUM_GAMES,
 		PK_GROUP_ENUM_GRAPHICS,
 		PK_GROUP_ENUM_INTERNET,
commit c184d102997c2993b11c2654f9463c734b637232
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Sep 10 10:00:18 2010 +0100

    yum: Fix searching by category when using the zif backend

diff --git a/backends/yum/pk-backend-yum.c b/backends/yum/pk-backend-yum.c
index f62fd11..b5a989b 100644
--- a/backends/yum/pk-backend-yum.c
+++ b/backends/yum/pk-backend-yum.c
@@ -568,7 +568,22 @@ backend_search_thread (PkBackend *backend)
 		} else if (role == PK_ROLE_ENUM_SEARCH_DETAILS) {
 			array = zif_store_array_search_details (store_array, search, state_local, &error);
 		} else if (role == PK_ROLE_ENUM_SEARCH_GROUP) {
-			array = zif_store_array_search_category (store_array, search, state_local, &error);
+			gchar **search_stripped;
+			guint search_entries;
+			guint i;
+
+			/* if the search temp is prefixed with '@' then it is a
+			 * category search, and we have to strip it */
+			if (search[0][0] == '@') {
+				search_entries = g_strv_length (search);
+				search_stripped = g_new0 (gchar *, search_entries + 1);
+				for (i=0; i < search_entries; i++)
+					search_stripped[i] = g_strdup (&search[i][1]);
+				array = zif_store_array_search_category (store_array, search_stripped, state_local, &error);
+				g_strfreev (search_stripped);
+			} else {
+				array = zif_store_array_search_group (store_array, search, state_local, &error);
+			}
 		} else if (role == PK_ROLE_ENUM_SEARCH_FILE) {
 			array = zif_store_array_search_file (store_array, search, state_local, &error);
 		} else if (role == PK_ROLE_ENUM_RESOLVE) {
@@ -581,11 +596,6 @@ backend_search_thread (PkBackend *backend)
 			g_error_free (error);
 			goto out;
 		}
-
-//			/* strip off the prefix '@' */
-//			search_tmp = search[i];
-//			if (g_str_has_prefix (search_tmp, "@"))
-//				search_tmp = search_tmp+1;
 	}
 
 	/* this section done */


More information about the PackageKit-commit mailing list