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

Richard Hughes hughsient at kemper.freedesktop.org
Fri Aug 22 10:18:07 PDT 2008


 backends/apt/aptDBUSBackend.py              |   35 +++-
 backends/apt/pk-backend-apt.c               |   15 +
 backends/conary/helpers/conaryBackend.py    |   36 +---
 backends/conary/helpers/install-packages.py |    4 
 backends/conary/helpers/remove-packages.py  |    4 
 backends/conary/pk-backend-conary.c         |   14 -
 backends/yum/helpers/yumBackend.py          |   10 -
 backends/zypp/pk-backend-zypp.cpp           |    3 
 client/Makefile.am                          |    5 
 client/pk-console.c                         |   40 ++++
 client/pk-generate-pack.c                   |  241 +++++++++++++---------------
 configure.ac                                |   21 +-
 contrib/PackageKit.spec.in                  |    6 
 contrib/packagekit-plugin/src/contents.cpp  |   15 +
 contrib/pk-completion.bash                  |    1 
 docs/html/pk-matrix.html                    |   17 +
 libpackagekit/Makefile.am                   |    3 
 libpackagekit/pk-client.c                   |   97 +++++++++++
 libpackagekit/pk-client.h                   |    6 
 libpackagekit/pk-distro-upgrade-obj.c       |  149 +++++++++++++++++
 libpackagekit/pk-distro-upgrade-obj.h       |   51 +++++
 src/Makefile.am                             |    8 
 src/pk-backend.c                            |    3 
 src/pk-engine.c                             |    2 
 src/pk-transaction.c                        |  136 +++++++++++++--
 tools/add-error-enum.sh                     |    2 
 26 files changed, 704 insertions(+), 220 deletions(-)

New commits:
commit 20f9d06773ad1ac4142cfa900a7539e40846adf3
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu Aug 21 17:33:40 2008 +0100

    trivial fixes to pkcon for DownloadPackages

