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

Richard Hughes hughsient at kemper.freedesktop.org
Wed Oct 8 06:19:08 PDT 2008


 RELEASE                                  |   16 
 backends/alpm/pk-backend-alpm.c          |    1 
 backends/apt.deprecated/pk-backend-apt.c |    1 
 backends/apt/aptDBUSBackend.py           |    2 
 backends/apt/pk-backend-apt.c            |    8 
 backends/box/pk-backend-box.c            |    1 
 backends/conary/pk-backend-conary.c      |    1 
 backends/dummy/pk-backend-dummy.c        |    1 
 backends/opkg/pk-backend-opkg.c          |    1 
 backends/pisi/pk-backend-pisi.c          |    1 
 backends/poldek/pk-backend-poldek.c      |    1 
 backends/razor/pk-backend-razor.c        |    1 
 backends/smart/pk-backend-smart.c        |    1 
 backends/test/pk-backend-test-dbus.c     |    1 
 backends/test/pk-backend-test-fail.c     |    1 
 backends/test/pk-backend-test-nop.c      |    1 
 backends/test/pk-backend-test-spawn.c    |    1 
 backends/test/pk-backend-test-succeed.c  |    1 
 backends/test/pk-backend-test-thread.c   |    1 
 backends/urpmi/pk-backend-urpmi.c        |    1 
 backends/yum/pk-backend-yum.c            |   10 
 backends/yum/yumBackend.py               |  155 ++++-
 backends/yum/yumComps.py                 |    9 
 backends/zypp/pk-backend-zypp.cpp        |    1 
 client/Makefile.am                       |    7 
 client/pk-console.c                      |   28 +
 client/pk-generate-pack-main.c           |  163 ------
 client/pk-generate-pack.c                |  748 ++++++----------------------
 client/pk-generate-pack.h                |   46 -
 client/pk-self-test.c                    |    2 
 client/pk-service-pack.c                 |    1 
 client/pk-service-pack.h                 |    1 
 configure.ac                             |    2 
 contrib/PackageKit.spec.in               |   10 
 contrib/gstreamer-plugin/README          |   44 +
 contrib/pk-completion.bash               |    1 
 libpackagekit/Makefile.am                |    3 
 libpackagekit/egg-obj-list.c             |   35 +
 libpackagekit/egg-obj-list.h             |    3 
 libpackagekit/pk-category-obj.c          |  144 +++++
 libpackagekit/pk-category-obj.h          |   54 ++
 libpackagekit/pk-client.c                |  149 +++++
 libpackagekit/pk-client.h                |   11 
 libpackagekit/pk-enum.c                  |    1 
 libpackagekit/pk-enum.h                  |    1 
 man/pkgenpack.xml                        |  131 +++--
 po/POTFILES.in                           |    1 
 po/de.po                                 |  146 ++---
 po/el.po                                 |  426 +++++++++++-----
 python/packagekit/backend.py             |   26 -
 python/packagekit/client.py              |   20 
 python/packagekit/filter.py              |    9 
 python/packagekit/misc.py                |   11 
 python/wrapper-test.py                   |   10 
 src/Makefile.am                          |    2 
 src/pk-backend-dbus.c                    |   49 +
 src/pk-backend-dbus.h                    |    1 
 src/pk-backend-spawn.c                   |   34 +
 src/pk-backend.c                         |   36 +
 src/pk-backend.h                         |   13 
 src/pk-interface-transaction.xml         |   85 +++
 src/pk-service-pack.c                    |  803 +++++++++++++++++++++++++++++++
 src/pk-service-pack.h                    |   77 ++
 src/pk-transaction.c                     |  282 +++-------
 src/pk-transaction.h                     |    2 
 65 files changed, 2542 insertions(+), 1294 deletions(-)

New commits:
commit 77da13371771237b4ccad26a8cfdff0ba659f581
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 8 13:28:47 2008 +0100

    trivial: fix up the pkgenpack man page

