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

Richard Hughes hughsient at kemper.freedesktop.org
Fri Oct 9 06:11:17 PDT 2009


 backends/aptcc/apt-utils.cpp                     |    7 
 backends/aptcc/apt-utils.h                       |    6 
 backends/aptcc/apt.cpp                           |  582 ++++++++++++++---------
 backends/aptcc/apt.h                             |   33 -
 backends/aptcc/pk-backend-aptcc.cpp              |  136 ++---
 backends/zypp/pk-backend-zypp.cpp                |    8 
 contrib/command-not-found/pk-command-not-found.c |    1 
 docs/html/pk-matrix.html                         |    6 
 lib/packagekit-glib2/pk-client.c                 |   92 +++
 lib/packagekit-glib2/pk-package-sack.c           |   12 
 lib/packagekit-glib2/pk-task-text.c              |   39 -
 lib/packagekit-glib2/pk-task.c                   |   61 --
 src/pk-backend.c                                 |   16 
 src/pk-engine.c                                  |   64 ++
 src/pk-transaction.c                             |   36 -
 15 files changed, 712 insertions(+), 387 deletions(-)

New commits:
commit fc617bdc2c3f70e88e75fa0da155b9f9724b2f1f
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Oct 9 13:56:23 2009 +0100

    Ensure we print a newline if command-not-found finds exactly 0 possible results

diff --git a/contrib/command-not-found/pk-command-not-found.c b/contrib/command-not-found/pk-command-not-found.c
index da273b4..2cdbc10 100644
--- a/contrib/command-not-found/pk-command-not-found.c
+++ b/contrib/command-not-found/pk-command-not-found.c
@@ -699,6 +699,7 @@ main (int argc, char *argv[])
 	/* no possibilities */
 	if (array->len == 0) {
 		retval = EXIT_COMMAND_NOT_FOUND;
+		g_print ("\n");
 		goto out;
 	}
 
commit 3bf12653557f1fa2735d4c83bd94eb8de227d43e
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Oct 9 10:05:34 2009 +0100

    glib2: add an 'idle' parameter to PkClient to show when all pending transactions have finished

diff --git a/lib/packagekit-glib2/pk-client.c b/lib/packagekit-glib2/pk-client.c
index d340fd5..22cb860 100644
--- a/lib/packagekit-glib2/pk-client.c
+++ b/lib/packagekit-glib2/pk-client.c
@@ -66,6 +66,7 @@ struct _PkClientPrivate
 	gchar			*locale;
 	gboolean		 background;
 	gboolean		 interactive;
+	gboolean		 idle;
 };
 
 enum {
@@ -73,6 +74,7 @@ enum {
 	PROP_LOCALE,
 	PROP_BACKGROUND,
 	PROP_INTERACTIVE,
+	PROP_IDLE,
 	PROP_LAST
 };
 
@@ -155,6 +157,9 @@ pk_client_get_property (GObject *object, guint prop_id, GValue *value, GParamSpe
 	case PROP_INTERACTIVE:
 		g_value_set_boolean (value, priv->interactive);
 		break;
+	case PROP_IDLE:
+		g_value_set_boolean (value, priv->idle);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -544,6 +549,43 @@ pk_client_cancellable_cancel_cb (GCancellable *cancellable, PkClientState *state
 }
 
 /**
+ * pk_client_state_remove:
+ **/
+static void
+pk_client_state_remove (PkClient *client, PkClientState *state)
+{
+	gboolean is_idle;
+	g_ptr_array_remove (client->priv->calls, state);
+	egg_debug ("state array remove %p", state);
+
+	/* has the idle state changed? */
+	is_idle = (client->priv->calls->len == 0);
+	if (is_idle != client->priv->idle) {
+		client->priv->idle = is_idle;
+		g_object_notify (G_OBJECT(client), "idle");
+	}
+}
+
+/**
+ * pk_client_state_add:
+ **/
+static void
+pk_client_state_add (PkClient *client, PkClientState *state)
+{
+	gboolean is_idle;
+
+	g_ptr_array_add (client->priv->calls, state);
+	egg_debug ("state array add %p", state);
+
+	/* has the idle state changed? */
+	is_idle = (client->priv->calls->len == 0);
+	if (is_idle != client->priv->idle) {
+		client->priv->idle = is_idle;
+		g_object_notify (G_OBJECT(client), "idle");
+	}
+}
+
+/**
  * pk_client_state_finish:
  **/
 static void
@@ -578,8 +620,7 @@ pk_client_state_finish (PkClientState *state, const GError *error)
 	}
 
 	/* remove from list */
-	g_ptr_array_remove (priv->calls, state);
-	egg_debug ("state array remove %p", state);
+	pk_client_state_remove (state->client, state);
 
 	/* complete */
 	g_simple_async_result_complete_in_idle (state->res);
@@ -3479,8 +3520,7 @@ pk_client_adopt_async (PkClient *client, const gchar *transaction_id, GCancellab
 		      NULL);
 
 	/* track state */
-	g_ptr_array_add (client->priv->calls, state);
-	egg_debug ("state array add %p", state);
+	pk_client_state_add (client, state);
 
 	g_object_unref (res);
 }
@@ -3543,8 +3583,7 @@ pk_client_get_progress_state_finish (PkClientState *state, GError *error)
 	}
 
 	/* remove from list */
-	g_ptr_array_remove (priv->calls, state);
-	egg_debug ("state array remove %p", state);
+	pk_client_state_remove (state->client, state);
 
 	/* complete */
 	g_simple_async_result_complete_in_idle (state->res);
@@ -3652,8 +3691,7 @@ pk_client_get_progress_async (PkClient *client, const gchar *transaction_id, GCa
 	egg_debug ("getting progress on %s, started DBus call: %p", state->tid, state->call);
 
 	/* track state */
-	g_ptr_array_add (client->priv->calls, state);
-	egg_debug ("state array add %p", state);
+	pk_client_state_add (client, state);
 
 	g_object_unref (res);
 }
@@ -3719,6 +3757,14 @@ pk_client_class_init (PkClientClass *klass)
 				      G_PARAM_READWRITE);
 	g_object_class_install_property (object_class, PROP_INTERACTIVE, pspec);
 
+	/**
+	 * PkClient:idle:
+	 */
+	pspec = g_param_spec_boolean ("idle", NULL, "if there are no transactions in progress on this client",
+				      TRUE,
+				      G_PARAM_READABLE);
+	g_object_class_install_property (object_class, PROP_IDLE, pspec);
+
 	g_type_class_add_private (klass, sizeof (PkClientPrivate));
 }
 
@@ -3733,6 +3779,7 @@ pk_client_init (PkClient *client)
 	client->priv->calls = g_ptr_array_new ();
 	client->priv->background = FALSE;
 	client->priv->interactive = TRUE;
+	client->priv->idle = TRUE;
 
 	/* check dbus connections, exit if not valid */
 	client->priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
@@ -3866,6 +3913,7 @@ pk_client_test_resolve_cb (GObject *object, GAsyncResult *res, EggTest *test)
 	GPtrArray *packages;
 	const PkItemPackage *item;
 	guint i;
+	gboolean idle;
 
 	/* get the results */
 	results = pk_client_generic_finish (client, res, &error);
@@ -3883,6 +3931,11 @@ pk_client_test_resolve_cb (GObject *object, GAsyncResult *res, EggTest *test)
 	if (packages == NULL)
 		egg_test_failed (test, "no packages!");
 
+	/* check idle */
+	g_object_get (client, "idle", &idle, NULL);
+	if (!idle)
+		egg_test_failed (test, "not idle in finished handler");
+
 	/* list, just for shits and giggles */
 	for (i=0; i<packages->len; i++) {
 		item = g_ptr_array_index (packages, i);
@@ -4110,6 +4163,17 @@ pk_client_test_recursive_signal_cb (PkControl *control, EggTest *test)
 		egg_test_failed (test, "could not get properties sync");
 }
 
