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

Richard Hughes hughsient at kemper.freedesktop.org
Mon Nov 1 09:30:50 PDT 2010


 NEWS                                             |   59 
 backends/dummy/Makefile.am                       |    3 
 backends/dummy/pk-backend-dummy.c                |  141 +
 backends/yum/Makefile.am                         |    2 
 backends/yum/Yum.conf                            |    2 
 backends/yum/pk-backend-yum.c                    |  249 ++
 backends/yum/yumBackend.py                       |   80 
 backends/yum/yumFilter.py                        |    4 
 client/pk-console.c                              |    5 
 configure.ac                                     |   12 
 contrib/command-not-found/pk-command-not-found.c |    5 
 data/tests/Makefile.am                           |    1 
 data/tests/pk-client-helper-test.py              |   42 
 docs/html/pk-download.html                       |    1 
 etc/PackageKit.conf.in                           |    9 
 lib/packagekit-glib2/.gitignore                  |    1 
 lib/packagekit-glib2/Makefile.am                 |    9 
 lib/packagekit-glib2/pk-client-helper.c          |  557 ++++++
 lib/packagekit-glib2/pk-client-helper.h          |   78 
 lib/packagekit-glib2/pk-client.c                 |  290 +++
 lib/packagekit-glib2/pk-client.h                 |   15 
 lib/packagekit-glib2/pk-debug.c                  |   11 
 lib/packagekit-glib2/pk-debug.h                  |    1 
 lib/packagekit-glib2/pk-self-test.c              |  148 +
 lib/packagekit-glib2/pk-socket-example.c         |  117 +
 lib/packagekit-glib2/pk-task.c                   |   70 
 lib/packagekit-glib2/pk-task.h                   |    8 
 lib/python/packagekit/backend.py                 |    9 
 po/en_GB.po                                      | 1912 +++++++++++++++--------
 src/org.freedesktop.PackageKit.Transaction.xml   |   37 
 src/pk-backend-spawn.c                           |   13 
 src/pk-backend.c                                 |   36 
 src/pk-backend.h                                 |    5 
 src/pk-transaction.c                             |   29 
 34 files changed, 3245 insertions(+), 716 deletions(-)

New commits:
commit 8a88c258f168146361a473d42b44bbc4b95f7d43
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Nov 1 16:30:25 2010 +0000

    Release version 0.6.10

diff --git a/NEWS b/NEWS
index 90fb4e6..38064b0 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,62 @@
+Version 0.6.10
+~~~~~~~~~~~~~~
+Released: 2010-11-01
+
+Notes:
+ - This is the first release of PackageKit to support session
+   configuration helper support in the GLib and QT libraries.
+ - This allows debconf to work when using PackageKit on Debian.
+ - A formal transaction lifecyle is now in place, which allows future
+   extensions to hook into the transaction at certain points.
+
+Libraries:
+ - glib: Add several more FSF free licenses (Richard Hughes)
+ - glib: Add some C getters and setters for PkClient and PkTask (Richard Hughes)
+ - glib: Fix up a lot of the gobject-introspection warnings (Richard Hughes)
+
+Backends:
+ - alpm: Fixed detection code (Valeriy Lyasotskiy)
+ - aptcc: Add a nicer string pointing to launchpad when the changelog is not available (Daniel Nicoletti)
+ - aptcc: Feature: added a fetcher/parser for updates changelogs (Daniel Nicoletti)
+ - dummy: Add a self test which uses the frontend-socket hint, and plays ping-pong with the client (Richard Hughes)
+ - slapt: Updated backend for compatibility with slapt-get 0.10.2g (Jason Woodward)
+ - smart: dpkg requires a PATH variable, so set it (Anders F Bjorklund)
+ - smart: Set PATH for FreeBSD and Linux (Anders F Bjorklund)
+ - test: Add a pk_backend_get_description() vfunc to allow the backends to be loaded (Richard Hughes)
+ - yum: Add some initial code to support SearchGroup(collections) when using the Zif backend (Richard Hughes)
+ - yum: Fix compile with libzif from git master (Richard Hughes)
+ - yum: Properly fix the Resolve(@category) search as pkcon needs this to work to be able to install and remove groups (Richard Hughes)
+ - yum: Remove selinux-policy from InfrastructurePackages, it's updated way too often (Richard Hughes)
+ - yum: Support SearchGroup(newest) when using the Zif backend (Richard Hughes)
+ - yum: Use the cache-age if set by the frontend (Richard Hughes)
+ - yum: Use the Zif 'action-changed' signal to emit StatusChanged events for the transaction (Richard Hughes)
+ - yum: When returning results from SearchGroup(collections) check if the groups are installed (Richard Hughes)
+ - zypp: Call zypp_build_pool() when searching with what_provides (Zhang Qiang)
+
+New Features:
+ - Add a new optional hint, 'cache-age' to allow the frontend to control the maximum age of the metadata (Richard Hughes)
+ - Add PkClientHelper, which allows a helper session program to be run for a transaction (Richard Hughes)
+ - Add the concept of a transaction lifecycle (Richard Hughes)
+ - Document the @category resolve special case in the specification as it's been used for at least a year now (Richard Hughes)
+ - Document the @category search in the docs, as it's been used in a few backends for over two years... (Richard Hughes)
+
+Bugfixes:
+ - Add a special case of a DBus unique name of :org.freedesktop.PackageKit which is used in the self check code (Richard Hughes)
+ - Always emit Message(BackendError) when there is a parsing error from a spawned process (Richard Hughes)
+ - Always emit the locked and unlocked signals even if HAL is not available (Richard Hughes)
+ - cnf: Pass all arguments to comand-not-found so we open the newly installed tool with existing argv (Richard Hughes)
+ - Do not strip the trailing plus when comparing licences, as GPL+ exists, but GPL does not (Richard Hughes)
+ - Ensure we notice when a spawn command is invalid by printing it in red on the command line (Richard Hughes)
+ - Make PkLsof find lsof on Debian (Matthias Klumpp)
+ - Make the output of command-not-found match the bash builtin. Fixes rh#641311 (Richard Hughes)
+ - Move the managed bindings to a seporate repo as they are very out of date (Richard Hughes)
+ - Prevent a segfault when estimating the time when the backend issues many ProgressChanged signals at one time. Fixes #30941 (Richard Hughes)
+ - Raise the default of StateChangedTimeoutPriority from 5 seconds to 30 seconds. Fixes rh#641691 (Richard Hughes)
+ - Require GTK >= 2.91.0 for the GTK3 version of the PackageKit font install module (Richard Hughes)
+ - Return with success if the database contained no proxy values for a transaction, as this could be correct (Richard Hughes)
+ - Switch from EggDebug to the GLib debugging framework (Richard Hughes)
+ - Switch the default to UseUpdateCache=false now we are using cache-age (Richard Hughes)
+
 Version 0.6.9
 ~~~~~~~~~~~~~
 Released: 2010-10-04
diff --git a/configure.ac b/configure.ac
index f350f27..51cae63 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=4
+LT_REVISION=5
 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 2d1fdd6..51c0bec 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.10</td><td></td><td>2010-11-01</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>
commit 7503df97dfb4fdacced759fdac16201651a97b03
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Nov 1 16:18:34 2010 +0000

    trivial: don't spray the client helper process stderr on the PackageKit console, just log it

diff --git a/lib/packagekit-glib2/pk-client-helper.c b/lib/packagekit-glib2/pk-client-helper.c
index ccf3b10..fd440ac 100644
--- a/lib/packagekit-glib2/pk-client-helper.c
+++ b/lib/packagekit-glib2/pk-client-helper.c
@@ -70,9 +70,11 @@ struct _PkClientHelperPrivate
 	GIOChannel			*io_channel_socket;
 	GIOChannel			*io_channel_child_stdin;
 	GIOChannel			*io_channel_child_stdout;
+	GIOChannel			*io_channel_child_stderr;
 	guint				 io_channel_socket_listen_id;
 	guint				 io_channel_child_stdin_listen_id;
 	guint				 io_channel_child_stdout_listen_id;
+	guint				 io_channel_child_stderr_listen_id;
 	gchar				**argv;
 	gchar				**envp;
 	GSocket				*socket;
@@ -117,6 +119,8 @@ pk_client_helper_stop (PkClientHelper *client_helper, GError **error)
 		g_source_remove (priv->io_channel_socket_listen_id);
 	if (priv->io_channel_child_stdout_listen_id > 0)
 		g_source_remove (priv->io_channel_child_stdout_listen_id);
+	if (priv->io_channel_child_stderr_listen_id > 0)
+		g_source_remove (priv->io_channel_child_stderr_listen_id);
 	if (priv->io_channel_child_stdin_listen_id > 0)
 		g_source_remove (priv->io_channel_child_stdin_listen_id);
 
@@ -166,6 +170,13 @@ pk_client_helper_copy_stdout_cb (GIOChannel *source, GIOCondition condition, PkC
 			ret = FALSE;
 			goto out;
 		}
