From a02570c1ce80a173563730880f35931d6cbccfcc Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Tue, 28 Oct 2008 21:30:11 +0100 Subject: hal_0.5.11: Move back to the hal directory and make it default for Openmoko hal 0.5.11 is fixing many, many, many memory leaks and is required if someone wants to have the device powered on for more than two days. I heavily encourage other distributions to switch as well. I can not see the autoreconf errors mentioned in koen's move a765a58dfd410eef8147e2e6ad1d0e4cef922c58 he is free to send them to me. I'm using tmp/staging/i686-linux/usr/bin/autoreconf --version autoreconf (GNU Autoconf) 2.61 --- conf/distro/include/preferred-om-2008-versions.inc | 2 +- packages/hal/hal_0.5.11.bb | 4 ++++ packages/nonworking/hal/hal_0.5.11.bb | 4 ---- 3 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 packages/hal/hal_0.5.11.bb delete mode 100644 packages/nonworking/hal/hal_0.5.11.bb diff --git a/conf/distro/include/preferred-om-2008-versions.inc b/conf/distro/include/preferred-om-2008-versions.inc index 3d3c3858e0..43bdc8f259 100644 --- a/conf/distro/include/preferred-om-2008-versions.inc +++ b/conf/distro/include/preferred-om-2008-versions.inc @@ -648,7 +648,7 @@ PREFERRED_VERSION_gvim ?= "7.0" PREFERRED_VERSION_gweled ?= "0.5" PREFERRED_VERSION_gxine ?= "0.4.1enhanced" PREFERRED_VERSION_gzip ?= "1.3.5" -PREFERRED_VERSION_hal ?= "0.5.9" +PREFERRED_VERSION_hal ?= "0.5.11" PREFERRED_VERSION_hal-info ?= "20080508" PREFERRED_VERSION_haserl ?= "0.8.0" PREFERRED_VERSION_havp ?= "0.86" diff --git a/packages/hal/hal_0.5.11.bb b/packages/hal/hal_0.5.11.bb new file mode 100644 index 0000000000..5408756510 --- /dev/null +++ b/packages/hal/hal_0.5.11.bb @@ -0,0 +1,4 @@ +require hal.inc + +SRC_URI += " file://hal-right-input-h.patch;patch=1" +EXTRA_OECONF += "--with-linux-input-header=${STAGING_INCDIR}/linux/input.h" diff --git a/packages/nonworking/hal/hal_0.5.11.bb b/packages/nonworking/hal/hal_0.5.11.bb deleted file mode 100644 index 5408756510..0000000000 --- a/packages/nonworking/hal/hal_0.5.11.bb +++ /dev/null @@ -1,4 +0,0 @@ -require hal.inc - -SRC_URI += " file://hal-right-input-h.patch;patch=1" -EXTRA_OECONF += "--with-linux-input-header=${STAGING_INCDIR}/linux/input.h" -- cgit v1.2.3 From 59fdade6ad1501f59761af8438cd5f80ec0015a4 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Tue, 22 Jul 2008 21:55:19 +0200 Subject: app-restarter: Add the little helper utility to relaunch X11 apps --- conf/distro/include/sane-srcrevs.inc | 1 + packages/openmoko-tools/app-restarter_svn.bb | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 packages/openmoko-tools/app-restarter_svn.bb diff --git a/conf/distro/include/sane-srcrevs.inc b/conf/distro/include/sane-srcrevs.inc index da791ff4c5..8cc03b1744 100644 --- a/conf/distro/include/sane-srcrevs.inc +++ b/conf/distro/include/sane-srcrevs.inc @@ -14,6 +14,7 @@ SRCREV_pn-accelges ?= "206" SRCREV_pn-aircrack-ng ?= "802" SRCREV_pn-alsa-scenario ?= "633aaccc37f845146e490090dbd2a1ebb8064fd6" +SRCREV_pn-app-restarter ?= "4549" SRCREV_pn-assassin ?= "217" SRCREV_pn-assassin-thumbnail ?= "4513" SRCREV_pn-bfin-uclibc ?= "1857" diff --git a/packages/openmoko-tools/app-restarter_svn.bb b/packages/openmoko-tools/app-restarter_svn.bb new file mode 100644 index 0000000000..90ac2b1777 --- /dev/null +++ b/packages/openmoko-tools/app-restarter_svn.bb @@ -0,0 +1,17 @@ +DESCRIPTION = "Small utility to restart a crashing application" +LICENSE = "GPL" + +SRC_URI="svn://svn.openmoko.org/developers/zecke/;module=app_restarter;proto=http" +S = "${WORKDIR}/app_restarter" + +inherit pkgconfig + +do_compile() { + cd ${S} + oe_runmake +} + +do_install() { + install -d ${D}/${bindir} + install -m 0755 ${S}/app_restarter ${D}/${bindir}/${PN} +} -- cgit v1.2.3 From 7434683fdabb5cc28ef98e9b6aa1f0717ea32edd Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 23 Jul 2008 11:38:42 +0200 Subject: sane-srcrevs.inc: Upgrade app-restarter and fix the PV, bump the PE --- conf/distro/include/sane-srcrevs.inc | 2 +- packages/openmoko-tools/app-restarter_svn.bb | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/conf/distro/include/sane-srcrevs.inc b/conf/distro/include/sane-srcrevs.inc index 8cc03b1744..c7dc459cd4 100644 --- a/conf/distro/include/sane-srcrevs.inc +++ b/conf/distro/include/sane-srcrevs.inc @@ -14,7 +14,7 @@ SRCREV_pn-accelges ?= "206" SRCREV_pn-aircrack-ng ?= "802" SRCREV_pn-alsa-scenario ?= "633aaccc37f845146e490090dbd2a1ebb8064fd6" -SRCREV_pn-app-restarter ?= "4549" +SRCREV_pn-app-restarter ?= "4552" SRCREV_pn-assassin ?= "217" SRCREV_pn-assassin-thumbnail ?= "4513" SRCREV_pn-bfin-uclibc ?= "1857" diff --git a/packages/openmoko-tools/app-restarter_svn.bb b/packages/openmoko-tools/app-restarter_svn.bb index 90ac2b1777..c256b41e78 100644 --- a/packages/openmoko-tools/app-restarter_svn.bb +++ b/packages/openmoko-tools/app-restarter_svn.bb @@ -3,6 +3,8 @@ LICENSE = "GPL" SRC_URI="svn://svn.openmoko.org/developers/zecke/;module=app_restarter;proto=http" S = "${WORKDIR}/app_restarter" +PV = "1.0+svn${SRCREV}" +PE = "1" inherit pkgconfig -- cgit v1.2.3 From 1bcbcaea6f28567a7c1b3c928fc256b5720e2da2 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 6 Aug 2008 02:29:49 +0200 Subject: app-restarter: Add X11 to the dependencies. --- packages/openmoko-tools/app-restarter_svn.bb | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/openmoko-tools/app-restarter_svn.bb b/packages/openmoko-tools/app-restarter_svn.bb index c256b41e78..ea71a2533e 100644 --- a/packages/openmoko-tools/app-restarter_svn.bb +++ b/packages/openmoko-tools/app-restarter_svn.bb @@ -1,5 +1,6 @@ DESCRIPTION = "Small utility to restart a crashing application" LICENSE = "GPL" +DEPENDS = "virtual/libx11" SRC_URI="svn://svn.openmoko.org/developers/zecke/;module=app_restarter;proto=http" S = "${WORKDIR}/app_restarter" -- cgit v1.2.3 From cae3aa1ba13e84dc8897111e16efc9d9ac58d6c8 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Wed, 27 Aug 2008 13:37:27 +0100 Subject: app-restarter: fix versions --- packages/openmoko-tools/app-restarter_svn.bb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/openmoko-tools/app-restarter_svn.bb b/packages/openmoko-tools/app-restarter_svn.bb index ea71a2533e..61b68b5173 100644 --- a/packages/openmoko-tools/app-restarter_svn.bb +++ b/packages/openmoko-tools/app-restarter_svn.bb @@ -4,8 +4,8 @@ DEPENDS = "virtual/libx11" SRC_URI="svn://svn.openmoko.org/developers/zecke/;module=app_restarter;proto=http" S = "${WORKDIR}/app_restarter" -PV = "1.0+svn${SRCREV}" -PE = "1" +PV = "1.0+svnr${SRCREV}" +PE = "2" inherit pkgconfig -- cgit v1.2.3 From 12e84f237f6340e2688415dba8bb3204021a38f3 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 6 Aug 2008 02:38:34 +0200 Subject: openmoko: Add a Gtk+ utility to set the root password This utility will be installable through the feed. --- conf/distro/include/sane-srcrevs.inc | 1 + .../openmoko-tools/openmoko-set-root-password.bb | 25 ++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 packages/openmoko-tools/openmoko-set-root-password.bb diff --git a/conf/distro/include/sane-srcrevs.inc b/conf/distro/include/sane-srcrevs.inc index c7dc459cd4..aa0f82322d 100644 --- a/conf/distro/include/sane-srcrevs.inc +++ b/conf/distro/include/sane-srcrevs.inc @@ -147,6 +147,7 @@ SRCREV_pn-openmoko-panel-memory ?= "3903" SRCREV_pn-openmoko-panel-usb ?= "3360" SRCREV_pn-openmoko-panel-wifi ?= "4344" SRCREV_pn-openmoko-sample2 ?= "3537" +SRCREV_pn-openmoko-set-root-password ?= "4590" SRCREV_pn-openmoko-sound-theme-standard2 ?= "4271" SRCREV_pn-openmoko-tasks2 ?= "399" SRCREV_pn-openmoko-terminal2 ?= "4726" diff --git a/packages/openmoko-tools/openmoko-set-root-password.bb b/packages/openmoko-tools/openmoko-set-root-password.bb new file mode 100644 index 0000000000..a521a1fd6d --- /dev/null +++ b/packages/openmoko-tools/openmoko-set-root-password.bb @@ -0,0 +1,25 @@ +DESCRIPTION = "Set the root password." +SUMMARY = "On installation you will be prompted to set a root password. With \ +this password you can then log into the machine." +LICENSE = "GPL" +DEPENDS = "gtk+" +PKG_TAGS_${PN} = "group::programming" + +SRC_URI = "svn://svn.openmoko.org/developers/zecke/;module=root-password;proto=http" +S = "${WORKDIR}/root-password" +PV = "1.0+svn${SRCREV}" + +do_compile () { + cd ${S} + oe_runmake +} + +do_install() { + install -d ${D}/${sbindir} + install -m 0755 ${S}/root-password ${D}/${sbindir}/${PN} +} + +pkg_postinst_${PN} () { + # assume we use display 0 + DISPLAY=:0 ${sbindir}/${PN} +} -- cgit v1.2.3 From c5431547e51cd95e0746e9a7f7727cdb822dedb7 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Wed, 27 Aug 2008 13:37:43 +0100 Subject: openmoko-set-root-password: fix versions --- packages/openmoko-tools/openmoko-set-root-password.bb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/openmoko-tools/openmoko-set-root-password.bb b/packages/openmoko-tools/openmoko-set-root-password.bb index a521a1fd6d..f64c7031c1 100644 --- a/packages/openmoko-tools/openmoko-set-root-password.bb +++ b/packages/openmoko-tools/openmoko-set-root-password.bb @@ -7,7 +7,8 @@ PKG_TAGS_${PN} = "group::programming" SRC_URI = "svn://svn.openmoko.org/developers/zecke/;module=root-password;proto=http" S = "${WORKDIR}/root-password" -PV = "1.0+svn${SRCREV}" +PV = "1.0+svnr${SRCREV}" +PE = "1" do_compile () { cd ${S} -- cgit v1.2.3 From 078b0e63359b8dc61ab95e028b37d8668cdc1671 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sun, 1 Jun 2008 19:17:58 +0200 Subject: xserver-nodm-init: Make sure to set a HOME and LOGNAME when launching Set a HOME and LOGNAME when none is being set. --- packages/xserver-kdrive-common/xserver-nodm-init.bb | 2 +- packages/xserver-kdrive-common/xserver-nodm-init/xserver-nodm | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/xserver-kdrive-common/xserver-nodm-init.bb b/packages/xserver-kdrive-common/xserver-nodm-init.bb index cea9f0cb28..bea21793a6 100644 --- a/packages/xserver-kdrive-common/xserver-nodm-init.bb +++ b/packages/xserver-kdrive-common/xserver-nodm-init.bb @@ -2,7 +2,7 @@ DESCRIPTION = "Simple Xserver Init Script (no dm)" LICENSE = "GPL" SECTION = "x11" PRIORITY = "optional" -PR = "r8" +PR = "r9" SRC_URI = "file://xserver-nodm" S = ${WORKDIR} diff --git a/packages/xserver-kdrive-common/xserver-nodm-init/xserver-nodm b/packages/xserver-kdrive-common/xserver-nodm-init/xserver-nodm index a56edaa15b..2251c6aab2 100755 --- a/packages/xserver-kdrive-common/xserver-nodm-init/xserver-nodm +++ b/packages/xserver-kdrive-common/xserver-nodm-init/xserver-nodm @@ -24,6 +24,9 @@ case "$1" in $0 $1 background & else . /etc/profile + [ -z $LOGNAME ] && export LOGNAME=root && export HOME=/home/root + [ -z $HOME ] && export HOME=/home/$LOGNAME + echo "Starting Xserver" /etc/X11/Xserver & -- cgit v1.2.3 From cc8f1710d3078a49c44183f13b7118d3b73b9785 Mon Sep 17 00:00:00 2001 From: Julian_chu Date: Wed, 30 Jul 2008 16:07:53 +0800 Subject: apmd: Correct the .la file Apmd install the .la file but the content was wrong. It should remove the STAGING path. --- packages/apmd/apmd_3.2.2.bb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/apmd/apmd_3.2.2.bb b/packages/apmd/apmd_3.2.2.bb index 503f830bd9..471ee9ca10 100644 --- a/packages/apmd/apmd_3.2.2.bb +++ b/packages/apmd/apmd_3.2.2.bb @@ -3,7 +3,7 @@ SECTION = "base" PRIORITY = "required" DEPENDS = "libtool-cross" LICENSE = "GPL" -PR = "r11" +PR = "r11.01" SRC_URI = "${DEBIAN_MIRROR}/main/a/apmd/apmd_${PV}.orig.tar.gz \ file://debian.patch;patch=1 \ @@ -55,6 +55,10 @@ do_install() { install -m 0644 ${WORKDIR}/default ${D}${sysconfdir}/default/apmd oe_libinstall -so libapm ${D}${libdir} install -m 0644 apm.h ${D}${includedir} + for i in `find ${D} -name "*.la"` ; do \ + sed -i -e s:${STAGING_LIBDIR}:${libdir}:g $i + sed -i -e s:${STAGING_DIR_HOST}::g $i + done cat ${WORKDIR}/init | sed -e 's,/usr/sbin,${sbindir},g; s,/etc,${sysconfdir},g;' > ${D}${sysconfdir}/init.d/apmd chmod 755 ${D}${sysconfdir}/init.d/apmd -- cgit v1.2.3 From 294c894b7a89c8cc28098a0086fa2d9e8884361b Mon Sep 17 00:00:00 2001 From: John Lee Date: Wed, 3 Sep 2008 17:45:31 +0800 Subject: dropbear: improve dropbear security by listening only on usb0 by default trac #1853, originated by RuiSeabra --- packages/dropbear/dropbear.inc | 7 +++++++ packages/dropbear/dropbear/openmoko/default | 1 + packages/dropbear/dropbear_0.51.bb | 4 ++-- 3 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 packages/dropbear/dropbear/openmoko/default diff --git a/packages/dropbear/dropbear.inc b/packages/dropbear/dropbear.inc index 31edd26cc8..37ce47cba5 100644 --- a/packages/dropbear/dropbear.inc +++ b/packages/dropbear/dropbear.inc @@ -14,6 +14,9 @@ SRC_URI = "\ file://allow-nopw.patch \ file://init \ " +SRC_URI_append_openmoko = "\ + file://default \ +" inherit autotools update-rc.d @@ -56,6 +59,8 @@ do_install() { -e 's,/usr/bin,${bindir},g' \ -e 's,/usr,${prefix},g' > ${D}${sysconfdir}/init.d/dropbear chmod 755 ${D}${sysconfdir}/init.d/dropbear + test -e ${WORKDIR}/default && \ + install -m 0644 ${WORKDIR}/default ${D}${sysconfdir}/default/dropbear } pkg_postinst () { @@ -73,3 +78,5 @@ pkg_postrm_append () { update-alternatives --remove ssh ${bindir}/dropbearmulti update-alternatives --remove scp ${bindir}/dropbearmulti } + +CONFFILES_${PN} += "${sysconfdir}/default/dropbear" diff --git a/packages/dropbear/dropbear/openmoko/default b/packages/dropbear/dropbear/openmoko/default new file mode 100644 index 0000000000..19816b32a6 --- /dev/null +++ b/packages/dropbear/dropbear/openmoko/default @@ -0,0 +1 @@ +DROPBEAR_PORT=`ip addr list usb0 | awk 'BEGIN { FS="[ /]+" } /inet / { print $3 }'`:22 diff --git a/packages/dropbear/dropbear_0.51.bb b/packages/dropbear/dropbear_0.51.bb index 888819c0e5..2566fbbd9b 100644 --- a/packages/dropbear/dropbear_0.51.bb +++ b/packages/dropbear/dropbear_0.51.bb @@ -1,4 +1,4 @@ require dropbear.inc -PR = "r1" +PR = "r1.01" -SRC_URI += "file://no-host-lookup.patch;patch=1" \ No newline at end of file +SRC_URI += "file://no-host-lookup.patch;patch=1" -- cgit v1.2.3 From 4688924045a881a3c1f5ae7cb6ec338f71de1e99 Mon Sep 17 00:00:00 2001 From: John Lee Date: Thu, 4 Sep 2008 14:38:20 +0800 Subject: dropbear: add /etc/default/dropbear in conffiles only on openmoko distro. thanks holger for pointing it out. --- packages/dropbear/dropbear.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dropbear/dropbear.inc b/packages/dropbear/dropbear.inc index 37ce47cba5..168cedbf8a 100644 --- a/packages/dropbear/dropbear.inc +++ b/packages/dropbear/dropbear.inc @@ -79,4 +79,4 @@ pkg_postrm_append () { update-alternatives --remove scp ${bindir}/dropbearmulti } -CONFFILES_${PN} += "${sysconfdir}/default/dropbear" +CONFFILES_${PN}_openmoko += "${sysconfdir}/default/dropbear" -- cgit v1.2.3 From 2f2fce10c427389f819a585fe938bec81f77eef6 Mon Sep 17 00:00:00 2001 From: Julian Chu Date: Mon, 19 May 2008 17:33:59 +0000 Subject: packagekit: Change revision of packagekit. To make it buildable, add a patch to it. In next time we update the packagekit version, this patch doesn't need anymore. ( it should enter in upstream) --- conf/distro/include/sane-srcrevs.inc | 2 +- packages/packagekit/packagekit_git.bb | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/conf/distro/include/sane-srcrevs.inc b/conf/distro/include/sane-srcrevs.inc index aa0f82322d..dba50cb7b3 100644 --- a/conf/distro/include/sane-srcrevs.inc +++ b/conf/distro/include/sane-srcrevs.inc @@ -165,7 +165,7 @@ SRCREV_pn-opkg-sdk ?= "4640" SRCREV_pn-opkg-utils ?= "4534" SRCREV_pn-opkg-utils-native ?= "4534" SRCREV_pn-oprofileui ?= "173" -SRCREV_pn-packagekit ?= "813fa8cfb139246cf180d52895b52b28616ae2f5" +SRCREV_pn-packagekit ?= "ebbbfa191257861bd19bd47ba646dce590b51858" SRCREV_pn-portaudio-v19 ?= "1387" SRCREV_pn-psplash ?= "249" SRCREV_pn-pty-forward-native ?= "4214" diff --git a/packages/packagekit/packagekit_git.bb b/packages/packagekit/packagekit_git.bb index 8e2adff2cf..1d16560186 100644 --- a/packages/packagekit/packagekit_git.bb +++ b/packages/packagekit/packagekit_git.bb @@ -8,7 +8,8 @@ PV = "0.2.3+gitr${SRCREV}" PR = "r9" SRC_URI = "git://anongit.freedesktop.org/git/packagekit;protocol=git \ - file://disable-docbook2man.patch;patch=1" + file://disable-docbook2man.patch;patch=1 \ + file://d1e096c3267c1c9492041382b954e9327bc8bbec.patch;patch=0" S = "${WORKDIR}/git" -- cgit v1.2.3 From 3c2efdd0d3453bd42887895be26a9c76b7ae13f3 Mon Sep 17 00:00:00 2001 From: walkingice Date: Wed, 21 May 2008 14:53:04 +0800 Subject: Modify packagekit to make it patch successful --- packages/packagekit/packagekit_git.bb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/packagekit/packagekit_git.bb b/packages/packagekit/packagekit_git.bb index 1d16560186..ba8f99dc05 100644 --- a/packages/packagekit/packagekit_git.bb +++ b/packages/packagekit/packagekit_git.bb @@ -5,11 +5,11 @@ LICENSE = "GPL" DEPENDS = "dbus (>= 1.1.1) dbus-glib glib-2.0 sqlite3 opkg intltool intltool-native (>= 0.37.1)" RDEPENDS_${PN} = "opkg" PV = "0.2.3+gitr${SRCREV}" -PR = "r9" +PR = "r10" SRC_URI = "git://anongit.freedesktop.org/git/packagekit;protocol=git \ file://disable-docbook2man.patch;patch=1 \ - file://d1e096c3267c1c9492041382b954e9327bc8bbec.patch;patch=0" + file://d1e096c3267c1c9492041382b954e9327bc8bbec.patch;patch=1" S = "${WORKDIR}/git" -- cgit v1.2.3 From b8842ec5493a818e72e0dd8f2e22a998466037c9 Mon Sep 17 00:00:00 2001 From: Julian_chu Date: Mon, 2 Jun 2008 11:19:56 +0800 Subject: packagekit: Add 2 patched for packagekit. New stuff will be: * Added a new error enum to packagekit to support "corrupt-package" message. * Improve the error handling for update and install functions, with new opkg. --- ..._d1e096c3267c1c9492041382b954e9327bc8bbec.patch | 2938 ++++ ..._9ced8313fb12f0f89ad6ced7c0fdc7241ff00d77.patch | 13544 +++++++++++++++++++ .../d1e096c3267c1c9492041382b954e9327bc8bbec.patch | 2938 ---- packages/packagekit/packagekit_git.bb | 6 +- 4 files changed, 16486 insertions(+), 2940 deletions(-) create mode 100644 packages/packagekit/files/01_d1e096c3267c1c9492041382b954e9327bc8bbec.patch create mode 100644 packages/packagekit/files/02_9ced8313fb12f0f89ad6ced7c0fdc7241ff00d77.patch delete mode 100644 packages/packagekit/files/d1e096c3267c1c9492041382b954e9327bc8bbec.patch diff --git a/packages/packagekit/files/01_d1e096c3267c1c9492041382b954e9327bc8bbec.patch b/packages/packagekit/files/01_d1e096c3267c1c9492041382b954e9327bc8bbec.patch new file mode 100644 index 0000000000..f050a50002 --- /dev/null +++ b/packages/packagekit/files/01_d1e096c3267c1c9492041382b954e9327bc8bbec.patch @@ -0,0 +1,2938 @@ +diff --git a/backends/alpm/pk-backend-alpm.c b/backends/alpm/pk-backend-alpm.c +index 3270e42..45e7a44 100644 +--- a/backends/alpm/pk-backend-alpm.c ++++ b/backends/alpm/pk-backend-alpm.c +@@ -895,7 +895,7 @@ backend_get_repo_list (PkBackend *backend, PkFilterEnum filters) + static gboolean + backend_install_files_thread (PkBackend *backend) + { +- pk_backend_no_percentage_updates (backend); ++ pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); + + gchar **full_paths = pk_backend_get_strv (backend, "full_paths"); + +@@ -1050,7 +1050,7 @@ backend_install_packages (PkBackend *backend, gchar **package_ids) + static gboolean + backend_refresh_cache_thread (PkBackend *backend) + { +- pk_backend_no_percentage_updates (backend); ++ pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); + + if (alpm_trans_init (PM_TRANS_TYPE_SYNC, PM_TRANS_FLAG_NOSCRIPTLET, cb_trans_evt, cb_trans_conv, cb_trans_progress) != 0) { + pk_backend_error_code (backend, PK_ERROR_ENUM_TRANSACTION_ERROR, alpm_strerror (pm_errno)); +diff --git a/backends/apt/pk-apt-build-db.cpp b/backends/apt/pk-apt-build-db.cpp +index d47c348..885275d 100644 +--- a/backends/apt/pk-apt-build-db.cpp ++++ b/backends/apt/pk-apt-build-db.cpp +@@ -40,7 +40,7 @@ void apt_build_db(PkBackend * backend, sqlite3 *db) + sqlite3_stmt *package = NULL; + + pk_backend_set_status(backend, PK_STATUS_ENUM_QUERY); +- pk_backend_no_percentage_updates(backend); ++ pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); + + sdir = g_build_filename(_config->Find("Dir").c_str(),_config->Find("Dir::State").c_str(),_config->Find("Dir::State::lists").c_str(), NULL); + dir = g_dir_open(sdir,0,&error); +diff --git a/backends/apt/pk-sqlite-pkg-cache.cpp b/backends/apt/pk-sqlite-pkg-cache.cpp +index 770fcdf..1bf9a50 100644 +--- a/backends/apt/pk-sqlite-pkg-cache.cpp ++++ b/backends/apt/pk-sqlite-pkg-cache.cpp +@@ -81,7 +81,7 @@ sqlite_search_packages_thread (PkBackend *backend) + const gchar *search; + + pk_backend_set_status(backend, PK_STATUS_ENUM_QUERY); +- pk_backend_no_percentage_updates(backend); ++ pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); + type = pk_backend_get_uint (backend, "type"); + search = pk_backend_get_string (backend, "search"); + +@@ -176,7 +176,7 @@ sqlite_get_details_thread (PkBackend *backend) + } + + pk_backend_set_status(backend, PK_STATUS_ENUM_QUERY); +- pk_backend_no_percentage_updates(backend); ++ pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); + + pk_debug("finding %s", pi->name); + +diff --git a/backends/box/pk-backend-box.c b/backends/box/pk-backend-box.c +index b7b8167..9263781 100644 +--- a/backends/box/pk-backend-box.c ++++ b/backends/box/pk-backend-box.c +@@ -138,7 +138,7 @@ backend_find_packages_thread (PkBackend *backend) + filter_box = filter_box | PKG_SEARCH_DETAILS; + } + +- pk_backend_no_percentage_updates (backend); ++ pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); + + db = db_open(); + +diff --git a/backends/dummy/pk-backend-dummy.c b/backends/dummy/pk-backend-dummy.c +index 49d4e5a..2df445e 100644 +--- a/backends/dummy/pk-backend-dummy.c ++++ b/backends/dummy/pk-backend-dummy.c +@@ -254,7 +254,7 @@ static void + backend_get_updates (PkBackend *backend, PkFilterEnum filters) + { + pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY); +- pk_backend_no_percentage_updates (backend); ++ pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); + /* check network state */ + if (!pk_backend_is_online (backend)) { + pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot check when offline"); +@@ -268,6 +268,8 @@ static gboolean + backend_install_timeout (gpointer data) + { + PkBackend *backend = (PkBackend *) data; ++ guint sub_percent; ++ + if (_progress_percentage == 100) { + pk_backend_finished (backend); + return FALSE; +@@ -283,9 +285,18 @@ backend_install_timeout (gpointer data) + pk_backend_package (backend, PK_INFO_ENUM_INSTALLING, + "gtkhtml2-devel;2.19.1-0.fc8;i386;fedora", + "Devel files for gtkhtml"); ++ /* this duplicate package should be ignored */ ++ pk_backend_package (backend, PK_INFO_ENUM_INSTALLING, ++ "gtkhtml2-devel;2.19.1-0.fc8;i386;fedora", NULL); + pk_backend_set_status (backend, PK_STATUS_ENUM_INSTALL); + } +- _progress_percentage += 10; ++ if (_progress_percentage > 30 && _progress_percentage < 50) { ++ sub_percent = ((gfloat) (_progress_percentage - 30.0f) / 20.0f) * 100.0f; ++ pk_backend_set_sub_percentage (backend, sub_percent); ++ } else { ++ pk_backend_set_sub_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); ++ } ++ _progress_percentage += 1; + pk_backend_set_percentage (backend, _progress_percentage); + return TRUE; + } +@@ -348,7 +359,7 @@ backend_install_packages (PkBackend *backend, gchar **package_ids) + pk_backend_package (backend, PK_INFO_ENUM_DOWNLOADING, + "gtkhtml2;2.19.1-4.fc8;i386;fedora", + "An HTML widget for GTK+ 2.0"); +- _signal_timeout = g_timeout_add (1000, backend_install_timeout, backend); ++ _signal_timeout = g_timeout_add (100, backend_install_timeout, backend); + } + + /** +@@ -526,7 +537,7 @@ backend_search_name_timeout (gpointer data) + static void + backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search) + { +- pk_backend_no_percentage_updates (backend); ++ pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); + pk_backend_set_allow_cancel (backend, TRUE); + pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY); + _signal_timeout = g_timeout_add (2000, backend_search_name_timeout, backend); +diff --git a/backends/opkg/pk-backend-opkg.c b/backends/opkg/pk-backend-opkg.c +index ecc97be..7649bab 100644 +--- a/backends/opkg/pk-backend-opkg.c ++++ b/backends/opkg/pk-backend-opkg.c +@@ -155,6 +155,38 @@ pk_opkg_progress_cb (opkg_t *opkg, const opkg_progress_data_t *pdata, void *data + return; + + pk_backend_set_percentage (backend, pdata->percentage); ++ if (pdata->package) ++ { ++ gchar *uid; ++ opkg_package_t *pkg = pdata->package; ++ gint status = PK_INFO_ENUM_UNKNOWN; ++ ++ uid = g_strdup_printf ("%s;%s;%s;", ++ pkg->name, pkg->version, pkg->architecture); ++ ++ if (pdata->action == OPKG_DOWNLOAD) ++ status = PK_INFO_ENUM_DOWNLOADING; ++ else if (pdata->action == OPKG_INSTALL) ++ status = PK_INFO_ENUM_INSTALLING; ++ else if (pdata->action == OPKG_REMOVE) ++ status = PK_INFO_ENUM_REMOVING; ++ ++ pk_backend_package (backend, status, uid, pkg->description); ++ g_free (uid); ++ } ++ ++ switch (pdata->action) ++ { ++ case OPKG_DOWNLOAD: ++ pk_backend_set_status (backend, PK_STATUS_ENUM_DOWNLOAD); ++ break; ++ case OPKG_INSTALL: ++ pk_backend_set_status (backend, PK_STATUS_ENUM_INSTALL); ++ break; ++ case OPKG_REMOVE: ++ pk_backend_set_status (backend, PK_STATUS_ENUM_REMOVE); ++ break; ++ } + } + + static gboolean +@@ -163,8 +195,12 @@ backend_refresh_cache_thread (PkBackend *backend) + int ret; + + ret = opkg_update_package_lists (opkg, pk_opkg_progress_cb, backend); ++ + if (ret) { +- opkg_unknown_error (backend, ret, "Refreshing cache"); ++ if (ret == OPKG_DOWNLOAD_FAILED) ++ pk_backend_error_code (backend, PK_ERROR_ENUM_REPO_NOT_AVAILABLE, NULL); ++ else ++ opkg_unknown_error (backend, ret, "Refreshing cache"); + } + pk_backend_finished (backend); + +@@ -178,7 +214,7 @@ static void + backend_refresh_cache (PkBackend *backend, gboolean force) + { + pk_backend_set_status (backend, PK_STATUS_ENUM_REFRESH_CACHE); +- pk_backend_no_percentage_updates (backend); ++ pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); + + + pk_backend_thread_create (backend, backend_refresh_cache_thread); +@@ -279,7 +315,7 @@ backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *sear + + + pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY); +- pk_backend_no_percentage_updates (backend); ++ pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); + + params = g_new0 (SearchParams, 1); + params->filters = filters; +@@ -301,7 +337,7 @@ backend_search_description (PkBackend *backend, PkFilterEnum filters, const gcha + + + pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY); +- pk_backend_no_percentage_updates (backend); ++ pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); + + params = g_new0 (SearchParams, 1); + params->filters = filters; +@@ -320,7 +356,7 @@ backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *sea + + + pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY); +- pk_backend_no_percentage_updates (backend); ++ pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); + + params = g_new0 (SearchParams, 1); + params->filters = filters; +@@ -337,30 +373,52 @@ static gboolean + backend_install_packages_thread (PkBackend *backend) + { + PkPackageId *pi; +- gint err; +- const gchar *package_id; ++ gint err, i; ++ gchar **package_ids; + +- package_id = pk_backend_get_string (backend, "pkid"); +- pk_backend_package (backend, PK_INFO_ENUM_INSTALLING, package_id, NULL); ++ package_ids = pk_backend_get_strv (backend, "pkids"); + +- pi = pk_package_id_new_from_string (package_id); ++ err = 0; ++ ++ for (i = 0; package_ids[i]; i++) ++ { ++ pk_backend_package (backend, PK_INFO_ENUM_INSTALLING, package_ids[0], NULL); + +- err = opkg_install_package (opkg, pi->name, pk_opkg_progress_cb, backend); +- if (err != 0) +- opkg_unknown_error (backend, err, "Install"); ++ pi = pk_package_id_new_from_string (package_ids[0]); ++ ++ err = opkg_install_package (opkg, pi->name, pk_opkg_progress_cb, backend); ++ switch (err) ++ { ++ case OPKG_NO_ERROR: ++ break; ++ case OPKG_DEPENDANCIES_FAILED: ++ pk_backend_error_code (backend, PK_ERROR_ENUM_DEP_RESOLUTION_FAILED, NULL); ++ break; ++ case OPKG_PACKAGE_ALREADY_INSTALLED: ++ pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_ALREADY_INSTALLED, NULL); ++ break; ++ case OPKG_PACKAGE_NOT_AVAILABLE: ++ pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, NULL); ++ break; ++ default: ++ opkg_unknown_error (backend, err, "Install"); ++ } ++ pk_package_id_free (pi); ++ if (err != 0) ++ break; ++ } + +- pk_package_id_free (pi); + pk_backend_finished (backend); + return (err == 0); + } + + static void +-backend_install_packages (PkBackend *backend, gchar **package_id) ++backend_install_packages (PkBackend *backend, gchar **package_ids) + { +- pk_backend_no_percentage_updates (backend); ++ pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); + pk_backend_set_status (backend, PK_STATUS_ENUM_INSTALL); + +- pk_backend_set_string (backend, "pkid", package_id[0]); ++ pk_backend_set_strv (backend, "pkids", package_ids); + + pk_backend_thread_create (backend, backend_install_packages_thread); + } +@@ -369,7 +427,7 @@ static gboolean + backend_remove_packages_thread (PkBackend *backend) + { + PkPackageId *pi; +- gint err; ++ gint err, i; + gchar **package_ids; + gboolean allow_deps; + gboolean autoremove; +@@ -382,19 +440,34 @@ backend_remove_packages_thread (PkBackend *backend) + autoremove = GPOINTER_TO_INT (data[2]); + g_free (data); + +- pi = pk_package_id_new_from_string (package_ids[0]); +- pk_backend_package (backend, PK_INFO_ENUM_REMOVING, package_ids[0], NULL); +- + opkg_set_option (opkg, "autoremove", &autoremove); + opkg_set_option (opkg, "force_removal_of_dependent_packages", &allow_deps); + +- err = opkg_remove_package (opkg, pi->name, pk_opkg_progress_cb, backend); ++ err = 0; + +- /* TODO: improve error reporting */ +- if (err != 0) +- opkg_unknown_error (backend, err, "Remove"); ++ for (i = 0; package_ids[i]; i++) ++ { ++ pi = pk_package_id_new_from_string (package_ids[0]); ++ pk_backend_package (backend, PK_INFO_ENUM_REMOVING, package_ids[0], NULL); ++ ++ err = opkg_remove_package (opkg, pi->name, pk_opkg_progress_cb, backend); ++ ++ switch (err) ++ { ++ case OPKG_NO_ERROR: ++ break; ++ case OPKG_PACKAGE_NOT_INSTALLED: ++ pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED, NULL); ++ break; ++ default: ++ opkg_unknown_error (backend, err, "Remove"); ++ } ++ pk_package_id_free (pi); ++ ++ if (err != 0) ++ break; ++ } + +- pk_package_id_free (pi); + pk_backend_finished (backend); + return (err == 0); + } +@@ -405,7 +478,7 @@ backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow + gpointer *params; + + pk_backend_set_status (backend, PK_STATUS_ENUM_REMOVE); +- pk_backend_no_percentage_updates (backend); ++ pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); + + /* params is a small array we can pack our thread parameters into */ + params = g_new0 (gpointer, 2); +@@ -450,7 +523,7 @@ static void + backend_update_system (PkBackend *backend) + { + pk_backend_set_status (backend, PK_STATUS_ENUM_UPDATE); +- pk_backend_no_percentage_updates (backend); ++ pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); + + pk_backend_thread_create (backend, backend_update_system_thread); + } +@@ -478,8 +551,14 @@ backend_update_package_thread (PkBackend *backend) + } + + err = opkg_upgrade_package (opkg, pi->name, pk_opkg_progress_cb, backend); +- +- if (err != 0) { ++ switch (err) ++ { ++ case OPKG_NO_ERROR: ++ break; ++ case OPKG_PACKAGE_NOT_INSTALLED: ++ pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED, NULL); ++ break; ++ default: + opkg_unknown_error (backend, err, "Update package"); + } + +@@ -494,7 +573,7 @@ backend_update_packages (PkBackend *backend, gchar **package_ids) + gint i; + + pk_backend_set_status (backend, PK_STATUS_ENUM_UPDATE); +- pk_backend_no_percentage_updates (backend); ++ pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); + + for (i = 0; package_ids[i]; i++) { + pk_backend_set_string (backend, "pkgid", package_ids[i]); +@@ -536,7 +615,7 @@ static void + backend_get_updates (PkBackend *backend, PkFilterEnum filters) + { + pk_backend_set_status (backend, PK_STATUS_ENUM_UPDATE); +- pk_backend_no_percentage_updates (backend); ++ pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); + + pk_backend_thread_create (backend, backend_get_updates_thread); + } +@@ -572,19 +651,26 @@ backend_get_details_thread (PkBackend *backend) + if (pi == NULL) + { + pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "invalid package id"); +- pk_package_id_free (pi); ++ pk_backend_finished (backend); + return FALSE; + } + + + pkg = opkg_find_package (opkg, pi->name, pi->version, pi->arch, pi->data); ++ pk_package_id_free (pi); ++ ++ if (!pkg) ++ { ++ pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, NULL); ++ pk_backend_finished (backend); ++ return FALSE; ++ } + + newid = g_strdup_printf ("%s;%s;%s;%s", pkg->name, pkg->version, pkg->architecture, pkg->repository); + + pk_backend_details (backend, newid, NULL, 0, pkg->description, pkg->url, pkg->size); + + g_free (newid); +- pk_package_id_free (pi); + pk_backend_finished (backend); + return TRUE; + } +@@ -592,7 +678,7 @@ backend_get_details_thread (PkBackend *backend) + static void + backend_get_details (PkBackend *backend, const gchar *package_id) + { +- pk_backend_no_percentage_updates (backend); ++ pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); + pk_backend_thread_create (backend, backend_get_details_thread); + } + +diff --git a/backends/test/pk-backend-test-dbus.c b/backends/test/pk-backend-test-dbus.c +index 5dfea32..76686dc 100644 +--- a/backends/test/pk-backend-test-dbus.c ++++ b/backends/test/pk-backend-test-dbus.c +@@ -36,7 +36,7 @@ static void + backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search) + { + pk_backend_set_allow_cancel (backend, TRUE); +- pk_backend_no_percentage_updates (backend); ++ pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); + pk_backend_dbus_search_name (dbus, filters, search); + } + +diff --git a/backends/test/pk-backend-test-spawn.c b/backends/test/pk-backend-test-spawn.c +index 2958c05..584f44c 100644 +--- a/backends/test/pk-backend-test-spawn.c ++++ b/backends/test/pk-backend-test-spawn.c +@@ -35,7 +35,7 @@ backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *sear + { + gchar *filters_text; + pk_backend_set_allow_cancel (backend, TRUE); +- pk_backend_no_percentage_updates (backend); ++ pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); + filters_text = pk_filter_enums_to_text (filters); + pk_backend_spawn_helper (spawn, "search-name.sh", filters_text, search, NULL); + g_free (filters_text); +diff --git a/backends/test/pk-backend-test-succeed.c b/backends/test/pk-backend-test-succeed.c +index 17cdc6e..c046c1d 100644 +--- a/backends/test/pk-backend-test-succeed.c ++++ b/backends/test/pk-backend-test-succeed.c +@@ -236,7 +236,7 @@ backend_search_name_timeout (gpointer data) + static void + backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search) + { +- pk_backend_no_percentage_updates (backend); ++ pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); + g_timeout_add (200000, backend_search_name_timeout, backend); + } + +diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py +index f76e27c..5b2da8f 100644 +--- a/backends/yum/helpers/yumBackend.py ++++ b/backends/yum/helpers/yumBackend.py +@@ -801,6 +801,8 @@ class PackageKitYumBackend(PackageKitBaseBackend): + old_throttle = self.yumbase.conf.throttle + self.yumbase.conf.throttle = "60%" # Set bandwidth throttle to 60% + # to avoid taking all the system's bandwidth. ++ old_skip_broken = self.yumbase.conf.skip_broken ++ self.yumbase.conf.skip_broken = 1 + + try: + txmbr = self.yumbase.update() # Add all updates to Transaction +@@ -812,6 +814,7 @@ class PackageKitYumBackend(PackageKitBaseBackend): + self.error(ERROR_NO_PACKAGES_TO_UPDATE,"Nothing to do") + + self.yumbase.conf.throttle = old_throttle ++ self.yumbase.conf.skip_broken = old_skip_broken + + def refresh_cache(self): + ''' +@@ -905,7 +908,7 @@ class PackageKitYumBackend(PackageKitBaseBackend): + if txmbrs: + self._runYumTransaction() + else: +- self.error(ERROR_PACKAGE_ALREADY_INSTALLED,"This package could not be installed as it is already installed") ++ self.error(ERROR_PACKAGE_ALREADY_INSTALLED,"The package is already installed") + + def _checkForNewer(self,po): + pkgs = self.yumbase.pkgSack.returnNewestByName(name=po.name) +@@ -1003,7 +1006,7 @@ class PackageKitYumBackend(PackageKitBaseBackend): + return False + + if self._is_inst(po): +- self.error(ERROR_PACKAGE_ALREADY_INSTALLED, "%s is already installed" % str(po)) ++ self.error(ERROR_PACKAGE_ALREADY_INSTALLED, "The package %s is already installed" % str(po)) + return False + + if len(self.yumbase.conf.exclude) > 0: +diff --git a/backends/yum2/helpers/testyum2.py b/backends/yum2/helpers/testyum2.py +index cdec507..85b47f9 100755 +--- a/backends/yum2/helpers/testyum2.py ++++ b/backends/yum2/helpers/testyum2.py +@@ -80,7 +80,7 @@ try: + #iface.GetPackages(FILTER_INSTALLED,'no') + if cmd == 'get-repolist' or cmd == 'all': + print "Testing GetRepoList()" +- iface.GetRepoList() ++ iface.GetRepoList("") + if cmd == 'get-updatedetail' or cmd == 'all': + print "Testing GetUpdateDetail(PKG_ID)" + iface.GetUpdateDetail(PKG_ID) +diff --git a/backends/yum2/helpers/yumDBUSBackend.py b/backends/yum2/helpers/yumDBUSBackend.py +index 9cfed94..29f5b03 100755 +--- a/backends/yum2/helpers/yumDBUSBackend.py ++++ b/backends/yum2/helpers/yumDBUSBackend.py +@@ -434,7 +434,7 @@ class PackageKitYumBackend(PackageKitBaseBackend): + try: + pkgGroupDict = self._buildGroupDict() + fltlist = filters.split(';') +- found = {} ++ installed_nevra = [] # yum returns packages as available even when installed + + if not FILTER_NOT_INSTALLED in fltlist: + # Check installed for group +@@ -450,21 +450,31 @@ class PackageKitYumBackend(PackageKitBaseBackend): + group = groupMap[cg] # use the pk group name, instead of yum 'category/group' + if group == key: + if self._do_extra_filtering(pkg, fltlist): +- self._show_package(pkg, INFO_INSTALLED) ++ package_list.append((pkg,INFO_INSTALLED)) ++ installed_nevra.append(self._get_nevra(pkg)) ++ + if not FILTER_INSTALLED in fltlist: + # Check available for group + for pkg in self.yumbase.pkgSack: + if self._cancel_check("Search cancelled."): + # _cancel_check() sets the error message, unlocks yum, and calls Finished() + return +- group = GROUP_OTHER +- if pkgGroupDict.has_key(pkg.name): +- cg = pkgGroupDict[pkg.name] +- if groupMap.has_key(cg): +- group = groupMap[cg] +- if group == key: +- if self._do_extra_filtering(pkg, fltlist): +- self._show_package(pkg, INFO_AVAILABLE) ++ ++ nevra = self._get_nevra(pkg) ++ if nevra not in installed_nevra: ++ group = GROUP_OTHER ++ if pkgGroupDict.has_key(pkg.name): ++ cg = pkgGroupDict[pkg.name] ++ if groupMap.has_key(cg): ++ group = groupMap[cg] ++ if group == key: ++ if self._do_extra_filtering(pkg, fltlist): ++ package_list.append((pkg,INFO_AVAILABLE)) ++ ++ except yum.Errors.GroupsError,e: ++ self._unlock_yum() ++ self.ErrorCode(ERROR_GROUP_NOT_FOUND, str(e)) ++ self.Finished(EXIT_FAILED) + except yum.Errors.RepoError,e: + self.Message(MESSAGE_NOTICE, "The package cache is invalid and is being rebuilt.") + self._refresh_yum_cache() +@@ -473,6 +483,14 @@ class PackageKitYumBackend(PackageKitBaseBackend): + + return + ++ # basename filter if specified ++ if FILTER_BASENAME in fltlist: ++ for (pkg,status) in self._basename_filter(package_list): ++ self._show_package(pkg,status) ++ else: ++ for (pkg,status) in package_list: ++ self._show_package(pkg,status) ++ + self._unlock_yum() + self.Finished(EXIT_SUCCESS) + +@@ -724,6 +742,11 @@ class PackageKitYumBackend(PackageKitBaseBackend): + #we might have a rounding error + self.PercentageChanged(100) + ++ except yum.Errors.RepoError,e: ++ self._unlock_yum() ++ self.ErrorCode(ERROR_REPO_CONFIGURATION_ERROR,str(e)) ++ self.Finished(EXIT_FAILED) ++ self.Exit() + except yum.Errors.YumBaseError, e: + self._unlock_yum() + # This should be a better-defined error, but I'm not sure +@@ -837,6 +860,7 @@ class PackageKitYumBackend(PackageKitBaseBackend): + Needed to be implemented in a sub class + ''' + if inst_file.endswith('.src.rpm'): ++ self._unlock_yum() + self.ErrorCode(ERROR_CANNOT_INSTALL_SOURCE_PACKAGE,'Backend will not install a src rpm file') + self.Finished(EXIT_FAILED) + return +@@ -1385,30 +1409,30 @@ class PackageKitYumBackend(PackageKitBaseBackend): + res = self.yumbase.searchGenerator(searchlist, [key]) + fltlist = filters.split(';') + +- available = [] +- count = 1 ++ seen_nevra = [] # yum returns packages as available even when installed ++ pkg_list = [] # only do the second iteration on not installed pkgs ++ package_list = [] #we can't do emitting as found if we are post-processing ++ + for (pkg,values) in res: + if self._cancel_check("Search cancelled."): + return False + # are we installed? + if pkg.repo.id == 'installed': +- if FILTER_NOT_INSTALLED not in fltlist: +- if self._do_extra_filtering(pkg,fltlist): +- count+=1 +- if count > 100: +- break +- self._show_package(pkg, INFO_INSTALLED) ++ if self._do_extra_filtering(pkg,fltlist): ++ package_list.append((pkg,INFO_INSTALLED)) ++ seen_nevra.append(self._get_nevra(pkg)) + else: +- available.append(pkg) ++ pkg_list.append(pkg) + +- # Now show available packages. +- if FILTER_INSTALLED not in fltlist: +- for pkg in available: +- if self._cancel_check("Search cancelled."): +- return False +- if self._do_extra_filtering(pkg,fltlist): +- self._show_package(pkg, INFO_AVAILABLE) ++ for pkg in pkg_list: ++ if self._cancel_check("Search cancelled."): ++ return False + ++ nevra = self._get_nevra(pkg) ++ if nevra not in seen_nevra: ++ if self._do_extra_filtering(pkg,fltlist): ++ package_list.append((pkg,INFO_AVAILABLE)) ++ seen_nevra.append(self._get_nevra(pkg)) + except yum.Errors.RepoError,e: + self.Message(MESSAGE_NOTICE, "The package cache is invalid and is being rebuilt.") + self._refresh_yum_cache() +@@ -1417,13 +1441,22 @@ class PackageKitYumBackend(PackageKitBaseBackend): + + return False + ++ # basename filter if specified ++ if FILTER_BASENAME in fltlist: ++ for (pkg,status) in self._basename_filter(package_list): ++ self._show_package(pkg,status) ++ else: ++ for (pkg,status) in package_list: ++ self._show_package(pkg,status) ++ + return True + + def _do_extra_filtering(self,pkg,filterList): + ''' do extra filtering (gui,devel etc) ''' + for filter in filterList: + if filter in (FILTER_INSTALLED, FILTER_NOT_INSTALLED): +- continue ++ if not self._do_installed_filtering(filter,pkg): ++ return False + elif filter in (FILTER_GUI, FILTER_NOT_GUI): + if not self._do_gui_filtering(filter, pkg): + return False +@@ -1433,11 +1466,17 @@ class PackageKitYumBackend(PackageKitBaseBackend): + elif filter in (FILTER_FREE, FILTER_NOT_FREE): + if not self._do_free_filtering(filter, pkg): + return False +- elif filter in (FILTER_BASENAME, FILTER_NOT_BASENAME): +- if not self._do_basename_filtering(filter, pkg): +- return False + return True + ++ def _do_installed_filtering(self,flt,pkg): ++ isInstalled = False ++ if flt == FILTER_INSTALLED: ++ wantInstalled = True ++ else: ++ wantInstalled = False ++ isInstalled = pkg.repo.id == 'installed' ++ return isInstalled == wantInstalled ++ + def _do_gui_filtering(self,flt,pkg): + isGUI = False + if flt == FILTER_GUI: +@@ -1477,32 +1516,7 @@ class PackageKitYumBackend(PackageKitBaseBackend): + + return isFree == wantFree + +- def _do_basename_filtering(self,flt,pkg): +- if flt == FILTER_BASENAME: +- wantBase = True +- else: +- wantBase = False +- +- isBase = self._check_basename(pkg) +- +- return isBase == wantBase + +- def _check_basename(self, pkg): +- ''' +- If a package does not have a source rpm (If that ever +- happens), or it does have a source RPM, and the package's name +- is the same as the source RPM's name, then we assume it is the +- 'base' package. +- ''' +- basename = pkg.name +- +- if pkg.sourcerpm: +- basename = rpmUtils.miscutils.splitFilename(pkg.sourcerpm)[0] +- +- if basename == pkg.name: +- return True +- +- return False + + def _is_development_repo(self, repo): + if repo.endswith('-debuginfo'): +@@ -1576,28 +1590,41 @@ class PackageKitYumBackend(PackageKitBaseBackend): + ''' + find a package based on a package id (name;version;arch;repoid) + ''' +- # Split up the id +- (n,idver,a,d) = self.get_package_from_id(id) +- # get e,v,r from package id version +- e,v,r = self._getEVR(idver) ++ # is this an real id or just an name ++ if len(id.split(';')) > 1: ++ # Split up the id ++ (n,idver,a,d) = self.get_package_from_id(id) ++ # get e,v,r from package id version ++ e,v,r = self._getEVR(idver) ++ else: ++ n = id ++ e = v = r = a = None + # search the rpmdb for the nevra + pkgs = self.yumbase.rpmdb.searchNevra(name=n,epoch=e,ver=v,rel=r,arch=a) +- # if the package is found, then return it ++ # if the package is found, then return it (do not have to match the repo_id) + if len(pkgs) != 0: + return pkgs[0],True + # search the pkgSack for the nevra +- pkgs = self.yumbase.pkgSack.searchNevra(name=n,epoch=e,ver=v,rel=r,arch=a) +- # if the package is found, then return it +- if len(pkgs) != 0: +- return pkgs[0],False +- else: ++ try: ++ pkgs = self.yumbase.pkgSack.searchNevra(name=n,epoch=e,ver=v,rel=r,arch=a) ++ except yum.Errors.RepoError,e: ++ self.error(ERROR_REPO_NOT_AVAILABLE,str(e)) ++ # nothing found ++ if len(pkgs) == 0: + return None,False ++ # one NEVRA in a single repo ++ if len(pkgs) == 1: ++ return pkgs[0],False ++ # we might have the same NEVRA in multiple repos, match by repo name ++ for pkg in pkgs: ++ if d == pkg.repoid: ++ return pkg,False ++ # repo id did not match ++ return None,False + + def _is_inst(self,pkg): + return self.yumbase.rpmdb.installed(po=pkg) + +- +- + def _installable(self, pkg, ematch=False): + + """check if the package is reasonably installable, true/false""" +@@ -1764,6 +1791,57 @@ class PackageKitYumBackend(PackageKitBaseBackend): + return INFO_ENHANCEMENT + else: + return INFO_UNKNOWN ++ def _is_main_package(self,repo): ++ if repo.endswith('-debuginfo'): ++ return False ++ if repo.endswith('-devel'): ++ return False ++ if repo.endswith('-libs'): ++ return False ++ return True ++ ++ def _basename_filter(self,package_list): ++ ''' ++ Filter the list so that the number of packages are reduced. ++ This is done by only displaying gtk2 rather than gtk2-devel, gtk2-debuginfo, etc. ++ This imlementation is done by comparing the SRPM name, and if not falling back ++ to the first entry. ++ We have to fall back else we don't emit packages where the SRPM does not produce a ++ RPM with the same name, for instance, mono produces mono-core, mono-data and mono-winforms. ++ @package_list: a (pkg,status) list of packages ++ A new list is returned that has been filtered ++ ''' ++ base_list = [] ++ output_list = [] ++ base_list_already_got = [] ++ ++ #find out the srpm name and add to a new array of compound data ++ for (pkg,status) in package_list: ++ if pkg.sourcerpm: ++ base = rpmUtils.miscutils.splitFilename(pkg.sourcerpm)[0] ++ base_list.append ((pkg,status,base,pkg.version)); ++ else: ++ base_list.append ((pkg,status,'nosrpm',pkg.version)); ++ ++ #find all the packages that match thier basename name (done seporately so we get the "best" match) ++ for (pkg,status,base,version) in base_list: ++ if base == pkg.name and (base,version) not in base_list_already_got: ++ output_list.append((pkg,status)) ++ base_list_already_got.append ((base,version)) ++ ++ #for all the ones not yet got, can we match against a non devel match? ++ for (pkg,status,base,version) in base_list: ++ if (base,version) not in base_list_already_got: ++ if self._is_main_package(pkg.name): ++ output_list.append((pkg,status)) ++ base_list_already_got.append ((base,version)) ++ ++ #add the remainder of the packages, which should just be the single debuginfo's ++ for (pkg,status,base,version) in base_list: ++ if (base,version) not in base_list_already_got: ++ output_list.append((pkg,status)) ++ base_list_already_got.append ((base,version)) ++ return output_list + + def _get_obsoleted(self,name): + obsoletes = self.yumbase.up.getObsoletesTuples( newest=1 ) +diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp +index 746da82..15c4b4f 100644 +--- a/backends/zypp/pk-backend-zypp.cpp ++++ b/backends/zypp/pk-backend-zypp.cpp +@@ -1170,7 +1170,7 @@ backend_find_packages_thread (PkBackend *backend) + mode = pk_backend_get_uint (backend, "mode"); + + pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY); +- pk_backend_no_percentage_updates (backend); ++ pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); + + std::vector *v = new std::vector; + std::vector *v2 = new std::vector; +diff --git a/client/pk-console.c b/client/pk-console.c +index 8f69068..5a05a8e 100644 +--- a/client/pk-console.c ++++ b/client/pk-console.c +@@ -50,7 +50,7 @@ static gboolean awaiting_space = FALSE; + static gboolean trusted = TRUE; + static guint timer_id = 0; + static guint percentage_last = 0; +-static gchar *filename = NULL; ++static gchar **files_cache = NULL; + static PkControl *control = NULL; + static PkClient *client = NULL; + static PkClient *client_task = NULL; +@@ -494,6 +494,12 @@ pk_console_perhaps_resolve (PkClient *client, PkFilterEnum filter, const gchar * + return g_strdup (package); + } + ++ ret = pk_client_reset (client_task, error); ++ if (ret == FALSE) { ++ pk_warning ("failed to reset client task"); ++ return NULL; ++ } ++ + /* we need to resolve it */ + ret = pk_client_resolve (client_task, filter, package, error); + if (ret == FALSE) { +@@ -549,20 +555,93 @@ pk_console_perhaps_resolve (PkClient *client, PkFilterEnum filter, const gchar * + } + + /** +- * pk_console_install_package: ++ * pk_console_install_stuff: + **/ + static gboolean +-pk_console_install_package (PkClient *client, const gchar *package, GError **error) ++pk_console_install_stuff (PkClient *client, gchar **packages, GError **error) + { +- gboolean ret; +- gchar *package_id; +- package_id = pk_console_perhaps_resolve (client, PK_FILTER_ENUM_NOT_INSTALLED, package, error); +- if (package_id == NULL) { +- g_print ("%s\n", _("Could not find a package with that name to install, or package already installed")); +- return FALSE; ++ gboolean ret = TRUE; ++ gboolean is_local; ++ gchar *package_id = NULL; ++ gchar **package_ids = NULL; ++ gchar **files = NULL; ++ guint i; ++ guint length; ++ GPtrArray *array_packages; ++ GPtrArray *array_files; ++ ++ array_packages = g_ptr_array_new (); ++ array_files = g_ptr_array_new (); ++ length = g_strv_length (packages); ++ for (i=2; ilen > 0) { ++ /* convert to strv */ ++ package_ids = pk_ptr_array_to_argv (array_packages); ++ ++ /* reset */ ++ ret = pk_client_reset (client, error); ++ if (!ret) { ++ pk_warning ("failed to reset"); ++ goto out; ++ } ++ ++ ret = pk_client_install_package (client, package_id, error); ++ if (!ret) { ++ pk_warning ("failed to install packages"); ++ goto out; ++ } ++ } ++ ++ /* any to process? */ ++ if (array_files->len > 0) { ++ /* convert to strv */ ++ files = pk_ptr_array_to_argv (array_files); ++ ++ /* save for untrusted callback */ ++ g_strfreev (files_cache); ++ files_cache = g_strdupv (files); ++ ++ /* reset */ ++ ret = pk_client_reset (client, error); ++ if (!ret) { ++ pk_warning ("failed to reset"); ++ goto out; ++ } ++ ++ ret = pk_client_install_files (client, trusted, files, error); ++ if (!ret) { ++ pk_warning ("failed to install files"); ++ goto out; ++ } ++ } ++ ++out: ++ g_strfreev (package_ids); ++ g_strfreev (files); ++ g_ptr_array_free (array_files, TRUE); ++ g_ptr_array_free (array_packages, TRUE); + return ret; + } + +@@ -570,16 +649,16 @@ pk_console_install_package (PkClient *client, const gchar *package, GError **err + * pk_console_remove_only: + **/ + static gboolean +-pk_console_remove_only (PkClient *client, const gchar *package_id, gboolean force, gboolean autoremove, GError **error) ++pk_console_remove_only (PkClient *client, gchar **package_ids, gboolean force, GError **error) + { + gboolean ret; + +- pk_debug ("remove %s", package_id); ++ pk_debug ("remove+ %s", package_ids[0]); + ret = pk_client_reset (client, error); + if (!ret) { + return ret; + } +- return pk_client_remove_package (client, package_id, force, autoremove, error); ++ return pk_client_remove_packages (client, package_ids, force, FALSE, error); + } + + /** +@@ -625,64 +704,99 @@ pk_console_get_prompt (const gchar *question, gboolean defaultyes) + } + + /** +- * pk_console_remove_package: ++ * pk_console_remove_packages: + **/ + static gboolean +-pk_console_remove_package (PkClient *client, const gchar *package, GError **error) ++pk_console_remove_packages (PkClient *client, gchar **packages, GError **error) + { + gchar *package_id; +- gboolean ret; +- guint length; ++ gboolean ret = TRUE; + PkPackageItem *item; + PkPackageId *ident; +- guint i; ++ guint i, j; ++ guint size; ++ guint length; + gboolean remove; ++ GPtrArray *array; ++ gchar **package_ids = NULL; ++ PkPackageList *list; ++ ++ array = g_ptr_array_new (); ++ list = pk_package_list_new (); ++ length = g_strv_length (packages); ++ for (i=2; ipackage_id); + g_print ("%i\t%s-%s\n", i, ident->name, ident->version); + pk_package_id_free (ident); +@@ -694,14 +808,17 @@ pk_console_remove_package (PkClient *client, const gchar *package, GError **erro + /* we chickened out */ + if (remove == FALSE) { + g_print ("%s\n", _("Cancelled!")); +- g_free (package_id); +- return FALSE; ++ ret = FALSE; ++ goto out; + } + + /* remove all the stuff */ +- ret = pk_console_remove_only (client, package_id, TRUE, FALSE, error); +- g_free (package_id); ++ ret = pk_console_remove_only (client, package_ids, TRUE, error); + ++out: ++ g_object_unref (list); ++ g_strfreev (package_ids); ++ g_ptr_array_free (array, TRUE); + return ret; + } + +@@ -840,7 +957,7 @@ pk_console_error_code_cb (PkClient *client, PkErrorCodeEnum error_code, const gc + error_code == PK_ERROR_ENUM_MISSING_GPG_SIGNATURE && trusted) { + pk_debug ("need to try again with trusted FALSE"); + trusted = FALSE; +- ret = pk_client_install_file (client_install_files, trusted, filename, &error); ++ ret = pk_client_install_files (client_install_files, trusted, files_cache, &error); + /* we succeeded, so wait for the requeue */ + if (!ret) { + pk_warning ("failed to install file second time: %s", error->message); +@@ -1153,7 +1270,6 @@ main (int argc, char *argv[]) + const gchar *value = NULL; + const gchar *details = NULL; + const gchar *parameter = NULL; +- PkRoleEnum roles; + PkGroupEnum groups; + gchar *text; + ret = FALSE; +@@ -1324,15 +1440,7 @@ main (int argc, char *argv[]) + g_print (_("You need to specify a package or file to install")); + goto out; + } +- /* is it a local file? */ +- ret = g_file_test (value, G_FILE_TEST_EXISTS); +- if (ret) { +- ret = pk_client_install_file (client, trusted, value, &error); +- /* we need this for the untrusted try */ +- filename = g_strdup (value); +- } else { +- ret = pk_console_install_package (client, value, &error); +- } ++ ret = pk_console_install_stuff (client, argv, &error); + + } else if (strcmp (mode, "install-sig") == 0) { + if (value == NULL || details == NULL || parameter == NULL) { +@@ -1346,7 +1454,7 @@ main (int argc, char *argv[]) + g_print (_("You need to specify a package to remove")); + goto out; + } +- ret = pk_console_remove_package (client, value, &error); ++ ret = pk_console_remove_packages (client, argv, &error); + + } else if (strcmp (mode, "accept-eula") == 0) { + if (value == NULL) { +@@ -1465,9 +1573,9 @@ main (int argc, char *argv[]) + ret = pk_client_get_packages (client, filters, &error); + + } else if (strcmp (mode, "get-actions") == 0) { +- roles = pk_control_get_actions (control); + text = pk_role_enums_to_text (roles); +- g_print ("roles=%s\n", text); ++ g_strdelimit (text, ";", '\n'); ++ g_print ("%s\n", text); + g_free (text); + maybe_sync = FALSE; + /* these can never fail */ +@@ -1476,7 +1584,8 @@ main (int argc, char *argv[]) + } else if (strcmp (mode, "get-filters") == 0) { + filters = pk_control_get_filters (control); + text = pk_filter_enums_to_text (filters); +- g_print ("filters=%s\n", text); ++ g_strdelimit (text, ";", '\n'); ++ g_print ("%s\n", text); + g_free (text); + maybe_sync = FALSE; + /* these can never fail */ +@@ -1485,7 +1594,8 @@ main (int argc, char *argv[]) + } else if (strcmp (mode, "get-groups") == 0) { + groups = pk_control_get_groups (control); + text = pk_group_enums_to_text (groups); +- g_print ("groups=%s\n", text); ++ g_strdelimit (text, ";", '\n'); ++ g_print ("%s\n", text); + g_free (text); + maybe_sync = FALSE; + /* these can never fail */ +@@ -1525,7 +1635,7 @@ out: + g_free (options_help); + g_free (filter); + g_free (summary); +- g_free (filename); ++ g_strfreev (files_cache); + g_object_unref (control); + g_object_unref (client); + g_object_unref (client_task); +diff --git a/configure.ac b/configure.ac +index 9d734e1..f614d2b 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -535,7 +535,7 @@ if test x$enable_box = xyes; then + fi + + if test x$enable_opkg = xyes; then +- PKG_CHECK_MODULES(OPKG, libopkg = 0.1.3) ++ PKG_CHECK_MODULES(OPKG, libopkg = 0.1.4) + AC_SUBST(OPKG_CFLAGS) + AC_SUBST(OPKG_LIBS) + fi +diff --git a/contrib/yum-packagekit/refresh-packagekit.py b/contrib/yum-packagekit/refresh-packagekit.py +index 9c0bdf4..b440539 100644 +--- a/contrib/yum-packagekit/refresh-packagekit.py ++++ b/contrib/yum-packagekit/refresh-packagekit.py +@@ -35,7 +35,7 @@ def posttrans_hook(conduit): + '/org/freedesktop/PackageKit') + packagekit_iface = dbus.Interface(packagekit_proxy, 'org.freedesktop.PackageKit') + packagekit_iface.StateHasChanged('posttrans') +- except dbus.DBusException, e: ++ except Exception, e: + conduit.info(2, "Unable to send message to PackageKit") + conduit.info(6, "%s" %(e,)) + +diff --git a/data/tests/Makefile.am b/data/tests/Makefile.am +index d15dd6c..6935e66 100644 +--- a/data/tests/Makefile.am ++++ b/data/tests/Makefile.am +@@ -5,6 +5,7 @@ NULL = + + TEST_FILES = \ + pk-spawn-test.sh \ ++ pk-spawn-proxy.sh \ + pk-spawn-test-sigquit.sh \ + pk-spawn-test-profiling.sh \ + $(NULL) +diff --git a/data/tests/pk-spawn-proxy.sh b/data/tests/pk-spawn-proxy.sh +new file mode 100755 +index 0000000..57774f1 +--- /dev/null ++++ b/data/tests/pk-spawn-proxy.sh +@@ -0,0 +1,20 @@ ++#!/bin/bash ++# Copyright (C) 2008 Richard Hughes ++# 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. ++ ++if [ -z "${http_proxy}" ]; then ++ echo "no http proxy" ++ exit 1 ++fi ++ ++if [ -z "${ftp_proxy}" ]; then ++ echo "no ftp proxy" ++ exit 1 ++fi ++ ++echo -e "percentage\t100" ++ +diff --git a/docs/html/index.html b/docs/html/index.html +index 7270eb7..d60f825 100644 +--- a/docs/html/index.html ++++ b/docs/html/index.html +@@ -9,9 +9,9 @@ + + + +- ++ + +- ++ + +
[img]

PackageKit Main Page

[img]
+ +@@ -20,10 +20,10 @@ + + + +- +- +- +- ++ ++ ++ ++ + + + +@@ -32,10 +32,10 @@ + + + +- +- +- +- ++ ++ ++ ++ + + + +diff --git a/docs/html/pk-authors.html b/docs/html/pk-authors.html +index 08289ad..607a7a4 100644 +--- a/docs/html/pk-authors.html ++++ b/docs/html/pk-authors.html +@@ -9,9 +9,9 @@ + +
[img][img][img][img]

What is
PackageKit?

Screenshots

[img][img][img][img]

Who develops
PackageKit?

+ +- ++ + +- ++ + +
[img]

Who develops PackageKit?

[img]
+ +@@ -22,7 +22,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+- [img] ++ + +

Richard Hughes

+@@ -48,7 +48,7 @@ + +
+- [img] ++ + +

Ken VanDine

+@@ -66,7 +66,7 @@ + +
+- [img] ++ + +

Boyd Timothy

+@@ -84,7 +84,7 @@ + +
+- [img] ++ + +

Robin Norwood

+@@ -101,7 +101,7 @@ + +
+- [img] ++ + +

Tom Parker

+@@ -118,7 +118,7 @@ + +
+- [img] ++ + +

Tim Lauridsen

+@@ -139,7 +139,7 @@ + +
+- [img] ++ + +

Luke Macken

+@@ -154,7 +154,7 @@ + +
+- [img] ++ + +

Grzegorz Dąbrowski

+@@ -173,7 +173,7 @@ + +
+- [img] ++ + +

S.Çağlar Onur

+@@ -195,7 +195,7 @@ + +
+- [img] ++ + +

Elliot Peele

+@@ -210,7 +210,7 @@ + +
+- [img] ++ + +

James Bowes

+@@ -227,7 +227,7 @@ + +
+- [img] ++ + +

Thomas Wood

+@@ -247,7 +247,7 @@ + +
+- [img] ++ + +

Scott Reeves

+diff --git a/docs/html/pk-bugs.html b/docs/html/pk-bugs.html +index 89f7c48..2ee12ea 100644 +--- a/docs/html/pk-bugs.html ++++ b/docs/html/pk-bugs.html +@@ -9,9 +9,9 @@ + + + +- ++ + +- ++ + +
[img]

Reporting Bugs

[img]
+ +diff --git a/docs/html/pk-download.html b/docs/html/pk-download.html +index 6f796b8..0cdc85c 100644 +--- a/docs/html/pk-download.html ++++ b/docs/html/pk-download.html +@@ -9,9 +9,9 @@ + + + +- ++ + +- ++ + +
[img]

Where can I download it?

[img]
+ +diff --git a/docs/html/pk-faq.html b/docs/html/pk-faq.html +index a25e2b7..efa8344 100644 +--- a/docs/html/pk-faq.html ++++ b/docs/html/pk-faq.html +@@ -9,9 +9,9 @@ + + + +- ++ + +- ++ + +
[img]

Frequently Asked Questions

[img]
+ +@@ -22,6 +22,7 @@ +

Table Of Contents

+
+ +
++

When run as root, gpk-application and pkcon do not work!

++

++GTK+ tools should not be run as the root user, PERIOD. ++Any GTK+ program run as the root user is a massive security hole -- GTK+ just isn't designed with ++this in mind. ++There are numerous attack vectors when running as root, and programs shouldn't do such ++insane and insecure things. ++

++

++Please see the GTK+ explanation for more rationale. ++

++ ++
+

Why is there a session service and and a system service?

+

+ PackageKit runs a process packagekitd that is a daemon that runs per-system. +diff --git a/docs/html/pk-help.html b/docs/html/pk-help.html +index 5b44d50..5bc7827 100644 +--- a/docs/html/pk-help.html ++++ b/docs/html/pk-help.html +@@ -9,9 +9,9 @@ + + + +- ++ + +- ++ + +
[img]

How can I help?

[img]
+ +@@ -72,9 +72,9 @@ as for instructions! + 0.2.2 - To be released June 2008 +

+
    +-
  • Multiple package install and remove from pkcon (0%)
  • ++
  • Network proxy server support (70%)
  • ++
  • Multiple package install and remove from pkcon (80%)
  • +
  • NetworkManager integration so we can detect GPRS (and modem) connections. (10%)
  • +-
  • Filter for source packages. (0%)
  • +
+

+ 0.2.3 - To be released July 2008 +@@ -84,6 +84,12 @@ as for instructions! +

  • Multiple package installs from gpk-application (0%)
  • +
  • Ignoring packages from the update viewer per-session (10%)
  • + ++

    ++0.3.0 - To be released December 2008 ++

    ++
      ++
    • More composite types s to as (0%)
    • ++
    + +

    Back to the main page

    + +diff --git a/docs/html/pk-intro.html b/docs/html/pk-intro.html +index c42be21..64f72fc 100644 +--- a/docs/html/pk-intro.html ++++ b/docs/html/pk-intro.html +@@ -9,9 +9,9 @@ + + + +- ++ + +- ++ + +
    [img]

    What is PackageKit?

    [img]
    + +diff --git a/docs/html/pk-screenshots.html b/docs/html/pk-screenshots.html +index 78bd01f..5c7d4fa 100644 +--- a/docs/html/pk-screenshots.html ++++ b/docs/html/pk-screenshots.html +@@ -9,9 +9,9 @@ + + + +- ++ + +- ++ + +
    [img]

    Screenshots

    [img]
    + +@@ -26,77 +26,77 @@ + +

    GNOME Screenshots

    + +-
    [img]
    ++
    +

    Add/Remove Software search

    + +-
    [img]
    ++
    +

    Add/Remove Software groups

    + +-
    [img]
    ++
    +

    Transaction viewer

    + +-
    [img]
    ++
    +

    Update viewer overview

    + +-
    [img]
    ++
    +

    Update viewer

    + +-
    [img]
    ++
    +

    Auto update preferences

    + +-
    [img]
    ++
    +

    Progress dialog

    + +-
    [img]
    ++
    +

    Added check warning

    + +-
    [img]
    ++
    +

    EULA dialog

    + +-
    [img]
    ++
    +

    Remove check warning

    + +-
    [img]
    ++
    +

    Repository authentication

    + +-
    [img]
    ++
    +

    Repository viewer

    + +-
    [img]
    ++
    +

    PackageKit backend status

    + +-
    [img]
    ++
    +

    Libnotify updates warning

    + +-
    [img]
    ++
    +

    Tasks waiting

    + +-
    [img]
    ++
    +

    Intergration with gnome-power-manager

    + +-
    [img]
    ++
    +

    Inhibit with gnome-power-manager

    + +-
    [img]
    ++
    +

    We sometimes need to do a restart

    + +-
    [img]
    ++
    +

    Auto update install dialog

    + +

    KDE Screenshots

    + +-
    [img]
    ++
    +

    KPackageKit Searching

    + +-
    [img]
    ++
    +

    KPackageKit Package Information

    + +-
    [img]
    ++
    +

    OpenSuse Updater

    + +

    OpenMoko Screenshots

    + +-
    [img]
    ++
    +

    Assassin

    + +

    Back to the main page

    +diff --git a/docs/html/pk-using.html b/docs/html/pk-using.html +index cc455c7..b2b028e 100644 +--- a/docs/html/pk-using.html ++++ b/docs/html/pk-using.html +@@ -9,9 +9,9 @@ + + + +- ++ + +- ++ + +
    [img]

    How do I use PackageKit?

    [img]
    + +diff --git a/docs/spec/pk-concepts.xml b/docs/spec/pk-concepts.xml +index 312c5a4..0b75b10 100644 +--- a/docs/spec/pk-concepts.xml ++++ b/docs/spec/pk-concepts.xml +@@ -127,6 +127,13 @@ + This allows the used to choose non-native packages if a multi-lib policy is allowed. + + ++ ++ source or ~source ++ ++ The source filter will only return source packages. ++ These are typically useful when rebuilding other packages. ++ ++ + + + +diff --git a/etc/PackageKit.conf.in b/etc/PackageKit.conf.in +index a6af99b..8f9bd57 100644 +--- a/etc/PackageKit.conf.in ++++ b/etc/PackageKit.conf.in +@@ -31,3 +31,13 @@ ShutdownTimeout=300 + # default=@defaultbackend@ + DefaultBackend=@defaultbackend@ + ++# Proxy settings, uncomment as required ++# ++# NOTE: PackageKit does not use these settings, they are passed to backends. ++# Backends may ignore these values, or they may be updated from the session. ++# ++# They are in the format username:password@server:port ++# ++# ProxyHTTP=username:password@server.lan:8080 ++# ProxyFTP=username:password@server.lan:21 ++ +diff --git a/libpackagekit/Makefile.am b/libpackagekit/Makefile.am +index 6b8c6b8..aeafe44 100644 +--- a/libpackagekit/Makefile.am ++++ b/libpackagekit/Makefile.am +@@ -37,6 +37,7 @@ libpackagekit_include_HEADERS = \ + pk-connection.h \ + pk-package-id.h \ + pk-package-ids.h \ ++ pk-package-item.h \ + pk-package-list.h \ + pk-enum.h \ + pk-common.h \ +@@ -59,6 +60,8 @@ libpackagekit_la_SOURCES = \ + pk-package-id.h \ + pk-package-ids.c \ + pk-package-ids.h \ ++ pk-package-item.c \ ++ pk-package-item.h \ + pk-package-list.c \ + pk-package-list.h \ + pk-enum.h \ +diff --git a/libpackagekit/pk-enum.c b/libpackagekit/pk-enum.c +index b5b6ac3..5743dcb 100644 +--- a/libpackagekit/pk-enum.c ++++ b/libpackagekit/pk-enum.c +@@ -193,6 +193,8 @@ static PkEnumMatch enum_filter[] = { + {PK_FILTER_ENUM_NOT_NEWEST, "~newest"}, + {PK_FILTER_ENUM_ARCH, "arch"}, + {PK_FILTER_ENUM_NOT_ARCH, "~arch"}, ++ {PK_FILTER_ENUM_SOURCE, "source"}, ++ {PK_FILTER_ENUM_NOT_SOURCE, "~source"}, + {0, NULL} + }; + +diff --git a/libpackagekit/pk-enum.h b/libpackagekit/pk-enum.h +index 33e8a91..e616b64 100644 +--- a/libpackagekit/pk-enum.h ++++ b/libpackagekit/pk-enum.h +@@ -182,7 +182,9 @@ typedef enum { + PK_FILTER_ENUM_NOT_NEWEST = 1 << 15, + PK_FILTER_ENUM_ARCH = 1 << 16, + PK_FILTER_ENUM_NOT_ARCH = 1 << 17, +- PK_FILTER_ENUM_UNKNOWN = 1 << 18 ++ PK_FILTER_ENUM_SOURCE = 1 << 18, ++ PK_FILTER_ENUM_NOT_SOURCE = 1 << 19, ++ PK_FILTER_ENUM_UNKNOWN = 1 << 20 + } PkFilterEnum; + + /** +diff --git a/libpackagekit/pk-package-item.c b/libpackagekit/pk-package-item.c +new file mode 100644 +index 0000000..87905dc +--- /dev/null ++++ b/libpackagekit/pk-package-item.c +@@ -0,0 +1,190 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- ++ * ++ * Copyright (C) 2007-2008 Richard Hughes ++ * ++ * Licensed under the GNU General Public License Version 2 ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++/** ++ * SECTION:pk-package-item ++ * @short_description: A cached Package structure ++ * ++ * These provide a way to query and store a single package. ++ */ ++ ++#include "config.h" ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#ifdef HAVE_UNISTD_H ++#include ++#endif /* HAVE_UNISTD_H */ ++ ++#include ++ ++#include "pk-debug.h" ++#include "pk-common.h" ++#include "pk-package-item.h" ++ ++/** ++ * pk_package_item_new: ++ **/ ++PkPackageItem * ++pk_package_item_new (PkInfoEnum info, const gchar *package_id, const gchar *summary) ++{ ++ PkPackageItem *item; ++ ++ g_return_val_if_fail (package_id != NULL, FALSE); ++ ++ pk_debug ("adding to cache item package %s, %s, %s", pk_info_enum_to_text (info), package_id, summary); ++ item = g_new0 (PkPackageItem, 1); ++ item->info = info; ++ item->package_id = g_strdup (package_id); ++ item->summary = g_strdup (summary); ++ return item; ++} ++ ++/** ++ * pk_package_item_free: ++ **/ ++gboolean ++pk_package_item_free (PkPackageItem *item) ++{ ++ if (item == NULL) { ++ return FALSE; ++ } ++ g_free (item->package_id); ++ g_free (item->summary); ++ g_free (item); ++ return TRUE; ++} ++ ++/** ++ * pk_package_item_equal: ++ * ++ * Only compares the package_id's and the info enum ++ **/ ++gboolean ++pk_package_item_equal (PkPackageItem *item1, PkPackageItem *item2) ++{ ++ if (item1 == NULL || item2 == NULL) { ++ return FALSE; ++ } ++ return (item1->info == item2->info && ++ pk_strequal (item1->package_id, item2->package_id)); ++} ++ ++/** ++ * pk_package_item_copy: ++ * ++ * Copy a PkPackageItem ++ **/ ++PkPackageItem * ++pk_package_item_copy (PkPackageItem *item) ++{ ++ g_return_val_if_fail (item != NULL, NULL); ++ return pk_package_item_new (item->info, item->package_id, item->summary); ++} ++ ++/*************************************************************************** ++ *** MAKE CHECK TESTS *** ++ ***************************************************************************/ ++#ifdef PK_BUILD_TESTS ++#include ++ ++void ++libst_package_item (LibSelfTest *test) ++{ ++ PkPackageItem *item1; ++ PkPackageItem *item2; ++ PkPackageItem *item3; ++ gboolean ret; ++ ++ if (libst_start (test, "PkPackageItem", CLASS_AUTO) == FALSE) { ++ return; ++ } ++ ++ /************************************************************/ ++ libst_title (test, "add entry"); ++ item1 = pk_package_item_new (PK_INFO_ENUM_INSTALLED, "gnome;1.23;i386;data", "GNOME!"); ++ if (item1 != NULL) { ++ libst_success (test, NULL); ++ } else { ++ libst_failed (test, NULL); ++ } ++ ++ /************************************************************/ ++ libst_title (test, "add entry"); ++ item2 = pk_package_item_new (PK_INFO_ENUM_INSTALLED, "gnome;1.23;i386;data", "GNOME foo!"); ++ if (item2 != NULL) { ++ libst_success (test, NULL); ++ } else { ++ libst_failed (test, NULL); ++ } ++ ++ /************************************************************/ ++ libst_title (test, "copy entry"); ++ item3 = pk_package_item_copy (item2); ++ if (item3 != NULL) { ++ libst_success (test, NULL); ++ } else { ++ libst_failed (test, NULL); ++ } ++ ++ /************************************************************/ ++ libst_title (test, "check equal"); ++ ret = pk_package_item_equal (item1, item3); ++ if (ret) { ++ libst_success (test, NULL); ++ } else { ++ libst_failed (test, NULL); ++ } ++ ++ pk_package_item_free (item2); ++ pk_package_item_free (item3); ++ ++ /************************************************************/ ++ libst_title (test, "add entry"); ++ item2 = pk_package_item_new (PK_INFO_ENUM_INSTALLED, "gnome-do;1.23;i386;data", "GNOME doo!"); ++ if (item2 != NULL) { ++ libst_success (test, NULL); ++ } else { ++ libst_failed (test, NULL); ++ } ++ ++ /************************************************************/ ++ libst_title (test, "check !equal"); ++ ret = pk_package_item_equal (item1, item2); ++ if (!ret) { ++ libst_success (test, NULL); ++ } else { ++ libst_failed (test, NULL); ++ } ++ ++ pk_package_item_free (item1); ++ pk_package_item_free (item2); ++ ++ libst_end (test); ++} ++#endif ++ +diff --git a/libpackagekit/pk-package-item.h b/libpackagekit/pk-package-item.h +new file mode 100644 +index 0000000..c41a6ea +--- /dev/null ++++ b/libpackagekit/pk-package-item.h +@@ -0,0 +1,48 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- ++ * ++ * Copyright (C) 2008 Richard Hughes ++ * ++ * Licensed under the GNU General Public License Version 2 ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++#ifndef __PK_PACKAGE_ITEM_H ++#define __PK_PACKAGE_ITEM_H ++ ++#include ++#include ++ ++/** ++ * PkPackageItem: ++ * ++ * A cached store for the complete Package object ++ */ ++typedef struct { ++ PkInfoEnum info; ++ gchar *package_id; ++ gchar *summary; ++} PkPackageItem; ++ ++PkPackageItem *pk_package_item_new (PkInfoEnum info, ++ const gchar *package_id, ++ const gchar *summary); ++gboolean pk_package_item_free (PkPackageItem *item); ++PkPackageItem *pk_package_item_copy (PkPackageItem *item); ++gboolean pk_package_item_equal (PkPackageItem *item1, ++ PkPackageItem *item2); ++ ++#endif /* __PK_PACKAGE_ITEM_H */ ++ +diff --git a/libpackagekit/pk-package-list.c b/libpackagekit/pk-package-list.c +index b0a1a71..5d95e1b 100644 +--- a/libpackagekit/pk-package-list.c ++++ b/libpackagekit/pk-package-list.c +@@ -45,6 +45,7 @@ + #include "pk-debug.h" + #include "pk-common.h" + #include "pk-package-id.h" ++#include "pk-package-item.h" + #include "pk-package-list.h" + + static void pk_package_list_class_init (PkPackageListClass *klass); +@@ -77,16 +78,42 @@ pk_package_list_add (PkPackageList *plist, PkInfoEnum info, const gchar *package + g_return_val_if_fail (package_id != NULL, FALSE); + + pk_debug ("adding to cache array package %s, %s, %s", pk_info_enum_to_text (info), package_id, summary); +- item = g_new0 (PkPackageItem, 1); +- item->info = info; +- item->package_id = g_strdup (package_id); +- item->summary = g_strdup (summary); ++ item = pk_package_item_new (info, package_id, summary); + g_ptr_array_add (plist->priv->array, item); + + return TRUE; + } + + /** ++ * pk_package_list_add_item: ++ * ++ * Makes a deep copy, and adds to the array ++ **/ ++gboolean ++pk_package_list_add_item (PkPackageList *plist, PkPackageItem *item) ++{ ++ gboolean ret; ++ PkPackageItem *item_new; ++ ++ g_return_val_if_fail (PK_IS_PACKAGE_LIST (plist), FALSE); ++ g_return_val_if_fail (item != NULL, FALSE); ++ ++ ret = pk_package_list_contains_item (plist, item); ++ if (ret) { ++ pk_debug ("already added item"); ++ return FALSE; ++ } ++ ++ pk_debug ("adding to cache array package %s, %s, %s", ++ pk_info_enum_to_text (item->info), item->package_id, item->summary); ++ ++ item_new = pk_package_item_copy (item); ++ g_ptr_array_add (plist->priv->array, item_new); ++ ++ return TRUE; ++} ++ ++/** + * pk_package_list_get_string: + **/ + gchar * +@@ -152,9 +179,7 @@ pk_package_list_clear (PkPackageList *plist) + + while (plist->priv->array->len > 0) { + item = g_ptr_array_index (plist->priv->array, 0); +- g_free (item->package_id); +- g_free (item->summary); +- g_free (item); ++ pk_package_item_free (item); + g_ptr_array_remove_index_fast (plist->priv->array, 0); + } + return TRUE; +@@ -186,6 +211,31 @@ pk_package_list_contains (PkPackageList *plist, const gchar *package_id) + } + + /** ++ * pk_package_list_contains_item: ++ **/ ++gboolean ++pk_package_list_contains_item (PkPackageList *plist, PkPackageItem *item) ++{ ++ PkPackageItem *item_temp; ++ guint i; ++ guint length; ++ gboolean ret = FALSE; ++ ++ g_return_val_if_fail (PK_IS_PACKAGE_LIST (plist), FALSE); ++ g_return_val_if_fail (item != NULL, FALSE); ++ ++ length = plist->priv->array->len; ++ for (i=0; ipriv->array, i); ++ ret = pk_package_item_equal (item_temp, item); ++ if (ret) { ++ break; ++ } ++ } ++ return ret; ++} ++ ++/** + * pk_package_list_class_init: + * @klass: The PkPackageListClass + **/ +diff --git a/libpackagekit/pk-package-list.h b/libpackagekit/pk-package-list.h +index 9178f77..9734af4 100644 +--- a/libpackagekit/pk-package-list.h ++++ b/libpackagekit/pk-package-list.h +@@ -25,6 +25,8 @@ + #include + #include + ++#include "pk-package-item.h" ++ + G_BEGIN_DECLS + + #define PK_TYPE_PACKAGE_LIST (pk_package_list_get_type ()) +@@ -49,26 +51,18 @@ struct _PkPackageListClass + GObjectClass parent_class; + }; + +-/** +- * PkPackageItem: +- * +- * A cached store for the complete Package object +- */ +-typedef struct +-{ +- PkInfoEnum info; +- gchar *package_id; +- gchar *summary; +-} PkPackageItem; +- + GType pk_package_list_get_type (void) G_GNUC_CONST; + PkPackageList *pk_package_list_new (void); + gboolean pk_package_list_add (PkPackageList *plist, + PkInfoEnum info, + const gchar *package_id, + const gchar *summary); ++gboolean pk_package_list_add_item (PkPackageList *plist, ++ PkPackageItem *item); + gboolean pk_package_list_contains (PkPackageList *plist, + const gchar *package_id); ++gboolean pk_package_list_contains_item (PkPackageList *plist, ++ PkPackageItem *item); + gchar *pk_package_list_get_string (PkPackageList *plist) + G_GNUC_WARN_UNUSED_RESULT; + guint pk_package_list_get_size (PkPackageList *plist); +diff --git a/libpackagekit/pk-self-test.c b/libpackagekit/pk-self-test.c +index 62e225b..bf151fb 100644 +--- a/libpackagekit/pk-self-test.c ++++ b/libpackagekit/pk-self-test.c +@@ -29,6 +29,7 @@ + /* prototypes */ + void libst_package_id (LibSelfTest *test); + void libst_package_ids (LibSelfTest *test); ++void libst_package_item (LibSelfTest *test); + void libst_package_list (LibSelfTest *test); + void libst_enum (LibSelfTest *test); + void libst_common (LibSelfTest *test); +@@ -51,6 +52,7 @@ main (int argc, char **argv) + libst_common (&test); + libst_package_id (&test); + libst_package_ids (&test); ++ libst_package_item (&test); + libst_package_list (&test); + libst_enum (&test); + libst_extra (&test); +diff --git a/python/packagekit/daemonBackend.py b/python/packagekit/daemonBackend.py +index 3711f01..5253b39 100644 +--- a/python/packagekit/daemonBackend.py ++++ b/python/packagekit/daemonBackend.py +@@ -789,6 +789,21 @@ class PackageKitBaseBackend(dbus.service.Object): + 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): + ''' +diff --git a/src/pk-backend-dbus.c b/src/pk-backend-dbus.c +index b06e584..4c6837a 100644 +--- a/src/pk-backend-dbus.c ++++ b/src/pk-backend-dbus.c +@@ -123,16 +123,6 @@ pk_backend_dbus_sub_percentage_changed_cb (DBusGProxy *proxy, guint sub_percenta + } + + /** +- * pk_backend_dbus_no_percentage_updates_cb: +- **/ +-static void +-pk_backend_dbus_no_percentage_updates_cb (DBusGProxy *proxy, PkBackendDbus *backend_dbus) +-{ +- pk_debug ("got signal"); +- pk_backend_no_percentage_updates (backend_dbus->priv->backend); +-} +- +-/** + * pk_backend_dbus_package_cb: + **/ + static void +@@ -325,8 +315,6 @@ pk_backend_dbus_remove_callbacks (PkBackendDbus *backend_dbus) + G_CALLBACK (pk_backend_dbus_percentage_changed_cb), backend_dbus); + dbus_g_proxy_disconnect_signal (proxy, "SubPercentageChanged", + G_CALLBACK (pk_backend_dbus_sub_percentage_changed_cb), backend_dbus); +- dbus_g_proxy_disconnect_signal (proxy, "NoPercentageChanged", +- G_CALLBACK (pk_backend_dbus_no_percentage_updates_cb), backend_dbus); + dbus_g_proxy_disconnect_signal (proxy, "Package", + G_CALLBACK (pk_backend_dbus_package_cb), backend_dbus); + dbus_g_proxy_disconnect_signal (proxy, "Details", +@@ -353,6 +341,31 @@ pk_backend_dbus_remove_callbacks (PkBackendDbus *backend_dbus) + } + + /** ++ * pk_backend_dbus_set_proxy: ++ **/ ++static gboolean ++pk_backend_dbus_set_proxy (PkBackendDbus *backend_dbus, const gchar *proxy_http, const gchar *proxy_ftp) ++{ ++ gboolean ret; ++ GError *error = NULL; ++ ++ g_return_val_if_fail (PK_IS_BACKEND_DBUS (backend_dbus), FALSE); ++ g_return_val_if_fail (backend_dbus->priv->proxy != NULL, FALSE); ++ ++ /* new sync method call */ ++ pk_backend_dbus_time_reset (backend_dbus); ++ ret = dbus_g_proxy_call (backend_dbus->priv->proxy, "SetProxy", &error, ++ G_TYPE_STRING, proxy_http, ++ G_TYPE_STRING, proxy_ftp, ++ G_TYPE_INVALID, G_TYPE_INVALID); ++ if (error != NULL) { ++ pk_warning ("%s", error->message); ++ g_error_free (error); ++ } ++ return ret; ++} ++ ++/** + * pk_backend_dbus_set_name: + **/ + gboolean +@@ -385,7 +398,6 @@ pk_backend_dbus_set_name (PkBackendDbus *backend_dbus, const gchar *service) + G_TYPE_UINT, G_TYPE_INVALID); + dbus_g_proxy_add_signal (proxy, "SubPercentageChanged", + G_TYPE_UINT, G_TYPE_INVALID); +- dbus_g_proxy_add_signal (proxy, "NoPercentageChanged", G_TYPE_INVALID); + dbus_g_proxy_add_signal (proxy, "Package", + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID); + dbus_g_proxy_add_signal (proxy, "Details", +@@ -424,8 +436,6 @@ pk_backend_dbus_set_name (PkBackendDbus *backend_dbus, const gchar *service) + G_CALLBACK (pk_backend_dbus_percentage_changed_cb), backend_dbus, NULL); + dbus_g_proxy_connect_signal (proxy, "SubPercentageChanged", + G_CALLBACK (pk_backend_dbus_sub_percentage_changed_cb), backend_dbus, NULL); +- dbus_g_proxy_connect_signal (proxy, "NoPercentageChanged", +- G_CALLBACK (pk_backend_dbus_no_percentage_updates_cb), backend_dbus, NULL); + dbus_g_proxy_connect_signal (proxy, "Package", + G_CALLBACK (pk_backend_dbus_package_cb), backend_dbus, NULL); + dbus_g_proxy_connect_signal (proxy, "Details", +@@ -465,6 +475,18 @@ pk_backend_dbus_set_name (PkBackendDbus *backend_dbus, const gchar *service) + pk_backend_finished (backend_dbus->priv->backend); + g_error_free (error); + } ++ ++ /* set the proxy */ ++ if (ret) { ++ gchar *proxy_http; ++ gchar *proxy_ftp; ++ proxy_http = pk_backend_get_proxy_http (backend_dbus->priv->backend); ++ proxy_ftp = pk_backend_get_proxy_http (backend_dbus->priv->backend); ++ pk_backend_dbus_set_proxy (backend_dbus, proxy_http, proxy_ftp); ++ g_free (proxy_http); ++ g_free (proxy_ftp); ++ } ++ + if (ret) { + pk_backend_dbus_time_check (backend_dbus); + } +diff --git a/src/pk-backend-internal.h b/src/pk-backend-internal.h +index 2213fed..2bffaff 100644 +--- a/src/pk-backend-internal.h ++++ b/src/pk-backend-internal.h +@@ -59,6 +59,9 @@ gboolean pk_backend_reset (PkBackend *backend); + gboolean pk_backend_set_name (PkBackend *backend, + const gchar *name) + G_GNUC_WARN_UNUSED_RESULT; ++gboolean pk_backend_set_proxy (PkBackend *backend, ++ const gchar *proxy_http, ++ const gchar *proxy_ftp); + gchar *pk_backend_get_name (PkBackend *backend) + G_GNUC_WARN_UNUSED_RESULT; + gboolean pk_backend_get_backend_detail (PkBackend *backend, +diff --git a/src/pk-backend-spawn.c b/src/pk-backend-spawn.c +index f9e8b68..f9c9f12 100644 +--- a/src/pk-backend-spawn.c ++++ b/src/pk-backend-spawn.c +@@ -313,7 +313,7 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line) + ret = FALSE; + goto out; + } +- pk_backend_no_percentage_updates (backend_spawn->priv->backend); ++ pk_backend_set_percentage (backend_spawn->priv->backend, PK_BACKEND_PERCENTAGE_INVALID); + } else if (pk_strequal (command, "repo-signature-required")) { + + if (size != 9+99) { +@@ -440,6 +440,44 @@ pk_backend_spawn_helper_new (PkBackendSpawn *backend_spawn) + } + + /** ++ * pk_backend_spawn_get_envp: ++ * ++ * Return all the environment variables the script will need ++ **/ ++static gchar ** ++pk_backend_spawn_get_envp (PkBackendSpawn *backend_spawn) ++{ ++ gchar **envp; ++ gchar *value; ++ gchar *line; ++ GPtrArray *array; ++ ++ array = g_ptr_array_new (); ++ ++ /* http_proxy */ ++ value = pk_backend_get_proxy_http (backend_spawn->priv->backend); ++ if (!pk_strzero (value)) { ++ line = g_strdup_printf ("%s=%s", "http_proxy", value); ++ pk_debug ("setting evp '%s'", line); ++ g_ptr_array_add (array, line); ++ } ++ g_free (value); ++ ++ /* ftp_proxy */ ++ value = pk_backend_get_proxy_ftp (backend_spawn->priv->backend); ++ if (!pk_strzero (value)) { ++ line = g_strdup_printf ("%s=%s", "ftp_proxy", value); ++ pk_debug ("setting evp '%s'", line); ++ g_ptr_array_add (array, line); ++ } ++ g_free (value); ++ ++ envp = pk_ptr_array_to_argv (array); ++ g_ptr_array_free (array, TRUE); ++ return envp; ++} ++ ++/** + * pk_backend_spawn_helper_va_list: + **/ + static gboolean +@@ -448,6 +486,7 @@ pk_backend_spawn_helper_va_list (PkBackendSpawn *backend_spawn, const gchar *exe + gboolean ret; + gchar *filename; + gchar **argv; ++ gchar **envp; + + g_return_val_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn), FALSE); + +@@ -476,7 +515,8 @@ pk_backend_spawn_helper_va_list (PkBackendSpawn *backend_spawn, const gchar *exe + argv[0] = g_strdup (filename); + + pk_backend_spawn_helper_new (backend_spawn); +- ret = pk_spawn_argv (backend_spawn->priv->spawn, argv); ++ envp = pk_backend_spawn_get_envp (backend_spawn); ++ ret = pk_spawn_argv (backend_spawn->priv->spawn, argv, envp); + if (!ret) { + pk_backend_spawn_helper_delete (backend_spawn); + pk_backend_error_code (backend_spawn->priv->backend, PK_ERROR_ENUM_INTERNAL_ERROR, +diff --git a/src/pk-backend.c b/src/pk-backend.c +index 225c488..37ed024 100644 +--- a/src/pk-backend.c ++++ b/src/pk-backend.c +@@ -33,6 +33,7 @@ + #include + #include + ++#include "pk-package-item.h" + #include "pk-debug.h" + #include "pk-common.h" + #include "pk-marshal.h" +@@ -44,13 +45,6 @@ + #define PK_BACKEND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_BACKEND, PkBackendPrivate)) + + /** +- * PK_BACKEND_PERCENTAGE_INVALID: +- * +- * The unknown percentage value +- */ +-#define PK_BACKEND_PERCENTAGE_INVALID 101 +- +-/** + * PK_BACKEND_PERCENTAGE_DEFAULT: + * + * The default percentage value, should never be emitted, but should be +@@ -84,12 +78,15 @@ struct _PkBackendPrivate + GHashTable *eulas; + gchar *name; + gchar *c_tid; ++ gchar *proxy_http; ++ gchar *proxy_ftp; + gboolean locked; + gboolean set_error; + gboolean set_signature; + gboolean set_eula; + gboolean has_sent_package; + PkNetwork *network; ++ PkPackageItem *last_package; + PkRoleEnum role; /* this never changes for the lifetime of a transaction */ + PkStatusEnum status; /* this changes */ + PkExitEnum exit; +@@ -592,6 +589,44 @@ out: + } + + /** ++ * pk_backend_set_proxy: ++ **/ ++gboolean ++pk_backend_set_proxy (PkBackend *backend, const gchar *proxy_http, const gchar *proxy_ftp) ++{ ++ g_return_val_if_fail (PK_IS_BACKEND (backend), FALSE); ++ g_free (backend->priv->proxy_http); ++ g_free (backend->priv->proxy_ftp); ++ backend->priv->proxy_http = g_strdup (proxy_http); ++ backend->priv->proxy_ftp = g_strdup (proxy_ftp); ++ return TRUE; ++} ++ ++/** ++ * pk_backend_get_proxy_http: ++ * ++ * Return value: proxy string in the form username:password@server:port ++ **/ ++gchar * ++pk_backend_get_proxy_http (PkBackend *backend) ++{ ++ g_return_val_if_fail (PK_IS_BACKEND (backend), NULL); ++ return g_strdup (backend->priv->proxy_http); ++} ++ ++/** ++ * pk_backend_get_proxy_ftp: ++ * ++ * Return value: proxy string in the form username:password@server:port ++ **/ ++gchar * ++pk_backend_get_proxy_ftp (PkBackend *backend) ++{ ++ g_return_val_if_fail (PK_IS_BACKEND (backend), NULL); ++ return g_strdup (backend->priv->proxy_ftp); ++} ++ ++/** + * pk_backend_lock: + * + * Responsible for initialising the external backend object. +@@ -803,35 +838,6 @@ pk_backend_set_sub_percentage (PkBackend *backend, guint percentage) + } + + /** +- * pk_backend_no_percentage_updates: +- **/ +-gboolean +-pk_backend_no_percentage_updates (PkBackend *backend) +-{ +- g_return_val_if_fail (PK_IS_BACKEND (backend), FALSE); +- g_return_val_if_fail (backend->priv->locked != FALSE, FALSE); +- +- /* have we already set an error? */ +- if (backend->priv->set_error) { +- pk_warning ("already set error, cannot process"); +- return FALSE; +- } +- +- /* set the same twice? */ +- if (backend->priv->last_percentage == PK_BACKEND_PERCENTAGE_INVALID) { +- pk_debug ("duplicate set of %i", PK_BACKEND_PERCENTAGE_INVALID); +- return FALSE; +- } +- +- /* invalidate previous percentage */ +- backend->priv->last_percentage = PK_BACKEND_PERCENTAGE_INVALID; +- +- /* emit the progress changed signal */ +- pk_backend_emit_progress_changed (backend); +- return TRUE; +-} +- +-/** + * pk_backend_set_status: + **/ + gboolean +@@ -901,11 +907,26 @@ gboolean + pk_backend_package (PkBackend *backend, PkInfoEnum info, const gchar *package_id, const gchar *summary) + { + gchar *summary_safe; ++ PkPackageItem *item; ++ gboolean ret; + + g_return_val_if_fail (PK_IS_BACKEND (backend), FALSE); + g_return_val_if_fail (package_id != NULL, FALSE); + g_return_val_if_fail (backend->priv->locked != FALSE, FALSE); + ++ /* check against the old one */ ++ item = pk_package_item_new (info, package_id, summary); ++ ret = pk_package_item_equal (item, backend->priv->last_package); ++ if (ret) { ++ pk_package_item_free (item); ++ pk_debug ("skipping duplicate %s", package_id); ++ return FALSE; ++ } ++ /* update the 'last' package */ ++ pk_package_item_free (backend->priv->last_package); ++ backend->priv->last_package = pk_package_item_copy (item); ++ pk_package_item_free (item); ++ + /* have we already set an error? */ + if (backend->priv->set_error) { + pk_warning ("already set error, cannot process"); +@@ -1689,6 +1710,8 @@ pk_backend_finalize (GObject *object) + pk_debug ("backend finalise"); + + pk_backend_reset (backend); ++ g_free (backend->priv->proxy_http); ++ g_free (backend->priv->proxy_ftp); + g_free (backend->priv->name); + g_free (backend->priv->c_tid); + g_object_unref (backend->priv->time); +@@ -1818,6 +1841,7 @@ pk_backend_reset (PkBackend *backend) + + /* TODO: need to wait for Finished() if running */ + ++ pk_package_item_free (backend->priv->last_package); + backend->priv->set_error = FALSE; + backend->priv->set_signature = FALSE; + backend->priv->set_eula = FALSE; +@@ -1825,6 +1849,7 @@ pk_backend_reset (PkBackend *backend) + backend->priv->finished = FALSE; + backend->priv->has_sent_package = FALSE; + backend->priv->thread = NULL; ++ backend->priv->last_package = NULL; + backend->priv->status = PK_STATUS_ENUM_UNKNOWN; + backend->priv->exit = PK_EXIT_ENUM_UNKNOWN; + backend->priv->role = PK_ROLE_ENUM_UNKNOWN; +@@ -1855,8 +1880,11 @@ pk_backend_init (PkBackend *backend) + backend->priv->handle = NULL; + backend->priv->name = NULL; + backend->priv->c_tid = NULL; ++ backend->priv->proxy_http = NULL; ++ backend->priv->proxy_ftp = NULL; + backend->priv->file_changed_func = NULL; + backend->priv->file_changed_data = NULL; ++ backend->priv->last_package = NULL; + backend->priv->locked = FALSE; + backend->priv->signal_finished = 0; + backend->priv->signal_error_timeout = 0; +diff --git a/src/pk-backend.h b/src/pk-backend.h +index 95b7fa8..fb17e3c 100644 +--- a/src/pk-backend.h ++++ b/src/pk-backend.h +@@ -30,6 +30,13 @@ + + G_BEGIN_DECLS + ++/** ++ * PK_BACKEND_PERCENTAGE_INVALID: ++ * ++ * The unknown percentage value ++ */ ++#define PK_BACKEND_PERCENTAGE_INVALID 101 ++ + typedef struct _PkBackend PkBackend; + + /* set the state */ +@@ -51,7 +58,6 @@ gboolean pk_backend_set_sub_percentage (PkBackend *backend, + guint percentage); + gboolean pk_backend_set_exit_code (PkBackend *backend, + PkExitEnum exit); +-gboolean pk_backend_no_percentage_updates (PkBackend *backend); + gboolean pk_backend_set_transaction_data (PkBackend *backend, + const gchar *data); + +@@ -66,6 +72,8 @@ gboolean pk_backend_get_progress (PkBackend *backend, + guint *elapsed, + guint *remaining); + guint pk_backend_get_runtime (PkBackend *backend); ++gchar *pk_backend_get_proxy_ftp (PkBackend *backend); ++gchar *pk_backend_get_proxy_http (PkBackend *backend); + + /* signal helpers */ + gboolean pk_backend_finished (PkBackend *backend); +diff --git a/src/pk-engine.c b/src/pk-engine.c +index db81d36..028a0d0 100644 +--- a/src/pk-engine.c ++++ b/src/pk-engine.c +@@ -101,6 +101,7 @@ struct PkEnginePrivate + PkNetwork *network; + PkSecurity *security; + PkNotify *notify; ++ PkConf *conf; + PkFileMonitor *file_monitor; + PkRoleEnum actions; + PkGroupEnum groups; +@@ -579,10 +580,15 @@ pk_engine_init (PkEngine *engine) + DBusGConnection *connection; + gboolean ret; + gchar *filename; ++ gchar *proxy_http; ++ gchar *proxy_ftp; + + engine->priv = PK_ENGINE_GET_PRIVATE (engine); + engine->priv->restart_schedule = FALSE; + ++ /* use the config file */ ++ engine->priv->conf = pk_conf_new (); ++ + /* setup the backend backend */ + engine->priv->backend = pk_backend_new (); + g_signal_connect (engine->priv->backend, "finished", +@@ -639,6 +645,13 @@ pk_engine_init (PkEngine *engine) + G_CALLBACK (pk_engine_file_monitor_changed_cb), engine); + g_free (filename); + ++ /* set the proxy */ ++ proxy_http = pk_conf_get_string (engine->priv->conf, "ProxyHTTP"); ++ proxy_ftp = pk_conf_get_string (engine->priv->conf, "ProxyFTP"); ++ pk_backend_set_proxy (engine->priv->backend, proxy_http, proxy_ftp); ++ g_free (proxy_http); ++ g_free (proxy_ftp); ++ + engine->priv->transaction_list = pk_transaction_list_new (); + g_signal_connect (engine->priv->transaction_list, "changed", + G_CALLBACK (pk_engine_transaction_list_changed_cb), engine); +@@ -696,6 +709,7 @@ pk_engine_finalize (GObject *object) + g_object_unref (engine->priv->notify); + g_object_unref (engine->priv->backend); + g_object_unref (engine->priv->cache); ++ g_object_unref (engine->priv->conf); + + G_OBJECT_CLASS (pk_engine_parent_class)->finalize (object); + } +diff --git a/src/pk-network-unix.c b/src/pk-network-unix.c +index 11c23a2..74b266c 100644 +--- a/src/pk-network-unix.c ++++ b/src/pk-network-unix.c +@@ -138,6 +138,11 @@ pk_network_unix_get_network_state (PkNetworkUnix *network_unix) + continue; + } + ++ /* is loopback? */ ++ if (pk_strequal (sections[0], "lo")) { ++ continue; ++ } ++ + /* is correct parameters? */ + number_sections = g_strv_length (sections); + if (number_sections != 11) { +@@ -145,9 +150,8 @@ pk_network_unix_get_network_state (PkNetworkUnix *network_unix) + continue; + } + +- /* is MTU and gateway nonzero? */ +- if (!pk_strequal (sections[8], "0") && +- !pk_strequal (sections[2], "00000000")) { ++ /* is gateway nonzero? */ ++ if (!pk_strequal (sections[2], "00000000")) { + pk_debug ("interface %s is valid", sections[0]); + online = TRUE; + } +diff --git a/src/pk-network.c b/src/pk-network.c +index 9656958..0ad839e 100644 +--- a/src/pk-network.c ++++ b/src/pk-network.c +@@ -39,6 +39,7 @@ + #ifdef HAVE_UNISTD_H + #include + #endif /* HAVE_UNISTD_H */ ++#include + + #include + +@@ -67,6 +68,7 @@ struct _PkNetworkPrivate + PkNetworkNm *net_nm; + PkNetworkUnix *net_unix; + PkConf *conf; ++ LibGBus *nm_bus; + }; + + enum { +@@ -154,6 +156,7 @@ pk_network_class_init (PkNetworkClass *klass) + static void + pk_network_init (PkNetwork *network) + { ++ gboolean nm_alive; + network->priv = PK_NETWORK_GET_PRIVATE (network); + network->priv->conf = pk_conf_new (); + network->priv->net_nm = pk_network_nm_new (); +@@ -167,6 +170,17 @@ pk_network_init (PkNetwork *network) + network->priv->use_nm = pk_conf_get_bool (network->priv->conf, "UseNetworkManager"); + network->priv->use_unix = pk_conf_get_bool (network->priv->conf, "UseNetworkHeuristic"); + ++ /* check if NM is on the bus */ ++ network->priv->nm_bus = libgbus_new (); ++ libgbus_assign (network->priv->nm_bus, LIBGBUS_SYSTEM, "org.freedesktop.NetworkManager"); ++ nm_alive = libgbus_is_connected (network->priv->nm_bus); ++ ++ /* NetworkManager isn't up, so we can't use it */ ++ if (network->priv->use_nm && !nm_alive) { ++ pk_warning ("UseNetworkManager true, but org.freedesktop.NetworkManager not up"); ++ network->priv->use_nm = FALSE; ++ } ++ + #if !PK_BUILD_NETWORKMANAGER + /* check we can actually use the default */ + if (network->priv->use_nm) { +@@ -190,6 +204,7 @@ pk_network_finalize (GObject *object) + + g_return_if_fail (network->priv != NULL); + g_object_unref (network->priv->conf); ++ g_object_unref (network->priv->nm_bus); + g_object_unref (network->priv->net_nm); + g_object_unref (network->priv->net_unix); + G_OBJECT_CLASS (pk_network_parent_class)->finalize (object); +diff --git a/src/pk-spawn.c b/src/pk-spawn.c +index 9b415b1..c4622f9 100644 +--- a/src/pk-spawn.c ++++ b/src/pk-spawn.c +@@ -273,7 +273,7 @@ pk_spawn_kill (PkSpawn *spawn) + * + **/ + gboolean +-pk_spawn_argv (PkSpawn *spawn, gchar **argv) ++pk_spawn_argv (PkSpawn *spawn, gchar **argv, gchar **envp) + { + gboolean ret; + +@@ -284,7 +284,7 @@ pk_spawn_argv (PkSpawn *spawn, gchar **argv) + spawn->priv->finished = FALSE; + + /* create spawned object for tracking */ +- ret = g_spawn_async_with_pipes (NULL, argv, NULL, ++ ret = g_spawn_async_with_pipes (NULL, argv, envp, + G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH, + NULL, NULL, &spawn->priv->child_pid, + NULL, /* stdin */ +@@ -484,6 +484,7 @@ libst_spawn (LibSelfTest *test) + gboolean ret; + gchar *path; + gchar **argv; ++ gchar **envp; + + if (libst_start (test, "PkSpawn", CLASS_AUTO) == FALSE) { + return; +@@ -496,7 +497,7 @@ libst_spawn (LibSelfTest *test) + libst_title (test, "make sure return error for missing file"); + mexit = BAD_EXIT; + argv = g_strsplit ("pk-spawn-test-xxx.sh", " ", 0); +- ret = pk_spawn_argv (spawn, argv); ++ ret = pk_spawn_argv (spawn, argv, NULL); + g_strfreev (argv); + if (ret == FALSE) { + libst_success (test, "failed to run invalid file"); +@@ -517,7 +518,7 @@ libst_spawn (LibSelfTest *test) + mexit = -1; + path = pk_test_get_data ("pk-spawn-test.sh"); + argv = g_strsplit (path, " ", 0); +- ret = pk_spawn_argv (spawn, argv); ++ ret = pk_spawn_argv (spawn, argv, NULL); + g_free (path); + g_strfreev (argv); + if (ret) { +@@ -558,11 +559,34 @@ libst_spawn (LibSelfTest *test) + new_spawn_object (test, &spawn); + + /************************************************************/ ++ libst_title (test, "make sure we set the proxy"); ++ mexit = -1; ++ path = pk_test_get_data ("pk-spawn-proxy.sh"); ++ argv = g_strsplit (path, " ", 0); ++ envp = g_strsplit ("http_proxy=username:password@server:port " ++ "ftp_proxy=username:password@server:port", " ", 0); ++ ret = pk_spawn_argv (spawn, argv, envp); ++ g_free (path); ++ g_strfreev (argv); ++ if (ret) { ++ libst_success (test, "ran correct file"); ++ } else { ++ libst_failed (test, "did not run helper"); ++ } ++ ++ /* wait for finished */ ++ libst_loopwait (test, 10000); ++ libst_loopcheck (test); ++ ++ /* get new object */ ++ new_spawn_object (test, &spawn); ++ ++ /************************************************************/ + libst_title (test, "make sure run correct helper, and kill it"); + mexit = BAD_EXIT; + path = pk_test_get_data ("pk-spawn-test.sh"); + argv = g_strsplit (path, " ", 0); +- ret = pk_spawn_argv (spawn, argv); ++ ret = pk_spawn_argv (spawn, argv, NULL); + g_free (path); + g_strfreev (argv); + if (ret) { +@@ -592,7 +616,7 @@ libst_spawn (LibSelfTest *test) + mexit = BAD_EXIT; + path = pk_test_get_data ("pk-spawn-test-sigquit.sh"); + argv = g_strsplit (path, " ", 0); +- ret = pk_spawn_argv (spawn, argv); ++ ret = pk_spawn_argv (spawn, argv, NULL); + g_free (path); + g_strfreev (argv); + if (ret) { +@@ -618,7 +642,7 @@ libst_spawn (LibSelfTest *test) + libst_title (test, "run lots of data for profiling"); + path = pk_test_get_data ("pk-spawn-test-profiling.sh"); + argv = g_strsplit (path, " ", 0); +- ret = pk_spawn_argv (spawn, argv); ++ ret = pk_spawn_argv (spawn, argv, NULL); + g_free (path); + g_strfreev (argv); + if (ret) { +diff --git a/src/pk-spawn.h b/src/pk-spawn.h +index 1b20fef..0e58859 100644 +--- a/src/pk-spawn.h ++++ b/src/pk-spawn.h +@@ -52,7 +52,8 @@ GType pk_spawn_get_type (void) G_GNUC_CONST; + PkSpawn *pk_spawn_new (void); + + gboolean pk_spawn_argv (PkSpawn *spawn, +- gchar **argv) ++ gchar **argv, ++ gchar **envp) + G_GNUC_WARN_UNUSED_RESULT; + gboolean pk_spawn_kill (PkSpawn *spawn); + diff --git a/packages/packagekit/files/02_9ced8313fb12f0f89ad6ced7c0fdc7241ff00d77.patch b/packages/packagekit/files/02_9ced8313fb12f0f89ad6ced7c0fdc7241ff00d77.patch new file mode 100644 index 0000000000..fb617c5eda --- /dev/null +++ b/packages/packagekit/files/02_9ced8313fb12f0f89ad6ced7c0fdc7241ff00d77.patch @@ -0,0 +1,13544 @@ +:000000 100644 0000000... bd0cc2e... A RELEASE +:100644 100644 fcc8347... 20279b3... M backends/Makefile.am +:000000 100644 0000000... c851833... A backends/apt.deprecated/.gitignore +:000000 100644 0000000... 07b4131... A backends/apt.deprecated/Makefile.am +:000000 100644 0000000... 0d20b64... A backends/apt.deprecated/helpers/.gitignore +:000000 100644 0000000... 0299df2... A backends/apt.deprecated/helpers/Makefile.am +:000000 100644 0000000... e5f78ca... A backends/apt.deprecated/helpers/aptBackend.py +:000000 100755 0000000... 94dca4a... A backends/apt.deprecated/helpers/get-depends.py +:000000 100755 0000000... a813640... A backends/apt.deprecated/helpers/get-details.py +:000000 100755 0000000... 5529f72... A backends/apt.deprecated/helpers/get-repo-list.py +:000000 100755 0000000... e581010... A backends/apt.deprecated/helpers/get-requires.py +:000000 100755 0000000... 5524d9a... A backends/apt.deprecated/helpers/get-update-detail.py +:000000 100755 0000000... 4f45fbf... A backends/apt.deprecated/helpers/get-updates.py +:000000 100755 0000000... dfa024c... A backends/apt.deprecated/helpers/install-files.py +:000000 120000 0000000... 8d22531... A backends/apt.deprecated/helpers/packagekit +:000000 100755 0000000... 881479d... A backends/apt.deprecated/helpers/refresh-cache.py +:000000 100755 0000000... 3cc36ae... A backends/apt.deprecated/helpers/repo-enable.py +:000000 100755 0000000... aac34df... A backends/apt.deprecated/helpers/resolve.py +:000000 100755 0000000... d02f1b0... A backends/apt.deprecated/helpers/search-details.py +:000000 100755 0000000... ec60319... A backends/apt.deprecated/helpers/search-file.py +:000000 100755 0000000... f63ee80... A backends/apt.deprecated/helpers/search-group.py +:000000 100755 0000000... 9f73c89... A backends/apt.deprecated/helpers/search-name.py +:000000 100644 0000000... 885275d... A backends/apt.deprecated/pk-apt-build-db.cpp +:000000 100644 0000000... bb786a9... A backends/apt.deprecated/pk-apt-build-db.h +:000000 100644 0000000... 5e5b4e5... A backends/apt.deprecated/pk-apt-search-plain.c +:000000 100644 0000000... 98bdc7f... A backends/apt.deprecated/pk-apt-search-sqlite.cpp +:000000 100644 0000000... e36e89f... A backends/apt.deprecated/pk-apt-search.h +:000000 100644 0000000... f59cd88... A backends/apt.deprecated/pk-backend-apt.c +:000000 100644 0000000... 1bf9a50... A backends/apt.deprecated/pk-sqlite-pkg-cache.cpp +:000000 100644 0000000... 68fad42... A backends/apt.deprecated/pk-sqlite-pkg-cache.h +:000000 100644 0000000... 2b99c5d... A backends/apt/HACKING +:100644 100644 07b4131... e315ba9... M backends/apt/Makefile.am +:000000 100644 0000000... 0a3da6e... A backends/apt/README +:000000 100644 0000000... bee2f3d... A backends/apt/TODO +:000000 100755 0000000... 22eb714... A backends/apt/aptDBUSBackend.py +:100644 000000 0d20b64... 0000000... D backends/apt/helpers/.gitignore +:100644 000000 0299df2... 0000000... D backends/apt/helpers/Makefile.am +:100644 000000 e5f78ca... 0000000... D backends/apt/helpers/aptBackend.py +:100755 000000 94dca4a... 0000000... D backends/apt/helpers/get-depends.py +:100755 000000 a813640... 0000000... D backends/apt/helpers/get-details.py +:100755 000000 5529f72... 0000000... D backends/apt/helpers/get-repo-list.py +:100755 000000 e581010... 0000000... D backends/apt/helpers/get-requires.py +:100755 000000 5524d9a... 0000000... D backends/apt/helpers/get-update-detail.py +:100755 000000 4f45fbf... 0000000... D backends/apt/helpers/get-updates.py +:100755 000000 dfa024c... 0000000... D backends/apt/helpers/install-files.py +:100755 000000 881479d... 0000000... D backends/apt/helpers/refresh-cache.py +:100755 000000 3cc36ae... 0000000... D backends/apt/helpers/repo-enable.py +:100755 000000 aac34df... 0000000... D backends/apt/helpers/resolve.py +:100755 000000 d02f1b0... 0000000... D backends/apt/helpers/search-details.py +:100755 000000 ec60319... 0000000... D backends/apt/helpers/search-file.py +:100755 000000 f63ee80... 0000000... D backends/apt/helpers/search-group.py +:100755 000000 9f73c89... 0000000... D backends/apt/helpers/search-name.py +:000000 120000 0000000... 0b64032... A backends/apt/packagekit +:100644 000000 885275d... 0000000... D backends/apt/pk-apt-build-db.cpp +:100644 000000 bb786a9... 0000000... D backends/apt/pk-apt-build-db.h +:100644 000000 5e5b4e5... 0000000... D backends/apt/pk-apt-search-plain.c +:100644 000000 98bdc7f... 0000000... D backends/apt/pk-apt-search-sqlite.cpp +:100644 000000 e36e89f... 0000000... D backends/apt/pk-apt-search.h +:100644 100644 f59cd88... 70836b2... M backends/apt/pk-backend-apt.c +:100644 000000 1bf9a50... 0000000... D backends/apt/pk-sqlite-pkg-cache.cpp +:100644 000000 68fad42... 0000000... D backends/apt/pk-sqlite-pkg-cache.h +:000000 100644 0000000... 1b5d30f... A backends/apt/profiler.py +:000000 100755 0000000... a1d5ffb... A backends/apt/test.py +:100644 000000 c851833... 0000000... D backends/apt2/.gitignore +:100644 000000 2b99c5d... 0000000... D backends/apt2/HACKING +:100644 000000 91c0c46... 0000000... D backends/apt2/Makefile.am +:100644 000000 0a3da6e... 0000000... D backends/apt2/README +:100644 000000 bee2f3d... 0000000... D backends/apt2/TODO +:100755 000000 b7fc500... 0000000... D backends/apt2/aptDBUSBackend.py +:120000 000000 0b64032... 0000000... D backends/apt2/packagekit +:100644 000000 4f78ec4... 0000000... D backends/apt2/pk-backend-apt2.c +:100644 000000 1b5d30f... 0000000... D backends/apt2/profiler.py +:100755 000000 a1d5ffb... 0000000... D backends/apt2/test.py +:100644 100644 2df445e... 5714e9f... M backends/dummy/pk-backend-dummy.c +:100644 100644 7649bab... 2d70108... M backends/opkg/pk-backend-opkg.c +:100644 100644 fdc99d3... 2691414... M backends/poldek/pk-backend-poldek.c +:000000 100644 0000000... 996fb0d... A backends/urpmi/.gitignore +:000000 100644 0000000... 56743a1... A backends/urpmi/Makefile.am +:000000 100644 0000000... 2f78cf5... A backends/urpmi/helpers/.gitignore +:000000 100644 0000000... 88f144e... A backends/urpmi/helpers/Makefile.am +:000000 100755 0000000... bf936c5... A backends/urpmi/helpers/get-depends.pl +:000000 100755 0000000... 3207e9b... A backends/urpmi/helpers/get-details.pl +:000000 100755 0000000... 74ae157... A backends/urpmi/helpers/get-files.pl +:000000 100755 0000000... 9e3e525... A backends/urpmi/helpers/get-packages.pl +:000000 100755 0000000... 0012b2a... A backends/urpmi/helpers/get-requires.pl +:000000 100755 0000000... 69ea452... A backends/urpmi/helpers/get-update-detail.pl +:000000 100755 0000000... 02d574c... A backends/urpmi/helpers/get-updates.pl +:000000 100755 0000000... c9cf6c8... A backends/urpmi/helpers/install-packages.pl +:000000 100644 0000000... 6ed63b5... A backends/urpmi/helpers/perl_packagekit/Makefile.am +:000000 100644 0000000... 8dbb4b0... A backends/urpmi/helpers/perl_packagekit/enums.pm +:000000 100644 0000000... 7411ca9... A backends/urpmi/helpers/perl_packagekit/prints.pm +:000000 100755 0000000... 555a8b8... A backends/urpmi/helpers/refresh-cache.pl +:000000 100755 0000000... 3be38ea... A backends/urpmi/helpers/remove-packages.pl +:000000 100755 0000000... 32e0866... A backends/urpmi/helpers/resolve.pl +:000000 100755 0000000... 3081abe... A backends/urpmi/helpers/search-details.pl +:000000 100755 0000000... 03d348e... A backends/urpmi/helpers/search-file.pl +:000000 100755 0000000... e5b7b92... A backends/urpmi/helpers/search-group.pl +:000000 100755 0000000... 383921f... A backends/urpmi/helpers/search-name.pl +:000000 100755 0000000... 88274bc... A backends/urpmi/helpers/update-packages.pl +:000000 100644 0000000... 3eb8280... A backends/urpmi/helpers/urpmi_backend/Makefile.am +:000000 100644 0000000... a01b893... A backends/urpmi/helpers/urpmi_backend/actions.pm +:000000 100644 0000000... 2c2f13a... A backends/urpmi/helpers/urpmi_backend/filters.pm +:000000 100644 0000000... d377ab2... A backends/urpmi/helpers/urpmi_backend/groups.pm +:000000 100644 0000000... 795edc6... A backends/urpmi/helpers/urpmi_backend/open_db.pm +:000000 100644 0000000... e078134... A backends/urpmi/helpers/urpmi_backend/tools.pm +:000000 100644 0000000... e7b56a7... A backends/urpmi/pk-backend-urpmi.c +:100644 100644 5b2da8f... d70d8dc... M backends/yum/helpers/yumBackend.py +:100755 100755 29f5b03... a708a0c... M backends/yum2/helpers/yumDBUSBackend.py +:100644 100644 15c4b4f... a971707... M backends/zypp/pk-backend-zypp.cpp +:100644 100644 2b848f0... d81d0dd... M backends/zypp/zypp-utils.cpp +:100644 100644 9e3bad1... 4f785cf... M backends/zypp/zypp-utils.h +:100644 100644 5a05a8e... ec93978... M client/pk-console.c +:100644 100644 f5be0a5... bfe364f... M client/pk-import-desktop.c +:100644 100644 cf14cc2... bffd45b... M client/pk-import-specspo.c +:100644 100644 f614d2b... 7510b03... M configure.ac +:100644 100644 4d4a7e3... 61a67d1... M contrib/PackageKit.spec.in +:100644 100644 a97fc3b... ded7799... M contrib/gnome-packagekit.spec.in +:100644 100644 607a7a4... 7aa298b... M docs/html/pk-authors.html +:100644 100644 0cdc85c... d276a05... M docs/html/pk-download.html +:100644 100644 efa8344... 3e37cc1... M docs/html/pk-faq.html +:100644 100644 0b75b10... 51a165a... M docs/spec/pk-concepts.xml +:100644 100644 a79e647... 2970dda... M docs/spec/pk-signals.xml +:100644 100644 8f9bd57... 7a48320... M etc/PackageKit.conf.in +:100644 100644 dd2387b... 8fb82f1... M libpackagekit/pk-client.c +:100644 100644 2b1d1a2... 6617159... M libpackagekit/pk-client.h +:100644 100644 9d3cff7... 0be0e6e... M libpackagekit/pk-common.c +:100644 100644 9908ec2... 9e5a05e... M libpackagekit/pk-common.h +:100644 100644 f2de5ae... 5a54ccc... M libpackagekit/pk-control.c +:100644 100644 63b30d3... c1b1be8... M libpackagekit/pk-control.h +:100644 100644 5743dcb... 9dccdd0... M libpackagekit/pk-enum.c +:100644 100644 e616b64... 4cc317e... M libpackagekit/pk-enum.h +:100644 100644 7f01a4c... d0f0776... M libpackagekit/pk-extra.c +:100644 100644 87905dc... ff4bd4e... M libpackagekit/pk-package-item.c +:100644 100644 5d95e1b... 6bdb0d4... M libpackagekit/pk-package-list.c +:100644 100644 9734af4... 83901ab... M libpackagekit/pk-package-list.h +:100644 100644 dceb656... 7308a29... M libpackagekit/pk-polkit-client.c +:100644 100644 76ab022... 3dc1db0... M libpackagekit/pk-task-list.c +:100644 100644 6dbee0e... f87e6b3... M po/LINGUAS +:100644 100644 33d30c1... 6e8013e... M po/de.po +:000000 100644 0000000... ea732d0... A po/hu.po +:100644 100644 32efce7... 4c4607d... M policy/org.freedesktop.packagekit.policy.in +:100644 100644 5253b39... 9fd627a... M python/packagekit/daemonBackend.py +:100644 100644 f9c9f12... 2bd416d... M src/pk-backend-spawn.c +:100644 100644 37ed024... f0f245f... M src/pk-backend.c +:100644 100644 fb17e3c... a7ba754... M src/pk-backend.h +:100644 100644 028a0d0... 14ecf41... M src/pk-engine.c +:100644 100644 c59b1f3... 668451f... M src/pk-engine.h +:100644 100644 e9e74e1... 7290bbe... M src/pk-interface.xml +:100644 100644 9abf992... 81332d0... M src/pk-security-polkit.c +:100644 100644 3432095... eb55932... M src/pk-security.h +:100644 100644 7aa183f... d42bc7a... M src/pk-transaction-db.c +:100644 100644 0921c7c... f325f94... M src/pk-transaction-list.c +:100644 100644 07ffdee... 15faed3... M src/pk-transaction.c +:100755 100755 f78c891... 6521e69... M tools/add-error-enum.sh +:100755 000000 ebbd8f7... 0000000... D tools/rpmbuild.sh + +diff --git a/RELEASE b/RELEASE +new file mode 100644 +index 0000000..bd0cc2e +--- /dev/null ++++ b/RELEASE +@@ -0,0 +1,50 @@ ++PackageKit Release Notes ++ ++1. Write NEWS entries for PackageKit and gnome-packagekit in the same ++ format as usual. Ignore any trivial commits. ++ ++$git-shortlog GNOME_PACKAGEKIT_0_2_1.. | grep -v trivial > NEWS.new ++ ++2. Add download date to docs/html/pk-download.html, save file. ++ ++3. Update library version if new ABI in configure.ac and change DEVELOPMENT_RELEASE if needed ++ ++4. Commit changes in PackageKit git: ++ ++$git commit -a -m "Release version 0.2.2" ++$git tag -a -f -m "Release 0.2.2" PACKAGEKIT_0_2_2 ++$git push --tags ++$git push ++ ++5. Commit changes in gnome-packagekit git: ++ ++$git commit -a -m "Release version 0.2.2" ++$git-tag GNOME_PACKAGEKIT_0_2_2 ++$git push --tags ++$git push ++ ++6. Upload both tarballs to: ++ ++$scp *.tar.gz packagekit.org/srv/www/html/releases/ ++ ++7. Do post release version bump in configure.ac ++ ++8. Commit changes in both projects: ++ ++$git commit -a -m "post release version bump" ++$git push ++ ++9. Send an email to packagekit@lists.freedesktop.org ++ ++================================================= ++Subject: PackageKit and gnome-packagekit 0.2.2 released! ++ ++Today I released PackageKit and gnome-packagekit 0.2.2. ++ ++PackageKit release notes: http://gitweb.freedesktop.org/?p=packagekit.git;a=blob;f=NEWS ++gnome-packagekit release notes: http://gitweb.freedesktop.org/?p=users/hughsient/gnome-packagekit.git;a=blob;f=NEWS ++ ++Tarballs available here: http://people.freedesktop.org/~hughsient/releases/ ++Thanks to all those who made this possible. ++================================================= ++ +diff --git a/backends/Makefile.am b/backends/Makefile.am +index fcc8347..20279b3 100644 +--- a/backends/Makefile.am ++++ b/backends/Makefile.am +@@ -8,10 +8,6 @@ if BACKEND_TYPE_APT + SUBDIRS += apt + endif + +-if BACKEND_TYPE_APT_DBUS +-SUBDIRS += apt2 +-endif +- + if BACKEND_TYPE_BOX + SUBDIRS += box + endif +@@ -32,6 +28,10 @@ if BACKEND_TYPE_SMART + SUBDIRS += smart + endif + ++if BACKEND_TYPE_URPMI ++SUBDIRS += urpmi ++endif ++ + if BACKEND_TYPE_YUM + SUBDIRS += yum + endif +diff --git a/backends/apt.deprecated/.gitignore b/backends/apt.deprecated/.gitignore +new file mode 100644 +index 0000000..c851833 +--- /dev/null ++++ b/backends/apt.deprecated/.gitignore +@@ -0,0 +1,10 @@ ++.deps ++.libs ++Makefile ++Makefile.in ++*.la ++*.lo ++*.loT ++*.o ++*~ ++ +diff --git a/backends/apt.deprecated/Makefile.am b/backends/apt.deprecated/Makefile.am +new file mode 100644 +index 0000000..07b4131 +--- /dev/null ++++ b/backends/apt.deprecated/Makefile.am +@@ -0,0 +1,30 @@ ++NULL = ++ ++SUBDIRS = helpers ++plugindir = $(PK_PLUGIN_DIR) ++plugin_LTLIBRARIES = libpk_backend_apt.la ++ ++libpk_backend_apt_la_LIBADD = $(PK_PLUGIN_LIBS) ++libpk_backend_apt_la_LDFLAGS = -module -avoid-version $(APT_LIBS) ++libpk_backend_apt_la_CFLAGS = $(PK_PLUGIN_CFLAGS) $(APT_CFLAGS) ++libpk_backend_apt_la_CXXFLAGS = $(PK_PLUGIN_CFLAGS) $(APT_CFLAGS) -DPK_DB_DIR=\""$(PK_DB_DIR)"\" ++ ++libpk_backend_apt_la_SOURCES = \ ++ pk-backend-apt.c \ ++ pk-apt-search.h \ ++ $(NULL) ++ ++if APT_SEARCH_PLAIN ++libpk_backend_apt_la_SOURCES += \ ++ pk-apt-search-plain.c \ ++ $(NULL) ++endif ++ ++if APT_SEARCH_SQLITE ++libpk_backend_apt_la_SOURCES += \ ++ pk-sqlite-pkg-cache.h \ ++ pk-sqlite-pkg-cache.cpp \ ++ pk-apt-build-db.cpp \ ++ pk-apt-search-sqlite.cpp \ ++ $(NULL) ++endif +diff --git a/backends/apt.deprecated/helpers/.gitignore b/backends/apt.deprecated/helpers/.gitignore +new file mode 100644 +index 0000000..0d20b64 +--- /dev/null ++++ b/backends/apt.deprecated/helpers/.gitignore +@@ -0,0 +1 @@ ++*.pyc +diff --git a/backends/apt.deprecated/helpers/Makefile.am b/backends/apt.deprecated/helpers/Makefile.am +new file mode 100644 +index 0000000..0299df2 +--- /dev/null ++++ b/backends/apt.deprecated/helpers/Makefile.am +@@ -0,0 +1,29 @@ ++ ++helperdir = $(datadir)/PackageKit/helpers/apt ++ ++NULL = ++ ++dist_helper_DATA = \ ++ install-files.py \ ++ search-name.py \ ++ search-details.py \ ++ search-group.py \ ++ search-file.py \ ++ get-depends.py \ ++ get-details.py \ ++ get-repo-list.py \ ++ get-requires.py \ ++ get-update-detail.py \ ++ get-updates.py \ ++ refresh-cache.py \ ++ repo-enable.py \ ++ resolve.py \ ++ aptBackend.py \ ++ $(NULL) ++ ++install-data-hook: ++ chmod a+rx $(DESTDIR)$(helperdir)/*.py ++ ++clean-local : ++ rm -f *~ ++ +diff --git a/backends/apt.deprecated/helpers/aptBackend.py b/backends/apt.deprecated/helpers/aptBackend.py +new file mode 100644 +index 0000000..e5f78ca +--- /dev/null ++++ b/backends/apt.deprecated/helpers/aptBackend.py +@@ -0,0 +1,536 @@ ++# ++# vim: ts=4 et sts=4 ++# ++# Copyright (C) 2007 Ali Sabil ++# Copyright (C) 2007 Tom Parker ++# ++# 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. ++ ++import sys ++import os ++import re ++ ++from packagekit.backend import * ++import apt_pkg,apt_inst ++ ++import warnings ++warnings.filterwarnings(action='ignore', category=FutureWarning) ++import apt ++from aptsources.distro import get_distro ++from aptsources.sourceslist import SourcesList ++from sets import Set ++from os.path import join,exists ++from urlparse import urlparse ++from apt.debfile import DebPackage ++from os import system ++ ++class Package(apt.Package): ++ def __str__(self): ++ return "Package %s, version %s"%(self.name,self._version) ++ ++ def _cmp_deps(self,deps, version): ++ for (v,c) in deps: ++ if not apt_pkg.CheckDep(version,c,v): ++ return False ++ return True ++ ++ def __init__(self, backend, pkg, data="",version=[]): ++ apt.package.Package.__init__(self, pkg._cache, pkg._depcache, ++ pkg._records, pkg._list, pkg._pcache, ++ pkg._pkg) ++ self._version = version ++ self._data = data ++ self._backend = backend ++ wanted_ver = None ++ if self.installedVersion!=None and self._cmp_deps(version,self.installedVersion): ++ wanted_ver = self.installedVersion ++ elif self.installedVersion == None and version == []: ++ #self.markInstall(False,False) ++ wanted_ver = self.candidateVersion ++ ++ for ver in pkg._pkg.VersionList: ++ #print "vers",dir(ver),version,ver ++ #print data ++ if (wanted_ver == None or wanted_ver == ver.VerStr) and self._cmp_deps(version,ver.VerStr): ++ f, index = ver.FileList.pop(0) ++ if self._data == "": ++ if f.Origin=="" and f.Archive=="now": ++ self._data = "local_install" ++ elif f.Origin!="" or f.Archive!="": ++ self._data = "%s/%s"%(f.Origin.replace("/","_"),f.Archive.replace("/","_")) ++ else: ++ self._data = "%s/unknown"%f.Site ++ self._version = ver.VerStr ++ break ++ else: ++ print "wanted",wanted_ver ++ for ver in pkg._pkg.VersionList: ++ print "vers",version,ver.VerStr ++ backend.error(ERROR_PACKAGE_NOT_FOUND, "Can't find version %s for %s"%(version,self.name)) ++ ++ def setVersion(self,version,compare="="): ++ if version!=None and (self.installedVersion == None or not apt_pkg.CheckDep(version,compare,self.installedVersion)): ++ self.markInstall(False,False) ++ if self.candidateVersion != version: ++ if self._data == "": ++ for ver in pkg._pkg.VersionList: ++ f, index = ver.FileList.pop(0) ++ self._data = "%s/%s"%(f.Origin,f.Archive) ++ if ver.VerStr == version: ++ break ++ ++ # FIXME: this is a nasty hack, assuming that the best way to resolve ++ # deps for non-default repos is by switching the default release. ++ # We really need a better resolver (but that's hard) ++ assert self._data!="" ++ origin = self._data[self._data.find("/")+1:] ++ print "origin",origin ++ name = self.name ++ apt_pkg.Config.Set("APT::Default-Release",origin) ++ if not self._backend._caches.has_key(origin): ++ self._backend._caches[origin] = apt.Cache(PackageKitProgress(self)) ++ print "new cache for %s"%origin ++ self.__setParent(self._backend._caches[origin][name]) ++ self.markInstall(False,False) ++ if not apt_pkg.CheckDep(self.candidateVersion,compare,version): ++ self._backend.error(ERROR_PACKAGE_NOT_FOUND, ++ "Unable to locate package version %s (only got %s) for %s"%(version,self.candidateVersion,name)) ++ return ++ self.markKeep() ++ ++ @property ++ def group(self): ++ section = self.section.split('/')[-1].lower() ++ #if section in (): ++ # return GROUP_ACCESSIBILITY ++ if section in ('utils',): ++ return "accessories" ++ #if section in (): ++ # return GROUP_EDUCATION ++ if section in ('games',): ++ return "games" ++ if section in ('graphics',): ++ return "graphics" ++ if section in ('net', 'news', 'web', 'comm'): ++ return "internet" ++ if section in ('editors', 'tex'): ++ return "office" ++ if section in ('misc',): ++ return "other" ++ if section in ('devel', 'libdevel', 'interpreters', 'perl', 'python'): ++ return "programming" ++ if section in ('sound',): ++ return "multimedia" ++ if section in ('base', 'admin'): ++ return "system" ++ return "unknown" ++ ++ @property ++ def isInstalled(self): ++ return super(self.__class__,self).isInstalled and self.installedVersion == self._version ++ ++ @property ++ def isDevelopment(self): ++ name = self.name.lower() ++ section = self.section.split('/')[-1].lower() ++ return name.endswith('-dev') or name.endswith('-dbg') or \ ++ section in ('devel', 'libdevel') ++ ++ @property ++ def isGui(self): ++ section = self.section.split('/')[-1].lower() ++ return section in ('x11', 'gnome', 'kde') ++ ++ _HYPHEN_PATTERN = re.compile(r'(\s|_)+') ++ ++ def matchName(self, name): ++ needle = name.strip().lower() ++ haystack = self.name.lower() ++ needle = Package._HYPHEN_PATTERN.sub('-', needle) ++ haystack = Package._HYPHEN_PATTERN.sub('-', haystack) ++ if haystack.find(needle) >= 0: ++ return True ++ return False ++ ++ def matchDetails(self, details): ++ if self.matchName(details): ++ return True ++ needle = details.strip().lower() ++ haystack = self.description.lower() ++ if haystack.find(needle) >= 0: ++ return True ++ return False ++ ++ def matchGroup(self, name): ++ needle = name.strip().lower() ++ haystack = self.group ++ if haystack.startswith(needle): ++ return True ++ return False ++ ++class PackageKitProgress(apt.progress.OpProgress, apt.progress.FetchProgress): ++ def __init__(self, backend): ++ self._backend = backend ++ apt.progress.OpProgress.__init__(self) ++ apt.progress.FetchProgress.__init__(self) ++ ++ # OpProgress callbacks ++ def update(self, percent): ++ pass ++ ++ def done(self): ++ pass ++ ++ # FetchProgress callbacks ++ def pulse(self): ++ apt.progress.FetchProgress.pulse(self) ++ self._backend.percentage(self.percent) ++ return True ++ ++ def stop(self): ++ self._backend.percentage(100) ++ ++ def mediaChange(self, medium, drive): ++ # This probably should not be an error, but a Message. ++ self._backend.error(ERROR_UNKNOWN, ++ "Medium change needed") ++ ++class PackageKitAptBackend(PackageKitBaseBackend): ++ def __init__(self, args): ++ PackageKitBaseBackend.__init__(self, args) ++ self.status(STATUS_SETUP) ++ self._caches = {} ++ self._apt_cache = apt.Cache(PackageKitProgress(self)) ++ default = apt_pkg.Config.Find("APT::Default-Release") ++ if default=="": ++ d = get_distro() ++ if d.id == "Debian": ++ default = "stable" ++ elif d.id == "Ubuntu": ++ default = "main" ++ else: ++ raise Exception,d.id ++ ++ self._caches[default] = self._apt_cache ++ ++ ++ def search_name(self, filters, key): ++ ''' ++ Implement the {backend}-search-name functionality ++ ''' ++ self.status(STATUS_INFO) ++ self.allow_cancel(True) ++ for package in self._do_search(filters, ++ lambda pkg: pkg.matchName(key)): ++ self._emit_package(package) ++ ++ def search_details(self, filters, key): ++ ''' ++ Implement the {backend}-search-details functionality ++ ''' ++ self.status(STATUS_INFO) ++ self.allow_cancel(True) ++ for package in self._do_search(filters, ++ lambda pkg: pkg.matchDetails(key)): ++ self._emit_package(package) ++ ++ def search_group(self, filters, key): ++ ''' ++ Implement the {backend}-search-group functionality ++ ''' ++ self.status(STATUS_INFO) ++ self.allow_cancel(True) ++ for package in self._do_search(filters, ++ lambda pkg: pkg.matchGroup(key)): ++ self._emit_package(package) ++ ++ def search_file(self, filters, key): ++ ''' ++ Implement the {backend}-search-file functionality ++ ''' ++ self.allow_cancel(True) ++ self.percentage(None) ++ ++ self.error(ERROR_NOT_SUPPORTED, ++ "This function is not implemented in this backend") ++ ++ def refresh_cache(self): ++ ''' ++ Implement the {backend}-refresh_cache functionality ++ ''' ++ self.status(STATUS_REFRESH_CACHE) ++ try: ++ res = self._apt_cache.update(PackageKitProgress(self)) ++ except Exception, error_message: ++ self.error(ERROR_UNKNOWN, ++ "Failed to fetch the following items:\n%s" % error_message) ++ return res ++ ++ def get_details(self, package): ++ ''' ++ Implement the {backend}-get-details functionality ++ ''' ++ self.status(STATUS_INFO) ++ name, version, arch, data = self.get_package_from_id(package) ++ pkg = Package(self, self._apt_cache[name]) ++ description = re.sub('\s+', ' ', pkg.description).strip() ++ self.description(package, 'unknown', pkg.group, description, ++ pkg.architecture, pkg.packageSize) ++ ++ def resolve(self, name): ++ ''' ++ Implement the {backend}-resolve functionality ++ ''' ++ self.status(STATUS_INFO) ++ try: ++ pkg = Package(self,self._apt_cache[name]) ++ self._emit_package(pkg) ++ except KeyError: ++ self.error(ERROR_PACKAGE_NOT_FOUND,"Can't find a package called '%s'"%name) ++ ++ def _do_deps(self,inp,deps,recursive): ++ inp.markInstall() ++ newkeys = [] ++ for x in inp.candidateDependencies: ++ n = x.or_dependencies[0].name ++ if not deps.has_key(n): ++ deps[n] = [] ++ newkeys.append(n) ++ deps[n].append((x.or_dependencies[0].version,x.or_dependencies[0].relation)) ++ if recursive: ++ for n in newkeys: ++ try: ++ deps = self._do_deps(Package(self,self._apt_cache[n],version=deps[n]),deps,recursive) ++ except KeyError: # FIXME: we're assuming this is a virtual package, which we can't cope with yet ++ del deps[n] ++ continue ++ return deps ++ ++ def get_depends(self,filters,package, recursive): ++ ''' ++ Implement the {backend}-get-depends functionality ++ ''' ++ self.allow_cancel(True) ++ self.status(STATUS_INFO) ++ recursive = (recursive == "True") ++ name, version, arch, data = self.get_package_from_id(package) ++ pkg = Package(self,self._apt_cache[name],version=[(version,"=")],data=data) ++ pkg.setVersion(version) ++ deps = self._do_deps(pkg, {}, recursive) ++ for n in deps.keys(): ++ self._emit_package(Package(self,self._apt_cache[n],version=deps[n])) ++ ++ def _do_reqs(self,inp,pkgs,recursive): ++ extra = [] ++ fails = [] ++ for r in inp._pkg.RevDependsList: ++ ch = apt_pkg.CheckDep(inp._version,r.CompType,r.TargetVer) ++ v = (r.ParentPkg.Name,r.ParentVer.VerStr) ++ if not ch or v in fails: ++ #print "skip",r.TargetVer,r.CompType,r.ParentPkg.Name,r.ParentVer.VerStr ++ fails.append(v) ++ continue ++ p = Package(self,self._apt_cache[r.ParentPkg.Name],r.ParentVer.VerStr) ++ if v not in pkgs: ++ extra.append(p) ++ #print "new pkg",p ++ self._emit_package(p) ++ pkgs.add(v) ++ if recursive: ++ for e in extra: ++ pkgs = self._do_reqs(p, pkgs,recursive) ++ return pkgs ++ ++ def get_requires(self,package,recursive): ++ ''' ++ Implement the {backend}-get-requires functionality ++ ''' ++ self.allow_cancel(True) ++ self.status(STATUS_INFO) ++ recursive = (recursive == "True") ++ name, version, arch, data = self.get_package_from_id(package) ++ pkg = Package(self,self._apt_cache[name], version=[(version,"=")], data=data) ++ ++ pkgs = Set() ++ self._do_reqs(pkg,pkgs, recursive) ++ ++ def _build_repo_list(self): ++ repo = {} ++ ++ sources = SourcesList() ++ repo["__sources"] = sources ++ ++ root = apt_pkg.Config.FindDir("Dir::State::Lists") ++ #print root ++ for entry in sources: ++ if entry.type!="": ++ url = entry.uri ++ #if entry.template!=None: ++ url +="/dists/" ++ url += entry.dist ++ url = url.replace("//dists","/dists") ++ #print url ++ path = join(root,"%s_Release"%(apt_pkg.URItoFileName(url))) ++ if not exists(path): ++ #print path ++ name = "%s/unknown"%urlparse(entry.uri)[1] ++ else: ++ lines = file(path).readlines() ++ origin = "" ++ suite = "" ++ for l in lines: ++ if l.find("Origin: ")==0: ++ origin = l.split(" ",1)[1].strip() ++ elif l.find("Suite: ")==0: ++ suite = l.split(" ",1)[1].strip() ++ assert origin!="" and suite!="" ++ name = "%s/%s"%(origin,suite) ++ if entry.type == "deb-src": ++ name += "-src" ++ ++ repo[name] = {"entry":entry} ++ return repo ++ ++ def get_repo_list(self, filters): ++ ''' ++ Implement the {backend}-get-repo-list functionality ++ ''' ++ self.allow_interrupt(True) ++ self.status(STATUS_INFO) ++ repo = self._build_repo_list() ++ for e in repo.keys(): ++ if e == "__sources": ++ continue ++ self.repo_detail(repo[e]["entry"].line.strip(),e,not repo[e]["entry"].disabled) ++ ++ def repo_enable(self, repoid, enable): ++ ''' ++ Implement the {backend}-repo-enable functionality ++ ''' ++ enable = (enable == "True") ++ repo = self._build_repo_list() ++ if not repo.has_key(repoid): ++ self.error(ERROR_REPO_NOT_FOUND,"Couldn't find repo '%s'"%repoid) ++ return ++ r = repo[repoid] ++ if not r["entry"].disabled == enable: # already there ++ return ++ r["entry"].set_enabled(enable) ++ try: ++ repo["__sources"].save() ++ except IOError,e: ++ self.error(ERROR_UNKNOWN, "Problem while trying to save repo settings to %s: %s"%(e.filename,e.strerror)) ++ ++ def get_updates(self, filter): ++ self._apt_cache.upgrade(False) ++ for pkg in self._apt_cache.getChanges(): ++ self._emit_package(Package(self, pkg)) ++ ++ def get_update_detail(self, package): ++ self.allow_cancel(True) ++ self.percentage(None) ++ self.status(STATUS_INFO) ++ name, version, arch, data = self.get_package_from_id(package) ++ update = "" ++ obsolete = "" ++ cve_url = "" ++ bz_url = "" ++ vendor_url = "" ++ reboot = "none" ++ desc = self._apt_cache[name].description ++ self.update_detail(package,update,obsolete,vendor_url,bz_url,cve_url,reboot,desc) ++ ++ ++ def install_files (self, inst_files): ++ ''' ++ Implement the {backend}-install_files functionality ++ Install the package containing the inst_file file ++ ''' ++ if not exists(inst_file): ++ self.error(ERROR_PACKAGE_NOT_FOUND,"Can't find %s"%inst_file) ++ return ++ deb = DebPackage(inst_file) ++ deps = {} ++ for k in ["Depends","Recommends"]: ++ if not deb._sections.has_key(k): ++ continue ++ for items in apt_pkg.ParseDepends(deb[k]): ++ assert len(items) == 1,"Can't handle or deps properly yet" ++ (pkg,ver,comp) = items[0] ++ if not deps.has_key(pkg): ++ deps[pkg] = [] ++ deps[pkg].append((ver,comp)) ++ for n in deps.keys(): ++ p = Package(self,self._apt_cache[n],version=deps[n]) ++ if not p.isInstalled: ++ p.markInstall() ++ assert self._apt_cache.getChanges()==[],"Don't handle install changes yet" ++ # FIXME: nasty hack. Need a better way in ++ ret = system("dpkg -i %s"%inst_file) ++ if ret!=0: ++ self.error(ERROR_UNKNOWN,"Can't install package") ++ ++ ### Helpers ### ++ def _emit_package(self, package): ++ id = self.get_package_id(package.name, ++ package._version, ++ package.architecture, ++ package._data) ++ if package.isInstalled: ++ status = INFO_INSTALLED ++ else: ++ status = INFO_AVAILABLE ++ summary = package.summary ++ self.package(id, status, summary) ++ ++ def _do_search(self, filters, condition): ++ filters = filters.split(';') ++ size = len(self._apt_cache) ++ percentage = 0 ++ for i, pkg in enumerate(self._apt_cache): ++ new_percentage = i / float(size) * 100 ++ if new_percentage - percentage >= 5: ++ percentage = new_percentage ++ self.percentage(percentage) ++ package = Package(self, pkg) ++ if package.installedVersion is None and \ ++ package.candidateVersion is None: ++ continue ++ if not condition(package): ++ continue ++ continue ++ vers = [x.VerStr for x in package._pkg.VersionList] ++ if package.installedVersion!=None: ++ i = package.installedVersion ++ if i in vers and vers[0]!=i: ++ del vers[vers.index(i)] ++ vers.insert(0,i) ++ ++ for ver in vers: ++ p = Package(self, package, version=[[ver,"="]]) ++ if self._do_filtering(p, filters): ++ yield p ++ self.percentage(100) ++ ++ def _do_filtering(self, package, filters): ++ if len(filters) == 0 or filters == ['none']: ++ return True ++ if (FILTER_INSTALLED in filters) and (not package.isInstalled): ++ return False ++ if (FILTER_NOT_INSTALLED in filters) and package.isInstalled: ++ return False ++ if (FILTER_GUI in filters) and (not package.isGui): ++ return False ++ if (FILTER_NOT_GUI in filters) and package.isGui: ++ return False ++ if (FILTER_DEVELOPMENT in filters) and (not package.isDevelopment): ++ return False ++ if (FILTER_NOT_DEVELOPMENT in filters) and package.isDevelopment: ++ return False ++ return True ++ +diff --git a/backends/apt.deprecated/helpers/get-depends.py b/backends/apt.deprecated/helpers/get-depends.py +new file mode 100755 +index 0000000..94dca4a +--- /dev/null ++++ b/backends/apt.deprecated/helpers/get-depends.py +@@ -0,0 +1,20 @@ ++#!/usr/bin/python ++# ++# Copyright (C) 2007 Richard Hughes ++# ++# 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. ++ ++import sys ++ ++from aptBackend import PackageKitAptBackend ++filters=sys.argv[1] ++package=sys.argv[2] ++recursive = sys.argv[3] ++backend = PackageKitAptBackend(sys.argv[1:]) ++backend.get_depends(filters, package, recursive) ++sys.exit(0) +diff --git a/backends/apt.deprecated/helpers/get-details.py b/backends/apt.deprecated/helpers/get-details.py +new file mode 100755 +index 0000000..a813640 +--- /dev/null ++++ b/backends/apt.deprecated/helpers/get-details.py +@@ -0,0 +1,18 @@ ++#!/usr/bin/python ++# ++# Copyright (C) 2007 Ali Sabil ++# ++# 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. ++ ++import sys ++from aptBackend import PackageKitAptBackend ++ ++package = sys.argv[1] ++backend = PackageKitAptBackend(sys.argv[1:]) ++backend.get_details(package) ++sys.exit(0) +diff --git a/backends/apt.deprecated/helpers/get-repo-list.py b/backends/apt.deprecated/helpers/get-repo-list.py +new file mode 100755 +index 0000000..5529f72 +--- /dev/null ++++ b/backends/apt.deprecated/helpers/get-repo-list.py +@@ -0,0 +1,20 @@ ++#!/usr/bin/python ++# ++# Copyright (C) 2007 Richard Hughes ++# ++# 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. ++ ++import sys ++ ++from aptBackend import PackageKitAptBackend ++filters = sys.argv[1] ++ ++backend = PackageKitAptBackend(sys.argv[2:]) ++backend.get_repo_list(filters) ++backend.unLock() ++sys.exit(0) +diff --git a/backends/apt.deprecated/helpers/get-requires.py b/backends/apt.deprecated/helpers/get-requires.py +new file mode 100755 +index 0000000..e581010 +--- /dev/null ++++ b/backends/apt.deprecated/helpers/get-requires.py +@@ -0,0 +1,20 @@ ++#!/usr/bin/python ++# ++# Copyright (C) 2007 Richard Hughes ++# ++# 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. ++ ++import sys ++ ++from aptBackend import PackageKitAptBackend ++package = sys.argv[1] ++recursive = sys.argv[2] ++ ++backend = PackageKitAptBackend(sys.argv[1:]) ++backend.get_requires(package, recursive) ++sys.exit(0) +diff --git a/backends/apt.deprecated/helpers/get-update-detail.py b/backends/apt.deprecated/helpers/get-update-detail.py +new file mode 100755 +index 0000000..5524d9a +--- /dev/null ++++ b/backends/apt.deprecated/helpers/get-update-detail.py +@@ -0,0 +1,18 @@ ++#!/usr/bin/python ++# ++# Copyright (C) 2008 Michael Vogt ++# ++# 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. ++ ++import sys ++ ++from aptBackend import PackageKitAptBackend ++package=sys.argv[1] ++backend = PackageKitAptBackend(sys.argv[2:]) ++backend.get_update_detail(package) ++sys.exit(0) +diff --git a/backends/apt.deprecated/helpers/get-updates.py b/backends/apt.deprecated/helpers/get-updates.py +new file mode 100755 +index 0000000..4f45fbf +--- /dev/null ++++ b/backends/apt.deprecated/helpers/get-updates.py +@@ -0,0 +1,19 @@ ++#!/usr/bin/python ++# ++# Copyright (C) 2008 Michael Vogt ++# ++# 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. ++ ++import sys ++from aptBackend import PackageKitAptBackend ++ ++filter = sys.argv[1] ++ ++backend = PackageKitAptBackend(sys.argv[1:]) ++backend.get_updates(filter) ++sys.exit(0) +diff --git a/backends/apt.deprecated/helpers/install-files.py b/backends/apt.deprecated/helpers/install-files.py +new file mode 100755 +index 0000000..dfa024c +--- /dev/null ++++ b/backends/apt.deprecated/helpers/install-files.py +@@ -0,0 +1,21 @@ ++#!/usr/bin/python ++# ++# Copyright (C) 2007 Richard Hughes ++# Copyright (C) 2007 Red Hat Inc, Seth Vidal ++# ++# 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. ++ ++import sys ++ ++from aptBackend import PackageKitAptBackend ++ ++trusted = sys.argv[1] ++files_to_inst = sys.argv[2:] ++backend = PackageKitAptBackend(sys.argv[1:]) ++backend.install_files(trusted, files_to_inst) ++sys.exit(0) +diff --git a/backends/apt.deprecated/helpers/packagekit b/backends/apt.deprecated/helpers/packagekit +new file mode 120000 +index 0000000..8d22531 +--- /dev/null ++++ b/backends/apt.deprecated/helpers/packagekit +@@ -0,0 +1 @@ ++../../../python/packagekit +\ No newline at end of file +diff --git a/backends/apt.deprecated/helpers/refresh-cache.py b/backends/apt.deprecated/helpers/refresh-cache.py +new file mode 100755 +index 0000000..881479d +--- /dev/null ++++ b/backends/apt.deprecated/helpers/refresh-cache.py +@@ -0,0 +1,17 @@ ++#!/usr/bin/python ++# ++# Copyright (C) 2007 Ali Sabil ++# ++# 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. ++ ++import sys ++from aptBackend import PackageKitAptBackend ++ ++backend = PackageKitAptBackend(sys.argv[1:]) ++backend.refresh_cache() ++sys.exit(0) +diff --git a/backends/apt.deprecated/helpers/repo-enable.py b/backends/apt.deprecated/helpers/repo-enable.py +new file mode 100755 +index 0000000..3cc36ae +--- /dev/null ++++ b/backends/apt.deprecated/helpers/repo-enable.py +@@ -0,0 +1,20 @@ ++#!/usr/bin/python ++# ++# Copyright (C) 2007 Richard Hughes ++# ++# 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. ++ ++import sys ++ ++from aptBackend import PackageKitAptBackend ++repoid = sys.argv[1] ++state=sys.argv[2] ++backend = PackageKitAptBackend(sys.argv[2:]) ++backend.repo_enable(repoid,state) ++backend.unLock() ++sys.exit(0) +diff --git a/backends/apt.deprecated/helpers/resolve.py b/backends/apt.deprecated/helpers/resolve.py +new file mode 100755 +index 0000000..aac34df +--- /dev/null ++++ b/backends/apt.deprecated/helpers/resolve.py +@@ -0,0 +1,20 @@ ++#!/usr/bin/python ++# ++# Copyright (C) 2007 Richard Hughes ++# ++# 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. ++ ++import sys ++ ++from aptBackend import PackageKitAptBackend ++filters = sys.argv[1] ++name=sys.argv[2] ++backend = PackageKitAptBackend(sys.argv[2:]) ++backend.resolve(name) ++backend.unLock() ++sys.exit(0) +diff --git a/backends/apt.deprecated/helpers/search-details.py b/backends/apt.deprecated/helpers/search-details.py +new file mode 100755 +index 0000000..d02f1b0 +--- /dev/null ++++ b/backends/apt.deprecated/helpers/search-details.py +@@ -0,0 +1,21 @@ ++#!/usr/bin/python ++# ++# Copyright (C) 2007 Ali Sabil ++# ++# 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. ++ ++import sys ++ ++options = sys.argv[1] ++searchlist = sys.argv[2] ++ ++from aptBackend import PackageKitAptBackend ++ ++backend = PackageKitAptBackend(sys.argv[1:]) ++backend.search_details(options,searchlist) ++sys.exit(0) +diff --git a/backends/apt.deprecated/helpers/search-file.py b/backends/apt.deprecated/helpers/search-file.py +new file mode 100755 +index 0000000..ec60319 +--- /dev/null ++++ b/backends/apt.deprecated/helpers/search-file.py +@@ -0,0 +1,21 @@ ++#!/usr/bin/python ++# ++# Copyright (C) 2007 Ali Sabil ++# ++# 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. ++ ++import sys ++ ++options = sys.argv[1] ++searchlist = sys.argv[2] ++ ++from aptBackend import PackageKitAptBackend ++ ++backend = PackageKitAptBackend(sys.argv[1:]) ++backend.search_file(options,searchlist) ++sys.exit(0) +diff --git a/backends/apt.deprecated/helpers/search-group.py b/backends/apt.deprecated/helpers/search-group.py +new file mode 100755 +index 0000000..f63ee80 +--- /dev/null ++++ b/backends/apt.deprecated/helpers/search-group.py +@@ -0,0 +1,21 @@ ++#!/usr/bin/python ++# ++# Copyright (C) 2007 Ali Sabil ++# ++# 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. ++ ++import sys ++ ++options = sys.argv[1] ++searchlist = sys.argv[2] ++ ++from aptBackend import PackageKitAptBackend ++ ++backend = PackageKitAptBackend(sys.argv[1:]) ++backend.search_group(options,searchlist) ++sys.exit(0) +diff --git a/backends/apt.deprecated/helpers/search-name.py b/backends/apt.deprecated/helpers/search-name.py +new file mode 100755 +index 0000000..9f73c89 +--- /dev/null ++++ b/backends/apt.deprecated/helpers/search-name.py +@@ -0,0 +1,21 @@ ++#!/usr/bin/python ++# ++# Copyright (C) 2007 Ali Sabil ++# ++# 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. ++ ++import sys ++ ++options = sys.argv[1] ++searchlist = sys.argv[2] ++ ++from aptBackend import PackageKitAptBackend ++ ++backend = PackageKitAptBackend(sys.argv[1:]) ++backend.search_name(options,searchlist) ++sys.exit(0) +diff --git a/backends/apt.deprecated/pk-apt-build-db.cpp b/backends/apt.deprecated/pk-apt-build-db.cpp +new file mode 100644 +index 0000000..885275d +--- /dev/null ++++ b/backends/apt.deprecated/pk-apt-build-db.cpp +@@ -0,0 +1,284 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- ++ * ++ * Copyright (C) 2007 Tom Parker ++ * ++ * Licensed under the GNU General Public License Version 2 ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++//#include "pk-backend-apt.h" ++#include ++#include ++#include ++ ++typedef enum {FIELD_PKG=1,FIELD_VER,FIELD_DEPS,FIELD_ARCH,FIELD_SHORT,FIELD_LONG,FIELD_REPO} Fields; ++ ++void apt_build_db(PkBackend * backend, sqlite3 *db) ++{ ++ GMatchInfo *match_info; ++ GError *error = NULL; ++ gchar *contents = NULL; ++ gchar *sdir; ++ const gchar *fname; ++ GRegex *origin, *suite; ++ GDir *dir; ++ GHashTable *releases; ++ int res; ++ sqlite3_stmt *package = NULL; ++ ++ pk_backend_set_status(backend, PK_STATUS_ENUM_QUERY); ++ pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); ++ ++ sdir = g_build_filename(_config->Find("Dir").c_str(),_config->Find("Dir::State").c_str(),_config->Find("Dir::State::lists").c_str(), NULL); ++ dir = g_dir_open(sdir,0,&error); ++ if (error!=NULL) ++ { ++ pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "can't open %s",dir); ++ g_error_free(error); ++ goto search_task_cleanup; ++ } ++ ++ origin = g_regex_new("^Origin: (\\S+)",(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE|G_REGEX_MULTILINE),(GRegexMatchFlags)0,NULL); ++ suite = g_regex_new("^Suite: (\\S+)",(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE|G_REGEX_MULTILINE),(GRegexMatchFlags)0,NULL); ++ ++ releases = g_hash_table_new_full(g_str_hash,g_str_equal,g_free,g_free); ++ while ((fname = g_dir_read_name(dir))!=NULL) ++ { ++ gchar *temp, *parsed_name; ++ gchar** items = g_strsplit(fname,"_",-1); ++ guint len = g_strv_length(items); ++ if(len<=3) // minimum is __ ++ { ++ g_strfreev(items); ++ continue; ++ } ++ ++ /* warning: nasty hack with g_strjoinv */ ++ temp = items[len-2]; ++ items[len-2] = NULL; ++ parsed_name = g_strjoinv("_",items); ++ items[len-2] = temp; ++ ++ if (g_ascii_strcasecmp(items[len-1],"Release")==0 && g_ascii_strcasecmp(items[len-2],"source")!=0) ++ { ++ gchar * repo = NULL, *fullname; ++ fullname = g_build_filename(sdir,fname,NULL); ++ if (g_file_get_contents(fullname,&contents,NULL,NULL) == FALSE) ++ { ++ pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "error loading %s",fullname); ++ goto search_task_cleanup; ++ } ++ g_free(fullname); ++ ++ g_regex_match (origin, contents, (GRegexMatchFlags)0, &match_info); ++ if (!g_match_info_matches(match_info)) ++ { ++ pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "origin regex failure in %s",fname); ++ goto search_task_cleanup; ++ } ++ repo = g_match_info_fetch (match_info, 1); ++ ++ g_regex_match (suite, contents, (GRegexMatchFlags)0, &match_info); ++ if (g_match_info_matches(match_info)) ++ { ++ temp = g_strconcat(repo,"/",g_match_info_fetch (match_info, 1),NULL); ++ g_free(repo); ++ repo = temp; ++ } ++ ++ temp = parsed_name; ++ parsed_name = g_strconcat(temp,"_",items[len-2],NULL); ++ g_free(temp); ++ ++ pk_debug("type is %s, group is %s, parsed_name is %s",items[len-2],items[len-1],parsed_name); ++ ++ g_hash_table_insert(releases, parsed_name, repo); ++ g_free(contents); ++ contents = NULL; ++ } ++ else ++ g_free(parsed_name); ++ g_strfreev(items); ++ } ++ g_dir_close(dir); ++ ++ /* and then we need to do this again, but this time we're looking for the packages */ ++ dir = g_dir_open(sdir,0,&error); ++ res = sqlite3_prepare_v2(db, "insert or replace into packages values (?,?,?,?,?,?,?)", -1, &package, NULL); ++ if (res!=SQLITE_OK) ++ pk_error("sqlite error during insert prepare: %s", sqlite3_errmsg(db)); ++ else ++ pk_debug("insert prepare ok for %p",package); ++ while ((fname = g_dir_read_name(dir))!=NULL) ++ { ++ gchar** items = g_strsplit(fname,"_",-1); ++ guint len = g_strv_length(items); ++ if(len<=3) // minimum is __ ++ { ++ g_strfreev(items); ++ continue; ++ } ++ ++ if (g_ascii_strcasecmp(items[len-1],"Packages")==0) ++ { ++ const gchar *repo; ++ gchar *temp=NULL, *parsed_name=NULL; ++ gchar *fullname= NULL; ++ gchar *begin=NULL, *next=NULL, *description = NULL; ++ glong count = 0; ++ gboolean haspk = FALSE; ++ ++ /* warning: nasty hack with g_strjoinv */ ++ if (g_str_has_prefix(items[len-2],"binary-")) ++ { ++ temp = items[len-3]; ++ items[len-3] = NULL; ++ parsed_name = g_strjoinv("_",items); ++ items[len-3] = temp; ++ } ++ else ++ { ++ temp = items[len-1]; ++ items[len-1] = NULL; ++ parsed_name = g_strjoinv("_",items); ++ items[len-1] = temp; ++ } ++ ++ pk_debug("type is %s, group is %s, parsed_name is %s",items[len-2],items[len-1],parsed_name); ++ ++ repo = (const gchar *)g_hash_table_lookup(releases,parsed_name); ++ if (repo == NULL) ++ { ++ pk_debug("Can't find repo for %s, marking as \"unknown\"",parsed_name); ++ repo = g_strdup("unknown"); ++ //g_assert(0); ++ } ++ else ++ pk_debug("repo for %s is %s",parsed_name,repo); ++ g_free(parsed_name); ++ ++ fullname = g_build_filename(sdir,fname,NULL); ++ pk_debug("loading %s",fullname); ++ if (g_file_get_contents(fullname,&contents,NULL,NULL) == FALSE) ++ { ++ pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "error loading %s",fullname); ++ goto search_task_cleanup; ++ } ++ /*else ++ pk_debug("loaded");*/ ++ ++ res = sqlite3_bind_text(package,FIELD_REPO,repo,-1,SQLITE_TRANSIENT); ++ if (res!=SQLITE_OK) ++ pk_error("sqlite error during repo bind: %s", sqlite3_errmsg(db)); ++ /*else ++ pk_debug("repo bind ok");*/ ++ ++ res = sqlite3_exec(db,"begin",NULL,NULL,NULL); ++ g_assert(res == SQLITE_OK); ++ ++ begin = contents; ++ ++ while (true) ++ { ++ next = strstr(begin,"\n"); ++ if (next!=NULL) ++ { ++ next[0] = '\0'; ++ next++; ++ } ++ ++ if (begin[0]=='\0') ++ { ++ if (haspk) ++ { ++ if (description!=NULL) ++ { ++ res=sqlite3_bind_text(package,FIELD_LONG,description,-1,SQLITE_TRANSIENT); ++ if (res!=SQLITE_OK) ++ pk_error("sqlite error during description bind: %s", sqlite3_errmsg(db)); ++ g_free(description); ++ description = NULL; ++ } ++ res = sqlite3_step(package); ++ if (res!=SQLITE_DONE) ++ pk_error("sqlite error during step: %s", sqlite3_errmsg(db)); ++ sqlite3_reset(package); ++ //pk_debug("added package"); ++ haspk = FALSE; ++ } ++ //g_assert(0); ++ } ++ else if (begin[0]==' ') ++ { ++ if (description == NULL) ++ description = g_strdup(&begin[1]); ++ else ++ { ++ gchar *oldval = description; ++ description = g_strconcat(oldval, "\n",&begin[1],NULL); ++ g_free(oldval); ++ } ++ } ++ else ++ { ++ gchar *colon = strchr(begin,':'); ++ g_assert(colon!=NULL); ++ colon[0] = '\0'; ++ colon+=2; ++ /*if (strlen(colon)>3000) ++ pk_error("strlen(colon) = %d\ncolon = %s",strlen(colon),colon);*/ ++ //pk_debug("entry = '%s','%s'",begin,colon); ++ if (begin[0] == 'P' && g_strcasecmp("Package",begin)==0) ++ { ++ res=sqlite3_bind_text(package,FIELD_PKG,colon,-1,SQLITE_STATIC); ++ haspk = TRUE; ++ count++; ++ if (count%1000==0) ++ pk_debug("Package %ld (%s)",count,colon); ++ } ++ else if (begin[0] == 'V' && g_strcasecmp("Version",begin)==0) ++ res=sqlite3_bind_text(package,FIELD_VER,colon,-1,SQLITE_STATIC); ++ else if (begin[0] == 'D' && g_strcasecmp("Depends",begin)==0) ++ res=sqlite3_bind_text(package,FIELD_DEPS,colon,-1,SQLITE_STATIC); ++ else if (begin[0] == 'A' && g_strcasecmp("Architecture",begin)==0) ++ res=sqlite3_bind_text(package,FIELD_ARCH,colon,-1,SQLITE_STATIC); ++ else if (begin[0] == 'D' && g_strcasecmp("Description",begin)==0) ++ res=sqlite3_bind_text(package,FIELD_SHORT,colon,-1,SQLITE_STATIC); ++ if (res!=SQLITE_OK) ++ pk_error("sqlite error during %s bind: %s", begin, sqlite3_errmsg(db)); ++ } ++ if (next == NULL) ++ break; ++ begin = next; ++ } ++ res = sqlite3_exec(db,"commit",NULL,NULL,NULL); ++ if (res!=SQLITE_OK) ++ pk_error("sqlite error during commit: %s", sqlite3_errmsg(db)); ++ res = sqlite3_clear_bindings(package); ++ if (res!=SQLITE_OK) ++ pk_error("sqlite error during clear: %s", sqlite3_errmsg(db)); ++ g_free(contents); ++ contents = NULL; ++ } ++ } ++ sqlite3_finalize(package); ++ ++search_task_cleanup: ++ g_dir_close(dir); ++ g_free(sdir); ++ g_free(contents); ++} ++ +diff --git a/backends/apt.deprecated/pk-apt-build-db.h b/backends/apt.deprecated/pk-apt-build-db.h +new file mode 100644 +index 0000000..bb786a9 +--- /dev/null ++++ b/backends/apt.deprecated/pk-apt-build-db.h +@@ -0,0 +1,30 @@ ++#ifndef PK_APT_BUILD_DB ++#define PK_APT_BUILD_DB ++ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- ++ * ++ * Copyright (C) 2007 Tom Parker ++ * ++ * Licensed under the GNU General Public License Version 2 ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++#include ++#include ++ ++void apt_build_db(PkBackend * backend, sqlite3 *db); ++ ++#endif +diff --git a/backends/apt.deprecated/pk-apt-search-plain.c b/backends/apt.deprecated/pk-apt-search-plain.c +new file mode 100644 +index 0000000..5e5b4e5 +--- /dev/null ++++ b/backends/apt.deprecated/pk-apt-search-plain.c +@@ -0,0 +1,106 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- ++ * ++ * Copyright (C) 2007 Ali Sabil ++ * ++ * Licensed under the GNU General Public License Version 2 ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++extern PkBackendSpawn *spawn; ++ ++/** ++ * backend_get_groups: ++ */ ++static PkGroupEnum ++backend_get_groups (PkBackend *backend) ++{ ++ return (PK_GROUP_ENUM_ACCESSORIES | ++ PK_GROUP_ENUM_GAMES | ++ PK_GROUP_ENUM_GRAPHICS | ++ PK_GROUP_ENUM_INTERNET | ++ PK_GROUP_ENUM_OFFICE | ++ PK_GROUP_ENUM_OTHER | ++ PK_GROUP_ENUM_PROGRAMMING | ++ PK_GROUP_ENUM_MULTIMEDIA | ++ PK_GROUP_ENUM_SYSTEM); ++} ++ ++/** ++ * backend_get_filters: ++ */ ++static PkFilterEnum ++backend_get_filters (PkBackend *backend) ++{ ++ return (PK_FILTER_ENUM_GUI | ++ PK_FILTER_ENUM_INSTALLED | ++ PK_FILTER_ENUM_DEVELOPMENT); ++} ++ ++/** ++ * backend_get_details: ++ */ ++ ++void ++backend_get_details (PkBackend *backend, const gchar *package_id) ++{ ++ pk_backend_spawn_helper (spawn, "get-details.py", package_id, NULL); ++} ++ ++/** ++ * backend_search_details: ++ */ ++ ++void ++backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *search) ++{ ++ gchar *filters_text; ++ filters_text = pk_filter_enums_to_text (filters); ++ pk_backend_spawn_helper (spawn, "search-details.py", filters_texts_text, search, NULL); ++ g_free (filters_text); ++} ++ ++/** ++ * backend_search_name: ++ */ ++void ++backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search) ++{ ++ gchar *filters_text; ++ filters_text = pk_filter_enums_to_text (filters); ++ pk_backend_spawn_helper (spawn, "search-name.py", filters_text, search, NULL); ++ g_free (filters_text); ++} ++ ++/** ++ * backend_search_group: ++ */ ++void ++backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *search) ++{ ++ gchar *filters_text; ++ pk_backend_spawn_helper (spawn, "search-group.py", filters_text, search, NULL); ++ g_free (filters_text); ++} ++ ++/* don't need to do any setup/finalize in the plain search mode */ ++void backend_init_search(PkBackend *backend) {} ++void backend_finish_search(PkBackend *backend) {} +diff --git a/backends/apt.deprecated/pk-apt-search-sqlite.cpp b/backends/apt.deprecated/pk-apt-search-sqlite.cpp +new file mode 100644 +index 0000000..98bdc7f +--- /dev/null ++++ b/backends/apt.deprecated/pk-apt-search-sqlite.cpp +@@ -0,0 +1,135 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- ++ * ++ * Copyright (C) 2007 Ali Sabil ++ * ++ * Licensed under the GNU General Public License Version 2 ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "pk-sqlite-pkg-cache.h" ++#include ++#include ++#include "pk-apt-build-db.h" ++ ++static PkBackendSpawn *spawn; ++ ++/** ++ * backend_get_groups: ++ */ ++extern "C" PkGroupEnum ++backend_get_groups (PkBackend *backend) ++{ ++ return (PK_GROUP_ENUM_ACCESSORIES | ++ PK_GROUP_ENUM_GAMES | ++ PK_GROUP_ENUM_GRAPHICS | ++ PK_GROUP_ENUM_INTERNET | ++ PK_GROUP_ENUM_OFFICE | ++ PK_GROUP_ENUM_OTHER | ++ PK_GROUP_ENUM_PROGRAMMING | ++ PK_GROUP_ENUM_MULTIMEDIA | ++ PK_GROUP_ENUM_SYSTEM); ++} ++ ++/** ++ * backend_get_filters: ++ */ ++extern "C" PkFilterEnum ++backend_get_filters (PkBackend *backend) ++{ ++ return (PK_FILTER_ENUM_GUI | ++ PK_FILTER_ENUM_INSTALLED | ++ PK_FILTER_ENUM_DEVELOPMENT); ++} ++ ++/** ++ * backend_get_details: ++ */ ++ ++extern "C" void ++backend_get_details (PkBackend *backend, const gchar *package_id) ++{ ++ sqlite_get_details(backend,package_id); ++} ++ ++/** ++ * backend_search_details: ++ */ ++ ++extern "C" void ++backend_search_details (PkBackend *backend, const gchar *filter, const gchar *search) ++{ ++ sqlite_search_details(backend,filter,search); ++} ++ ++/** ++ * backend_search_name: ++ */ ++extern "C" void ++backend_search_name (PkBackend *backend, const gchar *filter, const gchar *search) ++{ ++ sqlite_search_name(backend,filter,search); ++} ++ ++/** ++ * backend_search_group: ++ */ ++extern "C" void ++backend_search_group (PkBackend *backend, const gchar *filter, const gchar *search) ++{ ++ pk_backend_set_allow_cancel (backend, TRUE); ++ pk_backend_spawn_helper (spawn, "search-group.py", filter, search, NULL); ++} ++ ++static gboolean inited = FALSE; ++ ++#define APT_DB PK_DB_DIR "/apt.db" ++ ++extern "C" void backend_init_search(PkBackend *backend) ++{ ++ if (!inited) ++ { ++ gchar *apt_fname = NULL; ++ if (pkgInitConfig(*_config) == false) ++ pk_debug("pkginitconfig was false"); ++ if (pkgInitSystem(*_config, _system) == false) ++ pk_debug("pkginitsystem was false"); ++ ++ apt_fname = g_strconcat( ++ _config->Find("Dir").c_str(), ++ _config->Find("Dir::Cache").c_str(), ++ _config->Find("Dir::Cache::pkgcache").c_str(), ++ NULL); ++ ++ //sqlite_set_installed_check(is_installed); ++ sqlite_init_cache(backend, APT_DB, apt_fname, apt_build_db); ++ g_free(apt_fname); ++ ++ spawn = pk_backend_spawn_new (); ++ pk_backend_spawn_set_name (spawn, "apt-sqlite"); ++ ++ inited = TRUE; ++ } ++} ++ ++extern "C" void backend_finish_search(PkBackend *backend) ++{ ++ sqlite_finish_cache(backend); ++} +diff --git a/backends/apt.deprecated/pk-apt-search.h b/backends/apt.deprecated/pk-apt-search.h +new file mode 100644 +index 0000000..e36e89f +--- /dev/null ++++ b/backends/apt.deprecated/pk-apt-search.h +@@ -0,0 +1,36 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- ++ * ++ * Copyright (C) 2007 Tom Parker ++ * ++ * Licensed under the GNU General Public License Version 2 ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++#ifndef __PK_APT_SEARCH_H ++#define __PK_APT_SEARCH_H ++ ++#include ++#include ++ ++void backend_init_search(PkBackend *backend); ++void backend_finish_search(PkBackend *backend); ++ ++void backend_get_details (PkBackend *backend, const gchar *package_id); ++void backend_search_details (PkBackend *backend, const gchar *filter, const gchar *search); ++void backend_search_name (PkBackend *backend, const gchar *filter, const gchar *search); ++void backend_search_group (PkBackend *backend, const gchar *filter, const gchar *search); ++ ++#endif +diff --git a/backends/apt.deprecated/pk-backend-apt.c b/backends/apt.deprecated/pk-backend-apt.c +new file mode 100644 +index 0000000..f59cd88 +--- /dev/null ++++ b/backends/apt.deprecated/pk-backend-apt.c +@@ -0,0 +1,268 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- ++ * ++ * Copyright (C) 2007 Ali Sabil ++ * Copyright (C) 2007 Tom Parker ++ * ++ * Licensed under the GNU General Public License Version 2 ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "pk-apt-search.h" ++#include "config.h" ++ ++PkBackendSpawn *spawn; ++ ++/** ++ * backend_initialize: ++ * This should only be run once per backend load, i.e. not every transaction ++ */ ++static void ++backend_initialize (PkBackend *backend) ++{ ++ pk_debug ("FILTER: initialize"); ++ spawn = pk_backend_spawn_new (); ++ pk_backend_spawn_set_name (spawn, "apt"); ++ backend_init_search (backend); ++} ++ ++/** ++ * backend_destroy: ++ * This should only be run once per backend load, i.e. not every transaction ++ */ ++static void ++backend_destroy (PkBackend *backend) ++{ ++ pk_debug ("FILTER: destroy"); ++ backend_finish_search (backend); ++ g_object_unref (spawn); ++} ++ ++/** ++ * backend_get_groups: ++ */ ++static PkGroupEnum ++backend_get_groups (PkBackend *backend) ++{ ++ return (PK_GROUP_ENUM_ACCESSORIES | ++ PK_GROUP_ENUM_GAMES | ++ PK_GROUP_ENUM_GRAPHICS | ++ PK_GROUP_ENUM_INTERNET | ++ PK_GROUP_ENUM_OFFICE | ++ PK_GROUP_ENUM_OTHER | ++ PK_GROUP_ENUM_PROGRAMMING | ++ PK_GROUP_ENUM_MULTIMEDIA | ++ PK_GROUP_ENUM_SYSTEM); ++} ++ ++/** ++ * backend_get_filters: ++ */ ++static PkFilterEnum ++backend_get_filters (PkBackend *backend) ++{ ++ return (PK_FILTER_ENUM_GUI | ++ PK_FILTER_ENUM_INSTALLED | ++ PK_FILTER_ENUM_DEVELOPMENT); ++} ++ ++/** ++ * pk_backend_bool_to_text: ++ */ ++static const gchar * ++pk_backend_bool_to_text (gboolean value) ++{ ++ if (value == TRUE) { ++ return "yes"; ++ } ++ return "no"; ++} ++ ++/** ++ * backend_get_depends: ++ */ ++static void ++backend_get_depends (PkBackend *backend, PkFilterEnum filters, const gchar *package_id, gboolean recursive) ++{ ++ gchar *filters_text; ++ filters_text = pk_filter_enums_to_text (filters); ++ pk_backend_spawn_helper (spawn, "get-depends.py", filters_text, package_id, pk_backend_bool_to_text (recursive), NULL); ++ g_free (filters_text); ++} ++ ++/** ++ * backend_get_updates: ++ */ ++static void ++backend_get_updates (PkBackend *backend, PkFilterEnum filters) ++{ ++ gchar *filters_text; ++ filters_text = pk_filter_enums_to_text (filters); ++ pk_backend_spawn_helper (spawn, "get-updates.py", filters_text, NULL); ++ g_free (filters_text); ++} ++ ++/** ++ * backend_get_update_detail: ++ */ ++static void ++backend_get_update_detail (PkBackend *backend, const gchar *package_id) ++{ ++ pk_backend_spawn_helper (spawn, "get-update-detail.py", package_id, NULL); ++} ++ ++/** ++ * backend_install_packages: ++ */ ++static void ++backend_install_packages (PkBackend *backend, gchar **package_ids) ++{ ++ gchar *package_ids_temp; ++ ++ /* check network state */ ++ if (!pk_backend_is_online (backend)) { ++ pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot install when offline"); ++ pk_backend_finished (backend); ++ return; ++ } ++ ++ /* send the complete list as stdin */ ++ package_ids_temp = pk_package_ids_to_text (package_ids, "|"); ++ pk_backend_spawn_helper (spawn, "install-packages.py", package_ids_temp, NULL); ++ g_free (package_ids_temp); ++} ++ ++/** ++ * backend_refresh_cache: ++ */ ++static void ++backend_refresh_cache (PkBackend *backend, gboolean force) ++{ ++ /* check network state */ ++ if (!pk_backend_is_online (backend)) { ++ pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot refresh cache whilst offline"); ++ pk_backend_finished (backend); ++ return; ++ } ++ ++ pk_backend_spawn_helper (spawn, "refresh-cache.py", NULL); ++} ++ ++/** ++ * pk_backend_remove_packages: ++ * ++static void ++backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow_deps, gboolean autoremove) ++{ ++ gchar *package_ids_temp; ++ package_ids_temp = pk_package_ids_to_text (package_ids, "|"); ++ pk_backend_spawn_helper (spawn, "remove-packages.py", pk_backend_bool_to_text (allow_deps), package_ids_temp, NULL); ++ g_free (package_ids_temp); ++} */ ++ ++/** ++ * pk_backend_update_packages: ++ */ ++static void ++backend_update_packages (PkBackend *backend, gchar **package_ids) ++{ ++ gchar *package_ids_temp; ++ ++ /* check network state */ ++ if (!pk_backend_is_online (backend)) { ++ pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot install when offline"); ++ pk_backend_finished (backend); ++ return; ++ } ++ ++ /* send the complete list as stdin */ ++ package_ids_temp = pk_package_ids_to_text (package_ids, "|"); ++ pk_backend_spawn_helper (spawn, "update-packages.py", package_ids_temp, NULL); ++ g_free (package_ids_temp); ++} ++ ++/** ++ * pk_backend_update_system: ++ */ ++static void ++backend_update_system (PkBackend *backend) ++{ ++ pk_backend_spawn_helper (spawn, "update-system.py", NULL); ++} ++ ++/** ++ * pk_backend_resolve: ++ */ ++static void ++backend_resolve (PkBackend *backend, PkFilterEnum filters, const gchar *package_id) ++{ ++ gchar *filters_text; ++ filters_text = pk_filter_enums_to_text (filters); ++ pk_backend_spawn_helper (spawn, "resolve.py", filters_text, package_id, NULL); ++ g_free (filters_text); ++} ++ ++/** ++ * pk_backend_get_repo_list: ++ */ ++static void ++backend_get_repo_list (PkBackend *backend, PkFilterEnum filters) ++{ ++ gchar *filters_text; ++ filters_text = pk_filter_enums_to_text (filters); ++ pk_backend_spawn_helper (spawn, "get-repo-list.py", filters_text, NULL); ++ g_free (filters_text); ++} ++ ++PK_BACKEND_OPTIONS ( ++ "Apt (with " APT_SEARCH " searching)", /* description */ ++ "Ali Sabil ; Tom Parker ", /* author */ ++ backend_initialize, /* initalize */ ++ backend_destroy, /* destroy */ ++ backend_get_groups, /* get_groups */ ++ backend_get_filters, /* get_filters */ ++ NULL, /* cancel */ ++ backend_get_depends, /* get_depends */ ++ backend_get_details, /* get_details */ ++ NULL, /* get_files */ ++ NULL, /* get_packages */ ++ backend_get_repo_list, /* get_repo_list */ ++ NULL, /* get_requires */ ++ backend_get_update_detail, /* get_update_detail */ ++ backend_get_updates, /* get_updates */ ++ NULL, /* install_files */ ++ backend_install_packages, /* install_packages */ ++ NULL, /* install_signature */ ++ backend_refresh_cache, /* refresh_cache */ ++ NULL, /* remove_packages */ ++ NULL, /* repo_enable */ ++ NULL, /* repo_set_data */ ++ backend_resolve, /* resolve */ ++ NULL, /* rollback */ ++ backend_search_details, /* search_details */ ++ NULL, /* search_file */ ++ backend_search_group, /* search_group */ ++ backend_search_name, /* search_name */ ++ NULL, /* service_pack */ ++ backend_update_package, /* update_package */ ++ backend_update_system, /* update_system */ ++ NULL /* what_provides */ ++); +diff --git a/backends/apt.deprecated/pk-sqlite-pkg-cache.cpp b/backends/apt.deprecated/pk-sqlite-pkg-cache.cpp +new file mode 100644 +index 0000000..1bf9a50 +--- /dev/null ++++ b/backends/apt.deprecated/pk-sqlite-pkg-cache.cpp +@@ -0,0 +1,215 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- ++ * ++ * Copyright (C) 2007 Tom Parker ++ * ++ * Licensed under the GNU General Public License Version 2 ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++#include ++#include ++#include "pk-sqlite-pkg-cache.h" ++ ++static sqlite3 *db = NULL; ++static PkBackend *backend; ++static gboolean(*is_installed) (const PkPackageId *) = NULL; ++ ++void sqlite_set_installed_check(gboolean(*func) (const PkPackageId *)) ++{ ++ is_installed = func; ++} ++ ++void ++sqlite_init_cache(PkBackend *backend, const char* dbname, const char *compare_fname, void (*build_db)(PkBackend *, sqlite3 *)) ++{ ++ int ret; ++ struct stat st; ++ time_t db_age; ++ ++ ret = sqlite3_open (dbname, &db); ++ g_assert(ret == SQLITE_OK); ++ g_assert(db!=NULL); ++ ret = sqlite3_exec(db,"PRAGMA synchronous = OFF",NULL,NULL,NULL); ++ g_assert(ret == SQLITE_OK); ++ ++ g_stat(dbname, &st); ++ db_age = st.st_mtime; ++ g_stat(compare_fname, &st); ++ if (db_age>=st.st_mtime) ++ { ++ ret = sqlite3_exec(db, "select value from params where name = 'build_complete'", NULL, NULL, NULL); ++ if (ret != SQLITE_ERROR) ++ return; ++ pk_debug("ages are %lu for db, and %lu for comparism",db_age,st.st_mtime); ++ } ++ ret = sqlite3_exec(db,"drop table packages",NULL,NULL,NULL); // wipe it! ++ //g_assert(ret == SQLITE_OK); ++ pk_debug("wiped db"); ++ ret = sqlite3_exec(db,"create table packages (name text, version text, deps text, arch text, short_desc text, long_desc text, repo string, primary key(name,version,arch,repo))",NULL,NULL,NULL); ++ g_assert(ret == SQLITE_OK); ++ ++ build_db(backend,db); ++ ++ sqlite3_exec(db,"create table params (name text primary key, value integer)", NULL, NULL, NULL); ++ sqlite3_exec(db,"insert into params values ('build_complete',1)", NULL, NULL, NULL); ++} ++ ++void sqlite_finish_cache(PkBackend *backend) ++{ ++ sqlite3_close(db); ++} ++ ++// sqlite_search_packages_thread ++static gboolean ++sqlite_search_packages_thread (PkBackend *backend) ++{ ++ int res; ++ gchar *sel; ++ const gchar *search; ++ ++ pk_backend_set_status(backend, PK_STATUS_ENUM_QUERY); ++ pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); ++ type = pk_backend_get_uint (backend, "type"); ++ search = pk_backend_get_string (backend, "search"); ++ ++ pk_debug("finding %s", search); ++ ++ sqlite3_stmt *package = NULL; ++ g_strdelimit(search," ",'%'); ++ ++ if (type == SEARCH_NAME) ++ sel = g_strdup_printf("select name,version,arch,repo,short_desc from packages where name like '%%%s%%'",search); ++ else if (type == SEARCH_DETAILS) ++ sel = g_strdup_printf("select name,version,arch,repo,short_desc from packages where name like '%%%s%%' or short_desc like '%%%s%%' or long_desc like '%%%s%%'",search, search, search); ++ else ++ { ++ pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "Unknown search task type"); ++ goto end_search_packages; ++ } ++ ++ pk_debug("statement is '%s'",sel); ++ res = sqlite3_prepare_v2(db,sel, -1, &package, NULL); ++ g_free(sel); ++ if (res!=SQLITE_OK) ++ pk_error("sqlite error during select prepare: %s", sqlite3_errmsg(db)); ++ res = sqlite3_step(package); ++ while (res == SQLITE_ROW) ++ { ++ PkPackageId *pid = pk_package_id_new_from_list((const gchar*)sqlite3_column_text(package,0), ++ (const gchar*)sqlite3_column_text(package,1), ++ (const gchar*)sqlite3_column_text(package,2), ++ (const gchar*)sqlite3_column_text(package,3)); ++ ++ gchar *cpid = pk_package_id_to_string(pid); ++ PkInfoEnum pie = PK_INFO_ENUM_UNKNOWN; ++ ++ if (is_installed != NULL) ++ pie = is_installed(pid)?PK_INFO_ENUM_INSTALLED:PK_INFO_ENUM_AVAILABLE; ++ ++ pk_backend_package(backend, pie, cpid, (const gchar*)sqlite3_column_text(package,4)); ++ ++ g_free(cpid); ++ pk_package_id_free(pid); ++ ++ if (res==SQLITE_ROW) ++ res = sqlite3_step(package); ++ } ++ if (res!=SQLITE_DONE) ++ { ++ pk_debug("sqlite error during step (%d): %s", res, sqlite3_errmsg(db)); ++ g_assert(0); ++ } ++ ++end_search_packages: ++ pk_backend_finished (backend); ++ return TRUE; ++} ++ ++/** ++ * sqlite_search_details: ++ */ ++void ++sqlite_search_details (PkBackend *backend, const gchar *filter, const gchar *search) ++{ ++ pk_backend_set_uint (backend, "type", SEARCH_DETAILS); ++ pk_backend_thread_create (backend, sqlite_search_packages_thread); ++} ++ ++/** ++ * sqlite_search_name: ++ */ ++void ++sqlite_search_name (PkBackend *backend, const gchar *filter, const gchar *search) ++{ ++ pk_backend_set_uint (backend, "type", SEARCH_NAME); ++ pk_backend_thread_create (backend, sqlite_search_packages_thread); ++} ++ ++// sqlite_get_details_thread ++static gboolean ++sqlite_get_details_thread (PkBackend *backend) ++{ ++ PkPackageId *pi; ++ const gchar *package_id; ++ int res; ++ ++ package_id = pk_backend_get_string (backend, "package_id"); ++ pi = pk_package_id_new_from_string(package_id); ++ if (pi == NULL) ++ { ++ pk_backend_error_code(backend, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "invalid package id"); ++ pk_backend_finished(backend); ++ return; ++ } ++ ++ pk_backend_set_status(backend, PK_STATUS_ENUM_QUERY); ++ pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); ++ ++ pk_debug("finding %s", pi->name); ++ ++ sqlite3_stmt *package = NULL; ++ gchar *sel = g_strdup_printf("select long_desc from packages where name = '%s' and version = '%s' and repo = '%s'",pi->name,pi->version,pi->data); ++ pk_debug("statement is '%s'",sel); ++ res = sqlite3_prepare_v2(db,sel, -1, &package, NULL); ++ g_free(sel); ++ if (res!=SQLITE_OK) ++ pk_error("sqlite error during select prepare: %s", sqlite3_errmsg(db)); ++ res = sqlite3_step(package); ++ pk_backend_details(backend,pi->name, "unknown", PK_GROUP_ENUM_OTHER,(const gchar*)sqlite3_column_text(package,0),"",0); ++ res = sqlite3_step(package); ++ if (res==SQLITE_ROW) ++ pk_error("multiple matches for that package!"); ++ if (res!=SQLITE_DONE) ++ { ++ pk_debug("sqlite error during step (%d): %s", res, sqlite3_errmsg(db)); ++ g_assert(0); ++ } ++ ++ g_free(dt); ++ ++ return TRUE; ++} ++ ++/** ++ * sqlite_get_details: ++ */ ++extern "C++" void ++sqlite_get_details (PkBackend *backend, const gchar *package_id) ++{ ++ pk_backend_thread_create (backend, sqlite_get_details_thread); ++ return; ++} ++ +diff --git a/backends/apt.deprecated/pk-sqlite-pkg-cache.h b/backends/apt.deprecated/pk-sqlite-pkg-cache.h +new file mode 100644 +index 0000000..68fad42 +--- /dev/null ++++ b/backends/apt.deprecated/pk-sqlite-pkg-cache.h +@@ -0,0 +1,42 @@ ++#ifndef SQLITE_PKT_CACHE ++#define SQLITE_PKT_CACHE ++ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- ++ * ++ * Copyright (C) 2007 Tom Parker ++ * ++ * 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. ++ */ ++ ++typedef enum { ++ SEARCH_NAME = 1, ++ SEARCH_DETAILS, ++ SEARCH_FILE ++} SearchDepth; ++ ++#include ++#include ++ ++void sqlite_init_cache(PkBackend *backend, const char* dbname, const char* compare_fname, void (*build_db)(PkBackend *, sqlite3 *db)); ++void sqlite_finish_cache(PkBackend *backend); ++ ++void sqlite_search_details (PkBackend *backend, const gchar *filter, const gchar *search); ++void sqlite_search_name (PkBackend *backend, const gchar *filter, const gchar *search); ++void backend_search_common(PkBackend * backend, const gchar * filter, const gchar * search, SearchDepth which, PkBackendThreadFunc func); ++void sqlite_get_details (PkBackend *backend, const gchar *package_id); ++ ++#endif +diff --git a/backends/apt/HACKING b/backends/apt/HACKING +new file mode 100644 +index 0000000..2b99c5d +--- /dev/null ++++ b/backends/apt/HACKING +@@ -0,0 +1,5 @@ ++The backend can be tested by running it as root from the source code ++repository. Make sure to kill packagekitd before to force a reintializing ++of the cache: ++ ++ killall packagekitd; python aptDBUSBackend.py +diff --git a/backends/apt/Makefile.am b/backends/apt/Makefile.am +index 07b4131..e315ba9 100644 +--- a/backends/apt/Makefile.am ++++ b/backends/apt/Makefile.am +@@ -1,30 +1,25 @@ +-NULL = ++NULL = + +-SUBDIRS = helpers + plugindir = $(PK_PLUGIN_DIR) + plugin_LTLIBRARIES = libpk_backend_apt.la +- ++libpk_backend_apt_la_SOURCES = pk-backend-apt.c + libpk_backend_apt_la_LIBADD = $(PK_PLUGIN_LIBS) +-libpk_backend_apt_la_LDFLAGS = -module -avoid-version $(APT_LIBS) +-libpk_backend_apt_la_CFLAGS = $(PK_PLUGIN_CFLAGS) $(APT_CFLAGS) +-libpk_backend_apt_la_CXXFLAGS = $(PK_PLUGIN_CFLAGS) $(APT_CFLAGS) -DPK_DB_DIR=\""$(PK_DB_DIR)"\" ++libpk_backend_apt_la_LDFLAGS = -module -avoid-version ++libpk_backend_apt_la_CFLAGS = $(PK_PLUGIN_CFLAGS) ++ ++dbusinstancedir = $(LIBEXECDIR) ++dbusinstance_DATA = \ ++ aptDBUSBackend.py \ ++ $(NULL) ++ ++EXTRA_DIST = \ ++ $(dbusinstance_DATA) \ ++ $(NULL) + +-libpk_backend_apt_la_SOURCES = \ +- pk-backend-apt.c \ +- pk-apt-search.h \ +- $(NULL) ++install-data-hook: ++ chmod a+rx $(DESTDIR)$(libexecdir)/*.py + +-if APT_SEARCH_PLAIN +-libpk_backend_apt_la_SOURCES += \ +- pk-apt-search-plain.c \ +- $(NULL) +-endif ++clean-local : ++ rm -f *~ ++ rm -f *.pyc + +-if APT_SEARCH_SQLITE +-libpk_backend_apt_la_SOURCES += \ +- pk-sqlite-pkg-cache.h \ +- pk-sqlite-pkg-cache.cpp \ +- pk-apt-build-db.cpp \ +- pk-apt-search-sqlite.cpp \ +- $(NULL) +-endif +diff --git a/backends/apt/README b/backends/apt/README +new file mode 100644 +index 0000000..0a3da6e +--- /dev/null ++++ b/backends/apt/README +@@ -0,0 +1,23 @@ ++The name of this backend is apt2. ++ ++It supports apt which is mainly used by Debian and its derivates. In contrast to ++the backend called apt this one uses DBus for the communication with the ++packagekit daemon. This allows to perform actions without having to reopen ++the cache for each one. ++ ++To provide a tremendously fast search function a Xapian database is used. ++It is provided by Enrico Zini's apt-xapian-index. Debtags will be used to ++enhance the quality of the search results further. ++ ++A list of implemented functions are listed in the PackageKit FAQ: ++ ++http://www.packagekit.org/pk-faq.html ++ ++You can find packages for Ubuntu here: ++ ++https://www.launchpad.net/~packagekit/+ppa ++ ++Packages for Debian Unstable will be provided soon. ++ ++Feel free to send comments or bug reports to the PackageKit mailing list ++or to the author. +diff --git a/backends/apt/TODO b/backends/apt/TODO +new file mode 100644 +index 0000000..bee2f3d +--- /dev/null ++++ b/backends/apt/TODO +@@ -0,0 +1,70 @@ ++ISSUES: ++ ++ * Support delayed or hidden debconf questions ++ ++Unresolved issues can be discussed at the following wiki page: ++http://wiki.debian.org/PackageKit ++ ++ ++TODO: ++ ++ * Implement all open backend methods. A list of implemented backend methods ++ can be found in PackageKit FAQ or in pk-backend-apt2.c. ++ ++ * Blacklist packages requiring input on the terminal and try to change ++ the Debian policy in the long run. Way of automation? ++ ++ * Allow to inject alternative apt.package.Package classes into the ++ cache to support PackageKit and distribution specific needs ++ (e.g. when is a package called free or supported) ++ ++ * Allow to reinject debtags into the search results to get ++ similar software which not matches on the search terms ++ ++ * Index file list and add properties for package name and section to ++ the xapian database to also make use of it in search group and ++ search name (do we want this?) ++ ++ * Map Debian/Ubuntu sections to PackageKit groups: ++ - admin : System Administration => admin-tools ++ - base : Base System => system ++ - comm : Communication => communication ++ - devel : Development => programming ++ - doc : Documentation => ??? ++ - editors : Editors => accessoires ++ - electronics : Electronics => other ++ - embedded : Embedded Devices => system ++ - games : Games and Amusement => games ++ - gnome : GNOME Desktop Environment => desktop-gnome ++ - graphics : Graphics => graphics ++ - hamradio : Amateur Radio => communication ++ - interpreters : Interpreted Computer L. => programming ++ - kde : KDE Desktop Environment => desktop-kde ++ - libdevel : Libraries - Development => programming ++ - libs : Libraries => system ++ - mail : Email => internet ++ - math : Mathematics => ??? science/education ++ - misc : Miscellaneous - Text Based => other ++ - net : Networkinga => network ++ - news : Newsgroup => internet ++ - oldlibs : Libraries - Old => legacy ++ - otherosfs : Cross Platform => system ++ - perl : Perl Programming Language => programming ++ - python : Python Programming Language => programming ++ - science : Science => ??? science/education ++ - shells : Shells => system ++ - sound : Multimedia => multimedia ++ - tex : TeX Authoring => publishing ++ - text : Word Processing => publishing ++ - utils : Utilities => accessoires ++ - web : World Wide Web => internet ++ - x11 : Miscellaneous - Graphical => desktop-other ++ - unknown : Unknown => unknown ++ - alien : Converted From RPM by Alien" => unknown ++ - translations => localization ++ The following could not be maped: science, documentation, electronics ++ Are there any derivates with additional sections? ++ ++ * Fix the dbus policy. Should we require at_console for searching? ++ ++DONE: +diff --git a/backends/apt/aptDBUSBackend.py b/backends/apt/aptDBUSBackend.py +new file mode 100755 +index 0000000..22eb714 +--- /dev/null ++++ b/backends/apt/aptDBUSBackend.py +@@ -0,0 +1,679 @@ ++#!/usr/bin/env python ++# -*- coding: utf-8 -*- ++""" ++Provides an apt backend to PackageKit ++ ++Copyright (C) 2007 Ali Sabil ++Copyright (C) 2007 Tom Parker ++Copyright (C) 2008 Sebastian Heinlein ++ ++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. ++""" ++ ++__author__ = "Sebastian Heinlein " ++__state__ = "experimental" ++ ++import os ++import pty ++import re ++import signal ++import time ++import threading ++import warnings ++ ++import apt ++import apt_pkg ++import dbus ++import dbus.glib ++import dbus.service ++import dbus.mainloop.glib ++import gobject ++ ++from packagekit.daemonBackend import PACKAGEKIT_DBUS_INTERFACE, PACKAGEKIT_DBUS_PATH, PackageKitBaseBackend, PackagekitProgress, pklog, threaded, async ++from packagekit.enums import * ++ ++warnings.filterwarnings(action='ignore', category=FutureWarning) ++ ++PACKAGEKIT_DBUS_SERVICE = 'org.freedesktop.PackageKitAptBackend' ++ ++XAPIANDBPATH = os.environ.get("AXI_DB_PATH", "/var/lib/apt-xapian-index") ++XAPIANDB = XAPIANDBPATH + "/index" ++XAPIANDBVALUES = XAPIANDBPATH + "/values" ++ ++# Required for daemon mode ++os.putenv("PATH", ++ "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin") ++# Avoid questions from the maintainer scripts as far as possible ++os.putenv("DEBIAN_FRONTEND", "noninteractive") ++os.putenv("APT_LISTCHANGES_FRONTEND", "none") ++ ++# Setup threading support ++gobject.threads_init() ++dbus.glib.threads_init() ++ ++class PackageKitOpProgress(apt.progress.OpProgress): ++ ''' ++ Handle the cache opening process ++ ''' ++ def __init__(self, backend, prange=(0,100), progress=True): ++ self._backend = backend ++ apt.progress.OpProgress.__init__(self) ++ self.steps = [] ++ for v in [0.12, 0.25, 0.50, 0.75, 1.00]: ++ s = prange[0] + (prange[1] - prange[0]) * v ++ self.steps.append(s) ++ self.pstart = float(prange[0]) ++ self.pend = self.steps.pop(0) ++ self.pprev = None ++ self.show_progress = progress ++ ++ # OpProgress callbacks ++ def update(self, percent): ++ progress = int(self.pstart + percent / 100 * (self.pend - self.pstart)) ++ if self.show_progress == True and self.pprev < progress: ++ self._backend.PercentageChanged(progress) ++ self.pprev = progress ++ ++ def done(self): ++ self.pstart = self.pend ++ try: ++ self.pend = self.steps.pop(0) ++ except: ++ pklog.warning("An additional step to open the cache is required") ++ ++class PackageKitFetchProgress(apt.progress.FetchProgress): ++ ''' ++ Handle the package download process ++ ''' ++ def __init__(self, backend, prange=(0,100)): ++ self._backend = backend ++ apt.progress.FetchProgress.__init__(self) ++ self.pstart = prange[0] ++ self.pend = prange[1] ++ self.pprev = None ++ ++ # FetchProgress callbacks ++ def pulse(self): ++ if self._backend._canceled.isSet(): ++ return False ++ percent = ((self.currentBytes + self.currentItems)*100.0)/float(self.totalBytes+self.totalItems) ++ progress = int(self.pstart + percent/100 * (self.pend - self.pstart)) ++ if self.pprev < progress: ++ self._backend.PercentageChanged(progress) ++ self.pprev = progress ++ apt.progress.FetchProgress.pulse(self) ++ return True ++ ++ def start(self): ++ self._backend.StatusChanged(STATUS_DOWNLOAD) ++ self._backend.AllowCancel(True) ++ ++ def stop(self): ++ self._backend.PercentageChanged(self.pend) ++ self._backend.AllowCancel(False) ++ ++ def mediaChange(self, medium, drive): ++ #FIXME: use the Message method to notify the user ++ self._backend.error(ERROR_UNKNOWN, ++ "Medium change needed") ++ ++class PackageKitInstallProgress(apt.progress.InstallProgress): ++ ''' ++ Handle the installation and removal process. Bits taken from ++ DistUpgradeViewNonInteractive. ++ ''' ++ def __init__(self, backend, prange=(0,100)): ++ apt.progress.InstallProgress.__init__(self) ++ self._backend = backend ++ self.timeout = 900 ++ self.pstart = prange[0] ++ self.pend = prange[1] ++ self.pprev = None ++ ++ def statusChange(self, pkg, percent, status): ++ progress = self.pstart + percent/100 * (self.pend - self.pstart) ++ if self.pprev < progress: ++ self._backend.PercentageChanged(int(progress)) ++ self.pprev = progress ++ pklog.debug("PM status: %s" % status) ++ ++ def startUpdate(self): ++ self._backend.StatusChanged(STATUS_INSTALL) ++ self.last_activity = time.time() ++ ++ def updateInterface(self): ++ pklog.debug("Updating interface") ++ apt.progress.InstallProgress.updateInterface(self) ++ ++ def conffile(self, current, new): ++ pklog.critical("Config file prompt: '%s'" % current) ++ ++def sigquit(signum, frame): ++ pklog.error("Was killed") ++ sys.exit(1) ++ ++class PackageKitAptBackend(PackageKitBaseBackend): ++ ''' ++ PackageKit backend for apt ++ ''' ++ def __init__(self, bus_name, dbus_path): ++ pklog.info("Initializing APT backend") ++ signal.signal(signal.SIGQUIT, sigquit) ++ self._cache = None ++ self._canceled = threading.Event() ++ self._canceled.clear() ++ self._lock = threading.Lock() ++ # Check for xapian support ++ self._use_xapian = False ++ try: ++ import xapian ++ except ImportError: ++ pass ++ else: ++ if os.access(XAPIANDB, os.R_OK): ++ self._use_xapian = True ++ PackageKitBaseBackend.__init__(self, bus_name, dbus_path) ++ ++ # Methods ( client -> engine -> backend ) ++ ++ def doInit(self): ++ pklog.info("Initializing cache") ++ self.StatusChanged(STATUS_SETUP) ++ self.AllowCancel(False) ++ self.NoPercentageUpdates() ++ self._open_cache(progress=False) ++ ++ def doExit(self): ++ pass ++ ++ @threaded ++ def doCancel(self): ++ pklog.info("Canceling current action") ++ self.StatusChanged(STATUS_CANCEL) ++ self._canceled.set() ++ self._canceled.wait() ++ ++ @threaded ++ def doSearchName(self, filters, search): ++ ''' ++ Implement the apt2-search-name functionality ++ ''' ++ pklog.info("Searching for package name: %s" % search) ++ self.StatusChanged(STATUS_QUERY) ++ self.NoPercentageUpdates() ++ self._check_init(progress=False) ++ self.AllowCancel(True) ++ ++ for pkg in self._cache: ++ if self._canceled.isSet(): ++ self.ErrorCode(ERROR_TRANSACTION_CANCELLED, ++ "The search was canceled") ++ self.Finished(EXIT_KILL) ++ self._canceled.clear() ++ return ++ elif search in pkg.name and self._is_package_visible(pkg, filters): ++ self._emit_package(pkg) ++ self.Finished(EXIT_SUCCESS) ++ ++ @threaded ++ def doSearchDetails(self, filters, search): ++ ''' ++ Implement the apt2-search-details functionality ++ ''' ++ pklog.info("Searching for package name: %s" % search) ++ self.StatusChanged(STATUS_QUERY) ++ self.NoPercentageUpdates() ++ self._check_init(progress=False) ++ self.AllowCancel(True) ++ results = [] ++ ++ if self._use_xapian == True: ++ search_flags = (xapian.QueryParser.FLAG_BOOLEAN | ++ xapian.QueryParser.FLAG_PHRASE | ++ xapian.QueryParser.FLAG_LOVEHATE | ++ xapian.QueryParser.FLAG_BOOLEAN_ANY_CASE) ++ pklog.debug("Performing xapian db based search") ++ db = xapian.Database(XAPIANDB) ++ parser = xapian.QueryParser() ++ query = parser.parse_query(unicode(search), ++ search_flags) ++ enquire = xapian.Enquire(db) ++ enquire.set_query(query) ++ matches = enquire.get_mset(0, 1000) ++ for r in map(lambda m: m[xapian.MSET_DOCUMENT].get_data(), ++ enquire.get_mset(0,1000)): ++ if self._cache.has_key(r): ++ results.append(self._cache[r]) ++ else: ++ pklog.debug("Performing apt cache based search") ++ for p in self._cache._dict.values(): ++ if self._check_canceled("Search was canceled"): return ++ needle = search.strip().lower() ++ haystack = p.description.lower() ++ if p.name.find(needle) >= 0 or haystack.find(needle) >= 0: ++ results.append(p) ++ ++ for r in results: ++ if self._check_canceled("Search was canceled"): return ++ if self._is_package_visible(r, filters) == True: ++ self._emit_package(r) ++ ++ self.Finished(EXIT_SUCCESS) ++ ++ @threaded ++ @async ++ def doGetUpdates(self, filters): ++ ''' ++ Implement the {backend}-get-update functionality ++ ''' ++ #FIXME: Implment the basename filter ++ pklog.info("Get updates") ++ self.StatusChanged(STATUS_INFO) ++ self.AllowCancel(True) ++ self.NoPercentageUpdates() ++ self._check_init(progress=False) ++ self._cache.upgrade(False) ++ for pkg in self._cache.getChanges(): ++ if self._canceled.isSet(): ++ self.ErrorCode(ERROR_TRANSACTION_CANCELLED, ++ "Calculating updates was canceled") ++ self.Finished(EXIT_KILL) ++ self._canceled.clear() ++ return ++ else: ++ self._emit_package(pkg) ++ self._open_cache(progress=False) ++ self.Finished(EXIT_SUCCESS) ++ ++ @threaded ++ def GetDetails(self, pkg_id): ++ ''' ++ Implement the {backend}-get-details functionality ++ ''' ++ pklog.info("Get details of %s" % pkg_id) ++ self.StatusChanged(STATUS_INFO) ++ self.NoPercentageUpdates() ++ self.AllowCancel(False) ++ self._check_init(progress=False) ++ name, version, arch, data = self.get_package_from_id(pkg_id) ++ if not self._cache.has_key(name): ++ self.ErrorCode(ERROR_PACKAGE_NOT_FOUND, ++ "Package %s isn't available" % name) ++ self.Finished(EXIT_FAILED) ++ return ++ pkg = self._cache[name] ++ #FIXME: should perhaps go to python-apt since we need this in ++ # several applications ++ desc = pkg.description ++ # Skip the first line - it's a duplicate of the summary ++ i = desc.find('\n') ++ desc = desc[i+1:] ++ # do some regular expression magic on the description ++ # Add a newline before each bullet ++ p = re.compile(r'^(\s|\t)*(\*|0|-)',re.MULTILINE) ++ desc = p.sub(ur'\n\u2022', desc) ++ # replace all newlines by spaces ++ p = re.compile(r'\n', re.MULTILINE) ++ desc = p.sub(" ", desc) ++ # replace all multiple spaces by newlines ++ p = re.compile(r'\s\s+', re.MULTILINE) ++ desc = p.sub('\n', desc) ++ #FIXME: group and licence information missing ++ self.Details(pkg_id, 'unknown', 'unknown', desc, ++ pkg.homepage, pkg.packageSize) ++ self.Finished(EXIT_SUCCESS) ++ ++ @threaded ++ @async ++ def doUpdateSystem(self): ++ ''' ++ Implement the {backend}-update-system functionality ++ ''' ++ pklog.info("Upgrading system") ++ self.StatusChanged(STATUS_UPDATE) ++ self.AllowCancel(False) ++ self.PercentageChanged(0) ++ self._check_init(prange=(0,5)) ++ try: ++ self._cache.upgrade(distUpgrade=False) ++ self._cache.commit(PackageKitFetchProgress(self, prange=(5,50)), ++ PackageKitInstallProgress(self, prange=(50,95))) ++ except apt.cache.FetchFailedException: ++ self._open_cache() ++ self.ErrorCode(ERROR_PACKAGE_DOWNLOAD_FAILED, "Download failed") ++ self.Finished(EXIT_FAILED) ++ return ++ except apt.cache.FetchCancelledException: ++ self._open_cache(prange=(95,100)) ++ self.ErrorCode(ERROR_TRANSACTION_CANCELLED, "Download was canceled") ++ self.Finished(EXIT_KILL) ++ self._canceled.clear() ++ return ++ except: ++ self._open_cache(prange=(95,100)) ++ self.ErrorCode(ERROR_UNKNOWN, "System update failed") ++ self.Finished(EXIT_FAILED) ++ return ++ self.PercentageChanged(100) ++ self.Finished(EXIT_SUCCESS) ++ ++ @threaded ++ @async ++ def doRemovePackages(self, ids, deps=True, auto=False): ++ ''' ++ Implement the {backend}-remove functionality ++ ''' ++ pklog.info("Removing package(s): id %s" % ids) ++ self.StatusChanged(STATUS_REMOVE) ++ self.AllowCancel(False) ++ self.PercentageChanged(0) ++ self._check_init(prange=(0,10)) ++ pkgs=[] ++ for id in ids: ++ pkg = self._find_package_by_id(id) ++ if pkg == None: ++ self.ErrorCode(ERROR_PACKAGE_NOT_FOUND, ++ "Package %s isn't available" % id) ++ self.Finished(EXIT_FAILED) ++ return ++ if not pkg.isInstalled: ++ self.ErrorCode(ERROR_PACKAGE_NOT_INSTALLED, ++ "Package %s isn't installed" % pkg.name) ++ self.Finished(EXIT_FAILED) ++ return ++ pkgs.append(pkg.name[:]) ++ try: ++ pkg.markDelete() ++ except: ++ self._open_cache(prange=(90,99)) ++ self.ErrorCode(ERROR_UNKNOWN, "Removal of %s failed" % pkg.name) ++ self.Finished(EXIT_FAILED) ++ return ++ try: ++ self._cache.commit(PackageKitFetchProgress(self, prange=(10,10)), ++ PackageKitInstallProgress(self, prange=(10,90))) ++ except: ++ self._open_cache(prange=(90,99)) ++ self.ErrorCode(ERROR_UNKNOWN, "Removal failed") ++ self.Finished(EXIT_FAILED) ++ return ++ self._open_cache(prange=(90,99)) ++ for p in pkgs: ++ if self._cache.has_key(p) and self._cache[p].isInstalled: ++ self.ErrorCode(ERROR_UNKNOWN, "%s is still installed" % p) ++ self.Finished(EXIT_FAILED) ++ return ++ self.PercentageChanged(100) ++ self.Finished(EXIT_SUCCESS) ++ ++ @threaded ++ @async ++ def doInstallPackages(self, ids): ++ ''' ++ Implement the {backend}-install functionality ++ ''' ++ pklog.info("Installing package with id %s" % ids) ++ self.StatusChanged(STATUS_INSTALL) ++ self.AllowCancel(False) ++ self.PercentageChanged(0) ++ self._check_init(prange=(0,10)) ++ pkgs=[] ++ for id in ids: ++ pkg = self._find_package_by_id(id) ++ if pkg == None: ++ self.ErrorCode(ERROR_PACKAGE_NOT_FOUND, ++ "Package %s isn't available" % id) ++ self.Finished(EXIT_FAILED) ++ return ++ if pkg.isInstalled: ++ self.ErrorCode(ERROR_PACKAGE_ALREADY_INSTALLED, ++ "Package %s is already installed" % pkg.name) ++ self.Finished(EXIT_FAILED) ++ return ++ pkgs.append(pkg.name[:]) ++ try: ++ pkg.markInstall() ++ except: ++ self._open_cache(prange=(90,100)) ++ self.ErrorCode(ERROR_UNKNOWN, "%s could not be queued for " ++ "installation" % pkg.name) ++ self.Finished(EXIT_FAILED) ++ return ++ try: ++ self._cache.commit(PackageKitFetchProgress(self, prange=(10,50)), ++ PackageKitInstallProgress(self, prange=(50,90))) ++ except: ++ self._open_cache(prange=(90,100)) ++ self.ErrorCode(ERROR_UNKNOWN, "Installation failed") ++ self.Finished(EXIT_FAILED) ++ return ++ self._open_cache(prange=(90,100)) ++ self.PercentageChanged(100) ++ pklog.debug("Checking success of operation") ++ for p in pkgs: ++ if not self._cache.has_key(p) or not self._cache[p].isInstalled: ++ self.ErrorCode(ERROR_UNKNOWN, "%s was not installed" % p) ++ self.Finished(EXIT_FAILED) ++ return ++ pklog.debug("Sending success signal") ++ self.Finished(EXIT_SUCCESS) ++ ++ @threaded ++ @async ++ def doRefreshCache(self, force): ++ ''' ++ Implement the {backend}-refresh_cache functionality ++ ''' ++ pklog.info("Refresh cache") ++ self.StatusChanged(STATUS_REFRESH_CACHE) ++ self.last_action_time = time.time() ++ self.AllowCancel(False); ++ self.PercentageChanged(0) ++ self._check_init((0,10)) ++ try: ++ self._cache.update(PackageKitFetchProgress(self, prange=(10,95))) ++ except apt.cache.FetchFailedException: ++ self.ErrorCode(ERROR_NO_NETWORK, "Download failed") ++ self.Finished(EXIT_FAILED) ++ return ++ except apt.cache.FetchCancelledException: ++ self._canceled.clear() ++ self.ErrorCode(ERROR_TRANSACTION_CANCELLED, "Download was canceled") ++ self.Finished(EXIT_KILL) ++ return ++ except: ++ self._open_cache(prange=(95,100)) ++ self.ErrorCode(ERROR_UNKNOWN, "Refreshing cache failed") ++ self.Finished(EXIT_FAILED) ++ return ++ self.PercentageChanged(100) ++ self.Finished(EXIT_SUCCESS) ++ ++ @threaded ++ def doGetPackages(self, filters): ++ ''' ++ Implement the apt2-get-packages functionality ++ ''' ++ pklog.info("Get all packages") ++ self.StatusChanged(STATUS_QUERY) ++ self.NoPercentageUpdates() ++ self._check_init(progress=False) ++ self.AllowCancel(True) ++ ++ for pkg in self._cache: ++ if self._canceled.isSet(): ++ self.ErrorCode(ERROR_TRANSACTION_CANCELLED, ++ "The search was canceled") ++ self.Finished(EXIT_KILL) ++ self._canceled.clear() ++ return ++ elif self._is_package_visible(pkg, filters): ++ self._emit_package(pkg) ++ self.Finished(EXIT_SUCCESS) ++ ++ @threaded ++ def doResolve(self, filters, name): ++ ''' ++ Implement the apt2-resolve functionality ++ ''' ++ pklog.info("Resolve") ++ self.StatusChanged(STATUS_QUERY) ++ self.NoPercentageUpdates() ++ self._check_init(progress=False) ++ self.AllowCancel(False) ++ ++ #FIXME: Support candidates ++ if self._cache.has_key(name) and self.is_package_visible(pkg, filters): ++ self._emit_package(name) ++ self.Finished(EXIT_SUCCESS) ++ else: ++ self.ErrorCode(ERROR_PACKAGE_NOT_FOUND, ++ "Package name %s could not be resolved" % name) ++ self.Finished(EXIT_FAILED) ++ ++ # Helpers ++ ++ def _open_cache(self, prange=(0,100), progress=True): ++ ''' ++ (Re)Open the APT cache ++ ''' ++ pklog.debug("Open APT cache") ++ self.StatusChanged(STATUS_REFRESH_CACHE) ++ try: ++ self._cache = apt.Cache(PackageKitOpProgress(self, prange, ++ progress)) ++ except: ++ self.ErrorCode(ERROR_NO_CACHE, "Package cache could not be opened") ++ self.Finished(EXIT_FAILED) ++ self.Exit() ++ return ++ if self._cache._depcache.BrokenCount > 0: ++ self.ErrorCode(ERROR_DEP_RESOLUTION_FAILED, ++ "Not all dependecies can be satisfied") ++ self.Finished(EXIT_FAILED) ++ self.Exit() ++ return ++ ++ def _lock_cache(self): ++ ''' ++ Lock the cache ++ ''' ++ pklog.debug("Locking cache") ++ self._locked.acquire() ++ ++ def _unlock_cache(self): ++ ''' ++ Unlock the cache ++ ''' ++ pklog.debug("Releasing cache") ++ self._locked.release() ++ ++ def _check_init(self, prange=(0,10), progress=True): ++ ''' ++ Check if the backend was initialized well and try to recover from ++ a broken setup ++ ''' ++ pklog.debug("Check apt cache and xapian database") ++ if not isinstance(self._cache, apt.cache.Cache) or \ ++ self._cache._depcache.BrokenCount > 0: ++ self._open_cache(prange, progress) ++ ++ def _check_canceled(self, msg): ++ ''' ++ Check if the current transaction was canceled. If so send the ++ corresponding error message and return True ++ ''' ++ if self._canceled.isSet(): ++ self.ErrorCode(ERROR_TRANSACTION_CANCELLED, msg) ++ self.Finished(EXIT_KILL) ++ self._canceled.clear() ++ return True ++ return False ++ ++ def get_id_from_package(self, pkg, installed=False): ++ ''' ++ Return the id of the installation candidate of a core ++ apt package. If installed is set to True the id of the currently ++ installed package will be returned. ++ ''' ++ origin = '' ++ if installed == False and pkg.isInstalled: ++ pkgver = pkg.installedVersion ++ else: ++ pkgver = pkg.candidateVersion ++ if pkg.candidateOrigin: ++ origin = pkg.candidateOrigin[0].label ++ id = self._get_package_id(pkg.name, pkgver, pkg.architecture, origin) ++ return id ++ ++ def _emit_package(self, pkg): ++ ''' ++ Send the Package signal for a given apt package ++ ''' ++ id = self.get_id_from_package(pkg) ++ if pkg.isInstalled: ++ status = INFO_INSTALLED ++ else: ++ status = INFO_AVAILABLE ++ summary = pkg.summary ++ self.Package(status, id, summary) ++ ++ def _is_package_visible(self, pkg, filters): ++ ''' ++ Return True if the package should be shown in the user interface ++ ''' ++ #FIXME: Needs to be optmized ++ if filters == 'none': ++ return True ++ if FILTER_INSTALLED in filters and not pkg.isInstalled: ++ return False ++ if FILTER_NOT_INSTALLED in filters and pkg.isInstalled: ++ return False ++ if FILTER_GUI in filters and not self._package_has_gui(pkg): ++ return False ++ if FILTER_NOT_GUI in filters and self._package_has_gui(pkg): ++ return False ++ if FILTER_DEVELOPMENT in filters and not self._package_is_devel(pkg): ++ return False ++ if FILTER_NOT_DEVELOPMENT in filters and self._package_is_devel(pkg): ++ return False ++ return True ++ ++ def _package_has_gui(self, pkg): ++ #FIXME: should go to a modified Package class ++ #FIXME: take application data into account. perhaps checking for ++ # property in the xapian database ++ return pkg.section.split('/')[-1].lower() in ['x11', 'gnome', 'kde'] ++ ++ def _package_is_devel(self, pkg): ++ #FIXME: should go to a modified Package class ++ return pkg.name.endswith("-dev") or pkg.name.endswith("-dbg") or \ ++ pkg.section.split('/')[-1].lower() in ['devel', 'libdevel'] ++ ++ def _find_package_by_id(self, id): ++ ''' ++ Return a package matching to the given package id ++ ''' ++ # FIXME: Perform more checks ++ name, version, arch, data = self.get_package_from_id(id) ++ if self._cache.has_key(name): ++ return self._cache[name] ++ else: ++ return None ++ ++ ++def main(): ++ loop = dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) ++ bus = dbus.SystemBus(mainloop=loop) ++ bus_name = dbus.service.BusName(PACKAGEKIT_DBUS_SERVICE, bus=bus) ++ manager = PackageKitAptBackend(bus_name, PACKAGEKIT_DBUS_PATH) ++ ++if __name__ == '__main__': ++ main() ++ ++# vim: ts=4 et sts=4 +diff --git a/backends/apt/helpers/.gitignore b/backends/apt/helpers/.gitignore +deleted file mode 100644 +index 0d20b64..0000000 +--- a/backends/apt/helpers/.gitignore ++++ /dev/null +@@ -1 +0,0 @@ +-*.pyc +diff --git a/backends/apt/helpers/Makefile.am b/backends/apt/helpers/Makefile.am +deleted file mode 100644 +index 0299df2..0000000 +--- a/backends/apt/helpers/Makefile.am ++++ /dev/null +@@ -1,29 +0,0 @@ +- +-helperdir = $(datadir)/PackageKit/helpers/apt +- +-NULL = +- +-dist_helper_DATA = \ +- install-files.py \ +- search-name.py \ +- search-details.py \ +- search-group.py \ +- search-file.py \ +- get-depends.py \ +- get-details.py \ +- get-repo-list.py \ +- get-requires.py \ +- get-update-detail.py \ +- get-updates.py \ +- refresh-cache.py \ +- repo-enable.py \ +- resolve.py \ +- aptBackend.py \ +- $(NULL) +- +-install-data-hook: +- chmod a+rx $(DESTDIR)$(helperdir)/*.py +- +-clean-local : +- rm -f *~ +- +diff --git a/backends/apt/helpers/aptBackend.py b/backends/apt/helpers/aptBackend.py +deleted file mode 100644 +index e5f78ca..0000000 +--- a/backends/apt/helpers/aptBackend.py ++++ /dev/null +@@ -1,536 +0,0 @@ +-# +-# vim: ts=4 et sts=4 +-# +-# Copyright (C) 2007 Ali Sabil +-# Copyright (C) 2007 Tom Parker +-# +-# 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. +- +-import sys +-import os +-import re +- +-from packagekit.backend import * +-import apt_pkg,apt_inst +- +-import warnings +-warnings.filterwarnings(action='ignore', category=FutureWarning) +-import apt +-from aptsources.distro import get_distro +-from aptsources.sourceslist import SourcesList +-from sets import Set +-from os.path import join,exists +-from urlparse import urlparse +-from apt.debfile import DebPackage +-from os import system +- +-class Package(apt.Package): +- def __str__(self): +- return "Package %s, version %s"%(self.name,self._version) +- +- def _cmp_deps(self,deps, version): +- for (v,c) in deps: +- if not apt_pkg.CheckDep(version,c,v): +- return False +- return True +- +- def __init__(self, backend, pkg, data="",version=[]): +- apt.package.Package.__init__(self, pkg._cache, pkg._depcache, +- pkg._records, pkg._list, pkg._pcache, +- pkg._pkg) +- self._version = version +- self._data = data +- self._backend = backend +- wanted_ver = None +- if self.installedVersion!=None and self._cmp_deps(version,self.installedVersion): +- wanted_ver = self.installedVersion +- elif self.installedVersion == None and version == []: +- #self.markInstall(False,False) +- wanted_ver = self.candidateVersion +- +- for ver in pkg._pkg.VersionList: +- #print "vers",dir(ver),version,ver +- #print data +- if (wanted_ver == None or wanted_ver == ver.VerStr) and self._cmp_deps(version,ver.VerStr): +- f, index = ver.FileList.pop(0) +- if self._data == "": +- if f.Origin=="" and f.Archive=="now": +- self._data = "local_install" +- elif f.Origin!="" or f.Archive!="": +- self._data = "%s/%s"%(f.Origin.replace("/","_"),f.Archive.replace("/","_")) +- else: +- self._data = "%s/unknown"%f.Site +- self._version = ver.VerStr +- break +- else: +- print "wanted",wanted_ver +- for ver in pkg._pkg.VersionList: +- print "vers",version,ver.VerStr +- backend.error(ERROR_PACKAGE_NOT_FOUND, "Can't find version %s for %s"%(version,self.name)) +- +- def setVersion(self,version,compare="="): +- if version!=None and (self.installedVersion == None or not apt_pkg.CheckDep(version,compare,self.installedVersion)): +- self.markInstall(False,False) +- if self.candidateVersion != version: +- if self._data == "": +- for ver in pkg._pkg.VersionList: +- f, index = ver.FileList.pop(0) +- self._data = "%s/%s"%(f.Origin,f.Archive) +- if ver.VerStr == version: +- break +- +- # FIXME: this is a nasty hack, assuming that the best way to resolve +- # deps for non-default repos is by switching the default release. +- # We really need a better resolver (but that's hard) +- assert self._data!="" +- origin = self._data[self._data.find("/")+1:] +- print "origin",origin +- name = self.name +- apt_pkg.Config.Set("APT::Default-Release",origin) +- if not self._backend._caches.has_key(origin): +- self._backend._caches[origin] = apt.Cache(PackageKitProgress(self)) +- print "new cache for %s"%origin +- self.__setParent(self._backend._caches[origin][name]) +- self.markInstall(False,False) +- if not apt_pkg.CheckDep(self.candidateVersion,compare,version): +- self._backend.error(ERROR_PACKAGE_NOT_FOUND, +- "Unable to locate package version %s (only got %s) for %s"%(version,self.candidateVersion,name)) +- return +- self.markKeep() +- +- @property +- def group(self): +- section = self.section.split('/')[-1].lower() +- #if section in (): +- # return GROUP_ACCESSIBILITY +- if section in ('utils',): +- return "accessories" +- #if section in (): +- # return GROUP_EDUCATION +- if section in ('games',): +- return "games" +- if section in ('graphics',): +- return "graphics" +- if section in ('net', 'news', 'web', 'comm'): +- return "internet" +- if section in ('editors', 'tex'): +- return "office" +- if section in ('misc',): +- return "other" +- if section in ('devel', 'libdevel', 'interpreters', 'perl', 'python'): +- return "programming" +- if section in ('sound',): +- return "multimedia" +- if section in ('base', 'admin'): +- return "system" +- return "unknown" +- +- @property +- def isInstalled(self): +- return super(self.__class__,self).isInstalled and self.installedVersion == self._version +- +- @property +- def isDevelopment(self): +- name = self.name.lower() +- section = self.section.split('/')[-1].lower() +- return name.endswith('-dev') or name.endswith('-dbg') or \ +- section in ('devel', 'libdevel') +- +- @property +- def isGui(self): +- section = self.section.split('/')[-1].lower() +- return section in ('x11', 'gnome', 'kde') +- +- _HYPHEN_PATTERN = re.compile(r'(\s|_)+') +- +- def matchName(self, name): +- needle = name.strip().lower() +- haystack = self.name.lower() +- needle = Package._HYPHEN_PATTERN.sub('-', needle) +- haystack = Package._HYPHEN_PATTERN.sub('-', haystack) +- if haystack.find(needle) >= 0: +- return True +- return False +- +- def matchDetails(self, details): +- if self.matchName(details): +- return True +- needle = details.strip().lower() +- haystack = self.description.lower() +- if haystack.find(needle) >= 0: +- return True +- return False +- +- def matchGroup(self, name): +- needle = name.strip().lower() +- haystack = self.group +- if haystack.startswith(needle): +- return True +- return False +- +-class PackageKitProgress(apt.progress.OpProgress, apt.progress.FetchProgress): +- def __init__(self, backend): +- self._backend = backend +- apt.progress.OpProgress.__init__(self) +- apt.progress.FetchProgress.__init__(self) +- +- # OpProgress callbacks +- def update(self, percent): +- pass +- +- def done(self): +- pass +- +- # FetchProgress callbacks +- def pulse(self): +- apt.progress.FetchProgress.pulse(self) +- self._backend.percentage(self.percent) +- return True +- +- def stop(self): +- self._backend.percentage(100) +- +- def mediaChange(self, medium, drive): +- # This probably should not be an error, but a Message. +- self._backend.error(ERROR_UNKNOWN, +- "Medium change needed") +- +-class PackageKitAptBackend(PackageKitBaseBackend): +- def __init__(self, args): +- PackageKitBaseBackend.__init__(self, args) +- self.status(STATUS_SETUP) +- self._caches = {} +- self._apt_cache = apt.Cache(PackageKitProgress(self)) +- default = apt_pkg.Config.Find("APT::Default-Release") +- if default=="": +- d = get_distro() +- if d.id == "Debian": +- default = "stable" +- elif d.id == "Ubuntu": +- default = "main" +- else: +- raise Exception,d.id +- +- self._caches[default] = self._apt_cache +- +- +- def search_name(self, filters, key): +- ''' +- Implement the {backend}-search-name functionality +- ''' +- self.status(STATUS_INFO) +- self.allow_cancel(True) +- for package in self._do_search(filters, +- lambda pkg: pkg.matchName(key)): +- self._emit_package(package) +- +- def search_details(self, filters, key): +- ''' +- Implement the {backend}-search-details functionality +- ''' +- self.status(STATUS_INFO) +- self.allow_cancel(True) +- for package in self._do_search(filters, +- lambda pkg: pkg.matchDetails(key)): +- self._emit_package(package) +- +- def search_group(self, filters, key): +- ''' +- Implement the {backend}-search-group functionality +- ''' +- self.status(STATUS_INFO) +- self.allow_cancel(True) +- for package in self._do_search(filters, +- lambda pkg: pkg.matchGroup(key)): +- self._emit_package(package) +- +- def search_file(self, filters, key): +- ''' +- Implement the {backend}-search-file functionality +- ''' +- self.allow_cancel(True) +- self.percentage(None) +- +- self.error(ERROR_NOT_SUPPORTED, +- "This function is not implemented in this backend") +- +- def refresh_cache(self): +- ''' +- Implement the {backend}-refresh_cache functionality +- ''' +- self.status(STATUS_REFRESH_CACHE) +- try: +- res = self._apt_cache.update(PackageKitProgress(self)) +- except Exception, error_message: +- self.error(ERROR_UNKNOWN, +- "Failed to fetch the following items:\n%s" % error_message) +- return res +- +- def get_details(self, package): +- ''' +- Implement the {backend}-get-details functionality +- ''' +- self.status(STATUS_INFO) +- name, version, arch, data = self.get_package_from_id(package) +- pkg = Package(self, self._apt_cache[name]) +- description = re.sub('\s+', ' ', pkg.description).strip() +- self.description(package, 'unknown', pkg.group, description, +- pkg.architecture, pkg.packageSize) +- +- def resolve(self, name): +- ''' +- Implement the {backend}-resolve functionality +- ''' +- self.status(STATUS_INFO) +- try: +- pkg = Package(self,self._apt_cache[name]) +- self._emit_package(pkg) +- except KeyError: +- self.error(ERROR_PACKAGE_NOT_FOUND,"Can't find a package called '%s'"%name) +- +- def _do_deps(self,inp,deps,recursive): +- inp.markInstall() +- newkeys = [] +- for x in inp.candidateDependencies: +- n = x.or_dependencies[0].name +- if not deps.has_key(n): +- deps[n] = [] +- newkeys.append(n) +- deps[n].append((x.or_dependencies[0].version,x.or_dependencies[0].relation)) +- if recursive: +- for n in newkeys: +- try: +- deps = self._do_deps(Package(self,self._apt_cache[n],version=deps[n]),deps,recursive) +- except KeyError: # FIXME: we're assuming this is a virtual package, which we can't cope with yet +- del deps[n] +- continue +- return deps +- +- def get_depends(self,filters,package, recursive): +- ''' +- Implement the {backend}-get-depends functionality +- ''' +- self.allow_cancel(True) +- self.status(STATUS_INFO) +- recursive = (recursive == "True") +- name, version, arch, data = self.get_package_from_id(package) +- pkg = Package(self,self._apt_cache[name],version=[(version,"=")],data=data) +- pkg.setVersion(version) +- deps = self._do_deps(pkg, {}, recursive) +- for n in deps.keys(): +- self._emit_package(Package(self,self._apt_cache[n],version=deps[n])) +- +- def _do_reqs(self,inp,pkgs,recursive): +- extra = [] +- fails = [] +- for r in inp._pkg.RevDependsList: +- ch = apt_pkg.CheckDep(inp._version,r.CompType,r.TargetVer) +- v = (r.ParentPkg.Name,r.ParentVer.VerStr) +- if not ch or v in fails: +- #print "skip",r.TargetVer,r.CompType,r.ParentPkg.Name,r.ParentVer.VerStr +- fails.append(v) +- continue +- p = Package(self,self._apt_cache[r.ParentPkg.Name],r.ParentVer.VerStr) +- if v not in pkgs: +- extra.append(p) +- #print "new pkg",p +- self._emit_package(p) +- pkgs.add(v) +- if recursive: +- for e in extra: +- pkgs = self._do_reqs(p, pkgs,recursive) +- return pkgs +- +- def get_requires(self,package,recursive): +- ''' +- Implement the {backend}-get-requires functionality +- ''' +- self.allow_cancel(True) +- self.status(STATUS_INFO) +- recursive = (recursive == "True") +- name, version, arch, data = self.get_package_from_id(package) +- pkg = Package(self,self._apt_cache[name], version=[(version,"=")], data=data) +- +- pkgs = Set() +- self._do_reqs(pkg,pkgs, recursive) +- +- def _build_repo_list(self): +- repo = {} +- +- sources = SourcesList() +- repo["__sources"] = sources +- +- root = apt_pkg.Config.FindDir("Dir::State::Lists") +- #print root +- for entry in sources: +- if entry.type!="": +- url = entry.uri +- #if entry.template!=None: +- url +="/dists/" +- url += entry.dist +- url = url.replace("//dists","/dists") +- #print url +- path = join(root,"%s_Release"%(apt_pkg.URItoFileName(url))) +- if not exists(path): +- #print path +- name = "%s/unknown"%urlparse(entry.uri)[1] +- else: +- lines = file(path).readlines() +- origin = "" +- suite = "" +- for l in lines: +- if l.find("Origin: ")==0: +- origin = l.split(" ",1)[1].strip() +- elif l.find("Suite: ")==0: +- suite = l.split(" ",1)[1].strip() +- assert origin!="" and suite!="" +- name = "%s/%s"%(origin,suite) +- if entry.type == "deb-src": +- name += "-src" +- +- repo[name] = {"entry":entry} +- return repo +- +- def get_repo_list(self, filters): +- ''' +- Implement the {backend}-get-repo-list functionality +- ''' +- self.allow_interrupt(True) +- self.status(STATUS_INFO) +- repo = self._build_repo_list() +- for e in repo.keys(): +- if e == "__sources": +- continue +- self.repo_detail(repo[e]["entry"].line.strip(),e,not repo[e]["entry"].disabled) +- +- def repo_enable(self, repoid, enable): +- ''' +- Implement the {backend}-repo-enable functionality +- ''' +- enable = (enable == "True") +- repo = self._build_repo_list() +- if not repo.has_key(repoid): +- self.error(ERROR_REPO_NOT_FOUND,"Couldn't find repo '%s'"%repoid) +- return +- r = repo[repoid] +- if not r["entry"].disabled == enable: # already there +- return +- r["entry"].set_enabled(enable) +- try: +- repo["__sources"].save() +- except IOError,e: +- self.error(ERROR_UNKNOWN, "Problem while trying to save repo settings to %s: %s"%(e.filename,e.strerror)) +- +- def get_updates(self, filter): +- self._apt_cache.upgrade(False) +- for pkg in self._apt_cache.getChanges(): +- self._emit_package(Package(self, pkg)) +- +- def get_update_detail(self, package): +- self.allow_cancel(True) +- self.percentage(None) +- self.status(STATUS_INFO) +- name, version, arch, data = self.get_package_from_id(package) +- update = "" +- obsolete = "" +- cve_url = "" +- bz_url = "" +- vendor_url = "" +- reboot = "none" +- desc = self._apt_cache[name].description +- self.update_detail(package,update,obsolete,vendor_url,bz_url,cve_url,reboot,desc) +- +- +- def install_files (self, inst_files): +- ''' +- Implement the {backend}-install_files functionality +- Install the package containing the inst_file file +- ''' +- if not exists(inst_file): +- self.error(ERROR_PACKAGE_NOT_FOUND,"Can't find %s"%inst_file) +- return +- deb = DebPackage(inst_file) +- deps = {} +- for k in ["Depends","Recommends"]: +- if not deb._sections.has_key(k): +- continue +- for items in apt_pkg.ParseDepends(deb[k]): +- assert len(items) == 1,"Can't handle or deps properly yet" +- (pkg,ver,comp) = items[0] +- if not deps.has_key(pkg): +- deps[pkg] = [] +- deps[pkg].append((ver,comp)) +- for n in deps.keys(): +- p = Package(self,self._apt_cache[n],version=deps[n]) +- if not p.isInstalled: +- p.markInstall() +- assert self._apt_cache.getChanges()==[],"Don't handle install changes yet" +- # FIXME: nasty hack. Need a better way in +- ret = system("dpkg -i %s"%inst_file) +- if ret!=0: +- self.error(ERROR_UNKNOWN,"Can't install package") +- +- ### Helpers ### +- def _emit_package(self, package): +- id = self.get_package_id(package.name, +- package._version, +- package.architecture, +- package._data) +- if package.isInstalled: +- status = INFO_INSTALLED +- else: +- status = INFO_AVAILABLE +- summary = package.summary +- self.package(id, status, summary) +- +- def _do_search(self, filters, condition): +- filters = filters.split(';') +- size = len(self._apt_cache) +- percentage = 0 +- for i, pkg in enumerate(self._apt_cache): +- new_percentage = i / float(size) * 100 +- if new_percentage - percentage >= 5: +- percentage = new_percentage +- self.percentage(percentage) +- package = Package(self, pkg) +- if package.installedVersion is None and \ +- package.candidateVersion is None: +- continue +- if not condition(package): +- continue +- continue +- vers = [x.VerStr for x in package._pkg.VersionList] +- if package.installedVersion!=None: +- i = package.installedVersion +- if i in vers and vers[0]!=i: +- del vers[vers.index(i)] +- vers.insert(0,i) +- +- for ver in vers: +- p = Package(self, package, version=[[ver,"="]]) +- if self._do_filtering(p, filters): +- yield p +- self.percentage(100) +- +- def _do_filtering(self, package, filters): +- if len(filters) == 0 or filters == ['none']: +- return True +- if (FILTER_INSTALLED in filters) and (not package.isInstalled): +- return False +- if (FILTER_NOT_INSTALLED in filters) and package.isInstalled: +- return False +- if (FILTER_GUI in filters) and (not package.isGui): +- return False +- if (FILTER_NOT_GUI in filters) and package.isGui: +- return False +- if (FILTER_DEVELOPMENT in filters) and (not package.isDevelopment): +- return False +- if (FILTER_NOT_DEVELOPMENT in filters) and package.isDevelopment: +- return False +- return True +- +diff --git a/backends/apt/helpers/get-depends.py b/backends/apt/helpers/get-depends.py +deleted file mode 100755 +index 94dca4a..0000000 +--- a/backends/apt/helpers/get-depends.py ++++ /dev/null +@@ -1,20 +0,0 @@ +-#!/usr/bin/python +-# +-# Copyright (C) 2007 Richard Hughes +-# +-# 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. +- +-import sys +- +-from aptBackend import PackageKitAptBackend +-filters=sys.argv[1] +-package=sys.argv[2] +-recursive = sys.argv[3] +-backend = PackageKitAptBackend(sys.argv[1:]) +-backend.get_depends(filters, package, recursive) +-sys.exit(0) +diff --git a/backends/apt/helpers/get-details.py b/backends/apt/helpers/get-details.py +deleted file mode 100755 +index a813640..0000000 +--- a/backends/apt/helpers/get-details.py ++++ /dev/null +@@ -1,18 +0,0 @@ +-#!/usr/bin/python +-# +-# Copyright (C) 2007 Ali Sabil +-# +-# 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. +- +-import sys +-from aptBackend import PackageKitAptBackend +- +-package = sys.argv[1] +-backend = PackageKitAptBackend(sys.argv[1:]) +-backend.get_details(package) +-sys.exit(0) +diff --git a/backends/apt/helpers/get-repo-list.py b/backends/apt/helpers/get-repo-list.py +deleted file mode 100755 +index 5529f72..0000000 +--- a/backends/apt/helpers/get-repo-list.py ++++ /dev/null +@@ -1,20 +0,0 @@ +-#!/usr/bin/python +-# +-# Copyright (C) 2007 Richard Hughes +-# +-# 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. +- +-import sys +- +-from aptBackend import PackageKitAptBackend +-filters = sys.argv[1] +- +-backend = PackageKitAptBackend(sys.argv[2:]) +-backend.get_repo_list(filters) +-backend.unLock() +-sys.exit(0) +diff --git a/backends/apt/helpers/get-requires.py b/backends/apt/helpers/get-requires.py +deleted file mode 100755 +index e581010..0000000 +--- a/backends/apt/helpers/get-requires.py ++++ /dev/null +@@ -1,20 +0,0 @@ +-#!/usr/bin/python +-# +-# Copyright (C) 2007 Richard Hughes +-# +-# 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. +- +-import sys +- +-from aptBackend import PackageKitAptBackend +-package = sys.argv[1] +-recursive = sys.argv[2] +- +-backend = PackageKitAptBackend(sys.argv[1:]) +-backend.get_requires(package, recursive) +-sys.exit(0) +diff --git a/backends/apt/helpers/get-update-detail.py b/backends/apt/helpers/get-update-detail.py +deleted file mode 100755 +index 5524d9a..0000000 +--- a/backends/apt/helpers/get-update-detail.py ++++ /dev/null +@@ -1,18 +0,0 @@ +-#!/usr/bin/python +-# +-# Copyright (C) 2008 Michael Vogt +-# +-# 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. +- +-import sys +- +-from aptBackend import PackageKitAptBackend +-package=sys.argv[1] +-backend = PackageKitAptBackend(sys.argv[2:]) +-backend.get_update_detail(package) +-sys.exit(0) +diff --git a/backends/apt/helpers/get-updates.py b/backends/apt/helpers/get-updates.py +deleted file mode 100755 +index 4f45fbf..0000000 +--- a/backends/apt/helpers/get-updates.py ++++ /dev/null +@@ -1,19 +0,0 @@ +-#!/usr/bin/python +-# +-# Copyright (C) 2008 Michael Vogt +-# +-# 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. +- +-import sys +-from aptBackend import PackageKitAptBackend +- +-filter = sys.argv[1] +- +-backend = PackageKitAptBackend(sys.argv[1:]) +-backend.get_updates(filter) +-sys.exit(0) +diff --git a/backends/apt/helpers/install-files.py b/backends/apt/helpers/install-files.py +deleted file mode 100755 +index dfa024c..0000000 +--- a/backends/apt/helpers/install-files.py ++++ /dev/null +@@ -1,21 +0,0 @@ +-#!/usr/bin/python +-# +-# Copyright (C) 2007 Richard Hughes +-# Copyright (C) 2007 Red Hat Inc, Seth Vidal +-# +-# 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. +- +-import sys +- +-from aptBackend import PackageKitAptBackend +- +-trusted = sys.argv[1] +-files_to_inst = sys.argv[2:] +-backend = PackageKitAptBackend(sys.argv[1:]) +-backend.install_files(trusted, files_to_inst) +-sys.exit(0) +diff --git a/backends/apt/helpers/refresh-cache.py b/backends/apt/helpers/refresh-cache.py +deleted file mode 100755 +index 881479d..0000000 +--- a/backends/apt/helpers/refresh-cache.py ++++ /dev/null +@@ -1,17 +0,0 @@ +-#!/usr/bin/python +-# +-# Copyright (C) 2007 Ali Sabil +-# +-# 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. +- +-import sys +-from aptBackend import PackageKitAptBackend +- +-backend = PackageKitAptBackend(sys.argv[1:]) +-backend.refresh_cache() +-sys.exit(0) +diff --git a/backends/apt/helpers/repo-enable.py b/backends/apt/helpers/repo-enable.py +deleted file mode 100755 +index 3cc36ae..0000000 +--- a/backends/apt/helpers/repo-enable.py ++++ /dev/null +@@ -1,20 +0,0 @@ +-#!/usr/bin/python +-# +-# Copyright (C) 2007 Richard Hughes +-# +-# 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. +- +-import sys +- +-from aptBackend import PackageKitAptBackend +-repoid = sys.argv[1] +-state=sys.argv[2] +-backend = PackageKitAptBackend(sys.argv[2:]) +-backend.repo_enable(repoid,state) +-backend.unLock() +-sys.exit(0) +diff --git a/backends/apt/helpers/resolve.py b/backends/apt/helpers/resolve.py +deleted file mode 100755 +index aac34df..0000000 +--- a/backends/apt/helpers/resolve.py ++++ /dev/null +@@ -1,20 +0,0 @@ +-#!/usr/bin/python +-# +-# Copyright (C) 2007 Richard Hughes +-# +-# 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. +- +-import sys +- +-from aptBackend import PackageKitAptBackend +-filters = sys.argv[1] +-name=sys.argv[2] +-backend = PackageKitAptBackend(sys.argv[2:]) +-backend.resolve(name) +-backend.unLock() +-sys.exit(0) +diff --git a/backends/apt/helpers/search-details.py b/backends/apt/helpers/search-details.py +deleted file mode 100755 +index d02f1b0..0000000 +--- a/backends/apt/helpers/search-details.py ++++ /dev/null +@@ -1,21 +0,0 @@ +-#!/usr/bin/python +-# +-# Copyright (C) 2007 Ali Sabil +-# +-# 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. +- +-import sys +- +-options = sys.argv[1] +-searchlist = sys.argv[2] +- +-from aptBackend import PackageKitAptBackend +- +-backend = PackageKitAptBackend(sys.argv[1:]) +-backend.search_details(options,searchlist) +-sys.exit(0) +diff --git a/backends/apt/helpers/search-file.py b/backends/apt/helpers/search-file.py +deleted file mode 100755 +index ec60319..0000000 +--- a/backends/apt/helpers/search-file.py ++++ /dev/null +@@ -1,21 +0,0 @@ +-#!/usr/bin/python +-# +-# Copyright (C) 2007 Ali Sabil +-# +-# 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. +- +-import sys +- +-options = sys.argv[1] +-searchlist = sys.argv[2] +- +-from aptBackend import PackageKitAptBackend +- +-backend = PackageKitAptBackend(sys.argv[1:]) +-backend.search_file(options,searchlist) +-sys.exit(0) +diff --git a/backends/apt/helpers/search-group.py b/backends/apt/helpers/search-group.py +deleted file mode 100755 +index f63ee80..0000000 +--- a/backends/apt/helpers/search-group.py ++++ /dev/null +@@ -1,21 +0,0 @@ +-#!/usr/bin/python +-# +-# Copyright (C) 2007 Ali Sabil +-# +-# 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. +- +-import sys +- +-options = sys.argv[1] +-searchlist = sys.argv[2] +- +-from aptBackend import PackageKitAptBackend +- +-backend = PackageKitAptBackend(sys.argv[1:]) +-backend.search_group(options,searchlist) +-sys.exit(0) +diff --git a/backends/apt/helpers/search-name.py b/backends/apt/helpers/search-name.py +deleted file mode 100755 +index 9f73c89..0000000 +--- a/backends/apt/helpers/search-name.py ++++ /dev/null +@@ -1,21 +0,0 @@ +-#!/usr/bin/python +-# +-# Copyright (C) 2007 Ali Sabil +-# +-# 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. +- +-import sys +- +-options = sys.argv[1] +-searchlist = sys.argv[2] +- +-from aptBackend import PackageKitAptBackend +- +-backend = PackageKitAptBackend(sys.argv[1:]) +-backend.search_name(options,searchlist) +-sys.exit(0) +diff --git a/backends/apt/packagekit b/backends/apt/packagekit +new file mode 120000 +index 0000000..0b64032 +--- /dev/null ++++ b/backends/apt/packagekit +@@ -0,0 +1 @@ ++../../python/packagekit/ +\ No newline at end of file +diff --git a/backends/apt/pk-apt-build-db.cpp b/backends/apt/pk-apt-build-db.cpp +deleted file mode 100644 +index 885275d..0000000 +--- a/backends/apt/pk-apt-build-db.cpp ++++ /dev/null +@@ -1,284 +0,0 @@ +-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- +- * +- * Copyright (C) 2007 Tom Parker +- * +- * Licensed under the GNU General Public License Version 2 +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +- */ +- +-//#include "pk-backend-apt.h" +-#include +-#include +-#include +- +-typedef enum {FIELD_PKG=1,FIELD_VER,FIELD_DEPS,FIELD_ARCH,FIELD_SHORT,FIELD_LONG,FIELD_REPO} Fields; +- +-void apt_build_db(PkBackend * backend, sqlite3 *db) +-{ +- GMatchInfo *match_info; +- GError *error = NULL; +- gchar *contents = NULL; +- gchar *sdir; +- const gchar *fname; +- GRegex *origin, *suite; +- GDir *dir; +- GHashTable *releases; +- int res; +- sqlite3_stmt *package = NULL; +- +- pk_backend_set_status(backend, PK_STATUS_ENUM_QUERY); +- pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); +- +- sdir = g_build_filename(_config->Find("Dir").c_str(),_config->Find("Dir::State").c_str(),_config->Find("Dir::State::lists").c_str(), NULL); +- dir = g_dir_open(sdir,0,&error); +- if (error!=NULL) +- { +- pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "can't open %s",dir); +- g_error_free(error); +- goto search_task_cleanup; +- } +- +- origin = g_regex_new("^Origin: (\\S+)",(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE|G_REGEX_MULTILINE),(GRegexMatchFlags)0,NULL); +- suite = g_regex_new("^Suite: (\\S+)",(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE|G_REGEX_MULTILINE),(GRegexMatchFlags)0,NULL); +- +- releases = g_hash_table_new_full(g_str_hash,g_str_equal,g_free,g_free); +- while ((fname = g_dir_read_name(dir))!=NULL) +- { +- gchar *temp, *parsed_name; +- gchar** items = g_strsplit(fname,"_",-1); +- guint len = g_strv_length(items); +- if(len<=3) // minimum is __ +- { +- g_strfreev(items); +- continue; +- } +- +- /* warning: nasty hack with g_strjoinv */ +- temp = items[len-2]; +- items[len-2] = NULL; +- parsed_name = g_strjoinv("_",items); +- items[len-2] = temp; +- +- if (g_ascii_strcasecmp(items[len-1],"Release")==0 && g_ascii_strcasecmp(items[len-2],"source")!=0) +- { +- gchar * repo = NULL, *fullname; +- fullname = g_build_filename(sdir,fname,NULL); +- if (g_file_get_contents(fullname,&contents,NULL,NULL) == FALSE) +- { +- pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "error loading %s",fullname); +- goto search_task_cleanup; +- } +- g_free(fullname); +- +- g_regex_match (origin, contents, (GRegexMatchFlags)0, &match_info); +- if (!g_match_info_matches(match_info)) +- { +- pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "origin regex failure in %s",fname); +- goto search_task_cleanup; +- } +- repo = g_match_info_fetch (match_info, 1); +- +- g_regex_match (suite, contents, (GRegexMatchFlags)0, &match_info); +- if (g_match_info_matches(match_info)) +- { +- temp = g_strconcat(repo,"/",g_match_info_fetch (match_info, 1),NULL); +- g_free(repo); +- repo = temp; +- } +- +- temp = parsed_name; +- parsed_name = g_strconcat(temp,"_",items[len-2],NULL); +- g_free(temp); +- +- pk_debug("type is %s, group is %s, parsed_name is %s",items[len-2],items[len-1],parsed_name); +- +- g_hash_table_insert(releases, parsed_name, repo); +- g_free(contents); +- contents = NULL; +- } +- else +- g_free(parsed_name); +- g_strfreev(items); +- } +- g_dir_close(dir); +- +- /* and then we need to do this again, but this time we're looking for the packages */ +- dir = g_dir_open(sdir,0,&error); +- res = sqlite3_prepare_v2(db, "insert or replace into packages values (?,?,?,?,?,?,?)", -1, &package, NULL); +- if (res!=SQLITE_OK) +- pk_error("sqlite error during insert prepare: %s", sqlite3_errmsg(db)); +- else +- pk_debug("insert prepare ok for %p",package); +- while ((fname = g_dir_read_name(dir))!=NULL) +- { +- gchar** items = g_strsplit(fname,"_",-1); +- guint len = g_strv_length(items); +- if(len<=3) // minimum is __ +- { +- g_strfreev(items); +- continue; +- } +- +- if (g_ascii_strcasecmp(items[len-1],"Packages")==0) +- { +- const gchar *repo; +- gchar *temp=NULL, *parsed_name=NULL; +- gchar *fullname= NULL; +- gchar *begin=NULL, *next=NULL, *description = NULL; +- glong count = 0; +- gboolean haspk = FALSE; +- +- /* warning: nasty hack with g_strjoinv */ +- if (g_str_has_prefix(items[len-2],"binary-")) +- { +- temp = items[len-3]; +- items[len-3] = NULL; +- parsed_name = g_strjoinv("_",items); +- items[len-3] = temp; +- } +- else +- { +- temp = items[len-1]; +- items[len-1] = NULL; +- parsed_name = g_strjoinv("_",items); +- items[len-1] = temp; +- } +- +- pk_debug("type is %s, group is %s, parsed_name is %s",items[len-2],items[len-1],parsed_name); +- +- repo = (const gchar *)g_hash_table_lookup(releases,parsed_name); +- if (repo == NULL) +- { +- pk_debug("Can't find repo for %s, marking as \"unknown\"",parsed_name); +- repo = g_strdup("unknown"); +- //g_assert(0); +- } +- else +- pk_debug("repo for %s is %s",parsed_name,repo); +- g_free(parsed_name); +- +- fullname = g_build_filename(sdir,fname,NULL); +- pk_debug("loading %s",fullname); +- if (g_file_get_contents(fullname,&contents,NULL,NULL) == FALSE) +- { +- pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "error loading %s",fullname); +- goto search_task_cleanup; +- } +- /*else +- pk_debug("loaded");*/ +- +- res = sqlite3_bind_text(package,FIELD_REPO,repo,-1,SQLITE_TRANSIENT); +- if (res!=SQLITE_OK) +- pk_error("sqlite error during repo bind: %s", sqlite3_errmsg(db)); +- /*else +- pk_debug("repo bind ok");*/ +- +- res = sqlite3_exec(db,"begin",NULL,NULL,NULL); +- g_assert(res == SQLITE_OK); +- +- begin = contents; +- +- while (true) +- { +- next = strstr(begin,"\n"); +- if (next!=NULL) +- { +- next[0] = '\0'; +- next++; +- } +- +- if (begin[0]=='\0') +- { +- if (haspk) +- { +- if (description!=NULL) +- { +- res=sqlite3_bind_text(package,FIELD_LONG,description,-1,SQLITE_TRANSIENT); +- if (res!=SQLITE_OK) +- pk_error("sqlite error during description bind: %s", sqlite3_errmsg(db)); +- g_free(description); +- description = NULL; +- } +- res = sqlite3_step(package); +- if (res!=SQLITE_DONE) +- pk_error("sqlite error during step: %s", sqlite3_errmsg(db)); +- sqlite3_reset(package); +- //pk_debug("added package"); +- haspk = FALSE; +- } +- //g_assert(0); +- } +- else if (begin[0]==' ') +- { +- if (description == NULL) +- description = g_strdup(&begin[1]); +- else +- { +- gchar *oldval = description; +- description = g_strconcat(oldval, "\n",&begin[1],NULL); +- g_free(oldval); +- } +- } +- else +- { +- gchar *colon = strchr(begin,':'); +- g_assert(colon!=NULL); +- colon[0] = '\0'; +- colon+=2; +- /*if (strlen(colon)>3000) +- pk_error("strlen(colon) = %d\ncolon = %s",strlen(colon),colon);*/ +- //pk_debug("entry = '%s','%s'",begin,colon); +- if (begin[0] == 'P' && g_strcasecmp("Package",begin)==0) +- { +- res=sqlite3_bind_text(package,FIELD_PKG,colon,-1,SQLITE_STATIC); +- haspk = TRUE; +- count++; +- if (count%1000==0) +- pk_debug("Package %ld (%s)",count,colon); +- } +- else if (begin[0] == 'V' && g_strcasecmp("Version",begin)==0) +- res=sqlite3_bind_text(package,FIELD_VER,colon,-1,SQLITE_STATIC); +- else if (begin[0] == 'D' && g_strcasecmp("Depends",begin)==0) +- res=sqlite3_bind_text(package,FIELD_DEPS,colon,-1,SQLITE_STATIC); +- else if (begin[0] == 'A' && g_strcasecmp("Architecture",begin)==0) +- res=sqlite3_bind_text(package,FIELD_ARCH,colon,-1,SQLITE_STATIC); +- else if (begin[0] == 'D' && g_strcasecmp("Description",begin)==0) +- res=sqlite3_bind_text(package,FIELD_SHORT,colon,-1,SQLITE_STATIC); +- if (res!=SQLITE_OK) +- pk_error("sqlite error during %s bind: %s", begin, sqlite3_errmsg(db)); +- } +- if (next == NULL) +- break; +- begin = next; +- } +- res = sqlite3_exec(db,"commit",NULL,NULL,NULL); +- if (res!=SQLITE_OK) +- pk_error("sqlite error during commit: %s", sqlite3_errmsg(db)); +- res = sqlite3_clear_bindings(package); +- if (res!=SQLITE_OK) +- pk_error("sqlite error during clear: %s", sqlite3_errmsg(db)); +- g_free(contents); +- contents = NULL; +- } +- } +- sqlite3_finalize(package); +- +-search_task_cleanup: +- g_dir_close(dir); +- g_free(sdir); +- g_free(contents); +-} +- +diff --git a/backends/apt/pk-apt-build-db.h b/backends/apt/pk-apt-build-db.h +deleted file mode 100644 +index bb786a9..0000000 +--- a/backends/apt/pk-apt-build-db.h ++++ /dev/null +@@ -1,30 +0,0 @@ +-#ifndef PK_APT_BUILD_DB +-#define PK_APT_BUILD_DB +- +-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- +- * +- * Copyright (C) 2007 Tom Parker +- * +- * Licensed under the GNU General Public License Version 2 +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +- */ +- +-#include +-#include +- +-void apt_build_db(PkBackend * backend, sqlite3 *db); +- +-#endif +diff --git a/backends/apt/pk-apt-search-plain.c b/backends/apt/pk-apt-search-plain.c +deleted file mode 100644 +index 5e5b4e5..0000000 +--- a/backends/apt/pk-apt-search-plain.c ++++ /dev/null +@@ -1,106 +0,0 @@ +-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- +- * +- * Copyright (C) 2007 Ali Sabil +- * +- * Licensed under the GNU General Public License Version 2 +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +- */ +- +-#include +-#include +-#include +-#include +-#include +- +-extern PkBackendSpawn *spawn; +- +-/** +- * backend_get_groups: +- */ +-static PkGroupEnum +-backend_get_groups (PkBackend *backend) +-{ +- return (PK_GROUP_ENUM_ACCESSORIES | +- PK_GROUP_ENUM_GAMES | +- PK_GROUP_ENUM_GRAPHICS | +- PK_GROUP_ENUM_INTERNET | +- PK_GROUP_ENUM_OFFICE | +- PK_GROUP_ENUM_OTHER | +- PK_GROUP_ENUM_PROGRAMMING | +- PK_GROUP_ENUM_MULTIMEDIA | +- PK_GROUP_ENUM_SYSTEM); +-} +- +-/** +- * backend_get_filters: +- */ +-static PkFilterEnum +-backend_get_filters (PkBackend *backend) +-{ +- return (PK_FILTER_ENUM_GUI | +- PK_FILTER_ENUM_INSTALLED | +- PK_FILTER_ENUM_DEVELOPMENT); +-} +- +-/** +- * backend_get_details: +- */ +- +-void +-backend_get_details (PkBackend *backend, const gchar *package_id) +-{ +- pk_backend_spawn_helper (spawn, "get-details.py", package_id, NULL); +-} +- +-/** +- * backend_search_details: +- */ +- +-void +-backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *search) +-{ +- gchar *filters_text; +- filters_text = pk_filter_enums_to_text (filters); +- pk_backend_spawn_helper (spawn, "search-details.py", filters_texts_text, search, NULL); +- g_free (filters_text); +-} +- +-/** +- * backend_search_name: +- */ +-void +-backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search) +-{ +- gchar *filters_text; +- filters_text = pk_filter_enums_to_text (filters); +- pk_backend_spawn_helper (spawn, "search-name.py", filters_text, search, NULL); +- g_free (filters_text); +-} +- +-/** +- * backend_search_group: +- */ +-void +-backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *search) +-{ +- gchar *filters_text; +- pk_backend_spawn_helper (spawn, "search-group.py", filters_text, search, NULL); +- g_free (filters_text); +-} +- +-/* don't need to do any setup/finalize in the plain search mode */ +-void backend_init_search(PkBackend *backend) {} +-void backend_finish_search(PkBackend *backend) {} +diff --git a/backends/apt/pk-apt-search-sqlite.cpp b/backends/apt/pk-apt-search-sqlite.cpp +deleted file mode 100644 +index 98bdc7f..0000000 +--- a/backends/apt/pk-apt-search-sqlite.cpp ++++ /dev/null +@@ -1,135 +0,0 @@ +-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- +- * +- * Copyright (C) 2007 Ali Sabil +- * +- * Licensed under the GNU General Public License Version 2 +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include "pk-sqlite-pkg-cache.h" +-#include +-#include +-#include "pk-apt-build-db.h" +- +-static PkBackendSpawn *spawn; +- +-/** +- * backend_get_groups: +- */ +-extern "C" PkGroupEnum +-backend_get_groups (PkBackend *backend) +-{ +- return (PK_GROUP_ENUM_ACCESSORIES | +- PK_GROUP_ENUM_GAMES | +- PK_GROUP_ENUM_GRAPHICS | +- PK_GROUP_ENUM_INTERNET | +- PK_GROUP_ENUM_OFFICE | +- PK_GROUP_ENUM_OTHER | +- PK_GROUP_ENUM_PROGRAMMING | +- PK_GROUP_ENUM_MULTIMEDIA | +- PK_GROUP_ENUM_SYSTEM); +-} +- +-/** +- * backend_get_filters: +- */ +-extern "C" PkFilterEnum +-backend_get_filters (PkBackend *backend) +-{ +- return (PK_FILTER_ENUM_GUI | +- PK_FILTER_ENUM_INSTALLED | +- PK_FILTER_ENUM_DEVELOPMENT); +-} +- +-/** +- * backend_get_details: +- */ +- +-extern "C" void +-backend_get_details (PkBackend *backend, const gchar *package_id) +-{ +- sqlite_get_details(backend,package_id); +-} +- +-/** +- * backend_search_details: +- */ +- +-extern "C" void +-backend_search_details (PkBackend *backend, const gchar *filter, const gchar *search) +-{ +- sqlite_search_details(backend,filter,search); +-} +- +-/** +- * backend_search_name: +- */ +-extern "C" void +-backend_search_name (PkBackend *backend, const gchar *filter, const gchar *search) +-{ +- sqlite_search_name(backend,filter,search); +-} +- +-/** +- * backend_search_group: +- */ +-extern "C" void +-backend_search_group (PkBackend *backend, const gchar *filter, const gchar *search) +-{ +- pk_backend_set_allow_cancel (backend, TRUE); +- pk_backend_spawn_helper (spawn, "search-group.py", filter, search, NULL); +-} +- +-static gboolean inited = FALSE; +- +-#define APT_DB PK_DB_DIR "/apt.db" +- +-extern "C" void backend_init_search(PkBackend *backend) +-{ +- if (!inited) +- { +- gchar *apt_fname = NULL; +- if (pkgInitConfig(*_config) == false) +- pk_debug("pkginitconfig was false"); +- if (pkgInitSystem(*_config, _system) == false) +- pk_debug("pkginitsystem was false"); +- +- apt_fname = g_strconcat( +- _config->Find("Dir").c_str(), +- _config->Find("Dir::Cache").c_str(), +- _config->Find("Dir::Cache::pkgcache").c_str(), +- NULL); +- +- //sqlite_set_installed_check(is_installed); +- sqlite_init_cache(backend, APT_DB, apt_fname, apt_build_db); +- g_free(apt_fname); +- +- spawn = pk_backend_spawn_new (); +- pk_backend_spawn_set_name (spawn, "apt-sqlite"); +- +- inited = TRUE; +- } +-} +- +-extern "C" void backend_finish_search(PkBackend *backend) +-{ +- sqlite_finish_cache(backend); +-} +diff --git a/backends/apt/pk-apt-search.h b/backends/apt/pk-apt-search.h +deleted file mode 100644 +index e36e89f..0000000 +--- a/backends/apt/pk-apt-search.h ++++ /dev/null +@@ -1,36 +0,0 @@ +-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- +- * +- * Copyright (C) 2007 Tom Parker +- * +- * Licensed under the GNU General Public License Version 2 +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +- */ +- +-#ifndef __PK_APT_SEARCH_H +-#define __PK_APT_SEARCH_H +- +-#include +-#include +- +-void backend_init_search(PkBackend *backend); +-void backend_finish_search(PkBackend *backend); +- +-void backend_get_details (PkBackend *backend, const gchar *package_id); +-void backend_search_details (PkBackend *backend, const gchar *filter, const gchar *search); +-void backend_search_name (PkBackend *backend, const gchar *filter, const gchar *search); +-void backend_search_group (PkBackend *backend, const gchar *filter, const gchar *search); +- +-#endif +diff --git a/backends/apt/pk-backend-apt.c b/backends/apt/pk-backend-apt.c +index f59cd88..70836b2 100644 +--- a/backends/apt/pk-backend-apt.c ++++ b/backends/apt/pk-backend-apt.c +@@ -20,16 +20,12 @@ + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +-#include +-#include +-#include + #include +-#include +-#include +-#include "pk-apt-search.h" +-#include "config.h" ++#include + +-PkBackendSpawn *spawn; ++static PkBackendDbus *dbus; ++ ++#define PK_DBUS_BACKEND_SERVICE_APT "org.freedesktop.PackageKitAptBackend" + + /** + * backend_initialize: +@@ -39,9 +35,8 @@ static void + backend_initialize (PkBackend *backend) + { + pk_debug ("FILTER: initialize"); +- spawn = pk_backend_spawn_new (); +- pk_backend_spawn_set_name (spawn, "apt"); +- backend_init_search (backend); ++ dbus = pk_backend_dbus_new (); ++ pk_backend_dbus_set_name (dbus, PK_DBUS_BACKEND_SERVICE_APT); + } + + /** +@@ -52,8 +47,8 @@ static void + backend_destroy (PkBackend *backend) + { + pk_debug ("FILTER: destroy"); +- backend_finish_search (backend); +- g_object_unref (spawn); ++ pk_backend_dbus_kill (dbus); ++ g_object_unref (dbus); + } + + /** +@@ -85,184 +80,144 @@ backend_get_filters (PkBackend *backend) + } + + /** +- * pk_backend_bool_to_text: ++ * backend_get_updates: + */ +-static const gchar * +-pk_backend_bool_to_text (gboolean value) ++static void ++backend_get_updates (PkBackend *backend, PkFilterEnum filters) + { +- if (value == TRUE) { +- return "yes"; +- } +- return "no"; ++ pk_backend_dbus_get_updates (dbus, filters); + } + + /** +- * backend_get_depends: +- */ ++ * backend_refresh_cache: ++ * */ + static void +-backend_get_depends (PkBackend *backend, PkFilterEnum filters, const gchar *package_id, gboolean recursive) ++backend_refresh_cache (PkBackend *backend, gboolean force) + { +- gchar *filters_text; +- filters_text = pk_filter_enums_to_text (filters); +- pk_backend_spawn_helper (spawn, "get-depends.py", filters_text, package_id, pk_backend_bool_to_text (recursive), NULL); +- g_free (filters_text); ++ // check network state ++ if (!pk_backend_is_online (backend)) { ++ pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot refresh cache whilst offline"); ++ pk_backend_finished (backend); ++ return; ++ } ++ ++ pk_backend_dbus_refresh_cache(dbus, force); + } + + /** +- * backend_get_updates: +- */ ++ * pk_backend_update_system: ++ * */ + static void +-backend_get_updates (PkBackend *backend, PkFilterEnum filters) ++backend_update_system (PkBackend *backend) + { +- gchar *filters_text; +- filters_text = pk_filter_enums_to_text (filters); +- pk_backend_spawn_helper (spawn, "get-updates.py", filters_text, NULL); +- g_free (filters_text); ++ pk_backend_dbus_update_system (dbus); + } + + /** +- * backend_get_update_detail: +- */ ++ * backend_install_packages ++ * */ + static void +-backend_get_update_detail (PkBackend *backend, const gchar *package_id) ++backend_install_packages (PkBackend *backend, gchar **package_ids) + { +- pk_backend_spawn_helper (spawn, "get-update-detail.py", package_id, NULL); ++ pk_backend_dbus_install_packages (dbus, package_ids); + } + + /** +- * backend_install_packages: +- */ ++ * backend_remove_packages ++ * */ + static void +-backend_install_packages (PkBackend *backend, gchar **package_ids) ++backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow_deps, gboolean autoremove) + { +- gchar *package_ids_temp; +- +- /* check network state */ +- if (!pk_backend_is_online (backend)) { +- pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot install when offline"); +- pk_backend_finished (backend); +- return; +- } +- +- /* send the complete list as stdin */ +- package_ids_temp = pk_package_ids_to_text (package_ids, "|"); +- pk_backend_spawn_helper (spawn, "install-packages.py", package_ids_temp, NULL); +- g_free (package_ids_temp); ++ pk_backend_dbus_remove_packages (dbus, package_ids, allow_deps, autoremove); + } + + /** +- * backend_refresh_cache: +- */ ++ * backend_get_details: ++ * */ + static void +-backend_refresh_cache (PkBackend *backend, gboolean force) ++backend_get_details (PkBackend *backend, const gchar *package_id) + { +- /* check network state */ +- if (!pk_backend_is_online (backend)) { +- pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot refresh cache whilst offline"); +- pk_backend_finished (backend); +- return; +- } +- +- pk_backend_spawn_helper (spawn, "refresh-cache.py", NULL); ++ pk_backend_dbus_get_details (dbus, package_id); + } + + /** +- * pk_backend_remove_packages: +- * ++ * * pk_backend_search_details: ++ * */ + static void +-backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow_deps, gboolean autoremove) ++backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *search) + { +- gchar *package_ids_temp; +- package_ids_temp = pk_package_ids_to_text (package_ids, "|"); +- pk_backend_spawn_helper (spawn, "remove-packages.py", pk_backend_bool_to_text (allow_deps), package_ids_temp, NULL); +- g_free (package_ids_temp); +-} */ ++ pk_backend_dbus_search_details (dbus, filters, search); ++} + + /** +- * pk_backend_update_packages: +- */ ++ * * pk_backend_search_name: ++ * */ + static void +-backend_update_packages (PkBackend *backend, gchar **package_ids) ++backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search) + { +- gchar *package_ids_temp; +- +- /* check network state */ +- if (!pk_backend_is_online (backend)) { +- pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot install when offline"); +- pk_backend_finished (backend); +- return; +- } +- +- /* send the complete list as stdin */ +- package_ids_temp = pk_package_ids_to_text (package_ids, "|"); +- pk_backend_spawn_helper (spawn, "update-packages.py", package_ids_temp, NULL); +- g_free (package_ids_temp); ++ pk_backend_dbus_search_name (dbus, filters, search); + } + + /** +- * pk_backend_update_system: +- */ ++ * * pk_backend_cancel: ++ * */ + static void +-backend_update_system (PkBackend *backend) ++backend_cancel (PkBackend *backend) + { +- pk_backend_spawn_helper (spawn, "update-system.py", NULL); ++ pk_backend_dbus_cancel (dbus); + } + + /** +- * pk_backend_resolve: +- */ ++ * * pk_backend_resolve: ++ * */ + static void + backend_resolve (PkBackend *backend, PkFilterEnum filters, const gchar *package_id) + { +- gchar *filters_text; +- filters_text = pk_filter_enums_to_text (filters); +- pk_backend_spawn_helper (spawn, "resolve.py", filters_text, package_id, NULL); +- g_free (filters_text); ++ pk_backend_dbus_resolve (dbus, filters, package_id); + } + + /** +- * pk_backend_get_repo_list: +- */ ++ * * pk_backend_get_packages: ++ * */ + static void +-backend_get_repo_list (PkBackend *backend, PkFilterEnum filters) ++backend_get_packages (PkBackend *backend, PkFilterEnum filters) + { +- gchar *filters_text; +- filters_text = pk_filter_enums_to_text (filters); +- pk_backend_spawn_helper (spawn, "get-repo-list.py", filters_text, NULL); +- g_free (filters_text); ++ pk_backend_dbus_get_packages (dbus, filters); + } + ++ ++ + PK_BACKEND_OPTIONS ( +- "Apt (with " APT_SEARCH " searching)", /* description */ +- "Ali Sabil ; Tom Parker ", /* author */ ++ "Apt", /* description */ ++ "Ali Sabil ; Tom Parker ; Sebastian Heinlein ", /* author */ + backend_initialize, /* initalize */ + backend_destroy, /* destroy */ + backend_get_groups, /* get_groups */ + backend_get_filters, /* get_filters */ +- NULL, /* cancel */ +- backend_get_depends, /* get_depends */ ++ backend_cancel, /* cancel */ ++ NULL, /* get_depends */ + backend_get_details, /* get_details */ + NULL, /* get_files */ +- NULL, /* get_packages */ +- backend_get_repo_list, /* get_repo_list */ ++ backend_get_packages, /* get_packages */ ++ NULL, /* get_repo_list */ + NULL, /* get_requires */ +- backend_get_update_detail, /* get_update_detail */ ++ NULL, /* get_update_detail */ + backend_get_updates, /* get_updates */ + NULL, /* install_files */ + backend_install_packages, /* install_packages */ + NULL, /* install_signature */ + backend_refresh_cache, /* refresh_cache */ +- NULL, /* remove_packages */ ++ backend_remove_packages, /* remove_packages */ + NULL, /* repo_enable */ + NULL, /* repo_set_data */ + backend_resolve, /* resolve */ + NULL, /* rollback */ + backend_search_details, /* search_details */ + NULL, /* search_file */ +- backend_search_group, /* search_group */ ++ NULL, /* search_group */ + backend_search_name, /* search_name */ + NULL, /* service_pack */ +- backend_update_package, /* update_package */ ++ NULL, /* update_packages */ + backend_update_system, /* update_system */ + NULL /* what_provides */ + ); +diff --git a/backends/apt/pk-sqlite-pkg-cache.cpp b/backends/apt/pk-sqlite-pkg-cache.cpp +deleted file mode 100644 +index 1bf9a50..0000000 +--- a/backends/apt/pk-sqlite-pkg-cache.cpp ++++ /dev/null +@@ -1,215 +0,0 @@ +-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- +- * +- * Copyright (C) 2007 Tom Parker +- * +- * Licensed under the GNU General Public License Version 2 +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +- */ +- +-#include +-#include +-#include "pk-sqlite-pkg-cache.h" +- +-static sqlite3 *db = NULL; +-static PkBackend *backend; +-static gboolean(*is_installed) (const PkPackageId *) = NULL; +- +-void sqlite_set_installed_check(gboolean(*func) (const PkPackageId *)) +-{ +- is_installed = func; +-} +- +-void +-sqlite_init_cache(PkBackend *backend, const char* dbname, const char *compare_fname, void (*build_db)(PkBackend *, sqlite3 *)) +-{ +- int ret; +- struct stat st; +- time_t db_age; +- +- ret = sqlite3_open (dbname, &db); +- g_assert(ret == SQLITE_OK); +- g_assert(db!=NULL); +- ret = sqlite3_exec(db,"PRAGMA synchronous = OFF",NULL,NULL,NULL); +- g_assert(ret == SQLITE_OK); +- +- g_stat(dbname, &st); +- db_age = st.st_mtime; +- g_stat(compare_fname, &st); +- if (db_age>=st.st_mtime) +- { +- ret = sqlite3_exec(db, "select value from params where name = 'build_complete'", NULL, NULL, NULL); +- if (ret != SQLITE_ERROR) +- return; +- pk_debug("ages are %lu for db, and %lu for comparism",db_age,st.st_mtime); +- } +- ret = sqlite3_exec(db,"drop table packages",NULL,NULL,NULL); // wipe it! +- //g_assert(ret == SQLITE_OK); +- pk_debug("wiped db"); +- ret = sqlite3_exec(db,"create table packages (name text, version text, deps text, arch text, short_desc text, long_desc text, repo string, primary key(name,version,arch,repo))",NULL,NULL,NULL); +- g_assert(ret == SQLITE_OK); +- +- build_db(backend,db); +- +- sqlite3_exec(db,"create table params (name text primary key, value integer)", NULL, NULL, NULL); +- sqlite3_exec(db,"insert into params values ('build_complete',1)", NULL, NULL, NULL); +-} +- +-void sqlite_finish_cache(PkBackend *backend) +-{ +- sqlite3_close(db); +-} +- +-// sqlite_search_packages_thread +-static gboolean +-sqlite_search_packages_thread (PkBackend *backend) +-{ +- int res; +- gchar *sel; +- const gchar *search; +- +- pk_backend_set_status(backend, PK_STATUS_ENUM_QUERY); +- pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); +- type = pk_backend_get_uint (backend, "type"); +- search = pk_backend_get_string (backend, "search"); +- +- pk_debug("finding %s", search); +- +- sqlite3_stmt *package = NULL; +- g_strdelimit(search," ",'%'); +- +- if (type == SEARCH_NAME) +- sel = g_strdup_printf("select name,version,arch,repo,short_desc from packages where name like '%%%s%%'",search); +- else if (type == SEARCH_DETAILS) +- sel = g_strdup_printf("select name,version,arch,repo,short_desc from packages where name like '%%%s%%' or short_desc like '%%%s%%' or long_desc like '%%%s%%'",search, search, search); +- else +- { +- pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "Unknown search task type"); +- goto end_search_packages; +- } +- +- pk_debug("statement is '%s'",sel); +- res = sqlite3_prepare_v2(db,sel, -1, &package, NULL); +- g_free(sel); +- if (res!=SQLITE_OK) +- pk_error("sqlite error during select prepare: %s", sqlite3_errmsg(db)); +- res = sqlite3_step(package); +- while (res == SQLITE_ROW) +- { +- PkPackageId *pid = pk_package_id_new_from_list((const gchar*)sqlite3_column_text(package,0), +- (const gchar*)sqlite3_column_text(package,1), +- (const gchar*)sqlite3_column_text(package,2), +- (const gchar*)sqlite3_column_text(package,3)); +- +- gchar *cpid = pk_package_id_to_string(pid); +- PkInfoEnum pie = PK_INFO_ENUM_UNKNOWN; +- +- if (is_installed != NULL) +- pie = is_installed(pid)?PK_INFO_ENUM_INSTALLED:PK_INFO_ENUM_AVAILABLE; +- +- pk_backend_package(backend, pie, cpid, (const gchar*)sqlite3_column_text(package,4)); +- +- g_free(cpid); +- pk_package_id_free(pid); +- +- if (res==SQLITE_ROW) +- res = sqlite3_step(package); +- } +- if (res!=SQLITE_DONE) +- { +- pk_debug("sqlite error during step (%d): %s", res, sqlite3_errmsg(db)); +- g_assert(0); +- } +- +-end_search_packages: +- pk_backend_finished (backend); +- return TRUE; +-} +- +-/** +- * sqlite_search_details: +- */ +-void +-sqlite_search_details (PkBackend *backend, const gchar *filter, const gchar *search) +-{ +- pk_backend_set_uint (backend, "type", SEARCH_DETAILS); +- pk_backend_thread_create (backend, sqlite_search_packages_thread); +-} +- +-/** +- * sqlite_search_name: +- */ +-void +-sqlite_search_name (PkBackend *backend, const gchar *filter, const gchar *search) +-{ +- pk_backend_set_uint (backend, "type", SEARCH_NAME); +- pk_backend_thread_create (backend, sqlite_search_packages_thread); +-} +- +-// sqlite_get_details_thread +-static gboolean +-sqlite_get_details_thread (PkBackend *backend) +-{ +- PkPackageId *pi; +- const gchar *package_id; +- int res; +- +- package_id = pk_backend_get_string (backend, "package_id"); +- pi = pk_package_id_new_from_string(package_id); +- if (pi == NULL) +- { +- pk_backend_error_code(backend, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "invalid package id"); +- pk_backend_finished(backend); +- return; +- } +- +- pk_backend_set_status(backend, PK_STATUS_ENUM_QUERY); +- pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID); +- +- pk_debug("finding %s", pi->name); +- +- sqlite3_stmt *package = NULL; +- gchar *sel = g_strdup_printf("select long_desc from packages where name = '%s' and version = '%s' and repo = '%s'",pi->name,pi->version,pi->data); +- pk_debug("statement is '%s'",sel); +- res = sqlite3_prepare_v2(db,sel, -1, &package, NULL); +- g_free(sel); +- if (res!=SQLITE_OK) +- pk_error("sqlite error during select prepare: %s", sqlite3_errmsg(db)); +- res = sqlite3_step(package); +- pk_backend_details(backend,pi->name, "unknown", PK_GROUP_ENUM_OTHER,(const gchar*)sqlite3_column_text(package,0),"",0); +- res = sqlite3_step(package); +- if (res==SQLITE_ROW) +- pk_error("multiple matches for that package!"); +- if (res!=SQLITE_DONE) +- { +- pk_debug("sqlite error during step (%d): %s", res, sqlite3_errmsg(db)); +- g_assert(0); +- } +- +- g_free(dt); +- +- return TRUE; +-} +- +-/** +- * sqlite_get_details: +- */ +-extern "C++" void +-sqlite_get_details (PkBackend *backend, const gchar *package_id) +-{ +- pk_backend_thread_create (backend, sqlite_get_details_thread); +- return; +-} +- +diff --git a/backends/apt/pk-sqlite-pkg-cache.h b/backends/apt/pk-sqlite-pkg-cache.h +deleted file mode 100644 +index 68fad42..0000000 +--- a/backends/apt/pk-sqlite-pkg-cache.h ++++ /dev/null +@@ -1,42 +0,0 @@ +-#ifndef SQLITE_PKT_CACHE +-#define SQLITE_PKT_CACHE +- +-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- +- * +- * Copyright (C) 2007 Tom Parker +- * +- * 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. +- */ +- +-typedef enum { +- SEARCH_NAME = 1, +- SEARCH_DETAILS, +- SEARCH_FILE +-} SearchDepth; +- +-#include +-#include +- +-void sqlite_init_cache(PkBackend *backend, const char* dbname, const char* compare_fname, void (*build_db)(PkBackend *, sqlite3 *db)); +-void sqlite_finish_cache(PkBackend *backend); +- +-void sqlite_search_details (PkBackend *backend, const gchar *filter, const gchar *search); +-void sqlite_search_name (PkBackend *backend, const gchar *filter, const gchar *search); +-void backend_search_common(PkBackend * backend, const gchar * filter, const gchar * search, SearchDepth which, PkBackendThreadFunc func); +-void sqlite_get_details (PkBackend *backend, const gchar *package_id); +- +-#endif +diff --git a/backends/apt/profiler.py b/backends/apt/profiler.py +new file mode 100644 +index 0000000..1b5d30f +--- /dev/null ++++ b/backends/apt/profiler.py +@@ -0,0 +1,40 @@ ++#!/usr/bin/env python ++# 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) 2008 ++# Sebastian Heinlein ++ ++""" ++Allows to start the apt2 backend in a profling mode ++""" ++ ++__author__ = "Sebastian Heinlein " ++ ++ ++import hotshot ++import sys ++ ++from aptDBUSBackend import main ++ ++if len(sys.argv) == 2: ++ profile = sys.argv[1] ++else: ++ profile = "profile" ++ ++prof = hotshot.Profile(profile) ++print prof.runcall(main) ++prof.close() +diff --git a/backends/apt/test.py b/backends/apt/test.py +new file mode 100755 +index 0000000..a1d5ffb +--- /dev/null ++++ b/backends/apt/test.py +@@ -0,0 +1,98 @@ ++#!/usr/bin/python ++# 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 ++ ++import sys ++import dbus ++from packagekit.enums import * ++ ++PACKAGEKIT_DBUS_SERVICE = 'org.freedesktop.PackageKitAptBackend' ++PACKAGEKIT_DBUS_INTERFACE = 'org.freedesktop.PackageKitBackend' ++PACKAGEKIT_DBUS_PATH = '/org/freedesktop/PackageKitBackend' ++PKG_ID = 'xterm;232-1;i386;Debian' ++ ++try: ++ bus = dbus.SystemBus() ++except dbus.DBusException, e: ++ print "Unable to connect to dbus" ++ print "%s" %(e,) ++ sys.exit(1) ++ ++try: ++ proxy = bus.get_object(PACKAGEKIT_DBUS_SERVICE, PACKAGEKIT_DBUS_PATH) ++ iface = dbus.Interface(proxy, PACKAGEKIT_DBUS_INTERFACE) ++ cmd = sys.argv[1] ++ if cmd == 'init' or cmd == 'all': ++ print "Testing Init()" ++ iface.Init() ++ if cmd == 'cancel': ++ print "Canceling" ++ iface.Cancel() ++ if cmd == 'get-updates' or cmd == 'all': ++ print "Testing GetUpdate()" ++ iface.GetUpdates() ++ if cmd == 'search-name' or cmd == 'all': ++ print "Testing SearchName(FILTER_NONE,'apt')" ++ iface.SearchName(FILTER_NONE,'apt') ++ if cmd == 'search-details' or cmd == 'all': ++ print "SearchDetails(FILTER_NONE,'dbus')" ++ iface.SearchDetails(FILTER_NONE,'dbus') ++ if cmd == 'search-group' or cmd == 'all': ++ print "Testing SearchGroup(FILTER_NONE,GROUP_GAMES)" ++ iface.SearchGroup(FILTER_NONE,GROUP_GAMES) ++ if cmd == 'search-file' or cmd == 'all': ++ print "Testing SearchFile(FILTER_NONE,'/usr/bin/yum')" ++ iface.SearchFile(FILTER_NONE,'/usr/bin/yum') ++ if cmd == 'get-requires' or cmd == 'all': ++ print "Testing GetRequires(PKG_ID,False)" ++ iface.GetRequires(PKG_ID,False) ++ if cmd == 'get-depends' or cmd == 'all': ++ print "Testing GetDepends(PKG_ID,False)" ++ iface.GetDepends(PKG_ID,False) ++ if cmd == 'refresh-cache' or cmd == 'all': ++ print "Testing RefreshCache()" ++ iface.RefreshCache() ++ if cmd == 'resolve' or cmd == 'all': ++ print "Testing Resolve(FILTER_NONE,'yum')" ++ iface.Resolve(FILTER_NONE,'yum') ++ if cmd == 'get-details' or cmd == 'all': ++ print "Testing GetDetails(PKG_ID)" ++ iface.GetDetails(PKG_ID) ++ if cmd == 'get-files' or cmd == 'all': ++ print "Testing GetFiles(PKG_ID)" ++ iface.GetFiles(PKG_ID) ++ if cmd == 'get-packages' or cmd == 'all': ++ print "Testing GetPackages(FILTER_INSTALLED,'no')" ++ iface.GetPackages(FILTER_INSTALLED,'no') ++ if cmd == 'get-repolist' or cmd == 'all': ++ print "Testing GetRepoList()" ++ iface.GetRepoList() ++ if cmd == 'get-updatedetail' or cmd == 'all': ++ print "Testing GetUpdateDetail(PKG_ID)" ++ iface.GetUpdateDetail(PKG_ID) ++ #print "Testing " ++ #iface. ++ if cmd == 'exit' or cmd == 'all': ++ print "Testing Exit()" ++ iface.Exit() ++ ++except dbus.DBusException, e: ++ print "Unable to send message on dbus" ++ print "%s" %(e,) ++ sys.exit(1) +diff --git a/backends/apt2/.gitignore b/backends/apt2/.gitignore +deleted file mode 100644 +index c851833..0000000 +--- a/backends/apt2/.gitignore ++++ /dev/null +@@ -1,10 +0,0 @@ +-.deps +-.libs +-Makefile +-Makefile.in +-*.la +-*.lo +-*.loT +-*.o +-*~ +- +diff --git a/backends/apt2/HACKING b/backends/apt2/HACKING +deleted file mode 100644 +index 2b99c5d..0000000 +--- a/backends/apt2/HACKING ++++ /dev/null +@@ -1,5 +0,0 @@ +-The backend can be tested by running it as root from the source code +-repository. Make sure to kill packagekitd before to force a reintializing +-of the cache: +- +- killall packagekitd; python aptDBUSBackend.py +diff --git a/backends/apt2/Makefile.am b/backends/apt2/Makefile.am +deleted file mode 100644 +index 91c0c46..0000000 +--- a/backends/apt2/Makefile.am ++++ /dev/null +@@ -1,25 +0,0 @@ +-NULL = +- +-plugindir = $(PK_PLUGIN_DIR) +-plugin_LTLIBRARIES = libpk_backend_apt2.la +-libpk_backend_apt2_la_SOURCES = pk-backend-apt2.c +-libpk_backend_apt2_la_LIBADD = $(PK_PLUGIN_LIBS) +-libpk_backend_apt2_la_LDFLAGS = -module -avoid-version +-libpk_backend_apt2_la_CFLAGS = $(PK_PLUGIN_CFLAGS) +- +-dbusinstancedir = $(LIBEXECDIR) +-dbusinstance_DATA = \ +- aptDBUSBackend.py \ +- $(NULL) +- +-EXTRA_DIST = \ +- $(dbusinstance_DATA) \ +- $(NULL) +- +-install-data-hook: +- chmod a+rx $(DESTDIR)$(libexecdir)/*.py +- +-clean-local : +- rm -f *~ +- rm -f *.pyc +- +diff --git a/backends/apt2/README b/backends/apt2/README +deleted file mode 100644 +index 0a3da6e..0000000 +--- a/backends/apt2/README ++++ /dev/null +@@ -1,23 +0,0 @@ +-The name of this backend is apt2. +- +-It supports apt which is mainly used by Debian and its derivates. In contrast to +-the backend called apt this one uses DBus for the communication with the +-packagekit daemon. This allows to perform actions without having to reopen +-the cache for each one. +- +-To provide a tremendously fast search function a Xapian database is used. +-It is provided by Enrico Zini's apt-xapian-index. Debtags will be used to +-enhance the quality of the search results further. +- +-A list of implemented functions are listed in the PackageKit FAQ: +- +-http://www.packagekit.org/pk-faq.html +- +-You can find packages for Ubuntu here: +- +-https://www.launchpad.net/~packagekit/+ppa +- +-Packages for Debian Unstable will be provided soon. +- +-Feel free to send comments or bug reports to the PackageKit mailing list +-or to the author. +diff --git a/backends/apt2/TODO b/backends/apt2/TODO +deleted file mode 100644 +index bee2f3d..0000000 +--- a/backends/apt2/TODO ++++ /dev/null +@@ -1,70 +0,0 @@ +-ISSUES: +- +- * Support delayed or hidden debconf questions +- +-Unresolved issues can be discussed at the following wiki page: +-http://wiki.debian.org/PackageKit +- +- +-TODO: +- +- * Implement all open backend methods. A list of implemented backend methods +- can be found in PackageKit FAQ or in pk-backend-apt2.c. +- +- * Blacklist packages requiring input on the terminal and try to change +- the Debian policy in the long run. Way of automation? +- +- * Allow to inject alternative apt.package.Package classes into the +- cache to support PackageKit and distribution specific needs +- (e.g. when is a package called free or supported) +- +- * Allow to reinject debtags into the search results to get +- similar software which not matches on the search terms +- +- * Index file list and add properties for package name and section to +- the xapian database to also make use of it in search group and +- search name (do we want this?) +- +- * Map Debian/Ubuntu sections to PackageKit groups: +- - admin : System Administration => admin-tools +- - base : Base System => system +- - comm : Communication => communication +- - devel : Development => programming +- - doc : Documentation => ??? +- - editors : Editors => accessoires +- - electronics : Electronics => other +- - embedded : Embedded Devices => system +- - games : Games and Amusement => games +- - gnome : GNOME Desktop Environment => desktop-gnome +- - graphics : Graphics => graphics +- - hamradio : Amateur Radio => communication +- - interpreters : Interpreted Computer L. => programming +- - kde : KDE Desktop Environment => desktop-kde +- - libdevel : Libraries - Development => programming +- - libs : Libraries => system +- - mail : Email => internet +- - math : Mathematics => ??? science/education +- - misc : Miscellaneous - Text Based => other +- - net : Networkinga => network +- - news : Newsgroup => internet +- - oldlibs : Libraries - Old => legacy +- - otherosfs : Cross Platform => system +- - perl : Perl Programming Language => programming +- - python : Python Programming Language => programming +- - science : Science => ??? science/education +- - shells : Shells => system +- - sound : Multimedia => multimedia +- - tex : TeX Authoring => publishing +- - text : Word Processing => publishing +- - utils : Utilities => accessoires +- - web : World Wide Web => internet +- - x11 : Miscellaneous - Graphical => desktop-other +- - unknown : Unknown => unknown +- - alien : Converted From RPM by Alien" => unknown +- - translations => localization +- The following could not be maped: science, documentation, electronics +- Are there any derivates with additional sections? +- +- * Fix the dbus policy. Should we require at_console for searching? +- +-DONE: +diff --git a/backends/apt2/aptDBUSBackend.py b/backends/apt2/aptDBUSBackend.py +deleted file mode 100755 +index b7fc500..0000000 +--- a/backends/apt2/aptDBUSBackend.py ++++ /dev/null +@@ -1,628 +0,0 @@ +-#!/usr/bin/env python +-# -*- coding: utf-8 -*- +-""" +-Provides an apt backend to PackageKit +- +-Copyright (C) 2007 Ali Sabil +-Copyright (C) 2007 Tom Parker +-Copyright (C) 2008 Sebastian Heinlein +- +-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. +-""" +- +-__author__ = "Sebastian Heinlein " +-__state__ = "experimental" +- +-import os +-import pty +-import re +-import signal +-import time +-import threading +-import warnings +- +-import apt +-import apt_pkg +-import dbus +-import dbus.glib +-import dbus.service +-import dbus.mainloop.glib +-import gobject +-import xapian +- +-from packagekit.daemonBackend import PACKAGEKIT_DBUS_INTERFACE, PACKAGEKIT_DBUS_PATH, PackageKitBaseBackend, PackagekitProgress, pklog, threaded +-from packagekit.enums import * +- +-warnings.filterwarnings(action='ignore', category=FutureWarning) +- +-PACKAGEKIT_DBUS_SERVICE = 'org.freedesktop.PackageKitAptBackend' +- +-XAPIANDBPATH = os.environ.get("AXI_DB_PATH", "/var/lib/apt-xapian-index") +-XAPIANDB = XAPIANDBPATH + "/index" +-XAPIANDBVALUES = XAPIANDBPATH + "/values" +-DEFAULT_SEARCH_FLAGS = (xapian.QueryParser.FLAG_BOOLEAN | +- xapian.QueryParser.FLAG_PHRASE | +- xapian.QueryParser.FLAG_LOVEHATE | +- xapian.QueryParser.FLAG_BOOLEAN_ANY_CASE) +- +-# Required for daemon mode +-os.putenv("PATH", +- "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin") +-# Avoid questions from the maintainer scripts as far as possible +-os.putenv("DEBIAN_FRONTEND", "noninteractive") +-os.putenv("APT_LISTCHANGES_FRONTEND", "none") +- +-# Setup threading support +-gobject.threads_init() +-dbus.glib.threads_init() +- +-class PackageKitOpProgress(apt.progress.OpProgress): +- ''' +- Handle the cache opening process +- ''' +- def __init__(self, backend, prange=(0,100), progress=True): +- self._backend = backend +- apt.progress.OpProgress.__init__(self) +- self.steps = [] +- for v in [0.12, 0.25, 0.50, 0.75, 1.00]: +- s = prange[0] + (prange[1] - prange[0]) * v +- self.steps.append(s) +- self.pstart = float(prange[0]) +- self.pend = self.steps.pop(0) +- self.pprev = None +- self.show_progress = progress +- +- # OpProgress callbacks +- def update(self, percent): +- progress = int(self.pstart + percent / 100 * (self.pend - self.pstart)) +- if self.show_progress == True and self.pprev < progress: +- self._backend.PercentageChanged(progress) +- self.pprev = progress +- +- def done(self): +- self.pstart = self.pend +- try: +- self.pend = self.steps.pop(0) +- except: +- pklog.warning("An additional step to open the cache is required") +- +-class PackageKitFetchProgress(apt.progress.FetchProgress): +- ''' +- Handle the package download process +- ''' +- def __init__(self, backend, prange=(0,100)): +- self._backend = backend +- apt.progress.FetchProgress.__init__(self) +- self.pstart = prange[0] +- self.pend = prange[1] +- self.pprev = None +- +- # FetchProgress callbacks +- def pulse(self): +- if self._backend._canceled.isSet(): +- return False +- percent = ((self.currentBytes + self.currentItems)*100.0)/float(self.totalBytes+self.totalItems) +- progress = int(self.pstart + percent/100 * (self.pend - self.pstart)) +- if self.pprev < progress: +- self._backend.PercentageChanged(progress) +- self.pprev = progress +- apt.progress.FetchProgress.pulse(self) +- return True +- +- def start(self): +- self._backend.StatusChanged(STATUS_DOWNLOAD) +- self._backend.AllowCancel(True) +- +- def stop(self): +- self._backend.PercentageChanged(self.pend) +- self._backend.AllowCancel(False) +- +- def mediaChange(self, medium, drive): +- #FIXME: use the Message method to notify the user +- self._backend.error(ERROR_UNKNOWN, +- "Medium change needed") +- +-class PackageKitInstallProgress(apt.progress.InstallProgress): +- ''' +- Handle the installation and removal process. Bits taken from +- DistUpgradeViewNonInteractive. +- ''' +- def __init__(self, backend, prange=(0,100)): +- apt.progress.InstallProgress.__init__(self) +- self._backend = backend +- self.timeout = 900 +- self.pstart = prange[0] +- self.pend = prange[1] +- self.pprev = None +- +- def statusChange(self, pkg, percent, status): +- progress = self.pstart + percent/100 * (self.pend - self.pstart) +- if self.pprev < progress: +- self._backend.PercentageChanged(int(progress)) +- self.pprev = progress +- pklog.debug("PM status: %s" % status) +- +- def startUpdate(self): +- self._backend.StatusChanged(STATUS_INSTALL) +- self.last_activity = time.time() +- +- def updateInterface(self): +- pklog.debug("Updating interface") +- apt.progress.InstallProgress.updateInterface(self) +- +- def conffile(self, current, new): +- pklog.critical("Config file prompt: '%s'" % current) +- +-def sigquit(signum, frame): +- pklog.error("Was killed") +- sys.exit(1) +- +-class PackageKitAptBackend(PackageKitBaseBackend): +- ''' +- PackageKit backend for apt +- ''' +- +- def locked(func): +- ''' +- Decorator to run a method with a lock +- ''' +- def wrapper(*args, **kwargs): +- backend = args[0] +- backend._lock_cache() +- ret = func(*args, **kwargs) +- backend._unlock_cache() +- return ret +- wrapper.__name__ = func.__name__ +- return wrapper +- +- def __init__(self, bus_name, dbus_path): +- pklog.info("Initializing APT backend") +- signal.signal(signal.SIGQUIT, sigquit) +- self._cache = None +- self._xapian = None +- self._canceled = threading.Event() +- self._canceled.clear() +- self._locked = threading.Lock() +- PackageKitBaseBackend.__init__(self, bus_name, dbus_path) +- +- # Methods ( client -> engine -> backend ) +- +- def doInit(self): +- pklog.info("Initializing cache") +- self.StatusChanged(STATUS_SETUP) +- self.AllowCancel(False) +- self.NoPercentageUpdates() +- self._open_cache(progress=False) +- +- def doExit(self): +- pass +- +- @threaded +- def doCancel(self): +- pklog.info("Canceling current action") +- self.StatusChanged(STATUS_CANCEL) +- self._canceled.set() +- self._canceled.wait() +- +- @threaded +- def doSearchName(self, filters, search): +- ''' +- Implement the apt2-search-name functionality +- ''' +- pklog.info("Searching for package name: %s" % search) +- self.StatusChanged(STATUS_QUERY) +- self.NoPercentageUpdates() +- self._check_init(progress=False) +- self.AllowCancel(True) +- +- for pkg in self._cache: +- if self._canceled.isSet(): +- self.ErrorCode(ERROR_TRANSACTION_CANCELLED, +- "The search was canceled") +- self.Finished(EXIT_KILL) +- self._canceled.clear() +- return +- elif search in pkg.name and self._is_package_visible(pkg, filters): +- self._emit_package(pkg) +- self.Finished(EXIT_SUCCESS) +- +- @threaded +- def doSearchDetails(self, filters, search): +- ''' +- Implement the apt2-search-details functionality +- ''' +- pklog.info("Searching for package name: %s" % search) +- self.StatusChanged(STATUS_QUERY) +- self.NoPercentageUpdates() +- self._check_init(progress=False) +- self.AllowCancel(True) +- results = [] +- +- if os.access(XAPIANDB, os.R_OK): +- pklog.debug("Performing xapian db based search") +- db = xapian.Database(XAPIANDB) +- parser = xapian.QueryParser() +- query = parser.parse_query(unicode(search), +- DEFAULT_SEARCH_FLAGS) +- enquire = xapian.Enquire(db) +- enquire.set_query(query) +- matches = enquire.get_mset(0, 1000) +- for r in map(lambda m: m[xapian.MSET_DOCUMENT].get_data(), +- enquire.get_mset(0,1000)): +- if self._cache.has_key(r): +- results.append(self._cache[r]) +- else: +- pklog.debug("Performing apt cache based search") +- for p in self._cache._dict.values(): +- if self._check_canceled("Search was canceled"): return +- needle = search.strip().lower() +- haystack = p.description.lower() +- if p.name.find(needle) >= 0 or haystack.find(needle) >= 0: +- results.append(p) +- +- for r in results: +- if self._check_canceled("Search was canceled"): return +- if self._is_package_visible(r, filters) == True: +- self._emit_package(r) +- +- self.Finished(EXIT_SUCCESS) +- +- @threaded +- @locked +- def doGetUpdates(self, filters): +- ''' +- Implement the {backend}-get-update functionality +- ''' +- #FIXME: Implment the basename filter +- pklog.info("Get updates") +- self.StatusChanged(STATUS_INFO) +- self.AllowCancel(True) +- self.NoPercentageUpdates() +- self._check_init(progress=False) +- self._cache.upgrade(False) +- for pkg in self._cache.getChanges(): +- if self._canceled.isSet(): +- self.ErrorCode(ERROR_TRANSACTION_CANCELLED, +- "Calculating updates was canceled") +- self.Finished(EXIT_KILL) +- self._canceled.clear() +- return +- else: +- self._emit_package(pkg) +- self._open_cache(progress=False) +- self.Finished(EXIT_SUCCESS) +- +- @threaded +- def GetDetails(self, pkg_id): +- ''' +- Implement the {backend}-get-details functionality +- ''' +- pklog.info("Get details of %s" % pkg_id) +- self.StatusChanged(STATUS_INFO) +- self.NoPercentageUpdates() +- self.AllowCancel(False) +- self._check_init(progress=False) +- name, version, arch, data = self.get_package_from_id(pkg_id) +- if not self._cache.has_key(name): +- self.ErrorCode(ERROR_PACKAGE_NOT_FOUND, +- "Package %s isn't available" % name) +- self.Finished(EXIT_FAILED) +- return +- pkg = self._cache[name] +- #FIXME: should perhaps go to python-apt since we need this in +- # several applications +- desc = pkg.description +- # Skip the first line - it's a duplicate of the summary +- i = desc.find('\n') +- desc = desc[i+1:] +- # do some regular expression magic on the description +- # Add a newline before each bullet +- p = re.compile(r'^(\s|\t)*(\*|0|-)',re.MULTILINE) +- desc = p.sub(ur'\n\u2022', desc) +- # replace all newlines by spaces +- p = re.compile(r'\n', re.MULTILINE) +- desc = p.sub(" ", desc) +- # replace all multiple spaces by newlines +- p = re.compile(r'\s\s+', re.MULTILINE) +- desc = p.sub('\n', desc) +- #FIXME: group and licence information missing +- self.Details(pkg_id, 'unknown', 'unknown', desc, +- pkg.homepage, pkg.packageSize) +- self.Finished(EXIT_SUCCESS) +- +- @threaded +- @locked +- def doUpdateSystem(self): +- ''' +- Implement the {backend}-update-system functionality +- ''' +- #FIXME: Better exception and error handling +- #FIXME: Distupgrade or Upgrade? +- #FIXME: Handle progress in a more sane way +- pklog.info("Upgrading system") +- self.StatusChanged(STATUS_UPDATE) +- self.AllowCancel(False) +- self.PercentageChanged(0) +- self._check_init(prange=(0,5)) +- try: +- self._cache.upgrade(distUpgrade=True) +- self._cache.commit(PackageKitFetchProgress(self, prange=(5,50)), +- PackageKitInstallProgress(self, prange=(50,95))) +- except apt.cache.FetchFailedException: +- self._open_cache() +- self.ErrorCode(ERROR_PACKAGE_DOWNLOAD_FAILED, "Download failed") +- self.Finished(EXIT_FAILED) +- return +- except apt.cache.FetchCancelledException: +- self._open_cache(prange=(95,100)) +- self.ErrorCode(ERROR_TRANSACTION_CANCELLED, "Download was canceled") +- self.Finished(EXIT_KILL) +- self._canceled.clear() +- return +- except: +- self._open_cache(prange=(95,100)) +- self.ErrorCode(ERROR_UNKNOWN, "System update failed") +- self.Finished(EXIT_FAILED) +- return +- self.PercentageChanged(100) +- self.Finished(EXIT_SUCCESS) +- +- @threaded +- @locked +- def doRemovePackages(self, ids, deps=True, auto=False): +- ''' +- Implement the {backend}-remove functionality +- ''' +- #FIXME: Handle progress in a more sane way +- pklog.info("Removing package with id %s" % id) +- self.StatusChanged(STATUS_REMOVE) +- self.AllowCancel(False) +- self.PercentageChanged(0) +- self._check_init(prange=(0,10)) +- pkg = self._find_package_by_id(id) +- if pkg == None: +- self.ErrorCode(ERROR_PACKAGE_NOT_FOUND, +- "Package %s isn't available" % pkg.name) +- self.Finished(EXIT_FAILED) +- return +- if not pkg.isInstalled: +- self.ErrorCode(ERROR_PACKAGE_NOT_INSTALLED, +- "Package %s isn't installed" % pkg.name) +- self.Finished(EXIT_FAILED) +- return +- name = pkg.name[:] +- try: +- pkg.markDelete() +- self._cache.commit(PackageKitFetchProgress(self, prange=(10,10)), +- PackageKitInstallProgress(self, prange=(10,90))) +- except: +- self._open_cache(prange=(90,100)) +- self.ErrorCode(ERROR_UNKNOWN, "Removal failed") +- self.Finished(EXIT_FAILED) +- return +- self._open_cache(prange=(90,100)) +- self.PercentageChanged(100) +- if not self._cache.has_key(name) or not self._cache[name].isInstalled: +- self.Finished(EXIT_SUCCESS) +- else: +- self.ErrorCode(ERROR_UNKNOWN, "Package is still installed") +- self.Finished(EXIT_FAILED) +- +- @threaded +- @locked +- def doInstallPackages(self, ids): +- ''' +- Implement the {backend}-install functionality +- ''' +- #FIXME: Handle progress in a more sane way +- pklog.info("Installing package with id %s" % id) +- self.StatusChanged(STATUS_INSTALL) +- self.AllowCancel(False) +- self.PercentageChanged(0) +- self._check_init(prange=(0,10)) +- pkg = self._find_package_by_id(id) +- if pkg == None: +- self.ErrorCode(ERROR_PACKAGE_NOT_FOUND, +- "Package %s isn't available" % pkg.name) +- self.Finished(EXIT_FAILED) +- return +- if pkg.isInstalled: +- self.ErrorCode(ERROR_PACKAGE_ALREADY_INSTALLED, +- "Package %s is already installed" % pkg.name) +- self.Finished(EXIT_FAILED) +- return +- name = pkg.name[:] +- try: +- pkg.markInstall() +- self._cache.commit(PackageKitFetchProgress(self, prange=(10,50)), +- PackageKitInstallProgress(self, prange=(50,90))) +- except: +- self._open_cache(prange=(90,100)) +- self.ErrorCode(ERROR_UNKNOWN, "Installation failed") +- self.Finished(EXIT_FAILED) +- return +- self._open_cache(prange=(90,100)) +- self.PercentageChanged(100) +- if self._cache.has_key(name) and self._cache[name].isInstalled: +- self.Finished(EXIT_SUCCESS) +- else: +- self.ErrorCode(ERROR_UNKNOWN, "Installation failed") +- self.Finished(EXIT_FAILED) +- +- @threaded +- @locked +- def doRefreshCache(self, force): +- ''' +- Implement the {backend}-refresh_cache functionality +- ''' +- pklog.info("Refresh cache") +- self.StatusChanged(STATUS_REFRESH_CACHE) +- self.last_action_time = time.time() +- self.AllowCancel(False); +- self.PercentageChanged(0) +- self._check_init((0,10)) +- try: +- self._cache.update(PackageKitFetchProgress(self, prange=(10,95))) +- except apt.cache.FetchFailedException: +- self.ErrorCode(ERROR_NO_NETWORK, "Download failed") +- self.Finished(EXIT_FAILED) +- return +- except apt.cache.FetchCancelledException: +- self._canceled.clear() +- self.ErrorCode(ERROR_TRANSACTION_CANCELLED, "Download was canceled") +- self.Finished(EXIT_KILL) +- return +- except: +- self._open_cache(prange=(95,100)) +- self.ErrorCode(ERROR_UNKNOWN, "Refreshing cache failed") +- self.Finished(EXIT_FAILED) +- return +- self.PercentageChanged(100) +- self.Finished(EXIT_SUCCESS) +- +- # Helpers +- +- def _open_cache(self, prange=(0,100), progress=True): +- ''' +- (Re)Open the APT cache +- ''' +- pklog.debug("Open APT cache") +- self.StatusChanged(STATUS_REFRESH_CACHE) +- try: +- self._cache = apt.Cache(PackageKitOpProgress(self, prange, +- progress)) +- except: +- self.ErrorCode(ERROR_NO_CACHE, "Package cache could not be opened") +- self.Finished(EXIT_FAILED) +- self.Exit() +- return +- if self._cache._depcache.BrokenCount > 0: +- self.ErrorCode(ERROR_DEP_RESOLUTION_FAILED, +- "Not all dependecies can be satisfied") +- self.Finished(EXIT_FAILED) +- self.Exit() +- return +- +- def _lock_cache(self): +- ''' +- Lock the cache +- ''' +- pklog.debug("Locking cache") +- self._locked.acquire() +- +- def _unlock_cache(self): +- ''' +- Unlock the cache +- ''' +- pklog.debug("Releasing cache") +- self._locked.release() +- +- def _check_init(self, prange=(0,10), progress=True): +- ''' +- Check if the backend was initialized well and try to recover from +- a broken setup +- ''' +- pklog.debug("Check apt cache and xapian database") +- if not isinstance(self._cache, apt.cache.Cache) or \ +- self._cache._depcache.BrokenCount > 0: +- self._open_cache(prange, progress) +- +- def _check_canceled(self, msg): +- ''' +- Check if the current transaction was canceled. If so send the +- corresponding error message and return True +- ''' +- if self._canceled.isSet(): +- self.ErrorCode(ERROR_TRANSACTION_CANCELLED, msg) +- self.Finished(EXIT_KILL) +- self._canceled.clear() +- return True +- return False +- +- def get_id_from_package(self, pkg, installed=False): +- ''' +- Return the id of the installation candidate of a core +- apt package. If installed is set to True the id of the currently +- installed package will be returned. +- ''' +- origin = '' +- if installed == False and pkg.isInstalled: +- pkgver = pkg.installedVersion +- else: +- pkgver = pkg.candidateVersion +- if pkg.candidateOrigin: +- origin = pkg.candidateOrigin[0].label +- id = self._get_package_id(pkg.name, pkgver, pkg.architecture, origin) +- return id +- +- def _emit_package(self, pkg): +- ''' +- Send the Package signal for a given apt package +- ''' +- id = self.get_id_from_package(pkg) +- if pkg.isInstalled: +- status = INFO_INSTALLED +- else: +- status = INFO_AVAILABLE +- summary = pkg.summary +- self.Package(status, id, summary) +- +- def _is_package_visible(self, pkg, filters): +- ''' +- Return True if the package should be shown in the user interface +- ''' +- #FIXME: Needs to be optmized +- if filters == 'none': +- return True +- if FILTER_INSTALLED in filters and not pkg.isInstalled: +- return False +- if FILTER_NOT_INSTALLED in filters and pkg.isInstalled: +- return False +- if FILTER_GUI in filters and not self._package_has_gui(pkg): +- return False +- if FILTER_NOT_GUI in filters and self._package_has_gui(pkg): +- return False +- if FILTER_DEVELOPMENT in filters and not self._package_is_devel(pkg): +- return False +- if FILTER_NOT_DEVELOPMENT in filters and self._package_is_devel(pkg): +- return False +- return True +- +- def _package_has_gui(self, pkg): +- #FIXME: should go to a modified Package class +- #FIXME: take application data into account. perhaps checking for +- # property in the xapian database +- return pkg.section.split('/')[-1].lower() in ['x11', 'gnome', 'kde'] +- +- def _package_is_devel(self, pkg): +- #FIXME: should go to a modified Package class +- return pkg.name.endswith("-dev") or pkg.name.endswith("-dbg") or \ +- pkg.section.split('/')[-1].lower() in ['devel', 'libdevel'] +- +- def _find_package_by_id(self, id): +- ''' +- Return a package matching to the given package id +- ''' +- # FIXME: Perform more checks +- name, version, arch, data = self.get_package_from_id(id) +- if self._cache.has_key(name): +- return self._cache[name] +- else: +- return None +- +- +-def main(): +- loop = dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) +- bus = dbus.SystemBus(mainloop=loop) +- bus_name = dbus.service.BusName(PACKAGEKIT_DBUS_SERVICE, bus=bus) +- manager = PackageKitAptBackend(bus_name, PACKAGEKIT_DBUS_PATH) +- +-if __name__ == '__main__': +- main() +- +-# vim: ts=4 et sts=4 +diff --git a/backends/apt2/pk-backend-apt2.c b/backends/apt2/pk-backend-apt2.c +deleted file mode 100644 +index 4f78ec4..0000000 +--- a/backends/apt2/pk-backend-apt2.c ++++ /dev/null +@@ -1,204 +0,0 @@ +-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- +- * +- * Copyright (C) 2007 Ali Sabil +- * Copyright (C) 2007 Tom Parker +- * +- * Licensed under the GNU General Public License Version 2 +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +- */ +- +-#include +-#include +- +-static PkBackendDbus *dbus; +- +-#define PK_DBUS_BACKEND_SERVICE_APT "org.freedesktop.PackageKitAptBackend" +- +-/** +- * backend_initialize: +- * This should only be run once per backend load, i.e. not every transaction +- */ +-static void +-backend_initialize (PkBackend *backend) +-{ +- pk_debug ("FILTER: initialize"); +- dbus = pk_backend_dbus_new (); +- pk_backend_dbus_set_name (dbus, PK_DBUS_BACKEND_SERVICE_APT); +-} +- +-/** +- * backend_destroy: +- * This should only be run once per backend load, i.e. not every transaction +- */ +-static void +-backend_destroy (PkBackend *backend) +-{ +- pk_debug ("FILTER: destroy"); +- pk_backend_dbus_kill (dbus); +- g_object_unref (dbus); +-} +- +-/** +- * backend_get_groups: +- */ +-static PkGroupEnum +-backend_get_groups (PkBackend *backend) +-{ +- return (PK_GROUP_ENUM_ACCESSORIES | +- PK_GROUP_ENUM_GAMES | +- PK_GROUP_ENUM_GRAPHICS | +- PK_GROUP_ENUM_INTERNET | +- PK_GROUP_ENUM_OFFICE | +- PK_GROUP_ENUM_OTHER | +- PK_GROUP_ENUM_PROGRAMMING | +- PK_GROUP_ENUM_MULTIMEDIA | +- PK_GROUP_ENUM_SYSTEM); +-} +- +-/** +- * backend_get_filters: +- */ +-static PkFilterEnum +-backend_get_filters (PkBackend *backend) +-{ +- return (PK_FILTER_ENUM_GUI | +- PK_FILTER_ENUM_INSTALLED | +- PK_FILTER_ENUM_DEVELOPMENT); +-} +- +-/** +- * backend_get_updates: +- */ +-static void +-backend_get_updates (PkBackend *backend, PkFilterEnum filters) +-{ +- pk_backend_dbus_get_updates (dbus, filters); +-} +- +-/** +- * backend_refresh_cache: +- * */ +-static void +-backend_refresh_cache (PkBackend *backend, gboolean force) +-{ +- // check network state +- if (!pk_backend_is_online (backend)) { +- pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot refresh cache whilst offline"); +- pk_backend_finished (backend); +- return; +- } +- +- pk_backend_dbus_refresh_cache(dbus, force); +-} +- +-/** +- * pk_backend_update_system: +- * */ +-static void +-backend_update_system (PkBackend *backend) +-{ +- pk_backend_dbus_update_system (dbus); +-} +- +-/** +- * backend_install_packages +- * */ +-static void +-backend_install_packages (PkBackend *backend, gchar **package_ids) +-{ +- pk_backend_dbus_install_packages (dbus, package_ids); +-} +- +-/** +- * backend_remove_packages +- * */ +-static void +-backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow_deps, gboolean autoremove) +-{ +- pk_backend_dbus_remove_packages (dbus, package_ids, allow_deps, autoremove); +-} +- +-/** +- * backend_get_details: +- * */ +-static void +-backend_get_details (PkBackend *backend, const gchar *package_id) +-{ +- pk_backend_dbus_get_details (dbus, package_id); +-} +- +-/** +- * * pk_backend_search_details: +- * */ +-static void +-backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *search) +-{ +- pk_backend_dbus_search_details (dbus, filters, search); +-} +- +-/** +- * * pk_backend_search_name: +- * */ +-static void +-backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search) +-{ +- pk_backend_dbus_search_name (dbus, filters, search); +-} +- +-/** +- * * pk_backend_cancel: +- * */ +-static void +-backend_cancel (PkBackend *backend) +-{ +- pk_backend_dbus_cancel (dbus); +-} +- +- +-PK_BACKEND_OPTIONS ( +- "Apt", /* description */ +- "Ali Sabil ; Tom Parker ; Sebastian Heinlein ", /* author */ +- backend_initialize, /* initalize */ +- backend_destroy, /* destroy */ +- backend_get_groups, /* get_groups */ +- backend_get_filters, /* get_filters */ +- backend_cancel, /* cancel */ +- NULL, /* get_depends */ +- backend_get_details, /* get_details */ +- NULL, /* get_files */ +- NULL, /* get_packages */ +- NULL, /* get_repo_list */ +- NULL, /* get_requires */ +- NULL, /* get_update_detail */ +- backend_get_updates, /* get_updates */ +- NULL, /* install_files */ +- backend_install_packages, /* install_packages */ +- NULL, /* install_signature */ +- backend_refresh_cache, /* refresh_cache */ +- backend_remove_packages, /* remove_packages */ +- NULL, /* repo_enable */ +- NULL, /* repo_set_data */ +- NULL, /* resolve */ +- NULL, /* rollback */ +- backend_search_details, /* search_details */ +- NULL, /* search_file */ +- NULL, /* search_group */ +- backend_search_name, /* search_name */ +- NULL, /* service_pack */ +- NULL, /* update_packages */ +- backend_update_system, /* update_system */ +- NULL /* what_provides */ +-); +diff --git a/backends/apt2/profiler.py b/backends/apt2/profiler.py +deleted file mode 100644 +index 1b5d30f..0000000 +--- a/backends/apt2/profiler.py ++++ /dev/null +@@ -1,40 +0,0 @@ +-#!/usr/bin/env python +-# 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) 2008 +-# Sebastian Heinlein +- +-""" +-Allows to start the apt2 backend in a profling mode +-""" +- +-__author__ = "Sebastian Heinlein " +- +- +-import hotshot +-import sys +- +-from aptDBUSBackend import main +- +-if len(sys.argv) == 2: +- profile = sys.argv[1] +-else: +- profile = "profile" +- +-prof = hotshot.Profile(profile) +-print prof.runcall(main) +-prof.close() +diff --git a/backends/apt2/test.py b/backends/apt2/test.py +deleted file mode 100755 +index a1d5ffb..0000000 +--- a/backends/apt2/test.py ++++ /dev/null +@@ -1,98 +0,0 @@ +-#!/usr/bin/python +-# 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 +- +-import sys +-import dbus +-from packagekit.enums import * +- +-PACKAGEKIT_DBUS_SERVICE = 'org.freedesktop.PackageKitAptBackend' +-PACKAGEKIT_DBUS_INTERFACE = 'org.freedesktop.PackageKitBackend' +-PACKAGEKIT_DBUS_PATH = '/org/freedesktop/PackageKitBackend' +-PKG_ID = 'xterm;232-1;i386;Debian' +- +-try: +- bus = dbus.SystemBus() +-except dbus.DBusException, e: +- print "Unable to connect to dbus" +- print "%s" %(e,) +- sys.exit(1) +- +-try: +- proxy = bus.get_object(PACKAGEKIT_DBUS_SERVICE, PACKAGEKIT_DBUS_PATH) +- iface = dbus.Interface(proxy, PACKAGEKIT_DBUS_INTERFACE) +- cmd = sys.argv[1] +- if cmd == 'init' or cmd == 'all': +- print "Testing Init()" +- iface.Init() +- if cmd == 'cancel': +- print "Canceling" +- iface.Cancel() +- if cmd == 'get-updates' or cmd == 'all': +- print "Testing GetUpdate()" +- iface.GetUpdates() +- if cmd == 'search-name' or cmd == 'all': +- print "Testing SearchName(FILTER_NONE,'apt')" +- iface.SearchName(FILTER_NONE,'apt') +- if cmd == 'search-details' or cmd == 'all': +- print "SearchDetails(FILTER_NONE,'dbus')" +- iface.SearchDetails(FILTER_NONE,'dbus') +- if cmd == 'search-group' or cmd == 'all': +- print "Testing SearchGroup(FILTER_NONE,GROUP_GAMES)" +- iface.SearchGroup(FILTER_NONE,GROUP_GAMES) +- if cmd == 'search-file' or cmd == 'all': +- print "Testing SearchFile(FILTER_NONE,'/usr/bin/yum')" +- iface.SearchFile(FILTER_NONE,'/usr/bin/yum') +- if cmd == 'get-requires' or cmd == 'all': +- print "Testing GetRequires(PKG_ID,False)" +- iface.GetRequires(PKG_ID,False) +- if cmd == 'get-depends' or cmd == 'all': +- print "Testing GetDepends(PKG_ID,False)" +- iface.GetDepends(PKG_ID,False) +- if cmd == 'refresh-cache' or cmd == 'all': +- print "Testing RefreshCache()" +- iface.RefreshCache() +- if cmd == 'resolve' or cmd == 'all': +- print "Testing Resolve(FILTER_NONE,'yum')" +- iface.Resolve(FILTER_NONE,'yum') +- if cmd == 'get-details' or cmd == 'all': +- print "Testing GetDetails(PKG_ID)" +- iface.GetDetails(PKG_ID) +- if cmd == 'get-files' or cmd == 'all': +- print "Testing GetFiles(PKG_ID)" +- iface.GetFiles(PKG_ID) +- if cmd == 'get-packages' or cmd == 'all': +- print "Testing GetPackages(FILTER_INSTALLED,'no')" +- iface.GetPackages(FILTER_INSTALLED,'no') +- if cmd == 'get-repolist' or cmd == 'all': +- print "Testing GetRepoList()" +- iface.GetRepoList() +- if cmd == 'get-updatedetail' or cmd == 'all': +- print "Testing GetUpdateDetail(PKG_ID)" +- iface.GetUpdateDetail(PKG_ID) +- #print "Testing " +- #iface. +- if cmd == 'exit' or cmd == 'all': +- print "Testing Exit()" +- iface.Exit() +- +-except dbus.DBusException, e: +- print "Unable to send message on dbus" +- print "%s" %(e,) +- sys.exit(1) +diff --git a/backends/dummy/pk-backend-dummy.c b/backends/dummy/pk-backend-dummy.c +index 2df445e..5714e9f 100644 +--- a/backends/dummy/pk-backend-dummy.c ++++ b/backends/dummy/pk-backend-dummy.c +@@ -187,6 +187,7 @@ backend_get_update_detail_timeout (gpointer data) + "", PK_RESTART_ENUM_NONE, "Update to newest upstream source"); + } else if (pk_strequal (_package_id, "kernel;2.6.23-0.115.rc3.git1.fc8;i386;installed")) { + pk_backend_update_detail (backend, "kernel;2.6.23-0.115.rc3.git1.fc8;i386;available", ++ "kernel;2.6.22-0.104.rc3.git6.fc8;i386;installed^" + "kernel;2.6.22-0.105.rc3.git7.fc8;i386;installed", "", + "http://www.distro-update.org/page?moo;Bugfix release for kernel", + "http://bgzilla.fd.org/result.php?#12344;Freedesktop Bugzilla #12344;" +@@ -199,7 +200,11 @@ backend_get_update_detail_timeout (gpointer data) + "http://www.distro-update.org/page?moo;Bugfix release for gtkhtml", + "http://bgzilla.gnome.org/result.php?#9876;GNOME Bugzilla #9876", + NULL, +- PK_RESTART_ENUM_SESSION, "Update to latest whizz bang version"); ++ PK_RESTART_ENUM_SESSION, ++ "Update to latest whizz bang version\n" ++ "* support this new thing\n" ++ "* something else\n" ++ "- and that new thing"); + } else { + pk_backend_message (backend, PK_MESSAGE_ENUM_DAEMON, "Got unexpected package_id '%s'", _package_id); + } +diff --git a/backends/opkg/pk-backend-opkg.c b/backends/opkg/pk-backend-opkg.c +index 7649bab..2d70108 100644 +--- a/backends/opkg/pk-backend-opkg.c ++++ b/backends/opkg/pk-backend-opkg.c +@@ -115,6 +115,39 @@ opkg_check_tag (opkg_package_t *pkg, gchar *tag) + return FALSE; + } + ++static void ++handle_install_error (PkBackend *backend, int err) ++{ ++ switch (err) ++ { ++ case OPKG_NO_ERROR: ++ break; ++ case OPKG_PACKAGE_NOT_INSTALLED: ++ pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED, NULL); ++ break; ++ case OPKG_PACKAGE_ALREADY_INSTALLED: ++ pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_ALREADY_INSTALLED, NULL); ++ break; ++ case OPKG_GPG_ERROR: ++ pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, NULL); ++ break; ++ case OPKG_DOWNLOAD_FAILED: ++ pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_DOWNLOAD_FAILED, NULL); ++ break; ++ case OPKG_DEPENDENCIES_FAILED: ++ pk_backend_error_code (backend, PK_ERROR_ENUM_DEP_RESOLUTION_FAILED, NULL); ++ break; ++ case OPKG_MD5_ERROR: ++ pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_CORRUPT, NULL); ++ break; ++ case OPKG_PACKAGE_NOT_AVAILABLE: ++ pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, NULL); ++ break; ++ default: ++ opkg_unknown_error (backend, err, "Update package"); ++ } ++} ++ + /** + * backend_initialize: + */ +@@ -387,22 +420,9 @@ backend_install_packages_thread (PkBackend *backend) + pi = pk_package_id_new_from_string (package_ids[0]); + + err = opkg_install_package (opkg, pi->name, pk_opkg_progress_cb, backend); +- switch (err) +- { +- case OPKG_NO_ERROR: +- break; +- case OPKG_DEPENDANCIES_FAILED: +- pk_backend_error_code (backend, PK_ERROR_ENUM_DEP_RESOLUTION_FAILED, NULL); +- break; +- case OPKG_PACKAGE_ALREADY_INSTALLED: +- pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_ALREADY_INSTALLED, NULL); +- break; +- case OPKG_PACKAGE_NOT_AVAILABLE: +- pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, NULL); +- break; +- default: +- opkg_unknown_error (backend, err, "Install"); +- } ++ if (err) ++ handle_install_error (backend, err); ++ + pk_package_id_free (pi); + if (err != 0) + break; +@@ -551,16 +571,9 @@ backend_update_package_thread (PkBackend *backend) + } + + err = opkg_upgrade_package (opkg, pi->name, pk_opkg_progress_cb, backend); +- switch (err) +- { +- case OPKG_NO_ERROR: +- break; +- case OPKG_PACKAGE_NOT_INSTALLED: +- pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED, NULL); +- break; +- default: +- opkg_unknown_error (backend, err, "Update package"); +- } ++ if (err) ++ handle_install_error (backend, err); ++ + + pk_package_id_free (pi); + pk_backend_finished (backend); +diff --git a/backends/poldek/pk-backend-poldek.c b/backends/poldek/pk-backend-poldek.c +index fdc99d3..2691414 100644 +--- a/backends/poldek/pk-backend-poldek.c ++++ b/backends/poldek/pk-backend-poldek.c +@@ -53,7 +53,33 @@ enum { + SEARCH_ENUM_NAME, + SEARCH_ENUM_GROUP, + SEARCH_ENUM_DETAILS, +- SEARCH_ENUM_FILE ++ SEARCH_ENUM_FILE, ++ SEARCH_ENUM_PROVIDES ++}; ++ ++typedef struct { ++ PkGroupEnum group; ++ const gchar *regex; ++} PLDGroupRegex; ++ ++static PLDGroupRegex group_perlre[] = { ++ {PK_GROUP_ENUM_ACCESSORIES, "/.*Archiving\\|.*Dictionaries/"}, ++ {PK_GROUP_ENUM_ADMIN_TOOLS, "/.*Databases.*\\|.*Admin/"}, ++ {PK_GROUP_ENUM_COMMUNICATION, "/.*Communications/"}, ++ {PK_GROUP_ENUM_EDUCATION, "/.*Engineering\\|.*Math\\|.*Science/"}, ++ {PK_GROUP_ENUM_FONTS, "/Fonts/"}, ++ {PK_GROUP_ENUM_GAMES, "/.*Games.*/"}, ++ {PK_GROUP_ENUM_GRAPHICS, "/.*Graphics/"}, ++ {PK_GROUP_ENUM_LOCALIZATION, "/I18n/"}, ++ {PK_GROUP_ENUM_MULTIMEDIA, "/.*Multimedia\\|.*Sound/"}, ++ {PK_GROUP_ENUM_NETWORK, "/.*Networking.*\\|/.*Mail\\|.*News\\|.*WWW/"}, ++ {PK_GROUP_ENUM_OFFICE, "/.*Editors.*\\|.*Spreadsheets/"}, ++ {PK_GROUP_ENUM_OTHER, "/^Applications$\\|.*Console\\|.*Emulators\\|.*File\\|.*Printing\\|.*Terminal\\|.*Text\\|Documentation\\|^Libraries.*\\|^Themes.*\\|^X11$\\|.*Amusements\\|^X11\\/Applications$\\|^X11\\/Libraries$\\|.*Window\\ Managers.*/"}, ++ {PK_GROUP_ENUM_PROGRAMMING, "/.*Development.*/"}, ++ {PK_GROUP_ENUM_PUBLISHING, "/.*Publishing.*/"}, ++ {PK_GROUP_ENUM_SERVERS, "/Daemons\\|.*Servers/"}, ++ {PK_GROUP_ENUM_SYSTEM, "/.*Shells\\|.*System\\|Base.*/"}, ++ {0, NULL} + }; + + typedef struct { +@@ -501,6 +527,79 @@ poldek_pkg_set_installed (struct pkg *pkg, gboolean installed) { + } + + /** ++ * pld_group_to_enum: ++ * ++ * Converts PLD RPM group to PkGroupEnum. ++ **/ ++static PkGroupEnum ++pld_group_to_enum (const gchar *group) ++{ ++ g_return_val_if_fail (group != NULL, PK_GROUP_ENUM_OTHER); ++ ++ if (strstr (group, "Archiving") != NULL || ++ strstr (group, "Dictionaries") != NULL) ++ return PK_GROUP_ENUM_ACCESSORIES; ++ else if (strstr (group, "Databases") != NULL || ++ strstr (group, "Admin") != NULL) ++ return PK_GROUP_ENUM_ADMIN_TOOLS; ++ else if (strstr (group, "Communications") != NULL) ++ return PK_GROUP_ENUM_COMMUNICATION; ++ else if (strstr (group, "Engineering") != NULL || ++ strstr (group, "Math") != NULL || ++ strstr (group, "Science") != NULL) ++ return PK_GROUP_ENUM_EDUCATION; ++ else if (strcmp (group, "Fonts") == 0) ++ return PK_GROUP_ENUM_FONTS; ++ else if (strstr (group, "Games") != NULL) ++ return PK_GROUP_ENUM_GAMES; ++ else if (strstr (group, "Graphics") != NULL) ++ return PK_GROUP_ENUM_GRAPHICS; ++ else if (strcmp (group, "I18n") == 0) ++ return PK_GROUP_ENUM_LOCALIZATION; ++ else if (strstr (group, "Multimedia") != NULL || ++ strstr (group, "Sound") != NULL) ++ return PK_GROUP_ENUM_MULTIMEDIA; ++ else if (strstr (group, "Networking") != NULL || ++ strstr (group, "Mail") != NULL || ++ strstr (group, "News") != NULL || ++ strstr (group, "WWW") != NULL) ++ return PK_GROUP_ENUM_NETWORK; ++ else if (strstr (group, "Editors") != NULL || ++ strstr (group, "Spreadsheets") != NULL) ++ return PK_GROUP_ENUM_OFFICE; ++ else if (strstr (group, "Development") != NULL) ++ return PK_GROUP_ENUM_PROGRAMMING; ++ else if (strstr (group, "Publishing") != NULL) ++ return PK_GROUP_ENUM_PUBLISHING; ++ else if (strstr (group, "Daemons") != NULL || ++ strstr (group, "Servers") != NULL) ++ return PK_GROUP_ENUM_SERVERS; ++ else if (strstr (group, "Shells") != NULL || ++ strstr (group, "System") != NULL || ++ strstr (group, "Base") != NULL) ++ return PK_GROUP_ENUM_SYSTEM; ++ else ++ return PK_GROUP_ENUM_OTHER; ++} ++ ++/** ++ * pld_group_get_regex_from_enum: ++ **/ ++static const gchar* ++pld_group_get_regex_from_enum (PkGroupEnum value) ++{ ++ gint i; ++ ++ for (i = 0;; i++) { ++ if (group_perlre[i].regex == NULL) ++ return NULL; ++ ++ if (group_perlre[i].group == value) ++ return group_perlre[i].regex; ++ } ++} ++ ++/** + * poldek_pkg_evr: + */ + static gchar* +@@ -916,7 +1015,8 @@ poldek_pkg_is_gui (struct pkg *pkg) + static gboolean + search_package_thread (PkBackend *backend) + { +- PkFilterEnum filters; ++ PkFilterEnum filters; ++ PkProvidesEnum provides; + gchar *search_cmd = NULL; + struct poclidek_rcmd *cmd = NULL; + const gchar *search; +@@ -930,30 +1030,38 @@ search_package_thread (PkBackend *backend) + search = pk_backend_get_string (backend, "search"); + filters = pk_backend_get_uint (backend, "filters"); + +- switch (mode) { +- /* GetPackages */ +- case SEARCH_ENUM_NONE: +- search_cmd = g_strdup ("ls -q"); +- break; +- /* SearchName */ +- case SEARCH_ENUM_NAME: +- search_cmd = g_strdup_printf ("ls -q *%s*", search); +- break; +- /* SearchGroup */ +- case SEARCH_ENUM_GROUP: +- search_cmd = g_strdup_printf ("search -qg *%s*", search); +- break; +- /* SearchDetails */ +- case SEARCH_ENUM_DETAILS: +- search_cmd = g_strdup_printf ("search -dsq *%s*", search); +- break; +- /* SearchFile */ +- case SEARCH_ENUM_FILE: +- search_cmd = g_strdup_printf ("search -qlf *%s*", search); +- break; +- default: +- /* Error */ +- break; ++ /* GetPackages*/ ++ if (mode == SEARCH_ENUM_NONE) { ++ search_cmd = g_strdup ("ls -q"); ++ /* SearchName */ ++ } else if (mode == SEARCH_ENUM_NAME) { ++ search_cmd = g_strdup_printf ("ls -q *%s*", search); ++ /* SearchGroup */ ++ } else if (mode == SEARCH_ENUM_GROUP) { ++ PkGroupEnum group; ++ const gchar *regex; ++ ++ group = pk_group_enum_from_text (search); ++ regex = pld_group_get_regex_from_enum (group); ++ ++ search_cmd = g_strdup_printf ("search -qg --perlre %s", regex); ++ /* SearchDetails */ ++ } else if (mode == SEARCH_ENUM_DETAILS) { ++ search_cmd = g_strdup_printf ("search -dsq *%s*", search); ++ /* SearchFile */ ++ } else if (mode == SEARCH_ENUM_FILE) { ++ search_cmd = g_strdup_printf ("search -qlf *%s*", search); ++ /* WhatProvides */ ++ } else if (mode == SEARCH_ENUM_PROVIDES) { ++ provides = pk_backend_get_uint (backend, "provides"); ++ ++ if (provides == PK_PROVIDES_ENUM_ANY) { ++ search_cmd = g_strdup_printf ("search -qp %s", search); ++ } else if (provides == PK_PROVIDES_ENUM_MODALIAS) { ++ } else if (provides == PK_PROVIDES_ENUM_CODEC) { ++ } else if (provides == PK_PROVIDES_ENUM_MIMETYPE) { ++ search_cmd = g_strdup_printf ("search -qp mimetype(%s)", search); ++ } + } + + if (cmd != NULL && search_cmd) +@@ -1307,6 +1415,30 @@ backend_destroy (PkBackend *backend) + } + + /** ++ * backend_get_groups: ++ **/ ++static PkGroupEnum ++backend_get_groups (PkBackend *backend) ++{ ++ return (PK_GROUP_ENUM_ACCESSORIES | ++ PK_GROUP_ENUM_ADMIN_TOOLS | ++ PK_GROUP_ENUM_COMMUNICATION | ++ PK_GROUP_ENUM_EDUCATION | ++ PK_GROUP_ENUM_FONTS | ++ PK_GROUP_ENUM_GAMES | ++ PK_GROUP_ENUM_GRAPHICS | ++ PK_GROUP_ENUM_LOCALIZATION | ++ PK_GROUP_ENUM_MULTIMEDIA | ++ PK_GROUP_ENUM_NETWORK | ++ PK_GROUP_ENUM_OFFICE | ++ PK_GROUP_ENUM_OTHER | ++ PK_GROUP_ENUM_PROGRAMMING | ++ PK_GROUP_ENUM_PUBLISHING | ++ PK_GROUP_ENUM_SERVERS | ++ PK_GROUP_ENUM_SYSTEM); ++} ++ ++/** + * backend_get_filters: + */ + static PkFilterEnum +@@ -1398,14 +1530,17 @@ backend_get_details_thread (PkBackend *backend) + if (pkg) + { + struct pkguinf *pkgu = NULL; ++ PkGroupEnum group; + + pkgu = pkg_uinf (pkg); + ++ group = pld_group_to_enum (pkg_group (pkg)); ++ + if (pkgu) { + pk_backend_details (backend, + package_id, + pkguinf_get (pkgu, PKGUINF_LICENSE), +- PK_GROUP_ENUM_OTHER, ++ group, + pkguinf_get (pkgu, PKGUINF_DESCRIPTION), + pkguinf_get (pkgu, PKGUINF_URL), + pkg->size); +@@ -1414,7 +1549,7 @@ backend_get_details_thread (PkBackend *backend) + pk_backend_details (backend, + package_id, + "", +- PK_GROUP_ENUM_OTHER, ++ group, + "", + "", + pkg->size); +@@ -2213,12 +2348,26 @@ backend_get_repo_list (PkBackend *backend, PkFilterEnum filters) + pk_backend_finished (backend); + } + ++/** ++ * backend_what_provides: ++ **/ ++static void ++backend_what_provides (PkBackend *backend, PkFilterEnum filters, PkProvidesEnum provides, const gchar *search) ++{ ++ pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY); ++ poldek_backend_set_allow_cancel (backend, TRUE, TRUE); ++ pb_error_clean (); ++ ++ pk_backend_set_uint (backend, "mode", SEARCH_ENUM_PROVIDES); ++ pk_backend_thread_create (backend, search_package_thread); ++} ++ + PK_BACKEND_OPTIONS ( + "poldek", /* description */ + "Marcin Banasiak ", /* author */ + backend_initalize, /* initalize */ + backend_destroy, /* destroy */ +- NULL, /* get_groups */ ++ backend_get_groups, /* get_groups */ + backend_get_filters, /* get_filters */ + backend_get_cancel, /* cancel */ + backend_get_depends, /* get_depends */ +@@ -2245,6 +2394,6 @@ PK_BACKEND_OPTIONS ( + NULL, /* service pack */ + backend_update_packages, /* update_packages */ + backend_update_system, /* update_system */ +- NULL /* what_provides */ ++ backend_what_provides /* what_provides */ + ); + +diff --git a/backends/urpmi/.gitignore b/backends/urpmi/.gitignore +new file mode 100644 +index 0000000..996fb0d +--- /dev/null ++++ b/backends/urpmi/.gitignore +@@ -0,0 +1,14 @@ ++.deps ++.libs ++Makefile ++Makefile.in ++*.la ++*.lo ++*.loT ++*.o ++*~ ++*.gcov ++*.gcda ++*.gcno ++*.out ++ +diff --git a/backends/urpmi/Makefile.am b/backends/urpmi/Makefile.am +new file mode 100644 +index 0000000..56743a1 +--- /dev/null ++++ b/backends/urpmi/Makefile.am +@@ -0,0 +1,11 @@ ++SUBDIRS = helpers ++plugindir = $(PK_PLUGIN_DIR) ++plugin_LTLIBRARIES = libpk_backend_urpmi.la ++libpk_backend_urpmi_la_SOURCES = pk-backend-urpmi.c ++libpk_backend_urpmi_la_LIBADD = $(PK_PLUGIN_LIBS) ++libpk_backend_urpmi_la_LDFLAGS = -module -avoid-version ++libpk_backend_urpmi_la_CFLAGS = $(PK_PLUGIN_CFLAGS) ++ ++clean-local: ++ rm -f *.gcno ++ +diff --git a/backends/urpmi/helpers/.gitignore b/backends/urpmi/helpers/.gitignore +new file mode 100644 +index 0000000..2f78cf5 +--- /dev/null ++++ b/backends/urpmi/helpers/.gitignore +@@ -0,0 +1,2 @@ ++*.pyc ++ +diff --git a/backends/urpmi/helpers/Makefile.am b/backends/urpmi/helpers/Makefile.am +new file mode 100644 +index 0000000..88f144e +--- /dev/null ++++ b/backends/urpmi/helpers/Makefile.am +@@ -0,0 +1,31 @@ ++SUBDIRS = perl_packagekit urpmi_backend ++ ++helperdir = $(datadir)/PackageKit/helpers/urpmi ++ ++NULL = ++ ++dist_helper_DATA = \ ++ search-name.pl \ ++ get-details.pl \ ++ get-depends.pl \ ++ get-files.pl \ ++ get-updates.pl \ ++ get-update-detail.pl \ ++ refresh-cache.pl \ ++ install-packages.pl \ ++ remove-packages.pl \ ++ search-group.pl \ ++ get-packages.pl \ ++ get-requires.pl \ ++ search-details.pl \ ++ search-file.pl \ ++ resolve.pl \ ++ update-packages.pl \ ++ $(NULL) ++ ++install-data-hook: ++ chmod a+rx $(DESTDIR)$(helperdir)/*.pl ++ ++clean-local : ++ rm -f *~ ++ +diff --git a/backends/urpmi/helpers/get-depends.pl b/backends/urpmi/helpers/get-depends.pl +new file mode 100755 +index 0000000..bf936c5 +--- /dev/null ++++ b/backends/urpmi/helpers/get-depends.pl +@@ -0,0 +1,85 @@ ++#!/usr/bin/perl ++ ++use strict; ++ ++use lib; ++use File::Basename; ++ ++BEGIN { ++ push @INC, dirname($0); ++} ++ ++use URPM; ++use urpm; ++use urpm::args; ++use urpm::media; ++use urpm::select; ++ ++use urpmi_backend::open_db; ++use urpmi_backend::tools; ++ ++use perl_packagekit::enums; ++use perl_packagekit::prints; ++ ++# Two arguments (filter, package id) ++exit if($#ARGV != 2); ++ ++my @filters = split(/;/, $ARGV[0]); ++my @pkgid = split(/;/, $ARGV[1]); ++my $recursive_option = 0; ++$recursive_option = 1 if($ARGV[2] eq "yes"); ++ ++# Only recursive option is supported ++# So, if user set no tu recursive option, ++# backend will return error ++if(!$recursive_option) { ++ printf("error\tnot-supported\tOnly recursive option to yes is supported\n"); ++ exit; ++} ++ ++pk_print_status(PK_STATUS_ENUM_DEP_RESOLVE); ++ ++my $urpm = urpm->new_parse_cmdline; ++urpm::media::configure($urpm); ++ ++my %requested; ++my @names = (@pkgid[0]); ++my $results = urpm::select::search_packages($urpm, \%requested, \@names, ++ fuzzy => 0, ++ caseinsensitive => 0, ++ all => 0 ++); ++ ++exit if !$results; ++my @requested_keys = keys %requested; ++my $package_id = pop @requested_keys; ++ ++my %resolv_request = (); ++%resolv_request->{$package_id} = 1; ++ ++my $empty_db = new URPM; ++my $state = {}; ++$urpm->resolve_requested($empty_db, ++ $state, ++ \%resolv_request, ++); ++ ++my $db = open_rpm_db(); ++$urpm->compute_installed_flags($db); ++ ++my %selected = %{$state->{selected}}; ++my @selected_keys = keys %selected; ++my @depslist = @{$urpm->{depslist}}; ++ ++foreach(sort {@depslist[$b]->flag_installed <=> @depslist[$a]->flag_installed} @selected_keys) { ++ my $pkg = @depslist[$_]; ++ if($pkg->flag_installed) { ++ next if(grep(/^${\FILTER_NOT_INSTALLED}$/, @filters)); ++ pk_print_package(INFO_INSTALLED, get_package_id($pkg), $pkg->summary); ++ } ++ else { ++ next if(grep(/^${\FILTER_INSTALLED}$/, @filters)); ++ pk_print_package(INFO_AVAILABLE, get_package_id($pkg), $pkg->summary); ++ } ++} ++ +diff --git a/backends/urpmi/helpers/get-details.pl b/backends/urpmi/helpers/get-details.pl +new file mode 100755 +index 0000000..3207e9b +--- /dev/null ++++ b/backends/urpmi/helpers/get-details.pl +@@ -0,0 +1,48 @@ ++#!/usr/bin/perl ++ ++use strict; ++ ++use lib; ++use File::Basename; ++ ++BEGIN { ++ push @INC, dirname($0); ++} ++ ++use urpm; ++use urpm::args; ++use urpm::media; ++use urpmi_backend::tools; ++use MDK::Common; ++ ++use perl_packagekit::prints; ++ ++# One argument (package id) ++exit if($#ARGV != 0); ++ ++my $urpm = urpm->new_parse_cmdline; ++urpm::media::configure($urpm); ++ ++my $pkg = get_package_by_package_id($urpm, $ARGV[0]); ++ ++my $medium = pkg2medium($pkg, $urpm); ++my $xml_info = 'info'; ++my $xml_info_file = urpm::media::any_xml_info($urpm, $medium, $xml_info, undef, undef); ++ ++if(!$xml_info_file) { ++ pk_print_details(get_package_id($pkg), "N/A", $pkg->group, "N/A", "N/A", 0); ++ exit 0; ++} ++ ++require urpm::xml_info; ++require urpm::xml_info_pkg; ++my $name = urpm_name($pkg); ++my %nodes = eval { urpm::xml_info::get_nodes($xml_info, $xml_info_file, [ $name ]) }; ++my %xml_info_pkgs; ++put_in_hash($xml_info_pkgs{$name} ||= {}, $nodes{$name}); ++my $description = $xml_info_pkgs{$name}{description}; ++$description =~ s/\n/;/g; ++$description =~ s/\t/ /g; ++ ++pk_print_details(get_package_id($pkg), "N/A", $pkg->group, ensure_utf8($description), "N/A", $pkg->size); ++ +diff --git a/backends/urpmi/helpers/get-files.pl b/backends/urpmi/helpers/get-files.pl +new file mode 100755 +index 0000000..74ae157 +--- /dev/null ++++ b/backends/urpmi/helpers/get-files.pl +@@ -0,0 +1,40 @@ ++#!/usr/bin/perl ++ ++use strict; ++ ++use lib; ++use File::Basename; ++ ++BEGIN { ++ push @INC, dirname($0); ++} ++ ++use urpm; ++use urpm::args; ++use urpm::media; ++use urpmi_backend::tools; ++use MDK::Common; ++ ++use perl_packagekit::prints; ++ ++# One argument (package id) ++exit if($#ARGV != 0); ++ ++ ++my $urpm = urpm->new_parse_cmdline; ++urpm::media::configure($urpm); ++ ++my $pkg = get_package_by_package_id($urpm, $ARGV[0]); ++ ++my $medium = pkg2medium($pkg, $urpm); ++my $xml_info = 'files'; ++my $xml_info_file = urpm::media::any_xml_info($urpm, $medium, $xml_info, undef, undef); ++require urpm::xml_info; ++require urpm::xml_info_pkg; ++my $name = urpm_name($pkg); ++my %nodes = eval { urpm::xml_info::get_nodes($xml_info, $xml_info_file, [ $name ]) }; ++my %xml_info_pkgs; ++put_in_hash($xml_info_pkgs{$name} ||= {}, $nodes{$name}); ++my @files = map { chomp_($_) } split("\n", $xml_info_pkgs{$name}{files}); ++ ++pk_print_files(get_package_id($pkg), join(';', @files)); +diff --git a/backends/urpmi/helpers/get-packages.pl b/backends/urpmi/helpers/get-packages.pl +new file mode 100755 +index 0000000..9e3e525 +--- /dev/null ++++ b/backends/urpmi/helpers/get-packages.pl +@@ -0,0 +1,53 @@ ++#!/usr/bin/perl ++ ++use strict; ++ ++use lib; ++use File::Basename; ++ ++BEGIN { ++ push @INC, dirname($0); ++} ++ ++use urpm; ++use urpm::media; ++use urpm::args; ++ ++use urpmi_backend::open_db; ++use urpmi_backend::tools; ++use urpmi_backend::filters; ++ ++use perl_packagekit::enums; ++use perl_packagekit::prints; ++ ++# One argument (the filter) ++exit if ($#ARGV != 0); ++my @filters = split(/;/, $ARGV[0]); ++ ++my $urpm = urpm->new_parse_cmdline; ++ ++urpm::media::configure($urpm); ++ ++my $db = open_rpm_db(); ++$urpm->compute_installed_flags($db); ++ ++# Here we display installed packages ++if(not grep(/^${\FILTER_NOT_INSTALLED}$/, @filters)) { ++ $db->traverse(sub { ++ my ($pkg) = @_; ++ if(filter($pkg, \@filters, {FILTER_DEVELOPMENT => 1, FILTER_GUI => 1})) { ++ pk_print_package(INFO_INSTALLED, get_package_id($pkg), ensure_utf8($pkg->summary)); ++ } ++ }); ++} ++ ++# Here are package which can be installed ++if(not grep(/^${\FILTER_INSTALLED}$/, @filters)) { ++ foreach my $pkg(@{$urpm->{depslist}}) { ++ if($pkg->flag_upgrade) { ++ if(filter($pkg, \@filters, {FILTER_DEVELOPMENT => 1, FILTER_GUI => 1})) { ++ pk_print_package(INFO_AVAILABLE, get_package_id($pkg), ensure_utf8($pkg->summary)); ++ } ++ } ++ } ++} +diff --git a/backends/urpmi/helpers/get-requires.pl b/backends/urpmi/helpers/get-requires.pl +new file mode 100755 +index 0000000..0012b2a +--- /dev/null ++++ b/backends/urpmi/helpers/get-requires.pl +@@ -0,0 +1,54 @@ ++#!/usr/bin/perl ++ ++use strict; ++ ++use lib; ++use File::Basename; ++ ++BEGIN { ++ push @INC, dirname($0); ++} ++ ++use urpm; ++use urpm::args; ++use urpm::media; ++use urpm::select; ++use urpmi_backend::tools; ++use urpmi_backend::actions; ++use urpmi_backend::filters; ++use perl_packagekit::enums; ++use perl_packagekit::prints; ++ ++# 3 arguments ++# (filter, packageid, and recursive option) ++exit if($#ARGV != 2); ++ ++my @filters = split(/;/, $ARGV[0]); ++my $pkgid = $ARGV[1]; ++my $recursive_option = 0; ++$recursive_option = 1 if($ARGV[2] eq "yes"); ++ ++my $urpm = urpm->new_parse_cmdline; ++urpm::media::configure($urpm); ++ ++my $pkg = get_package_by_package_id($urpm, $pkgid); ++if(!$pkg) { ++ pk_print_error(PK_ERROR_ENUM_PACKAGE_NOT_FOUND, "Requested package wasn't found"); ++ exit; ++} ++# print "Checking requires of the package : ", urpm_name($pkg), "\n"; ++pk_print_status(PK_STATUS_ENUM_DEP_RESOLVE); ++my @requires = perform_requires_search($urpm, $pkg, $recursive_option); ++ ++foreach(@requires) { ++ if(filter($_, \@filters, { FILTER_GUI => 1, FILTER_DEVELOPMENT => 1 })) { ++ if(package_version_is_installed($_)) { ++ !grep(/^${\FILTER_NOT_INSTALLED}$/, @filters) and pk_print_package(INFO_INSTALLED, get_package_id($_), $_->summary); ++ } ++ else { ++ !grep(/^${\FILTER_INSTALLED}$/, @filters) and pk_print_package(INFO_AVAILABLE, get_package_id($_), $_->summary); ++ } ++ } ++} ++pk_print_status(PK_STATUS_ENUM_FINISHED); ++ +diff --git a/backends/urpmi/helpers/get-update-detail.pl b/backends/urpmi/helpers/get-update-detail.pl +new file mode 100755 +index 0000000..69ea452 +--- /dev/null ++++ b/backends/urpmi/helpers/get-update-detail.pl +@@ -0,0 +1,88 @@ ++#!/usr/bin/perl ++ ++use strict; ++ ++use lib; ++use File::Basename; ++ ++BEGIN { ++ push @INC, dirname($0); ++} ++ ++use urpm; ++use urpm::args; ++use urpm::media; ++use urpm::select; ++use urpmi_backend::tools; ++use urpmi_backend::open_db; ++use perl_packagekit::enums; ++use perl_packagekit::prints; ++use MDK::Common; ++ ++# One argument (package id) ++exit if($#ARGV != 0); ++ ++my $urpm = urpm->new_parse_cmdline; ++urpm::media::configure($urpm); ++ ++my $pkg = get_package_by_package_id($urpm, @ARGV[0]); ++ ++if(!$pkg) { ++ pk_print_error(PK_ERROR_ENUM_PACKAGE_NOT_FOUND, "Requested package was not found"); ++ exit; ++} ++ ++my %requested; ++$requested{$pkg->id} = 1; ++ ++if(!find_installed_version($pkg)) { ++ pk_print_error(PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED, "The selected package isn't installed on your system"); ++} ++elsif(package_version_is_installed($pkg)) { ++ pk_print_error(PK_ERROR_ENUM_PACKAGE_ALREADY_INSTALLED, "The selected package is already at the latest version"); ++} ++else { ++ my $state = {}; ++ my $restart = urpm::select::resolve_dependencies($urpm, $state, \%requested); ++ my %selected = %{$state->{selected}}; ++ my @ask_unselect = urpm::select::unselected_packages($urpm, $state); ++ my @to_remove = urpm::select::removed_packages($urpm, $state); ++ my @to_install = @{$urpm->{depslist}}[sort { $a <=> $b } keys %{$state->{selected}}]; ++ my ($src, $binary) = partition { $_->arch eq 'src' } @to_install; ++ @to_install = @$binary; ++ my $updates_descr = urpm::get_updates_description($urpm); ++ my $updesc = $updates_descr->{URPM::pkg2media($urpm->{media}, $pkg)->{name}}{$pkg->name}; ++ my $desc; ++ if($updesc) { ++ $desc = $updesc->{pre}; ++ $desc =~ s/\n/;/g; ++ } ++ ++ my @to_upgrade_pkids; ++ foreach(@to_install) { ++ my $pkid = get_installed_version_pkid($_); ++ push @to_upgrade_pkids, $pkid if $pkid; ++ } ++ ++ if($restart) { ++ pk_print_update_detail(get_package_id($pkg), ++ join("^", @to_upgrade_pkids), ++ join("^", map(fullname_to_package_id($_), @to_remove)), ++ "http://qa.mandriva.com", ++ "http://qa.mandriva.com", ++ "http://qa.mandriva.com", ++ PK_RESTART_ENUM_SYSTEM, ++ $desc); ++ } ++ else { ++ pk_print_update_detail(get_package_id($pkg), ++ join("^", @to_upgrade_pkids), ++ join("^", map(fullname_to_package_id($_), @to_remove)), ++ "http://qa.mandriva.com", ++ "http://qa.mandriva.com", ++ "http://qa.mandriva.com", ++ PK_RESTART_ENUM_APPLICATION, ++ $desc); ++ } ++ ++} +diff --git a/backends/urpmi/helpers/get-updates.pl b/backends/urpmi/helpers/get-updates.pl +new file mode 100755 +index 0000000..02d574c +--- /dev/null ++++ b/backends/urpmi/helpers/get-updates.pl +@@ -0,0 +1,46 @@ ++#!/usr/bin/perl ++ ++use strict; ++ ++use lib; ++use File::Basename; ++ ++BEGIN { ++ push @INC, dirname($0); ++} ++ ++use urpm; ++use urpm::args; ++use urpm::media; ++use urpm::select; ++use MDK::Common; ++use urpmi_backend::tools; ++use perl_packagekit::enums; ++use perl_packagekit::prints; ++ ++# On argument (filter) ++exit if($#ARGV != 0); ++# Fix me ++# Filter are to be implemented. ++ ++my $urpm = urpm->new_parse_cmdline; ++urpm::media::configure($urpm); ++ ++my $state = {}; ++my %requested; ++my $restart = urpm::select::resolve_dependencies($urpm, $state, \%requested, ++ auto_select => 1); ++ ++my %selected = %{$state->{selected} || {}}; ++my @ask_unselect = urpm::select::unselected_packages($urpm, $state); ++my @to_remove = urpm::select::removed_packages($urpm, $state); ++my @to_install = @{$urpm->{depslist}}[sort { $a <=> $b } keys %{$state->{selected}}]; ++my ($src, $binary) = partition { $_->arch eq 'src' } @to_install; ++@to_install = @$binary; ++ ++foreach(@to_install) { ++ # Fix me ++ # Be default, we set to bugfix info type ++ # Need to be implemented, see urpmq source. ++ pk_print_package(INFO_BUGFIX, get_package_id($_), $_->summary); ++} +diff --git a/backends/urpmi/helpers/install-packages.pl b/backends/urpmi/helpers/install-packages.pl +new file mode 100755 +index 0000000..c9cf6c8 +--- /dev/null ++++ b/backends/urpmi/helpers/install-packages.pl +@@ -0,0 +1,40 @@ ++#!/usr/bin/perl ++ ++use strict; ++ ++use lib; ++use File::Basename; ++ ++BEGIN { ++ push @INC, dirname($0); ++} ++ ++use urpm; ++use urpm::media; ++use urpm::select; ++ ++use urpmi_backend::actions; ++use urpmi_backend::tools; ++ ++# One argument (package id) ++exit if($#ARGV != 0); ++ ++my @pkg_ids = split(/\|/, pop @ARGV); ++my @names; ++foreach(@pkg_ids) { ++ my @pkg_id = (split(/;/, $_)); ++ push @names, $pkg_id[0]; ++} ++ ++ ++my $urpm = urpm->new_parse_cmdline; ++urpm::media::configure($urpm); ++ ++my %requested; ++ ++urpm::select::search_packages($urpm, \%requested, \@names, ++ fuzzy => 0, ++ caseinsensitive => 0, ++ all => 0); ++ ++perform_installation($urpm, \%requested); +diff --git a/backends/urpmi/helpers/perl_packagekit/Makefile.am b/backends/urpmi/helpers/perl_packagekit/Makefile.am +new file mode 100644 +index 0000000..6ed63b5 +--- /dev/null ++++ b/backends/urpmi/helpers/perl_packagekit/Makefile.am +@@ -0,0 +1,12 @@ ++helperdir = $(datadir)/PackageKit/helpers/urpmi/perl_packagekit/ ++ ++NULL = ++ ++dist_helper_DATA = \ ++ enums.pm \ ++ prints.pm \ ++ $(NULL) ++ ++clean-local : ++ rm -f *~ ++ +diff --git a/backends/urpmi/helpers/perl_packagekit/enums.pm b/backends/urpmi/helpers/perl_packagekit/enums.pm +new file mode 100644 +index 0000000..8dbb4b0 +--- /dev/null ++++ b/backends/urpmi/helpers/perl_packagekit/enums.pm +@@ -0,0 +1,293 @@ ++package perl_packagekit::enums; ++ ++use Exporter; ++ ++our @ISA = qw(Exporter); ++our @EXPORT = qw( ++ FILTER_BASENAME ++ FILTER_DEVELOPMENT ++ FILTER_FREE ++ FILTER_GUI ++ FILTER_INSTALLED ++ FILTER_NEWEST ++ FILTER_NONE ++ FILTER_NOT_BASENAME ++ FILTER_NOT_DEVELOPMENT ++ FILTER_NOT_FREE ++ FILTER_NOT_GUI ++ FILTER_NOT_INSTALLED ++ FILTER_NOT_NEWEST ++ FILTER_NOT_SUPPORTED ++ FILTER_NOT_VISIBLE ++ FILTER_SUPPORTED ++ FILTER_UNKNOWN ++ FILTER_VISIBLE ++ ++ GROUP_ACCESSIBILITY ++ GROUP_ACCESSORIES ++ GROUP_ADMIN_TOOLS ++ GROUP_COMMUNICATION ++ GROUP_DESKTOP_GNOME ++ GROUP_DESKTOP_KDE ++ GROUP_DESKTOP_OTHER ++ GROUP_DESKTOP_XFCE ++ GROUP_EDUCATION ++ GROUP_FONTS ++ GROUP_GAMES ++ GROUP_GRAPHICS ++ GROUP_INTERNET ++ GROUP_LEGACY ++ GROUP_LOCALIZATION ++ GROUP_MAPS ++ GROUP_MULTIMEDIA ++ GROUP_NETWORK ++ GROUP_OFFICE ++ GROUP_OTHER ++ GROUP_POWER_MANAGEMENT ++ GROUP_PROGRAMMING ++ GROUP_PUBLISHING ++ GROUP_REPOS ++ GROUP_SECURITY ++ GROUP_SERVERS ++ GROUP_SYSTEM ++ GROUP_UNKNOWN ++ GROUP_VIRTUALIZATION ++ ++ INFO_AVAILABLE ++ INFO_BLOCKED ++ INFO_BUGFIX ++ INFO_CLEANUP ++ INFO_DOWNLOADING ++ INFO_ENHANCEMENT ++ INFO_IMPORTANT ++ INFO_INSTALLED ++ INFO_INSTALLING ++ INFO_LOW ++ INFO_NORMAL ++ INFO_OBSOLETING ++ INFO_REMOVING ++ INFO_SECURITY ++ INFO_UNKNOWN ++ INFO_UPDATING ++ ++ PK_ERROR_ENUM_UNKNOWN ++ PK_ERROR_ENUM_OOM ++ PK_ERROR_ENUM_NO_CACHE ++ PK_ERROR_ENUM_NO_NETWORK ++ PK_ERROR_ENUM_NOT_SUPPORTED ++ PK_ERROR_ENUM_INTERNAL_ERROR ++ PK_ERROR_ENUM_GPG_FAILURE ++ PK_ERROR_ENUM_FILTER_INVALID ++ PK_ERROR_ENUM_PACKAGE_ID_INVALID ++ PK_ERROR_ENUM_TRANSACTION_ERROR ++ PK_ERROR_ENUM_TRANSACTION_CANCELLED ++ PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED ++ PK_ERROR_ENUM_PACKAGE_NOT_FOUND ++ PK_ERROR_ENUM_PACKAGE_ALREADY_INSTALLED ++ PK_ERROR_ENUM_PACKAGE_DOWNLOAD_FAILED ++ PK_ERROR_ENUM_GROUP_NOT_FOUND ++ PK_ERROR_ENUM_GROUP_LIST_INVALID ++ PK_ERROR_ENUM_DEP_RESOLUTION_FAILED ++ PK_ERROR_ENUM_CREATE_THREAD_FAILED ++ PK_ERROR_ENUM_REPO_NOT_FOUND ++ PK_ERROR_ENUM_CANNOT_REMOVE_SYSTEM_PACKAGE ++ PK_ERROR_ENUM_PROCESS_KILL ++ PK_ERROR_ENUM_FAILED_INITIALIZATION ++ PK_ERROR_ENUM_FAILED_FINALISE ++ PK_ERROR_ENUM_FAILED_CONFIG_PARSING ++ PK_ERROR_ENUM_CANNOT_CANCEL ++ PK_ERROR_ENUM_CANNOT_GET_LOCK ++ PK_ERROR_ENUM_NO_PACKAGES_TO_UPDATE ++ PK_ERROR_ENUM_CANNOT_WRITE_REPO_CONFIG ++ PK_ERROR_ENUM_LOCAL_INSTALL_FAILED ++ PK_ERROR_ENUM_BAD_GPG_SIGNATURE ++ PK_ERROR_ENUM_MISSING_GPG_SIGNATURE ++ PK_ERROR_ENUM_CANNOT_INSTALL_SOURCE_PACKAGE ++ PK_ERROR_ENUM_REPO_CONFIGURATION_ERROR ++ PK_ERROR_ENUM_NO_LICENSE_AGREEMENT ++ PK_ERROR_ENUM_FILE_CONFLICTS ++ PK_ERROR_ENUM_REPO_NOT_AVAILABLE ++ PK_ERROR_ENUM_INVALID_PACKAGE_FILE ++ PK_ERROR_ENUM_PACKAGE_INSTALL_BLOCKED ++ ++ PK_RESTART_ENUM_UNKNOWN ++ PK_RESTART_ENUM_NONE ++ PK_RESTART_ENUM_SYSTEM ++ PK_RESTART_ENUM_SESSION ++ PK_RESTART_ENUM_APPLICATION ++ ++ PK_STATUS_ENUM_UNKNOWN ++ PK_STATUS_ENUM_WAIT ++ PK_STATUS_ENUM_SETUP ++ PK_STATUS_ENUM_RUNNING ++ PK_STATUS_ENUM_QUERY ++ PK_STATUS_ENUM_INFO ++ PK_STATUS_ENUM_REFRESH_CACHE ++ PK_STATUS_ENUM_REMOVE ++ PK_STATUS_ENUM_DOWNLOAD ++ PK_STATUS_ENUM_INSTALL ++ PK_STATUS_ENUM_UPDATE ++ PK_STATUS_ENUM_CLEANUP ++ PK_STATUS_ENUM_OBSOLETE ++ PK_STATUS_ENUM_DEP_RESOLVE ++ PK_STATUS_ENUM_SIG_CHECK ++ PK_STATUS_ENUM_ROLLBACK ++ PK_STATUS_ENUM_TEST_COMMIT ++ PK_STATUS_ENUM_COMMIT ++ PK_STATUS_ENUM_REQUEST ++ PK_STATUS_ENUM_FINISHED ++ PK_STATUS_ENUM_CANCEL ++ PK_STATUS_ENUM_DOWNLOAD_REPOSITORY ++ PK_STATUS_ENUM_DOWNLOAD_PACKAGELIST ++ PK_STATUS_ENUM_DOWNLOAD_FILELIST ++ PK_STATUS_ENUM_DOWNLOAD_CHANGELOG ++ PK_STATUS_ENUM_DOWNLOAD_GROUP ++ PK_STATUS_ENUM_DOWNLOAD_UPDATEINFO ++ ++ ); ++ ++use constant { ++ FILTER_BASENAME => "basename", ++ FILTER_DEVELOPMENT => "devel", ++ FILTER_FREE => "free", ++ FILTER_GUI => "gui", ++ FILTER_INSTALLED => "installed", ++ FILTER_NEWEST => "newest", ++ FILTER_NONE => "none", ++ FILTER_NOT_BASENAME => "~basename", ++ FILTER_NOT_DEVELOPMENT => "~devel", ++ FILTER_NOT_FREE => "~free", ++ FILTER_NOT_GUI => "~gui", ++ FILTER_NOT_INSTALLED => "~installed", ++ FILTER_NOT_NEWEST => "~newest", ++ FILTER_NOT_SUPPORTED => "~supported", ++ FILTER_NOT_VISIBLE => "~visible", ++ FILTER_SUPPORTED => "supported", ++ FILTER_UNKNOWN => "unknown", ++ FILTER_VISIBLE => "visible", ++ ++ GROUP_ACCESSIBILITY => "accessibility", ++ GROUP_ACCESSORIES => "accessories", ++ GROUP_ADMIN_TOOLS => "admin-tools", ++ GROUP_COMMUNICATION => "communication", ++ GROUP_DESKTOP_GNOME => "desktop-gnome", ++ GROUP_DESKTOP_KDE => "desktop-kde", ++ GROUP_DESKTOP_OTHER => "desktop-other", ++ GROUP_DESKTOP_XFCE => "desktop-xfce", ++ GROUP_EDUCATION => "education", ++ GROUP_FONTS => "fonts", ++ GROUP_GAMES => "games", ++ GROUP_GRAPHICS => "graphics", ++ GROUP_INTERNET => "internet", ++ GROUP_LEGACY => "legacy", ++ GROUP_LOCALIZATION => "localization", ++ GROUP_MAPS => "maps", ++ GROUP_MULTIMEDIA => "multimedia", ++ GROUP_NETWORK => "network", ++ GROUP_OFFICE => "office", ++ GROUP_OTHER => "other", ++ GROUP_POWER_MANAGEMENT => "power-management", ++ GROUP_PROGRAMMING => "programming", ++ GROUP_PUBLISHING => "publishing", ++ GROUP_REPOS => "repos", ++ GROUP_SECURITY => "security", ++ GROUP_SERVERS => "servers", ++ GROUP_SYSTEM => "system", ++ GROUP_UNKNOWN => "unknown", ++ GROUP_VIRTUALIZATION => "virtualization", ++ ++ INFO_AVAILABLE => "available", ++ INFO_BLOCKED => "blocked", ++ INFO_BUGFIX => "bugfix", ++ INFO_CLEANUP => "cleanup", ++ INFO_DOWNLOADING => "downloading", ++ INFO_ENHANCEMENT => "enhancement", ++ INFO_IMPORTANT => "important", ++ INFO_INSTALLED => "installed", ++ INFO_INSTALLING => "installing", ++ INFO_LOW => "low", ++ INFO_NORMAL => "normal", ++ INFO_OBSOLETING => "obsoleting", ++ INFO_REMOVING => "removing", ++ INFO_SECURITY => "security", ++ INFO_UNKNOWN => "unknown", ++ INFO_UPDATING => "updating", ++ ++ PK_ERROR_ENUM_UNKNOWN => "unknown", ++ PK_ERROR_ENUM_OOM => "out-of-memory", ++ PK_ERROR_ENUM_NO_CACHE => "no-cache", ++ PK_ERROR_ENUM_NO_NETWORK => "no-network", ++ PK_ERROR_ENUM_NOT_SUPPORTED => "not-supported", ++ PK_ERROR_ENUM_INTERNAL_ERROR => "internal-error", ++ PK_ERROR_ENUM_GPG_FAILURE => "gpg-failure", ++ PK_ERROR_ENUM_FILTER_INVALID => "filter-invalid", ++ PK_ERROR_ENUM_PACKAGE_ID_INVALID => "package-id-invalid", ++ PK_ERROR_ENUM_TRANSACTION_ERROR => "transaction-error", ++ PK_ERROR_ENUM_TRANSACTION_CANCELLED => "transaction-cancelled", ++ PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED => "package-not-installed", ++ PK_ERROR_ENUM_PACKAGE_NOT_FOUND => "package-not-found", ++ PK_ERROR_ENUM_PACKAGE_ALREADY_INSTALLED => "package-already-installed", ++ PK_ERROR_ENUM_PACKAGE_DOWNLOAD_FAILED => "package-download-failed", ++ PK_ERROR_ENUM_GROUP_NOT_FOUND => "group-not-found", ++ PK_ERROR_ENUM_GROUP_LIST_INVALID => "group-list-invalid", ++ PK_ERROR_ENUM_DEP_RESOLUTION_FAILED => "dep-resolution-failed", ++ PK_ERROR_ENUM_CREATE_THREAD_FAILED => "create-thread-failed", ++ PK_ERROR_ENUM_REPO_NOT_FOUND => "repo-not-found", ++ PK_ERROR_ENUM_CANNOT_REMOVE_SYSTEM_PACKAGE => "cannot-remove-system-package", ++ PK_ERROR_ENUM_PROCESS_KILL => "process-kill", ++ PK_ERROR_ENUM_FAILED_INITIALIZATION => "failed-initialization", ++ PK_ERROR_ENUM_FAILED_FINALISE => "failed-finalise", ++ PK_ERROR_ENUM_FAILED_CONFIG_PARSING => "failed-config-parsing", ++ PK_ERROR_ENUM_CANNOT_CANCEL => "cannot-cancel", ++ PK_ERROR_ENUM_CANNOT_GET_LOCK => "cannot-get-lock", ++ PK_ERROR_ENUM_NO_PACKAGES_TO_UPDATE => "no-packages-to-update", ++ PK_ERROR_ENUM_CANNOT_WRITE_REPO_CONFIG => "cannot-write-repo-config", ++ PK_ERROR_ENUM_LOCAL_INSTALL_FAILED => "local-install-failed", ++ PK_ERROR_ENUM_BAD_GPG_SIGNATURE => "bad-gpg-signature", ++ PK_ERROR_ENUM_MISSING_GPG_SIGNATURE => "missing-gpg-signature", ++ PK_ERROR_ENUM_CANNOT_INSTALL_SOURCE_PACKAGE => "cannot-install-source-package", ++ PK_ERROR_ENUM_REPO_CONFIGURATION_ERROR => "repo-configuration-error", ++ PK_ERROR_ENUM_NO_LICENSE_AGREEMENT => "no-license-agreement", ++ PK_ERROR_ENUM_FILE_CONFLICTS => "file-conflicts", ++ PK_ERROR_ENUM_REPO_NOT_AVAILABLE => "repo-not-available", ++ PK_ERROR_ENUM_INVALID_PACKAGE_FILE => "invalid-package-file", ++ PK_ERROR_ENUM_PACKAGE_INSTALL_BLOCKED => "package-install-blocked", ++ ++ PK_RESTART_ENUM_UNKNOWN => "unknown", ++ PK_RESTART_ENUM_NONE => "none", ++ PK_RESTART_ENUM_SYSTEM => "system", ++ PK_RESTART_ENUM_SESSION => "session", ++ PK_RESTART_ENUM_APPLICATION => "application", ++ ++ PK_STATUS_ENUM_UNKNOWN => "unknown", ++ PK_STATUS_ENUM_WAIT => "wait", ++ PK_STATUS_ENUM_SETUP => "setup", ++ PK_STATUS_ENUM_RUNNING => "running", ++ PK_STATUS_ENUM_QUERY => "query", ++ PK_STATUS_ENUM_INFO => "info", ++ PK_STATUS_ENUM_REFRESH_CACHE => "refresh-cache", ++ PK_STATUS_ENUM_REMOVE => "remove", ++ PK_STATUS_ENUM_DOWNLOAD => "download", ++ PK_STATUS_ENUM_INSTALL => "install", ++ PK_STATUS_ENUM_UPDATE => "update", ++ PK_STATUS_ENUM_CLEANUP => "cleanup", ++ PK_STATUS_ENUM_OBSOLETE => "obsolete", ++ PK_STATUS_ENUM_DEP_RESOLVE => "dep-resolve", ++ PK_STATUS_ENUM_SIG_CHECK => "sig-check", ++ PK_STATUS_ENUM_ROLLBACK => "rollback", ++ PK_STATUS_ENUM_TEST_COMMIT => "test-commit", ++ PK_STATUS_ENUM_COMMIT => "commit", ++ PK_STATUS_ENUM_REQUEST => "request", ++ PK_STATUS_ENUM_FINISHED => "finished", ++ PK_STATUS_ENUM_CANCEL => "cancel", ++ PK_STATUS_ENUM_DOWNLOAD_REPOSITORY => "download-repository", ++ PK_STATUS_ENUM_DOWNLOAD_PACKAGELIST => "download-package", ++ PK_STATUS_ENUM_DOWNLOAD_FILELIST => "download-filelist", ++ PK_STATUS_ENUM_DOWNLOAD_CHANGELOG => "download-changelog", ++ PK_STATUS_ENUM_DOWNLOAD_GROUP => "download-group", ++ PK_STATUS_ENUM_DOWNLOAD_UPDATEINFO => "download-updateinfo", ++ ++ ++}; ++ ++1; +diff --git a/backends/urpmi/helpers/perl_packagekit/prints.pm b/backends/urpmi/helpers/perl_packagekit/prints.pm +new file mode 100644 +index 0000000..7411ca9 +--- /dev/null ++++ b/backends/urpmi/helpers/perl_packagekit/prints.pm +@@ -0,0 +1,95 @@ ++package perl_packagekit::prints; ++ ++use Exporter; ++ ++our @ISA = qw(Exporter); ++our @EXPORT = qw( ++ pk_print_package ++ pk_print_status ++ pk_print_details ++ pk_print_files ++ pk_print_update_detail ++ pk_print_require_restart ++ pk_print_error ++ pk_print_percentage ++ pk_print_sub_percentage ++ ); ++ ++sub pk_print_package { ++ # send 'package' signal ++ # @param info: the enumerated INFO_* string ++ # @param id: The package ID name, e.g. openoffice-clipart;2.6.22;ppc64;fedora ++ # @param summary: The package Summary ++ my ($info, $id, $summary) = @_; ++ printf("package\t%s\t%s\t%s\n", $info, $id, $summary); ++} ++ ++sub pk_print_status { ++ # send 'status' signal ++ # @param state: STATUS_* ++ my ($status) = @_; ++ printf("status\t%s\n", $status); ++} ++ ++sub pk_print_details { ++ # Send 'details' signal ++ # @param id: The package ID name, e.g. openoffice-clipart;2.6.22;ppc64;fedora ++ # @param license: The license of the package ++ # @param group: The enumerated group ++ # @param desc: The multi line package description ++ # @param url: The upstream project homepage ++ # @param bytes: The size of the package, in bytes ++ my ($id, $license, $group, $desc, $url, $bytes) = @_; ++ printf("details\t%s\t%s\t%s\t%s\t%s\t%ld\n", $id, $license, $group, $desc, $url, $bytes); ++} ++ ++sub pk_print_files { ++ # Send 'files' signal ++ # @param file_list: List of the files in the package, separated by ';' ++ my ($id, $file_list) = @_; ++ printf("files\t%s\t%s\n", $id, $file_list); ++} ++ ++sub pk_print_update_detail { ++ # Send 'updatedetail' signal ++ # @param id: The package ID name, e.g. openoffice-clipart;2.6.22;ppc64;fedora ++ # @param updates: ++ # @param obsoletes: ++ # @param vendor_url: ++ # @param bugzilla_url: ++ # @param cve_url: ++ # @param restart: ++ # @param update_text: ++ my ($id, $updates, $obsoletes, $vendor_url, $bugzilla_url, $cve_url, $restart, $update_text) = @_; ++ printf("updatedetail\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", $id, $updates, $obsoletes, $vendor_url, $bugzilla_url, $cve_url, $restart, $update_text); ++} ++ ++sub pk_print_require_restart { ++ # Send 'requirerestart' signal ++ # @param restart_type: RESTART_SYSTEM, RESTART_APPLICATION,RESTART_SESSION ++ # @param details: Optional details about the restart ++ my ($restart_type, $details) = @_; ++ printf("requirerestart\t%s\t%s\n", $restart_type, $details); ++} ++ ++sub pk_print_error { ++ # send 'error' ++ # @param err: Error Type ERROR_* ++ # @param description: Error description ++ # @param exit: exit application with rc=1, if true ++ my ($err, $description) = @_; ++ printf("error\t%s\t%s\n", $err, $description); ++ exit if($exit); ++} ++ ++sub pk_print_percentage { ++ my ($percentage) = @_; ++ printf("percentage\t%i\n", $percentage); ++} ++ ++sub pk_print_sub_percentage { ++ my ($sub_percentage) = @_; ++ printf("subpercentage\t%i\n", $sub_percentage); ++} ++ ++1; +diff --git a/backends/urpmi/helpers/refresh-cache.pl b/backends/urpmi/helpers/refresh-cache.pl +new file mode 100755 +index 0000000..555a8b8 +--- /dev/null ++++ b/backends/urpmi/helpers/refresh-cache.pl +@@ -0,0 +1,33 @@ ++#!/usr/bin/perl ++ ++use strict; ++ ++use lib; ++use File::Basename; ++ ++BEGIN { ++ push @INC, dirname($0); ++} ++ ++use urpm; ++use urpm::media; ++use urpm::select; ++use urpm::args; ++use urpmi_backend::actions; ++ ++# No arguments ++exit if($#ARGV != -1); ++ ++#my $urpm = urpm->new_parse_cmdline; ++my $urpm = urpm->new_parse_cmdline; ++my $urpmi_lock = urpm::lock::urpmi_db($urpm, 'exclusive', wait => 0); ++urpm::media::read_config($urpm); ++ ++my @entries = map { $_->{name} } @{$urpm->{media}}; ++@entries == 0 and die N("nothing to update (use urpmi.addmedia to add a media)\n"); ++ ++my %options = ( all => 1 ); ++ ++my $ok = urpm::media::update_media($urpm, %options, ++ quiet => 0); ++exit($ok ? 0 : 1); +diff --git a/backends/urpmi/helpers/remove-packages.pl b/backends/urpmi/helpers/remove-packages.pl +new file mode 100755 +index 0000000..3be38ea +--- /dev/null ++++ b/backends/urpmi/helpers/remove-packages.pl +@@ -0,0 +1,90 @@ ++#!/usr/bin/perl ++ ++use strict; ++ ++use lib; ++use File::Basename; ++ ++BEGIN { ++ push @INC, dirname($0); ++} ++ ++use urpm; ++use urpm::args; ++use urpm::media; ++use urpm::select; ++use urpm::install; ++use urpmi_backend::tools; ++use perl_packagekit::enums; ++use perl_packagekit::prints; ++ ++my $notfound = 0; ++my @breaking_pkgs = (); ++my $allowdeps_option = 0; ++my @pkgid; ++my $state = {}; ++my $notfound_callback = sub { ++ $notfound = 1; ++}; ++ ++# This script call only be called with two arguments (allow_deps (yes/no) and a package id) ++exit if($#ARGV != 1); ++ ++my $urpm = urpm->new_parse_cmdline; ++my $urpmi_lock = urpm::lock::urpmi_db($urpm, 'exclusive', wait => 1); ++urpm::media::configure($urpm); ++ ++$allowdeps_option = 1 if($ARGV[0] eq "yes"); ++ ++my @pkg_ids = split(/\|/, pop @ARGV); ++my @names; ++foreach(@pkg_ids) { ++ my @pkg_id = (split(/;/, $_)); ++ push @names, $pkg_id[0]; ++} ++ ++pk_print_status(PK_STATUS_ENUM_DEP_RESOLVE); ++ ++my @to_remove = urpm::select::find_packages_to_remove($urpm, ++ $state, ++ \@names, ++ callback_notfound => $notfound_callback, ++ callback_fuzzy => $notfound_callback, ++ callback_base => sub { ++ my $urpm = shift @_; ++ push @breaking_pkgs, @_; ++ } ++); ++ ++if($notfound) { ++ # printf("Error: package %s not found\n", $pkgid[0]); ++ pk_print_error(PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED, "Selected package isn't installed on your system"); ++} ++elsif(@breaking_pkgs) { ++ # printf("Error: These packages will break your system = \n\t%s\n", join("\n\t", @breaking_pkgs)); ++ pk_print_error(PK_ERROR_ENUM_CANNOT_REMOVE_SYSTEM_PACKAGE, "Removing selected packages will break your system"); ++} ++else { ++ # printf("It's ok, I will remove %s NOW !\n", $pkgid[0]); ++ # printf("To remove list = \n\t%s\n", join("\n\t", @to_remove)); ++ if(!$allowdeps_option && $#to_remove > 1) { ++ pk_print_error(PK_ERROR_ENUM_TRANSACTION_ERROR, "Packages can't be removed because dependencies remove is forbidden"); ++ # printf("I can't remove, because you don't allow deps remove :'(\n"); ++ } ++ else { ++ # printf("Let's go for removing ...\n"); ++ pk_print_status(PK_STATUS_ENUM_REMOVE); ++ urpm::install::install($urpm, ++ \@to_remove, {}, {}, ++ callback_report_uninst => sub { ++ my @return = split(/ /, $_[0]); ++ # printf("Package\tRemoving\t%s\n", fullname_to_package_id($return[$#return])); ++ pk_print_package(INFO_REMOVING, fullname_to_package_id($return[$#return]), ""); ++ } ++ ); ++ } ++} ++ ++$urpmi_lock->unlock; ++ ++pk_print_status(PK_STATUS_ENUM_FINISHED); +diff --git a/backends/urpmi/helpers/resolve.pl b/backends/urpmi/helpers/resolve.pl +new file mode 100755 +index 0000000..32e0866 +--- /dev/null ++++ b/backends/urpmi/helpers/resolve.pl +@@ -0,0 +1,64 @@ ++#!/usr/bin/perl ++ ++use strict; ++ ++use lib; ++use File::Basename; ++ ++BEGIN { ++ push @INC, dirname($0); ++} ++ ++use urpm; ++use urpm::args; ++use urpm::media; ++use urpmi_backend::open_db; ++use urpmi_backend::tools; ++use urpmi_backend::filters; ++use perl_packagekit::enums; ++use perl_packagekit::prints; ++ ++# Two arguments (filter and package name) ++exit if ($#ARGV != 1); ++my @filters = split(/;/, $ARGV[0]); ++my $search_term = $ARGV[1]; ++ ++my $urpm = urpm->new_parse_cmdline; ++urpm::media::configure($urpm); ++ ++my @names = ( $search_term ); ++my %requested; ++my $result = urpm::select::search_packages($urpm, \%requested, \@names, ++ fuzzy => 0, ++ caseinsensitive => 0, ++ all => 0 ++); ++ ++if($result) { ++ my @requested_keys = keys %requested; ++ my $db = open_rpm_db(); ++ $urpm->compute_installed_flags($db); ++ my $pkg = @{$urpm->{depslist}}[$requested_keys[0]]; ++ ++ # We exit the script if found package does not match with ++ # specified filters ++ if(!filter($pkg, \@filters, {FILTER_DEVELOPMENT => 1, FILTER_GUI => 1})) { ++ exit; ++ } ++ if($pkg->version."-".$pkg->release eq find_installed_version($pkg)) { ++ if(grep(/^${\FILTER_NOT_INSTALLED}$/, @filters)) { ++ exit; ++ } ++ pk_print_package(INFO_INSTALLED, get_package_id($pkg), $pkg->summary); ++ } ++ else { ++ if(grep(/^${\FILTER_INSTALLED}$/, @filters)) { ++ exit; ++ } ++ pk_print_package(INFO_AVAILABLE, get_package_id($pkg), $pkg->summary); ++ } ++} ++else { ++ pk_print_error(PK_ERROR_ENUM_PACKAGE_NOT_FOUND, "Can't find any package for the specified name"); ++} ++ +diff --git a/backends/urpmi/helpers/search-details.pl b/backends/urpmi/helpers/search-details.pl +new file mode 100755 +index 0000000..3081abe +--- /dev/null ++++ b/backends/urpmi/helpers/search-details.pl +@@ -0,0 +1,57 @@ ++#!/usr/bin/perl ++ ++use strict; ++ ++use lib; ++use File::Basename; ++ ++BEGIN { ++ push @INC, dirname($0); ++} ++ ++use urpm; ++use urpm::media; ++use urpm::args; ++ ++use urpmi_backend::open_db; ++use urpmi_backend::tools; ++use urpmi_backend::filters; ++ ++use perl_packagekit::enums; ++use perl_packagekit::prints; ++ ++# Two arguments (filterand search term) ++exit if ($#ARGV != 1); ++my @filters = split(/;/, $ARGV[0]); ++my $search_term = $ARGV[1]; ++ ++my $urpm = urpm->new_parse_cmdline; ++urpm::media::configure($urpm); ++ ++my $db = open_rpm_db(); ++$urpm->compute_installed_flags($db); ++ ++# Here we display installed packages ++if(not grep(/^${\FILTER_NOT_INSTALLED}$/, @filters)) { ++ $db->traverse(sub { ++ my ($pkg) = @_; ++ if(filter($pkg, \@filters, {FILTER_DEVELOPMENT => 1, FILTER_GUI => 1})) { ++ if($pkg->name =~ /$search_term/ || $pkg->summary =~ /$search_term/ || $pkg->url =~ /$search_term/) { ++ pk_print_package(INFO_INSTALLED, get_package_id($pkg), ensure_utf8($pkg->summary)); ++ } ++ } ++ }); ++} ++ ++# Here are package which can be installed ++if(not grep(/^${\FILTER_INSTALLED}$/, @filters)) { ++ foreach my $pkg(@{$urpm->{depslist}}) { ++ if($pkg->flag_upgrade) { ++ if(filter($pkg, \@filters, {FILTER_DEVELOPMENT => 1, FILTER_GUI => 1})) { ++ if($pkg->name =~ /$search_term/ || $pkg->summary =~ /$search_term/ || $pkg->url =~ /$search_term/) { ++ pk_print_package(INFO_AVAILABLE, get_package_id($pkg), ensure_utf8($pkg->summary)); ++ } ++ } ++ } ++ } ++} +diff --git a/backends/urpmi/helpers/search-file.pl b/backends/urpmi/helpers/search-file.pl +new file mode 100755 +index 0000000..03d348e +--- /dev/null ++++ b/backends/urpmi/helpers/search-file.pl +@@ -0,0 +1,48 @@ ++#!/usr/bin/perl ++ ++use strict; ++ ++use lib; ++use File::Basename; ++ ++BEGIN { ++ push @INC, dirname($0); ++} ++ ++use urpm; ++use urpm::media; ++ ++use urpmi_backend::actions; ++use urpmi_backend::filters; ++use urpmi_backend::tools; ++use perl_packagekit::prints; ++use perl_packagekit::enums; ++ ++# Two arguments (filter and search term) ++exit if ($#ARGV != 1); ++my @filters = split(/;/, $ARGV[0]); ++my $search_term = $ARGV[1]; ++ ++my $urpm = urpm->new_parse_cmdline; ++urpm::media::configure($urpm); ++ ++my %requested; ++ ++pk_print_status(PK_STATUS_ENUM_QUERY); ++ ++perform_file_search($urpm, \%requested, $search_term, fuzzy => 1); ++ ++foreach(keys %requested) { ++ my $p = @{$urpm->{depslist}}[$_]; ++ if(filter($p, \@filters, { FILTER_INSTALLED => 1, FILTER_DEVELOPMENT=> 1, FILTER_GUI => 1})) { ++ my $version = find_installed_version($p); ++ if($version eq $p->version."-".$p->release) { ++ pk_print_package(INFO_INSTALLED, get_package_id($p), ensure_utf8($p->summary)); ++ } ++ else { ++ pk_print_package(INFO_AVAILABLE, get_package_id($p), ensure_utf8($p->summary)); ++ } ++ } ++} ++ ++pk_print_status(PK_STATUS_ENUM_FINISHED); +diff --git a/backends/urpmi/helpers/search-group.pl b/backends/urpmi/helpers/search-group.pl +new file mode 100755 +index 0000000..e5b7b92 +--- /dev/null ++++ b/backends/urpmi/helpers/search-group.pl +@@ -0,0 +1,58 @@ ++#!/usr/bin/perl ++ ++use strict; ++ ++use lib; ++use File::Basename; ++ ++BEGIN { ++ push @INC, dirname($0); ++} ++ ++use urpm; ++use urpm::media; ++use urpm::args; ++ ++use urpmi_backend::open_db; ++use urpmi_backend::tools; ++use urpmi_backend::filters; ++use urpmi_backend::groups; ++ ++use perl_packagekit::enums; ++use perl_packagekit::prints; ++ ++# Two arguments (filter and packagekit group) ++exit if ($#ARGV != 1); ++my @filters = split(/;/, $ARGV[0]); ++my $pk_group = $ARGV[1]; ++ ++my $urpm = urpm->new_parse_cmdline; ++urpm::media::configure($urpm); ++ ++my $db = open_rpm_db(); ++$urpm->compute_installed_flags($db); ++ ++# Here we display installed packages ++if(not grep(/^${\FILTER_NOT_INSTALLED}$/, @filters)) { ++ $db->traverse(sub { ++ my ($pkg) = @_; ++ if(filter($pkg, \@filters, {FILTER_DEVELOPMENT => 1, FILTER_GUI => 1})) { ++ if(package_belongs_to_pk_group($pkg, $pk_group)) { ++ pk_print_package(INFO_INSTALLED, get_package_id($pkg), ensure_utf8($pkg->summary)); ++ } ++ } ++ }); ++} ++ ++# Here are package which can be installed ++if(not grep(/^${\FILTER_INSTALLED}$/, @filters)) { ++ foreach my $pkg(@{$urpm->{depslist}}) { ++ if($pkg->flag_upgrade) { ++ if(filter($pkg, \@filters, {FILTER_DEVELOPMENT => 1, FILTER_GUI => 1})) { ++ if(package_belongs_to_pk_group($pkg, $pk_group)) { ++ pk_print_package(INFO_AVAILABLE, get_package_id($pkg), ensure_utf8($pkg->summary)); ++ } ++ } ++ } ++ } ++} +diff --git a/backends/urpmi/helpers/search-name.pl b/backends/urpmi/helpers/search-name.pl +new file mode 100755 +index 0000000..383921f +--- /dev/null ++++ b/backends/urpmi/helpers/search-name.pl +@@ -0,0 +1,64 @@ ++#!/usr/bin/perl ++ ++use strict; ++ ++use lib; ++use File::Basename; ++ ++BEGIN { ++ push @INC, dirname($0); ++} ++ ++use urpm; ++use urpm::media; ++use urpm::args; ++ ++use urpmi_backend::open_db; ++use urpmi_backend::tools; ++use urpmi_backend::filters; ++ ++use perl_packagekit::enums; ++use perl_packagekit::prints; ++ ++# Two arguments (filter, search term) ++exit if ($#ARGV != 1); ++ ++my @filters = split(/;/, $ARGV[0]); ++my $search_term = $ARGV[1]; ++ ++my $basename_option = FILTER_BASENAME; ++$basename_option = grep(/$basename_option/, @filters); ++ ++my $urpm = urpm->new_parse_cmdline; ++ ++urpm::media::configure($urpm); ++ ++my $db = open_rpm_db(); ++$urpm->compute_installed_flags($db); ++ ++# Here we display installed packages ++if(not grep(/^${\FILTER_NOT_INSTALLED}$/, @filters)) { ++ $db->traverse(sub { ++ my ($pkg) = @_; ++ if(filter($pkg, \@filters, {FILTER_DEVELOPMENT => 1, FILTER_GUI => 1})) { ++ if( (!$basename_option && $pkg->name =~ /$search_term/) ++ || $pkg->name =~ /^$search_term$/ ) { ++ pk_print_package(INFO_INSTALLED, get_package_id($pkg), ensure_utf8($pkg->summary)); ++ } ++ } ++ }); ++} ++ ++# Here are packages which can be installed ++if(grep(/^${\FILTER_INSTALLED}$/, @filters)) { ++ exit 0; ++} ++ ++foreach my $pkg(@{$urpm->{depslist}}) { ++ if($pkg->flag_upgrade && filter($pkg, \@filters, {FILTER_DEVELOPMENT => 1, FILTER_GUI => 1})) { ++ if( (!$basename_option && $pkg->name =~ /$search_term/) ++ || $pkg->name =~ /^$search_term$/ ) { ++ pk_print_package(INFO_AVAILABLE, get_package_id($pkg), ensure_utf8($pkg->summary)); ++ } ++ } ++} +diff --git a/backends/urpmi/helpers/update-packages.pl b/backends/urpmi/helpers/update-packages.pl +new file mode 100755 +index 0000000..88274bc +--- /dev/null ++++ b/backends/urpmi/helpers/update-packages.pl +@@ -0,0 +1,50 @@ ++#!/usr/bin/perl ++ ++use strict; ++ ++use lib; ++use File::Basename; ++ ++BEGIN { ++ push @INC, dirname($0); ++} ++ ++use urpm; ++use urpm::media; ++use urpm::select; ++use urpm::args; ++use urpmi_backend::tools; ++use urpmi_backend::open_db; ++use urpmi_backend::actions; ++ ++# This script call only be called with one argument (the package id) ++exit if($#ARGV != 0); ++ ++my @names; ++foreach(split(/\|/, $ARGV[0])) { ++ my @pkgid = split(/;/, $_); ++ push @names, $pkgid[0]; ++} ++ ++my $urpm = urpm->new_parse_cmdline; ++urpm::media::configure($urpm); ++ ++my $db = open_rpm_db(); ++$urpm->compute_installed_flags($db); ++ ++my %requested; ++ ++my @depslist = @{$urpm->{depslist}}; ++my $pkg = undef; ++foreach my $depslistpkg (@depslist) { ++ foreach my $name (@names) { ++ if($depslistpkg->name =~ /^$name$/ && $depslistpkg->flag_upgrade) { ++ $requested{$depslistpkg->id} = 1; ++ goto tonext; ++ } ++ } ++ tonext: ++} ++ ++perform_installation($urpm, \%requested); ++ +diff --git a/backends/urpmi/helpers/urpmi_backend/Makefile.am b/backends/urpmi/helpers/urpmi_backend/Makefile.am +new file mode 100644 +index 0000000..3eb8280 +--- /dev/null ++++ b/backends/urpmi/helpers/urpmi_backend/Makefile.am +@@ -0,0 +1,15 @@ ++helperdir = $(datadir)/PackageKit/helpers/urpmi/urpmi_backend/ ++ ++NULL = ++ ++dist_helper_DATA = \ ++ actions.pm \ ++ filters.pm \ ++ groups.pm \ ++ open_db.pm \ ++ tools.pm \ ++ $(NULL) ++ ++clean-local : ++ rm -f *~ ++ +diff --git a/backends/urpmi/helpers/urpmi_backend/actions.pm b/backends/urpmi/helpers/urpmi_backend/actions.pm +new file mode 100644 +index 0000000..a01b893 +--- /dev/null ++++ b/backends/urpmi/helpers/urpmi_backend/actions.pm +@@ -0,0 +1,297 @@ ++package urpmi_backend::actions; ++ ++use strict; ++ ++use urpm; ++use urpm::args; ++use urpm::msg; ++use urpm::main_loop; ++use urpm::lock; ++use urpmi_backend::tools; ++use urpmi_backend::open_db; ++use MDK::Common; ++use perl_packagekit::enums; ++use perl_packagekit::prints; ++ ++use Exporter; ++our @ISA = qw(Exporter); ++our @EXPORT = qw( ++ perform_installation ++ perform_file_search ++ perform_requires_search ++); ++ ++sub perform_installation { ++ my ($urpm, $requested, %options) = @_; ++ my $state = {}; ++ my $restart; ++ my $no_remove = 0; ++ ++ # Here we lock urpmi & rpm databases ++ # In third argument we can specified if the script must wait until urpmi or rpm ++ # databases are locked ++ my $lock = urpm::lock::urpmi_db($urpm, undef, wait => 0); ++ my $rpm_lock = urpm::lock::rpm_db($urpm, 'exclusive'); ++ ++ pk_print_status(PK_STATUS_ENUM_DEP_RESOLVE); ++ ++ $restart = urpm::select::resolve_dependencies($urpm, $state, $requested, auto_select => $options{auto_select}); ++ my %selected = %{$state->{selected} || {}}; ++ ++ print "Dependencies = \n\t"; ++ print join("\n\t", map(@{$urpm->{depslist}}[$_]->name, keys %selected)), "\n"; ++ ++ # Here we have packages which cannot be installed because of dependencies ++ my @unselected_uninstalled = @{$state->{unselected_uninstalled} || []}; ++ if(@unselected_uninstalled) { ++ my $list = join "\n", map { $_->name . '-' . $_->version . '-' . $_->release } @unselected_uninstalled; ++ } ++ # Fix me ! ++ # Display warning (With pk enum?) which warning the user ++ # that the following packages can't be installed because they depend ++ # on packages that are older than the installed ones (copy/paste from ++ # the diplayed message in urpmi) ++ ++ # Here we have packages which cannot be installed ++ my @ask_unselect = urpm::select::unselected_packages($urpm, $state); ++ if (@ask_unselect) { ++ my $list = urpm::select::translate_why_unselected($urpm, $state, @ask_unselect); ++ } ++ # Fix me ! ++ # Display warning (With pk enum?) which warning the user ++ # that the following packages can't be installed (copy/paste from ++ # the diplayed message in urpmi) ++ ++ my @ask_remove = urpm::select::removed_packages($urpm, $state); ++ if(@ask_remove) { ++ my $db = urpm::db_open_or_die($urpm, $urpm->{root}); ++ urpm::select::find_removed_from_basesystem($urpm, $db, $state, sub { ++ my $urpm = shift @_; ++ foreach (@_) { ++ # Fix me ++ # Someting like that. With a clean pk error enum. ++ # printf ("removing package %s will break your system", $_); ++ } ++ @_ and $no_remove = 1; ++ }); ++ my $list = urpm::select::translate_why_removed($urpm, $state, @ask_remove); ++ if($no_remove) { ++ # Fix me ++ # Display message to prevent that the installation cannot continue because some ++ # packages has to be removed for others to be upgraded. ++ exit 0; ++ } ++ # Else, it's ok. ++ # Here we can display $list, which describe packages which has to be removed for ++ # others to be upgraded. ++ printf("Following package(s) will be removed for others to be upgraded:\n%s\n", $list); ++ } ++ ++ # sorted by medium for format_selected_packages ++ my @to_install = @{$urpm->{depslist}}[sort { $a <=> $b } keys %{$state->{selected}}]; ++ my ($src, $binary) = partition { $_->arch eq 'src' } @to_install; ++ # With packagekit, we will never install src packages. ++ @to_install = @$binary; ++ ++ print "\@to_install debug : \n\t"; ++ print join("\n\t", map(urpm_name($_), @to_install)), "\n"; ++ ++ my $nb_to_install = $#to_install + 1; ++ my $percentage = 0; ++ ++ $urpm->{nb_install} = @to_install; ++ # For debug issue, we will display sizes ++ my ($size, $filesize) = $urpm->selected_size_filesize($state); ++ printf("%s of additional disk space will be used.\n", formatXiB($size)); ++ printf("%s of packages will be retrieved.\n", formatXiB($filesize)); ++ ++ my $callback_inst = sub { ++ my ($urpm, $type, $id, $subtype, $amount, $total) = @_; ++ my $pkg = defined $id ? $urpm->{depslist}[$id] : undef; ++ if ($subtype eq 'start') { ++ if ($type eq 'trans') { ++ print "Preparing packages installation ...\n"; ++ pk_print_status(PK_STATUS_ENUM_INSTALL); ++ } ++ elsif (defined $pkg) { ++ printf("Installing package %s ...\n", $pkg->name); ++ pk_print_package(INFO_INSTALLING, get_package_id($pkg), $pkg->summary); ++ } ++ } ++ elsif ($subtype eq 'progress') { ++ print "($type) Progress : total = ", $total, " ; amount/total = ", $amount/$total, " ; amount = ", $amount, "\n"; ++ if($type eq "inst") { ++ pk_print_percentage($percentage + ($amount/$total)*(100/$nb_to_install)); ++ if(($amount/$total) == 1) { ++ $percentage = $percentage + ($amount/$total)*(100/$nb_to_install); ++ } ++ } ++ } ++ }; ++ ++ # Now, the script will call the urpmi main loop to make installation ++ my $exit_code = urpm::main_loop::run($urpm, $state, undef, \@ask_unselect, $requested, { ++ inst => $callback_inst, ++ trans => $callback_inst, ++ trans_log => sub { ++ my ($mode, $file, $percent, $total, $eta, $speed) = @_; ++ # Transfer log need to be improved. ++ if($mode eq "progress") { ++ pk_print_status(PK_STATUS_ENUM_DOWNLOAD); ++ } ++ print "Install current mode = ", $mode, "\n"; ++ }, ++ bad_signature => sub { ++ # Here we display a message (with PK enum) to warn the user ++ # about a bad signature, then we exit ++ exit 1; ++ }, ++ ask_yes_or_no => sub { ++ # Return 1 = Return Yes ++ return 1; ++ }, ++ need_restart => sub { ++ my ($need_restart_formatted) = @_; ++ print "$_\n" foreach values %$need_restart_formatted; ++ }, ++ completed => sub { ++ undef $lock; ++ undef $rpm_lock; ++ pk_print_status(PK_STATUS_ENUM_FINISHED); ++ }, ++ post_download => sub { ++ # Fix me ! ++ # At this point, we need to refuse cancel action ++ }, ++ } ++ ); ++} ++ ++sub perform_file_search { ++ my ($urpm, $requested, $search_term, %options) = @_; ++ my $db = open_rpm_db(); ++ $urpm->compute_installed_flags($db); ++ ++ my $xml_info = 'files'; ++ my %result_hash; ++ ++ # - For each medium, we browse the xml info file, ++ # while looking for files which matched with the ++ # search term given in argument. We store results ++ # in a hash. ++ foreach my $medium (urpm::media::non_ignored_media($urpm)) { ++ my $xml_info_file = urpm::media::any_xml_info($urpm, $medium, ( "files", "summary" ), undef, undef); ++ $xml_info_file or next; ++ require urpm::xml_info; ++ require urpm::xml_info_pkg; ++ my $F = urpm::xml_info::open_lzma($xml_info_file); ++ my $fn; ++ local $_; ++ while (<$F>) { ++ if (m!^{fatal}("fast algorithm is broken, please report a bug"); ++ my $pkg = urpm::xml_info_pkg->new({ fn => $fn }); ++ $result_hash{$pkg->name} = $pkg; ++ } ++ } ++ } ++ ++ # - In order to get package summaries, we need to ++ # use the search package method from perl-URPM ++ # which return Package type on which we can call ++ # methods to create the printing output. ++ # (It's about the same code as search-name.pl) ++ my @names = keys %result_hash; ++ ++ urpm::select::search_packages($urpm, $requested, \@names, ++ fuzzy => 0, ++ caseinsensitive => 0, ++ all => 0,); ++} ++ ++sub perform_requires_search { ++ ++ my ($urpm, $pkg, $recursive_option) = @_; ++ ++ my (@properties, %requires, %properties, $dep); ++ my %requested; ++ urpm::select::search_packages($urpm, ++ \%requested, [ $pkg->name ], ++ use_provides => 0, ++ fuzzy => 0, ++ all => 0 ++ ); ++ @properties = keys %requested; ++ my $state = {}; ++ ++ foreach my $pkg (@{$urpm->{depslist}}) { ++ foreach ($pkg->requires_nosense) { ++ $requires{$_}{$pkg->id} = undef; ++ } ++ } ++ ++ while (defined ($dep = shift @properties)) { ++ my $packages = $urpm->find_candidate_packages($dep); ++ foreach (values %$packages) { ++ my ($best_requested, $best); ++ foreach (@$_) { ++ if ($best_requested || exists $requested{$_->id}) { ++ if ($best_requested && $best_requested != $_) { ++ $_->compare_pkg($best_requested) > 0 and $best_requested = $_; ++ } else { ++ $best_requested = $_; ++ } ++ } elsif ($best && $best != $_) { ++ $_->compare_pkg($best) > 0 and $best = $_; ++ } else { ++ $best = $_; ++ } ++ } ++ ++ my $pkg = $best_requested || $best or next; ++ exists $state->{selected}{$pkg->id} and next; ++ $state->{selected}{$pkg->id} = undef; ++ ++ next if !$requested{$dep} && !$recursive_option; ++ ++ #- for all provides of package, look up what is requiring them. ++ foreach ($pkg->provides) { ++ if (my ($n, $s) = /^([^\s\[]*)(?:\[\*\])?\[?([^\s\]]*\s*[^\s\]]*)/) { ++ if (my @l = grep { $_ ne $pkg->name } map { $_->name } $urpm->packages_providing($n)) { ++ #- If another package provides this requirement, ++ #- then don't bother finding stuff that needs it as it will be invalid ++ # $urpm->{log}(sprintf "skipping package(s) requiring %s via %s, since %s is also provided by %s", $pkg->name, $n, $n, join(' ', @l)); ++ next; ++ } ++ ++ foreach (map { $urpm->{depslist}[$_] } ++ grep { ! exists $state->{selected}{$_} && ! exists $properties{$_} } ++ keys %{$requires{$n} || {}}) { ++ if (grep { URPM::ranges_overlap("$n $s", $_) } $_->requires) { ++ push @properties, $_->id; ++ # $urpm->{debug} and $urpm->{debug}(sprintf "adding package %s (requires %s%s)", $_->name, $pkg->name, $n eq $pkg->name ? '' : " via $n"); ++ $properties{$_->id} = undef; ++ } ++ } ++ } ++ } ++ } ++ } ++ ++ my @depslist = @{$urpm->{depslist}}; ++ my @requires = (); ++ foreach(@depslist) { ++ my $pkgid = $_->id; ++ if(grep(/^$pkgid$/, keys %{$state->{selected}})) { ++ push @requires, $_; ++ } ++ } ++ ++ @requires; ++ ++} +diff --git a/backends/urpmi/helpers/urpmi_backend/filters.pm b/backends/urpmi/helpers/urpmi_backend/filters.pm +new file mode 100644 +index 0000000..2c2f13a +--- /dev/null ++++ b/backends/urpmi/helpers/urpmi_backend/filters.pm +@@ -0,0 +1,78 @@ ++package urpmi_backend::filters; ++ ++use MDK::Common; ++use perl_packagekit::enums; ++use urpmi_backend::tools; ++ ++use Exporter; ++our @ISA = qw(Exporter); ++our @EXPORT = qw(filter); ++ ++my @gui_pkgs = map { chomp; $_ } cat_('/usr/share/rpmdrake/gui.lst'); ++ ++sub filter { ++ my ($pkg, $filters, $enabled_filters) = @_; ++ ++ my %e_filters = %{$enabled_filters}; ++ ++ foreach my $filter (@{$filters}) { ++ if($filter eq FILTER_INSTALLED || $filter eq FILTER_NOT_INSTALLED) { ++ if($e_filters{FILTER_INSTALLED}) { ++ return 0 if not filter_installed($pkg, $filter); ++ } ++ } ++ elsif($filter eq FILTER_DEVELOPMENT || $filter eq FILTER_NOT_DEVELOPMENT) { ++ if($e_filters{FILTER_DEVELOPMENT}) { ++ return 0 if not filter_devel($pkg, $filter); ++ } ++ } ++ elsif($filter eq FILTER_GUI || $filter eq FILTER_NOT_GUI) { ++ if($e_filters{FILTER_GUI}) { ++ return 0 if not filter_gui($pkg, $filter); ++ } ++ } ++ } ++ return 1; ++} ++ ++sub filter_installed { ++ my ($pkg, $filter) = @_; ++ my $installed; ++ $installed = 1 if(find_installed_version($pkg)); ++ if($filter eq FILTER_INSTALLED && $installed) { ++ return 1; ++ } ++ if($filter eq FILTER_NOT_INSTALLED && !$installed) { ++ return 1; ++ } ++ return 0; ++} ++ ++sub filter_devel { ++ my ($pkg, $filter) = @_; ++ my $pkgname = $pkg->name; ++ my $devel = ($pkgname =~ /-devel$/); ++ if($filter eq FILTER_DEVELOPMENT && $devel) { ++ return 1; ++ } ++ if($filter eq FILTER_NOT_DEVELOPMENT && !$devel) { ++ return 1; ++ } ++ return 0; ++} ++ ++sub filter_gui { ++ my ($pkg, $filter) = @_; ++ my $pkgname = $pkg->name; ++ my $gui = member($pkgname, @gui_pkgs); ++ ++ if($filter eq FILTER_NOT_GUI && !$gui) { ++ return 1; ++ } ++ if($filter eq FILTER_GUI && $gui) { ++ return 1; ++ } ++ return 0; ++} ++ ++1; +diff --git a/backends/urpmi/helpers/urpmi_backend/groups.pm b/backends/urpmi/helpers/urpmi_backend/groups.pm +new file mode 100644 +index 0000000..d377ab2 +--- /dev/null ++++ b/backends/urpmi/helpers/urpmi_backend/groups.pm +@@ -0,0 +1,129 @@ ++package urpmi_backend::groups; ++ ++use strict; ++ ++use perl_packagekit::enums; ++use Exporter; ++ ++our @ISA = qw(Exporter); ++our @EXPORT = qw( ++ MDV_GROUPS ++ get_mdv_groups ++ get_pk_group ++ package_belongs_to_pk_group ++); ++ ++use constant MDV_GROUPS => { ++ 'Accessibility' => GROUP_ACCESSIBILITY, ++ 'Archiving/Backup' => GROUP_OTHER, ++ 'Archiving/Cd burning' => GROUP_MULTIMEDIA, ++ 'Archiving/Compression' => GROUP_ACCESSORIES, ++ 'Archiving/Other' => GROUP_OTHER, ++ 'Books/Computer books' => GROUP_OTHER, ++ 'Books/Faqs' => GROUP_OTHER, ++ 'Books/Howtos' => GROUP_OTHER, ++ 'Books/Literature' => GROUP_OTHER, ++ 'Books/Other' => GROUP_OTHER, ++ 'Communications' => GROUP_COMMUNICATION, ++ 'Databases' => GROUP_PROGRAMMING, ++ 'Development/C' => GROUP_PROGRAMMING, ++ 'Development/C++' => GROUP_PROGRAMMING, ++ 'Development/Databases' => GROUP_PROGRAMMING, ++ 'Development/GNOME and GTK+' => GROUP_PROGRAMMING, ++ 'Development/Java' => GROUP_PROGRAMMING, ++ 'Development/KDE and Qt' => GROUP_PROGRAMMING, ++ 'Development/Kernel' => GROUP_PROGRAMMING, ++ 'Development/Other' => GROUP_PROGRAMMING, ++ 'Development/Perl' => GROUP_PROGRAMMING, ++ 'Development/PHP' => GROUP_PROGRAMMING, ++ 'Development/Python' => GROUP_PROGRAMMING, ++ 'Development/Ruby' => GROUP_PROGRAMMING, ++ 'Development/X11' => GROUP_PROGRAMMING, ++ 'Editors' => GROUP_ACCESSORIES, ++ 'Education' => GROUP_EDUCATION, ++ 'Emulators' => GROUP_VIRTUALIZATION, ++ 'File tools' => GROUP_ACCESSORIES, ++ 'Games/Adventure' => GROUP_GAMES, ++ 'Games/Arcade' => GROUP_GAMES, ++ 'Games/Boards' => GROUP_GAMES, ++ 'Games/Cards' => GROUP_GAMES, ++ 'Games/Other' => GROUP_GAMES, ++ 'Games/Puzzles' => GROUP_GAMES, ++ 'Games/Sports' => GROUP_GAMES, ++ 'Games/Strategy' => GROUP_GAMES, ++ 'Graphical desktop/Enlightenment' => GROUP_DESKTOP_OTHER, ++ 'Graphical desktop/FVWM based' => GROUP_DESKTOP_OTHER, ++ 'Graphical desktop/GNOME' => GROUP_DESKTOP_GNOME, ++ 'Graphical desktop/Icewm' => GROUP_DESKTOP_OTHER, ++ 'Graphical desktop/KDE' => GROUP_DESKTOP_KDE, ++ 'Graphical desktop/Other' => GROUP_DESKTOP_OTHER, ++ 'Graphical desktop/Sawfish' => GROUP_DESKTOP_OTHER, ++ 'Graphical desktop/WindowMaker' => GROUP_DESKTOP_OTHER, ++ 'Graphical desktop/Xfce' => GROUP_DESKTOP_XFCE, ++ 'Graphics' => GROUP_GRAPHICS, ++ 'Monitoring' => GROUP_NETWORK, ++ 'Networking/Chat' => GROUP_INTERNET, ++ 'Networking/File transfer' => GROUP_INTERNET, ++ 'Networking/IRC' => GROUP_INTERNET, ++ 'Networking/Instant messaging' => GROUP_INTERNET, ++ 'Networking/Mail' => GROUP_INTERNET, ++ 'Networking/News' => GROUP_INTERNET, ++ 'Networking/Other' => GROUP_INTERNET, ++ 'Networking/Remote access' => GROUP_INTERNET, ++ 'Networking/WWW' => GROUP_INTERNET, ++ 'Office' => GROUP_OFFICE, ++ 'Publishing' => GROUP_PUBLISHING, ++ 'Sciences/Astronomy' => GROUP_OTHER, ++ 'Sciences/Biology' => GROUP_OTHER, ++ 'Sciences/Chemistry' => GROUP_OTHER, ++ 'Sciences/Computer science' => GROUP_OTHER, ++ 'Sciences/Geosciences' => GROUP_OTHER, ++ 'Sciences/Mathematics' => GROUP_OTHER, ++ 'Sciences/Other' => GROUP_OTHER, ++ 'Sciences/Physics' => GROUP_OTHER, ++ 'Shells' => GROUP_SYSTEM, ++ 'Sound' => GROUP_MULTIMEDIA, ++ 'System/Base' => GROUP_SYSTEM, ++ 'System/Cluster' => GROUP_SYSTEM, ++ 'System/Configuration/Boot and Init' => GROUP_SYSTEM, ++ 'System/Configuration/Hardware' => GROUP_SYSTEM, ++ 'System/Configuration/Networking' => GROUP_SYSTEM, ++ 'System/Configuration/Other' => GROUP_SYSTEM, ++ 'System/Configuration/Packaging' => GROUP_SYSTEM, ++ 'System/Configuration/Printing' => GROUP_SYSTEM, ++ 'System/Fonts/Console' => GROUP_FONTS, ++ 'System/Fonts/True type' => GROUP_FONTS, ++ 'System/Fonts/Type1' => GROUP_FONTS, ++ 'System/Fonts/X11 bitmap' => GROUP_FONTS, ++ 'System/Internationalization' => GROUP_LOCALIZATION, ++ 'System/Kernel and hardware' => GROUP_SYSTEM, ++ 'System/Libraries' => GROUP_SYSTEM, ++ 'System/Printing' => GROUP_SYSTEM, ++ 'System/Servers' => GROUP_SYSTEM, ++ 'System/X11' => GROUP_SYSTEM, ++ 'Terminals' => GROUP_SYSTEM, ++ 'Text tools' => GROUP_ACCESSORIES, ++ 'Toys' => GROUP_GAMES, ++ 'Video' => GROUP_MULTIMEDIA ++ }; ++ ++sub get_mdv_groups { ++ my ($pk_group) = @_; ++ my @groups = (); ++ foreach(keys %{(MDV_GROUPS)}) { ++ if(%{(MDV_GROUPS)}->{$_} eq $pk_group) { ++ push @groups, $_; ++ } ++ } ++ return @groups; ++} ++ ++sub package_belongs_to_pk_group { ++ my ($pkg, $pk_group) = @_; ++ my @groups = get_mdv_groups($pk_group); ++ my $pkg_group = $pkg->group; ++ return grep(/$pkg_group/, @groups); ++} ++ ++1; ++ +diff --git a/backends/urpmi/helpers/urpmi_backend/open_db.pm b/backends/urpmi/helpers/urpmi_backend/open_db.pm +new file mode 100644 +index 0000000..795edc6 +--- /dev/null ++++ b/backends/urpmi/helpers/urpmi_backend/open_db.pm +@@ -0,0 +1,48 @@ ++package urpmi_backend::open_db; ++ ++use strict; ++ ++use MDK::Common; ++ ++use urpm; ++use urpm::media; ++use urpm::select; ++ ++use URPM; ++ ++use Exporter; ++our @ISA = qw(Exporter); ++our @EXPORT = qw(fast_open_urpmi_db open_urpmi_db open_rpm_db); ++ ++# Note that most part of this perl module ++# is extracted from Rpmdrake ++ ++sub fast_open_urpmi_db() { ++ my $urpm = urpm->new; ++ $urpm->get_global_options; ++ urpm::media::read_config($urpm); ++ $urpm; ++} ++ ++sub open_urpmi_db { ++ my (%urpmi_options) = @_; ++ my $urpm = fast_open_urpmi_db(); ++ my $media = ''; # See Rpmdrake source code for more information. ++ ++ my $searchmedia = $urpmi_options{update} ? undef : join(',', get_inactive_backport_media($urpm)); ++ $urpm->{lock} = urpm::lock::urpmi_db($urpm, undef, wait => $urpm->{options}{wait_lock}); ++ my $previous = ''; # Same as $media above. ++ urpm::select::set_priority_upgrade_option($urpm, (ref $previous ? join(',', @$previous) : ())); ++ urpm::media::configure($urpm, media => $media, if_($searchmedia, searchmedia => $searchmedia), %urpmi_options); ++ $urpm; ++} ++ ++sub get_inactive_backport_media { ++ my ($urpm) = @_; ++ map { $_->{name} } grep { $_->{ignore} && $_->{name} =~ /backport/i } @{$urpm->{media}}; ++} ++ ++sub open_rpm_db { ++ URPM::DB::open() or die "Couldn't open RPM DB"; ++} ++ +diff --git a/backends/urpmi/helpers/urpmi_backend/tools.pm b/backends/urpmi/helpers/urpmi_backend/tools.pm +new file mode 100644 +index 0000000..e078134 +--- /dev/null ++++ b/backends/urpmi/helpers/urpmi_backend/tools.pm +@@ -0,0 +1,151 @@ ++package urpmi_backend::tools; ++ ++use strict; ++ ++use URPM; ++use urpmi_backend::open_db; ++ ++use Exporter; ++our @ISA = qw(Exporter); ++our @EXPORT = qw( ++ get_update_medias ++ rpm_description ++ urpm_name ++ find_installed_version ++ get_package_id ++ ensure_utf8 ++ pkg2medium ++ fullname_to_package_id ++ get_package_by_package_id ++ package_version_is_installed ++ get_package_upgrade ++ get_installed_version ++ get_installed_version_pkid ++); ++ ++sub get_update_medias { ++ my ($urpm) = @_; ++ grep { !$_->{ignore} && $_->{update} } @{$urpm->{media}}; ++} ++ ++sub rpm_description { ++ my ($description) = @_; ++ ensure_utf8($description); ++ my ($t, $tmp); ++ foreach (split "\n", $description) { ++ s/^\s*//; ++ if (/^$/ || /^\s*(-|\*|\+|o)\s/) { ++ $t || $tmp and $t .= "$tmp\n"; ++ $tmp = $_; ++ } else { ++ $tmp = ($tmp ? "$tmp " : ($t && "\n") . $tmp) . $_; ++ } ++ } ++ "$t$tmp\n"; ++} ++ ++sub urpm_name { ++ return '?-?-?.?' unless ref $_[0]; ++ my ($name, $version, $release, $arch) = $_[0]->fullname; ++ "$name-$version-$release.$arch"; ++} ++ ++sub ensure_utf8 { ++ my ($s) = @_; ++ require Encode; ++ Encode::_utf8_on($s); #- this is done on the copy ++ if (!Encode::is_utf8($s, 1)) { ++ Encode::_utf8_off($_[0]); ++ Encode::from_to($_[0], 'iso-8859-15', 'utf8'); # most probable ++ } ++ Encode::_utf8_on($_[0]); #- now we know it is valid utf8 ++ $_[0]; ++} ++ ++sub find_installed_version { ++ my ($p) = @_; ++ my @version; ++ URPM::DB::open()->traverse_tag('name', [ $p->name ], sub { push @version, $_[0]->version . '-' . $_[0]->release }); ++ @version ? join(',', sort @version) : ""; ++} ++ ++sub get_package_id { ++ my ($pkg) = @_; ++ return $pkg->name.";".$pkg->version."-".$pkg->release.";".$pkg->arch.";mandriva"; ++} ++ ++sub pkg2medium { ++ my ($p, $urpm) = @_; ++ return if !ref $p; ++ return { name => N("None (installed)") } if !$p->id; # if installed ++ URPM::pkg2media($urpm->{media}, $p) || undef; ++} ++ ++sub fullname_to_package_id { ++ # fullname, ie 'xeyes-1.0.1-5mdv2008.1.i586' ++ my ($pkg_string) = @_; ++ chomp($pkg_string); ++ $pkg_string =~ /^(.*)-([^-]*)-([^-]*)\.([^\.]*)$/; ++ my %pkg = ( ++ name => $1, ++ version => $2, ++ release => $3, ++ arch => $4 ++ ); ++ return $pkg{name}.";".$pkg{version}."-".$pkg{release}.";".$pkg{arch}.";mandriva"; ++} ++ ++sub get_package_by_package_id { ++ my ($urpm, $package_id) = @_; ++ my @depslist = @{$urpm->{depslist}}; ++ foreach(@depslist) { ++ if(get_package_id($_) eq $package_id) { ++ return $_; ++ } ++ } ++ return; ++} ++ ++sub package_version_is_installed { ++ my ($pkg) = @_; ++ return $pkg->version."-".$pkg->release eq find_installed_version($pkg); ++} ++ ++sub get_package_upgrade { ++ my ($urpm, $pkg) = @_; ++ my $db = open_rpm_db(); ++ $urpm->compute_installed_flags($db); ++ my @depslist = @{$urpm->{depslist}}; ++ my $pkgname = $pkg->name; ++ foreach(@depslist) { ++ if($_->name =~ /^$pkgname$/ && $_->flag_upgrade) { ++ return $_; ++ } ++ } ++} ++ ++sub get_installed_version { ++ my ($urpm, $pkg) = @_; ++ my @depslist = @{$urpm->{depslist}}; ++ my $pkgname = $pkg->name; ++ foreach $_ (@depslist) { ++ if($_->name =~ /^$pkgname$/ && package_version_is_installed($_)) { ++ return $_; ++ } ++ } ++ return; ++} ++ ++sub get_installed_version_pkid { ++ my ($pkg) = @_; ++ my $pkgname = $pkg->name; ++ my $db = open_rpm_db(); ++ my $installed_pkid; ++ $db->traverse(sub { ++ my ($pkg) = @_; ++ if($pkg->name =~ /^$pkgname$/) { ++ $installed_pkid = get_package_id($pkg); ++ } ++ }); ++ return $installed_pkid; ++} +diff --git a/backends/urpmi/pk-backend-urpmi.c b/backends/urpmi/pk-backend-urpmi.c +new file mode 100644 +index 0000000..e7b56a7 +--- /dev/null ++++ b/backends/urpmi/pk-backend-urpmi.c +@@ -0,0 +1,355 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- ++ * ++ * Copyright (C) 2007-2008 Richard Hughes ++ * ++ * Licensed under the GNU General Public License Version 2 ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++#include ++#include ++#include ++ ++static PkBackendSpawn *spawn; ++ ++/** ++ * backend_initialize: ++ * This should only be run once per backend load, i.e. not every transaction ++ */ ++static void ++backend_initialize (PkBackend *backend) ++{ ++ pk_debug ("FILTER: initialize"); ++ spawn = pk_backend_spawn_new (); ++ pk_backend_spawn_set_name (spawn, "urpmi"); ++} ++ ++/** ++ * backend_destroy: ++ * This should only be run once per backend load, i.e. not every transaction ++ */ ++static void ++backend_destroy (PkBackend *backend) ++{ ++ pk_debug ("FILTER: destroy"); ++ g_object_unref (spawn); ++} ++ ++/** ++ * backend_get_groups: ++ */ ++static PkGroupEnum ++backend_get_groups (PkBackend *backend) ++{ ++ return(PK_GROUP_ENUM_UNKNOWN | ++ PK_GROUP_ENUM_ACCESSIBILITY | ++ PK_GROUP_ENUM_ACCESSORIES | ++ PK_GROUP_ENUM_EDUCATION | ++ PK_GROUP_ENUM_GAMES | ++ PK_GROUP_ENUM_GRAPHICS | ++ PK_GROUP_ENUM_INTERNET | ++ PK_GROUP_ENUM_OFFICE | ++ PK_GROUP_ENUM_OTHER | ++ PK_GROUP_ENUM_PROGRAMMING | ++ PK_GROUP_ENUM_MULTIMEDIA | ++ PK_GROUP_ENUM_SYSTEM | ++ PK_GROUP_ENUM_DESKTOP_GNOME | ++ PK_GROUP_ENUM_DESKTOP_KDE | ++ PK_GROUP_ENUM_DESKTOP_XFCE | ++ PK_GROUP_ENUM_DESKTOP_OTHER | ++ PK_GROUP_ENUM_PUBLISHING | ++ PK_GROUP_ENUM_SERVERS | ++ PK_GROUP_ENUM_FONTS | ++ PK_GROUP_ENUM_ADMIN_TOOLS | ++ PK_GROUP_ENUM_LEGACY | ++ PK_GROUP_ENUM_LOCALIZATION | ++ PK_GROUP_ENUM_VIRTUALIZATION | ++ PK_GROUP_ENUM_POWER_MANAGEMENT | ++ PK_GROUP_ENUM_SECURITY | ++ PK_GROUP_ENUM_COMMUNICATION | ++ PK_GROUP_ENUM_NETWORK | ++ PK_GROUP_ENUM_MAPS | ++ PK_GROUP_ENUM_REPOS); ++} ++ ++/** ++ * backend_get_filters: ++ */ ++static PkFilterEnum ++backend_get_filters (PkBackend *backend) ++{ ++ return (PK_FILTER_ENUM_GUI | ++ PK_FILTER_ENUM_INSTALLED | ++ PK_FILTER_ENUM_DEVELOPMENT); ++} ++ ++/** ++ * pk_backend_bool_to_text: ++ */ ++static const gchar * ++pk_backend_bool_to_text (gboolean value) ++{ ++ if (value == TRUE) { ++ return "yes"; ++ } ++ return "no"; ++} ++ ++ ++/** ++ * pk_backend_search_name: ++ */ ++static void ++backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search) ++{ ++ gchar *filters_text; ++ filters_text = pk_filter_enums_to_text (filters); ++ pk_backend_spawn_helper (spawn, "search-name.pl", filters_text, search, NULL); ++ g_free (filters_text); ++} ++ ++/** ++ * backend_get_details: ++ */ ++static void ++backend_get_details (PkBackend *backend, const gchar *package_id) ++{ ++ pk_backend_spawn_helper (spawn, "get-details.pl", package_id, NULL); ++} ++ ++/** ++ * backend_get_files: ++ */ ++static void ++backend_get_files (PkBackend *backend, const gchar *package_id) ++{ ++ pk_backend_spawn_helper (spawn, "get-files.pl", package_id, NULL); ++} ++ ++/** ++ * backend_get_depends: ++ */ ++static void ++backend_get_depends (PkBackend *backend, PkFilterEnum filters, const gchar *package_id, gboolean recursive) ++{ ++ gchar *filters_text; ++ filters_text = pk_filter_enums_to_text (filters); ++ pk_backend_spawn_helper (spawn, "get-depends.pl", filters_text, package_id, pk_backend_bool_to_text (recursive), NULL); ++ g_free (filters_text); ++} ++ ++/** ++ * backend_get_updates: ++ */ ++static void ++backend_get_updates (PkBackend *backend, PkFilterEnum filters) ++{ ++ gchar *filters_text; ++ filters_text = pk_filter_enums_to_text (filters); ++ pk_backend_spawn_helper (spawn, "get-updates.pl", filters_text, NULL); ++ g_free (filters_text); ++} ++ ++/** ++ * backend_get_update_detail: ++ */ ++static void ++backend_get_update_detail (PkBackend *backend, const gchar *package_id) ++{ ++ pk_backend_spawn_helper (spawn, "get-update-detail.pl", package_id, NULL); ++} ++ ++/** ++ * backend_refresh_cache: ++ */ ++static void ++backend_refresh_cache (PkBackend *backend, gboolean force) ++{ ++ /* check network state */ ++ if (!pk_backend_is_online (backend)) { ++ pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot refresh cache whilst offline"); ++ pk_backend_finished (backend); ++ return; ++ } ++ ++ pk_backend_spawn_helper (spawn, "refresh-cache.pl", NULL); ++} ++ ++/** ++ * backend_install_packages: ++ */ ++static void ++backend_install_packages (PkBackend *backend, gchar **package_ids) ++{ ++ gchar *package_ids_temp; ++ ++ /* check network state */ ++ if (!pk_backend_is_online (backend)) { ++ pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot install when offline"); ++ pk_backend_finished (backend); ++ return; ++ } ++ ++ /* send the complete list as stdin */ ++ package_ids_temp = pk_package_ids_to_text (package_ids, "|"); ++ pk_backend_spawn_helper (spawn, "install-packages.pl", package_ids_temp, NULL); ++ g_free (package_ids_temp); ++} ++ ++/** ++ * pk_backend_remove_packages: ++ */ ++static void ++backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow_deps, gboolean autoremove) ++{ ++ gchar *package_ids_temp; ++ ++ /* send the complete list as stdin */ ++ package_ids_temp = pk_package_ids_to_text (package_ids, "|"); ++ pk_backend_spawn_helper (spawn, "remove-packages.pl", pk_backend_bool_to_text (allow_deps), package_ids_temp, NULL); ++ g_free (package_ids_temp); ++} ++ ++/** ++ * pk_backend_search_group: ++ */ ++static void ++backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *search) ++{ ++ gchar *filters_text; ++ filters_text = pk_filter_enums_to_text (filters); ++ pk_backend_spawn_helper (spawn, "search-group.pl", filters_text, search, NULL); ++ g_free (filters_text); ++} ++ ++/** ++ * backend_get_packages: ++ */ ++static void ++backend_get_packages (PkBackend *backend, PkFilterEnum filters) ++{ ++ gchar *filters_text; ++ filters_text = pk_filter_enums_to_text (filters); ++ pk_backend_spawn_helper (spawn, "get-packages.pl", filters_text, NULL); ++ g_free (filters_text); ++} ++ ++/** ++ * backend_get_requires: ++ */ ++static void ++backend_get_requires (PkBackend *backend, PkFilterEnum filters, const gchar *package_id, gboolean recursive) ++{ ++ gchar *filters_text; ++ filters_text = pk_filter_enums_to_text (filters); ++ pk_backend_spawn_helper (spawn, "get-requires.pl", filters_text, package_id, pk_backend_bool_to_text (recursive), NULL); ++ g_free (filters_text); ++} ++ ++/** ++ * pk_backend_search_details: ++ */ ++static void ++backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *search) ++{ ++ gchar *filters_text; ++ filters_text = pk_filter_enums_to_text (filters); ++ pk_backend_spawn_helper (spawn, "search-details.pl", filters_text, search, NULL); ++ g_free (filters_text); ++} ++ ++/** ++ * pk_backend_search_file: ++ */ ++static void ++backend_search_file (PkBackend *backend, PkFilterEnum filters, const gchar *search) ++{ ++ gchar *filters_text; ++ filters_text = pk_filter_enums_to_text (filters); ++ pk_backend_spawn_helper (spawn, "search-file.pl", filters_text, search, NULL); ++ g_free (filters_text); ++} ++ ++/** ++ * pk_backend_resolve: ++ */ ++static void ++backend_resolve (PkBackend *backend, PkFilterEnum filters, const gchar *package_id) ++{ ++ gchar *filters_text; ++ filters_text = pk_filter_enums_to_text (filters); ++ pk_backend_spawn_helper (spawn, "resolve.pl", filters_text, package_id, NULL); ++ g_free (filters_text); ++} ++ ++/** ++ * pk_backend_update_packages: ++ */ ++static void ++backend_update_packages (PkBackend *backend, gchar **package_ids) ++{ ++ gchar *package_ids_temp; ++ ++ ++ /* check network state */ ++ if (!pk_backend_is_online (backend)) { ++ pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot install when offline"); ++ pk_backend_finished (backend); ++ return; ++ } ++ ++ /* send the complete list as stdin */ ++ package_ids_temp = pk_package_ids_to_text (package_ids, "|"); ++ pk_backend_spawn_helper (spawn, "update-packages.pl", package_ids_temp, NULL); ++ g_free (package_ids_temp); ++} ++ ++ ++PK_BACKEND_OPTIONS ( ++ "URPMI", /* description */ ++ "Aurelien Lefebvre ", /* author */ ++ backend_initialize, /* initalize */ ++ backend_destroy, /* destroy */ ++ backend_get_groups, /* get_groups */ ++ backend_get_filters, /* get_filters */ ++ NULL, /* cancel */ ++ backend_get_depends, /* get_depends */ ++ backend_get_details, /* get_details */ ++ backend_get_files, /* get_files */ ++ backend_get_packages, /* get_packages */ ++ NULL, /* get_repo_list */ ++ backend_get_requires, /* get_requires */ ++ backend_get_update_detail, /* get_update_detail */ ++ backend_get_updates, /* get_updates */ ++ NULL, /* install_files */ ++ backend_install_packages, /* install_packages */ ++ NULL, /* install_signature */ ++ backend_refresh_cache, /* refresh_cache */ ++ backend_remove_packages, /* remove_packages */ ++ NULL, /* repo_enable */ ++ NULL, /* repo_set_data */ ++ backend_resolve, /* resolve */ ++ NULL, /* rollback */ ++ backend_search_details, /* search_details */ ++ backend_search_file, /* search_file */ ++ backend_search_group, /* search_group */ ++ backend_search_name, /* search_name */ ++ NULL, /* service_pack */ ++ backend_update_packages, /* update_packages */ ++ NULL, /* update_system */ ++ NULL /* what_provides */ ++); ++ +diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py +index 5b2da8f..d70d8dc 100644 +--- a/backends/yum/helpers/yumBackend.py ++++ b/backends/yum/helpers/yumBackend.py +@@ -901,14 +901,16 @@ class PackageKitYumBackend(PackageKitBaseBackend): + if pkg and not inst: + repo = self.yumbase.repos.getRepo(pkg.repoid) + if not already_warned and not repo.gpgcheck: +- self.message(MESSAGE_WARNING,"The package %s was installed untrusted from %s." % (pkg.name, repo)) ++ self.message(MESSAGE_WARNING,"The untrusted package %s will be installed from %s." % (pkg.name, repo)) + already_warned = True + txmbr = self.yumbase.install(name=pkg.name) + txmbrs.extend(txmbr) ++ if inst: ++ self.error(ERROR_PACKAGE_ALREADY_INSTALLED,"The package %s is already installed", pkg.name) + if txmbrs: + self._runYumTransaction() + else: +- self.error(ERROR_PACKAGE_ALREADY_INSTALLED,"The package is already installed") ++ self.error(ERROR_PACKAGE_ALREADY_INSTALLED,"The packages failed to be installed") + + def _checkForNewer(self,po): + pkgs = self.yumbase.pkgSack.returnNewestByName(name=po.name) +@@ -927,6 +929,10 @@ class PackageKitYumBackend(PackageKitBaseBackend): + if inst_file.endswith('.src.rpm'): + self.error(ERROR_CANNOT_INSTALL_SOURCE_PACKAGE,'Backend will not install a src rpm file') + return ++ for inst_file in inst_files: ++ if not inst_file.endswith('.rpm'): ++ self.error(ERROR_INVALID_PACKAGE_FILE,'Only rpm packages are supported') ++ return + self._check_init() + self.allow_cancel(False); + self.percentage(0) +@@ -1056,8 +1062,11 @@ class PackageKitYumBackend(PackageKitBaseBackend): + + def _format_msgs(self,msgs): + if isinstance(msgs,basestring): +- msgs = msgs.split('\n') +- return ";".join(msgs) ++ msgs = msgs.split('\n') ++ text = ";".join(msgs) ++ text = text.replace("Missing Dependency: ","") ++ text = text.replace(" (installed)","") ++ return text + + def _runYumTransaction(self,removedeps=None): + ''' +@@ -1092,16 +1101,19 @@ class PackageKitYumBackend(PackageKitBaseBackend): + if not keyData: + self.error(ERROR_BAD_GPG_SIGNATURE, + "GPG key not imported, and no GPG information was found.") +- + id = self._pkg_to_id(keyData['po']) ++ fingerprint = keyData['fingerprint'] ++ hex_fingerprint = "%02x" * len(fingerprint) % tuple(map(ord, fingerprint)) ++ # Borrowed from http://mail.python.org/pipermail/python-list/2000-September/053490.html ++ + self.repo_signature_required(id, + keyData['po'].repoid, +- keyData['keyurl'], ++ keyData['keyurl'].replace("file://",""), + keyData['userid'], + keyData['hexkeyid'], +- keyData['fingerprint'], +- keyData['timestamp'], +- 'GPG') ++ hex_fingerprint, ++ time.ctime(keyData['timestamp']), ++ 'gpg') + self.error(ERROR_GPG_FAILURE,"GPG key %s required" % keyData['hexkeyid']) + except yum.Errors.YumBaseError,ye: + message = self._format_msgs(ye.value) +@@ -1110,7 +1122,7 @@ class PackageKitYumBackend(PackageKitBaseBackend): + else: + self.error(ERROR_TRANSACTION_ERROR,message) + +- def remove(self,allowdep,package): ++ def remove_packages(self,allowdep,package): + ''' + Implement the {backend}-remove functionality + Needed to be implemented in a sub class +@@ -1394,6 +1406,10 @@ class PackageKitYumBackend(PackageKitBaseBackend): + typ = ref['type'] + href = ref['href'] + title = ref['title'] or "" ++ ++ # Description can sometimes have ';' in them, and we use that as the delimiter ++ title = title.replace(";",",") ++ + if href: + if typ in ('bugzilla','cve'): + urls[typ].append("%s;%s" % (href,title)) +@@ -1555,11 +1571,7 @@ class DownloadCallback(BaseMeter): + ''' + Get the name of the package being downloaded + ''' +- if self.text and type(self.text) == type(""): +- name = self.text +- else: +- name = self.basename +- return name ++ return self.basename + + def updateProgress(self,name,frac,fread,ftime): + ''' +diff --git a/backends/yum2/helpers/yumDBUSBackend.py b/backends/yum2/helpers/yumDBUSBackend.py +index 29f5b03..a708a0c 100755 +--- a/backends/yum2/helpers/yumDBUSBackend.py ++++ b/backends/yum2/helpers/yumDBUSBackend.py +@@ -823,15 +823,24 @@ class PackageKitYumBackend(PackageKitBaseBackend): + self.PercentageChanged(0) + self.StatusChanged(STATUS_RUNNING) + +- pkg,inst = self._findPackage(package) +- if pkg: ++ txmbrs = [] ++ already_warned = False ++ for package in packages: ++ pkg,inst = self._findPackage(package) ++ if pkg and not inst: ++ repo = self.yumbase.repos.getRepo(pkg.repoid) ++ if not already_warned and not repo.gpgcheck: ++ self.message(MESSAGE_WARNING,"The untrusted package %s will be installed from %s." % (pkg.name, repo)) ++ already_warned = True ++ txmbr = self.yumbase.install(name=pkg.name) ++ txmbrs.extend(txmbr) + if inst: + self._unlock_yum() +- self.ErrorCode(ERROR_PACKAGE_ALREADY_INSTALLED,'Package already installed') ++ self.ErrorCode(ERROR_PACKAGE_ALREADY_INSTALLED,"The package %s is already installed", pkg.name) + self.Finished(EXIT_FAILED) + return ++ if txmbrs: + try: +- txmbr = self.yumbase.install(name=pkg.name) + successful = self._runYumTransaction() + if not successful: + # _runYumTransaction unlocked yum, set the error code, and called Finished. +@@ -844,7 +853,7 @@ class PackageKitYumBackend(PackageKitBaseBackend): + return + else: + self._unlock_yum() +- self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,"Package was not found") ++ self.ErrorCode(ERROR_PACKAGE_ALREADY_INSTALLED,"The packages failed to be installed") + self.Finished(EXIT_FAILED) + return + +@@ -1761,13 +1770,15 @@ class PackageKitYumBackend(PackageKitBaseBackend): + "GPG key not imported, but no GPG information received from Yum.") + self.Finished(EXIT_FAILED) + return False +- self.RepoSignatureRequired(keyData['po'].repoid, +- keyData['keyurl'], ++ id = self._pkg_to_id(keyData['po']) ++ self.RepoSignatureRequired(id, ++ keyData['po'].repoid, ++ keyData['keyurl'].replace("file://",""), + keyData['userid'], + keyData['hexkeyid'], + keyData['fingerprint'], +- keyData['timestamp'], +- SIGTYE_GPG) ++ time.ctime(keyData['timestamp']), ++ SIGTYPE_GPG) + self._unlock_yum() + self.ErrorCode(ERROR_GPG_FAILURE,"GPG key not imported.") + self.Finished(EXIT_FAILED) +@@ -1893,6 +1904,10 @@ class PackageKitYumBackend(PackageKitBaseBackend): + type_ = ref['type'] + href = ref['href'] + title = ref['title'] or "" ++ ++ # Description can sometimes have ';' in them, and we use that as the delimiter ++ title = title.replace(";",",") ++ + if href: + if type_ in ('bugzilla', 'cve'): + urls[type_].append("%s;%s" % (href, title)) +diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp +index 15c4b4f..a971707 100644 +--- a/backends/zypp/pk-backend-zypp.cpp ++++ b/backends/zypp/pk-backend-zypp.cpp +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -47,7 +48,6 @@ + #include + #include + #include +-#include + #include + + #include +@@ -90,12 +90,13 @@ std::map *> _signatures; + static void + backend_initialize (PkBackend *backend) + { +- zypp::base::LogControl::instance ().logfile("/var/log/pk_backend_zypp"); ++ zypp_logging (); + pk_debug ("zypp_backend_initialize"); + EventDirector *eventDirector = new EventDirector (backend); + _eventDirectors [backend] = eventDirector; + std::vector *signature = new std::vector (); + _signatures [backend] = signature; ++ _updating_self = FALSE; + } + + /** +@@ -287,7 +288,9 @@ backend_get_filters (PkBackend *backend) + return (PkFilterEnum) (PK_FILTER_ENUM_INSTALLED | + PK_FILTER_ENUM_NOT_INSTALLED | + PK_FILTER_ENUM_ARCH | +- PK_FILTER_ENUM_NOT_ARCH); ++ PK_FILTER_ENUM_NOT_ARCH | ++ PK_FILTER_ENUM_SOURCE | ++ PK_FILTER_ENUM_NOT_SOURCE); + } + + static gboolean +@@ -403,7 +406,7 @@ backend_get_depends_thread (PkBackend *backend) + package_id_temp = pk_package_id_build (it->second.name ().c_str(), + it->second.edition ().asString ().c_str(), + it->second.arch ().c_str(), +- it->second.repository ().name ().c_str()); ++ it->second.repository ().alias ().c_str()); + + zypp::PoolItem item = zypp::ResPool::instance ().find (it->second); + +@@ -570,6 +573,32 @@ backend_refresh_cache (PkBackend *backend, gboolean force) + pk_backend_thread_create (backend, backend_refresh_cache_thread); + } + ++/* If a critical self update (see qualifying steps below) is available then only show/install that update first. ++ 1. there is a patch available with the tag set ++ 2. The patch contains the package "PackageKit" or "gnome-packagekit ++*/ ++/*static gboolean ++check_for_self_update (PkBackend *backend, std::set *candidates) ++{ ++ std::set::iterator cb = candidates->begin (), ce = candidates->end (), ci; ++ for (ci = cb; ci != ce; ++ci) { ++ zypp::ResObject::constPtr res = ci->resolvable(); ++ if (zypp::isKind(res)) { ++ zypp::Patch::constPtr patch = zypp::asKind(res); ++ //pk_debug ("restart_suggested is %d",(int)patch->restartSuggested()); ++ if (patch->restartSuggested ()) { ++ if (!strcmp (PACKAGEKIT_RPM_NAME, res->satSolvable ().name ().c_str ()) || ++ !strcmp (GNOME_PACKAGKEKIT_RPM_NAME, res->satSolvable ().name ().c_str ())) { ++ g_free (update_self_patch_name); ++ update_self_patch_name = zypp_build_package_id_from_resolvable (res->satSolvable ()); ++ return TRUE; ++ } ++ } ++ } ++ } ++ return FALSE; ++}*/ ++ + static gboolean + backend_get_updates_thread (PkBackend *backend) + { +@@ -586,12 +615,23 @@ backend_get_updates_thread (PkBackend *backend) + pk_backend_set_percentage (backend, 40); + + // get all Packages and Patches for Update +- std::set *candidates = zypp_get_updates (); +- std::set *candidates2 = zypp_get_patches (); ++ std::set *candidates = zypp_get_patches (); ++ std::set *candidates2 = new std::set (); ++ ++ if (!_updating_self) { ++ // exclude the patch-repository ++ std::string patchRepo; ++ if (!candidates->empty ()) { ++ patchRepo = candidates->begin ()->resolvable ()->repoInfo ().alias (); ++ } ++ ++ candidates2 = zypp_get_updates (patchRepo); + +- candidates->insert (candidates2->begin (), candidates2->end ()); ++ candidates->insert (candidates2->begin (), candidates2->end ()); ++ } + + pk_backend_set_percentage (backend, 80); ++ + std::set::iterator cb = candidates->begin (), ce = candidates->end (), ci; + for (ci = cb; ci != ce; ++ci) { + zypp::ResObject::constPtr res = ci->resolvable(); +@@ -716,7 +756,7 @@ backend_install_files_thread (PkBackend *backend) + gboolean found = FALSE; + + for (std::vector::iterator it = solvables->begin (); it != solvables->end (); it ++) { +- if (it->repository ().name () == "PK_TMP_DIR") { ++ if (it->repository ().alias () == "PK_TMP_DIR") { + item = new zypp::PoolItem(*it); + found = TRUE; + break; +@@ -861,14 +901,28 @@ backend_update_system_thread (PkBackend *backend) + zypp::ResPool pool = zypp_build_pool (TRUE); + pk_backend_set_percentage (backend, 40); + +- // get all Packages for Update +- std::set *candidates = zypp_get_updates (); + //get all Patches for Update +- std::set *candidates2 = zypp_get_patches (); ++ std::set *candidates = zypp_get_patches (); ++ std::set *candidates2 = new std::set (); ++ ++ if (_updating_self) { ++ pk_backend_require_restart (backend, PK_RESTART_ENUM_SESSION, "Package Management System updated - restart needed"); ++ _updating_self = FALSE; ++ } ++ else { ++ //disabling patchrepo ++ std::string patchRepo; ++ if (!candidates->empty ()) { ++ patchRepo = candidates->begin ()->resolvable ()->repoInfo ().alias (); ++ } ++ ++ //get all Updates ++ candidates2 = zypp_get_updates (patchRepo); + +- //concatenate these sets ++ //concatenate these sets + +- candidates->insert (candidates->begin (), candidates->end ()); ++ candidates->insert (candidates2->begin (), candidates2->end ()); ++ } + + pk_backend_set_percentage (backend, 80); + std::set::iterator cb = candidates->begin (), ce = candidates->end (), ci; +@@ -1332,6 +1386,10 @@ backend_repo_enable (PkBackend *backend, const gchar *rid, gboolean enabled) + repo = manager.getRepositoryInfo (rid); + repo.setEnabled (enabled); + manager.modifyRepository (rid, repo); ++ if (!enabled) { ++ zypp::Repository repository = zypp::sat::Pool::instance ().reposFind (repo.alias ()); ++ repository.eraseFromPool (); ++ } + } catch (const zypp::repo::RepoNotFoundException &ex) { + pk_backend_error_code (backend, PK_ERROR_ENUM_REPO_NOT_FOUND, "Couldn't find the specified repository"); + pk_backend_finished (backend); +@@ -1463,6 +1521,13 @@ backend_update_packages_thread (PkBackend *backend) + gchar **package_ids; + package_ids = pk_backend_get_strv (backend, "package_ids"); + ++ zypp_get_patches (); // make shure _updating_self is set ++ ++ if (_updating_self) { ++ pk_debug ("updating self and setting restart"); ++ pk_backend_require_restart (backend, PK_RESTART_ENUM_SESSION, "Package Management System updated - restart needed"); ++ _updating_self = FALSE; ++ } + for (guint i = 0; i < g_strv_length (package_ids); i++) { + zypp::sat::Solvable solvable = zypp_get_package_by_id (package_ids[i]); + zypp::PoolItem item = zypp::ResPool::instance ().find (solvable); +diff --git a/backends/zypp/zypp-utils.cpp b/backends/zypp/zypp-utils.cpp +index 2b848f0..d81d0dd 100644 +--- a/backends/zypp/zypp-utils.cpp ++++ b/backends/zypp/zypp-utils.cpp +@@ -25,6 +25,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -45,6 +47,7 @@ + #include + #include + #include ++#include + + #include + +@@ -53,6 +56,7 @@ + #include "zypp-utils.h" + + gchar * _repoName; ++gboolean _updating_self = FALSE; + /** + * Collect items, select best edition. This is used to find the best + * available or installed. The name of the class is a bit misleading though ... +@@ -98,6 +102,34 @@ get_zypp () + return zypp; + } + ++/** ++ * Enable and rotate zypp logging ++ */ ++gboolean ++zypp_logging () ++{ ++ gchar *file = g_strdup ("/var/log/pk_backend_zypp"); ++ gchar *file_old = g_strdup ("/var/log/pk_backend_zypp-1"); ++ ++ if (g_file_test (file, G_FILE_TEST_EXISTS)) { ++ struct stat buffer; ++ g_stat (file, &buffer); ++ // if the file is bigger than 10 MB rotate ++ if ((guint)buffer.st_size > 10485760) { ++ if (g_file_test (file_old, G_FILE_TEST_EXISTS)) ++ g_remove (file_old); ++ g_rename (file, file_old); ++ } ++ } ++ ++ zypp::base::LogControl::instance ().logfile(file); ++ ++ g_free (file); ++ g_free (file_old); ++ ++ return TRUE; ++} ++ + gboolean + zypp_is_changeable_media (const zypp::Url &url) + { +@@ -120,13 +152,13 @@ zypp_build_pool (gboolean include_local) + zypp::ZYpp::Ptr zypp = get_zypp (); + + if (include_local == TRUE) { +- //FIXME have to wait for fix in zypp (repeated loading of target) +- if (zypp::sat::Pool::instance().reposFind( zypp::sat::Pool::systemRepoName() ).solvablesEmpty ()) +- { +- // Add local resolvables +- zypp::Target_Ptr target = zypp->target (); +- target->load (); +- } ++ //FIXME have to wait for fix in zypp (repeated loading of target) ++ if (zypp::sat::Pool::instance().reposFind( zypp::sat::Pool::systemRepoAlias() ).solvablesEmpty ()) ++ { ++ // Add local resolvables ++ zypp::Target_Ptr target = zypp->target (); ++ target->load (); ++ } + } + + // Add resolvables from enabled repos +@@ -163,16 +195,16 @@ zypp_build_pool (gboolean include_local) + zypp::ResPool + zypp_build_local_pool () + { +- zypp::sat::Pool pool = zypp::sat::Pool::instance (); ++ zypp::sat::Pool pool = zypp::sat::Pool::instance (); + zypp::ZYpp::Ptr zypp = get_zypp (); + + try { + for (zypp::detail::RepositoryIterator it = pool.reposBegin (); it != pool.reposEnd (); it++){ + if (! it->isSystemRepo ()) +- pool.reposErase(it->name ()); ++ pool.reposErase(it->alias ()); + } + +- if (zypp::sat::Pool::instance().reposFind( zypp::sat::Pool::systemRepoName() ).solvablesEmpty ()) ++ if (zypp::sat::Pool::instance().reposFind( zypp::sat::Pool::systemRepoAlias() ).solvablesEmpty ()) + { + // Add local resolvables + zypp::Target_Ptr target = zypp->target (); +@@ -371,27 +403,49 @@ zypp_build_package_id_from_resolvable (zypp::sat::Solvable resolvable) + package_id = pk_package_id_build (resolvable.name ().c_str (), + resolvable.edition ().asString ().c_str (), + resolvable.arch ().asString ().c_str (), +- resolvable.repository (). name().c_str ()); ++ resolvable.repository (). alias().c_str ()); + + return package_id; + } + ++zypp::RepoInfo ++zypp_get_Repository (PkBackend *backend, const gchar *alias) ++{ ++ zypp::RepoInfo info; ++ ++ try { ++ zypp::RepoManager manager; ++ info = manager.getRepositoryInfo (alias); ++ } catch (const zypp::repo::RepoNotFoundException &ex) { ++ pk_backend_error_code (backend, PK_ERROR_ENUM_REPO_NOT_FOUND, ex.asUserString().c_str() ); ++ return zypp::RepoInfo (); ++ } ++ ++ return info; ++} ++ + gboolean + zypp_signature_required (PkBackend *backend, const zypp::PublicKey &key) + { + gboolean ok = FALSE; + + if (std::find (_signatures[backend]->begin (), _signatures[backend]->end (), key.id ()) == _signatures[backend]->end ()) { ++ zypp::RepoInfo info = zypp_get_Repository (backend, _repoName); ++ if (info.type () == zypp::repo::RepoType::NONE) { ++ pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, "Repository unknown"); ++ return FALSE; ++ } ++ + pk_backend_repo_signature_required (backend, + "dummy;0.0.1;i386;data", + _repoName, +- key.path ().c_str (), +- key.id ().c_str (), ++ info.baseUrlsBegin ()->asString ().c_str (), ++ key.name ().c_str (), + key.id ().c_str (), + key.fingerprint ().c_str (), + key.created ().asString ().c_str (), + PK_SIGTYPE_ENUM_GPG); +- pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, "Repo signature verification failed"); ++ pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, "Signature verification for Repository %s failed", _repoName); + }else{ + ok = TRUE; + } +@@ -405,16 +459,22 @@ zypp_signature_required (PkBackend *backend, const std::string &file, const std: + gboolean ok = FALSE; + + if (std::find (_signatures[backend]->begin (), _signatures[backend]->end (), id) == _signatures[backend]->end ()) { ++ zypp::RepoInfo info = zypp_get_Repository (backend, _repoName); ++ if (info.type () == zypp::repo::RepoType::NONE) { ++ pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, "Repository unknown"); ++ return FALSE; ++ } ++ + pk_backend_repo_signature_required (backend, + "dummy;0.0.1;i386;data", + _repoName, +- file.c_str (), ++ info.baseUrlsBegin ()->asString ().c_str (), + id.c_str (), + id.c_str (), + "UNKNOWN", + "UNKNOWN", + PK_SIGTYPE_ENUM_GPG); +- pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, "Repo signature verification failed"); ++ pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, "Signature verification for Repository %s failed", _repoName); + }else{ + ok = TRUE; + } +@@ -428,16 +488,22 @@ zypp_signature_required (PkBackend *backend, const std::string &file) + gboolean ok = FALSE; + + if (std::find (_signatures[backend]->begin (), _signatures[backend]->end (), file) == _signatures[backend]->end ()) { +- pk_backend_repo_signature_required (backend, ++ zypp::RepoInfo info = zypp_get_Repository (backend, _repoName); ++ if (info.type () == zypp::repo::RepoType::NONE) { ++ pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, "Repository unknown"); ++ return FALSE; ++ } ++ ++ pk_backend_repo_signature_required (backend, + "dummy;0.0.1;i386;data", + _repoName, +- file.c_str (), ++ info.baseUrlsBegin ()->asString ().c_str (), + "UNKNOWN", + file.c_str (), + "UNKNOWN", + "UNKNOWN", + PK_SIGTYPE_ENUM_GPG); +- pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, "Repo signature verification failed"); ++ pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, "Signature verification for Repository %s failed", _repoName); + }else{ + ok = TRUE; + } +@@ -481,6 +547,12 @@ zypp_emit_packages_in_list (PkBackend *backend, std::vector + system_and_package_are_x86 (*it)) + print = FALSE; + } ++ if (i == PK_FILTER_ENUM_SOURCE && !(zypp::isKind(*it))) { ++ print = FALSE; ++ } ++ if (i == PK_FILTER_ENUM_NOT_SOURCE && zypp::isKind(*it)) { ++ print = FALSE; ++ } + //const gchar * myarch = zypp::ZConfig::defaultSystemArchitecture().asString().c_str(); + //pk_debug ("my default arch is %s", myarch); + } +@@ -527,7 +599,7 @@ zypp_find_arch_update_item (const zypp::ResPool & pool, zypp::PoolItem item) + } + + std::set * +-zypp_get_updates () ++zypp_get_updates (std::string repo) + { + std::set *pks = new std::set (); + zypp::ResPool pool = zypp::ResPool::instance (); +@@ -542,7 +614,12 @@ zypp_get_updates () + zypp::PoolItem candidate = zypp_find_arch_update_item (pool, *it); + if (!candidate.resolvable ()) + continue; +- pks->insert (candidate); ++ if (repo.empty ()) { ++ pks->insert (candidate); ++ }else{ ++ if (candidate->repoInfo ().alias ().compare (repo) != 0) ++ pks->insert (candidate); ++ } + } + + return pks; +@@ -552,6 +629,7 @@ std::set * + zypp_get_patches () + { + std::set *patches = new std::set (); ++ _updating_self = FALSE; + + zypp::ZYpp::Ptr zypp; + zypp = get_zypp (); +@@ -561,8 +639,18 @@ zypp_get_patches () + for (zypp::ResPoolProxy::const_iterator it = zypp->poolProxy ().byKindBegin(); + it != zypp->poolProxy ().byKindEnd(); it ++) { + // check if patch is needed +- if((*it)->candidateObj ().isBroken()) ++ if((*it)->candidateObj ().isBroken()) { + patches->insert ((*it)->candidateObj ()); ++ zypp::Patch::constPtr patch = zypp::asKind((*it)->candidateObj ().resolvable ()); ++ ++ // check if the patch updates libzypp or packageKit and show only this one ++ if (patch->restartSuggested ()) { ++ _updating_self = TRUE; ++ patches->clear (); ++ patches->insert ((*it)->candidateObj ()); ++ break; ++ } ++ } + + } + +diff --git a/backends/zypp/zypp-utils.h b/backends/zypp/zypp-utils.h +index 9e3bad1..4f785cf 100644 +--- a/backends/zypp/zypp-utils.h ++++ b/backends/zypp/zypp-utils.h +@@ -62,6 +62,11 @@ typedef enum { + */ + extern std::map *> _signatures; + ++/** Used to show/install only an update to ourself. This way if we find a critical bug ++ * in the way we update packages we will install the fix before any other updates. ++ */ ++extern gboolean _updating_self; ++ + /** A string to store the last refreshed repo + * this is needed for gpg-key handling stuff (UGLY HACK) + * FIXME +@@ -70,6 +75,11 @@ extern gchar *_repoName; + + zypp::ZYpp::Ptr get_zypp (); + ++/** ++ * Enable and rotate logging ++ */ ++gboolean zypp_logging (); ++ + gboolean zypp_is_changeable_media (const zypp::Url &url); + + /** +@@ -125,6 +135,12 @@ zypp::sat::Solvable zypp_get_package_by_id (const gchar *package_id); + gchar * zypp_build_package_id_from_resolvable (zypp::sat::Solvable resolvable); + + /** ++ * Get the RepoInfo ++ */ ++zypp::RepoInfo ++zypp_get_Repository (PkBackend *backend, const gchar *alias); ++ ++/** + * Ask the User if it is OK to import an GPG-Key for a repo + */ + gboolean zypp_signature_required (PkBackend *backend, const zypp::PublicKey &key); +@@ -145,9 +161,9 @@ gboolean zypp_signature_required (PkBackend *backend, const std::string &file, c + zypp::PoolItem zypp_find_arch_update_item (const zypp::ResPool & pool, zypp::PoolItem item); + + /** +- * Returns a set of all packages the could be updated ++ * Returns a set of all packages the could be updated (you're able to exclude a repo) + */ +-std::set * zypp_get_updates (); ++std::set * zypp_get_updates (std::string repo); + + /** + * Returns a set of all patches the could be installed +diff --git a/client/pk-console.c b/client/pk-console.c +index 5a05a8e..ec93978 100644 +--- a/client/pk-console.c ++++ b/client/pk-console.c +@@ -76,7 +76,6 @@ pk_console_bar (guint subpercentage) + return; + } + if (!has_output_bar) { +- pk_warning ("no bar"); + return; + } + /* restore cursor */ +@@ -487,6 +486,7 @@ pk_console_perhaps_resolve (PkClient *client, PkFilterEnum filter, const gchar * + guint i; + guint length; + PkPackageItem *item; ++ PkPackageList *list; + + /* have we passed a complete package_id? */ + valid = pk_package_id_check (package); +@@ -508,7 +508,9 @@ pk_console_perhaps_resolve (PkClient *client, PkFilterEnum filter, const gchar * + } + + /* get length of items found */ +- length = pk_client_package_buffer_get_size (client_task); ++ list = pk_client_get_package_list (client_task); ++ length = pk_package_list_get_size (list); ++ g_object_unref (list); + + /* didn't resolve to anything, try to get a provide */ + if (length == 0) { +@@ -524,8 +526,9 @@ pk_console_perhaps_resolve (PkClient *client, PkFilterEnum filter, const gchar * + } + } + +- /* get length of items found again (we might have has success) */ +- length = pk_client_package_buffer_get_size (client_task); ++ /* get length of items found again (we might have had success) */ ++ list = pk_client_get_package_list (client_task); ++ length = pk_package_list_get_size (list); + if (length == 0) { + pk_warning (_("Could not find a package match")); + return NULL; +@@ -533,7 +536,7 @@ pk_console_perhaps_resolve (PkClient *client, PkFilterEnum filter, const gchar * + + /* only found one, great! */ + if (length == 1) { +- item = pk_client_package_buffer_get_item (client_task, 0); ++ item = pk_package_list_get_item (list, 0); + return g_strdup (item->package_id); + } + +@@ -543,14 +546,16 @@ pk_console_perhaps_resolve (PkClient *client, PkFilterEnum filter, const gchar * + } + g_print ("%s\n", _("There are multiple package matches")); + for (i=0; ipackage_id); + } + + /* find out what package the user wants to use */ + i = pk_console_get_number (_("Please enter the package number: "), length); +- item = pk_client_package_buffer_get_item (client_task, i-1); ++ item = pk_package_list_get_item (list, i-1); + pk_debug ("package_id = %s", item->package_id); ++ g_object_unref (list); ++ + return g_strdup (item->package_id); + } + +@@ -574,7 +579,8 @@ pk_console_install_stuff (PkClient *client, gchar **packages, GError **error) + array_files = g_ptr_array_new (); + length = g_strv_length (packages); + for (i=2; imessage); + g_error_free (error); +- return NULL; ++ goto out; + } + + ret = pk_client_search_file (client, PK_FILTER_ENUM_INSTALLED, filename, &error); + if (!ret) { + pk_warning ("failed to search file: %s", error->message); + g_error_free (error); +- return NULL; ++ goto out; + } + + /* check that we only matched one package */ +- size = pk_client_package_buffer_get_size (client); ++ list = pk_client_get_package_list (client); ++ size = pk_package_list_get_size (list); + if (size != 1) { + pk_warning ("not correct size, %i", size); +- return NULL; ++ goto out; + } + + /* get the item */ +- item = pk_client_package_buffer_get_item (client, 0); ++ item = pk_package_list_get_item (list, 0); + if (item == NULL) { + pk_error ("cannot get item"); +- return NULL; ++ goto out; + } + + /* get the package name */ + pid = pk_package_id_new_from_string (item->package_id); + if (pid == NULL) { + pk_error ("cannot allocate package id"); +- return NULL; ++ goto out; + } + + /* strip the name */ + name = g_strdup (pid->name); + pk_package_id_free (pid); + +- /* return a copy */ ++out: ++ if (list != NULL) { ++ g_object_unref (list); ++ } + return name; + } + +diff --git a/client/pk-import-specspo.c b/client/pk-import-specspo.c +index cf14cc2..bffd45b 100644 +--- a/client/pk-import-specspo.c ++++ b/client/pk-import-specspo.c +@@ -56,6 +56,7 @@ pk_import_specspo_get_summary (const gchar *name) + gboolean ret; + PkPackageItem *item; + GError *error = NULL; ++ PkPackageList *list; + + ret = pk_client_reset (client, &error); + if (!ret) { +@@ -74,18 +75,21 @@ pk_import_specspo_get_summary (const gchar *name) + } + + /* check that we only matched one package */ +- size = pk_client_package_buffer_get_size (client); ++ list = pk_client_get_package_list (client); ++ size = pk_package_list_get_size (list); + if (size != 1) { + pk_warning ("not correct size, %i", size); + return NULL; + } + + /* get the item */ +- item = pk_client_package_buffer_get_item (client, 0); ++ item = pk_package_list_get_item (list, 0); + if (item == NULL) { + pk_error ("cannot get item"); ++ g_object_unref (list); + return NULL; + } ++ g_object_unref (list); + + return item->summary; + } +diff --git a/configure.ac b/configure.ac +index f614d2b..7510b03 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -223,7 +223,6 @@ AC_ARG_ENABLE(gprof, AS_HELP_STRING([--enable-gprof],[compile with gprof support + # backends + AC_ARG_ENABLE(alpm, AS_HELP_STRING([--enable-alpm],[use the ALPM backend]),enable_alpm=$enableval,enable_alpm=no) + AC_ARG_ENABLE(apt, AS_HELP_STRING([--enable-apt],[use the APT backend]),enable_apt=$enableval,enable_apt=no) +-AC_ARG_ENABLE(apt2, AS_HELP_STRING([--enable-apt2],[use the DBus based APT backend]),enable_apt2=$enableval,enable_apt2=no) + AC_ARG_ENABLE(box, AS_HELP_STRING([--enable-box],[use the BOX backend]),enable_box=$enableval,enable_box=no) + AC_ARG_ENABLE(conary, AS_HELP_STRING([--enable-conary],[use the CONARY backend]),enable_conary=$enableval,enable_conary=no) + AC_ARG_ENABLE(dummy, AS_HELP_STRING([--enable-dummy],[use the dummy backend]),enable_dummy=$enableval,enable_dummy=yes) +@@ -231,6 +230,7 @@ AC_ARG_ENABLE(opkg, AS_HELP_STRING([--enable-opkg],[use the OPKG backend]),enabl + AC_ARG_ENABLE(pisi, AS_HELP_STRING([--enable-pisi],[use the PiSi backend]),enable_pisi=$enableval,enable_pisi=no) + AC_ARG_ENABLE(poldek, AS_HELP_STRING([--enable-poldek],[use the poldek backend]),enable_poldek=$enableval,enable_poldek=no) + AC_ARG_ENABLE(smart, AS_HELP_STRING([--enable-smart],[use the SMART backend]),enable_smart=$enableval,enable_smart=no) ++AC_ARG_ENABLE(urpmi, AS_HELP_STRING([--enable-urpmi],[use the URPMI backend]),enable_urpmi=$enableval,enable_urpmi=no) + AC_ARG_ENABLE(yum, AS_HELP_STRING([--enable-yum],[use the YUM backend]),enable_yum=$enableval,enable_yum=no) + AC_ARG_ENABLE(yum2, AS_HELP_STRING([--enable-yum2],[use the YUM DBUS backend]),enable_yum2=$enableval,enable_yum2=no) + AC_ARG_ENABLE(zypp, AS_HELP_STRING([--enable-zypp],[use the Zypp backend]),enable_zypp=$enableval,enable_zypp=no) +@@ -238,7 +238,6 @@ AC_ARG_ENABLE(zypp, AS_HELP_STRING([--enable-zypp],[use the Zypp backend]),enabl + # export to Makefile.am's + AM_CONDITIONAL(BACKEND_TYPE_ALPM, [test x$enable_alpm = xyes], [using ALPM backend]) + AM_CONDITIONAL(BACKEND_TYPE_APT, [test x$enable_apt = xyes], [using APT backend]) +-AM_CONDITIONAL(BACKEND_TYPE_APT_DBUS, [test x$enable_apt2 = xyes], [using DBus based APT backend]) + AM_CONDITIONAL(BACKEND_TYPE_BOX, [test x$enable_box = xyes], [using BOX backend]) + AM_CONDITIONAL(BACKEND_TYPE_CONARY, [test x$enable_conary = xyes], [using CONARY backend]) + AM_CONDITIONAL(BACKEND_TYPE_DUMMY, [test x$enable_dummy = xyes], [using dummy backend]) +@@ -246,6 +245,7 @@ AM_CONDITIONAL(BACKEND_TYPE_OPKG, [test x$enable_opkg = xyes], [using OPKG backe + AM_CONDITIONAL(BACKEND_TYPE_PISI, [test x$enable_pisi = xyes], [using PiSi backend]) + AM_CONDITIONAL(BACKEND_TYPE_POLDEK, [test x$enable_poldek = xyes], [using poldek backend]) + AM_CONDITIONAL(BACKEND_TYPE_SMART, [test x$enable_smart = xyes], [using SMART backend]) ++AM_CONDITIONAL(BACKEND_TYPE_URPMI, [test x$enable_urpmi = xyes], [using URPMI backend]) + AM_CONDITIONAL(BACKEND_TYPE_YUM, [test x$enable_yum = xyes], [using YUM backend]) + AM_CONDITIONAL(BACKEND_TYPE_YUM2, [test x$enable_yum2 = xyes], [using YUM DBUS backend]) + AM_CONDITIONAL(BACKEND_TYPE_ZYPP, [test x$enable_zypp = xyes], [using Zypp backend]) +@@ -369,7 +369,7 @@ dnl --------------------------------------------------------------------------- + AC_ARG_WITH([default_backend], + AS_HELP_STRING([--with-default-backend=