diff --git a/client/pk-console.c b/client/pk-console.c
index 629ecaf..91cee17 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -1040,7 +1040,17 @@ static void
 pk_console_files_cb (PkClient *client, const gchar *package_id,
 		     const gchar *filelist, gpointer data)
 {
-	gchar **filevector = g_strsplit (filelist, ";", 0);
+	PkRoleEnum role;
+	gchar **filevector;
+
+	/* don't print if we are DownloadPackages */
+	pk_client_get_role (client, &role, NULL, NULL);
+	if (role == PK_ROLE_ENUM_DOWNLOAD_PACKAGES) {
+		pk_debug ("ignoring ::files");
+		return;
+	}
+
+	filevector = g_strsplit (filelist, ";", 0);
 
 	if (awaiting_space) {
 		g_print ("\n");
@@ -1340,7 +1350,6 @@ main (int argc, char *argv[])
 	}
 	dbus_g_thread_init ();
 	g_type_init ();
-	pk_debug_init (verbose);
 
 	/* do stuff on ctrl-c */
 	signal (SIGINT, pk_console_sigint_handler);
@@ -1371,6 +1380,9 @@ main (int argc, char *argv[])
 	options_help = g_option_context_get_help (context, TRUE, NULL);
 	g_option_context_free (context);
 
+	/* we are now parsed */
+	pk_debug_init (verbose);
+
 	if (program_version) {
 		g_print (VERSION "\n");
 		return 0;
commit 1e1186196dd0ccc78f270faf1ae97aecf23121d6
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu Aug 21 17:33:12 2008 +0100

    trivial: do the file copy sync, not async

diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 3742447..1ce2a47 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -699,7 +699,7 @@ pk_client_file_copy (const gchar *filename, const gchar *directory)
 	/* TODO: use GIO when we have a hard dep on it */
 	command = g_strdup_printf ("cp \"%s\" \"%s\"", filename, directory);
 	pk_debug ("command: %s", command);
-	ret = g_spawn_command_line_async (command, &error);
+	ret = g_spawn_command_line_sync (command, NULL, NULL, NULL, &error);
 	if (!ret) {
 		pk_warning ("failed to copy: %s", error->message);
 		g_error_free (error);
@@ -724,7 +724,7 @@ pk_client_files_cb (DBusGProxy *proxy, const gchar *package_id, const gchar *fil
 	g_signal_emit (client , signals [PK_CLIENT_FILES], 0, package_id, filelist);
 
 	/* we are a callback from DownloadPackages */
-	if (client->priv->role == PK_ROLE_ENUM_DOWNLOAD_PACKAGES && pk_strzero (package_id)) {
+	if (client->priv->role == PK_ROLE_ENUM_DOWNLOAD_PACKAGES) {
 		split = g_strsplit (filelist, ";", -1);
 		length = g_strv_length (split);
 		for (i=0; i<length; i++) {
commit 07b0fa90f520f56317ef9ad0fca677febe3f135e
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu Aug 21 17:32:33 2008 +0100

    trivial: fix the rpmbuild by checking chdir() and getcwd() for errors

diff --git a/src/pk-transaction.c b/src/pk-transaction.c
index 63b15fc..04b31c7 100644
--- a/src/pk-transaction.c
+++ b/src/pk-transaction.c
@@ -2176,13 +2176,19 @@ gboolean
 pk_transaction_archive_extract (const gchar *filename, const gchar *directory, GError **error)
 {
 	gboolean ret = FALSE;
-	struct archive *arch;
+	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 */
-	getcwd (buf, PATH_MAX);
+	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 ();
@@ -2196,7 +2202,11 @@ pk_transaction_archive_extract (const gchar *filename, const gchar *directory, G
 	}
 
 	/* switch to our destination directory */
-	chdir (directory);
+	retval = chdir (directory);
+	if (retval != 0) {
+		*error = g_error_new (1, 0, "failed chdir to %s", directory);
+		goto out;
+	}
 
 	/* decompress each file */
 	for (;;) {
@@ -2218,11 +2228,16 @@ pk_transaction_archive_extract (const gchar *filename, const gchar *directory, G
 	ret = TRUE;
 out:
 	/* close the archive */
-	archive_read_close (arch);
-	archive_read_finish (arch);
+	if (arch != NULL) {
+		archive_read_close (arch);
+		archive_read_finish (arch);
+	}
 
 	/* switch back to PWD */
-	chdir (buf);
+	retval = chdir (buf);
+	if (retval != 0)
+		pk_warning ("cannot chdir back!");
+
 	return ret;
 }
 #else /* HAVE_ARCHIVE_H */
commit 5fb72d56f21f4bab012df140ec3d35d4cf7d1c5c
Author: Shishir Goel <crazyontheedge at gmail.com>
Date:   Thu Aug 21 20:53:08 2008 +0530

    trivial: fix up an error enum in the yum backend

diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py
index 85a3af6..c025ed7 100644
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@ -412,7 +412,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
                     path = repo.getPackage(pkg_download)
                     files.append(path)
                 except IOError, e:
-                    self.error(PACKAGE_DOWNLOAD_FAILED,"Cannot write to file")
+                    self.error(ERROR_PACKAGE_DOWNLOAD_FAILED,"Cannot write to file")
                     continue
             percentage += bump
 
commit 52b3b7316970b6699358d90a7b65653c8c2f964c
Author: Shishir Goel <crazyontheedge at gmail.com>
Date:   Thu Aug 21 15:05:49 2008 +0100

    yum:fix InstallFile to make it work for multiple simultaneous packs and files installations

diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py
index a17cf31..85a3af6 100644
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@ -863,11 +863,12 @@ class PackageKitYumBackend(PackageKitBaseBackend):
                 return
 
         self._check_init()
-        self.allow_cancel(False);
+        self.allow_cancel(False)
         self.percentage(0)
         self.status(STATUS_RUNNING)
 
         # process these first
+        tempdir = tempfile.mkdtemp()
         inst_packs = []
 
         for inst_file in inst_files:
@@ -875,16 +876,15 @@ class PackageKitYumBackend(PackageKitBaseBackend):
                 continue
             elif inst_file.endswith('.pack'):
                 inst_packs.append(inst_file)
-                inst_files.remove(inst_file)
             else:
                 self.error(ERROR_INVALID_PACKAGE_FILE,'Only rpm files and packs are supported')
                 return
 
         # decompress and add the contents of any .pack files
         for inst_pack in inst_packs:
+            inst_files.remove(inst_pack)
             pack = tarfile.TarFile(name = inst_pack,mode = "r")
             members = pack.getnames()
-            tempdir = tempfile.mkdtemp()
             for mem in members:
                 pack.extract(mem,path = tempdir)
             files = os.listdir(tempdir)
commit 854acaf377312e5110c48a3c281993272ac94cd2
Author: Shishir Goel <crazyontheedge at gmail.com>
Date:   Thu Aug 21 15:04:42 2008 +0100

    trivial: fix add-error-enum.sh script

diff --git a/tools/add-error-enum.sh b/tools/add-error-enum.sh
index 6521e69..5748d5d 100755
--- a/tools/add-error-enum.sh
+++ b/tools/add-error-enum.sh
@@ -7,5 +7,5 @@
 # the Free Software Foundation; either version 2 of the License, or
 # (at your option) any later version.
 
-$EDITOR docs/spec/pk-concepts.xml libpackagekit/pk-enum.h libpackagekit/pk-enum.c ../gnome-packagekit/src/gpk-common.c
+$EDITOR docs/api/spec/pk-concepts.xml libpackagekit/pk-enum.h libpackagekit/pk-enum.c ../gnome-packagekit/src/gpk-common.c
 
commit 852cf69e2018648075485dd5198650b82f4b83e7
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu Aug 21 15:03:58 2008 +0100

    trivial: fix up an error enum in the yum backend

diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py
index 5cce784..a17cf31 100644
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@ -412,7 +412,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
                     path = repo.getPackage(pkg_download)
                     files.append(path)
                 except IOError, e:
-                    self.error(ERROR_WRITE_ERROR,"Cannot write to file")
+                    self.error(PACKAGE_DOWNLOAD_FAILED,"Cannot write to file")
                     continue
             percentage += bump
 
commit 5cdf6f88fab7a40e48cecfe3bbaa80df4f7b371c
Author: Shishir Goel <crazyontheedge at gmail.com>
Date:   Thu Aug 21 14:59:07 2008 +0100

    bugfix: pkcon:fix a memory leak in RemovePackages

diff --git a/client/pk-console.c b/client/pk-console.c
index a4fc7ac..629ecaf 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -776,6 +776,7 @@ pk_console_remove_packages (PkClient *client, gchar **packages, GError **error)
 out:
 	g_object_unref (list);
 	g_strfreev (package_ids);
+	g_ptr_array_foreach (array, (GFunc) g_free, NULL);
 	g_ptr_array_free (array, TRUE);
 	return ret;
 }
commit 9e24534b985dc3d8a7d452c0f430e266f44ed1dc
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu Aug 21 14:50:51 2008 +0100

    remove the libtar code, and instead use the libarchive library. libtar is old, clunky, and unmaintained

diff --git a/client/Makefile.am b/client/Makefile.am
index dc02e80..54bb3c0 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -71,7 +71,7 @@ pkgenpack_SOURCES =					\
 	$(NULL)
 
 pkgenpack_LDADD = 					\
-	$(TAR_LIBS)					\
+	$(ARCHIVE_LIBS)					\
 	$(GLIB_LIBS)					\
 	$(DBUS_LIBS)					\
 	$(PK_LIBS)					\
@@ -129,7 +129,7 @@ pk_self_test_LDADD =					\
 	$(GLIB_LIBS)					\
 	$(DBUS_LIBS)					\
 	$(SELFTEST_LIBS)				\
-	$(TAR_LIBS)					\
+	$(ARCHIVE_LIBS)					\
 	$(PK_LIBS)					\
 	$(NULL)
 
diff --git a/client/pk-generate-pack.c b/client/pk-generate-pack.c
index 87e797a..ccc7d08 100644
--- a/client/pk-generate-pack.c
+++ b/client/pk-generate-pack.c
@@ -37,9 +37,10 @@
 #include <pk-control.h>
 #include <pk-package-id.h>
 #include <pk-common.h>
-#ifdef HAVE_LIBTAR_H
-  #include <libtar.h>
-#endif
+#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>
@@ -265,89 +266,127 @@ out:
 	return ret;
 }
 
-#ifdef HAVE_LIBTAR_H
+#ifdef HAVE_ARCHIVE_H
 /**
- * pk_generate_pack_create:
+ * pk_generate_pack_archive_add_file:
  **/
-gboolean
-pk_generate_pack_create (const gchar *tarfilename, GPtrArray *file_array, GError **error)
+static gboolean
+pk_generate_pack_archive_add_file (struct archive *arch, const gchar *filename, GError **error)
 {
-	gboolean ret = TRUE;
-	guint retval;
-	TAR *t;
-	FILE *file;
-	guint i;
-	gchar *src;
-	gchar *dest;
-	gchar *meta_src;
-	gchar *meta_dest = NULL;
+	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];
 
-	/* create a file with metadata in it */
-	meta_src = g_build_filename (g_get_tmp_dir (), "metadata.conf", NULL);
-	ret = pk_generate_pack_set_metadata (meta_src);
-	if (!ret) {
-		*error = g_error_new (1, 0, "failed to generate metadata file %s", meta_src);
-		ret = FALSE;
+	/* stat file */
+	retval = stat (filename, &st);
+	if (retval != 0) {
+		*error = g_error_new (1, 0, "file not found %s", filename);
 		goto out;
 	}
+	pk_debug ("stat(%s), size=%lu bytes\n", filename, st.st_size);
 
-	/* create the tar file */
-	file = g_fopen (tarfilename, "a+");
-	retval = tar_open (&t, (gchar *)tarfilename, NULL, O_WRONLY, 0, TAR_GNU);
-	if (retval != 0) {
-		*error = g_error_new (1, 0, "failed to open tar file: %s", tarfilename);
-		ret = FALSE;
+	/* 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;
 	}
 
-	/* add the metadata first */
-	meta_dest = g_path_get_basename (meta_src);
-	retval = tar_append_file(t, (gchar *)meta_src, meta_dest);
-	if (retval != 0) {
-		*error = g_error_new (1, 0, "failed to copy %s into %s", meta_src, meta_dest);
-		ret = FALSE;
+	/* 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;
 	}
 
-	/* check for NULL values */
-	if (file_array == NULL) {
-		g_remove ((gchar *) tarfilename);
-		ret = FALSE;
-		goto out;
+	/* write data to archive -- how come no convenience function? */
+	len = read (fd, buff, sizeof (buff));
+	while (len > 0) {
+		wrote = archive_write_data (arch, buff, len);
+		if (wrote != len)
+			pk_warning("wrote %i instead of %i\n", wrote, len);
+		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;
+}
 
-	/* add each of the files */
-	for (i=0; i<file_array->len; i++) {
-		src = (gchar *) g_ptr_array_index (file_array, i);
-		dest =  g_path_get_basename (src);
-
-		/* add file to archive */
-		pk_debug ("adding %s", src);
-		retval = tar_append_file (t, (gchar *)src, dest);
-		if (retval != 0) {
-			*error = g_error_new (1, 0, "failed to copy %s into %s", src, dest);
-			ret = FALSE;
-		}
+/**
+ * pk_generate_pack_create:
+ **/
+gboolean
+pk_generate_pack_create (const gchar *tarfilename, GPtrArray *file_array, GError **error)
+{
+	struct archive *arch = NULL;
+	gboolean ret = FALSE;
+	const gchar *src;
+	guint i;
+	gchar *metadata_filename;
 
-		/* delete file */
-		g_remove (src);
-		g_free (src);
+	g_return_val_if_fail (tarfilename != 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);
+	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));
 
-		/* free the stripped filename */
-		g_free (dest);
+	/* 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, tarfilename);
 
-		/* abort */
+	/* 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);
 		if (!ret)
-			break;
+			goto out;
 	}
-	tar_append_eof (t);
-	tar_close (t);
-	fclose (file);
+
+	/* completed all okay */
+	ret = TRUE;
 out:
-	/* delete metadata file */
-	g_remove (meta_src);
-	g_free (meta_src);
-	g_free (meta_dest);
+	/* 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
@@ -658,70 +697,6 @@ libst_generate_pack (LibSelfTest *test)
 		libst_failed (test, NULL);
 
 	/************************************************************/
-	libst_title (test, "generate pack NULL NULL");
-	ret = pk_generate_pack_create (NULL, NULL, &error);
-	if (!ret) {
-		if (error != NULL)
-			libst_success (test, "failed to create pack %s" , error->message);
-		else
-			libst_failed (test, "could not set error");
-	} else {
-		libst_failed (test, NULL);
-	}
-
-	/************************************************************/
-	libst_title (test, "generate pack /tmp/test.pack NULL");
-	ret = pk_generate_pack_create ("/tmp/test.pack", NULL, &error);
-	if (!ret) {
-		if (error != NULL)
-			libst_success (test, "failed to create pack %s" , error->message);
-		else
-			libst_failed (test, "could not set error");
-	} else {
-		libst_failed (test, NULL);
-	}
-
-	/************************************************************/
-	libst_title (test, "generate pack /tmp/test NULL");
-	ret = pk_generate_pack_create ("/tmp/test", NULL, &error);
-	if (!ret) {
-		if (error != NULL)
-			libst_success (test, "failed to create pack %s" , error->message);
-		else
-			libst_failed (test, "could not set error");
-	} else {
-		libst_failed (test, NULL);
-	}
-
-	/************************************************************/
-	libst_title (test, "generate pack /tmp/test.tar NULL");
-	ret = pk_generate_pack_create ("test.tar", NULL, &error);
-	if (!ret) {
-		if (error != NULL)
-			libst_success (test, "failed to create pack %s" , error->message);
-		else
-			libst_failed (test, "could not set error");
-	} else {
-		libst_failed (test, NULL);
-	}
-
-	/************************************************************/
-	libst_title (test, "generate pack NULL gitk");
-	file_array = g_ptr_array_new ();
-	g_ptr_array_add (file_array, NULL);
-	ret = pk_generate_pack_create (NULL, file_array, &error);
-	if (!ret) {
-		if (error != NULL)
-			libst_success (test, "failed to create pack %s" , error->message);
-		else
-			libst_failed (test, "could not set error");
-	} else {
-		libst_failed (test, NULL);
-	}
-	if (file_array != NULL)
-		g_ptr_array_free (file_array, TRUE);
-
-	/************************************************************/
 	libst_title (test, "generate pack /tmp/gitk.pack gitk");
 	file_array = g_ptr_array_new ();
 	src = g_build_filename ("/tmp", "gitk-1.5.5.1-1.fc9.i386.rpm", NULL);
diff --git a/configure.ac b/configure.ac
index f001ac1..ef2f67e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -105,19 +105,19 @@ AC_SUBST(DBUS_LIBS)
 
 
 dnl ---------------------------------------------------------------------------
-dnl - libtar
-dnl ---------------------------------------------------------------------------
-AC_CHECK_HEADERS(libtar.h,
-		 HAVE_LIBTAR_H="yes",
-		 HAVE_LIBTAR_H="no")
-if test "x$HAVE_LIBTAR_H" = "xyes"; then
-		AC_DEFINE(HAVE_LIBTAR_H)
-		TAR_LIBS=-ltar
-		AC_SUBST(TAR_LIBS)
+dnl - libarchive
+dnl ---------------------------------------------------------------------------
+AC_CHECK_HEADERS(archive.h,
+		 HAVE_ARCHIVE_H="yes",
+		 HAVE_ARCHIVE_H="no")
+if test "x$HAVE_ARCHIVE_H" = "xyes"; then
+		AC_DEFINE(HAVE_ARCHIVE_H)
+		ARCHIVE_LIBS=-larchive
+		AC_SUBST(ARCHIVE_LIBS)
 else
-		AC_MSG_WARN([Can't find libtar.h. Service packs cannot be created or checked.])
+		AC_MSG_WARN([Cannot find archive.h. Service packs cannot be created or checked.])
 fi
-AM_CONDITIONAL(HAVE_LIBTAR_H, test x$HAVE_LIBTAR_H = xyes)
+AM_CONDITIONAL(HAVE_ARCHIVE_H, test x$HAVE_ARCHIVE_H = xyes)
 
 
 dnl ---------------------------------------------------------------------------
diff --git a/contrib/PackageKit.spec.in b/contrib/PackageKit.spec.in
index 24fb8b7..3792bec 100644
--- a/contrib/PackageKit.spec.in
+++ b/contrib/PackageKit.spec.in
@@ -22,7 +22,7 @@ Requires: dbus-glib >= %{dbus_glib_version}
 Requires: PackageKit-libs = %{epoch}:%{version}-%{release}
 Requires: yum-packagekit = %{epoch}:%{version}-%{release}
 Requires: yum >= 3.2.6
-Requires: libtar
+Requires: libarchive
 Requires: shared-mime-info
 
 BuildRequires: glib2-devel >= %{glib2_version}
@@ -43,7 +43,7 @@ BuildRequires: perl(XML::Parser)
 BuildRequires: intltool
 BuildRequires: gettext
 BuildRequires: xulrunner-devel
-BuildRequires: libtar-devel
+BuildRequires: libarchive-devel
 
 %description 
 PackageKit is a D-Bus abstraction layer that allows the session user
diff --git a/src/Makefile.am b/src/Makefile.am
index a67f4cc..d7faa83 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -127,7 +127,7 @@ packagekitd_LDADD =					\
 	$(POLKIT_LIBS)					\
 	$(SELFTEST_LIBS)				\
 	$(GIO_LIBS)					\
-	$(TAR_LIBS)					\
+	$(ARCHIVE_LIBS)					\
 	$(NULL)
 
 if BACKEND_TYPE_BOX
@@ -185,7 +185,7 @@ pk_self_test_LDADD =					\
 	$(PK_LIBS)					\
 	$(POLKIT_LIBS)					\
 	$(GIO_LIBS)					\
-	$(TAR_LIBS)					\
+	$(ARCHIVE_LIBS)					\
 	$(NULL)
 
 TESTS = pk-self-test
diff --git a/src/pk-transaction.c b/src/pk-transaction.c
index fbb6db3..63b15fc 100644
--- a/src/pk-transaction.c
+++ b/src/pk-transaction.c
@@ -36,16 +36,17 @@
 #include <fcntl.h>
 #include <sys/stat.h>
 
-#ifdef HAVE_LIBTAR_H
-#include <libtar.h>
-#endif /* HAVE_LIBTAR_H */
-
 #include <glib/gstdio.h>
 #include <glib/gi18n.h>
 #include <pk-dbus-monitor.h>
 #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>
@@ -2119,7 +2120,6 @@ pk_transaction_get_updates (PkTransaction *transaction, const gchar *filter, DBu
 	}
 }
 
-#ifdef HAVE_LIBTAR_H
 /**
  * pk_transaction_check_metadata_conf:
  **/
@@ -2163,6 +2163,78 @@ out:
 }
 
 /**
+ * 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;
+	struct archive_entry *entry;
+	int r;
+	gchar buf[PATH_MAX];
+
+	/* save the PWD as we chdir to extract */
+	getcwd (buf, PATH_MAX);
+
+	/* 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 */
+	chdir (directory);
+
+	/* 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 */
+	archive_read_close (arch);
+	archive_read_finish (arch);
+
+	/* switch back to PWD */
+	chdir (buf);
+	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
@@ -2171,31 +2243,18 @@ pk_transaction_check_pack_distro_id (const gchar *full_path, gchar **failure)
 	gboolean ret = TRUE;
 	gchar *meta_src = NULL;
 	gchar *metafile = NULL;
-	gboolean retval;
-	TAR *t;
 	GDir *dir = NULL;
 	const gchar *filename;
+	GError *error = NULL;
 
-	/* open */
-	retval = tar_open (&t, (gchar *) full_path, NULL, O_RDONLY, 0, TAR_GNU);
-	if (retval != 0) {
-		*failure = g_strdup_printf ("failed to open tar file: %s", full_path);
-		ret = FALSE;
-		goto out;
-	}
-
-	/* extract */
 	meta_src = g_build_filename (g_get_tmp_dir (), "meta", NULL);
-	retval = tar_extract_all (t, meta_src);
-	if (retval != 0) {
-		*failure = g_strdup_printf ("failed to extract from tar file: %s", full_path);
-		ret = FALSE;
+	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;
 	}
 
-	/* close */
-	tar_close (t);
-
 	/* get the files */
 	dir = g_dir_open (meta_src, 0, NULL);
 	if (dir == NULL) {
@@ -2223,18 +2282,6 @@ out:
 	g_dir_close (dir);
 	return ret;
 }
-#else /* HAVE_LIBTAR_H */
-/**
- * pk_transaction_check_pack_distro_id:
- **/
-static gboolean
-pk_transaction_check_pack_distro_id (const gchar *full_path, gchar **failure)
-{
-	*failure = g_strdup ("Cannot check PackageKit as not built with libtar support");
-	return FALSE;
-}
-#endif /* HAVE_LIBTAR_H */
-
 
 /**
  * pk_transaction_install_files:
commit fa2554203c2b49a22fd040897471c232094c4442
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu Aug 21 09:02:22 2008 +0100

    bugfix: make libtar a conditional requirement, original patch from Sebastian Heinlein

diff --git a/client/pk-generate-pack.c b/client/pk-generate-pack.c
index 60b3608..87e797a 100644
--- a/client/pk-generate-pack.c
+++ b/client/pk-generate-pack.c
@@ -37,7 +37,9 @@
 #include <pk-control.h>
 #include <pk-package-id.h>
 #include <pk-common.h>
-#include <libtar.h>
+#ifdef HAVE_LIBTAR_H
+  #include <libtar.h>
+#endif
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <dirent.h>
@@ -263,6 +265,7 @@ out:
 	return ret;
 }
 
+#ifdef HAVE_LIBTAR_H
 /**
  * pk_generate_pack_create:
  **/
@@ -347,6 +350,17 @@ out:
 	g_free (meta_dest);
 	return ret;
 }
+#else
+/**
+ * pk_generate_pack_create:
+ **/
+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");
+	return FALSE;
+}
+#endif
 
 /**
  * pk_generate_pack_scan_dir:
diff --git a/configure.ac b/configure.ac
index 6ff1fbe..f001ac1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -103,9 +103,22 @@ PKG_CHECK_MODULES(DBUS, \
 AC_SUBST(DBUS_CFLAGS)
 AC_SUBST(DBUS_LIBS)
 
-AC_CHECK_HEADERS(libtar.h, [AC_DEFINE(HAVE_LIBTAR_H)], [AC_MSG_ERROR([Can't find libtar.h. Please install libtar.])])
-TAR_LIBS=-ltar
-AC_SUBST(TAR_LIBS)
+
+dnl ---------------------------------------------------------------------------
+dnl - libtar
+dnl ---------------------------------------------------------------------------
+AC_CHECK_HEADERS(libtar.h,
+		 HAVE_LIBTAR_H="yes",
+		 HAVE_LIBTAR_H="no")
+if test "x$HAVE_LIBTAR_H" = "xyes"; then
+		AC_DEFINE(HAVE_LIBTAR_H)
+		TAR_LIBS=-ltar
+		AC_SUBST(TAR_LIBS)
+else
+		AC_MSG_WARN([Can't find libtar.h. Service packs cannot be created or checked.])
+fi
+AM_CONDITIONAL(HAVE_LIBTAR_H, test x$HAVE_LIBTAR_H = xyes)
+
 
 dnl ---------------------------------------------------------------------------
 dnl - xsltproc
@@ -251,7 +264,7 @@ PKG_CHECK_MODULES(PK_BROWSER_PLUGIN, mozilla-plugin gio-unix-2.0 cairo pango gtk
                   build_browser_plugin=yes, build_browser_plugin=no)
 
 AM_CONDITIONAL(PK_BUILD_BROWSER_PLUGIN, test $build_browser_plugin = "yes")
-		 
+
 AC_SUBST(PK_BROWSER_PLUGIN_CFLAGS)
 AC_SUBST(PK_BROWSER_PLUGIN_LIBS)
 
diff --git a/src/pk-transaction.c b/src/pk-transaction.c
index 53548d3..fbb6db3 100644
--- a/src/pk-transaction.c
+++ b/src/pk-transaction.c
@@ -34,9 +34,12 @@
 
 #include <sys/wait.h>
 #include <fcntl.h>
-#include <libtar.h>
 #include <sys/stat.h>
 
+#ifdef HAVE_LIBTAR_H
+#include <libtar.h>
+#endif /* HAVE_LIBTAR_H */
+
 #include <glib/gstdio.h>
 #include <glib/gi18n.h>
 #include <pk-dbus-monitor.h>
@@ -2116,6 +2119,7 @@ pk_transaction_get_updates (PkTransaction *transaction, const gchar *filter, DBu
 	}
 }
 
+#ifdef HAVE_LIBTAR_H
 /**
  * pk_transaction_check_metadata_conf:
  **/
@@ -2219,6 +2223,18 @@ out:
 	g_dir_close (dir);
 	return ret;
 }
+#else /* HAVE_LIBTAR_H */
+/**
+ * pk_transaction_check_pack_distro_id:
+ **/
+static gboolean
+pk_transaction_check_pack_distro_id (const gchar *full_path, gchar **failure)
+{
+	*failure = g_strdup ("Cannot check PackageKit as not built with libtar support");
+	return FALSE;
+}
+#endif /* HAVE_LIBTAR_H */
+
 
 /**
  * pk_transaction_install_files:
commit 7347229032adeb0721e417320752113abe6fc14c
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Wed Aug 20 23:46:43 2008 +0200

    APT: do not report the package itself on GetDepends

diff --git a/backends/apt/aptDBUSBackend.py b/backends/apt/aptDBUSBackend.py
index 9b3726a..bc58216 100755
--- a/backends/apt/aptDBUSBackend.py
+++ b/backends/apt/aptDBUSBackend.py
@@ -833,6 +833,7 @@ class PackageKitAptBackend(PackageKitBaseBackend):
 
         # Mark all packages for installation
         self._cache._depcache.Init()
+        pkgs = []
         for id in ids:
             if self._is_canceled(): return
             pkg = self._find_package_by_id(id)
@@ -850,9 +851,11 @@ class PackageKitAptBackend(PackageKitBaseBackend):
                                "Dependecies for %s cannot be satisfied: %s" % e)
                 self.Finished(EXIT_FAILED)
                 return
+            pkgs.append(pkg)
         # Check the status of the resulting changes
         for p in self._cache.getChanges():
             if self._is_canceled(): return
+            if p in pkgs: continue
             if p.markedDelete:
                 # Packagekit policy forbids removing packages for installation
                 self.ErrorCode(ERROR_DEP_RESOLUTION_FAILED,
commit 33f4a1a51d79fc505b2c46d6c4203f3001c23afb
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Wed Aug 20 18:45:42 2008 +0200

    Build fix for pk-import-desktop

diff --git a/client/Makefile.am b/client/Makefile.am
index 82b2330..dc02e80 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -97,6 +97,7 @@ pk_import_desktop_LDADD =				\
 	$(GLIB_LIBS)					\
 	$(SQLITE_LIBS)					\
 	$(PK_LIBS)					\
+	$(SELFTEST_LIBS)				\
 	$(NULL)
 
 pk_import_specspo_SOURCES =				\
commit 68259f272e947c4ad4d7b672e7bf8a9ac1e0ff9d
Merge: 2dfd9fe... b510f03...
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Wed Aug 20 17:30:20 2008 +0200

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

commit b510f03808d2a662e37951fd4da4313500d226e6
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Aug 20 12:11:46 2008 +0100

    add a structure type PkDistroUpgradeObj so we can use it in the DistroUpgrade callback easily

diff --git a/client/pk-console.c b/client/pk-console.c
index 1007131..a4fc7ac 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -39,6 +39,7 @@
 #include <pk-common.h>
 #include <pk-connection.h>
 #include <pk-update-detail-obj.h>
+#include <pk-distro-upgrade-obj.h>
 
 #include "pk-tools-common.h"
 
@@ -209,17 +210,14 @@ pk_console_transaction_cb (PkClient *client, const gchar *tid, const gchar *time
  * pk_console_distro_upgrade_cb:
  **/
 static void
-pk_console_distro_upgrade_cb (PkClient *client, PkUpdateStateEnum type, const gchar *name,
-			      const gchar *summary, gpointer user_data)
+pk_console_distro_upgrade_cb (PkClient *client, const PkDistroUpgradeObj *obj, gpointer user_data)
 {
-	const gchar *type_text;
-	type_text = pk_update_state_enum_to_text (type);
 	if (awaiting_space) {
 		g_print ("\n");
 	}
-	g_print ("Distro       : %s\n", name);
-	g_print (" type        : %s\n", type_text);
-	g_print (" summary     : %s\n", summary);
+	g_print ("Distro       : %s\n", obj->name);
+	g_print (" type        : %s\n", pk_update_state_enum_to_text (obj->state));
+	g_print (" summary     : %s\n", obj->summary);
 }
 
 /**
diff --git a/libpackagekit/Makefile.am b/libpackagekit/Makefile.am
index 27b4c9d..cf6b9b7 100644
--- a/libpackagekit/Makefile.am
+++ b/libpackagekit/Makefile.am
@@ -33,6 +33,7 @@ libpackagekit_include_HEADERS =					\
 	pk-package-list.h					\
 	pk-update-detail-obj.h					\
 	pk-update-detail-list.h					\
+	pk-distro-upgrade-obj.h					\
 	pk-details-obj.h					\
 	pk-enum.h						\
 	pk-bitfield.h						\
@@ -67,6 +68,8 @@ libpackagekit_la_SOURCES =					\
 	pk-update-detail-obj.h					\
 	pk-update-detail-list.c					\
 	pk-update-detail-list.h					\
+	pk-distro-upgrade-obj.c					\
+	pk-distro-upgrade-obj.h					\
 	pk-details-obj.c					\
 	pk-details-obj.h					\
 	pk-enum.c						\
diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 8d8ce85..3742447 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -59,6 +59,7 @@
 #include "pk-control.h"
 #include "pk-update-detail-obj.h"
 #include "pk-details-obj.h"
+#include "pk-distro-upgrade-obj.h"
 
 static void     pk_client_class_init	(PkClientClass *klass);
 static void     pk_client_init		(PkClient      *client);
@@ -605,11 +606,14 @@ pk_client_distro_upgrade_cb (DBusGProxy *proxy, const gchar *type_text, const gc
 			     const gchar *summary, PkClient *client)
 {
 	PkUpdateStateEnum type;
+	PkDistroUpgradeObj *obj;
 	g_return_if_fail (PK_IS_CLIENT (client));
 
 	type = pk_update_state_enum_from_text (type_text);
+	obj = pk_distro_upgrade_obj_new_from_data  (type, name, summary);
 	pk_debug ("emitting distro_upgrade %s, %s, %s", type_text, name, summary);
-	g_signal_emit (client, signals [PK_CLIENT_DISTRO_UPGRADE], 0, type, name, summary);
+	g_signal_emit (client, signals [PK_CLIENT_DISTRO_UPGRADE], 0, obj);
+	pk_distro_upgrade_obj_free (obj);
 }
 
 /**
@@ -3520,8 +3524,8 @@ pk_client_class_init (PkClientClass *klass)
 		g_signal_new ("distro-upgrade",
 			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
 			      G_STRUCT_OFFSET (PkClientClass, distro_upgrade),
-			      NULL, NULL, pk_marshal_VOID__UINT_STRING_STRING,
-			      G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING);
+			      NULL, NULL, g_cclosure_marshal_VOID__POINTER,
+			      G_TYPE_NONE, 1, G_TYPE_POINTER);
 	/**
 	 * PkClient::update-detail:
 	 * @client: the #PkClient instance that emitted the signal
diff --git a/libpackagekit/pk-distro-upgrade-obj.c b/libpackagekit/pk-distro-upgrade-obj.c
new file mode 100644
index 0000000..55aef54
--- /dev/null
+++ b/libpackagekit/pk-distro-upgrade-obj.c
@@ -0,0 +1,149 @@
+/* -*- 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.
+ */
+
+/**
+ * SECTION:pk-update-detail-obj
+ * @short_description: Functionality to create an update detail struct
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <glib/gi18n.h>
+
+#include <pk-enum.h>
+#include "pk-debug.h"
+#include "pk-common.h"
+#include "pk-distro-upgrade-obj.h"
+
+/**
+ * pk_distro_upgrade_obj_new:
+ *
+ * Creates a new #PkDistroUpgradeObj object with default values
+ *
+ * Return value: a new #PkDistroUpgradeObj object
+ **/
+PkDistroUpgradeObj *
+pk_distro_upgrade_obj_new (void)
+{
+	PkDistroUpgradeObj *obj;
+	obj = g_new0 (PkDistroUpgradeObj, 1);
+	obj->name = NULL;
+	obj->summary = NULL;
+	obj->state = PK_DISTRO_UPGRADE_ENUM_UNKNOWN;
+	return obj;
+}
+
+/**
+ * pk_distro_upgrade_obj_new_from_data:
+ *
+ * Creates a new #PkDistroUpgradeObj object with values.
+ *
+ * Return value: a new #PkDistroUpgradeObj object
+ **/
+PkDistroUpgradeObj *
+pk_distro_upgrade_obj_new_from_data (PkUpdateStateEnum state, const gchar *name, const gchar *summary)
+{
+	PkDistroUpgradeObj *obj = NULL;
+
+	/* create new object */
+	obj = pk_distro_upgrade_obj_new ();
+	obj->state = state;
+	obj->name = g_strdup (name);
+	obj->summary = g_strdup (summary);
+	return obj;
+}
+
+/**
+ * pk_distro_upgrade_obj_copy:
+ *
+ * Return value: a new #PkDistroUpgradeObj object
+ **/
+PkDistroUpgradeObj *
+pk_distro_upgrade_obj_copy (const PkDistroUpgradeObj *obj)
+{
+	g_return_val_if_fail (obj != NULL, NULL);
+	return pk_distro_upgrade_obj_new_from_data (obj->state, obj->name, obj->summary);
+}
+
+/**
+ * pk_distro_upgrade_obj_free:
+ * @obj: the #PkDistroUpgradeObj object
+ *
+ * Return value: %TRUE if the #PkDistroUpgradeObj object was freed.
+ **/
+gboolean
+pk_distro_upgrade_obj_free (PkDistroUpgradeObj *obj)
+{
+	if (obj == NULL) {
+		return FALSE;
+	}
+	g_free (obj->name);
+	g_free (obj->summary);
+	g_free (obj);
+	return TRUE;
+}
+
+/***************************************************************************
+ ***                          MAKE CHECK TESTS                           ***
+ ***************************************************************************/
+#ifdef PK_BUILD_TESTS
+#include <libselftest.h>
+
+void
+libst_distro_upgrade (LibSelfTest *test)
+{
+	gboolean ret;
+	PkDistroUpgradeObj *obj;
+
+	if (libst_start (test, "PkDistroUpgradeObj", CLASS_AUTO) == FALSE) {
+		return;
+	}
+
+	/************************************************************
+	 ****************          IDENT           ******************
+	 ************************************************************/
+
+	/************************************************************/
+	libst_title (test, "get an upgrade object");
+	obj = pk_distro_upgrade_obj_new ();
+	if (obj != NULL) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, NULL);
+	}
+
+	/************************************************************/
+	libst_title (test, "test upgrade");
+	ret = pk_distro_upgrade_obj_free (obj);
+	if (ret) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, NULL);
+	}
+
+	libst_end (test);
+}
+#endif
+
diff --git a/libpackagekit/pk-distro-upgrade-obj.h b/libpackagekit/pk-distro-upgrade-obj.h
new file mode 100644
index 0000000..590816b
--- /dev/null
+++ b/libpackagekit/pk-distro-upgrade-obj.h
@@ -0,0 +1,51 @@
+/* -*- 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_DISTRO_UPGRADE_H
+#define __PK_DISTRO_UPGRADE_H
+
+#include <glib-object.h>
+#include <pk-enum.h>
+
+G_BEGIN_DECLS
+
+/**
+ * PkDistroUpgradeObj:
+ *
+ * Cached object to represent details about the update.
+ **/
+typedef struct
+{
+	PkUpdateStateEnum		 state;
+	gchar				*name;
+	gchar				*summary;
+} PkDistroUpgradeObj;
+
+PkDistroUpgradeObj	*pk_distro_upgrade_obj_new		(void);
+PkDistroUpgradeObj	*pk_distro_upgrade_obj_copy		(const PkDistroUpgradeObj *obj);
+PkDistroUpgradeObj	*pk_distro_upgrade_obj_new_from_data	(PkUpdateStateEnum	 state,
+								 const gchar		*name,
+								 const gchar		*summary);
+gboolean		 pk_distro_upgrade_obj_free		(PkDistroUpgradeObj	*obj);
+
+G_END_DECLS
+
+#endif /* __PK_DISTRO_UPGRADE_H */
commit 9f86b3754947d4e3677f3ec3d124d3c69939c856
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Aug 20 11:08:48 2008 +0100

    trivial: now we can use GetDistroUpgrades, advertise it

diff --git a/src/pk-backend.c b/src/pk-backend.c
index 462ac81..f52c32b 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -257,6 +257,9 @@ pk_backend_get_actions (PkBackend *backend)
 	if (desc->repo_set_data != NULL) {
 		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);
+	}
 	return roles;
 }
 
commit b881f686b4abb7de5f63d112f26b096f764fa24e
Merge: 4656e50... 8e7be89...
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Aug 20 11:06:22 2008 +0100

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

commit 4656e50d3615885fe0dba7bdbd871b6125911fdd
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Aug 20 10:52:12 2008 +0100

    trivial: add the distro-upgrade hooks into PkClient a pkcon

diff --git a/client/pk-console.c b/client/pk-console.c
index 0825513..1007131 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -206,6 +206,23 @@ pk_console_transaction_cb (PkClient *client, const gchar *tid, const gchar *time
 }
 
 /**
+ * pk_console_distro_upgrade_cb:
+ **/
+static void
+pk_console_distro_upgrade_cb (PkClient *client, PkUpdateStateEnum type, const gchar *name,
+			      const gchar *summary, gpointer user_data)
+{
+	const gchar *type_text;
+	type_text = pk_update_state_enum_to_text (type);
+	if (awaiting_space) {
+		g_print ("\n");
+	}
+	g_print ("Distro       : %s\n", name);
+	g_print (" type        : %s\n", type_text);
+	g_print (" summary     : %s\n", summary);
+}
+
+/**
  * pk_console_update_detail_cb:
  **/
 static void
@@ -1249,6 +1266,9 @@ pk_console_get_summary (PkBitfield roles)
 	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_GET_DETAILS)) {
 		g_string_append_printf (string, "  %s\n", "get-details [package]");
 	}