+		status = g_io_channel_shutdown (priv->io_channel_child_stderr, FALSE, &error);
+		if (status != G_IO_STATUS_NORMAL) {
+			g_warning ("failed to shutdown channel: %s", error->message);
+			g_error_free (error);
+			ret = FALSE;
+			goto out;
+		}
 		if (priv->active_conn != NULL) {
 			ret = g_socket_close (priv->active_conn, &error);
 			if (!ret) {
@@ -213,6 +224,37 @@ out:
 }
 
 /**
+ * pk_client_helper_echo_stderr_cb:
+ **/
+static gboolean
+pk_client_helper_echo_stderr_cb (GIOChannel *source, GIOCondition condition, PkClientHelper *client_helper)
+{
+	gchar data[1024];
+	gsize len = 0;
+	GIOStatus status;
+	gboolean ret = TRUE;
+
+	/* there is data to read */
+	if ((condition & G_IO_IN) == 0)
+		goto out;
+
+	/* read data */
+	status = g_io_channel_read_chars (source, data, 1024, &len, NULL);
+	if (status == G_IO_STATUS_EOF) {
+		ret = FALSE;
+		goto out;
+	}
+	if (len == 0)
+		goto out;
+
+	/* write to socket */
+	data[len] = '\0';
+	g_debug ("child has error: %s", data);
+out:
+	return ret;
+}
+
+/**
  * pk_client_helper_copy_conn_cb:
  **/
 static gboolean
@@ -283,6 +325,7 @@ pk_client_helper_accept_connection_cb (GIOChannel *source, GIOCondition conditio
 	PkClientHelperPrivate *priv = client_helper->priv;
 	gint standard_input = 0;
 	gint standard_output = 0;
+	gint standard_error = 0;
 	gint fd;
 	GError *error = NULL;
 	gboolean ret = TRUE;
@@ -305,7 +348,7 @@ pk_client_helper_accept_connection_cb (GIOChannel *source, GIOCondition conditio
 
 	/* spawn helper executable */
 	ret = g_spawn_async_with_pipes (NULL, priv->argv, priv->envp, 0, NULL, NULL, &priv->child_pid,
-					&standard_input, &standard_output, NULL, &error);
+					&standard_input, &standard_output, &standard_error, &error);
 	if (!ret) {
 		g_warning ("failed to spawn: %s", error->message);
 		g_error_free (error);
@@ -316,6 +359,7 @@ pk_client_helper_accept_connection_cb (GIOChannel *source, GIOCondition conditio
 	/* connect up */
 	priv->io_channel_child_stdin = g_io_channel_unix_new (standard_input);
 	priv->io_channel_child_stdout = g_io_channel_unix_new (standard_output);
+	priv->io_channel_child_stderr = g_io_channel_unix_new (standard_error);
 
 	/* binary data */
 	status = g_io_channel_set_encoding (priv->io_channel_child_stdin, NULL, &error);
@@ -335,6 +379,15 @@ pk_client_helper_accept_connection_cb (GIOChannel *source, GIOCondition conditio
 	}
 	g_io_channel_set_buffered (priv->io_channel_child_stdout, FALSE);
 
+	/* binary data */
+	status = g_io_channel_set_encoding (priv->io_channel_child_stderr, NULL, &error);
+	if (status != G_IO_STATUS_NORMAL) {
+		g_warning ("failed to set encoding: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+	g_io_channel_set_buffered (priv->io_channel_child_stderr, FALSE);
+
 	/* socket has data */
 	fd = g_socket_get_fd (priv->active_conn);
 	priv->io_channel_socket = g_io_channel_unix_new (fd);
@@ -356,6 +409,9 @@ pk_client_helper_accept_connection_cb (GIOChannel *source, GIOCondition conditio
 		g_io_add_watch_full (priv->io_channel_child_stdout, G_PRIORITY_HIGH_IDLE,
 				     G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
 				     (GIOFunc) pk_client_helper_copy_stdout_cb, client_helper, NULL);
+	priv->io_channel_child_stderr_listen_id =
+		g_io_add_watch_full (priv->io_channel_child_stderr, G_PRIORITY_HIGH_IDLE, G_IO_IN,
+				     (GIOFunc) pk_client_helper_echo_stderr_cb, client_helper, NULL);
 out:
 	return TRUE;
 }
@@ -477,6 +533,8 @@ pk_client_helper_finalize (GObject *object)
 		g_io_channel_unref (priv->io_channel_child_stdin);
 	if (priv->io_channel_child_stdout != NULL)
 		g_io_channel_unref (priv->io_channel_child_stdout);
+	if (priv->io_channel_child_stderr != NULL)
+		g_io_channel_unref (priv->io_channel_child_stderr);
 	g_strfreev (priv->argv);
 	g_strfreev (priv->envp);
 
commit d171be48499c5c4cb13990946c2d662ac38abd8f
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Nov 1 15:51:38 2010 +0000

    trivial: Set the debconf TERM environment so pkcon can work without a DISPLAY

diff --git a/lib/packagekit-glib2/pk-client.c b/lib/packagekit-glib2/pk-client.c
index 71945eb..faa7777 100644
--- a/lib/packagekit-glib2/pk-client.c
+++ b/lib/packagekit-glib2/pk-client.c
@@ -1828,22 +1828,37 @@ pk_client_create_helper_socket (PkClientState *state)
 	guint argvi = 0;
 	guint envpi = 0;
 	const gchar *display;
+	const gchar *term;
+	const gchar *dialog = NULL;
 
 	/* do we have any supported clients */
 	if (g_file_test ("/usr/bin/debconf-communicate", G_FILE_TEST_EXISTS)) {
 		argv = g_new0 (gchar *, 2);
 		argv[argvi++] = g_strdup ("/usr/bin/debconf-communicate");
-		envp = g_new0 (gchar *, 7);
+		envp = g_new0 (gchar *, 8);
 		envp[envpi++] = g_strdup ("DEBCONF_DB_REPLACE=configdb");
 		envp[envpi++] = g_strdup ("DEBCONF_DB_OVERRIDE=Pipe{infd:none outfd:none}");
 		if (pk_debug_is_verbose ())
 			envp[envpi++] = g_strdup ("DEBCONF_DEBUG=.");
+
+		/* do we have an available terminal to use */
+		term = g_getenv ("TERM");
+		if (term != NULL) {
+			envp[envpi++] = g_strdup_printf ("TERM=%s", term);
+			dialog = "dialog";
+		}
+
+		/* do we have access to the display */
 		display = g_getenv ("DISPLAY");
 		if (display != NULL) {
 			envp[envpi++] = g_strdup_printf ("DISPLAY=%s", display);
-			envp[envpi++] = g_strdup ("DEBIAN_FRONTEND=gnome");
-		} else {
-			envp[envpi++] = g_strdup ("DEBIAN_FRONTEND=dialog");
+			dialog = "gnome";
+		}
+
+		/* indicate a prefered frontend */
+		if (dialog != NULL) {
+			envp[envpi++] = g_strdup_printf ("DEBIAN_FRONTEND=%s", dialog);
+			g_debug ("using frontend %s", dialog);
 		}
 	} else if (g_file_test (TESTDATADIR "/pk-client-helper-test.py", G_FILE_TEST_EXISTS)) {
 		argv = g_new0 (gchar *, 2);
commit 35a631480ab22657f23637ba75688a7c9ad1259f
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Nov 1 14:53:38 2010 +0000

    trivial: I need to setup a 64 bit machine here

diff --git a/lib/packagekit-glib2/pk-socket-example.c b/lib/packagekit-glib2/pk-socket-example.c
index 7c3ad36..c988122 100644
--- a/lib/packagekit-glib2/pk-socket-example.c
+++ b/lib/packagekit-glib2/pk-socket-example.c
@@ -50,7 +50,7 @@ pk_socket_example_accept_connection_cb (GSocket *socket, GIOCondition condition,
 		}
 		if (len == 0)
 			goto out;
-		g_debug ("got data: %s : %i", buffer, len);
+		g_debug ("got data: %s : %" G_GSIZE_FORMAT, buffer, len);
 	}
 out:
 	return ret;
commit 5c1c0e629deade85ae2385d8e78e957ea9724a50
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Nov 1 13:03:50 2010 +0000

    trivial: fix compile with 64 bit size_t, harder

diff --git a/lib/packagekit-glib2/pk-client-helper.c b/lib/packagekit-glib2/pk-client-helper.c
index cfe3ec8..ccf3b10 100644
--- a/lib/packagekit-glib2/pk-client-helper.c
+++ b/lib/packagekit-glib2/pk-client-helper.c
@@ -206,7 +206,7 @@ pk_client_helper_copy_stdout_cb (GIOChannel *source, GIOCondition condition, PkC
 				   "only wrote %" G_GSIZE_FORMAT " bytes", len, written);
 			goto out;
 		}
-		g_debug ("wrote %i bytes to socket", written);
+		g_debug ("wrote %" G_GSIZE_FORMAT " bytes to socket", written);
 	}
 out:
 	return ret;
@@ -268,7 +268,7 @@ pk_client_helper_copy_conn_cb (GIOChannel *source, GIOCondition condition, PkCli
 				   "only wrote %" G_GSIZE_FORMAT " bytes", len, written);
 			goto out;
 		}
-		g_debug ("wrote %i bytes to stdin of %s", written, priv->argv[0]);
+		g_debug ("wrote %" G_GSIZE_FORMAT " bytes to stdin of %s", written, priv->argv[0]);
 	}
 out:
 	return ret;
commit 30efcf464395604a353670943ebdce3395c646dd
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Nov 1 12:59:57 2010 +0000

    trivial: fix compile with 64 bit size_t

diff --git a/lib/packagekit-glib2/pk-client-helper.c b/lib/packagekit-glib2/pk-client-helper.c
index c9b35ef..cfe3ec8 100644
--- a/lib/packagekit-glib2/pk-client-helper.c
+++ b/lib/packagekit-glib2/pk-client-helper.c
@@ -161,8 +161,9 @@ pk_client_helper_copy_stdout_cb (GIOChannel *source, GIOCondition condition, PkC
 		g_debug ("helper process exited");
 		status = g_io_channel_shutdown (priv->io_channel_child_stdout, FALSE, &error);
 		if (status != G_IO_STATUS_NORMAL) {
-			g_error ("failed to shutdown channel: %s", error->message);
+			g_warning ("failed to shutdown channel: %s", error->message);
 			g_error_free (error);
+			ret = FALSE;
 			goto out;
 		}
 		if (priv->active_conn != NULL) {
@@ -188,19 +189,12 @@ pk_client_helper_copy_stdout_cb (GIOChannel *source, GIOCondition condition, PkC
 			ret = FALSE;
 			goto out;
 		}
-		if (status != G_IO_STATUS_NORMAL) {
-			g_error ("failed to read: %s", error->message);
-			g_error_free (error);
-			goto out;
-		}
 		if (len == 0)
 			goto out;
-		data[len] = '\0';
-		g_debug ("child has input to push to the socket: %s", data);
 
 		/* write to socket */
 		data[len] = '\0';
-		g_debug ("socket has data to push to child: '%s'", data);
+		g_debug ("child has input to push to the socket: %s", data);
 		status = g_io_channel_write_chars (priv->io_channel_socket, data, len, &written, &error);
 		if (status != G_IO_STATUS_NORMAL) {
 			g_warning ("failed to write to socket: %s", error->message);
@@ -208,7 +202,8 @@ pk_client_helper_copy_stdout_cb (GIOChannel *source, GIOCondition condition, PkC
 			goto out;
 		}
 		if (written != len) {
-			g_warning ("failed to write %i bytes, only wrote %i bytes", len, written);
+			g_warning ("failed to write %" G_GSIZE_FORMAT " bytes, "
+				   "only wrote %" G_GSIZE_FORMAT " bytes", len, written);
 			goto out;
 		}
 		g_debug ("wrote %i bytes to socket", written);
@@ -250,8 +245,6 @@ pk_client_helper_copy_conn_cb (GIOChannel *source, GIOCondition condition, PkCli
 		status = g_io_channel_read_chars (source, data, 1024, &len, &error);
 		if (status == G_IO_STATUS_EOF)
 			goto out;
-		if (status != G_IO_STATUS_NORMAL)
-			g_error ("status = %i (%i,%i,%i,%i)", status, G_IO_STATUS_NORMAL, G_IO_STATUS_AGAIN, G_IO_STATUS_EOF, G_IO_STATUS_ERROR);
 		if (error != NULL) {
 			ret = FALSE;
 			g_warning ("failed to read: %s", error->message);
@@ -271,7 +264,8 @@ pk_client_helper_copy_conn_cb (GIOChannel *source, GIOCondition condition, PkCli
 			goto out;
 		}
 		if (written != len) {
-			g_warning ("failed to write %i bytes, only wrote %i bytes", len, written);
+			g_warning ("failed to write %" G_GSIZE_FORMAT " bytes, "
+				   "only wrote %" G_GSIZE_FORMAT " bytes", len, written);
 			goto out;
 		}
 		g_debug ("wrote %i bytes to stdin of %s", written, priv->argv[0]);
commit 13d85b0308b44e7bcbb13883121789a21c0720f6
Author: Richard Hughes <richard at hughsie.com>
Date:   Sun Oct 31 20:29:52 2010 +0000

    Switch the default to UseUpdateCache=false now we are using a cache-age

diff --git a/etc/PackageKit.conf.in b/etc/PackageKit.conf.in
index 9841461..cc4d4cd 100644
--- a/etc/PackageKit.conf.in
+++ b/etc/PackageKit.conf.in
@@ -152,11 +152,12 @@ CheckTestingRepos=true
 
 # Use update cache when possible to avoid using the backend
 #
-# NOTE: Don't disable this unless you're trying to find bugs in packagekitd
-# and you want your backend to service every request.
+# NOTE: Enabling this reduces calls to the backend, although using the
+# SetHints(cache-age) parameter will return unpredicable results for
+# transactions.
 #
-# default=true
-UseUpdateCache=true
+# default=false
+UseUpdateCache=false
 
 # Use strict developer checking in the daemon
 #
commit 2b3d77d5472af9e54b5ce975974e7a0b6882c7b8
Author: Richard Hughes <richard at hughsie.com>
Date:   Sun Oct 31 20:21:11 2010 +0000

    Add some C getters and setters for PkClient and PkTask

diff --git a/lib/packagekit-glib2/pk-client.c b/lib/packagekit-glib2/pk-client.c
index 1dda2eb..71945eb 100644
--- a/lib/packagekit-glib2/pk-client.c
+++ b/lib/packagekit-glib2/pk-client.c
@@ -4503,6 +4503,163 @@ pk_client_cancel_all_dbus_methods (PkClient *client)
 }
 
 /**
+ * pk_client_set_locale:
+ * @client: a valid #PkClient instance
+ * @locale: the locale to set, e.g. "en_GB.UTF-8"
+ *
+ * Sets the locale to be used for the client. This may affect returned
+ * results.
+ *
+ * Since: 0.6.10
+ **/
+void
+pk_client_set_locale (PkClient *client, const gchar *locale)
+{
+	g_return_if_fail (PK_IS_CLIENT (client));
+	client->priv->locale = g_strdup (locale);
+	g_object_notify (G_OBJECT (client), "locale");
+}
+
+/**
+ * pk_client_get_locale:
+ * @client: a valid #PkClient instance
+ *
+ * Gets the locale used for this transaction.
+ *
+ * Return value: The locale.
+ *
+ * Since: 0.6.10
+ **/
+const gchar *
+pk_client_get_locale (PkClient *client)
+{
+	g_return_val_if_fail (PK_IS_CLIENT (client), NULL);
+	return client->priv->locale;
+}
+
+/**
+ * pk_client_set_background:
+ * @client: a valid #PkClient instance
+ * @background: if the transaction is a background transaction
+ *
+ * Sets the background value for the client. A background transaction
+ * is usually scheduled at a lower priority and is usually given less
+ * network and disk performance.
+ *
+ * Since: 0.6.10
+ **/
+void
+pk_client_set_background (PkClient *client, gboolean background)
+{
+	g_return_if_fail (PK_IS_CLIENT (client));
+	client->priv->background = background;
+	g_object_notify (G_OBJECT (client), "background");
+}
+
+/**
+ * pk_client_get_background:
+ * @client: a valid #PkClient instance
+ *
+ * Gets the background value.
+ *
+ * Return value: The background status.
+ *
+ * Since: 0.6.10
+ **/
+gboolean
+pk_client_get_background (PkClient *client)
+{
+	g_return_val_if_fail (PK_IS_CLIENT (client), FALSE);
+	return client->priv->background;
+}
+
+/**
+ * pk_client_set_interactive:
+ * @client: a valid #PkClient instance
+ * @interactive: the value to set
+ *
+ * Sets the interactive value for the client. Interactive transactions
+ * are usally allowed to ask the user questions.
+ *
+ * Since: 0.6.10
+ **/
+void
+pk_client_set_interactive (PkClient *client, gboolean interactive)
+{
+	g_return_if_fail (PK_IS_CLIENT (client));
+	client->priv->interactive = interactive;
+	g_object_notify (G_OBJECT (client), "interactive");
+}
+
+/**
+ * pk_client_get_interactive:
+ * @client: a valid #PkClient instance
+ *
+ * Gets the client interactive value.
+ *
+ * Return value: if the transaction is due to run interactivly.
+ *
+ * Since: 0.6.10
+ **/
+gboolean
+pk_client_get_interactive (PkClient *client)
+{
+	g_return_val_if_fail (PK_IS_CLIENT (client), FALSE);
+	return client->priv->interactive;
+}
+
+/**
+ * pk_client_get_idle:
+ * @client: a valid #PkClient instance
+ *
+ * Gets if the transaction client idle value.
+ *
+ * Return value: if this client is idle.
+ *
+ * Since: 0.6.10
+ **/
+gboolean
+pk_client_get_idle (PkClient *client)
+{
+	g_return_val_if_fail (PK_IS_CLIENT (client), FALSE);
+	return client->priv->idle;
+}
+
+/**
+ * pk_client_set_cache_age:
+ * @client: a valid #PkClient instance
+ * @cache_age: the cache age to set
+ *
+ * Sets the maximum cache age value for the client.
+ *
+ * Since: 0.6.10
+ **/
+void
+pk_client_set_cache_age (PkClient *client, guint cache_age)
+{
+	g_return_if_fail (PK_IS_CLIENT (client));
+	client->priv->cache_age = cache_age;
+	g_object_notify (G_OBJECT (client), "cache-age");
+}
+
+/**
+ * pk_client_get_cache_age:
+ * @client: a valid #PkClient instance
+ *
+ * Gets the maximum cache age value.
+ *
+ * Return value: The cache age in seconds
+ *
+ * Since: 0.6.10
+ **/
+guint
+pk_client_get_cache_age (PkClient *client)
+{
+	g_return_val_if_fail (PK_IS_CLIENT (client), FALSE);
+	return client->priv->cache_age;
+}
+
+/**
  * pk_client_class_init:
  **/
 static void
diff --git a/lib/packagekit-glib2/pk-client.h b/lib/packagekit-glib2/pk-client.h
index 2643237..0a52d4d 100644
--- a/lib/packagekit-glib2/pk-client.h
+++ b/lib/packagekit-glib2/pk-client.h
@@ -411,6 +411,21 @@ void		 pk_client_get_progress_async 		(PkClient		*client,
 							 GAsyncReadyCallback	 callback_ready,
 							 gpointer		 user_data);
 
+/* getters and setters */
+void		 pk_client_set_locale			(PkClient		*client,
+							 const gchar		*locale);
+const gchar	*pk_client_get_locale			(PkClient		*client);
+void		 pk_client_set_background		(PkClient		*client,
+							 gboolean		 background);
+gboolean	 pk_client_get_background		(PkClient		*client);
+void		 pk_client_set_interactive		(PkClient		*client,
+							 gboolean		 interactive);
+gboolean	 pk_client_get_interactive		(PkClient		*client);
+gboolean	 pk_client_get_idle			(PkClient		*client);
+void		 pk_client_set_cache_age		(PkClient		*client,
+							 guint			 cache_age);
+guint		 pk_client_get_cache_age		(PkClient		*client);
+
 G_END_DECLS
 
 #endif /* __PK_CLIENT_H */
diff --git a/lib/packagekit-glib2/pk-task.c b/lib/packagekit-glib2/pk-task.c
index 696c1c5..ba6f5f5 100644
--- a/lib/packagekit-glib2/pk-task.c
+++ b/lib/packagekit-glib2/pk-task.c
@@ -2210,6 +2210,76 @@ pk_task_generic_finish (PkTask *task, GAsyncResult *res, GError **error)
 }
 
 /**
+ * pk_task_set_simulate:
+ * @task: a valid #PkTask instance
+ * @simulate: the simulate mode
+ *
+ * If the simulate step should be run without the actual transaction.
+ *
+ * Since: 0.6.10
+ **/
+void
+pk_task_set_simulate (PkTask *task, gboolean simulate)
+{
+	g_return_if_fail (PK_IS_TASK (task));
+	task->priv->simulate = simulate;
+	g_object_notify (G_OBJECT (task), "simulate");
+}
+
+/**
+ * pk_task_get_simulate:
+ * @task: a valid #PkTask instance
+ *
+ * Gets if we are simulating.
+ *
+ * Return value: %TRUE if we are simulating
+ *
+ * Since: 0.6.10
+ **/
+gboolean
+pk_task_get_simulate (PkTask *task)
+{
+	g_return_val_if_fail (PK_IS_TASK (task), FALSE);
+	return task->priv->simulate;
+}
+
+
+/**
+ * pk_task_set_interactive:
+ * @task: a valid #PkTask instance
+ * @interactive: if we are interactive
+ *
+ * Sets the interactive mode, i.e. if the user is allowed to ask
+ * questions.
+ *
+ * Since: 0.6.10
+ **/
+void
+pk_task_set_interactive (PkTask *task, gboolean interactive)
+{
+	g_return_if_fail (PK_IS_TASK (task));
+	task->priv->interactive = interactive;
+	g_object_notify (G_OBJECT (task), "interactive");
+}
+
+/**
+ * pk_task_get_interactive:
+ * @task: a valid #PkTask instance
+ *
+ * Gets if the transaction is interactive.
+ *
+ * Return value: %TRUE for an interactive transaction.
+ *
+ * Since: 0.6.10
+ **/
+gboolean
+pk_task_get_interactive (PkTask *task)
+{
+	g_return_val_if_fail (PK_IS_TASK (task), FALSE);
+	return task->priv->interactive;
+}
+
+/**
  * pk_task_get_property:
  **/
 static void
diff --git a/lib/packagekit-glib2/pk-task.h b/lib/packagekit-glib2/pk-task.h
index 83a976e..de40af6 100644
--- a/lib/packagekit-glib2/pk-task.h
+++ b/lib/packagekit-glib2/pk-task.h
@@ -274,6 +274,14 @@ gboolean	 pk_task_user_accepted			(PkTask			*task,
 gboolean	 pk_task_user_declined			(PkTask			*task,
 							 guint			 request);
 
+/* getters and setters */
+void		 pk_task_set_simulate			(PkTask			*task,
+							 gboolean		 simulate);
+gboolean	 pk_task_get_simulate			(PkTask			*task);
+void		 pk_task_set_interactive		(PkTask			*task,
+							 gboolean		 interactive);
+gboolean	 pk_task_get_interactive		(PkTask			*task);
+
 G_END_DECLS
 
 #endif /* __PK_TASK_H */
commit 0af9993fe6cfb8509b33a38df02bad6b4543fb25
Author: Richard Hughes <richard at hughsie.com>
Date:   Sun Oct 31 12:10:43 2010 +0000

    yum: use the cache-age if set by the frontend

diff --git a/backends/yum/pk-backend-yum.c b/backends/yum/pk-backend-yum.c
index fd0dc93..4594e6c 100644
--- a/backends/yum/pk-backend-yum.c
+++ b/backends/yum/pk-backend-yum.c
@@ -184,6 +184,7 @@ pk_backend_transaction_start (PkBackend *backend)
 	const gchar *root;
 	guint i;
 	guint pid;
+	guint cache_age;
 	gchar *http_proxy = NULL;
 
 	/* quit the spawned backend rather than waiting for it to time out */
@@ -231,12 +232,17 @@ pk_backend_transaction_start (PkBackend *backend)
 	/* get network state */
 	ret = pk_backend_is_online (backend);
 	if (!ret) {
-		zif_config_set_local (priv->config, "network", "false", NULL);
+		zif_config_set_boolean (priv->config, "network", FALSE, NULL);
 		goto out;
 	}
 
 	/* tell ZifConfig it's okay to contact the network */
-	zif_config_set_local (priv->config, "network", "true", NULL);
+	zif_config_set_boolean (priv->config, "network", TRUE, NULL);
+
+	/* set cache age */
+	cache_age = pk_backend_get_cache_age (backend);
+	if (cache_age > 0)
+		zif_config_set_uint (priv->config, "max-age", cache_age, NULL);
 
 	/* set the proxy */
 	http_proxy = pk_backend_get_proxy_http (backend);
diff --git a/backends/yum/yumBackend.py b/backends/yum/yumBackend.py
index ca22942..f956d3e 100755
--- a/backends/yum/yumBackend.py
+++ b/backends/yum/yumBackend.py
@@ -3004,21 +3004,14 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
                 repo.metadata_expire = -1  # never refresh
             self.yumbase.conf.cache = 1
 
-        # we don't care about freshest data
-        elif lazy_cache:
-            for repo in self.yumbase.repos.listEnabled():
-                # is physical media
-                if repo.mediaid:
-                    continue
-                repo.metadata_expire = 60 * 60 * 24  # 24 hours
-
-        # default
-        else:
-            for repo in self.yumbase.repos.listEnabled():
-                # is physical media
-                if repo.mediaid:
-                    continue
-                repo.metadata_expire = 60 * 60 * 1.5 # 1.5 hours, the default
+        # choose a good default if the client didn't specify a timeout
+        if self.cache_age == 0:
+            self.cache_age = 60 * 60 * 24  # 24 hours
+        for repo in self.yumbase.repos.listEnabled():
+            # is physical media
+            if repo.mediaid:
+                continue
+            repo.metadata_expire = self.cache_age
 
         # disable repos that are not contactable
         for repo in self.yumbase.repos.listEnabled():
diff --git a/lib/python/packagekit/backend.py b/lib/python/packagekit/backend.py
index 83ac9c2..e89d174 100644
--- a/lib/python/packagekit/backend.py
+++ b/lib/python/packagekit/backend.py
@@ -90,7 +90,7 @@ class PackageKitBaseBackend:
 
         # try to get CACHE_AGE state
         try:
-            self.cache_age = int(os.environ['CACHE_AGE']):
+            self.cache_age = int(os.environ['CACHE_AGE'])
         except KeyError, e:
             pass
 
commit 8f15eb03c19c2af4c0b6d035da5547b2320c0f4a
Author: Richard Hughes <richard at hughsie.com>
Date:   Sun Oct 31 10:54:55 2010 +0000

    Add a new hint, 'cache-age' to allow the frontend to control the maximum age of the metadata

diff --git a/backends/yum/yumBackend.py b/backends/yum/yumBackend.py
index 9e034a6..ca22942 100755
--- a/backends/yum/yumBackend.py
+++ b/backends/yum/yumBackend.py
@@ -21,11 +21,13 @@
 #    Luke Macken <lmacken at redhat.com>
 #    James Bowes <jbowes at dangerouslyinc.com>
 #    Robin Norwood <rnorwood at redhat.com>
+#
+# Copyright (C) 2007-2010
 #    Richard Hughes <richard at hughsie.com>
 #
-#    MediaGrabber:
-#    Based on the logic of pirut by Jeremy Katz <katzj at redhat.com>
-#    Rewritten by Muayyad Alsadi <alsadi at ojuba.org>
+# Copyright (C) 2009
+#    MediaGrabber, based on the logic of pirut by Jeremy Katz <katzj at redhat.com>
+#    Muayyad Alsadi <alsadi at ojuba.org>
 
 # imports
 from packagekit.backend import *
diff --git a/client/pk-console.c b/client/pk-console.c
index 5c976ac..3f50821 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -1251,6 +1251,7 @@ main (int argc, char *argv[])
 	GError *error_local = NULL;
 	gboolean background = FALSE;
 	gboolean noninteractive = FALSE;
+	guint cache_age = 0;
 	gboolean plain = FALSE;
 	gboolean program_version = FALSE;
 	GOptionContext *context;
@@ -1290,6 +1291,9 @@ main (int argc, char *argv[])
 		{ "plain", 'p', 0, G_OPTION_ARG_NONE, &plain,
 			/* TRANSLATORS: command line argument, just output without fancy formatting */
 			_("Print to screen a machine readable output, rather than using animated widgets"), NULL},
+		{ "cache-age", 'c', 0, G_OPTION_ARG_INT, &cache_age,
+			/* TRANSLATORS: command line argument, just output without fancy formatting */
+			_("The maximum metadata cache age. Use -1 for 'never'."), NULL},
 		{ NULL}
 	};
 
@@ -1363,6 +1367,7 @@ main (int argc, char *argv[])
 		      "background", background,
 		      "simulate", !noninteractive,
 		      "interactive", !noninteractive,
+		      "cache-age", cache_age,
 		      NULL);
 
 	/* set the proxy */
diff --git a/contrib/command-not-found/pk-command-not-found.c b/contrib/command-not-found/pk-command-not-found.c
index 4d3aab7..05d1d53 100644
--- a/contrib/command-not-found/pk-command-not-found.c
+++ b/contrib/command-not-found/pk-command-not-found.c
@@ -719,6 +719,11 @@ main (int argc, char *argv[])
 	/* get policy config */
 	config = pk_cnf_get_config ();
 	task = PK_TASK(pk_task_text_new ());
+	g_object_set (task,
+		      "cache-age", G_MAXUINT,
+		      "interactive", FALSE,
+		      "background", FALSE,
+		      NULL);
 	cancellable = g_cancellable_new ();
 
 	/* get length */
diff --git a/lib/packagekit-glib2/pk-client.c b/lib/packagekit-glib2/pk-client.c
index 587ed99..1dda2eb 100644
--- a/lib/packagekit-glib2/pk-client.c
+++ b/lib/packagekit-glib2/pk-client.c
@@ -1,6 +1,6 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  *
- * Copyright (C) 2008 Richard Hughes <richard at hughsie.com>
+ * Copyright (C) 2008-2010 Richard Hughes <richard at hughsie.com>
  *
  * Licensed under the GNU Lesser General Public License Version 2.1
  *
@@ -67,6 +67,7 @@ struct _PkClientPrivate
 	gboolean		 background;
 	gboolean		 interactive;
 	gboolean		 idle;
+	guint			 cache_age;
 };
 
 enum {
@@ -75,6 +76,7 @@ enum {
 	PROP_BACKGROUND,
 	PROP_INTERACTIVE,
 	PROP_IDLE,
+	PROP_CACHE_AGE,
 	PROP_LAST
 };
 
@@ -164,6 +166,9 @@ pk_client_get_property (GObject *object, guint prop_id, GValue *value, GParamSpe
 	case PROP_IDLE:
 		g_value_set_boolean (value, priv->idle);
 		break;
+	case PROP_CACHE_AGE:
+		g_value_set_uint (value, priv->cache_age);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -190,6 +195,9 @@ pk_client_set_property (GObject *object, guint prop_id, const GValue *value, GPa
 	case PROP_INTERACTIVE:
 		priv->interactive = g_value_get_boolean (value);
 		break;
+	case PROP_CACHE_AGE:
+		priv->cache_age = g_value_get_uint (value);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -1925,6 +1933,12 @@ pk_client_get_tid_cb (GObject *object, GAsyncResult *res, PkClientState *state)
 	hint = g_strdup_printf ("interactive=%s", pk_client_bool_to_string (state->client->priv->interactive));
 	g_ptr_array_add (array, hint);
 
+	/* cache-age */
+	if (state->client->priv->cache_age > 0) {
+		hint = g_strdup_printf ("cache-age=%i", state->client->priv->cache_age);
+		g_ptr_array_add (array, hint);
+	}
+
 	/* create socket for roles that need interaction */
 	if (state->role == PK_ROLE_ENUM_INSTALL_FILES ||
 	    state->role == PK_ROLE_ENUM_INSTALL_PACKAGES ||
@@ -4541,6 +4555,16 @@ pk_client_class_init (PkClientClass *klass)
 	g_object_class_install_property (object_class, PROP_IDLE, pspec);
 
 	g_type_class_add_private (klass, sizeof (PkClientPrivate));
+
+	/**
+	 * PkClient:cache-age:
+	 *
+	 * Since: 0.6.10
+	 */
+	pspec = g_param_spec_uint ("cache-age", NULL, NULL,
+				   0, G_MAXUINT, 0,
+				   G_PARAM_READWRITE);
+	g_object_class_install_property (object_class, PROP_CACHE_AGE, pspec);
 }
 
 /**
@@ -4555,6 +4579,7 @@ pk_client_init (PkClient *client)
 	client->priv->background = FALSE;
 	client->priv->interactive = TRUE;
 	client->priv->idle = TRUE;
+	client->priv->cache_age = 0;
 
 	/* check dbus connections, exit if not valid */
 	client->priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
diff --git a/lib/python/packagekit/backend.py b/lib/python/packagekit/backend.py
index 50e1e25..83ac9c2 100644
--- a/lib/python/packagekit/backend.py
+++ b/lib/python/packagekit/backend.py
@@ -15,7 +15,7 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
 # Copyright (C) 2007 Tim Lauridsen <timlau at fedoraproject.org>
-
+# Copyright (C) 2007-2010 Richard Hughes <richard at hughsie.com>
 #
 # This file contain the base classes to implement a PackageKit python backend
 #
@@ -57,6 +57,7 @@ class PackageKitBaseBackend:
         self.has_network = False
         self.background = False
         self.interactive = False
+        self.cache_age = 0
         self.percentage_old = 0
         self.sub_percentage_old = 0
 
@@ -87,6 +88,12 @@ class PackageKitBaseBackend:
         except KeyError, e:
             print "Error: No INTERACTIVE envp"
 
+        # try to get CACHE_AGE state
+        try:
+            self.cache_age = int(os.environ['CACHE_AGE']):
+        except KeyError, e:
+            pass
+
     def doLock(self):
         ''' Generic locking, overide and extend in child class'''
         self._locked = True
diff --git a/src/org.freedesktop.PackageKit.Transaction.xml b/src/org.freedesktop.PackageKit.Transaction.xml
index c39fb8e..5c259d6 100644
--- a/src/org.freedesktop.PackageKit.Transaction.xml
+++ b/src/org.freedesktop.PackageKit.Transaction.xml
@@ -137,6 +137,9 @@
             method can be sent, although some backends may only use the values
             that were set before the transaction was started.
           </doc:para>
+          <doc:para>
+            Each parameter value is optional.
+          </doc:para>
         </doc:description>
       </doc:doc>
       <arg type="as" name="hints" direction="in">
@@ -144,7 +147,7 @@
           <doc:summary>
             <doc:para>
               The values as an array of strings, for example
-              <doc:tt>['locale=en_GB.utf8','idle=true','interactive=false']</doc:tt>.
+              <doc:tt>['locale=en_GB.utf8','idle=true','interactive=false','cache-age=3600']</doc:tt>.
             </doc:para>
             <doc:para>
               The following parameter values are understood:
@@ -174,6 +177,20 @@
                   and other values will result in an error.
                 </doc:definition>
               </doc:item>
+              <doc:item>
+                <doc:term>cache-age</doc:term>
+                <doc:definition>
+                  This allows the frontend to set how fresh it needs the
+                  metadata used in the transaction.
+                  This allows fine control of the age of the returned results,
+                  but means the frontend probably has to query the updates
+                  check value and pass it this value for <doc:tt>GetUpdates</doc:tt>,
+                  and choose something sane otherwise.
+                  Most interactive clients will set this to <doc:tt>intmax</doc:tt>doc:tt>
+                  which means "never download new metadata, unless required to return results".
+                  Most transactions will not have this value set.
+                </doc:definition>
+              </doc:item>
             </doc:list>
             <doc:para>
               Other values will cause a verbose warning in the daemon, but will
diff --git a/src/pk-backend-spawn.c b/src/pk-backend-spawn.c
index 29a3ca1..8dcca42 100644
--- a/src/pk-backend-spawn.c
+++ b/src/pk-backend-spawn.c
@@ -1,6 +1,6 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  *
- * Copyright (C) 2007-2008 Richard Hughes <richard at hughsie.com>
+ * Copyright (C) 2007-2010 Richard Hughes <richard at hughsie.com>
  *
  * Licensed under the GNU General Public License Version 2
  *
@@ -692,6 +692,7 @@ pk_backend_spawn_get_envp (PkBackendSpawn *backend_spawn)
 	gchar *transaction_id = NULL;
 	const gchar *value;
 	guint i;
+	guint cache_age;
 	GPtrArray *array;
 	gboolean ret;
 	PkHintEnum interactive;
@@ -765,6 +766,13 @@ pk_backend_spawn_get_envp (PkBackendSpawn *backend_spawn)
 	line = g_strdup_printf ("%s=%s", "INTERACTIVE", interactive ? "TRUE" : "FALSE");
 	g_ptr_array_add (array, line);
 
+	/* CACHE_AGE */
+	cache_age = pk_backend_get_cache_age (priv->backend);
+	if (cache_age > 0) {
+		line = g_strdup_printf ("%s=%i", "CACHE_AGE", cache_age);
+		g_ptr_array_add (array, line);
+	}
+
 	/* ensure the malicious user can't inject anthing from the session */
 	for (i=0; i<array->len; i++) {
 		line = g_ptr_array_index (array, i);
diff --git a/src/pk-backend.c b/src/pk-backend.c
index 1ccebf7..92f07e7 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -1,6 +1,6 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  *
- * Copyright (C) 2008 Richard Hughes <richard at hughsie.com>
+ * Copyright (C) 2008-2010 Richard Hughes <richard at hughsie.com>
  *
  * Licensed under the GNU General Public License Version 2
  *
@@ -101,6 +101,7 @@ struct PkBackendPrivate
 	gchar			*transaction_id;
 	gchar			*locale;
 	gchar			*frontend_socket;
+	guint			 cache_age;
 	gchar			*name;
 	gchar			*proxy_ftp;
 	gchar			*proxy_http;
@@ -1438,6 +1439,33 @@ pk_backend_set_frontend_socket (PkBackend *backend, const gchar *frontend_socket
 }
 
 /**
+ * pk_backend_get_cache_age:
+ *
+ * Gets the maximum cache age in seconds.
+ *
+ * Return value: the cache age in seconds, or 0 for unset or %G_MAXUINT for 'infinity'
+ **/
+guint
+pk_backend_get_cache_age (PkBackend *backend)
+{
+	g_return_val_if_fail (PK_IS_BACKEND (backend), 0);
+	return backend->priv->cache_age;
+}
+
+/**
+ * pk_backend_set_cache_age:
+ **/
+void
+pk_backend_set_cache_age (PkBackend *backend, guint cache_age)
+{
+	g_return_if_fail (PK_IS_BACKEND (backend));
+	g_return_if_fail (backend->priv->locked != FALSE);
+
+	g_debug ("cache-age changed to %i", cache_age);
+	backend->priv->cache_age = cache_age;
+}
+
+/**
  * pk_backend_details:
  **/
 gboolean
@@ -3386,6 +3414,7 @@ pk_backend_init (PkBackend *backend)
 	backend->priv->name = NULL;
 	backend->priv->locale = NULL;
 	backend->priv->frontend_socket = NULL;
+	backend->priv->cache_age = 0;
 	backend->priv->transaction_id = NULL;
 	backend->priv->proxy_http = NULL;
 	backend->priv->proxy_ftp = NULL;
diff --git a/src/pk-backend.h b/src/pk-backend.h
index 79d7403..1e3c44b 100644
--- a/src/pk-backend.h
+++ b/src/pk-backend.h
@@ -1,6 +1,6 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  *
- * Copyright (C) 2007-2008 Richard Hughes <richard at hughsie.com>
+ * Copyright (C) 2007-2010 Richard Hughes <richard at hughsie.com>
  *
  * Licensed under the GNU General Public License Version 2
  *
@@ -218,6 +218,8 @@ gboolean	 pk_backend_set_locale			(PkBackend	*backend,
 							 const gchar	*code);
 gboolean	 pk_backend_set_frontend_socket		(PkBackend	*backend,
 							 const gchar	*frontend_socket);
+void		 pk_backend_set_cache_age		(PkBackend	*backend,
+							 guint		 cache_age);
 
 /* get the state */
 gboolean	 pk_backend_get_allow_cancel		(PkBackend	*backend);
@@ -233,6 +235,7 @@ gchar		*pk_backend_get_proxy_http		(PkBackend	*backend);
 const gchar	*pk_backend_get_root			(PkBackend	*backend);
 gchar		*pk_backend_get_locale			(PkBackend	*backend);
 gchar		*pk_backend_get_frontend_socket		(PkBackend	*backend);
+guint		 pk_backend_get_cache_age		(PkBackend	*backend);
 
 /* signal helpers */
 gboolean	 pk_backend_finished			(PkBackend	*backend);
diff --git a/src/pk-transaction.c b/src/pk-transaction.c
index 0226833..28bc62d 100644
--- a/src/pk-transaction.c
+++ b/src/pk-transaction.c
@@ -1,6 +1,6 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  *
- * Copyright (C) 2008-2009 Richard Hughes <richard at hughsie.com>
+ * Copyright (C) 2008-2010 Richard Hughes <richard at hughsie.com>
  *
  * Licensed under the GNU General Public License Version 2
  *
@@ -103,6 +103,7 @@ struct PkTransactionPrivate
 	PkHintEnum		 interactive;
 	gchar			*locale;
 	gchar			*frontend_socket;
+	guint			 cache_age;
 	guint			 uid;
 	EggDbusMonitor		*monitor;
 	PkBackend		*backend;
@@ -1829,6 +1830,10 @@ pk_transaction_set_running (PkTransaction *transaction)
 	/* set the frontend socket if it exists */
 	pk_backend_set_frontend_socket (priv->backend, priv->frontend_socket);
 
+	/* set the cache-age */
+	if (priv->cache_age > 0)
+		pk_backend_set_cache_age (priv->backend, priv->cache_age);
+
 	/* set proxy */
 	ret = pk_transaction_set_session_state (transaction, &error);
 	if (!ret) {
@@ -4792,6 +4797,25 @@ pk_transaction_set_hint (PkTransaction *transaction, const gchar *key, const gch
 		goto out;
 	}
 
+	/* cache-age=<time-in-seconds> */
+	if (g_strcmp0 (key, "cache-age") == 0) {
+		ret = egg_strtouint (value, &priv->cache_age);
+		if (!ret) {
+			priv->cache_age = G_MAXUINT;
+			g_set_error (error, PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_NOT_SUPPORTED,
+				     "cannot parse cache age value %s", value);
+			ret = FALSE;
+		}
+		if (priv->cache_age == 0) {
+			priv->cache_age = G_MAXUINT;
+			g_set_error_literal (error, PK_TRANSACTION_ERROR,
+					     PK_TRANSACTION_ERROR_NOT_SUPPORTED,
+					     "cannot set a cache age of zero");
+			ret = FALSE;
+		}
+		goto out;
+	}
+
 	/* to preserve forwards and backwards compatibility, we ignore extra options here */
 	g_warning ("unknown option: %s with value %s", key, value);
 out:
@@ -5692,6 +5716,7 @@ pk_transaction_init (PkTransaction *transaction)
 	transaction->priv->sender = NULL;
 	transaction->priv->locale = NULL;
 	transaction->priv->frontend_socket = NULL;
+	transaction->priv->cache_age = 0;
 #ifdef USE_SECURITY_POLKIT
 	transaction->priv->subject = NULL;
 #endif
commit 1997d1e583a3ce8122b8eb937ee82dcd608d915e
Author: Richard Hughes <richard at hughsie.com>
Date:   Sat Oct 30 22:46:58 2010 +0100

    trivial: Actually pass a UNIX socket to the helper process, rather than a pipe

diff --git a/backends/dummy/pk-backend-dummy.c b/backends/dummy/pk-backend-dummy.c
index aefec67..6f8dec8 100644
--- a/backends/dummy/pk-backend-dummy.c
+++ b/backends/dummy/pk-backend-dummy.c
@@ -23,6 +23,8 @@
 #include <glib.h>
 #include <string.h>
 #include <stdlib.h>
+#include <gio/gio.h>
+#include <gio/gunixsocketaddress.h>
 
 #include <pk-backend.h>
 
@@ -47,6 +49,8 @@ static gboolean _use_gpg = FALSE;
 static gboolean _use_trusted = TRUE;
 static gboolean _use_distro_upgrade = FALSE;
 static PkBitfield _filters = 0;
+static GSocket *_socket = NULL;
+static guint _socket_listen_id = 0;
 
 /**
  * pk_backend_initialize:
@@ -958,9 +962,6 @@ pk_backend_update_packages (PkBackend *backend, gboolean only_trusted, gchar **p
 	_signal_timeout = g_timeout_add (200, pk_backend_update_packages_download_timeout, backend);
 }
 
-static GIOChannel *_io_channel = NULL;
-static guint _io_channel_listen_id = 0;
-
 static gboolean
 pk_backend_update_system_timeout (gpointer data)
 {
@@ -968,10 +969,10 @@ pk_backend_update_system_timeout (gpointer data)
 	if (_progress_percentage == 100) {
 
 		/* cleanup socket stuff */
-		if (_io_channel != NULL)
-			g_io_channel_unref (_io_channel);
-		if (_io_channel_listen_id != 0)
-			g_source_remove (_io_channel_listen_id);
+		if (_socket != NULL)
+			g_object_unref (_socket);
+		if (_socket_listen_id != 0)
+			g_source_remove (_socket_listen_id);
 
 		pk_backend_finished (backend);
 		return FALSE;
@@ -1034,65 +1035,66 @@ pk_backend_update_system_timeout (gpointer data)
  * pk_backend_socket_has_data_cb:
  **/
 static gboolean
-pk_backend_socket_has_data_cb (GIOChannel *source, GIOCondition condition, PkBackend *backend)
+pk_backend_socket_has_data_cb (GSocket *socket, GIOCondition condition, PkBackend *backend)
 {
-	gchar data[1024];
 	GError *error = NULL;
-	gsize len = 0;
-	GIOStatus status;
-	gsize written = 0;
-	gboolean ret = FALSE;
-
-	/* read any response from the client */
-	status = g_io_channel_read_chars (_io_channel, data, 1024, &len, &error);
-	if (status == G_IO_STATUS_EOF) {
-		ret = TRUE;
-		goto out;
-	}
-	if (status != G_IO_STATUS_NORMAL) {
+	gsize len;
+	gchar buffer[1024];
+	gboolean ret = TRUE;
+	gint wrote = 0;
+
+	/* the helper process exited */
+	if ((condition & G_IO_HUP) > 0) {
 		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR,
-				       "failed to read: %s", error->message);
+				       "socket was disconnected: %s", error->message);
 		pk_backend_finished (backend);
-		g_error_free (error);
+		ret = FALSE;
 		goto out;
 	}
-	if (len == 0)
-		goto out;
-
-	data[len] = '\0';
-	g_debug ("there is data: '%s'", data);
 
-	if (g_strcmp0 (data, "pong\n") == 0) {
-		/* send a message so we can verify in the self checks */
-		pk_backend_message (backend, PK_MESSAGE_ENUM_PARAMETER_INVALID, data);
-
-		/* verify we can write into the written channel */
-		status = g_io_channel_write_chars (_io_channel, "invalid\n", -1, &written, &error);
-		if (status != G_IO_STATUS_NORMAL) {
+	/* there is data */
+	if ((condition & G_IO_IN) > 0) {
+		len = g_socket_receive (socket, buffer, 1024, NULL, &error);
+		if (error != NULL) {
 			pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR,
-				       "failed to write to channel: %s", error->message);
+					       "failed to read: %s", error->message);
 			pk_backend_finished (backend);
 			g_error_free (error);
+			ret = FALSE;
 			goto out;
 		}
-		if (written != 8) {
+		if (len == 0)
+			goto out;
+		buffer[len] = '\0';
+		if (g_strcmp0 (buffer, "pong\n") == 0) {
+			/* send a message so we can verify in the self checks */
+			pk_backend_message (backend, PK_MESSAGE_ENUM_PARAMETER_INVALID, buffer);
+
+			/* verify we can write into the socket */
+			wrote = g_socket_send (_socket, "invalid\n", 8, NULL, &error);
+			if (error != NULL) {
+				pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR,
+						       "failed to write to socket: %s", error->message);
+				pk_backend_finished (backend);
+				g_error_free (error);
+				goto out;
+			}
+			if (wrote != 8) {
+				pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR,
+						       "failed to write, only %i bytes", wrote);
+				pk_backend_finished (backend);
+				goto out;
+			}
+		} else if (g_strcmp0 (buffer, "you said to me: invalid\n") == 0) {
+			g_debug ("ignoring invalid data (one is good)");
+		} else {
 			pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR,
-					       "failed to write, only %i bytes", written);
+					       "unexpected data: %s", buffer);
+			g_source_remove (_signal_timeout);
 			pk_backend_finished (backend);
 			goto out;
 		}
-	} else if (g_strcmp0 (data, "you said to me: invalid\n") == 0) {
-		g_debug ("ignoring invalid data (one is good)");
-	} else {
-		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR,
-				       "unexpected data: %s", data);
-		g_source_remove (_signal_timeout);
-		pk_backend_finished (backend);
-		goto out;
 	}
-
-	/* success */
-	ret = TRUE;
 out:
 	return ret;
 }
@@ -1104,16 +1106,18 @@ void
 pk_backend_update_system (PkBackend *backend, gboolean only_trusted)
 {
 	gchar *frontend_socket = NULL;
-	GIOStatus status;
 	GError *error = NULL;
-	gsize written = 0;
+	gboolean ret;
+	GSocketAddress *address = NULL;
+	gsize wrote;
+	GSource *source;
 
 	pk_backend_set_status (backend, PK_STATUS_ENUM_DOWNLOAD);
 	pk_backend_set_allow_cancel (backend, TRUE);
 	_progress_percentage = 0;
 
-	_io_channel = NULL;
-	_io_channel_listen_id = 0;
+	_socket = NULL;
+	_socket_listen_id = 0;
 
 	/* make sure we can contact the frontend */
 	frontend_socket = pk_backend_get_frontend_socket (backend);
@@ -1124,51 +1128,49 @@ pk_backend_update_system (PkBackend *backend, gboolean only_trusted)
 		goto out;
 	}
 
-	/* open the socket */
-	_io_channel = g_io_channel_new_file (frontend_socket, "r+", &error);
-	if (_io_channel == NULL) {
+	/* create socket */
+	_socket = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, &error);
+	if (_socket == NULL) {
 		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR,
-				       "failed to open io channel: %s", error->message);
+				       "failed to create socket: %s", error->message);
 		pk_backend_finished (backend);
 		g_error_free (error);
 		goto out;
 	}
+	g_socket_set_blocking (_socket, FALSE);
+	g_socket_set_keepalive (_socket, TRUE);
 
-	/* watch for any response */
-	_io_channel_listen_id = g_io_add_watch_full (_io_channel, G_PRIORITY_HIGH_IDLE, G_IO_IN,
-						     (GIOFunc) pk_backend_socket_has_data_cb, backend, NULL);
-
-	/* write "ping" */
-	status = g_io_channel_set_encoding (_io_channel, NULL, &error);
-	if (status != G_IO_STATUS_NORMAL) {
+	/* connect to it */
+	address = g_unix_socket_address_new_with_type (frontend_socket, -1, G_UNIX_SOCKET_ADDRESS_PATH);
+	ret = g_socket_connect (_socket, address, NULL, &error);
+	if (!ret) {
 		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR,
-				       "failed to set encoding: %s", error->message);
+				       "failed to open socket: %s", error->message);
 		pk_backend_finished (backend);
 		g_error_free (error);
 		goto out;
 	}
-	g_io_channel_set_buffered (_io_channel, FALSE);
 
-	status = g_io_channel_write_chars (_io_channel, "ping\n", -1, &written, &error);
-	if (status != G_IO_STATUS_NORMAL) {
-		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR,
-				       "failed to write to channel: %s", error->message);
-		pk_backend_finished (backend);
-		g_error_free (error);
-		goto out;
-	}
-	if (written != 5) {
+	/* socket has data */
+	source = g_socket_create_source (_socket, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, NULL);
+	g_source_set_callback (source, (GSourceFunc) pk_backend_socket_has_data_cb, backend, NULL);
+	_socket_listen_id = g_source_attach (source, NULL);
+
+	/* send some data */
+	wrote = g_socket_send (_socket, "ping\n", 5, NULL, &error);
+	if (wrote != 5) {
 		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR,
-				       "failed to write, only %i bytes", written);
+				       "failed to write, only %i bytes", wrote);
 		pk_backend_finished (backend);
 		goto out;
 	}
 
 	/* 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, pk_backend_update_system_timeout, backend);
 out:
+	if (address != NULL)
+		g_object_unref (address);
 	g_free (frontend_socket);
 }
 
diff --git a/configure.ac b/configure.ac
index 26bfc57..f350f27 100644
--- a/configure.ac
+++ b/configure.ac
@@ -749,8 +749,8 @@ AC_SUBST(PK_YUM_PLUGIN_DIR, "\$(prefix)/lib/yum-plugins")
 AC_SUBST(PK_DB_DIR, "\$(localstatedir)/lib/PackageKit")
 AC_SUBST(PK_LOG_DIR, "\$(localstatedir)/log")
 AC_SUBST(PK_PLUGIN_DIR, "\$(libdir)/packagekit-backend")
-AC_SUBST(PK_PLUGIN_CFLAGS, "-I\$(top_srcdir)/src -I\$(top_srcdir)/lib -DPK_COMPILATION $GLIB_CFLAGS $DBUS_CFLAGS $GMODULE_CFLAGS")
-AC_SUBST(PK_PLUGIN_LIBS, "$GLIB_LIBS $DBUS_LIBS $GMODULE_LIBS")
+AC_SUBST(PK_PLUGIN_CFLAGS, "-I\$(top_srcdir)/src -I\$(top_srcdir)/lib -DPK_COMPILATION $GLIB_CFLAGS $DBUS_CFLAGS $GMODULE_CFLAGS $GIO_CFLAGS")
+AC_SUBST(PK_PLUGIN_LIBS, "$GLIB_LIBS $DBUS_LIBS $GMODULE_LIBS $GIO_LIBS")
 
 dnl ---------------------------------------------------------------------------
 dnl - Makefiles, etc.
diff --git a/data/tests/pk-client-helper-test.py b/data/tests/pk-client-helper-test.py
old mode 100644
new mode 100755
diff --git a/lib/packagekit-glib2/.gitignore b/lib/packagekit-glib2/.gitignore
index 806b356..7fb56f6 100644
--- a/lib/packagekit-glib2/.gitignore
+++ b/lib/packagekit-glib2/.gitignore
@@ -7,6 +7,7 @@
 *-marshal.c
 *-marshal.h
 pk-self-test
+pk-socket-example
 *.loT
 *.db
 *.sh
diff --git a/lib/packagekit-glib2/Makefile.am b/lib/packagekit-glib2/Makefile.am
index d56ad54..ea16664 100644
--- a/lib/packagekit-glib2/Makefile.am
+++ b/lib/packagekit-glib2/Makefile.am
@@ -10,6 +10,7 @@ endif
 INCLUDES = \
 	$(GLIB_CFLAGS)						\
 	$(DBUS_CFLAGS)						\
+	$(GIO_CFLAGS)						\
 	$(POLKIT_CFLAGS)					\
 	$(SQLITE_CFLAGS)					\
 	-I$(top_srcdir)/lib					\
@@ -188,6 +189,11 @@ libpackagekitprivate_a_CFLAGS =					\
 	$(WARNINGFLAGS_C)					\
 	$(NULL)
 
+noinst_PROGRAMS = pk-socket-example
+pk_socket_example_SOURCES = pk-socket-example.c
+pk_socket_example_LDADD = $(GIO_LIBS) $(GLIB_LIBS)
+pk_socket_example_CFLAGS = $(WARNINGFLAGS_C)
+
 if EGG_BUILD_TESTS
 check_PROGRAMS =						\
 	pk-self-test
diff --git a/lib/packagekit-glib2/pk-client-helper.c b/lib/packagekit-glib2/pk-client-helper.c
index 08ed3f4..c9b35ef 100644
--- a/lib/packagekit-glib2/pk-client-helper.c
+++ b/lib/packagekit-glib2/pk-client-helper.c
@@ -2,6 +2,10 @@
  *
  * Copyright (C) 2010 Richard Hughes <richard at hughsie.com>
  *
+ * Loosely based on apt-daemon/debconf.py, which is:
+ *   Copyright (C) 2009 Sebastian Heinlein <devel at glatzor.de>
+ *   Copyright (C) 2009 Michael Vogt <michael.vogt at ubuntu.com>
+ *
  * Licensed under the GNU Lesser General Public License Version 2.1
  *
  * This library is free software; you can redistribute it and/or
@@ -26,6 +30,18 @@
  * This GObject can be used to run a session helper program out of band
  * with the normal PackageKit transaction. This allows an external program
  * such as debconf to be used that needs direct console access.
+ *
+ *
+ *   client ----> packagekit-glib ---> dbus ---> packagekitd ---> apt
+ *          .------------^                                         ^
+ *   debconf ___________________               (SetHints)          |
+ *    | \___|  PkClientHelper   \__.____.____.______/_.____.____.__/
+ *    ^-----|___________________/         (socket in tmp)
+ *   (stdin & stdout )
+ *
+ *  \------------.------------------/          \------------.---------/
+ *               |                                          |
+ *          user session                              system context
  */
 
 #include "config.h"
