[packagekit] packagekit: Branch 'master' - 6 commits

Richard Hughes hughsient at kemper.freedesktop.org
Thu Sep 6 11:24:27 PDT 2007


 TODO                                |    4 
 backends/apt/Makefile.am            |    6 
 backends/apt/pk-backend-apt.c       |  192 ----------
 backends/apt/pk-backend-apt.cpp     |  664 ++++++++++++++++++++++++++++++++++++
 backends/box/Makefile.am            |    3 
 backends/box/pk-backend-box.c       |  306 +++++++++++-----
 backends/conary/pk-backend-conary.c |   47 +-
 backends/dummy/pk-backend-dummy.c   |   51 +-
 backends/test/pk-backend-test.c     |   38 +-
 backends/yum/.gitignore             |   10 
 backends/yum/pk-backend-yum.c       |   65 +--
 libpackagekit/pk-task-utils.c       |  104 +++++
 libpackagekit/pk-task-utils.h       |   15 
 src/pk-backend-internal.h           |    7 
 src/pk-backend.c                    |   13 
 src/pk-backend.h                    |    6 
 src/pk-engine.c                     |   10 
 17 files changed, 1114 insertions(+), 427 deletions(-)

New commits:
diff-tree 702f6d1d66126606d4b48c409036c790774c5019 (from 83c8cdcde6a0ba7bb8b9debd316c7d3120431395)
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu Sep 6 19:20:04 2007 +0100

    add some new action building code

diff --git a/libpackagekit/pk-task-utils.c b/libpackagekit/pk-task-utils.c
index e7e5339..492c4b3 100644
--- a/libpackagekit/pk-task-utils.c
+++ b/libpackagekit/pk-task-utils.c
@@ -428,6 +428,110 @@ pk_task_action_contains (const gchar *ac
 	return ret;
 }
 