+/**
+ * pk_client_test_notify_idle_cb:
+ **/
+static void
+pk_client_test_notify_idle_cb (PkClient *client, GParamSpec *pspec, EggTest *test)
+{
+	gboolean idle;
+	g_object_get (client, "idle", &idle, NULL);
+	egg_debug ("idle=%i", idle);
+}
+
 void
 pk_client_test (gpointer user_data)
 {
@@ -4178,9 +4242,16 @@ pk_client_test (gpointer user_data)
 	/************************************************************/
 	egg_test_title (test, "get client");
 	client = pk_client_new ();
+	g_signal_connect (client, "notify::idle",
+			  G_CALLBACK (pk_client_test_notify_idle_cb), test);
 	egg_test_assert (test, client != NULL);
 
 	/************************************************************/
+	egg_test_title (test, "check idle");
+	g_object_get (client, "idle", &ret, NULL);
+	egg_test_assert (test, ret);
+
+	/************************************************************/
 	egg_test_title (test, "resolve package");
 	package_ids = pk_package_ids_from_text ("glib2;2.14.0;i386;fedora&powertop");
 	pk_client_resolve_async (client, pk_bitfield_value (PK_FILTER_ENUM_INSTALLED), package_ids, NULL,
@@ -4191,6 +4262,11 @@ pk_client_test (gpointer user_data)
 	egg_test_success (test, "resolved in %i", egg_test_elapsed (test));
 
 	/************************************************************/
+	egg_test_title (test, "check idle");
+	g_object_get (client, "idle", &ret, NULL);
+	egg_test_assert (test, ret);
+
+	/************************************************************/
 	egg_test_title (test, "get progress of past transaction");
 	progress = pk_client_get_progress (client, _tid, NULL, &error);
 	g_object_get (progress,
commit fcc1d4bec72b05e1eb7a17393e7398bf6d372888
Merge: f530062... 164388b...
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu Oct 8 22:21:17 2009 +0100

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

commit f530062f60a9fd81997925a990598afec4571394
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu Oct 8 22:20:50 2009 +0100

    Don't prompt for the authentication dialog when we set the proxy to the same as it was before
    
    This only happens on locked down workstations, not from upstream policy.

diff --git a/src/pk-engine.c b/src/pk-engine.c
index b6c0382..2050902 100644
--- a/src/pk-engine.c
+++ b/src/pk-engine.c
@@ -687,6 +687,48 @@ out:
 #endif
 
 /**
+ * pk_engine_is_proxy_unchanged:
+ **/
+static gboolean
+pk_engine_is_proxy_unchanged (PkEngine *engine, const gchar *proxy_http, const gchar *proxy_ftp)
+{
+	guint uid;
+	gboolean ret = FALSE;
+	gchar *session = NULL;
+	gchar *proxy_http_tmp = NULL;
+	gchar *proxy_ftp_tmp = NULL;
+
+	/* get uid */
+	uid = pk_dbus_get_uid (engine->priv->dbus, engine->priv->sender);
+	if (uid == G_MAXUINT) {
+		egg_warning ("failed to get the uid for %s", engine->priv->sender);
+		goto out;
+	}
+
+	/* get session */
+	session = pk_dbus_get_session (engine->priv->dbus, engine->priv->sender);
+	if (session == NULL) {
+		egg_warning ("failed to get the session for %s", engine->priv->sender);
+		goto out;
+	}
+
+	/* find out if they are the same as what we tried to set before */
+	ret = pk_transaction_db_get_proxy (engine->priv->transaction_db, uid, session, &proxy_http_tmp, &proxy_ftp_tmp);
+	if (!ret)
+		goto out;
+
+	/* are different? */
+	if (g_strcmp0 (proxy_http_tmp, proxy_http) != 0 ||
+	    g_strcmp0 (proxy_ftp_tmp, proxy_ftp) != 0)
+		ret = FALSE;
+out:
+	g_free (session);
+	g_free (proxy_http_tmp);
+	g_free (proxy_ftp_tmp);
+	return ret;
+}
+
+/**
  * pk_engine_set_proxy:
  **/
 void
@@ -694,12 +736,10 @@ pk_engine_set_proxy (PkEngine *engine, const gchar *proxy_http, const gchar *pro
 {
 	guint len;
 	GError *error = NULL;
+	gboolean ret;
 #ifdef USE_SECURITY_POLKIT
-	gchar *sender = NULL;
 	PolkitSubject *subject;
 	PolkitDetails *details;
-#else
-	gboolean ret;
 #endif
 	g_return_if_fail (PK_IS_ENGINE (engine));
 
@@ -727,20 +767,29 @@ pk_engine_set_proxy (PkEngine *engine, const gchar *proxy_http, const gchar *pro
 		return;
 	}
 
+	/* save sender */
+	g_free (engine->priv->sender);
+	engine->priv->sender = dbus_g_method_get_sender (context);
+
+	/* is exactly the same proxy? */
+	ret = pk_engine_is_proxy_unchanged (engine, proxy_http, proxy_ftp);
+	if (ret) {
+		egg_debug ("not changing proxy as the same as before");
+		dbus_g_method_return (context);
+		return;
+	}
+
 	/* save these so we can set them after the auth success */
 	g_free (engine->priv->proxy_http);
 	g_free (engine->priv->proxy_ftp);
-	g_free (engine->priv->sender);
 	engine->priv->proxy_http = g_strdup (proxy_http);
 	engine->priv->proxy_ftp = g_strdup (proxy_ftp);
-	engine->priv->sender = dbus_g_method_get_sender (context);
 	egg_debug ("changing http proxy to %s for %s", proxy_http, engine->priv->sender);
 	egg_debug ("changing ftp proxy to %s for %s", proxy_ftp, engine->priv->sender);
 
 #ifdef USE_SECURITY_POLKIT
 	/* check subject */
-	sender = dbus_g_method_get_sender (context);
-	subject = polkit_system_bus_name_new (sender);
+	subject = polkit_system_bus_name_new (engine->priv->sender);
 
 	/* insert details about the authorization */
 	details = polkit_details_new ();
@@ -776,7 +825,6 @@ pk_engine_set_proxy (PkEngine *engine, const gchar *proxy_http, const gchar *pro
 
 #ifdef USE_SECURITY_POLKIT
 	g_object_unref (subject);
-	g_free (sender);
 #endif
 }
 
commit 164388b8ef9b3fc6b7acd5563182f987bf510e9f
Author: Scott Reeves <sreeves at novell.com>
Date:   Thu Oct 8 11:11:42 2009 -0600

    zypp: add support for get_mime_types

diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp
index 386beed..3d8af63 100644
--- a/backends/zypp/pk-backend-zypp.cpp
+++ b/backends/zypp/pk-backend-zypp.cpp
@@ -1850,6 +1850,12 @@ backend_what_provides (PkBackend *backend, PkBitfield filters, PkProvidesEnum pr
 	pk_backend_thread_create (backend, backend_what_provides_thread);
 }
 
+static gchar *
+backend_get_mime_types (PkBackend *backend)
+{
+	return g_strdup ("application/x-rpm");
+}
+
 extern "C" PK_BACKEND_OPTIONS (
 	"Zypp",					/* description */
 	"Boyd Timothy <btimothy at gmail.com>, "
@@ -1859,7 +1865,7 @@ extern "C" PK_BACKEND_OPTIONS (
 	backend_destroy,			/* destroy */
 	backend_get_groups,			/* get_groups */
 	backend_get_filters,			/* get_filters */
-	NULL,					/* get_mime_types */
+	backend_get_mime_types,			/* get_mime_types */
 	NULL,					/* cancel */
 	NULL,					/* download_packages */
 	NULL,					/* get_categories */
commit 1f2e0555384319b421ed5679f6505d72d6ca64d4
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 7 13:26:33 2009 +0100

    glib2: remove all the finished packages before we pass the result to a simulate handler

diff --git a/lib/packagekit-glib2/pk-task.c b/lib/packagekit-glib2/pk-task.c
index 95cfbb6..2c49610 100644
--- a/lib/packagekit-glib2/pk-task.c
+++ b/lib/packagekit-glib2/pk-task.c
@@ -206,15 +206,13 @@ pk_task_simulate_ready_cb (GObject *source_object, GAsyncResult *res, PkTaskStat
 	GError *error = NULL;
 	PkResults *results;
 	PkPackageSack *sack = NULL;
-	PkPackage *package;
-	PkInfoEnum info;
 	guint length;
 	PkItemErrorCode *error_code;
+	guint idx = 0;
 	guint i;
-	guint j;
-	const gchar *package_id;
 	GPtrArray *array = NULL;
 	PkItemPackage *item;
+	gboolean ret;
 
 	/* old results no longer valid */
 	if (state->results != NULL)
@@ -256,54 +254,43 @@ pk_task_simulate_ready_cb (GObject *source_object, GAsyncResult *res, PkTaskStat
 	/* get data */
 	sack = pk_results_get_package_sack (results);
 
-	/* remove some results */
+	/* remove all the original packages from the sack */
 	length = g_strv_length (state->package_ids);
-	for (i=0; i<pk_package_sack_get_size (sack); i++) {
-		package = pk_package_sack_get_index (sack, i);
+	for (i=0; i<length; i++)
+		pk_package_sack_remove_package_by_id (sack, state->package_ids[i]);
 
-		/* get package details */
-		package_id = pk_package_get_id (package);
-		g_object_get (package,
-			      "info", &info,
-			      NULL);
-
-		/* remove all the PK_ENUM_INFO_CLEANUP packages */
-		if (info == PK_INFO_ENUM_CLEANUP) {
-			pk_package_sack_remove_package (sack, package);
-			continue;
-		}
-
-		/* remove all the original packages */
-		for (j=0; j<length; j++) {
-			if (g_strcmp0 (package_id, state->package_ids[j]) == 0) {
-				pk_package_sack_remove_package (sack, package);
-				break;
-			}
-		}
-	}
-
-	/* do the same for the raw array */
+	/* remove packages from the array that will not be useful */
 	array = pk_results_get_package_array (results);
-	for (i=0; i<array->len; i++) {
-		item = g_ptr_array_index (array, i);
+	while (idx < array->len) {
+		item = g_ptr_array_index (array, idx);
 
-		/* remove all the PK_ENUM_INFO_CLEANUP packages */
-		if (item->info == PK_INFO_ENUM_CLEANUP) {
+		/* remove all the cleanup and finished packages */
+		if (item->info == PK_INFO_ENUM_CLEANUP ||
+		    item->info == PK_INFO_ENUM_FINISHED) {
+			egg_debug ("removing %s", item->package_id);
 			g_ptr_array_remove (array, item);
 			continue;
 		}
+
 		/* remove all the original packages */
-		for (j=0; j<length; j++) {
-			if (g_strcmp0 (item->package_id, state->package_ids[j]) == 0) {
+		ret = FALSE;
+		for (i=0; i<length; i++) {
+			if (g_strcmp0 (item->package_id, state->package_ids[i]) == 0) {
+				egg_debug ("removing %s", item->package_id);
 				g_ptr_array_remove (array, item);
+				ret = TRUE;
 				break;
 			}
 		}
+		if (ret)
+			continue;
+
+		/* no removal done */
+		idx++;
 	}
 
 	/* no results from simulate */
-	length = pk_package_sack_get_size (sack);
-	if (length == 0) {
+	if (array->len == 0) {
 		pk_task_do_async_action (state);
 		goto out;
 	}
commit 4fae430876e1efacee74521f8affb729bd514fa7
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 7 13:25:02 2009 +0100

    trivial: switch Pktasktext away from a PkPackageSack, it doesn't actually need it

diff --git a/lib/packagekit-glib2/pk-task-text.c b/lib/packagekit-glib2/pk-task-text.c
index b9e47d3..c779986 100644
--- a/lib/packagekit-glib2/pk-task-text.c
+++ b/lib/packagekit-glib2/pk-task-text.c
@@ -285,15 +285,11 @@ static void
 pk_task_text_simulate_question (PkTask *task, guint request, PkResults *results)
 {
 	guint i;
-	guint len;
 	gboolean ret;
-	const gchar *package_id;
 	const gchar *title;
 	gchar *printable;
-	gchar *summary;
-	PkPackage *package;
-	PkPackageSack *sack;
-	PkInfoEnum info;
+	PkItemPackage *item;
+	GPtrArray *array;
 	PkInfoEnum info_last = PK_INFO_ENUM_UNKNOWN;
 	PkTaskTextPrivate *priv = PK_TASK_TEXT(task)->priv;
 
@@ -304,33 +300,24 @@ pk_task_text_simulate_question (PkTask *task, guint request, PkResults *results)
 	g_print ("\n");
 
 	/* get data */
-	sack = pk_results_get_package_sack (results);
+	array = pk_results_get_package_array (results);
 
 	/* print data */
-	len = pk_package_sack_get_size (sack);
-	for (i=0; i<len; i++) {
-		package = pk_package_sack_get_index (sack, i);
-		g_object_get (package,
-			      "info", &info,
-			      "summary", &summary,
-			      NULL);
+	for (i=0; i<array->len; i++) {
+		item = g_ptr_array_index (array, i);
 		/* new header */
-		if (info != info_last) {
-			title = pk_task_text_simulate_question_type_to_text (info);
+		if (item->info != info_last) {
+			title = pk_task_text_simulate_question_type_to_text (item->info);
 			if (title == NULL) {
-				title = pk_info_enum_to_text (info);
+				title = pk_info_enum_to_text (item->info);
 				egg_warning ("cannot translate '%s', please report!", title);
 			}
 			g_print ("%s\n", title);
-			info_last = info;
+			info_last = item->info;
 		}
-		package_id = pk_package_get_id (package);
-		printable = pk_package_id_to_printable (package_id);
-		g_print (" %s\t%s\n", printable, summary);
-
-		g_free (summary);
+		printable = pk_package_id_to_printable (item->package_id);
+		g_print (" %s\t%s\n", printable, item->summary);
 		g_free (printable);
-		g_object_unref (package);
 	}
 
 	/* TRANSLATORS: ask the user if the proposed changes are okay */
@@ -343,7 +330,7 @@ pk_task_text_simulate_question (PkTask *task, guint request, PkResults *results)
 		pk_task_user_declined (task, request);
 	}
 
-	g_object_unref (sack);
+	g_ptr_array_unref (array);
 }
 
 /**
commit 94073f8cc4d82f690addd41850148e10695fa9e9
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 7 13:15:01 2009 +0100

    bugfix: ensure we emulate FINISHED correctly for non-simultanous backends

diff --git a/src/pk-backend.c b/src/pk-backend.c
index 19ca698..f28dcbd 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -835,20 +835,28 @@ static gboolean
 pk_backend_package_emulate_finished_for_package (PkBackend *backend, const PkItemPackage *item)
 {
 	/* simultaneous handles this on it's own */
-	if (backend->priv->simultaneous)
+	if (backend->priv->simultaneous) {
+		egg_debug ("backend handling finished");
 		return FALSE;
+	}
 
 	/* first package in transaction */
-	if (backend->priv->last_package == NULL)
+	if (backend->priv->last_package == NULL) {
+		egg_debug ("first package, so no finished");
 		return FALSE;
+	}
 
 	/* sending finished already */
-	if (item->info == PK_INFO_ENUM_FINISHED)
+	if (item->info == PK_INFO_ENUM_FINISHED) {
+		egg_debug ("is finished ourelves");
 		return FALSE;
+	}
 
 	/* same package, just info change */
-	if (g_strcmp0 (backend->priv->last_package->package_id, item->package_id))
+	if (g_strcmp0 (backend->priv->last_package->package_id, item->package_id) == 0) {
+		egg_debug ("same package_id, ignoring");
 		return FALSE;
+	}
 
 	/* emit the old package as finished */
 	return pk_backend_package_emulate_finished (backend);
commit 4c3744256c17b05624915bf9b6c866b4b7deb671
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 7 13:13:27 2009 +0100

    trivial: speed optimisation in pk_package_sack_remove_package_by_id()

diff --git a/lib/packagekit-glib2/pk-package-sack.c b/lib/packagekit-glib2/pk-package-sack.c
index 28e8438..b438fa8 100644
--- a/lib/packagekit-glib2/pk-package-sack.c
+++ b/lib/packagekit-glib2/pk-package-sack.c
@@ -230,7 +230,7 @@ pk_package_sack_remove_package (PkPackageSack *sack, PkPackage *package)
  * Removes a package reference from the sack. As soon as one package is removed
  * the search is stopped.
  *
- * Return value: %TRUE if the package was removed to the sack
+ * Return value: %TRUE if the package was removed from the sack
  **/
 gboolean
 pk_package_sack_remove_package_by_id (PkPackageSack *sack, const gchar *package_id)
@@ -239,17 +239,17 @@ pk_package_sack_remove_package_by_id (PkPackageSack *sack, const gchar *package_
 	const gchar *id;
 	gboolean ret = FALSE;
 	guint i;
-	guint len;
+	GPtrArray *array;
 
 	g_return_val_if_fail (PK_IS_PACKAGE_SACK (sack), FALSE);
 	g_return_val_if_fail (package_id != NULL, FALSE);
 
-	len = sack->priv->array->len;
-	for (i=0; i<len; i++) {
-		package = g_ptr_array_index (sack->priv->array, i);
+	array = sack->priv->array;
+	for (i=0; i<array->len; i++) {
+		package = g_ptr_array_index (array, i);
 		id = pk_package_get_id (package);
 		if (g_strcmp0 (package_id, id) == 0) {
-			g_ptr_array_remove_index (sack->priv->array, i);
+			g_ptr_array_remove_index (array, i);
 			ret = TRUE;
 			break;
 		}
commit 53dc70cf3eb7503ddd886b7932ba38f66f184a7f
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 7 13:11:34 2009 +0100

    trivial: avoid printing '(NULL)' in client tools when we can't translate the info enum

diff --git a/lib/packagekit-glib2/pk-task-text.c b/lib/packagekit-glib2/pk-task-text.c
index 9ae463f..b9e47d3 100644
--- a/lib/packagekit-glib2/pk-task-text.c
+++ b/lib/packagekit-glib2/pk-task-text.c
@@ -317,6 +317,10 @@ pk_task_text_simulate_question (PkTask *task, guint request, PkResults *results)
 		/* new header */
 		if (info != info_last) {
 			title = pk_task_text_simulate_question_type_to_text (info);
+			if (title == NULL) {
+				title = pk_info_enum_to_text (info);
+				egg_warning ("cannot translate '%s', please report!", title);
+			}
 			g_print ("%s\n", title);
 			info_last = info;
 		}
commit b533608b4b9d85f835648d1312d07888a9981086
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 7 11:04:13 2009 +0100

    When cancelling, don't check the UID if the sender matches
    
    CHecking the UID takes some time as we have to poke ConsoleKit, and by
    then the process may have already exited.

diff --git a/src/pk-transaction.c b/src/pk-transaction.c
index e9443d0..53ed81c 100644
--- a/src/pk-transaction.c
+++ b/src/pk-transaction.c
@@ -2238,7 +2238,7 @@ pk_transaction_cancel (PkTransaction *transaction, DBusGMethodInvocation *contex
 {
 	gboolean ret;
 	GError *error = NULL;
-	gchar *sender;
+	gchar *sender = NULL;
 	guint uid;
 
 	g_return_if_fail (PK_IS_TRANSACTION (transaction));
@@ -2251,12 +2251,15 @@ pk_transaction_cancel (PkTransaction *transaction, DBusGMethodInvocation *contex
 		error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_NOT_SUPPORTED,
 				     "Cancel not yet supported by backend");
 		pk_transaction_dbus_return_error (context, error);
-		return;
+		goto out;
 	}
 
 	/* if it's finished, cancelling will have no action regardless of uid */
 	if (transaction->priv->finished) {
 		egg_debug ("No point trying to cancel a finished transaction, ignoring");
+
+		/* return from async with success */
+		pk_transaction_dbus_return (context);
 		goto out;
 	}
 
@@ -2264,7 +2267,7 @@ pk_transaction_cancel (PkTransaction *transaction, DBusGMethodInvocation *contex
 	if (transaction->priv->role == PK_ROLE_ENUM_UNKNOWN) {
 		error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_NO_ROLE, "No role");
 		pk_transaction_dbus_return_error (context, error);
-		return;
+		goto out;
 	}
 
 	/* check if it's safe to kill */
@@ -2274,7 +2277,15 @@ pk_transaction_cancel (PkTransaction *transaction, DBusGMethodInvocation *contex
 				     transaction->priv->tid,
 				     pk_role_enum_to_text (transaction->priv->role));
 		pk_transaction_dbus_return_error (context, error);
-		return;
+		goto out;
+	}
+
+	/* first, check the sender -- if it's the same we don't need to check the uid */
+	sender = dbus_g_method_get_sender (context);
+	ret = (g_strcmp0 (transaction->priv->sender, sender) == 0);
+	if (ret) {
+		egg_debug ("same sender, no need to check uid");
+		goto skip_uid;
 	}
 
 	/* check if we saved the uid */
@@ -2282,19 +2293,15 @@ pk_transaction_cancel (PkTransaction *transaction, DBusGMethodInvocation *contex
 		error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_CANNOT_CANCEL,
 				     "No context from caller to get UID from");
 		pk_transaction_dbus_return_error (context, error);
-		return;
+		goto out;
 	}
 
 	/* get the UID of the caller */
-	sender = dbus_g_method_get_sender (context);
 	uid = pk_dbus_get_uid (transaction->priv->dbus, sender);
-	g_free (sender);
-
-	/* check we got a valid value */
 	if (uid == PK_TRANSACTION_UID_INVALID) {
 		error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_INVALID_STATE, "unable to get uid of caller");
 		pk_transaction_dbus_return_error (context, error);
-		return;
+		goto out;
 	}
 
 	/* check the caller uid with the originator uid */
@@ -2303,10 +2310,11 @@ pk_transaction_cancel (PkTransaction *transaction, DBusGMethodInvocation *contex
 		ret = pk_transaction_obtain_authorization (transaction, FALSE, PK_ROLE_ENUM_CANCEL, &error);
 		if (!ret) {
 			pk_transaction_dbus_return_error (context, error);
-			return;
+			goto out;
 		}
 	}
 
+skip_uid:
 	/* if it's never been run, just remove this transaction from the list */
 	if (!transaction->priv->has_been_run) {
 		pk_transaction_progress_changed_emit (transaction, 100, 100, 0, 0);
@@ -2314,6 +2322,9 @@ pk_transaction_cancel (PkTransaction *transaction, DBusGMethodInvocation *contex
 		pk_transaction_status_changed_emit (transaction, PK_STATUS_ENUM_FINISHED);
 		pk_transaction_finished_emit (transaction, PK_EXIT_ENUM_CANCELLED, 0);
 		pk_transaction_release_tid (transaction);
+
+		/* return from async with success */
+		pk_transaction_dbus_return (context);
 		goto out;
 	}
 
@@ -2329,9 +2340,10 @@ pk_transaction_cancel (PkTransaction *transaction, DBusGMethodInvocation *contex
 	/* actually run the method */
 	pk_backend_cancel (transaction->priv->backend);
 
-out:
 	/* return from async with success */
 	pk_transaction_dbus_return (context);
+out:
+	g_free (sender);
 }
 
 /**
commit e34fd25c7bb10d630b9a1bb56e667927e56cd3af
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Oct 7 11:02:56 2009 +0100

    Revert "bugfix: allow Cancel() to work with pkcon when ctrl-c'd by introducing a small delay"
    
    This reverts commit 9b4d996ee98b2d9fe3d94f1b33b9e5f91d1d9682.

diff --git a/client/pk-console.c b/client/pk-console.c
index ec288ea..01dd2ec 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -840,18 +840,6 @@ pk_console_notify_connected_cb (PkControl *control_, GParamSpec *pspec, gpointer
 }
 
 /**
- * pk_console_sigint_idle_cb:
- **/
-static gboolean
-pk_console_sigint_idle_cb (gpointer user_data)
-{
-	/* kill ourselves */
-	egg_debug ("Retrying SIGINT");
-	kill (getpid (), SIGINT);
-	return FALSE;
-}
-
-/**
  * pk_console_sigint_cb:
  **/
 static void
@@ -865,8 +853,9 @@ pk_console_sigint_cb (int sig)
 	/* cancel any tasks still running */
 	g_cancellable_cancel (cancellable);
 
-	/* wait for packagekitd to cancel by waiting 100ms */
-	g_timeout_add (100, (GSourceFunc) pk_console_sigint_idle_cb, NULL);
+	/* kill ourselves */
+	egg_debug ("Retrying SIGINT");
+	kill (getpid (), SIGINT);
 }
 
 /**
commit f3ab55bddd4a9d8313bec242f2bf31be0cb07c53
Author: Daniel Nicoletti <dantti85-pk at yahoo.com.br>
Date:   Tue Oct 6 18:08:35 2009 -0300

    aptcc: Added install/remove/update support in non-interactive mode

diff --git a/backends/aptcc/apt-utils.cpp b/backends/aptcc/apt-utils.cpp
index 84a1d19..245ab96 100644
--- a/backends/aptcc/apt-utils.cpp
+++ b/backends/aptcc/apt-utils.cpp
@@ -313,3 +313,10 @@ bool ends_with (const string &str, const char *end)
 	size_t endSize = strlen(end);
 	return str.size() >= endSize && (memcmp(str.data() + str.size() - endSize, end, endSize) == 0);
 }
+
+bool starts_with (const string &str, const char *start)
+{
+	size_t startSize = strlen(start);
+	return str.size() >= startSize && (strncmp(str.data(), start, startSize) == 0);
+}
+
diff --git a/backends/aptcc/apt-utils.h b/backends/aptcc/apt-utils.h
index 869a4d7..be5a408 100644
--- a/backends/aptcc/apt-utils.h
+++ b/backends/aptcc/apt-utils.h
@@ -25,7 +25,6 @@
 
 #include <apt-pkg/pkgrecords.h>
 
-#include <packagekit-glib2/packagekit.h>
 #include <pk-backend.h>
 
 #include <string.h>
@@ -133,4 +132,9 @@ bool contains(vector<pair<pkgCache::PkgIterator, pkgCache::VerIterator> > packag
   */
 bool ends_with(const string &str, const char *end);
 
+/**
+  * Return if the given string starts with the other
+  */
+bool starts_with(const string &str, const char *end);
+
 #endif
diff --git a/backends/aptcc/apt.cpp b/backends/aptcc/apt.cpp
index a573d3f..d0a6def 100644
--- a/backends/aptcc/apt.cpp
+++ b/backends/aptcc/apt.cpp
@@ -24,6 +24,7 @@
 #include "aptcc_show_broken.h"
 #include "acqprogress.h"
 #include "pkg_acqfile.h"
+#include "aptcc_show_error.h"
 
 #include <apt-pkg/error.h>
 #include <apt-pkg/tagfile.h>
@@ -33,23 +34,27 @@
 #include <apt-pkg/sptr.h>
 #include <sys/statvfs.h>
 #include <sys/statfs.h>
+#include <sys/wait.h>
+#include <sys/fcntl.h>
+
 #define RAMFS_MAGIC     0x858458f6
 
 #include <fstream>
 #include <dirent.h>
 #include <assert.h>
 
-aptcc::aptcc(PkBackend *backend, bool &cancel, pkgSourceList &apt_source_list)
+aptcc::aptcc(PkBackend *backend, bool &cancel)
 	:
 	packageRecords(0),
 	packageCache(0),
 	packageDepCache(0),
+	packageSourceList(0),
 	Map(0),
 	Policy(0),
 	m_backend(backend),
-	_cancel(cancel),
-	m_pkgSourceList(apt_source_list)
+	_cancel(cancel)
 {
+	_cancel = false;
 }
 
 bool aptcc::init()
@@ -58,6 +63,9 @@ bool aptcc::init()
 	gchar *proxy_http;
 	gchar *proxy_ftp;
 
+	// Set PackageKit status
+	pk_backend_set_status(m_backend, PK_STATUS_ENUM_LOADING_CACHE);
+
 	// set locale
 	if (locale = pk_backend_get_locale(m_backend)) {
 		setlocale(LC_ALL, locale);
@@ -72,15 +80,23 @@ bool aptcc::init()
 	// set http proxy
 	if (proxy_http = pk_backend_get_proxy_http(m_backend)) {
 		_config->Set("Acquire::http::Proxy", proxy_http);
+	} else {
+		_config->Set("Acquire::http::Proxy", "");
 	}
 
 	// set ftp proxy
 	if (proxy_ftp = pk_backend_get_proxy_ftp(m_backend)) {
 		_config->Set("Acquire::ftp::Proxy", proxy_ftp);
+	} else {
+		_config->Set("Acquire::ftp::Proxy", "");
 	}
 
+	packageSourceList = new pkgSourceList;
+	// Read the source list
+	packageSourceList->ReadMainList();
+
 	// Generate it and map it
-	bool Res = pkgMakeStatusCache(m_pkgSourceList, Progress, &Map, true);
+	bool Res = pkgMakeStatusCache(*packageSourceList, Progress, &Map, true);
 	Progress.Done();
 	if(!Res) {
 		return false;
@@ -143,9 +159,25 @@ aptcc::~aptcc()
 		delete Policy;
 	}
 
+	if (packageSourceList)
+	{
+		delete packageSourceList;
+	}
+
 	delete Map;
 }
 
+void aptcc::cancel()
+{
+	if (!_cancel) {
+		_cancel = true;
+	        pk_backend_set_status(m_backend, PK_STATUS_ENUM_CANCEL);
+	}
+	if (m_child_pid > 0) {
+		kill(m_child_pid, SIGTERM);
+	}
+}
+
 pair<pkgCache::PkgIterator, pkgCache::VerIterator>
 		      aptcc::find_package_id(const gchar *package_id)
 {
@@ -662,37 +694,36 @@ void emit_files (PkBackend *backend, const gchar *pi)
 }
 
 
-static bool CheckAuth(pkgAcquire& Fetcher, PkBackend *backend)
+static bool checkTrusted(pkgAcquire &fetcher, PkBackend *backend)
 {
-   string UntrustedList;
-   for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd(); ++I)
-   {
-      if (!(*I)->IsTrusted())
-      {
-         UntrustedList += string((*I)->ShortDesc()) + " ";
-      }
-   }
-
-   if (UntrustedList == "")
-   {
-      return true;
-   }
-
-   string warning("WARNING: The following packages cannot be authenticated!\n");
-   warning += UntrustedList;
-   pk_backend_message(backend,
-		      PK_MESSAGE_ENUM_UNTRUSTED_PACKAGE,
-		      warning.c_str());
-
-//    ShowList(c2out,_("WARNING: The following packages cannot be authenticated!"),UntrustedList,"");
-
-   if (_config->FindB("APT::Get::AllowUnauthenticated", false) == true)
-   {
-      egg_debug ("Authentication warning overridden.\n");
-      return true;
-   }
-
-   return false;
+	string UntrustedList;
+	for (pkgAcquire::ItemIterator I = fetcher.ItemsBegin(); I < fetcher.ItemsEnd(); ++I)
+	{
+		if (!(*I)->IsTrusted())
+		{
+			UntrustedList += string((*I)->ShortDesc()) + " ";
+		}
+	}
+
+	if (UntrustedList == "")
+	{
+		return true;
+	}
+
+	if (pk_backend_get_bool(backend, "only_trusted") == false ||
+	    _config->FindB("APT::Get::AllowUnauthenticated", false) == true)
+	{
+		egg_debug ("Authentication warning overridden.\n");
+		return true;
+	}
+
+	string warning("The following packages cannot be authenticated:\n");
+	warning += UntrustedList;
+	pk_backend_error_code(backend,
+			      PK_ERROR_ENUM_CANNOT_INSTALL_REPO_UNSIGNED,
+			      warning.c_str());
+	_error->Discard();
+	return false;
 }
 
 bool aptcc::TryToInstall(pkgCache::PkgIterator Pkg,
@@ -820,6 +851,178 @@ void aptcc::emitChangedPackages(vector<pair<pkgCache::PkgIterator, pkgCache::Ver
 	emit_packages(updating,    PK_FILTER_ENUM_NONE, PK_INFO_ENUM_UPDATING);
 }
 
+void aptcc::populateInternalPackages(pkgCacheFile &Cache)
+{
+	for (pkgCache::PkgIterator pkg = Cache->PkgBegin(); ! pkg.end(); ++pkg)
+        {
+                if (Cache[pkg].NewInstall() == true) {
+                        // installing
+			m_pkgs.push_back(pair<pkgCache::PkgIterator, pkgCache::VerIterator>(pkg, find_candidate_ver(pkg)));
+                } else if (Cache[pkg].Delete() == true) {
+                        // removing
+			m_pkgs.push_back(pair<pkgCache::PkgIterator, pkgCache::VerIterator>(pkg, find_candidate_ver(pkg)));
+                } else if (Cache[pkg].Upgrade() == true) {
+                        // updating
+			m_pkgs.push_back(pair<pkgCache::PkgIterator, pkgCache::VerIterator>(pkg, find_candidate_ver(pkg)));
+                } else if (Cache[pkg].Downgrade() == true) {
+                        // downgrading
+                        m_pkgs.push_back(pair<pkgCache::PkgIterator, pkgCache::VerIterator>(pkg, find_candidate_ver(pkg)));
+                }
+        }
+}
+
+void aptcc::emitTransactionPackage(string name, PkInfoEnum state)
+{
+	for (vector<pair<pkgCache::PkgIterator, pkgCache::VerIterator> >::iterator i=m_pkgs.begin();
+	     i != m_pkgs.end();
+	     ++i)
+	{
+		if (i->first.Name() == name) {
+			emit_package(i->first, i->second, PK_FILTER_ENUM_NONE, state);
+			return;
+		}
+	}
+
+	pair<pkgCache::PkgIterator, pkgCache::VerIterator> pkg_ver;
+	pkg_ver.first = packageCache->FindPkg(name);
+	// Ignore packages that could not be found or that exist only due to dependencies.
+	if (pkg_ver.first.end() == true ||
+	    (pkg_ver.first.VersionList().end() && pkg_ver.first.ProvidesList().end()))
+	{
+		return;
+	}
+
+	pkg_ver.second = find_ver(pkg_ver.first);
+	// check to see if the provided package isn't virtual too
+	if (pkg_ver.second.end() == false)
+	{
+		emit_package(pkg_ver.first, pkg_ver.second, PK_FILTER_ENUM_NONE, state);
+	}
+
+	pkg_ver.second = find_candidate_ver(pkg_ver.first);
+	// check to see if we found the package
+	if (pkg_ver.second.end() == false)
+	{
+		emit_package(pkg_ver.first, pkg_ver.second, PK_FILTER_ENUM_NONE, state);
+	}
+}
+
+void aptcc::updateInterface(int fd, int writeFd)
+{
+	char buf[2];
+	static char line[1024] = "";
+	int i=0;
+
+	while (1) {
+		// This algorithm should be improved (it's the same as the rpm one ;)
+		int len = read(fd, buf, 1);
+
+		// nothing was read
+		if(len < 1) {
+			break;
+		}
+
+		// update the time we last saw some action
+		last_term_action = time(NULL);
+
+		if( buf[0] == '\n') {
+			if (_cancel) {
+				kill(m_child_pid, SIGTERM);
+			}
+			//cout << "got line: " << line << endl;
+
+			gchar **split = g_strsplit(line, ":",5);
+			gchar *status = g_strstrip(split[0]);
+			gchar *pkg = g_strstrip(split[1]);
+			gchar *percent = g_strstrip(split[2]);
+			gchar *str = g_strdup(g_strstrip(split[3]));
+
+			// major problem here, we got unexpected input. should _never_ happen
+			if(!(pkg && status)) {
+				continue;
+			}
+
+			// first check for errors and conf-file prompts
+			if (strstr(status, "pmerror") != NULL) {
+				// error from dpkg, needs to be parsed different
+cout << "PK: Error in package: " << split[1] << endl;
+//				str = g_strdup_printf(_("Error in package %s"), split[1]);
+//				string err = split[1] + string(": ") + split[3];
+//				_error->Error("%s",utf8(err.c_str()));
+			} else if (strstr(status, "pmconffile") != NULL) {
+				// conffile-request from dpkg, needs to be parsed different
+cout << "PK: Oops Conf file detected!!! -> PKG: " << pkg << " " << split[2] << " " << split[3] << endl;
+cout << "write " << write(writeFd, "n\n", 2);
+				//cout << split[2] << " " << split[3] << endl;
+			} else if (strstr(status, "pmstatus") != NULL) {
+				// Let's start parsing the status:
+				if (starts_with(str, "Preparing")) {
+					// Preparing to Install/configure
+					cout << "Found Preparing! " << line << endl;
+					emitTransactionPackage(pkg, PK_INFO_ENUM_PREPARING);
+				} else if (starts_with(str, "Unpacking")) {
+					cout << "Found Unpacking! " << line << endl;
+					emitTransactionPackage(pkg, PK_INFO_ENUM_DECOMPRESSING);
+				} else if (starts_with(str, "Configuring")) {
+					// Installing Package
+					cout << "Found Configuring! " << line << endl;
+					emitTransactionPackage(pkg, PK_INFO_ENUM_INSTALLING);
+				} else if (starts_with(str, "Running dpkg")) {
+					cout << "Found Running dpkg! " << line << endl;
+				} else if (starts_with(str, "Running")) {
+					cout << "Found Running! " << line << endl;
+					emitTransactionPackage(pkg, PK_INFO_ENUM_CLEANUP);
+				} else if (starts_with(str, "Installing")) {
+					cout << "Found Installing! " << line << endl;
+					emitTransactionPackage(pkg, PK_INFO_ENUM_INSTALLING);
+				} else if (starts_with(str, "Removing")) {
+					cout << "Found Removing! " << line << endl;
+					emitTransactionPackage(pkg, PK_INFO_ENUM_REMOVING);
+				} else if (starts_with(str, "Installed") ||
+					   starts_with(str, "Removed")) {
+					cout << "Found FINISHED! " << line << endl;
+					emitTransactionPackage(pkg, PK_INFO_ENUM_FINISHED);
+				} else {
+					cout << ">>>Unmaped value<<< :" << line << endl;
+				}
+			} else {
+				_startCounting = true;
+			}
+
+			int val = atoi(percent);
+			//cout << "progress: " << val << endl;
+			pk_backend_set_percentage(m_backend, val);
+
+			// clean-up
+			g_strfreev(split);
+			g_free(str);
+			line[0] = 0;
+		} else {
+			buf[1] = 0;
+			strcat(line, buf);
+		}
+	}
+
+	time_t now = time(NULL);
+
+	if(!_startCounting) {
+		usleep(100000);
+//		gtk_progress_bar_pulse (GTK_PROGRESS_BAR(_pbarTotal));
+		// wait until we get the first message from apt
+		last_term_action = now;
+	}
+
+	if ((now - last_term_action) > _terminalTimeout) {
+		// get some debug info
+		gchar *s;
+		g_warning("no statusfd changes/content updates in terminal for %i"
+			  " seconds",_terminalTimeout);
+		g_warning("TerminalTimeout in step: %s", s);
+		last_term_action = time(NULL);
+	}
+
+	usleep(5000);
+}
 									/*}}}*/
 
 // InstallPackages - Actually download and install the packages		/*{{{*/
@@ -827,29 +1030,25 @@ void aptcc::emitChangedPackages(vector<pair<pkgCache::PkgIterator, pkgCache::Ver
 /* This displays the informative messages describing what is going to
    happen and then calls the download routines */
 bool aptcc::installPackages(pkgDepCache &Cache,
-			    bool ShwKept,
-			    bool Ask,
 			    bool Safety)
 {
+cout << "installPackages() called" << endl;
 	if (_config->FindB("APT::Get::Purge",false) == true)
 	{
-	    pkgCache::PkgIterator I = Cache.PkgBegin();
-	    for (; I.end() == false; I++)
-	    {
-		if (I.Purge() == false && Cache[I].Mode == pkgDepCache::ModeDelete)
-		    Cache.MarkDelete(I,true);
-	    }
+		pkgCache::PkgIterator I = Cache.PkgBegin();
+		for (; I.end() == false; I++)
+		{
+			if (I.Purge() == false && Cache[I].Mode == pkgDepCache::ModeDelete) {
+				Cache.MarkDelete(I,true);
+			}
+		}
 	}
 
-	bool Fail = false;
+//	bool Fail = false;
 	bool Essential = false;
 
 // we don't show things here
 	// Show all the various warning indicators
-// 	ShowDel(c1out,Cache);
-// 	ShowNew(c1out,Cache);
-// 	if (ShwKept == true)
-// 	    ShowKept(c1out,Cache);
 // 	Fail |= !ShowHold(c1out,Cache);
 // 	if (_config->FindB("APT::Get::Show-Upgraded",true) == true)
 // 	    ShowUpgraded(c1out,Cache);
@@ -863,13 +1062,14 @@ bool aptcc::installPackages(pkgDepCache &Cache,
 	if (Cache.BrokenCount() != 0)
 	{
 // 	    ShowBroken(c1out,Cache,false);
-	    show_broken(m_backend, this);
-	    return _error->Error("Internal error, InstallPackages was called with broken packages!");
+		show_broken(m_backend, this);
+		return _error->Error("Internal error, InstallPackages was called with broken packages!");
 	}
 
 	if (Cache.DelCount() == 0 && Cache.InstCount() == 0 &&
-	    Cache.BadCount() == 0)
-	    return true;
+	    Cache.BadCount() == 0) {
+		return true;
+	}
 
 	// No remove flag
 	if (Cache.DelCount() != 0 && _config->FindB("APT::Get::Remove",true) == false) {
@@ -878,36 +1078,34 @@ bool aptcc::installPackages(pkgDepCache &Cache,
 
 	// Create the text record parser
 	pkgRecords Recs(Cache);
-	if (_error->PendingError() == true)
-	    return false;
+	if (_error->PendingError() == true) {
+		return false;
+	}
 
 	// Lock the archive directory
 	FileFd Lock;
 	if (_config->FindB("Debug::NoLocking",false) == false &&
 	    _config->FindB("APT::Get::Print-URIs") == false)
 	{
-	    Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
-	    if (_error->PendingError() == true)
-		return _error->Error("Unable to lock the download directory");
+		Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
+		if (_error->PendingError() == true) {
+			return _error->Error("Unable to lock the download directory");
+		}
 	}
 
 	// Create the download object
 	AcqPackageKitStatus Stat(this, m_backend, _cancel, _config->FindI("quiet",0));
-	pkgAcquire Fetcher(&Stat);
 
-	// Read the source list
-// 	pkgSourceList List;
-// 	if (List.ReadMainList() == false)
-// 	    return _error->Error("The list of sources could not be read.");
+	// get a fetcher
+	pkgAcquire fetcher(&Stat);
 
 	// Create the package manager and prepare to download
 	SPtr<pkgPackageManager> PM= _system->CreatePM(&Cache);
-	if (PM->GetArchives(&Fetcher, &m_pkgSourceList, &Recs) == false ||
+	if (PM->GetArchives(&fetcher, packageSourceList, &Recs) == false ||
 	    _error->PendingError() == true) {
 		return false;
 	}
 
-
 	// Generate the list of affected packages and sort it
 	for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
 	{
@@ -932,13 +1130,13 @@ bool aptcc::installPackages(pkgDepCache &Cache,
 	}
 
 	// Display statistics
-	double FetchBytes = Fetcher.FetchNeeded();
-	double FetchPBytes = Fetcher.PartialPresent();
-	double DebBytes = Fetcher.TotalNeeded();
+	double FetchBytes = fetcher.FetchNeeded();
+	double FetchPBytes = fetcher.PartialPresent();
+	double DebBytes = fetcher.TotalNeeded();
 	if (DebBytes != Cache.DebSize())
 	{
 // 	    c0out << DebBytes << ',' << Cache.DebSize() << endl;
-	    _error->Warning("How odd.. The sizes didn't match, email apt at packages.debian.org");
+		_error->Warning("How odd.. The sizes didn't match, email apt at packages.debian.org");
 	}
 
 	// Number of bytes
@@ -957,21 +1155,23 @@ bool aptcc::installPackages(pkgDepCache &Cache,
 // 	    ioprintf(c1out, "After this operation, %sB disk space will be freed.\n",
 // 		    SizeToStr(-1*Cache.UsrSize()).c_str());
 
-	if (_error->PendingError() == true)
-	    return false;
+	if (_error->PendingError() == true) {
+		return false;
+	}
 
 	/* Check for enough free space */
 	struct statvfs Buf;
 	string OutputDir = _config->FindDir("Dir::Cache::Archives");
 	if (statvfs(OutputDir.c_str(),&Buf) != 0) {
-		return _error->Errno("statvfs", "Couldn't determine free space in %s",
-				    OutputDir.c_str());
+		return _error->Errno("statvfs",
+				     "Couldn't determine free space in %s",
+				     OutputDir.c_str());
 	}
 	if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
 	{
 		struct statfs Stat;
 		if (statfs(OutputDir.c_str(), &Stat) != 0 ||
-				unsigned(Stat.f_type) != RAMFS_MAGIC)
+		    unsigned(Stat.f_type)            != RAMFS_MAGIC)
 		{
 			pk_backend_error_code(m_backend,
 					      PK_ERROR_ENUM_NO_SPACE_ON_DEVICE,
@@ -991,147 +1191,114 @@ bool aptcc::installPackages(pkgDepCache &Cache,
 
 	if (Essential == true && Safety == true)
 	{
-	    if (_config->FindB("APT::Get::Trivial-Only",false) == true)
-		return _error->Error("Trivial Only specified but this is not a trivial operation.");
-
-	    pk_backend_error_code(m_backend,
-				  PK_ERROR_ENUM_TRANSACTION_ERROR,
-				  "You was about to do something potentially harmful.\n"
-				  "Please use aptitude or synaptic to have more information.");
-	    return false;
-// 	    const char *Prompt = "Yes, do as I say!";
-// 	    ioprintf(c2out,
-// 		    "You are about to do something potentially harmful.\n"
-// 			"To continue type in the phrase '%s'\n"
-// 			" ?] ",Prompt);
-// 	    c2out << flush;
-// 	    if (AnalPrompt(Prompt) == false)
-// 	    {
-// 		c2out << "Abort." << endl;
-// 		exit(1);
-// 	    }
-	}
-
-	// Just print out the uris an exit if the --print-uris flag was used
-// 	if (_config->FindB("APT::Get::Print-URIs") == true)
-// 	{
-// 	    pkgAcquire::UriIterator I = Fetcher.UriBegin();
-// 	    for (; I != Fetcher.UriEnd(); I++)
-// 		cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
-// 		    I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl;
-// 	    return true;
-// 	}
+		if (_config->FindB("APT::Get::Trivial-Only",false) == true) {
+			return _error->Error("Trivial Only specified but this is not a trivial operation.");
+		}
 
-	if (!CheckAuth(Fetcher, m_backend))
-	    return false;
+		pk_backend_error_code(m_backend,
+				      PK_ERROR_ENUM_TRANSACTION_ERROR,
+				      "You was about to do something potentially harmful.\n"
+				      "Please use aptitude or synaptic to have more information.");
+		return false;
+	}
 
-	/* Unlock the dpkg lock if we are not going to be doing an install
-	    after. */
-// 	if (_config->FindB("APT::Get::Download-Only",false) == true)
-// 	    _system->UnLock();
+	if (!checkTrusted(fetcher, m_backend)) {
+		return false;
+	}
 
-	// Run it
-	while (1)
+	// Download and check if we can continue
+	if (fetcher.Run() != pkgAcquire::Continue
+	    && _cancel == false)
 	{
-	    bool Transient = false;
-	    if (_config->FindB("APT::Get::Download",true) == false)
-	    {
-		for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd();)
-		{
-		    if ((*I)->Local == true)
-		    {
-		    I++;
-		    continue;
-		    }
-
-		    // Close the item and check if it was found in cache
-		    (*I)->Finished();
-		    if ((*I)->Complete == false)
-		    Transient = true;
-
-		    // Clear it out of the fetch list
-		    delete *I;
-		    I = Fetcher.ItemsBegin();
-		}
-	    }
-
-	    if (Fetcher.Run() == pkgAcquire::Failed)
+		// We failed and we did not cancel
+		show_errors(m_backend, PK_ERROR_ENUM_PACKAGE_DOWNLOAD_FAILED);
 		return false;
+	}
 
-	    // Print out errors
-	    bool Failed = false;
-	    for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
-	    {
-		if ((*I)->Status == pkgAcquire::Item::StatDone &&
-		    (*I)->Complete == true)
-		    continue;
+	// TODO true or false?
+	if (_cancel) {
+		return true;
+	}
 
-		if ((*I)->Status == pkgAcquire::Item::StatIdle)
-		{
-		    Transient = true;
-		    // Failed = true;
-		    continue;
-		}
+	// Download should be finished by now, changing it's status
+	pk_backend_set_status (m_backend, PK_STATUS_ENUM_RUNNING);
+	pk_backend_set_percentage(m_backend, PK_BACKEND_PERCENTAGE_INVALID);
+	pk_backend_set_sub_percentage(m_backend, PK_BACKEND_PERCENTAGE_INVALID);
 
-		string fetchError("Failed to fetch:\n");
-		fetchError += (*I)->DescURI() + "  ";
-		fetchError += (*I)->ErrorText;
-		pk_backend_error_code(m_backend,
-				      PK_ERROR_ENUM_PACKAGE_DOWNLOAD_FAILED,
-				      fetchError.c_str());
-// 		fprintf(stderr, "Failed to fetch %s  %s\n", (*I)->DescURI().c_str(),
-// 			(*I)->ErrorText.c_str());
-		Failed = true;
-	    }
-
-	    /* If we are in no download mode and missing files and there were
-		'failures' then the user must specify -m. Furthermore, there
-		is no such thing as a transient error in no-download mode! */
-	    if (Transient == true &&
-		_config->FindB("APT::Get::Download",true) == false)
-	    {
-		Transient = false;
-		Failed = true;
-	    }
-
-// 	    if (_config->FindB("APT::Get::Download-Only",false) == true)
-// 	    {
-// 		if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
-// 		    return _error->Error("Some files failed to download");
-// 		c1out << "Download complete and in download only mode" << endl;
-// 		return true;
-// 	    }
-
-	    if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
-	    {
-		return _error->Error("Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?");
-	    }
-
-	    if (Transient == true && Failed == true)
-		return _error->Error("--fix-missing and media swapping is not currently supported");
-
-	    // Try to deal with missing package files
-	    if (Failed == true && PM->FixMissing() == false)
-	    {
-		cerr << "Unable to correct missing packages." << endl;
-		return _error->Error("Aborting install.");
-	    }
-
-	    _system->UnLock();
-	    int status_fd = _config->FindI("APT::Status-Fd",-1);
-	    pkgPackageManager::OrderResult Res = PM->DoInstall(status_fd);
-	    if (Res == pkgPackageManager::Failed || _error->PendingError() == true)
+	// TODO DBus activated does not have all vars
+	// we could try to see if this is the case
+	setenv("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 1);
+	_system->UnLock();
+
+	pkgPackageManager::OrderResult res;
+	res = PM->DoInstallPreFork();
+	if (res == pkgPackageManager::Failed) {
 		return false;
-	    if (Res == pkgPackageManager::Completed)
-		return true;
+	}
 
-	    // Reload the fetcher object and loop again for media swapping
-	    Fetcher.Shutdown();
-	    if (PM->GetArchives(&Fetcher, &m_pkgSourceList, &Recs) == false)
+	// File descriptors for reading dpkg --status-fd
+	int readFromChildFD[2];
+	int writeToChildFD[2];
+	if (pipe(readFromChildFD) < 0 || pipe(writeToChildFD) < 0) {
+		cout << "Failed to create a pipe" << endl;
 		return false;
+	}
+
+	m_child_pid = fork();
+	if (m_child_pid == -1) {
+		return false;
+	}
+
+	if (m_child_pid == 0) {
+		cout << "FORKED: installPackages(): DoInstall" << endl;
+		// close Forked stdout and the read end of the pipe
+		close(0);
+		close(1);
+		close(readFromChildFD[0]);
+		close(writeToChildFD[1]);
+
+		// redirect writeToChildFD to stdin
+		if (dup(writeToChildFD[0]) != 0) {
+			cerr << "Aptcc: dup failed duplicate pipe to stdin" << endl;
+			close(readFromChildFD[1]);
+			close(writeToChildFD[0]);
+			_exit(1);
+		}
+
+		// Change the locale AND lang to not get it localized
+		setenv("LANG", "C", 1);
+		setlocale(LC_ALL, "C");
+
+		// Pass the write end of the pipe to the install function
+		res = PM->DoInstallPostFork(readFromChildFD[1]);
 
-	    _system->Lock();
+		// dump errors into cerr (pass it to the parent process)
+		_error->DumpErrors();
+
+		close(readFromChildFD[1]);
+		close(writeToChildFD[0]);
+
+		_exit(res);
 	}
+	close(readFromChildFD[1]);
+	close(writeToChildFD[0]);
+
+	cout << "PARENT proccess running..." << endl;
+	// make it nonblocking, verry important otherwise
+	// when the child finish we stay stuck.
+	fcntl(readFromChildFD[0], F_SETFL, O_NONBLOCK);
+
+	// Check if the child died
+	int ret;
+	while (waitpid(m_child_pid, &ret, WNOHANG) == 0) {
+		updateInterface(readFromChildFD[0], writeToChildFD[1]);
+	}
+
+	close(readFromChildFD[0]);
+	close(writeToChildFD[1]);
+
+	cout << "Parent finished..." << endl;
+	return true;
 }
 
 // DoAutomaticRemove - Remove all automatic unused packages		/*{{{*/
@@ -1176,12 +1343,12 @@ bool aptcc::DoAutomaticRemove(pkgCacheFile &Cache)
 	return true;
 }
 
-bool aptcc::prepare_transaction(vector<pair<pkgCache::PkgIterator, pkgCache::VerIterator> > &pkgs,
-				bool simulate,
-				bool remove)
+bool aptcc::runTransaction(vector<pair<pkgCache::PkgIterator, pkgCache::VerIterator> > &pkgs,
+			   bool simulate,
+			   bool remove)
 {
 	cout << "==============================================================" << endl;
-	cout << "prepare_transaction" << simulate << remove << endl;
+	cout << "runTransaction" << simulate << remove << endl;
 	bool WithLock = !simulate; // Check to see if we are just simulating,
 				   //since for that no lock is needed
 
@@ -1203,6 +1370,7 @@ bool aptcc::prepare_transaction(vector<pair<pkgCache::PkgIterator, pkgCache::Ver
 			timeout--;
 		}
 	}
+	pk_backend_set_status (m_backend, PK_STATUS_ENUM_RUNNING);
 
 	// Enter the special broken fixing mode if the user specified arguments
 	bool BrokenFix = false;
@@ -1278,8 +1446,8 @@ bool aptcc::prepare_transaction(vector<pair<pkgCache::PkgIterator, pkgCache::Ver
 	    // See if we need to prompt
 	//     if (Cache->InstCount() == ExpectedInst && Cache->DelCount() == 0)
 	// 	return InstallPackages(Cache,false,false);
-
-	//     return InstallPackages(Cache,false);
-		return true;
+		populateInternalPackages(Cache);
+	        return installPackages(Cache, false);
+	//	return true;
 	}
 }
diff --git a/backends/aptcc/apt.h b/backends/aptcc/apt.h
index 2a63a76..e4a081c 100644
--- a/backends/aptcc/apt.h
+++ b/backends/aptcc/apt.h
@@ -48,10 +48,11 @@ class aptcc
 {
 //     typedef int user_tag_reference;
 public:
-	aptcc(PkBackend *backend, bool &cancel, pkgSourceList &apt_source_list);
+	aptcc(PkBackend *backend, bool &cancel);
 	~aptcc();
 
 	bool init();
+	void cancel();
 
 	// Check the returned VerIterator.end()
 	// if it's true we could not find it
@@ -62,16 +63,16 @@ public:
 	bool is_held(const pkgCache::PkgIterator &pkg);
 
 	/**
-	 *  prepare a transaction to install/remove/update packages
+	 *  runs a transaction to install/remove/update packages
 	 *  - for install and update, \p remove should be set to false
 	 *  - if you are going to remove, \p remove should be true
-	 *  - If you don't want to actually install/update/remove
-	 *    simulate should be true, in this case packages with
+	 *  - if you don't want to actually install/update/remove
+	 *    \p simulate should be true, in this case packages with
 	 *    what's going to happen will be emitted.
 	 */
-	bool prepare_transaction(vector<pair<pkgCache::PkgIterator, pkgCache::VerIterator> > &pkgs,
-				 bool simulate,
-				 bool remove);
+	bool runTransaction(vector<pair<pkgCache::PkgIterator, pkgCache::VerIterator> > &pkgs,
+			    bool simulate,
+			    bool remove);
 
 	/**
 	 *  get the state cache of the package
@@ -118,10 +119,13 @@ public:
 	 *  seems to install packages
 	 */
 	bool installPackages(pkgDepCache &Cache,
-			     bool ShwKept,
-			     bool Ask = true,
 			     bool Safety = true);
 
+	/**
+	 *  interprets dpkg status fd
+	 */
+	void updateInterface(int readFd, int writeFd);
+
 	/** Marks all upgradable and non-held packages for upgrade.
 	 *
 	 *  \param with_autoinst if \b true, the dependencies of packages
@@ -141,6 +145,7 @@ public:
 	pkgRecords    *packageRecords;
 	pkgCache      *packageCache;
 	pkgDepCache   *packageDepCache;
+	pkgSourceList *packageSourceList;
 
 private:
 	MMap       *Map;
@@ -148,7 +153,6 @@ private:
 	pkgPolicy  *Policy;
 	PkBackend  *m_backend;
 	bool &_cancel;
-	pkgSourceList &m_pkgSourceList;
 
 	/** This flag is \b true iff the persistent state has changed (ie, we
 	 *  need to save the cache).
@@ -165,6 +169,15 @@ private:
 	bool DoAutomaticRemove(pkgCacheFile &Cache);
 	void emitChangedPackages(vector<pair<pkgCache::PkgIterator, pkgCache::VerIterator> > &pkgs,
 				 pkgCacheFile &Cache);
+
+	vector<pair<pkgCache::PkgIterator, pkgCache::VerIterator> > m_pkgs;
+	void populateInternalPackages(pkgCacheFile &Cache);
+	void emitTransactionPackage(string name, PkInfoEnum state);
+	time_t last_term_action;
+	bool _startCounting;
+	// when the internal terminal timesout after no activity
+	int _terminalTimeout;
+	pid_t m_child_pid;
 };
 
 #endif
diff --git a/backends/aptcc/pk-backend-aptcc.cpp b/backends/aptcc/pk-backend-aptcc.cpp
index 40c9d11..91175bc 100644
--- a/backends/aptcc/pk-backend-aptcc.cpp
+++ b/backends/aptcc/pk-backend-aptcc.cpp
@@ -44,7 +44,6 @@ using namespace std;
 
 /* static bodges */
 static bool _cancel = false;
-static pkgSourceList *apt_source_list = 0;
 
 /**
  * backend_initialize:
@@ -63,10 +62,6 @@ backend_initialize (PkBackend *backend)
 	{
 		egg_debug ("ERROR initializing backend");
 	}
-
-	// Open the cache file
-	apt_source_list = new pkgSourceList;
-	apt_source_list->ReadMainList();
 }
 
 /**
@@ -76,11 +71,6 @@ static void
 backend_destroy (PkBackend *backend)
 {
 	egg_debug ("APTcc being destroyed");
-	if (apt_source_list)
-	{
-		delete apt_source_list;
-		apt_source_list = NULL;
-	}
 }
 
 /**
@@ -142,8 +132,10 @@ backend_get_mime_types (PkBackend *backend)
 static void
 backend_cancel (PkBackend *backend)
 {
-	_cancel = true;
-	pk_backend_set_status(backend, PK_STATUS_ENUM_CANCEL);
+	aptcc *m_apt = (aptcc*) pk_backend_get_pointer(backend, "aptcc_obj");
+	if (m_apt) {
+		m_apt->cancel();
+	}
 }
 
 static gboolean
@@ -157,12 +149,11 @@ backend_get_depends_or_requires_thread (PkBackend *backend)
 	package_ids = pk_backend_get_strv (backend, "package_ids");
 	filters = (PkBitfield) pk_backend_get_uint (backend, "filters");
 	recursive = pk_backend_get_bool (backend, "recursive");
-	_cancel = false;
 
 	pk_backend_set_allow_cancel (backend, true);
-	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 
-	aptcc *m_apt = new aptcc(backend, _cancel, *apt_source_list);
+	aptcc *m_apt = new aptcc(backend, _cancel);
+	pk_backend_set_pointer(backend, "aptcc_obj", m_apt);
 	if (m_apt->init()) {
 		egg_debug ("Failed to create apt cache");
 		delete m_apt;
@@ -172,6 +163,7 @@ backend_get_depends_or_requires_thread (PkBackend *backend)
 
 	bool depends = pk_backend_get_bool(backend, "get_depends");
 
+	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	vector<pair<pkgCache::PkgIterator, pkgCache::VerIterator> > output;
 	for (uint i = 0; i < g_strv_length(package_ids); i++) {
 		if (_cancel) {
@@ -251,9 +243,8 @@ backend_get_files_thread (PkBackend *backend)
 		return false;
 	}
 
-	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
-
-	aptcc *m_apt = new aptcc(backend, _cancel, *apt_source_list);
+	aptcc *m_apt = new aptcc(backend, _cancel);
+	pk_backend_set_pointer(backend, "aptcc_obj", m_apt);
 	if (m_apt->init()) {
 		egg_debug ("Failed to create apt cache");
 		delete m_apt;
@@ -261,6 +252,7 @@ backend_get_files_thread (PkBackend *backend)
 		return false;
 	}
 
+	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	for (uint i = 0; i < g_strv_length(package_ids); i++) {
 		pi = package_ids[i];
 		if (pk_package_id_check(pi) == false) {
@@ -315,8 +307,8 @@ backend_get_details_thread (PkBackend *backend)
 		return false;
 	}
 
-	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
-	aptcc *m_apt = new aptcc(backend, _cancel, *apt_source_list);
+	aptcc *m_apt = new aptcc(backend, _cancel);
+	pk_backend_set_pointer(backend, "aptcc_obj", m_apt);
 	if (m_apt->init()) {
 		egg_debug ("Failed to create apt cache");
 		delete m_apt;
@@ -324,6 +316,7 @@ backend_get_details_thread (PkBackend *backend)
 		return false;
 	}
 
+	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	for (uint i = 0; i < g_strv_length(package_ids); i++) {
 		pi = package_ids[i];
 		if (pk_package_id_check(pi) == false) {
@@ -383,12 +376,10 @@ backend_get_details (PkBackend *backend, gchar **package_ids)
 static gboolean
 backend_update_system_thread (PkBackend *backend)
 {
-	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
-
-	_cancel = false;
 	pk_backend_set_allow_cancel (backend, true);
 
-	aptcc *m_apt = new aptcc(backend, _cancel, *apt_source_list);
+	aptcc *m_apt = new aptcc(backend, _cancel);
+	pk_backend_set_pointer(backend, "aptcc_obj", m_apt);
 	if (m_apt->init()) {
 		egg_debug ("Failed to create apt cache");
 		delete m_apt;
@@ -396,6 +387,7 @@ backend_update_system_thread (PkBackend *backend)
 		return false;
 	}
 
+	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	// create a cachefile object
 	pkgCacheFile Cache;
 	OpTextProgress Prog(*_config);
@@ -439,13 +431,10 @@ backend_get_updates_thread (PkBackend *backend)
 {
 	PkBitfield filters;
 	filters = (PkBitfield) pk_backend_get_uint (backend, "filters");
-
-	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
-
-	_cancel = false;
 	pk_backend_set_allow_cancel (backend, true);
 
-	aptcc *m_apt = new aptcc(backend, _cancel, *apt_source_list);
+	aptcc *m_apt = new aptcc(backend, _cancel);
+	pk_backend_set_pointer(backend, "aptcc_obj", m_apt);
 	if (m_apt->init()) {
 		egg_debug ("Failed to create apt cache");
 		delete m_apt;
@@ -453,6 +442,7 @@ backend_get_updates_thread (PkBackend *backend)
 		return false;
 	}
 
+	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pkgset to_install, to_hold, to_remove, to_purge;
 	// Build to_install to avoid a big printout
 	for(pkgCache::PkgIterator i=m_apt->packageCache->PkgBegin(); !i.end(); ++i)
@@ -639,12 +629,10 @@ backend_download_packages_thread (PkBackend *backend)
 
 	package_ids = pk_backend_get_strv(backend, "package_ids");
 	directory = _config->FindDir("Dir::Cache::archives") + "partial/";
-
-	_cancel = false;
 	pk_backend_set_allow_cancel (backend, true);
-	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 
-	aptcc *m_apt = new aptcc(backend, _cancel, *apt_source_list);
+	aptcc *m_apt = new aptcc(backend, _cancel);
+	pk_backend_set_pointer(backend, "aptcc_obj", m_apt);
 	if (m_apt->init()) {
 		egg_debug ("Failed to create apt cache");
 		delete m_apt;
@@ -652,6 +640,7 @@ backend_download_packages_thread (PkBackend *backend)
 		return false;
 	}
 
+	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	// Create the progress
 	AcqPackageKitStatus Stat(m_apt, backend, _cancel, _config->FindI("quiet",0));
 
@@ -660,6 +649,26 @@ backend_download_packages_thread (PkBackend *backend)
 	string filelist;
 	gchar *pi;
 
+	// TODO this might be useful when the item is in the cache
+// 	for (pkgAcquire::ItemIterator I = fetcher.ItemsBegin(); I < fetcher.ItemsEnd();)
+// 	{
+// 		if ((*I)->Local == true)
+// 		{
+// 			I++;
+// 			continue;
+// 		}
+//
+// 		// Close the item and check if it was found in cache
+// 		(*I)->Finished();
+// 		if ((*I)->Complete == false) {
+// 			Transient = true;
+// 		}
+//
+// 		// Clear it out of the fetch list
+// 		delete *I;
+// 		I = fetcher.ItemsBegin();
+// 	}
+
 	for (uint i = 0; i < g_strv_length(package_ids); i++) {
 		pi = package_ids[i];
 		if (pk_package_id_check(pi) == false) {
@@ -692,7 +701,7 @@ backend_download_packages_thread (PkBackend *backend)
 
 			string storeFileName;
 			if (get_archive(&fetcher,
-					apt_source_list,
+					m_apt->packageSourceList,
 					m_apt->packageRecords,
 					pkg_ver.second,
 					directory,
@@ -709,9 +718,9 @@ backend_download_packages_thread (PkBackend *backend)
 		}
 	}
 
-	pk_backend_set_status(backend, PK_STATUS_ENUM_DOWNLOAD);
-	if (fetcher.Run() != pkgAcquire::Continue)
-	// We failed or were cancelled
+	if (fetcher.Run() != pkgAcquire::Continue
+	    && _cancel == false)
+	// We failed and we did not cancel
 	{
 		show_errors(backend, PK_ERROR_ENUM_PACKAGE_DOWNLOAD_FAILED);
 		delete m_apt;
@@ -742,13 +751,10 @@ backend_download_packages (PkBackend *backend, gchar **package_ids, const gchar
 static gboolean
 backend_refresh_cache_thread (PkBackend *backend)
 {
-	_cancel = false;
 	pk_backend_set_allow_cancel (backend, true);
-	pk_backend_set_status (backend, PK_STATUS_ENUM_REFRESH_CACHE);
 
-	// we re-read it here since it might have changed
-	apt_source_list->ReadMainList();
-	aptcc *m_apt = new aptcc(backend, _cancel, *apt_source_list);
+	aptcc *m_apt = new aptcc(backend, _cancel);
+	pk_backend_set_pointer(backend, "aptcc_obj", m_apt);
 	if (m_apt->init()) {
 		egg_debug ("Failed to create apt cache");
 		delete m_apt;
@@ -756,6 +762,7 @@ backend_refresh_cache_thread (PkBackend *backend)
 		return false;
 	}
 
+	pk_backend_set_status (backend, PK_STATUS_ENUM_REFRESH_CACHE);
 	// Lock the list directory
 	FileFd Lock;
 	if (_config->FindB("Debug::NoLocking", false) == false)
@@ -774,7 +781,7 @@ backend_refresh_cache_thread (PkBackend *backend)
 
 	// do the work
 	if (_config->FindB("APT::Get::Download",true) == true) {
-		ListUpdate(Stat, *apt_source_list);
+		ListUpdate(Stat, *m_apt->packageSourceList);
 	}
 
 	// Rebuild the cache.
@@ -818,11 +825,10 @@ backend_resolve_thread (PkBackend *backend)
 
 	filters = (PkBitfield) pk_backend_get_uint (backend, "filters");
 	package_ids = pk_backend_get_strv (backend, "package_ids");
-	_cancel = false;
 	pk_backend_set_allow_cancel (backend, true);
-	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 
-	aptcc *m_apt = new aptcc(backend, _cancel, *apt_source_list);
+	aptcc *m_apt = new aptcc(backend, _cancel);
+	pk_backend_set_pointer(backend, "aptcc_obj", m_apt);
 	if (m_apt->init()) {
 		egg_debug ("Failed to create apt cache");
 		delete m_apt;
@@ -830,6 +836,7 @@ backend_resolve_thread (PkBackend *backend)
 		return false;
 	}
 
+	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	gchar *pi;
 	vector<pair<pkgCache::PkgIterator, pkgCache::VerIterator> > output;
 	for (uint i = 0; i < g_strv_length(package_ids); i++) {
@@ -897,13 +904,12 @@ backend_search_file_thread (PkBackend *backend)
 	search = pk_backend_get_string (backend, "search");
 	filters = (PkBitfield) pk_backend_get_uint (backend, "filters");
 
-	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
-	_cancel = false;
 	pk_backend_set_allow_cancel (backend, true);
 
 	// as we can only search for installed files lets avoid the opposite
 	if (!pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED)) {
-		aptcc *m_apt = new aptcc(backend, _cancel, *apt_source_list);
+		aptcc *m_apt = new aptcc(backend, _cancel);
+		pk_backend_set_pointer(backend, "aptcc_obj", m_apt);
 		if (m_apt->init()) {
 			egg_debug ("Failed to create apt cache");
 			delete m_apt;
@@ -911,6 +917,7 @@ backend_search_file_thread (PkBackend *backend)
 			return false;
 		}
 
+		pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 		vector<string> packages = search_file (backend, search, _cancel);
 		vector<pair<pkgCache::PkgIterator, pkgCache::VerIterator> > output;
 		for(vector<string>::iterator i = packages.begin();
@@ -954,7 +961,6 @@ backend_search_group_thread (PkBackend *backend)
 
 	group = pk_backend_get_string (backend, "search");
 	filters = (PkBitfield) pk_backend_get_uint (backend, "filters");
-	_cancel = false;
 	pk_backend_set_allow_cancel (backend, true);
 
 	if (group == NULL) {
@@ -965,12 +971,12 @@ backend_search_group_thread (PkBackend *backend)
 		return false;
 	}
 
-	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pk_backend_set_percentage (backend, 0);
 
 	PkGroupEnum pkGroup = pk_group_enum_from_text (group);
 
-	aptcc *m_apt = new aptcc(backend, _cancel, *apt_source_list);
+	aptcc *m_apt = new aptcc(backend, _cancel);
+	pk_backend_set_pointer(backend, "aptcc_obj", m_apt);
 	if (m_apt->init()) {
 		egg_debug ("Failed to create apt cache");
 		delete m_apt;
@@ -978,6 +984,7 @@ backend_search_group_thread (PkBackend *backend)
 		return false;
 	}
 
+	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	vector<pair<pkgCache::PkgIterator, pkgCache::VerIterator> > output;
 	for (pkgCache::PkgIterator pkg = m_apt->packageCache->PkgBegin(); !pkg.end(); ++pkg) {
 		if (_cancel) {
@@ -1033,9 +1040,7 @@ backend_search_package_thread (PkBackend *backend)
 	filters = (PkBitfield) pk_backend_get_uint (backend, "filters");
 
 	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
-	_cancel = false;
 	pk_backend_set_allow_cancel (backend, true);
-	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 
 	matcher *m_matcher = new matcher(string(search));
 	if (m_matcher->hasError()) {
@@ -1045,7 +1050,8 @@ backend_search_package_thread (PkBackend *backend)
 		return false;
 	}
 
-	aptcc *m_apt = new aptcc(backend, _cancel, *apt_source_list);
+	aptcc *m_apt = new aptcc(backend, _cancel);
+	pk_backend_set_pointer(backend, "aptcc_obj", m_apt);
 	if (m_apt->init()) {
 		egg_debug ("Failed to create apt cache");
 		delete m_matcher;
@@ -1062,6 +1068,7 @@ backend_search_package_thread (PkBackend *backend)
 		return false;
 	}
 
+	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pkgDepCache::Policy Plcy;
 	vector<pair<pkgCache::PkgIterator, pkgCache::VerIterator> > output;
 	if (pk_backend_get_bool (backend, "search_details")) {
@@ -1203,11 +1210,10 @@ backend_manage_packages_thread (PkBackend *backend)
 	simulate = pk_backend_get_bool (backend, "simulate");
 	remove = pk_backend_get_bool (backend, "remove");
 
-	_cancel = false;
 	pk_backend_set_allow_cancel (backend, true);
-	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 
-	aptcc *m_apt = new aptcc(backend, _cancel, *apt_source_list);
+	aptcc *m_apt = new aptcc(backend, _cancel);
+	pk_backend_set_pointer(backend, "aptcc_obj", m_apt);
 	if (m_apt->init()) {
 		egg_debug ("Failed to create apt cache");
 		delete m_apt;
@@ -1215,6 +1221,7 @@ backend_manage_packages_thread (PkBackend *backend)
 		return false;
 	}
 
+	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	vector<pair<pkgCache::PkgIterator, pkgCache::VerIterator> > pkgs;
 	for (uint i = 0; i < g_strv_length(package_ids); i++) {
 		if (_cancel) {
@@ -1248,9 +1255,9 @@ backend_manage_packages_thread (PkBackend *backend)
 		}
 	}
 
-	if (!m_apt->prepare_transaction(pkgs, simulate, remove)) {
+	if (!m_apt->runTransaction(pkgs, simulate, remove)) {
 		// Print transaction errors
-		cout << "prepare_transaction failed" << endl;
+		cout << "runTransaction failed" << endl;
 		delete m_apt;
 		pk_backend_finished (backend);
 		return false;
@@ -1405,7 +1412,6 @@ backend_repo_manager_thread (PkBackend *backend)
 			_error->Error("Could not update sources file");
 			show_errors(backend, PK_ERROR_ENUM_CANNOT_WRITE_REPO_CONFIG);
 		}
-		apt_source_list->ReadMainList();
 	}
 	pk_backend_finished (backend);
 	return true;
@@ -1436,13 +1442,10 @@ backend_get_packages_thread (PkBackend *backend)
 {
 	PkBitfield filters;
 	filters = (PkBitfield) pk_backend_get_uint (backend, "filters");
-
-	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
-
-	_cancel = false;
 	pk_backend_set_allow_cancel (backend, true);
 
-	aptcc *m_apt = new aptcc(backend, _cancel, *apt_source_list);
+	aptcc *m_apt = new aptcc(backend, _cancel);
+	pk_backend_set_pointer(backend, "aptcc_obj", m_apt);
 	if (m_apt->init()) {
 		egg_debug ("Failed to create apt cache");
 		delete m_apt;
@@ -1450,6 +1453,7 @@ backend_get_packages_thread (PkBackend *backend)
 		return false;
 	}
 
+	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	vector<pair<pkgCache::PkgIterator, pkgCache::VerIterator> > output;
 	output.reserve(m_apt->packageCache->HeaderP->PackageCount);
 	for(pkgCache::PkgIterator pkg = m_apt->packageCache->PkgBegin();
diff --git a/docs/html/pk-matrix.html b/docs/html/pk-matrix.html
index 7cab339..f49962f 100644
--- a/docs/html/pk-matrix.html
+++ b/docs/html/pk-matrix.html
@@ -256,7 +256,7 @@
 <tr>
 <td><b>InstallPackages</b></td>
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- aptcc -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- aptcc -->
 <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 -->
@@ -310,7 +310,7 @@
 <tr>
 <td><b>RemovePackages</b></td>
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- aptcc -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- aptcc -->
 <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 -->
@@ -544,7 +544,7 @@
 <tr>
 <td><b>UpdatePackages</b></td>
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- aptcc -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- aptcc -->
 <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 9b4d996ee98b2d9fe3d94f1b33b9e5f91d1d9682
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Oct 6 15:55:09 2009 +0100

    bugfix: allow Cancel() to work with pkcon when ctrl-c'd by introducing a small delay

diff --git a/client/pk-console.c b/client/pk-console.c
index 01dd2ec..ec288ea 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -840,6 +840,18 @@ pk_console_notify_connected_cb (PkControl *control_, GParamSpec *pspec, gpointer
 }
 
 /**
+ * pk_console_sigint_idle_cb:
+ **/
+static gboolean
+pk_console_sigint_idle_cb (gpointer user_data)
+{
+	/* kill ourselves */
+	egg_debug ("Retrying SIGINT");
+	kill (getpid (), SIGINT);
+	return FALSE;
+}
+
+/**
  * pk_console_sigint_cb:
  **/
 static void
@@ -853,9 +865,8 @@ pk_console_sigint_cb (int sig)
 	/* cancel any tasks still running */
 	g_cancellable_cancel (cancellable);
 
-	/* kill ourselves */
-	egg_debug ("Retrying SIGINT");
-	kill (getpid (), SIGINT);
+	/* wait for packagekitd to cancel by waiting 100ms */
+	g_timeout_add (100, (GSourceFunc) pk_console_sigint_idle_cb, NULL);
 }
 
 /**


More information about the PackageKit-commit mailing list