@@ -34,6 +50,7 @@
 #include <errno.h>
 #include <glib-object.h>
 #include <gio/gio.h>
+#include <gio/gunixsocketaddress.h>
 
 #include <packagekit-glib2/pk-client-helper.h>
 
@@ -49,12 +66,17 @@ static void     pk_client_helper_finalize	(GObject     *object);
 struct _PkClientHelperPrivate
 {
 	GFile				*socket_file;
+	GIOChannel			*io_channel_temp;
 	GIOChannel			*io_channel_socket;
 	GIOChannel			*io_channel_child_stdin;
 	GIOChannel			*io_channel_child_stdout;
 	guint				 io_channel_socket_listen_id;
+	guint				 io_channel_child_stdin_listen_id;
 	guint				 io_channel_child_stdout_listen_id;
 	gchar				**argv;
+	gchar				**envp;
+	GSocket				*socket;
+	GSocket				*active_conn;
 	GPid				 child_pid;
 };
 
@@ -85,11 +107,18 @@ pk_client_helper_stop (PkClientHelper *client_helper, GError **error)
 	/* make sure started */
 	g_return_val_if_fail (priv->socket_file != NULL, FALSE);
 
+	/* close the socket */
+	ret = g_socket_close (priv->socket, error);
+	if (!ret)
+		goto out;
+
 	/* stop watching for events */
 	if (priv->io_channel_socket_listen_id > 0)
 		g_source_remove (priv->io_channel_socket_listen_id);
 	if (priv->io_channel_child_stdout_listen_id > 0)
 		g_source_remove (priv->io_channel_child_stdout_listen_id);
+	if (priv->io_channel_child_stdin_listen_id > 0)
+		g_source_remove (priv->io_channel_child_stdin_listen_id);
 
 	/* kill process */
 	if (priv->child_pid > 0) {
@@ -114,10 +143,10 @@ out:
 }
 
 /**
- * pk_client_helper_child_has_output_cb:
+ * pk_client_helper_copy_stdout_cb:
  **/
 static gboolean