+/**
+ * pk_util_action_new:
+ **/
+PkActionList *
+pk_util_action_new (PkTaskAction action, ...)
+{
+	va_list args;
+	guint i;
+	PkActionList *alist;
+	PkTaskAction action_temp;
+
+	/* create a new list. A list must have at least one entry */
+	alist = g_ptr_array_new ();
+	g_ptr_array_add (alist, GUINT_TO_POINTER(action));
+
+	/* process the valist */
+	va_start (args, action);
+	for (i=0;; i++) {
+		action_temp = va_arg (args, PkTaskAction);
+		if (action_temp == 0) break;
+		g_ptr_array_add (alist, GUINT_TO_POINTER(action_temp));
+	}
+	va_end (args);
+
+	return alist;
+}
+
+
+/**
+ * pk_util_action_new_from_string:
+ **/
+PkActionList *
+pk_util_action_new_from_string (const gchar *actions)
+{
+	PkActionList *alist;
+	gchar **sections;
+	guint i;
+	PkTaskAction action_temp;
+
+	if (actions == NULL) {
+		pk_warning ("actions null");
+		return FALSE;
+	}
+
+	/* split by delimeter ';' */
+	sections = g_strsplit (actions, ";", 0);
+
+	/* create a new list. A list must have at least one entry */
+	alist = g_ptr_array_new ();
+
+	for (i=0; sections[i]; i++) {
+		action_temp = pk_task_action_from_text (sections[i]);
+		g_ptr_array_add (alist, GUINT_TO_POINTER(action_temp));
+	}
+	g_strfreev (sections);
+	return alist;
+}
+
+/**
+ * pk_util_action_free:
+ **/
+gboolean
+pk_util_action_free (PkActionList *alist)
+{
+	g_ptr_array_free (alist, TRUE);
+	return TRUE;
+}
+
+/**
+ * pk_util_action_to_string:
+ **/
+gchar *
+pk_util_action_to_string (PkActionList *alist)
+{
+	guint i;
+	GString *string;
+
+	string = g_string_new ("");
+	for (i=0; i<alist->len; i++) {
+		g_string_append (string, g_ptr_array_index (alist, i));
+		g_string_append (string, ";");
+	}
+
+	/* remove last ';' */
+	g_string_set_size (string, string->len - 1);
+
+	return g_string_free (string, FALSE);
+}
+
+/**
+ * pk_util_action_contains:
+ **/
+gboolean
+pk_util_action_contains (PkActionList *alist, PkTaskAction action)
+{
+	guint i;
+	for (i=0; i<alist->len; i++) {
+		if (GPOINTER_TO_UINT (g_ptr_array_index (alist, i)) == action) {
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+
 /***************************************************************************
  ***                          MAKE CHECK TESTS                           ***
  ***************************************************************************/
diff --git a/libpackagekit/pk-task-utils.h b/libpackagekit/pk-task-utils.h
index 1961445..873caa6 100644
--- a/libpackagekit/pk-task-utils.h
+++ b/libpackagekit/pk-task-utils.h
@@ -23,6 +23,7 @@
 #define __PK_TASK_UTILS_H
 
 #include <glib-object.h>
+#include <glib.h>
 
 G_BEGIN_DECLS
 
@@ -133,9 +134,17 @@ const gchar	*pk_task_action_to_text			(P
 gboolean	 pk_task_filter_check			(const gchar	*filter);
 
 /* actions */
-gchar		*pk_task_action_build			(PkTaskAction	  action, ...);
-gboolean	 pk_task_action_contains		(const gchar	 *actions,
-							 PkTaskAction	  action);
+gchar		*pk_task_action_build			(PkTaskAction	 action, ...);
+gboolean	 pk_task_action_contains		(const gchar	*actions,
+							 PkTaskAction	 action);
+
+typedef GPtrArray PkActionList;
+PkActionList	*pk_util_action_new			(PkTaskAction	 action, ...);
+PkActionList	*pk_util_action_new_from_string		(const gchar	*actions);
+gchar		*pk_util_action_to_string		(PkActionList	*alist);
+gboolean	 pk_util_action_contains		(PkActionList	*alist,
+							 PkTaskAction	 action);
+gboolean	 pk_util_action_free			(PkActionList	*alist);
 
 G_END_DECLS
 
diff-tree 83c8cdcde6a0ba7bb8b9debd316c7d3120431395 (from 67ef712edcb52b0b75ab43d44222f8b172a92b64)
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu Sep 6 18:29:12 2007 +0100

    save the backend name

diff --git a/src/pk-engine.c b/src/pk-engine.c
index 7dd1c91..a61181a 100644
--- a/src/pk-engine.c
+++ b/src/pk-engine.c
@@ -61,6 +61,7 @@ struct PkEnginePrivate
 	guint			 job_count;
 	PolKitContext		*pk_context;
 	DBusConnection		*connection;
+	gchar			*backend;
 };
 
 enum {
@@ -134,6 +135,7 @@ gboolean
 pk_engine_use_backend (PkEngine *engine, const gchar *backend)
 {
 	pk_debug ("trying backend %s", backend);
+	engine->priv->backend = g_strdup (backend);
 	return TRUE;
 }
 
@@ -1496,6 +1498,7 @@ pk_engine_init (PkEngine *engine)
 	engine->priv = PK_ENGINE_GET_PRIVATE (engine);
 	engine->priv->array = g_ptr_array_new ();
 	engine->priv->timer = g_timer_new ();
+	engine->priv->backend = NULL;
 
 	engine->priv->job_count = pk_engine_load_job_count (engine);
 
@@ -1538,6 +1541,7 @@ pk_engine_finalize (GObject *object)
 	/* compulsory gobjects */
 	g_ptr_array_free (engine->priv->array, TRUE);
 	g_timer_destroy (engine->priv->timer);
+	g_free (engine->priv->backend);
 	polkit_context_unref (engine->priv->pk_context);
 
 	G_OBJECT_CLASS (pk_engine_parent_class)->finalize (object);
diff-tree 67ef712edcb52b0b75ab43d44222f8b172a92b64 (from 8945391449b41cc8411ad1a845f6db1b774754b3)
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu Sep 6 18:24:26 2007 +0100

    convert the apt backend - totally untested

diff --git a/TODO b/TODO
index d4ec301..973f032 100644
--- a/TODO
+++ b/TODO
@@ -22,11 +22,11 @@ string updates
 string obsoletes
 string update_text
 }
-* Get the set_job and get_job out of the pk-task structure (use g_object)
 * Switch to dlopened backends and remove bodge of pk-task-common.*
+* add errors OutOfMemory, CannotCreateThread
+* Remove the _TASK_ in the enums
 
 Backends:
 * Complete conary backend
 * Dummy backend should use subpercent and install deps
-* Add enough new error enums for all the backends
 
diff --git a/backends/apt/Makefile.am b/backends/apt/Makefile.am
index 934daf1..76992c1 100644
--- a/backends/apt/Makefile.am
+++ b/backends/apt/Makefile.am
@@ -1,6 +1,8 @@
 #plugindir = @PK_PLUGIN_DIR@
 #plugin_LTLIBRARIES = libpk_backend_apt.la
-#libpk_backend_apt_la_SOURCES = pk-backend-apt.c
-#libpk_backend_apt_la_LIBADD = @PK_PLUGIN_LIBS@
+#libpk_backend_apt_la_INCLUDES = $(APT_CFLAGS)
+#libpk_backend_apt_la_SOURCES = pk-backend-apt.cpp
+#libpk_backend_apt_la_LIBADD = @PK_PLUGIN_LIBS@ $(APT_LIBS)
 #libpk_backend_apt_la_LDFLAGS = -module -avoid-version
 #libpk_backend_apt_la_CFLAGS = @PK_PLUGIN_CFLAGS@
+
diff --git a/backends/apt/pk-backend-apt.c b/backends/apt/pk-backend-apt.c
deleted file mode 100644
index ac050e3..0000000
--- a/backends/apt/pk-backend-apt.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2007 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.
- */
-
-#include <gmodule.h>
-#include <glib.h>
-#include <string.h>
-#include <pk-backend.h>
-
-/**
- * backend_initalize:
- */
-static void
-backend_initalize (PkBackend *backend)
-{
-	g_return_if_fail (backend != NULL);
-}
-
-/**
- * backend_destroy:
- */
-static void
-backend_destroy (PkBackend *backend)
-{
-	g_return_if_fail (backend != NULL);
-}
-
-/**
- * backend_cancel_job_try:
- */
-static void
-backend_cancel_job_try (PkBackend *backend)
-{
-	g_return_if_fail (backend != NULL);
-}
-
-/**
- * backend_get_depends:
- */
-static void
-backend_get_depends (PkBackend *backend, const gchar *package_id)
-{
-	g_return_if_fail (backend != NULL);
-}
-
-/**
- * backend_get_description:
- */
-static void
-backend_get_description (PkBackend *backend, const gchar *package_id)
-{
-	g_return_if_fail (backend != NULL);
-}
-
-/**
- * backend_get_requires:
- */
-static void
-backend_get_requires (PkBackend *backend, const gchar *package_id)
-{
-	g_return_if_fail (backend != NULL);
-}
-
-/**
- * backend_get_updates:
- */
-static void
-backend_get_updates (PkBackend *backend)
-{
-	g_return_if_fail (backend != NULL);
-}
-
-/**
- * backend_install_package:
- */
-static void
-backend_install_package (PkBackend *backend, const gchar *package_id)
-{
-	g_return_if_fail (backend != NULL);
-}
-
-/**
- * backend_refresh_cache:
- */
-static void
-backend_refresh_cache (PkBackend *backend, gboolean force)
-{
-	g_return_if_fail (backend != NULL);
-}
-
-/**
- * backend_remove_package:
- */
-static void
-backend_remove_package (PkBackend *backend, const gchar *package_id, gboolean allow_deps)
-{
-	g_return_if_fail (backend != NULL);
-}
-
-/**
- * backend_search_details:
- */
-static void
-backend_search_details (PkBackend *backend, const gchar *filter, const gchar *search)
-{
-	g_return_if_fail (backend != NULL);
-}
-
-/**
- * backend_search_file:
- */
-static void
-backend_search_file (PkBackend *backend, const gchar *filter, const gchar *search)
-{
-	g_return_if_fail (backend != NULL);
-}
-
-/**
- * backend_search_group:
- */
-static void
-backend_search_group (PkBackend *backend, const gchar *filter, const gchar *search)
-{
-	g_return_if_fail (backend != NULL);
-}
-
-/**
- * backend_search_name:
- */
-static void
-backend_search_name (PkBackend *backend, const gchar *filter, const gchar *search)
-{
-	g_return_if_fail (backend != NULL);
-}
-
-/**
- * backend_update_package:
- */
-static void
-backend_update_package (PkBackend *backend, const gchar *package_id)
-{
-	g_return_if_fail (backend != NULL);
-}
-
-/**
- * backend_update_system:
- */
-static void
-backend_update_system (PkBackend *backend)
-{
-	g_return_if_fail (backend != NULL);
-}
-
-PK_BACKEND_OPTIONS (
-	"APT Backend",				/* description */
-	"0.0.1",				/* version */
-	"Richard Hughes <richard at hughsie.com>",	/* author */
-	backend_initalize,			/* initalize */
-	backend_destroy,			/* destroy */
-	backend_cancel_job_try,			/* cancel_job_try */
-	backend_get_depends,			/* get_depends */
-	backend_get_description,		/* get_description */
-	backend_get_requires,			/* get_requires */
-	backend_get_updates,			/* get_updates */
-	backend_install_package,		/* install_package */
-	backend_refresh_cache,			/* refresh_cache */
-	backend_remove_package,			/* remove_package */
-	backend_search_details,			/* search_details */
-	backend_search_file,			/* search_file */
-	backend_search_group,			/* search_group */
-	backend_search_name,			/* search_name */
-	backend_update_package,			/* update_package */
-	backend_update_system			/* update_system */
-);
-
diff --git a/backends/apt/pk-backend-apt.cpp b/backends/apt/pk-backend-apt.cpp
new file mode 100644
index 0000000..35d3311
--- /dev/null
+++ b/backends/apt/pk-backend-apt.cpp
@@ -0,0 +1,664 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 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.
+ */
+
+#include <gmodule.h>
+#include <glib.h>
+#include <string.h>
+#include <pk-backend.h>
+
+#include <apt-pkg/pkgcachegen.h>
+#include <apt-pkg/pkgcache.h>
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/progress.h>
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/pkgrecords.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/acquire.h>
+#include <apt-pkg/acquire-item.h>
+
+#include <regex.h>
+#include <string.h>
+#include <math.h>
+
+static pkgCacheFile *fileCache = NULL;
+pkgSourceList *SrcList = 0;
+
+typedef struct {
+	PkBackend *backend;
+} UpdateData;
+
+typedef enum {
+	SEARCH_NAME = 1,
+	SEARCH_DETAILS
+} SearchDepth;
+
+struct search_task {
+	PkBackend *backend;
+	gchar *search;
+	gchar *filter;
+	SearchDepth depth;
+};
+
+struct desc_task {
+	PkBackend *backend;
+	PkPackageId *pi;
+};
+
+struct ExDescFile {
+	AptCompFile *Df;
+	const char *verstr;
+	const char *arch;
+	gboolean installed;
+	gboolean available;
+	char *repo;
+	bool NameMatch;
+};
+
+#ifdef APT_PKG_RPM
+typedef pkgCache::VerFile AptCompFile;
+#elif defined(APT_PKG_DEB)
+typedef pkgCache::DescFile AptCompFile;
+#else
+#error Need either rpm or deb defined
+#endif
+
+
+static pkgCacheFile *getCache()
+{
+	if (fileCache == NULL)
+	{
+		MMap *Map = 0;
+		OpTextProgress Prog;
+		if (pkgInitConfig(*_config) == false)
+			pk_debug("pkginitconfig was false");
+		if (pkgInitSystem(*_config, _system) == false)
+			pk_debug("pkginitsystem was false");
+		// Open the cache file
+		SrcList = new pkgSourceList;
+		SrcList->ReadMainList();
+
+		// Generate it and map it
+		pkgMakeStatusCache(*SrcList, Prog, &Map, true);
+
+		fileCache = new pkgCacheFile();
+
+		if (fileCache->Open(Prog, FALSE) == FALSE)
+		{
+			pk_debug("I need more privelges");
+			fileCache->Close();
+			fileCache = NULL;
+		}
+		else
+			pk_debug("cache inited");
+	}
+	return fileCache;
+}
+
+class UpdatePercentage:public pkgAcquireStatus
+{
+	double old;
+	PkBackend *backend;
+
+	public:
+	UpdatePercentage(PkBackend *tk)
+	{
+		old = -1;
+		backend = tk;
+	}
+	
+	virtual bool MediaChange(string Media,string Drive)
+	{
+		pk_debug("PANIC!: we don't handle mediachange");
+		return FALSE;
+	}
+	
+	virtual bool Pulse(pkgAcquire *Owner)
+	{
+		pkgAcquireStatus::Pulse(Owner);
+		double percent = double(CurrentBytes*100.0)/double(TotalBytes);
+		if (old!=percent)
+		{
+			pk_backend_change_percentage(backend,(guint)percent);
+			pk_backend_change_sub_percentage(backend,((guint)(percent*100.0))%100);
+			old = percent;
+		}
+		return true;	
+	}
+};
+
+// do_update_thread - Update the package lists 
+// Swiped from apt-get's update mode
+void *do_update_thread(gpointer data)
+{
+	UpdateData *ud = (UpdateData*)data;
+	pkgCacheFile *Cache;
+	bool Failed = false;
+	bool TransientNetworkFailure = false;
+	OpTextProgress Prog;
+	
+	/* easy as that */
+	pk_backend_change_job_status(ud->backend, PK_TASK_STATUS_REFRESH_CACHE);
+
+	Cache = getCache();
+
+	// Get the source list
+	pkgSourceList List;
+	if (List.ReadMainList() == false)
+	{
+		pk_backend_error_code(ud->backend, PK_TASK_ERROR_CODE_UNKNOWN, "Failure reading lists");
+		pk_backend_finished(ud->backend, PK_TASK_EXIT_FAILED);
+		return NULL;
+	}
+
+	// Lock the list directory
+	FileFd Lock;
+	if (_config->FindB("Debug::NoLocking", false) == false)
+	{
+		Lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock"));
+		if (_error->PendingError() == true)
+		{
+			_error->DumpErrors();
+			pk_backend_error_code(ud->backend, PK_TASK_ERROR_CODE_UNKNOWN, "Unable to lock the list directory");
+			pk_backend_finished(ud->backend, PK_TASK_EXIT_FAILED);
+			return NULL;
+		}
+	}
+
+	// Create the download object
+	UpdatePercentage *Stat = new UpdatePercentage(ud->backend);
+	pkgAcquire Fetcher(Stat);
+
+	// Populate it with the source selection
+	if (List.GetIndexes(&Fetcher) == false)
+	{
+		pk_backend_error_code(ud->backend, PK_TASK_ERROR_CODE_UNKNOWN, "Generic Error");
+		goto do_update_clean;
+	}
+
+	// Run it
+	if (Fetcher.Run() == pkgAcquire::Failed)
+	{
+		pk_backend_error_code(ud->backend, PK_TASK_ERROR_CODE_UNKNOWN, "Generic Error");
+		goto do_update_clean;
+	}
+
+	for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
+	{
+		if ((*I)->Status == pkgAcquire::Item::StatDone)
+			continue;
+
+		(*I)->Finished();
+
+		fprintf(stderr, "Failed to fetch %s  %s\n", (*I)->DescURI().c_str(), (*I)->ErrorText.c_str());
+
+		if ((*I)->Status == pkgAcquire::Item::StatTransientNetworkError)
+		{
+			TransientNetworkFailure = true;
+			continue;
+		}
+
+		Failed = true;
+	}
+
+	// Clean out any old list files
+	if (!TransientNetworkFailure && _config->FindB("APT::Get::List-Cleanup", true) == true)
+	{
+		if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false ||
+		    Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false)
+		{
+			pk_backend_error_code(ud->backend, PK_TASK_ERROR_CODE_UNKNOWN, "Generic Error");
+			goto do_update_clean;
+		}
+	}
+
+	// Prepare the cache.   
+	Cache = getCache();
+	if (Cache->BuildCaches(Prog,false) == false)
+	{
+		pk_backend_error_code(ud->backend, PK_TASK_ERROR_CODE_UNKNOWN, "Generic Error");
+		goto do_update_clean;
+	}
+
+	if (TransientNetworkFailure == true)
+		pk_debug("Some index files failed to download, they have been ignored, or old ones used instead.");
+	else if (Failed == true)
+	{
+		pk_backend_error_code(ud->backend, PK_TASK_ERROR_CODE_UNKNOWN, "Generic Error");
+		goto do_update_clean;
+	}
+
+	delete Stat;
+	pk_backend_finished(ud->backend, PK_TASK_EXIT_SUCCESS);
+	return NULL;
+
+	do_update_clean:
+	delete Stat;
+	pk_backend_finished(ud->backend, PK_TASK_EXIT_FAILED);
+	return NULL;
+}
+
+/**
+ * pk_backend_refresh_cache:
+ **/
+gboolean pk_backend_refresh_cache(PkBackend * backend, gboolean force)
+{
+	/* check network state */
+	if (pk_network_is_online(backend->priv->network) == FALSE)
+	{
+		pk_backend_error_code(backend, PK_TASK_ERROR_CODE_NO_NETWORK, "Cannot refresh cache whilst offline");
+		pk_backend_finished(backend, PK_TASK_EXIT_FAILED);
+		return TRUE;
+	}
+
+	UpdateData *data = g_new(UpdateData, 1);
+	if (data == NULL)
+	{
+		pk_backend_error_code(backend, PK_TASK_ERROR_CODE_UNKNOWN, "can't allocate memory for update task");
+		pk_backend_finished(backend, PK_TASK_EXIT_FAILED);
+	}
+	else
+	{
+		data->backend = backend;
+		if (g_thread_create(do_update_thread, data, false, NULL) == NULL)
+		{
+			pk_backend_error_code(backend, PK_TASK_ERROR_CODE_UNKNOWN, "can't spawn update thread");
+			pk_backend_finished(backend, PK_TASK_EXIT_FAILED);
+		}
+	}
+	return TRUE;
+}
+
+// LocalitySort - Sort a version list by package file locality		/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+static int LocalityCompare(const void *a, const void *b)
+{
+	pkgCache::VerFile *A = *(pkgCache::VerFile **)a;
+	pkgCache::VerFile *B = *(pkgCache::VerFile **)b;
+
+	if (A == 0 && B == 0)
+		return 0;
+	if (A == 0)
+		return 1;
+	if (B == 0)
+		return -1;
+
+	if (A->File == B->File)
+		return A->Offset - B->Offset;
+	return A->File - B->File;
+}
+
+static void LocalitySort(AptCompFile **begin,
+		  unsigned long Count,size_t Size)
+{
+	qsort(begin,Count,Size,LocalityCompare);
+}
+
+static gboolean buildExDesc(ExDescFile *DFList, unsigned int pid, pkgCache::VerIterator V)
+{
+	// Find the proper version to use. 
+	DFList[pid].available = false;
+	if (V.end() == false)
+	{
+	#ifdef APT_PKG_RPM
+		DFList[pid].Df = V.FileList();
+	#else	
+		DFList[pid].Df = V.DescriptionList().FileList();
+	#endif
+		DFList[pid].verstr = V.VerStr();
+		DFList[pid].arch = V.Arch();
+		for (pkgCache::VerFileIterator VF = V.FileList(); VF.end() == false; VF++)
+		{
+			// Locate the associated index files so we can derive a description
+			pkgIndexFile *Indx;
+			bool hasLocal = _system->FindIndex(VF.File(),Indx);
+			if (SrcList->FindIndex(VF.File(),Indx) == false && !hasLocal)
+			{
+			   pk_debug("Cache is out of sync, can't x-ref a package file");
+			   break;
+			}
+			gchar** items = g_strsplit_set(Indx->Describe(true).c_str()," \t",-1);
+			DFList[pid].repo = g_strdup(items[1]); // should be in format like "http://ftp.nl.debian.org unstable/main Packages"
+			DFList[pid].installed = hasLocal;
+			g_strfreev(items);
+			DFList[pid].available = true;
+			if (hasLocal)
+				break;
+		}	 
+	}
+	return DFList[pid].available;
+}
+
+// get_search_thread
+// Swiped from apt-cache's search mode
+static void *get_search_thread(gpointer data)
+{
+	search_task *st = (search_task *) data;
+	ExDescFile *DFList = NULL;
+
+	pk_backend_change_job_status(st->backend, PK_TASK_STATUS_QUERY);
+	pk_backend_no_percentage_updates(st->backend);
+
+	pk_debug("finding %s", st->search);
+	pkgCache & pkgCache = *(getCache());
+	pkgDepCache::Policy Plcy;
+	// Create the text record parser
+	pkgRecords Recs(pkgCache);
+
+	// Compile the regex pattern
+	regex_t *Pattern = new regex_t;
+	memset(Pattern, 0, sizeof(*Pattern));
+	if (regcomp(Pattern, st->search, REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0)
+	{
+		pk_backend_error_code(st->backend, PK_TASK_ERROR_CODE_UNKNOWN, "regex compilation error");
+		pk_backend_finished(st->backend, PK_TASK_EXIT_FAILED);
+		goto search_task_cleanup;
+	}
+
+	DFList = new ExDescFile[pkgCache.HeaderP->PackageCount + 1];
+	memset(DFList, 0, sizeof(*DFList) * pkgCache.HeaderP->PackageCount + 1);
+
+	// Map versions that we want to write out onto the VerList array.
+	for (pkgCache::PkgIterator P = pkgCache.PkgBegin(); P.end() == false; P++)
+	{
+		DFList[P->ID].NameMatch = true;
+		if (regexec(Pattern, P.Name(), 0, 0, 0) == 0)
+			DFList[P->ID].NameMatch &= true;
+		else
+			DFList[P->ID].NameMatch = false;
+
+		// Doing names only, drop any that dont match..
+		if (st->depth == SEARCH_NAME && DFList[P->ID].NameMatch == false)
+			continue;
+
+		// Find the proper version to use. 
+		pkgCache::VerIterator V = Plcy.GetCandidateVer(P);
+		buildExDesc(DFList, P->ID, V);
+	}
+
+	// Include all the packages that provide matching names too
+	for (pkgCache::PkgIterator P = pkgCache.PkgBegin(); P.end() == false; P++)
+	{
+		if (DFList[P->ID].NameMatch == false)
+			continue;
+
+		for (pkgCache::PrvIterator Prv = P.ProvidesList(); Prv.end() == false; Prv++)
+		{
+			pkgCache::VerIterator V = Plcy.GetCandidateVer(Prv.OwnerPkg());
+			if (buildExDesc(DFList, Prv.OwnerPkg()->ID, V))
+				DFList[Prv.OwnerPkg()->ID].NameMatch = true;
+		}
+	}
+
+	LocalitySort(&DFList->Df, pkgCache.HeaderP->PackageCount, sizeof(*DFList));
+
+	// Iterate over all the version records and check them
+	for (ExDescFile * J = DFList; J->Df != 0; J++)
+	{
+#ifdef APT_PKG_RPM
+		pkgRecords::Parser & P = Recs.Lookup(pkgCache::VerFileIterator(pkgCache, J->Df));
+#else
+		pkgRecords::Parser & P = Recs.Lookup(pkgCache::DescFileIterator(pkgCache, J->Df));
+#endif
+
+		gboolean Match = true;
+		if (J->NameMatch == false)
+		{
+			string LongDesc = P.LongDesc();
+			if (regexec(Pattern, LongDesc.c_str(), 0, 0, 0) == 0)
+				Match = true;
+			else
+				Match = false;
+		}
+
+		if (Match == true)// && pk_task_filter_package_name(st->backend,P.Name().c_str()))
+		{
+			gchar *pid = pk_package_id_build(P.Name().c_str(),J->verstr,J->arch,J->repo);
+			pk_backend_package(st->backend, J->installed, pid, P.ShortDesc().c_str());
+			g_free(pid);
+		}
+	}
+
+	pk_backend_finished(st->backend, PK_TASK_EXIT_SUCCESS);
+
+search_task_cleanup:
+	for (ExDescFile * J = DFList; J->Df != 0; J++)
+	{
+		g_free(J->repo);
+	}
+	delete[]DFList;
+	regfree(Pattern);
+	g_free(st->search);
+	g_free(st);
+
+	return NULL;
+}
+
+/**
+ * pk_backend_search
+ **/
+static gboolean
+pk_backend_search(PkBackend * backend, const gchar * filter, const gchar * search, SearchDepth which)
+{
+
+	if (pk_backend_filter_check(filter) == FALSE)
+	{
+		pk_backend_error_code(backend, PK_TASK_ERROR_CODE_FILTER_INVALID, "filter '%s' not valid", filter);
+		pk_backend_finished(backend, PK_TASK_EXIT_FAILED);
+		return TRUE;
+	}
+
+	search_task *data = g_new(struct search_task, 1);
+	if (data == NULL)
+	{
+		pk_backend_error_code(backend, PK_TASK_ERROR_CODE_UNKNOWN, "can't allocate memory for search task");
+		pk_backend_finished(backend, PK_TASK_EXIT_FAILED);
+	}
+	else
+	{
+		data->backend = backend;
+		data->search = g_strdup(search);
+		data->filter = g_strdup(filter);
+		data->depth = which;
+
+		if (g_thread_create(get_search_thread, data, false, NULL) == NULL)
+		{
+			pk_backend_error_code(backend, PK_TASK_ERROR_CODE_UNKNOWN, "can't spawn thread");
+			pk_backend_finished(backend, PK_TASK_EXIT_FAILED);
+		}
+	}
+	return TRUE;
+}
+
+static GHashTable *PackageRecord(pkgCache::VerIterator V)
+{
+	GHashTable *ret = NULL;
+	
+	pkgCache & pkgCache = *(getCache());
+	// Find an appropriate file
+	pkgCache::VerFileIterator Vf = V.FileList();
+	for (; Vf.end() == false; Vf++)
+	{
+		if ((Vf.File()->Flags & pkgCache::Flag::NotSource) == 0)
+			break;
+		if (Vf.end() == true)
+			Vf = V.FileList();
+	}
+		
+	// Check and load the package list file
+	pkgCache::PkgFileIterator I = Vf.File();
+	if (I.IsOk() == false)
+		return NULL;
+	
+	FileFd PkgF(I.FileName(),FileFd::ReadOnly);
+	if (_error->PendingError() == true)
+		return NULL;
+	
+	// Read the record
+	char *Buffer = new char[pkgCache.HeaderP->MaxVerFileSize+1];
+	Buffer[V.FileList()->Size] = '\0';
+	if (PkgF.Seek(V.FileList()->Offset) == false ||
+		 PkgF.Read(Buffer,V.FileList()->Size) == false)
+	{
+		delete [] Buffer;
+		return NULL;
+	}
+	//pk_debug("buffer: '%s'\n",Buffer);
+	ret = g_hash_table_new_full(g_str_hash,g_str_equal,g_free,g_free);
+	gchar ** lines = g_strsplit(Buffer,"\n",-1);
+	guint i;
+	for (i=0;i<g_strv_length(lines);i++)
+	{
+		gchar ** parts = g_strsplit_set(lines[i],": ",2);
+		if (g_strv_length(parts)>1)
+		{
+			//pk_debug("entry =  '%s' : '%s'",parts[0],parts[1]);
+			if (parts[0][0]=='\0')
+			{
+				gchar *oldval = g_strdup((const gchar*)g_hash_table_lookup(ret,"Description"));
+				g_hash_table_insert(ret,g_strdup("Description"),g_strconcat(oldval, "\n",parts[1],NULL));
+				//pk_debug("new entry =  '%s'",(const gchar*)g_hash_table_lookup(ret,"Description"));
+				g_free(oldval);
+			}
+			else
+				g_hash_table_insert(ret,g_strdup(parts[0]),g_strdup(parts[1]));
+		}
+		g_strfreev(parts);
+	}
+	g_strfreev(lines);
+	return ret;
+
+}
+
+// get_description_thread
+static void *get_description_thread(gpointer data)
+{
+	desc_task *dt = (desc_task *) data;
+
+	pk_backend_change_job_status(dt->backend, PK_TASK_STATUS_QUERY);
+	pk_backend_no_percentage_updates(dt->backend);
+
+	pk_debug("finding %s", dt->pi->name);
+	pkgCache & pkgCache = *(getCache());
+	pkgDepCache::Policy Plcy;
+
+	// Map versions that we want to write out onto the VerList array.
+	for (pkgCache::PkgIterator P = pkgCache.PkgBegin(); P.end() == false; P++)
+	{
+		if (strcmp(dt->pi->name, P.Name())!=0)
+			continue;
+
+		// Find the proper version to use. 
+		pkgCache::VerIterator V = Plcy.GetCandidateVer(P);
+		GHashTable *pkg = PackageRecord(V);
+		pk_backend_description(dt->backend,dt->pi->name,
+					PK_TASK_GROUP_OTHER,(const gchar*)g_hash_table_lookup(pkg,"Description"),"");
+		g_hash_table_unref(pkg);
+	}
+	pk_backend_finished(dt->backend, PK_TASK_EXIT_SUCCESS);
+	return NULL;
+}
+
+/**
+ * backend_get_description:
+ */
+static void
+backend_get_description (PkBackend *backend, const gchar *package_id)
+{
+	g_return_if_fail (backend != NULL);
+	desc_task *data = g_new(struct desc_task, 1);
+	if (data == NULL)
+	{
+		pk_backend_error_code(backend, PK_TASK_ERROR_CODE_INTERNAL_ERROR, "can't allocate memory for search task");
+		pk_backend_finished(backend, PK_TASK_EXIT_FAILED);
+		return;
+	}
+
+	data->backend = backend;
+	data->pi = pk_package_id_new_from_string(package);
+	if (data->pi == NULL)
+	{
+		pk_backend_error_code(backend, PK_TASK_ERROR_CODE_PACKAGE_ID_INVALID, "invalid package id");
+		pk_backend_finished(backend, PK_TASK_EXIT_FAILED);
+		return;
+	}
+
+	if (g_thread_create(get_description_thread, data, false, NULL) == NULL)
+	{
+		pk_backend_error_code(backend, PK_TASK_ERROR_CODE_INTERNAL_ERROR, "can't spawn thread");
+		pk_backend_finished(backend, PK_TASK_EXIT_FAILED);
+	}
+	return;
+}
+
+/**
+ * backend_refresh_cache:
+ */
+static void
+backend_refresh_cache (PkBackend *backend, gboolean force)
+{
+	g_return_if_fail (backend != NULL);
+}
+
+/**
+ * backend_search_details:
+ */
+static void
+backend_search_details (PkBackend *backend, const gchar *filter, const gchar *search)
+{
+	g_return_if_fail (backend != NULL);
+	pk_backend_search(backend, filter, search, SEARCH_DETAILS);
+}
+
+/**
+ * backend_search_name:
+ */
+static void
+backend_search_name (PkBackend *backend, const gchar *filter, const gchar *search)
+{
+	g_return_if_fail (backend != NULL);
+	pk_backend_search(backend, filter, search, SEARCH_NAME);s
+}
+
+PK_BACKEND_OPTIONS (
+	"APT Backend",				/* description */
+	"0.0.1",				/* version */
+	"Richard Hughes <richard at hughsie.com>",	/* author */
+	NULL,					/* initalize */
+	NULL,					/* destroy */
+	NULL,					/* cancel_job_try */
+	NULL,					/* get_depends */
+	backend_get_description,		/* get_description */
+	NULL,					/* get_requires */
+	NULL,					/* get_updates */
+	NULL,					/* install_package */
+	backend_refresh_cache,			/* refresh_cache */
+	NULL,					/* remove_package */
+	backend_search_details,			/* search_details */
+	NULL,					/* search_file */
+	NULL,					/* search_group */
+	backend_search_name,			/* search_name */
+	NULL,					/* update_package */
+	NULL					/* update_system */
+);
+
diff --git a/backends/yum/.gitignore b/backends/yum/.gitignore
new file mode 100644
index 0000000..c851833
--- /dev/null
+++ b/backends/yum/.gitignore
@@ -0,0 +1,10 @@
+.deps
+.libs
+Makefile
+Makefile.in
+*.la
+*.lo
+*.loT
+*.o
+*~
+
diff --git a/src/pk-backend.h b/src/pk-backend.h
index 7d30c33..e903a51 100644
--- a/src/pk-backend.h
+++ b/src/pk-backend.h
@@ -24,6 +24,7 @@
 
 #include <glib.h>
 #include <pk-task-utils.h>
+#include <pk-package-id.h>
 
 G_BEGIN_DECLS
 
diff-tree 8945391449b41cc8411ad1a845f6db1b774754b3 (from baa1599f5e1c9a39c37d27b09546394bcc927bb9)
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu Sep 6 18:01:45 2007 +0100

    do pk_backend_set_job_role in the backend helper as all the backends should be common

diff --git a/backends/apt/pk-backend-apt.c b/backends/apt/pk-backend-apt.c
index 183eb9e..ac050e3 100644
--- a/backends/apt/pk-backend-apt.c
+++ b/backends/apt/pk-backend-apt.c
@@ -169,24 +169,24 @@ backend_update_system (PkBackend *backen
 }
 
 PK_BACKEND_OPTIONS (
-	"Dummy Backend",		/* description */
-	"0.0.1",			/* version */
-	"richard at hughsie.com",		/* author */
-	backend_initalize,		/* initalize */
-	backend_destroy,		/* destroy */
-	backend_cancel_job_try,		/* cancel_job_try */
-	backend_get_depends,		/* get_depends */
-	backend_get_description,	/* get_description */
-	backend_get_requires,		/* get_requires */
-	backend_get_updates,		/* get_updates */
-	backend_install_package,	/* install_package */
-	backend_refresh_cache,		/* refresh_cache */
-	backend_remove_package,		/* remove_package */
-	backend_search_details,		/* search_details */
-	backend_search_file,		/* search_file */
-	backend_search_group,		/* search_group */
-	backend_search_name,		/* search_name */
-	backend_update_package,		/* update_package */
-	backend_update_system		/* update_system */
+	"APT Backend",				/* description */
+	"0.0.1",				/* version */
+	"Richard Hughes <richard at hughsie.com>",	/* author */
+	backend_initalize,			/* initalize */
+	backend_destroy,			/* destroy */
+	backend_cancel_job_try,			/* cancel_job_try */
+	backend_get_depends,			/* get_depends */
+	backend_get_description,		/* get_description */
+	backend_get_requires,			/* get_requires */
+	backend_get_updates,			/* get_updates */
+	backend_install_package,		/* install_package */
+	backend_refresh_cache,			/* refresh_cache */
+	backend_remove_package,			/* remove_package */
+	backend_search_details,			/* search_details */
+	backend_search_file,			/* search_file */
+	backend_search_group,			/* search_group */
+	backend_search_name,			/* search_name */
+	backend_update_package,			/* update_package */
+	backend_update_system			/* update_system */
 );
 
diff --git a/backends/conary/pk-backend-conary.c b/backends/conary/pk-backend-conary.c
index 0da201e..c379181 100644
--- a/backends/conary/pk-backend-conary.c
+++ b/backends/conary/pk-backend-conary.c
@@ -33,7 +33,6 @@ backend_get_description (PkBackend *back
 {
 	g_return_if_fail (backend != NULL);
 	pk_backend_allow_interrupt (backend, TRUE);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, package_id);
 	pk_backend_spawn_helper (backend, "get-description.py", package_id, NULL);
 }
 
@@ -44,7 +43,6 @@ static void
 backend_get_updates (PkBackend *backend)
 {
 	g_return_if_fail (backend != NULL);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, NULL);
 	pk_backend_spawn_helper (backend, "get-updates.py", NULL);
 }
 
@@ -61,8 +59,6 @@ backend_install_package (PkBackend *back
 		pk_backend_finished (backend, PK_TASK_EXIT_FAILED);
 		return;
 	}
-
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_PACKAGE_INSTALL, package_id);
 	pk_backend_spawn_helper (backend, "install.py", package_id, NULL);
 }
 