diff --git a/client/pk-generate-pack.c b/client/pk-generate-pack.c
index 28573b3..c2ac69a 100644
--- a/client/pk-generate-pack.c
+++ b/client/pk-generate-pack.c
@@ -176,7 +176,7 @@ main (int argc, char *argv[])
 		{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
 			_("Show extra debugging information"), NULL },
 		{ "with-package-list", 'l', 0, G_OPTION_ARG_STRING, &package_list,
-			_("Set the path of the file with the list of packages/dependencies to be excluded"), NULL},
+			_("Set the filename of dependencies to be excluded"), NULL},
 		{ "output", 'o', 0, G_OPTION_ARG_STRING, &directory,
 			_("The directory to put the pack file, or the current directory if ommitted"), NULL},
 		{ "package", 'p', 0, G_OPTION_ARG_STRING, &package,
diff --git a/man/pkgenpack.xml b/man/pkgenpack.xml
index 4ec8962..e3a09f1 100644
--- a/man/pkgenpack.xml
+++ b/man/pkgenpack.xml
@@ -44,9 +44,12 @@ manpage.1: manpage.xml
   <refsynopsisdiv>
     <cmdsynopsis>
       <command>&package;</command>
-      <arg><option>options</option></arg>
-      <arg><option>path</option></arg>
-      <arg><option>package ..</option></arg>
+      <arg><option>--help</option></arg>
+      <arg><option>--verbose</option></arg>
+      <arg><option>--with-package-list</option></arg>
+      <arg><option>--output</option></arg>
+      <arg><option>--package</option></arg>
+      <arg><option>--updates</option></arg>
     </cmdsynopsis>
   </refsynopsisdiv>
   <refsect1>
@@ -61,80 +64,130 @@ manpage.1: manpage.xml
   <refsect1>
     <title>What is a Service Pack?</title>
     <para>
-      A service pack is a tarball which contains the particular package and its dependencies.
-      The user can select the dependencies to be packed using the --with-package-list option.
+      A service pack is a tarball which contains a set of packages and their dependencies.
+      The user can reduce the dependencies to be packed using the --with-package-list option.
       Along with the dependencies, a service pack has a file named metadata.conf which contains
-      the information like distro_id and date of creation of the pack.
+      the information about the distribution and creation date of the pack.
     </para>
   </refsect1>
   <refsect1>
     <title>Creating a Service Pack?</title>
     <para>
-      A service pack can be created using pkgenpack. When creating a pack, the user needs to specify
-      a valid path for the service pack and the package for which the pack has to be created.
+      A service pack is created using the command <command>pkgenpack</command>.
     </para>
   </refsect1>
   <refsect1>
     <title>Options</title>
     <para>
-      --with-package-list
-    </para>
-    <para>
-      allows the user to explicitly specify the file list of packages from which the dependencies
-        are to be excluded. Generally, the file list of packages is generated using
-      pk-generate-package-list on the target system. If not used, pkgenpack
-        uses /var/lib/PackageKit/package-list.txt by default.
-    </para>
-    <para>
-      --verbose or -v
-    </para>
-    <para>
-      presents the debugging details to the user.
-    </para>
+      This program follows the usual &gnu; command line syntax, with long options
+      starting with two dashes (`-').
+      A summary of options is included below.
+    </para>
+    <variablelist>
+      <varlistentry>
+        <term>
+          <option>--help</option>
+        </term>
+        <listitem>
+          <para>Show summary of options.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>
+          <option>--verbose</option>
+        </term>
+        <listitem>
+          <para>Show extra debugging information.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>
+          <option>--with-package-list</option>
+        </term>
+        <listitem>
+          <para>Set the filename of dependencies to be excluded.</para>
+          <para>
+            Generally, the file list of packages is generated using
+            <command>pk-generate-package-list</command> on the target system.
+            If not specified, <command>pkgenpack</command> uses
+            /var/lib/PackageKit/package-list.txt by default.
+          </para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>
+          <option>--output</option>
+        </term>
+        <listitem>
+          <para>The directory to put the pack file, or the current directory if omitted.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>
+          <option>--package</option>
+        </term>
+        <listitem>
+          <para>The package to be put into the ServicePack.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>
+          <option>--update</option>
+        </term>
+        <listitem>
+          <para>Put all updates available in the ServicePack.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
   </refsect1>
   <refsect1>
     <title>Naming a Service Pack</title>
     <para>
-     The only valid extension for a service pack is ".servicepack". The user needs to specify
-     the full path of the pack, when using pkgenpack to generate a service pack.
+     The only valid extension for a service pack is ".servicepack".
     </para>
   </refsect1>
   <refsect1>
     <title>Examples</title>
     <para>
-      1. Tim is facing problems with his Internet connection at home. He needs a service pack
-      with valgrind and it's dependancies for his system. He asks James to generate a pack for him. Both know
-      James's system should contain similar packages as Tim's system, as both of them
-      have installed Fedora 9 two days ago. James simply runs:
+      1. Tim is facing problems with his Internet connection at home.
+      He needs a service pack with valgrind and it's dependencies for his system.
+      He asks James to generate a pack for him.
+      Both know James's system should contain similar packages as Tim's system,
+      as both of them have installed Fedora 9 two days ago. James simply runs:
     </para>
     <para>
-      [james at jamesbook:~]$pkgenpack /media/USB/TimPacks/valgrind.servicepack valgrind
+      [james at jamesbook:~]$ pkgenpack --output=/media/USB/TimPacks --package=valgrind
     </para>
     <para>
-     This generates a file valgrind.servicepack on the USB key Tim gave to James. Tim can now go home,
-     insert the USB key and double click on the valgrind.servicepack to be prompted to install these packages.
+     This generates a file /media/USB/TimPacks/valgrind-fedora-9-i686.servicepack
+     on the USB key Tim gave to James.
+     Tim can now go home, insert the USB key and double clicks on the
+     valgrind-fedora-9-i686.servicepack file to be prompted to install these packages.
     </para>
     <para>
-      2. Bill wants to create a service pack named kdegames.servicepack for his new system which does not have
-      an internet connection. He generates a list of packages on his system using pk-generate-package-list
-      and copies that list to his USB key. He then gives that USB to Rishi who has a good internet connectivity.
+      2. Bill wants to create a service pack named kdegames-fedora-9-i686.servicepack for
+      his new system which does not have an internet connection.
+      He generates a list of packages on his system using <command>pk-generate-package-list</command>
+      and copies that list to his USB key.
+      He then gives that USB to Rishi who has a good internet connectivity.
       Rishi runs the following command on his system:
     </para>
     <para>
-      [rishi at devils-temple:~]$pkgenpack --with-package-list /media/USB/package-list.txt /home/rishi/Desktop/kdegames.servicepack kdegames
+      [rishi at devils-temple:~]$ pkgenpack --with-package-list=/media/USB/package-list.txt --output=/home/rishi/Desktop --program=kdegames
     </para>
     <para>
-      This generates a service pack, kdegames.servicepack, on Rishi's Desktop, which can be distributed
-      to Bill and users with similar requirements.
+      This generates a service pack, kdegames-fedora-9-i686.servicepack, on Rishi's
+      Desktop, which can be distributed to Bill and users with similar requirements.
     </para>
   </refsect1>
   <refsect1>
     <title>Installing A Service Pack</title>
     <para>
-      Service Packs can be installed using pkcon by specifying the valid path. For example:
+      Service Packs can be installed using pkcon.
+      For example:
     </para>
     <para>
-      [hacker at tim-lounge:~]$pkcon install /home/USB/TimPacks/valgrind.servicepack
+      [hacker at tim-lounge:~]$ pkcon install /home/USB/TimPacks/valgrind-fedora-9-i686.servicepack
     </para>
   </refsect1>
   <refsect1>
commit 6d203adbb6254924fc62fb92900aca24a9e7aa17
Merge: 9a428d0... 98bc037...
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 8 12:48:48 2008 +0100

    Merge branch 'master' of git+ssh://hughsie@git.packagekit.org/srv/git/PackageKit

commit 9a428d0c43e30c803e25c3af669d7d505805814e
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 8 12:48:02 2008 +0100

    feature: add a -u option to pkgenpack so we can generate a package of update plus deps

diff --git a/src/pk-service-pack.c b/src/pk-service-pack.c
index ee74b60..576623e 100644
--- a/src/pk-service-pack.c
+++ b/src/pk-service-pack.c
@@ -682,11 +682,39 @@ pk_service_pack_create_for_package_id (PkServicePack *pack, const gchar *package
 gboolean
 pk_service_pack_create_for_updates (PkServicePack *pack, GError **error)
 {
+	gchar **package_ids = NULL;
+	GError *error_local = NULL;
+	gboolean ret = FALSE;
+	PkPackageList *list;
+
 	g_return_val_if_fail (PK_IS_SERVICE_PACK (pack), FALSE);
 	g_return_val_if_fail (pack->priv->filename != NULL, FALSE);
 	g_return_val_if_fail (pack->priv->directory != NULL, FALSE);
-	*error = g_error_new (1, 0, "not yet supported");
-	return TRUE;
+
+	/* get updates */
+	ret = pk_client_reset (pack->priv->client, &error_local);
+	if (!ret) {
+		*error = g_error_new (1, 0, "failed to reset: %s", error_local->message);
+		g_error_free (error_local);
+		goto out;
+	}
+
+	egg_debug ("Getting updates");
+	ret = pk_client_get_updates (pack->priv->client, PK_FILTER_ENUM_NONE, &error_local);
+	if (!ret) {
+		*error = g_error_new (1, 0, "failed to get updates: %s", error_local->message);
+		g_error_free (error_local);
+		goto out;
+	}
+
+	/* get the updates, and download them with deps */
+	list = pk_client_get_package_list (pack->priv->client);
+	package_ids = pk_package_list_to_strv (list);
+	g_object_unref (list);
+	ret = pk_service_pack_create_for_package_ids (pack, package_ids, error);
+out:
+	g_strfreev (package_ids);
+	return ret;
 }
 
 /**
commit 1877480b097fcbae7666b9c11b883f4346b08575
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 8 12:42:40 2008 +0100

    trivial: factor out pk_service_pack_create_for_package_ids

diff --git a/src/pk-service-pack.c b/src/pk-service-pack.c
index abe0d71..ee74b60 100644
--- a/src/pk-service-pack.c
+++ b/src/pk-service-pack.c
@@ -558,12 +558,12 @@ out:
 }
 
 /**
- * pk_service_pack_create_for_package_id:
+ * pk_service_pack_create_for_package_ids:
  **/
 gboolean
-pk_service_pack_create_for_package_id (PkServicePack *pack, const gchar *package_id, GError **error)
+pk_service_pack_create_for_package_ids (PkServicePack *pack, gchar **package_ids, GError **error)
 {
-	gchar **package_ids = NULL;
+	gchar **package_ids_deps = NULL;
 	PkPackageList *list = NULL;
 	guint length;
 	guint i;
@@ -574,14 +574,12 @@ pk_service_pack_create_for_package_id (PkServicePack *pack, const gchar *package
 	gchar *text;
 
 	g_return_val_if_fail (PK_IS_SERVICE_PACK (pack), FALSE);
-	g_return_val_if_fail (package_id != NULL, FALSE);
+	g_return_val_if_fail (package_ids != NULL, FALSE);
 	g_return_val_if_fail (pack->priv->filename != NULL, FALSE);
 	g_return_val_if_fail (pack->priv->directory != NULL, FALSE);
 
 	/* download this package */
-	package_ids = pk_package_ids_from_id (package_id);
 	ret = pk_service_pack_download_package_ids (pack, package_ids);
-	g_strfreev (package_ids);
 	if (!ret) {
 		*error = g_error_new (1, 0, "failed to download main package: %s", error_local->message);
 		g_error_free (error_local);
@@ -596,7 +594,7 @@ pk_service_pack_create_for_package_id (PkServicePack *pack, const gchar *package
 		goto out;
 	}
 
-	egg_debug ("Getting depends for %s", package_id);
+	egg_debug ("Getting depends for %s", package_ids[0]);
 	ret = pk_client_get_depends (pack->priv->client, PK_FILTER_ENUM_NONE, package_ids, TRUE, &error_local);
 	if (!ret) {
 		*error = g_error_new (1, 0, "failed to get depends: %s", error_local->message);
@@ -622,19 +620,17 @@ pk_service_pack_create_for_package_id (PkServicePack *pack, const gchar *package
 	/* confirm we want the deps */
 	if (length != 0) {
 		/* download additional package_ids */
-		package_ids = pk_package_list_to_strv (list);
-		ret = pk_service_pack_download_package_ids (pack, package_ids);
-		g_strfreev (package_ids);
+		package_ids_deps = pk_package_list_to_strv (list);
+		ret = pk_service_pack_download_package_ids (pack, package_ids_deps);
+		g_strfreev (package_ids_deps);
 
 		/* failed to get deps */
 		if (!ret) {
-			*error = g_error_new (1, 0, "xxxxxxxxxxxxxxxxxx: %s", error_local->message);
-			egg_warning ("failed to download deps of package: %s", package_id);
+			*error = g_error_new (1, 0, "failed to download deps of package: %s", package_ids[0]);
 			goto out;
 		}
 	}
 
-
 	/* find packages that were downloaded */
 	file_array = pk_service_pack_scan_files_in_directory (pack);
 	if (file_array == NULL) {
@@ -661,6 +657,26 @@ out:
 }
 
 /**
+ * pk_service_pack_create_for_package_id:
+ **/
+gboolean
+pk_service_pack_create_for_package_id (PkServicePack *pack, const gchar *package_id, GError **error)
+{
+	gchar **package_ids;
+	gboolean ret;
+
+	g_return_val_if_fail (PK_IS_SERVICE_PACK (pack), FALSE);
+	g_return_val_if_fail (package_id != NULL, FALSE);
+	g_return_val_if_fail (pack->priv->filename != NULL, FALSE);
+	g_return_val_if_fail (pack->priv->directory != NULL, FALSE);
+
+	package_ids = pk_package_ids_from_id (package_id);
+	ret = pk_service_pack_create_for_package_ids (pack, package_ids, error);
+	g_strfreev (package_ids);
+	return ret;
+}
+
+/**
  * pk_service_pack_create_for_updates:
  **/
 gboolean
diff --git a/src/pk-service-pack.h b/src/pk-service-pack.h
index 3d497be..328e858 100644
--- a/src/pk-service-pack.h
+++ b/src/pk-service-pack.h
@@ -65,6 +65,9 @@ gboolean	 pk_service_pack_set_exclude_list		(PkServicePack	*pack,
 gboolean	 pk_service_pack_create_for_package_id		(PkServicePack	*pack,
 								 const gchar	*package_id,
 								 GError		**error);
+gboolean	 pk_service_pack_create_for_package_ids		(PkServicePack	*pack,
+								 gchar		**package_ids,
+								 GError		**error);
 gboolean	 pk_service_pack_create_for_updates		(PkServicePack	*pack,
 								 GError		**error);
 
commit 18d408c0165e45521b5a7ced588637586637fb3b
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 8 12:37:18 2008 +0100

    trivial: rename base filename and re-instate copyright

diff --git a/client/Makefile.am b/client/Makefile.am
index f839134..77482f8 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -68,7 +68,7 @@ pkgenpack_SOURCES =					\
 	egg-debug.h					\
 	egg-string.c					\
 	egg-string.h					\
-	pk-generate-pack-main.c				\
+	pk-generate-pack.c				\
 	pk-service-pack.c				\
 	pk-service-pack.h				\
 	pk-tools-common.c				\
@@ -111,9 +111,6 @@ pk_self_test_SOURCES =					\
 	egg-test.c					\
 	egg-test.h					\
 	pk-self-test.c					\
-	pk-generate-pack.c				\
-	pk-tools-common.c				\
-	pk-tools-common.h				\
 	$(shared_SOURCES)				\
 	$(NULL)
 
diff --git a/client/pk-generate-pack-main.c b/client/pk-generate-pack-main.c
deleted file mode 100644
index 28573b3..0000000
--- a/client/pk-generate-pack-main.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/* -*- 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 Shishir Goel <crazyontheedge at gmail.com>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <glib/gstdio.h>
-
-#include "egg-debug.h"
-
-#include <pk-client.h>
-#include <pk-control.h>
-#include <pk-common.h>
-#include <pk-package-list.h>
-#include <pk-package-id.h>
-#include <pk-package-ids.h>
-#include <pk-client.h>
-
-#include "pk-tools-common.h"
-#include "pk-service-pack.h"
-
-/**
- * pk_generate_pack_get_filename:
- **/
-static gchar *
-pk_generate_pack_get_filename (const gchar *name, const gchar *directory)
-{
-	gchar *filename = NULL;
-	gchar *distro_id;
-	gchar *iso_time = NULL;
-
-	distro_id = pk_get_distro_id ();
-	if (name != NULL) {
-		filename = g_strdup_printf ("%s/%s-%s.servicepack", directory, name, distro_id);
-	} else {
-		iso_time = pk_iso8601_present ();
-		filename = g_strdup_printf ("%s/updates-%s-%s.servicepack", directory, iso_time, distro_id);
-	}
-	g_free (distro_id);
-	g_free (iso_time);
-	return filename;
-}
-
-/**
- * pk_generate_pack_package_resolve:
- **/
-static gchar *
-pk_generate_pack_package_resolve (PkClient *client, PkBitfield filter, const gchar *package, GError **error)
-{
-	gboolean ret;
-	gboolean valid;
-	guint i;
-	guint length;
-	const PkPackageObj *obj;
-	PkPackageList *list;
-	gchar **packages;
-
-	/* check for NULL values */
-	if (package == NULL) {
-		egg_warning ("Cannot resolve the package: invalid package");
-		return NULL;
-	}
-
-	/* have we passed a complete package_id? */
-	valid = pk_package_id_check (package);
-	if (valid)
-		return g_strdup (package);
-
-	ret = pk_client_reset (client, error);
-	if (ret == FALSE) {
-		egg_warning ("failed to reset client task");
-		return NULL;
-	}
-
-	/* we need to resolve it */
-	packages = pk_package_ids_from_id (package);
-	ret = pk_client_resolve (client, filter, packages, error);
-	g_strfreev (packages);
-	if (ret == FALSE) {
-		egg_warning ("Resolve failed");
-		return NULL;
-	}
-
-	/* get length of items found */
-	list = pk_client_get_package_list (client);
-	length = pk_package_list_get_size (list);
-	g_object_unref (list);
-
-	/* didn't resolve to anything, try to get a provide */
-	if (length == 0) {
-		ret = pk_client_reset (client, error);
-		if (ret == FALSE) {
-			egg_warning ("failed to reset client task");
-			return NULL;
-		}
-		ret = pk_client_what_provides (client, filter, PK_PROVIDES_ENUM_ANY, package, error);
-		if (ret == FALSE) {
-			egg_warning ("WhatProvides is not supported in this backend");
-			return NULL;
-		}
-	}
-
-	/* get length of items found again (we might have had success) */
-	list = pk_client_get_package_list (client);
-	length = pk_package_list_get_size (list);
-	if (length == 0) {
-		egg_warning (_("Could not find a package match"));
-		return NULL;
-	}
-
-	/* only found one, great! */
-	if (length == 1) {
-		obj = pk_package_list_get_obj (list, 0);
-		return pk_package_id_to_string (obj->id);
-	}
-	g_print ("%s\n", _("There are multiple package matches"));
-	for (i=0; i<length; i++) {
-		obj = pk_package_list_get_obj (list, i);
-		g_print ("%i. %s-%s.%s\n", i+1, obj->id->name, obj->id->version, obj->id->arch);
-	}
-
-	/* find out what package the user wants to use */
-	i = pk_console_get_number (_("Please enter the package number: "), length);
-	obj = pk_package_list_get_obj (list, i-1);
-	g_object_unref (list);
-
-	return pk_package_id_to_string (obj->id);
-}
-
-int
-main (int argc, char *argv[])
-{
-	GError *error = NULL;
-	GOptionContext *context;
-	gchar *options_help;
-	gboolean ret;
-	guint retval;
-	gchar *filename = NULL;
-	PkControl *control = NULL;
-	PkBitfield roles;
-	gchar *tempdir = NULL;
-	gboolean exists;
-	gboolean overwrite;
-	PkServicePack *pack = NULL;
-	PkPackageList *list = NULL;
-	PkClient *client = NULL;
-	gchar *package_id = NULL;
-
-	gboolean verbose = FALSE;
-	gchar *directory = NULL;
-	gchar *package_list = NULL;
-	gchar *package = NULL;
-	gboolean updates = FALSE;
-
-	const GOptionEntry options[] = {
-		{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
-			_("Show extra debugging information"), NULL },
-		{ "with-package-list", 'l', 0, G_OPTION_ARG_STRING, &package_list,
-			_("Set the path of the file with the list of packages/dependencies to be excluded"), NULL},
-		{ "output", 'o', 0, G_OPTION_ARG_STRING, &directory,
-			_("The directory to put the pack file, or the current directory if ommitted"), NULL},
-		{ "package", 'p', 0, G_OPTION_ARG_STRING, &package,
-			_("The package to be put into the ServicePack"), NULL},
-		{ "updates", 'u', 0, G_OPTION_ARG_NONE, &updates,
-			_("Put all updates available in the ServicePack"), NULL},
-		{ NULL}
-	};
-
-	if (! g_thread_supported ())
-		g_thread_init (NULL);
-
-	g_type_init ();
-
-	context = g_option_context_new ("PackageKit Pack Generator");
-	g_option_context_add_main_entries (context, options, NULL);
-	g_option_context_parse (context, &argc, &argv, NULL);
-	/* Save the usage string in case command parsing fails. */
-	options_help = g_option_context_get_help (context, TRUE, NULL);
-	g_option_context_free (context);
-	egg_debug_init (verbose);
-
-	/* neither options selected */
-	if (package == NULL && !updates) {
-		g_print ("%s\n", _("Neither option selected"));
-		g_print ("%s", options_help);
-		return 1;
-	}
-
-	/* both options selected */
-	if (package != NULL && updates) {
-		g_print ("%s\n", _("Both optiosn selected"));
-		g_print ("%s", options_help);
-		return 1;
-	}
-
-	/* fall back to the system copy */
-	if (package_list == NULL)
-		package_list = g_strdup ("/var/lib/PackageKit/package-list.txt");
-
-	/* fall back to CWD */
-	if (directory == NULL)
-		directory = g_get_current_dir ();
-
-	/* are we dumb and can't check for depends? */
-	control = pk_control_new ();
-	roles = pk_control_get_actions (control, NULL);
-	if (!pk_bitfield_contain (roles, PK_ROLE_ENUM_GET_DEPENDS)) {
-		g_print ("Please use a backend that supports GetDepends!\n");
-		goto out;
-	}
-
-	/* get fn */
-	filename = pk_generate_pack_get_filename (package, directory);
-
-	/* download packages to a temporary directory */
-	tempdir = g_build_filename (g_get_tmp_dir (), "pack", NULL);
-
-	/* check if file exists before we overwrite it */
-	exists = g_file_test (filename, G_FILE_TEST_EXISTS);
-
-	/*ask user input*/
-	if (exists) {
-		overwrite = pk_console_get_prompt (_("A pack with the same name already exists, do you want to overwrite it?"), FALSE);
-		if (!overwrite) {
-			g_print ("%s\n", _("Cancelled!"));
-			goto out;
-		}
-	}
-
-	/* get rid of temp directory if it already exists */
-	g_rmdir (tempdir);
-
-	/* make the temporary directory */
-	retval = g_mkdir_with_parents (tempdir, 0777);
-	if (retval != 0) {
-		g_print ("%s: %s\n", _("Failed to create directory"), tempdir);
-		goto out;
-	}
-
-	/* get the exclude list */
-	list = pk_package_list_new ();
-	ret = pk_package_list_add_file (list, package_list);
-	if (!ret) {
-		g_print ("%s: %s\n", _("Failed to open package list"), package_list);
-		goto out;
-	}
-
-	/* resolve package name to package_id */
-	if (!updates) {
-		client = pk_client_new ();
-		pk_client_set_use_buffer (client, TRUE, NULL);
-		pk_client_set_synchronous (client, TRUE, NULL);
-		g_print ("%s\n", _("Resolving package name to remote object"));
-		package_id = pk_generate_pack_package_resolve (client, PK_FILTER_ENUM_NONE, package, &error);
-		if (package_id == NULL) {
-			g_print (_("Failed to find package '%s': %s"), package, error->message);
-			g_error_free (error);
-			goto out;
-		}
-	}
-
-	/* create pack and set initial values */
-	pack = pk_service_pack_new ();
-	pk_service_pack_set_filename (pack, filename);
-	pk_service_pack_set_temp_directory (pack, tempdir);
-	pk_service_pack_set_exclude_list (pack, list);
-
-	/* generate the pack */
-	g_print (_("Creating service pack: %s\n"), filename);
-	if (updates)
-		ret = pk_service_pack_create_for_updates (pack, &error);
-	else
-		ret = pk_service_pack_create_for_package_id (pack, package_id, &error);
-	g_print ("%s\n", _("Done!"));
-
-out:
-	/* get rid of temp directory */
-	g_rmdir (tempdir);
-
-	if (pack != NULL)
-		g_object_unref (pack);
-	if (client != NULL)
-		g_object_unref (client);
-	if (list != NULL)
-		g_object_unref (list);
-	g_free (tempdir);
-	g_free (filename);
-	g_free (package_id);
-	g_free (directory);
-	g_free (package_list);
-	g_free (options_help);
-	g_object_unref (control);
-	return 0;
-}
diff --git a/client/pk-generate-pack.c b/client/pk-generate-pack.c
new file mode 100644
index 0000000..28573b3
--- /dev/null
+++ b/client/pk-generate-pack.c
@@ -0,0 +1,314 @@
+/* -*- 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 Shishir Goel <crazyontheedge at gmail.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+
+#include "egg-debug.h"
+
+#include <pk-client.h>
+#include <pk-control.h>
+#include <pk-common.h>
+#include <pk-package-list.h>
+#include <pk-package-id.h>
+#include <pk-package-ids.h>
+#include <pk-client.h>
+
+#include "pk-tools-common.h"
+#include "pk-service-pack.h"
+
+/**
+ * pk_generate_pack_get_filename:
+ **/
+static gchar *
+pk_generate_pack_get_filename (const gchar *name, const gchar *directory)
+{
+	gchar *filename = NULL;
+	gchar *distro_id;
+	gchar *iso_time = NULL;
+
+	distro_id = pk_get_distro_id ();
+	if (name != NULL) {
+		filename = g_strdup_printf ("%s/%s-%s.servicepack", directory, name, distro_id);
+	} else {
+		iso_time = pk_iso8601_present ();
+		filename = g_strdup_printf ("%s/updates-%s-%s.servicepack", directory, iso_time, distro_id);
+	}
+	g_free (distro_id);
+	g_free (iso_time);
+	return filename;
+}
+
+/**
+ * pk_generate_pack_package_resolve:
+ **/
+static gchar *
+pk_generate_pack_package_resolve (PkClient *client, PkBitfield filter, const gchar *package, GError **error)
+{
+	gboolean ret;
+	gboolean valid;
+	guint i;
+	guint length;
+	const PkPackageObj *obj;
+	PkPackageList *list;
+	gchar **packages;
+
+	/* check for NULL values */
+	if (package == NULL) {
+		egg_warning ("Cannot resolve the package: invalid package");
+		return NULL;
+	}
+
+	/* have we passed a complete package_id? */
+	valid = pk_package_id_check (package);
+	if (valid)
+		return g_strdup (package);
+
+	ret = pk_client_reset (client, error);
+	if (ret == FALSE) {
+		egg_warning ("failed to reset client task");
+		return NULL;
+	}
+
+	/* we need to resolve it */
+	packages = pk_package_ids_from_id (package);
+	ret = pk_client_resolve (client, filter, packages, error);
+	g_strfreev (packages);
+	if (ret == FALSE) {
+		egg_warning ("Resolve failed");
+		return NULL;
+	}
+
+	/* get length of items found */
+	list = pk_client_get_package_list (client);
+	length = pk_package_list_get_size (list);
+	g_object_unref (list);
+
+	/* didn't resolve to anything, try to get a provide */
+	if (length == 0) {
+		ret = pk_client_reset (client, error);
+		if (ret == FALSE) {
+			egg_warning ("failed to reset client task");
+			return NULL;
+		}
+		ret = pk_client_what_provides (client, filter, PK_PROVIDES_ENUM_ANY, package, error);
+		if (ret == FALSE) {
+			egg_warning ("WhatProvides is not supported in this backend");
+			return NULL;
+		}
+	}
+
+	/* get length of items found again (we might have had success) */
+	list = pk_client_get_package_list (client);
+	length = pk_package_list_get_size (list);
+	if (length == 0) {
+		egg_warning (_("Could not find a package match"));
+		return NULL;
+	}
+
+	/* only found one, great! */
+	if (length == 1) {
+		obj = pk_package_list_get_obj (list, 0);
+		return pk_package_id_to_string (obj->id);
+	}
+	g_print ("%s\n", _("There are multiple package matches"));
+	for (i=0; i<length; i++) {
+		obj = pk_package_list_get_obj (list, i);
+		g_print ("%i. %s-%s.%s\n", i+1, obj->id->name, obj->id->version, obj->id->arch);
+	}
+
+	/* find out what package the user wants to use */
+	i = pk_console_get_number (_("Please enter the package number: "), length);
+	obj = pk_package_list_get_obj (list, i-1);
+	g_object_unref (list);
+
+	return pk_package_id_to_string (obj->id);
+}
+
+int
+main (int argc, char *argv[])
+{
+	GError *error = NULL;
+	GOptionContext *context;
+	gchar *options_help;
+	gboolean ret;
+	guint retval;
+	gchar *filename = NULL;
+	PkControl *control = NULL;
+	PkBitfield roles;
+	gchar *tempdir = NULL;
+	gboolean exists;
+	gboolean overwrite;
+	PkServicePack *pack = NULL;
+	PkPackageList *list = NULL;
+	PkClient *client = NULL;
+	gchar *package_id = NULL;
+
+	gboolean verbose = FALSE;
+	gchar *directory = NULL;
+	gchar *package_list = NULL;
+	gchar *package = NULL;
+	gboolean updates = FALSE;
+
+	const GOptionEntry options[] = {
+		{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
+			_("Show extra debugging information"), NULL },
+		{ "with-package-list", 'l', 0, G_OPTION_ARG_STRING, &package_list,
+			_("Set the path of the file with the list of packages/dependencies to be excluded"), NULL},
+		{ "output", 'o', 0, G_OPTION_ARG_STRING, &directory,
+			_("The directory to put the pack file, or the current directory if ommitted"), NULL},
+		{ "package", 'p', 0, G_OPTION_ARG_STRING, &package,
+			_("The package to be put into the ServicePack"), NULL},
+		{ "updates", 'u', 0, G_OPTION_ARG_NONE, &updates,
+			_("Put all updates available in the ServicePack"), NULL},
+		{ NULL}
+	};
+
+	if (! g_thread_supported ())
+		g_thread_init (NULL);
+
+	g_type_init ();
+
+	context = g_option_context_new ("PackageKit Pack Generator");
+	g_option_context_add_main_entries (context, options, NULL);
+	g_option_context_parse (context, &argc, &argv, NULL);
+	/* Save the usage string in case command parsing fails. */
+	options_help = g_option_context_get_help (context, TRUE, NULL);
+	g_option_context_free (context);
+	egg_debug_init (verbose);
+
+	/* neither options selected */
+	if (package == NULL && !updates) {
+		g_print ("%s\n", _("Neither option selected"));
+		g_print ("%s", options_help);
+		return 1;
+	}
+
+	/* both options selected */
+	if (package != NULL && updates) {
+		g_print ("%s\n", _("Both optiosn selected"));
+		g_print ("%s", options_help);
+		return 1;
+	}
+
+	/* fall back to the system copy */
+	if (package_list == NULL)
+		package_list = g_strdup ("/var/lib/PackageKit/package-list.txt");
+
+	/* fall back to CWD */
+	if (directory == NULL)
+		directory = g_get_current_dir ();
+
+	/* are we dumb and can't check for depends? */
+	control = pk_control_new ();
+	roles = pk_control_get_actions (control, NULL);
+	if (!pk_bitfield_contain (roles, PK_ROLE_ENUM_GET_DEPENDS)) {
+		g_print ("Please use a backend that supports GetDepends!\n");
+		goto out;
+	}
+
+	/* get fn */
+	filename = pk_generate_pack_get_filename (package, directory);
+
+	/* download packages to a temporary directory */
+	tempdir = g_build_filename (g_get_tmp_dir (), "pack", NULL);
+
+	/* check if file exists before we overwrite it */
+	exists = g_file_test (filename, G_FILE_TEST_EXISTS);
+
+	/*ask user input*/
+	if (exists) {
+		overwrite = pk_console_get_prompt (_("A pack with the same name already exists, do you want to overwrite it?"), FALSE);
+		if (!overwrite) {
+			g_print ("%s\n", _("Cancelled!"));
+			goto out;
+		}
+	}
+
+	/* get rid of temp directory if it already exists */
+	g_rmdir (tempdir);
+
+	/* make the temporary directory */
+	retval = g_mkdir_with_parents (tempdir, 0777);
+	if (retval != 0) {
+		g_print ("%s: %s\n", _("Failed to create directory"), tempdir);
+		goto out;
+	}
+
+	/* get the exclude list */
+	list = pk_package_list_new ();
+	ret = pk_package_list_add_file (list, package_list);
+	if (!ret) {
+		g_print ("%s: %s\n", _("Failed to open package list"), package_list);
+		goto out;
+	}
+
+	/* resolve package name to package_id */
+	if (!updates) {
+		client = pk_client_new ();
+		pk_client_set_use_buffer (client, TRUE, NULL);
+		pk_client_set_synchronous (client, TRUE, NULL);
+		g_print ("%s\n", _("Resolving package name to remote object"));
+		package_id = pk_generate_pack_package_resolve (client, PK_FILTER_ENUM_NONE, package, &error);
+		if (package_id == NULL) {
+			g_print (_("Failed to find package '%s': %s"), package, error->message);
+			g_error_free (error);
+			goto out;
+		}
+	}
+
+	/* create pack and set initial values */
+	pack = pk_service_pack_new ();
+	pk_service_pack_set_filename (pack, filename);
+	pk_service_pack_set_temp_directory (pack, tempdir);
+	pk_service_pack_set_exclude_list (pack, list);
+
+	/* generate the pack */
+	g_print (_("Creating service pack: %s\n"), filename);
+	if (updates)
+		ret = pk_service_pack_create_for_updates (pack, &error);
+	else
+		ret = pk_service_pack_create_for_package_id (pack, package_id, &error);
+	g_print ("%s\n", _("Done!"));
+
+out:
+	/* get rid of temp directory */
+	g_rmdir (tempdir);
+
+	if (pack != NULL)
+		g_object_unref (pack);
+	if (client != NULL)
+		g_object_unref (client);
+	if (list != NULL)
+		g_object_unref (list);
+	g_free (tempdir);
+	g_free (filename);
+	g_free (package_id);
+	g_free (directory);
+	g_free (package_list);
+	g_free (options_help);
+	g_object_unref (control);
+	return 0;
+}
diff --git a/client/pk-self-test.c b/client/pk-self-test.c
index e8da773..eba7cc5 100644
--- a/client/pk-self-test.c
+++ b/client/pk-self-test.c
@@ -40,7 +40,7 @@ main (int argc, char **argv)
 	egg_debug_init (TRUE);
 
 	/* tests go here */
-	pk_genpack_test (test);
+	//pk_genpack_test (test);
 	
 	return (egg_test_finish (test));
 }
diff --git a/po/POTFILES.in b/po/POTFILES.in
index b8c490e..92468c7 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -2,7 +2,7 @@
 # List of source files containing translatable strings.
 # Please keep this file sorted alphabetically.
 client/pk-console.c
-client/pk-generate-pack-main.c
+client/pk-generate-pack.c
 client/pk-import-specspo.c
 client/pk-monitor.c
 client/pk-tools-common.c
diff --git a/src/pk-service-pack.c b/src/pk-service-pack.c
index 3f47439..abe0d71 100644
--- a/src/pk-service-pack.c
+++ b/src/pk-service-pack.c
@@ -1,6 +1,7 @@
 /* -*- 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 Shishir Goel <crazyontheedge at gmail.com>
  *
  * Licensed under the GNU General Public License Version 2
  *
commit de9be373b5de61d88f8790a09056dbb53e1d0e69
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 8 12:34:48 2008 +0100

    trivial: remove onsolete file

diff --git a/client/Makefile.am b/client/Makefile.am
index bc79b07..f839134 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -69,8 +69,6 @@ pkgenpack_SOURCES =					\
 	egg-string.c					\
 	egg-string.h					\
 	pk-generate-pack-main.c				\
-	pk-generate-pack.c				\
-	pk-generate-pack.h				\
 	pk-service-pack.c				\
 	pk-service-pack.h				\
 	pk-tools-common.c				\
diff --git a/client/pk-generate-pack-main.c b/client/pk-generate-pack-main.c
index 30fe571..28573b3 100644
--- a/client/pk-generate-pack-main.c
+++ b/client/pk-generate-pack-main.c
@@ -37,7 +37,6 @@
 #include <pk-client.h>
 
 #include "pk-tools-common.h"
-#include "pk-generate-pack.h"
 #include "pk-service-pack.h"
 
 /**
@@ -292,14 +291,6 @@ main (int argc, char *argv[])
 		ret = pk_service_pack_create_for_updates (pack, &error);
 	else
 		ret = pk_service_pack_create_for_package_id (pack, package_id, &error);
-
-	/* old method */
-	ret = pk_service_pack_main (filename, tempdir, package_id, list, &error);
-	if (!ret) {
-		g_print ("%s: %s\n", _("Failed to create pack"), error->message);
-		g_error_free (error);
-		goto out;
-	}
 	g_print ("%s\n", _("Done!"));
 
 out:
diff --git a/client/pk-generate-pack.c b/client/pk-generate-pack.c
deleted file mode 100644
index cc8180d..0000000
--- a/client/pk-generate-pack.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/* -*- 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 Shishir Goel <crazyontheedge at gmail.com>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <glib/gstdio.h>
-#include <dbus/dbus-glib.h>
-
-#include <pk-client.h>
-#include <pk-control.h>
-#include <pk-package-id.h>
-#include <pk-package-ids.h>
-#include <pk-common.h>
-#ifdef HAVE_ARCHIVE_H
-#include <archive.h>
-#include <archive_entry.h>
-#endif /* HAVE_ARCHIVE_H */
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <dirent.h>
-
-#include "egg-debug.h"
-#include "egg-string.h"
-
-#include "pk-tools-common.h"
-
-/**
- * pk_service_pack_main:
- **/
-gboolean
-pk_service_pack_main (const gchar *pack_filename, const gchar *directory, const gchar *package_id, PkPackageList *exclude_list, GError **error)
-{
-	return TRUE;
-}
-
-/***************************************************************************
- ***                          MAKE CHECK TESTS                           ***
- ***************************************************************************/
-#ifdef EGG_TEST
-#include "egg-test.h"
-
-void
-pk_genpack_test (EggTest *test)
-{
-	PkClient *client = NULL;
-	gboolean ret;
-	gboolean retval;
-	GError *error = NULL;
-	gchar *file;
-	PkPackageList *list = NULL;
-	GPtrArray *file_array = NULL;
-	gchar *src;
-	gchar **package_ids;
-
-	if (!egg_test_start (test, "PkGeneratePack"))
-		return;
-
-	/************************************************************/
-	egg_test_title (test, "get client");
-	client = pk_client_new ();
-	if (client != NULL)
-		egg_test_success (test, NULL);
-	else
-		egg_test_failed (test, NULL);
-
-	/************************************************************/
-	egg_test_title (test, "download only NULL");
-	ret = pk_service_pack_download_package_ids (client, NULL, NULL);
-	if (!ret)
-		egg_test_success (test, NULL);
-	else
-		egg_test_failed (test, NULL);
-
-	/************************************************************/
-	egg_test_title (test, "download only gitk");
-	package_ids = pk_package_ids_from_id ("gitk;1.5.5.1-1.fc9;i386;installed");
-	ret = pk_service_pack_download_package_ids (client, package_ids, "/tmp");
-	if (ret)
-		egg_test_success (test, NULL);
-	else
-		egg_test_failed (test, NULL);
-	g_strfreev (package_ids);
-	g_object_unref (client);
-
-	/************************************************************/
-	egg_test_title (test, "metadata NULL");
-	ret = pk_service_pack_create_from_files_metadata_file (NULL);
-	if (!ret)
-		egg_test_success (test, NULL);
-	else
-		egg_test_failed (test, NULL);
-
-	/************************************************************/
-	egg_test_title (test, "metadata /tmp/metadata.conf");
-	ret = pk_service_pack_create_from_files_metadata_file ("/tmp/metadata.conf");
-	if (ret)
-		egg_test_success (test, NULL);
-	else
-		egg_test_failed (test, NULL);
-	g_remove ("/tmp/metadata.conf");
-
-	/************************************************************/
-	egg_test_title (test, "scandir NULL");
-	file_array = pk_service_pack_scan_files_in_directory (NULL);
-	if (file_array == NULL)
-		egg_test_success (test, NULL);
-	else
-		egg_test_failed (test, NULL);
-
-	/************************************************************/
-	egg_test_title (test, "scandir /tmp");
-	file_array = pk_service_pack_scan_files_in_directory ("/tmp");
-	if (file_array != NULL)
-		egg_test_success (test, NULL);
-	else
-		egg_test_failed (test, NULL);
-
-	/************************************************************/
-	egg_test_title (test, "generate pack /tmp/gitk.servicepack gitk");
-	file_array = g_ptr_array_new ();
-	src = g_build_filename ("/tmp", "gitk-1.5.5.1-1.fc9.i386.rpm", NULL);
-	g_ptr_array_add (file_array, src);
-	ret = pk_service_pack_create_from_files ("/tmp/gitk.servicepack", file_array, &error);
-	if (!ret) {
-		if (error != NULL) {
-			egg_test_failed (test, "failed to create pack %s" , error->message);
-			g_error_free (error);
-		} else {
-			egg_test_failed (test, "could not set error");
-		}
-	} else
-		egg_test_success (test, NULL);
-
-	if (file_array != NULL) {
-		g_ptr_array_foreach (file_array, (GFunc) g_free, NULL);
-		g_ptr_array_free (file_array, TRUE);
-	}
-	g_remove ("/tmp/gitk.servicepack");
-
-	/************************************************************/
-	egg_test_end (test);
-}
-#endif
diff --git a/client/pk-generate-pack.h b/client/pk-generate-pack.h
deleted file mode 100644
index 320918f..0000000
--- a/client/pk-generate-pack.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* -*- 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 Shishir Goel <crazyontheedge at gmail.com>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __PK_GENERATE_PACK_H
-#define __PK_GENERATE_PACK_H
-
-gboolean	 pk_service_pack_main				(const gchar *pack_filename,
-								 const gchar *directory,
-								 const gchar *package_id,
-								 PkPackageList *exclude_list,
-								 GError **error);
-
-#endif /* __PK_GENERATE_PACK_H */
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 9d00eb7..b8c490e 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -2,7 +2,6 @@
 # List of source files containing translatable strings.
 # Please keep this file sorted alphabetically.
 client/pk-console.c
-client/pk-generate-pack.c
 client/pk-generate-pack-main.c
 client/pk-import-specspo.c
 client/pk-monitor.c
commit 475d6f04d54286f0bc78af6574eee864fc90cd66
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 8 12:33:10 2008 +0100

    trivial: remove a lot of the unstructured code in pk-generate-pack and more it into pk-service-pack.c

diff --git a/client/pk-generate-pack-main.c b/client/pk-generate-pack-main.c
index da616c0..30fe571 100644
--- a/client/pk-generate-pack-main.c
+++ b/client/pk-generate-pack-main.c
@@ -22,14 +22,9 @@
 
 #include "config.h"
 
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <glib/gstdio.h>
-#include <dbus/dbus-glib.h>
 
 #include "egg-debug.h"
 
@@ -195,7 +190,6 @@ main (int argc, char *argv[])
 	if (! g_thread_supported ())
 		g_thread_init (NULL);
 
-	dbus_g_thread_init ();
 	g_type_init ();
 
 	context = g_option_context_new ("PackageKit Pack Generator");
@@ -264,12 +258,6 @@ main (int argc, char *argv[])
 		goto out;
 	}
 
-	/* not yet */
-	if (updates) {
-		g_print ("Not working yet...\n");
-		return 1;
-	}
-
 	/* get the exclude list */
 	list = pk_package_list_new ();
 	ret = pk_package_list_add_file (list, package_list);
diff --git a/client/pk-generate-pack.c b/client/pk-generate-pack.c
index 5285a0f..cc8180d 100644
--- a/client/pk-generate-pack.c
+++ b/client/pk-generate-pack.c
@@ -50,391 +50,12 @@
 #include "pk-tools-common.h"
 
 /**
- * pk_service_pack_download_package_ids:
- **/
-static gboolean
-pk_service_pack_download_package_ids (PkClient *client, gchar **package_ids, const gchar *directory)
-{
-	gboolean ret;
-	GError *error = NULL;
-
-	/* check for NULL values */
-	if (package_ids == NULL || directory == NULL) {
-		egg_warning (_("failed to download: invalid package_id and/or directory"));
-		ret = FALSE;
-		goto out;
-	}
-
-	egg_debug ("download+ %s %s", package_ids[0], directory);
-	ret = pk_client_reset (client, &error);
-	if (!ret) {
-		egg_warning ("failed to download: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-	ret = pk_client_download_packages (client, package_ids, directory, &error);
-	if (!ret) {
-		egg_warning ("failed to download: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-out:
-	return ret;
-}
-
-/**
- * pk_service_pack_exclude_packages:
- **/
-static gboolean
-pk_service_pack_exclude_packages (PkPackageList *list, PkPackageList *list_packages)
-{
-	guint i;
-	guint length;
-	gboolean found;
-	const PkPackageObj *obj;
-
-	/* do not just download everything, uselessly */
-	length = pk_package_list_get_size (list_packages);
-	for (i=0; i<length; i++) {
-		obj = pk_package_list_get_obj (list_packages, i);
-		/* will just ignore if the obj is not there */
-		found = pk_package_list_remove_obj (list, obj);
-		if (found)
-			egg_debug ("removed %s", obj->id->name);
-	}
-	return TRUE;
-}
-
-/**
- * pk_service_pack_create_from_files_metadata_file:
- **/
-static gboolean
-pk_service_pack_create_from_files_metadata_file (const gchar *filename)
-{
-	gboolean ret = FALSE;
-	gchar *distro_id = NULL;
-	gchar *iso_time = NULL;
-	GError *error = NULL;
-	GKeyFile *file = NULL;
-	gchar *data = NULL;
-
-	file = g_key_file_new ();
-
-	/* check for NULL values */
-	if (filename == NULL) {
-		egg_warning (_("Could not find a valid metadata file"));
-		goto out;
-	}
-
-	/* get needed data */
-	distro_id = pk_get_distro_id ();
-	if (distro_id == NULL)
-		goto out;
-	iso_time = pk_iso8601_present ();
-	if (iso_time == NULL)
-		goto out;
-
-	g_key_file_set_string (file, PK_SERVICE_PACK_GROUP_NAME, "distro_id", distro_id);
-	g_key_file_set_string (file, PK_SERVICE_PACK_GROUP_NAME, "created", iso_time);
-
-	/* convert to text */
-	data = g_key_file_to_data (file, NULL, &error);
-	if (data == NULL) {
-		egg_warning ("failed to convert to text: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-	/* save contents */
-	ret = g_file_set_contents (filename, data, -1, &error);
-	if (!ret) {
-		egg_warning ("failed to save file: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-out:
-	g_key_file_free (file);
-	g_free (data);
-	g_free (distro_id);
-	g_free (iso_time);
-	return ret;
-}
-
-#ifdef HAVE_ARCHIVE_H
-/**
- * pk_service_pack_archive_add_file:
- **/
-static gboolean
-pk_service_pack_archive_add_file (struct archive *arch, const gchar *filename, GError **error)
-{
-	int retval;
-	int len;
-	int fd = -1;
-	int wrote;
-	gboolean ret = FALSE;
-	gchar *filename_basename = NULL;
-	struct archive_entry *entry = NULL;
-	struct stat st;
-	gchar buff[8192];
-
-	/* stat file */
-	retval = stat (filename, &st);
-	if (retval != 0) {
-		*error = g_error_new (1, 0, "file not found %s", filename);
-		goto out;
-	}
-	egg_debug ("stat(%s), size=%lu bytes\n", filename, st.st_size);
-
-	/* create new entry */
-	entry = archive_entry_new ();
-	archive_entry_copy_stat (entry, &st);
-	filename_basename = g_path_get_basename (filename);
-	archive_entry_set_pathname (entry, filename_basename);
-
-	/* ._BIG FAT BUG_. We should not have to do this, as it should be
-	 * set from archive_entry_copy_stat() */
-	archive_entry_set_size (entry, st.st_size);
-
-	/* write header */
-	retval = archive_write_header (arch, entry);
-	if (retval != ARCHIVE_OK) {
-		*error = g_error_new (1, 0, "failed to write header: %s\n", archive_error_string (arch));
-		goto out;
-	}
-
-	/* open file to copy */
-	fd = open (filename, O_RDONLY);
-	if (fd < 0) {
-		*error = g_error_new (1, 0, "failed to get fd for %s", filename);
-		goto out;
-	}
-
-	/* ITS4: ignore, buffer statically preallocated  */
-	len = read (fd, buff, sizeof (buff));
-	/* write data to archive -- how come no convenience function? */
-	while (len > 0) {
-		wrote = archive_write_data (arch, buff, len);
-		if (wrote != len)
-			egg_warning("wrote %i instead of %i\n", wrote, len);
-		/* ITS4: ignore, buffer statically preallocated  */
-		len = read (fd, buff, sizeof (buff));
-	}
-	ret = TRUE;
-out:
-	if (fd >= 0)
-		close (fd);
-	if (entry != NULL)
-		archive_entry_free (entry);
-	g_free (filename_basename);
-	return ret;
-}
-
-/**
- * pk_service_pack_create_from_files:
- **/
-static gboolean
-pk_service_pack_create_from_files (const gchar *filename, GPtrArray *file_array, GError **error)
-{
-	struct archive *arch = NULL;
-	gboolean ret = FALSE;
-	const gchar *src;
-	guint i;
-	gchar *metadata_filename;
-
-	g_return_val_if_fail (filename != NULL, FALSE);
-	g_return_val_if_fail (file_array != NULL, FALSE);
-	g_return_val_if_fail (error != NULL, FALSE);
-
-	/* create a file with metadata in it */
-	metadata_filename = g_build_filename (g_get_tmp_dir (), "metadata.conf", NULL);
-	ret = pk_service_pack_create_from_files_metadata_file (metadata_filename);
-	if (!ret) {
-	        *error = g_error_new (1, 0, "failed to generate metadata file %s", metadata_filename);
-	        goto out;
-	}
-	g_ptr_array_add (file_array, g_strdup (metadata_filename));
-
-	/* we can only write tar achives */
-	arch = archive_write_new ();
-	archive_write_set_compression_none (arch);
-	archive_write_set_format_ustar (arch);
-	archive_write_open_filename (arch, filename);
-
-	/* for each filename */
-	for (i=0; i<file_array->len; i++) {
-		src = (const gchar *) g_ptr_array_index (file_array, i);
-		/* try to add to archive */
-		ret = pk_service_pack_archive_add_file (arch, src, error);
-		if (!ret)
-			goto out;
-	}
-
-	/* completed all okay */
-	ret = TRUE;
-out:
-	g_free (metadata_filename);
-	/* delete each filename */
-	for (i=0; i<file_array->len; i++) {
-		src = (const gchar *) g_ptr_array_index (file_array, i);
-		g_remove (src);
-	}
-
-	/* close the archive */
-	if (arch != NULL) {
-		archive_write_close (arch);
-		archive_write_finish (arch);
-	}
-	return ret;
-}
-#else
-/**
- * pk_service_pack_create_from_files:
- **/
-static gboolean
-pk_service_pack_create_from_files (const gchar *filename, GPtrArray *file_array, GError **error)
-{
-	*error = g_error_new (1, 0, "Cannot create pack as PackageKit as not built with libarchive support");
-	return FALSE;
-}
-#endif
-
-/**
- * pk_service_pack_scan_files_in_directory:
- **/
-static GPtrArray *
-pk_service_pack_scan_files_in_directory (const gchar *directory)
-{
-	gchar *src;
-	GPtrArray *file_array = NULL;
-	GDir *dir;
-	const gchar *filename;
-
-	/* check for NULL values */
-	if (directory == NULL) {
-		egg_warning ("failed to get directory");
-		goto out;
-	}
-
-	/* try and open the directory */
-	dir = g_dir_open (directory, 0, NULL);
-	if (dir == NULL) {
-		egg_warning ("failed to get directory for %s", directory);
-		goto out;
-	}
-
-	/* add each file to an array */
-	file_array = g_ptr_array_new ();
-	while ((filename = g_dir_read_name (dir))) {
-		src = g_build_filename (directory, filename, NULL);
-		g_ptr_array_add (file_array, src);
-	}
-	g_dir_close (dir);
-out:
-	return file_array;
-}
-
-/**
  * pk_service_pack_main:
  **/
 gboolean
 pk_service_pack_main (const gchar *pack_filename, const gchar *directory, const gchar *package_id, PkPackageList *exclude_list, GError **error)
 {
-
-	gchar **package_ids;
-	PkPackageList *list = NULL;
-	guint length;
-	guint i;
-	const PkPackageObj *obj;
-	GPtrArray *file_array = NULL;
-	PkClient *client;
-	GError *error_local = NULL;
-	gboolean ret = FALSE;
-	gchar *text;
-
-	client = pk_client_new ();
-	pk_client_set_use_buffer (client, TRUE, NULL);
-	pk_client_set_synchronous (client, TRUE, NULL);
-
-	/* download this package */
-	package_ids = pk_package_ids_from_id (package_id);
-	ret = pk_service_pack_download_package_ids (client, package_ids, directory);
-	if (!ret) {
-		egg_warning ("failed to download main package: %s", error_local->message);
-		g_error_free (error_local);
-		goto out;
-	}
-
-	/* get depends */
-	ret = pk_client_reset (client, &error_local);
-	if (!ret) {
-		egg_warning ("failed to reset: %s", error_local->message);
-		g_error_free (error_local);
-		goto out;
-	}
-
-	egg_debug ("Getting depends for %s", package_id);
-	ret = pk_client_get_depends (client, PK_FILTER_ENUM_NONE, package_ids, TRUE, &error_local);
-	if (!ret) {
-		egg_warning ("failed to get depends: %s", error_local->message);
-		g_error_free (error_local);
-		goto out;
-	}
-	g_strfreev (package_ids);
-
-	/* get the deps */
-	list = pk_client_get_package_list (client);
-
-	/* remove some deps */
-	pk_service_pack_exclude_packages (list, exclude_list);
-
-	/* list deps */
-	length = pk_package_list_get_size (list);
-	for (i=0; i<length; i++) {
-		obj = pk_package_list_get_obj (list, i);
-		text = pk_package_obj_to_string (obj);
-		g_print ("%s\n", text);
-		g_free (text);
-	}
-
-	/* confirm we want the deps */
-	if (length != 0) {
-		/* download additional package_ids */
-		package_ids = pk_package_list_to_strv (list);
-		ret = pk_service_pack_download_package_ids (client, package_ids, directory);
-		g_strfreev (package_ids);
-	}
-
-	/* failed to get deps */
-	if (!ret) {
-		egg_warning ("failed to download deps of package: %s", package_id);
-		goto out;
-	}
-
-	/* find packages that were downloaded */
-	file_array = pk_service_pack_scan_files_in_directory (directory);
-	if (file_array == NULL) {
-		egg_warning ("failed to scan directory: %s", directory);
-		goto out;
-	}
-
-	/* generate pack file */
-	ret = pk_service_pack_create_from_files (pack_filename, file_array, &error_local);
-	if (!ret) {
-		egg_warning ("failed to create archive: %s", error_local->message);
-		g_error_free (error_local);
-		goto out;
-	}
-
-out:
-	g_object_unref (client);
-	if (list != NULL)
-		g_object_unref (list);
-	if (file_array != NULL) {
-		g_ptr_array_foreach (file_array, (GFunc) g_free, NULL);
-		g_ptr_array_free (file_array, TRUE);
-	}
-	return ret;
+	return TRUE;
 }
 
 /***************************************************************************
diff --git a/src/pk-service-pack.c b/src/pk-service-pack.c
index b9a4a6c..3f47439 100644
--- a/src/pk-service-pack.c
+++ b/src/pk-service-pack.c
@@ -23,6 +23,8 @@
 #  include <config.h>
 #endif
 
+#include <fcntl.h>
+
 #ifdef HAVE_ARCHIVE_H
 #include <archive.h>
 #include <archive_entry.h>
@@ -35,6 +37,8 @@
 #include "egg-string.h"
 
 #include <pk-common.h>
+#include <pk-client.h>
+#include <pk-package-ids.h>
 
 #include "pk-service-pack.h"
 
@@ -45,6 +49,7 @@ struct PkServicePackPrivate
 	PkPackageList		*exclude_list;
 	gchar			*filename;
 	gchar			*directory;
+	PkClient		*client;
 };
 
 G_DEFINE_TYPE (PkServicePack, pk_service_pack, G_TYPE_OBJECT)
@@ -273,16 +278,385 @@ pk_service_pack_set_exclude_list (PkServicePack *pack, PkPackageList *list)
 }
 
 /**
+ * pk_service_pack_download_package_ids:
+ **/
+static gboolean
+pk_service_pack_download_package_ids (PkServicePack *pack, gchar **package_ids)
+{
+	gboolean ret;
+	GError *error = NULL;
+
+	g_return_val_if_fail (PK_IS_SERVICE_PACK (pack), FALSE);
+	g_return_val_if_fail (package_ids != NULL, FALSE);
+	g_return_val_if_fail (pack->priv->directory != NULL, FALSE);
+
+	egg_debug ("download+ %s", package_ids[0]);
+	ret = pk_client_reset (pack->priv->client, &error);
+	if (!ret) {
+		egg_warning ("failed to download: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+	ret = pk_client_download_packages (pack->priv->client, package_ids, pack->priv->directory, &error);
+	if (!ret) {
+		egg_warning ("failed to download: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+out:
+	return ret;
+}
+
+/**
+ * pk_service_pack_exclude_packages:
+ **/
+static gboolean
+pk_service_pack_exclude_packages (PkServicePack *pack, PkPackageList *list)
+{
+	guint i;
+	guint length;
+	gboolean found;
+	const PkPackageObj *obj;
+
+	g_return_val_if_fail (PK_IS_SERVICE_PACK (pack), FALSE);
+	g_return_val_if_fail (pack->priv->exclude_list != NULL, FALSE);
+
+	/* do not just download everything, uselessly */
+	length = pk_package_list_get_size (pack->priv->exclude_list);
+	for (i=0; i<length; i++) {
+		obj = pk_package_list_get_obj (pack->priv->exclude_list, i);
+		/* will just ignore if the obj is not there */
+		found = pk_package_list_remove_obj (list, obj);
+		if (found)
+			egg_debug ("removed %s", obj->id->name);
+	}
+	return TRUE;
+}
+
+/**
+ * pk_service_pack_create_metadata_file:
+ **/
+static gboolean
+pk_service_pack_create_metadata_file (const gchar *filename)
+{
+	gboolean ret = FALSE;
+	gchar *distro_id = NULL;
+	gchar *iso_time = NULL;
+	GError *error = NULL;
+	GKeyFile *file = NULL;
+	gchar *data = NULL;
+
+	g_return_val_if_fail (filename != NULL, FALSE);
+
+	file = g_key_file_new ();
+
+	/* get needed data */
+	distro_id = pk_get_distro_id ();
+	if (distro_id == NULL)
+		goto out;
+	iso_time = pk_iso8601_present ();
+	if (iso_time == NULL)
+		goto out;
+
+	g_key_file_set_string (file, PK_SERVICE_PACK_GROUP_NAME, "distro_id", distro_id);
+	g_key_file_set_string (file, PK_SERVICE_PACK_GROUP_NAME, "created", iso_time);
+
+	/* convert to text */
+	data = g_key_file_to_data (file, NULL, &error);
+	if (data == NULL) {
+		egg_warning ("failed to convert to text: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* save contents */
+	ret = g_file_set_contents (filename, data, -1, &error);
+	if (!ret) {
+		egg_warning ("failed to save file: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+out:
+	g_key_file_free (file);
+	g_free (data);
+	g_free (distro_id);
+	g_free (iso_time);
+	return ret;
+}
+
+#ifdef HAVE_ARCHIVE_H
+/**
+ * pk_service_pack_archive_add_file:
+ **/
+static gboolean
+pk_service_pack_archive_add_file (struct archive *arch, const gchar *filename, GError **error)
+{
+	int retval;
+	int len;
+	int fd = -1;
+	int wrote;
+	gboolean ret = FALSE;
+	gchar *filename_basename = NULL;
+	struct archive_entry *entry = NULL;
+	struct stat st;
+	gchar buff[8192];
+
+	/* stat file */
+	retval = stat (filename, &st);
+	if (retval != 0) {
+		*error = g_error_new (1, 0, "file not found %s", filename);
+		goto out;
+	}
+	egg_debug ("stat(%s), size=%lu bytes\n", filename, st.st_size);
+
+	/* create new entry */
+	entry = archive_entry_new ();
+	archive_entry_copy_stat (entry, &st);
+	filename_basename = g_path_get_basename (filename);
+	archive_entry_set_pathname (entry, filename_basename);
+
+	/* ._BIG FAT BUG_. We should not have to do this, as it should be
+	 * set from archive_entry_copy_stat() */
+	archive_entry_set_size (entry, st.st_size);
+
+	/* write header */
+	retval = archive_write_header (arch, entry);
+	if (retval != ARCHIVE_OK) {
+		*error = g_error_new (1, 0, "failed to write header: %s\n", archive_error_string (arch));
+		goto out;
+	}
+
+	/* open file to copy */
+	fd = open (filename, O_RDONLY);
+	if (fd < 0) {
+		*error = g_error_new (1, 0, "failed to get fd for %s", filename);
+		goto out;
+	}
+
+	/* ITS4: ignore, buffer statically preallocated  */
+	len = read (fd, buff, sizeof (buff));
+	/* write data to archive -- how come no convenience function? */
+	while (len > 0) {
+		wrote = archive_write_data (arch, buff, len);
+		if (wrote != len)
+			egg_warning("wrote %i instead of %i\n", wrote, len);
+		/* ITS4: ignore, buffer statically preallocated  */
+		len = read (fd, buff, sizeof (buff));
+	}
+	ret = TRUE;
+out:
+	if (fd >= 0)
+		close (fd);
+	if (entry != NULL)
+		archive_entry_free (entry);
+	g_free (filename_basename);
+	return ret;
+}
+
+/**
+ * pk_service_pack_create_from_files:
+ **/
+static gboolean
+pk_service_pack_create_from_files (PkServicePack *pack, GPtrArray *file_array, GError **error)
+{
+	struct archive *arch = NULL;
+	gboolean ret = FALSE;
+	const gchar *src;
+	guint i;
+	gchar *filename;
+
+	g_return_val_if_fail (PK_IS_SERVICE_PACK (pack), FALSE);
+	g_return_val_if_fail (file_array != NULL, FALSE);
+	g_return_val_if_fail (error != NULL, FALSE);
+
+	/* create a file with metadata in it */
+	filename = g_build_filename (g_get_tmp_dir (), "metadata.conf", NULL);
+	ret = pk_service_pack_create_metadata_file (filename);
+	if (!ret) {
+	        *error = g_error_new (1, 0, "failed to generate metadata file %s", filename);
+	        goto out;
+	}
+	g_ptr_array_add (file_array, g_strdup (filename));
+
+	/* we can only write tar achives */
+	arch = archive_write_new ();
+	archive_write_set_compression_none (arch);
+	archive_write_set_format_ustar (arch);
+	archive_write_open_filename (arch, pack->priv->filename);
+
+	/* for each filename */
+	for (i=0; i<file_array->len; i++) {
+		src = (const gchar *) g_ptr_array_index (file_array, i);
+		/* try to add to archive */
+		ret = pk_service_pack_archive_add_file (arch, src, error);
+		if (!ret)
+			goto out;
+	}
+
+	/* completed all okay */
+	ret = TRUE;
+out:
+	g_free (filename);
+	/* delete each filename */
+	for (i=0; i<file_array->len; i++) {
+		src = (const gchar *) g_ptr_array_index (file_array, i);
+		g_remove (src);
+	}
+
+	/* close the archive */
+	if (arch != NULL) {
+		archive_write_close (arch);
+		archive_write_finish (arch);
+	}
+	return ret;
+}
+#else
+/**
+ * pk_service_pack_create_from_files:
+ **/
+static gboolean
+pk_service_pack_create_from_files (PkServicePack *pack, GPtrArray *file_array, GError **error)
+{
+	g_return_val_if_fail (PK_IS_SERVICE_PACK (pack), FALSE);
+	*error = g_error_new (1, 0, "Cannot create pack as PackageKit as not built with libarchive support");
+	return FALSE;
+}
+#endif
+
+/**
+ * pk_service_pack_scan_files_in_directory:
+ **/
+static GPtrArray *
+pk_service_pack_scan_files_in_directory (PkServicePack *pack)
+{
+	gchar *src;
+	GPtrArray *file_array = NULL;
+	GDir *dir;
+	const gchar *filename;
+
+	g_return_val_if_fail (PK_IS_SERVICE_PACK (pack), FALSE);
+	g_return_val_if_fail (pack->priv->directory != NULL, FALSE);
+
+	/* try and open the directory */
+	dir = g_dir_open (pack->priv->directory, 0, NULL);
+	if (dir == NULL) {
+		egg_warning ("failed to get directory for %s", pack->priv->directory);
+		goto out;
+	}
+
+	/* add each file to an array */
+	file_array = g_ptr_array_new ();
+	while ((filename = g_dir_read_name (dir))) {
+		src = g_build_filename (pack->priv->directory, filename, NULL);
+		g_ptr_array_add (file_array, src);
+	}
+	g_dir_close (dir);
+out:
+	return file_array;
+}
+
+/**
  * pk_service_pack_create_for_package_id:
  **/
 gboolean
 pk_service_pack_create_for_package_id (PkServicePack *pack, const gchar *package_id, GError **error)
 {
+	gchar **package_ids = NULL;
+	PkPackageList *list = NULL;
+	guint length;
+	guint i;
+	const PkPackageObj *obj;
+	GPtrArray *file_array = NULL;
+	GError *error_local = NULL;
+	gboolean ret = FALSE;
+	gchar *text;
+
 	g_return_val_if_fail (PK_IS_SERVICE_PACK (pack), FALSE);
 	g_return_val_if_fail (package_id != NULL, FALSE);
 	g_return_val_if_fail (pack->priv->filename != NULL, FALSE);
 	g_return_val_if_fail (pack->priv->directory != NULL, FALSE);
-	return TRUE;
+
+	/* download this package */
+	package_ids = pk_package_ids_from_id (package_id);
+	ret = pk_service_pack_download_package_ids (pack, package_ids);
+	g_strfreev (package_ids);
+	if (!ret) {
+		*error = g_error_new (1, 0, "failed to download main package: %s", error_local->message);
+		g_error_free (error_local);
+		goto out;
+	}
+
+	/* get depends */
+	ret = pk_client_reset (pack->priv->client, &error_local);
+	if (!ret) {
+		*error = g_error_new (1, 0, "failed to reset: %s", error_local->message);
+		g_error_free (error_local);
+		goto out;
+	}
+
+	egg_debug ("Getting depends for %s", package_id);
+	ret = pk_client_get_depends (pack->priv->client, PK_FILTER_ENUM_NONE, package_ids, TRUE, &error_local);
+	if (!ret) {
+		*error = g_error_new (1, 0, "failed to get depends: %s", error_local->message);
+		g_error_free (error_local);
+		goto out;
+	}
+
+	/* get the deps */
+	list = pk_client_get_package_list (pack->priv->client);
+
+	/* remove some deps */
+	pk_service_pack_exclude_packages (pack, list);
+
+	/* list deps */
+	length = pk_package_list_get_size (list);
+	for (i=0; i<length; i++) {
+		obj = pk_package_list_get_obj (list, i);
+		text = pk_package_obj_to_string (obj);
+		g_print ("downloading %s\n", text);
+		g_free (text);
+	}
+
+	/* confirm we want the deps */
+	if (length != 0) {
+		/* download additional package_ids */
+		package_ids = pk_package_list_to_strv (list);
+		ret = pk_service_pack_download_package_ids (pack, package_ids);
+		g_strfreev (package_ids);
+
+		/* failed to get deps */
+		if (!ret) {
+			*error = g_error_new (1, 0, "xxxxxxxxxxxxxxxxxx: %s", error_local->message);
+			egg_warning ("failed to download deps of package: %s", package_id);
+			goto out;
+		}
+	}
+
+
+	/* find packages that were downloaded */
+	file_array = pk_service_pack_scan_files_in_directory (pack);
+	if (file_array == NULL) {
+		*error = g_error_new (1, 0, "failed to scan directory: %s", pack->priv->directory);
+		goto out;
+	}
+
+	/* generate pack file */
+	ret = pk_service_pack_create_from_files (pack, file_array, &error_local);
+	if (!ret) {
+		*error = g_error_new (1, 0, "failed to create archive: %s", error_local->message);
+		g_error_free (error_local);
+		goto out;
+	}
+
+out:
+	if (list != NULL)
+		g_object_unref (list);
+	if (file_array != NULL) {
+		g_ptr_array_foreach (file_array, (GFunc) g_free, NULL);
+		g_ptr_array_free (file_array, TRUE);
+	}
+	return ret;
 }
 
 /**
@@ -294,6 +668,7 @@ pk_service_pack_create_for_updates (PkServicePack *pack, GError **error)
 	g_return_val_if_fail (PK_IS_SERVICE_PACK (pack), FALSE);
 	g_return_val_if_fail (pack->priv->filename != NULL, FALSE);
 	g_return_val_if_fail (pack->priv->directory != NULL, FALSE);
+	*error = g_error_new (1, 0, "not yet supported");
 	return TRUE;
 }
 
@@ -311,6 +686,7 @@ pk_service_pack_finalize (GObject *object)
 
 	if (pack->priv->exclude_list != NULL)
 		g_object_unref (pack->priv->exclude_list);
+	g_object_unref (pack->priv->client);
 	g_free (pack->priv->directory);
 	g_free (pack->priv->filename);
 
@@ -338,6 +714,9 @@ pk_service_pack_init (PkServicePack *pack)
 	pack->priv->exclude_list = NULL;
 	pack->priv->filename = NULL;
 	pack->priv->directory = NULL;
+	pack->priv->client = pk_client_new ();
+	pk_client_set_use_buffer (pack->priv->client, TRUE, NULL);
+	pk_client_set_synchronous (pack->priv->client, TRUE, NULL);
 }
 
 /**
commit b8729db36cfdeb97f0ac3be92d7b57d45adadcc3
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 8 12:06:16 2008 +0100

    trivial: rename some service pack functions and variables, no functional changes - 2

diff --git a/client/pk-generate-pack.c b/client/pk-generate-pack.c
index 5e7c7a3..5285a0f 100644
--- a/client/pk-generate-pack.c
+++ b/client/pk-generate-pack.c
@@ -106,14 +106,14 @@ pk_service_pack_exclude_packages (PkPackageList *list, PkPackageList *list_packa
 }
 
 /**
- * pk_service_pack_create_metadata_file:
+ * pk_service_pack_create_from_files_metadata_file:
  **/
 static gboolean
-pk_service_pack_create_metadata_file (const gchar *filename)
+pk_service_pack_create_from_files_metadata_file (const gchar *filename)
 {
 	gboolean ret = FALSE;
 	gchar *distro_id = NULL;
-	gchar *datetime = NULL;
+	gchar *iso_time = NULL;
 	GError *error = NULL;
 	GKeyFile *file = NULL;
 	gchar *data = NULL;
@@ -130,12 +130,12 @@ pk_service_pack_create_metadata_file (const gchar *filename)
 	distro_id = pk_get_distro_id ();
 	if (distro_id == NULL)
 		goto out;
-	datetime = pk_iso8601_present ();
-	if (datetime == NULL)
+	iso_time = pk_iso8601_present ();
+	if (iso_time == NULL)
 		goto out;
 
 	g_key_file_set_string (file, PK_SERVICE_PACK_GROUP_NAME, "distro_id", distro_id);
-	g_key_file_set_string (file, PK_SERVICE_PACK_GROUP_NAME, "created", datetime);
+	g_key_file_set_string (file, PK_SERVICE_PACK_GROUP_NAME, "created", iso_time);
 
 	/* convert to text */
 	data = g_key_file_to_data (file, NULL, &error);
@@ -157,7 +157,7 @@ out:
 	g_key_file_free (file);
 	g_free (data);
 	g_free (distro_id);
-	g_free (datetime);
+	g_free (iso_time);
 	return ret;
 }
 
@@ -231,10 +231,10 @@ out:
 }
 
 /**
- * pk_service_pack_create:
+ * pk_service_pack_create_from_files:
  **/
 static gboolean
-pk_service_pack_create (const gchar *filename, GPtrArray *file_array, GError **error)
+pk_service_pack_create_from_files (const gchar *filename, GPtrArray *file_array, GError **error)
 {
 	struct archive *arch = NULL;
 	gboolean ret = FALSE;
@@ -248,7 +248,7 @@ pk_service_pack_create (const gchar *filename, GPtrArray *file_array, GError **e
 
 	/* create a file with metadata in it */
 	metadata_filename = g_build_filename (g_get_tmp_dir (), "metadata.conf", NULL);
-	ret = pk_service_pack_create_metadata_file (metadata_filename);
+	ret = pk_service_pack_create_from_files_metadata_file (metadata_filename);
 	if (!ret) {
 	        *error = g_error_new (1, 0, "failed to generate metadata file %s", metadata_filename);
 	        goto out;
@@ -289,10 +289,10 @@ out:
 }
 #else
 /**
- * pk_service_pack_create:
+ * pk_service_pack_create_from_files:
  **/
 static gboolean
-pk_service_pack_create (const gchar *filename, GPtrArray *file_array, GError **error)
+pk_service_pack_create_from_files (const gchar *filename, GPtrArray *file_array, GError **error)
 {
 	*error = g_error_new (1, 0, "Cannot create pack as PackageKit as not built with libarchive support");
 	return FALSE;
@@ -419,7 +419,7 @@ pk_service_pack_main (const gchar *pack_filename, const gchar *directory, const
 	}
 
 	/* generate pack file */
-	ret = pk_service_pack_create (pack_filename, file_array, &error_local);
+	ret = pk_service_pack_create_from_files (pack_filename, file_array, &error_local);
 	if (!ret) {
 		egg_warning ("failed to create archive: %s", error_local->message);
 		g_error_free (error_local);
@@ -488,7 +488,7 @@ pk_genpack_test (EggTest *test)
 
 	/************************************************************/
 	egg_test_title (test, "metadata NULL");
-	ret = pk_service_pack_create_metadata_file (NULL);
+	ret = pk_service_pack_create_from_files_metadata_file (NULL);
 	if (!ret)
 		egg_test_success (test, NULL);
 	else
@@ -496,7 +496,7 @@ pk_genpack_test (EggTest *test)
 
 	/************************************************************/
 	egg_test_title (test, "metadata /tmp/metadata.conf");
-	ret = pk_service_pack_create_metadata_file ("/tmp/metadata.conf");
+	ret = pk_service_pack_create_from_files_metadata_file ("/tmp/metadata.conf");
 	if (ret)
 		egg_test_success (test, NULL);
 	else
@@ -524,7 +524,7 @@ pk_genpack_test (EggTest *test)
 	file_array = g_ptr_array_new ();
 	src = g_build_filename ("/tmp", "gitk-1.5.5.1-1.fc9.i386.rpm", NULL);
 	g_ptr_array_add (file_array, src);
-	ret = pk_service_pack_create ("/tmp/gitk.servicepack", file_array, &error);
+	ret = pk_service_pack_create_from_files ("/tmp/gitk.servicepack", file_array, &error);
 	if (!ret) {
 		if (error != NULL) {
 			egg_test_failed (test, "failed to create pack %s" , error->message);
commit 2c27ca416b3341b24b4b34b375c239b85df1c723
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 8 12:03:34 2008 +0100

    trivial: rename some service pack functions and variables, no functional changes

diff --git a/client/pk-generate-pack-main.c b/client/pk-generate-pack-main.c
index 0f77c4e..da616c0 100644
--- a/client/pk-generate-pack-main.c
+++ b/client/pk-generate-pack-main.c
@@ -306,7 +306,7 @@ main (int argc, char *argv[])
 		ret = pk_service_pack_create_for_package_id (pack, package_id, &error);
 
 	/* old method */
-	ret = pk_generate_pack_main (filename, tempdir, package_id, list, &error);
+	ret = pk_service_pack_main (filename, tempdir, package_id, list, &error);
 	if (!ret) {
 		g_print ("%s: %s\n", _("Failed to create pack"), error->message);
 		g_error_free (error);
diff --git a/client/pk-generate-pack.c b/client/pk-generate-pack.c
index e5ddaf2..5e7c7a3 100644
--- a/client/pk-generate-pack.c
+++ b/client/pk-generate-pack.c
@@ -50,10 +50,10 @@
 #include "pk-tools-common.h"
 
 /**
- * pk_generate_pack_download_only:
+ * pk_service_pack_download_package_ids:
  **/
 static gboolean
-pk_generate_pack_download_only (PkClient *client, gchar **package_ids, const gchar *directory)
+pk_service_pack_download_package_ids (PkClient *client, gchar **package_ids, const gchar *directory)
 {
 	gboolean ret;
 	GError *error = NULL;
@@ -83,10 +83,10 @@ out:
 }
 
 /**
- * pk_generate_pack_exclude_packages:
+ * pk_service_pack_exclude_packages:
  **/
 static gboolean
-pk_generate_pack_exclude_packages (PkPackageList *list, PkPackageList *list_packages)
+pk_service_pack_exclude_packages (PkPackageList *list, PkPackageList *list_packages)
 {
 	guint i;
 	guint length;
@@ -106,10 +106,10 @@ pk_generate_pack_exclude_packages (PkPackageList *list, PkPackageList *list_pack
 }
 
 /**
- * pk_generate_pack_set_metadata:
+ * pk_service_pack_create_metadata_file:
  **/
 static gboolean
-pk_generate_pack_set_metadata (const gchar *full_path)
+pk_service_pack_create_metadata_file (const gchar *filename)
 {
 	gboolean ret = FALSE;
 	gchar *distro_id = NULL;
@@ -121,7 +121,7 @@ pk_generate_pack_set_metadata (const gchar *full_path)
 	file = g_key_file_new ();
 
 	/* check for NULL values */
-	if (full_path == NULL) {
+	if (filename == NULL) {
 		egg_warning (_("Could not find a valid metadata file"));
 		goto out;
 	}
@@ -146,7 +146,7 @@ pk_generate_pack_set_metadata (const gchar *full_path)
 	}
 
 	/* save contents */
-	ret = g_file_set_contents (full_path, data, -1, &error);
+	ret = g_file_set_contents (filename, data, -1, &error);
 	if (!ret) {
 		egg_warning ("failed to save file: %s", error->message);
 		g_error_free (error);
@@ -163,10 +163,10 @@ out:
 
 #ifdef HAVE_ARCHIVE_H
 /**
- * pk_generate_pack_archive_add_file:
+ * pk_service_pack_archive_add_file:
  **/
 static gboolean
-pk_generate_pack_archive_add_file (struct archive *arch, const gchar *filename, GError **error)
+pk_service_pack_archive_add_file (struct archive *arch, const gchar *filename, GError **error)
 {
 	int retval;
 	int len;
@@ -231,10 +231,10 @@ out:
 }
 
 /**
- * pk_generate_pack_create:
+ * pk_service_pack_create:
  **/
 static gboolean
-pk_generate_pack_create (const gchar *tarfilename, GPtrArray *file_array, GError **error)
+pk_service_pack_create (const gchar *filename, GPtrArray *file_array, GError **error)
 {
 	struct archive *arch = NULL;
 	gboolean ret = FALSE;
@@ -242,13 +242,13 @@ pk_generate_pack_create (const gchar *tarfilename, GPtrArray *file_array, GError
 	guint i;
 	gchar *metadata_filename;
 
-	g_return_val_if_fail (tarfilename != NULL, FALSE);
+	g_return_val_if_fail (filename != NULL, FALSE);
 	g_return_val_if_fail (file_array != NULL, FALSE);
 	g_return_val_if_fail (error != NULL, FALSE);
 
 	/* create a file with metadata in it */
 	metadata_filename = g_build_filename (g_get_tmp_dir (), "metadata.conf", NULL);
-	ret = pk_generate_pack_set_metadata (metadata_filename);
+	ret = pk_service_pack_create_metadata_file (metadata_filename);
 	if (!ret) {
 	        *error = g_error_new (1, 0, "failed to generate metadata file %s", metadata_filename);
 	        goto out;
@@ -259,13 +259,13 @@ pk_generate_pack_create (const gchar *tarfilename, GPtrArray *file_array, GError
 	arch = archive_write_new ();
 	archive_write_set_compression_none (arch);
 	archive_write_set_format_ustar (arch);
-	archive_write_open_filename (arch, tarfilename);
+	archive_write_open_filename (arch, filename);
 
 	/* for each filename */
 	for (i=0; i<file_array->len; i++) {
 		src = (const gchar *) g_ptr_array_index (file_array, i);
 		/* try to add to archive */
-		ret = pk_generate_pack_archive_add_file (arch, src, error);
+		ret = pk_service_pack_archive_add_file (arch, src, error);
 		if (!ret)
 			goto out;
 	}
@@ -289,21 +289,21 @@ out:
 }
 #else
 /**
- * pk_generate_pack_create:
+ * pk_service_pack_create:
  **/
 static gboolean
-pk_generate_pack_create (const gchar *tarfilename, GPtrArray *file_array, GError **error)
+pk_service_pack_create (const gchar *filename, GPtrArray *file_array, GError **error)
 {
-	*error = g_error_new (1, 0, "Cannot create pack as PackageKit as not built with libtar support");
+	*error = g_error_new (1, 0, "Cannot create pack as PackageKit as not built with libarchive support");
 	return FALSE;
 }
 #endif
 
 /**
- * pk_generate_pack_scan_dir:
+ * pk_service_pack_scan_files_in_directory:
  **/
 static GPtrArray *
-pk_generate_pack_scan_dir (const gchar *directory)
+pk_service_pack_scan_files_in_directory (const gchar *directory)
 {
 	gchar *src;
 	GPtrArray *file_array = NULL;
@@ -335,16 +335,15 @@ out:
 }
 
 /**
- * pk_generate_pack_main:
+ * pk_service_pack_main:
  **/
 gboolean
-pk_generate_pack_main (const gchar *pack_filename, const gchar *directory, const gchar *package_id, PkPackageList *exclude_list, GError **error)
+pk_service_pack_main (const gchar *pack_filename, const gchar *directory, const gchar *package_id, PkPackageList *exclude_list, GError **error)
 {
 
 	gchar **package_ids;
 	PkPackageList *list = NULL;
 	guint length;
-	gboolean download;
 	guint i;
 	const PkPackageObj *obj;
 	GPtrArray *file_array = NULL;
@@ -359,7 +358,7 @@ pk_generate_pack_main (const gchar *pack_filename, const gchar *directory, const
 
 	/* download this package */
 	package_ids = pk_package_ids_from_id (package_id);
-	ret = pk_generate_pack_download_only (client, package_ids, directory);
+	ret = pk_service_pack_download_package_ids (client, package_ids, directory);
 	if (!ret) {
 		egg_warning ("failed to download main package: %s", error_local->message);
 		g_error_free (error_local);
@@ -387,7 +386,7 @@ pk_generate_pack_main (const gchar *pack_filename, const gchar *directory, const
 	list = pk_client_get_package_list (client);
 
 	/* remove some deps */
-	pk_generate_pack_exclude_packages (list, exclude_list);
+	pk_service_pack_exclude_packages (list, exclude_list);
 
 	/* list deps */
 	length = pk_package_list_get_size (list);
@@ -400,19 +399,9 @@ pk_generate_pack_main (const gchar *pack_filename, const gchar *directory, const
 
 	/* confirm we want the deps */
 	if (length != 0) {
-		/* get user input */
-		download = pk_console_get_prompt (_("Okay to download the additional packages"), TRUE);
-
-		/* we chickened out */
-		if (download == FALSE) {
-			g_print ("%s\n", _("Cancelled!"));
-			ret = FALSE;
-			goto out;
-		}
-
-		/* convert to list of package_ids */
+		/* download additional package_ids */
 		package_ids = pk_package_list_to_strv (list);
-		ret = pk_generate_pack_download_only (client, package_ids, directory);
+		ret = pk_service_pack_download_package_ids (client, package_ids, directory);
 		g_strfreev (package_ids);
 	}
 
@@ -423,14 +412,14 @@ pk_generate_pack_main (const gchar *pack_filename, const gchar *directory, const
 	}
 
 	/* find packages that were downloaded */
-	file_array = pk_generate_pack_scan_dir (directory);
+	file_array = pk_service_pack_scan_files_in_directory (directory);
 	if (file_array == NULL) {
 		egg_warning ("failed to scan directory: %s", directory);
 		goto out;
 	}
 
 	/* generate pack file */
-	ret = pk_generate_pack_create (pack_filename, file_array, &error_local);
+	ret = pk_service_pack_create (pack_filename, file_array, &error_local);
 	if (!ret) {
 		egg_warning ("failed to create archive: %s", error_local->message);
 		g_error_free (error_local);
@@ -480,7 +469,7 @@ pk_genpack_test (EggTest *test)
 
 	/************************************************************/
 	egg_test_title (test, "download only NULL");
-	ret = pk_generate_pack_download_only (client, NULL, NULL);
+	ret = pk_service_pack_download_package_ids (client, NULL, NULL);
 	if (!ret)
 		egg_test_success (test, NULL);
 	else
@@ -489,7 +478,7 @@ pk_genpack_test (EggTest *test)
 	/************************************************************/
 	egg_test_title (test, "download only gitk");
 	package_ids = pk_package_ids_from_id ("gitk;1.5.5.1-1.fc9;i386;installed");
-	ret = pk_generate_pack_download_only (client, package_ids, "/tmp");
+	ret = pk_service_pack_download_package_ids (client, package_ids, "/tmp");
 	if (ret)
 		egg_test_success (test, NULL);
 	else
@@ -499,7 +488,7 @@ pk_genpack_test (EggTest *test)
 
 	/************************************************************/
 	egg_test_title (test, "metadata NULL");
-	ret = pk_generate_pack_set_metadata (NULL);
+	ret = pk_service_pack_create_metadata_file (NULL);
 	if (!ret)
 		egg_test_success (test, NULL);
 	else
@@ -507,7 +496,7 @@ pk_genpack_test (EggTest *test)
 
 	/************************************************************/
 	egg_test_title (test, "metadata /tmp/metadata.conf");
-	ret = pk_generate_pack_set_metadata ("/tmp/metadata.conf");
+	ret = pk_service_pack_create_metadata_file ("/tmp/metadata.conf");
 	if (ret)
 		egg_test_success (test, NULL);
 	else
@@ -516,7 +505,7 @@ pk_genpack_test (EggTest *test)
 
 	/************************************************************/
 	egg_test_title (test, "scandir NULL");
-	file_array = pk_generate_pack_scan_dir (NULL);
+	file_array = pk_service_pack_scan_files_in_directory (NULL);
 	if (file_array == NULL)
 		egg_test_success (test, NULL);
 	else
@@ -524,7 +513,7 @@ pk_genpack_test (EggTest *test)
 
 	/************************************************************/
 	egg_test_title (test, "scandir /tmp");
-	file_array = pk_generate_pack_scan_dir ("/tmp");
+	file_array = pk_service_pack_scan_files_in_directory ("/tmp");
 	if (file_array != NULL)
 		egg_test_success (test, NULL);
 	else
@@ -535,7 +524,7 @@ pk_genpack_test (EggTest *test)
 	file_array = g_ptr_array_new ();
 	src = g_build_filename ("/tmp", "gitk-1.5.5.1-1.fc9.i386.rpm", NULL);
 	g_ptr_array_add (file_array, src);
-	ret = pk_generate_pack_create ("/tmp/gitk.servicepack", file_array, &error);
+	ret = pk_service_pack_create ("/tmp/gitk.servicepack", file_array, &error);
 	if (!ret) {
 		if (error != NULL) {
 			egg_test_failed (test, "failed to create pack %s" , error->message);
diff --git a/client/pk-generate-pack.h b/client/pk-generate-pack.h
index 5b1f973..320918f 100644
--- a/client/pk-generate-pack.h
+++ b/client/pk-generate-pack.h
@@ -23,21 +23,7 @@
 #ifndef __PK_GENERATE_PACK_H
 #define __PK_GENERATE_PACK_H
 
-gchar		*pk_generate_pack_perhaps_resolve		(PkClient *client,
-								 PkBitfield filter,
-								 const gchar *package,
-								 GError **error);
-gboolean	 pk_generate_pack_download_only 		(PkClient *client,
-								 gchar **package_ids,
-								 const gchar *directory);
-gboolean	 pk_generate_pack_exclude_packages		(PkPackageList *list,
-								 const gchar *package_list);
-gboolean	 pk_generate_pack_set_metadata			(const gchar *full_path);
-gboolean	 pk_generate_pack_create 			(const gchar *tarfilename,
-								 GPtrArray *file_array,
-								 GError **error);
-GPtrArray 	*pk_generate_pack_scan_dir			(const gchar *directory);
-gboolean	 pk_generate_pack_main				(const gchar *pack_filename,
+gboolean	 pk_service_pack_main				(const gchar *pack_filename,
 								 const gchar *directory,
 								 const gchar *package_id,
 								 PkPackageList *exclude_list,
commit 711398f679a44173abc4d825fece31d6212a13ec
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 8 11:58:19 2008 +0100

    trivial: static'ify some internal functions

diff --git a/client/pk-generate-pack.c b/client/pk-generate-pack.c
index 5b82f3f..e5ddaf2 100644
--- a/client/pk-generate-pack.c
+++ b/client/pk-generate-pack.c
@@ -52,7 +52,7 @@
 /**
  * pk_generate_pack_download_only:
  **/
-gboolean
+static gboolean
 pk_generate_pack_download_only (PkClient *client, gchar **package_ids, const gchar *directory)
 {
 	gboolean ret;
@@ -85,7 +85,7 @@ out:
 /**
  * pk_generate_pack_exclude_packages:
  **/
-gboolean
+static gboolean
 pk_generate_pack_exclude_packages (PkPackageList *list, PkPackageList *list_packages)
 {
 	guint i;
@@ -108,7 +108,7 @@ pk_generate_pack_exclude_packages (PkPackageList *list, PkPackageList *list_pack
 /**
  * pk_generate_pack_set_metadata:
  **/
-gboolean
+static gboolean
 pk_generate_pack_set_metadata (const gchar *full_path)
 {
 	gboolean ret = FALSE;
@@ -233,7 +233,7 @@ out:
 /**
  * pk_generate_pack_create:
  **/
-gboolean
+static gboolean
 pk_generate_pack_create (const gchar *tarfilename, GPtrArray *file_array, GError **error)
 {
 	struct archive *arch = NULL;
@@ -291,7 +291,7 @@ out:
 /**
  * pk_generate_pack_create:
  **/
-gboolean
+static gboolean
 pk_generate_pack_create (const gchar *tarfilename, GPtrArray *file_array, GError **error)
 {
 	*error = g_error_new (1, 0, "Cannot create pack as PackageKit as not built with libtar support");
@@ -302,7 +302,7 @@ pk_generate_pack_create (const gchar *tarfilename, GPtrArray *file_array, GError
 /**
  * pk_generate_pack_scan_dir:
  **/
-GPtrArray *
+static GPtrArray *
 pk_generate_pack_scan_dir (const gchar *directory)
 {
 	gchar *src;
commit 00219ade18fb10ae010dec9ba5f82af9fb800e5d
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 8 11:56:23 2008 +0100

    trivial: send a PkPackageList to pk_generate_pack_main, not a filename

diff --git a/client/pk-generate-pack-main.c b/client/pk-generate-pack-main.c
index b1bde5f..0f77c4e 100644
--- a/client/pk-generate-pack-main.c
+++ b/client/pk-generate-pack-main.c
@@ -306,7 +306,7 @@ main (int argc, char *argv[])
 		ret = pk_service_pack_create_for_package_id (pack, package_id, &error);
 
 	/* old method */
-	ret = pk_generate_pack_main (filename, tempdir, package_id, package_list, &error);
+	ret = pk_generate_pack_main (filename, tempdir, package_id, list, &error);
 	if (!ret) {
 		g_print ("%s: %s\n", _("Failed to create pack"), error->message);
 		g_error_free (error);
diff --git a/client/pk-generate-pack.c b/client/pk-generate-pack.c
index 81636a1..5b82f3f 100644
--- a/client/pk-generate-pack.c
+++ b/client/pk-generate-pack.c
@@ -86,28 +86,12 @@ out:
  * pk_generate_pack_exclude_packages:
  **/
 gboolean
-pk_generate_pack_exclude_packages (PkPackageList *list, const gchar *package_list)
+pk_generate_pack_exclude_packages (PkPackageList *list, PkPackageList *list_packages)
 {
 	guint i;
 	guint length;
 	gboolean found;
-	PkPackageList *list_packages;
 	const PkPackageObj *obj;
-	gboolean ret;
-
-	list_packages = pk_package_list_new ();
-
-	/* check for NULL values */
-	if (package_list == NULL) {
-		egg_warning ("Cannot find the list of packages to be excluded");
-		ret = FALSE;
-		goto out;
-	}
-
-	/* load a list of packages already found on the users system */
-	ret = pk_package_list_add_file (list_packages, package_list);
-	if (!ret)
-		goto out;
 
 	/* do not just download everything, uselessly */
 	length = pk_package_list_get_size (list_packages);
@@ -118,10 +102,7 @@ pk_generate_pack_exclude_packages (PkPackageList *list, const gchar *package_lis
 		if (found)
 			egg_debug ("removed %s", obj->id->name);
 	}
-
-out:
-	g_object_unref (list_packages);
-	return ret;
+	return TRUE;
 }
 
 /**
@@ -357,7 +338,7 @@ out:
  * pk_generate_pack_main:
  **/
 gboolean
-pk_generate_pack_main (const gchar *pack_filename, const gchar *directory, const gchar *package_id, const gchar *package_list, GError **error)
+pk_generate_pack_main (const gchar *pack_filename, const gchar *directory, const gchar *package_id, PkPackageList *exclude_list, GError **error)
 {
 
 	gchar **package_ids;
@@ -406,11 +387,7 @@ pk_generate_pack_main (const gchar *pack_filename, const gchar *directory, const
 	list = pk_client_get_package_list (client);
 
 	/* remove some deps */
-	ret = pk_generate_pack_exclude_packages (list, package_list);
-	if (!ret) {
-		egg_warning ("failed to exclude packages");
-		goto out;
-	}
+	pk_generate_pack_exclude_packages (list, exclude_list);
 
 	/* list deps */
 	length = pk_package_list_get_size (list);
@@ -521,35 +498,6 @@ pk_genpack_test (EggTest *test)
 	g_object_unref (client);
 
 	/************************************************************/
-	egg_test_title (test, "exclude NULL");
-	list = pk_package_list_new ();
-	ret = pk_generate_pack_exclude_packages (list, NULL);
-	if (!ret)
-		egg_test_success (test, NULL);
-	else
-		egg_test_failed (test, NULL);
-
-	/************************************************************/
-	egg_test_title (test, "exclude /var/lib/PackageKit/package-list.txt");
-	list = pk_package_list_new ();
-	ret = pk_generate_pack_exclude_packages (list, "/var/lib/PackageKit/package-list.txt");
-	if (ret)
-		egg_test_success (test, NULL);
-	else
-		egg_test_failed (test, NULL);
-	g_object_unref (list);
-
-	/************************************************************/
-	egg_test_title (test, "exclude false.txt");
-	list = pk_package_list_new ();
-	ret = pk_generate_pack_exclude_packages (list, "/media/USB/false.txt");
-	if (!ret)
-		egg_test_success (test, NULL);
-	else
-		egg_test_failed (test, NULL);
-	g_object_unref (list);
-
-	/************************************************************/
 	egg_test_title (test, "metadata NULL");
 	ret = pk_generate_pack_set_metadata (NULL);
 	if (!ret)
diff --git a/client/pk-generate-pack.h b/client/pk-generate-pack.h
index d345f6c..5b1f973 100644
--- a/client/pk-generate-pack.h
+++ b/client/pk-generate-pack.h
@@ -40,7 +40,7 @@ GPtrArray 	*pk_generate_pack_scan_dir			(const gchar *directory);
 gboolean	 pk_generate_pack_main				(const gchar *pack_filename,
 								 const gchar *directory,
 								 const gchar *package_id,
-								 const gchar *package_list,
+								 PkPackageList *exclude_list,
 								 GError **error);
 
 #endif /* __PK_GENERATE_PACK_H */
commit 98bc037d57550e783f511a22c26c01cadb6ca43c
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Wed Oct 8 12:51:56 2008 +0200

    APT: Do not require to be online to make a refresh

diff --git a/backends/apt/pk-backend-apt.c b/backends/apt/pk-backend-apt.c
index 4812eaa..d43f1d4 100644
--- a/backends/apt/pk-backend-apt.c
+++ b/backends/apt/pk-backend-apt.c
@@ -116,13 +116,6 @@ backend_get_updates (PkBackend *backend, PkBitfield filters)
 static void
 backend_refresh_cache (PkBackend *backend, gboolean force)
 {
-	// check network state
-	if (!pk_backend_is_online (backend)) {
-		pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot refresh cache whilst offline");
-		pk_backend_finished (backend);
-		return;
-	}
-
 	pk_backend_dbus_refresh_cache(dbus, force);
 }
 
commit 31543908799d335f6a77e5be42311bf7e3ca046f
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 8 11:49:01 2008 +0100

    trivial: remove unused function

diff --git a/client/pk-generate-pack.c b/client/pk-generate-pack.c
index ab8ce7f..81636a1 100644
--- a/client/pk-generate-pack.c
+++ b/client/pk-generate-pack.c
@@ -49,93 +49,6 @@
 
 #include "pk-tools-common.h"
 
-
-/**
- * pk_generate_pack_package_resolve:
- **/
-gchar *
-pk_generate_pack_package_resolve (PkClient *client, PkBitfield filter, const gchar *package, GError **error)
-{
-	gboolean ret;
-	gboolean valid;
-	guint i;
-	guint length;
-	const PkPackageObj *obj;
-	PkPackageList *list;
-	gchar **packages;
-
-	/* check for NULL values */
-	if (package == NULL) {
-		egg_warning ("Cannot resolve the package: invalid package");
-		return NULL;
-	}
-
-	/* have we passed a complete package_id? */
-	valid = pk_package_id_check (package);
-	if (valid)
-		return g_strdup (package);
-
-	ret = pk_client_reset (client, error);
-	if (ret == FALSE) {
-		egg_warning ("failed to reset client task");
-		return NULL;
-	}
-
-	/* we need to resolve it */
-	packages = pk_package_ids_from_id (package);
-	ret = pk_client_resolve (client, filter, packages, error);
-	g_strfreev (packages);
-	if (ret == FALSE) {
-		egg_warning ("Resolve failed");
-		return NULL;
-	}
-
-	/* get length of items found */
-	list = pk_client_get_package_list (client);
-	length = pk_package_list_get_size (list);
-	g_object_unref (list);
-
-	/* didn't resolve to anything, try to get a provide */
-	if (length == 0) {
-		ret = pk_client_reset (client, error);
-		if (ret == FALSE) {
-			egg_warning ("failed to reset client task");
-			return NULL;
-		}
-		ret = pk_client_what_provides (client, filter, PK_PROVIDES_ENUM_ANY, package, error);
-		if (ret == FALSE) {
-			egg_warning ("WhatProvides is not supported in this backend");
-			return NULL;
-		}
-	}
-
-	/* get length of items found again (we might have had success) */
-	list = pk_client_get_package_list (client);
-	length = pk_package_list_get_size (list);
-	if (length == 0) {
-		egg_warning (_("Could not find a package match"));
-		return NULL;
-	}
-
-	/* only found one, great! */
-	if (length == 1) {
-		obj = pk_package_list_get_obj (list, 0);
-		return pk_package_id_to_string (obj->id);
-	}
-	g_print ("%s\n", _("There are multiple package matches"));
-	for (i=0; i<length; i++) {
-		obj = pk_package_list_get_obj (list, i);
-		g_print ("%i. %s-%s.%s\n", i+1, obj->id->name, obj->id->version, obj->id->arch);
-	}
-
-	/* find out what package the user wants to use */
-	i = pk_console_get_number (_("Please enter the package number: "), length);
-	obj = pk_package_list_get_obj (list, i-1);
-	g_object_unref (list);
-
-	return pk_package_id_to_string (obj->id);
-}
-
 /**
  * pk_generate_pack_download_only:
  **/
@@ -589,28 +502,6 @@ pk_genpack_test (EggTest *test)
 		egg_test_failed (test, NULL);
 
 	/************************************************************/
-	egg_test_title (test, "test perhaps resolve NULL");
-	retval = pk_client_reset (client, &error);
-	file = pk_generate_pack_package_resolve (client, PK_FILTER_ENUM_NONE, NULL, &error);
-	if (file == NULL)
-		egg_test_success (test, NULL);
-	else {
-		egg_test_failed (test, "failed to resolve %s", error->message);
-		g_error_free (error);
-	}
-	g_free (file);
-
-	/************************************************************/
-	egg_test_title (test, "test perhaps resolve gitk");
-	retval = pk_client_reset(client, &error);
-	file = pk_generate_pack_package_resolve (client, PK_FILTER_ENUM_NONE, "gitk;1.5.5.1-1.fc9;i386;installed", &error);
-	if (file != NULL && egg_strequal (file, "gitk;1.5.5.1-1.fc9;i386;installed"))
-		egg_test_success (test, NULL);
-	else
-		egg_test_failed (test, "got: %s", file);
-	g_free (file);
-
-	/************************************************************/
 	egg_test_title (test, "download only NULL");
 	ret = pk_generate_pack_download_only (client, NULL, NULL);
 	if (!ret)
commit 5da29a134fb55a675a96a7ddd5588d662594fc36
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 8 11:47:44 2008 +0100

    trivial: more the resolving from pk-gererate-pack.c to pk-generate-pack-main.c, and pass a package_id instead

diff --git a/client/pk-generate-pack-main.c b/client/pk-generate-pack-main.c
index 6dba1b4..b1bde5f 100644
--- a/client/pk-generate-pack-main.c
+++ b/client/pk-generate-pack-main.c
@@ -37,6 +37,9 @@
 #include <pk-control.h>
 #include <pk-common.h>
 #include <pk-package-list.h>
+#include <pk-package-id.h>
+#include <pk-package-ids.h>
+#include <pk-client.h>
 
 #include "pk-tools-common.h"
 #include "pk-generate-pack.h"
@@ -64,6 +67,92 @@ pk_generate_pack_get_filename (const gchar *name, const gchar *directory)
 	return filename;
 }
 
+/**
+ * pk_generate_pack_package_resolve:
+ **/
+static gchar *
+pk_generate_pack_package_resolve (PkClient *client, PkBitfield filter, const gchar *package, GError **error)
+{
+	gboolean ret;
+	gboolean valid;
+	guint i;
+	guint length;
+	const PkPackageObj *obj;
+	PkPackageList *list;
+	gchar **packages;
+
+	/* check for NULL values */
+	if (package == NULL) {
+		egg_warning ("Cannot resolve the package: invalid package");
+		return NULL;
+	}
+
+	/* have we passed a complete package_id? */
+	valid = pk_package_id_check (package);
+	if (valid)
+		return g_strdup (package);
+
+	ret = pk_client_reset (client, error);
+	if (ret == FALSE) {
+		egg_warning ("failed to reset client task");
+		return NULL;
+	}
+
+	/* we need to resolve it */
+	packages = pk_package_ids_from_id (package);
+	ret = pk_client_resolve (client, filter, packages, error);
+	g_strfreev (packages);
+	if (ret == FALSE) {
+		egg_warning ("Resolve failed");
+		return NULL;
+	}
+
+	/* get length of items found */
+	list = pk_client_get_package_list (client);
+	length = pk_package_list_get_size (list);
+	g_object_unref (list);
+
+	/* didn't resolve to anything, try to get a provide */
+	if (length == 0) {
+		ret = pk_client_reset (client, error);
+		if (ret == FALSE) {
+			egg_warning ("failed to reset client task");
+			return NULL;
+		}
+		ret = pk_client_what_provides (client, filter, PK_PROVIDES_ENUM_ANY, package, error);
+		if (ret == FALSE) {
+			egg_warning ("WhatProvides is not supported in this backend");
+			return NULL;
+		}
+	}
+
+	/* get length of items found again (we might have had success) */
+	list = pk_client_get_package_list (client);
+	length = pk_package_list_get_size (list);
+	if (length == 0) {
+		egg_warning (_("Could not find a package match"));
+		return NULL;
+	}
+
+	/* only found one, great! */
+	if (length == 1) {
+		obj = pk_package_list_get_obj (list, 0);
+		return pk_package_id_to_string (obj->id);
+	}
+	g_print ("%s\n", _("There are multiple package matches"));
+	for (i=0; i<length; i++) {
+		obj = pk_package_list_get_obj (list, i);
+		g_print ("%i. %s-%s.%s\n", i+1, obj->id->name, obj->id->version, obj->id->arch);
+	}
+
+	/* find out what package the user wants to use */
+	i = pk_console_get_number (_("Please enter the package number: "), length);
+	obj = pk_package_list_get_obj (list, i-1);
+	g_object_unref (list);
+
+	return pk_package_id_to_string (obj->id);
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -80,6 +169,8 @@ main (int argc, char *argv[])
 	gboolean overwrite;
 	PkServicePack *pack = NULL;
 	PkPackageList *list = NULL;
+	PkClient *client = NULL;
+	gchar *package_id = NULL;
 
 	gboolean verbose = FALSE;
 	gchar *directory = NULL;
@@ -94,7 +185,7 @@ main (int argc, char *argv[])
 			_("Set the path of the file with the list of packages/dependencies to be excluded"), NULL},
 		{ "output", 'o', 0, G_OPTION_ARG_STRING, &directory,
 			_("The directory to put the pack file, or the current directory if ommitted"), NULL},
-		{ "package", 'i', 0, G_OPTION_ARG_STRING, &package,
+		{ "package", 'p', 0, G_OPTION_ARG_STRING, &package,
 			_("The package to be put into the ServicePack"), NULL},
 		{ "updates", 'u', 0, G_OPTION_ARG_NONE, &updates,
 			_("Put all updates available in the ServicePack"), NULL},
@@ -187,6 +278,20 @@ main (int argc, char *argv[])
 		goto out;
 	}
 
+	/* resolve package name to package_id */
+	if (!updates) {
+		client = pk_client_new ();
+		pk_client_set_use_buffer (client, TRUE, NULL);
+		pk_client_set_synchronous (client, TRUE, NULL);
+		g_print ("%s\n", _("Resolving package name to remote object"));
+		package_id = pk_generate_pack_package_resolve (client, PK_FILTER_ENUM_NONE, package, &error);
+		if (package_id == NULL) {
+			g_print (_("Failed to find package '%s': %s"), package, error->message);
+			g_error_free (error);
+			goto out;
+		}
+	}
+
 	/* create pack and set initial values */
 	pack = pk_service_pack_new ();
 	pk_service_pack_set_filename (pack, filename);
@@ -195,7 +300,13 @@ main (int argc, char *argv[])
 
 	/* generate the pack */
 	g_print (_("Creating service pack: %s\n"), filename);
-	ret = pk_generate_pack_main (filename, tempdir, package, package_list, &error);
+	if (updates)
+		ret = pk_service_pack_create_for_updates (pack, &error);
+	else
+		ret = pk_service_pack_create_for_package_id (pack, package_id, &error);
+
+	/* old method */
+	ret = pk_generate_pack_main (filename, tempdir, package_id, package_list, &error);
 	if (!ret) {
 		g_print ("%s: %s\n", _("Failed to create pack"), error->message);
 		g_error_free (error);
@@ -209,10 +320,13 @@ out:
 
 	if (pack != NULL)
 		g_object_unref (pack);
+	if (client != NULL)
+		g_object_unref (client);
 	if (list != NULL)
 		g_object_unref (list);
 	g_free (tempdir);
 	g_free (filename);
+	g_free (package_id);
 	g_free (directory);
 	g_free (package_list);
 	g_free (options_help);
diff --git a/client/pk-generate-pack.c b/client/pk-generate-pack.c
index b0e4cd3..ab8ce7f 100644
--- a/client/pk-generate-pack.c
+++ b/client/pk-generate-pack.c
@@ -31,10 +31,10 @@
 #include <glib/gstdio.h>
 #include <dbus/dbus-glib.h>
 
-#include <pk-package-ids.h>
 #include <pk-client.h>
 #include <pk-control.h>
 #include <pk-package-id.h>
+#include <pk-package-ids.h>
 #include <pk-common.h>
 #ifdef HAVE_ARCHIVE_H
 #include <archive.h>
@@ -51,10 +51,10 @@
 
 
 /**
- * pk_generate_pack_perhaps_resolve:
+ * pk_generate_pack_package_resolve:
  **/
 gchar *
-pk_generate_pack_perhaps_resolve (PkClient *client, PkBitfield filter, const gchar *package, GError **error)
+pk_generate_pack_package_resolve (PkClient *client, PkBitfield filter, const gchar *package, GError **error)
 {
 	gboolean ret;
 	gboolean valid;
@@ -72,9 +72,8 @@ pk_generate_pack_perhaps_resolve (PkClient *client, PkBitfield filter, const gch
 
 	/* have we passed a complete package_id? */
 	valid = pk_package_id_check (package);
-	if (valid) {
+	if (valid)
 		return g_strdup (package);
-	}
 
 	ret = pk_client_reset (client, error);
 	if (ret == FALSE) {
@@ -445,10 +444,9 @@ out:
  * pk_generate_pack_main:
  **/
 gboolean
-pk_generate_pack_main (const gchar *pack_filename, const gchar *directory, const gchar *package, const gchar *package_list, GError **error)
+pk_generate_pack_main (const gchar *pack_filename, const gchar *directory, const gchar *package_id, const gchar *package_list, GError **error)
 {
 
-	gchar *package_id;
 	gchar **package_ids;
 	PkPackageList *list = NULL;
 	guint length;
@@ -465,14 +463,6 @@ pk_generate_pack_main (const gchar *pack_filename, const gchar *directory, const
 	pk_client_set_use_buffer (client, TRUE, NULL);
 	pk_client_set_synchronous (client, TRUE, NULL);
 
-	/* resolve package */
-	package_id = pk_generate_pack_perhaps_resolve (client, PK_FILTER_ENUM_NONE, package, &error_local);
-	if (package_id == NULL) {
-		egg_warning ("failed to resolve: %s", error_local->message);
-		g_error_free (error_local);
-		goto out;
-	}
-
 	/* download this package */
 	package_ids = pk_package_ids_from_id (package_id);
 	ret = pk_generate_pack_download_only (client, package_ids, directory);
@@ -561,7 +551,6 @@ out:
 	g_object_unref (client);
 	if (list != NULL)
 		g_object_unref (list);
-	g_free (package_id);
 	if (file_array != NULL) {
 		g_ptr_array_foreach (file_array, (GFunc) g_free, NULL);
 		g_ptr_array_free (file_array, TRUE);
@@ -602,7 +591,7 @@ pk_genpack_test (EggTest *test)
 	/************************************************************/
 	egg_test_title (test, "test perhaps resolve NULL");
 	retval = pk_client_reset (client, &error);
-	file = pk_generate_pack_perhaps_resolve (client, PK_FILTER_ENUM_NONE, NULL, &error);
+	file = pk_generate_pack_package_resolve (client, PK_FILTER_ENUM_NONE, NULL, &error);
 	if (file == NULL)
 		egg_test_success (test, NULL);
 	else {
@@ -614,7 +603,7 @@ pk_genpack_test (EggTest *test)
 	/************************************************************/
 	egg_test_title (test, "test perhaps resolve gitk");
 	retval = pk_client_reset(client, &error);
-	file = pk_generate_pack_perhaps_resolve (client, PK_FILTER_ENUM_NONE, "gitk;1.5.5.1-1.fc9;i386;installed", &error);
+	file = pk_generate_pack_package_resolve (client, PK_FILTER_ENUM_NONE, "gitk;1.5.5.1-1.fc9;i386;installed", &error);
 	if (file != NULL && egg_strequal (file, "gitk;1.5.5.1-1.fc9;i386;installed"))
 		egg_test_success (test, NULL);
 	else
diff --git a/client/pk-generate-pack.h b/client/pk-generate-pack.h
index 57daef7..d345f6c 100644
--- a/client/pk-generate-pack.h
+++ b/client/pk-generate-pack.h
@@ -39,7 +39,7 @@ gboolean	 pk_generate_pack_create 			(const gchar *tarfilename,
 GPtrArray 	*pk_generate_pack_scan_dir			(const gchar *directory);
 gboolean	 pk_generate_pack_main				(const gchar *pack_filename,
 								 const gchar *directory,
-								 const gchar *package,
+								 const gchar *package_id,
 								 const gchar *package_list,
 								 GError **error);
 
diff --git a/src/pk-service-pack.c b/src/pk-service-pack.c
index b5313e8..b9a4a6c 100644
--- a/src/pk-service-pack.c
+++ b/src/pk-service-pack.c
@@ -273,13 +273,13 @@ pk_service_pack_set_exclude_list (PkServicePack *pack, PkPackageList *list)
 }
 
 /**
- * pk_service_pack_create_for_package:
+ * pk_service_pack_create_for_package_id:
  **/
 gboolean
-pk_service_pack_create_for_package (PkServicePack *pack, const gchar *package, GError **error)
+pk_service_pack_create_for_package_id (PkServicePack *pack, const gchar *package_id, GError **error)
 {
 	g_return_val_if_fail (PK_IS_SERVICE_PACK (pack), FALSE);
-	g_return_val_if_fail (package != NULL, FALSE);
+	g_return_val_if_fail (package_id != NULL, FALSE);
 	g_return_val_if_fail (pack->priv->filename != NULL, FALSE);
 	g_return_val_if_fail (pack->priv->directory != NULL, FALSE);
 	return TRUE;
diff --git a/src/pk-service-pack.h b/src/pk-service-pack.h
index 89174a3..3d497be 100644
--- a/src/pk-service-pack.h
+++ b/src/pk-service-pack.h
@@ -62,8 +62,8 @@ gboolean	 pk_service_pack_set_temp_directory		(PkServicePack	*pack,
 gboolean	 pk_service_pack_set_exclude_list		(PkServicePack	*pack,
 								 PkPackageList	*list);
 
-gboolean	 pk_service_pack_create_for_package		(PkServicePack	*pack,
-								 const gchar	*package,
+gboolean	 pk_service_pack_create_for_package_id		(PkServicePack	*pack,
+								 const gchar	*package_id,
 								 GError		**error);
 gboolean	 pk_service_pack_create_for_updates		(PkServicePack	*pack,
 								 GError		**error);
commit 554e1bb183c63930288d4bb6e53bf10bbd2e89c0
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 8 11:33:53 2008 +0100

    trivial: setup PkServicePack state in pkgenpack

diff --git a/client/pk-generate-pack-main.c b/client/pk-generate-pack-main.c
index cd20ae7..6dba1b4 100644
--- a/client/pk-generate-pack-main.c
+++ b/client/pk-generate-pack-main.c
@@ -36,9 +36,11 @@
 #include <pk-client.h>
 #include <pk-control.h>
 #include <pk-common.h>
+#include <pk-package-list.h>
 
 #include "pk-tools-common.h"
 #include "pk-generate-pack.h"
+#include "pk-service-pack.h"
 
 /**
  * pk_generate_pack_get_filename:
@@ -76,6 +78,8 @@ main (int argc, char *argv[])
 	gchar *tempdir = NULL;
 	gboolean exists;
 	gboolean overwrite;
+	PkServicePack *pack = NULL;
+	PkPackageList *list = NULL;
 
 	gboolean verbose = FALSE;
 	gchar *directory = NULL;
@@ -175,6 +179,20 @@ main (int argc, char *argv[])
 		return 1;
 	}
 
+	/* get the exclude list */
+	list = pk_package_list_new ();
+	ret = pk_package_list_add_file (list, package_list);
+	if (!ret) {
+		g_print ("%s: %s\n", _("Failed to open package list"), package_list);
+		goto out;
+	}
+
+	/* create pack and set initial values */
+	pack = pk_service_pack_new ();
+	pk_service_pack_set_filename (pack, filename);
+	pk_service_pack_set_temp_directory (pack, tempdir);
+	pk_service_pack_set_exclude_list (pack, list);
+
 	/* generate the pack */
 	g_print (_("Creating service pack: %s\n"), filename);
 	ret = pk_generate_pack_main (filename, tempdir, package, package_list, &error);
@@ -188,6 +206,11 @@ main (int argc, char *argv[])
 out:
 	/* get rid of temp directory */
 	g_rmdir (tempdir);
+
+	if (pack != NULL)
+		g_object_unref (pack);
+	if (list != NULL)
+		g_object_unref (list);
 	g_free (tempdir);
 	g_free (filename);
 	g_free (directory);
commit 1832a7f25ba18334c8036b21cd198c77944c6b25
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 8 11:26:52 2008 +0100

    trivial: symlink pk-package-list to client

diff --git a/client/Makefile.am b/client/Makefile.am
index e83ba3d..bc79b07 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -71,6 +71,8 @@ pkgenpack_SOURCES =					\
 	pk-generate-pack-main.c				\
 	pk-generate-pack.c				\
 	pk-generate-pack.h				\
+	pk-service-pack.c				\
+	pk-service-pack.h				\
 	pk-tools-common.c				\
 	pk-tools-common.h				\
 	$(NULL)
diff --git a/client/pk-service-pack.c b/client/pk-service-pack.c
new file mode 120000
index 0000000..e8dbe96
--- /dev/null
+++ b/client/pk-service-pack.c
@@ -0,0 +1 @@
+../src/pk-service-pack.c
\ No newline at end of file
diff --git a/client/pk-service-pack.h b/client/pk-service-pack.h
new file mode 120000
index 0000000..700ac31
--- /dev/null
+++ b/client/pk-service-pack.h
@@ -0,0 +1 @@
+../src/pk-service-pack.h
\ No newline at end of file
commit 93650442a68b96349d515669d8dea0d03f178189
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 8 11:24:40 2008 +0100

    trivial: add some more stubs in PkServicePack

diff --git a/src/pk-service-pack.c b/src/pk-service-pack.c
index 1aab25e..b5313e8 100644
--- a/src/pk-service-pack.c
+++ b/src/pk-service-pack.c
@@ -42,7 +42,9 @@
 
 struct PkServicePackPrivate
 {
-	PkPackageList		*list;
+	PkPackageList		*exclude_list;
+	gchar			*filename;
+	gchar			*directory;
 };
 
 G_DEFINE_TYPE (PkServicePack, pk_service_pack, G_TYPE_OBJECT)
@@ -181,7 +183,7 @@ pk_service_pack_extract (const gchar *filename, const gchar *directory, GError *
  * pk_service_pack_check_valid:
  **/
 gboolean
-pk_service_pack_check_valid (PkServicePack *pack, const gchar *filename, GError **error)
+pk_service_pack_check_valid (PkServicePack *pack, GError **error)
 {
 	gboolean ret = TRUE;
 	gchar *directory = NULL;
@@ -191,12 +193,13 @@ pk_service_pack_check_valid (PkServicePack *pack, const gchar *filename, GError
 	GError *error_local = NULL;
 
 	g_return_val_if_fail (PK_IS_SERVICE_PACK (pack), FALSE);
+	g_return_val_if_fail (pack->priv->filename != NULL, FALSE);
 
 	/* ITS4: ignore, the user has no control over the daemon envp  */
 	directory = g_build_filename (g_get_tmp_dir (), "meta", NULL);
-	ret = pk_service_pack_extract (filename, directory, &error_local);
+	ret = pk_service_pack_extract (pack->priv->filename, directory, &error_local);
 	if (!ret) {
-		*error = g_error_new (1, 0, "failed to check %s: %s", filename, error_local->message);
+		*error = g_error_new (1, 0, "failed to check %s: %s", pack->priv->filename, error_local->message);
 		g_error_free (error_local);
 		goto out;
 	}
@@ -215,7 +218,7 @@ pk_service_pack_check_valid (PkServicePack *pack, const gchar *filename, GError
 		if (egg_strequal (filename_entry, "metadata.conf")) {
 			ret = pk_service_pack_check_metadata_file (metafile);
 			if (!ret) {
-				*error = g_error_new (1, 0, "Service Pack %s not compatible with your distro", filename);
+				*error = g_error_new (1, 0, "Service Pack %s not compatible with your distro", pack->priv->filename);
 				ret = FALSE;
 				goto out;
 			}
@@ -230,6 +233,71 @@ out:
 }
 
 /**
+ * pk_service_pack_set_filename:
+ **/
+gboolean
+pk_service_pack_set_filename (PkServicePack *pack, const gchar *filename)
+{
+	g_return_val_if_fail (PK_IS_SERVICE_PACK (pack), FALSE);
+	g_return_val_if_fail (filename != NULL, FALSE);
+	g_free (pack->priv->filename);
+	pack->priv->filename = g_strdup (filename);
+	return TRUE;
+}
+
+/**
+ * pk_service_pack_set_temp_directory:
+ **/
+gboolean
+pk_service_pack_set_temp_directory (PkServicePack *pack, const gchar *directory)
+{
+	g_return_val_if_fail (PK_IS_SERVICE_PACK (pack), FALSE);
+	g_return_val_if_fail (directory != NULL, FALSE);
+	g_free (pack->priv->directory);
+	pack->priv->directory = g_strdup (directory);
+	return TRUE;
+}
+
+/**
+ * pk_service_pack_set_exclude_list:
+ **/
+gboolean
+pk_service_pack_set_exclude_list (PkServicePack *pack, PkPackageList *list)
+{
+	g_return_val_if_fail (PK_IS_SERVICE_PACK (pack), FALSE);
+	g_return_val_if_fail (list != NULL, FALSE);
+	if (pack->priv->exclude_list != NULL)
+		g_object_unref (pack->priv->exclude_list);
+	pack->priv->exclude_list = g_object_ref (list);
+	return TRUE;
+}
+
+/**
+ * pk_service_pack_create_for_package:
+ **/
+gboolean
+pk_service_pack_create_for_package (PkServicePack *pack, const gchar *package, GError **error)
+{
+	g_return_val_if_fail (PK_IS_SERVICE_PACK (pack), FALSE);
+	g_return_val_if_fail (package != NULL, FALSE);
+	g_return_val_if_fail (pack->priv->filename != NULL, FALSE);
+	g_return_val_if_fail (pack->priv->directory != NULL, FALSE);
+	return TRUE;
+}
+
+/**
+ * pk_service_pack_create_for_updates:
+ **/
+gboolean
+pk_service_pack_create_for_updates (PkServicePack *pack, GError **error)
+{
+	g_return_val_if_fail (PK_IS_SERVICE_PACK (pack), FALSE);
+	g_return_val_if_fail (pack->priv->filename != NULL, FALSE);
+	g_return_val_if_fail (pack->priv->directory != NULL, FALSE);
+	return TRUE;
+}
+
+/**
  * pk_service_pack_finalize:
  **/
 static void
@@ -241,6 +309,11 @@ pk_service_pack_finalize (GObject *object)
 	g_return_if_fail (PK_IS_SERVICE_PACK (object));
 	pack = PK_SERVICE_PACK (object);
 
+	if (pack->priv->exclude_list != NULL)
+		g_object_unref (pack->priv->exclude_list);
+	g_free (pack->priv->directory);
+	g_free (pack->priv->filename);
+
 	G_OBJECT_CLASS (pk_service_pack_parent_class)->finalize (object);
 }
 
@@ -262,6 +335,9 @@ static void
 pk_service_pack_init (PkServicePack *pack)
 {
 	pack->priv = PK_SERVICE_PACK_GET_PRIVATE (pack);
+	pack->priv->exclude_list = NULL;
+	pack->priv->filename = NULL;
+	pack->priv->directory = NULL;
 }
 
 /**
diff --git a/src/pk-service-pack.h b/src/pk-service-pack.h
index 05eeb6c..89174a3 100644
--- a/src/pk-service-pack.h
+++ b/src/pk-service-pack.h
@@ -52,7 +52,6 @@ PkServicePack	*pk_service_pack_new				(void);
 
 /* used by the server */
 gboolean	 pk_service_pack_check_valid			(PkServicePack	*pack,
-								 const gchar	*filename,
 								 GError		**error);
 
 /* used by clients */
diff --git a/src/pk-transaction.c b/src/pk-transaction.c
index b9ed840..b8a71fc 100644
--- a/src/pk-transaction.c
+++ b/src/pk-transaction.c
@@ -2378,7 +2378,8 @@ pk_transaction_install_files (PkTransaction *transaction, gboolean trusted,
 		/* valid */
 		if (g_str_has_suffix (full_paths[i], ".servicepack")) {
 			service_pack = pk_service_pack_new ();
-			ret = pk_service_pack_check_valid (service_pack, full_paths[i], &error_local);
+			pk_service_pack_set_filename (service_pack, full_paths[i]);
+			ret = pk_service_pack_check_valid (service_pack, &error_local);
 			g_object_unref (service_pack);
 			if (!ret) {
 				error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_PACK_INVALID, "%s", error_local->message);
commit 7a7c23b17c242fc4797c9e580a1bb2b3ebfd5471
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 8 11:15:04 2008 +0100

    trivial: move the service pack checking out of PkTransaction and into PkServicePack, no functional code changes

diff --git a/src/pk-service-pack.c b/src/pk-service-pack.c
index d58166d..1aab25e 100644
--- a/src/pk-service-pack.c
+++ b/src/pk-service-pack.c
@@ -23,10 +23,18 @@
 #  include <config.h>
 #endif
 
+#ifdef HAVE_ARCHIVE_H
+#include <archive.h>
+#include <archive_entry.h>
+#endif /* HAVE_ARCHIVE_H */
+
 #include <glib.h>
-#include <glib/gi18n.h>
+#include <glib/gstdio.h>
 
 #include "egg-debug.h"
+#include "egg-string.h"
+
+#include <pk-common.h>
 
 #include "pk-service-pack.h"
 
@@ -39,14 +47,186 @@ struct PkServicePackPrivate
 
 G_DEFINE_TYPE (PkServicePack, pk_service_pack, G_TYPE_OBJECT)
 
+
+/**
+ * pk_service_pack_check_metadata_file:
+ **/
+static gboolean
+pk_service_pack_check_metadata_file (const gchar *full_path)
+{
+	GKeyFile *file;
+	gboolean ret;
+	GError *error = NULL;
+	gchar *distro_id = NULL;
+	gchar *distro_id_us = NULL;
+
+	/* load the file */
+	file = g_key_file_new ();
+	ret = g_key_file_load_from_file (file, full_path, G_KEY_FILE_NONE, &error);
+	if (!ret) {
+		egg_warning ("failed to load file: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* read the value */
+	distro_id = g_key_file_get_string (file, PK_SERVICE_PACK_GROUP_NAME, "distro_id", &error);
+	if (!ret) {
+		egg_warning ("failed to get value: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* get this system id */
+	distro_id_us = pk_get_distro_id ();
+
+	/* do we match? */
+	ret = egg_strequal (distro_id_us, distro_id);
+
+out:
+	g_key_file_free (file);
+	g_free (distro_id);
+	g_free (distro_id_us);
+	return ret;
+}
+
+/**
+ * pk_service_pack_extract:
+ * @directory: the directory to unpack into
+ * @error: a valid %GError
+ *
+ * Decompress a tar file
+ *
+ * Return value: %TRUE if the file was decompressed
+ **/
+#ifdef HAVE_ARCHIVE_H
+static gboolean
+pk_service_pack_extract (const gchar *filename, const gchar *directory, GError **error)
+{
+	gboolean ret = FALSE;
+	struct archive *arch = NULL;
+	struct archive_entry *entry;
+	int r;
+	int retval;
+	gchar *retcwd;
+	gchar buf[PATH_MAX];
+
+	/* save the PWD as we chdir to extract */
+	retcwd = getcwd (buf, PATH_MAX);
+	if (retcwd == NULL) {
+		*error = g_error_new (1, 0, "failed to get cwd");
+		goto out;
+	}
+
+	/* we can only read tar achives */
+	arch = archive_read_new ();
+	archive_read_support_format_tar (arch);
+
+	/* open the tar file */
+	r = archive_read_open_file (arch, filename, 10240);
+	if (r) {
+		*error = g_error_new (1, 0, "cannot open: %s", archive_error_string (arch));
+		goto out;
+	}
+
+	/* switch to our destination directory */
+	retval = chdir (directory);
+	if (retval != 0) {
+		*error = g_error_new (1, 0, "failed chdir to %s", directory);
+		goto out;
+	}
+
+	/* decompress each file */
+	for (;;) {
+		r = archive_read_next_header (arch, &entry);
+		if (r == ARCHIVE_EOF)
+			break;
+		if (r != ARCHIVE_OK) {
+			*error = g_error_new (1, 0, "cannot read header: %s", archive_error_string (arch));
+			goto out;
+		}
+		r = archive_read_extract (arch, entry, 0);
+		if (r != ARCHIVE_OK) {
+			*error = g_error_new (1, 0, "cannot extract: %s", archive_error_string (arch));
+			goto out;
+		}
+	}
+
+	/* completed all okay */
+	ret = TRUE;
+out:
+	/* close the archive */
+	if (arch != NULL) {
+		archive_read_close (arch);
+		archive_read_finish (arch);
+	}
+
+	/* switch back to PWD */
+	retval = chdir (buf);
+	if (retval != 0)
+		egg_warning ("cannot chdir back!");
+
+	return ret;
+}
+#else /* HAVE_ARCHIVE_H */
+gboolean
+pk_service_pack_extract (const gchar *filename, const gchar *directory, GError **error)
+{
+	*error = g_error_new (1, 0, "Cannot check PackageKit as not built with libarchive support");
+	return FALSE;
+}
+#endif /* HAVE_ARCHIVE_H */
+
 /**
  * pk_service_pack_check_valid:
  **/
 gboolean
 pk_service_pack_check_valid (PkServicePack *pack, const gchar *filename, GError **error)
 {
+	gboolean ret = TRUE;
+	gchar *directory = NULL;
+	gchar *metafile = NULL;
+	GDir *dir = NULL;
+	const gchar *filename_entry;
+	GError *error_local = NULL;
+
 	g_return_val_if_fail (PK_IS_SERVICE_PACK (pack), FALSE);
-	return TRUE;
+
+	/* ITS4: ignore, the user has no control over the daemon envp  */
+	directory = g_build_filename (g_get_tmp_dir (), "meta", NULL);
+	ret = pk_service_pack_extract (filename, directory, &error_local);
+	if (!ret) {
+		*error = g_error_new (1, 0, "failed to check %s: %s", filename, error_local->message);
+		g_error_free (error_local);
+		goto out;
+	}
+
+	/* get the files */
+	dir = g_dir_open (directory, 0, NULL);
+	if (dir == NULL) {
+		*error = g_error_new (1, 0, "failed to get directory for %s", directory);
+		ret = FALSE;
+		goto out;
+	}
+
+	/* find the file, and check the metadata */
+	while ((filename_entry = g_dir_read_name (dir))) {
+		metafile = g_build_filename (directory, filename_entry, NULL);
+		if (egg_strequal (filename_entry, "metadata.conf")) {
+			ret = pk_service_pack_check_metadata_file (metafile);
+			if (!ret) {
+				*error = g_error_new (1, 0, "Service Pack %s not compatible with your distro", filename);
+				ret = FALSE;
+				goto out;
+			}
+		}
+		g_free (metafile);
+	}
+out:
+	g_rmdir (directory);
+	g_free (directory);
+	g_dir_close (dir);
+	return ret;
 }
 
 /**
diff --git a/src/pk-transaction.c b/src/pk-transaction.c
index 96d0467..b9ed840 100644
--- a/src/pk-transaction.c
+++ b/src/pk-transaction.c
@@ -41,11 +41,6 @@
 #include <dbus/dbus-glib.h>
 #include <dbus/dbus-glib-lowlevel.h>
 
-#ifdef HAVE_ARCHIVE_H
-#include <archive.h>
-#include <archive_entry.h>
-#endif /* HAVE_ARCHIVE_H */
-
 #include <pk-common.h>
 #include <pk-package-id.h>
 #include <pk-package-ids.h>
@@ -72,6 +67,7 @@
 #include "pk-notify.h"
 #include "pk-security.h"
 #include "pk-refresh.h"
+#include "pk-service-pack.h"
 
 static void     pk_transaction_class_init	(PkTransactionClass *klass);
 static void     pk_transaction_init		(PkTransaction      *transaction);
@@ -2335,185 +2331,6 @@ pk_transaction_get_updates (PkTransaction *transaction, const gchar *filter, DBu
 }
 
 /**
- * pk_transaction_check_metadata_conf:
- **/
-static gboolean
-pk_transaction_check_metadata_conf (const gchar *full_path)
-{
-	GKeyFile *file;
-	gboolean ret;
-	GError *error = NULL;
-	gchar *distro_id = NULL;
-	gchar *distro_id_us = NULL;
-
-	/* load the file */
-	file = g_key_file_new ();
-	ret = g_key_file_load_from_file (file, full_path, G_KEY_FILE_NONE, &error);
-	if (!ret) {
-		egg_warning ("failed to load file: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-	/* read the value */
-	distro_id = g_key_file_get_string (file, PK_SERVICE_PACK_GROUP_NAME, "distro_id", &error);
-	if (!ret) {
-		egg_warning ("failed to get value: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-	/* get this system id */
-	distro_id_us = pk_get_distro_id ();
-
-	/* do we match? */
-	ret = egg_strequal (distro_id_us, distro_id);
-
-out:
-	g_key_file_free (file);
-	g_free (distro_id);
-	g_free (distro_id_us);
-	return ret;
-}
-
-/**
- * pk_transaction_archive_extract:
- * @directory: the directory to unpack into
- * @error: a valid %GError
- *
- * Decompress a tar file
- *
- * Return value: %TRUE if the file was decompressed
- **/
-#ifdef HAVE_ARCHIVE_H
-gboolean
-pk_transaction_archive_extract (const gchar *filename, const gchar *directory, GError **error)
-{
-	gboolean ret = FALSE;
-	struct archive *arch = NULL;
-	struct archive_entry *entry;
-	int r;
-	int retval;
-	gchar *retcwd;
-	gchar buf[PATH_MAX];
-
-	/* save the PWD as we chdir to extract */
-	retcwd = getcwd (buf, PATH_MAX);
-	if (retcwd == NULL) {
-		*error = g_error_new (1, 0, "failed to get cwd");
-		goto out;
-	}
-
-	/* we can only read tar achives */
-	arch = archive_read_new ();
-	archive_read_support_format_tar (arch);
-
-	/* open the tar file */
-	r = archive_read_open_file (arch, filename, 10240);
-	if (r) {
-		*error = g_error_new (1, 0, "cannot open: %s", archive_error_string (arch));
-		goto out;
-	}
-
-	/* switch to our destination directory */
-	retval = chdir (directory);
-	if (retval != 0) {
-		*error = g_error_new (1, 0, "failed chdir to %s", directory);
-		goto out;
-	}
-
-	/* decompress each file */
-	for (;;) {
-		r = archive_read_next_header (arch, &entry);
-		if (r == ARCHIVE_EOF)
-			break;
-		if (r != ARCHIVE_OK) {
-			*error = g_error_new (1, 0, "cannot read header: %s", archive_error_string (arch));
-			goto out;
-		}
-		r = archive_read_extract (arch, entry, 0);
-		if (r != ARCHIVE_OK) {
-			*error = g_error_new (1, 0, "cannot extract: %s", archive_error_string (arch));
-			goto out;
-		}
-	}
-
-	/* completed all okay */
-	ret = TRUE;
-out:
-	/* close the archive */
-	if (arch != NULL) {
-		archive_read_close (arch);
-		archive_read_finish (arch);
-	}
-
-	/* switch back to PWD */
-	retval = chdir (buf);
-	if (retval != 0)
-		egg_warning ("cannot chdir back!");
-
-	return ret;
-}
-#else /* HAVE_ARCHIVE_H */
-gboolean
-pk_transaction_archive_extract (const gchar *filename, const gchar *directory, GError **error)
-{
-	*error = g_error_new (1, 0, "Cannot check PackageKit as not built with libarchive support");
-	return FALSE;
-}
-#endif /* HAVE_ARCHIVE_H */
-
-/**
- * pk_transaction_check_pack_distro_id:
- **/
-static gboolean
-pk_transaction_check_pack_distro_id (const gchar *full_path, gchar **failure)
-{
-	gboolean ret = TRUE;
-	gchar *meta_src = NULL;
-	gchar *metafile = NULL;
-	GDir *dir = NULL;
-	const gchar *filename;
-	GError *error = NULL;
-
-	/* ITS4: ignore, the user has no control over the daemon envp  */
-	meta_src = g_build_filename (g_get_tmp_dir (), "meta", NULL);
-	ret = pk_transaction_archive_extract (full_path, meta_src, &error);
-	if (!ret) {
-		*failure = g_strdup_printf ("failed to check %s: %s", full_path, error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-	/* get the files */
-	dir = g_dir_open (meta_src, 0, NULL);
-	if (dir == NULL) {
-		*failure = g_strdup_printf ("failed to get directory for %s", meta_src);
-		ret = FALSE;
-		goto out;
-	}
-
-	/* find the file, and check the metadata */
-	while ((filename = g_dir_read_name (dir))) {
-		metafile = g_build_filename (meta_src, filename, NULL);
-		if (egg_strequal (filename, "metadata.conf")) {
-			ret = pk_transaction_check_metadata_conf (metafile);
-			if (!ret) {
-				*failure = g_strdup_printf ("Service Pack %s not compatible with your distro", full_path);
-				ret = FALSE;
-				goto out;
-			}
-		}
-		g_free (metafile);
-	}
-out:
-	g_rmdir (meta_src);
-	g_free (meta_src);
-	g_dir_close (dir);
-	return ret;
-}
-
-/**
  * pk_transaction_install_files:
  **/
 void
@@ -2523,8 +2340,9 @@ pk_transaction_install_files (PkTransaction *transaction, gboolean trusted,
 	gchar *full_paths_temp;
 	gboolean ret;
 	GError *error;
+	GError *error_local = NULL;
+	PkServicePack *service_pack;
 	gchar *sender;
-	gchar *failure = NULL;
 	guint length;
 	guint i;
 
@@ -2547,6 +2365,7 @@ pk_transaction_install_files (PkTransaction *transaction, gboolean trusted,
 
 	/* check all files exists and are valid */
 	length = g_strv_length (full_paths);
+
 	for (i=0; i<length; i++) {
 		/* exists */
 		ret = g_file_test (full_paths[i], G_FILE_TEST_EXISTS);
@@ -2558,11 +2377,13 @@ pk_transaction_install_files (PkTransaction *transaction, gboolean trusted,
 		}
 		/* valid */
 		if (g_str_has_suffix (full_paths[i], ".servicepack")) {
-			ret = pk_transaction_check_pack_distro_id (full_paths[i], &failure);
+			service_pack = pk_service_pack_new ();
+			ret = pk_service_pack_check_valid (service_pack, full_paths[i], &error_local);
+			g_object_unref (service_pack);
 			if (!ret) {
-				error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_PACK_INVALID, "%s", failure);
+				error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_PACK_INVALID, "%s", error_local->message);
 				dbus_g_method_return_error (context, error);
-				g_free (failure);
+				g_error_free (error_local);
 				return;
 			}
 		}
commit a52ac40a32e51c688a7746c4fc1e5fabd2000eac
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 8 11:02:20 2008 +0100

    trivial: add the skeleton shell of a PkServicePack GObject to make some of the code a little more managable

diff --git a/src/Makefile.am b/src/Makefile.am
index bebee18..0b04919 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -53,6 +53,8 @@ shared_SOURCES =					\
 	egg-dbus-monitor.h				\
 	pk-marshal.c					\
 	pk-marshal.h					\
+	pk-service-pack.c				\
+	pk-service-pack.h				\
 	pk-transaction.c				\
 	pk-transaction.h				\
 	pk-backend.c					\
diff --git a/src/pk-service-pack.c b/src/pk-service-pack.c
new file mode 100644
index 0000000..d58166d
--- /dev/null
+++ b/src/pk-service-pack.c
@@ -0,0 +1,123 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Richard Hughes <richard at hughsie.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#include "egg-debug.h"
+
+#include "pk-service-pack.h"
+
+#define PK_SERVICE_PACK_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_SERVICE_PACK, PkServicePackPrivate))
+
+struct PkServicePackPrivate
+{
+	PkPackageList		*list;
+};
+
+G_DEFINE_TYPE (PkServicePack, pk_service_pack, G_TYPE_OBJECT)
+
+/**
+ * pk_service_pack_check_valid:
+ **/
+gboolean
+pk_service_pack_check_valid (PkServicePack *pack, const gchar *filename, GError **error)
+{
+	g_return_val_if_fail (PK_IS_SERVICE_PACK (pack), FALSE);
+	return TRUE;
+}
+
+/**
+ * pk_service_pack_finalize:
+ **/
+static void
+pk_service_pack_finalize (GObject *object)
+{
+	PkServicePack *pack;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (PK_IS_SERVICE_PACK (object));
+	pack = PK_SERVICE_PACK (object);
+
+	G_OBJECT_CLASS (pk_service_pack_parent_class)->finalize (object);
+}
+
+/**
+ * pk_service_pack_class_init:
+ **/
+static void
+pk_service_pack_class_init (PkServicePackClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	object_class->finalize = pk_service_pack_finalize;
+	g_type_class_add_private (klass, sizeof (PkServicePackPrivate));
+}
+
+/**
+ * pk_service_pack_init:
+ **/
+static void
+pk_service_pack_init (PkServicePack *pack)
+{
+	pack->priv = PK_SERVICE_PACK_GET_PRIVATE (pack);
+}
+
+/**
+ * pk_service_pack_new:
+ * Return value: A new service_pack class instance.
+ **/
+PkServicePack *
+pk_service_pack_new (void)
+{
+	PkServicePack *pack;
+	pack = g_object_new (PK_TYPE_SERVICE_PACK, NULL);
+	return PK_SERVICE_PACK (pack);
+}
+
+/***************************************************************************
+ ***                          MAKE CHECK TESTS                           ***
+ ***************************************************************************/
+#ifdef EGG_TEST
+#include "egg-test.h"
+
+void
+egg_test_service_pack (EggTest *test)
+{
+	PkServicePack *pack;
+
+	if (!egg_test_start (test, "PkServicePack"))
+		return;
+
+	/************************************************************/
+	egg_test_title (test, "get an instance");
+	pack = pk_service_pack_new ();
+	egg_test_assert (test, pack != NULL);
+
+	g_object_unref (pack);
+
+	egg_test_end (test);
+}
+#endif
+
diff --git a/src/pk-service-pack.h b/src/pk-service-pack.h
new file mode 100644
index 0000000..05eeb6c
--- /dev/null
+++ b/src/pk-service-pack.h
@@ -0,0 +1,75 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Richard Hughes <richard at hughsie.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __PK_SERVICE_PACK_H
+#define __PK_SERVICE_PACK_H
+
+#include <glib-object.h>
+#include <pk-package-list.h>
+
+G_BEGIN_DECLS
+
+#define PK_TYPE_SERVICE_PACK		(pk_service_pack_get_type ())
+#define PK_SERVICE_PACK(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), PK_TYPE_SERVICE_PACK, PkServicePack))
+#define PK_SERVICE_PACK_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), PK_TYPE_SERVICE_PACK, PkServicePackClass))
+#define PK_IS_SERVICE_PACK(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), PK_TYPE_SERVICE_PACK))
+#define PK_IS_SERVICE_PACK_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), PK_TYPE_SERVICE_PACK))
+#define PK_SERVICE_PACK_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), PK_TYPE_SERVICE_PACK, PkServicePackClass))
+
+typedef struct PkServicePackPrivate PkServicePackPrivate;
+
+typedef struct
+{
+	GObject		      parent;
+	PkServicePackPrivate     *priv;
+} PkServicePack;
+
+typedef struct
+{
+	GObjectClass	parent_class;
+} PkServicePackClass;
+
+GType		 pk_service_pack_get_type			(void) G_GNUC_CONST;
+PkServicePack	*pk_service_pack_new				(void);
+
+/* used by the server */
+gboolean	 pk_service_pack_check_valid			(PkServicePack	*pack,
+								 const gchar	*filename,
+								 GError		**error);
+
+/* used by clients */
+gboolean	 pk_service_pack_set_filename			(PkServicePack	*pack,
+								 const gchar	*filename);
+gboolean	 pk_service_pack_set_temp_directory		(PkServicePack	*pack,
+								 const gchar	*directory);
+gboolean	 pk_service_pack_set_exclude_list		(PkServicePack	*pack,
+								 PkPackageList	*list);
+
+gboolean	 pk_service_pack_create_for_package		(PkServicePack	*pack,
+								 const gchar	*package,
+								 GError		**error);
+gboolean	 pk_service_pack_create_for_updates		(PkServicePack	*pack,
+								 GError		**error);
+
+G_END_DECLS
+
+#endif /* __PK_SERVICE_PACK_H */
+
commit a47afa8653d4a6820ada369d0924ccef146f2920
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 8 10:38:47 2008 +0100

    feature: make the command line parsing on pkgenpack more sane

diff --git a/client/pk-generate-pack-main.c b/client/pk-generate-pack-main.c
index 9655dc6..cd20ae7 100644
--- a/client/pk-generate-pack-main.c
+++ b/client/pk-generate-pack-main.c
@@ -31,45 +31,75 @@
 #include <glib/gstdio.h>
 #include <dbus/dbus-glib.h>
 
-#include <egg-debug.h>
+#include "egg-debug.h"
+
 #include <pk-client.h>
 #include <pk-control.h>
-
+#include <pk-common.h>
 
 #include "pk-tools-common.h"
 #include "pk-generate-pack.h"
 
+/**
+ * pk_generate_pack_get_filename:
+ **/
+static gchar *
+pk_generate_pack_get_filename (const gchar *name, const gchar *directory)
+{
+	gchar *filename = NULL;
+	gchar *distro_id;
+	gchar *iso_time = NULL;
+
+	distro_id = pk_get_distro_id ();
+	if (name != NULL) {
+		filename = g_strdup_printf ("%s/%s-%s.servicepack", directory, name, distro_id);
+	} else {
+		iso_time = pk_iso8601_present ();
+		filename = g_strdup_printf ("%s/updates-%s-%s.servicepack", directory, iso_time, distro_id);
+	}
+	g_free (distro_id);
+	g_free (iso_time);
+	return filename;
+}
+
 int
 main (int argc, char *argv[])
 {
 	GError *error = NULL;
-	gboolean verbose = FALSE;
-	gchar *with_package_list = NULL;
 	GOptionContext *context;
 	gchar *options_help;
 	gboolean ret;
 	guint retval;
-	const gchar *package = NULL;
-	gchar *pack_filename = NULL;
-	gchar *packname = NULL;
+	gchar *filename = NULL;
 	PkControl *control = NULL;
 	PkBitfield roles;
-	const gchar *package_list = NULL;
 	gchar *tempdir = NULL;
 	gboolean exists;
 	gboolean overwrite;
 
+	gboolean verbose = FALSE;
+	gchar *directory = NULL;
+	gchar *package_list = NULL;
+	gchar *package = NULL;
+	gboolean updates = FALSE;
+
 	const GOptionEntry options[] = {
 		{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
 			_("Show extra debugging information"), NULL },
-		{ "with-package-list", '\0', 0, G_OPTION_ARG_STRING, &with_package_list,
+		{ "with-package-list", 'l', 0, G_OPTION_ARG_STRING, &package_list,
 			_("Set the path of the file with the list of packages/dependencies to be excluded"), NULL},
+		{ "output", 'o', 0, G_OPTION_ARG_STRING, &directory,
+			_("The directory to put the pack file, or the current directory if ommitted"), NULL},
+		{ "package", 'i', 0, G_OPTION_ARG_STRING, &package,
+			_("The package to be put into the ServicePack"), NULL},
+		{ "updates", 'u', 0, G_OPTION_ARG_NONE, &updates,
+			_("Put all updates available in the ServicePack"), NULL},
 		{ NULL}
 	};
 
-	if (! g_thread_supported ()) {
+	if (! g_thread_supported ())
 		g_thread_init (NULL);
-	}
+
 	dbus_g_thread_init ();
 	g_type_init ();
 
@@ -81,17 +111,28 @@ main (int argc, char *argv[])
 	g_option_context_free (context);
 	egg_debug_init (verbose);
 
-	if (with_package_list != NULL) {
-		package_list = with_package_list;
-	} else {
-		package_list = "/var/lib/PackageKit/package-list.txt";
+	/* neither options selected */
+	if (package == NULL && !updates) {
+		g_print ("%s\n", _("Neither option selected"));
+		g_print ("%s", options_help);
+		return 1;
 	}
 
-	if (argc < 2) {
+	/* both options selected */
+	if (package != NULL && updates) {
+		g_print ("%s\n", _("Both optiosn selected"));
 		g_print ("%s", options_help);
 		return 1;
 	}
 
+	/* fall back to the system copy */
+	if (package_list == NULL)
+		package_list = g_strdup ("/var/lib/PackageKit/package-list.txt");
+
+	/* fall back to CWD */
+	if (directory == NULL)
+		directory = g_get_current_dir ();
+
 	/* are we dumb and can't check for depends? */
 	control = pk_control_new ();
 	roles = pk_control_get_actions (control, NULL);
@@ -100,29 +141,14 @@ main (int argc, char *argv[])
 		goto out;
 	}
 
-	/* get the arguments */
-	pack_filename = argv[1];
-	if (argc > 2) {
-		package = argv[2];
-	}
-
-	/* have we specified the right things */
-	if (pack_filename == NULL || package == NULL) {
-		g_print (_("You need to specify the pack name and packages to be packed\n"));
-		goto out;
-	}
-
-	/* check the suffix */
-	if (!g_str_has_suffix (pack_filename,".servicepack")) {
-		g_print(_("Invalid name for the service pack, Specify a name with .servicepack extension\n"));
-		goto out;
-	}
+	/* get fn */
+	filename = pk_generate_pack_get_filename (package, directory);
 
 	/* download packages to a temporary directory */
 	tempdir = g_build_filename (g_get_tmp_dir (), "pack", NULL);
 
 	/* check if file exists before we overwrite it */
-	exists = g_file_test (pack_filename, G_FILE_TEST_EXISTS);
+	exists = g_file_test (filename, G_FILE_TEST_EXISTS);
 
 	/*ask user input*/
 	if (exists) {
@@ -143,20 +169,29 @@ main (int argc, char *argv[])
 		goto out;
 	}
 
+	/* not yet */
+	if (updates) {
+		g_print ("Not working yet...\n");
+		return 1;
+	}
+
 	/* generate the pack */
-	ret = pk_generate_pack_main (pack_filename, tempdir, package, package_list, &error);
+	g_print (_("Creating service pack: %s\n"), filename);
+	ret = pk_generate_pack_main (filename, tempdir, package, package_list, &error);
 	if (!ret) {
 		g_print ("%s: %s\n", _("Failed to create pack"), error->message);
 		g_error_free (error);
 		goto out;
 	}
+	g_print ("%s\n", _("Done!"));
 
 out:
 	/* get rid of temp directory */
 	g_rmdir (tempdir);
 	g_free (tempdir);
-	g_free (packname);
-	g_free (with_package_list);
+	g_free (filename);
+	g_free (directory);
+	g_free (package_list);
 	g_free (options_help);
 	g_object_unref (control);
 	return 0;
commit f81f496231be015df365dae26bd21433f68e52a1
Merge: 054ae70... 643740f...
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Tue Oct 7 23:34:44 2008 +0200

    Merge branch 'master' of git+ssh://glatzor@git.packagekit.org/srv/git/PackageKit

commit 643740fe316f7b4a89991be9e694fdc03b48073b
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Oct 7 17:34:11 2008 +0100

    trivial: fix up the yum backend execption handlng printing

diff --git a/backends/yum/yumBackend.py b/backends/yum/yumBackend.py
index 07477e9..90de0ce 100755
--- a/backends/yum/yumBackend.py
+++ b/backends/yum/yumBackend.py
@@ -1381,7 +1381,7 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
             rc, msgs =  self.yumbase.buildTransaction()
         except yum.Errors.RepoError, e:
             self.error(ERROR_REPO_NOT_AVAILABLE, str(e))
-        except:
+        except Exception, e:
             self.error(ERROR_INTERNAL_ERROR, str(e))
         if rc != 2:
             self.error(ERROR_DEP_RESOLUTION_FAILED, _format_msgs(msgs))
@@ -1429,7 +1429,7 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
                     self.error(ERROR_PACKAGE_CONFLICTS, message)
                 else:
                     self.error(ERROR_TRANSACTION_ERROR, message)
-            except:
+            except Exception, e:
                 self.error(ERROR_INTERNAL_ERROR, str(e))
 
     def remove_packages(self, allowdep, package_ids):
commit 7f1892ee199f9c91451fa4b4d4b5b244bedd093c
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Oct 7 16:02:09 2008 +0100

    trivial: do the yum category icon fallback correctly

diff --git a/backends/yum/yumBackend.py b/backends/yum/yumBackend.py
index 2862142..07477e9 100755
--- a/backends/yum/yumBackend.py
+++ b/backends/yum/yumBackend.py
@@ -571,7 +571,7 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
             for grp_id in grps:
                 grp = self.yumbase.comps.return_group(grp_id)
                 if grp:
-                    cat_id = "@%s" % (grp_id)
+                    cat_id_name = "@%s" % (grp_id)
                     name = grp.nameByLang(self._lang)
                     summary = grp.descriptionByLang(self._lang)
                     icon = "image-missing"
@@ -582,7 +582,7 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
                         fn = "/usr/share/pixmaps/comps/%s.png" % cat_id
                         if os.access(fn, os.R_OK):
                             icon = cat_id
-                    self.category(cat, cat_id, name, summary, icon)
+                    self.category(cat, cat_id_name, name, summary, icon)
 
     def download_packages(self, directory, package_ids):
         '''
commit 7955eadf78a8a9a97026fd0195012ca1e42b52de
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Oct 7 15:34:02 2008 +0100

    trivial: update fedora spec file with icons link

diff --git a/contrib/PackageKit.spec.in b/contrib/PackageKit.spec.in
index 4351fc3..af33f7f 100644
--- a/contrib/PackageKit.spec.in
+++ b/contrib/PackageKit.spec.in
@@ -24,6 +24,7 @@ Requires: PackageKit-yum-plugin = %{version}-%{release}
 Requires: PackageKit-yum = %{version}-%{release}
 Requires: shared-mime-info
 Requires: python-sqlite2
+Requires: comps-extras
 
 BuildRequires: glib2-devel >= %{glib2_version}
 BuildRequires: dbus-devel  >= %{dbus_version}
@@ -179,6 +180,14 @@ pushd ${RPM_BUILD_ROOT}%{_libexecdir} > /dev/null
 ln -s pk-gstreamer-install gst-install-plugins-helper
 popd > /dev/null
 
+# create a link that from the comps icons to PK, as PackageKit frontends
+# cannot add /usr/share/pixmaps/comps to the icon search path as some distros
+# do not use comps. Patching this in the frontend is not a good idea, as there
+# are multiple frontends in multiple programming languages.
+pushd ${RPM_BUILD_ROOT}%{_datadir}/PackageKit > /dev/null
+ln -s ../pixmaps/comps icons
+popd > /dev/null
+
 %find_lang %name
 
 %clean
@@ -212,6 +221,7 @@ update-mime-database %{_datadir}/mime &> /dev/null || :
 %config(noreplace) %{_sysconfdir}/PackageKit/*.conf
 %config %{_sysconfdir}/dbus-1/system.d/*
 %dir %{_datadir}/PackageKit/helpers/test_spawn
+%dir %{_datadir}/PackageKit/icons
 %{_datadir}/PackageKit/helpers/test_spawn/*
 %{_datadir}/man/man1/*.1.gz
 %{_datadir}/PolicyKit/policy/*.policy
commit 96479a8a3e7b4226de15976808e4832c7ce038db
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Oct 7 14:27:13 2008 +0100

    yum: don't emit full paths for icons, just emit the icon name

diff --git a/backends/yum/yumBackend.py b/backends/yum/yumBackend.py
index 25d5a01..2862142 100755
--- a/backends/yum/yumBackend.py
+++ b/backends/yum/yumBackend.py
@@ -236,7 +236,7 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
         '''
         name = self._to_unicode(name)
         summary = self._to_unicode(summary)
-        PackageKitBaseBackend.category(self,parent_id,cat_id, name, summary, icon)
+        PackageKitBaseBackend.category(self, parent_id, cat_id, name, summary, icon)
 
     def _to_unicode(self, txt, encoding='utf-8'):
         if isinstance(txt, basestring):
@@ -367,7 +367,7 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
             self.error(ERROR_GROUP_LIST_INVALID, 'No groups could be found. A cache refresh should fix this.')
 
         pct = 20
-        old_pct = -1;
+        old_pct = -1
         step = (100.0 - pct) / len(collections)
         for col in collections:
             self._show_meta_package(col, fltlist)
@@ -411,10 +411,9 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
 
         # handle dynamic groups (yum comps group)
         if group_key[0] == '@':
-            id = group_key[1:]
-            print id
+            cat_id = group_key[1:]
              # get the packagelist for this group
-            all_packages = self.comps.get_meta_package_list(id)
+            all_packages = self.comps.get_meta_package_list(cat_id)
         else: # this is an group_enum
             # get the packagelist for this group enum
             all_packages = self.comps.get_package_list(group_key)
@@ -543,21 +542,21 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
         self.status(STATUS_QUERY)
         self.allow_cancel(True)
         for cat in self.yumbase.comps.categories:
-            id = cat.categoryid
+            cat_id = cat.categoryid
             # yum >= 3.2.10
             # name = cat.nameByLang(self._lang)
             # summary = cat.descriptionByLang(self._lang)
             name = cat.name
             summary = cat.description
-            fn = "/usr/share/pixmaps/comps/%s.png" % id
+            fn = "/usr/share/pixmaps/comps/%s.png" % cat_id
             if os.access(fn, os.R_OK):
-                icon = fn
+                icon = cat_id
             else:
-                icon = ""
-            self.category("",id,name,summary,icon)
-            self._get_groups(id)
+                icon = "image-missing"
+            self.category("", cat_id, name, summary, icon)
+            self._get_groups(cat_id)
 
-    def _get_groups(self,cat_id):
+    def _get_groups(self, cat_id):
         '''
         Implement the {backend}-get-collections functionality
         '''
@@ -572,20 +571,18 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
             for grp_id in grps:
                 grp = self.yumbase.comps.return_group(grp_id)
                 if grp:
-                    id = "@%s" % (grp_id)
+                    cat_id = "@%s" % (grp_id)
                     name = grp.nameByLang(self._lang)
                     summary = grp.descriptionByLang(self._lang)
-                    icon = ""
+                    icon = "image-missing"
                     fn = "/usr/share/pixmaps/comps/%s.png" % grp_id
                     if os.access(fn, os.R_OK):
-                        icon = fn
+                        icon = grp_id
                     else:
-                        fn = "/usr/share/pixmaps/comps/%s.png" % cat
+                        fn = "/usr/share/pixmaps/comps/%s.png" % cat_id
                         if os.access(fn, os.R_OK):
-                            icon = fn
-                    self.category(cat, id, name, summary, icon)
-
-
+                            icon = cat_id
+                    self.category(cat, cat_id, name, summary, icon)
 
     def download_packages(self, directory, package_ids):
         '''
@@ -969,7 +966,7 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
         # which we can emulate quicker by doing a transaction, but not
         # executing it
         if filters == FILTER_NOT_INSTALLED:
-            self._get_depends_not_installed (fltlist, package_ids,recursive)
+            self._get_depends_not_installed (fltlist, package_ids, recursive)
             return
 
         percentage = 0
commit 8d895866f1afbda94fb51436aad2b996d4141602
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Oct 7 14:23:20 2008 +0100

    trivial: dont print the summary or parent ID if not valid in pkcon

diff --git a/client/pk-console.c b/client/pk-console.c
index 144f9cd..05802b7 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -271,9 +271,11 @@ pk_console_category_cb (PkClient *client, const PkCategoryObj *obj, gpointer use
 	}
 	g_print ("Category  : %s\n", obj->name);
 	g_print (" cat_id   : %s\n", obj->cat_id);
-	g_print (" parent   : %s\n", obj->parent_id);
+	if (!egg_strzero (obj->parent_id))
+		g_print (" parent   : %s\n", obj->parent_id);
 	g_print (" name     : %s\n", obj->name);
-	g_print (" summary  : %s\n", obj->summary);
+	if (!egg_strzero (obj->summary))
+		g_print (" summary  : %s\n", obj->summary);
 	g_print (" icon     : %s\n", obj->icon);
 }
 
commit 6e4e2ca8dbe40870539bdadb830c0b0b6f249800
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Oct 7 14:22:46 2008 +0100

    trivial: be more strict and require an icon in the category

diff --git a/src/pk-backend-spawn.c b/src/pk-backend-spawn.c
index 5919389..741ba74 100644
--- a/src/pk-backend-spawn.c
+++ b/src/pk-backend-spawn.c
@@ -406,6 +406,16 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 			ret = FALSE;
 			goto out;
 		}
+		if (egg_strzero (sections[5])) {
+			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR, "icon cannot not blank");
+			ret = FALSE;
+			goto out;
+		}
+		if (g_str_has_prefix (sections[5], "/")) {
+			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR, "icon '%s' should be a named icon, not a path", sections[5]);
+			ret = FALSE;
+			goto out;
+		}
 		ret = pk_backend_category (backend_spawn->priv->backend, sections[1], sections[2], sections[3], sections[4], sections[5]);
 		goto out;
 	} else {
diff --git a/src/pk-interface-transaction.xml b/src/pk-interface-transaction.xml
index 6490eee..78c0aaf 100644
--- a/src/pk-interface-transaction.xml
+++ b/src/pk-interface-transaction.xml
@@ -1388,6 +1388,7 @@
           <doc:summary>
             <doc:para>
               The icon name for the category, e.g. <doc:tt>server-cfg</doc:tt>.
+              If the icon is not known, then it should be set to <doc:tt>image-missing</doc:tt>.
             </doc:para>
           </doc:summary>
         </doc:doc>
commit 44892109329007ac8f54200e4d718ae8474b3154
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Oct 7 13:48:34 2008 +0100

    trivial: remove unused struct member

diff --git a/libpackagekit/pk-category-obj.c b/libpackagekit/pk-category-obj.c
index be9b02a..e3a3954 100644
--- a/libpackagekit/pk-category-obj.c
+++ b/libpackagekit/pk-category-obj.c
@@ -48,7 +48,6 @@ pk_category_obj_new (void)
 {
 	PkCategoryObj *obj;
 	obj = g_new0 (PkCategoryObj, 1);
-	obj->parent = NULL;
 	obj->parent_id = NULL;
 	obj->cat_id = NULL;
 	obj->name = NULL;
diff --git a/libpackagekit/pk-category-obj.h b/libpackagekit/pk-category-obj.h
index 4bf2364..e4e47ca 100644
--- a/libpackagekit/pk-category-obj.h
+++ b/libpackagekit/pk-category-obj.h
@@ -33,7 +33,6 @@ G_BEGIN_DECLS
  **/
 typedef struct
 {
-	struct PkCategoryObj		*parent;
 	gchar				*parent_id;
 	gchar				*cat_id;
 	gchar				*name;
commit ac6ef18ef363249e92eaac10c23ac6c7b9db38db
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Oct 7 13:46:22 2008 +0100

    trivial: egg updates

diff --git a/libpackagekit/egg-obj-list.c b/libpackagekit/egg-obj-list.c
index a4c149c..9c1ae32 100644
--- a/libpackagekit/egg-obj-list.c
+++ b/libpackagekit/egg-obj-list.c
@@ -288,7 +288,6 @@ egg_obj_list_add_array (EggObjList *list, const GPtrArray *data)
 	gconstpointer obj;
 
 	g_return_if_fail (EGG_IS_OBJ_LIST (list));
-	g_return_if_fail (EGG_IS_OBJ_LIST (data));
 
 	/* add data items to list */
 	for (i=0; i < data->len; i++) {
commit e6873205beb92350b83f883ab793f5149e93706c
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Oct 7 12:57:53 2008 +0100

    trivial: add the convenience function egg_obj_list_add_array()

diff --git a/libpackagekit/egg-obj-list.c b/libpackagekit/egg-obj-list.c
index 7da1c5a..a4c149c 100644
--- a/libpackagekit/egg-obj-list.c
+++ b/libpackagekit/egg-obj-list.c
@@ -275,6 +275,29 @@ egg_obj_list_add_list (EggObjList *list, const EggObjList *data)
 }
 
 /**
+ * egg_obj_list_add_array:
+ *
+ * Makes a deep copy of the data in the array.
+ * The data going into the list MUST be the correct type,
+ * else bad things will happen.
+ **/
+void
+egg_obj_list_add_array (EggObjList *list, const GPtrArray *data)
+{
+	guint i;
+	gconstpointer obj;
+
+	g_return_if_fail (EGG_IS_OBJ_LIST (list));
+	g_return_if_fail (EGG_IS_OBJ_LIST (data));
+
+	/* add data items to list */
+	for (i=0; i < data->len; i++) {
+		obj = g_ptr_array_index (data, i);
+		egg_obj_list_add (list, obj);
+	}
+}
+
+/**
  * egg_obj_list_remove_list:
  *
  * Makes a deep copy of the list
diff --git a/libpackagekit/egg-obj-list.h b/libpackagekit/egg-obj-list.h
index f6bdd6b..3ccf01b 100644
--- a/libpackagekit/egg-obj-list.h
+++ b/libpackagekit/egg-obj-list.h
@@ -82,6 +82,8 @@ void		 egg_obj_list_add		(EggObjList		*list,
 						 gconstpointer		 data);
 void		 egg_obj_list_add_list		(EggObjList		*list,
 						 const EggObjList	*data);
+void		 egg_obj_list_add_array		(EggObjList		*list,
+						 const GPtrArray	*data);
 void		 egg_obj_list_remove_list	(EggObjList		*list,
 						 const EggObjList	*data);
 void		 egg_obj_list_remove_duplicate	(EggObjList		*list);
commit b0e5bda7b8ed2f715df0c148a48de1c64af3ec68
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Oct 7 12:22:04 2008 +0100

    feature: speed up filtering by nearly an order of magnitude of large lists using a dictionary. This speeds up GetPackages by 12 seconds

diff --git a/python/packagekit/filter.py b/python/packagekit/filter.py
index a64c012..243ed26 100644
--- a/python/packagekit/filter.py
+++ b/python/packagekit/filter.py
@@ -28,27 +28,28 @@ class PackagekitFilter(object, PackagekitPackage):
         ''' save state '''
         self.fltlist = fltlist
         self.package_list = [] #we can't do emitting as found if we are post-processing
-        self.installed_unique = []
+        self.installed_unique = {}
 
     def add_installed(self, pkgs):
         ''' add a list of packages that are already installed '''
         for pkg in pkgs:
             if self.pre_process(pkg):
                 self.package_list.append((pkg, INFO_INSTALLED))
-            self.installed_unique.append(self._pkg_get_unique(pkg))
+            nevra = self._pkg_get_unique(pkg)
+            self.installed_unique[nevra] = pkg
 
     def add_available(self, pkgs):
         ''' add a list of packages that are available '''
         for pkg in pkgs:
             nevra = self._pkg_get_unique(pkg)
-            if nevra not in self.installed_unique:
+            if not self.installed_unique.has_key(nevra):
                 if self.pre_process(pkg):
                     self.package_list.append((pkg, INFO_AVAILABLE))
 
     def add_custom(self, pkg, info):
         ''' add a custom packages indervidually '''
         nevra = self._pkg_get_unique(pkg)
-        if nevra not in self.installed_unique:
+        if not self.installed_unique.has_key(nevra):
             if self.pre_process(pkg):
                 self.package_list.append((pkg, info))
 
commit 660f7fc0e313b673cba75ddd83fc614832e58ac2
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Oct 7 10:47:29 2008 +0100

    trivial: add a new PkClient API call to get the cached objects. Nothing uses this yet

diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index af4610f..efe0758 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -48,6 +48,7 @@
 
 #include "egg-debug.h"
 #include "egg-string.h"
+#include "egg-obj-list.h"
 
 #include "pk-enum.h"
 #include "pk-bitfield.h"
@@ -86,6 +87,7 @@ struct _PkClientPrivate
 	gboolean		 synchronous;
 	gchar			*tid;
 	PkControl		*control;
+	EggObjList		*cached_data;
 	PkPackageList		*package_list;
 	PkConnection		*pconnection;
 	gulong			 pconnection_signal_id;
@@ -480,6 +482,25 @@ pk_client_get_package_list (PkClient *client)
 }
 
 /**
+ * pk_client_get_cached_objects:
+ * @client: a valid #PkClient instance
+ *
+ * Return the cached object list
+ *
+ * Return value: The #GPtrArray of cached objects or %NULL if invalid
+ **/
+const GPtrArray	*
+pk_client_get_cached_objects (PkClient *client)
+{
+	const GPtrArray *array;
+	g_return_val_if_fail (PK_IS_CLIENT (client), NULL);
+	if (!client->priv->use_buffer)
+		return NULL;
+	array = egg_obj_list_get_array (client->priv->cached_data);
+	return array;
+}
+
+/**
  * pk_client_destroy_cb:
  */
 static void
@@ -629,6 +650,11 @@ pk_client_distro_upgrade_cb (DBusGProxy *proxy, const gchar *type_text, const gc
 	obj = pk_distro_upgrade_obj_new_from_data  (type, name, summary);
 	egg_debug ("emitting distro_upgrade %s, %s, %s", type_text, name, summary);
 	g_signal_emit (client, signals [PK_CLIENT_DISTRO_UPGRADE], 0, obj);
+
+	/* cache */
+	if (client->priv->use_buffer || client->priv->synchronous)
+		egg_obj_list_add (client->priv->cached_data, obj);
+
 	pk_distro_upgrade_obj_free (obj);
 }
 
@@ -668,6 +694,10 @@ pk_client_update_detail_cb (DBusGProxy  *proxy, const gchar *package_id, const g
 						     issued, updated);
 	g_signal_emit (client, signals [PK_CLIENT_UPDATE_DETAIL], 0, detail);
 
+	/* cache */
+	if (client->priv->use_buffer || client->priv->synchronous)
+		egg_obj_list_add (client->priv->cached_data, detail);
+
 	if (issued != NULL)
 		g_date_free (issued);
 	if (updated != NULL)
@@ -692,6 +722,10 @@ pk_client_category_cb (DBusGProxy  *proxy, const gchar *parent_id, const gchar *
 	category = pk_category_obj_new_from_data (parent_id, cat_id, name, summary, icon);
 	g_signal_emit (client, signals [PK_CLIENT_CATEGORY], 0, category);
 
+	/* cache */
+	if (client->priv->use_buffer || client->priv->synchronous)
+		egg_obj_list_add (client->priv->cached_data, category);
+
 	pk_category_obj_free (category);
 }
 
@@ -717,6 +751,11 @@ pk_client_details_cb (DBusGProxy *proxy, const gchar *package_id, const gchar *l
 
 	details = pk_details_obj_new_from_data (id, license, group, description, url, size);
 	g_signal_emit (client, signals [PK_CLIENT_DETAILS], 0, details);
+
+	/* cache */
+	if (client->priv->use_buffer || client->priv->synchronous)
+		egg_obj_list_add (client->priv->cached_data, details);
+
 	pk_package_id_free (id);
 	pk_details_obj_free (details);
 }
@@ -1267,6 +1306,10 @@ pk_client_get_categories (PkClient *client, GError **error)
 	/* save this so we can re-issue it */
 	client->priv->role = PK_ROLE_ENUM_GET_CATEGORIES;
 
+	/* we use the cached objects support */
+	egg_obj_list_set_copy (client->priv->cached_data, (EggObjListCopyFunc) pk_category_obj_copy);
+	egg_obj_list_set_free (client->priv->cached_data, (EggObjListFreeFunc) pk_category_obj_free);
+
 	/* check to see if we have a valid proxy */
 	if (client->priv->proxy == NULL) {
 		pk_client_error_set (error, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction");
@@ -1974,6 +2017,10 @@ pk_client_get_update_detail (PkClient *client, gchar **package_ids, GError **err
 	client->priv->role = PK_ROLE_ENUM_GET_UPDATE_DETAIL;
 	client->priv->cached_package_ids = g_strdupv (package_ids);
 
+	/* we use the cached objects support */
+	egg_obj_list_set_copy (client->priv->cached_data, (EggObjListCopyFunc) pk_update_detail_obj_copy);
+	egg_obj_list_set_free (client->priv->cached_data, (EggObjListFreeFunc) pk_update_detail_obj_free);
+
 	/* check to see if we have a valid proxy */
 	if (client->priv->proxy == NULL) {
 		pk_client_error_set (error, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction");
@@ -2134,6 +2181,10 @@ pk_client_get_details (PkClient *client, gchar **package_ids, GError **error)
 	if (!ret)
 		return FALSE;
 
+	/* we use the cached objects support */
+	egg_obj_list_set_copy (client->priv->cached_data, (EggObjListCopyFunc) pk_details_obj_copy);
+	egg_obj_list_set_free (client->priv->cached_data, (EggObjListFreeFunc) pk_details_obj_free);
+
 	/* save this so we can re-issue it */
 	client->priv->role = PK_ROLE_ENUM_GET_DETAILS;
 	client->priv->cached_package_ids = g_strdupv (package_ids);
@@ -2184,6 +2235,10 @@ pk_client_get_distro_upgrades (PkClient *client, GError **error)
 	/* save this so we can re-issue it */
 	client->priv->role = PK_ROLE_ENUM_GET_DISTRO_UPGRADES;
 
+	/* we use the cached objects support */
+	egg_obj_list_set_copy (client->priv->cached_data, (EggObjListCopyFunc) pk_distro_upgrade_obj_copy);
+	egg_obj_list_set_free (client->priv->cached_data, (EggObjListFreeFunc) pk_distro_upgrade_obj_free);
+
 	/* check to see if we have a valid proxy */
 	if (client->priv->proxy == NULL) {
 		pk_client_error_set (error, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction");
@@ -3299,6 +3354,7 @@ pk_client_requeue (PkClient *client, GError **error)
 
 	/* clear package list */
 	pk_package_list_clear (client->priv->package_list);
+	egg_obj_list_clear (client->priv->cached_data);
 
 	/* do the correct action with the cached parameters */
 	if (priv->role == PK_ROLE_ENUM_GET_DEPENDS)
@@ -3919,6 +3975,7 @@ pk_client_reset (PkClient *client, GError **error)
 	client->priv->is_finished = FALSE;
 
 	pk_package_list_clear (client->priv->package_list);
+	egg_obj_list_clear (client->priv->cached_data);
 	return TRUE;
 }
 
@@ -3941,6 +3998,7 @@ pk_client_init (PkClient *client)
 	client->priv->is_finished = FALSE;
 	client->priv->is_finishing = FALSE;
 	client->priv->package_list = pk_package_list_new ();
+	client->priv->cached_data = egg_obj_list_new ();
 	client->priv->cached_package_id = NULL;
 	client->priv->cached_package_ids = NULL;
 	client->priv->cached_transaction_id = NULL;
@@ -4081,6 +4139,7 @@ pk_client_finalize (GObject *object)
 	pk_client_disconnect_proxy (client);
 	g_object_unref (client->priv->pconnection);
 	g_object_unref (client->priv->package_list);
+	g_object_unref (client->priv->cached_data);
 	g_object_unref (client->priv->control);
 
 	G_OBJECT_CLASS (pk_client_parent_class)->finalize (object);
diff --git a/libpackagekit/pk-client.h b/libpackagekit/pk-client.h
index 29d3b4e..f2cf2bc 100644
--- a/libpackagekit/pk-client.h
+++ b/libpackagekit/pk-client.h
@@ -346,6 +346,7 @@ gboolean	 pk_client_repo_set_data		(PkClient	*client,
 /* cached stuff */
 PkPackageList	*pk_client_get_package_list		(PkClient	*client);
 PkRestartEnum	 pk_client_get_require_restart		(PkClient	*client);
+const GPtrArray	*pk_client_get_cached_objects		(PkClient	*client);
 
 /* not job specific */
 gboolean	 pk_client_reset			(PkClient	*client,
commit cf52fbc88e4b2ce1fc1c89e0f6b434c74b4d8ede
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Oct 7 10:30:06 2008 +0100

    trivial: add a way to get the array data from a EggObjList

diff --git a/libpackagekit/egg-obj-list.c b/libpackagekit/egg-obj-list.c
index e64115b..7da1c5a 100644
--- a/libpackagekit/egg-obj-list.c
+++ b/libpackagekit/egg-obj-list.c
@@ -129,6 +129,19 @@ egg_obj_list_set_from_string (EggObjList *list, EggObjListFromStringFunc func)
 }
 
 /**
+ * egg_obj_list_get_array:
+ * @list: a valid #EggObjList instance
+ *
+ * Gets a GPtrArray representation of the package list
+ **/
+const GPtrArray	*
+egg_obj_list_get_array (const EggObjList *list)
+{
+	g_return_val_if_fail (EGG_IS_OBJ_LIST (list), NULL);
+	return list->priv->array;
+}
+
+/**
  * egg_obj_list_clear:
  * @list: a valid #EggObjList instance
  *
diff --git a/libpackagekit/egg-obj-list.h b/libpackagekit/egg-obj-list.h
index 5237df7..f6bdd6b 100644
--- a/libpackagekit/egg-obj-list.h
+++ b/libpackagekit/egg-obj-list.h
@@ -91,6 +91,7 @@ gboolean	 egg_obj_list_remove_index	(EggObjList		*list,
 						 guint			 index);
 gconstpointer	 egg_obj_list_index		(const EggObjList	*list,
 						 guint			 index);
+const GPtrArray	*egg_obj_list_get_array		(const EggObjList	*list);
 
 G_END_DECLS
 
commit 2197d002e86efe3e045018e5dfc67e39a47bf622
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Oct 7 10:29:03 2008 +0100

    trivial: add a check for parent_id == cat_id

diff --git a/src/pk-backend-spawn.c b/src/pk-backend-spawn.c
index 3c9cce4..5919389 100644
--- a/src/pk-backend-spawn.c
+++ b/src/pk-backend-spawn.c
@@ -391,6 +391,11 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 			ret = FALSE;
 			goto out;
 		}
+		if (egg_strequal (sections[1], sections[2])) {
+			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR, "cat_id cannot be the same as parent_id");
+			ret = FALSE;
+			goto out;
+		}
 		if (egg_strzero (sections[2])) {
 			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR, "cat_id cannot not blank");
 			ret = FALSE;
commit f67228fc36966d442d3234b760e5045693e9b91a
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Oct 7 10:09:50 2008 +0100

    feature: add support for getting the category list in PkClient and pkcon

diff --git a/client/pk-console.c b/client/pk-console.c
index bb2eb36..144f9cd 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -41,6 +41,7 @@
 #include <pk-common.h>
 #include <pk-connection.h>
 #include <pk-update-detail-obj.h>
+#include <pk-category-obj.h>
 #include <pk-distro-upgrade-obj.h>
 
 #include "pk-tools-common.h"
@@ -260,6 +261,23 @@ pk_console_distro_upgrade_cb (PkClient *client, const PkDistroUpgradeObj *obj, g
 }
 
 /**
+ * pk_console_category_cb:
+ **/
+static void
+pk_console_category_cb (PkClient *client, const PkCategoryObj *obj, gpointer user_data)
+{
+	if (awaiting_space) {
+		g_print ("\n");
+	}
+	g_print ("Category  : %s\n", obj->name);
+	g_print (" cat_id   : %s\n", obj->cat_id);
+	g_print (" parent   : %s\n", obj->parent_id);
+	g_print (" name     : %s\n", obj->name);
+	g_print (" summary  : %s\n", obj->summary);
+	g_print (" icon     : %s\n", obj->icon);
+}
+
+/**
  * pk_console_update_detail_cb:
  **/
 static void
@@ -1343,6 +1361,9 @@ pk_console_get_summary (PkBitfield roles)
 	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_ACCEPT_EULA)) {
 		g_string_append_printf (string, "  %s\n", "accept-eula [eula-id]");
 	}
+	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_GET_CATEGORIES)) {
+		g_string_append_printf (string, "  %s\n", "get-categories");
+	}
 	return g_string_free (string, FALSE);
 }
 
@@ -1447,6 +1468,8 @@ main (int argc, char *argv[])
 			  G_CALLBACK (pk_console_transaction_cb), NULL);
 	g_signal_connect (client, "distro-upgrade",
 			  G_CALLBACK (pk_console_distro_upgrade_cb), NULL);
+	g_signal_connect (client, "category",
+			  G_CALLBACK (pk_console_category_cb), NULL);
 	g_signal_connect (client, "details",
 			  G_CALLBACK (pk_console_details_cb), NULL);
 	g_signal_connect (client, "files",
@@ -1680,6 +1703,9 @@ main (int argc, char *argv[])
 	} else if (strcmp (mode, "get-updates") == 0) {
 		ret = pk_client_get_updates (client, filters, &error);
 
+	} else if (strcmp (mode, "get-categories") == 0) {
+		ret = pk_client_get_categories (client, &error);
+
 	} else if (strcmp (mode, "get-packages") == 0) {
 		ret = pk_client_get_packages (client, filters, &error);
 
diff --git a/libpackagekit/Makefile.am b/libpackagekit/Makefile.am
index 25fb1d7..ef1a439 100644
--- a/libpackagekit/Makefile.am
+++ b/libpackagekit/Makefile.am
@@ -28,6 +28,7 @@ libpackagekit_include_HEADERS =					\
 	pk-package-ids.h					\
 	pk-package-obj.h					\
 	pk-package-list.h					\
+	pk-category-obj.h					\
 	pk-update-detail-obj.h					\
 	pk-distro-upgrade-obj.h					\
 	pk-details-obj.h					\
@@ -63,6 +64,8 @@ libpackagekit_la_SOURCES =					\
 	pk-package-obj.h					\
 	pk-package-list.c					\
 	pk-package-list.h					\
+	pk-category-obj.c					\
+	pk-category-obj.h					\
 	pk-update-detail-obj.c					\
 	pk-update-detail-obj.h					\
 	pk-distro-upgrade-obj.c					\
diff --git a/libpackagekit/pk-category-obj.c b/libpackagekit/pk-category-obj.c
new file mode 100644
index 0000000..be9b02a
--- /dev/null
+++ b/libpackagekit/pk-category-obj.c
@@ -0,0 +1,145 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Richard Hughes <richard at hughsie.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more category.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:pk-category-obj
+ * @short_description: Functionality to create a category struct
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <glib/gi18n.h>
+
+#include "egg-debug.h"
+#include "pk-common.h"
+#include "pk-category-obj.h"
+
+/**
+ * pk_category_obj_new:
+ *
+ * Creates a new #PkCategoryObj object with default values
+ *
+ * Return value: a new #PkCategoryObj object
+ **/
+PkCategoryObj *
+pk_category_obj_new (void)
+{
+	PkCategoryObj *obj;
+	obj = g_new0 (PkCategoryObj, 1);
+	obj->parent = NULL;
+	obj->parent_id = NULL;
+	obj->cat_id = NULL;
+	obj->name = NULL;
+	obj->summary = NULL;
+	obj->icon = NULL;
+
+	return obj;
+}
+
+/**
+ * pk_category_obj_new_from_data:
+ *
+ * Creates a new #PkCategoryObj object with values.
+ *
+ * Return value: a new #PkCategoryObj object
+ **/
+PkCategoryObj *
+pk_category_obj_new_from_data (const gchar *parent_id, const gchar *cat_id, const gchar *name,
+			       const gchar *summary, const gchar *icon)
+{
+	PkCategoryObj *obj = NULL;
+
+	/* create new object */
+	obj = pk_category_obj_new ();
+	obj->parent_id = g_strdup (parent_id);
+	obj->cat_id = g_strdup (cat_id);
+	obj->name = g_strdup (name);
+	obj->summary = g_strdup (summary);
+	obj->icon = g_strdup (icon);
+
+	return obj;
+}
+
+/**
+ * pk_category_obj_copy:
+ *
+ * Return value: a new #PkCategoryObj object
+ **/
+PkCategoryObj *
+pk_category_obj_copy (const PkCategoryObj *obj)
+{
+	g_return_val_if_fail (obj != NULL, NULL);
+	return pk_category_obj_new_from_data (obj->parent_id, obj->cat_id, obj->name, obj->summary, obj->icon);
+}
+
+/**
+ * pk_category_obj_free:
+ * @obj: the #PkCategoryObj object
+ *
+ * Return value: %TRUE if the #PkCategoryObj object was freed.
+ **/
+gboolean
+pk_category_obj_free (PkCategoryObj *obj)
+{
+	if (obj == NULL)
+		return FALSE;
+	g_free (obj->parent_id);
+	g_free (obj->cat_id);
+	g_free (obj->name);
+	g_free (obj->summary);
+	g_free (obj->icon);
+	g_free (obj);
+	return TRUE;
+}
+
+/***************************************************************************
+ ***                          MAKE CHECK TESTS                           ***
+ ***************************************************************************/
+#ifdef EGG_TEST
+#include "egg-test.h"
+
+void
+pk_category_test (EggTest *test)
+{
+	gboolean ret;
+	PkCategoryObj *obj;
+
+	if (!egg_test_start (test, "PkCategoryObj"))
+		return;
+
+	/************************************************************/
+	egg_test_title (test, "get an category object");
+	obj = pk_category_obj_new ();
+	egg_test_assert (test, obj != NULL);
+
+	/************************************************************/
+	egg_test_title (test, "test category");
+	ret = pk_category_obj_free (obj);
+	egg_test_assert (test, ret);
+
+	egg_test_end (test);
+}
+#endif
+
diff --git a/libpackagekit/pk-category-obj.h b/libpackagekit/pk-category-obj.h
new file mode 100644
index 0000000..4bf2364
--- /dev/null
+++ b/libpackagekit/pk-category-obj.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Richard Hughes <richard at hughsie.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more category.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __PK_CATEGORY_H
+#define __PK_CATEGORY_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/**
+ * PkCategoryObj:
+ *
+ * Cached object to represent category about the package.
+ **/
+typedef struct
+{
+	struct PkCategoryObj		*parent;
+	gchar				*parent_id;
+	gchar				*cat_id;
+	gchar				*name;
+	gchar				*summary;
+	gchar				*icon;
+} PkCategoryObj;
+
+PkCategoryObj	*pk_category_obj_new			(void);
+PkCategoryObj	*pk_category_obj_copy			(const PkCategoryObj	*obj);
+PkCategoryObj	*pk_category_obj_new_from_data		(const gchar		*parent_id,
+							 const gchar		*cat_id,
+							 const gchar		*name,
+							 const gchar		*summary,
+							 const gchar		*icon);
+gboolean	 pk_category_obj_free			(PkCategoryObj		*obj);
+
+G_END_DECLS
+
+#endif /* __PK_CATEGORY_H */
diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index addb031..af4610f 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -61,6 +61,7 @@
 #include "pk-control.h"
 #include "pk-update-detail-obj.h"
 #include "pk-details-obj.h"
+#include "pk-category-obj.h"
 #include "pk-distro-upgrade-obj.h"
 
 static void     pk_client_class_init	(PkClientClass *klass);
@@ -676,6 +677,25 @@ pk_client_update_detail_cb (DBusGProxy  *proxy, const gchar *package_id, const g
 }
 
 /**
+ * pk_client_category_cb:
+ */
+static void
+pk_client_category_cb (DBusGProxy  *proxy, const gchar *parent_id, const gchar *cat_id,
+		       const gchar *name, const gchar *summary, const gchar *icon, PkClient *client)
+{
+	PkCategoryObj *category;
+
+	g_return_if_fail (PK_IS_CLIENT (client));
+
+	egg_debug ("emit category %s, %s, %s, %s, %s", parent_id, cat_id, name, summary, icon);
+
+	category = pk_category_obj_new_from_data (parent_id, cat_id, name, summary, icon);
+	g_signal_emit (client, signals [PK_CLIENT_CATEGORY], 0, category);
+
+	pk_category_obj_free (category);
+}
+
+/**
  * pk_client_details_cb:
  */
 static void
@@ -1223,6 +1243,50 @@ pk_client_get_updates (PkClient *client, PkBitfield filters, GError **error)
 }
 
 /**
+ * pk_client_get_categories:
+ * @client: a valid #PkClient instance
+ * @error: a %GError to put the error code and message in, or %NULL
+ *
+ * Get a list of all categories supported
+ *
+ * Return value: %TRUE if we got told the daemon to get the category list
+ **/
+gboolean
+pk_client_get_categories (PkClient *client, GError **error)
+{
+	gboolean ret;
+
+	g_return_val_if_fail (PK_IS_CLIENT (client), FALSE);
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+	/* get and set a new ID */
+	ret = pk_client_allocate_transaction_id (client, error);
+	if (!ret)
+		return FALSE;
+
+	/* save this so we can re-issue it */
+	client->priv->role = PK_ROLE_ENUM_GET_CATEGORIES;
+
+	/* check to see if we have a valid proxy */
+	if (client->priv->proxy == NULL) {
+		pk_client_error_set (error, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction");
+		return FALSE;
+	}
+	ret = dbus_g_proxy_call (client->priv->proxy, "GetCategories", error,
+				 G_TYPE_INVALID, G_TYPE_INVALID);
+	if (ret && !client->priv->is_finished) {
+		/* allow clients to respond in the status changed callback */
+		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
+
+		/* spin until finished */
+		if (client->priv->synchronous)
+			g_main_loop_run (client->priv->loop);
+	}
+	pk_client_error_fixup (error);
+	return ret;
+}
+
+/**
  * pk_client_update_system_action:
  **/
 static gboolean
@@ -3279,6 +3343,8 @@ pk_client_requeue (PkClient *client, GError **error)
 		ret = pk_client_update_system (client, error);
 	else if (priv->role == PK_ROLE_ENUM_GET_REPO_LIST)
 		ret = pk_client_get_repo_list (client, priv->cached_filters, error);
+	else if (priv->role == PK_ROLE_ENUM_GET_CATEGORIES)
+		ret = pk_client_get_categories (client, error);
 	else {
 		pk_client_error_set (error, PK_CLIENT_ERROR_ROLE_UNKNOWN, "role unknown for reque");
 		return FALSE;
@@ -3364,6 +3430,8 @@ pk_client_set_tid (PkClient *client, const gchar *tid, GError **error)
 	dbus_g_proxy_add_signal (proxy, "CallerActiveChanged", G_TYPE_BOOLEAN, G_TYPE_INVALID);
 	dbus_g_proxy_add_signal (proxy, "AllowCancel", G_TYPE_BOOLEAN, G_TYPE_INVALID);
 	dbus_g_proxy_add_signal (proxy, "Destroy", G_TYPE_INVALID);
+	dbus_g_proxy_add_signal (proxy, "Category", G_TYPE_STRING, G_TYPE_STRING,
+				 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
 
 	dbus_g_proxy_connect_signal (proxy, "Finished",
 				     G_CALLBACK (pk_client_finished_cb), client, NULL);
@@ -3399,6 +3467,8 @@ pk_client_set_tid (PkClient *client, const gchar *tid, GError **error)
 				     G_CALLBACK (pk_client_caller_active_changed_cb), client, NULL);
 	dbus_g_proxy_connect_signal (proxy, "AllowCancel",
 				     G_CALLBACK (pk_client_allow_cancel_cb), client, NULL);
+	dbus_g_proxy_connect_signal (proxy, "Category",
+				     G_CALLBACK (pk_client_category_cb), client, NULL);
 	dbus_g_proxy_connect_signal (proxy, "Destroy",
 				     G_CALLBACK (pk_client_destroy_cb), client, NULL);
 	client->priv->proxy = proxy;
@@ -3673,6 +3743,19 @@ pk_client_class_init (PkClientClass *klass)
 			      NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN,
 			      G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
 	/**
+	 * PkClient::category:
+	 * @client: the #PkClient instance that emitted the signal
+	 * @details: a pointer to a PkCategoryObj structure describing the category
+	 *
+	 * The ::category signal is emitted when GetCategories() is called.
+	 **/
+	signals [PK_CLIENT_CATEGORY] =
+		g_signal_new ("category",
+			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (PkClientClass, category),
+			      NULL, NULL, g_cclosure_marshal_VOID__POINTER,
+			      G_TYPE_NONE, 1, G_TYPE_POINTER);
+	/**
 	 * PkClient::finished:
 	 * @client: the #PkClient instance that emitted the signal
 	 * @exit: the #PkExitEnum status value, e.g. PK_EXIT_ENUM_SUCCESS
@@ -3959,6 +4042,10 @@ pk_client_init (PkClient *client)
 	dbus_g_object_register_marshaller (pk_marshal_VOID__STRING_STRING_BOOL_STRING_UINT_STRING,
 					   G_TYPE_NONE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN,
 					   G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID);
+	/* Category */
+	dbus_g_object_register_marshaller (pk_marshal_VOID__STRING_STRING_STRING_STRING_STRING,
+					   G_TYPE_NONE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+					   G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
 }
 
 /**
diff --git a/libpackagekit/pk-client.h b/libpackagekit/pk-client.h
index c53e33b..29d3b4e 100644
--- a/libpackagekit/pk-client.h
+++ b/libpackagekit/pk-client.h
@@ -143,12 +143,17 @@ struct _PkClientClass
 	void		(* finished)			(PkClient	*client,
 							 PkExitEnum	 exit,
 							 guint		 runtime);
+	void		(* category)			(PkClient	*client,
+							 const gchar	*parent_id,
+							 const gchar	*cat_id,
+							 const gchar	*name,
+							 const gchar	*summary,
+							 const gchar	*icon);
 	/* Padding for future expansion */
 	void (*_pk_reserved1) (void);
 	void (*_pk_reserved2) (void);
 	void (*_pk_reserved3) (void);
 	void (*_pk_reserved4) (void);
-	void (*_pk_reserved5) (void);
 };
 
 GQuark		 pk_client_error_quark			(void);
@@ -264,6 +269,9 @@ gboolean	 pk_client_get_files			(PkClient	*client,
 							 gchar		**package_ids,
 							 GError		**error)
 							 G_GNUC_WARN_UNUSED_RESULT;
+gboolean	 pk_client_get_categories		(PkClient	*client,
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_remove_packages		(PkClient	*client,
 							 gchar		**package_ids,
 							 gboolean	 allow_deps,
commit 330c1f09e4d1f031342d5ceacc619f73f02b5ee5
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Oct 7 09:40:15 2008 +0100

    trivial: fix the size of the category command in PkBackendSpawn

diff --git a/src/pk-backend-spawn.c b/src/pk-backend-spawn.c
index 768b041..3c9cce4 100644
--- a/src/pk-backend-spawn.c
+++ b/src/pk-backend-spawn.c
@@ -386,7 +386,7 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 		goto out;
 	} else if (egg_strequal (command, "category")) {
 
-		if (size != 5) {
+		if (size != 6) {
 			egg_warning ("invalid command '%s'", command);
 			ret = FALSE;
 			goto out;
commit 1a4fe302dec9372b49556140af1c3c358f2c58ca
Author: Tim Lauridsen <timlau at fedoraproject.org>
Date:   Tue Oct 7 07:33:34 2008 +0200

    python: use stdin.readline instead of raw_inout as it behave better process termination

diff --git a/python/packagekit/backend.py b/python/packagekit/backend.py
index 355a449..40fca97 100644
--- a/python/packagekit/backend.py
+++ b/python/packagekit/backend.py
@@ -606,8 +606,8 @@ class PackageKitBaseBackend:
         if len(args) > 0:
             self.dispatch_command(args[0], args[1:])
         while True:
-            line = raw_input('')
-            if line == 'exit':
+            line = sys.stdin.readline().strip('\n')
+            if not line or line == 'exit':
                 break
             args = line.split('\t')
             self.dispatch_command(args[0], args[1:])
commit b528b3bd3b11eaaef05f2d3accfad022347dba4a
Author: Tim Lauridsen <timlau at fedoraproject.org>
Date:   Tue Oct 7 07:27:24 2008 +0200

    python api: fixed cut & paste error

diff --git a/python/packagekit/client.py b/python/packagekit/client.py
index 053e3a4..fa7914a 100644
--- a/python/packagekit/client.py
+++ b/python/packagekit/client.py
@@ -129,7 +129,7 @@ class PackageKitClient:
         'license', 'group', 'description', 'upstream_url', 'size'.keys
         '''
         result = []
-        details_cb = lambda  parent_id, cat_id, name, summary, icon: result.append(
+        category_cb = lambda  parent_id, cat_id, name, summary, icon: result.append(
             PackageKitCategory( parent_id, cat_id, name, summary, icon))
 
         self._wrapCall(pk_xn, method, {'Category' : category_cb})
commit 67f4572707ce5a55d1e75211aa537a0e7c2c2cf7
Author: Tim Lauridsen <timlau at fedoraproject.org>
Date:   Tue Oct 7 07:11:10 2008 +0200

    yum: add support for categories

diff --git a/backends/yum/pk-backend-yum.c b/backends/yum/pk-backend-yum.c
index a5e7e86..7c11c0e 100644
--- a/backends/yum/pk-backend-yum.c
+++ b/backends/yum/pk-backend-yum.c
@@ -459,6 +459,15 @@ backend_what_provides (PkBackend *backend, PkBitfield filters, PkProvidesEnum pr
 	g_free (filters_text);
 }
 
+/**
+ * pk_backend_get_categories:
+ */
+static void
+backend_get_categories (PkBackend *backend)
+{
+	pk_backend_spawn_helper (spawn, "yumBackend.py", "get-categories", NULL);
+}
+
 PK_BACKEND_OPTIONS (
 	"YUM",					/* description */
 	"Tim Lauridsen <timlau at fedoraproject.org>, Richard Hughes <richard at hughsie.com>",	/* author */
@@ -469,7 +478,7 @@ PK_BACKEND_OPTIONS (
 	backend_get_mime_types,			/* get_mime_types */
 	backend_cancel,				/* cancel */
 	backend_download_packages,		/* download_packages */
-	NULL,					/* get_categories */
+	backend_get_categories,			/* get_categories */
 	backend_get_depends,			/* get_depends */
 	backend_get_details,			/* get_details */
 	backend_get_distro_upgrades,		/* get_distro_upgrades */
diff --git a/backends/yum/yumBackend.py b/backends/yum/yumBackend.py
index 1b4c426..25d5a01 100755
--- a/backends/yum/yumBackend.py
+++ b/backends/yum/yumBackend.py
@@ -236,7 +236,7 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
         '''
         name = self._to_unicode(name)
         summary = self._to_unicode(summary)
-        PackageKitBaseBackend.category(self, parent_id, cat_id, name, summary, icon)
+        PackageKitBaseBackend.category(self,parent_id,cat_id, name, summary, icon)
 
     def _to_unicode(self, txt, encoding='utf-8'):
         if isinstance(txt, basestring):
@@ -409,8 +409,15 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
             self._handle_collections(fltlist)
             return
 
-        # get the packagelist for this group
-        all_packages = self.comps.get_package_list(group_key)
+        # handle dynamic groups (yum comps group)
+        if group_key[0] == '@':
+            id = group_key[1:]
+            print id
+             # get the packagelist for this group
+            all_packages = self.comps.get_meta_package_list(id)
+        else: # this is an group_enum
+            # get the packagelist for this group enum
+            all_packages = self.comps.get_package_list(group_key)
 
         # group don't exits, just bail out
         if not all_packages:
@@ -529,6 +536,57 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
         package_list = pkgfilter.post_process()
         self._show_package_list(package_list)
 
+    def get_categories(self):
+        '''
+        Implement the {backend}-get-categories functionality
+        '''
+        self.status(STATUS_QUERY)
+        self.allow_cancel(True)
+        for cat in self.yumbase.comps.categories:
+            id = cat.categoryid
+            # yum >= 3.2.10
+            # name = cat.nameByLang(self._lang)
+            # summary = cat.descriptionByLang(self._lang)
+            name = cat.name
+            summary = cat.description
+            fn = "/usr/share/pixmaps/comps/%s.png" % id
+            if os.access(fn, os.R_OK):
+                icon = fn
+            else:
+                icon = ""
+            self.category("",id,name,summary,icon)
+            self._get_groups(id)
+
+    def _get_groups(self,cat_id):
+        '''
+        Implement the {backend}-get-collections functionality
+        '''
+        self.status(STATUS_QUERY)
+        self.allow_cancel(True)
+        if cat_id:
+            cats = [cat_id]
+        else:
+            cats =  [cat.categoryid for cat in self.yumbase.comps.categories]
+        for cat in cats:
+            grps = self.comps.get_groups(cat)
+            for grp_id in grps:
+                grp = self.yumbase.comps.return_group(grp_id)
+                if grp:
+                    id = "@%s" % (grp_id)
+                    name = grp.nameByLang(self._lang)
+                    summary = grp.descriptionByLang(self._lang)
+                    icon = ""
+                    fn = "/usr/share/pixmaps/comps/%s.png" % grp_id
+                    if os.access(fn, os.R_OK):
+                        icon = fn
+                    else:
+                        fn = "/usr/share/pixmaps/comps/%s.png" % cat
+                        if os.access(fn, os.R_OK):
+                            icon = fn
+                    self.category(cat, id, name, summary, icon)
+
+
+
     def download_packages(self, directory, package_ids):
         '''
         Implement the {backend}-download-packages functionality
@@ -596,10 +654,15 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
         if len(package_id.split(';')) > 1:
             # Split up the id
             (name, idver, a, repo) = self.get_package_from_id(package_id)
+            isGroup = False
             if repo == 'meta':
                 grp = self.yumbase.comps.return_group(name)
-                if not grp:
-                    self.error(ERROR_PACKAGE_NOT_FOUND, "The Group %s dont exist" % name)
+                isGroup = True
+            elif name[0] == '@':
+                grp = self.yumbase.comps.return_group(name[1:])
+                isGroup = True
+            if isGroup and not grp:
+                self.error(ERROR_PACKAGE_NOT_FOUND, "The Group %s dont exist" % name)
         return grp
 
     def _findPackage(self, package_id):
@@ -665,29 +728,27 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
                 if not grp.installed:
                     self.error(ERROR_PACKAGE_NOT_INSTALLED, "The Group %s is not installed" % grp.groupid)
                 else:
-                    txmbr = self.yumbase.groupRemove(grp.groupid)
-                    rc, msgs =  self.yumbase.buildTransaction()
-                    if rc != 2:
-                        self.error(ERROR_DEP_RESOLUTION_FAILED, _format_msgs(msgs))
-                    else:
-                        for txmbr in self.yumbase.tsInfo:
-                            deps_list.append(txmbr.po)
+                    txmbrs = self.yumbase.groupRemove(grp.groupid)
+                    for txmbr in self.yumbase.tsInfo:
+                        deps_list.append(txmbr.po)
             else:
                 pkg, inst = self._findPackage(package)
                 # This simulates the removal of the package
                 if inst and pkg:
                     resolve_list.append(pkg)
                     txmbrs = self.yumbase.remove(po=pkg)
-                    if txmbrs:
-                        rc, msgs =  self.yumbase.buildTransaction()
-                        if rc != 2:
-                            self.error(ERROR_DEP_RESOLUTION_FAILED, _format_msgs(msgs))
-                        else:
-                            for txmbr in self.yumbase.tsInfo:
-                                if pkg not in deps_list:
-                                    deps_list.append(txmbr.po)
             percentage += bump
 
+        # do the depsolve to pull in deps
+        if len(self.yumbase.tsInfo) > 0  and recursive:
+            rc, msgs =  self.yumbase.buildTransaction()
+            if rc != 2:
+                self.error(ERROR_DEP_RESOLUTION_FAILED, _format_msgs(msgs))
+            else:
+                for txmbr in self.yumbase.tsInfo:
+                    if txmbr.po not in deps_list:
+                        deps_list.append(txmbr.po)
+
         # remove any of the original names
         for pkg in resolve_list:
             if pkg in deps_list:
@@ -847,7 +908,7 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
             self.yumbase.groupUnremove(grp.groupid)
         return pkgs
 
-    def _get_depends_not_installed(self, fltlist, package_ids):
+    def _get_depends_not_installed(self, fltlist, package_ids, recursive):
         percentage = 0
         bump = 100 / len(package_ids)
         deps_list = []
@@ -860,29 +921,27 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
                 if grp.installed:
                     self.error(ERROR_PACKAGE_ALREADY_INSTALLED, "The Group %s is already installed" % grp.groupid)
                 else:
-                    txmbr = self.yumbase.selectGroup(grp.groupid)
-                    rc, msgs =  self.yumbase.buildTransaction()
-                    if rc != 2:
-                        self.error(ERROR_DEP_RESOLUTION_FAILED, _format_msgs(msgs))
-                    else:
-                        for txmbr in self.yumbase.tsInfo:
-                            deps_list.append(txmbr.po)
+                    txmbrs = self.yumbase.selectGroup(grp.groupid)
+                    for txmbr in self.yumbase.tsInfo:
+                        deps_list.append(txmbr.po)
             else:
                 pkg, inst = self._findPackage(package)
                 # This simulates the addition of the package
                 if not inst and pkg:
                     resolve_list.append(pkg)
                     txmbrs = self.yumbase.install(po=pkg)
-                    if txmbrs:
-                        rc, msgs =  self.yumbase.buildTransaction()
-                        if rc != 2:
-                            self.error(ERROR_DEP_RESOLUTION_FAILED, _format_msgs(msgs))
-                        else:
-                            for txmbr in self.yumbase.tsInfo:
-                                if pkg not in deps_list:
-                                    deps_list.append(txmbr.po)
             percentage += bump
 
+        if len(self.yumbase.tsInfo) > 0 and recursive:
+            rc, msgs =  self.yumbase.buildTransaction()
+            if rc != 2:
+                self.error(ERROR_DEP_RESOLUTION_FAILED, _format_msgs(msgs))
+            else:
+                for txmbr in self.yumbase.tsInfo:
+                    if txmbr.po not in deps_list:
+                        deps_list.append(txmbr.po)
+
+
         # make unique list
         deps_list = unique(deps_list)
 
@@ -909,8 +968,8 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
         # before we do an install we do ~installed + recursive true,
         # which we can emulate quicker by doing a transaction, but not
         # executing it
-        if filters == FILTER_NOT_INSTALLED and recursive:
-            self._get_depends_not_installed (fltlist, package_ids)
+        if filters == FILTER_NOT_INSTALLED:
+            self._get_depends_not_installed (fltlist, package_ids,recursive)
             return
 
         percentage = 0
diff --git a/backends/yum/yumComps.py b/backends/yum/yumComps.py
index 7bb1d7c..a99254a 100755
--- a/backends/yum/yumComps.py
+++ b/backends/yum/yumComps.py
@@ -310,7 +310,7 @@ class yumComps:
     def get_meta_package_list(self, groupid):
         ''' for a comps group, get the packagelist for this group (mandatory, default)'''
         all_packages = []
-        self.cursor.execute('SELECT name FROM groups WHERE groupid = ? AND ( pkgtype = "mandatory" OR pkgtype = "default");', [groupid])
+        self.cursor.execute('SELECT name FROM groups WHERE groupid = ? ;', [groupid])
         for row in self.cursor:
             all_packages.append(row[0])
         return all_packages
@@ -324,6 +324,13 @@ class yumComps:
             break
         return category
 
+    def get_groups(self,cat_id):
+        grps = set()
+        self.cursor.execute('SELECT groupid FROM groups WHERE category = ?',[cat_id])
+        for row in self.cursor:
+            grps.add(row[0])
+        return list(grps)
+
 if __name__ == "__main__":
     import yum
     _yb = yum.YumBase()
commit f8da2aba3ac208e4f5cb16eeafb21e98ae4328b2
Author: Thomas Spura <spurath at students.uni-mainz.de>
Date:   Mon Oct 6 22:21:40 2008 +0000

    Updated German Translation
    
    Transmitted-via: Transifex (translate.fedoraproject.org)

diff --git a/po/de.po b/po/de.po
index 17bdeea..0bcf7d8 100644
--- a/po/de.po
+++ b/po/de.po
@@ -15,8 +15,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: policycoreutils.HEAD.de\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-25 00:31+0000\n"
-"PO-Revision-Date: 2008-10-03 14:17+0200\n"
+"POT-Creation-Date: 2008-10-01 20:51+0000\n"
+"PO-Revision-Date: 2008-10-07 00:19+0200\n"
 "Last-Translator: Fabian Affolter <fab at fedoraproject.org>\n"
 "Language-Team:  <en at li.org>\n"
 "MIME-Version: 1.0\n"
@@ -42,7 +42,7 @@ msgstr "Ein Programm-Neustart wird benötigt"
 
 #: ../client/pk-console.c:588 ../client/pk-generate-pack.c:126
 msgid "There are multiple package matches"
-msgstr "Es passen mehrere Packete"
+msgstr "Es passen mehrere Packete zu Ihrer Anfrage"
 
 #. find out what package the user wants to use
 #: ../client/pk-console.c:595 ../client/pk-generate-pack.c:133
@@ -51,20 +51,20 @@ msgstr "Bitte geben Sie die Packet-Nummer ein: "
 
 #: ../client/pk-console.c:629
 msgid "Could not find package to install"
-msgstr ""
+msgstr "Packet zum Installieren konnte nicht gefunden werden"
 
 #: ../client/pk-console.c:735
 msgid "Could not find package to remove"
-msgstr "Die Packete zum Löschen konnten nicht gefunden werden"
+msgstr "Packet zum Löschen konnte nicht gefunden werden"
 
 #: ../client/pk-console.c:796
 msgid "The following packages have to be removed"
-msgstr "Die folgenden Packete müssen entfernt werden"
+msgstr "Die folgenden Packeten müssen entfernt werden"
 
 #. get user input
 #: ../client/pk-console.c:803
 msgid "Okay to remove additional packages?"
-msgstr "Dürfen die zusätzlichen Packete entfernt werden?"
+msgstr "Sollen die zusätzlichen Packete entfernt werden?"
 
 #: ../client/pk-console.c:807 ../client/pk-generate-pack.c:528
 #: ../client/pk-generate-pack-main.c:131
@@ -73,15 +73,15 @@ msgstr "Abbruch!"
 
 #: ../client/pk-console.c:841
 msgid "Could not find package to download"
-msgstr ""
+msgstr "Das Packet zum Herunterladen konnte nicht gefunden werden"
 
 #: ../client/pk-console.c:893
 msgid "Could not find package to update"
-msgstr ""
+msgstr "Das Packet zum Aktualisieren konnte nicht gefunden werden"
 
 #: ../client/pk-console.c:915
 msgid "Could not find what packages require"
-msgstr ""
+msgstr "Konnte nicht herausfinden, was die Packete benötigen"
 
 #: ../client/pk-console.c:936
 msgid "Could not get dependencies for"
@@ -93,16 +93,15 @@ msgstr "Konnte keine Details finden für"
 
 #: ../client/pk-console.c:980
 msgid "Could not find the files for this package"
-msgstr "Die Dateien für dieses Packet konnte nicht gefunden werden"
+msgstr "Die Dateien für dieses Packet konnten nicht gefunden werden"
 
 #: ../client/pk-console.c:987
-#, fuzzy
 msgid "Could not get the file list"
-msgstr "Die Dateiliste konnte nicht geholt werden"
+msgstr "Die Datei-Liste konnte nicht erstellt werden"
 
 #: ../client/pk-console.c:1006
 msgid "Could not find the update details for"
-msgstr "Die Aktualisierungsdetails konnten nicht gefunden werden für"
+msgstr "Konnte keine Aktualisierungsdetails nicht finden für"
 
 #: ../client/pk-console.c:1067
 msgid "Package description"
@@ -119,7 +118,7 @@ msgstr "Keine Dateien"
 #. get user input
 #: ../client/pk-console.c:1140
 msgid "Okay to import key?"
-msgstr "Darf der Schlüssel importiert werden?"
+msgstr "Soll der Schlüssel importiert werden?"
 
 #: ../client/pk-console.c:1143
 msgid "Did not import key"
@@ -132,16 +131,16 @@ msgstr "Sind Sie einverstanden?"
 
 #: ../client/pk-console.c:1186
 msgid "Did not agree to licence, task will fail"
-msgstr ""
+msgstr "Sie stimmten der Lizenz nicht zu, die Aufgabe wird fehlschlagen"
 
 #: ../client/pk-console.c:1215
 msgid "The daemon crashed mid-transaction!"
-msgstr ""
+msgstr "Der Dämon stürzte während der Transaktion ab!"
 
 #. header
 #: ../client/pk-console.c:1268
 msgid "PackageKit Console Interface"
-msgstr ""
+msgstr "PackageKit-Konsolen-Interface"
 
 #: ../client/pk-console.c:1268
 msgid "Subcommands:"
@@ -150,7 +149,7 @@ msgstr "Unterbefehle:"
 #: ../client/pk-console.c:1378 ../client/pk-generate-pack-main.c:64
 #: ../client/pk-monitor.c:118 ../src/pk-main.c:192
 msgid "Show extra debugging information"
-msgstr ""
+msgstr "Zeige extra Debup-Informationen"
 
 #: ../client/pk-console.c:1380 ../client/pk-monitor.c:120
 msgid "Show the program version and exit"
@@ -162,15 +161,15 @@ msgstr "Setze den Filter, z.B. installiert"
 
 #: ../client/pk-console.c:1384
 msgid "Exit without waiting for actions to complete"
-msgstr "Beende ohne auf fertigzustellende Aktionen zu warten"
+msgstr "Beende, ohne auf Beendigung der Aktionen zu warten"
 
 #: ../client/pk-console.c:1407
 msgid "Could not connect to system DBUS."
-msgstr "Konnte nicht mit dem System-DBUS verbinden."
+msgstr "Konnte nicht zum System-DBUS verbinden"
 
 #: ../client/pk-console.c:1500
 msgid "You need to specify a search type, e.g. name"
-msgstr ""
+msgstr "Sie müssen einen Suchtyp angeben, z.B. einen Namen"
 
 #: ../client/pk-console.c:1505 ../client/pk-console.c:1512
 #: ../client/pk-console.c:1519 ../client/pk-console.c:1526
@@ -185,66 +184,62 @@ msgstr "Ungültiger Suchtyp"
 
 #: ../client/pk-console.c:1536
 msgid "You need to specify a package or file to install"
-msgstr ""
+msgstr "Sie müssen ein Packet oder eine Datei zum Installieren angeben"
 
 #: ../client/pk-console.c:1543
 msgid "You need to specify a type, key_id and package_id"
-msgstr ""
+msgstr "Sie müssen einen Typ, Schlüssel_id und Packet_id auswählen"
 
 #: ../client/pk-console.c:1550
 msgid "You need to specify a package to remove"
-msgstr ""
+msgstr "Sie müssen ein Packet zum Löschen angeben"
 
 #: ../client/pk-console.c:1556
 msgid ""
 "You need to specify the destination directory and then the packages to "
 "download"
 msgstr ""
+"Sie müssen ein Zielverzeichnis und dann die Packete zum Herunterladen angeben"
 
 #: ../client/pk-console.c:1561
 msgid "Directory not found"
 msgstr "Verzeichnis nicht gefunden"
 
 #: ../client/pk-console.c:1567
-#, fuzzy
 msgid "You need to specify a eula-id"
-msgstr "Sie müssen einen Wert angeben"
+msgstr "Sie müssen eine eula-id auswählen"
 
 #: ../client/pk-console.c:1583
 msgid "You need to specify a package name to resolve"
-msgstr ""
+msgstr "Sie müssen einen Packetnamen zum Auflösen angeben"
 
 #: ../client/pk-console.c:1592 ../client/pk-console.c:1599
-#, fuzzy
 msgid "You need to specify a repo name"
-msgstr "Sie müssen einen Wert angeben"
+msgstr "Sie müssen einen Repository-Namen angeben"
 
 #: ../client/pk-console.c:1606
 msgid "You need to specify a repo name/parameter and value"
-msgstr ""
+msgstr "Sie müssen einen Repositorynamen/Parameter und Wert angeben"
 
 #: ../client/pk-console.c:1619
-#, fuzzy
 msgid "You need to specify a time term"
-msgstr "Sie müssen einen Wert angeben"
+msgstr "Sie müssen einen Zeit-Begriff angeben"
 
 #: ../client/pk-console.c:1624
-#, fuzzy
 msgid "You need to specify a correct role"
-msgstr "Sie müssen einen Wert angeben"
+msgstr "Sie müssen eine korrekte Rolle angeben"
 
 #: ../client/pk-console.c:1629
-#, fuzzy
 msgid "Failed to get last time"
-msgstr "Erwerb des neuen Kontexts fehlgeschlagen.\n"
+msgstr "Die letzte Zeit konnte nicht herausgefunden werden"
 
 #: ../client/pk-console.c:1668
 msgid "You need to specify a package to find the details for"
-msgstr ""
+msgstr "Sie müssen ein Packet, für das nach Details gesucht wird, angeben"
 
 #: ../client/pk-console.c:1675
 msgid "You need to specify a package to find the files for"
-msgstr ""
+msgstr "Sie müssen ein Packet, für das nach Dateien gesucht wird, angeben"
 
 #: ../client/pk-console.c:1724
 #, c-format
@@ -253,7 +248,7 @@ msgstr "Optino '%s' nicht unterstützt"
 
 #: ../client/pk-console.c:1737
 msgid "You don't have the necessary privileges for this operation"
-msgstr ""
+msgstr "Sie haben nicht die notwendigen Privilegien für diese Operation"
 
 #: ../client/pk-console.c:1739
 msgid "Command failed"
@@ -261,83 +256,84 @@ msgstr "Befehl fehlgeschlagen"
 
 #: ../client/pk-generate-pack.c:117
 msgid "Could not find a package match"
-msgstr ""
+msgstr "Es konnte kein Packet gefunden werden"
 
 #: ../client/pk-generate-pack.c:151
+#, fuzzy
 msgid "failed to download: invalid package_id and/or directory"
-msgstr ""
+msgstr "Fehler beim Runterladen: Ungültige package_id und/oder ungültiges Verzeichnis"
 
 #: ../client/pk-generate-pack.c:232
 #, fuzzy
 msgid "Could not find a valid metadata file"
-msgstr "Kann keinen gültigen Eintrag in der \"passwd\"-Datei finden.\n"
+msgstr "Eine gültige Metadata–Datei konnte nicht gefunden werden"
 
 #. get user input
 #: ../client/pk-generate-pack.c:524
 msgid "Okay to download the additional packages"
-msgstr ""
+msgstr "Möchten Sie die zusätzlichen Packete herunterladen"
 
 #: ../client/pk-generate-pack-main.c:66
+#, fuzzy
 msgid ""
 "Set the path of the file with the list of packages/dependencies to be "
 "excluded"
 msgstr ""
+"Setze den Pfad der Datei mit der Packet-/Abhängigkeitsliste, die ausgeschlossen werden"
 
 #: ../client/pk-generate-pack-main.c:111
 msgid "You need to specify the pack name and packages to be packed\n"
-msgstr ""
+msgstr "Sie müssen einen Packnamen und Packete zum Packen angeben\n"
 
 #: ../client/pk-generate-pack-main.c:117
 msgid ""
 "Invalid name for the service pack, Specify a name with .servicepack "
 "extension\n"
 msgstr ""
+"Ungültiger Name für ein Service Pack, geben Sie einen Namen an mit .servicepack als Endung\n"
 
 #: ../client/pk-generate-pack-main.c:129
 msgid "A pack with the same name already exists, do you want to overwrite it?"
-msgstr "Ein Packet mit dem selben Namen existiert bereits, möchten Sie es überschreiben?"
+msgstr "Ein Pack mit dem selben Namen existiert bereits, möchten Sie es überschreiben?"
 
 #: ../client/pk-generate-pack-main.c:142
-#, fuzzy
 msgid "Failed to create directory"
-msgstr "Schliessen von TTY fehlgeschlagen\n"
+msgstr "Verzeichnis konnte nicht erstellt werden"
 
 #: ../client/pk-generate-pack-main.c:149
-#, fuzzy
 msgid "Failed to create pack"
-msgstr "Schliessen von TTY fehlgeschlagen\n"
+msgstr "Pack konnte nicht erstellt werden"
 
 #: ../client/pk-import-specspo.c:185
-#, fuzzy
 msgid "Could not set database readonly"
-msgstr "semanage-Transaktion konnte nicht gestartet werden"
+msgstr "Datenbank konnte nicht nur-lesbar gesetzt werden"
 
 #: ../client/pk-import-specspo.c:192
-#, fuzzy, c-format
+#, c-format
 msgid "Could not open database: %s"
-msgstr "Konnte Datei %s nicht öffnen\n"
+msgstr "Datenbank %s konnte nicht geöffnet werden"
 
 #: ../client/pk-import-specspo.c:193
 msgid "You probably need to run this program as the root user"
-msgstr "Sie müssen dieses Programm vermutlich als root starten"
+msgstr "Sie sollten dieses Programm vermutlich als Benutzer root ausführen"
 
 #: ../client/pk-monitor.c:131
 msgid "PackageKit Monitor"
-msgstr ""
+msgstr "PackageKit Monitor"
 
 #: ../client/pk-tools-common.c:51
-#, fuzzy, c-format
+#, c-format
 msgid "Please enter a number from 1 to %i: "
-msgstr "Ports müssen zahlen zwischen 1 und %d sein"
+msgstr "Bitte geben Sie eine Zahl zwischen 1 und %i ein: "
 
 #: ../contrib/packagekit-plugin/src/contents.cpp:300
 msgid "Getting package information..."
-msgstr "Packet-Informationen werden geholt"
+msgstr "Bekomme Packet-Informationen..."
 
 #: ../contrib/packagekit-plugin/src/contents.cpp:304
 #, c-format
 msgid "<span color='#%06x' underline='single' size='larger'>Run %s</span>"
-msgstr ""
+msgstr "<span color='#%06x' underline='single' size='larger'>%s wird ausgeführt</span>"
 
 #: ../contrib/packagekit-plugin/src/contents.cpp:308
 #: ../contrib/packagekit-plugin/src/contents.cpp:313
@@ -381,7 +377,7 @@ msgid ""
 "<span color='#%06x' underline='single'>Upgrade to version %s</span>"
 msgstr ""
 "\n"
-"<span color='#%06x' underline='single'>Aktualisierung zu Version %s</span>"
+"<span color='#%06x' underline='single'>Aktualisiere zu Version %s</span>"
 
 #: ../contrib/packagekit-plugin/src/contents.cpp:330
 #, c-format
@@ -405,7 +401,7 @@ msgid ""
 "<small>No packages found for your system</small>"
 msgstr ""
 "\n"
-"<small>Es wurden keine Packete für Ihr System gefunden</small>"
+"<small>Es wurden keine Packete für Ihren Rechner gefunden</small>"
 
 #: ../contrib/packagekit-plugin/src/contents.cpp:341
 msgid ""
@@ -421,11 +417,11 @@ msgstr "PackageKit Katalog"
 
 #: ../data/packagekit-pack.xml.in.h:1
 msgid "PackageKit Service Pack"
-msgstr ""
+msgstr "PackageKit Service Pack"
 
 #: ../src/pk-main.c:85
 msgid "Startup failed due to security policies on this machine."
-msgstr ""
+msgstr "Startfehler wegen Sicherheitseinstellungen auf diesem Rechner"
 
 #: ../src/pk-main.c:86
 msgid "This can happen for two reasons:"
@@ -433,13 +429,14 @@ msgstr "Dies kann aus zwei Gründen passieren:"
 
 #: ../src/pk-main.c:87
 msgid "The correct user is not launching the executable (usually root)"
-msgstr ""
+msgstr "Der korrekte Benutzer führt nicht das Programm aus (normalerweise root)"
 
 #: ../src/pk-main.c:88
 msgid ""
 "The org.freedesktop.PackageKit.conf file is not installed in the system /etc/"
 "dbus-1/system.d directory"
-msgstr "Die org.freedesktop.PackageKit.conf-Datei ist nicht auf Ihrem Rechner in /etc/dbus-1/system.d installiert"
+msgstr ""
+"Die org.freedesktop.PackageKit.conf-Datei ist nicht auf Ihrem Rechner im Verzeichnis /etc/dbus-1/system.d installiert."
 
 #: ../src/pk-main.c:188
 msgid "Packaging backend to use, e.g. dummy"
@@ -447,7 +444,7 @@ msgstr ""
 
 #: ../src/pk-main.c:190
 msgid "Daemonize and detach from the terminal"
-msgstr ""
+msgstr "Dämonisiere und löse vom Terminal ab"
 
 #: ../src/pk-main.c:194
 msgid "Disable the idle timer"
@@ -455,30 +452,29 @@ msgstr ""
 
 #: ../src/pk-main.c:196
 msgid "Show version and exit"
-msgstr ""
+msgstr "Zeige Version und beende"
 
 #: ../src/pk-main.c:198
 msgid "Exit after a small delay"
 msgstr "Beende nach kurzer Verzögerung"
 
 #: ../src/pk-main.c:200
+#, fuzzy
 msgid "Exit after the engine has loaded"
-msgstr ""
+msgstr "Beende, nachdem die Maschine angeworfen wurde"
 
 #: ../src/pk-main.c:210
-#, fuzzy
 msgid "PackageKit service"
-msgstr "Name-Dienst"
+msgstr "PackageKIt-Dienst"
 
 #: ../src/pk-main.c:246
-#, fuzzy
 msgid "Cannot connect to the system bus"
-msgstr "Fehler beim Verbinden für Systemprüfung.\n"
+msgstr "Konnte nicht zum System-Bus verbinden"
 
 #: ../src/pk-main.c:286
-#, fuzzy, c-format
+#, c-format
 msgid "Error trying to start: %s\n"
-msgstr "Fehler beim Verbinden für Systemprüfung.\n"
+msgstr "Fehler beim Starten von: %s\n"
 
 #~ msgid ""
 #~ "USAGE: run_init <script> <args ...>\n"
commit 054ae7019ea13ea8035e59a794964ff8c3f88245
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Mon Oct 6 21:23:56 2008 +0200

    APT: fix the gstreamer whatprovides regular expression

diff --git a/backends/apt/aptDBUSBackend.py b/backends/apt/aptDBUSBackend.py
index 61a5137..8d1626f 100755
--- a/backends/apt/aptDBUSBackend.py
+++ b/backends/apt/aptDBUSBackend.py
@@ -1540,7 +1540,7 @@ class PackageKitAptBackend(PackageKitBaseBackend):
         self.AllowCancel(False)
         if provides_type == PROVIDES_CODEC:
             # The search term from the codec helper looks like this one:
-            match = re.match(r"gstreamer(.+)\((.+)\)\((.+)\)", search)
+            match = re.match(r"gstreamer([0-9\.]+)\((.+?)\)", search)
             if not match:
                 self.ErrorCode(ERROR_UNKNOWN,
                                "The search term is invalid")
commit 2163f7e7c5ff138e1bf8014da02f97a147ae4266
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Oct 6 16:44:52 2008 +0100

    trivial: add some text for the GStreamer README

diff --git a/contrib/gstreamer-plugin/README b/contrib/gstreamer-plugin/README
index 2bedfb1..5969ece 100644
--- a/contrib/gstreamer-plugin/README
+++ b/contrib/gstreamer-plugin/README
@@ -12,10 +12,33 @@ Introduction:
  4. Distribution patches /etc/PackageKit/Vendor.conf with URLs to wiki pages.
  3. Done. It's really that simple.
 
+Detecting the calling application:
+
+When an application calls the DBUS interface to install plugins or codecs
+then the XID and timestamp along with the codec string is passed on the
+interface.
+
+The caller (the exe from ConsoleKit) is then sent to SearchFile and the result
+used in the GUI. This ensures that all applications can use the interface,
+but they cannot pretend to be other applications by changing application
+window properties.
+
+This of course, causes a problem as all installs will be resolved to the
+PackageKit-gstreamer-plugin as this owns the /usr/libexec/pk-gstreamer-install
+file.
+
+This file, /usr/libexec/pk-gstreamer-install is treated specially (as it is
+compiled, and cannot be modified without root access). In this special case
+we use the XID of the calling window (provided by GStreamer) and lookup the
+program name and icon from the window properties.
+
 Notes:
 
  * You will need to restart any applications using GStreamer before they will
    request plugings using PackageKit.
  * Although PackageKit 0.3.4 supports codec installing, 0.3.6 is the first
-   release that returns the correct return valus to GStreamer.
+   release that returns the correct return values to GStreamer.
+ * Totem versions less than 2.24.1 have a bug where it sends the wrong XID,
+   you need to upgrade for focus stealing prevention to work and for the title
+   and icon to be set correctly.
 
commit 6edf1285160547596f0e06889da28abf1424cc3a
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Oct 6 15:30:45 2008 +0100

    trivial: add a README file for the GStreamer plugin

diff --git a/contrib/gstreamer-plugin/README b/contrib/gstreamer-plugin/README
new file mode 100644
index 0000000..2bedfb1
--- /dev/null
+++ b/contrib/gstreamer-plugin/README
@@ -0,0 +1,21 @@
+README:
+
+PackageKit installs missing GStreamer plugins as it requested: this is how
+the whole system is designed to work.
+
+Introduction:
+
+ 1. Package installs pk-gstreamer-install into /usr/libexec
+ 2. _If_ the distro wants PackageKit to handle the codec install, and
+    not an application like codeina then you need to symlink
+    pk-gstreamer-install to gst-install-plugins-helper
+ 4. Distribution patches /etc/PackageKit/Vendor.conf with URLs to wiki pages.
+ 3. Done. It's really that simple.
+
+Notes:
+
+ * You will need to restart any applications using GStreamer before they will
+   request plugings using PackageKit.
+ * Although PackageKit 0.3.4 supports codec installing, 0.3.6 is the first
+   release that returns the correct return valus to GStreamer.
+
commit 0d82c801d10c26df1d8c3517917b9d70a821a8f8
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Oct 6 16:18:14 2008 +0100

    feature, API addition: add a GetCategories method and Category signal so we can build a dynamic group list

diff --git a/backends/alpm/pk-backend-alpm.c b/backends/alpm/pk-backend-alpm.c
index 70d4e0a..071495b 100644
--- a/backends/alpm/pk-backend-alpm.c
+++ b/backends/alpm/pk-backend-alpm.c
@@ -1466,6 +1466,7 @@ PK_BACKEND_OPTIONS (
 	NULL,						/* get_mime_types */
 	backend_cancel,					/* cancel */
 	NULL,						/* download_packages */
+	NULL,						/* get_categories */
 	backend_get_depends,				/* get_depends */
 	backend_get_details,				/* get_details */
 	NULL,						/* get_distro_upgrades */
diff --git a/backends/apt.deprecated/pk-backend-apt.c b/backends/apt.deprecated/pk-backend-apt.c
index de41f91..638df97 100644
--- a/backends/apt.deprecated/pk-backend-apt.c
+++ b/backends/apt.deprecated/pk-backend-apt.c
@@ -246,6 +246,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* get_mime_types */
 	NULL,					/* cancel */
 	NULL,					/* download_packages */
+	NULL,					/* get_categories */
 	backend_get_depends,			/* get_depends */
 	backend_get_details,			/* get_details */
 	NULL,					/* get_distro_upgrades */
diff --git a/backends/apt/pk-backend-apt.c b/backends/apt/pk-backend-apt.c
index d90a75b..4812eaa 100644
--- a/backends/apt/pk-backend-apt.c
+++ b/backends/apt/pk-backend-apt.c
@@ -344,6 +344,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* get_mime_types */
 	backend_cancel,				/* cancel */
 	backend_download_packages,		/* download_packages */
+	NULL,					/* get_categories */
 	backend_get_depends,			/* get_depends */
 	backend_get_details,			/* get_details */
 #ifdef HAVE_PYTHON_META_RELEASE
diff --git a/backends/box/pk-backend-box.c b/backends/box/pk-backend-box.c
index 6000324..f22db04 100644
--- a/backends/box/pk-backend-box.c
+++ b/backends/box/pk-backend-box.c
@@ -670,6 +670,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* get_mime_types */
 	NULL,					/* cancel */
 	NULL,					/* download_packages */
+	NULL,					/* get_categories */
 	backend_get_depends,			/* get_depends */
 	backend_get_details,			/* get_details */
 	NULL,					/* get_distro_upgrades */
diff --git a/backends/conary/pk-backend-conary.c b/backends/conary/pk-backend-conary.c
index 1b01102..6ef0b48 100644
--- a/backends/conary/pk-backend-conary.c
+++ b/backends/conary/pk-backend-conary.c
@@ -280,6 +280,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* get_mime_types */
 	backend_cancel,				/* cancel */
 	NULL,					/* download_packages */
+	NULL,					/* get_categories */
 	NULL,					/* get_depends */
 	backend_get_details,			/* get_details */
 	NULL,					/* get_distro_upgrades */
diff --git a/backends/dummy/pk-backend-dummy.c b/backends/dummy/pk-backend-dummy.c
index 11bc33b..f5c0cf4 100644
--- a/backends/dummy/pk-backend-dummy.c
+++ b/backends/dummy/pk-backend-dummy.c
@@ -941,6 +941,7 @@ PK_BACKEND_OPTIONS (
 	backend_get_mime_types,			/* get_mime_types */
 	backend_cancel,				/* cancel */
 	backend_download_packages,		/* download_packages */
+	NULL,					/* get_categories */
 	backend_get_depends,			/* get_depends */
 	backend_get_details,			/* get_details */
 	backend_get_distro_upgrades,		/* get_distro_upgrades */
diff --git a/backends/opkg/pk-backend-opkg.c b/backends/opkg/pk-backend-opkg.c
index ffd5cfb..de98d2b 100644
--- a/backends/opkg/pk-backend-opkg.c
+++ b/backends/opkg/pk-backend-opkg.c
@@ -724,6 +724,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* get_mime_types */
 	NULL,					/* cancel */
 	NULL,					/* download_packages */
+	NULL,					/* get_categories */
 	NULL,					/* get_depends */
 	backend_get_details,			/* get_details */
 	NULL,					/* get_distro_upgrades */
diff --git a/backends/pisi/pk-backend-pisi.c b/backends/pisi/pk-backend-pisi.c
index 3480485..5e8192d 100644
--- a/backends/pisi/pk-backend-pisi.c
+++ b/backends/pisi/pk-backend-pisi.c
@@ -369,6 +369,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* get_mime_types */
 	backend_cancel,				/* cancel */
 	NULL,					/* download_packages */
+	NULL,					/* get_categories */
 	backend_get_depends,			/* get_depends */
 	backend_get_details,			/* get_details */
 	NULL,					/* get_distro_upgrades */
diff --git a/backends/poldek/pk-backend-poldek.c b/backends/poldek/pk-backend-poldek.c
index 89a30f3..9ffd7ea 100644
--- a/backends/poldek/pk-backend-poldek.c
+++ b/backends/poldek/pk-backend-poldek.c
@@ -2850,6 +2850,7 @@ PK_BACKEND_OPTIONS (
 	NULL,						/* get_mime_types */
 	backend_get_cancel,				/* cancel */
 	backend_download_packages,			/* download_packages */
+	NULL,						/* get_categories */
 	backend_get_depends,				/* get_depends */
 	backend_get_details,				/* get_details */
 	NULL,						/* get_distro_upgrades */
diff --git a/backends/razor/pk-backend-razor.c b/backends/razor/pk-backend-razor.c
index 455c28d..ac11b0a 100644
--- a/backends/razor/pk-backend-razor.c
+++ b/backends/razor/pk-backend-razor.c
@@ -404,6 +404,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* get_mime_types */
 	NULL,					/* cancel */
 	NULL,					/* download_packages */
+	NULL,					/* get_categories */
 	NULL,					/* get_depends */
 	backend_get_details,			/* get_details */
 	NULL,					/* get_distro_upgrades */
diff --git a/backends/smart/pk-backend-smart.c b/backends/smart/pk-backend-smart.c
index 8d61b39..bd9727a 100644
--- a/backends/smart/pk-backend-smart.c
+++ b/backends/smart/pk-backend-smart.c
@@ -467,6 +467,7 @@ PK_BACKEND_OPTIONS (
 	backend_get_mime_types,				/* get_mime_types */
 	backend_cancel,					/* cancel */
 	backend_download_packages,			/* download_packages */
+	NULL,						/* get_categories */
 	backend_get_depends,				/* get_depends */
 	backend_get_details,				/* get_details */
 	NULL,						/* get_distro_upgrades */
diff --git a/backends/test/pk-backend-test-dbus.c b/backends/test/pk-backend-test-dbus.c
index 49771b0..697e919 100644
--- a/backends/test/pk-backend-test-dbus.c
+++ b/backends/test/pk-backend-test-dbus.c
@@ -83,6 +83,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* get_mime_types */
 	backend_cancel,				/* cancel */
 	NULL,					/* download_packages */
+	NULL,					/* get_categories */
 	NULL,					/* get_depends */
 	NULL,					/* get_details */
 	NULL,					/* get_distro_upgrades */
diff --git a/backends/test/pk-backend-test-fail.c b/backends/test/pk-backend-test-fail.c
index 1fa1edd..27ea3f6 100644
--- a/backends/test/pk-backend-test-fail.c
+++ b/backends/test/pk-backend-test-fail.c
@@ -257,6 +257,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* get_mime_types */
 	backend_cancel,				/* cancel */
 	NULL,					/* download_packages */
+	NULL,					/* get_categories */
 	backend_get_depends,			/* get_depends */
 	backend_get_details,			/* get_details */
 	NULL,					/* get_distro_upgrades */
diff --git a/backends/test/pk-backend-test-nop.c b/backends/test/pk-backend-test-nop.c
index 7f1cde5..ce21b4b 100644
--- a/backends/test/pk-backend-test-nop.c
+++ b/backends/test/pk-backend-test-nop.c
@@ -33,6 +33,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* get_mime_types */
 	NULL,					/* cancel */
 	NULL,					/* download_packages */
+	NULL,					/* get_categories */
 	NULL,					/* get_depends */
 	NULL,					/* get_details */
 	NULL,					/* get_distro_upgrades */
diff --git a/backends/test/pk-backend-test-spawn.c b/backends/test/pk-backend-test-spawn.c
index 14242e1..e9cac03 100644
--- a/backends/test/pk-backend-test-spawn.c
+++ b/backends/test/pk-backend-test-spawn.c
@@ -74,6 +74,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* get_mime_types */
 	NULL,					/* cancel */
 	NULL,					/* download_packages */
+	NULL,					/* get_categories */
 	NULL,					/* get_depends */
 	NULL,					/* get_details */
 	NULL,					/* get_distro_upgrades */
diff --git a/backends/test/pk-backend-test-succeed.c b/backends/test/pk-backend-test-succeed.c
index 3d43af1..6998ab7 100644
--- a/backends/test/pk-backend-test-succeed.c
+++ b/backends/test/pk-backend-test-succeed.c
@@ -326,6 +326,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* get_mime_types */
 	backend_cancel,				/* cancel */
 	NULL,					/* download_packages */
+	NULL,					/* get_categories */
 	backend_get_depends,			/* get_depends */
 	backend_get_details,			/* get_details */
 	NULL,					/* get_distro_upgrades */
diff --git a/backends/test/pk-backend-test-thread.c b/backends/test/pk-backend-test-thread.c
index 17eac1f..05d9e3b 100644
--- a/backends/test/pk-backend-test-thread.c
+++ b/backends/test/pk-backend-test-thread.c
@@ -146,6 +146,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* get_mime_types */
 	backend_cancel,				/* cancel */
 	NULL,					/* download_packages */
+	NULL,					/* get_categories */
 	NULL,					/* get_depends */
 	NULL,					/* get_details */
 	NULL,					/* get_distro_upgrades */
diff --git a/backends/urpmi/pk-backend-urpmi.c b/backends/urpmi/pk-backend-urpmi.c
index 3f3e7d0..e7007fb 100644
--- a/backends/urpmi/pk-backend-urpmi.c
+++ b/backends/urpmi/pk-backend-urpmi.c
@@ -367,6 +367,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* get_mime_types */
 	NULL,					/* cancel */
 	NULL,					/* download_packages */
+	NULL,					/* get_categories */
 	backend_get_depends,			/* get_depends */
 	backend_get_details,			/* get_details */
 	backend_get_distro_upgrades,		/* get_distro_upgrades */
diff --git a/backends/yum/pk-backend-yum.c b/backends/yum/pk-backend-yum.c
index 5acb06e..a5e7e86 100644
--- a/backends/yum/pk-backend-yum.c
+++ b/backends/yum/pk-backend-yum.c
@@ -469,6 +469,7 @@ PK_BACKEND_OPTIONS (
 	backend_get_mime_types,			/* get_mime_types */
 	backend_cancel,				/* cancel */
 	backend_download_packages,		/* download_packages */
+	NULL,					/* get_categories */
 	backend_get_depends,			/* get_depends */
 	backend_get_details,			/* get_details */
 	backend_get_distro_upgrades,		/* get_distro_upgrades */
diff --git a/backends/yum/yumBackend.py b/backends/yum/yumBackend.py
index eac513d..1b4c426 100755
--- a/backends/yum/yumBackend.py
+++ b/backends/yum/yumBackend.py
@@ -225,6 +225,25 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
         summary = _to_unicode(summary)
         PackageKitBaseBackend.package(self, package_id, status, summary)
 
+    def category(self, parent_id, cat_id, name, summary, icon):
+        '''
+        Send 'category' signal
+        parent_id : A parent id, e.g. "admin" or "" if there is no parent
+        cat_id    : a unique category id, e.g. "admin;network"
+        name      : a verbose category name in current locale.
+        summery   : a summary of the category in current locale.
+        icon      : an icon name to represent the category
+        '''
+        name = self._to_unicode(name)
+        summary = self._to_unicode(summary)
+        PackageKitBaseBackend.category(self, parent_id, cat_id, name, summary, icon)
+
+    def _to_unicode(self, txt, encoding='utf-8'):
+        if isinstance(txt, basestring):
+            if not isinstance(txt, unicode):
+                txt = unicode(txt, encoding, errors='replace')
+        return txt
+
     def doLock(self):
         ''' Lock Yum'''
         retries = 0
diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp
index 719fc70..3806ba2 100644
--- a/backends/zypp/pk-backend-zypp.cpp
+++ b/backends/zypp/pk-backend-zypp.cpp
@@ -1844,6 +1844,7 @@ extern "C" PK_BACKEND_OPTIONS (
 	NULL,					/* get_mime_types */
 	NULL,					/* cancel */
 	NULL,					/* download_packages */
+	NULL,					/* get_categories */
 	backend_get_depends,			/* get_depends */
 	backend_get_details,			/* get_details */
 	backend_get_distro_upgrades,		/* get_distro_upgrades */
diff --git a/contrib/pk-completion.bash b/contrib/pk-completion.bash
index 784a882..c2ec252 100755
--- a/contrib/pk-completion.bash
+++ b/contrib/pk-completion.bash
@@ -32,6 +32,7 @@ __pkcon_commandlist="
     get-transactions
     get-update-detail
     get-updates
+    get-categories
     install
     refresh
     remove
diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 24e56e1..addb031 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -104,7 +104,7 @@ struct _PkClientPrivate
 	gchar			*cached_search;
 	gchar			*cached_directory;
 	PkProvidesEnum		 cached_provides;
-	PkBitfield	 cached_filters;
+	PkBitfield		 cached_filters;
 };
 
 typedef enum {
@@ -125,6 +125,7 @@ typedef enum {
 	PK_CLIENT_CALLER_ACTIVE_CHANGED,
 	PK_CLIENT_REPO_DETAIL,
 	PK_CLIENT_ALLOW_CANCEL,
+	PK_CLIENT_CATEGORY,
 	PK_CLIENT_DESTROY,
 	PK_CLIENT_LAST_SIGNAL
 } PkSignals;
diff --git a/libpackagekit/pk-enum.c b/libpackagekit/pk-enum.c
index 10c153b..e110a9a 100644
--- a/libpackagekit/pk-enum.c
+++ b/libpackagekit/pk-enum.c
@@ -117,6 +117,7 @@ static const PkEnumMatch enum_role[] = {
 	{PK_ROLE_ENUM_ACCEPT_EULA,		"accept-eula"},
 	{PK_ROLE_ENUM_DOWNLOAD_PACKAGES,	"download-packages"},
 	{PK_ROLE_ENUM_GET_DISTRO_UPGRADES,	"get-distro-upgrades"},
+	{PK_ROLE_ENUM_GET_CATEGORIES,		"get-categories"},
 	{0, NULL}
 };
 
diff --git a/libpackagekit/pk-enum.h b/libpackagekit/pk-enum.h
index 6a3bcb2..f808c6a 100644
--- a/libpackagekit/pk-enum.h
+++ b/libpackagekit/pk-enum.h
@@ -75,6 +75,7 @@ typedef enum {
 	PK_ROLE_ENUM_ACCEPT_EULA,
 	PK_ROLE_ENUM_DOWNLOAD_PACKAGES,
 	PK_ROLE_ENUM_GET_DISTRO_UPGRADES,
+	PK_ROLE_ENUM_GET_CATEGORIES,
 	PK_ROLE_ENUM_UNKNOWN
 } PkRoleEnum;
 
diff --git a/python/packagekit/backend.py b/python/packagekit/backend.py
index 3339fec..355a449 100644
--- a/python/packagekit/backend.py
+++ b/python/packagekit/backend.py
@@ -164,6 +164,18 @@ class PackageKitBaseBackend:
         print >> sys.stdout, "files\t%s\t%s" % (package_id, file_list)
         sys.stdout.flush()
 
+    def category(self, parent_id, cat_id, name, summary, icon):
+        '''
+        Send 'category' signal
+        parent_id : A parent id, e.g. "admin" or "" if there is no parent
+        cat_id    : a unique category id, e.g. "admin;network"
+        name      : a verbose category name in current locale.
+        summery   : a summary of the category in current locale.
+        icon      : an icon name to represent the category
+        '''
+        print >> sys.stdout,"category\t%s\t%s\t%s\t%s\t%s" % (parent_id, cat_id, name, summary, icon)
+        sys.stdout.flush()
+
     def finished(self):
         '''
         Send 'finished' signal
@@ -430,6 +442,13 @@ class PackageKitBaseBackend:
         '''
         self.error(ERROR_NOT_SUPPORTED, "This function is not implemented in this backend")
 
+    def get_categories(self):
+        '''
+        Implement the {backend}-get-categories functionality
+        Needed to be implemented in a sub class
+        '''
+        self.error(ERROR_NOT_SUPPORTED,"This function is not implemented in this backend")
+
     def customTracebackHandler(self, tb):
         '''
         Custom Traceback Handler
@@ -575,6 +594,9 @@ class PackageKitBaseBackend:
             code = args[0]
             self.set_locale(code)
             self.finished()
+        elif cmd == 'get-categories':
+            self.get_categories()
+            self.finished()
         else:
             errmsg = "command '%s' is not known" % cmd
             self.error(ERROR_INTERNAL_ERROR, errmsg, exit=False)
diff --git a/python/packagekit/client.py b/python/packagekit/client.py
index 9866bc6..053e3a4 100644
--- a/python/packagekit/client.py
+++ b/python/packagekit/client.py
@@ -122,6 +122,19 @@ class PackageKitClient:
         self._wrapCall(pk_xn, method, {'Details' : details_cb})
         return result
 
+    def _wrapCategoryCall(self, pk_xn, method):
+        '''
+        Wraps a call which emits Finished, ErrorCode on completion and
+        Details for information returns a list of dicts with 'id',
+        'license', 'group', 'description', 'upstream_url', 'size'.keys
+        '''
+        result = []
+        details_cb = lambda  parent_id, cat_id, name, summary, icon: result.append(
+            PackageKitCategory( parent_id, cat_id, name, summary, icon))
+
+        self._wrapCall(pk_xn, method, {'Category' : category_cb})
+        return result
+
     def _wrapUpdateDetailsCall(self, pk_xn, method):
         '''
         Wraps a call which emits Finished, ErrorCode on completion and
@@ -313,6 +326,13 @@ class PackageKitClient:
         xn = self._get_xn()
         return self._wrapPackageCall(xn, lambda : xn.GetUpdates(filters))
 
+    def GetCategories(self):
+        '''
+        This method should return a list of Categories
+        '''
+        xn = self._get_xn()
+        return self._wrapCategoryCall(xn, lambda : xn.GetCategories())
+
     def GetPackages(self, filters=FILTER_NONE):
         '''
         This method should return a total list of packages, limited by the
diff --git a/python/packagekit/misc.py b/python/packagekit/misc.py
index f6950f2..5ba0b59 100644
--- a/python/packagekit/misc.py
+++ b/python/packagekit/misc.py
@@ -109,3 +109,14 @@ class PackageKitFiles:
         self.id = str(package_id)
         self.files = str(files)
 
+class PackageKitCategory:
+    '''
+    container class from values from the Category signal
+    '''
+    def __init__(self, parent_id, cat_id, name, summary, icon):
+        self.parent_id = str(parent_id)
+        self.cat_id = str(cat_id)
+        self.name = _to_unicode(name)
+        self.summary = _to_unicode(summary)
+        self.icon = str(icon)
+
diff --git a/python/wrapper-test.py b/python/wrapper-test.py
index 8265949..bab51ad 100755
--- a/python/wrapper-test.py
+++ b/python/wrapper-test.py
@@ -19,6 +19,7 @@
 #    Tim Lauridsen <timlau at fedoraproject.org>
 
 import sys
+
 from packagekit.client import PackageKitClient
 from packagekit.enums import *
 
@@ -39,7 +40,8 @@ def show_package(pkg):
     if pkg:
         if isinstance(pkg, list):
             pkg = pkg[0]
-        print str(pkg)
+        print pkg
+        print pkg.summary
     else:
         print "no package found"
 
@@ -128,5 +130,11 @@ if __name__ == '__main__':
             print "Installing : %s " % pkg[0].id
             print pk.DownloadPackages(pkg[0].id)
 
+    if "get-categories" in cmd:
+        print '---- GetCategories() -----'
+        cats = pk.GetCategories()
+        for cat in cats:
+            print cat.name
+
     pk.SuggestDaemonQuit()
 
diff --git a/src/pk-backend-dbus.c b/src/pk-backend-dbus.c
index c68a413..b856aec 100644
--- a/src/pk-backend-dbus.c
+++ b/src/pk-backend-dbus.c
@@ -164,6 +164,17 @@ pk_backend_dbus_distro_upgrade_cb (DBusGProxy *proxy,
 }
 
 /**
+ * pk_backend_dbus_category_cb:
+ **/
+static void
+pk_backend_dbus_category_cb (DBusGProxy *proxy, const gchar *parent_id, const gchar *cat_id, const gchar *name,
+			     const gchar *summary, const gchar *icon, PkBackendDbus *backend_dbus)
+{
+	egg_debug ("got signal");
+	pk_backend_category (backend_dbus->priv->backend, parent_id, cat_id, name, summary, icon);
+}
+
+/**
  * pk_backend_dbus_files_cb:
  **/
 static void
@@ -358,6 +369,8 @@ pk_backend_dbus_remove_callbacks (PkBackendDbus *backend_dbus)
 					G_CALLBACK (pk_backend_dbus_repo_signature_required_cb), backend_dbus);
 	dbus_g_proxy_disconnect_signal (proxy, "EulaRequired",
 					G_CALLBACK (pk_backend_dbus_eula_required_cb), backend_dbus);
+	dbus_g_proxy_disconnect_signal (proxy, "Category",
+					G_CALLBACK (pk_backend_dbus_category_cb), backend_dbus);
 	dbus_g_proxy_disconnect_signal (proxy, "DistroUpgrade",
 					G_CALLBACK (pk_backend_dbus_distro_upgrade_cb), backend_dbus);
 	return TRUE;
@@ -497,6 +510,9 @@ pk_backend_dbus_set_name (PkBackendDbus *backend_dbus, const gchar *service)
 				 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT64, G_TYPE_INVALID);
 	dbus_g_proxy_add_signal (proxy, "Files",
 				 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
+	dbus_g_proxy_add_signal (proxy, "Category",
+				 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+				 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
 	dbus_g_proxy_add_signal (proxy, "UpdateDetail",
 				 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
 				 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
@@ -538,6 +554,8 @@ pk_backend_dbus_set_name (PkBackendDbus *backend_dbus, const gchar *service)
 				     G_CALLBACK (pk_backend_dbus_details_cb), backend_dbus, NULL);
 	dbus_g_proxy_connect_signal (proxy, "Files",
 				     G_CALLBACK (pk_backend_dbus_files_cb), backend_dbus, NULL);
+	dbus_g_proxy_connect_signal (proxy, "Category",
+				     G_CALLBACK (pk_backend_dbus_category_cb), backend_dbus, NULL);
 	dbus_g_proxy_connect_signal (proxy, "UpdateDetail",
 				     G_CALLBACK (pk_backend_dbus_update_detail_cb), backend_dbus, NULL);
 	dbus_g_proxy_connect_signal (proxy, "Finished",
@@ -771,6 +789,33 @@ pk_backend_dbus_update_system (PkBackendDbus *backend_dbus)
 }
 
 /**
+ * pk_backend_dbus_get_categories:
+ **/
+gboolean
+pk_backend_dbus_get_categories (PkBackendDbus *backend_dbus)
+{
+	gboolean ret;
+	GError *error = NULL;
+
+	g_return_val_if_fail (PK_IS_BACKEND_DBUS (backend_dbus), FALSE);
+	g_return_val_if_fail (backend_dbus->priv->proxy != NULL, FALSE);
+
+	/* new sync method call */
+	pk_backend_dbus_time_reset (backend_dbus);
+	ret = dbus_g_proxy_call (backend_dbus->priv->proxy, "GetCategories", &error,
+				 G_TYPE_INVALID, G_TYPE_INVALID);
+	if (error != NULL) {
+		egg_warning ("%s", error->message);
+		pk_backend_error_code (backend_dbus->priv->backend, PK_ERROR_ENUM_INTERNAL_ERROR, error->message);
+		pk_backend_finished (backend_dbus->priv->backend);
+		g_error_free (error);
+	}
+	if (ret)
+		pk_backend_dbus_time_check (backend_dbus);
+	return ret;
+}
+
+/**
  * pk_backend_dbus_repo_enable:
  **/
 gboolean
@@ -1538,6 +1583,10 @@ pk_backend_dbus_init (PkBackendDbus *backend_dbus)
 	dbus_g_object_register_marshaller (pk_marshal_VOID__STRING_STRING,
 					   G_TYPE_NONE, G_TYPE_STRING,
 					   G_TYPE_STRING, G_TYPE_INVALID);
+	/* Category */
+	dbus_g_object_register_marshaller (pk_marshal_VOID__STRING_STRING,
+					   G_TYPE_NONE, G_TYPE_STRING, G_TYPE_STRING,
+					   G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
 
 	/* Repo Signature Required */
 	dbus_g_object_register_marshaller (pk_marshal_VOID__STRING_STRING_STRING_STRING_STRING_STRING_STRING_UINT,
diff --git a/src/pk-backend-dbus.h b/src/pk-backend-dbus.h
index eb53962..e65e1d2 100644
--- a/src/pk-backend-dbus.h
+++ b/src/pk-backend-dbus.h
@@ -66,6 +66,7 @@ PkBackendDbus	*pk_backend_dbus_new			(void);
 gboolean	 pk_backend_dbus_refresh_cache		(PkBackendDbus		*backend_dbus,
 							 gboolean		 force);
 gboolean	 pk_backend_dbus_update_system		(PkBackendDbus		*backend_dbus);
+gboolean	 pk_backend_dbus_get_categories		(PkBackendDbus		*backend_dbus);
 gboolean	 pk_backend_dbus_resolve		(PkBackendDbus		*backend_dbus,
 							 PkBitfield	 filters,
 							 gchar			**packages);
diff --git a/src/pk-backend-spawn.c b/src/pk-backend-spawn.c
index 9878340..768b041 100644
--- a/src/pk-backend-spawn.c
+++ b/src/pk-backend-spawn.c
@@ -384,6 +384,25 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 
 		ret = pk_backend_distro_upgrade (backend_spawn->priv->backend, distro_upgrade_enum, sections[2], sections[3]);
 		goto out;
+	} else if (egg_strequal (command, "category")) {
+
+		if (size != 5) {
+			egg_warning ("invalid command '%s'", command);
+			ret = FALSE;
+			goto out;
+		}
+		if (egg_strzero (sections[2])) {
+			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR, "cat_id cannot not blank");
+			ret = FALSE;
+			goto out;
+		}
+		if (egg_strzero (sections[3])) {
+			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR, "name cannot not blank");
+			ret = FALSE;
+			goto out;
+		}
+		ret = pk_backend_category (backend_spawn->priv->backend, sections[1], sections[2], sections[3], sections[4], sections[5]);
+		goto out;
 	} else {
 		egg_warning ("invalid command '%s'", command);
 	}
diff --git a/src/pk-backend.c b/src/pk-backend.c
index 0befc22..8cc58e6 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -131,6 +131,7 @@ enum {
 	PK_BACKEND_FINISHED,
 	PK_BACKEND_ALLOW_CANCEL,
 	PK_BACKEND_REPO_DETAIL,
+	PK_BACKEND_CATEGORY,
 	PK_BACKEND_LAST_SIGNAL
 };
 
@@ -247,6 +248,8 @@ pk_backend_get_actions (PkBackend *backend)
 		pk_bitfield_add (roles, PK_ROLE_ENUM_REPO_SET_DATA);
 	if (desc->get_distro_upgrades != NULL)
 		pk_bitfield_add (roles, PK_ROLE_ENUM_GET_DISTRO_UPGRADES);
+	if (desc->get_categories != NULL)
+		pk_bitfield_add (roles, PK_ROLE_ENUM_GET_CATEGORIES);
 	return roles;
 }
 
@@ -1213,6 +1216,34 @@ pk_backend_repo_detail (PkBackend *backend, const gchar *repo_id,
 }
 
 /**
+ * pk_backend_category:
+ **/
+gboolean
+pk_backend_category (PkBackend *backend, const gchar *parent_id, const gchar *cat_id, const gchar *name, const gchar *summary, const gchar *icon)
+{
+	gchar *summary_safe;
+
+	g_return_val_if_fail (PK_IS_BACKEND (backend), FALSE);
+	g_return_val_if_fail (cat_id != NULL, FALSE);
+	g_return_val_if_fail (backend->priv->locked != FALSE, FALSE);
+
+	/* have we already set an error? */
+	if (backend->priv->set_error) {
+		egg_warning ("already set error, cannot process: category %s", cat_id);
+		return FALSE;
+	}
+
+	/* replace unsafe chars */
+	summary_safe = pk_strsafe (summary);
+
+	egg_debug ("emit category %s, %s, %s, %s, %s", parent_id, cat_id, name, summary_safe, icon);
+	g_signal_emit (backend, signals [PK_BACKEND_CATEGORY], 0, parent_id, cat_id, name, summary, icon);
+	g_free (summary_safe);
+	return TRUE;
+
+}
+
+/**
  * pk_backend_error_timeout_delay_cb:
  *
  * We have to call Finished() within PK_BACKEND_FINISHED_ERROR_TIMEOUT of ErrorCode(), enforce this.
@@ -1777,6 +1808,11 @@ pk_backend_class_init (PkBackendClass *klass)
 			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
 			      0, NULL, NULL, pk_marshal_VOID__STRING_STRING_BOOL,
 			      G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN);
+	signals [PK_BACKEND_CATEGORY] =
+		g_signal_new ("category",
+			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+			      0, NULL, NULL, pk_marshal_VOID__STRING_STRING_STRING_STRING_STRING,
+			      G_TYPE_NONE, 5, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
 	g_type_class_add_private (klass, sizeof (PkBackendPrivate));
 }
 
diff --git a/src/pk-backend.h b/src/pk-backend.h
index 4cec320..8f653d4 100644
--- a/src/pk-backend.h
+++ b/src/pk-backend.h
@@ -141,6 +141,12 @@ gboolean         pk_backend_eula_required		(PkBackend      *backend,
 							 const gchar    *package_id,
 							 const gchar    *vendor_name,
 							 const gchar    *license_agreement);
+gboolean         pk_backend_category			(PkBackend      *backend,
+							 const gchar	*parent_id,
+							 const gchar	*cat_id,
+							 const gchar    *name,
+							 const gchar    *summary,
+							 const gchar    *icon);
 
 /* set backend instance data */
 gboolean	 pk_backend_set_array			(PkBackend	*backend,
@@ -207,6 +213,7 @@ typedef struct {
 	void		(*download_packages)		(PkBackend	*backend,
 							 gchar		**package_ids,
 							 const gchar	*directory);
+	void		(*get_categories)		(PkBackend	*backend);
 	void		(*get_depends)			(PkBackend	*backend,
 							 PkBitfield	 filters,
 							 gchar		**package_ids,
@@ -280,8 +287,9 @@ typedef struct {
 	gpointer	padding[10];
 } PkBackendDesc;
 
-#define PK_BACKEND_OPTIONS(description, author, initialize, destroy, get_groups, get_filters, get_mime_types, cancel, download_packages, \
-			   get_depends, get_details, get_distro_upgrades, get_files, get_packages, get_repo_list, get_requires,	\
+#define PK_BACKEND_OPTIONS(description, author, initialize, destroy, get_groups, get_filters, 		\
+			   get_mime_types, cancel, download_packages, get_categories, get_depends,	\
+			   get_details, get_distro_upgrades, get_files, get_packages, get_repo_list, get_requires,	\
 			   get_update_detail, get_updates, install_files, install_packages,		\
 			   install_signature, refresh_cache, remove_packages, repo_enable,		\
 			   repo_set_data, resolve, rollback, search_details, search_file, search_group,	\
@@ -296,6 +304,7 @@ typedef struct {
 		get_mime_types,		\
 		cancel,			\
 		download_packages,	\
+		get_categories,		\
 		get_depends,		\
 		get_details,		\
 		get_distro_upgrades,	\
diff --git a/src/pk-interface-transaction.xml b/src/pk-interface-transaction.xml
index d86d5a3..6490eee 100644
--- a/src/pk-interface-transaction.xml
+++ b/src/pk-interface-transaction.xml
@@ -110,6 +110,23 @@
     </method>
 
     <!--*****************************************************************************************-->
+    <method name="GetCategories">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <doc:doc>
+        <doc:description>
+          <doc:para>
+            This method return the collection categories
+          </doc:para>
+        </doc:description>
+          <doc:para>
+            This method typically emits
+            <literal>Categories</literal>,
+            <literal>Error</literal> and
+          </doc:para>
+      </doc:doc>
+    </method>
+
+    <!--*****************************************************************************************-->
     <method name="GetDepends">
       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
       <doc:doc>
@@ -1311,6 +1328,73 @@
     </signal>
 
     <!--*****************************************************************************************-->
+    <signal name="Category">
+      <doc:doc>
+        <doc:description>
+          <doc:para>
+            This signal send information about a collection category
+          </doc:para>
+        </doc:description>
+      </doc:doc>
+      <arg type="s" name="parent_id" direction="out">
+        <doc:doc>
+          <doc:summary>
+            <doc:para>
+              The parent identifier, e.g. <doc:tt>applications</doc:tt>.
+              If the category is a root entry, use a blank parent.
+            </doc:para>
+          </doc:summary>
+        </doc:doc>
+      </arg>
+      <arg type="s" name="cat_id" direction="out">
+        <doc:doc>
+          <doc:summary>
+            <doc:para>
+              The category identifier, e.g. <doc:tt>applications;system-tools</doc:tt>.
+              The identifier does not have to be related to the <doc:tt>parent_id</doc:tt>
+              in any way.
+              A menu tree is made from multiple Category signals.
+              The tree does not have any depth or bredth limits, although it should be kept
+              to less than about 100 entries as this will be shown to the user in a menu.
+            </doc:para>
+            <doc:para>
+              The <doc:tt>cat_id</doc:tt> will be sent as a parameter to <doc:tt>SearchGroup</doc:tt>
+              so you may have to prefix or otherwise identify the ID to not confuse the search method.
+            </doc:para>
+          </doc:summary>
+        </doc:doc>
+      </arg>
+      <arg type="s" name="name" direction="out">
+        <doc:doc>
+          <doc:summary>
+            <doc:para>
+              The localised name of the category, e.g. <doc:tt>System Tools</doc:tt>.
+            </doc:para>
+          </doc:summary>
+        </doc:doc>
+      </arg>
+      <arg type="s" name="summary" direction="out">
+        <doc:doc>
+          <doc:summary>
+            <doc:para>
+              The localised category summary, e.g. <doc:tt>Tools for mangaing system state</doc:tt>.
+              This is not normally shown in the menus, but may be shown in helper popups.
+            </doc:para>
+          </doc:summary>
+        </doc:doc>
+      </arg>
+      <arg type="s" name="icon" direction="out">
+        <doc:doc>
+          <doc:summary>
+            <doc:para>
+              The icon name for the category, e.g. <doc:tt>server-cfg</doc:tt>.
+            </doc:para>
+          </doc:summary>
+        </doc:doc>
+      </arg>
+    </signal>
+
+    <!--*****************************************************************************************-->
     <signal name="Details">
       <doc:doc>
         <doc:description>
diff --git a/src/pk-transaction.c b/src/pk-transaction.c
index 903513a..96d0467 100644
--- a/src/pk-transaction.c
+++ b/src/pk-transaction.c
@@ -133,6 +133,7 @@ struct PkTransactionPrivate
 	gchar			*cached_parameter;
 	gchar			*cached_value;
 	gchar			*cached_directory;
+	gchar			*cached_cat_id;
 	PkProvidesEnum		 cached_provides;
 
 	guint			 signal_allow_cancel;
@@ -150,6 +151,7 @@ struct PkTransactionPrivate
 	guint			 signal_require_restart;
 	guint			 signal_status_changed;
 	guint			 signal_update_detail;
+	guint			 signal_category;
 };
 
 enum {
@@ -170,6 +172,7 @@ enum {
 	PK_TRANSACTION_STATUS_CHANGED,
 	PK_TRANSACTION_TRANSACTION,
 	PK_TRANSACTION_UPDATE_DETAIL,
+	PK_TRANSACTION_CATEGORY,
 	PK_TRANSACTION_DESTROY,
 	PK_TRANSACTION_LAST_SIGNAL
 };
@@ -515,6 +518,21 @@ pk_transaction_files_cb (PkBackend *backend, const gchar *package_id,
 }
 
 /**
+ * pk_transaction_category_cb:
+ **/
+static void
+pk_transaction_category_cb (PkBackend *backend, const gchar *parent_id, const gchar *cat_id,
+			 const gchar *name, const gchar *summary, const gchar *icon,
+			 PkTransaction *transaction)
+{
+	g_return_if_fail (PK_IS_TRANSACTION (transaction));
+	g_return_if_fail (transaction->priv->tid != NULL);
+
+	egg_debug ("emitting category %s, %s, %s, %s, %s ", parent_id, cat_id, name, summary, icon);
+	g_signal_emit (transaction, signals [PK_TRANSACTION_CATEGORY], 0, parent_id, cat_id, name, summary, icon);
+}
+
+/**
  * pk_transaction_distro_upgrade_cb:
  **/
 static void
@@ -566,6 +584,7 @@ pk_transaction_finished_cb (PkBackend *backend, PkExitEnum exit, PkTransaction *
 	g_signal_handler_disconnect (transaction->priv->backend, transaction->priv->signal_require_restart);
 	g_signal_handler_disconnect (transaction->priv->backend, transaction->priv->signal_status_changed);
 	g_signal_handler_disconnect (transaction->priv->backend, transaction->priv->signal_update_detail);
+	g_signal_handler_disconnect (transaction->priv->backend, transaction->priv->signal_category);
 
 	/* do some optional extra actions when we've finished refreshing the cache */
 	if (exit == PK_EXIT_ENUM_SUCCESS &&
@@ -977,6 +996,9 @@ pk_transaction_set_running (PkTransaction *transaction)
 	transaction->priv->signal_update_detail =
 		g_signal_connect (transaction->priv->backend, "update-detail",
 				  G_CALLBACK (pk_transaction_update_detail_cb), transaction);
+	transaction->priv->signal_category =
+		g_signal_connect (transaction->priv->backend, "category",
+				  G_CALLBACK (pk_transaction_category_cb), transaction);
 
 	/* mark running */
 	transaction->priv->running = TRUE;
@@ -1056,6 +1078,8 @@ pk_transaction_set_running (PkTransaction *transaction)
 		desc->update_packages (priv->backend, priv->cached_package_ids);
 	else if (priv->role == PK_ROLE_ENUM_UPDATE_SYSTEM)
 		desc->update_system (priv->backend);
+	else if (priv->role == PK_ROLE_ENUM_GET_CATEGORIES)
+		desc->get_categories (priv->backend);
 	else if (priv->role == PK_ROLE_ENUM_GET_REPO_LIST)
 		desc->get_repo_list (priv->backend, priv->cached_filters);
 	else if (priv->role == PK_ROLE_ENUM_REPO_ENABLE)
@@ -1506,6 +1530,61 @@ pk_transaction_get_allow_cancel (PkTransaction *transaction, gboolean *allow_can
 }
 
 /**
+ * pk_transaction_get_categories:
+ **/
+void
+pk_transaction_get_categories (PkTransaction *transaction, DBusGMethodInvocation *context)
+{
+	gboolean ret;
+	GError *error;
+	gchar *sender;
+
+	g_return_if_fail (PK_IS_TRANSACTION (transaction));
+	g_return_if_fail (transaction->priv->tid != NULL);
+
+	egg_debug ("GetCategories method called");
+
+	/* not implemented yet */
+	if (transaction->priv->backend->desc->get_categories == NULL) {
+		error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_NOT_SUPPORTED,
+				     "Operation not yet supported by backend");
+		pk_transaction_list_remove (transaction->priv->transaction_list,
+					    transaction->priv->tid);
+		dbus_g_method_return_error (context, error);
+		return;
+	}
+
+	/* set the dbus name, so we can get the disconnect */
+	if (context != NULL) {
+		/* not set inside the test suite */
+		sender = dbus_g_method_get_sender (context);
+		pk_transaction_set_dbus_name (transaction, sender);
+		g_free (sender);
+	}
+
+	/* are we already performing an update? */
+	if (pk_transaction_list_role_present (transaction->priv->transaction_list, PK_ROLE_ENUM_GET_CATEGORIES)) {
+		error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_TRANSACTION_EXISTS_WITH_ROLE,
+				     "Already performing get categories");
+		dbus_g_method_return_error (context, error);
+		return;
+	}
+
+	pk_transaction_set_role (transaction, PK_ROLE_ENUM_GET_CATEGORIES);
+
+	/* try to commit this */
+	ret = pk_transaction_commit (transaction);
+	if (!ret) {
+		error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_COMMIT_FAILED,
+				     "Could not commit to a transaction object");
+		dbus_g_method_return_error (context, error);
+		return;
+	}
+
+	dbus_g_method_return (context);
+}
+
+/**
  * pk_transaction_get_depends:
  **/
 void
@@ -3666,6 +3745,11 @@ pk_transaction_class_init (PkTransactionClass *klass)
 			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
 			      0, NULL, NULL, pk_marshal_VOID__STRING_STRING,
 			      G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
+	signals [PK_TRANSACTION_CATEGORY] =
+		g_signal_new ("category",
+			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+			      0, NULL, NULL, pk_marshal_VOID__STRING_STRING_STRING_STRING_STRING,
+			      G_TYPE_NONE, 5, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
 	signals [PK_TRANSACTION_DISTRO_UPGRADE] =
 		g_signal_new ("distro-upgrade",
 			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
diff --git a/src/pk-transaction.h b/src/pk-transaction.h
index 0c7814d..9fa46e6 100644
--- a/src/pk-transaction.h
+++ b/src/pk-transaction.h
@@ -104,6 +104,8 @@ void		 pk_transaction_download_packages	(PkTransaction  *transaction,
 gboolean	 pk_transaction_get_allow_cancel	(PkTransaction	*transaction,
 							 gboolean	*allow_cancel,
 							 GError		**error);
+void		 pk_transaction_get_categories		(PkTransaction	*transaction,
+							 DBusGMethodInvocation *context);
 void		 pk_transaction_get_depends		(PkTransaction	*transaction,
 							 const gchar	*filter,
 							 gchar		**package_ids,
commit a569ae56056935931c8d89f95c0c45a52b2169e9
Author: Nikos Charonitakis <nikosx at gmail.com>
Date:   Mon Oct 6 13:35:41 2008 +0000

    Updated Greek translation
    
    Transmitted-via: Transifex (translate.fedoraproject.org)

diff --git a/po/el.po b/po/el.po
index 6258a21..ca1d0fb 100644
--- a/po/el.po
+++ b/po/el.po
@@ -7,340 +7,516 @@ msgid ""
 msgstr ""
 "Project-Id-Version: packagekit.master\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-04-22 23:08+0300\n"
-"PO-Revision-Date: 2008-04-22 23:43+0300\n"
-"Last-Translator: Dimitris Glezos <dimitris at glezos.com>\n"
+"POT-Creation-Date: 2008-09-25 00:31+0000\n"
+"PO-Revision-Date: 2008-10-06 16:34+0200\n"
+"Last-Translator: nikosCharonitakis <nikosx at gmail.com>\n"
 "Language-Team: Greek Fedora team <fedora-trans-el at redhat.com>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "X-Generator: KBabel 1.11.4\n"
-"Plural-Forms:  nplurals=2; plural=(n != 1);\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: ../client/pk-console.c:208
-#, fuzzy
+#: ../client/pk-console.c:274
 msgid "Update detail"
-msgstr "Ενημέρωση"
+msgstr "Λεπτομέρειες ενημέρωσης"
 
-#: ../client/pk-console.c:400
+#: ../client/pk-console.c:491
 msgid "A system restart is required"
 msgstr "Απαιτείται επανεκκίνηση του συστήματος"
 
-#: ../client/pk-console.c:402
+#: ../client/pk-console.c:493
 msgid "A logout and login is required"
 msgstr "Απαιτείται επανασύνδεση του χρήστη"
 
-#: ../client/pk-console.c:404
+#: ../client/pk-console.c:495
 msgid "An application restart is required"
 msgstr "Απαιτείται επανεκκίνηση της εφαρμογής"
 
-#: ../client/pk-console.c:443
-#, c-format
-msgid "Please enter a number from 1 to %i: "
-msgstr "Παρακαλούμε εισάγετε έναν αριθμό από το 1 μέχρι το %i: "
-
-#: ../client/pk-console.c:493
-msgid "Could not find a package match"
-msgstr "Δε μπόρεσε να βρεθεί αντιστοιχία πακέτου"
-
-#: ../client/pk-console.c:507
+#: ../client/pk-console.c:588
+#: ../client/pk-generate-pack.c:126
 msgid "There are multiple package matches"
 msgstr "Υπάρχουν πολλές αντιστοιχίες πακέτων"
 
 #. find out what package the user wants to use
-#: ../client/pk-console.c:514
+#: ../client/pk-console.c:595
+#: ../client/pk-generate-pack.c:133
 msgid "Please enter the package number: "
 msgstr "Παρακαλούμε εισάγετε τον αριθμό του πακέτου: "
 
-#: ../client/pk-console.c:530
-msgid ""
-"Could not find a package with that name to install, or package already "
-"installed"
-msgstr "Δε μπόρεσε να βρεθεί ένα πακέτο με αυτό το όνομα για να εγκατασταθεί, ή το πακέτο είναι ήδη εγκατεστημένο"
+#: ../client/pk-console.c:629
+#, fuzzy
+msgid "Could not find package to install"
+msgstr "Δε μπόρεσε να βρεθεί αντιστοιχία πακέτου"
 
-#: ../client/pk-console.c:612
-msgid "Could not find a package with that name to remove"
+#: ../client/pk-console.c:735
+#, fuzzy
+msgid "Could not find package to remove"
 msgstr "Δε μπόρεσε να βρεθεί ένα πακέτο με αυτό το όνομα προς αφαίρεση"
 
-#: ../client/pk-console.c:652
+#: ../client/pk-console.c:796
 msgid "The following packages have to be removed"
 msgstr "Τα παρακάτω πακέτα πρέπει να αφαιρεθούν"
 
 #. get user input
-#: ../client/pk-console.c:661
+#: ../client/pk-console.c:803
 msgid "Okay to remove additional packages?"
 msgstr "Εντάξει για την αφαίρεση επιπλέον πακέτων;"
 
-#: ../client/pk-console.c:665
+#: ../client/pk-console.c:807
+#: ../client/pk-generate-pack.c:528
+#: ../client/pk-generate-pack-main.c:131
 msgid "Cancelled!"
 msgstr "Ακυρώθηκε!"
 
-#: ../client/pk-console.c:687
-msgid "Could not find a package with that name to update"
-msgstr "Δε μπόρεσε να βρεθεί πακέτο με αυτό το όνομα για προς ενημέρωση"
+#: ../client/pk-console.c:841
+#, fuzzy
+msgid "Could not find package to download"
+msgstr "Δε μπόρεσε να βρεθεί αντιστοιχία πακέτου"
 
-#: ../client/pk-console.c:705
-msgid "Could not find what packages require this package"
+#: ../client/pk-console.c:893
+#, fuzzy
+msgid "Could not find package to update"
+msgstr "Δε μπόρεσε να βρεθεί αντιστοιχία πακέτου"
+
+#: ../client/pk-console.c:915
+#, fuzzy
+msgid "Could not find what packages require"
 msgstr "Δε μπόρεσε να βρεθεί ποια πακέτα απαιτούν αυτό το πακέτο"
 
-#: ../client/pk-console.c:723
+#: ../client/pk-console.c:936
 #, fuzzy
-msgid "Could not get dependencies for this package"
+msgid "Could not get dependencies for"
 msgstr "όχι get εξαρτήσεις για πακέτο"
 
-#: ../client/pk-console.c:741
+#: ../client/pk-console.c:957
 #, fuzzy
-msgid "Could not find a description for this package"
-msgstr "όχι a περιγραφή για πακέτο"
+msgid "Could not find details for"
+msgstr "όχι αρχεία για πακέτο"
 
-#: ../client/pk-console.c:759
+#: ../client/pk-console.c:980
 #, fuzzy
 msgid "Could not find the files for this package"
 msgstr "όχι αρχεία για πακέτο"
 
-#: ../client/pk-console.c:819
+#: ../client/pk-console.c:987
+#, fuzzy
+msgid "Could not get the file list"
+msgstr "όχι αρχεία για πακέτο"
+
+#: ../client/pk-console.c:1006
+#, fuzzy
+msgid "Could not find the update details for"
+msgstr "όχι αρχεία για πακέτο"
+
+#: ../client/pk-console.c:1067
 msgid "Package description"
 msgstr "Περιγραφή πακέτου"
 
-#: ../client/pk-console.c:842
+#: ../client/pk-console.c:1100
 msgid "Package files"
 msgstr "Αρχεία πακέτου"
 
-#: ../client/pk-console.c:850
+#: ../client/pk-console.c:1108
 msgid "No files"
 msgstr "Χωρίς αρχεία"
 
 #. get user input
-#: ../client/pk-console.c:882
+#: ../client/pk-console.c:1140
 msgid "Okay to import key?"
 msgstr "Εντάξει για την εισαγωγή κλειδιού;"
 
-#: ../client/pk-console.c:885
+#: ../client/pk-console.c:1143
 msgid "Did not import key"
 msgstr "Δεν έγινε εισαγωγή κλειδιού"
 
 #. get user input
-#: ../client/pk-console.c:925
+#: ../client/pk-console.c:1183
 msgid "Do you agree?"
 msgstr "Συμφωνείτε;"
 
-#: ../client/pk-console.c:928
+#: ../client/pk-console.c:1186
 msgid "Did not agree to licence, task will fail"
 msgstr "Δεν έγινε συμφωνία με την άδεια χρήσης, η ενέργεια θα αποτύχει"
 
-#: ../client/pk-console.c:957
+#: ../client/pk-console.c:1215
 msgid "The daemon crashed mid-transaction!"
 msgstr ""
 
 #. header
-#: ../client/pk-console.c:1010
+#: ../client/pk-console.c:1268
 #, fuzzy
 msgid "PackageKit Console Interface"
 msgstr "Κονσόλα"
 
-#: ../client/pk-console.c:1010
+#: ../client/pk-console.c:1268
 msgid "Subcommands:"
 msgstr "Υποεντολές:"
 
-#: ../client/pk-console.c:1114 ../client/pk-monitor.c:100 ../src/pk-main.c:189
-#, fuzzy
+#: ../client/pk-console.c:1378
+#: ../client/pk-generate-pack-main.c:64
+#: ../client/pk-monitor.c:118
+#: ../src/pk-main.c:192
 msgid "Show extra debugging information"
-msgstr "Προβολή επιπρόσθετων επιλογών αποσφαλμάτωσης"
+msgstr "Εμφάνιση επιπρόσθετων πληροφοριών αποσφαλμάτωσης"
 
-#: ../client/pk-console.c:1116 ../client/pk-monitor.c:102
-#, fuzzy
+#: ../client/pk-console.c:1380
+#: ../client/pk-monitor.c:120
 msgid "Show the program version and exit"
-msgstr "πρόγραμμα έκδοση και"
+msgstr "Εμφάνιση έκδοσης προγράμματος και έξοδος"
 
-#: ../client/pk-console.c:1118
+#: ../client/pk-console.c:1382
 #, fuzzy
 msgid "Set the filter, e.g. installed"
 msgstr "Ορισμός φίλτρο e g εγκατεστημένο"
 
-#: ../client/pk-console.c:1120
+#: ../client/pk-console.c:1384
 #, fuzzy
 msgid "Exit without waiting for actions to complete"
 msgstr "Έξοδος για ολοκληρωμένο"
 
-#: ../client/pk-console.c:1143
-#, fuzzy
+#: ../client/pk-console.c:1407
 msgid "Could not connect to system DBUS."
-msgstr "όχι σύνδεση σύστημα."
+msgstr "Αδυναμία σύνδεσης στο DBUS του συστήματος."
 
-#: ../client/pk-console.c:1231
+#: ../client/pk-console.c:1500
 #, fuzzy
-msgid "You need to specify a search type"
+msgid "You need to specify a search type, e.g. name"
 msgstr "a τύπος"
 
-#: ../client/pk-console.c:1236 ../client/pk-console.c:1243
-#: ../client/pk-console.c:1250 ../client/pk-console.c:1257
-#: ../client/pk-console.c:1361 ../client/pk-console.c:1368
-#: ../client/pk-console.c:1375 ../client/pk-console.c:1382
+#: ../client/pk-console.c:1505
+#: ../client/pk-console.c:1512
+#: ../client/pk-console.c:1519
+#: ../client/pk-console.c:1526
+#: ../client/pk-console.c:1637
+#: ../client/pk-console.c:1647
+#: ../client/pk-console.c:1654
+#: ../client/pk-console.c:1661
 #, fuzzy
 msgid "You need to specify a search term"
 msgstr "a όρος"
 
-#: ../client/pk-console.c:1262
-#, fuzzy
+#: ../client/pk-console.c:1531
 msgid "Invalid search type"
-msgstr "Μη έγκυρο τύπος"
+msgstr "Μη έγκυρος τύπος αναζήτησης"
 
-#: ../client/pk-console.c:1267
+#: ../client/pk-console.c:1536
 #, fuzzy
 msgid "You need to specify a package or file to install"
 msgstr "a πακέτο ή αρχείο"
 
-#: ../client/pk-console.c:1280
+#: ../client/pk-console.c:1543
 #, fuzzy
 msgid "You need to specify a type, key_id and package_id"
 msgstr "a τύπος και"
 
-#: ../client/pk-console.c:1287
+#: ../client/pk-console.c:1550
 #, fuzzy
 msgid "You need to specify a package to remove"
 msgstr "a πακέτο αφαίρεση"
 
-#: ../client/pk-console.c:1294
+#: ../client/pk-console.c:1556
+#, fuzzy
+msgid "You need to specify the destination directory and then the packages to download"
+msgstr "a τύπος και"
+
+#: ../client/pk-console.c:1561
+msgid "Directory not found"
+msgstr "Δε βρέθηκε ο κατάλογος"
+
+#: ../client/pk-console.c:1567
 #, fuzzy
 msgid "You need to specify a eula-id"
 msgstr "a id"
 
-#: ../client/pk-console.c:1309
+#: ../client/pk-console.c:1583
 #, fuzzy
 msgid "You need to specify a package name to resolve"
 msgstr "a πακέτο όνομα"
 
-#: ../client/pk-console.c:1316 ../client/pk-console.c:1323
+#: ../client/pk-console.c:1592
+#: ../client/pk-console.c:1599
 #, fuzzy
 msgid "You need to specify a repo name"
 msgstr "a όνομα"
 
-#: ../client/pk-console.c:1330
+#: ../client/pk-console.c:1606
 #, fuzzy
 msgid "You need to specify a repo name/parameter and value"
 msgstr "a όνομα και τιμή"
 
-#: ../client/pk-console.c:1343
+#: ../client/pk-console.c:1619
 #, fuzzy
 msgid "You need to specify a time term"
 msgstr "a ώρα όρος"
 
-#: ../client/pk-console.c:1348
+#: ../client/pk-console.c:1624
 #, fuzzy
 msgid "You need to specify a correct role"
 msgstr "a σωστό"
 
-#: ../client/pk-console.c:1353
+#: ../client/pk-console.c:1629
 #, fuzzy
 msgid "Failed to get last time"
 msgstr "Απέτυχε get ώρα"
 
-#: ../client/pk-console.c:1389
+#: ../client/pk-console.c:1668
 #, fuzzy
-msgid "You need to specify a package to find the description for"
-msgstr "a πακέτο περιγραφή για"
+msgid "You need to specify a package to find the details for"
+msgstr "a πακέτο αρχεία για"
 
-#: ../client/pk-console.c:1396
+#: ../client/pk-console.c:1675
 #, fuzzy
 msgid "You need to specify a package to find the files for"
 msgstr "a πακέτο αρχεία για"
 
-#: ../client/pk-console.c:1441
+#: ../client/pk-console.c:1724
 #, c-format
-#, fuzzy
 msgid "Option '%s' not supported"
-msgstr "όχι υποστηρίζεται"
+msgstr "Δεν υποστηρίζεται η επιλογή '%s'"
 
-#: ../client/pk-console.c:1452
-#, fuzzy
+#: ../client/pk-console.c:1737
+msgid "You don't have the necessary privileges for this operation"
+msgstr "Δεν έχετε τα απαραίτητα δικαιώματα για αυτή τη λειτουργία"
+
+#: ../client/pk-console.c:1739
 msgid "Command failed"
-msgstr "Εντολή απέτυχε"
+msgstr "Η εντολή απέτυχε"
+
+#: ../client/pk-generate-pack.c:117
+msgid "Could not find a package match"
+msgstr "Δε μπόρεσε να βρεθεί αντιστοιχία πακέτου"
+
+#: ../client/pk-generate-pack.c:151
+msgid "failed to download: invalid package_id and/or directory"
+msgstr ""
 
-#: ../client/pk-console.c:1456
+#: ../client/pk-generate-pack.c:232
 #, fuzzy
-msgid "You don't have the necessary privileges for this operation"
-msgstr "t για"
+msgid "Could not find a valid metadata file"
+msgstr "Δε μπόρεσε να βρεθεί αντιστοιχία πακέτου"
 
-#: ../client/pk-monitor.c:113
+#. get user input
+#: ../client/pk-generate-pack.c:524
 #, fuzzy
-msgid "PackageKit Monitor"
-msgstr "Οθόνη"
+msgid "Okay to download the additional packages"
+msgstr "Εντάξει για την αφαίρεση επιπλέον πακέτων;"
 
-#: ../client/pk-import-desktop.c:283 ../client/pk-import-specspo.c:169
-#, c-format
+#: ../client/pk-generate-pack-main.c:66
+msgid "Set the path of the file with the list of packages/dependencies to be excluded"
+msgstr ""
+
+#: ../client/pk-generate-pack-main.c:111
+#, fuzzy
+msgid "You need to specify the pack name and packages to be packed\n"
+msgstr "a πακέτο αφαίρεση"
+
+#: ../client/pk-generate-pack-main.c:117
+msgid "Invalid name for the service pack, Specify a name with .servicepack extension\n"
+msgstr ""
+
+#: ../client/pk-generate-pack-main.c:129
+msgid "A pack with the same name already exists, do you want to overwrite it?"
+msgstr ""
+
+#: ../client/pk-generate-pack-main.c:142
+msgid "Failed to create directory"
+msgstr "Αποτυχία δημιουργίας καταλόγου"
+
+#: ../client/pk-generate-pack-main.c:149
 #, fuzzy
+msgid "Failed to create pack"
+msgstr "Απέτυχε get ώρα"
+
+#: ../client/pk-import-specspo.c:185
+#, fuzzy
+msgid "Could not set database readonly"
+msgstr "όχι open"
+
+#: ../client/pk-import-specspo.c:192
+#, fuzzy, c-format
 msgid "Could not open database: %s"
 msgstr "όχι open"
 
-#: ../client/pk-import-desktop.c:284 ../client/pk-import-specspo.c:170
+#: ../client/pk-import-specspo.c:193
 #, fuzzy
 msgid "You probably need to run this program as the root user"
 msgstr "πρόγραμμα χρήστης"
 
-#: ../src/pk-main.c:83
+#: ../client/pk-monitor.c:131
+#, fuzzy
+msgid "PackageKit Monitor"
+msgstr "Οθόνη"
+
+#: ../client/pk-tools-common.c:51
+#, c-format
+msgid "Please enter a number from 1 to %i: "
+msgstr "Παρακαλούμε εισάγετε έναν αριθμό από το 1 μέχρι το %i: "
+
+#: ../contrib/packagekit-plugin/src/contents.cpp:300
+msgid "Getting package information..."
+msgstr "Λήψη πληροφοριών πακέτου..."
+
+#: ../contrib/packagekit-plugin/src/contents.cpp:304
+#, c-format
+msgid "<span color='#%06x' underline='single' size='larger'>Run %s</span>"
+msgstr "<span color='#%06x' underline='single' size='larger'>Εκτέλεση %s</span>"
+
+#: ../contrib/packagekit-plugin/src/contents.cpp:308
+#: ../contrib/packagekit-plugin/src/contents.cpp:313
+#: ../contrib/packagekit-plugin/src/contents.cpp:336
+#: ../contrib/packagekit-plugin/src/contents.cpp:340
+#, c-format
+msgid "<big>%s</big>"
+msgstr "<big>%s</big>"
+
+#: ../contrib/packagekit-plugin/src/contents.cpp:310
+#, c-format
+msgid ""
+"\n"
+"<small>Installed version: %s</small>"
+msgstr ""
+"\n"
+"<small>Εγκατεστημένη έκδοση: %s</small>"
+
+#: ../contrib/packagekit-plugin/src/contents.cpp:316
+#, c-format
+msgid ""
+"\n"
+"<span color='#%06x' underline='single'>Run version %s now</span>"
+msgstr ""
+
+#: ../contrib/packagekit-plugin/src/contents.cpp:321
+#, c-format
+msgid ""
+"\n"
+"<span color='#%06x' underline='single'>Run now</span>"
+msgstr ""
+"\n"
+"<span color='#%06x' underline='single'>Εκτέλεση τώρα</span>"
+
+#: ../contrib/packagekit-plugin/src/contents.cpp:325
+#, c-format
+msgid ""
+"\n"
+"<span color='#%06x' underline='single'>Upgrade to version %s</span>"
+msgstr ""
+
+#: ../contrib/packagekit-plugin/src/contents.cpp:330
+#, c-format
+msgid "<span color='#%06x' underline='single' size='larger'>Install %s Now</span>"
+msgstr "<span color='#%06x' underline='single' size='larger'>Εγκατάσταση %s τώρα</span>"
+
+#: ../contrib/packagekit-plugin/src/contents.cpp:333
+#, c-format
+msgid ""
+"\n"
+"<small>Version: %s</small>"
+msgstr ""
+"\n"
+"<small>Έκδοση: %s</small>"
+
+#: ../contrib/packagekit-plugin/src/contents.cpp:337
+msgid ""
+"\n"
+"<small>No packages found for your system</small>"
+msgstr ""
+"\n"
+"<small>Δεν βρέθηκαν πακέτα για το σύστημα σας</small>"
+
+#: ../contrib/packagekit-plugin/src/contents.cpp:341
+msgid ""
+"\n"
+"<small>Installing...</small>"
+msgstr ""
+"\n"
+"<small>Γίνεται εγκατάσταση...</small>"
+
+#: ../data/packagekit-catalog.xml.in.h:1
+#, fuzzy
+msgid "PackageKit Catalog"
+msgstr "Οθόνη"
+
+#: ../data/packagekit-pack.xml.in.h:1
+#, fuzzy
+msgid "PackageKit Service Pack"
+msgstr "Υπηρεσία PackageKit"
+
+#: ../src/pk-main.c:85
 #, fuzzy
 msgid "Startup failed due to security policies on this machine."
 msgstr "απέτυχε ενεργό."
 
-#: ../src/pk-main.c:84
-#, fuzzy
+#: ../src/pk-main.c:86
 msgid "This can happen for two reasons:"
-msgstr "για δύο:"
+msgstr "Αυτό μπορεί να συμβεί για δύο λόγους:"
 
-#: ../src/pk-main.c:85
+#: ../src/pk-main.c:87
 #, fuzzy
 msgid "The correct user is not launching the executable (usually root)"
 msgstr "σωστό χρήστης είναι όχι"
 
-#: ../src/pk-main.c:86
+#: ../src/pk-main.c:88
 #, fuzzy
-msgid ""
-"The org.freedesktop.PackageKit.conf file is not installed in the system /etc/"
-"dbus-1/system.d directory"
+msgid "The org.freedesktop.PackageKit.conf file is not installed in the system /etc/dbus-1/system.d directory"
 msgstr "οργανισμός αρχείο είναι όχι εγκατεστημένο μέσα σύστημα σύστημα ημ"
 
-#: ../src/pk-main.c:185
+#: ../src/pk-main.c:188
 #, fuzzy
 msgid "Packaging backend to use, e.g. dummy"
 msgstr "Πακετάρισμα e g dummy"
 
-#: ../src/pk-main.c:187
+#: ../src/pk-main.c:190
 #, fuzzy
 msgid "Daemonize and detach from the terminal"
 msgstr "και από"
 
-#: ../src/pk-main.c:191
+#: ../src/pk-main.c:194
 #, fuzzy
 msgid "Disable the idle timer"
 msgstr "Απενεργοποίηση χρονόμετρο"
 
-#: ../src/pk-main.c:193
-#, fuzzy
+#: ../src/pk-main.c:196
 msgid "Show version and exit"
-msgstr "έκδοση και"
+msgstr "Προβολή έκδοσης και έξοδος"
 
-#: ../src/pk-main.c:195
-#, fuzzy
+#: ../src/pk-main.c:198
 msgid "Exit after a small delay"
-msgstr "Έξοδος a μικρό"
+msgstr "Έξοδος μετά από μια μικρή καθυστέρηση"
 
-#: ../src/pk-main.c:197
+#: ../src/pk-main.c:200
 #, fuzzy
 msgid "Exit after the engine has loaded"
 msgstr "Έξοδος φορτωμένο"
 
-#: ../src/pk-main.c:207
+#: ../src/pk-main.c:210
 msgid "PackageKit service"
 msgstr "Υπηρεσία PackageKit"
 
-#: ../src/pk-main.c:233
+#: ../src/pk-main.c:246
 #, fuzzy
 msgid "Cannot connect to the system bus"
 msgstr "σύνδεση σύστημα"
 
-#: ../src/pk-main.c:273
+#: ../src/pk-main.c:286
 #, c-format
-#, fuzzy
 msgid "Error trying to start: %s\n"
-msgstr "Σφάλμα έναρξη n"
+msgstr "Σφάλμα στην προσπάθεια εκκίνησης του %s\n"
+
+#~ msgid ""
+#~ "Could not find a package with that name to install, or package already "
+#~ "installed"
+#~ msgstr ""
+#~ "Δε μπόρεσε να βρεθεί ένα πακέτο με αυτό το όνομα για να εγκατασταθεί, ή "
+#~ "το πακέτο είναι ήδη εγκατεστημένο"
+#~ msgid "Could not find a package with that name to update"
+#~ msgstr "Δε μπόρεσε να βρεθεί πακέτο με αυτό το όνομα για προς ενημέρωση"
+
+#, fuzzy
+#~ msgid "Could not find a description for this package"
+#~ msgstr "όχι a περιγραφή για πακέτο"
+
+#, fuzzy
+#~ msgid "You need to specify a package to find the description for"
+#~ msgstr "a πακέτο περιγραφή για"
 
commit 401a72ef2d041bf8c13c239719aeebb8223db95c
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Oct 6 11:08:18 2008 +0100

    trivial: update RELEASE

diff --git a/RELEASE b/RELEASE
index 1944363..4ae824b 100644
--- a/RELEASE
+++ b/RELEASE
@@ -3,8 +3,8 @@ PackageKit Release Notes
 1. Write NEWS entries for PackageKit and gnome-packagekit in the same
    format as usual. Ignore any trivial commits.
 
-git-shortlog PACKAGEKIT_0_3_5.. | grep -v trivial | grep -v Merge > NEWS.new
-git-shortlog GNOME_PACKAGEKIT_0_3_5.. | grep -v trivial | grep -v Merge > NEWS.new
+git-shortlog PACKAGEKIT_0_3_6.. | grep -v trivial | grep -v Merge > NEWS.new
+git-shortlog GNOME_PACKAGEKIT_0_3_6.. | grep -v trivial | grep -v Merge > NEWS.new
 
 2. Add download date to docs/html/pk-download.html, save file.
 
@@ -12,8 +12,8 @@ git-shortlog GNOME_PACKAGEKIT_0_3_5.. | grep -v trivial | grep -v Merge > NEWS.n
 
 4. Commit changes in PackageKit git:
 
-git commit -a -m "Release version 0.3.6"
-git tag -a -f -m "Release 0.3.6" PACKAGEKIT_0_3_6
+git commit -a -m "Release version 0.3.7"
+git tag -a -f -m "Release 0.3.7" PACKAGEKIT_0_3_7
 git push --tags
 git push
 git push git+ssh://hughsient@git.freedesktop.org/git/packagekit
@@ -21,8 +21,8 @@ git push --tags git+ssh://hughsient@git.freedesktop.org/git/packagekit
 
 5. Commit changes in gnome-packagekit git:
 
-git commit -a -m "Release version 0.3.6"
-git-tag GNOME_PACKAGEKIT_0_3_6
+git commit -a -m "Release version 0.3.7"
+git-tag GNOME_PACKAGEKIT_0_3_7
 git push --tags
 git push
 
@@ -42,9 +42,9 @@ git push
 10. Send an email to packagekit at lists.freedesktop.org
 
 =================================================
-Subject: PackageKit and gnome-packagekit 0.3.6 released!
+Subject: PackageKit and gnome-packagekit 0.3.7 released!
 
-Today I released PackageKit and gnome-packagekit 0.3.6.
+Today I released PackageKit and gnome-packagekit 0.3.7.
 
 PackageKit release notes: http://gitweb.freedesktop.org/?p=packagekit.git;a=blob;f=NEWS
 
commit 73481f83e4d4e78996c7eee989ddf8e4a88e3f3b
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Oct 6 11:06:40 2008 +0100

    trivial: post release version bump

diff --git a/configure.ac b/configure.ac
index 1903595..26c131b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
 AC_PREREQ(2.52)
 
-AC_INIT(PackageKit, 0.3.6)
+AC_INIT(PackageKit, 0.3.7)
 AC_CONFIG_SRCDIR(src)
 AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
 AM_CONFIG_HEADER(config.h)


More information about the PackageKit-commit mailing list