-pk_client_helper_child_has_output_cb (GIOChannel *source, GIOCondition condition, PkClientHelper *client_helper)
+pk_client_helper_copy_stdout_cb (GIOChannel *source, GIOCondition condition, PkClientHelper *client_helper)
 {
 	gchar data[1024];
 	GError *error = NULL;
@@ -127,46 +156,72 @@ pk_client_helper_child_has_output_cb (GIOChannel *source, GIOCondition condition
 	gboolean ret = TRUE;
 	PkClientHelperPrivate *priv = client_helper->priv;
 
-	/* read data */
-	status = g_io_channel_read_chars (source, data, 1024, &len, &error);
-	if (status == G_IO_STATUS_EOF) {
-		g_warning ("child closed unexpectedly");
+	/* the helper process exited */
+	if ((condition & G_IO_HUP) > 0) {
+		g_debug ("helper process exited");
+		status = g_io_channel_shutdown (priv->io_channel_child_stdout, FALSE, &error);
+		if (status != G_IO_STATUS_NORMAL) {
+			g_error ("failed to shutdown channel: %s", error->message);
+			g_error_free (error);
+			goto out;
+		}
+		if (priv->active_conn != NULL) {
+			ret = g_socket_close (priv->active_conn, &error);
+			if (!ret) {
+				g_warning ("failed to close socket");
+				g_error_free (error);
+			}
+			g_object_unref (priv->active_conn);
+			priv->active_conn = NULL;
+		}
 		ret = FALSE;
 		goto out;
 	}
-	if (status != G_IO_STATUS_NORMAL) {
-		g_warning ("failed to read: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-	if (len == 0)
-		goto out;
-	data[len] = '\0';
-	g_debug ("child has input to push to the socket: %s", data);
 
-	/* write to socket */
-	data[len] = '\0';
-	g_debug ("socket has data to push to child: '%s'", data);
-	status = g_io_channel_write_chars (priv->io_channel_socket, data, len, &written, &error);
-	if (status != G_IO_STATUS_NORMAL) {
-		g_warning ("failed to write to socket: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-	if (written != len) {
-		g_warning ("failed to write %i bytes, only wrote %i bytes", len, written);
-		goto out;
+	/* there is data to read */
+	if ((condition & G_IO_IN) > 0) {
+
+		/* read data */
+		status = g_io_channel_read_chars (source, data, 1024, &len, &error);
+		if (status == G_IO_STATUS_EOF) {
+			g_warning ("child closed unexpectedly");
+			ret = FALSE;
+			goto out;
+		}
+		if (status != G_IO_STATUS_NORMAL) {
+			g_error ("failed to read: %s", error->message);
+			g_error_free (error);
+			goto out;
+		}
+		if (len == 0)
+			goto out;
+		data[len] = '\0';
+		g_debug ("child has input to push to the socket: %s", data);
+
+		/* write to socket */
+		data[len] = '\0';
+		g_debug ("socket has data to push to child: '%s'", data);
+		status = g_io_channel_write_chars (priv->io_channel_socket, data, len, &written, &error);
+		if (status != G_IO_STATUS_NORMAL) {
+			g_warning ("failed to write to socket: %s", error->message);
+			g_error_free (error);
+			goto out;
+		}
+		if (written != len) {
+			g_warning ("failed to write %i bytes, only wrote %i bytes", len, written);
+			goto out;
+		}
+		g_debug ("wrote %i bytes to socket", written);
 	}
-	g_debug ("wrote %i bytes to socket", written);
 out:
 	return ret;
 }
 
 /**
- * pk_client_helper_socket_has_input_cb:
+ * pk_client_helper_copy_conn_cb:
  **/
 static gboolean
-pk_client_helper_socket_has_input_cb (GIOChannel *source, GIOCondition condition, PkClientHelper *client_helper)
+pk_client_helper_copy_conn_cb (GIOChannel *source, GIOCondition condition, PkClientHelper *client_helper)
 {
 	PkClientHelperPrivate *priv = client_helper->priv;
 	gchar data[1024];
@@ -176,36 +231,139 @@ pk_client_helper_socket_has_input_cb (GIOChannel *source, GIOCondition condition
 	gsize written = 0;
 	gboolean ret = TRUE;
 
-	/* read data */
-	status = g_io_channel_read_chars (source, data, 1024, &len, &error);
-	if (status == G_IO_STATUS_EOF)
+	/* package manager is done processing a package */
+	if ((condition & G_IO_HUP) > 0) {
+		g_debug ("socket hung up");
+		ret = g_socket_close (priv->active_conn, &error);
+		if (!ret) {
+			g_warning ("failed to close socket");
+			g_error_free (error);
+		}
+		g_object_unref (priv->active_conn);
+		priv->active_conn = NULL;
+		ret = FALSE;
+		goto out;
+	}
+
+	/* there is data to read */
+	if ((condition & G_IO_IN) > 0) {
+		status = g_io_channel_read_chars (source, data, 1024, &len, &error);
+		if (status == G_IO_STATUS_EOF)
+			goto out;
+		if (status != G_IO_STATUS_NORMAL)
+			g_error ("status = %i (%i,%i,%i,%i)", status, G_IO_STATUS_NORMAL, G_IO_STATUS_AGAIN, G_IO_STATUS_EOF, G_IO_STATUS_ERROR);
+		if (error != NULL) {
+			ret = FALSE;
+			g_warning ("failed to read: %s", error->message);
+			g_error_free (error);
+			goto out;
+		}
+		if (len == 0)
+			goto out;
+
+		/* write to child */
+		data[len] = '\0';
+		g_debug ("socket has data to push to child: '%s'", data);
+		status = g_io_channel_write_chars (priv->io_channel_child_stdin, data, len, &written, &error);
+		if (status != G_IO_STATUS_NORMAL) {
+			g_warning ("failed to write to stdin: %s", error->message);
+			g_error_free (error);
+			goto out;
+		}
+		if (written != len) {
+			g_warning ("failed to write %i bytes, only wrote %i bytes", len, written);
+			goto out;
+		}
+		g_debug ("wrote %i bytes to stdin of %s", written, priv->argv[0]);
+	}
+out:
+	return ret;
+}
+
+/**
+ * pk_client_helper_accept_connection_cb:
+ **/
+static gboolean
+pk_client_helper_accept_connection_cb (GIOChannel *source, GIOCondition condition, PkClientHelper *client_helper)
+{
+	PkClientHelperPrivate *priv = client_helper->priv;
+	gint standard_input = 0;
+	gint standard_output = 0;
+	gint fd;
+	GError *error = NULL;
+	gboolean ret = TRUE;
+	GIOStatus status;
+
+	/* delaying connection */
+	if (priv->active_conn != NULL)
+		goto out;
+
+	/* accept the connection request */
+	priv->active_conn = g_socket_accept (priv->socket, NULL, &error);
+	if (priv->active_conn == NULL) {
+		g_warning ("failed to accept socket: %s", error->message);
+		g_error_free (error);
 		goto out;
-	if (status != G_IO_STATUS_NORMAL)
-		g_error ("status = %i (%i,%i,%i,%i)", status, G_IO_STATUS_NORMAL, G_IO_STATUS_AGAIN, G_IO_STATUS_EOF, G_IO_STATUS_ERROR);
-	if (error != NULL) {
-		g_warning ("failed to read: %s", error->message);
+	}
+	g_debug ("accepting connection %i for socket %i",
+		 g_socket_get_fd (priv->active_conn),
+		 g_socket_get_fd (priv->socket));
+
+	/* spawn helper executable */
+	ret = g_spawn_async_with_pipes (NULL, priv->argv, priv->envp, 0, NULL, NULL, &priv->child_pid,
+					&standard_input, &standard_output, NULL, &error);
+	if (!ret) {
+		g_warning ("failed to spawn: %s", error->message);
 		g_error_free (error);
 		goto out;
 	}
-	if (len == 0)
+	g_debug ("started process %s with pid %i", priv->argv[0], priv->child_pid);
+
+	/* connect up */
+	priv->io_channel_child_stdin = g_io_channel_unix_new (standard_input);
+	priv->io_channel_child_stdout = g_io_channel_unix_new (standard_output);
+
+	/* binary data */
+	status = g_io_channel_set_encoding (priv->io_channel_child_stdin, NULL, &error);
+	if (status != G_IO_STATUS_NORMAL) {
+		g_warning ("failed to set encoding: %s", error->message);
+		g_error_free (error);
 		goto out;
+	}
+	g_io_channel_set_buffered (priv->io_channel_child_stdin, FALSE);
 
-	/* write to child */
-	data[len] = '\0';
-	g_debug ("socket has data to push to child: '%s'", data);
-	status = g_io_channel_write_chars (priv->io_channel_child_stdin, data, len, &written, &error);
+	/* binary data */
+	status = g_io_channel_set_encoding (priv->io_channel_child_stdout, NULL, &error);
 	if (status != G_IO_STATUS_NORMAL) {
-		g_warning ("failed to write to stdin: %s", error->message);
+		g_warning ("failed to set encoding: %s", error->message);
 		g_error_free (error);
 		goto out;
 	}
-	if (written != len) {
-		g_warning ("failed to write %i bytes, only wrote %i bytes", len, written);
+	g_io_channel_set_buffered (priv->io_channel_child_stdout, FALSE);
+
+	/* socket has data */
+	fd = g_socket_get_fd (priv->active_conn);
+	priv->io_channel_socket = g_io_channel_unix_new (fd);
+	priv->io_channel_child_stdin_listen_id =
+		g_io_add_watch_full (priv->io_channel_socket, G_PRIORITY_HIGH_IDLE,
+				     G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+				     (GIOFunc) pk_client_helper_copy_conn_cb, client_helper, NULL);
+	/* binary data */
+	status = g_io_channel_set_encoding (priv->io_channel_socket, NULL, &error);
+	if (status != G_IO_STATUS_NORMAL) {
+		g_warning ("failed to set encoding: %s", error->message);
+		g_error_free (error);
 		goto out;
 	}
-	g_debug ("wrote %i bytes to stdin of %s", written, priv->argv[0]);
+	g_io_channel_set_buffered (priv->io_channel_socket, FALSE);
+
+	/* frontend has data */
+	priv->io_channel_child_stdout_listen_id =
+		g_io_add_watch_full (priv->io_channel_child_stdout, G_PRIORITY_HIGH_IDLE,
+				     G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+				     (GIOFunc) pk_client_helper_copy_stdout_cb, client_helper, NULL);
 out:
-	return ret;
+	return TRUE;
 }
 
 /**
@@ -229,16 +387,14 @@ pk_client_helper_start (PkClientHelper *client_helper,
 			gchar **argv, gchar **envp,
 			GError **error)
 {
-	PkClientHelperPrivate *priv = client_helper->priv;
-	GIOStatus status;
 	gboolean ret = FALSE;
-	gint standard_input = 0;
-	gint standard_output = 0;
+	gint fd;
+	GSocketAddress *address = NULL;
+	PkClientHelperPrivate *priv = client_helper->priv;
 
 	g_return_val_if_fail (PK_IS_CLIENT_HELPER (client_helper), FALSE);
 	g_return_val_if_fail (socket_filename != NULL, FALSE);
 	g_return_val_if_fail (argv != NULL, FALSE);
-	g_return_val_if_fail (envp != NULL, FALSE);
 	g_return_val_if_fail (socket_filename != NULL, FALSE);
 	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
@@ -256,57 +412,35 @@ pk_client_helper_start (PkClientHelper *client_helper,
 
 	/* cache for actual start */
 	priv->argv = g_strdupv (argv);
+	priv->envp = g_strdupv (envp);
 
-	/* create file */
+	/* create socket */
 	priv->socket_file = g_file_new_for_path (socket_filename);
-	priv->io_channel_socket = g_io_channel_new_file (socket_filename, "w+", error);
-	if (priv->io_channel_socket == NULL)
+	priv->socket = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, error);
+	if (priv->socket == NULL)
 		goto out;
 
-	/* binary data */
-	status = g_io_channel_set_encoding (priv->io_channel_socket, NULL, error);
-	if (status != G_IO_STATUS_NORMAL)
-		goto out;
-	g_io_channel_set_buffered (priv->io_channel_socket, FALSE);
-
-	/* spawn helper executable */
-	ret = g_spawn_async_with_pipes (NULL, argv, envp, 0, NULL, NULL, &priv->child_pid,
-					&standard_input, &standard_output, NULL, error);
+	/* bind to the socket */
+	address = g_unix_socket_address_new_with_type (socket_filename, -1, G_UNIX_SOCKET_ADDRESS_PATH);
+	ret = g_socket_bind (priv->socket, address, TRUE, error);
 	if (!ret)
 		goto out;
-	g_debug ("started process %s with pid %i", priv->argv[0], priv->child_pid);
-
-	/* connect up */
-	priv->io_channel_child_stdin = g_io_channel_unix_new (standard_input);
-	priv->io_channel_child_stdout = g_io_channel_unix_new (standard_output);
-
-	/* binary data */
-	status = g_io_channel_set_encoding (priv->io_channel_child_stdin, NULL, error);
-	if (status != G_IO_STATUS_NORMAL)
-		goto out;
-	g_io_channel_set_buffered (priv->io_channel_child_stdin, FALSE);
 
-	/* binary data */
-	status = g_io_channel_set_encoding (priv->io_channel_child_stdout, NULL, error);
-	if (status != G_IO_STATUS_NORMAL)
+	/* listen to the socket */
+	ret = g_socket_listen (priv->socket, error);
+	if (!ret)
 		goto out;
-	g_io_channel_set_buffered (priv->io_channel_child_stdout, FALSE);
 
 	/* socket has data */
+	fd = g_socket_get_fd (priv->socket);
+	priv->io_channel_temp = g_io_channel_unix_new (fd);
 	priv->io_channel_socket_listen_id =
-		g_io_add_watch_full (priv->io_channel_socket, G_PRIORITY_HIGH_IDLE,
-				     G_IO_IN,
-				     (GIOFunc) pk_client_helper_socket_has_input_cb, client_helper, NULL);
-
-	/* frontend has data */
-	priv->io_channel_child_stdout_listen_id =
-		g_io_add_watch_full (priv->io_channel_child_stdout, G_PRIORITY_HIGH_IDLE,
-				     G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
-				     (GIOFunc) pk_client_helper_child_has_output_cb, client_helper, NULL);
-
-	/* success */
-	ret = TRUE;
+		g_io_add_watch_full (priv->io_channel_temp,
+				     G_PRIORITY_DEFAULT_IDLE, G_IO_IN,
+				     (GIOFunc) pk_client_helper_accept_connection_cb, client_helper, NULL);
 out:
+	if (address != NULL)
+		g_object_unref (address);
 	return ret;
 }
 
@@ -343,11 +477,14 @@ pk_client_helper_finalize (GObject *object)
 		g_object_unref (priv->socket_file);
 	if (priv->io_channel_socket != NULL)
 		g_io_channel_unref (priv->io_channel_socket);
+	if (priv->io_channel_temp != NULL)
+		g_io_channel_unref (priv->io_channel_temp);
 	if (priv->io_channel_child_stdin != NULL)
 		g_io_channel_unref (priv->io_channel_child_stdin);
 	if (priv->io_channel_child_stdout != NULL)
 		g_io_channel_unref (priv->io_channel_child_stdout);
 	g_strfreev (priv->argv);
+	g_strfreev (priv->envp);
 
 	G_OBJECT_CLASS (pk_client_helper_parent_class)->finalize (object);
 }
diff --git a/lib/packagekit-glib2/pk-self-test.c b/lib/packagekit-glib2/pk-self-test.c
index 4e39475..4be31b1 100644
--- a/lib/packagekit-glib2/pk-self-test.c
+++ b/lib/packagekit-glib2/pk-self-test.c
@@ -23,6 +23,7 @@
 
 #include <glib-object.h>
 #include <glib/gstdio.h>
+#include <gio/gunixsocketaddress.h>
 
 #include "pk-catalog.h"
 #include "pk-client.h"
@@ -298,35 +299,34 @@ pk_test_catalog_func (void)
  * pk_test_client_helper_output_cb:
  **/
 static gboolean
-pk_test_client_helper_output_cb (GIOChannel *source, GIOCondition condition, gpointer user_data)
+pk_test_client_helper_output_cb (GSocket *socket, GIOCondition condition, gpointer user_data)
 {
-	gchar data[6];
 	GError *error = NULL;
-	gsize len = 0;
-	GIOStatus status;
+	gsize len;
+	gchar buffer[6];
 	gboolean ret = TRUE;
 
-	/* read data */
-	status = g_io_channel_read_chars (source, data, 6, &len, &error);
-	if (status == G_IO_STATUS_EOF)
-		goto out;
-	if (status != G_IO_STATUS_NORMAL) {
-		g_warning ("failed to read: %s", error->message);
-		g_error_free (error);
+	/* the helper process exited */
+	if ((condition & G_IO_HUP) > 0) {
+		g_warning ("socket was disconnected");
+		ret = FALSE;
 		goto out;
 	}
-	if (len == 0)
-		goto out;
-	data[len] = '\0';
 
-	/* good for us */
-	if (g_strcmp0 (data, "pong\n") == 0) {
-		_g_test_loop_quit ();
-		goto out;
-	}
+	/* there is data */
+	if ((condition & G_IO_IN) > 0) {
+		len = g_socket_receive (socket, buffer, 6, NULL, &error);
+		g_assert_no_error (error);
+		g_assert_cmpint (len, >, 0);
 
-	/* bad */
-	g_warning ("child returned unexpected data: %s", data);
+		/* good for us */
+		if (g_strcmp0 (buffer, "pong\n") == 0) {
+			_g_test_loop_quit ();
+			goto out;
+		}
+		/* bad */
+		g_warning ("child returned unexpected data: %s", buffer);
+	}
 out:
 	return ret;
 }
@@ -338,11 +338,12 @@ pk_test_client_helper_func (void)
 	GError *error = NULL;
 	gchar *filename;
 	PkClientHelper *client_helper;
-	GIOStatus status;
-	gsize written;
 	const gchar *argv[] = { TESTDATADIR "/pk-client-helper-test.py", NULL };
 	const gchar *envp[] = { "DAVE=1", NULL };
-	GIOChannel *io_channel;
+	GSocket *socket = NULL;
+	GSocketAddress *address = NULL;
+	gsize wrote;
+	GSource *source;
 
 	client_helper = pk_client_helper_new ();
 	g_assert (client_helper != NULL);
@@ -366,31 +367,31 @@ pk_test_client_helper_func (void)
 	g_assert (ret);
 	g_assert (g_file_test (filename, G_FILE_TEST_EXISTS));
 
-	/* open the socket */
-	io_channel = g_io_channel_new_file (filename, "r+", &error);
+	/* create socket */
+	socket = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, &error);
 	g_assert_no_error (error);
-	g_assert (io_channel != NULL);
-
-	/* get reply */
-	g_io_add_watch_full (io_channel, G_PRIORITY_HIGH_IDLE,
-			     G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
-			     (GIOFunc) pk_test_client_helper_output_cb,
-			     NULL, NULL);
+	g_assert (socket != NULL);
+	g_socket_set_blocking (socket, FALSE);
+	g_socket_set_keepalive (socket, TRUE);
 
-	/* set no buffering */
-	status = g_io_channel_set_encoding (io_channel, NULL, &error);
+	/* connect to it */
+	address = g_unix_socket_address_new_with_type (filename, -1, G_UNIX_SOCKET_ADDRESS_PATH);
+	ret = g_socket_connect (socket, address, NULL, &error);
 	g_assert_no_error (error);
-	g_assert (status == G_IO_STATUS_NORMAL);
-	g_io_channel_set_buffered (io_channel, FALSE);
+	g_assert (ret);
+
+	/* socket has data */
+	source = g_socket_create_source (socket, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, NULL);
+	g_source_set_callback (source, (GSourceFunc) pk_test_client_helper_output_cb, NULL, NULL);
+	g_source_attach (source, NULL);
 
-	/* expect a response back */
-	status = g_io_channel_write_chars (io_channel, "ping\n", -1, &written, &error);
+	/* send some data */
+	wrote = g_socket_send (socket, "ping\n", 5, NULL, &error);
 	g_assert_no_error (error);
-	g_assert (status == G_IO_STATUS_NORMAL);
-	g_assert_cmpint (written, ==, 5);
+	g_assert_cmpint (wrote, ==, 5);
 
 	/* run for a few seconds */
-	_g_test_loop_run_with_timeout (3000);
+	_g_test_loop_run_with_timeout (1000);
 
 	/* stop the demo program */
 	ret = pk_client_helper_stop (client_helper, &error);
@@ -401,6 +402,8 @@ pk_test_client_helper_func (void)
 	g_unlink (filename);
 
 	g_free (filename);
+	g_object_unref (socket);
+	g_object_unref (address);
 	g_object_unref (client_helper);
 }
 
diff --git a/lib/packagekit-glib2/pk-socket-example.c b/lib/packagekit-glib2/pk-socket-example.c
new file mode 100644
index 0000000..7c3ad36
--- /dev/null
+++ b/lib/packagekit-glib2/pk-socket-example.c
@@ -0,0 +1,117 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2010 Richard Hughes <richard at hughsie.com>
+ *
+ * Licensed under the GNU Lesser General Public License Version 2.1
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <gio/gio.h>
+#include <gio/gunixsocketaddress.h>
+
+static gboolean
+pk_socket_example_accept_connection_cb (GSocket *socket, GIOCondition condition, gpointer user_data)
+{
+	GError *error = NULL;
+	gsize len;
+	gchar buffer[1024];
+	gboolean ret = TRUE;
+	GMainLoop *loop = (GMainLoop *) user_data;
+
+	/* the helper process exited */
+	if ((condition & G_IO_HUP) > 0) {
+		g_warning ("socket was disconnected");
+		g_main_loop_quit (loop);
+		ret = FALSE;
+		goto out;
+	}
+
+	/* there is data */
+	if ((condition & G_IO_IN) > 0) {
+		len = g_socket_receive (socket, buffer, 1024, NULL, &error);
+		if (error != NULL) {
+			g_warning ("failed to get data: %s", error->message);
+			g_error_free (error);
+			ret = FALSE;
+			goto out;
+		}
+		if (len == 0)
+			goto out;
+		g_debug ("got data: %s : %i", buffer, len);
+	}
+out:
+	return ret;
+}
+
+gint
+main (void)
+{
+	gboolean ret;
+	GSocket *socket = NULL;
+	GSocketAddress *address = NULL;
+	GError *error = NULL;
+	gsize wrote;
+	const gchar *buffer = "ping\n";
+	const gchar *socket_filename = "/tmp/pk-self-test.socket";
+	GSource *source;
+	GMainLoop *loop;
+
+	g_type_init ();
+	loop = g_main_loop_new (NULL, FALSE);
+
+	/* create socket */
+	socket = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, &error);
+	if (socket == NULL) {
+		g_warning ("failed to create socket: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+	g_socket_set_blocking (socket, FALSE);
+	g_socket_set_keepalive (socket, TRUE);
+
+	/* connect to it */
+	address = g_unix_socket_address_new_with_type (socket_filename, -1, G_UNIX_SOCKET_ADDRESS_PATH);
+	ret = g_socket_connect (socket, address, NULL, &error);
+	if (!ret) {
+		g_warning ("failed to connect to socket: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* socket has data */
+	source = g_socket_create_source (socket, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, NULL);
+	g_source_set_callback (source, (GSourceFunc) pk_socket_example_accept_connection_cb, loop, NULL);
+	g_source_attach (source, NULL);
+
+	/* send some data */
+	wrote = g_socket_send (socket, buffer, 5, NULL, &error);
+	if (wrote != 5) {
+		g_warning ("failed to write 5 bytes");
+		goto out;
+	}
+
+	/* run main loop */
+	g_debug ("running main loop");
+	g_main_loop_run (loop);
+out:
+	if (loop != NULL)
+		g_main_loop_unref (loop);
+	if (socket != NULL)
+		g_object_unref (socket);
+	if (address != NULL)
+		g_object_unref (address);
+	return 0;
+}
commit 19d6e8824ba43fcece5de3248c5672b0fd6a00db
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Oct 29 18:01:19 2010 +0100

    Set the DISPLAY when using debconf-communicate

diff --git a/lib/packagekit-glib2/pk-client.c b/lib/packagekit-glib2/pk-client.c
index bfbbf95..587ed99 100644
--- a/lib/packagekit-glib2/pk-client.c
+++ b/lib/packagekit-glib2/pk-client.c
@@ -41,6 +41,7 @@
 #include <packagekit-glib2/pk-client-helper.h>
 #include <packagekit-glib2/pk-common.h>
 #include <packagekit-glib2/pk-control.h>
+#include <packagekit-glib2/pk-debug.h>
 #include <packagekit-glib2/pk-enum.h>
 #include <packagekit-glib2/pk-marshal.h>
 #include <packagekit-glib2/pk-package-id.h>
@@ -1814,18 +1815,31 @@ pk_client_create_helper_socket (PkClientState *state)
 	gchar *socket_id = NULL;
 	GError *error = NULL;
 	gboolean ret;
-	const gchar *argv[2] = { NULL, NULL };
-	const gchar *envp[5] = { NULL, NULL, NULL, NULL, NULL };
+	gchar **argv = NULL;
+	gchar **envp = NULL;
+	guint argvi = 0;
+	guint envpi = 0;
+	const gchar *display;
 
 	/* do we have any supported clients */
 	if (g_file_test ("/usr/bin/debconf-communicate", G_FILE_TEST_EXISTS)) {
-		argv[0] = "/usr/bin/debconf-communicate";
-		envp[0] = "DEBCONF_DB_REPLACE=configdb";
-		envp[1] = "DEBCONF_DB_OVERRIDE=Pipe{infd:none outfd:none}";
-		envp[2] = "DEBIAN_FRONTEND=gnome";
-		envp[3] = "DEBCONF_DEBUG=.";
+		argv = g_new0 (gchar *, 2);
+		argv[argvi++] = g_strdup ("/usr/bin/debconf-communicate");
+		envp = g_new0 (gchar *, 7);
+		envp[envpi++] = g_strdup ("DEBCONF_DB_REPLACE=configdb");
+		envp[envpi++] = g_strdup ("DEBCONF_DB_OVERRIDE=Pipe{infd:none outfd:none}");
+		if (pk_debug_is_verbose ())
+			envp[envpi++] = g_strdup ("DEBCONF_DEBUG=.");
+		display = g_getenv ("DISPLAY");
+		if (display != NULL) {
+			envp[envpi++] = g_strdup_printf ("DISPLAY=%s", display);
+			envp[envpi++] = g_strdup ("DEBIAN_FRONTEND=gnome");
+		} else {
+			envp[envpi++] = g_strdup ("DEBIAN_FRONTEND=dialog");
+		}
 	} else if (g_file_test (TESTDATADIR "/pk-client-helper-test.py", G_FILE_TEST_EXISTS)) {
-		argv[0] = TESTDATADIR "/pk-client-helper-test.py";
+		argv = g_new0 (gchar *, 2);
+		argv[argvi++] = g_build_filename (TESTDATADIR, "pk-client-helper-test.py", NULL);
 	} else {
 		g_debug ("no supported frontends available");
 		goto out;
@@ -1839,7 +1853,7 @@ pk_client_create_helper_socket (PkClientState *state)
 	socket_filename = g_build_filename (g_get_tmp_dir (), socket_id, NULL);
 
 	/* start the helper process */
-	ret = pk_client_helper_start (state->client_helper, socket_filename, (gchar**)argv, (gchar**)envp, &error);
+	ret = pk_client_helper_start (state->client_helper, socket_filename, argv, envp, &error);
 	if (!ret) {
 		g_warning ("failed to open debconf socket: %s", error->message);
 		g_error_free (error);
@@ -1851,6 +1865,8 @@ pk_client_create_helper_socket (PkClientState *state)
 out:
 	g_free (socket_id);
 	g_free (socket_filename);
+	g_strfreev (argv);
+	g_strfreev (envp);
 	return hint;
 }
 
commit 71bdef61b7bd8a6f4abf249e0ac9a7a29b5d5d4f
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Oct 29 15:53:02 2010 +0100

    dummy: Add a self test which uses the frontend-socket hint, and plays ping-pong with the client

diff --git a/backends/dummy/pk-backend-dummy.c b/backends/dummy/pk-backend-dummy.c
index d3aaf9f..aefec67 100644
--- a/backends/dummy/pk-backend-dummy.c
+++ b/backends/dummy/pk-backend-dummy.c
@@ -958,11 +958,21 @@ pk_backend_update_packages (PkBackend *backend, gboolean only_trusted, gchar **p
 	_signal_timeout = g_timeout_add (200, pk_backend_update_packages_download_timeout, backend);
 }
 
+static GIOChannel *_io_channel = NULL;
+static guint _io_channel_listen_id = 0;
+
 static gboolean
 pk_backend_update_system_timeout (gpointer data)
 {
 	PkBackend *backend = (PkBackend *) data;
 	if (_progress_percentage == 100) {
+
+		/* cleanup socket stuff */
+		if (_io_channel != NULL)
+			g_io_channel_unref (_io_channel);
+		if (_io_channel_listen_id != 0)
+			g_source_remove (_io_channel_listen_id);
+
 		pk_backend_finished (backend);
 		return FALSE;
 	}
@@ -1019,20 +1029,147 @@ pk_backend_update_system_timeout (gpointer data)
 	return TRUE;
 }
 
+
+/**
+ * pk_backend_socket_has_data_cb:
+ **/
+static gboolean
+pk_backend_socket_has_data_cb (GIOChannel *source, GIOCondition condition, PkBackend *backend)
+{
+	gchar data[1024];
+	GError *error = NULL;
+	gsize len = 0;
+	GIOStatus status;
+	gsize written = 0;
+	gboolean ret = FALSE;
+
+	/* read any response from the client */
+	status = g_io_channel_read_chars (_io_channel, data, 1024, &len, &error);
+	if (status == G_IO_STATUS_EOF) {
+		ret = TRUE;
+		goto out;
+	}
+	if (status != G_IO_STATUS_NORMAL) {
+		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR,
+				       "failed to read: %s", error->message);
+		pk_backend_finished (backend);
+		g_error_free (error);
+		goto out;
+	}
+	if (len == 0)
+		goto out;
+
+	data[len] = '\0';
+	g_debug ("there is data: '%s'", data);
+
+	if (g_strcmp0 (data, "pong\n") == 0) {
+		/* send a message so we can verify in the self checks */
+		pk_backend_message (backend, PK_MESSAGE_ENUM_PARAMETER_INVALID, data);
+
+		/* verify we can write into the written channel */
+		status = g_io_channel_write_chars (_io_channel, "invalid\n", -1, &written, &error);
+		if (status != G_IO_STATUS_NORMAL) {
+			pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR,
+				       "failed to write to channel: %s", error->message);
+			pk_backend_finished (backend);
+			g_error_free (error);
+			goto out;
+		}
+		if (written != 8) {
+			pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR,
+					       "failed to write, only %i bytes", written);
+			pk_backend_finished (backend);
+			goto out;
+		}
+	} else if (g_strcmp0 (data, "you said to me: invalid\n") == 0) {
+		g_debug ("ignoring invalid data (one is good)");
+	} else {
+		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR,
+				       "unexpected data: %s", data);
+		g_source_remove (_signal_timeout);
+		pk_backend_finished (backend);
+		goto out;
+	}
+
+	/* success */
+	ret = TRUE;
+out:
+	return ret;
+}
+
 /**
  * pk_backend_update_system:
  */
 void
 pk_backend_update_system (PkBackend *backend, gboolean only_trusted)
 {
+	gchar *frontend_socket = NULL;
+	GIOStatus status;
+	GError *error = NULL;
+	gsize written = 0;
+
 	pk_backend_set_status (backend, PK_STATUS_ENUM_DOWNLOAD);
 	pk_backend_set_allow_cancel (backend, TRUE);
 	_progress_percentage = 0;
 
+	_io_channel = NULL;
+	_io_channel_listen_id = 0;
+
+	/* make sure we can contact the frontend */
+	frontend_socket = pk_backend_get_frontend_socket (backend);
+	if (frontend_socket == NULL) {
+		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR,
+				       "failed to get frontend socket");
+		pk_backend_finished (backend);
+		goto out;
+	}
+
+	/* open the socket */
+	_io_channel = g_io_channel_new_file (frontend_socket, "r+", &error);
+	if (_io_channel == NULL) {
+		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR,
+				       "failed to open io channel: %s", error->message);
+		pk_backend_finished (backend);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* watch for any response */
+	_io_channel_listen_id = g_io_add_watch_full (_io_channel, G_PRIORITY_HIGH_IDLE, G_IO_IN,
+						     (GIOFunc) pk_backend_socket_has_data_cb, backend, NULL);
+
+	/* write "ping" */
+	status = g_io_channel_set_encoding (_io_channel, NULL, &error);
+	if (status != G_IO_STATUS_NORMAL) {
+		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR,
+				       "failed to set encoding: %s", error->message);
+		pk_backend_finished (backend);
+		g_error_free (error);
+		goto out;
+	}
+	g_io_channel_set_buffered (_io_channel, FALSE);
+
+	status = g_io_channel_write_chars (_io_channel, "ping\n", -1, &written, &error);
+	if (status != G_IO_STATUS_NORMAL) {
+		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR,
+				       "failed to write to channel: %s", error->message);
+		pk_backend_finished (backend);
+		g_error_free (error);
+		goto out;
+	}
+	if (written != 5) {
+		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR,
+				       "failed to write, only %i bytes", written);
+		pk_backend_finished (backend);
+		goto out;
+	}
+
 	/* 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, pk_backend_update_system_timeout, backend);
+out:
+	g_free (frontend_socket);
 }
 
 /**
diff --git a/lib/packagekit-glib2/pk-self-test.c b/lib/packagekit-glib2/pk-self-test.c
index 247fe22..4e39475 100644
--- a/lib/packagekit-glib2/pk-self-test.c
+++ b/lib/packagekit-glib2/pk-self-test.c
@@ -639,6 +639,28 @@ pk_test_client_notify_idle_cb (PkClient *client, GParamSpec *pspec, gpointer use
 }
 
 static void
+pk_test_client_update_system_socket_test_cb (GObject *object, GAsyncResult *res, gpointer user_data)
+{
+	PkClient *client = PK_CLIENT (object);
+	GError *error = NULL;
+	PkResults *results = NULL;
+	GPtrArray *messages;
+
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	g_assert_no_error (error);
+	g_assert (results != NULL);
+
+	/* make sure we handled the ping/pong frontend-socket thing, which is 5 + 1 */
+	messages = pk_results_get_message_array (results);
+	g_assert_cmpint (messages->len, ==, 6);
+	g_ptr_array_unref (messages);
+
+	g_object_unref (results);
+	_g_test_loop_quit ();
+}
+
+static void
 pk_test_client_func (void)
 {
 	PkClient *client;
@@ -785,6 +807,12 @@ pk_test_client_func (void)
 	/* okay now */
 	g_cancellable_reset (cancellable);
 
+	/* do the update-system role to trigger the fake pipe stuff */
+	pk_client_update_system_async (client, TRUE, NULL,
+				       (PkProgressCallback) pk_test_client_progress_cb, NULL,
+				       (GAsyncReadyCallback) pk_test_client_update_system_socket_test_cb, NULL);
+	_g_test_loop_run_with_timeout (15000);
+
 	/* do downloads */
 	package_ids = pk_package_ids_from_id ("powertop;1.8-1.fc8;i386;fedora");
 	pk_client_download_packages_async (client, package_ids, "/tmp", cancellable,
commit a85a3087b3649cbba61f8eac9d9210ed70bb71aa
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Oct 29 15:51:33 2010 +0100

    Run the specified session helper for some transactions that may interact with the user
    
    This allows the user to interact with debconf on Debian, but it's untested.

diff --git a/lib/packagekit-glib2/pk-client.c b/lib/packagekit-glib2/pk-client.c
index d1523ed..bfbbf95 100644
--- a/lib/packagekit-glib2/pk-client.c
+++ b/lib/packagekit-glib2/pk-client.c
@@ -38,6 +38,7 @@
 #include <stdlib.h>
 
 #include <packagekit-glib2/pk-client.h>
+#include <packagekit-glib2/pk-client-helper.h>
 #include <packagekit-glib2/pk-common.h>
 #include <packagekit-glib2/pk-control.h>
 #include <packagekit-glib2/pk-enum.h>
@@ -118,6 +119,7 @@ typedef struct {
 	PkSigTypeEnum			 type;
 	guint				 refcount;
 	gboolean			 signals_connected;
+	PkClientHelper			*client_helper;
 } PkClientState;
 
 static void pk_client_finished_cb (DBusGProxy *proxy, const gchar *exit_text, guint runtime, PkClientState *state);
@@ -602,6 +604,7 @@ static void
 pk_client_state_finish (PkClientState *state, const GError *error)
 {
 	gboolean ret;
+	GError *error_local = NULL;
 
 	/* force finished (if not already set) so clients can update the UI's */
 	ret = pk_progress_set_status (state->progress, PK_STATUS_ENUM_FINISHED);
@@ -627,6 +630,16 @@ pk_client_state_finish (PkClientState *state, const GError *error)
 		g_simple_async_result_set_from_error (state->res, error);
 	}
 
+	/* remove any socket file */
+	if (state->client_helper != NULL) {
+		ret = pk_client_helper_stop (state->client_helper, &error_local);
+		if (!ret) {
+			g_warning ("failed to stop the client helper: %s", error_local->message);
+			g_error_free (error_local);
+		}
+		g_object_unref (state->client_helper);
+	}
+
 	/* remove from list */
 	pk_client_state_remove (state->client, state);
 
@@ -1791,6 +1804,57 @@ pk_client_bool_to_string (gboolean value)
 }
 
 /**
+ * pk_client_create_helper_socket:
+ **/
+static gchar *
+pk_client_create_helper_socket (PkClientState *state)
+{
+	gchar *hint = NULL;
+	gchar *socket_filename = NULL;
+	gchar *socket_id = NULL;
+	GError *error = NULL;
+	gboolean ret;
+	const gchar *argv[2] = { NULL, NULL };
+	const gchar *envp[5] = { NULL, NULL, NULL, NULL, NULL };
+
+	/* do we have any supported clients */
+	if (g_file_test ("/usr/bin/debconf-communicate", G_FILE_TEST_EXISTS)) {
+		argv[0] = "/usr/bin/debconf-communicate";
+		envp[0] = "DEBCONF_DB_REPLACE=configdb";
+		envp[1] = "DEBCONF_DB_OVERRIDE=Pipe{infd:none outfd:none}";
+		envp[2] = "DEBIAN_FRONTEND=gnome";
+		envp[3] = "DEBCONF_DEBUG=.";
+	} else if (g_file_test (TESTDATADIR "/pk-client-helper-test.py", G_FILE_TEST_EXISTS)) {
+		argv[0] = TESTDATADIR "/pk-client-helper-test.py";
+	} else {
+		g_debug ("no supported frontends available");
+		goto out;
+	}
+
+	/* create object */
+	state->client_helper = pk_client_helper_new ();
+
+	/* create socket to read from /tmp */
+	socket_id = g_strdup_printf ("gpk-%s.socket", &state->tid[1]);
+	socket_filename = g_build_filename (g_get_tmp_dir (), socket_id, NULL);
+
+	/* start the helper process */
+	ret = pk_client_helper_start (state->client_helper, socket_filename, (gchar**)argv, (gchar**)envp, &error);
+	if (!ret) {
+		g_warning ("failed to open debconf socket: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* success */
+	hint = g_strdup_printf ("frontend-socket=%s", socket_filename);
+out:
+	g_free (socket_id);
+	g_free (socket_filename);
+	return hint;
+}
+
+/**
  * pk_client_get_tid_cb:
  **/
 static void
@@ -1845,6 +1909,17 @@ pk_client_get_tid_cb (GObject *object, GAsyncResult *res, PkClientState *state)
 	hint = g_strdup_printf ("interactive=%s", pk_client_bool_to_string (state->client->priv->interactive));
 	g_ptr_array_add (array, hint);
 
+	/* create socket for roles that need interaction */
+	if (state->role == PK_ROLE_ENUM_INSTALL_FILES ||
+	    state->role == PK_ROLE_ENUM_INSTALL_PACKAGES ||
+	    state->role == PK_ROLE_ENUM_REMOVE_PACKAGES ||
+	    state->role == PK_ROLE_ENUM_UPDATE_PACKAGES ||
+	    state->role == PK_ROLE_ENUM_UPDATE_SYSTEM) {
+		hint = pk_client_create_helper_socket (state);
+		if (hint != NULL)
+			g_ptr_array_add (array, hint);
+	}
+
 	/* set hints */
 	hints = pk_ptr_array_to_strv (array);
 	state->call = dbus_g_proxy_begin_call (state->proxy, "SetHints",
commit 237d1d3294b0d43d9e3aa2142f9bf5b124c54d0e
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Oct 29 15:48:58 2010 +0100

    Add PkClientHelper, which allows a helper session program to be run for a transaction

diff --git a/data/tests/Makefile.am b/data/tests/Makefile.am
index aa719e2..cee4377 100644
--- a/data/tests/Makefile.am
+++ b/data/tests/Makefile.am
@@ -5,6 +5,7 @@ NULL =
 
 TEST_FILES =						\
 	test.catalog					\
+	pk-client-helper-test.py			\
 	pk-spawn-test.sh				\
 	pk-spawn-proxy.sh				\
 	pk-spawn-test-sigquit.sh			\
diff --git a/data/tests/pk-client-helper-test.py b/data/tests/pk-client-helper-test.py
new file mode 100644
index 0000000..e8f1d35
--- /dev/null
+++ b/data/tests/pk-client-helper-test.py
@@ -0,0 +1,42 @@
+#!/usr/bin/python
+# 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.
+#
+# Copyright (C) 2010 Richard Hughes <richard at hughsie.com>
+
+import sys
+
+def main():
+    while True:
+        try:
+            line = sys.stdin.readline().strip('\n')
+        except IOError, e:
+            print "could not read from stdin: %s", str(e)
+            break
+        except KeyboardInterrupt, e:
+            print "process was killed by ctrl-c", str(e)
+            break;
+        if not line or line == 'exit':
+            break
+        if line == 'ping':
+            sys.stdout.write ('pong\n')
+            sys.stdout.flush()
+        else:
+            sys.stdout.write ("you said to me: %s\n" % line)
+            sys.stdout.flush()
+
+if __name__ == "__main__":
+    main()
diff --git a/lib/packagekit-glib2/Makefile.am b/lib/packagekit-glib2/Makefile.am
index 366db1c..d56ad54 100644
--- a/lib/packagekit-glib2/Makefile.am
+++ b/lib/packagekit-glib2/Makefile.am
@@ -40,6 +40,7 @@ libpackagekit_glib2_include_HEADERS =				\
 	pk-catalog.h						\
 	pk-category.h						\
 	pk-client.h						\
+	pk-client-helper.h					\
 	pk-client-sync.h					\
 	pk-common.h						\
 	pk-control.h						\
@@ -82,6 +83,8 @@ libpackagekit_glib2_la_SOURCES =				\
 	pk-category.h						\
 	pk-client.c						\
 	pk-client.h						\
+	pk-client-helper.c					\
+	pk-client-helper.h					\
 	pk-client-sync.c					\
 	pk-client-sync.h					\
 	pk-common.c						\
diff --git a/lib/packagekit-glib2/pk-client-helper.c b/lib/packagekit-glib2/pk-client-helper.c
new file mode 100644
index 0000000..08ed3f4
--- /dev/null
+++ b/lib/packagekit-glib2/pk-client-helper.c
@@ -0,0 +1,368 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2010 Richard Hughes <richard at hughsie.com>
+ *
+ * Licensed under the GNU Lesser General Public License Version 2.1
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+/**
+ * SECTION:pk-client-helper
+ * @short_description: helper object to run a helper session process for the lifetime of a transaction
+ *
+ * This GObject can be used to run a session helper program out of band
+ * with the normal PackageKit transaction. This allows an external program
+ * such as debconf to be used that needs direct console access.
+ */
+
+#include "config.h"
+
+#include <signal.h>
+#include <errno.h>
+#include <glib-object.h>
+#include <gio/gio.h>
+
+#include <packagekit-glib2/pk-client-helper.h>
+
+static void     pk_client_helper_finalize	(GObject     *object);
+
+#define PK_CLIENT_HELPER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_CLIENT_HELPER, PkClientHelperPrivate))
+
+/**
+ * PkClientHelperPrivate:
+ *
+ * Private #PkClientHelper data
+ **/
+struct _PkClientHelperPrivate
+{
+	GFile				*socket_file;
+	GIOChannel			*io_channel_socket;
+	GIOChannel			*io_channel_child_stdin;
+	GIOChannel			*io_channel_child_stdout;
+	guint				 io_channel_socket_listen_id;
+	guint				 io_channel_child_stdout_listen_id;
+	gchar				**argv;
+	GPid				 child_pid;
+};
+
+G_DEFINE_TYPE (PkClientHelper, pk_client_helper, G_TYPE_OBJECT)
+
+/**
+ * pk_client_helper_stop:
+ * @client_helper: a valid #PkClientHelper instance
+ * @error: A #GError or %NULL
+ *
+ * Stops the helper process, by killing the helper process and deleting
+ * the socket.
+ *
+ * Return value: %TRUE for success
+ *
+ * Since: 0.6.10
+ **/
+gboolean
+pk_client_helper_stop (PkClientHelper *client_helper, GError **error)
+{
+	PkClientHelperPrivate *priv = client_helper->priv;
+	gboolean ret = FALSE;
+	gint retval;
+
+	g_return_val_if_fail (PK_IS_CLIENT_HELPER (client_helper), FALSE);
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+	/* make sure started */
+	g_return_val_if_fail (priv->socket_file != NULL, FALSE);
+
+	/* stop watching for events */
+	if (priv->io_channel_socket_listen_id > 0)
+		g_source_remove (priv->io_channel_socket_listen_id);
+	if (priv->io_channel_child_stdout_listen_id > 0)
+		g_source_remove (priv->io_channel_child_stdout_listen_id);
+
+	/* kill process */
+	if (priv->child_pid > 0) {
+		g_debug ("sending SIGQUIT %ld", (long)priv->child_pid);
+		retval = kill (priv->child_pid, SIGQUIT);
+		if (retval == EINVAL) {
+			g_set_error (error, 1, 0, "failed to kill, signum argument is invalid");
+			goto out;
+		}
+		if (retval == EPERM) {
+			g_set_error (error, 1, 0, "failed to kill, no permission");
+			goto out;
+		}
+	}
+
+	/* remove any socket file */
+	ret = g_file_delete (priv->socket_file, NULL, error);
+	if (!ret)
+		goto out;
+out:
+	return ret;
+}
+
+/**
+ * pk_client_helper_child_has_output_cb:
+ **/
+static gboolean
+pk_client_helper_child_has_output_cb (GIOChannel *source, GIOCondition condition, PkClientHelper *client_helper)
+{
+	gchar data[1024];
+	GError *error = NULL;
+	gsize len = 0;
+	gsize written = 0;
+	GIOStatus status;
+	gboolean ret = TRUE;
+	PkClientHelperPrivate *priv = client_helper->priv;
+
+	/* read data */
+	status = g_io_channel_read_chars (source, data, 1024, &len, &error);
+	if (status == G_IO_STATUS_EOF) {
+		g_warning ("child closed unexpectedly");
+		ret = FALSE;
+		goto out;
+	}
+	if (status != G_IO_STATUS_NORMAL) {
+		g_warning ("failed to read: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+	if (len == 0)
+		goto out;
+	data[len] = '\0';
+	g_debug ("child has input to push to the socket: %s", data);
+
+	/* write to socket */
+	data[len] = '\0';
+	g_debug ("socket has data to push to child: '%s'", data);
+	status = g_io_channel_write_chars (priv->io_channel_socket, data, len, &written, &error);
+	if (status != G_IO_STATUS_NORMAL) {
+		g_warning ("failed to write to socket: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+	if (written != len) {
+		g_warning ("failed to write %i bytes, only wrote %i bytes", len, written);
+		goto out;
+	}
+	g_debug ("wrote %i bytes to socket", written);
+out:
+	return ret;
+}
+
+/**
+ * pk_client_helper_socket_has_input_cb:
+ **/
+static gboolean
+pk_client_helper_socket_has_input_cb (GIOChannel *source, GIOCondition condition, PkClientHelper *client_helper)
+{
+	PkClientHelperPrivate *priv = client_helper->priv;
+	gchar data[1024];
+	GError *error = NULL;
+	gsize len = 0;
+	GIOStatus status;
+	gsize written = 0;
+	gboolean ret = TRUE;
+
+	/* read data */
+	status = g_io_channel_read_chars (source, data, 1024, &len, &error);
+	if (status == G_IO_STATUS_EOF)
+		goto out;
+	if (status != G_IO_STATUS_NORMAL)
+		g_error ("status = %i (%i,%i,%i,%i)", status, G_IO_STATUS_NORMAL, G_IO_STATUS_AGAIN, G_IO_STATUS_EOF, G_IO_STATUS_ERROR);
+	if (error != NULL) {
+		g_warning ("failed to read: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+	if (len == 0)
+		goto out;
+
+	/* write to child */
+	data[len] = '\0';
+	g_debug ("socket has data to push to child: '%s'", data);
+	status = g_io_channel_write_chars (priv->io_channel_child_stdin, data, len, &written, &error);
+	if (status != G_IO_STATUS_NORMAL) {
+		g_warning ("failed to write to stdin: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+	if (written != len) {
+		g_warning ("failed to write %i bytes, only wrote %i bytes", len, written);
+		goto out;
+	}
+	g_debug ("wrote %i bytes to stdin of %s", written, priv->argv[0]);
+out:
+	return ret;
+}
+
+/**
+ * pk_client_helper_start:
+ * @client_helper: a valid #PkClientHelper instance
+ * @socket_filename: a socket filename that does not already exist
+ * @argv: the executable, along with any arguments
+ * @envp: the environment
+ * @error: A #GError or %NULL
+ *
+ * Starts the helper process, by running the helper process and setting
+ * up the socket for use.
+ *
+ * Return value: %TRUE for success
+ *
+ * Since: 0.6.10
+ **/
+gboolean
+pk_client_helper_start (PkClientHelper *client_helper,
+			const gchar *socket_filename,
+			gchar **argv, gchar **envp,
+			GError **error)
+{
+	PkClientHelperPrivate *priv = client_helper->priv;
+	GIOStatus status;
+	gboolean ret = FALSE;
+	gint standard_input = 0;
+	gint standard_output = 0;
+
+	g_return_val_if_fail (PK_IS_CLIENT_HELPER (client_helper), FALSE);
+	g_return_val_if_fail (socket_filename != NULL, FALSE);
+	g_return_val_if_fail (argv != NULL, FALSE);
+	g_return_val_if_fail (envp != NULL, FALSE);
+	g_return_val_if_fail (socket_filename != NULL, FALSE);
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+	/* make sure not been started before */
+	g_return_val_if_fail (priv->argv == NULL, FALSE);
+	g_return_val_if_fail (priv->socket_file == NULL, FALSE);
+
+	/* already exists? */
+	if (g_file_test (socket_filename, G_FILE_TEST_EXISTS)) {
+		g_set_error (error, 1, 0, "socket %s already exists", socket_filename);
+		goto out;
+	}
+
+	g_debug ("using socket in %s", socket_filename);
+
+	/* cache for actual start */
+	priv->argv = g_strdupv (argv);
+
+	/* create file */
+	priv->socket_file = g_file_new_for_path (socket_filename);
+	priv->io_channel_socket = g_io_channel_new_file (socket_filename, "w+", error);
+	if (priv->io_channel_socket == NULL)
+		goto out;
+
+	/* binary data */
+	status = g_io_channel_set_encoding (priv->io_channel_socket, NULL, error);
+	if (status != G_IO_STATUS_NORMAL)
+		goto out;
+	g_io_channel_set_buffered (priv->io_channel_socket, FALSE);
+
+	/* spawn helper executable */
+	ret = g_spawn_async_with_pipes (NULL, argv, envp, 0, NULL, NULL, &priv->child_pid,
+					&standard_input, &standard_output, NULL, error);
+	if (!ret)
+		goto out;
+	g_debug ("started process %s with pid %i", priv->argv[0], priv->child_pid);
+
+	/* connect up */
+	priv->io_channel_child_stdin = g_io_channel_unix_new (standard_input);
+	priv->io_channel_child_stdout = g_io_channel_unix_new (standard_output);
+
+	/* binary data */
+	status = g_io_channel_set_encoding (priv->io_channel_child_stdin, NULL, error);
+	if (status != G_IO_STATUS_NORMAL)
+		goto out;
+	g_io_channel_set_buffered (priv->io_channel_child_stdin, FALSE);
+
+	/* binary data */
+	status = g_io_channel_set_encoding (priv->io_channel_child_stdout, NULL, error);
+	if (status != G_IO_STATUS_NORMAL)
+		goto out;
+	g_io_channel_set_buffered (priv->io_channel_child_stdout, FALSE);
+
+	/* socket has data */
+	priv->io_channel_socket_listen_id =
+		g_io_add_watch_full (priv->io_channel_socket, G_PRIORITY_HIGH_IDLE,
+				     G_IO_IN,
+				     (GIOFunc) pk_client_helper_socket_has_input_cb, client_helper, NULL);
+
+	/* frontend has data */
+	priv->io_channel_child_stdout_listen_id =
+		g_io_add_watch_full (priv->io_channel_child_stdout, G_PRIORITY_HIGH_IDLE,
+				     G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+				     (GIOFunc) pk_client_helper_child_has_output_cb, client_helper, NULL);
+
+	/* success */
+	ret = TRUE;
+out:
+	return ret;
+}
+
+/**
+ * pk_client_helper_class_init:
+ **/
+static void
+pk_client_helper_class_init (PkClientHelperClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	object_class->finalize = pk_client_helper_finalize;
+	g_type_class_add_private (klass, sizeof (PkClientHelperPrivate));
+}
+
+/**
+ * pk_client_helper_init:
+ **/
+static void
+pk_client_helper_init (PkClientHelper *client_helper)
+{
+	client_helper->priv = PK_CLIENT_HELPER_GET_PRIVATE (client_helper);
+}
+
+/**
+ * pk_client_helper_finalize:
+ **/
+static void
+pk_client_helper_finalize (GObject *object)
+{
+	PkClientHelper *client_helper = PK_CLIENT_HELPER (object);
+	PkClientHelperPrivate *priv = client_helper->priv;
+
+	if (priv->socket_file != NULL)
+		g_object_unref (priv->socket_file);
+	if (priv->io_channel_socket != NULL)
+		g_io_channel_unref (priv->io_channel_socket);
+	if (priv->io_channel_child_stdin != NULL)
+		g_io_channel_unref (priv->io_channel_child_stdin);
+	if (priv->io_channel_child_stdout != NULL)
+		g_io_channel_unref (priv->io_channel_child_stdout);
+	g_strfreev (priv->argv);
+
+	G_OBJECT_CLASS (pk_client_helper_parent_class)->finalize (object);
+}
+
+/**
+ * pk_client_helper_new:
+ *
+ * Return value: a new PkClientHelper object.
+ *
+ * Since: 0.6.10
+ **/
+PkClientHelper *
+pk_client_helper_new (void)
+{
+	PkClientHelper *client_helper;
+	client_helper = g_object_new (PK_TYPE_CLIENT_HELPER, NULL);
+	return PK_CLIENT_HELPER (client_helper);
+}
diff --git a/lib/packagekit-glib2/pk-client-helper.h b/lib/packagekit-glib2/pk-client-helper.h
new file mode 100644
index 0000000..9b09f83
--- /dev/null
+++ b/lib/packagekit-glib2/pk-client-helper.h
@@ -0,0 +1,78 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2010 Richard Hughes <richard at hughsie.com>
+ *
+ * Licensed under the GNU Lesser General Public License Version 2.1
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#if !defined (__PACKAGEKIT_H_INSIDE__) && !defined (PK_COMPILATION)
+#error "Only <packagekit.h> can be included directly."
+#endif
+
+#ifndef __PK_CLIENT_HELPER_H
+#define __PK_CLIENT_HELPER_H
+
+#include <glib-object.h>
+
+#include <packagekit-glib2/pk-source.h>
+#include <packagekit-glib2/pk-enum.h>
+
+G_BEGIN_DECLS
+
+#define PK_TYPE_CLIENT_HELPER			(pk_client_helper_get_type ())
+#define PK_CLIENT_HELPER(o)			(G_TYPE_CHECK_INSTANCE_CAST ((o), PK_TYPE_CLIENT_HELPER, PkClientHelper))
+#define PK_CLIENT_HELPER_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST((k), PK_TYPE_CLIENT_HELPER, PkClientHelperClass))
+#define PK_IS_CLIENT_HELPER(o)			(G_TYPE_CHECK_INSTANCE_TYPE ((o), PK_TYPE_CLIENT_HELPER))
+#define PK_IS_CLIENT_HELPER_CLASS(k)		(G_TYPE_CHECK_CLASS_TYPE ((k), PK_TYPE_CLIENT_HELPER))
+#define PK_CLIENT_HELPER_GET_CLASS(o)		(G_TYPE_INSTANCE_GET_CLASS ((o), PK_TYPE_CLIENT_HELPER, PkClientHelperClass))
+
+typedef struct _PkClientHelperPrivate	PkClientHelperPrivate;
+typedef struct _PkClientHelper		PkClientHelper;
+typedef struct _PkClientHelperClass	PkClientHelperClass;
+
+struct _PkClientHelper
+{
+	 GObject		 parent;
+	 PkClientHelperPrivate	*priv;
+};
+
+struct _PkClientHelperClass
+{
+	GObjectClass	parent_class;
+	/* padding for future expansion */
+	void (*_pk_reserved1) (void);
+	void (*_pk_reserved2) (void);
+	void (*_pk_reserved3) (void);
+	void (*_pk_reserved4) (void);
+	void (*_pk_reserved5) (void);
+};
+
+GType		 pk_client_helper_get_type		(void);
+PkClientHelper	*pk_client_helper_new			(void);
+
+gboolean	 pk_client_helper_stop			(PkClientHelper	*client_helper,
+							 GError		**error);
+gboolean	 pk_client_helper_start			(PkClientHelper	*client_helper,
+							 const gchar	*socket_filename,
+							 gchar		**argv,
+							 gchar		**envp,
+							 GError		**error);
+
+G_END_DECLS
+
+#endif /* __PK_CLIENT_HELPER_H */
+
diff --git a/lib/packagekit-glib2/pk-self-test.c b/lib/packagekit-glib2/pk-self-test.c
index 39a6779..247fe22 100644
--- a/lib/packagekit-glib2/pk-self-test.c
+++ b/lib/packagekit-glib2/pk-self-test.c
@@ -22,9 +22,11 @@
 #include "config.h"
 
 #include <glib-object.h>
+#include <glib/gstdio.h>
 
 #include "pk-catalog.h"
 #include "pk-client.h"
+#include "pk-client-helper.h"
 #include "pk-common.h"
 #include "pk-control.h"
 #include "pk-console-shared.h"
@@ -292,6 +294,116 @@ pk_test_catalog_func (void)
 	g_object_unref (catalog);
 }
 
+/**
+ * pk_test_client_helper_output_cb:
+ **/
+static gboolean
+pk_test_client_helper_output_cb (GIOChannel *source, GIOCondition condition, gpointer user_data)
+{
+	gchar data[6];
+	GError *error = NULL;
+	gsize len = 0;
+	GIOStatus status;
+	gboolean ret = TRUE;
+
+	/* read data */
+	status = g_io_channel_read_chars (source, data, 6, &len, &error);
+	if (status == G_IO_STATUS_EOF)
+		goto out;
+	if (status != G_IO_STATUS_NORMAL) {
+		g_warning ("failed to read: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+	if (len == 0)
+		goto out;
+	data[len] = '\0';
+
+	/* good for us */
+	if (g_strcmp0 (data, "pong\n") == 0) {
+		_g_test_loop_quit ();
+		goto out;
+	}
+
+	/* bad */
+	g_warning ("child returned unexpected data: %s", data);
+out:
+	return ret;
+}
+
+static void
+pk_test_client_helper_func (void)
+{
+	gboolean ret;
+	GError *error = NULL;
+	gchar *filename;
+	PkClientHelper *client_helper;
+	GIOStatus status;
+	gsize written;
+	const gchar *argv[] = { TESTDATADIR "/pk-client-helper-test.py", NULL };
+	const gchar *envp[] = { "DAVE=1", NULL };
+	GIOChannel *io_channel;
+
+	client_helper = pk_client_helper_new ();
+	g_assert (client_helper != NULL);
+
+	/* unref without using */
+	g_object_unref (client_helper);
+
+	/* new object */
+	client_helper = pk_client_helper_new ();
+	g_assert (client_helper != NULL);
+
+	/* create a socket filename */
+	filename = g_build_filename (g_get_tmp_dir (), "pk-self-test.socket", NULL);
+
+	/* ensure previous sockets are deleted */
+	g_unlink (filename);
+
+	/* start a demo program */
+	ret = pk_client_helper_start (client_helper, filename, (gchar**) argv, (gchar**) envp, &error);
+	g_assert_no_error (error);
+	g_assert (ret);
+	g_assert (g_file_test (filename, G_FILE_TEST_EXISTS));
+
+	/* open the socket */
+	io_channel = g_io_channel_new_file (filename, "r+", &error);
+	g_assert_no_error (error);
+	g_assert (io_channel != NULL);
+
+	/* get reply */
+	g_io_add_watch_full (io_channel, G_PRIORITY_HIGH_IDLE,
+			     G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+			     (GIOFunc) pk_test_client_helper_output_cb,
+			     NULL, NULL);
+
+	/* set no buffering */
+	status = g_io_channel_set_encoding (io_channel, NULL, &error);
+	g_assert_no_error (error);
+	g_assert (status == G_IO_STATUS_NORMAL);
+	g_io_channel_set_buffered (io_channel, FALSE);
+
+	/* expect a response back */
+	status = g_io_channel_write_chars (io_channel, "ping\n", -1, &written, &error);
+	g_assert_no_error (error);
+	g_assert (status == G_IO_STATUS_NORMAL);
+	g_assert_cmpint (written, ==, 5);
+
+	/* run for a few seconds */
+	_g_test_loop_run_with_timeout (3000);
+
+	/* stop the demo program */
+	ret = pk_client_helper_stop (client_helper, &error);
+	g_assert_no_error (error);
+	g_assert (ret);
+
+	/* delete socket */
+	g_unlink (filename);
+
+	g_free (filename);
+	g_object_unref (client_helper);
+}
+
 static void
 pk_test_client_resolve_cb (GObject *object, GAsyncResult *res, gpointer user_data)
 {
@@ -1926,6 +2038,7 @@ main (int argc, char **argv)
 	g_test_add_func ("/packagekit-glib2/package", pk_test_package_func);
 	g_test_add_func ("/packagekit-glib2/control", pk_test_control_func);
 	g_test_add_func ("/packagekit-glib2/transaction-list", pk_test_transaction_list_func);
+	g_test_add_func ("/packagekit-glib2/client-helper", pk_test_client_helper_func);
 	g_test_add_func ("/packagekit-glib2/client", pk_test_client_func);
 	g_test_add_func ("/packagekit-glib2/catalog", pk_test_catalog_func);
 	g_test_add_func ("/packagekit-glib2/package-sack", pk_test_package_sack_func);
commit 1eba1c8e6cc8c523fd60305b4bbc61865df8bf33
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Oct 29 15:46:57 2010 +0100

    trivial: add pk_debug_set_verbose() so we can get pretty output from the self test programs

diff --git a/backends/dummy/Makefile.am b/backends/dummy/Makefile.am
index 051cba0..8cce1a2 100644
--- a/backends/dummy/Makefile.am
+++ b/backends/dummy/Makefile.am
@@ -1,3 +1,6 @@
+INCLUDES = \
+	-DG_LOG_DOMAIN=\"PackageKit-Dummy\"
+
 plugindir = $(PK_PLUGIN_DIR)
 plugin_LTLIBRARIES = libpk_backend_dummy.la
 libpk_backend_dummy_la_SOURCES = pk-backend-dummy.c
diff --git a/lib/packagekit-glib2/pk-debug.c b/lib/packagekit-glib2/pk-debug.c
index 59339c4..72570d7 100644
--- a/lib/packagekit-glib2/pk-debug.c
+++ b/lib/packagekit-glib2/pk-debug.c
@@ -162,6 +162,16 @@ pk_debug_add_log_domain (const gchar *log_domain)
 }
 
 /**
+ * pk_debug_set_verbose:
+ */
+void
+pk_debug_set_verbose (gboolean verbose)
+{
+	_verbose = verbose;
+	_console = (isatty (fileno (stdout)) == 1);
+}
+
+/**
  * pk_debug_post_parse_hook:
  */
 static gboolean
diff --git a/lib/packagekit-glib2/pk-debug.h b/lib/packagekit-glib2/pk-debug.h
index 81ea48e..b705658 100644
--- a/lib/packagekit-glib2/pk-debug.h
+++ b/lib/packagekit-glib2/pk-debug.h
@@ -31,5 +31,6 @@
 gboolean	 pk_debug_is_verbose		(void);
 GOptionGroup	*pk_debug_get_option_group	(void);
 void		 pk_debug_add_log_domain	(const gchar	*log_domain);
+void		 pk_debug_set_verbose		(gboolean	 verbose);
 
 #endif /* __PK_DEBUG_H__ */
diff --git a/lib/packagekit-glib2/pk-self-test.c b/lib/packagekit-glib2/pk-self-test.c
index afa5798..39a6779 100644
--- a/lib/packagekit-glib2/pk-self-test.c
+++ b/lib/packagekit-glib2/pk-self-test.c
@@ -44,6 +44,7 @@
 #include "pk-client-sync.h"
 #include "pk-progress-bar.h"
 #include "pk-service-pack.h"
+#include "pk-debug.h"
 
 /** ver:1.0 ***********************************************************/
 static GMainLoop *_test_loop = NULL;
@@ -1910,6 +1911,9 @@ main (int argc, char **argv)
 
 	g_test_init (&argc, &argv, NULL);
 
+	pk_debug_set_verbose (TRUE);
+	pk_debug_add_log_domain (G_LOG_DOMAIN);
+
 	/* tests go here */
 	g_test_add_func ("/packagekit-glib2/common", pk_test_common_func);
 	g_test_add_func ("/packagekit-glib2/enum", pk_test_enum_func);
commit dc734d6580eec9f7718bfc694dd99a118d5491cd
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 27 20:04:09 2010 +0100

    yum: properly fix the Resolve(@category) search as pkcon needs this to work to be able to install and remove groups
    
    This also means you don't have to resort to using cat;;;meta on the command line
    to install groups.

diff --git a/backends/yum/pk-backend-yum.c b/backends/yum/pk-backend-yum.c
index 7063c71..fd0dc93 100644
--- a/backends/yum/pk-backend-yum.c
+++ b/backends/yum/pk-backend-yum.c
@@ -450,6 +450,12 @@ pk_backend_emit_package_array (PkBackend *backend, GPtrArray *array, ZifState *s
 static gboolean
 pk_backend_error_handler_cb (const GError *error, PkBackend *backend)
 {
+	/* if we try to do a comps search on a local store */
+	if (error->domain == ZIF_STORE_ERROR &&
+	    error->code == ZIF_STORE_ERROR_NO_SUPPORT) {
+		g_debug ("ignoring operation on PkStoreLocal: %s", error->message);
+		return TRUE;
+	}
 	/* emit a warning, this isn't fatal */
 	pk_backend_message (backend, PK_MESSAGE_ENUM_BROKEN_MIRROR, "%s", error->message);
 	return TRUE;
@@ -526,6 +532,69 @@ out:
 }
 
 /**
+ * pk_backend_create_meta_package_for_category:
+ */
+static ZifPackage *
+pk_backend_create_meta_package_for_category (GPtrArray *store_array, ZifCategory *cat, ZifState *state, GError **error)
+{
+	ZifPackage *package = NULL;
+	ZifPackage *package_tmp;
+	GPtrArray *array_packages;
+	gchar *package_id = NULL;
+	gboolean ret;
+	ZifString *string;
+	guint j;
+	const gchar *to_array[] = { NULL, NULL };
+	PkInfoEnum info = PK_INFO_ENUM_COLLECTION_INSTALLED;
+
+	/* are all the packages in this group installed? */
+	to_array[0] = zif_category_get_id (cat);
+	array_packages = zif_store_array_search_category (store_array, (gchar**)to_array, state, error);
+	if (array_packages == NULL)
+		goto out;
+
+	/* if any are not installed, then this is not installed */
+	for (j=0; j<array_packages->len; j++) {
+		package_tmp = g_ptr_array_index (array_packages, j);
+		if (!zif_package_is_installed (package_tmp)) {
+			info = PK_INFO_ENUM_COLLECTION_AVAILABLE;
+			g_debug ("%s is not installed, so marking as not installed %s collection",
+				 zif_package_get_id (package_tmp),
+				 zif_category_get_id (cat));
+			break;
+		}
+	}
+
+	/* fake something */
+	package_id = g_strdup_printf ("%s;;;meta",
+				      zif_category_get_id (cat));
+	package = zif_package_new ();
+	ret = zif_package_set_id (package, package_id, NULL);
+	if (!ret) {
+		g_object_unref (package);
+		package = NULL;
+		goto out;
+	}
+
+	/* set summary */
+	string = zif_string_new (zif_category_get_name (cat));
+	zif_package_set_summary (package, string);
+	zif_string_unref (string);
+
+	/* map to simple binary installed value */
+	zif_package_set_installed (package, (info == PK_INFO_ENUM_COLLECTION_INSTALLED));
+
+	/* add to results */
+	/* TODO: make a proper property */
+	g_object_set_data (G_OBJECT(package), "kind", (gpointer)pk_info_enum_to_string (info));
+out:
+	if (array_packages != NULL)
+		g_ptr_array_unref (array_packages);
+	g_free (package_id);
+	return package;
+}
+
+/**
  * pk_backend_search_collections:
  */
 static GPtrArray *
@@ -535,17 +604,12 @@ pk_backend_search_collections (GPtrArray *store_array, ZifState *state, GError *
 	gchar *package_id;
 	GPtrArray *array = NULL;
 	GPtrArray *array_tmp;
-	GPtrArray *array_packages;
 	GError *error_local = NULL;
-	guint i, j;
-	PkInfoEnum info;
 	ZifCategory *cat;
+	guint i;
 	ZifPackage *package;
-	ZifPackage *package_tmp;
 	ZifState *state_local;
 	ZifState *state_loop;
-	ZifString *string;
-	const gchar *to_array[] = { NULL, NULL };
 
 	/* set steps */
 	zif_state_set_number_steps (state, 2);
@@ -575,41 +639,10 @@ pk_backend_search_collections (GPtrArray *store_array, ZifState *state, GError *
 			continue;
 
 		/* fake something here */
-		package_id = g_strdup_printf ("%s;;;meta",
-					      zif_category_get_id (cat));
-		package = zif_package_new ();
-		ret = zif_package_set_id (package, package_id, NULL);
-		if (ret) {
-			/* are all the packages in this group installed? */
-			state_loop = zif_state_get_child (state_local);
-			to_array[0] = zif_category_get_id (cat);
-			array_packages = zif_store_array_search_category (store_array, (gchar**)to_array, state_loop, error);
-			if (array_packages == NULL)
-				goto out;
-
-			/* if any are not installed, then this is not installed */
-			info = PK_INFO_ENUM_COLLECTION_INSTALLED;
-			for (j=0; j<array_packages->len; j++) {
-				package_tmp = g_ptr_array_index (array_packages, j);
-				if (!zif_package_is_installed (package_tmp)) {
-					info = PK_INFO_ENUM_COLLECTION_AVAILABLE;
-					g_debug ("%s is not installed, so marking as not installed %s collection",
-						 zif_package_get_id (package_tmp),
-						 zif_category_get_id (cat));
-					break;
-				}
-			}
-
-			/* map to simple binary installed value */
-			zif_package_set_installed (package, (info == PK_INFO_ENUM_COLLECTION_INSTALLED));
-			string = zif_string_new (zif_category_get_name (cat));
-			zif_package_set_summary (package, string);
-			zif_string_unref (string);
-
-			/* add to results */
+		state_loop = zif_state_get_child (state_local);
+		package = pk_backend_create_meta_package_for_category (store_array, cat, state_loop, &error_local);
+		if (package != NULL) {
 			g_ptr_array_add (array, g_object_ref (package));
-			/* TODO: make a proper property */
-			g_object_set_data (G_OBJECT(package), "kind", (gpointer)pk_info_enum_to_string (info));
 		} else {
 			g_warning ("failed to add id %s: %s", package_id, error_local->message);
 			g_clear_error (&error_local);
@@ -620,7 +653,6 @@ pk_backend_search_collections (GPtrArray *store_array, ZifState *state, GError *
 		if (!ret)
 			goto out;
 
-		g_free (package_id);
 		g_object_unref (package);
 	}
 
@@ -637,6 +669,117 @@ out:
 #endif
 
 /**
+ * pk_backend_get_cat_for_id:
+ */
+static ZifCategory *
+pk_backend_get_cat_for_id (GPtrArray *store_array, const gchar *id, ZifState *state, GError **error)
+{
+	GPtrArray *array = NULL;
+	ZifCategory *cat = NULL;
+	ZifCategory *cat_tmp;
+	guint i;
+
+	/* get all cats */
+	array = zif_store_array_get_categories (store_array, state, error);
+	if (array == NULL)
+		goto out;
+
+	/* find one that matches */
+	for (i=0; i<array->len; i++) {
+		cat_tmp = g_ptr_array_index (array, i);
+		if (g_strcmp0 (zif_category_get_id (cat_tmp), id) == 0) {
+			cat = g_object_ref (cat_tmp);
+			break;
+		}
+	}
+
+	/* nothing found, so set error */
+	if (cat == NULL)
+		g_set_error (error, 1, 0, "no category %s found", id);
+out:
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	return cat;
+}
+
+/**
+ * pk_backend_resolve_groups:
+ */
+static GPtrArray *
+pk_backend_resolve_groups (GPtrArray *store_array, gchar **search, ZifState *state, GError **error)
+{
+	gboolean ret;
+	GError *error_local = NULL;
+	GPtrArray *array = NULL;
+	GPtrArray *array_retval = NULL;
+	guint i;
+	ZifCategory *cat;
+	ZifPackage *package;
+	ZifState *state_local;
+	ZifState *state_loop;
+
+	/* set steps */
+	zif_state_set_number_steps (state, g_strv_length (search));
+
+	/* resolve all the groups */
+	array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
+	for (i=0; search[i] != NULL; i++) {
+		state_local = zif_state_get_child (state);
+
+		/* set steps */
+		zif_state_set_number_steps (state_local, 2);
+
+		/* get the category */
+		state_loop = zif_state_get_child (state_local);
+		cat = pk_backend_get_cat_for_id (store_array, search[i]+1, state_loop, &error_local);
+		if (cat == NULL) {
+			g_debug ("group %s not found: %s", search[i], error_local->message);
+			g_clear_error (&error_local);
+
+			/* this part done */
+			ret = zif_state_finished (state_loop, error);
+			if (!ret)
+				goto out;
+			ret = zif_state_done (state_local, error);
+			if (!ret)
+				goto out;
+		} else {
+			ret = zif_state_done (state_local, error);
+			if (!ret)
+				goto out;
+
+			/* fake something here */
+			state_loop = zif_state_get_child (state_local);
+			package = pk_backend_create_meta_package_for_category (store_array, cat, state_loop, &error_local);
+			if (package != NULL) {
+				g_ptr_array_add (array, package);
+			} else {
+				g_warning ("failed to add id %s: %s",
+					   zif_category_get_id (cat),
+					   error_local->message);
+				g_clear_error (&error_local);
+				ret = zif_state_finished (state_loop, error);
+			}
+		}
+
+		/* this part done */
+		ret = zif_state_done (state_local, error);
+		if (!ret)
+			goto out;
+		ret = zif_state_done (state, error);
+		if (!ret)
+			goto out;
+	}
+
+	/* success */
+	array_retval = g_ptr_array_ref (array);
+out:
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	return array_retval;
+}
+
+/**
  * pk_backend_search_thread:
  */
 static gboolean
@@ -653,6 +796,8 @@ pk_backend_search_thread (PkBackend *backend)
 	GError *error = NULL;
 	gchar **search;
 	guint recent;
+	guint i;
+
 	filters = (PkBitfield) pk_backend_get_uint (backend, "filters");
 	role = pk_backend_get_role (backend);
 
@@ -707,7 +852,6 @@ pk_backend_search_thread (PkBackend *backend)
 		} else if (role == PK_ROLE_ENUM_SEARCH_GROUP) {
 			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 */
@@ -739,7 +883,12 @@ pk_backend_search_thread (PkBackend *backend)
 		} 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) {
-			array = zif_store_array_resolve (store_array, search, state_local, &error);
+			if (search[0][0] == '@') {
+				/* this is a group */
+				array = pk_backend_resolve_groups (store_array, search, state_local, &error);
+			} else {
+				array = zif_store_array_resolve (store_array, search, state_local, &error);
+			}
 		} else if (role == PK_ROLE_ENUM_WHAT_PROVIDES) {
 			array = zif_store_array_what_provides (store_array, search, state_local, &error);
 		}
@@ -838,7 +987,9 @@ out:
 	ret = g_key_file_load_from_file (keyfile, PACKAGE_MEDIA_REPO_FILENAME,
 					 G_KEY_FILE_KEEP_COMMENTS, &error);
 	if (!ret) {
-		g_debug ("failed to open %s", error->message);
+		g_debug ("failed to load %s: %s",
+			 PACKAGE_MEDIA_REPO_FILENAME,
+			 error->message);
 		g_error_free (error);
 		goto out;
 	}
diff --git a/backends/yum/yumBackend.py b/backends/yum/yumBackend.py
index 92f9095..9e034a6 100755
--- a/backends/yum/yumBackend.py
+++ b/backends/yum/yumBackend.py
@@ -40,7 +40,7 @@ from yum.constants import *
 from yum.update_md import UpdateMetadata
 from yum.callbacks import *
 from yum.misc import prco_tuple_to_string, unique
-from yum.packages import YumLocalPackage, parsePackages
+from yum.packages import YumLocalPackage, parsePackages, PackageObject
 from yum.packageSack import MetaSack
 import rpmUtils
 import exceptions
@@ -125,10 +125,13 @@ def _to_unicode(txt, encoding='utf-8'):
 
 def _get_package_ver(po):
     ''' return the a ver as epoch:version-release or version-release, if epoch=0'''
+    ver = ''
     if po.epoch != '0':
         ver = "%s:%s-%s" % (po.epoch, po.version, po.release)
-    else:
+    elif po.release:
         ver = "%s-%s" % (po.version, po.release)
+    elif po.version:
+        ver = po.version
     return ver
 
 def _format_package_id(package_id):
@@ -581,9 +584,9 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
         try:
             grp = self.yumbase.comps.return_group(grpid)
         except yum.Errors.RepoError, e:
-            raise PkError(ERROR_NO_CACHE, "failed to get groups from comps: %s" %_to_unicode(e))
+            raise PkError(ERROR_NO_CACHE, "failed to get groups from comps: %s" % _to_unicode(e))
         except yum.Errors.GroupsError, e:
-            raise PkError(ERROR_GROUP_NOT_FOUND, _to_unicode(e))
+            raise PkError(ERROR_GROUP_NOT_FOUND, "failed to find group '%s': %s" % (package_id, _to_unicode(e)))
         except exceptions.IOError, e:
             raise PkError(ERROR_NO_SPACE_ON_DEVICE, "Disk error: %s" % _to_unicode(e))
         except Exception, e:
@@ -1012,6 +1015,8 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
             (name, idver, a, repo) = self.get_package_from_id(package_id)
             isGroup = False
             if repo == 'meta':
+                if name[0] == '@':
+                    name == name[1:]
                 try:
                     grp = self.yumbase.comps.return_group(name)
                 except exceptions.IOError, e:
@@ -1028,7 +1033,8 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
                     self.error(ERROR_INTERNAL_ERROR, _format_str(traceback.format_exc()))
                 isGroup = True
             if isGroup and not grp:
-                self.error(ERROR_GROUP_NOT_FOUND, "The Group %s dont exist" % name)
+                self.error(ERROR_GROUP_NOT_FOUND, "group %s does not exist (searched for %s)" % (name, _format_package_id (package_id)))
+                return
         return grp
 
     def _findPackage(self, package_id):
@@ -1746,6 +1752,39 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
                 else:
                     pkgfilter.add_available(pkgs)
 
+        # is this a metapackage (a group)
+        for package_id in packages:
+            if package_id[0] == '@':
+                grps = self.comps.get_meta_packages()
+                for grpid in grps:
+                    if grpid == package_id[1:]:
+
+                        # create virtual package
+                        pkg = yum.packages.PackageObject()
+                        pkg.name = package_id[1:]
+                        pkg.version = ''
+                        pkg.release = ''
+                        pkg.arch = ''
+                        pkg.epoch = '0'
+                        pkg.repo = 'meta'
+
+                        # get the name and the installed status
+                        try:
+                            grp = self.yumbase.comps.return_group(grpid)
+                        except yum.Errors.RepoError, e:
+                            raise PkError(ERROR_NO_CACHE, "failed to get groups from comps: %s" % _to_unicode(e))
+                        except yum.Errors.GroupsError, e:
+                            raise PkError(ERROR_GROUP_NOT_FOUND, "failed to find group '%s': %s" % (package_id, _to_unicode(e)))
+                        except exceptions.IOError, e:
+                            raise PkError(ERROR_NO_SPACE_ON_DEVICE, "Disk error: %s" % _to_unicode(e))
+                        except Exception, e:
+                            raise PkError(ERROR_INTERNAL_ERROR, _format_str(traceback.format_exc()))
+                        pkg.summary = grp.name
+                        if grp.installed:
+                            pkgfilter.add_installed([pkg])
+                        else:
+                            pkgfilter.add_available([pkg])
+
         # we couldn't do this when generating the list
         package_list = pkgfilter.post_process()
         self._show_package_list(package_list)
diff --git a/backends/yum/yumFilter.py b/backends/yum/yumFilter.py
index 94a4114..71b9410 100644
--- a/backends/yum/yumFilter.py
+++ b/backends/yum/yumFilter.py
@@ -145,7 +145,9 @@ class YumFilter(PackagekitFilter):
         '''
         Return if the package is installed.
         '''
-        return pkg.repo.id == 'installed'
+        if type(pkg.repo) != str:
+            return pkg.repo.id == 'installed'
+        return False
 
     def _pkg_is_devel(self, pkg):
         '''
commit 77b33c0d5d615ddf9048adc7a22bf0fca443375c
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 27 20:02:49 2010 +0100

    Document the @category resolve special case in the specification as it's been used for at least a year now

diff --git a/src/org.freedesktop.PackageKit.Transaction.xml b/src/org.freedesktop.PackageKit.Transaction.xml
index e9ade58..c39fb8e 100644
--- a/src/org.freedesktop.PackageKit.Transaction.xml
+++ b/src/org.freedesktop.PackageKit.Transaction.xml
@@ -975,6 +975,15 @@
               The package names are case sensitive, so for instance:
               <doc:tt>Resolve('Packagekit')</doc:tt> would not match <doc:tt>PackageKit</doc:tt>.
             </doc:para>
+            <doc:para>
+              As a special case, if <doc:tt>Resolve()</doc:tt>doc:tt> is called
+              with a name prefixed with <doc:tt>@</doc:tt> then
+              this should be treated as a category, for example:
+              <doc:tt>@web-development</doc:tt>.
+              In this instance, a meta-package should be emitted, for example:
+              <doc:tt>web-development;;;meta</doc:tt> with the correct
+              installed status and summary for the category.
+            </doc:para>
           </doc:summary>
         </doc:doc>
       </arg>
commit ba71f01cb72cd1dcd104c1db57457eef14025065
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 27 20:01:16 2010 +0100

    Document the @category search in the docs, as it's been used in a few backends for over two years...

diff --git a/src/org.freedesktop.PackageKit.Transaction.xml b/src/org.freedesktop.PackageKit.Transaction.xml
index c2ecc33..e9ade58 100644
--- a/src/org.freedesktop.PackageKit.Transaction.xml
+++ b/src/org.freedesktop.PackageKit.Transaction.xml
@@ -1164,8 +1164,13 @@
         <doc:doc>
           <doc:summary>
             <doc:para>
-              An enumerated group_type, or <doc:tt>unknown</doc:tt>. The search
-              can't contain spaces. It must contains only one group_type.
+              An enumerated group type, or <doc:tt>unknown</doc:tt>. The search
+              cannot contain spaces.
+            </doc:para>
+            <doc:para>
+              If the values strings are prefixed with <doc:tt>@</doc:tt> then
+              this is treated as a category, for example:
+              <doc:tt>@web-development</doc:tt>.
             </doc:para>
           </doc:summary>
         </doc:doc>
commit 4a1969d64907a1f7e412b6bb17124debce6d74fb
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 27 20:00:18 2010 +0100

    trivial: fix up some syntax highlighting issues

diff --git a/configure.ac b/configure.ac
index 7ad23dd..26bfc57 100644
--- a/configure.ac
+++ b/configure.ac
@@ -185,7 +185,7 @@ if test x$enable_qt = xyes; then
 	if test ! -x "$MOC"; then
 		AC_PATH_PROG(MOC, moc)
 		if test ! -x "$MOC"; then
-			AC_MSG_ERROR([MOC hasn't been found])
+			AC_MSG_ERROR([MOC has not been found])
 		fi
 	fi
 	build_qt=yes
@@ -287,7 +287,7 @@ if test x$enable_man_pages != xno; then
 	AC_PATH_PROG(XSLTPROC, xsltproc, no)
 	if test x$enable_man_pages = xyes; then
 		if test "$XSLTPROC" = "no" ; then
-			AC_MSG_ERROR([xsltproc not found, it's needod to build man pages])
+			AC_MSG_ERROR([xsltproc not found, it is needed to build man pages])
 		fi
 	fi
 else
@@ -571,7 +571,7 @@ if test x$with_security_framework = xpolkit; then
 				  polkit-backend-1 \
 				  polkit-gobject-1 >= $POLKIT_GOBJECT_REQUIRED)
 	else
-		AC_DEFINE(USE_SECURITY_POLKIT_NEW, 1, [if we should use PolicyKit's new API])
+		AC_DEFINE(USE_SECURITY_POLKIT_NEW, 1, [if we should use the new PolicyKit API])
 	fi
 	AC_DEFINE(USE_SECURITY_POLKIT, 1, [if we should use PolicyKit])
 elif test x$with_security_framework = xdummy; then
commit b82ed41f65b56bcdef3616cb61dd5cb4c7d95ff9
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 27 19:57:59 2010 +0100

    yum: add 'resolve' to the list of operations to try with Zif

diff --git a/backends/yum/Yum.conf b/backends/yum/Yum.conf
index b79b59f..258979e 100644
--- a/backends/yum/Yum.conf
+++ b/backends/yum/Yum.conf
@@ -49,7 +49,7 @@ InfrastructurePackages=PackageKit;yum;rpm;gnome-packagekit;kpackagekit
 # to still use the awesomeness of Zif for some operations, but not others.
 #
 # For a nice speed boost, try:
-# UseZif=get-repo-list;repo-enable;search-file;search-name;search-details;search-group;get-categories;get-details;get-distro-upgrades
+# UseZif=get-repo-list;repo-enable;resolve;search-file;search-name;search-details;search-group;get-categories;get-details;get-distro-upgrades
 #
 # default=repo-list;repo-enable
 UseZif=get-repo-list;repo-enable
commit 0295872f763e369119cc92f0d5370d6db0893d3a
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 27 19:57:32 2010 +0100

    trivial: remove zif from the error domain define to avoid me confusing myself

diff --git a/backends/yum/Makefile.am b/backends/yum/Makefile.am
index 3ca09ed..aae70f7 100644
--- a/backends/yum/Makefile.am
+++ b/backends/yum/Makefile.am
@@ -8,7 +8,7 @@ dist_helper_DATA = 			\
 
 INCLUDES = \
 	-DI_KNOW_THE_PACKAGEKIT_GLIB2_API_IS_SUBJECT_TO_CHANGE	\
-	-DG_LOG_DOMAIN=\"PackageKit-Zif\"			\
+	-DG_LOG_DOMAIN=\"PackageKit-Yum\"			\
 	-DPK_COMPILATION					\
 	$(ZIF_CFLAGS)						\
 	-DSYSCONFDIR=\""$(sysconfdir)"\"
commit 60aee592e0bd40a14769ba04b2400f113a199e20
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 27 17:54:19 2010 +0100

    Ensure we notice when a spawn command is invalid by printing it in red on the command line

diff --git a/lib/packagekit-glib2/pk-debug.c b/lib/packagekit-glib2/pk-debug.c
index 1e8ce82..59339c4 100644
--- a/lib/packagekit-glib2/pk-debug.c
+++ b/lib/packagekit-glib2/pk-debug.c
@@ -112,6 +112,7 @@ pk_debug_handler_cb (const gchar *log_domain, GLogLevelFlags log_level,
 
 	/* critical is also in red */
 	if (log_level == G_LOG_LEVEL_CRITICAL ||
+	    log_level == G_LOG_LEVEL_WARNING ||
 	    log_level == G_LOG_LEVEL_ERROR) {
 		g_print ("%c[%dm%s\n%c[%dm", 0x1B, CONSOLE_RED, message, 0x1B, CONSOLE_RESET);
 	} else {
diff --git a/src/pk-backend-spawn.c b/src/pk-backend-spawn.c
index 365992d..29a3ca1 100644
--- a/src/pk-backend-spawn.c
+++ b/src/pk-backend-spawn.c
@@ -545,6 +545,7 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line,
 		ret = pk_backend_category (priv->backend, sections[1], sections[2], sections[3], sections[4], sections[5]);
 		goto out;
 	} else {
+		ret = FALSE;
 		g_set_error (error, 1, 0, "invalid command '%s'", command);
 	}
 out:
@@ -620,7 +621,7 @@ pk_backend_spawn_stdout_cb (PkBackendSpawn *spawn, const gchar *line, PkBackendS
 		pk_backend_message (backend_spawn->priv->backend,
 				    PK_MESSAGE_ENUM_BACKEND_ERROR,
 				    "Failed to parse output: %s", error->message);
-		g_debug ("failed to parse: %s: %s", line, error->message);
+		g_warning ("failed to parse: %s: %s", line, error->message);
 		g_error_free (error);
 	}
 }
diff --git a/src/pk-backend.c b/src/pk-backend.c
index 06d2ed9..1ccebf7 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -1143,7 +1143,10 @@ pk_backend_package (PkBackend *backend, PkInfoEnum info, const gchar *package_id
 
 	/* emit */
 	g_signal_emit (backend, signals[SIGNAL_PACKAGE], 0, item);
-	pk_results_add_package (backend->priv->results, item);
+
+	/* add to results if meaningful */
+	if (info != PK_INFO_ENUM_FINISHED)
+		pk_results_add_package (backend->priv->results, item);
 
 	/* success */
 	ret = TRUE;
diff --git a/src/pk-transaction.c b/src/pk-transaction.c
index 36d4dba..0226833 100644
--- a/src/pk-transaction.c
+++ b/src/pk-transaction.c
@@ -1139,7 +1139,7 @@ pk_transaction_message_cb (PkBackend *backend, PkMessage *item, PkTransaction *t
 	if (!developer_mode &&
 	    (type == PK_MESSAGE_ENUM_BACKEND_ERROR ||
 	     type == PK_MESSAGE_ENUM_DAEMON_ERROR)) {
-		g_warning ("ignoring message: %s", details);
+		g_debug ("ignoring message (turn on DeveloperMode): %s", details);
 		return;
 	}
 
commit 3c71e3bf29c60329f4ec1fe6a40459711348224c
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Oct 25 15:42:39 2010 +0000

    l10n: Updated English (United Kingdom) (en_GB) translation to 18%
    
    New status: 69 messages complete with 123 fuzzies and 178 untranslated.
    
    Transmitted-via: Transifex (www.transifex.net).

diff --git a/po/en_GB.po b/po/en_GB.po
index c5cc4e0..5ee5686 100644
--- a/po/en_GB.po
+++ b/po/en_GB.po
@@ -2,13 +2,13 @@
 # Copyright (C) 2009 THE PackageKit'S COPYRIGHT HOLDER
 # This file is distributed under the same license as the PackageKit package.
 # Tim Waugh <twaugh at redhat.com>, 2009.
-#
-#
+# 
+# 
 msgid ""
 msgstr ""
 "Project-Id-Version: PackageKit VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-24 11:06+0100\n"
+"POT-Creation-Date: 2010-10-25 15:38+0000\n"
 "PO-Revision-Date: 2009-01-16 12:28+0000\n"
 "Last-Translator: Tim Waugh <twaugh at redhat.com>\n"
 "Language-Team: English/GB <en at li.org>\n"
@@ -17,141 +17,151 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 
 #. TRANSLATORS: this is an atomic transaction
-#: ../client/pk-console.c:235
+#. TRANSLATORS: the role is the point of the transaction, e.g. update-system
+#: ../client/pk-console.c:174 ../client/pk-console.c:596
 msgid "Transaction"
-msgstr ""
+msgstr "Transaction"
 
-#. TRANSLATORS: this is the time the transaction was started in system timezone
-#: ../client/pk-console.c:237
+#. TRANSLATORS: this is the time the transaction was started in system
+#. timezone
+#: ../client/pk-console.c:176
 msgid "System time"
 msgstr ""
 
 #. TRANSLATORS: this is if the transaction succeeded or not
-#: ../client/pk-console.c:239
+#: ../client/pk-console.c:178
 msgid "Succeeded"
 msgstr ""
 
-#. TRANSLATORS: if the repo is enabled
-#: ../client/pk-console.c:239 ../client/pk-console.c:406
+#: ../client/pk-console.c:178
 msgid "True"
 msgstr ""
 
-#: ../client/pk-console.c:239 ../client/pk-console.c:406
+#: ../client/pk-console.c:178
 msgid "False"
 msgstr ""
 
 #. TRANSLATORS: this is the transactions role, e.g. "update-system"
 #. TRANSLATORS: the trasaction role, e.g. update-system
-#: ../client/pk-console.c:241 ../src/pk-polkit-action-lookup.c:327
+#: ../client/pk-console.c:180 ../src/pk-polkit-action-lookup.c:332
 msgid "Role"
 msgstr ""
 
 #. TRANSLATORS: this is The duration of the transaction
-#: ../client/pk-console.c:246
+#: ../client/pk-console.c:185
 msgid "Duration"
 msgstr ""
 
-#: ../client/pk-console.c:246
+#: ../client/pk-console.c:185
 msgid "(seconds)"
 msgstr ""
 
 #. TRANSLATORS: this is The command line used to do the action
 #. TRANSLATORS: the command line of the thing that wants the authentication
-#: ../client/pk-console.c:250 ../src/pk-polkit-action-lookup.c:341
+#: ../client/pk-console.c:189 ../src/pk-polkit-action-lookup.c:346
 #, fuzzy
 msgid "Command line"
 msgstr "Command failed"
 
 #. TRANSLATORS: this is the user ID of the user that started the action
-#: ../client/pk-console.c:252
+#: ../client/pk-console.c:191
 msgid "User ID"
 msgstr ""
 
 #. TRANSLATORS: this is the username, e.g. hughsie
-#: ../client/pk-console.c:259
+#: ../client/pk-console.c:198
 msgid "Username"
 msgstr ""
 
 #. TRANSLATORS: this is the users real name, e.g. "Richard Hughes"
-#: ../client/pk-console.c:263
+#: ../client/pk-console.c:202
 msgid "Real name"
 msgstr ""
 
-#: ../client/pk-console.c:271
+#: ../client/pk-console.c:210
 msgid "Affected packages:"
 msgstr ""
 
-#: ../client/pk-console.c:273
+#: ../client/pk-console.c:212
 msgid "Affected packages: None"
 msgstr ""
 
 #. TRANSLATORS: this is the distro, e.g. Fedora 10
-#: ../client/pk-console.c:298
+#: ../client/pk-console.c:247
 msgid "Distribution"
 msgstr ""
 
 #. TRANSLATORS: this is type of update, stable or testing
-#: ../client/pk-console.c:300
+#: ../client/pk-console.c:249
 msgid "Type"
 msgstr ""
 
 #. TRANSLATORS: this is any summary text describing the upgrade
 #. TRANSLATORS: this is the summary of the group
-#: ../client/pk-console.c:302 ../client/pk-console.c:325
+#: ../client/pk-console.c:251 ../client/pk-console.c:290
 msgid "Summary"
 msgstr ""
 
 #. TRANSLATORS: this is the group category name
-#: ../client/pk-console.c:314
+#: ../client/pk-console.c:279
 msgid "Category"
 msgstr ""
 
 #. TRANSLATORS: this is group identifier
-#: ../client/pk-console.c:316
+#: ../client/pk-console.c:281
 msgid "ID"
 msgstr ""
 
 #. TRANSLATORS: this is the parent group
-#: ../client/pk-console.c:319
+#: ../client/pk-console.c:284
 msgid "Parent"
 msgstr ""
 
 #. TRANSLATORS: this is the name of the parent group
-#: ../client/pk-console.c:322
+#: ../client/pk-console.c:287
 msgid "Name"
 msgstr ""
 
 #. TRANSLATORS: this is preferred icon for the group
-#: ../client/pk-console.c:328
+#: ../client/pk-console.c:293
 msgid "Icon"
 msgstr ""
 
 #. TRANSLATORS: this is a header for the package that can be updated
-#: ../client/pk-console.c:343
+#: ../client/pk-console.c:339
 msgid "Details about the update:"
 msgstr "Details about the update:"
 
 #. TRANSLATORS: details about the update, package name and version
+#. TRANSLATORS: the package that is being processed
+#. TRANSLATORS: the package that is not signed by a known key
+#. TRANSLATORS: the package name that was trying to be installed
 #. TRANSLATORS: title, the names of the packages that the method is processing
-#: ../client/pk-console.c:345 ../src/pk-polkit-action-lookup.c:352
+#: ../client/pk-console.c:345 ../client/pk-console.c:615
+#: ../lib/packagekit-glib2/pk-task-text.c:124
+#: ../lib/packagekit-glib2/pk-task-text.c:206
+#: ../src/pk-polkit-action-lookup.c:357
 #, fuzzy
 msgid "Package"
 msgid_plural "Packages"
 msgstr[0] "Package files"
 msgstr[1] "Package files"
 
-#. TRANSLATORS: details about the update, any packages that this update updates
+#. TRANSLATORS: details about the update, any packages that this update
+#. updates
 #: ../client/pk-console.c:348
 msgid "Updates"
 msgstr ""
 
-#. TRANSLATORS: details about the update, any packages that this update obsoletes
+#. TRANSLATORS: details about the update, any packages that this update
+#. obsoletes
 #: ../client/pk-console.c:352
 msgid "Obsoletes"
 msgstr ""
 
 #. TRANSLATORS: details about the update, the vendor URLs
-#: ../client/pk-console.c:356
+#. TRANSLATORS: the vendor (e.g. vmware) that is providing the EULA
+#: ../client/pk-console.c:356 ../lib/packagekit-glib2/pk-task-text.c:209
 msgid "Vendor"
 msgstr ""
 
@@ -186,1092 +196,979 @@ msgid "State"
 msgstr ""
 
 #. TRANSLATORS: details about the update, date the update was issued
-#: ../client/pk-console.c:385
+#: ../client/pk-console.c:384
 msgid "Issued"
 msgstr ""
 
 #. TRANSLATORS: details about the update, date the update was updated
-#: ../client/pk-console.c:390
+#. TRANSLATORS: The action of the package, in past tense
+#: ../client/pk-console.c:388 ../lib/packagekit-glib2/pk-console-shared.c:515
 msgid "Updated"
 msgstr ""
 
-#: ../client/pk-console.c:477 ../client/pk-console.c:479
-msgid "Percentage"
+#. TRANSLATORS: if the repo is enabled
+#: ../client/pk-console.c:424
+msgid "Enabled"
 msgstr ""
 
-#: ../client/pk-console.c:479
-msgid "Unknown"
+#. TRANSLATORS: if the repo is disabled
+#: ../client/pk-console.c:427
+msgid "Disabled"
 msgstr ""
 
 #. TRANSLATORS: a package requires the system to be restarted
-#: ../client/pk-console.c:521
+#: ../client/pk-console.c:459
 msgid "System restart required by:"
 msgstr ""
 
 #. TRANSLATORS: a package requires the session to be restarted
-#: ../client/pk-console.c:524
+#: ../client/pk-console.c:462
 #, fuzzy
 msgid "Session restart required:"
 msgstr "Repository signature required"
 
-#. TRANSLATORS: a package requires the system to be restarted due to a security update
-#: ../client/pk-console.c:527
+#. TRANSLATORS: a package requires the system to be restarted due to a
+#. security update
+#: ../client/pk-console.c:465
 msgid "System restart (security) required by:"
 msgstr ""
 
-#. TRANSLATORS: a package requires the session to be restarted due to a security update
-#: ../client/pk-console.c:530
+#. TRANSLATORS: a package requires the session to be restarted due to a
+#. security update
+#: ../client/pk-console.c:468
 msgid "Session restart (security) required:"
 msgstr ""
 
 #. TRANSLATORS: a package requires the application to be restarted
-#: ../client/pk-console.c:533
+#: ../client/pk-console.c:471
 msgid "Application restart required by:"
 msgstr ""
 
-#. TRANSLATORS: a package needs to restart their system
-#: ../client/pk-console.c:588
-msgid "Please restart the computer to complete the update."
-msgstr "Please restart the computer to complete the update."
+#. TRANSLATORS: This a list of details about the package
+#: ../client/pk-console.c:506
+msgid "Package description"
+msgstr "Package description"
 
-#. TRANSLATORS: a package needs to restart the session
-#: ../client/pk-console.c:591
-msgid "Please logout and login to complete the update."
-msgstr "Please logout and login to complete the update."
+#. TRANSLATORS: This a message (like a little note that may be of interest)
+#. from the transaction
+#: ../client/pk-console.c:537
+msgid "Message:"
+msgstr ""
 
-#. TRANSLATORS: a package needs to restart the application
-#: ../client/pk-console.c:594
-msgid "Please restart the application as it is being used."
-msgstr "Please restart the application as it is being used."
+#. TRANSLATORS: This where the package has no files
+#: ../client/pk-console.c:558
+msgid "No files"
+msgstr "No files"
 
-#. TRANSLATORS: a package needs to restart their system (due to security)
-#: ../client/pk-console.c:597
-#, fuzzy
-msgid ""
-"Please restart the computer to complete the update as important security "
-"updates have been installed."
-msgstr "Please restart the computer to complete the update."
+#. TRANSLATORS: This a list files contained in the package
+#: ../client/pk-console.c:563
+msgid "Package files"
+msgstr "Package files"
 
-#. TRANSLATORS: a package needs to restart the session (due to security)
-#: ../client/pk-console.c:600
-#, fuzzy
-msgid ""
-"Please logout and login to complete the update as important security updates "
-"have been installed."
-msgstr "Please logout and login to complete the update."
+#. TRANSLATORS: the percentage complete of the transaction
+#: ../client/pk-console.c:631
+msgid "Percentage"
+msgstr ""
 
-#. TRANSLATORS: The package is already installed on the system
-#: ../client/pk-console.c:727
-#, c-format
-msgid "The package %s is already installed"
-msgstr "The package %s is already installed"
+#. TRANSLATORS: the status of the transaction (e.g. downloading)
+#: ../client/pk-console.c:649
+msgid "Status"
+msgstr ""
 
-#. TRANSLATORS: The package name was not found in any software sources. The detailed error follows
-#: ../client/pk-console.c:735
-#, c-format
-msgid "The package %s could not be installed: %s"
-msgstr "The package %s could not be installed: %s"
+#. TRANSLATORS: the results from the transaction
+#: ../client/pk-console.c:678
+msgid "Results:"
+msgstr ""
 
-#. TRANSLATORS: There was a programming error that shouldn't happen. The detailed error follows
-#: ../client/pk-console.c:760 ../client/pk-console.c:783
-#: ../client/pk-console.c:879 ../client/pk-console.c:996
-#: ../client/pk-tools-common.c:62 ../client/pk-tools-common.c:81
-#: ../client/pk-tools-common.c:89
-#, c-format
-msgid "Internal error: %s"
+#. TRANSLATORS: we failed to get any results, which is pretty fatal in my book
+#: ../client/pk-console.c:685
+#, fuzzy
+msgid "Fatal error"
 msgstr "Internal error: %s"
 
-#. TRANSLATORS: There was an error installing the packages. The detailed error follows
-#: ../client/pk-console.c:768 ../client/pk-console.c:1392
-#, c-format
-msgid "This tool could not install the packages: %s"
-msgstr "This tool could not install the packages: %s"
-
-#. TRANSLATORS: There was an error installing the files. The detailed error follows
-#: ../client/pk-console.c:791
-#, c-format
-msgid "This tool could not install the files: %s"
-msgstr "This tool could not install the files: %s"
-
-#. TRANSLATORS: The package name was not found in the installed list. The detailed error follows
-#: ../client/pk-console.c:847
-#, c-format
-msgid "This tool could not remove %s: %s"
-msgstr "This tool could not remove %s: %s"
-
-#. TRANSLATORS: There was an error removing the packages. The detailed error follows
-#: ../client/pk-console.c:870 ../client/pk-console.c:908
-#: ../client/pk-console.c:941
-#, c-format
-msgid "This tool could not remove the packages: %s"
-msgstr "This tool could not remove the packages: %s"
-
-#. TRANSLATORS: When removing, we might have to remove other dependencies
-#: ../client/pk-console.c:920
-msgid "The following packages have to be removed:"
-msgstr "The following packages have to be removed:"
-
-#. TRANSLATORS: We are checking if it's okay to remove a list of packages
-#: ../client/pk-console.c:927
-msgid "Proceed removing additional packages?"
-msgstr "Proceed removing additional packages?"
-
-#. TRANSLATORS: We did not remove any packages
-#: ../client/pk-console.c:932
-msgid "The package removal was canceled!"
-msgstr "The package removal was cancelled!"
-
-#. TRANSLATORS: The package name was not found in any software sources
-#: ../client/pk-console.c:973
-#, c-format
-msgid "This tool could not download the package %s as it could not be found"
-msgstr "This tool could not download the package %s as it could not be found"
-
-#. TRANSLATORS: Could not download the packages for some reason. The detailed error follows
-#: ../client/pk-console.c:1004
-#, c-format
-msgid "This tool could not download the packages: %s"
-msgstr "This tool could not download the packages: %s"
-
-#. TRANSLATORS: There was an error getting the list of files for the package. The detailed error follows
-#: ../client/pk-console.c:1031 ../client/pk-console.c:1040
-#, c-format
-msgid "This tool could not update %s: %s"
-msgstr "This tool could not update %s: %s"
-
-#. TRANSLATORS: There was an error getting the list of files for the package. The detailed error follows
-#: ../client/pk-console.c:1062 ../client/pk-console.c:1070
-#, c-format
-msgid "This tool could not get the requirements for %s: %s"
-msgstr "This tool could not get the requirements for %s: %s"
-
-#. TRANSLATORS: There was an error getting the dependencies for the package. The detailed error follows
-#: ../client/pk-console.c:1092 ../client/pk-console.c:1100
-#, c-format
-msgid "This tool could not get the dependencies for %s: %s"
-msgstr "This tool could not get the dependencies for %s: %s"
-
-#. TRANSLATORS: There was an error getting the details about the package. The detailed error follows
-#: ../client/pk-console.c:1122 ../client/pk-console.c:1130
-#, c-format
-msgid "This tool could not get package details for %s: %s"
-msgstr "This tool could not get package details for %s: %s"
-
-#. TRANSLATORS: The package name was not found in any software sources. The detailed error follows
-#: ../client/pk-console.c:1152
-#, c-format
-msgid "This tool could not find the files for %s: %s"
-msgstr "This tool could not find the files for %s: %s"
-
-#. TRANSLATORS: There was an error getting the list of files for the package. The detailed error follows
-#: ../client/pk-console.c:1160
-#, c-format
-msgid "This tool could not get the file list for %s: %s"
-msgstr "This tool could not get the file list for %s: %s"
-
-#. TRANSLATORS: There was an error getting the list of packages. The filename follows
-#: ../client/pk-console.c:1182
-#, c-format
-msgid "File already exists: %s"
-msgstr "File already exists: %s"
-
-#. TRANSLATORS: follows a list of packages to install
-#: ../client/pk-console.c:1187 ../client/pk-console.c:1243
-#: ../client/pk-console.c:1318
-msgid "Getting package list"
-msgstr "Getting package list"
-
-#. TRANSLATORS: There was an error getting the list of packages. The detailed error follows
-#: ../client/pk-console.c:1193 ../client/pk-console.c:1249
-#: ../client/pk-console.c:1324
-#, c-format
-msgid "This tool could not get package list: %s"
-msgstr "This tool could not get package list: %s"
-
-#. TRANSLATORS: There was an error saving the list
-#: ../client/pk-console.c:1204
-#, c-format
-msgid "Failed to save to disk"
-msgstr "Failed to save to disk"
-
-#. TRANSLATORS: There was an error getting the list. The filename follows
-#: ../client/pk-console.c:1238 ../client/pk-console.c:1313
-#, c-format
-msgid "File does not exist: %s"
-msgstr "File does not exist: %s"
-
-#. TRANSLATORS: header to a list of packages newly added
-#: ../client/pk-console.c:1270
-msgid "Packages to add"
-msgstr "Packages to add"
-
-#. TRANSLATORS: header to a list of packages removed
-#: ../client/pk-console.c:1278
-msgid "Packages to remove"
-msgstr "Packages to remove"
+#. TRANSLATORS: the user asked to update everything, but there is nothing that
+#. can be updated
+#: ../client/pk-console.c:701
+msgid "There are no packages to update."
+msgstr ""
 
-#. TRANSLATORS: We didn't find any differences
-#: ../client/pk-console.c:1346
-#, c-format
-msgid "No new packages need to be installed"
-msgstr "No new packages need to be installed"
+#. TRANSLATORS: the transaction failed in a way we could not expect
+#: ../client/pk-console.c:704
+#: ../contrib/command-not-found/pk-command-not-found.c:639
+msgid "The transaction failed"
+msgstr ""
 
-#. TRANSLATORS: follows a list of packages to install
-#: ../client/pk-console.c:1352
-msgid "To install"
-msgstr "To install"
+#. TRANSLATORS: print a message when there are no updates
+#: ../client/pk-console.c:733
+#, fuzzy
+msgid "There are no updates available at this time."
+msgstr "Put all updates available in the service pack"
 
-#. TRANSLATORS: searching takes some time....
-#: ../client/pk-console.c:1364
-msgid "Searching for package: "
-msgstr "Searching for package: "
+#: ../client/pk-console.c:756
+msgid "There are no upgrades available at this time."
+msgstr ""
 
-#. TRANSLATORS: package was not found -- this is the end of a string ended in ...
-#: ../client/pk-console.c:1368
-msgid "not found."
-msgstr "not found."
+#. TRANSLATORS: a package needs to restart their system
+#: ../client/pk-console.c:823
+msgid "Please restart the computer to complete the update."
+msgstr "Please restart the computer to complete the update."
 
-#. TRANSLATORS: We didn't find any packages to install
-#: ../client/pk-console.c:1379
-#, c-format
-msgid "No packages can be found to install"
-msgstr "No packages can be found to install"
+#. TRANSLATORS: a package needs to restart the session
+#: ../client/pk-console.c:826
+msgid "Please logout and login to complete the update."
+msgstr "Please logout and login to complete the update."
 
-#. TRANSLATORS: installing new packages from package list
-#. TRANSLATORS: we are now installing the debuginfo packages we found earlier
-#: ../client/pk-console.c:1385
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:886
-#, c-format
-msgid "Installing packages"
-msgstr "Installing packages"
+#. TRANSLATORS: a package needs to restart their system (due to security)
+#: ../client/pk-console.c:829
+#, fuzzy
+msgid "Please restart the computer to complete the update as important security updates have been installed."
+msgstr "Please restart the computer to complete the update."
 
-#. TRANSLATORS: The package name was not found in any software sources. The detailed error follows
-#: ../client/pk-console.c:1421
-#, c-format
-msgid "This tool could not find the update details for %s: %s"
-msgstr "This tool could not find the update details for %s: %s"
+#. TRANSLATORS: a package needs to restart the session (due to security)
+#: ../client/pk-console.c:832
+#, fuzzy
+msgid "Please logout and login to complete the update as important security updates have been installed."
+msgstr "Please logout and login to complete the update."
 
-#. TRANSLATORS: There was an error getting the details about the update for the package. The detailed error follows
-#: ../client/pk-console.c:1429
+#. TRANSLATORS: The user used 'pkcon install dave.rpm' rather than 'pkcon
+#. install-local dave.rpm'
+#: ../client/pk-console.c:858
 #, c-format
-msgid "This tool could not get the update details for %s: %s"
-msgstr "This tool could not get the update details for %s: %s"
-
-#. TRANSLATORS: This was an unhandled error, and we don't have _any_ context
-#: ../client/pk-console.c:1460
-msgid "Error:"
-msgstr "Error:"
-
-#. TRANSLATORS: This a list of details about the package
-#: ../client/pk-console.c:1474
-msgid "Package description"
-msgstr "Package description"
-
-#. TRANSLATORS: This a message (like a little note that may be of interest) from the transaction
-#: ../client/pk-console.c:1490
-msgid "Message:"
+msgid "Expected package name, actually got file. Try using 'pkcon install-local %s' instead."
 msgstr ""
 
-#. TRANSLATORS: This a list files contained in the package
-#: ../client/pk-console.c:1518
-msgid "Package files"
-msgstr "Package files"
-
-#. TRANSLATORS: This where the package has no files
-#: ../client/pk-console.c:1526
-msgid "No files"
-msgstr "No files"
-
-#. TRANSLATORS: This a request for a GPG key signature from the backend, which the client will prompt for later
-#: ../client/pk-console.c:1549
-msgid "Repository signature required"
-msgstr "Repository signature required"
-
-#. TRANSLATORS: This a prompt asking the user to import the security key
-#: ../client/pk-console.c:1559
-msgid "Do you accept this signature?"
-msgstr "Do you accept this signature?"
-
-#. TRANSLATORS: This is where the user declined the security key
-#: ../client/pk-console.c:1563
-msgid "The signature was not accepted."
-msgstr "The signature was not accepted."
+#. TRANSLATORS: There was an error getting the list of files for the package.
+#. The detailed error follows
+#: ../client/pk-console.c:866
+#, fuzzy, c-format
+msgid "This tool could not find any available package: %s"
+msgstr "This tool could not install the packages: %s"
 
-#. TRANSLATORS: This a request for a EULA
-#: ../client/pk-console.c:1597
-msgid "End user license agreement required"
-msgstr "End user licence agreement required"
+#. TRANSLATORS: There was an error getting the list of files for the package.
+#. The detailed error follows
+#: ../client/pk-console.c:894
+#, fuzzy, c-format
+msgid "This tool could not find the installed package: %s"
+msgstr "This tool could not install the packages: %s"
 
-#. TRANSLATORS: This a prompt asking the user to agree to the license
-#: ../client/pk-console.c:1604
-msgid "Do you agree to this license?"
-msgstr "Do you agree to this licence?"
+#. TRANSLATORS: There was an error getting the list of files for the package.
+#. The detailed error follows
+#: ../client/pk-console.c:922 ../client/pk-console.c:950
+#, fuzzy, c-format
+msgid "This tool could not find the package: %s"
+msgstr "This tool could not install the packages: %s"
 
-#. TRANSLATORS: This is where the user declined the license
-#: ../client/pk-console.c:1608
-msgid "The license was refused."
-msgstr "The licence was refused."
+#. TRANSLATORS: There was an error getting the list of files for the package.
+#. The detailed error follows
+#. TRANSLATORS: There was an error getting the dependencies for the package.
+#. The detailed error follows
+#. TRANSLATORS: There was an error getting the details about the package. The
+#. detailed error follows
+#. TRANSLATORS: The package name was not found in any software sources. The
+#. detailed error follows
+#: ../client/pk-console.c:978 ../client/pk-console.c:1006
+#: ../client/pk-console.c:1034 ../client/pk-console.c:1062
+#: ../client/pk-console.c:1090
+#, fuzzy, c-format
+msgid "This tool could not find all the packages: %s"
+msgstr "This tool could not install the packages: %s"
 
-#. TRANSLATORS: This is when the daemon crashed, and we are up shit creek without a paddle
-#: ../client/pk-console.c:1637
+#. TRANSLATORS: This is when the daemon crashed, and we are up shit creek
+#. without a paddle
+#: ../client/pk-console.c:1119
 msgid "The daemon crashed mid-transaction!"
 msgstr "The daemon crashed mid-transaction!"
 
 #. TRANSLATORS: This is the header to the --help menu
-#: ../client/pk-console.c:1690
+#: ../client/pk-console.c:1153
 msgid "PackageKit Console Interface"
 msgstr "PackageKit Console Interface"
 
 #. these are commands we can use with pkcon
-#: ../client/pk-console.c:1692
+#: ../client/pk-console.c:1155
 msgid "Subcommands:"
 msgstr "Subcommands:"
 
-#. TRANSLATORS: command line argument, if we should show debugging information
-#. TRANSLATORS: if we should show debugging data
-#: ../client/pk-console.c:1785 ../client/pk-generate-pack.c:185
-#: ../client/pk-monitor.c:128
-#: ../contrib/command-not-found/pk-command-not-found.c:616
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:550
-#: ../contrib/device-rebind/pk-device-rebind.c:293 ../src/pk-main.c:211
-msgid "Show extra debugging information"
-msgstr "Show extra debugging information"
+#. TRANSLATORS: we keep a database updated with the time that an action was
+#. last executed
+#: ../client/pk-console.c:1234
+msgid "Failed to get the time since this action was last completed"
+msgstr ""
 
 #. TRANSLATORS: command line argument, just show the version string
-#: ../client/pk-console.c:1788 ../client/pk-monitor.c:130
+#: ../client/pk-console.c:1274 ../client/pk-monitor.c:371
 msgid "Show the program version and exit"
 msgstr "Show the program version and exit"
 
 #. TRANSLATORS: command line argument, use a filter to narrow down results
-#: ../client/pk-console.c:1791
+#: ../client/pk-console.c:1277
 msgid "Set the filter, e.g. installed"
 msgstr "Set the filter, e.g. installed"
 
+#. TRANSLATORS: command line argument, use a non-standard install prefix
+#: ../client/pk-console.c:1280
+msgid "Set the install root, e.g. '/' or '/mnt/ltsp'"
+msgstr ""
+
 #. TRANSLATORS: command line argument, work asynchronously
-#: ../client/pk-console.c:1794
+#: ../client/pk-console.c:1283
 msgid "Exit without waiting for actions to complete"
 msgstr "Exit without waiting for actions to complete"
 
-#. TRANSLATORS: This is when we could not connect to the system bus, and is fatal
-#: ../client/pk-console.c:1821
-msgid "This tool could not connect to system DBUS."
-msgstr "This tool could not connect to system DBUS."
+#. command line argument, do we ask questions
+#: ../client/pk-console.c:1286
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:525
+msgid "Install the packages without asking for confirmation"
+msgstr ""
+
+#. TRANSLATORS: command line argument, this command is not a priority
+#: ../client/pk-console.c:1289
+msgid "Run the command using idle network bandwidth and also using less power"
+msgstr ""
+
+#. TRANSLATORS: command line argument, just output without fancy formatting
+#: ../client/pk-console.c:1292
+msgid "Print to screen a machine readable output, rather than using animated widgets"
+msgstr ""
+
+#. TRANSLATORS: we failed to contact the daemon
+#: ../client/pk-console.c:1329
+#, fuzzy
+msgid "Failed to contact PackageKit"
+msgstr "Failed to open package list."
+
+#. TRANSLATORS: The user specified an incorrect filter
+#: ../client/pk-console.c:1376
+#, fuzzy
+msgid "The proxy could not be set"
+msgstr "The package could not be found"
 
 #. TRANSLATORS: The user specified an incorrect filter
-#: ../client/pk-console.c:1911
+#: ../client/pk-console.c:1388
+#, fuzzy
+msgid "The install root could not be set"
+msgstr "This tool could not remove %s: %s"
+
+#. TRANSLATORS: The user specified an incorrect filter
+#: ../client/pk-console.c:1400
 msgid "The filter specified was invalid"
 msgstr "The filter specified was invalid"
 
 #. TRANSLATORS: a search type can be name, details, file, etc
-#: ../client/pk-console.c:1930
+#: ../client/pk-console.c:1419
 msgid "A search type is required, e.g. name"
 msgstr ""
 
 #. TRANSLATORS: the user needs to provide a search term
-#: ../client/pk-console.c:1937 ../client/pk-console.c:1946
-#: ../client/pk-console.c:1955 ../client/pk-console.c:1964
+#: ../client/pk-console.c:1426 ../client/pk-console.c:1438
+#: ../client/pk-console.c:1450 ../client/pk-console.c:1462
 msgid "A search term is required"
 msgstr ""
 
 #. TRANSLATORS: the search type was provided, but invalid
-#: ../client/pk-console.c:1971
+#: ../client/pk-console.c:1472
 msgid "Invalid search type"
 msgstr "Invalid search type"
 
 #. TRANSLATORS: the user did not specify what they wanted to install
-#: ../client/pk-console.c:1977
-msgid "A package name or filename to install is required"
-msgstr ""
+#: ../client/pk-console.c:1478
+#, fuzzy
+msgid "A package name to install is required"
+msgstr "No new packages need to be installed"
+
+#. TRANSLATORS: the user did not specify what they wanted to install
+#: ../client/pk-console.c:1487
+#, fuzzy
+msgid "A filename to install is required"
+msgstr "Repository signature required"
 
 #. TRANSLATORS: geeky error, 99.9999% of users won't see this
-#: ../client/pk-console.c:1986
+#: ../client/pk-console.c:1498
 #, fuzzy
 msgid "A type, key_id and package_id are required"
 msgstr "You need to specify a type, key_id and package_id"
 
 #. TRANSLATORS: the user did not specify what they wanted to remove
-#: ../client/pk-console.c:1995
+#: ../client/pk-console.c:1509
 msgid "A package name to remove is required"
 msgstr ""
 
-#. TRANSLATORS: the user did not specify anything about what to download or where
-#: ../client/pk-console.c:2003
+#. TRANSLATORS: the user did not specify anything about what to download or
+#. where
+#: ../client/pk-console.c:1518
 #, fuzzy
 msgid "A destination directory and the package names to download are required"
-msgstr ""
-"You need to specify the destination directory and then the packages to "
-"download"
+msgstr "You need to specify the destination directory and then the packages to download"
 
 #. TRANSLATORS: the directory does not exist, so we can't continue
-#: ../client/pk-console.c:2010
+#: ../client/pk-console.c:1525
 msgid "Directory not found"
 msgstr "Directory not found"
 
 #. TRANSLATORS: geeky error, 99.9999% of users won't see this
-#: ../client/pk-console.c:2018
+#: ../client/pk-console.c:1534
 #, fuzzy
 msgid "A licence identifier (eula-id) is required"
 msgstr "You need to specify a licence identifier (eula-id)"
 
 #. TRANSLATORS: geeky error, 99.9999% of users won't see this
-#: ../client/pk-console.c:2028
+#: ../client/pk-console.c:1545
 msgid "A transaction identifier (tid) is required"
 msgstr ""
 
 #. TRANSLATORS: The user did not specify a package name
-#: ../client/pk-console.c:2045
+#: ../client/pk-console.c:1566
 msgid "A package name to resolve is required"
 msgstr ""
 
 #. TRANSLATORS: The user did not specify a repository (software source) name
-#: ../client/pk-console.c:2054 ../client/pk-console.c:2063
+#: ../client/pk-console.c:1577 ../client/pk-console.c:1588
 #, fuzzy
 msgid "A repository name is required"
 msgstr "Repository signature required"
 
 #. TRANSLATORS: The user didn't provide any data
-#: ../client/pk-console.c:2072
+#: ../client/pk-console.c:1599
 #, fuzzy
 msgid "A repo name, parameter and value are required"
 msgstr "You need to specify a repo name/parameter and value"
 
 #. TRANSLATORS: The user didn't specify what action to use
-#: ../client/pk-console.c:2086
+#: ../client/pk-console.c:1616
 #, fuzzy
 msgid "An action, e.g. 'update-system' is required"
 msgstr "You need to specify an action, e.g. 'update-system'"
 
 #. TRANSLATORS: The user specified an invalid action
-#: ../client/pk-console.c:2093
+#: ../client/pk-console.c:1623
 msgid "A correct role is required"
 msgstr ""
 
-#. TRANSLATORS: we keep a database updated with the time that an action was last executed
-#: ../client/pk-console.c:2100
-msgid "Failed to get the time since this action was last completed"
-msgstr ""
-
 #. TRANSLATORS: The user did not provide a package name
 #. TRANSLATORS: This is when the user fails to supply the package name
-#: ../client/pk-console.c:2110 ../client/pk-console.c:2122
-#: ../client/pk-console.c:2131 ../client/pk-console.c:2149
-#: ../client/pk-console.c:2158 ../client/pk-generate-pack.c:241
+#: ../client/pk-console.c:1633 ../client/pk-console.c:1647
+#: ../client/pk-console.c:1656 ../client/pk-console.c:1676
+#: ../client/pk-console.c:1685 ../client/pk-generate-pack.c:314
 msgid "A package name is required"
 msgstr ""
 
-#. TRANSLATORS: each package "provides" certain things, e.g. mime(gstreamer-decoder-mp3), the user didn't specify it
-#: ../client/pk-console.c:2140
+#. TRANSLATORS: each package "provides" certain things, e.g. mime(gstreamer-
+#. decoder-mp3), the user didn't specify it
+#: ../client/pk-console.c:1665
 msgid "A package provide string is required"
 msgstr ""
 
-#. TRANSLATORS: The user didn't specify a filename to create as a list
-#: ../client/pk-console.c:2167
-msgid "A list file name to create is required"
-msgstr ""
-
-#. TRANSLATORS: The user didn't specify a filename to open as a list
-#: ../client/pk-console.c:2177 ../client/pk-console.c:2187
-msgid "A list file to open is required"
-msgstr ""
-
-#. TRANSLATORS: The user tried to use an unsupported option on the command line
-#: ../client/pk-console.c:2241
+#. TRANSLATORS: The user tried to use an unsupported option on the command
+#. line
+#: ../client/pk-console.c:1746
 #, c-format
 msgid "Option '%s' is not supported"
 msgstr "Option '%s' is not supported"
 
-#. TRANSLATORS: User does not have permission to do this
-#: ../client/pk-console.c:2254
-#, fuzzy
-msgid "Incorrect privileges for this operation"
-msgstr "You don't have the necessary privileges for this operation"
-
 #. TRANSLATORS: Generic failure of what they asked to do
-#: ../client/pk-console.c:2257
+#: ../client/pk-console.c:1756
 msgid "Command failed"
 msgstr "Command failed"
 
-#. TRANSLATORS: This is the state of the transaction
-#: ../client/pk-generate-pack.c:101
-msgid "Downloading"
-msgstr "Downloading"
-
-#. TRANSLATORS: This is when the main packages are being downloaded
-#: ../client/pk-generate-pack.c:121
-msgid "Downloading packages"
-msgstr "Downloading packages"
-
-#. TRANSLATORS: This is when the dependency packages are being downloaded
-#: ../client/pk-generate-pack.c:126
-msgid "Downloading dependencies"
-msgstr "Downloading dependencies"
-
-#. TRANSLATORS: we can exclude certain packages (glibc) when we know they'll exist on the target
-#: ../client/pk-generate-pack.c:188
+#. TRANSLATORS: we can exclude certain packages (glibc) when we know they'll
+#. exist on the target
+#: ../client/pk-generate-pack.c:253
 msgid "Set the file name of dependencies to be excluded"
 msgstr "Set the file name of dependencies to be excluded"
 
 #. TRANSLATORS: the output location
-#: ../client/pk-generate-pack.c:191
+#: ../client/pk-generate-pack.c:256
 #, fuzzy
-msgid ""
-"The output file or directory (the current directory is used if ommitted)"
+msgid "The output file or directory (the current directory is used if omitted)"
 msgstr "The output directory (the current directory is used if omitted)"
 
 #. TRANSLATORS: put a list of packages in the pack
-#: ../client/pk-generate-pack.c:194
+#: ../client/pk-generate-pack.c:259
 msgid "The package to be put into the service pack"
 msgstr "The package to be put into the service pack"
 
 #. TRANSLATORS: put all pending updates in the pack
-#: ../client/pk-generate-pack.c:197
+#: ../client/pk-generate-pack.c:262
 msgid "Put all updates available in the service pack"
 msgstr "Put all updates available in the service pack"
 
 #. TRANSLATORS: This is when the user fails to supply the correct arguments
-#: ../client/pk-generate-pack.c:225
+#: ../client/pk-generate-pack.c:298
 msgid "Neither --package or --updates option selected."
 msgstr "Neither --package or --updates option selected."
 
 #. TRANSLATORS: This is when the user fails to supply just one argument
-#: ../client/pk-generate-pack.c:233
+#: ../client/pk-generate-pack.c:306
 msgid "Both options selected."
 msgstr "Both options selected."
 
 #. TRANSLATORS: This is when the user fails to supply the output
-#: ../client/pk-generate-pack.c:249
+#: ../client/pk-generate-pack.c:322
 msgid "A output directory or file name is required"
 msgstr ""
 
-#. TRANSLATORS: This is when the backend doesn't have the capability to get-depends
-#. TRANSLATORS: This is when the backend doesn't have the capability to download
-#: ../client/pk-generate-pack.c:267 ../client/pk-generate-pack.c:273
+#. TRANSLATORS: This is when the daemon is not-installed/broken and fails to
+#. startup
+#: ../client/pk-generate-pack.c:340
+#, fuzzy
+msgid "The daemon failed to startup"
+msgstr "The daemon crashed mid-transaction!"
+
+#. TRANSLATORS: This is when the backend doesn't have the capability to get-
+#. depends
+#. TRANSLATORS: This is when the backend doesn't have the capability to
+#. download
+#: ../client/pk-generate-pack.c:351 ../client/pk-generate-pack.c:357
 msgid "The package manager cannot perform this type of operation."
 msgstr ""
 
-#. TRANSLATORS: This is when the distro didn't include libarchive support into PK
-#: ../client/pk-generate-pack.c:280
-msgid ""
-"Service packs cannot be created as PackageKit was not built with libarchive "
-"support."
+#. TRANSLATORS: This is when the distro didn't include libarchive support into
+#. PK
+#: ../client/pk-generate-pack.c:364
+msgid "Service packs cannot be created as PackageKit was not built with libarchive support."
 msgstr ""
 
-#. TRANSLATORS: the user specified an absolute path, but didn't get the extension correct
-#: ../client/pk-generate-pack.c:291
+#. TRANSLATORS: the user specified an absolute path, but didn't get the
+#. extension correct
+#: ../client/pk-generate-pack.c:375
 msgid "If specifying a file, the service pack name must end with"
 msgstr ""
 
 #. TRANSLATORS: This is when file already exists
-#: ../client/pk-generate-pack.c:307
+#: ../client/pk-generate-pack.c:391
 msgid "A pack with the same name already exists, do you want to overwrite it?"
 msgstr "A pack with the same name already exists, do you want to overwrite it?"
 
 #. TRANSLATORS: This is when the pack was not overwritten
-#: ../client/pk-generate-pack.c:310
+#: ../client/pk-generate-pack.c:394
 msgid "The pack was not overwritten."
 msgstr "The pack was not overwritten."
 
-#. TRANSLATORS: This is when the temporary directory cannot be created, the directory name follows
-#: ../client/pk-generate-pack.c:323
+#. TRANSLATORS: This is when the temporary directory cannot be created, the
+#. directory name follows
+#: ../client/pk-generate-pack.c:407
 msgid "Failed to create directory:"
 msgstr "Failed to create directory:"
 
-#. TRANSLATORS: This is when the list of packages from the remote computer cannot be opened
-#: ../client/pk-generate-pack.c:333
+#. TRANSLATORS: This is when the list of packages from the remote computer
+#. cannot be opened
+#: ../client/pk-generate-pack.c:419
 msgid "Failed to open package list."
 msgstr "Failed to open package list."
 
 #. TRANSLATORS: The package name is being matched up to available packages
-#: ../client/pk-generate-pack.c:344
+#: ../client/pk-generate-pack.c:428
 msgid "Finding package name."
 msgstr "Finding package name."
 
-#. TRANSLATORS: This is when the package cannot be found in any software source. The detailed error follows
-#: ../client/pk-generate-pack.c:348
+#. TRANSLATORS: This is when the package cannot be found in any software
+#. source. The detailed error follows
+#: ../client/pk-generate-pack.c:432
 #, c-format
 msgid "Failed to find package '%s': %s"
 msgstr "Failed to find package '%s': %s"
 
-#. TRANSLATORS: This is telling the user we are in the process of making the pack
-#: ../client/pk-generate-pack.c:365
+#. TRANSLATORS: This is telling the user we are in the process of making the
+#. pack
+#: ../client/pk-generate-pack.c:440
 msgid "Creating service pack..."
 msgstr "Creating service pack..."
 
 #. TRANSLATORS: we succeeded in making the file
-#: ../client/pk-generate-pack.c:372
+#: ../client/pk-generate-pack.c:455
 #, c-format
 msgid "Service pack created '%s'"
 msgstr "Service pack created '%s'"
 
 #. TRANSLATORS: we failed to make te file
-#: ../client/pk-generate-pack.c:377
+#: ../client/pk-generate-pack.c:460
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "Failed to create '%s': %s"
 
+#: ../client/pk-monitor.c:284
+#, fuzzy
+msgid "Failed to get daemon state"
+msgstr "Failed to open package list."
+
+#: ../client/pk-monitor.c:349
+#, fuzzy
+msgid "Failed to get properties"
+msgstr "Failed to open package list."
+
 #. TRANSLATORS: this is a program that monitors PackageKit
-#: ../client/pk-monitor.c:146
+#: ../client/pk-monitor.c:387
 msgid "PackageKit Monitor"
 msgstr "PackageKit Monitor"
 
-#: ../client/pk-monitor.c:183
-msgid "Cannot show the list of transactions"
-msgstr ""
-
-#. TRANSLATORS: The package was not found in any software sources
-#: ../client/pk-tools-common.c:118
-#, c-format
-msgid "The package could not be found"
-msgstr "The package could not be found"
-
-#. TRANSLATORS: more than one package could be found that matched, to follow is a list of possible packages
-#: ../client/pk-tools-common.c:130
-msgid "More than one package matches:"
-msgstr "More than one package matches:"
-
-#. TRANSLATORS: This finds out which package in the list to use
-#: ../client/pk-tools-common.c:137
-msgid "Please choose the correct package: "
-msgstr "Please choose the correct package: "
-
-#: ../client/pk-tools-common.c:162
-#, c-format
-msgid "Please enter a number from 1 to %i: "
-msgstr "Please enter a number from 1 to %i: "
-
 #. TRANSLATORS: when we are getting data from the daemon
-#: ../contrib/browser-plugin/pk-plugin-install.c:466
+#: ../contrib/browser-plugin/pk-plugin-install.c:499
 msgid "Getting package information..."
 msgstr "Getting package information..."
 
 #. TRANSLATORS: run an applicaiton
-#: ../contrib/browser-plugin/pk-plugin-install.c:472
+#: ../contrib/browser-plugin/pk-plugin-install.c:505
 #, c-format
 msgid "Run %s"
 msgstr "Run %s"
 
 #. TRANSLATORS: show the installed version of a package
-#: ../contrib/browser-plugin/pk-plugin-install.c:478
+#: ../contrib/browser-plugin/pk-plugin-install.c:511
 msgid "Installed version"
 msgstr "Installed version"
 
 #. TRANSLATORS: run the application now
-#: ../contrib/browser-plugin/pk-plugin-install.c:486
+#: ../contrib/browser-plugin/pk-plugin-install.c:519
 #, c-format
 msgid "Run version %s now"
 msgstr "Run version %s now"
 
 #. TRANSLATORS: run the application now
-#: ../contrib/browser-plugin/pk-plugin-install.c:492
+#: ../contrib/browser-plugin/pk-plugin-install.c:525
 msgid "Run now"
 msgstr "Run now"
 
 #. TRANSLATORS: update to a new version of the package
-#: ../contrib/browser-plugin/pk-plugin-install.c:498
+#: ../contrib/browser-plugin/pk-plugin-install.c:531
 #, c-format
 msgid "Update to version %s"
 msgstr "Update to version %s"
 
 #. TRANSLATORS: To install a package
-#: ../contrib/browser-plugin/pk-plugin-install.c:504
+#: ../contrib/browser-plugin/pk-plugin-install.c:537
 #, c-format
 msgid "Install %s now"
 msgstr "Install %s now"
 
 #. TRANSLATORS: the version of the package
-#: ../contrib/browser-plugin/pk-plugin-install.c:507
+#: ../contrib/browser-plugin/pk-plugin-install.c:540
 msgid "Version"
 msgstr "Version"
 
 #. TRANSLATORS: noting found, so can't install
-#: ../contrib/browser-plugin/pk-plugin-install.c:512
+#: ../contrib/browser-plugin/pk-plugin-install.c:545
 msgid "No packages found for your system"
 msgstr "No packages found for your system"
 
 #. TRANSLATORS: package is being installed
-#: ../contrib/browser-plugin/pk-plugin-install.c:517
+#: ../contrib/browser-plugin/pk-plugin-install.c:550
 msgid "Installing..."
 msgstr "Installing..."
 
 #. TRANSLATORS: downloading repo data so we can search
-#: ../contrib/command-not-found/pk-command-not-found.c:349
+#: ../contrib/command-not-found/pk-command-not-found.c:366
 msgid "Downloading details about the software sources."
 msgstr ""
 
 #. TRANSLATORS: downloading file lists so we can search
-#: ../contrib/command-not-found/pk-command-not-found.c:353
+#: ../contrib/command-not-found/pk-command-not-found.c:370
 msgid "Downloading filelists (this may take some time to complete)."
 msgstr ""
 
 #. TRANSLATORS: waiting for native lock
-#: ../contrib/command-not-found/pk-command-not-found.c:357
+#: ../contrib/command-not-found/pk-command-not-found.c:374
 #, fuzzy
 msgid "Waiting for package manager lock."
 msgstr "Finding package name."
 
 #. TRANSLATORS: loading package cache so we can search
-#: ../contrib/command-not-found/pk-command-not-found.c:361
+#: ../contrib/command-not-found/pk-command-not-found.c:378
 #, fuzzy
 msgid "Loading list of packages."
 msgstr "Downloading packages"
 
 #. TRANSLATORS: we failed to find the package, this shouldn't happen
-#: ../contrib/command-not-found/pk-command-not-found.c:420
+#: ../contrib/command-not-found/pk-command-not-found.c:444
 #, fuzzy
 msgid "Failed to search for file"
 msgstr "Failed to save to disk"
 
+#. TRANSLATORS: the transaction failed in a way we could not expect
+#: ../contrib/command-not-found/pk-command-not-found.c:456
+msgid "Getting the list of files failed"
+msgstr ""
+
 #. TRANSLATORS: we failed to launch the executable, the error follows
-#: ../contrib/command-not-found/pk-command-not-found.c:557
+#: ../contrib/command-not-found/pk-command-not-found.c:602
 #, fuzzy
 msgid "Failed to launch:"
 msgstr "Failed to get last time"
 
+#. TRANSLATORS: we failed to install the package
+#: ../contrib/command-not-found/pk-command-not-found.c:630
+#, fuzzy
+msgid "Failed to install packages"
+msgstr "This tool could not install the packages: %s"
+
 #. TRANSLATORS: tool that gets called when the command is not found
-#: ../contrib/command-not-found/pk-command-not-found.c:632
+#: ../contrib/command-not-found/pk-command-not-found.c:706
 #, fuzzy
 msgid "PackageKit Command Not Found"
 msgstr "PackageKit Monitor"
 
-#. TRANSLATORS: the prefix of all the output telling the user why it's not executing
-#: ../contrib/command-not-found/pk-command-not-found.c:658
+#. TRANSLATORS: the prefix of all the output telling the user
+#. * why it's not executing. NOTE: this is lowercase to mimic
+#. * the style of bash itself -- apologies
+#: ../contrib/command-not-found/pk-command-not-found.c:734
 #, fuzzy
-msgid "Command not found."
+msgid "command not found"
 msgstr "not found."
 
 #. TRANSLATORS: tell the user what we think the command is
-#: ../contrib/command-not-found/pk-command-not-found.c:665
+#: ../contrib/command-not-found/pk-command-not-found.c:752
 #, fuzzy
 msgid "Similar command is:"
 msgstr "Subcommands:"
 
 #. TRANSLATORS: Ask the user if we should run the similar command
-#: ../contrib/command-not-found/pk-command-not-found.c:674
+#: ../contrib/command-not-found/pk-command-not-found.c:766
 msgid "Run similar command:"
 msgstr ""
 
 #. TRANSLATORS: show the user a list of commands that they could have meant
 #. TRANSLATORS: show the user a list of commands we could run
-#: ../contrib/command-not-found/pk-command-not-found.c:686
-#: ../contrib/command-not-found/pk-command-not-found.c:695
+#: ../contrib/command-not-found/pk-command-not-found.c:780
+#: ../contrib/command-not-found/pk-command-not-found.c:789
 #, fuzzy
 msgid "Similar commands are:"
 msgstr "Subcommands:"
 
 #. TRANSLATORS: ask the user to choose a file to run
-#: ../contrib/command-not-found/pk-command-not-found.c:702
+#: ../contrib/command-not-found/pk-command-not-found.c:796
 msgid "Please choose a command to run"
 msgstr ""
 
 #. TRANSLATORS: tell the user what package provides the command
-#: ../contrib/command-not-found/pk-command-not-found.c:721
+#: ../contrib/command-not-found/pk-command-not-found.c:814
 #, fuzzy
 msgid "The package providing this file is:"
 msgstr "The package %s is already installed"
 
-#. TRANSLATORS: as the user if we want to install a package to provide the command
-#: ../contrib/command-not-found/pk-command-not-found.c:726
+#. TRANSLATORS: as the user if we want to install a package to provide the
+#. command
+#: ../contrib/command-not-found/pk-command-not-found.c:821
 #, c-format
 msgid "Install package '%s' to provide command '%s'?"
 msgstr ""
 
 #. TRANSLATORS: Show the user a list of packages that provide this command
-#: ../contrib/command-not-found/pk-command-not-found.c:747
+#: ../contrib/command-not-found/pk-command-not-found.c:848
 msgid "Packages providing this file are:"
 msgstr ""
 
-#. TRANSLATORS: Show the user a list of packages that they can install to provide this command
-#: ../contrib/command-not-found/pk-command-not-found.c:756
+#. TRANSLATORS: Show the user a list of packages that they can install to
+#. provide this command
+#: ../contrib/command-not-found/pk-command-not-found.c:858
 msgid "Suitable packages are:"
 msgstr ""
 
 #. get selection
 #. TRANSLATORS: ask the user to choose a file to install
-#: ../contrib/command-not-found/pk-command-not-found.c:764
+#: ../contrib/command-not-found/pk-command-not-found.c:867
 #, fuzzy
 msgid "Please choose a package to install"
 msgstr "Please choose the correct package: "
 
 #. TRANSLATORS: we are starting to install the packages
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:187
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:195
 #, fuzzy
 msgid "Starting install"
 msgstr "To install"
 
 #. TRANSLATORS: we couldn't find the package name, non-fatal
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:397
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:407
 #, fuzzy, c-format
 msgid "Failed to find the package %s, or already installed: %s"
 msgstr "The package %s is already installed"
 
-#. command line argument, simulate what would be done, but don't actually do it
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:553
-msgid ""
-"Don't actually install any packages, only simulate what would be installed"
+#. command line argument, simulate what would be done, but don't actually do
+#. it
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:516
+msgid "Don't actually install any packages, only simulate what would be installed"
 msgstr ""
 
-#. command line argument, do we skip packages that depend on the ones specified
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:556
+#. command line argument, do we skip packages that depend on the ones
+#. specified
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:519
 msgid "Do not install dependencies of the core packages"
 msgstr ""
 
 #. command line argument, do we operate quietly
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:559
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:522
 msgid "Do not display information or progress"
 msgstr ""
 
 #. TRANSLATORS: tool that gets called when the command is not found
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:577
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:540
 #, fuzzy
 msgid "PackageKit Debuginfo Installer"
 msgstr "PackageKit Console Interface"
 
-#. TRANSLATORS: the use needs to specify a list of package names on the command line
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:589
+#. TRANSLATORS: the use needs to specify a list of package names on the
+#. command line
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:554
 #, fuzzy, c-format
 msgid "ERROR: Specify package names to install."
 msgstr "You need to specify a package or file to install"
 
 #. TRANSLATORS: we are getting the list of repositories
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:623
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:590
 #, fuzzy, c-format
 msgid "Getting sources list"
 msgstr "Getting package list"
 
+#. TRANSLATORS: operation was not successful
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:600
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:675
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:759
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:803
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:870
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:914
+msgid "FAILED."
+msgstr ""
+
 #. TRANSLATORS: all completed 100%
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:641
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:681
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:716
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:800
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:844
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:911
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:955
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:615
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:655
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:690
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:774
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:818
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:885
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:929
 #, c-format
 msgid "OK."
 msgstr ""
 
 #. TRANSLATORS: tell the user what we found
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:644
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:618
 #, c-format
 msgid "Found %i enabled and %i disabled sources."
 msgstr ""
 
 #. TRANSLATORS: we're finding repositories that match out pattern
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:651
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:625
 #, c-format
 msgid "Finding debugging sources"
 msgstr ""
 
 #. TRANSLATORS: tell the user what we found
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:684
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:658
 #, c-format
 msgid "Found %i disabled debuginfo repos."
 msgstr ""
 
 #. TRANSLATORS: we're now enabling all the debug sources we found
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:691
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:665
 #, c-format
 msgid "Enabling debugging sources"
 msgstr ""
 
-#. TRANSLATORS: operation was not successful
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:701
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:785
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:829
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:896
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:940
-msgid "FAILED."
-msgstr ""
-
 #. TRANSLATORS: tell the user how many we enabled
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:719
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:693
 #, c-format
 msgid "Enabled %i debugging sources."
 msgstr ""
 
 #. TRANSLATORS: we're now finding packages that match in all the repos
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:726
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:700
 #, fuzzy, c-format
 msgid "Finding debugging packages"
 msgstr "Finding package name."
 
 #. TRANSLATORS: we couldn't find the package name, non-fatal
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:738
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:712
 #, fuzzy, c-format
 msgid "Failed to find the package %s: %s"
 msgstr "Failed to find package '%s': %s"
 
 #. TRANSLATORS: we couldn't find the debuginfo package name, non-fatal
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:761
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:735
 #, fuzzy, c-format
 msgid "Failed to find the debuginfo package %s: %s"
 msgstr "Failed to find package '%s': %s"
 
 #. TRANSLATORS: no debuginfo packages could be found to be installed
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:789
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:763
 #, fuzzy, c-format
 msgid "Found no packages to install."
 msgstr "No new packages need to be installed"
 
 #. TRANSLATORS: tell the user we found some packages, and then list them
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:803
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:777
 #, fuzzy, c-format
 msgid "Found %i packages:"
 msgstr "Downloading packages"
 
 #. TRANSLATORS: tell the user we are searching for deps
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:819
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:793
 #, c-format
 msgid "Finding packages that depend on these packages"
 msgstr ""
 
 #. TRANSLATORS: could not install, detailed error follows
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:832
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:806
 #, fuzzy, c-format
 msgid "Could not find dependant packages: %s"
 msgstr "Failed to find package '%s': %s"
 
 #. TRANSLATORS: tell the user we found some more packages
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:848
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:822
 #, c-format
 msgid "Found %i extra packages."
 msgstr ""
 
 #. TRANSLATORS: tell the user we found some more packages
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:852
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:826
 #, c-format
 msgid "No extra packages required."
 msgstr ""
 
-#. TRANSLATORS: tell the user we found some packages (and deps), and then list them
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:861
+#. TRANSLATORS: tell the user we found some packages (and deps), and then list
+#. them
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:835
 #, fuzzy, c-format
 msgid "Found %i packages to install:"
 msgstr "No new packages need to be installed"
 
-#. TRANSLATORS: simulate mode is a testing mode where we quit before the action
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:874
+#. TRANSLATORS: simulate mode is a testing mode where we quit before the
+#. action
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:848
 #, fuzzy, c-format
 msgid "Not installing packages in simulate mode"
 msgstr "Installing packages"
 
+#. TRANSLATORS: we are now installing the debuginfo packages we found earlier
+#. TRANSLATORS: transaction state, installing packages
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:860
+#: ../lib/packagekit-glib2/pk-console-shared.c:287
+#, c-format
+msgid "Installing packages"
+msgstr "Installing packages"
+
 #. TRANSLATORS: could not install, detailed error follows
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:899
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:873
 #, fuzzy, c-format
 msgid "Could not install packages: %s"
 msgstr "This tool could not install the packages: %s"
 
 #. TRANSLATORS: we are now disabling all debuginfo repos we previously enabled
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:931
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:905
 #, c-format
 msgid "Disabling sources previously enabled"
 msgstr ""
 
-#. TRANSLATORS: no debuginfo packages could be found to be installed, detailed error follows
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:943
+#. TRANSLATORS: no debuginfo packages could be found to be installed, detailed
+#. error follows
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:917
 #, c-format
 msgid "Could not disable the debugging sources: %s"
 msgstr ""
 
 #. TRANSLATORS: we disabled all the debugging repos that we enabled before
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:958
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:932
 #, c-format
 msgid "Disabled %i debugging sources."
 msgstr ""
 
 #. TRANSLATORS: couldn't open device to write
-#: ../contrib/device-rebind/pk-device-rebind.c:61
+#: ../contrib/device-rebind/pk-device-rebind.c:62
 #, fuzzy
 msgid "Failed to open file"
 msgstr "Failed to open package list."
 
 #. TRANSLATORS: could not write to the device
-#: ../contrib/device-rebind/pk-device-rebind.c:70
+#: ../contrib/device-rebind/pk-device-rebind.c:71
 #, fuzzy
 msgid "Failed to write to the file"
 msgstr "Failed to get last time"
 
 #. TRANSLATORS: we failed to release the current driver
-#: ../contrib/device-rebind/pk-device-rebind.c:110
-#: ../contrib/device-rebind/pk-device-rebind.c:147
+#: ../contrib/device-rebind/pk-device-rebind.c:111
+#: ../contrib/device-rebind/pk-device-rebind.c:148
 #, fuzzy
 msgid "Failed to write to device"
 msgstr "Failed to save to disk"
 
 #. TRANSLATORS: the device could not be found in sysfs
-#: ../contrib/device-rebind/pk-device-rebind.c:175
+#: ../contrib/device-rebind/pk-device-rebind.c:176
 #, fuzzy
 msgid "Device could not be found"
 msgstr "The package could not be found"
 
 #. TRANSLATORS: we failed to release the current driver
-#: ../contrib/device-rebind/pk-device-rebind.c:202
+#: ../contrib/device-rebind/pk-device-rebind.c:203
 #, fuzzy
 msgid "Failed to unregister driver"
 msgstr "Failed to create directory:"
 
 #. TRANSLATORS: we failed to bind the old driver
-#: ../contrib/device-rebind/pk-device-rebind.c:211
+#: ../contrib/device-rebind/pk-device-rebind.c:212
 #, fuzzy
 msgid "Failed to register driver"
 msgstr "Failed to create directory:"
 
 #. TRANSLATORS: user did not specify a device sysfs path that exists
-#: ../contrib/device-rebind/pk-device-rebind.c:260
+#: ../contrib/device-rebind/pk-device-rebind.c:261
 #, fuzzy
 msgid "Device path not found"
 msgstr "Directory not found"
 
 #. TRANSLATORS: user did not specify a valid device sysfs path
-#: ../contrib/device-rebind/pk-device-rebind.c:268
+#: ../contrib/device-rebind/pk-device-rebind.c:269
 msgid "Incorrect device path specified"
 msgstr ""
 
-#. command line argument, simulate what would be done, but don't actually do it
-#: ../contrib/device-rebind/pk-device-rebind.c:296
+#: ../contrib/device-rebind/pk-device-rebind.c:294
+msgid "Show extra debugging information"
+msgstr "Show extra debugging information"
+
+#. command line argument, simulate what would be done, but don't actually do
+#. it
+#: ../contrib/device-rebind/pk-device-rebind.c:297
 msgid "Don't actually touch the hardware, only simulate what would be done"
 msgstr ""
 
 #. TRANSLATORS: command line option: a list of files to install
-#: ../contrib/device-rebind/pk-device-rebind.c:299
+#: ../contrib/device-rebind/pk-device-rebind.c:300
 msgid "Device paths"
 msgstr ""
 
-#. TRANSLATORS: tool that gets called when the device needs reloading after installing firmware
-#: ../contrib/device-rebind/pk-device-rebind.c:314
+#. TRANSLATORS: tool that gets called when the device needs reloading after
+#. installing firmware
+#: ../contrib/device-rebind/pk-device-rebind.c:315
 #, fuzzy
 msgid "PackageKit Device Reloader"
 msgstr "PackageKit Service Pack"
 
 #. TRANSLATORS: user did not specify a valid device sysfs path
-#: ../contrib/device-rebind/pk-device-rebind.c:322
+#: ../contrib/device-rebind/pk-device-rebind.c:323
 #, fuzzy
 msgid "You need to specify at least one valid device path"
 msgstr "You need to specify a list file to create"
 
 #. TRANSLATORS: user did not specify a valid device sysfs path
-#: ../contrib/device-rebind/pk-device-rebind.c:332
+#: ../contrib/device-rebind/pk-device-rebind.c:333
 msgid "This script can only be used by the root user"
 msgstr ""
 
 #. TRANSLATORS: we're going to verify the path first
-#: ../contrib/device-rebind/pk-device-rebind.c:341
+#: ../contrib/device-rebind/pk-device-rebind.c:342
 msgid "Verifying device path"
 msgstr ""
 
 #. TRANSLATORS: user did not specify a device sysfs path that exists
-#: ../contrib/device-rebind/pk-device-rebind.c:346
+#: ../contrib/device-rebind/pk-device-rebind.c:347
 #, fuzzy
 msgid "Failed to verify device path"
 msgstr "Failed to save to disk"
 
 #. TRANSLATORS: we're going to try
-#: ../contrib/device-rebind/pk-device-rebind.c:360
+#: ../contrib/device-rebind/pk-device-rebind.c:361
 msgid "Attempting to rebind device"
 msgstr ""
 
 #. TRANSLATORS: we failed to release the current driver
-#: ../contrib/device-rebind/pk-device-rebind.c:365
+#: ../contrib/device-rebind/pk-device-rebind.c:366
 #, fuzzy
 msgid "Failed to rebind device"
 msgstr "Failed to create directory:"
@@ -1288,12 +1185,696 @@ msgstr "PackageKit Package List"
 msgid "PackageKit Service Pack"
 msgstr "PackageKit Service Pack"
 
+#: ../lib/packagekit-glib2/pk-console-shared.c:63
+#, c-format
+msgid "Please enter a number from 1 to %i: "
+msgstr "Please enter a number from 1 to %i: "
+
+#. TRANSLATORS: more than one package could be found that matched, to follow
+#. is a list of possible packages
+#: ../lib/packagekit-glib2/pk-console-shared.c:189
+msgid "More than one package matches:"
+msgstr "More than one package matches:"
+
+#. TRANSLATORS: This finds out which package in the list to use
+#: ../lib/packagekit-glib2/pk-console-shared.c:200
+msgid "Please choose the correct package: "
+msgstr "Please choose the correct package: "
+
+#. TRANSLATORS: This is when the transaction status is not known
+#: ../lib/packagekit-glib2/pk-console-shared.c:255
+msgid "Unknown state"
+msgstr ""
+
+#. TRANSLATORS: transaction state, the daemon is in the process of starting
+#: ../lib/packagekit-glib2/pk-console-shared.c:259
+#, fuzzy
+msgid "Starting"
+msgstr "To install"
+
+#. TRANSLATORS: transaction state, the transaction is waiting for another to
+#. complete
+#: ../lib/packagekit-glib2/pk-console-shared.c:263
+msgid "Waiting in queue"
+msgstr ""
+
+#. TRANSLATORS: transaction state, just started
+#: ../lib/packagekit-glib2/pk-console-shared.c:267
+msgid "Running"
+msgstr ""
+
+#. TRANSLATORS: transaction state, is querying data
+#: ../lib/packagekit-glib2/pk-console-shared.c:271
+msgid "Querying"
+msgstr ""
+
+#. TRANSLATORS: transaction state, getting data from a server
+#: ../lib/packagekit-glib2/pk-console-shared.c:275
+#, fuzzy
+msgid "Getting information"
+msgstr "Getting package information..."
+
+#. TRANSLATORS: transaction state, removing packages
+#: ../lib/packagekit-glib2/pk-console-shared.c:279
+#, fuzzy
+msgid "Removing packages"
+msgstr "Getting package list"
+
+#. TRANSLATORS: transaction state, downloading package files
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:283
+#: ../lib/packagekit-glib2/pk-console-shared.c:661
+msgid "Downloading packages"
+msgstr "Downloading packages"
+
+#. TRANSLATORS: transaction state, refreshing internal lists
+#: ../lib/packagekit-glib2/pk-console-shared.c:291
+#, fuzzy
+msgid "Refreshing software list"
+msgstr "Getting package list"
+
+#. TRANSLATORS: transaction state, installing updates
+#: ../lib/packagekit-glib2/pk-console-shared.c:295
+#, fuzzy
+msgid "Installing updates"
+msgstr "Installing packages"
+
+#. TRANSLATORS: transaction state, removing old packages, and cleaning config
+#. files
+#: ../lib/packagekit-glib2/pk-console-shared.c:299
+#, fuzzy
+msgid "Cleaning up packages"
+msgstr "Downloading packages"
+
+#. TRANSLATORS: transaction state, obsoleting old packages
+#: ../lib/packagekit-glib2/pk-console-shared.c:303
+#, fuzzy
+msgid "Obsoleting packages"
+msgstr "Installing packages"
+
+#. TRANSLATORS: transaction state, checking the transaction before we do it
+#: ../lib/packagekit-glib2/pk-console-shared.c:307
+#, fuzzy
+msgid "Resolving dependencies"
+msgstr "Downloading dependencies"
+
+#. TRANSLATORS: transaction state, checking if we have all the security keys
+#. for the operation
+#: ../lib/packagekit-glib2/pk-console-shared.c:311
+msgid "Checking signatures"
+msgstr ""
+
+#. TRANSLATORS: transaction state, when we return to a previous system state
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:315
+#: ../lib/packagekit-glib2/pk-console-shared.c:621
+msgid "Rolling back"
+msgstr ""
+
+#. TRANSLATORS: transaction state, when we're doing a test transaction
+#: ../lib/packagekit-glib2/pk-console-shared.c:319
+#, fuzzy
+msgid "Testing changes"
+msgstr "Installing packages"
+
+#. TRANSLATORS: transaction state, when we're writing to the system package
+#. database
+#: ../lib/packagekit-glib2/pk-console-shared.c:323
+msgid "Committing changes"
+msgstr ""
+
+#. TRANSLATORS: transaction state, requesting data from a server
+#: ../lib/packagekit-glib2/pk-console-shared.c:327
+msgid "Requesting data"
+msgstr ""
+
+#. TRANSLATORS: transaction state, all done!
+#: ../lib/packagekit-glib2/pk-console-shared.c:331
+msgid "Finished"
+msgstr ""
+
+#. TRANSLATORS: transaction state, in the process of cancelling
+#: ../lib/packagekit-glib2/pk-console-shared.c:335
+msgid "Cancelling"
+msgstr ""
+
+#. TRANSLATORS: transaction state, downloading metadata
+#: ../lib/packagekit-glib2/pk-console-shared.c:339
+msgid "Downloading repository information"
+msgstr ""
+
+#. TRANSLATORS: transaction state, downloading metadata
+#: ../lib/packagekit-glib2/pk-console-shared.c:343
+#, fuzzy
+msgid "Downloading list of packages"
+msgstr "Downloading packages"
+
+#. TRANSLATORS: transaction state, downloading metadata
+#: ../lib/packagekit-glib2/pk-console-shared.c:347
+#, fuzzy
+msgid "Downloading file lists"
+msgstr "Downloading"
+
+#. TRANSLATORS: transaction state, downloading metadata
+#: ../lib/packagekit-glib2/pk-console-shared.c:351
+#, fuzzy
+msgid "Downloading lists of changes"
+msgstr "Downloading packages"
+
+#. TRANSLATORS: transaction state, downloading metadata
+#: ../lib/packagekit-glib2/pk-console-shared.c:355
+#, fuzzy
+msgid "Downloading groups"
+msgstr "Downloading"
+
+#. TRANSLATORS: transaction state, downloading metadata
+#: ../lib/packagekit-glib2/pk-console-shared.c:359
+#, fuzzy
+msgid "Downloading update information"
+msgstr "Getting package information..."
+
+#. TRANSLATORS: transaction state, repackaging delta files
+#: ../lib/packagekit-glib2/pk-console-shared.c:363
+#, fuzzy
+msgid "Repackaging files"
+msgstr "Package files"
+
+#. TRANSLATORS: transaction state, loading databases
+#: ../lib/packagekit-glib2/pk-console-shared.c:367
+#, fuzzy
+msgid "Loading cache"
+msgstr "Downloading packages"
+
+#. TRANSLATORS: transaction state, scanning for running processes
+#: ../lib/packagekit-glib2/pk-console-shared.c:371
+msgid "Scanning applications"
+msgstr ""
+
+#. TRANSLATORS: transaction state, generating a list of packages installed on
+#. the system
+#: ../lib/packagekit-glib2/pk-console-shared.c:375
+#, fuzzy
+msgid "Generating package lists"
+msgstr "Getting package list"
+
+#. TRANSLATORS: transaction state, when we're waiting for the native tools to
+#. exit
+#: ../lib/packagekit-glib2/pk-console-shared.c:379
+#, fuzzy
+msgid "Waiting for package manager lock"
+msgstr "Finding package name."
+
+#. TRANSLATORS: transaction state, waiting for user to type in a password
+#: ../lib/packagekit-glib2/pk-console-shared.c:383
+msgid "Waiting for authentication"
+msgstr ""
+
+#. TRANSLATORS: transaction state, we are updating the list of processes
+#: ../lib/packagekit-glib2/pk-console-shared.c:387
+msgid "Updating running applications"
+msgstr ""
+
+#. TRANSLATORS: transaction state, we are checking executable files currently
+#. in use
+#: ../lib/packagekit-glib2/pk-console-shared.c:391
+msgid "Checking applications in use"
+msgstr ""
+
+#. TRANSLATORS: transaction state, we are checking for libraries currently in
+#. use
+#: ../lib/packagekit-glib2/pk-console-shared.c:395
+msgid "Checking libraries in use"
+msgstr ""
+
+#. TRANSLATORS: transaction state, we are copying package files before or
+#. after the transaction
+#: ../lib/packagekit-glib2/pk-console-shared.c:399
+#, fuzzy
+msgid "Copying files"
+msgstr "No files"
+
+#. TRANSLATORS: The type of update
+#: ../lib/packagekit-glib2/pk-console-shared.c:417
+msgid "Trivial"
+msgstr ""
+
+#. TRANSLATORS: The type of update
+#: ../lib/packagekit-glib2/pk-console-shared.c:421
+msgid "Normal"
+msgstr ""
+
+#. TRANSLATORS: The type of update
+#: ../lib/packagekit-glib2/pk-console-shared.c:425
+msgid "Important"
+msgstr ""
+
+#. TRANSLATORS: The type of update
+#: ../lib/packagekit-glib2/pk-console-shared.c:429
+msgid "Security"
+msgstr ""
+
+#. TRANSLATORS: The type of update
+#: ../lib/packagekit-glib2/pk-console-shared.c:433
+msgid "Bug fix "
+msgstr ""
+
+#. TRANSLATORS: The type of update
+#: ../lib/packagekit-glib2/pk-console-shared.c:437
+msgid "Enhancement"
+msgstr ""
+
+#. TRANSLATORS: The type of update
+#: ../lib/packagekit-glib2/pk-console-shared.c:441
+msgid "Blocked"
+msgstr ""
+
+#. TRANSLATORS: The state of a package
+#. TRANSLATORS: The action of the package, in past tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:446
+#: ../lib/packagekit-glib2/pk-console-shared.c:519
+#, fuzzy
+msgid "Installed"
+msgstr "Installed version"
+
+#. TRANSLATORS: The state of a package, i.e. not installed
+#: ../lib/packagekit-glib2/pk-console-shared.c:451
+msgid "Available"
+msgstr ""
+
+#. TRANSLATORS: The action of the package, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:469
+msgid "Downloading"
+msgstr "Downloading"
+
+#. TRANSLATORS: The action of the package, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:473
+msgid "Updating"
+msgstr ""
+
+#. TRANSLATORS: The action of the package, in present tense
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:477
+#: ../lib/packagekit-glib2/pk-console-shared.c:597
+#, fuzzy
+msgid "Installing"
+msgstr "Installing..."
+
+#. TRANSLATORS: The action of the package, in present tense
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:481
+#: ../lib/packagekit-glib2/pk-console-shared.c:593
+msgid "Removing"
+msgstr ""
+
+#. TRANSLATORS: The action of the package, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:485
+msgid "Cleaning up"
+msgstr ""
+
+#. TRANSLATORS: The action of the package, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:489
+msgid "Obsoleting"
+msgstr ""
+
+#. TRANSLATORS: The action of the package, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:493
+#, fuzzy
+msgid "Reinstalling"
+msgstr "Installing..."
+
+#. TRANSLATORS: The action of the package, in past tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:511
+#, fuzzy
+msgid "Downloaded"
+msgstr "Downloading"
+
+#. TRANSLATORS: The action of the package, in past tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:523
+msgid "Removed"
+msgstr ""
+
+#. TRANSLATORS: The action of the package, in past tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:527
+msgid "Cleaned up"
+msgstr ""
+
+#. TRANSLATORS: The action of the package, in past tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:531
+msgid "Obsoleted"
+msgstr ""
+
+#. TRANSLATORS: The action of the package, in past tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:535
+#, fuzzy
+msgid "Reinstalled"
+msgstr "To install"
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:553
+msgid "Unknown role type"
+msgstr ""
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:557
+#, fuzzy
+msgid "Getting dependencies"
+msgstr "Downloading dependencies"
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:561
+#, fuzzy
+msgid "Getting update details"
+msgstr "Getting package list"
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:565
+#, fuzzy
+msgid "Getting details"
+msgstr "Getting package list"
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:569
+#, fuzzy
+msgid "Getting requires"
+msgstr "Getting package list"
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:573
+#, fuzzy
+msgid "Getting updates"
+msgstr "Getting package list"
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:577
+msgid "Searching by details"
+msgstr ""
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:581
+#, fuzzy
+msgid "Searching by file"
+msgstr "Searching for package: "
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:585
+#, fuzzy
+msgid "Searching groups"
+msgstr "Searching for package: "
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:589
+#, fuzzy
+msgid "Searching by name"
+msgstr "Searching for package: "
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:601
+#, fuzzy
+msgid "Installing files"
+msgstr "Installing packages"
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:605
+msgid "Refreshing cache"
+msgstr ""
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:609
+#, fuzzy
+msgid "Updating packages"
+msgstr "Installing packages"
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:613
+msgid "Updating system"
+msgstr ""
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:617
+msgid "Canceling"
+msgstr ""
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:625
+#, fuzzy
+msgid "Getting repositories"
+msgstr "Getting package list"
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:629
+msgid "Enabling repository"
+msgstr ""
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:633
+#, fuzzy
+msgid "Setting data"
+msgstr "To install"
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:637
+msgid "Resolving"
+msgstr ""
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:641
+#, fuzzy
+msgid "Getting file list"
+msgstr "Getting package list"
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:645
+#, fuzzy
+msgid "Getting provides"
+msgstr "Getting package list"
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:649
+#, fuzzy
+msgid "Installing signature"
+msgstr "Installing packages"
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:653
+#, fuzzy
+msgid "Getting packages"
+msgstr "Getting package list"
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:657
+msgid "Accepting EULA"
+msgstr ""
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:665
+#, fuzzy
+msgid "Getting upgrades"
+msgstr "Getting package list"
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:669
+#, fuzzy
+msgid "Getting categories"
+msgstr "Getting package list"
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:673
+#, fuzzy
+msgid "Getting transactions"
+msgstr "Getting package list"
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:677
+#: ../lib/packagekit-glib2/pk-console-shared.c:681
+#, fuzzy
+msgid "Simulating install"
+msgstr "To install"
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:685
+msgid "Simulating remove"
+msgstr ""
+
+#. TRANSLATORS: The role of the transaction, in present tense
+#: ../lib/packagekit-glib2/pk-console-shared.c:689
+msgid "Simulating update"
+msgstr ""
+
+#. TRANSLATORS: turn on all debugging
+#: ../lib/packagekit-glib2/pk-debug.c:132
+#, fuzzy
+msgid "Show debugging information for all files"
+msgstr "Show extra debugging information"
+
+#: ../lib/packagekit-glib2/pk-debug.c:190
+msgid "Debugging Options"
+msgstr ""
+
+#: ../lib/packagekit-glib2/pk-debug.c:190
+#, fuzzy
+msgid "Show debugging options"
+msgstr "Show extra debugging information"
+
+#. TRANSLATORS: ask the user if they are comfortable installing insecure
+#. packages
+#: ../lib/packagekit-glib2/pk-task-text.c:67
+msgid "Do you want to allow installing of unsigned software?"
+msgstr ""
+
+#. TRANSLATORS: tell the user we've not done anything
+#: ../lib/packagekit-glib2/pk-task-text.c:72
+#, fuzzy
+msgid "The unsigned software will not be installed."
+msgstr "The package %s could not be installed: %s"
+
+#. TRANSLATORS: the package repository is signed by a key that is not
+#. recognised
+#: ../lib/packagekit-glib2/pk-task-text.c:121
+#, fuzzy
+msgid "Software source signature required"
+msgstr "Repository signature required"
+
+#. TRANSLATORS: the package repository name
+#: ../lib/packagekit-glib2/pk-task-text.c:127
+msgid "Software source name"
+msgstr ""
+
+#. TRANSLATORS: the key URL
+#: ../lib/packagekit-glib2/pk-task-text.c:130
+msgid "Key URL"
+msgstr ""
+
+#. TRANSLATORS: the username of the key
+#: ../lib/packagekit-glib2/pk-task-text.c:133
+msgid "Key user"
+msgstr ""
+
+#. TRANSLATORS: the key ID, usually a few hex digits
+#: ../lib/packagekit-glib2/pk-task-text.c:136
+msgid "Key ID"
+msgstr ""
+
+#. TRANSLATORS: the key fingerprint, again, yet more hex
+#: ../lib/packagekit-glib2/pk-task-text.c:139
+msgid "Key fingerprint"
+msgstr ""
+
+#. TRANSLATORS: the timestamp (a bit like a machine readable time)
+#: ../lib/packagekit-glib2/pk-task-text.c:142
+msgid "Key Timestamp"
+msgstr ""
+
+#. TRANSLATORS: ask the user if they want to import
+#: ../lib/packagekit-glib2/pk-task-text.c:155
+msgid "Do you accept this signature?"
+msgstr "Do you accept this signature?"
+
+#. TRANSLATORS: tell the user we've not done anything
+#: ../lib/packagekit-glib2/pk-task-text.c:160
+msgid "The signature was not accepted."
+msgstr "The signature was not accepted."
+
+#. TRANSLATORS: this is another name for a software licence that has to be
+#. read before installing
+#: ../lib/packagekit-glib2/pk-task-text.c:203
+#, fuzzy
+msgid "End user licence agreement required"
+msgstr "End user licence agreement required"
+
+#. TRANSLATORS: the EULA text itself (long and boring)
+#: ../lib/packagekit-glib2/pk-task-text.c:212
+msgid "Agreement"
+msgstr ""
+
+#. TRANSLATORS: ask the user if they've read and accepted the EULA
+#: ../lib/packagekit-glib2/pk-task-text.c:221
+#, fuzzy
+msgid "Do you accept this agreement?"
+msgstr "Do you accept this signature?"
+
+#. TRANSLATORS: tell the user we've not done anything
+#: ../lib/packagekit-glib2/pk-task-text.c:226
+#, fuzzy
+msgid "The agreement was not accepted."
+msgstr "The signature was not accepted."
+
+#. TRANSLATORS: the user needs to change media inserted into the computer
+#: ../lib/packagekit-glib2/pk-task-text.c:265
+msgid "Media change required"
+msgstr ""
+
+#. TRANSLATORS: the type, e.g. DVD, CD, etc
+#: ../lib/packagekit-glib2/pk-task-text.c:268
+msgid "Media type"
+msgstr ""
+
+#. TRANSLATORS: the media label, usually like 'disk-1of3'
+#: ../lib/packagekit-glib2/pk-task-text.c:271
+msgid "Media label"
+msgstr ""
+
+#. TRANSLATORS: the media description, usually like 'Fedora 12 disk 5'
+#: ../lib/packagekit-glib2/pk-task-text.c:274
+msgid "Text"
+msgstr ""
+
+#. TRANSLATORS: ask the user to insert the media
+#: ../lib/packagekit-glib2/pk-task-text.c:280
+#, fuzzy
+msgid "Please insert the correct media"
+msgstr "Please choose the correct package: "
+
+#. TRANSLATORS: tell the user we've not done anything as they are lazy
+#: ../lib/packagekit-glib2/pk-task-text.c:285
+#, fuzzy
+msgid "The correct media was not inserted."
+msgstr "The signature was not accepted."
+
+#. TRANSLATORS: When processing, we might have to remove other dependencies
+#: ../lib/packagekit-glib2/pk-task-text.c:300
+msgid "The following packages have to be removed:"
+msgstr "The following packages have to be removed:"
+
+#. TRANSLATORS: When processing, we might have to install other dependencies
+#: ../lib/packagekit-glib2/pk-task-text.c:305
+#, fuzzy
+msgid "The following packages have to be installed:"
+msgstr "The following packages have to be removed:"
+
+#. TRANSLATORS: When processing, we might have to update other dependencies
+#: ../lib/packagekit-glib2/pk-task-text.c:310
+#, fuzzy
+msgid "The following packages have to be updated:"
+msgstr "The following packages have to be removed:"
+
+#. TRANSLATORS: When processing, we might have to reinstall other dependencies
+#: ../lib/packagekit-glib2/pk-task-text.c:315
+#, fuzzy
+msgid "The following packages have to be reinstalled:"
+msgstr "The following packages have to be removed:"
+
+#. TRANSLATORS: When processing, we might have to downgrade other dependencies
+#: ../lib/packagekit-glib2/pk-task-text.c:320
+#, fuzzy
+msgid "The following packages have to be downgraded:"
+msgstr "The following packages have to be removed:"
+
+#. TRANSLATORS: ask the user if the proposed changes are okay
+#: ../lib/packagekit-glib2/pk-task-text.c:380
+msgid "Proceed with changes?"
+msgstr ""
+
+#. TRANSLATORS: tell the user we didn't do anything
+#: ../lib/packagekit-glib2/pk-task-text.c:385
+msgid "The transaction did not proceed."
+msgstr ""
+
 #. SECURITY:
 #. - Normal users do not require admin authentication to accept new
 #. licence agreements.
 #. - Change this to 'auth_admin' for environments where users should not
 #. be given the option to make legal decisions.
-#.
+#. 
 #: ../policy/org.freedesktop.packagekit.policy.in.h:7
 msgid "Accept EULA"
 msgstr ""
@@ -1303,8 +1884,7 @@ msgid "Authentication is required to accept a EULA"
 msgstr ""
 
 #: ../policy/org.freedesktop.packagekit.policy.in.h:9
-msgid ""
-"Authentication is required to cancel a task that was not started by yourself"
+msgid "Authentication is required to cancel a task that was not started by yourself"
 msgstr ""
 
 #: ../policy/org.freedesktop.packagekit.policy.in.h:10
@@ -1312,42 +1892,42 @@ msgid "Authentication is required to change software source parameters"
 msgstr ""
 
 #: ../policy/org.freedesktop.packagekit.policy.in.h:11
-msgid ""
-"Authentication is required to consider a key used for signing packages as "
-"trusted"
+msgid "Authentication is required to change the location used to decompress packages"
 msgstr ""
 
 #: ../policy/org.freedesktop.packagekit.policy.in.h:12
-msgid "Authentication is required to install a signed package"
+msgid "Authentication is required to consider a key used for signing packages as trusted"
 msgstr ""
 
 #: ../policy/org.freedesktop.packagekit.policy.in.h:13
-msgid "Authentication is required to install an untrusted package"
+msgid "Authentication is required to install a signed package"
 msgstr ""
 
 #: ../policy/org.freedesktop.packagekit.policy.in.h:14
-msgid "Authentication is required to refresh the system sources"
+msgid "Authentication is required to install an untrusted package"
 msgstr ""
 
 #: ../policy/org.freedesktop.packagekit.policy.in.h:15
-msgid "Authentication is required to reload the device with a new driver"
+msgid "Authentication is required to refresh the system sources"
 msgstr ""
 
 #: ../policy/org.freedesktop.packagekit.policy.in.h:16
-msgid "Authentication is required to remove packages"
+msgid "Authentication is required to reload the device with a new driver"
 msgstr ""
 
 #: ../policy/org.freedesktop.packagekit.policy.in.h:17
-msgid "Authentication is required to rollback a transaction"
+msgid "Authentication is required to remove packages"
 msgstr ""
 
 #: ../policy/org.freedesktop.packagekit.policy.in.h:18
-msgid ""
-"Authentication is required to set the network proxy used for downloading "
-"packages"
+msgid "Authentication is required to rollback a transaction"
 msgstr ""
 
 #: ../policy/org.freedesktop.packagekit.policy.in.h:19
+msgid "Authentication is required to set the network proxy used for downloading packages"
+msgstr ""
+
+#: ../policy/org.freedesktop.packagekit.policy.in.h:20
 msgid "Authentication is required to update packages"
 msgstr ""
 
@@ -1355,17 +1935,28 @@ msgstr ""
 #. - Normal users are allowed to cancel their own task without
 #. authentication, but a different user id needs the admin password
 #. to cancel another users task.
-#.
-#: ../policy/org.freedesktop.packagekit.policy.in.h:25
+#. 
+#: ../policy/org.freedesktop.packagekit.policy.in.h:26
 msgid "Cancel foreign task"
 msgstr ""
 
 #. SECURITY:
+#. - This is used when users want to install to a different prefix, for
+#. instance to a LTSP image or a virtual machine.
+#. - This could be used to overwrite files not owned by the user using
+#. a carefully created package file.
+#. 
+#: ../policy/org.freedesktop.packagekit.policy.in.h:33
+#, fuzzy
+msgid "Change location that packages are installed"
+msgstr "The package %s is already installed"
+
+#. SECURITY:
 #. - Normal users require admin authentication to enable or disable
 #. software sources as this can be used to enable new updates or
 #. install different versions of software.
-#.
-#: ../policy/org.freedesktop.packagekit.policy.in.h:31
+#. 
+#: ../policy/org.freedesktop.packagekit.policy.in.h:39
 msgid "Change software source parameters"
 msgstr ""
 
@@ -1374,8 +1965,8 @@ msgstr ""
 #. from signed repositories, as this cannot exploit a system.
 #. - Paranoid users (or parents!) can change this to 'auth_admin' or
 #. 'auth_admin_keep'.
-#.
-#: ../policy/org.freedesktop.packagekit.policy.in.h:38
+#. 
+#: ../policy/org.freedesktop.packagekit.policy.in.h:46
 #, fuzzy
 msgid "Install signed package"
 msgstr "Installing packages"
@@ -1385,16 +1976,16 @@ msgstr "Installing packages"
 #. unrecognised packages, as allowing users to do this without a
 #. password would be a massive security hole.
 #. - This is not retained as each package should be authenticated.
-#.
-#: ../policy/org.freedesktop.packagekit.policy.in.h:45
+#. 
+#: ../policy/org.freedesktop.packagekit.policy.in.h:53
 msgid "Install untrusted local file"
 msgstr ""
 
 #. SECURITY:
 #. - Normal users do not require admin authentication to refresh the
 #. cache, as this doesn't actually install or remove software.
-#.
-#: ../policy/org.freedesktop.packagekit.policy.in.h:50
+#. 
+#: ../policy/org.freedesktop.packagekit.policy.in.h:58
 msgid "Refresh system sources"
 msgstr ""
 
@@ -1404,8 +1995,8 @@ msgstr ""
 #. - This should not be set to 'yes' as unprivileged users could then
 #. try to rebind drivers in use, for instance security authentication
 #. devices.
-#.
-#: ../policy/org.freedesktop.packagekit.policy.in.h:58
+#. 
+#: ../policy/org.freedesktop.packagekit.policy.in.h:66
 msgid "Reload a device"
 msgstr ""
 
@@ -1417,8 +2008,8 @@ msgstr ""
 #. admin authentication has been obtained, otherwise packages can still
 #. be removed. If this is not possible, change this authentication to
 #. 'auth_admin'.
-#.
-#: ../policy/org.freedesktop.packagekit.policy.in.h:68
+#. 
+#: ../policy/org.freedesktop.packagekit.policy.in.h:76
 msgid "Remove package"
 msgstr ""
 
@@ -1426,16 +2017,16 @@ msgstr ""
 #. - Normal users require admin authentication to rollback system state
 #. as this will change a large number of packages, and could expose the
 #. system to previously patched security vulnerabilities.
-#.
-#: ../policy/org.freedesktop.packagekit.policy.in.h:74
+#. 
+#: ../policy/org.freedesktop.packagekit.policy.in.h:82
 msgid "Rollback to a previous transaction"
 msgstr ""
 
 #. SECURITY:
 #. - Normal users do not require admin authentication to set the proxy
 #. used for downloading packages.
-#.
-#: ../policy/org.freedesktop.packagekit.policy.in.h:79
+#. 
+#: ../policy/org.freedesktop.packagekit.policy.in.h:87
 msgid "Set network proxy"
 msgstr ""
 
@@ -1444,8 +2035,8 @@ msgstr ""
 #. - This implies adding an explicit trust, and should not be granted
 #. without a secure authentication.
 #. - This is not kept as each package should be authenticated.
-#.
-#: ../policy/org.freedesktop.packagekit.policy.in.h:86
+#. 
+#: ../policy/org.freedesktop.packagekit.policy.in.h:94
 msgid "Trust a key used for signing packages"
 msgstr ""
 
@@ -1455,8 +2046,8 @@ msgstr ""
 #. to update the system when unattended.
 #. - Changing this to anything other than 'yes' will break unattended
 #. updates.
-#.
-#: ../policy/org.freedesktop.packagekit.policy.in.h:94
+#. 
+#: ../policy/org.freedesktop.packagekit.policy.in.h:102
 msgid "Update packages"
 msgstr ""
 
@@ -1477,100 +2068,179 @@ msgstr "The correct user is not launching the executable (usually root)"
 
 #. TRANSLATORS: or we are installed in a prefix
 #: ../src/pk-main.c:93
-msgid ""
-"The org.freedesktop.PackageKit.conf file is not installed in the system "
-"directory:"
-msgstr ""
-"The org.freedesktop.PackageKit.conf file is not installed in the system "
-"directory:"
+msgid "The org.freedesktop.PackageKit.conf file is not installed in the system directory:"
+msgstr "The org.freedesktop.PackageKit.conf file is not installed in the system directory:"
 
 #. TRANSLATORS: a backend is the system package tool, e.g. yum, apt
-#: ../src/pk-main.c:205
+#: ../src/pk-main.c:200
 msgid "Packaging backend to use, e.g. dummy"
 msgstr "Packaging backend to use, e.g. dummy"
 
 #. TRANSLATORS: if we should run in the background
-#: ../src/pk-main.c:208
+#: ../src/pk-main.c:203
 msgid "Daemonize and detach from the terminal"
 msgstr "Daemonize and detach from the terminal"
 
 #. TRANSLATORS: if we should not monitor how long we are inactive for
-#: ../src/pk-main.c:214
+#: ../src/pk-main.c:206
 msgid "Disable the idle timer"
 msgstr "Disable the idle timer"
 
 #. TRANSLATORS: show version
-#: ../src/pk-main.c:217
+#: ../src/pk-main.c:209
 msgid "Show version and exit"
 msgstr "Show version and exit"
 
 #. TRANSLATORS: exit after we've started up, used for user profiling
-#: ../src/pk-main.c:220
+#: ../src/pk-main.c:212
 msgid "Exit after a small delay"
 msgstr "Exit after a small delay"
 
 #. TRANSLATORS: exit straight away, used for automatic profiling
-#: ../src/pk-main.c:223
+#: ../src/pk-main.c:215
 msgid "Exit after the engine has loaded"
 msgstr "Exit after the engine has loaded"
 
 #. TRANSLATORS: describing the service that is running
-#: ../src/pk-main.c:238
+#: ../src/pk-main.c:230
 msgid "PackageKit service"
 msgstr "PackageKit service"
 
 #. TRANSLATORS: fatal error, dbus is not running
-#: ../src/pk-main.c:275
+#: ../src/pk-main.c:267
 msgid "Cannot connect to the system bus"
 msgstr "Cannot connect to the system bus"
 
-#. TRANSLATORS: cannot register on system bus, unknown reason -- geeky error follows
-#: ../src/pk-main.c:334
+#. TRANSLATORS: cannot register on system bus, unknown reason -- geeky error
+#. follows
+#: ../src/pk-main.c:316
 msgid "Error trying to start:"
 msgstr "Error trying to start:"
 
-#: ../src/pk-polkit-action-lookup.c:147
+#: ../src/pk-polkit-action-lookup.c:150
 #, fuzzy
 msgid "To install debugging packages, extra sources need to be enabled"
 msgstr "No new packages need to be installed"
 
 #. TRANSLATORS: is not GPG signed
-#: ../src/pk-polkit-action-lookup.c:168 ../src/pk-polkit-action-lookup.c:187
+#: ../src/pk-polkit-action-lookup.c:171 ../src/pk-polkit-action-lookup.c:190
 msgid "The software is not from a trusted source."
 msgstr ""
 
-#: ../src/pk-polkit-action-lookup.c:173
+#: ../src/pk-polkit-action-lookup.c:176
 msgid "Do not update this package unless you are sure it is safe to do so."
 msgstr ""
 
-#: ../src/pk-polkit-action-lookup.c:174
+#: ../src/pk-polkit-action-lookup.c:177
 msgid "Do not update these packages unless you are sure it is safe to do so."
 msgstr ""
 
-#: ../src/pk-polkit-action-lookup.c:192
+#: ../src/pk-polkit-action-lookup.c:195
 msgid "Do not install this package unless you are sure it is safe to do so."
 msgstr ""
 
-#: ../src/pk-polkit-action-lookup.c:193
+#: ../src/pk-polkit-action-lookup.c:196
 msgid "Do not install these packages unless you are sure it is safe to do so."
 msgstr ""
 
-#. TRANSLATORS: warn the user that all bets are off
-#: ../src/pk-polkit-action-lookup.c:199
-msgid "Malicious software can damage your computer or cause other harm."
-msgstr ""
-
 #. TRANSLATORS: too many packages to list each one
-#: ../src/pk-polkit-action-lookup.c:274
+#: ../src/pk-polkit-action-lookup.c:273
 #, fuzzy
 msgid "Many packages"
 msgstr "Installing packages"
 
 #. TRANSLATORS: if the transaction is forced to install only trusted packages
-#: ../src/pk-polkit-action-lookup.c:334
+#: ../src/pk-polkit-action-lookup.c:339
 msgid "Only trusted"
 msgstr ""
 
+#~ msgid "Please restart the application as it is being used."
+#~ msgstr "Please restart the application as it is being used."
+
+#~ msgid "The package %s is already installed"
+#~ msgstr "The package %s is already installed"
+
+#~ msgid "This tool could not install the files: %s"
+#~ msgstr "This tool could not install the files: %s"
+
+#~ msgid "This tool could not remove the packages: %s"
+#~ msgstr "This tool could not remove the packages: %s"
+
+#~ msgid "Proceed removing additional packages?"
+#~ msgstr "Proceed removing additional packages?"
+
+#~ msgid "The package removal was canceled!"
+#~ msgstr "The package removal was cancelled!"
+
+#~ msgid "This tool could not download the package %s as it could not be found"
+#~ msgstr "This tool could not download the package %s as it could not be found"
+
+#~ msgid "This tool could not download the packages: %s"
+#~ msgstr "This tool could not download the packages: %s"
+
+#~ msgid "This tool could not update %s: %s"
+#~ msgstr "This tool could not update %s: %s"
+
+#~ msgid "This tool could not get the requirements for %s: %s"
+#~ msgstr "This tool could not get the requirements for %s: %s"
+
+#~ msgid "This tool could not get the dependencies for %s: %s"
+#~ msgstr "This tool could not get the dependencies for %s: %s"
+
+#~ msgid "This tool could not get package details for %s: %s"
+#~ msgstr "This tool could not get package details for %s: %s"
+
+#~ msgid "This tool could not find the files for %s: %s"
+#~ msgstr "This tool could not find the files for %s: %s"
+
+#~ msgid "This tool could not get the file list for %s: %s"
+#~ msgstr "This tool could not get the file list for %s: %s"
+
+#~ msgid "File already exists: %s"
+#~ msgstr "File already exists: %s"
+
+#~ msgid "This tool could not get package list: %s"
+#~ msgstr "This tool could not get package list: %s"
+
+#~ msgid "Failed to save to disk"
+#~ msgstr "Failed to save to disk"
+
+#~ msgid "File does not exist: %s"
+#~ msgstr "File does not exist: %s"
+
+#~ msgid "Packages to add"
+#~ msgstr "Packages to add"
+
+#~ msgid "Packages to remove"
+#~ msgstr "Packages to remove"
+
+#~ msgid "not found."
+#~ msgstr "not found."
+
+#~ msgid "No packages can be found to install"
+#~ msgstr "No packages can be found to install"
+
+#~ msgid "This tool could not find the update details for %s: %s"
+#~ msgstr "This tool could not find the update details for %s: %s"
+
+#~ msgid "This tool could not get the update details for %s: %s"
+#~ msgstr "This tool could not get the update details for %s: %s"
+
+#~ msgid "Error:"
+#~ msgstr "Error:"
+
+#~ msgid "Do you agree to this license?"
+#~ msgstr "Do you agree to this licence?"
+
+#~ msgid "The license was refused."
+#~ msgstr "The licence was refused."
+
+#~ msgid "This tool could not connect to system DBUS."
+#~ msgstr "This tool could not connect to system DBUS."
+
+#~ msgid "Incorrect privileges for this operation"
+#~ msgstr "You don't have the necessary privileges for this operation"
+
 #~ msgid "You need to specify a search type, e.g. name"
 #~ msgstr "You need to specify a search type, e.g. name"
 


More information about the PackageKit-commit mailing list