@@ -79,7 +75,6 @@ backend_refresh_cache (PkBackend *backen
 		pk_backend_finished (backend, PK_TASK_EXIT_FAILED);
 		return;
 	}
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_REFRESH_CACHE, NULL);
 	pk_backend_spawn_helper (backend, "refresh-cache.py", NULL);
 }
 
@@ -96,8 +91,6 @@ backend_remove_package (PkBackend *backe
 	} else {
 		deps = "no";
 	}
-
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_PACKAGE_REMOVE, package_id);
 	pk_backend_spawn_helper (backend, "remove.py", deps, package_id, NULL);
 }
 
@@ -109,7 +102,6 @@ backend_search_details (PkBackend *backe
 {
 	g_return_if_fail (backend != NULL);
 	pk_backend_allow_interrupt (backend, TRUE);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, search);
 	pk_backend_spawn_helper (backend, "search-details.py", filter, search, NULL);
 }
 
@@ -122,29 +114,28 @@ backend_search_name (PkBackend *backend,
 	g_return_if_fail (backend != NULL);
 	pk_backend_allow_interrupt (backend, TRUE);
 	pk_backend_no_percentage_updates (backend);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, search);
 	pk_backend_spawn_helper (backend, "search-name.py", filter, search, NULL);
 }
 
 PK_BACKEND_OPTIONS (
-	"Conary Backend",		/* description */
-	"0.0.1",			/* version */
-	"ken at vandine.org",		/* author */
-	NULL,				/* initalize */
-	NULL,				/* destroy */
-	NULL,				/* cancel_job_try */
-	NULL,				/* get_depends */
-	backend_get_description,	/* get_description */
-	NULL,				/* get_requires */
-	backend_get_updates,		/* get_updates */
-	backend_install_package,	/* install_package */
-	backend_refresh_cache,		/* refresh_cache */
-	backend_remove_package,		/* remove_package */
-	backend_search_details,		/* search_details */
-	NULL,				/* search_file */
-	NULL,				/* search_group */
-	backend_search_name,		/* search_name */
-	NULL,				/* update_package */
-	NULL				/* update_system */
+	"Conary Backend",			/* description */
+	"0.0.1",				/* version */
+	"Ken VanDine <ken at vandine.org>",	/* author */
+	NULL,					/* initalize */
+	NULL,					/* destroy */
+	NULL,					/* cancel_job_try */
+	NULL,					/* get_depends */
+	backend_get_description,		/* get_description */
+	NULL,					/* get_requires */
+	backend_get_updates,			/* get_updates */
+	backend_install_package,		/* install_package */
+	backend_refresh_cache,			/* refresh_cache */
+	backend_remove_package,			/* remove_package */
+	backend_search_details,			/* search_details */
+	NULL,					/* search_file */
+	NULL,					/* search_group */
+	backend_search_name,			/* search_name */
+	NULL,					/* update_package */
+	NULL					/* update_system */
 );
 
