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

Richard Hughes hughsient at kemper.freedesktop.org
Fri Apr 24 13:14:43 PDT 2009


 backends/smart/smartBackend.py           |   19 
 backends/yum/yumBackend.py               |   10 
 configure.ac                             |    6 
 docs/api/spec/pk-backend-dbus.xml        |   33 
 docs/api/spec/pk-introduction.xml        |    5 
 docs/api/spec/pk-structure.svg           |   48 -
 lib/packagekit-glib/egg-debug.c          |    7 
 lib/packagekit-glib/pk-client.c          |    2 
 lib/packagekit-qt/CMakeLists.txt         |   15 
 lib/packagekit-qt/Makefile.am            |    1 
 lib/packagekit-qt/modules/CMakeLists.txt |    9 
 lib/packagekit-qt/modules/Makefile.am    |    1 
 lib/packagekit-qt/src/CMakeLists.txt     |   60 -
 lib/packagekit-qt/src/Makefile.am        |    1 
 lib/packagekit-qt/src/common.h           |    1 
 lib/packagekit-qt/src/config.h.cmake     |    1 
 lib/packagekit-qt/src/package.cpp        |    6 
 lib/packagekit-qt/src/package.h          |    6 
 lib/packagekit-qt/src/transaction.cpp    |   12 
 lib/packagekit-qt/test/CMakeLists.txt    |   35 -
 lib/packagekit-qt/test/Makefile.am       |    3 
 lib/python/packagekit/Makefile.am        |    1 
 lib/python/packagekit/daemonBackend.py   | 1073 -------------------------------
 src/pk-backend-spawn.c                   |   57 +
 src/pk-backend.c                         |    2 
 src/pk-main.c                            |    4 
 src/pk-security-dummy.c                  |    2 
 27 files changed, 135 insertions(+), 1285 deletions(-)

New commits:
commit ed15735b6fb9118ece9968f50a4d87f1e4a09dd4
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Apr 24 21:13:29 2009 +0100

    Bugfix: Fix compile on FreeBSD

diff --git a/configure.ac b/configure.ac
index 329acb2..260f9e5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -228,6 +228,12 @@ fi
 AM_CONDITIONAL(HAVE_ARCHIVE_H, test x$HAVE_ARCHIVE_H = xyes)
 
 dnl ---------------------------------------------------------------------------
+dnl - FreeBSD compatibility
+dnl ---------------------------------------------------------------------------
+AC_CHECK_HEADERS([execinfo.h])
+AC_CHECK_FUNCS(clearenv)
+
+dnl ---------------------------------------------------------------------------
 dnl - xsltproc
 dnl ---------------------------------------------------------------------------
 AC_PATH_PROG([XSLTPROC], [xsltproc])
diff --git a/lib/packagekit-glib/egg-debug.c b/lib/packagekit-glib/egg-debug.c
index 22c460f..dff185e 100644
--- a/lib/packagekit-glib/egg-debug.c
+++ b/lib/packagekit-glib/egg-debug.c
@@ -26,6 +26,8 @@
  * This file contains functions that can be used for debugging.
  */
 
+#include "config.h"
+
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <glib/gprintf.h>
@@ -39,7 +41,10 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <time.h>
+
+#ifdef HAVE_EXECINFO_H
 #include <execinfo.h>
+#endif
 
 #include "egg-debug.h"
 
@@ -78,6 +83,7 @@ pk_set_console_mode (guint console_code)
 void
 egg_debug_backtrace (void)
 {
+#ifdef HAVE_EXECINFO_H
 	void *call_stack[512];
 	int  call_stack_size;
 	char **symbols;
@@ -95,6 +101,7 @@ egg_debug_backtrace (void)
 		pk_set_console_mode (CONSOLE_RESET);
 		free (symbols);
 	}
+#endif
 }
 
 /**
diff --git a/src/pk-main.c b/src/pk-main.c
index 144d191..d5853f9 100644
--- a/src/pk-main.c
+++ b/src/pk-main.c
@@ -183,9 +183,11 @@ main (int argc, char *argv[])
 	PkSyslog *syslog = NULL;
 	GError *error = NULL;
 	GOptionContext *context;
+#ifdef HAVE_CLEARENV
 	const gchar *env_pk_verbose;
 	const gchar *env_pk_console;
 	const gchar *env_pk_logging;
+#endif
 
 	const GOptionEntry options[] = {
 		{ "backend", '\0', 0, G_OPTION_ARG_STRING, &backend_name,
@@ -267,6 +269,7 @@ main (int argc, char *argv[])
 
 	/* we don't actually need to do this, except it rules out the
 	 * 'it works from the command line but not service activation' bugs */
+#ifdef HAVE_CLEARENV
 	env_pk_verbose = g_getenv (EGG_VERBOSE);
 	env_pk_console = g_getenv (EGG_CONSOLE);
 	env_pk_logging = g_getenv (EGG_LOGGING);
@@ -274,6 +277,7 @@ main (int argc, char *argv[])
 	g_setenv (EGG_VERBOSE, env_pk_verbose, FALSE);
 	g_setenv (EGG_CONSOLE, env_pk_console, FALSE);
 	g_setenv (EGG_LOGGING, env_pk_logging, FALSE);
+#endif
 
 	/* get values from the config file */
 	conf = pk_conf_new ();
commit f5ebcbadfe620eac6217773eac2acd71681036f2
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Apr 24 21:12:54 2009 +0100

    trivial: Remove an unused header include

diff --git a/lib/packagekit-glib/pk-client.c b/lib/packagekit-glib/pk-client.c
index 031b060..9ef7d1d 100644
--- a/lib/packagekit-glib/pk-client.c
+++ b/lib/packagekit-glib/pk-client.c
@@ -33,7 +33,7 @@
 
 #include <string.h>
 #include <sys/types.h>
-#include <sys/prctl.h>
+
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif /* HAVE_UNISTD_H */
commit 8d1af4623765fdb396f3f9ed6db74c3103ea59fc
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Apr 24 21:07:24 2009 +0100

    bugfix: correct a typo which causes a compile error on FreeBSD

diff --git a/src/pk-backend.c b/src/pk-backend.c
index d16c3a8..0e6e7dd 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -363,7 +363,7 @@ pk_backend_get_array (PkBackend *backend, const gchar *key)
 /**
  * pk_backend_get_uint:
  **/