+	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_GET_DISTRO_UPGRADES)) {
+		g_string_append_printf (string, "  %s\n", "get-distro-upgrades");
+	}
 	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_GET_FILES)) {
 		g_string_append_printf (string, "  %s\n", "get-files [package]");
 	}
@@ -1374,6 +1394,8 @@ main (int argc, char *argv[])
 			  G_CALLBACK (pk_console_package_cb), NULL);
 	g_signal_connect (client, "transaction",
 			  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, "details",
 			  G_CALLBACK (pk_console_details_cb), NULL);
 	g_signal_connect (client, "files",
@@ -1570,6 +1592,9 @@ main (int argc, char *argv[])
 		}
 		ret = pk_console_get_depends (client, filters, value, &error);
 
+	} else if (strcmp (mode, "get-distro-upgrades") == 0) {
+		ret = pk_client_get_distro_upgrades (client, &error);
+
 	} else if (strcmp (mode, "get-update-detail") == 0) {
 		if (value == NULL) {
 			error = g_error_new (1, 0, "%s", _("You need to specify a search term"));
diff --git a/contrib/pk-completion.bash b/contrib/pk-completion.bash
index ec61a6d..784a882 100755
--- a/contrib/pk-completion.bash
+++ b/contrib/pk-completion.bash
@@ -21,6 +21,7 @@ __pkcon_commandlist="
     get-actions
     get-depends
     get-details
+    get-distro-upgrades
     get-files
     get-filters
     get-groups
diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index ff7b536..8d8ce85 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -112,6 +112,7 @@ typedef enum {
 	PK_CLIENT_REQUIRE_RESTART,
 	PK_CLIENT_MESSAGE,
 	PK_CLIENT_TRANSACTION,
+	PK_CLIENT_DISTRO_UPGRADE,
 	PK_CLIENT_STATUS_CHANGED,
 	PK_CLIENT_UPDATE_DETAIL,
 	PK_CLIENT_REPO_SIGNATURE_REQUIRED,
@@ -597,6 +598,21 @@ pk_client_transaction_cb (DBusGProxy *proxy, const gchar *old_tid, const gchar *
 }
 
 /**
+ * pk_client_distro_upgrade_cb:
+ */
+static void
+pk_client_distro_upgrade_cb (DBusGProxy *proxy, const gchar *type_text, const gchar *name,
+			     const gchar *summary, PkClient *client)
+{
+	PkUpdateStateEnum type;
+	g_return_if_fail (PK_IS_CLIENT (client));
+
+	type = pk_update_state_enum_from_text (type_text);
+	pk_debug ("emitting distro_upgrade %s, %s, %s", type_text, name, summary);
+	g_signal_emit (client, signals [PK_CLIENT_DISTRO_UPGRADE], 0, type, name, summary);
+}
+
+/**
  * pk_client_update_detail_cb:
  */
 static void
@@ -2083,6 +2099,53 @@ pk_client_get_details (PkClient *client, gchar **package_ids, GError **error)
 }
 
 /**
+ * pk_client_get_distro_upgrades:
+ * @client: a valid #PkClient instance
+ * @error: a %GError to put the error code and message in, or %NULL
+ *
+ * This method should return a list of distribution upgrades that are available.
+ * It should not return updates, only major upgrades.
+ *
+ * Return value: %TRUE if the daemon queued the transaction
+ **/
+gboolean
+pk_client_get_distro_upgrades (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_DISTRO_UPGRADES;
+
+	/* 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, "GetDistroUpgrades", 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_get_files:
  * @client: a valid #PkClient instance
  * @package_ids: an array of package_id structures such as "gnome-power-manager;0.0.1;i386;fedora"
@@ -3306,6 +3369,8 @@ pk_client_set_tid (PkClient *client, const gchar *tid, GError **error)
 				 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
 				 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
 				 G_TYPE_STRING, G_TYPE_INVALID);
+	dbus_g_proxy_add_signal (proxy, "DistroUpgrade",
+				 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
 	dbus_g_proxy_add_signal (proxy, "Details",
 				 G_TYPE_STRING, G_TYPE_STRING,
 				 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT64,
@@ -3336,6 +3401,8 @@ pk_client_set_tid (PkClient *client, const gchar *tid, GError **error)
 				     G_CALLBACK (pk_client_transaction_cb), client, NULL);
 	dbus_g_proxy_connect_signal (proxy, "UpdateDetail",
 				     G_CALLBACK (pk_client_update_detail_cb), client, NULL);
+	dbus_g_proxy_connect_signal (proxy, "DistroUpgrade",
+				     G_CALLBACK (pk_client_distro_upgrade_cb), client, NULL);
 	dbus_g_proxy_connect_signal (proxy, "Details",
 				     G_CALLBACK (pk_client_details_cb), client, NULL);
 	dbus_g_proxy_connect_signal (proxy, "Files",
@@ -3440,6 +3507,22 @@ pk_client_class_init (PkClientClass *klass)
 			      G_TYPE_NONE, 6, G_TYPE_STRING, G_TYPE_STRING,
 			      G_TYPE_BOOLEAN, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_STRING);
 	/**
+	 * PkClient::distro_upgrade:
+	 * @client: the #PkClient instance that emitted the signal
+	 * @type: A valid upgrade %PkUpdateStateEnum type
+	 * @name: The short name of the distribution, e.g. <literal>Fedora Core 10 RC1</literal>
+	 * @summary: The multi-line description of the release.
+	 *
+	 * The ::distro_upgrade signal is emitted when the method GetDistroUpgrades() is
+	 * called, and the upgrade options are being sent.
+	 **/
+	signals [PK_CLIENT_DISTRO_UPGRADE] =
+		g_signal_new ("distro-upgrade",
+			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (PkClientClass, distro_upgrade),
+			      NULL, NULL, pk_marshal_VOID__UINT_STRING_STRING,
+			      G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING);
+	/**
 	 * PkClient::update-detail:
 	 * @client: the #PkClient instance that emitted the signal
 	 * @details: a pointer to a PkUpdateDetailsObj strusture descibing the update
@@ -3670,6 +3753,8 @@ pk_client_disconnect_proxy (PkClient *client)
 				        G_CALLBACK (pk_client_package_cb), client);
 	dbus_g_proxy_disconnect_signal (client->priv->proxy, "Transaction",
 				        G_CALLBACK (pk_client_transaction_cb), client);
+	dbus_g_proxy_disconnect_signal (client->priv->proxy, "DistroUpgrade",
+				        G_CALLBACK (pk_client_distro_upgrade_cb), client);
 	dbus_g_proxy_disconnect_signal (client->priv->proxy, "Details",
 				        G_CALLBACK (pk_client_details_cb), client);
 	dbus_g_proxy_disconnect_signal (client->priv->proxy, "Files",
@@ -3804,6 +3889,10 @@ pk_client_init (PkClient *client)
 	/* Use a main control object */
 	client->priv->control = pk_control_new ();
 
+	/* DistroUpgrade */
+	dbus_g_object_register_marshaller (pk_marshal_VOID__STRING_STRING_STRING,
+					   G_TYPE_NONE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
+
 	/* ProgressChanged */
 	dbus_g_object_register_marshaller (pk_marshal_VOID__UINT_UINT_UINT_UINT,
 					   G_TYPE_NONE, G_TYPE_UINT,
diff --git a/libpackagekit/pk-client.h b/libpackagekit/pk-client.h
index 5ad87ba..86ede10 100644
--- a/libpackagekit/pk-client.h
+++ b/libpackagekit/pk-client.h
@@ -97,6 +97,10 @@ struct _PkClientClass
 							 PkRoleEnum	 role,
 							 guint		 duration,
 							 const gchar	*data);
+	void		(* distro_upgrade)		(PkClient	*client,
+							 PkUpdateStateEnum type,
+							 const gchar	*name,
+							 const gchar	*summary);
 	void		(* update_detail)		(PkClient	*client,
 							 PkUpdateDetailObj	*update_detail);
 	void		(* details)			(PkClient	*client,
@@ -253,6 +257,8 @@ gboolean	 pk_client_what_provides		(PkClient	*client,
 gboolean	 pk_client_get_details			(PkClient	*client,
 							 gchar		**package_ids,
 							 GError		**error);
+gboolean	 pk_client_get_distro_upgrades		(PkClient	*client,
+							 GError		**error);
 gboolean	 pk_client_get_files			(PkClient	*client,
 							 gchar		**package_ids,
 							 GError		**error)
commit 00a745d304b70dda4b3da085280d111d53abc95c
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Aug 20 10:50:11 2008 +0100

    add a check to make sure the backends ar respecting the installed filter

diff --git a/src/pk-transaction.c b/src/pk-transaction.c
index 600bab1..53548d3 100644
--- a/src/pk-transaction.c
+++ b/src/pk-transaction.c
@@ -109,7 +109,7 @@ struct PkTransactionPrivate
 	gchar			*cached_transaction_id;
 	gchar			*cached_full_path;
 	gchar			**cached_full_paths;
-	PkBitfield	 cached_filters;
+	PkBitfield		 cached_filters;
 	gchar			*cached_search;
 	gchar			*cached_repo_id;
 	gchar			*cached_key_id;
@@ -611,6 +611,24 @@ pk_transaction_package_cb (PkBackend *backend, const PkPackageObj *obj, PkTransa
 		}
 	}
 
+	/* check we are respecting the filters */
+	if (pk_bitfield_contain (transaction->priv->cached_filters, PK_FILTER_ENUM_NOT_INSTALLED)) {
+		if (obj->info == PK_INFO_ENUM_INSTALLED) {
+			pk_backend_message (transaction->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
+					    "backend emitted package that was installed when "
+					    "the ~installed filter is in place");
+			return;
+		}
+	}
+	if (pk_bitfield_contain (transaction->priv->cached_filters, PK_FILTER_ENUM_INSTALLED)) {
+		if (obj->info == PK_INFO_ENUM_AVAILABLE) {
+			pk_backend_message (transaction->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
+					    "backend emitted package that was ~installed when "
+					    "the installed filter is in place");
+			return;
+		}
+	}
+
 	/* add to package cache even if we already got a result */
 	info_text = pk_info_enum_to_text (obj->info);
 	pk_package_list_add_obj (transaction->priv->package_list, obj);
commit 2dfd9fe6cb52fd8f003d0920a3a65c51d5d757db
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Wed Aug 20 11:24:30 2008 +0200

    Add GetDistroUpgrades to the feature matrix

diff --git a/docs/html/pk-matrix.html b/docs/html/pk-matrix.html
index 807503b..b91c783 100644
--- a/docs/html/pk-matrix.html
+++ b/docs/html/pk-matrix.html
@@ -95,6 +95,21 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
 </tr>
 <tr>
+<td><b>GetDistroUpgrades</b></td>
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- box -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- opkg -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- pisi -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- poldek -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum2 -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- zypp -->
+</tr>
+<tr>
 <td><b>SearchName</b></td>
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm -->
commit 8e7be89f3c6d968fa3bd9b47622b75596c05cd89
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Wed Aug 20 11:20:57 2008 +0200

    Update feature matrix for apt. trivial

diff --git a/docs/html/pk-matrix.html b/docs/html/pk-matrix.html
index d70764d..807503b 100644
--- a/docs/html/pk-matrix.html
+++ b/docs/html/pk-matrix.html
@@ -261,7 +261,7 @@
 </tr>
 <tr>
 <td><b>GetFiles</b></td>
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary -->
commit 24fe6360971a158b5687c8270701e9187cec7dc6
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Aug 20 09:48:23 2008 +0100

    trivial fix to stop an error when we are testing the yum backend on the command line

diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py
index 9905761..5cce784 100644
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@ -448,7 +448,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
             e,v,r = self._getEVR(idver)
         else:
             n = id
-            e = v = r = a = None
+            e = v = r = a = d = None
         # search the rpmdb for the nevra
         pkgs = self.yumbase.rpmdb.searchNevra(name=n,epoch=e,ver=v,rel=r,arch=a)
         # if the package is found, then return it (do not have to match the repo_id)
commit c400e9a12555d40f4f1eaf32742f957583f072df
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Wed Aug 20 10:47:00 2008 +0200

    APT: report that we support the new groups science, doc and electronics

diff --git a/backends/apt/pk-backend-apt.c b/backends/apt/pk-backend-apt.c
index 16ff248..1ba2c7c 100644
--- a/backends/apt/pk-backend-apt.c
+++ b/backends/apt/pk-backend-apt.c
@@ -61,9 +61,11 @@ backend_get_groups (PkBackend *backend)
 		PK_GROUP_ENUM_ACCESSORIES,
 		PK_GROUP_ENUM_ADMIN_TOOLS,
 		PK_GROUP_ENUM_COMMUNICATION,
+		PK_GROUP_ENUM_DOCUMENTATION,
 		PK_GROUP_ENUM_DESKTOP_GNOME,
 		PK_GROUP_ENUM_DESKTOP_KDE,
 		PK_GROUP_ENUM_DESKTOP_OTHER,
+		PK_GROUP_ENUM_ELECTRONICS,
 		PK_GROUP_ENUM_GAMES,
 		PK_GROUP_ENUM_GRAPHICS,
 		PK_GROUP_ENUM_INTERNET,
@@ -74,6 +76,7 @@ backend_get_groups (PkBackend *backend)
 		PK_GROUP_ENUM_OTHER,
 		PK_GROUP_ENUM_PROGRAMMING,
 		PK_GROUP_ENUM_PUBLISHING,
+		PK_GROUP_ENUM_SCIENCE,
 		PK_GROUP_ENUM_SYSTEM,
 		PK_GROUP_ENUM_UNKNOWN,
 		-1);
commit 9b1becd5bbe103634659d641a5174f205f9073a3
Merge: 3971a05... 6bd80fd...
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Wed Aug 20 10:44:06 2008 +0200

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

commit 3971a05c3df9eb46cf1c3ddb38e2fc44a7731644
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Wed Aug 20 10:42:45 2008 +0200

    APT: Instead of sending an empty file list for a package send none

diff --git a/backends/apt/aptDBUSBackend.py b/backends/apt/aptDBUSBackend.py
index 8403765..9b3726a 100755
--- a/backends/apt/aptDBUSBackend.py
+++ b/backends/apt/aptDBUSBackend.py
@@ -1032,7 +1032,7 @@ class PackageKitAptBackend(PackageKitBaseBackend):
                 self.Finished(EXIT_FAILED)
                 return
             if not pkg.isInstalled:
-                self.Files(id, "")
+                continue
             path = "/var/lib/dpkg/info/%s.list" % pkg.name
             list = open(path)
             files = re.sub("\n", ";", list.read(), 0)
commit 800f73a3553f2c969a044e7e4d234cb3582a168f
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Wed Aug 20 10:42:02 2008 +0200

    APT: implement GetFiles

diff --git a/backends/apt/aptDBUSBackend.py b/backends/apt/aptDBUSBackend.py
index 81171fd..8403765 100755
--- a/backends/apt/aptDBUSBackend.py
+++ b/backends/apt/aptDBUSBackend.py
@@ -1019,6 +1019,26 @@ class PackageKitAptBackend(PackageKitBaseBackend):
             return
         self.Finished(EXIT_SUCCESS)
 
+    def doGetFiles(self, package_ids):
+        """
+        Emit the Files signal which includes the files included in a package
+        Apt only supports this for installed packages
+        """
+        for id in package_ids:
+            pkg = self._find_package_by_id(id)
+            if pkg == None:
+                self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
+                               "Package %s doesn't exist" % pkg.name)
+                self.Finished(EXIT_FAILED)
+                return
+            if not pkg.isInstalled:
+                self.Files(id, "")
+            path = "/var/lib/dpkg/info/%s.list" % pkg.name
+            list = open(path)
+            files = re.sub("\n", ";", list.read(), 0)
+            self.Files(id, files)
+        self.Finished(EXIT_SUCCESS)
+
     def doSetProxy(self, http_proxy, ftp_proxy):
         '''
         Set a proxy server for http and ftp transfer
diff --git a/backends/apt/pk-backend-apt.c b/backends/apt/pk-backend-apt.c
index 3a0e02e..16ff248 100644
--- a/backends/apt/pk-backend-apt.c
+++ b/backends/apt/pk-backend-apt.c
@@ -155,6 +155,16 @@ backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow
 }
 
 /**
+ * backend_get_files:
+ *  */
+static void
+backend_get_files (PkBackend *backend, gchar **package_ids)
+{
+	pk_backend_dbus_get_files (dbus, package_ids);
+}
+
+
+/**
  * backend_get_details:
  *  */
 static void
@@ -276,7 +286,7 @@ PK_BACKEND_OPTIONS (
 	backend_get_depends,			/* get_depends */
 	backend_get_details,			/* get_details */
 	NULL,					/* get_distro_upgrades */
-	NULL,					/* get_files */
+	backend_get_files,			/* get_files */
 	backend_get_packages,			/* get_packages */
 	NULL,					/* get_repo_list */
 	backend_get_requires,			/* get_requires */
commit 6bd80fd12ce1fe2ebf4c029f7d474bea40dfa1ba
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Aug 20 09:23:38 2008 +0100

    bugfix: make sure we create the /var/cache/PackageKit/downloads directory at install time

diff --git a/contrib/PackageKit.spec.in b/contrib/PackageKit.spec.in
index 7100756..24fb8b7 100644
--- a/contrib/PackageKit.spec.in
+++ b/contrib/PackageKit.spec.in
@@ -158,6 +158,8 @@ update-mime-database %{_datadir}/mime &> /dev/null || :
 %dir %{_localstatedir}/lib/PackageKit
 %dir %{python_sitelib}/packagekit
 %dir %{_localstatedir}/run/PackageKit
+%dir %{_localstatedir}/cache/PackageKit
+%dir %{_localstatedir}/cache/PackageKit/downloads
 %{python_sitelib}/packagekit/*py*
 %dir %{_sysconfdir}/bash_completion.d
 %config %{_sysconfdir}/bash_completion.d/pk-completion.bash
diff --git a/src/Makefile.am b/src/Makefile.am
index 6d5d757..a67f4cc 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -206,8 +206,8 @@ gprof: clean-gprof all check
 endif
 
 install-data-hook:
-	if test -w $(localstatedir); then \
-		mkdir -p $(localstatedir)/cache/PackageKit/downloads; \
+	if test -w $(DESTDIR)$(prefix)/; then \
+		mkdir -p $(DESTDIR)$(localstatedir)/cache/PackageKit/downloads; \
 	fi
 
 EXTRA_DIST =						\
commit 796aec47e7223225f7bdb6a12a3a7148aa207ae8
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Aug 20 09:01:36 2008 +0100

    trivial: fix a GError initialisation error -- reapply patch

diff --git a/src/pk-engine.c b/src/pk-engine.c
index 96618a4..75dcd07 100644
--- a/src/pk-engine.c
+++ b/src/pk-engine.c
@@ -628,7 +628,7 @@ pk_engine_remove_contents (const gchar *directory)
 {
 	gboolean ret = FALSE;
 	GDir *dir;
-	GError *error;
+	GError *error = NULL;
 	const gchar *filename;
 	gchar *src;
 	gint retval;
commit f82c53b2bdf72b502f36352b2b45fafaf179c76e
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Wed Aug 20 09:32:51 2008 +0200

    APT: Make use of the new groups documentation, electronics and science

diff --git a/backends/apt/aptDBUSBackend.py b/backends/apt/aptDBUSBackend.py
index f7f643a..81171fd 100755
--- a/backends/apt/aptDBUSBackend.py
+++ b/backends/apt/aptDBUSBackend.py
@@ -1359,13 +1359,11 @@ class PackageKitAptBackend(PackageKitBaseBackend):
         elif section == "devel":
             return GROUP_PROGRAMMING
         elif section == "doc":
-            #FIXME: introduce a new group
-            return GROUP_OTHER
+            return GROUP_DOCUMENTATION
         elif section == "editors":
             return GROUP_PUBLISHING
         elif section == "electronics":
-            #FIXME: do we need a special group?
-            return GROUP_OTHER
+            return GROUP_ELECTRONICS
         elif section == "embedded":
             return GROUP_SYSTEM
         elif section == "games":
@@ -1387,8 +1385,7 @@ class PackageKitAptBackend(PackageKitBaseBackend):
         elif section == "mail":
             return GROUP_INTERNET
         elif section == "math":
-            #FIXME: Need a group science
-            return GROUP_OTHER
+            return GROUP_SCIENCE
         elif section == "misc":
             return GROUP_OTHER
         elif section == "net":
@@ -1404,8 +1401,7 @@ class PackageKitAptBackend(PackageKitBaseBackend):
         elif section == "python":
             return GROUP_PROGRAMMING
         elif section == "science":
-            #FIXME Need a new group
-            return GROUP_OTHER
+            return GROUP_SCIENCE
         elif section == "shells":
             return GROUP_SYSTEM
         elif section == "sound":
commit c2edda89ea1a4f8c147447b434b6bd18ea077129
Merge: 31954bf... 79fd0ed...
Author: Ken VanDine <ken at vandine.org>
Date:   Tue Aug 19 21:46:33 2008 -0400

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

commit 31954bfdb72b5a76384f355bc314af2fec887560
Author: Ken VanDine <ken at vandine.org>
Date:   Tue Aug 19 21:46:05 2008 -0400

    more updates to work with 0.3.x series

diff --git a/backends/conary/helpers/conaryBackend.py b/backends/conary/helpers/conaryBackend.py
index 4d89cec..91c0ed2 100644
--- a/backends/conary/helpers/conaryBackend.py
+++ b/backends/conary/helpers/conaryBackend.py
@@ -115,6 +115,9 @@ def ExceptionHandler(func):
     return wrapper
 
 class PackageKitConaryBackend(PackageKitBaseBackend):
+    # Packages there require a reboot
+    rebootpkgs = ("kernel", "glibc", "hal", "dbus")
+
     def __init__(self, args):
         PackageKitBaseBackend.__init__(self, args)
 
@@ -313,8 +316,7 @@ class PackageKitConaryBackend(PackageKitBaseBackend):
 
         if name:
             if installed == INFO_INSTALLED:
-                self.error(ERROR_PACKAGE_ALREADY_INSTALLED,
-                    'Package already installed')
+                self.error(ERROR_PACKAGE_ALREADY_INSTALLED, 'Package already installed')
 
             else:
                 updJob, suggMap = self._get_package_update(name, version,
@@ -327,8 +329,7 @@ class PackageKitConaryBackend(PackageKitBaseBackend):
                     else:
                         self.package(id, INFO_AVAILABLE, '')
         else:
-            self.error(ERROR_PACKAGE_ALREADY_INSTALLED,
-                'Package was not found')
+            self.error(ERROR_PACKAGE_ALREADY_INSTALLED, 'Package was not found')
 
     @ExceptionHandler
     def get_files(self, package_id):
@@ -365,22 +366,6 @@ class PackageKitConaryBackend(PackageKitBaseBackend):
         updJob, suggMap = self._do_update(applyList)
 
     @ExceptionHandler
-    def update_packages(self, packages):
-        '''
-        Implement the {backend}-update functionality
-        '''
-        self.allow_cancel(True);
-        self.percentage(0)
-        self.status(STATUS_RUNNING)
-
-        for package in packages.split("|"):
-            name, version, flavor, installed = self._findPackage(package)
-            if name:
-                self._do_package_update(name, version, flavor)
-            else:
-                self.error(ERROR_PACKAGE_ALREADY_INSTALLED, 'No available updates')
-
-    @ExceptionHandler
     def refresh_cache(self):
         self.percentage()
         self.status(STATUS_REFRESH_CACHE)
@@ -404,11 +389,11 @@ class PackageKitConaryBackend(PackageKitBaseBackend):
                 self.error(ERROR_PACKAGE_ALREADY_INSTALLED, 'No available updates')
 
     @ExceptionHandler
-    def install_packages(self, package_ids):
+    def update_packages(self, package_ids):
         '''
-        Implement the {backend}-install-packages functionality
+        Implement the {backend}-{install,update}-packages functionality
         '''
-        for package_id in package_ids.split():
+        for package_id in package_ids.split('%'):
             name, version, flavor, installed = self._findPackage(package_id)
 
             self.allow_cancel(True)
@@ -435,7 +420,7 @@ class PackageKitConaryBackend(PackageKitBaseBackend):
         self.percentage(0)
         self.status(STATUS_RUNNING)
 
-        for package_id in package_ids:
+        for package_id in package_ids.split('%'):
             name, version, flavor, installed = self._findPackage(package_id)
 
             if name:
@@ -517,6 +502,9 @@ class PackageKitConaryBackend(PackageKitBaseBackend):
         else:
             return "",urls,"none"
 
+    def _check_for_reboot(self, name):
+        if name in self.rebootpkgs:
+            self.require_restart(RESTART_SYSTEM,"")
 
     @ExceptionHandler
     def get_update_detail(self,id):
diff --git a/backends/conary/helpers/install-packages.py b/backends/conary/helpers/install-packages.py
index c6147dc..125ffcf 100755
--- a/backends/conary/helpers/install-packages.py
+++ b/backends/conary/helpers/install-packages.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python2.4
 #
 # Copyright (C) 2007 Ken VanDine <ken at vandine.org>
 #
@@ -14,5 +14,5 @@ from conaryBackend import PackageKitConaryBackend
 
 package_ids = sys.argv[1]
 backend = PackageKitConaryBackend(sys.argv[1:])
-backend.install_packages(package_ids)
+backend.update_packages(package_ids)
 sys.exit(0)
diff --git a/backends/conary/helpers/remove-packages.py b/backends/conary/helpers/remove-packages.py
index fce9c68..260fe98 100755
--- a/backends/conary/helpers/remove-packages.py
+++ b/backends/conary/helpers/remove-packages.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python2.4
 #
 # Copyright (C) 2007 Ken VanDine <ken at vandine.org>
 #
@@ -13,7 +13,7 @@ import sys
 from conaryBackend import PackageKitConaryBackend
 
 allowDeps = sys.argv[1]
-package_ids = sys.argv[2:]
+package_ids = sys.argv[2]
 backend = PackageKitConaryBackend(sys.argv[1:])
 backend.remove_packages(allowDeps, package_ids)
 sys.exit(0)
diff --git a/backends/conary/pk-backend-conary.c b/backends/conary/pk-backend-conary.c
index 223e12c..3bd984c 100644
--- a/backends/conary/pk-backend-conary.c
+++ b/backends/conary/pk-backend-conary.c
@@ -109,7 +109,7 @@ static void
 backend_get_details (PkBackend *backend, gchar **package_ids)
 {
 	gchar *package_ids_temp;
-	package_ids_temp = pk_package_ids_to_text (package_ids, "|");
+	package_ids_temp = pk_package_ids_to_text (package_ids, "%");
 	pk_backend_spawn_helper (spawn, "get-details.py", package_ids_temp, NULL);
 	g_free (package_ids_temp);
 }
@@ -121,7 +121,7 @@ static void
 backend_get_files (PkBackend *backend, gchar **package_ids)
 {
 	gchar *package_ids_temp;
-	package_ids_temp = pk_package_ids_to_text (package_ids, "|");
+	package_ids_temp = pk_package_ids_to_text (package_ids, "%");
 	pk_backend_spawn_helper (spawn, "get-files.py", package_ids_temp, NULL);
 	g_free (package_ids_temp);
 }
@@ -145,7 +145,7 @@ static void
 backend_get_update_detail (PkBackend *backend, gchar **package_ids)
 {
 	gchar *package_ids_temp;
-	package_ids_temp = pk_package_ids_to_text (package_ids, "|");
+	package_ids_temp = pk_package_ids_to_text (package_ids, "%");
 	pk_backend_spawn_helper (spawn, "get-update-detail.py", package_ids_temp, NULL);
 	g_free (package_ids_temp);
 }
@@ -166,7 +166,7 @@ backend_install_packages (PkBackend *backend, gchar **package_ids)
 	}
 
 	/* send the complete list as stdin */
-	package_ids_temp = pk_package_ids_to_text (package_ids, "|");
+	package_ids_temp = pk_package_ids_to_text (package_ids, "%");
 	pk_backend_spawn_helper (spawn, "install-packages.py", package_ids_temp, NULL);
 	g_free (package_ids_temp);
 }
@@ -180,7 +180,7 @@ backend_install_files (PkBackend *backend, gboolean trusted, const gchar *full_p
 {
 	gchar *package_ids_temp;
 
-	package_ids_temp = pk_package_ids_to_text (package_ids, "|");
+	package_ids_temp = pk_package_ids_to_text (package_ids, "%");
 	pk_backend_spawn_helper (spawn, "install-files.py", full_paths, NULL);
 	g_free (package_ids_temp);
 }
@@ -211,7 +211,7 @@ backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow
 	gchar *package_ids_temp;
 
 	/* send the complete list as stdin */
-	package_ids_temp = pk_package_ids_to_text (package_ids, "|");
+	package_ids_temp = pk_package_ids_to_text (package_ids, "%");
 	pk_backend_spawn_helper (spawn, "remove-packages.py", pk_backend_bool_to_text (allow_deps), package_ids_temp, NULL);
 	g_free (package_ids_temp);
 }
@@ -245,7 +245,7 @@ backend_update_packages (PkBackend *backend, gchar **package_ids)
 	}
 
 	/* send the complete list as stdin */
-	package_ids_temp = pk_package_ids_to_text (package_ids, "|");
+	package_ids_temp = pk_package_ids_to_text (package_ids, "%");
 	pk_backend_spawn_helper (spawn, "update-packages.py", package_ids_temp, NULL);
 	g_free (package_ids_temp);
 }
commit 79fd0edfdf0d4c791646dc750d67a895866e0958
Author: Scott Reeves <sreeves at novell.com>
Date:   Tue Aug 19 16:00:13 2008 -0600

    finish the switch to PkBitfield

diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp
index a5babb4..5f99f60 100644
--- a/backends/zypp/pk-backend-zypp.cpp
+++ b/backends/zypp/pk-backend-zypp.cpp
@@ -262,7 +262,8 @@ backend_get_requires(PkBackend *backend, PkBitfield filters, gchar **package_ids
 static PkBitfield
 backend_get_groups (PkBackend *backend)
 {
-	return (PkGroupEnum)(PK_GROUP_ENUM_ADMIN_TOOLS,
+	return pk_bitfield_from_enums (
+		PK_GROUP_ENUM_ADMIN_TOOLS,
 		PK_GROUP_ENUM_COMMUNICATION,
 		PK_GROUP_ENUM_DESKTOP_GNOME,
 		PK_GROUP_ENUM_DESKTOP_KDE,
commit 771d297a4e6e551a7c559c7eb6b77e54f7d62c37
Author: Richard Hughes <hughsie at localhost.localdomain>
Date:   Tue Aug 19 22:04:32 2008 +0100

    bugfix: fix compiling the browser plugins where HAVE_GDK_APP_LAUNCH_CONTEXT_NEW is defined -- re-apply as I think git got itself in a tizz (trivial)

diff --git a/contrib/packagekit-plugin/src/contents.cpp b/contrib/packagekit-plugin/src/contents.cpp
index 9d51ac9..3be68fb 100644
--- a/contrib/packagekit-plugin/src/contents.cpp
+++ b/contrib/packagekit-plugin/src/contents.cpp
@@ -598,6 +598,9 @@ void
 PkpContents::runApplication (Time time)
 {
     GError *error = NULL;
+#ifdef HAVE_GDK_APP_LAUNCH_CONTEXT_NEW
+    GdkAppLaunchContext *context;
+#endif
 
     if (mAppInfo == 0) {
         g_warning("Didn't find application to launch");
@@ -607,20 +610,22 @@ PkpContents::runApplication (Time time)
     if (time == 0)
         time = get_server_timestamp();
 
-    GAppLaunchContext *context = 0;
 #ifdef HAVE_GDK_APP_LAUNCH_CONTEXT_NEW
     context = gdk_app_launch_context_new();
-    gdk_app_launch_context_set_timestamp(time);
+    gdk_app_launch_context_set_timestamp(context, time);
+    if (!g_app_info_launch(mAppInfo, NULL, G_APP_LAUNCH_CONTEXT (context), &error)) {
+#else
+    if (!g_app_info_launch(mAppInfo, NULL, NULL, &error)) {
 #endif
-
-    if (!g_app_info_launch(mAppInfo, NULL, context, &error)) {
         g_warning("%s\n", error->message);
         g_clear_error(&error);
         return;
     }
 
-    if (context != 0)
+#ifdef HAVE_GDK_APP_LAUNCH_CONTEXT_NEW
+    if (context != NULL)
         g_object_unref(context);
+#endif
 }
 
 void


More information about the PackageKit-commit mailing list