diff --git a/backends/dummy/pk-backend-dummy.c b/backends/dummy/pk-backend-dummy.c
index 9607822..3d9fd91 100644
--- a/backends/dummy/pk-backend-dummy.c
+++ b/backends/dummy/pk-backend-dummy.c
@@ -61,7 +61,6 @@ static void
 backend_get_depends (PkBackend *backend, const gchar *package_id)
 {
 	g_return_if_fail (backend != NULL);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, package_id);
 	pk_backend_package (backend, 1, "glib2;2.14.0;i386;fedora",
 			 "The GLib library");
 	pk_backend_package (backend, 1, "gtk2;gtk2-2.11.6-6.fc8;i386;fedora",
@@ -76,7 +75,6 @@ static void
 backend_get_description (PkBackend *backend, const gchar *package_id)
 {
 	g_return_if_fail (backend != NULL);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, package_id);
 	pk_backend_description (backend, "gnome-power-manager;2.6.19;i386;fedora", PK_TASK_GROUP_PROGRAMMING,
 "Scribus is an desktop open source page layout program with "
 "the aim of producing commercial grade output in PDF and "
@@ -96,7 +94,6 @@ static void
 backend_get_requires (PkBackend *backend, const gchar *package_id)
 {
 	g_return_if_fail (backend != NULL);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, package_id);
 	pk_backend_package (backend, 1, "glib2;2.14.0;i386;fedora",
 			 "The GLib library");
 	pk_backend_package (backend, 1, "gtk2;gtk2-2.11.6-6.fc8;i386;fedora",
@@ -111,7 +108,6 @@ static void
 backend_get_updates (PkBackend *backend)
 {
 	g_return_if_fail (backend != NULL);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, NULL);
 	pk_backend_package (backend, 0, "powertop;1.8-1.fc8;i386;fedora",
 			 "Power consumption monitor");
 	pk_backend_package (backend, 1, "kernel;2.6.23-0.115.rc3.git1.fc8;i386;installed",
@@ -143,7 +139,6 @@ static void
 backend_install_package (PkBackend *backend, const gchar *package_id)
 {
 	g_return_if_fail (backend != NULL);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_PACKAGE_INSTALL, package_id);
 	progress_percentage = 0;
 	g_timeout_add (1000, backend_install_timeout, backend);
 }
@@ -155,7 +150,6 @@ static void
 backend_refresh_cache (PkBackend *backend, gboolean force)
 {
 	g_return_if_fail (backend != NULL);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_REFRESH_CACHE, NULL);
 	pk_backend_finished (backend, PK_TASK_EXIT_SUCCESS);
 }
 
@@ -166,7 +160,6 @@ static void
 backend_remove_package (PkBackend *backend, const gchar *package_id, gboolean allow_deps)
 {
 	g_return_if_fail (backend != NULL);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_PACKAGE_REMOVE, package_id);
 	pk_backend_error_code (backend, PK_TASK_ERROR_CODE_NO_NETWORK, "No network connection available");
 	pk_backend_finished (backend, PK_TASK_EXIT_FAILED);
 }
@@ -178,7 +171,6 @@ static void
 backend_search_details (PkBackend *backend, const gchar *filter, const gchar *search)
 {
 	g_return_if_fail (backend != NULL);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, search);
 	pk_backend_package (backend, 0, "vips-doc;7.12.4-2.fc8;noarch;linva",
 			 "The vips documentation package.");
 	pk_backend_finished (backend, PK_TASK_EXIT_SUCCESS);
@@ -191,7 +183,6 @@ static void
 backend_search_file (PkBackend *backend, const gchar *filter, const gchar *search)
 {
 	g_return_if_fail (backend != NULL);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, search);
 	pk_backend_package (backend, 0, "vips-doc;7.12.4-2.fc8;noarch;linva",
 			 "The vips documentation package.");
 	pk_backend_finished (backend, PK_TASK_EXIT_SUCCESS);
@@ -204,7 +195,6 @@ static void
 backend_search_group (PkBackend *backend, const gchar *filter, const gchar *search)
 {
 	g_return_if_fail (backend != NULL);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, search);
 	pk_backend_package (backend, 0, "vips-doc;7.12.4-2.fc8;noarch;linva",
 			 "The vips documentation package.");
 	pk_backend_finished (backend, PK_TASK_EXIT_SUCCESS);
@@ -236,7 +226,6 @@ static void
 backend_search_name (PkBackend *backend, const gchar *filter, const gchar *search)
 {
 	g_return_if_fail (backend != NULL);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, search);
 	pk_backend_no_percentage_updates (backend);
 	g_timeout_add (2000, backend_search_name_timeout, backend);
 }