-uint
+guint
 pk_backend_get_uint (PkBackend *backend, const gchar *key)
 {
 	g_return_val_if_fail (PK_IS_BACKEND (backend), 0);
commit 331a0d98f58e07b16b2388ad8812f97c995961eb
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Apr 24 21:06:18 2009 +0100

    bugfix: allow the dummy security model to authorise actions
    
    NULL is used for 'not-known' which causes the methods to exit with a permissions error

diff --git a/src/pk-security-dummy.c b/src/pk-security-dummy.c
index 129f32d..3e3713a 100644
--- a/src/pk-security-dummy.c
+++ b/src/pk-security-dummy.c
@@ -52,7 +52,7 @@ PkSecurityCaller *
 pk_security_caller_new_from_sender (PkSecurity *security, const gchar *sender)
 {
 	g_return_val_if_fail (PK_IS_SECURITY (security), NULL);
-	return NULL;
+	return GUINT_TO_POINTER (1);
 }
 
 /**
commit 7af1423a989cac5af9cada6fbc5972f2b769c56b
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Apr 24 15:42:55 2009 +0100

    bugfix: To fix spawned backends, http_proxy has to be a URI not a bare proxy. Fixes RH#491859

diff --git a/src/pk-backend-spawn.c b/src/pk-backend-spawn.c
index 2942584..a283e97 100644
--- a/src/pk-backend-spawn.c
+++ b/src/pk-backend-spawn.c
@@ -538,6 +538,33 @@ pk_backend_spawn_stderr_cb (PkBackendSpawn *spawn, const gchar *line, PkBackendS
 }
 
 /**
+ * pk_backend_spawn_convert_uri:
+ *
+ * Our proxy variable is typically 'username:password at server:port'
+ * but http_proxy expects 'http://username:password@server:port/'
+ **/
+static gchar *
+pk_backend_spawn_convert_uri (const gchar *proxy)
+{
+	GString *string;
+	string = g_string_new (proxy);
+
+	/* if we didn't specify a prefix, add a default one */
+	if (!g_str_has_prefix (proxy, "http://") &&
+	    !g_str_has_prefix (proxy, "https://") &&
+	    !g_str_has_prefix (proxy, "ftp://")) {
+		g_string_prepend (string, "http://");
+	}
+
+	/* if we didn't specify a trailing slash, add one */
+	if (!g_str_has_suffix (proxy, "/")) {
+		g_string_append_c (string, '/');
+	}
+
+	return g_string_free (string, FALSE);
+}
+
+/**
  * pk_backend_spawn_get_envp:
  *
  * Return all the environment variables the script will need
@@ -548,6 +575,7 @@ pk_backend_spawn_get_envp (PkBackendSpawn *backend_spawn)
 	gchar **envp;
 	gchar *value;
 	gchar *line;
+	gchar *uri;
 	GPtrArray *array;
 	gboolean ret;
 
@@ -556,18 +584,22 @@ pk_backend_spawn_get_envp (PkBackendSpawn *backend_spawn)
 	/* http_proxy */
 	value = pk_backend_get_proxy_http (backend_spawn->priv->backend);
 	if (!egg_strzero (value)) {
-		line = g_strdup_printf ("%s=%s", "http_proxy", value);
+		uri = pk_backend_spawn_convert_uri (value);
+		line = g_strdup_printf ("%s=%s", "http_proxy", uri);
 		egg_debug ("setting evp '%s'", line);
 		g_ptr_array_add (array, line);
+		g_free (uri);
 	}
 	g_free (value);
 
 	/* ftp_proxy */
 	value = pk_backend_get_proxy_ftp (backend_spawn->priv->backend);
 	if (!egg_strzero (value)) {
-		line = g_strdup_printf ("%s=%s", "ftp_proxy", value);
+		uri = pk_backend_spawn_convert_uri (value);
+		line = g_strdup_printf ("%s=%s", "ftp_proxy", uri);
 		egg_debug ("setting evp '%s'", line);
 		g_ptr_array_add (array, line);
+		g_free (uri);
 	}
 	g_free (value);
 
@@ -897,6 +929,7 @@ pk_backend_test_spawn (EggTest *test)
 	const gchar *text;
 	guint refcount;
 	gboolean ret;
+	gchar *uri;
 
 	loop = g_main_loop_new (NULL, FALSE);
 
@@ -1029,6 +1062,26 @@ pk_backend_test_spawn (EggTest *test)
 	egg_test_assert (test, !ret);
 
 	/************************************************************
+	 **********         Check uri conversion          ***********
+	 ************************************************************/
+	egg_test_title (test, "convert proxy uri (bare)");
+	uri = pk_backend_spawn_convert_uri ("username:password at server:port");
+	egg_test_assert (test, (g_strcmp0 (uri, "http://username:password@server:port/") == 0));
+	g_free (uri);
+
+	/************************************************************/
+	egg_test_title (test, "convert proxy uri (full)");
+	uri = pk_backend_spawn_convert_uri ("http://username:password@server:port/");
+	egg_test_assert (test, (g_strcmp0 (uri, "http://username:password@server:port/") == 0));
+	g_free (uri);
+
+	/************************************************************/
+	egg_test_title (test, "convert proxy uri (partial)");
+	uri = pk_backend_spawn_convert_uri ("ftp://username:password@server:port");
+	egg_test_assert (test, (g_strcmp0 (uri, "ftp://username:password@server:port/") == 0));
+	g_free (uri);
+
+	/************************************************************
 	 **********        Check parsing common out       ***********
 	 ************************************************************/
 	egg_test_title (test, "test pk_backend_spawn_parse_common_out Package");
commit 59a74691d36decdd183a763882ec0a86b2884402
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Apr 24 15:02:50 2009 +0100

    trivial: Remove some docs about the removed DBus interfaces

diff --git a/docs/api/spec/pk-backend-dbus.xml b/docs/api/spec/pk-backend-dbus.xml
deleted file mode 100644
index d0f0024..0000000
--- a/docs/api/spec/pk-backend-dbus.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
-
-<chapter id="backend-dbus">
-  <title>DBUS Backends</title>
-  <para>
-    Backend helpers communicating over standard out and standard
-    error are easy to write, but can have some performance
-    problems.
-    For instance, if your packages system has to do a lot of work when it
-    starts up and shuts down, performance in the UI may suffer.
-    In these cases, you can use a persistant backend daemon that
-    communicates to the C backend over DBUS.
-  </para>
-  <para>
-    Your daemon will be started by DBUS, and should be responsible
-    for it's own thread management.
-    It should receive an <literal>Init()</literal> method call when the C
-    backend starts, and an <literal>Exit()</literal> method call before it
-    exits.
-    You should also consider adding a timeout value to your daemon so that
-    it will exit after a set time with no activity from the C backend.
-    That way the daemon will still exit even if the C backend crashes for
-    some reason.
-  </para>
-  <para>
-    Again, like the helper backends described above, a compiled
-    backend stub is needed. An example of a DBUS backend written
-    in python can be found in <literal>backends/apt</literal>,
-    along with a compiled stub written in C.
-  </para>
-</chapter>
-
diff --git a/docs/api/spec/pk-introduction.xml b/docs/api/spec/pk-introduction.xml
index d67838e..bf3ef34 100644
--- a/docs/api/spec/pk-introduction.xml
+++ b/docs/api/spec/pk-introduction.xml
@@ -43,9 +43,8 @@
       loaded at run-time and provides an interface to the underlying package
       commands.
       A backend converts an asynchronous request into either a new thread
-      in the same process, executes external "glue" files that
-      can be written in any language, or uses DBUS to signal a
-      daemon process to handle the request.
+      in the same process, or executes external "glue" files that
+      can be written in any language.
     </para>
     <para>
       Backends do not have to support all of the commands supported
diff --git a/docs/api/spec/pk-structure.svg b/docs/api/spec/pk-structure.svg
index afbee9e..4929c8d 100644
--- a/docs/api/spec/pk-structure.svg
+++ b/docs/api/spec/pk-structure.svg
@@ -1,8 +1,9 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- Created with Inkscape (http://www.inkscape.org/) -->
+
 <svg
    xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:cc="http://creativecommons.org/ns#"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:svg="http://www.w3.org/2000/svg"
    xmlns="http://www.w3.org/2000/svg"
@@ -12,15 +13,21 @@
    height="1052.3622047"
    id="svg2"
    sodipodi:version="0.32"
-   inkscape:version="0.45.1"
-   sodipodi:docbase="/home/hughsie/Code/PackageKit/docs/spec"
+   inkscape:version="0.46+devel"
    sodipodi:docname="pk-structure.svg"
-   inkscape:export-filename="/home/hughsie/Code/PackageKit/docs/spec/pk-structure.png"
+   inkscape:export-filename="/home/hughsie/Code/PackageKit/docs/api/spec/pk-structure.svg.png"
    inkscape:export-xdpi="51.209103"
    inkscape:export-ydpi="51.209103"
    inkscape:output_extension="org.inkscape.output.svg.inkscape">
   <defs
      id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective80" />
     <marker
        inkscape:stockid="Arrow1Send"
        orient="auto"
@@ -110,7 +117,7 @@
      inkscape:window-width="1270"
      inkscape:window-height="721"
      inkscape:window-x="0"
-     inkscape:window-y="24"
+     inkscape:window-y="25"
      showguides="true"
      inkscape:guide-bbox="true" />
   <metadata
@@ -121,6 +128,7 @@
         <dc:format>image/svg+xml</dc:format>
         <dc:type
            rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
       </cc:Work>
     </rdf:RDF>
   </metadata>
@@ -461,36 +469,6 @@
        id="path2230"
        inkscape:connector-type="polyline"
        sodipodi:nodetypes="cc" />
-    <rect
-       style="opacity:1;fill:#87de87;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect2232"
-       width="200"
-       height="80"
-       x="-100"
-       y="342.36218" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="4.5527229"
-       y="376.9657"
-       id="text2234"><tspan
-         sodipodi:role="line"
-         x="4.5527229"
-         y="376.9657"
-         style="font-size:28px;text-align:center;text-anchor:middle"
-         id="tspan2239">DBUS</tspan><tspan
-         sodipodi:role="line"
-         x="4.5527229"
-         y="411.9657"
-         style="font-size:28px;text-align:center;text-anchor:middle"
-         id="tspan2245">Service</tspan></text>
-    <path
-       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Send);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
-       d="M 89.090907,312.36218 L 50.90909,342.36218"
-       id="path2241"
-       inkscape:connector-type="polyline"
-       inkscape:connection-end="#rect2232"
-       inkscape:connection-start="#rect5369" />
     <path
        style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Send);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;marker-start:url(#Arrow1Sstart)"
        d="M 326.13636,452.36218 L 181.36363,312.36218"
commit a3d455e876a348d76d32389e86168d440e988986
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Apr 24 14:00:42 2009 +0100

    trivial: remove one last file releated to the DBus backends

diff --git a/lib/python/packagekit/Makefile.am b/lib/python/packagekit/Makefile.am
index ecc85ce..6f3e8d4 100644
--- a/lib/python/packagekit/Makefile.am
+++ b/lib/python/packagekit/Makefile.am
@@ -11,7 +11,6 @@ packagekitpython_PYTHON =				\
 	backend.py					\
 	frontend.py					\
 	enums.py					\
-	daemonBackend.py				\
 	pkexceptions.py					\
 	pkdbus.py					\
 	progress.py					\
diff --git a/lib/python/packagekit/daemonBackend.py b/lib/python/packagekit/daemonBackend.py
deleted file mode 100644
index 35ad9f5..0000000
--- a/lib/python/packagekit/daemonBackend.py
+++ /dev/null
@@ -1,1073 +0,0 @@
-# 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.
-
-# Copyright (C) 2007 Tim Lauridsen <timlau at fedoraproject.org>
-#                    Robin Norwood <rnorwood at redhat.com>
-
-#
-# This file contain the base classes to implement a PackageKit python backend
-#
-
-# imports
-import logging
-import logging.handlers
-import os
-import sys
-import threading
-import time
-import traceback
-
-import gobject
-import dbus.service
-
-from enums import *
-from pkexceptions import *
-
-# Setup Logging
-
-logging.basicConfig(format="%(levelname)s:%(message)s")
-pklog = logging.getLogger("PackageKitBackend")
-pklog.setLevel(logging.WARN)
-
-syslog = logging.handlers.SysLogHandler(facility=logging.handlers.SysLogHandler.LOG_DAEMON, address='/dev/log')
-formatter = logging.Formatter('PackageKit: %(levelname)s: %(message)s')
-syslog.setFormatter(formatter)
-pklog.addHandler(syslog)
-
-# Classes
-
-# This is common between backends
-PACKAGEKIT_DBUS_INTERFACE = 'org.freedesktop.PackageKitBackend'
-PACKAGEKIT_DBUS_PATH = '/org/freedesktop/PackageKitBackend'
-
-INACTIVE_CHECK_INTERVAL = 60 # Check every minute
-INACTIVE_TIMEOUT = 5 * 60 # timeout after 5 minutes of inactivity.
-
-def forked(func):
-    '''
-    Decorator to fork a worker process.
-
-    Use a custom doCancel method in your backend to cancel forks:
-
-    def doCancel(self):
-        if self._child_pid:
-            os.kill(self._child_pid, signal.SIGQUIT)
-            self._child_pid = None
-            self.Finished(EXIT_SUCCESS)
-            return
-        self.Finished(EXIT_FAILED)
-    '''
-    def wrapper(*args, **kwargs):
-        self = args[0]
-        self.AllowCancel(True)
-        # Make sure that we are not in the worker process
-        if self._child_pid == 0:
-            pklog.debug("forkme() called from child thread.")
-            raise Exception("forkme() called from child thread.")
-        # Make sure that there is no another child process running
-        retries = 0
-        while self._is_child_running() and retries < 5:
-            pklog.warning("Method called, but a child is already running")
-            time.sleep(0.1)
-            retries += 1
-        if self._is_child_running():
-            self.ErrorCode(ERROR_INTERNAL_ERROR,
-                           "Method called while child process is still "
-                           "running.")
-            raise Exception("Method called while child process is "
-                            "still running")
-        # Fork a worker process
-        self.last_action_time = time.time()
-        self._child_pid = os.fork()
-        if self._child_pid > 0:
-            gobject.child_watch_add(self._child_pid, self.on_child_exit)
-            return
-        self.loop.quit()
-        sys.exit(func(*args, **kwargs))
-    return wrapper
-
-class PackageKitThread(threading.Thread):
-    '''
-    Threading class which can handle crashes. Inspired by
-    http://spyced.blogspot.com/2007/06/workaround-for-sysexcepthook-bug.html
-    '''
-    def run(self):
-        try:
-            threading.Thread.run(self)
-        except (KeyboardInterrupt, SystemExit):
-            raise
-        except:
-            sys.excepthook(*sys.exc_info())
-
-def threaded(func):
-    '''
-    Decorator to run a PackageKitBaseBackend method in a separate thread
-    '''
-    def wrapper(*args, **kwargs):
-        backend = args[0]
-        backend.last_action_time = time.time()
-        thread = PackageKitThread(target=func, args=args, kwargs=kwargs)
-        thread.start()
-    wrapper.__name__ = func.__name__
-    return wrapper
-
-def serialize(func):
-    '''
-    Decorator which makes sure no other threads are running before executing function.
-    '''
-    def wrapper(*args, **kwargs):
-        backend = args[0]
-        backend._lock.acquire()
-        func(*args, **kwargs)
-        backend._lock.release()
-    wrapper.__name__ = func.__name__
-    return wrapper
-
-class PackageKitBaseBackend(dbus.service.Object):
-
-    def PKSignalHouseKeeper(func):
-        def wrapper(*args, **kwargs):
-            self = args[0]
-            self.last_action_time = time.time()
-
-            return func(*args, **kwargs)
-
-        return wrapper
-
-# I tried to do the same thing with methods as we do with signals, but
-# dbus-python's method decorator uses inspect.getargspec...since the
-# signature of the wrapper function is different.  So now each method
-# has to call self.last_action_time = time.time()
-#
-#    def PKMethodHouseKeeper(func):
-#        def wrapper(*args, **kwargs):
-#            self = args[0]
-#            self.last_action_time = time.time()
-#
-#            return func(*args, **kwargs)
-#
-#        return wrapper
-
-    def __init__(self, bus_name, dbus_path):
-        dbus.service.Object.__init__(self, bus_name, dbus_path)
-        sys.excepthook = self._excepthook
-
-        self._allow_cancel = False
-        self._child_pid = None
-        self._is_child = False
-
-        self.loop = gobject.MainLoop()
-
-    def run(self):
-        gobject.timeout_add_seconds(INACTIVE_CHECK_INTERVAL,
-                                    self.check_for_inactivity)
-        self.last_action_time = time.time()
-
-        self.loop.run()
-
-    def check_for_inactivity(self):
-        if time.time() - self.last_action_time > INACTIVE_TIMEOUT and \
-           threading.activeCount() == 1 and \
-           not self.loop.get_context().pending():
-            pklog.info("Exiting due to timeout.")
-            self.Exit()
-            return False
-        return True
-
-    def on_child_exit(self, pid, condition, data):
-        pass
-
-    def _is_child_running(self):
-        pklog.debug("in child_is_running")
-        if self._child_pid:
-            pklog.debug("in child_is_running, pid = %s" % self._child_pid)
-            running = True
-            try:
-                (pid, status) = os.waitpid(self._child_pid, os.WNOHANG)
-                if pid:
-                    running = False
-            except OSError, e:
-                pklog.error("OS Error: %s" % str(e))
-                running = False
-
-            if not running:
-                pklog.debug("child %s is stopped" % self._child_pid)
-                self._child_pid = None
-                return False
-
-            pklog.debug("child still running")
-            return True
-
-        pklog.debug("No child.")
-        return False
-
-#
-# Signals ( backend -> engine -> client )
-#
-
-    @PKSignalHouseKeeper
-    @dbus.service.signal(dbus_interface=PACKAGEKIT_DBUS_INTERFACE,
-                         signature='s')
-    def Finished(self, exit):
-        pklog.info("Finished (%s)" % (exit))
-
-    @PKSignalHouseKeeper
-    @dbus.service.signal(dbus_interface=PACKAGEKIT_DBUS_INTERFACE,
-                         signature='ssb')
-    def RepoDetail(self, repo_id, description, enabled):
-        pklog.info("RepoDetail (%s, %s, %i)" % (repo_id, description, enabled))
-
-    @PKSignalHouseKeeper
-    @dbus.service.signal(dbus_interface=PACKAGEKIT_DBUS_INTERFACE,
-                         signature='b')
-    def AllowCancel(self, allow_cancel):
-        self._allow_cancel = allow_cancel
-        pklog.info("AllowCancel (%i)" % allow_cancel)
-
-    @PKSignalHouseKeeper
-    @dbus.service.signal(dbus_interface=PACKAGEKIT_DBUS_INTERFACE,
-                         signature='sss')
-    def Package(self, status, package_id, summary):
-        pklog.info("Package (%s, %s, %s)" % (status, package_id, summary))
-
-    @PKSignalHouseKeeper
-    @dbus.service.signal(dbus_interface=PACKAGEKIT_DBUS_INTERFACE,
-                         signature='ssssst')
-    def Details(self, package_id, license, group, detail, url, size):
-        pklog.info("Details (%s, %s, %s, %s, %s, %u)" % (package_id, license, group, detail, url, size))
-
-    @PKSignalHouseKeeper
-    @dbus.service.signal(dbus_interface=PACKAGEKIT_DBUS_INTERFACE,
-                         signature='ss')
-    def Files(self, package_id, file_list):
-        pklog.info("Files (%s, %s)" % (package_id, file_list))
-
-    @PKSignalHouseKeeper
-    @dbus.service.signal(dbus_interface=PACKAGEKIT_DBUS_INTERFACE,
-                         signature='s')
-    def StatusChanged(self, status):
-        pklog.info("StatusChanged (%s)" % (status))
-
-    @PKSignalHouseKeeper
-    def NoPercentageUpdates(self):
-        pklog.info("NoPercentageUpdates ()")
-        self.PercentageChanged(101)
-
-    @PKSignalHouseKeeper
-    @dbus.service.signal(dbus_interface=PACKAGEKIT_DBUS_INTERFACE,
-                         signature='u')
-    def PercentageChanged(self, percentage):
-        pklog.info("PercentageChanged (%i)" % (percentage))
-
-    @PKSignalHouseKeeper
-    @dbus.service.signal(dbus_interface=PACKAGEKIT_DBUS_INTERFACE,
-                         signature='u')
-    def SubPercentageChanged(self, percentage):
-        pklog.info("SubPercentageChanged (%i)" % (percentage))
-
-    @PKSignalHouseKeeper
-    @dbus.service.signal(dbus_interface=PACKAGEKIT_DBUS_INTERFACE,
-                         signature='ssssssssssss')
-    def UpdateDetail(self, package_id, updates, obsoletes, vendor_url, bugzilla_url, cve_url, restart, update, changelog, state, issued, updated):
-        pklog.info("UpdateDetail (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)" % (package_id, updates, obsoletes, vendor_url, bugzilla_url, cve_url, restart, update, changelog, state, issued, updated))
-
-    @PKSignalHouseKeeper
-    @dbus.service.signal(dbus_interface=PACKAGEKIT_DBUS_INTERFACE,
-                         signature='ss')
-    def ErrorCode(self, code, description):
-        '''
-        send 'error'
-        @param err: Error Type (ERROR_NO_NETWORK, ERROR_NOT_SUPPORTED, ERROR_INTERNAL_ERROR)
-        @param description: Error description
-        '''
-        pklog.info("ErrorCode (%s, %s)" % (code, description))
-
-    @PKSignalHouseKeeper
-    @dbus.service.signal(dbus_interface=PACKAGEKIT_DBUS_INTERFACE,
-                         signature='ss')
-    def RequireRestart(self, type, details):
-        '''
-        send 'require-restart' signal:
-        @param type:   The level of restart required (system, application, session)
-        @param details:  Optional details about the restart
-        '''
-        pklog.info("RestartRequired (%s, %s)" % (type, details))
-
-    @PKSignalHouseKeeper
-    @dbus.service.signal(dbus_interface=PACKAGEKIT_DBUS_INTERFACE,
-                         signature='ss')
-    def Message(self, type, details):
-        '''
-        send 'message' signal:
-        @param type:   The type of message (warning, notice, daemon)
-        @param details:  Required details about the message
-        '''
-        pklog.info("Message (%s, %s)" % (type, details))
-
-    @PKSignalHouseKeeper
-    @dbus.service.signal(dbus_interface=PACKAGEKIT_DBUS_INTERFACE,
-                         signature='ssss')
-    def EulaRequired(self, eula_id, package_id, vendor_name, license_agreement):
-        '''
-        send 'eula-required' signal:
-        @param eula_id: unique identifier of the EULA agreement
-        @param package_id: the package affected by this agreement
-        @param vendor_name: the freedom hater
-        @param license_agreement: the plain text license agreement
-        '''
-        pklog.info("Eula required (%s, %s, %s, %s)" % (eula_id, package_id,
-                                                    vendor_name,
-                                                    license_agreement))
-
-    @PKSignalHouseKeeper
-    @dbus.service.signal(dbus_interface=PACKAGEKIT_DBUS_INTERFACE,
-                         signature='')
-    def UpdatesChanged(self, typ, fname):
-        '''
-        send 'updates-changed' signal:
-        '''
-        pklog.info("UpdatesChanged ()")
-
-    @PKSignalHouseKeeper
-    @dbus.service.signal(dbus_interface=PACKAGEKIT_DBUS_INTERFACE,
-                         signature='ssssssss')
-    def RepoSignatureRequired(self, id, repo_name, key_url, key_userid, key_id, key_fingerprint, key_timestamp, key_type):
-        '''
-        send 'repo-signature-required' signal:
-        '''
-        pklog.info("RepoSignatureRequired (%s, %s, %s, %s, %s, %s, %s, %s)" %
-                   (id, repo_name, key_url, key_userid, key_id, key_fingerprint, key_timestamp, key_type))
-
-    @PKSignalHouseKeeper
-    @dbus.service.signal(dbus_interface=PACKAGEKIT_DBUS_INTERFACE,
-                         signature='sss')
-    def DistroUpgrade(self, type, name, summary):
-        '''
-        send 'distro-upgrade' signal:
-        @param type:   The type of distro upgrade (e.g. stable or unstable)
-        @param name: Short name of the distribution e.g. Dapper Drake 6.06 LTS
-        @param summary: Multi-line description of the release
-        '''
-        pklog.info("DistroUpgrade (%s, %s, %s)" % (type, name, summary))
-
-#
-# Methods ( client -> engine -> backend )
-#
-# Python inheritence with decorators makes implementing these in the
-# base class and overriding them in child classes very ugly.  So
-# they're commented out here.  Just implement the ones you need in
-# your class, and don't forget the decorators.
-#
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='', out_signature='')
-    def Init(self):
-        pklog.info("Init()")
-        self.doInit()
-
-    def doInit(self):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    # We have to idle add this from self.Exit() so that DBUS gets a chance to reply
-    def _doExitDelay(self):
-        pklog.info("ExitDelay()")
-        self.loop.quit()
-        sys.exit(1)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='', out_signature='')
-    def Exit(self):
-        pklog.info("Exit()")
-        self.doExit()
-
-    def doExit(self):
-        '''
-        Should be replaced in the corresponding backend sub class
-        
-        Call this method at the end to make sure that dbus can still respond
-        gobject.idle_add (self._doExitDelay)
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='ss', out_signature='')
-    def SearchName(self, filters, search):
-        '''
-        Implement the {backend}-search-name functionality
-        '''
-        pklog.info("SearchName()")
-        self.doSearchName(filters, search)
-
-    def doSearchName(self, filters, search):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='s', out_signature='')
-    def GetPackages(self, filters):
-        '''
-        Implement the {backend}-get-packages functionality
-        '''
-        pklog.info("GetPackages()")
-        self.doGetPackages(filters)
-
-    def doGetPackages(self, filters):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='', out_signature='')
-    def Cancel(self):
-        pklog.info("Cancel()")
-        if not self._allow_cancel:
-            self.ErrorCode(ERROR_CANNOT_CANCEL, "Current action cannot be cancelled")
-            self.Finished(EXIT_FAILED)
-            return
-        self.doCancel()
-
-    def doCancel(self):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='ss', out_signature='')
-    def DownloadPackages(self, package_ids, directory):
-        '''
-        Implement the (backend)-download-packages functionality
-        '''
-        pklog.info("DownloadPackages(%s, %s)" % (package_ids, directory))
-        self.doDownloadPackages(package_ids, directory)
-
-    def doDownloadPackages(self, package_ids, directory):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='ss', out_signature='')
-    def SearchDetails(self, filters, key):
-        '''
-        Implement the {backend}-search-details functionality
-        '''
-        pklog.info("SearchDetails(%s, %s)" % (filters, key))
-        self.doSearchDetails(filters, key)
-
-    def doSearchDetails(self, filters, key):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='ss', out_signature='')
-    def SearchGroup(self, filters, key):
-        '''
-        Implement the {backend}-search-group functionality
-        '''
-        pklog.info("SearchGroup(%s, %s)" % (filters, key))
-        self.doSearchGroup(filters, key)
-
-    def doSearchGroup(self, filters, key):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='ss', out_signature='')
-    def SearchFile(self, filters, key):
-        '''
-        Implement the {backend}-search-file functionality
-        '''
-        pklog.info("SearchFile(%s, %s)" % (filters, key))
-        self.doSearchFile(filters, key)
-
-    def doSearchFile(self, filters, key):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='ssb', out_signature='')
-    def GetRequires(self, filters, package_ids, recursive):
-        '''
-        Print a list of requires for a given package
-        '''
-        pklog.info("GetRequires(%s, %s, %s)" % (filters, package_ids, recursive))
-        self.doGetRequires(filters, package_ids , recursive)
-
-    def doGetRequires(self, filters, package_ids, recursive):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='sss', out_signature='')
-    def WhatProvides(self, filters, provides_type, search):
-        '''
-        Print a list of packages for a given provide string
-        '''
-        pklog.info("WhatProvides(%s, %s, %s)" % (filters, provides_type, search))
-        self.doWhatProvides(filters, provides_type, search)
-
-    def doWhatProvides(self, filters, provides_type, search):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='ssb', out_signature='')
-    def GetDepends(self, filters, package_ids, recursive):
-        '''
-        Print a list of depends for a given package
-        '''
-        pklog.info("GetDepends(%s, %s, %s)" % (filters, package_ids, recursive))
-        self.doGetDepends(filters, package_ids, recursive)
-
-    def doGetDepends(self, filters, package_ids, recursive):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='', out_signature='')
-    def UpdateSystem(self):
-        '''
-        Implement the {backend}-update-system functionality
-        '''
-        pklog.info("UpdateSystem()")
-        self.doUpdateSystem()
-
-    def doUpdateSystem(self):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='b', out_signature='')
-    def RefreshCache(self, force):
-        '''
-        Implement the {backend}-refresh_cache functionality
-        '''
-        pklog.info("RefreshCache(%s)" % force)
-        self.doRefreshCache( force)
-
-    def doRefreshCache(self):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='sas', out_signature='')
-    def Resolve(self, filters, names):
-        '''
-        Implement the {backend}-resolve functionality
-        '''
-        pklog.info("Resolve(%s, %s)" % (filters, names))
-        self.doResolve(filters, names)
-
-    def doResolve(self, filters, names):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='as', out_signature='')
-    def InstallPackages(self, package_ids):
-        '''
-        Implement the {backend}-install functionality
-        '''
-        pklog.info("InstallPackages(%s)" % package_ids)
-        self.doInstallPackages(package_ids)
-
-    def doInstallPackages(self, package_ids):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='bas', out_signature='')
-    def InstallFiles (self, trusted, full_paths):
-        '''
-        Implement the {backend}-install_files functionality
-        Install the package containing the full_paths file
-        '''
-        pklog.info("InstallFiles(%i, %s)" % (trusted, full_paths))
-        self.doInstallFiles(trusted, full_paths)
-
-    def doInstallFiles(self, full_paths):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='as', out_signature='')
-    def UpdatePackages(self, package_ids):
-        '''
-        Implement the {backend}-update-packages functionality
-        '''
-        pklog.info("UpdatePackages(%s)" % package_ids)
-        self.doUpdatePackages(package_ids)
-
-    def doUpdatePackages(self, package_ids):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='asbb', out_signature='')
-    def RemovePackages(self, package_ids, allowdep, autoremove):
-        '''
-        Implement the {backend}-remove functionality
-        '''
-        pklog.info("RemovePackages(%s, %s, %s)" % (package_ids, allowdep,
-                                                 autoremove))
-        self.doRemovePackages(package_ids, allowdep, autoremove)
-
-    def doRemovePackages(self, package_ids, allowdep, autoremove):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='s', out_signature='')
-    def GetDetails(self, package_ids):
-        '''
-        Print a detailed details for a given package
-        '''
-        pklog.info("GetDetails(%s)" % package_ids)
-        self.doGetDetails(package_ids)
-
-    def doGetDetails(self, package_ids):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='s', out_signature='')
-    def GetFiles(self, package_ids):
-        '''
-        Implement the get-files method
-        '''
-        pklog.info("GetFiles(%s)" % package_ids)
-        self.doGetFiles(package_ids)
-
-    def doGetFiles(self, package_ids):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='', out_signature='')
-    def GetDistroUpgrades(self):
-        '''
-        Implement the {backend}-get-distro-upgrades functionality
-        '''
-        pklog.info("GetDistroUpgrades()")
-        self.doGetDistroUpgrades()
-
-    def doGetDistroUpgrades(self):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='s', out_signature='')
-    def GetUpdates(self, filters):
-        '''
-        Implement the {backend}-get-updates functionality
-        '''
-        pklog.info("GetUpdates(%s)" % filters)
-        self.doGetUpdates(filters)
-
-    def doGetUpdates(self, filters):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='sb', out_signature='')
-    def RepoEnable(self, repoid, enable):
-        '''
-        Implement the {backend}-repo-enable functionality
-        '''
-        pklog.info("RepoEnable(%s, %s)" % (repoid, enable))
-        self.doRepoEnable( repoid, enable)
-
-    def doRepoEnable(self, repoid, enable):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='', out_signature='')
-    def GetRepoList(self, filters):
-        '''
-        Implement the {backend}-get-repo-list functionality
-        '''
-        pklog.info("GetRepoList()")
-        self.doGetRepoList(filters)
-
-    def doGetRepoList(self, filters):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='s', out_signature='')
-    def GetUpdateDetail(self, package_ids):
-        '''
-        Implement the {backend}-get-update_detail functionality
-        '''
-        pklog.info("GetUpdateDetail(%s)" % package_ids)
-        self.doGetUpdateDetail(package_ids)
-
-    def doGetUpdateDetail(self, package_ids):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='sss', out_signature='')
-    def RepoSetData(self, repoid, parameter, value):
-        '''
-        Implement the {backend}-repo-set-data functionality
-        '''
-        pklog.info("RepoSetData(%s, %s, %s)" % (repoid, parameter, value))
-        self.doRepoSetData(repoid, parameter, value)
-
-    def doRepoSetData(self, repoid, parameter, value):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='ss', out_signature='')
-    def SetProxy(self, proxy_http, proxy_ftp):
-        '''
-        Set the proxy
-        '''
-        pklog.info("SetProxy(%s, %s)" % (proxy_http, proxy_ftp))
-        self.doSetProxy(proxy_http, proxy_ftp)
-
-    def doSetProxy(self, proxy_http, proxy_ftp):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        # do not use Finished() in this method
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='s', out_signature='')
-    def InstallPublicKey(self, keyurl):
-        '''
-        Implement the {backend}-install-public-key functionality
-        '''
-        pklog.info("InstallPublicKey(%s)" % keyurl)
-        self.doInstallPublicKey(keyurl)
-
-    def doInstallPublicKey(self, keyurl):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
-                         in_signature='s', out_signature='')
-    def SetLocale(self, code):
-        '''
-        Allow to set the locale of the backend.
-        '''
-        pklog.info("SetLocale(): %s" % code)
-        self.doSetLocale(code)
-
-    def doSetLocale(self, code):
-        '''
-        Should be replaced in the corresponding backend sub class
-        '''
-        self.ErrorCode(ERROR_NOT_SUPPORTED,
-                       "This function is not implemented in this backend")
-        self.Finished(EXIT_FAILED)
-
-#
-# Utility methods
-#
-
-    def _get_package_id(self, name, version, arch, data):
-        return "%s;%s;%s;%s" % (name, version, arch, data)
-
-    def get_package_from_id(self, id):
-        ''' split up a package id name;ver;arch;data into a tuple
-            containing (name, ver, arch, data)
-        '''
-        return tuple(id.split(';', 4))
-
-    def check_license_field(self, license_field):
-        '''
-        Check the string license_field for free licenses, indicated by
-        their short names as documented at
-        http://fedoraproject.org/wiki/Licensing
-
-        Licenses can be grouped by " or " to indicate that the package
-        can be redistributed under any of the licenses in the group.
-        For instance: GPLv2+ or Artistic or FooLicense.
-
-        Also, if a license ends with "+", the "+" is removed before
-        comparing it to the list of valid licenses.  So if license
-        "FooLicense" is free, then "FooLicense+" is considered free.
-
-        Groups of licenses can be grouped with " and " to indicate
-        that parts of the package are distributed under one group of
-        licenses, while other parts of the package are distributed
-        under another group.  Groups may be wrapped in parenthesis.
-        For instance:
-          (GPLv2+ or Artistic) and (GPL+ or Artistic) and FooLicense.
-
-        At least one license in each group must be free for the
-        package to be considered Free Software.  If the license_field
-        is empty, the package is considered non-free.
-        '''
-
-        groups = license_field.split(" and ")
-
-        if len(groups) == 0:
-            return False
-
-        one_free_group = False
-
-        for group in groups:
-            group = group.replace("(", "")
-            group = group.replace(")", "")
-            licenses = group.split(" or ")
-
-            group_is_free = False
-
-            for license in licenses:
-                license = license.strip()
-
-                if len(license) < 1:
-                    continue
-
-                if license[-1] == "+":
-                    license = license[0:-1]
-
-                if license in PackageKitEnum.free_licenses:
-                    one_free_group = True
-                    group_is_free = True
-                    break
-
-            if group_is_free == False:
-                return False
-
-        if one_free_group == False:
-            return False
-
-        return True
-
-    def _customTracebackHandler(self, exctype):
-        '''
-
-        '''
-        return False
-
-    def _excepthook(self, exctype, excvalue, exctb):
-        '''
-        Handle a crash: try to submit the message to packagekitd and the logger.
-        afterwards shutdown the daemon.
-        '''
-        if (issubclass(exctype, KeyboardInterrupt) or
-            issubclass(exctype, SystemExit)):
-            return
-        if self._customTracebackHandler(exctype):
-            return
-
-        tbtext = ''.join(traceback.format_exception(exctype, excvalue, exctb))
-        try:
-            self.ErrorCode(ERROR_INTERNAL_ERROR, tbtext)
-            self.Finished(EXIT_FAILED)
-        except:
-            pass
-        try:
-            pklog.critical(tbtext)
-        except:
-            pass
-        self.loop.quit()
-        sys.exit(1)
-
-class PackagekitProgress:
-    '''
-    Progress class there controls the total progress of a transaction
-    the transaction is divided in n milestones. the class contains a subpercentage
-    of the current step (milestone n -> n+1) and the percentage of the whole transaction
-
-    Usage:
-
-    from packagekit.backend import PackagekitProgress
-
-    steps = [10, 30, 50, 70] # Milestones in %
-    progress = PackagekitProgress()
-    progress.set_steps(steps)
-    for milestone in range(len(steps)):
-        # do the action is this step
-        for i in range(100):
-            # do some action
-            progress.set_subpercent(i+1)
-            print "progress : %s " % progress.percent
-        progress.step() # step to next milestone
-
-    '''
-
-    #TODO: Add support for elapsed/remaining time
-
-    def __init__(self):
-        self.percent = 0
-        self.steps = []
-        self.current_step = 0
-        self.subpercent = 0
-
-    def set_steps(self, steps):
-        '''
-        Set the steps for the whole transaction
-        @param steps: list of int representing the percentage of each step in the transaction
-        '''
-        self.reset()
-        self.steps = steps
-        self.current_step = 0
-
-    def reset(self):
-        self.percent = 0
-        self.steps = []
-        self.current_step = 0
-        self.subpercent = 0
-
-    def step(self):
-        '''
-        Step to the next step in the transaction
-        '''
-        if self.current_step < len(self.steps)-1:
-            self.current_step += 1
-            self.percent = self.steps[self.current_step]
-            self.subpercent = 0
-        else:
-            self.percent = 100
-            self.subpercent = 0
-
-    def set_subpercent(self, pct):
-        '''
-        Set subpercentage and update percentage
-        '''
-        self.subpercent = pct
-        self._update_percent()
-
-    def _update_percent(self):
-        '''
-        Increment percentage based on current step and subpercentage
-        '''
-        if self.current_step == 0:
-            startpct = 0
-        else:
-            startpct = self.steps[self.current_step-1]
-        if self.current_step < len(self.steps)-1:
-            endpct = self.steps[self.current_step+1]
-        else:
-            endpct = 100
-        deltapct = endpct -startpct
-        f = float(self.subpercent)/100.0
-        incr = int(f*deltapct)
-        self.percent = startpct + incr
commit b576ba19fbd987a30e57ec511e8c4a10277ad2b5
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Apr 24 11:23:41 2009 +0100

    Finish the removal of the CMake build scripts (and fix make dist)

diff --git a/lib/packagekit-qt/Makefile.am b/lib/packagekit-qt/Makefile.am
index e4b4c1b..e7b8b39 100644
--- a/lib/packagekit-qt/Makefile.am
+++ b/lib/packagekit-qt/Makefile.am
@@ -7,6 +7,5 @@ pkgconfig_DATA = 					\
 
 EXTRA_DIST =						\
 	packagekit-qt.pc.in				\
-	CMakeLists.txt					\
 	Doxyfile
 
diff --git a/lib/packagekit-qt/modules/Makefile.am b/lib/packagekit-qt/modules/Makefile.am
index a61e00b..f3dcab7 100644
--- a/lib/packagekit-qt/modules/Makefile.am
+++ b/lib/packagekit-qt/modules/Makefile.am
@@ -4,6 +4,5 @@ cmakemodule_DATA =					\
 	$(NULL)
 
 EXTRA_DIST =						\
-	CMakeLists.txt					\
 	$(cmakemodule_DATA)
 
diff --git a/lib/packagekit-qt/src/Makefile.am b/lib/packagekit-qt/src/Makefile.am
index ff26355..2567b7f 100644
--- a/lib/packagekit-qt/src/Makefile.am
+++ b/lib/packagekit-qt/src/Makefile.am
@@ -82,6 +82,5 @@ clean-local:
 	rm -f $(CLEANFILES)
 
 EXTRA_DIST =							\
-	CMakeLists.txt						\
 	$(NULL)
 
diff --git a/lib/packagekit-qt/src/config.h.cmake b/lib/packagekit-qt/src/config.h.cmake
deleted file mode 100644
index b1114da..0000000
--- a/lib/packagekit-qt/src/config.h.cmake
+++ /dev/null
@@ -1 +0,0 @@
-#cmakedefine USE_SECURITY_POLKIT
diff --git a/lib/packagekit-qt/test/Makefile.am b/lib/packagekit-qt/test/Makefile.am
index 2251653..a380087 100644
--- a/lib/packagekit-qt/test/Makefile.am
+++ b/lib/packagekit-qt/test/Makefile.am
@@ -63,6 +63,3 @@ MAINTAINERCLEANFILES =					\
 	Makefile.in					\
 	$(NULL)
 
-EXTRA_DIST =						\
-	CMakeLists.txt
-
commit 5c3396990ea6e973b239a168828c4ad64c58e91b
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Apr 24 09:45:55 2009 +0100

    yum: disable the refresh-packagekit plugin when running under PackageKit

diff --git a/backends/yum/yumBackend.py b/backends/yum/yumBackend.py
index f5ea431..457b36b 100755
--- a/backends/yum/yumBackend.py
+++ b/backends/yum/yumBackend.py
@@ -2791,6 +2791,16 @@ class PackageKitYumBase(yum.YumBase):
 
     def __init__(self, backend):
         yum.YumBase.__init__(self)
+
+        # disable the PackageKit plugin when running under PackageKit
+        try:
+            pc = self.preconf
+            pc.disabled_plugins = ['refresh-packagekit']
+        except yum.Errors.ConfigError, e:
+            raise PkError(ERROR_REPO_CONFIGURATION_ERROR, _to_unicode(e))
+        except ValueError, e:
+            raise PkError(ERROR_FAILED_CONFIG_PARSING, _to_unicode(e))
+
         self.missingGPGKey = None
         self.dsCallback = DepSolveCallback(backend)
         self.backend = backend
commit 4d32bf2c68142c3899e0a9fd993be6a3ba4c5642
Author: Anders F Bjorklund <afb at users.sourceforge.net>
Date:   Fri Apr 24 10:30:28 2009 +0200

    smart: better download status for slack/arch

diff --git a/backends/smart/smartBackend.py b/backends/smart/smartBackend.py
index d64e9e2..40994ba 100755
--- a/backends/smart/smartBackend.py
+++ b/backends/smart/smartBackend.py
@@ -107,9 +107,12 @@ class PackageKitSmartProgress(Progress):
                     or filename.find('Release') != -1:
                         self._backend.status(STATUS_DOWNLOAD_REPOSITORY)
                     elif filename.find('primary') != -1 \
-                    or filename.find('Packages') != -1:
+                    or filename.find('Packages') != -1 \
+                    or filename.find('PACKAGES.TXT') != -1 \
+                    or filename.find('.db.tar.gz') != -1:
                         self._backend.status(STATUS_DOWNLOAD_PACKAGELIST)
-                    elif filename.find('filelists') != -1:
+                    elif filename.find('filelists') != -1 \
+                    or filename.find('.files.tar.gz') != -1:
                         self._backend.status(STATUS_DOWNLOAD_FILELIST)
                     elif filename.find('other') != -1:
                         self._backend.status(STATUS_DOWNLOAD_CHANGELOG)
commit 2e68f52c1df128bf046f1d3e1bb9d9bdbb87d5ca
Author: Anders F Bjorklund <afb at users.sourceforge.net>
Date:   Fri Apr 24 10:22:42 2009 +0200

    smart: add arch package versioning support

diff --git a/backends/smart/smartBackend.py b/backends/smart/smartBackend.py
index 1555967..d64e9e2 100755
--- a/backends/smart/smartBackend.py
+++ b/backends/smart/smartBackend.py
@@ -946,6 +946,7 @@ class PackageKitSmartBackend(PackageKitBaseBackend):
         from smart.backends.rpm.base import RPMPackage
         from smart.backends.deb.base import DebPackage
         from smart.backends.slack.base import SlackPackage
+        #from smart.backends.arch.base import ArchPackage
         if isinstance(package, RPMPackage):
             name = package.name
             version, arch = package.version.split('@')
@@ -956,7 +957,13 @@ class PackageKitSmartBackend(PackageKitBaseBackend):
             name = package.name
             ver, arch, rel = package.version.rsplit('-')
             version = "%s-%s" % (ver, rel)
+        #elif isinstance(package, ArchPackage):
+        elif package.__class__.__name__ == 'ArchPackage':
+            name = package.name
+            ver, rel, arch = package.version.rsplit('-')
+            version = "%s-%s" % (ver, rel)
         else:
+            name = package.name
             version, arch = package.version, self._machine()
         return name, version, arch
 
@@ -970,6 +977,8 @@ class PackageKitSmartBackend(PackageKitBaseBackend):
                 self.systemchannel = "deb-sys"
             elif "slack-sys" in channels:
                 self.systemchannel = "slack-sys"
+            elif "arch-sys" in channels:
+                self.systemchannel = "arch-sys"
         if self.systemchannel == "rpm-sys":
             pkg = "%s-%s@%s" % (name, version, arch)
         elif self.systemchannel == "deb-sys":
@@ -977,6 +986,9 @@ class PackageKitSmartBackend(PackageKitBaseBackend):
         elif self.systemchannel == "slack-sys":
             ver, rel = version.rsplit("-")
             pkg = "%s-%s-%s-%s" % (name, ver, arch, rel)
+        elif self.systemchannel == "arch-sys":
+            ver, rel = version.rsplit("-")
+            pkg = "%s-%s-%s-%s" % (name, ver, rel, arch)
         else:
             pkg = "%s-%s" % (name, version)
         return pkg
commit ee0618496c7397f1c0ffe8ba78a10e04a61db1c7
Author: Daniel Nicoletti <dantti85-pk at yahoo.com.br>
Date:   Thu Apr 23 22:28:50 2009 -0300

    Packagekit-qt: changed License to QString in package

diff --git a/lib/packagekit-qt/src/package.cpp b/lib/packagekit-qt/src/package.cpp
index bc292eb..e81fb0e 100644
--- a/lib/packagekit-qt/src/package.cpp
+++ b/lib/packagekit-qt/src/package.cpp
@@ -28,7 +28,7 @@ class Package::Details::Private
 {
 public:
 	Package* package;
-	Package::License license;
+	QString license;
 	Client::Group group;
 	QString description;
 	QString url;
@@ -38,7 +38,7 @@ public:
 Package::Details::Details(Package* p, const QString& license, const QString& group, const QString& detail, const QString& url, qulonglong size) : d(new Private)
 {
 	d->package = p;
-	d->license = (License)Util::enumFromString<Package>(license, "License", "License");
+	d->license = license;
 	d->group = (Client::Group)Util::enumFromString<Client>(group, "Group", "Group");
 	d->description = detail;
 	d->url = url;
@@ -55,7 +55,7 @@ Package* Package::Details::package() const
 	return d->package;
 }
 
-Package::License Package::Details::license() const
+QString Package::Details::license() const
 {
 	return d->license;
 }
diff --git a/lib/packagekit-qt/src/package.h b/lib/packagekit-qt/src/package.h
index 8805e4d..7d9f12f 100644
--- a/lib/packagekit-qt/src/package.h
+++ b/lib/packagekit-qt/src/package.h
@@ -140,13 +140,13 @@ public:
 		LicenseCrystalStacker,
 		LicenseDoc,
 		LicenseWtfpl,
-		LicenseLicenseEpl,
+		LicenseEpl,
 		LicenseEcos,
 		LicenseEfl2Dot0,
 		LicenseEu_datagrid,
 		LicenseLgplv2WithExceptions,
 		LicenseFtl,
-		LicenseLicenseGiftware,
+		LicenseGiftware,
 		LicenseGplv2,
 		LicenseGplv2WithExceptions,
 		LicenseGplv2PlusWithExceptions,
@@ -262,7 +262,7 @@ public:
 			/**
 			 * Returns the package's license
 			 */
-			Package::License license() const;
+			QString license() const;
 
 			/**
 			 * Returns the package's group (for example Multimedia, Editors...)
commit b1a2d42253c40d9453d36ee577c1b411edfe1f5c
Author: Adrien BUSTANY <madcat at mymadcat.com>
Date:   Thu Apr 23 16:49:33 2009 +0200

    PackageKit-Qt : Really drop support for CMake :-s

diff --git a/lib/packagekit-qt/modules/CMakeLists.txt b/lib/packagekit-qt/modules/CMakeLists.txt
deleted file mode 100644
index f2e40c6..0000000
--- a/lib/packagekit-qt/modules/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
- 
-## install the cmake files
-
-file( GLOB cmakeFiles FindQPackageKit.cmake )
-set(module_install_dir ${CMAKE_ROOT}/Modules )
-
-install( FILES ${cmakeFiles} 
-         DESTINATION ${module_install_dir}  )
-
diff --git a/lib/packagekit-qt/src/CMakeLists.txt b/lib/packagekit-qt/src/CMakeLists.txt
deleted file mode 100644
index 30f23e1..0000000
--- a/lib/packagekit-qt/src/CMakeLists.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-project(packagekit-qt)
-
-
-include(FindPkgConfig)
-pkg_check_modules(POLKIT polkit-dbus)
-
-if(POLKIT_FOUND)
-	set(USE_SECURITY_POLKIT 1)
-else(POLKIT_FOUND)
-	set(USE_SECURITY_POLKIT 0)
-endif(POLKIT_FOUND)
-configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
-
-include_directories(
-	${QT_INCLUDES}
-	${POLKIT_INCLUDE_DIRS}
-	${CMAKE_SOURCE_DIR}
-	${CMAKE_BINARY_DIR}/src
-)
-
-set( lib_SRCS
-	client.cpp
-	clientprivate.cpp
-	daemonproxy.cpp
-	transaction.cpp
-	transactionprivate.cpp
-	transactionproxy.cpp
-	package.cpp
-	polkitclient.cpp
-	util.cpp
-)
-
-
-QT4_AUTOMOC(${lib_SRCS})
-
-add_library(packagekit-qt SHARED ${lib_SRCS})
-set_target_properties( packagekit-qt PROPERTIES VERSION 4.2 SOVERSION 0 )
-
-target_link_libraries(packagekit-qt
-  ${QT_QTCORE_LIBRARY}
-  ${QT_QTDBUS_LIBRARY}
-  ${QT_QTSQL_LIBRARY}
-  polkit-dbus
-  dbus-1
-)
-
-install(TARGETS
-	packagekit-qt
-	DESTINATION
-	lib${LIB_SUFFIX}
-)
-
-install(FILES
-	client.h
-	transaction.h
-	package.h
-	QPackageKit
-	DESTINATION
-	include/PackageKit/packagekit-qt)
-
diff --git a/lib/packagekit-qt/test/CMakeLists.txt b/lib/packagekit-qt/test/CMakeLists.txt
deleted file mode 100644
index 5cbcd6c..0000000
--- a/lib/packagekit-qt/test/CMakeLists.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-project(pktest)
-
-include(FindPkgConfig)
-pkg_check_modules(POLKIT polkit-dbus)
-
-include_directories(
-	${QT_INCLUDES}
-	${POLKIT_INCLUDE_DIRS}
-	${packagekit-qt_SOURCE_DIR}
-	${CMAKE_BINARY_DIR}/test
-)
-
-link_directories(
-	${packagekit-qt_BUILD_DIR}/src
-)
-
-set( test_SRCS
-	daemontest.cpp
-	transactiontest.cpp
-	main.cpp
-)
-
-QT4_AUTOMOC(${test_SRCS})
-
-add_executable(pktest ${test_SRCS})
-
-target_link_libraries(pktest
-  ${QT_QTCORE_LIBRARY}
-  ${QT_QTDBUS_LIBRARY}
-  polkit-dbus
-  dbus-1
-  cppunit
-  packagekit-qt
-)
-
commit 97bcf99fd0cfde3ef2bfb4603d0439f07ac7673c
Author: Adrien BUSTANY <madcat at mymadcat.com>
Date:   Thu Apr 23 16:48:48 2009 +0200

    PackageKit-Qt : Drop support for building with CMake. CMake module for the lib is still included.

diff --git a/lib/packagekit-qt/CMakeLists.txt b/lib/packagekit-qt/CMakeLists.txt
deleted file mode 100644
index 50a27e4..0000000
--- a/lib/packagekit-qt/CMakeLists.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-cmake_minimum_required(VERSION 2.4.8)
-
-project(packagekit-qt)
-
-set (LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)" )
-
-find_package(Qt4 REQUIRED)
-add_definitions(${QT_DEFINITIONS})
-
-add_subdirectory(src)
-add_subdirectory(modules)
-
-if(BUILD_TESTS)
-	add_subdirectory(test)
-endif(BUILD_TESTS)
commit f3619d6c53873b6e98d6286defbd05bfa735a8ee
Author: Adrien BUSTANY <madcat at mymadcat.com>
Date:   Thu Apr 23 16:46:30 2009 +0200

    PackageKit-Qt : Add support for cancel-foreign policykit action

diff --git a/lib/packagekit-qt/src/common.h b/lib/packagekit-qt/src/common.h
index 8c60f02..af32bbf 100644
--- a/lib/packagekit-qt/src/common.h
+++ b/lib/packagekit-qt/src/common.h
@@ -31,4 +31,5 @@
 #define AUTH_SYSTEM_SOURCES_CONFIGURE		"org.freedesktop.packagekit.system-sources-configure"
 #define AUTH_SYSTEM_SOURCES_REFRESH		"org.freedesktop.packagekit.system-sources-refresh"
 #define AUTH_SYSTEM_NETWORK_PROXY_CONFIGURE	"org.freedesktop.packagekit.system-network-proxy-configure"
+#define AUTH_CANCEL_FOREIGN 			"org.freedesktop.packagekit.cancel-foreign"
 
diff --git a/lib/packagekit-qt/src/transaction.cpp b/lib/packagekit-qt/src/transaction.cpp
index 30cf156..109c9de 100644
--- a/lib/packagekit-qt/src/transaction.cpp
+++ b/lib/packagekit-qt/src/transaction.cpp
@@ -24,6 +24,7 @@
 #include "package.h"
 #include "transactionprivate.h"
 #include "transactionproxy.h"
+#include "polkitclient.h"
 #include "util.h"
 
 using namespace PackageKit;
@@ -100,7 +101,16 @@ bool Transaction::callerActive()
 
 void Transaction::cancel()
 {
-	d->p->Cancel();
+	if (!d->p->Cancel().isValid ()) {
+		// Cancel failed, maybe it's not our transaction and we need authorization
+		if(!PolkitClient::instance()->getAuth(AUTH_CANCEL_FOREIGN)) {
+			// FIXME : should warn somehow here
+			qDebug () << "Authorization to cancel foreign failed";
+			return;
+		}
+
+		d->p->Cancel();
+	}
 }
 
 Package* Transaction::lastPackage()


More information about the PackageKit-commit mailing list