@@ -248,7 +237,6 @@ static void
 backend_update_package (PkBackend *backend, const gchar *package_id)
 {
 	g_return_if_fail (backend != NULL);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_PACKAGE_UPDATE, package_id);
 	pk_backend_package (backend, 1, package_id, "The same thing");
 	pk_backend_finished (backend, PK_TASK_EXIT_SUCCESS);
 }
@@ -274,7 +262,6 @@ static void
 backend_update_system (PkBackend *backend)
 {
 	g_return_if_fail (backend != NULL);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_SYSTEM_UPDATE, NULL);
 	pk_backend_change_job_status (backend, PK_TASK_STATUS_DOWNLOAD);
 	progress_percentage = 0;
 	pk_backend_require_restart (backend, PK_TASK_RESTART_SYSTEM, NULL);
@@ -282,24 +269,24 @@ backend_update_system (PkBackend *backen
 }
 
 PK_BACKEND_OPTIONS (
-	"Dummy Backend",		/* description */
-	"0.0.1",			/* version */
-	"richard at hughsie.com",		/* author */
-	backend_initalize,		/* initalize */
-	backend_destroy,		/* destroy */
-	backend_cancel_job_try,		/* cancel_job_try */
-	backend_get_depends,		/* get_depends */
-	backend_get_description,	/* get_description */
-	backend_get_requires,		/* get_requires */
-	backend_get_updates,		/* get_updates */
-	backend_install_package,	/* install_package */
-	backend_refresh_cache,		/* refresh_cache */
-	backend_remove_package,		/* remove_package */
-	backend_search_details,		/* search_details */
-	backend_search_file,		/* search_file */
-	backend_search_group,		/* search_group */
-	backend_search_name,		/* search_name */
-	backend_update_package,		/* update_package */
-	backend_update_system		/* update_system */
+	"Dummy Backend",			/* description */
+	"0.0.1",				/* version */
+	"Richard Hughes <richard at hughsie.com>",	/* author */
+	backend_initalize,			/* initalize */
+	backend_destroy,			/* destroy */
+	backend_cancel_job_try,			/* cancel_job_try */
+	backend_get_depends,			/* get_depends */
+	backend_get_description,		/* get_description */
+	backend_get_requires,			/* get_requires */
+	backend_get_updates,			/* get_updates */
+	backend_install_package,		/* install_package */
+	backend_refresh_cache,			/* refresh_cache */
+	backend_remove_package,			/* remove_package */
+	backend_search_details,			/* search_details */
+	backend_search_file,			/* search_file */
+	backend_search_group,			/* search_group */
+	backend_search_name,			/* search_name */
+	backend_update_package,			/* update_package */
+	backend_update_system			/* update_system */
 );
 
diff --git a/backends/test/pk-backend-test.c b/backends/test/pk-backend-test.c
index 1d6d35b..1e67d2f 100644
--- a/backends/test/pk-backend-test.c
+++ b/backends/test/pk-backend-test.c
@@ -183,24 +183,24 @@ backend_update_system (PkBackend *backen
 }
 
 PK_BACKEND_OPTIONS (
-	"Dummy Backend",		/* description */
-	"0.0.1",			/* version */
-	"richard at hughsie.com",		/* author */
-	backend_initalize,		/* initalize */
-	backend_destroy,		/* destroy */
-	backend_cancel_job_try,		/* cancel_job_try */
-	backend_get_depends,		/* get_depends */
-	backend_get_description,	/* get_description */
-	backend_get_requires,		/* get_requires */
-	backend_get_updates,		/* get_updates */
-	backend_install_package,	/* install_package */
-	backend_refresh_cache,		/* refresh_cache */
-	backend_remove_package,		/* remove_package */
-	backend_search_details,		/* search_details */
-	backend_search_file,		/* search_file */
-	backend_search_group,		/* search_group */
-	backend_search_name,		/* search_name */
-	backend_update_package,		/* update_package */
-	backend_update_system		/* update_system */
+	"Test Backend",				/* description */
+	"0.0.1",				/* version */
+	"Richard Hughes <richard at hughsie.com>",	/* author */
+	backend_initalize,			/* initalize */
+	backend_destroy,			/* destroy */
+	backend_cancel_job_try,			/* cancel_job_try */
+	backend_get_depends,			/* get_depends */
+	backend_get_description,		/* get_description */
+	backend_get_requires,			/* get_requires */
+	backend_get_updates,			/* get_updates */
+	backend_install_package,		/* install_package */
+	backend_refresh_cache,			/* refresh_cache */
+	backend_remove_package,			/* remove_package */
+	backend_search_details,			/* search_details */
+	backend_search_file,			/* search_file */
+	backend_search_group,			/* search_group */
+	backend_search_name,			/* search_name */
+	backend_update_package,			/* update_package */
+	backend_update_system			/* update_system */
 );
 
diff --git a/backends/yum/pk-backend-yum.c b/backends/yum/pk-backend-yum.c
index fa1b396..7e95a31 100644
--- a/backends/yum/pk-backend-yum.c
+++ b/backends/yum/pk-backend-yum.c
@@ -43,7 +43,6 @@ backend_get_depends (PkBackend *backend,
 {
 	g_return_if_fail (backend != NULL);
 	pk_backend_allow_interrupt (backend, TRUE);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, package_id);
 	pk_backend_spawn_helper (backend, "get-depends.py", package_id, NULL);
 }
 
@@ -55,7 +54,6 @@ backend_get_description (PkBackend *back
 {
 	g_return_if_fail (backend != NULL);
 	pk_backend_allow_interrupt (backend, TRUE);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, package_id);
 	pk_backend_spawn_helper (backend, "get-description.py", package_id, NULL);
 }
 
@@ -67,7 +65,6 @@ backend_get_requires (PkBackend *backend
 {
 	g_return_if_fail (backend != NULL);
 	pk_backend_allow_interrupt (backend, TRUE);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, package_id);
 	pk_backend_spawn_helper (backend, "get-requires.py", package_id, NULL);
 }
 
@@ -78,7 +75,6 @@ static void
 backend_get_updates (PkBackend *backend)
 {
 	g_return_if_fail (backend != NULL);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, NULL);
 	pk_backend_spawn_helper (backend, "get-updates.py", NULL);
 }
 
@@ -95,8 +91,6 @@ backend_install_package (PkBackend *back
 		pk_backend_finished (backend, PK_TASK_EXIT_FAILED);
 		return;
 	}
-
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_PACKAGE_INSTALL, package_id);
 	pk_backend_spawn_helper (backend, "install.py", package_id, NULL);
 }
 
@@ -113,7 +107,6 @@ backend_refresh_cache (PkBackend *backen
 		pk_backend_finished (backend, PK_TASK_EXIT_FAILED);
 		return;
 	}
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_REFRESH_CACHE, NULL);
 	pk_backend_spawn_helper (backend, "refresh-cache.py", NULL);
 }
 
@@ -130,8 +123,6 @@ backend_remove_package (PkBackend *backe
 	} else {
 		deps = "no";
 	}
-
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_PACKAGE_REMOVE, package_id);
 	pk_backend_spawn_helper (backend, "remove.py", deps, package_id, NULL);
 }
 
@@ -143,23 +134,10 @@ backend_search_details (PkBackend *backe
 {
 	g_return_if_fail (backend != NULL);
 	pk_backend_allow_interrupt (backend, TRUE);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, search);
 	pk_backend_spawn_helper (backend, "search-details.py", filter, search, NULL);
 }
 
 /**
- * backend_search_file:
- */
-static void
-backend_search_file (PkBackend *backend, const gchar *filter, const gchar *search)
-{
-	g_return_if_fail (backend != NULL);
-	pk_backend_allow_interrupt (backend, TRUE);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, search);
-	pk_backend_not_implemented_yet (backend, "SearchFile");
-}
-
-/**
  * backend_search_group:
  */
 static void
@@ -167,7 +145,6 @@ backend_search_group (PkBackend *backend
 {
 	g_return_if_fail (backend != NULL);
 	pk_backend_allow_interrupt (backend, TRUE);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, search);
 	pk_backend_spawn_helper (backend, "search-group.py", filter, search, NULL);
 }
 
@@ -180,7 +157,6 @@ backend_search_name (PkBackend *backend,
 	g_return_if_fail (backend != NULL);
 	pk_backend_allow_interrupt (backend, TRUE);
 	pk_backend_no_percentage_updates (backend);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, search);
 	pk_backend_spawn_helper (backend, "search-name.py", filter, search, NULL);
 }
 
@@ -197,8 +173,6 @@ backend_update_package (PkBackend *backe
 		pk_backend_finished (backend, PK_TASK_EXIT_FAILED);
 		return;
 	}
-
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_PACKAGE_UPDATE, package_id);
 	pk_backend_spawn_helper (backend, "update.py", package_id, NULL);
 }
 
@@ -209,29 +183,28 @@ static void
 backend_update_system (PkBackend *backend)
 {
 	g_return_if_fail (backend != NULL);
-	pk_backend_set_job_role (backend, PK_TASK_ROLE_SYSTEM_UPDATE, NULL);
 	pk_backend_spawn_helper (backend, "update-system.py", NULL);
 }
 
 PK_BACKEND_OPTIONS (
-	"Dummy Backend",		/* description */
-	"0.0.1",			/* version */
-	"richard at hughsie.com",		/* author */
-	NULL,				/* initalize */
-	NULL,				/* destroy */
-	backend_cancel_job_try,		/* cancel_job_try */
-	backend_get_depends,		/* get_depends */
-	backend_get_description,	/* get_description */
-	backend_get_requires,		/* get_requires */
-	backend_get_updates,		/* get_updates */
-	backend_install_package,	/* install_package */
-	backend_refresh_cache,		/* refresh_cache */
-	backend_remove_package,		/* remove_package */
-	backend_search_details,		/* search_details */
-	backend_search_file,		/* search_file */
-	backend_search_group,		/* search_group */
-	backend_search_name,		/* search_name */
-	backend_update_package,		/* update_package */
-	backend_update_system		/* update_system */
+	"Dummy Backend",			/* description */
+	"0.0.1",				/* version */
+	"Richard Hughes <richard at hughsie.com>",	/* author */
+	NULL,					/* initalize */
+	NULL,					/* destroy */
+	backend_cancel_job_try,			/* cancel_job_try */
+	backend_get_depends,			/* get_depends */
+	backend_get_description,		/* get_description */
+	backend_get_requires,			/* get_requires */
+	backend_get_updates,			/* get_updates */
+	backend_install_package,		/* install_package */
+	backend_refresh_cache,			/* refresh_cache */
+	backend_remove_package,			/* remove_package */
+	backend_search_details,			/* search_details */
+	NULL,					/* search_file */
+	backend_search_group,			/* search_group */
+	backend_search_name,			/* search_name */
+	backend_update_package,			/* update_package */
+	backend_update_system			/* update_system */
 );
 
diff --git a/src/pk-backend-internal.h b/src/pk-backend-internal.h
index 01d8d0a..7cb9e7e 100644
--- a/src/pk-backend-internal.h
+++ b/src/pk-backend-internal.h
@@ -93,6 +93,13 @@ gboolean	 pk_backend_get_job_role		(PkBa
 							 PkTaskRole	*role,
 							 const gchar	**package_id);
 
+/* these are external in nature, but we shouldn't be using them in helpers */
+gboolean	 pk_backend_set_job_role		(PkBackend	*backend,
+							 PkTaskRole	 role,
+							 const gchar	*package_id);
+gboolean	 pk_backend_not_implemented_yet		(PkBackend	*backend,
+							 const gchar	*method);
+
 G_END_DECLS
 
 #endif /* __PK_BACKEND_INTERNAL_H */
diff --git a/src/pk-backend.c b/src/pk-backend.c
index 4ddb867..964fa76 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -665,6 +665,7 @@ pk_backend_get_depends (PkBackend *backe
 		pk_backend_not_implemented_yet (backend, "GetDepends");
 		return FALSE;
 	}
+	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, package_id);
 	backend->desc->get_depends (backend, package_id);
 	backend->priv->assigned = TRUE;
 	return TRUE;
@@ -681,6 +682,7 @@ pk_backend_get_description (PkBackend *b
 		pk_backend_not_implemented_yet (backend, "GetDescription");
 		return FALSE;
 	}
+	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, package_id);
 	backend->desc->get_description (backend, package_id);
 	backend->priv->assigned = TRUE;
 	return TRUE;
@@ -697,6 +699,7 @@ pk_backend_get_requires (PkBackend *back
 		pk_backend_not_implemented_yet (backend, "GetRequires");
 		return FALSE;
 	}
+	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, package_id);
 	backend->desc->get_requires (backend, package_id);
 	backend->priv->assigned = TRUE;
 	return TRUE;
@@ -713,6 +716,7 @@ pk_backend_get_updates (PkBackend *backe
 		pk_backend_not_implemented_yet (backend, "GetUpdates");
 		return FALSE;
 	}
+	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, NULL);
 	backend->desc->get_updates (backend);
 	backend->priv->assigned = TRUE;
 	return TRUE;
@@ -729,6 +733,7 @@ pk_backend_install_package (PkBackend *b
 		pk_backend_not_implemented_yet (backend, "InstallPackage");
 		return FALSE;
 	}
+	pk_backend_set_job_role (backend, PK_TASK_ROLE_PACKAGE_INSTALL, package_id);
 	backend->desc->install_package (backend, package_id);
 	backend->priv->assigned = TRUE;
 	return TRUE;
@@ -745,6 +750,7 @@ pk_backend_refresh_cache (PkBackend *bac
 		pk_backend_not_implemented_yet (backend, "RefreshCache");
 		return FALSE;
 	}
+	pk_backend_set_job_role (backend, PK_TASK_ROLE_REFRESH_CACHE, NULL);
 	backend->desc->refresh_cache (backend, force);
 	backend->priv->assigned = TRUE;
 	return TRUE;
@@ -761,6 +767,7 @@ pk_backend_remove_package (PkBackend *ba
 		pk_backend_not_implemented_yet (backend, "RemovePackage");
 		return FALSE;
 	}
+	pk_backend_set_job_role (backend, PK_TASK_ROLE_PACKAGE_REMOVE, package_id);
 	backend->desc->remove_package (backend, package_id, allow_deps);
 	backend->priv->assigned = TRUE;
 	return TRUE;
@@ -777,6 +784,7 @@ pk_backend_search_details (PkBackend *ba
 		pk_backend_not_implemented_yet (backend, "SearchDetails");
 		return FALSE;
 	}
+	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, search);
 	backend->desc->search_details (backend, filter, search);
 	backend->priv->assigned = TRUE;
 	return TRUE;
@@ -793,6 +801,7 @@ pk_backend_search_file (PkBackend *backe
 		pk_backend_not_implemented_yet (backend, "SearchFile");
 		return FALSE;
 	}
+	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, search);
 	backend->desc->search_file (backend, filter, search);
 	backend->priv->assigned = TRUE;
 	return TRUE;
@@ -809,6 +818,7 @@ pk_backend_search_group (PkBackend *back
 		pk_backend_not_implemented_yet (backend, "SearchGroup");
 		return FALSE;
 	}
+	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, search);
 	backend->desc->search_group (backend, filter, search);
 	backend->priv->assigned = TRUE;
 	return TRUE;
@@ -825,6 +835,7 @@ pk_backend_search_name (PkBackend *backe
 		pk_backend_not_implemented_yet (backend, "SearchName");
 		return FALSE;
 	}
+	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, search);
 	backend->desc->search_name (backend, filter, search);
 	backend->priv->assigned = TRUE;
 	return TRUE;
@@ -841,6 +852,7 @@ pk_backend_update_package (PkBackend *ba
 		pk_backend_not_implemented_yet (backend, "UpdatePackage");
 		return FALSE;
 	}
+	pk_backend_set_job_role (backend, PK_TASK_ROLE_PACKAGE_UPDATE, package_id);
 	backend->desc->update_package (backend, package_id);
 	backend->priv->assigned = TRUE;
 	return TRUE;
@@ -857,6 +869,7 @@ pk_backend_update_system (PkBackend *bac
 		pk_backend_not_implemented_yet (backend, "UpdateSystem");
 		return FALSE;
 	}
+	pk_backend_set_job_role (backend, PK_TASK_ROLE_SYSTEM_UPDATE, NULL);
 	backend->desc->update_system (backend);
 	backend->priv->assigned = TRUE;
 	return TRUE;
diff --git a/src/pk-backend.h b/src/pk-backend.h
index 5e8e5eb..7d30c33 100644
--- a/src/pk-backend.h
+++ b/src/pk-backend.h
@@ -37,9 +37,6 @@ gboolean	 pk_backend_change_sub_percenta
 							 guint		 percentage);
 gboolean	 pk_backend_change_job_status		(PkBackend	*backend,
 							 PkTaskStatus	 status);
-gboolean	 pk_backend_set_job_role		(PkBackend	*backend,
-							 PkTaskRole	 role,
-							 const gchar	*package_id);
 gboolean	 pk_backend_no_percentage_updates	(PkBackend	*backend);
 gboolean	 pk_backend_finished			(PkBackend	*backend,
 							 PkTaskExit	 exit);
@@ -61,8 +58,6 @@ gboolean	 pk_backend_error_code			(PkBac
 gboolean	 pk_backend_spawn_helper		(PkBackend	*backend,
 							 const gchar	*script, ...);
 gboolean	 pk_backend_spawn_kill			(PkBackend	*backend);
-gboolean	 pk_backend_not_implemented_yet		(PkBackend	*backend,
-							 const gchar	*method);
 gboolean	 pk_backend_allow_interrupt		(PkBackend	*backend,
 							 gboolean	 allow_restart);
 gboolean	 pk_backend_network_is_online		(PkBackend	*backend);
diff-tree baa1599f5e1c9a39c37d27b09546394bcc927bb9 (from 03a784c5ce6a77271d79146961c3bb06909ce4bf)
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu Sep 6 18:01:05 2007 +0100

    convert the box backend to the new dlopened scheme

diff --git a/backends/box/Makefile.am b/backends/box/Makefile.am
index 1e554ae..9f9d0fa 100644
--- a/backends/box/Makefile.am
+++ b/backends/box/Makefile.am
@@ -2,7 +2,8 @@ SUBDIRS = helpers
 #plugindir = @PK_PLUGIN_DIR@
 #plugin_LTLIBRARIES = libpk_backend_box.la
 #libpk_backend_box_la_SOURCES = pk-backend-box.c
-#libpk_backend_box_la_LIBADD = @PK_PLUGIN_LIBS@
+#libpk_backend_box_la_LIBADD = @PK_PLUGIN_LIBS@ $(BOX_LIBS)
 #libpk_backend_box_la_LDFLAGS = -module -avoid-version
 #libpk_backend_box_la_CFLAGS = @PK_PLUGIN_CFLAGS@
+#libpk_backend_box_la_INCLUDES = $(BOX_CFLAGS)
 
diff --git a/backends/box/pk-backend-box.c b/backends/box/pk-backend-box.c
index 183eb9e..c6c6e0d 100644
--- a/backends/box/pk-backend-box.c
+++ b/backends/box/pk-backend-box.c
@@ -1,6 +1,6 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  *
- * Copyright (C) 2007 Richard Hughes <richard at hughsie.com>
+ * Copyright (C) 2007 Grzegorz DÄ…browski <gdx at o2.pl>
  *
  * Licensed under the GNU General Public License Version 2
  *
@@ -24,6 +24,11 @@
 #include <string.h>
 #include <pk-backend.h>
 
+#include <sqlite3.h>
+#include <libbox/libbox-db.h>
+#include <libbox/libbox-db-utils.h>
+#include <libbox/libbox-db-repos.h>
+
 /**
  * backend_initalize:
  */
@@ -42,22 +47,139 @@ backend_destroy (PkBackend *backend)
 	g_return_if_fail (backend != NULL);
 }
 
-/**
- * backend_cancel_job_try:
- */
 static void
-backend_cancel_job_try (PkBackend *backend)
+add_packages_from_list (PkBackend *backend, GList *list)
 {
-	g_return_if_fail (backend != NULL);
-}
+	PackageSearch *package = NULL;
+	GList *li = NULL;
+	gchar *pkg_string = NULL;
+
+	for (li = list; li != NULL; li = li->next) {
+		package = (PackageSearch*)li->data;
+		pkg_string = pk_package_id_build(package->package, package->version, package->arch, package->reponame);
+
+		pk_backend_package (backend, package->installed, pkg_string, package->description);
+
+		g_free(pkg_string);
+	}
+}
+
+/* TODO: rewrite and share this code */
+static void
+parse_filter (const gchar *filter, gboolean *installed, gboolean *available,
+	      gboolean *devel, gboolean *nondevel, gboolean *gui, gboolean *text)
+{
+	gchar **sections = NULL;
+	gint i = 0;
+
+	*installed = TRUE;
+	*available = TRUE;
+	*devel = TRUE;
+	*nondevel = TRUE;
+	*gui = TRUE;
+	*text = TRUE;
+
+	sections = g_strsplit (filter, ";", 0);
+	while (sections[i]) {
+		if (strcmp(sections[i], "installed") == 0)
+			*available = FALSE;
+		if (strcmp(sections[i], "~installed") == 0)
+			*installed = FALSE;
+		if (strcmp(sections[i], "devel") == 0)
+			*nondevel = FALSE;
+		if (strcmp(sections[i], "~devel") == 0)
+			*devel = FALSE;
+		if (strcmp(sections[i], "gui") == 0)
+			*text = FALSE;
+		if (strcmp(sections[i], "~gui") == 0)
+			*gui = FALSE;
+		i++;
+	}
+	g_strfreev (sections);
+}
+
+static gboolean
+find_packages (PkBackend *backend, const gchar *search, const gchar *filter, gint mode)
+{
+	GList *list = NULL;
+	sqlite3 *db = NULL;
+	gint devel_filter = 0;
+	gboolean installed;
+	gboolean available;
+	gboolean devel;
+	gboolean nondevel;
+	gboolean gui;
+	gboolean text;
+
+	pk_task_set_job_role (task, PK_TASK_ROLE_QUERY, search);
+	parse_filter (filter, &installed, &available, &devel, &nondevel, &gui, &text);
+
+	if (devel == TRUE) {
+		devel_filter = devel_filter | PKG_DEVEL;
+	}
+	if (nondevel == TRUE) {
+		devel_filter = devel_filter | PKG_NON_DEVEL;
+	}
+
+	pk_backend_change_job_status (backend, PK_TASK_STATUS_QUERY);
+	pk_backend_no_percentage_updates (backend);
+
+	db = box_db_open ("/");
+	box_db_attach_repo (db, "/", "core");
+	box_db_repos_init (db);
+
+	if (mode == 1) {
+		/* TODO: allow filtering */
+		/* TODO: make it more async */
+		list = box_db_repos_search_file (db, search);
+		add_packages_from_list (backend, list);
+		box_db_repos_package_list_free (list);
+		pk_backend_finished (backend, PK_TASK_EXIT_SUCCESS);
+	} else {
+
+		if (installed == FALSE && available == FALSE) {
+			pk_backend_error_code (backend, PK_TASK_ERROR_CODE_UNKNOWN, "invalid search mode");
+			pk_backend_finished (backend, PK_TASK_EXIT_FAILED);
+		} else	{
+			/* TODO: make it more async */
+			if (installed == TRUE && available == TRUE) {
+				list = box_db_repos_packages_search_all(db, (gchar *)search, devel_filter);
+			} else if (installed == TRUE) {
+				list = box_db_repos_packages_search_installed(db, (gchar *)search, devel_filter);
+			} else if (available == TRUE) {
+				list = box_db_repos_packages_search_available(db, (gchar *)search, devel_filter);
+			}
+			add_packages_from_list (backend, list);
+			box_db_repos_package_list_free (list);
+			pk_backend_finished (backend, PK_TASK_EXIT_SUCCESS);
+		}
+	}
+
+	box_db_detach_repo(db, "core");
+	box_db_close(db);
+
+	return TRUE;
+}
+
+static GList*
+find_package_by_id (PkPackageId *pi)
+{
+	sqlite3 *db = NULL;
+	GList *list;
+
+	db = box_db_open("/");
+	box_db_attach_repo(db, "/", "core");
+	box_db_repos_init(db);
+
+	/* only one element is returned */
+	list = box_db_repos_packages_search_by_data(db, pi->name, pi->version);
+	if (list == NULL)
+		return NULL;
 
-/**
- * backend_get_depends:
- */
-static void
-backend_get_depends (PkBackend *backend, const gchar *package_id)
-{
-	g_return_if_fail (backend != NULL);
+	box_db_detach_repo(db, "core");
+	box_db_close(db);
+
+	return list;
 }
 
 /**
@@ -66,16 +188,36 @@ backend_get_depends (PkBackend *backend,
 static void
 backend_get_description (PkBackend *backend, const gchar *package_id)
 {
-	g_return_if_fail (backend != NULL);
-}
+	PkPackageId *pi;
+	PackageSearch *ps;
+	GList *list;
 
-/**
- * backend_get_requires:
- */
-static void
-backend_get_requires (PkBackend *backend, const gchar *package_id)
-{
 	g_return_if_fail (backend != NULL);
+
+	pi = pk_package_id_new_from_string (package_id);
+	if (pi == NULL) {
+		pk_backend_error_code (backend, PK_TASK_ERROR_CODE_PACKAGE_ID_INVALID, "invalid package id");
+		pk_backend_finished (backend, PK_TASK_EXIT_FAILED);
+		return;
+	}
+
+	list = find_package_by_id (pi);
+	ps = (PackageSearch*) list->data;
+	if (list == NULL) {
+		pk_backend_error_code (backend, PK_TASK_ERROR_CODE_PACKAGE_ID_INVALID, "cannot find package by id");
+		pk_backend_finished (backend, PK_TASK_EXIT_FAILED);
+		return;
+	}
+
+
+	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, package_id);
+	pk_backend_description (backend, pi->name, PK_TASK_GROUP_OTHER, ps->description, "");
+
+	pk_package_id_free (pi);
+	box_db_repos_package_list_free (list);
+
+	pk_backend_finished (backend, PK_TASK_EXIT_SUCCESS);
+	return;
 }
 
 /**
@@ -84,43 +226,44 @@ backend_get_requires (PkBackend *backend
 static void
 backend_get_updates (PkBackend *backend)
 {
-	g_return_if_fail (backend != NULL);
-}
+	GList *list = NULL;
+	sqlite3 *db = NULL;
 
-/**
- * backend_install_package:
- */
-static void
-backend_install_package (PkBackend *backend, const gchar *package_id)
-{
 	g_return_if_fail (backend != NULL);
-}
 
-/**
- * backend_refresh_cache:
- */
-static void
-backend_refresh_cache (PkBackend *backend, gboolean force)
-{
-	g_return_if_fail (backend != NULL);
-}
+	pk_backend_set_job_role (backend, PK_TASK_ROLE_QUERY, NULL);
+	pk_backend_change_job_status (backend, PK_TASK_STATUS_QUERY);
 
-/**
- * backend_remove_package:
- */
-static void
-backend_remove_package (PkBackend *backend, const gchar *package_id, gboolean allow_deps)
-{
-	g_return_if_fail (backend != NULL);
+	db = box_db_open ("/");
+	box_db_attach_repo (db, "/", "core");
+	box_db_repos_init (db);
+
+	/* TODO: make it more async */
+	list = box_db_repos_packages_for_upgrade (db);
+	add_packages_from_list (backend, list);
+	box_db_repos_package_list_free (list);
+
+	pk_backend_finished (backend, PK_TASK_EXIT_SUCCESS);
+
+	box_db_detach_repo (db, "core");
+	box_db_close (db);
 }
 
 /**
- * backend_search_details:
+ * backend_refresh_cache:
  */
 static void
-backend_search_details (PkBackend *backend, const gchar *filter, const gchar *search)
+backend_refresh_cache (PkBackend *backend, gboolean force)
 {
 	g_return_if_fail (backend != NULL);
+	/* check network state */
+	if (pk_backend_network_is_online (backend) == FALSE) {
+		pk_backend_error_code (backend, PK_TASK_ERROR_CODE_NO_NETWORK, "Cannot refresh cache whilst offline");
+		pk_backend_finished (backend, PK_TASK_EXIT_FAILED);
+		return;
+	}
+	pk_backend_set_job_role (backend, PK_TASK_ROLE_REFRESH_CACHE, NULL);
+	pk_backend_spawn_helper (backend, "refresh-cache.sh", NULL);
 }
 
 /**
@@ -130,15 +273,7 @@ static void
 backend_search_file (PkBackend *backend, const gchar *filter, const gchar *search)
 {
 	g_return_if_fail (backend != NULL);
-}
-
-/**
- * backend_search_group:
- */
-static void
-backend_search_group (PkBackend *backend, const gchar *filter, const gchar *search)
-{
-	g_return_if_fail (backend != NULL);
+	find_packages (backend, search, filter, 1);
 }
 
 /**
@@ -148,45 +283,28 @@ static void
 backend_search_name (PkBackend *backend, const gchar *filter, const gchar *search)
 {
 	g_return_if_fail (backend != NULL);
-}
-
-/**
- * backend_update_package:
- */
-static void
-backend_update_package (PkBackend *backend, const gchar *package_id)
-{
-	g_return_if_fail (backend != NULL);
-}
-
-/**
- * backend_update_system:
- */
-static void
-backend_update_system (PkBackend *backend)
-{
-	g_return_if_fail (backend != NULL);
+	find_packages (backend, search, filter, 0);
 }
 
 PK_BACKEND_OPTIONS (
-	"Dummy Backend",		/* description */
-	"0.0.1",			/* version */
-	"richard at hughsie.com",		/* author */
-	backend_initalize,		/* initalize */
-	backend_destroy,		/* destroy */
-	backend_cancel_job_try,		/* cancel_job_try */
-	backend_get_depends,		/* get_depends */
-	backend_get_description,	/* get_description */
-	backend_get_requires,		/* get_requires */
-	backend_get_updates,		/* get_updates */
-	backend_install_package,	/* install_package */
-	backend_refresh_cache,		/* refresh_cache */
-	backend_remove_package,		/* remove_package */
-	backend_search_details,		/* search_details */
-	backend_search_file,		/* search_file */
-	backend_search_group,		/* search_group */
-	backend_search_name,		/* search_name */
-	backend_update_package,		/* update_package */
-	backend_update_system		/* update_system */
+	"Dummy Backend",			/* description */
+	"0.0.1",				/* version */
+	"Grzegorz DÄ…browski <gdx at o2.pl>",	/* author */
+	backend_initalize,			/* initalize */
+	backend_destroy,			/* destroy */
+	NULL,					/* cancel_job_try */
+	NULL,					/* get_depends */
+	backend_get_description,		/* get_description */
+	NULL,					/* get_requires */
+	backend_get_updates,			/* get_updates */
+	NULL,					/* install_package */
+	backend_refresh_cache,			/* refresh_cache */
+	NULL,					/* remove_package */
+	NULL,					/* search_details */
+	backend_search_file,			/* search_file */
+	NULL,					/* search_group */
+	backend_search_name,			/* search_name */
+	NULL,					/* update_package */
+	NULL					/* update_system */
 );
 
diff-tree 03a784c5ce6a77271d79146961c3bb06909ce4bf (from 1451794d8315f447f85fa51a639c0b85effc06c5)
Author: Grzegorz Dabrowski <gdx at o2.pl>
Date:   Thu Sep 6 07:27:37 2007 +0000

    don't use map->job if map is NULL

diff --git a/src/pk-engine.c b/src/pk-engine.c
index e8ff6e9..7dd1c91 100644
--- a/src/pk-engine.c
+++ b/src/pk-engine.c
@@ -1309,7 +1309,7 @@ pk_engine_get_job_status (PkEngine *engi
 	map = pk_get_map_from_job (engine, job);
 	if (map == NULL) {
 		g_set_error (error, PK_ENGINE_ERROR, PK_ENGINE_ERROR_NO_SUCH_JOB,
-			     "No job:%i", map->job);
+			     "No job:%i", job);
 		return FALSE;
 	}
 	pk_task_get_job_status (map->task, &status_enum);
@@ -1334,7 +1334,7 @@ pk_engine_get_job_role (PkEngine *engine
 	map = pk_get_map_from_job (engine, job);
 	if (map == NULL) {
 		g_set_error (error, PK_ENGINE_ERROR, PK_ENGINE_ERROR_NO_SUCH_JOB,
-			     "No job:%i", map->job);
+			     "No job:%i", job);
 		return FALSE;
 	}
 	pk_task_get_job_role (map->task, &role_enum, package_id);
@@ -1358,7 +1358,7 @@ pk_engine_cancel_job_try (PkEngine *engi
 	map = pk_get_map_from_job (engine, job);
 	if (map == NULL) {
 		g_set_error (error, PK_ENGINE_ERROR, PK_ENGINE_ERROR_NO_SUCH_JOB,
-			     "No job:%i", map->job);
+			     "No job:%i", job);
 		return FALSE;
 	}
 



More information about the PackageKit mailing list