diff options
Diffstat (limited to 'packages/packagekit/files')
-rw-r--r-- | packages/packagekit/files/01_d1e096c3267c1c9492041382b954e9327bc8bbec.patch (renamed from packages/packagekit/files/d1e096c3267c1c9492041382b954e9327bc8bbec.patch) | 0 | ||||
-rw-r--r-- | packages/packagekit/files/02_9ced8313fb12f0f89ad6ced7c0fdc7241ff00d77.patch | 13544 |
2 files changed, 13544 insertions, 0 deletions
diff --git a/packages/packagekit/files/d1e096c3267c1c9492041382b954e9327bc8bbec.patch b/packages/packagekit/files/01_d1e096c3267c1c9492041382b954e9327bc8bbec.patch index f050a50002..f050a50002 100644 --- a/packages/packagekit/files/d1e096c3267c1c9492041382b954e9327bc8bbec.patch +++ b/packages/packagekit/files/01_d1e096c3267c1c9492041382b954e9327bc8bbec.patch 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 <ali.sabil@gmail.com> ++# Copyright (C) 2007 Tom Parker <palfrey@tevp.net> ++# ++# 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 <richard@hughsie.com> ++# ++# Licensed under the GNU General Public License Version 2 ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++ ++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 <ali.sabil@gmail.com> ++# ++# Licensed under the GNU General Public License Version 2 ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++ ++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 <richard@hughsie.com> ++# ++# Licensed under the GNU General Public License Version 2 ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++ ++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 <richard@hughsie.com> ++# ++# Licensed under the GNU General Public License Version 2 ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++ ++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 <mvo@ubuntu.com> ++# ++# Licensed under the GNU General Public License Version 2 ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++ ++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 <mvo@ubuntu.com> ++# ++# Licensed under the GNU General Public License Version 2 ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++ ++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 <richard@hughsie.com> ++# Copyright (C) 2007 Red Hat Inc, Seth Vidal <skvidal@fedoraproject.org> ++# ++# 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 <ali.sabil@gmail.com> ++# ++# Licensed under the GNU General Public License Version 2 ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++ ++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 <richard@hughsie.com> ++# ++# Licensed under the GNU General Public License Version 2 ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++ ++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 <richard@hughsie.com> ++# ++# Licensed under the GNU General Public License Version 2 ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++ ++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 <ali.sabil@gmail.com> ++# ++# Licensed under the GNU General Public License Version 2 ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++ ++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 <ali.sabil@gmail.com> ++# ++# Licensed under the GNU General Public License Version 2 ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++ ++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 <ali.sabil@gmail.com> ++# ++# Licensed under the GNU General Public License Version 2 ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++ ++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 <ali.sabil@gmail.com> ++# ++# Licensed under the GNU General Public License Version 2 ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++ ++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 <palfrey@tevp.net> ++ * ++ * 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 <pk-backend.h> ++#include <apt-pkg/configuration.h> ++#include <sqlite3.h> ++ ++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 <source>_<type>_<group> ++ { ++ 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 <source>_<type>_<group> ++ { ++ 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 <palfrey@tevp.net> ++ * ++ * 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 <sqlite3.h> ++#include <pk-backend.h> ++ ++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 <ali.sabil@gmail.com> ++ * ++ * Licensed under the GNU General Public License Version 2 ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++#include <gmodule.h> ++#include <glib.h> ++#include <string.h> ++#include <pk-backend.h> ++#include <pk-backend-spawn.h> ++ ++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 <ali.sabil@gmail.com> ++ * ++ * Licensed under the GNU General Public License Version 2 ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++#include <gmodule.h> ++#include <glib.h> ++#include <string.h> ++#include <pk-backend.h> ++#include <pk-backend-spawn.h> ++#include "pk-sqlite-pkg-cache.h" ++#include <apt-pkg/configuration.h> ++#include <apt-pkg/init.h> ++#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 <palfrey@tevp.net> ++ * ++ * 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 <glib.h> ++#include <pk-backend.h> ++ ++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 <ali.sabil@gmail.com> ++ * Copyright (C) 2007 Tom Parker <palfrey@tevp.net> ++ * ++ * Licensed under the GNU General Public License Version 2 ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++#include <gmodule.h> ++#include <glib.h> ++#include <string.h> ++#include <pk-backend.h> ++#include <pk-backend-spawn.h> ++#include <pk-package-ids.h> ++#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 <ali.sabil@gmail.com>; Tom Parker <palfrey@tevp.net>", /* 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 <palfrey@tevp.net> ++ * ++ * 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 <glib.h> ++#include <glib/gstdio.h> ++#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 <palfrey@tevp.net> ++ * ++ * 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 <pk-backend.h> ++#include <sqlite3.h> ++ ++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 <ali.sabil@gmail.com> ++Copyright (C) 2007 Tom Parker <palfrey@tevp.net> ++Copyright (C) 2008 Sebastian Heinlein <glatzor@ubuntu.com> ++ ++Licensed under the GNU General Public License Version 2 ++ ++This program is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 2 of the License, or ++(at your option) any later version. ++""" ++ ++__author__ = "Sebastian Heinlein <devel@glatzor.de>" ++__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 <ali.sabil@gmail.com> +-# Copyright (C) 2007 Tom Parker <palfrey@tevp.net> +-# +-# 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 <richard@hughsie.com> +-# +-# Licensed under the GNU General Public License Version 2 +-# +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2 of the License, or +-# (at your option) any later version. +- +-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 <ali.sabil@gmail.com> +-# +-# Licensed under the GNU General Public License Version 2 +-# +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2 of the License, or +-# (at your option) any later version. +- +-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 <richard@hughsie.com> +-# +-# Licensed under the GNU General Public License Version 2 +-# +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2 of the License, or +-# (at your option) any later version. +- +-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 <richard@hughsie.com> +-# +-# Licensed under the GNU General Public License Version 2 +-# +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2 of the License, or +-# (at your option) any later version. +- +-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 <mvo@ubuntu.com> +-# +-# Licensed under the GNU General Public License Version 2 +-# +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2 of the License, or +-# (at your option) any later version. +- +-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 <mvo@ubuntu.com> +-# +-# Licensed under the GNU General Public License Version 2 +-# +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2 of the License, or +-# (at your option) any later version. +- +-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 <richard@hughsie.com> +-# Copyright (C) 2007 Red Hat Inc, Seth Vidal <skvidal@fedoraproject.org> +-# +-# 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 <ali.sabil@gmail.com> +-# +-# Licensed under the GNU General Public License Version 2 +-# +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2 of the License, or +-# (at your option) any later version. +- +-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 <richard@hughsie.com> +-# +-# Licensed under the GNU General Public License Version 2 +-# +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2 of the License, or +-# (at your option) any later version. +- +-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 <richard@hughsie.com> +-# +-# Licensed under the GNU General Public License Version 2 +-# +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2 of the License, or +-# (at your option) any later version. +- +-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 <ali.sabil@gmail.com> +-# +-# Licensed under the GNU General Public License Version 2 +-# +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2 of the License, or +-# (at your option) any later version. +- +-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 <ali.sabil@gmail.com> +-# +-# Licensed under the GNU General Public License Version 2 +-# +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2 of the License, or +-# (at your option) any later version. +- +-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 <ali.sabil@gmail.com> +-# +-# Licensed under the GNU General Public License Version 2 +-# +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2 of the License, or +-# (at your option) any later version. +- +-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 <ali.sabil@gmail.com> +-# +-# Licensed under the GNU General Public License Version 2 +-# +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2 of the License, or +-# (at your option) any later version. +- +-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 <palfrey@tevp.net> +- * +- * 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 <pk-backend.h> +-#include <apt-pkg/configuration.h> +-#include <sqlite3.h> +- +-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 <source>_<type>_<group> +- { +- 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 <source>_<type>_<group> +- { +- 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 <palfrey@tevp.net> +- * +- * 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 <sqlite3.h> +-#include <pk-backend.h> +- +-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 <ali.sabil@gmail.com> +- * +- * Licensed under the GNU General Public License Version 2 +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +- */ +- +-#include <gmodule.h> +-#include <glib.h> +-#include <string.h> +-#include <pk-backend.h> +-#include <pk-backend-spawn.h> +- +-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 <ali.sabil@gmail.com> +- * +- * Licensed under the GNU General Public License Version 2 +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +- */ +- +-#include <gmodule.h> +-#include <glib.h> +-#include <string.h> +-#include <pk-backend.h> +-#include <pk-backend-spawn.h> +-#include "pk-sqlite-pkg-cache.h" +-#include <apt-pkg/configuration.h> +-#include <apt-pkg/init.h> +-#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 <palfrey@tevp.net> +- * +- * 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 <glib.h> +-#include <pk-backend.h> +- +-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 <gmodule.h> +-#include <glib.h> +-#include <string.h> + #include <pk-backend.h> +-#include <pk-backend-spawn.h> +-#include <pk-package-ids.h> +-#include "pk-apt-search.h" +-#include "config.h" ++#include <pk-backend-dbus.h> + +-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 <ali.sabil@gmail.com>; Tom Parker <palfrey@tevp.net>", /* author */ ++ "Apt", /* description */ ++ "Ali Sabil <ali.sabil@gmail.com>; Tom Parker <palfrey@tevp.net>; Sebastian Heinlein <glatzor@ubuntu.com>", /* 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 <palfrey@tevp.net> +- * +- * 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 <glib.h> +-#include <glib/gstdio.h> +-#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 <palfrey@tevp.net> +- * +- * 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 <pk-backend.h> +-#include <sqlite3.h> +- +-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 <sebi@glatzor.de> ++ ++""" ++Allows to start the apt2 backend in a profling mode ++""" ++ ++__author__ = "Sebastian Heinlein <devel@glatzor.de>" ++ ++ ++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 <timlau@fedoraproject.org> ++ ++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 <ali.sabil@gmail.com> +-Copyright (C) 2007 Tom Parker <palfrey@tevp.net> +-Copyright (C) 2008 Sebastian Heinlein <glatzor@ubuntu.com> +- +-Licensed under the GNU General Public License Version 2 +- +-This program is free software; you can redistribute it and/or modify +-it under the terms of the GNU General Public License as published by +-the Free Software Foundation; either version 2 of the License, or +-(at your option) any later version. +-""" +- +-__author__ = "Sebastian Heinlein <devel@glatzor.de>" +-__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 <ali.sabil@gmail.com> +- * Copyright (C) 2007 Tom Parker <palfrey@tevp.net> +- * +- * 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.h> +-#include <pk-backend-dbus.h> +- +-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 <ali.sabil@gmail.com>; Tom Parker <palfrey@tevp.net>; Sebastian Heinlein <glatzor@ubuntu.com>", /* 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 <sebi@glatzor.de> +- +-""" +-Allows to start the apt2 backend in a profling mode +-""" +- +-__author__ = "Sebastian Heinlein <devel@glatzor.de>" +- +- +-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 <timlau@fedoraproject.org> +- +-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 <megabajt@pld-linux.org>", /* 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!^<!) { ++ ($fn) = /fn="(.*)"/; ++ } ++ elsif ( (!$options{'fuzzy'} && $_ =~ /^$search_term$/) ++ || ($options{'fuzzy'} && $_ =~ /$search_term/) ) { ++ # Fix me : Replace with pk error enum. ++ # $fn or $urpm->{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 <richard@hughsie.com> ++ * ++ * Licensed under the GNU General Public License Version 2 ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++#include <pk-backend.h> ++#include <pk-backend-spawn.h> ++#include <pk-package-ids.h> ++ ++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 <alefebvre@mandriva.com>", /* 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 <pk-debug.h> + #include <string> + #include <set> ++#include <glib/gi18n.h> + + #include <zypp/ZYppFactory.h> + #include <zypp/ResObject.h> +@@ -47,7 +48,6 @@ + #include <zypp/target/rpm/RpmDb.h> + #include <zypp/target/rpm/RpmHeader.h> + #include <zypp/target/rpm/RpmException.h> +-#include <zypp/base/LogControl.h> + #include <zypp/TmpPath.h> + + #include <zypp/sat/Solvable.h> +@@ -90,12 +90,13 @@ std::map<PkBackend *, std::vector<std::string> *> _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<std::string> *signature = new std::vector<std::string> (); + _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 <restart_suggested> tag set ++ 2. The patch contains the package "PackageKit" or "gnome-packagekit ++*/ ++/*static gboolean ++check_for_self_update (PkBackend *backend, std::set<zypp::PoolItem> *candidates) ++{ ++ std::set<zypp::PoolItem>::iterator cb = candidates->begin (), ce = candidates->end (), ci; ++ for (ci = cb; ci != ce; ++ci) { ++ zypp::ResObject::constPtr res = ci->resolvable(); ++ if (zypp::isKind<zypp::Patch>(res)) { ++ zypp::Patch::constPtr patch = zypp::asKind<zypp::Patch>(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<zypp::PoolItem> *candidates = zypp_get_updates (); +- std::set<zypp::PoolItem> *candidates2 = zypp_get_patches (); ++ std::set<zypp::PoolItem> *candidates = zypp_get_patches (); ++ std::set<zypp::PoolItem> *candidates2 = new std::set<zypp::PoolItem> (); ++ ++ 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<zypp::PoolItem>::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<zypp::sat::Solvable>::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<zypp::PoolItem> *candidates = zypp_get_updates (); + //get all Patches for Update +- std::set<zypp::PoolItem> *candidates2 = zypp_get_patches (); ++ std::set<zypp::PoolItem> *candidates = zypp_get_patches (); ++ std::set<zypp::PoolItem> *candidates2 = new std::set<zypp::PoolItem> (); ++ ++ 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<zypp::PoolItem>::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 <sstream> + #include <stdlib.h> + #include <glib.h> ++#include <glib/gstdio.h> ++#include <glib/gi18n.h> + #include <zypp/ZYpp.h> + #include <zypp/ZYppFactory.h> + #include <zypp/RepoManager.h> +@@ -45,6 +47,7 @@ + #include <zypp/target/rpm/RpmDb.h> + #include <zypp/target/rpm/RpmHeader.h> + #include <zypp/target/rpm/librpmDb.h> ++#include <zypp/base/LogControl.h> + + #include <zypp/base/Logger.h> + +@@ -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<zypp::sat::Solvable> + system_and_package_are_x86 (*it)) + print = FALSE; + } ++ if (i == PK_FILTER_ENUM_SOURCE && !(zypp::isKind<zypp::SrcPackage>(*it))) { ++ print = FALSE; ++ } ++ if (i == PK_FILTER_ENUM_NOT_SOURCE && zypp::isKind<zypp::SrcPackage>(*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::PoolItem> * +-zypp_get_updates () ++zypp_get_updates (std::string repo) + { + std::set<zypp::PoolItem> *pks = new std::set<zypp::PoolItem> (); + 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::PoolItem> * + zypp_get_patches () + { + std::set<zypp::PoolItem> *patches = new std::set<zypp::PoolItem> (); ++ _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<zypp::Patch>(); + it != zypp->poolProxy ().byKindEnd<zypp::Patch>(); it ++) { + // check if patch is needed +- if((*it)->candidateObj ().isBroken()) ++ if((*it)->candidateObj ().isBroken()) { + patches->insert ((*it)->candidateObj ()); ++ zypp::Patch::constPtr patch = zypp::asKind<zypp::Patch>((*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<PkBackend *, std::vector<std::string> *> _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::PoolItem> * zypp_get_updates (); ++std::set<zypp::PoolItem> * 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; i<length; i++) { +- item = pk_client_package_buffer_get_item (client_task, i); ++ item = pk_package_list_get_item (list, i); + g_print ("%i. %s\n", i+1, item->package_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; i<length; i++) { +- is_local = g_file_test (packages[i], G_FILE_TEST_EXISTS); ++ /* are we a local file */ ++ is_local = g_file_test (packages[i], G_FILE_TEST_EXISTS & G_FILE_TEST_IS_REGULAR); + if (is_local) { + g_ptr_array_add (array_files, g_strdup (packages[i])); + } else { +@@ -720,6 +726,7 @@ pk_console_remove_packages (PkClient *client, gchar **packages, GError **error) + GPtrArray *array; + gchar **package_ids = NULL; + PkPackageList *list; ++ PkPackageList *list_single; + + array = g_ptr_array_new (); + list = pk_package_list_new (); +@@ -769,11 +776,13 @@ pk_console_remove_packages (PkClient *client, gchar **packages, GError **error) + } + + /* see how many packages there are */ +- size = pk_client_package_buffer_get_size (client_task); ++ list_single = pk_client_get_package_list (client_task); ++ size = pk_package_list_get_size (list_single); + for (j=0; j<size; j++) { +- item = pk_client_package_buffer_get_item (client_task, j); ++ item = pk_package_list_get_item (list_single, j); + pk_package_list_add_item (list, item); + } ++ g_object_unref (list_single); + } + + /* one of the get-requires failed */ +diff --git a/client/pk-import-desktop.c b/client/pk-import-desktop.c +index f5be0a5..bfe364f 100644 +--- a/client/pk-import-desktop.c ++++ b/client/pk-import-desktop.c +@@ -44,53 +44,58 @@ static gchar * + pk_desktop_get_name_for_file (const gchar *filename) + { + guint size; +- gchar *name; ++ gchar *name = NULL; + PkPackageItem *item; + PkPackageId *pid; + gboolean ret; + GError *error = NULL; ++ PkPackageList *list = NULL; + + /* use PK to find the correct package */ + ret = pk_client_reset (client, &error); + if (!ret) { + pk_warning ("failed to reset client: %s", error->message); + 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=<option>], + [Default backend to use +- alpm,apt,apt2,box,conary,dummy,smart,yum,pisi,zypp,opkg (dummy)])) ++ alpm,apt,box,conary,dummy,smart,urpmi,yum,pisi,zypp,opkg (dummy)])) + # default to a sane option for the installed tool + if test x$with_default_backend = x; then + if test -f /usr/bin/yum ; then +@@ -388,6 +388,8 @@ if test x$with_default_backend = x; then + with_default_backend=pisi + elif test -f /usr/bin/poldek ; then + with_default_backend=poldek ++ elif test -f /usr/bin/urpmq ; then ++ with_default_backend=urpmi + elif test -f /usr/bin/zypper ; then + with_default_backend=zypp + else +@@ -398,134 +400,8 @@ fi + AC_DEFINE_UNQUOTED(DEFAULT_BACKEND, "$with_default_backend", [default backend prefix]) + AC_SUBST(DEFAULT_BACKEND, "$with_default_backend") + +-AC_DEFUN([APT_BACKEND], +-[ +- if test "$APT_PKG_TYPE" == "" ; then +- AC_LANG_PUSH(C++) +- _libaptpkg_save_cppflags=$CPPFLAGS +- CPPFLAGS="$APT_CFLAGS $CPPFLAGS" +- _APT_save_libs=$LIBS +- LIBS="$APT_LIBS $LIBS" +- +- AC_MSG_CHECKING([for apt support for $1 packages]) +- AC_RUN_IFELSE(AC_LANG_PROGRAM([ +- #include <apt-pkg/configuration.h> +- #include <apt-pkg/pkgsystem.h> +- #include <apt-pkg/init.h> +- #include <stdio.h> +- ],[ +- if (pkgInitConfig(*_config) == false) +- { +- fprintf(stderr,"pkginitconfig was false"); +- return -1; +- } +- if (pkgInitSystem(*_config, _system) == false) +- { +- fprintf(stderr,"pkginitsystem was false"); +- return -1; +- } +- if (_system->ArchiveSupported("$1")) +- return 0; +- else +- return 1; +- ]),[ +- APT_PKG_TYPE=$1 +- AC_MSG_RESULT([yes]) +- AC_DEFINE(APT_PKG_$2,1,[apt-pkg support files of type $1]) +- ],) +- AC_LANG_POP(C++) +- CPPFLAGS=$_libaptpkg_save_cppflags +- LIBS=$_libaptpkg_save_libs +- unset _libaptpkg_save_cppflags +- unset _libaptpkg_save_libs +- fi +-]) +- + if test x$enable_apt = xyes; then + PY_CHECK_MOD([apt_pkg],,,AC_MSG_ERROR([Apt backend needs python-apt])) +- +- AC_ARG_WITH([apt_search], +- AS_HELP_STRING([--with-apt-search=<option>], +- [Apt search type to use - plain,sqlite (plain)])) +- +- if test x$with_apt_search = x; then +- with_apt_search=plain +- fi +- AC_MSG_NOTICE([using $with_apt_search for apt searching]) +- AC_DEFINE_UNQUOTED(APT_SEARCH, "$with_apt_search", [apt search type]) +- AC_SUBST(APT_SEARCH, $with_apt_search) +- AM_CONDITIONAL(APT_SEARCH_PLAIN, [test x$with_apt_search = xplain], [using plain apt search]) +- AM_CONDITIONAL(APT_SEARCH_SQLITE, [test x$with_apt_search = xsqlite], [using sqlite apt search]) +- +- AC_ARG_WITH(libapt-pkg-lib, +- AC_HELP_STRING([--with-libapt-pkg-lib=DIR],[look for the libapt-pkg library in DIR]), +- [_libaptpkg_with_lib=$withval],[_libaptpkg_with_lib=no]) +- if test "$_libaptpkg_with_lib" == "no" ; then +- APT_LIBS="-lapt-pkg" +- else +- APT_LIBS="-L$withval -lapt-pkg" +- fi +- +- AC_ARG_WITH(libapt-pkg-includes, +- AC_HELP_STRING([--with-libapt-pkg-includes=DIR],[look for the libapt-pkg includes in DIR]), +- [_libaptpkg_with_inc=$withval],[_libaptpkg_with_inc=no]) +- if test "$_libaptpkg_with_inc" == "no" ; then +- APT_CFLAGS="-I/usr/include/apt-pkg" +- else +- APT_CFLAGS="-I$withval" +- fi +- +- AC_CACHE_CHECK([whether libapt-pkg is usable], +- [libaptpkg_usable], +- [ +- _libaptpkg_save_cppflags=$CPPFLAGS +- CPPFLAGS="$APT_CFLAGS $CPPFLAGS" +- _APT_save_libs=$LIBS +- LIBS="$APT_LIBS $LIBS" +- +- AC_LANG_PUSH(C++) +- AC_LINK_IFELSE(AC_LANG_PROGRAM([ +- #include <apt-pkg/configuration.h> +- #include <apt-pkg/pkgsystem.h> +- #include <apt-pkg/init.h> +- #include <stdio.h> +- ],[ +- if (pkgInitConfig(*_config) == false) +- { +- fprintf(stderr,"pkginitconfig was false"); +- return -1; +- } +- if (pkgInitSystem(*_config, _system) == false) +- { +- fprintf(stderr,"pkginitsystem was false"); +- return -1; +- } +- return 0; +-]),libaptpkg_usable=yes,AC_MSG_ERROR([libapt-pkg not found])) +- +- CPPFLAGS=$_libaptpkg_save_cppflags +- LIBS=$_libaptpkg_save_libs +- unset _libaptpkg_save_cppflags +- unset _libaptpkg_save_libs +- ]) +- AC_LANG_POP(C++) +- +- APT_BACKEND(deb,DEB) +- APT_BACKEND(rpm,RPM) +- if test "$APT_PKG_TYPE" == "" ; then +- AC_MSG_ERROR([Couldn't find support for any type of packages that we know about for Apt!]) +- fi +- +- AC_SUBST(APT_CFLAGS) +- AC_SUBST(APT_LIBS) +- AC_SUBST(APT_PKG_TYPE) +-else +- AM_CONDITIONAL(APT_SEARCH_PLAIN, [false]) +- AM_CONDITIONAL(APT_SEARCH_SQLITE, [false]) +-fi +- +-if test x$enable_apt2 = xyes; then +- PY_CHECK_MOD([apt_pkg],,,AC_MSG_ERROR([Apt backend needs python-apt])) + fi + + if test x$enable_box = xyes; then +@@ -535,7 +411,7 @@ if test x$enable_box = xyes; then + fi + + if test x$enable_opkg = xyes; then +- PKG_CHECK_MODULES(OPKG, libopkg = 0.1.4) ++ PKG_CHECK_MODULES(OPKG, libopkg = 0.1.5) + AC_SUBST(OPKG_CFLAGS) + AC_SUBST(OPKG_LIBS) + fi +@@ -555,7 +431,7 @@ if test x$enable_poldek = xyes; then + fi + + if test x$enable_zypp = xyes; then +- PKG_CHECK_MODULES(ZYPP, libzypp >= 4.14.0) ++ PKG_CHECK_MODULES(ZYPP, libzypp >= 4.25.0) + AC_SUBST(ZYPP_CFLAGS) + AC_SUBST(ZYPP_LIBS) + fi +@@ -568,11 +444,6 @@ AC_SUBST(PK_PLUGIN_DIR, "\$(libdir)/packagekit-backend") + AC_SUBST(PK_PLUGIN_CFLAGS, "-I\$(top_srcdir)/src -I\$(top_srcdir)/libpackagekit $GLIB_CFLAGS $DBUS_CFLAGS $GMODULE_CFLAGS") + AC_SUBST(PK_PLUGIN_LIBS, "$GLIB_LIBS $DBUS_LIBS $GMODULE_LIBS") + +-if test x$with_default_backend = xapt; then +- # now we've done the conditionals, rename for searching backend +- with_default_backend="apt (with $with_apt_search searching)" +-fi +- + dnl --------------------------------------------------------------------------- + dnl - Makefiles, etc. + dnl --------------------------------------------------------------------------- +@@ -592,8 +463,6 @@ contrib/yum-packagekit/Makefile + backends/Makefile + backends/alpm/Makefile + backends/apt/Makefile +-backends/apt/helpers/Makefile +-backends/apt2/Makefile + backends/box/Makefile + backends/conary/Makefile + backends/conary/helpers/Makefile +@@ -603,6 +472,10 @@ backends/smart/Makefile + backends/smart/helpers/Makefile + backends/test/Makefile + backends/test/helpers/Makefile ++backends/urpmi/Makefile ++backends/urpmi/helpers/Makefile ++backends/urpmi/helpers/perl_packagekit/Makefile ++backends/urpmi/helpers/urpmi_backend/Makefile + backends/yum/Makefile + backends/yum/helpers/Makefile + backends/yum2/Makefile +@@ -650,7 +523,6 @@ echo " + Backends: + ALPM backend: ${enable_alpm} + APT backend: ${enable_apt} +- APT DBus backend: ${enable_apt2} + BOX backend: ${enable_box} + CONARY backend: ${enable_conary} + dummy backend: ${enable_dummy} +@@ -658,6 +530,7 @@ echo " + PiSi backend: ${enable_pisi} + poldek backend: ${enable_poldek} + SMART backend: ${enable_smart} ++ URPMI backend: ${enable_urpmi} + YUM backend: ${enable_yum} + YUM2 backend: ${enable_yum2} + Zypp backend: ${enable_zypp} +diff --git a/contrib/PackageKit.spec.in b/contrib/PackageKit.spec.in +index 4d4a7e3..61a67d1 100644 +--- a/contrib/PackageKit.spec.in ++++ b/contrib/PackageKit.spec.in +@@ -10,6 +10,7 @@ Summary: System daemon that is a DBUS abstraction layer for packages + Name: PackageKit + Version: #VERSION# + Release: 0.#BUILD#%{?alphatag}%{?dist} ++Epoch: 1 + License: GPLv2+ + Group: System Environment/Libraries + URL: http://packagekit.freedesktop.org +@@ -17,8 +18,8 @@ Source0: http://people.freedesktop.org/~hughsient/releases/%{name}-%{version}. + BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) + + Requires: dbus >= %{dbus_version} +-Requires: PackageKit-libs = %{version}-%{release} +-Requires: yum-packagekit = %{version}-%{release} ++Requires: PackageKit-libs = %{epoch}:%{version}-%{release} ++Requires: yum-packagekit = %{epoch}:%{version}-%{release} + Requires: yum >= 3.2.6 + + BuildRequires: glib2-devel >= %{glib2_version} +@@ -69,7 +70,7 @@ will almost instantly update itself to reflect this. + Summary: Libraries for accessing PackageKit + Group: Development/Libraries + Requires: dbus >= %{dbus_version} +-Requires: %{name} = %{version}-%{release} ++Requires: %{name} = %{epoch}:%{version}-%{release} + + %description libs + Libraries for accessing PackageKit. +@@ -78,7 +79,7 @@ Libraries for accessing PackageKit. + Summary: Cron job and related utilities for PackageKit + Group: System Environment/Base + Requires: cronie +-Requires: %{name} = %{version}-%{release} ++Requires: %{name} = %{epoch}:%{version}-%{release} + + %description cron + Crontab and utilities for running PackageKit as a cron job. +@@ -86,7 +87,7 @@ Crontab and utilities for running PackageKit as a cron job. + %package devel + Summary: Libraries and headers for PackageKit + Group: Development/Libraries +-Requires: %{name} = %{version}-%{release} ++Requires: %{name} = %{epoch}:%{version}-%{release} + Requires: dbus-devel >= %{dbus_version} + Requires: pkgconfig + Requires: sqlite-devel +diff --git a/contrib/gnome-packagekit.spec.in b/contrib/gnome-packagekit.spec.in +index a97fc3b..ded7799 100644 +--- a/contrib/gnome-packagekit.spec.in ++++ b/contrib/gnome-packagekit.spec.in +@@ -6,6 +6,7 @@ Summary: GNOME PackageKit Client + Name: gnome-packagekit + Version: #VERSION# + Release: 0.#BUILD#%{?alphatag}%{?dist} ++Epoch: 1 + License: GPLv2+ + Group: Applications/System + URL: http://www.packagekit.org +diff --git a/docs/html/pk-authors.html b/docs/html/pk-authors.html +index 607a7a4..7aa298b 100644 +--- a/docs/html/pk-authors.html ++++ b/docs/html/pk-authors.html +@@ -262,6 +262,22 @@ + </td> + </tr> + ++<tr> ++ <td> ++ <img src="img/author-unknown.png" alt=""/><!-- image should be 120px wide --> ++ </td> ++ <td> ++ <h2>Aurelien Lefebvre</h2> ++ <p> ++ Aurelien works for <a href="http://www.mandriva.org">Mandriva</a>. ++ He works on the urpmi backend of PackageKit. ++ </p> ++ <p> ++ <b>Responsible for: urpmi backend</b> ++ </p> ++ </td> ++</tr> ++ + </table> + + <p>Back to the <a href="index.html">main page</a></p> +diff --git a/docs/html/pk-download.html b/docs/html/pk-download.html +index 0cdc85c..d276a05 100644 +--- a/docs/html/pk-download.html ++++ b/docs/html/pk-download.html +@@ -44,7 +44,7 @@ easier to install. + <h2>Released Versions</h2> + <p> + Released versions are found on +-<a href="http://people.freedesktop.org/~hughsient/releases/">people.freedesktop.org</a>. ++<a href="http://www.packagekit.org/releases/">http://www.packagekit.org/releases/</a>. + </p> + <table> + <tr><td><b>Version</b></td><td> </td><td><b>Date</b></td></tr> +diff --git a/docs/html/pk-faq.html b/docs/html/pk-faq.html +index efa8344..3e37cc1 100644 +--- a/docs/html/pk-faq.html ++++ b/docs/html/pk-faq.html +@@ -22,6 +22,7 @@ + <h2>Table Of Contents</h2> + <ul> + <li><a href="#how-complete">How complete are the backends?</a></li> ++<li><a href="#1-click-install">Does PackageKit support 1-Click Install?</a></li> + <li><a href="#run-as-root">When run as root, gpk-application and pkcon do not work!</a></li> + <li><a href="#session-system">Why is there a session service and and a system service?</a></li> + <li><a href="#session-methods">How do I use PackageKit in my application?</a></li> +@@ -52,7 +53,6 @@ + <tr> + <td width="150px"> </td> + <td><center>apt</center></td> +-<td><center>apt2</center></td> + <td><center>alpm</center></td> + <td><center>box</center></td> + <td><center>conary</center></td> +@@ -60,14 +60,14 @@ + <td><center>pisi</center></td> + <td><center>poldek</center></td> + <td><center>smart</center></td> ++<td><center>urpmi</center></td> + <td><center>yum</center></td> + <td><center>yum2</center></td> + <td><center>zypp</center></td> + </tr> + <tr> + <td><b>Resolve</b></td> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 --> ++<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary --> +@@ -75,6 +75,7 @@ + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart --> ++<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp --> +@@ -82,7 +83,6 @@ + <tr> + <td><b>RefreshCache</b></td> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt --> +-<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary --> +@@ -90,14 +90,14 @@ + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart --> ++<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp --> + </tr> + <tr> + <td><b>GetUpdates</b></td> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt2 --> ++<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary --> +@@ -105,14 +105,14 @@ + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart --> ++<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp --> + </tr> + <tr> + <td><b>UpdateSystem</b></td> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt2 --> ++<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary --> +@@ -120,6 +120,7 @@ + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart --> ++<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp --> +@@ -127,7 +128,6 @@ + <tr> + <td><b>SearchName</b></td> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt --> +-<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary --> +@@ -135,6 +135,7 @@ + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart --> ++<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp --> +@@ -142,7 +143,6 @@ + <tr> + <td><b>SearchDetails</b></td> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt --> +-<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary --> +@@ -150,6 +150,7 @@ + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart --> ++<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp --> +@@ -157,7 +158,6 @@ + <tr> + <td><b>SearchFile</b></td> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary --> +@@ -165,6 +165,7 @@ + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart --> ++<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp --> +@@ -172,22 +173,21 @@ + <tr> + <td><b>SearchGroup</b></td> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- box --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- opkg --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi --> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- poldek --> ++<td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart --> ++<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp --> + </tr> + <tr> + <td><b>InstallPackages</b></td> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt2 --> ++<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary --> +@@ -195,6 +195,7 @@ + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart --> ++<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp --> +@@ -202,7 +203,6 @@ + <tr> + <td><b>InstallFiles</b></td> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary --> +@@ -210,14 +210,14 @@ + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- poldek --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart --> ++<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp --> + </tr> + <tr> + <td><b>RemovePackages</b></td> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt2 --> ++<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary --> +@@ -225,6 +225,7 @@ + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart --> ++<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp --> +@@ -232,7 +233,6 @@ + <tr> + <td><b>UpdatePackage</b></td> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary --> +@@ -240,6 +240,7 @@ + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart --> ++<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp --> +@@ -247,7 +248,6 @@ + <tr> + <td><b>GetDepends</b></td> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary --> +@@ -255,6 +255,7 @@ + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart --> ++<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp --> +@@ -262,7 +263,6 @@ + <tr> + <td><b>GetRequires</b></td> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary --> +@@ -270,6 +270,7 @@ + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart --> ++<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp --> +@@ -277,7 +278,6 @@ + <tr> + <td><b>GetDetails</b></td> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt --> +-<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary --> +@@ -285,6 +285,7 @@ + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart --> ++<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp --> +@@ -292,7 +293,6 @@ + <tr> + <td><b>GetFiles</b></td> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary --> +@@ -300,6 +300,7 @@ + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart --> ++<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp --> +@@ -307,7 +308,6 @@ + <tr> + <td><b>GetUpdateDetail</b></td> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- box --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary --> +@@ -315,6 +315,7 @@ + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- pisi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart --> ++<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- zypp --> +@@ -322,7 +323,6 @@ + <tr> + <td><b>GetRepoList</b></td> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary --> +@@ -330,6 +330,7 @@ + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart --> ++<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp --> +@@ -337,7 +338,6 @@ + <tr> + <td><b>RepoEnable</b></td> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary --> +@@ -345,6 +345,7 @@ + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- pisi --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- poldek --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart --> ++<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp --> +@@ -352,7 +353,6 @@ + <tr> + <td><b>RepoSetData</b></td> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary --> +@@ -360,6 +360,7 @@ + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- poldek --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart --> ++<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp --> +@@ -367,7 +368,6 @@ + <tr> + <td><b>Cancel</b></td> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- box --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary --> +@@ -375,6 +375,7 @@ + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart --> ++<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- zypp --> +@@ -382,7 +383,6 @@ + <tr> + <td><b>ServicePack</b></td> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- box --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary --> +@@ -390,6 +390,7 @@ + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- pisi --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- poldek --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart --> ++<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum2 --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- zypp --> +@@ -397,22 +398,21 @@ + <tr> + <td><b>WhatProvides</b></td> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- box --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- opkg --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- pisi --> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- poldek --> ++<td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart --> ++<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp --> + </tr> + <tr> + <td><b>GetPackages</b></td> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 --> ++<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- box --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary --> +@@ -420,6 +420,7 @@ + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- pisi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart --> ++<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum2 --> + <td><img src="img/status-good.png" alt="[good]"/></td><!-- zypp --> +@@ -431,7 +432,6 @@ + <tr> + <td width="150px"> </td> + <td><center>apt</center></td> +-<td><center>apt2</center></td> + <td><center>alpm</center></td> + <td><center>box</center></td> + <td><center>conary</center></td> +@@ -439,6 +439,7 @@ + <td><center>pisi</center></td> + <td><center>poldek</center></td> + <td><center>smart</center></td> ++<td><center>urpmi</center></td> + <td><center>yum</center></td> + <td><center>yum2</center></td> + <td><center>zypp</center></td> +@@ -446,7 +447,6 @@ + <tr> + <td><b>Installed</b></td> + <td><img src="img/status-good.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-good.png" alt="[no]"/></td><!-- apt2 --> + <td><img src="img/status-good.png" alt="[no]"/></td><!-- alpm --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary --> +@@ -454,6 +454,7 @@ + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart --> ++<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp --> +@@ -461,7 +462,6 @@ + <tr> + <td><b>Development</b></td> + <td><img src="img/status-good.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-good.png" alt="[no]"/></td><!-- apt2 --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary --> +@@ -469,6 +469,7 @@ + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart --> ++<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- zypp --> +@@ -476,7 +477,6 @@ + <tr> + <td><b>GUI</b></td> + <td><img src="img/status-good.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-good.png" alt="[no]"/></td><!-- apt2 --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary --> +@@ -484,6 +484,7 @@ + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart --> ++<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- zypp --> +@@ -491,7 +492,6 @@ + <tr> + <td><b>Free</b></td> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- box --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary --> +@@ -499,6 +499,7 @@ + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- pisi --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- poldek --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart --> ++<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum2 --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- zypp --> +@@ -506,13 +507,13 @@ + <tr> + <td><b>Visible</b></td> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- box --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- opkg --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- pisi --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- poldek --> ++<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum2 --> +@@ -521,13 +522,13 @@ + <tr> + <td><b>Supported</b></td> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- box --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- opkg --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- pisi --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- poldek --> ++<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum2 --> +@@ -536,13 +537,13 @@ + <tr> + <td><b>Newest</b></td> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- box --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- opkg --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- pisi --> + <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek --> ++<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum2 --> +@@ -551,13 +552,13 @@ + <tr> + <td><b>Arch</b></td> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt --> +-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- box --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- opkg --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- pisi --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- poldek --> ++<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum --> + <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum2 --> +@@ -566,6 +567,43 @@ + </table> + + <hr> ++<h3><a name="1-click-install">Does PackageKit support 1-Click Install?</a></h3> ++<p> ++No, as they are a potential security problem. The issues are as follows: ++</p> ++<ul> ++<li> ++That some developer creates a repository with a package with a higher package epoch, and then the ++distro releases a critical security package (with an updated version, but smaller epoch) and the ++package does not get upgraded, leaving the user vulnerable. ++</li> ++<li> ++The user installs some random repository, where the developer pushes a few svn packages. ++The developer gets bored, and stop produces updates, and then one of the old packages blocks ++on the distribution update, causing no further automatic system updates. ++</li> ++<li> ++There's no signing of 1-click-install files, so we can't actually be sure that they come from a ++reputable source. ++</li> ++<li> ++There's no localisation in the 1-click-files. ++For instance, if we only show a French language speaker a description of "remote exploit trojan" ++they are not going to understand the description. ++</li> ++</ul> ++<p> ++So what's the solution? Using a standard <code>$vendor-release.rpm</code> or <code>.deb</code> ++you can ship the standard repo or source with a signed GPG key. ++</p> ++<p> ++Quoting Sebastian Heinlein, ++<i>Allowing to easily add third party repositories and install third party software without a ++certification infrastructure is like opening the gates to hell. ++Most user just don't have got the technical understanding to handle this well.</i> ++</p> ++ ++<hr> + <h3><a name="run-as-root">When run as root, <code>gpk-application</code> and <code>pkcon</code> do not work!</a></h3> + <p> + GTK+ tools should not be run as the root user, <b>PERIOD</b>. +diff --git a/docs/spec/pk-concepts.xml b/docs/spec/pk-concepts.xml +index 0b75b10..51a165a 100644 +--- a/docs/spec/pk-concepts.xml ++++ b/docs/spec/pk-concepts.xml +@@ -402,6 +402,13 @@ + signature is not valid in some way. + </entry> + </row> ++ <row> ++ <entry><literal>package-corrupt</literal></entry> ++ <entry> ++ The downloaded package is corrupt. ++ </entry> ++ </row> ++ + </tbody> + </tgroup> + </informaltable> +diff --git a/docs/spec/pk-signals.xml b/docs/spec/pk-signals.xml +index a79e647..2970dda 100644 +--- a/docs/spec/pk-signals.xml ++++ b/docs/spec/pk-signals.xml +@@ -360,11 +360,21 @@ + </row> + <row> + <entry><literal>updates</literal></entry> +- <entry>A list of package_id's that are to be updated</entry> ++ <entry> ++ A list of package_id's that are to be updated, seporated by <literal>^</literal>. ++ This odd delimited was chosen as <literal>\t</literal> is already being used in the ++ spawned backends, and <literal>^</literal> is a banned character in a package_id. ++ This will change in 0.3.x where <literal>updates</literal> will be a proper string ++ array field. ++ </entry> + </row> + <row> + <entry><literal>obsoletes</literal></entry> +- <entry>A list of package_id's that are to be obsoletes</entry> ++ <entry> ++ A list of package_id's that are to be obsoleted, seporated by <literal>^</literal> ++ This will change in 0.3.x where <literal>obsoletes</literal> will be a proper string ++ array field. ++ </entry> + </row> + <row> + <entry><literal>vendor_url</literal></entry> +diff --git a/etc/PackageKit.conf.in b/etc/PackageKit.conf.in +index 8f9bd57..7a48320 100644 +--- a/etc/PackageKit.conf.in ++++ b/etc/PackageKit.conf.in +@@ -39,5 +39,5 @@ DefaultBackend=@defaultbackend@ + # They are in the format username:password@server:port + # + # ProxyHTTP=username:password@server.lan:8080 +-# ProxyFTP=username:password@server.lan:21 ++# ProxyFTP=server.lan:21 + +diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c +index dd2387b..8fb82f1 100644 +--- a/libpackagekit/pk-client.c ++++ b/libpackagekit/pk-client.c +@@ -275,7 +275,7 @@ pk_client_get_tid (PkClient *client) + * If the package buffer is enabled then after the transaction has completed + * then the package list can be retrieved in one go, rather than processing + * each package request async. +- * If this is not set true explicitly, then pk_client_package_buffer_get_size ++ * If this is not set true explicitly, then pk_client_get_package_list + * will always return zero items. + * + * This is not forced on as there may be significant overhead if the list +@@ -364,26 +364,7 @@ pk_client_get_require_restart (PkClient *client) + } + + /** +- * pk_client_package_buffer_get_size: +- * @client: a valid #PkClient instance +- * +- * We do not provide access to the internal package list (as it could be being +- * updated) so provide a way to get access to the current size here. +- * +- * Return value: The size of the package buffer. +- **/ +-guint +-pk_client_package_buffer_get_size (PkClient *client) +-{ +- g_return_val_if_fail (PK_IS_CLIENT (client), 0); +- if (!client->priv->use_buffer) { +- return 0; +- } +- return pk_package_list_get_size (client->priv->package_list); +-} +- +-/** +- * pk_client_package_buffer_get_item: ++ * pk_client_get_package_list: + * @client: a valid #PkClient instance + * @item: the item in the package buffer + * +@@ -392,14 +373,17 @@ pk_client_package_buffer_get_size (PkClient *client) + * + * Return value: The #PkPackageItem or %NULL if not found or invalid + **/ +-PkPackageItem * +-pk_client_package_buffer_get_item (PkClient *client, guint item) ++PkPackageList * ++pk_client_get_package_list (PkClient *client) + { ++ PkPackageList *list; + g_return_val_if_fail (PK_IS_CLIENT (client), NULL); + if (!client->priv->use_buffer) { + return NULL; + } +- return pk_package_list_get_item (client->priv->package_list, item); ++ list = client->priv->package_list; ++ g_object_ref (list); ++ return list; + } + + /** +@@ -412,6 +396,10 @@ pk_client_finished_cb (DBusGProxy *proxy, const gchar *exit_text, guint runtime, + + g_return_if_fail (PK_IS_CLIENT (client)); + ++ /* ref in case we unref the PkClient in ::finished -- ++ * see https://bugzilla.novell.com/show_bug.cgi?id=390929 for rationale */ ++ g_object_ref (client); ++ + exit = pk_exit_enum_from_text (exit_text); + pk_debug ("emit finished %s, %i", exit_text, runtime); + +@@ -420,16 +408,13 @@ pk_client_finished_cb (DBusGProxy *proxy, const gchar *exit_text, guint runtime, + + g_signal_emit (client, signals [PK_CLIENT_FINISHED], 0, exit, runtime); + +- /* check we are still valid */ +- if (!PK_IS_CLIENT (client)) { +- pk_debug ("client was g_object_unref'd in finalise, object no longer valid"); +- return; +- } +- + /* exit our private loop */ + if (client->priv->synchronous) { + g_main_loop_quit (client->priv->loop); + } ++ ++ /* unref what we previously ref'd */ ++ g_object_unref (client); + } + + /** +@@ -491,7 +476,6 @@ pk_client_package_cb (DBusGProxy *proxy, + + /* cache */ + if (client->priv->use_buffer || client->priv->synchronous) { +- pk_debug ("adding to cache array package %i, %s, %s", info, package_id, summary); + pk_package_list_add (client->priv->package_list, info, package_id, summary); + } + } +@@ -566,16 +550,12 @@ pk_client_details_cb (DBusGProxy *proxy, + * pk_client_files_cb: + */ + static void +-pk_client_files_cb (DBusGProxy *proxy, +- const gchar *package_id, +- const gchar *filelist, +- PkClient *client) ++pk_client_files_cb (DBusGProxy *proxy, const gchar *package_id, const gchar *filelist, PkClient *client) + { + g_return_if_fail (PK_IS_CLIENT (client)); + +- pk_debug ("emit files %s, %s", package_id, filelist); +- g_signal_emit (client , signals [PK_CLIENT_FILES], 0, package_id, +- filelist); ++ pk_debug ("emit files %s, <lots of files>", package_id); ++ g_signal_emit (client , signals [PK_CLIENT_FILES], 0, package_id, filelist); + } + + /** +@@ -934,10 +914,8 @@ pk_client_cancel (PkClient *client, GError **error) + return TRUE; + } + +- /* special case - if the tid is already finished, then cancel should +- * return TRUE as it's what we wanted */ +- if (pk_strequal (error_local->message, "cancelling a non-running transaction") || +- g_str_has_suffix (error_local->message, " doesn't exist\n")) { ++ /* special case - if the tid is already finished, then cancel should return TRUE */ ++ if (g_str_has_suffix (error_local->message, " doesn't exist\n")) { + pk_debug ("error ignored '%s' as we are trying to cancel", error_local->message); + g_error_free (error_local); + return TRUE; +@@ -1022,7 +1000,7 @@ pk_client_get_updates (PkClient *client, PkFilterEnum filters, GError **error) + G_TYPE_STRING, filter_text, + G_TYPE_INVALID, G_TYPE_INVALID); + g_free (filter_text); +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -1112,7 +1090,7 @@ pk_client_update_system (PkClient *client, GError **error) + g_propagate_error (error, error_pk); + } + +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -1167,7 +1145,7 @@ pk_client_search_name (PkClient *client, PkFilterEnum filters, const gchar *sear + G_TYPE_STRING, search, + G_TYPE_INVALID, G_TYPE_INVALID); + g_free (filter_text); +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -1223,7 +1201,7 @@ pk_client_search_details (PkClient *client, PkFilterEnum filters, const gchar *s + G_TYPE_STRING, search, + G_TYPE_INVALID, G_TYPE_INVALID); + g_free (filter_text); +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -1277,7 +1255,7 @@ pk_client_search_group (PkClient *client, PkFilterEnum filters, const gchar *sea + G_TYPE_STRING, search, + G_TYPE_INVALID, G_TYPE_INVALID); + g_free (filter_text); +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -1331,7 +1309,7 @@ pk_client_search_file (PkClient *client, PkFilterEnum filters, const gchar *sear + G_TYPE_STRING, search, + G_TYPE_INVALID, G_TYPE_INVALID); + g_free (filter_text); +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -1397,7 +1375,7 @@ pk_client_get_depends (PkClient *client, PkFilterEnum filters, const gchar *pack + G_TYPE_BOOLEAN, recursive, + G_TYPE_INVALID, G_TYPE_INVALID); + g_free (filter_text); +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -1448,7 +1426,7 @@ pk_client_get_packages (PkClient *client, PkFilterEnum filters, GError **error) + G_TYPE_STRING, filter_text, + G_TYPE_INVALID, G_TYPE_INVALID); + g_free (filter_text); +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -1514,7 +1492,7 @@ pk_client_get_requires (PkClient *client, PkFilterEnum filters, const gchar *pac + G_TYPE_BOOLEAN, recursive, + G_TYPE_INVALID, G_TYPE_INVALID); + g_free (filter_text); +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -1579,7 +1557,7 @@ pk_client_what_provides (PkClient *client, PkFilterEnum filters, PkProvidesEnum + G_TYPE_STRING, search, + G_TYPE_INVALID, G_TYPE_INVALID); + g_free (filter_text); +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -1637,7 +1615,7 @@ pk_client_get_update_detail (PkClient *client, const gchar *package_id, GError * + ret = dbus_g_proxy_call (client->priv->proxy, "GetUpdateDetail", error, + G_TYPE_STRING, package_id, + G_TYPE_INVALID, G_TYPE_INVALID); +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -1686,7 +1664,7 @@ pk_client_rollback (PkClient *client, const gchar *transaction_id, GError **erro + ret = dbus_g_proxy_call (client->priv->proxy, "Rollback", error, + G_TYPE_STRING, transaction_id, + G_TYPE_INVALID, G_TYPE_INVALID); +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -1743,7 +1721,7 @@ pk_client_resolve (PkClient *client, PkFilterEnum filters, const gchar *package, + G_TYPE_STRING, package, + G_TYPE_INVALID, G_TYPE_INVALID); + g_free (filter_text); +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -1801,7 +1779,7 @@ pk_client_get_details (PkClient *client, const gchar *package_id, GError **error + ret = dbus_g_proxy_call (client->priv->proxy, "GetDetails", error, + G_TYPE_STRING, package_id, + G_TYPE_INVALID, G_TYPE_INVALID); +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -1858,7 +1836,7 @@ pk_client_get_files (PkClient *client, const gchar *package_id, GError **error) + ret = dbus_g_proxy_call (client->priv->proxy, "GetFiles", error, + G_TYPE_STRING, package_id, + G_TYPE_INVALID, G_TYPE_INVALID); +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -1963,7 +1941,7 @@ pk_client_remove_packages (PkClient *client, gchar **package_ids, gboolean allow + g_propagate_error (error, error_pk); + } + +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -2048,7 +2026,7 @@ pk_client_refresh_cache (PkClient *client, gboolean force, GError **error) + g_propagate_error (error, error_pk); + } + +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -2142,7 +2120,7 @@ pk_client_install_packages (PkClient *client, gchar **package_ids, GError **erro + g_propagate_error (error, error_pk); + } + +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -2242,7 +2220,7 @@ pk_client_install_signature (PkClient *client, PkSigTypeEnum type, const gchar * + g_propagate_error (error, error_pk); + } + +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -2340,7 +2318,7 @@ pk_client_update_packages (PkClient *client, gchar **package_ids, GError **error + g_propagate_error (error, error_pk); + } + +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -2570,7 +2548,7 @@ pk_client_install_files (PkClient *client, gboolean trusted, gchar **files_rel, + g_propagate_error (error, error_pk); + } + +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -2622,7 +2600,7 @@ pk_client_get_repo_list (PkClient *client, PkFilterEnum filters, GError **error) + G_TYPE_INVALID, G_TYPE_INVALID); + g_free (filter_text); + pk_client_error_fixup (error); +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -2703,7 +2681,7 @@ pk_client_accept_eula (PkClient *client, const gchar *eula_id, GError **error) + g_propagate_error (error, error_pk); + } + +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -2787,7 +2765,7 @@ pk_client_repo_enable (PkClient *client, const gchar *repo_id, gboolean enabled, + g_propagate_error (error, error_pk); + } + +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -2880,7 +2858,7 @@ pk_client_repo_set_data (PkClient *client, const gchar *repo_id, const gchar *pa + g_propagate_error (error, error_pk); + } + +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -2957,7 +2935,7 @@ pk_client_get_old_transactions (PkClient *client, guint number, GError **error) + G_TYPE_UINT, number, + G_TYPE_INVALID, G_TYPE_INVALID); + pk_client_error_fixup (error); +- if (ret) { ++ if (ret && !client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + } +@@ -3085,6 +3063,7 @@ pk_client_set_tid (PkClient *client, const gchar *tid, GError **error) + return FALSE; + } + client->priv->tid = g_strdup (tid); ++ pk_debug ("set tid %s on %p", client->priv->tid, client); + + dbus_g_proxy_add_signal (proxy, "Finished", + G_TYPE_STRING, G_TYPE_UINT, G_TYPE_INVALID); +@@ -3523,9 +3502,8 @@ pk_client_reset (PkClient *client, GError **error) + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + +- if (client->priv->tid != NULL && +- client->priv->is_finished != TRUE) { +- pk_debug ("not exit status, will try to cancel"); ++ if (client->priv->tid != NULL && !client->priv->is_finished) { ++ pk_debug ("not exit status, will try to cancel tid %s", client->priv->tid); + /* we try to cancel the running tranaction */ + ret = pk_client_cancel (client, error); + if (!ret) { +@@ -3790,6 +3768,7 @@ libst_client (LibSelfTest *test) + guint size_new; + guint i; + gchar *file; ++ PkPackageList *list; + + if (libst_start (test, "PkClient", CLASS_AUTO) == FALSE) { + return; +@@ -3833,6 +3812,15 @@ libst_client (LibSelfTest *test) + libst_failed (test, NULL); + } + ++ /************************************************************/ ++ libst_title (test, "reset client, unused"); ++ ret = pk_client_reset (client, NULL); ++ if (ret) { ++ libst_success (test, NULL); ++ } else { ++ libst_failed (test, NULL); ++ } ++ + /* check use after finalise */ + g_signal_connect (client, "finished", + G_CALLBACK (libst_client_finished_cb), test); +@@ -3871,7 +3859,9 @@ libst_client (LibSelfTest *test) + } + + /* get size */ +- size = pk_client_package_buffer_get_size (client); ++ list = pk_client_get_package_list (client); ++ size = pk_package_list_get_size (list); ++ g_object_unref (list); + if (size == 0) { + libst_failed (test, "failed: to get any results"); + } +@@ -3891,7 +3881,9 @@ libst_client (LibSelfTest *test) + g_error_free (error); + } + /* check we got the same results */ +- size_new = pk_client_package_buffer_get_size (client); ++ list = pk_client_get_package_list (client); ++ size_new = pk_package_list_get_size (list); ++ g_object_unref (list); + if (size != size_new) { + libst_failed (test, "old size %i, new size %", size, size_new); + } +diff --git a/libpackagekit/pk-client.h b/libpackagekit/pk-client.h +index 2b1d1a2..6617159 100644 +--- a/libpackagekit/pk-client.h ++++ b/libpackagekit/pk-client.h +@@ -346,9 +346,7 @@ gboolean pk_client_repo_set_data (PkClient *client, + G_GNUC_WARN_UNUSED_RESULT; + + /* cached stuff */ +-guint pk_client_package_buffer_get_size (PkClient *client); +-PkPackageItem *pk_client_package_buffer_get_item (PkClient *client, +- guint item); ++PkPackageList *pk_client_get_package_list (PkClient *client); + PkRestartEnum pk_client_get_require_restart (PkClient *client); + + /* not job specific */ +diff --git a/libpackagekit/pk-common.c b/libpackagekit/pk-common.c +index 9d3cff7..0be0e6e 100644 +--- a/libpackagekit/pk-common.c ++++ b/libpackagekit/pk-common.c +@@ -246,7 +246,7 @@ pk_strsafe (const gchar *text) + } + + /* rip out any insane characters */ +- delimiters = "\\\f\n\r\t\"'"; ++ delimiters = "\\\f\r\t\"'"; + text_safe = g_strdup (text); + g_strdelimit (text_safe, delimiters, ' '); + return text_safe; +@@ -613,6 +613,35 @@ pk_strpad_extra (const gchar *data, guint length, guint *extra) + } + + /** ++ * pk_strreplace: ++ * @text: The input text to make safe ++ * @find: What to search for ++ * @replace: What to replace with ++ * ++ * Replaces chars in the text with a replacement. ++ * The %find and %replace variables to not have to be of the same length ++ * ++ * Return value: the new string (copied) ++ **/ ++gchar * ++pk_strreplace (const gchar *text, const gchar *find, const gchar *replace) ++{ ++ gchar **array; ++ gchar *retval; ++ ++ /* common case, not found */ ++ if (strstr (text, find) == NULL) { ++ return g_strdup (text); ++ } ++ ++ /* split apart and rejoin with new delimiter */ ++ array = g_strsplit (text, find, 0); ++ retval = g_strjoinv (replace, array); ++ g_strfreev (array); ++ return retval; ++} ++ ++/** + * pk_delay_yield: + * @delay: the desired delay in seconds + * +@@ -850,6 +879,23 @@ libst_common (LibSelfTest *test) + } + g_free (text_safe); + ++ /************************************************************/ ++ libst_title (test, "pk_strequal same argument"); ++ temp = "dave"; ++ if (pk_strequal (temp, temp)) { ++ libst_success (test, NULL); ++ } else { ++ libst_failed (test, "incorrect ret when both same"); ++ } ++ ++ /************************************************************/ ++ libst_title (test, "pk_strequal both const"); ++ if (pk_strequal ("dave", "dave")) { ++ libst_success (test, NULL); ++ } else { ++ libst_failed (test, "incorrect ret when both same"); ++ } ++ + /************************************************************ + **************** build var args ************** + ************************************************************/ +@@ -1283,6 +1329,48 @@ libst_common (LibSelfTest *test) + g_free (text_safe); + + /************************************************************ ++ **************** Replace ****************** ++ ************************************************************/ ++ libst_title (test, "replace start"); ++ text_safe = pk_strreplace ("richard\nhughes", "r", "e"); ++ if (pk_strequal (text_safe, "eichaed\nhughes")) { ++ libst_success (test, NULL); ++ } else { ++ libst_failed (test, "failed the replace '%s'", text_safe); ++ } ++ g_free (text_safe); ++ ++ /************************************************************/ ++ libst_title (test, "replace none"); ++ text_safe = pk_strreplace ("richard\nhughes", "dave", "e"); ++ if (pk_strequal (text_safe, "richard\nhughes")) { ++ libst_success (test, NULL); ++ } else { ++ libst_failed (test, "failed the replace '%s'", text_safe); ++ } ++ g_free (text_safe); ++ ++ /************************************************************/ ++ libst_title (test, "replace end"); ++ text_safe = pk_strreplace ("richard\nhughes", "s", "e"); ++ if (pk_strequal (text_safe, "richard\nhughee")) { ++ libst_success (test, NULL); ++ } else { ++ libst_failed (test, "failed the replace '%s'", text_safe); ++ } ++ g_free (text_safe); ++ ++ /************************************************************/ ++ libst_title (test, "replace unicode"); ++ text_safe = pk_strreplace ("richard\n- hughes", "\n- ", "\n• "); ++ if (pk_strequal (text_safe, "richard\n• hughes")) { ++ libst_success (test, NULL); ++ } else { ++ libst_failed (test, "failed the replace '%s'", text_safe); ++ } ++ g_free (text_safe); ++ ++ /************************************************************ + **************** Padding ****************** + ************************************************************/ + libst_title (test, "pad smaller, no extra"); +diff --git a/libpackagekit/pk-common.h b/libpackagekit/pk-common.h +index 9908ec2..9e5a05e 100644 +--- a/libpackagekit/pk-common.h ++++ b/libpackagekit/pk-common.h +@@ -84,6 +84,9 @@ gchar **pk_strsplit (const gchar *id, + gchar *pk_strbuild_va (const gchar *first_element, + va_list *args) + G_GNUC_WARN_UNUSED_RESULT; ++gchar *pk_strreplace (const gchar *text, ++ const gchar *find, ++ const gchar *replace); + gchar **pk_ptr_array_to_argv (GPtrArray *array) + G_GNUC_WARN_UNUSED_RESULT; + gchar **pk_va_list_to_argv (const gchar *string_first, +diff --git a/libpackagekit/pk-control.c b/libpackagekit/pk-control.c +index f2de5ae..5a54ccc 100644 +--- a/libpackagekit/pk-control.c ++++ b/libpackagekit/pk-control.c +@@ -198,6 +198,43 @@ out: + } + + /** ++ * pk_control_set_proxy: ++ * @control: a valid #PkControl instance ++ * @proxy_http: a HTTP proxy string such as "username:password@server.lan:8080" ++ * @proxy_ftp: a FTP proxy string such as "server.lan:8080" ++ * ++ * Set a proxy on the PK daemon ++ * ++ * Return value: if we set the proxy successfully ++ **/ ++gboolean ++pk_control_set_proxy (PkControl *control, const gchar *proxy_http, const gchar *proxy_ftp) ++{ ++ gboolean ret = FALSE; ++ GError *error = NULL; ++ ++ g_return_val_if_fail (PK_IS_CONTROL (control), PK_GROUP_ENUM_UNKNOWN); ++ ++ /* check to see if we have a valid proxy */ ++ if (control->priv->proxy == NULL) { ++ pk_warning ("No proxy for manager"); ++ goto out; ++ } ++ ret = dbus_g_proxy_call (control->priv->proxy, "SetProxy", &error, ++ G_TYPE_STRING, proxy_http, ++ G_TYPE_STRING, proxy_ftp, ++ G_TYPE_INVALID, ++ G_TYPE_INVALID); ++ if (!ret) { ++ /* abort as the DBUS method failed */ ++ pk_warning ("SetProxy failed :%s", error->message); ++ g_error_free (error); ++ } ++out: ++ return ret; ++} ++ ++/** + * pk_control_get_groups: + * @control: a valid #PkControl instance + * +diff --git a/libpackagekit/pk-control.h b/libpackagekit/pk-control.h +index 63b30d3..c1b1be8 100644 +--- a/libpackagekit/pk-control.h ++++ b/libpackagekit/pk-control.h +@@ -88,6 +88,9 @@ PkControl *pk_control_new (void); + gboolean pk_control_allocate_transaction_id (PkControl *control, + gchar **tid, + GError **error); ++gboolean pk_control_set_proxy (PkControl *control, ++ const gchar *proxy_http, ++ const gchar *proxy_ftp); + PkRoleEnum pk_control_get_actions (PkControl *control); + PkFilterEnum pk_control_get_filters (PkControl *control); + PkGroupEnum pk_control_get_groups (PkControl *control); +diff --git a/libpackagekit/pk-enum.c b/libpackagekit/pk-enum.c +index 5743dcb..9dccdd0 100644 +--- a/libpackagekit/pk-enum.c ++++ b/libpackagekit/pk-enum.c +@@ -152,6 +152,7 @@ static PkEnumMatch enum_error[] = { + {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_ERROR_ENUM_PACKAGE_CORRUPT, "package-corrupt"}, + {0, NULL} + }; + +@@ -417,6 +418,8 @@ static PkEnumMatch enum_free_licenses[] = { + {PK_LICENSE_ENUM_XANO, "XANO"}, + {PK_LICENSE_ENUM_VOSTROM, "VOSTROM"}, + {PK_LICENSE_ENUM_XEROX, "Xerox License"}, ++ {PK_LICENSE_ENUM_RICEBSD, "RiceBSD"}, ++ {PK_LICENSE_ENUM_QHULL, "Qhull"}, + {0, NULL} + }; + +diff --git a/libpackagekit/pk-enum.h b/libpackagekit/pk-enum.h +index e616b64..4cc317e 100644 +--- a/libpackagekit/pk-enum.h ++++ b/libpackagekit/pk-enum.h +@@ -256,6 +256,7 @@ typedef enum { + PK_ERROR_ENUM_REPO_NOT_AVAILABLE, + PK_ERROR_ENUM_INVALID_PACKAGE_FILE, + PK_ERROR_ENUM_PACKAGE_INSTALL_BLOCKED, ++ PK_ERROR_ENUM_PACKAGE_CORRUPT, + PK_ERROR_ENUM_UNKNOWN + } PkErrorCodeEnum; + +@@ -493,6 +494,8 @@ typedef enum { + PK_LICENSE_ENUM_XANO, + PK_LICENSE_ENUM_VOSTROM, + PK_LICENSE_ENUM_XEROX, ++ PK_LICENSE_ENUM_RICEBSD, ++ PK_LICENSE_ENUM_QHULL, + PK_LICENSE_ENUM_UNKNOWN + } PkLicenseEnum; + +diff --git a/libpackagekit/pk-extra.c b/libpackagekit/pk-extra.c +index 7f01a4c..d0f0776 100644 +--- a/libpackagekit/pk-extra.c ++++ b/libpackagekit/pk-extra.c +@@ -130,7 +130,6 @@ pk_extra_populate_package_cache_callback (void *data, gint argc, gchar **argv, g + obj->icon_name = icon_name; + obj->exec = exec; + g_hash_table_insert (extra->priv->hash_package, (gpointer) package, (gpointer) obj); +- pk_debug ("adding %s, %s", package, icon_name); + out: + return 0; + } +@@ -180,7 +179,6 @@ pk_extra_populate_locale_cache_callback (void *data, gint argc, gchar **argv, gc + obj = g_new (PkExtraLocaleObj, 1); + obj->summary = summary; + g_hash_table_insert (extra->priv->hash_locale, (gpointer) package, (gpointer) obj); +- pk_debug ("adding %s, %s", package, summary); + out: + return 0; + } +diff --git a/libpackagekit/pk-package-item.c b/libpackagekit/pk-package-item.c +index 87905dc..ff4bd4e 100644 +--- a/libpackagekit/pk-package-item.c ++++ b/libpackagekit/pk-package-item.c +@@ -56,7 +56,6 @@ pk_package_item_new (PkInfoEnum info, const gchar *package_id, const gchar *summ + + 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); +diff --git a/libpackagekit/pk-package-list.c b/libpackagekit/pk-package-list.c +index 5d95e1b..6bdb0d4 100644 +--- a/libpackagekit/pk-package-list.c ++++ b/libpackagekit/pk-package-list.c +@@ -77,7 +77,6 @@ pk_package_list_add (PkPackageList *plist, PkInfoEnum info, const gchar *package + g_return_val_if_fail (PK_IS_PACKAGE_LIST (plist), FALSE); + 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 = pk_package_item_new (info, package_id, summary); + g_ptr_array_add (plist->priv->array, item); + +@@ -104,9 +103,6 @@ pk_package_list_add_item (PkPackageList *plist, PkPackageItem *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); + +@@ -114,6 +110,30 @@ pk_package_list_add_item (PkPackageList *plist, PkPackageItem *item) + } + + /** ++ * pk_package_list_add_list: ++ * ++ * Makes a deep copy of the list ++ **/ ++gboolean ++pk_package_list_add_list (PkPackageList *plist, PkPackageList *list) ++{ ++ guint i; ++ guint len; ++ PkPackageItem *item; ++ ++ g_return_val_if_fail (PK_IS_PACKAGE_LIST (plist), FALSE); ++ g_return_val_if_fail (PK_IS_PACKAGE_LIST (list), FALSE); ++ ++ /* add list to plist */ ++ len = pk_package_list_get_size (list); ++ for (i=0; i<len; i++) { ++ item = pk_package_list_get_item (list, i); ++ pk_package_list_add_item (plist, item); ++ } ++ return TRUE; ++} ++ ++/** + * pk_package_list_get_string: + **/ + gchar * +diff --git a/libpackagekit/pk-package-list.h b/libpackagekit/pk-package-list.h +index 9734af4..83901ab 100644 +--- a/libpackagekit/pk-package-list.h ++++ b/libpackagekit/pk-package-list.h +@@ -59,6 +59,8 @@ gboolean pk_package_list_add (PkPackageList *plist, + const gchar *summary); + gboolean pk_package_list_add_item (PkPackageList *plist, + PkPackageItem *item); ++gboolean pk_package_list_add_list (PkPackageList *plist, ++ PkPackageList *list); + gboolean pk_package_list_contains (PkPackageList *plist, + const gchar *package_id); + gboolean pk_package_list_contains_item (PkPackageList *plist, +diff --git a/libpackagekit/pk-polkit-client.c b/libpackagekit/pk-polkit-client.c +index dceb656..7308a29 100644 +--- a/libpackagekit/pk-polkit-client.c ++++ b/libpackagekit/pk-polkit-client.c +@@ -54,9 +54,6 @@ static void pk_polkit_client_finalize (GObject *object); + #define POLKIT_DBUS_PATH "/org/gnome/PolicyKit/Manager" + #define POLKIT_DBUS_INTERFACE "org.gnome.PolicyKit.Manager" + +-/* we only support auth on the the transaction interface */ +-#define PK_ERROR_REFUSED_BY_POLICY "org.freedesktop.PackageKit.Transaction.RefusedByPolicy" +- + /** + * PkPolkitClientPrivate: + * +@@ -175,7 +172,10 @@ pk_polkit_client_error_denied_by_policy (GError *error) + /* check for specific error */ + error_name = dbus_g_error_get_name (error); + pk_debug ("ERROR: %s: %s", error_name, error->message); +- if (pk_strequal (error_name, PK_ERROR_REFUSED_BY_POLICY)) { ++ if (pk_strequal (error_name, "org.freedesktop.PackageKit.RefusedByPolicy")) { ++ return TRUE; ++ } ++ if (pk_strequal (error_name, "org.freedesktop.PackageKit.Transaction.RefusedByPolicy")) { + return TRUE; + } + return FALSE; +diff --git a/libpackagekit/pk-task-list.c b/libpackagekit/pk-task-list.c +index 76ab022..3dc1db0 100644 +--- a/libpackagekit/pk-task-list.c ++++ b/libpackagekit/pk-task-list.c +@@ -161,7 +161,7 @@ pk_task_list_status_changed_cb (PkClient *client, PkStatusEnum status, PkTaskLis + g_return_if_fail (PK_IS_TASK_LIST (tlist)); + + tid = pk_client_get_tid (client); +- pk_debug ("tid %s is now %i", tid, status); ++ pk_debug ("tid %s is now %s", tid, pk_status_enum_to_text (status)); + + /* get correct item */ + item = pk_task_list_find_existing_tid (tlist, tid); +diff --git a/po/LINGUAS b/po/LINGUAS +index 6dbee0e..f87e6b3 100644 +--- a/po/LINGUAS ++++ b/po/LINGUAS +@@ -5,6 +5,7 @@ es + fi + fr + he ++hu + it + nl + no_nb +diff --git a/po/de.po b/po/de.po +index 33d30c1..6e8013e 100644 +--- a/po/de.po ++++ b/po/de.po +@@ -8,8 +8,8 @@ msgid "" + msgstr "" + "Project-Id-Version: PackageKit\n" + "Report-Msgid-Bugs-To: \n" +-"POT-Creation-Date: 2008-04-23 01:36+0000\n" +-"PO-Revision-Date: 2008-04-23 19:28+0100\n" ++"POT-Creation-Date: 2008-05-03 01:22+0000\n" ++"PO-Revision-Date: 2008-05-20 21:52+0100\n" + "Last-Translator: Fabian Affolter <fab@fedoraproject.org>\n" + "Language-Team: German <fedora-trans-de@redhat.com>\n" + "MIME-Version: 1.0\n" +@@ -18,239 +18,239 @@ msgstr "" + "Plural-Forms: nplurals=2; plural=(n != 1);\n" + "X-Poedit-Language: German\n" + +-#: ../client/pk-console.c:208 ++#: ../client/pk-console.c:224 + msgid "Update detail" + msgstr "Aktualisierungsdetails" + +-#: ../client/pk-console.c:400 ++#: ../client/pk-console.c:425 + msgid "A system restart is required" + msgstr "Ein Systemneustart ist erforderlich" + +-#: ../client/pk-console.c:402 ++#: ../client/pk-console.c:427 + msgid "A logout and login is required" + msgstr "Eine Neuanmeldung ist erforderlich" + +-#: ../client/pk-console.c:404 ++#: ../client/pk-console.c:429 + msgid "An application restart is required" + msgstr "Ein Neustart der Anwendung ist erforderlich" + +-#: ../client/pk-console.c:443 ++#: ../client/pk-console.c:474 + #, c-format + msgid "Please enter a number from 1 to %i: " + msgstr "Bitte eine Zahl zwischen 1 und %i eingeben: " + +-#: ../client/pk-console.c:493 ++#: ../client/pk-console.c:524 + msgid "Could not find a package match" + msgstr "Es konnte kein passendes Paket gefunden werden" + +-#: ../client/pk-console.c:507 ++#: ../client/pk-console.c:538 + msgid "There are multiple package matches" + msgstr "Es wurden mehrere passende Paket gefunden" + + #. find out what package the user wants to use +-#: ../client/pk-console.c:514 ++#: ../client/pk-console.c:545 + msgid "Please enter the package number: " + msgstr "Bitte die Paketnummer eingeben: " + +-#: ../client/pk-console.c:530 ++#: ../client/pk-console.c:561 + msgid "Could not find a package with that name to install, or package already installed" + msgstr "Es konnten weder installierte noch zu installierende Paket mit diesem Namen gefunden werden" + +-#: ../client/pk-console.c:612 ++#: ../client/pk-console.c:643 + msgid "Could not find a package with that name to remove" + msgstr "Es konnte kein Paket mit diesem Namen zum Deinstallieren gefunden werden" + +-#: ../client/pk-console.c:652 ++#: ../client/pk-console.c:683 + msgid "The following packages have to be removed" + msgstr "Die folgenden Paket werden entfernt" + + #. get user input +-#: ../client/pk-console.c:661 ++#: ../client/pk-console.c:692 + msgid "Okay to remove additional packages?" + msgstr "Die folgenden zusätzlichen Pakete entfernen?" + +-#: ../client/pk-console.c:665 ++#: ../client/pk-console.c:696 + msgid "Cancelled!" + msgstr "Abgebrochen!" + +-#: ../client/pk-console.c:687 ++#: ../client/pk-console.c:718 + msgid "Could not find a package with that name to update" + msgstr "Es konnte kein Paket mit diesem Namen zum Aktualisieren gefunden werden" + +-#: ../client/pk-console.c:705 ++#: ../client/pk-console.c:736 + msgid "Could not find what packages require this package" + msgstr "Es konnte nicht rausgefunden werden, welche Pakete dieses Paket benötigen" + +-#: ../client/pk-console.c:723 ++#: ../client/pk-console.c:754 + msgid "Could not get dependencies for this package" + msgstr "Die Abhängigkeiten für dieses Paket konnten nicht ermittelt werden" + +-#: ../client/pk-console.c:741 +-msgid "Could not find a description for this package" +-msgstr "Die Beschreibung für dieses Paket konnten nicht ermittelt werden" ++#: ../client/pk-console.c:772 ++msgid "Could not find details for this package" ++msgstr "Die Details für dieses Paket konnten nicht gefunden werden" + +-#: ../client/pk-console.c:759 ++#: ../client/pk-console.c:790 + msgid "Could not find the files for this package" + msgstr "Die Dateien für dieses Paket konnten nicht ermittelt werden" + +-#: ../client/pk-console.c:819 ++#: ../client/pk-console.c:870 + msgid "Package description" + msgstr "Paketbeschreibung" + +-#: ../client/pk-console.c:842 ++#: ../client/pk-console.c:893 + msgid "Package files" + msgstr "Paketinhalt" + +-#: ../client/pk-console.c:850 ++#: ../client/pk-console.c:901 + msgid "No files" + msgstr "Keine Dateien" + + #. get user input +-#: ../client/pk-console.c:882 ++#: ../client/pk-console.c:933 + msgid "Okay to import key?" + msgstr "Soll der Schlüssel importiert werden?" + +-#: ../client/pk-console.c:885 ++#: ../client/pk-console.c:936 + msgid "Did not import key" + msgstr "Den Schlüssel nicht importieren" + + #. get user input +-#: ../client/pk-console.c:925 ++#: ../client/pk-console.c:976 + msgid "Do you agree?" + msgstr "Sind Sie einverstanden?" + +-#: ../client/pk-console.c:928 ++#: ../client/pk-console.c:979 + msgid "Did not agree to licence, task will fail" + msgstr "Lizenz wurde abgelehnt, Aufgabe wird fehlschlagen" + +-#: ../client/pk-console.c:957 ++#: ../client/pk-console.c:1008 + msgid "The daemon crashed mid-transaction!" + msgstr "Der Dienst ist während der Verarbeitung abgestürzt!" + + #. header +-#: ../client/pk-console.c:1010 ++#: ../client/pk-console.c:1061 + msgid "PackageKit Console Interface" + msgstr "PackageKit-Konsolenschnittstelle" + +-#: ../client/pk-console.c:1010 ++#: ../client/pk-console.c:1061 + msgid "Subcommands:" + msgstr "Unterbefehle:" + +-#: ../client/pk-console.c:1114 +-#: ../client/pk-monitor.c:100 ++#: ../client/pk-console.c:1165 ++#: ../client/pk-monitor.c:104 + #: ../src/pk-main.c:189 + msgid "Show extra debugging information" + msgstr "Zusätzliche Debugging-Informationen anzeigen" + +-#: ../client/pk-console.c:1116 +-#: ../client/pk-monitor.c:102 ++#: ../client/pk-console.c:1167 ++#: ../client/pk-monitor.c:106 + msgid "Show the program version and exit" + msgstr "Die Programmversion anzeigen und beenden" + +-#: ../client/pk-console.c:1118 ++#: ../client/pk-console.c:1169 + msgid "Set the filter, e.g. installed" + msgstr "Setzt den Filter, z. B. installiert" + +-#: ../client/pk-console.c:1120 ++#: ../client/pk-console.c:1171 + msgid "Exit without waiting for actions to complete" + msgstr "Beenden ohne auf das Ende der Aktionen zu warten" + +-#: ../client/pk-console.c:1143 ++#: ../client/pk-console.c:1194 + msgid "Could not connect to system DBUS." + msgstr "Mit System-DBUS konnte nicht verbunden werden." + +-#: ../client/pk-console.c:1231 ++#: ../client/pk-console.c:1288 + msgid "You need to specify a search type" + msgstr "Es muss eine Suchart angegeben werden" + +-#: ../client/pk-console.c:1236 +-#: ../client/pk-console.c:1243 +-#: ../client/pk-console.c:1250 +-#: ../client/pk-console.c:1257 +-#: ../client/pk-console.c:1361 +-#: ../client/pk-console.c:1368 +-#: ../client/pk-console.c:1375 +-#: ../client/pk-console.c:1382 ++#: ../client/pk-console.c:1293 ++#: ../client/pk-console.c:1300 ++#: ../client/pk-console.c:1307 ++#: ../client/pk-console.c:1314 ++#: ../client/pk-console.c:1421 ++#: ../client/pk-console.c:1428 ++#: ../client/pk-console.c:1435 ++#: ../client/pk-console.c:1442 + msgid "You need to specify a search term" + msgstr "Es muss ein Suchausdruck angegeben werden" + +-#: ../client/pk-console.c:1262 ++#: ../client/pk-console.c:1319 + msgid "Invalid search type" + msgstr "Ungültige Suchart" + +-#: ../client/pk-console.c:1267 ++#: ../client/pk-console.c:1324 + msgid "You need to specify a package or file to install" + msgstr "Es muss ein Paket oder eine Datei zum Installieren angegeben werden" + +-#: ../client/pk-console.c:1280 ++#: ../client/pk-console.c:1339 + msgid "You need to specify a type, key_id and package_id" + msgstr "Es muss ein Typ angegeben werden, key_id oder package_id" + +-#: ../client/pk-console.c:1287 ++#: ../client/pk-console.c:1346 + msgid "You need to specify a package to remove" + msgstr "Es muss ein Paket zum Entfernen angegeben werden" + +-#: ../client/pk-console.c:1294 ++#: ../client/pk-console.c:1353 + msgid "You need to specify a eula-id" + msgstr "Es muss eine eula-id angegeben werden" + +-#: ../client/pk-console.c:1309 ++#: ../client/pk-console.c:1369 + msgid "You need to specify a package name to resolve" + msgstr "Es muss ein Paketname zum Auflösen angegeben werden" + +-#: ../client/pk-console.c:1316 +-#: ../client/pk-console.c:1323 ++#: ../client/pk-console.c:1376 ++#: ../client/pk-console.c:1383 + msgid "You need to specify a repo name" + msgstr "Es muss ein Repository-Name angegeben werden" + +-#: ../client/pk-console.c:1330 ++#: ../client/pk-console.c:1390 + msgid "You need to specify a repo name/parameter and value" + msgstr "Es muss ein Repository-Name/Argument und Wert angegeben werden" + +-#: ../client/pk-console.c:1343 ++#: ../client/pk-console.c:1403 + msgid "You need to specify a time term" + msgstr "Es muss ein Zeitausdruck angegeben werden" + +-#: ../client/pk-console.c:1348 ++#: ../client/pk-console.c:1408 + msgid "You need to specify a correct role" + msgstr "Es muss eine korrekte Rolle angegeben werden" + +-#: ../client/pk-console.c:1353 ++#: ../client/pk-console.c:1413 + msgid "Failed to get last time" + msgstr "Die letzte Zeit konnte nicht abgefragt werden" + +-#: ../client/pk-console.c:1389 +-msgid "You need to specify a package to find the description for" +-msgstr "Es muss ein Paket angegeben werden zu dem die Beschreibung gefunden werden soll" ++#: ../client/pk-console.c:1449 ++msgid "You need to specify a package to find the details for" ++msgstr "Es muss ein Paket angegeben werden zu dem die Details gefunden werden sollen" + +-#: ../client/pk-console.c:1396 ++#: ../client/pk-console.c:1456 + msgid "You need to specify a package to find the files for" + msgstr "Es muss ein Paket angegeben werden zu dem die Dateien gefunden werden sollen" + +-#: ../client/pk-console.c:1441 ++#: ../client/pk-console.c:1503 + #, c-format + msgid "Option '%s' not supported" + msgstr "Option '%s' wird nicht unterstützt" + +-#: ../client/pk-console.c:1452 ++#: ../client/pk-console.c:1514 + msgid "Command failed" + msgstr "Befehl fehlgeschlagen" + +-#: ../client/pk-console.c:1456 ++#: ../client/pk-console.c:1518 + msgid "You don't have the necessary privileges for this operation" + msgstr "Es fehlen die benötigten Rechte für diese Operation" + +-#: ../client/pk-monitor.c:113 ++#: ../client/pk-monitor.c:117 + msgid "PackageKit Monitor" + msgstr "PackageKit Monitor" + +-#: ../client/pk-import-desktop.c:283 ++#: ../client/pk-import-desktop.c:293 + #: ../client/pk-import-specspo.c:169 + #, c-format + msgid "Could not open database: %s" + msgstr "Datenbank konnte nicht geöffnet werden: %s" + +-#: ../client/pk-import-desktop.c:284 ++#: ../client/pk-import-desktop.c:294 + #: ../client/pk-import-specspo.c:170 + msgid "You probably need to run this program as the root user" + msgstr "Das Programm muss möglicherweise als Benutzer root ausgeführt werden" +@@ -308,6 +308,12 @@ msgstr "Es konnte nicht zum System-Bus verbunden werden" + msgid "Error trying to start: %s\n" + msgstr "Fehler beim Versuch zu starten: %s\n" + ++#~ msgid "Could not find a description for this package" ++#~ msgstr "Die Beschreibung für dieses Paket konnten nicht ermittelt werden" ++#~ msgid "You need to specify a package to find the description for" ++#~ msgstr "" ++#~ "Es muss ein Paket angegeben werden zu dem die Beschreibung gefunden " ++#~ "werden soll" + #~ msgid "Accept EULA" + #~ msgstr "EULA akzeptieren" + #~ msgid "Authentication is required to accept a EULA" +diff --git a/po/hu.po b/po/hu.po +new file mode 100644 +index 0000000..ea732d0 +--- /dev/null ++++ b/po/hu.po +@@ -0,0 +1,311 @@ ++# SOME DESCRIPTIVE TITLE. ++# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER ++# This file is distributed under the same license as the PACKAGE package. ++# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. ++# ++msgid "" ++msgstr "" ++"Project-Id-Version: packagekit\n" ++"Report-Msgid-Bugs-To: \n" ++"POT-Creation-Date: 2008-05-18 17:43+0000\n" ++"PO-Revision-Date: 2008-05-19 00:08+0100\n" ++"Last-Translator: Sulyok Péter <peti@fedoraproject.org>\n" ++"Language-Team: Hungarian <fedora-trans-hu@redhat.com>\n" ++"MIME-Version: 1.0\n" ++"Content-Type: text/plain; charset=utf-8\n" ++"Content-Transfer-Encoding: 8bit\n" ++"Plural-Forms: nplurals=2; plural=n>1\n" ++"X-Poedit-Language: Hungarian\n" ++"X-Poedit-Country: HUNGARY\n" ++"X-Poedit-SourceCharset: utf-8\n" ++ ++#: ../client/pk-console.c:224 ++msgid "Update detail" ++msgstr "Frissítés részletező" ++ ++#: ../client/pk-console.c:425 ++msgid "A system restart is required" ++msgstr "Rendszer-újraindítás szükséges" ++ ++#: ../client/pk-console.c:427 ++msgid "A logout and login is required" ++msgstr "Kijelentkezés és bejelentkezés szükséges" ++ ++#: ../client/pk-console.c:429 ++msgid "An application restart is required" ++msgstr "Alkalmazás-újraindítás szükséges" ++ ++#: ../client/pk-console.c:474 ++#, c-format ++msgid "Please enter a number from 1 to %i: " ++msgstr "Kérem adjon meg egy számot 1-től %i-ig:" ++ ++#: ../client/pk-console.c:524 ++msgid "Could not find a package match" ++msgstr "Nincs megfelelő csomag" ++ ++#: ../client/pk-console.c:538 ++msgid "There are multiple package matches" ++msgstr "Több csomag illik" ++ ++#. find out what package the user wants to use ++#: ../client/pk-console.c:545 ++msgid "Please enter the package number: " ++msgstr "Kérem adja meg a csomagszámot:" ++ ++#: ../client/pk-console.c:561 ++msgid "Could not find a package with that name to install, or package already installed" ++msgstr "Nem lehetett csomagot találni azzal a névvel telepítésre, vagy márt telepített csomagot" ++ ++#: ../client/pk-console.c:643 ++msgid "Could not find a package with that name to remove" ++msgstr "Nem lehetett csomagot találni azzal a névvel törlésre" ++ ++#: ../client/pk-console.c:683 ++msgid "The following packages have to be removed" ++msgstr "A következő csomagokat kell eltávolítani" ++ ++#. get user input ++#: ../client/pk-console.c:692 ++msgid "Okay to remove additional packages?" ++msgstr "Eltávolíthatók további csomagok?" ++ ++#: ../client/pk-console.c:696 ++msgid "Cancelled!" ++msgstr "Megszakítva!" ++ ++#: ../client/pk-console.c:718 ++msgid "Could not find a package with that name to update" ++msgstr "Nem lehetett csomagot találni azzal a névvel frissítésre" ++ ++#: ../client/pk-console.c:736 ++msgid "Could not find what packages require this package" ++msgstr "Nem lehetett megtudni mely csomagok szükségesek" ++ ++#: ../client/pk-console.c:754 ++msgid "Could not get dependencies for this package" ++msgstr "Nem lehetett csomagfüggőséget megkapni e csomaghoz" ++ ++#: ../client/pk-console.c:772 ++msgid "Could not find details for this package" ++msgstr "Nem lehetett részletezőt találni e csomaghoz" ++ ++#: ../client/pk-console.c:790 ++msgid "Could not find the files for this package" ++msgstr "Nem lehetett fájlokat találni e csomaghoz" ++ ++#: ../client/pk-console.c:870 ++msgid "Package description" ++msgstr "Csomagleírás" ++ ++#: ../client/pk-console.c:893 ++msgid "Package files" ++msgstr "Csomagfájlok" ++ ++#: ../client/pk-console.c:901 ++msgid "No files" ++msgstr "Nincs fájl" ++ ++#. get user input ++#: ../client/pk-console.c:933 ++msgid "Okay to import key?" ++msgstr "Behozhatunk kulcsot?" ++ ++#: ../client/pk-console.c:936 ++msgid "Did not import key" ++msgstr "Nem hoztunk be kulcsot" ++ ++#. get user input ++#: ../client/pk-console.c:976 ++msgid "Do you agree?" ++msgstr "Egyetért?" ++ ++#: ../client/pk-console.c:979 ++msgid "Did not agree to licence, task will fail" ++msgstr "Nem egyezett meg az engedélyben, a munka elbukik" ++ ++#: ../client/pk-console.c:1008 ++msgid "The daemon crashed mid-transaction!" ++msgstr "A szolgáltatás összeomlott tranzakció közben!" ++ ++#. header ++#: ../client/pk-console.c:1061 ++msgid "PackageKit Console Interface" ++msgstr "PackageKit parancssori felület" ++ ++#: ../client/pk-console.c:1061 ++msgid "Subcommands:" ++msgstr "Részparancsok:" ++ ++#: ../client/pk-console.c:1165 ++#: ../client/pk-monitor.c:104 ++#: ../src/pk-main.c:189 ++msgid "Show extra debugging information" ++msgstr "Extra hibakereső adatok megjelenítése" ++ ++#: ../client/pk-console.c:1167 ++#: ../client/pk-monitor.c:106 ++msgid "Show the program version and exit" ++msgstr "Programváltozat megmutatása és kilépés" ++ ++#: ../client/pk-console.c:1169 ++msgid "Set the filter, e.g. installed" ++msgstr "Szűrő beállítása, pl. telepítve" ++ ++#: ../client/pk-console.c:1171 ++msgid "Exit without waiting for actions to complete" ++msgstr "Kilépés cselekmény befejezésére várakozás nélkül" ++ ++#: ../client/pk-console.c:1194 ++msgid "Could not connect to system DBUS." ++msgstr "Nem lehetett kapcsolódni DBUS-hoz." ++ ++#: ../client/pk-console.c:1288 ++msgid "You need to specify a search type" ++msgstr "Meg kell adni a keresendő típust" ++ ++#: ../client/pk-console.c:1293 ++#: ../client/pk-console.c:1300 ++#: ../client/pk-console.c:1307 ++#: ../client/pk-console.c:1314 ++#: ../client/pk-console.c:1421 ++#: ../client/pk-console.c:1428 ++#: ../client/pk-console.c:1435 ++#: ../client/pk-console.c:1442 ++msgid "You need to specify a search term" ++msgstr "Meg kell adni a keresendő kifejezést" ++ ++#: ../client/pk-console.c:1319 ++msgid "Invalid search type" ++msgstr "Érvénytelen típus" ++ ++#: ../client/pk-console.c:1324 ++msgid "You need to specify a package or file to install" ++msgstr "Meg kell adnia a telepítendő csomag vagy fájl nevét" ++ ++#: ../client/pk-console.c:1339 ++msgid "You need to specify a type, key_id and package_id" ++msgstr "Meg kell adnia egy típust, kulcs azonosítót és csomag azonosítót" ++ ++#: ../client/pk-console.c:1346 ++msgid "You need to specify a package to remove" ++msgstr "Meg kell adnia egy eltávolítandó csomagot" ++ ++#: ../client/pk-console.c:1353 ++msgid "You need to specify a eula-id" ++msgstr "Meg kell adnia egy végfelhasználó azonosítót" ++ ++#: ../client/pk-console.c:1369 ++msgid "You need to specify a package name to resolve" ++msgstr "Meg kell adnia egy feloldandó csomagnevet" ++ ++#: ../client/pk-console.c:1376 ++#: ../client/pk-console.c:1383 ++msgid "You need to specify a repo name" ++msgstr "Meg kell adnia egy tár nevét" ++ ++#: ../client/pk-console.c:1390 ++msgid "You need to specify a repo name/parameter and value" ++msgstr "Meg kell adnia egy tárnevet/paramétert és értéket" ++ ++#: ../client/pk-console.c:1403 ++msgid "You need to specify a time term" ++msgstr "Meg kell adnia egy időszakot" ++ ++#: ../client/pk-console.c:1408 ++msgid "You need to specify a correct role" ++msgstr "Meg kell adnia egy helyes szerepet" ++ ++#: ../client/pk-console.c:1413 ++msgid "Failed to get last time" ++msgstr "Nem sikerült megkapni az utolsó időt" ++ ++#: ../client/pk-console.c:1449 ++msgid "You need to specify a package to find the details for" ++msgstr "Meg kell adnia egy egy csomagot, amihez részletező keresendő" ++ ++#: ../client/pk-console.c:1456 ++msgid "You need to specify a package to find the files for" ++msgstr "Meg kell adnia egy csomagot, amihez fájlokat kell találni" ++ ++#: ../client/pk-console.c:1503 ++#, c-format ++msgid "Option '%s' not supported" ++msgstr "„%s” opció nem támogatott" ++ ++#: ../client/pk-console.c:1514 ++msgid "Command failed" ++msgstr "Parancs elbukott" ++ ++#: ../client/pk-console.c:1518 ++msgid "You don't have the necessary privileges for this operation" ++msgstr "Önnek nincs meg szükséges jogosultsága e műveletre" ++ ++#: ../client/pk-monitor.c:117 ++msgid "PackageKit Monitor" ++msgstr "PackageKit figyelő" ++ ++#: ../client/pk-import-desktop.c:293 ++#: ../client/pk-import-specspo.c:169 ++#, c-format ++msgid "Could not open database: %s" ++msgstr "Nem lehetett megnyitni %s adatbázist" ++ ++#: ../client/pk-import-desktop.c:294 ++#: ../client/pk-import-specspo.c:170 ++msgid "You probably need to run this program as the root user" ++msgstr "E program valószínűleg rendszergazdaként futtatható" ++ ++#: ../src/pk-main.c:83 ++msgid "Startup failed due to security policies on this machine." ++msgstr "Indulás sikertelen a gép biztonsági szabályzata miatt." ++ ++#: ../src/pk-main.c:84 ++msgid "This can happen for two reasons:" ++msgstr "Két okból történet mehet:" ++ ++#: ../src/pk-main.c:85 ++msgid "The correct user is not launching the executable (usually root)" ++msgstr "A helyes használó nem indítja a futtathatót (rendszerint rendszergada)" ++ ++#: ../src/pk-main.c:86 ++msgid "The org.freedesktop.PackageKit.conf file is not installed in the system /etc/dbus-1/system.d directory" ++msgstr "Az org.freedesktop.PackageKit.conf a rendszert nem telepítették a system /etc/dbus-1/system.d mappába" ++ ++#: ../src/pk-main.c:185 ++msgid "Packaging backend to use, e.g. dummy" ++msgstr "Használandó csomagoló háttér, pl. dummy" ++ ++#: ../src/pk-main.c:187 ++msgid "Daemonize and detach from the terminal" ++msgstr "Szolgálatatás és leválasztás terminálról" ++ ++#: ../src/pk-main.c:191 ++msgid "Disable the idle timer" ++msgstr "Tétlen időzítő kikapcsolása" ++ ++#: ../src/pk-main.c:193 ++msgid "Show version and exit" ++msgstr "Változat mutatása és kilépés" ++ ++#: ../src/pk-main.c:195 ++msgid "Exit after a small delay" ++msgstr "Kilépés rövid késleltetés után" ++ ++#: ../src/pk-main.c:197 ++msgid "Exit after the engine has loaded" ++msgstr "Kilépés a motor betöltése után" ++ ++#: ../src/pk-main.c:207 ++msgid "PackageKit service" ++msgstr "PackageKit szolgáltatás" ++ ++#: ../src/pk-main.c:233 ++msgid "Cannot connect to the system bus" ++msgstr "Nem lehetett csatlakozni a rendszerbuszhoz" ++ ++#: ../src/pk-main.c:273 ++#, c-format ++msgid "Error trying to start: %s\n" ++msgstr "Hiba %s indításakor\n" ++ +diff --git a/policy/org.freedesktop.packagekit.policy.in b/policy/org.freedesktop.packagekit.policy.in +index 32efce7..4c4607d 100644 +--- a/policy/org.freedesktop.packagekit.policy.in ++++ b/policy/org.freedesktop.packagekit.policy.in +@@ -133,5 +133,17 @@ + <allow_active>yes</allow_active> + </defaults> + </action> ++ ++ <action id="org.freedesktop.packagekit.set-proxy"> ++ <_description>Set network proxy</_description> ++ <_message>Authentication is required to set the network proxy used for downloading packages</_message> ++ <icon_name>applications-internet</icon_name> ++ <vendor_url>http://www.packagekit.org/pk-reference.html#methods-set-proxy</vendor_url> ++ <defaults> ++ <allow_inactive>no</allow_inactive> ++ <allow_active>yes</allow_active> ++ </defaults> ++ </action> ++ + </policyconfig> + +diff --git a/python/packagekit/daemonBackend.py b/python/packagekit/daemonBackend.py +index 5253b39..9fd627a 100644 +--- a/python/packagekit/daemonBackend.py ++++ b/python/packagekit/daemonBackend.py +@@ -325,13 +325,13 @@ class PackageKitBaseBackend(dbus.service.Object): + + @PKSignalHouseKeeper + @dbus.service.signal(dbus_interface=PACKAGEKIT_DBUS_INTERFACE, +- signature='sssssss') +- def RepoSignatureRequired(self,repo_name,key_url,key_userid,key_id,key_fingerprint,key_timestamp,key_type): ++ signature='ssssssss') ++ def RepoSignatureRequired(self,id,repo_name,key_url,key_userid,key_id,key_fingerprint,key_timestamp,key_type): + ''' + send 'repo-signature-required' signal: + ''' + pklog.info("RepoSignatureRequired (%s, %s, %s, %s, %s, %s, %s, %s)" % +- (repo_name,key_url,key_userid,key_id,key_fingerprint,key_timestamp,key_type)) ++ (id,repo_name,key_url,key_userid,key_id,key_fingerprint,key_timestamp,key_type)) + + + # +@@ -658,8 +658,9 @@ class PackageKitBaseBackend(dbus.service.Object): + ''' + Implement the {backend}-remove functionality + ''' +- pklog.info("RemovePackages(%s, %s, %s)" % (package[0], allowdep, autoremove)) +- self.doRemovePackages(package, allowdep, autoremove) ++ pklog.info("RemovePackages(%s, %s, %s)" % (packages, allowdep, ++ autoremove)) ++ self.doRemovePackages(packages, allowdep, autoremove) + + def doRemovePackages(self, packages, allowdep, autoremove): + ''' +diff --git a/src/pk-backend-spawn.c b/src/pk-backend-spawn.c +index f9c9f12..2bd416d 100644 +--- a/src/pk-backend-spawn.c ++++ b/src/pk-backend-spawn.c +@@ -316,8 +316,8 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line) + pk_backend_set_percentage (backend_spawn->priv->backend, PK_BACKEND_PERCENTAGE_INVALID); + } else if (pk_strequal (command, "repo-signature-required")) { + +- if (size != 9+99) { +- pk_error ("invalid command '%s'", command); ++ if (size != 9) { ++ pk_warning ("invalid command '%s'", command); + ret = FALSE; + goto out; + } +diff --git a/src/pk-backend.c b/src/pk-backend.c +index 37ed024..f0f245f 100644 +--- a/src/pk-backend.c ++++ b/src/pk-backend.c +@@ -1484,8 +1484,7 @@ pk_backend_finished (PkBackend *backend) + backend->priv->role == PK_ROLE_ENUM_REMOVE_PACKAGES || + backend->priv->role == PK_ROLE_ENUM_UPDATE_PACKAGES)) { + pk_backend_message (backend, PK_MESSAGE_ENUM_DAEMON, +- "Backends need to send a Package() for this role!"); +- return FALSE; ++ "Backends should send a Package() for this role!"); + } + + /* if we set an error code notifier, clear */ +diff --git a/src/pk-backend.h b/src/pk-backend.h +index fb17e3c..a7ba754 100644 +--- a/src/pk-backend.h ++++ b/src/pk-backend.h +@@ -256,7 +256,7 @@ typedef struct { + void (*update_system) (PkBackend *backend); + void (*what_provides) (PkBackend *backend, + PkFilterEnum filters, +- PkProvidesEnum provide, ++ PkProvidesEnum provides, + const gchar *search); + gpointer padding[10]; + } PkBackendDesc; +diff --git a/src/pk-engine.c b/src/pk-engine.c +index 028a0d0..14ecf41 100644 +--- a/src/pk-engine.c ++++ b/src/pk-engine.c +@@ -154,6 +154,8 @@ pk_engine_error_get_type (void) + static const GEnumValue values[] = + { + ENUM_ENTRY (PK_ENGINE_ERROR_INVALID_STATE, "InvalidState"), ++ ENUM_ENTRY (PK_ENGINE_ERROR_REFUSED_BY_POLICY, "RefusedByPolicy"), ++ ENUM_ENTRY (PK_ENGINE_ERROR_CANNOT_SET_PROXY, "CannotSetProxy"), + { 0, NULL, NULL } + }; + etype = g_enum_register_static ("PkEngineError", values); +@@ -502,6 +504,47 @@ pk_engine_suggest_daemon_quit (PkEngine *engine, GError **error) + } + + /** ++ * pk_engine_set_proxy: ++ **/ ++void ++pk_engine_set_proxy (PkEngine *engine, const gchar *proxy_http, const gchar *proxy_ftp, DBusGMethodInvocation *context) ++{ ++ gboolean ret; ++ GError *error; ++ gchar *sender = NULL; ++ gchar *error_detail = NULL; ++ ++ g_return_if_fail (PK_IS_ENGINE (engine)); ++ ++ pk_debug ("SetProxy method called: %s, %s", proxy_http, proxy_ftp); ++ ++ /* check if the action is allowed from this client - if not, set an error */ ++ sender = dbus_g_method_get_sender (context); ++ ++ /* use security model to get auth */ ++ ret = pk_security_action_is_allowed (engine->priv->security, sender, FALSE, PK__ROLE_ENUM_SET_PROXY, &error_detail); ++ if (!ret) { ++ error = g_error_new (PK_ENGINE_ERROR, PK_ENGINE_ERROR_REFUSED_BY_POLICY, "%s", error_detail); ++ dbus_g_method_return_error (context, error); ++ goto out; ++ } ++ ++ /* try to set the new proxy */ ++ ret = pk_backend_set_proxy (engine->priv->backend, proxy_http, proxy_ftp); ++ if (!ret) { ++ error = g_error_new (PK_ENGINE_ERROR, PK_ENGINE_ERROR_CANNOT_SET_PROXY, "%s", "setting the proxy failed"); ++ dbus_g_method_return_error (context, error); ++ goto out; ++ } ++ ++ /* all okay */ ++ dbus_g_method_return (context); ++out: ++ g_free (sender); ++ g_free (error_detail); ++} ++ ++/** + * pk_engine_class_init: + * @klass: The PkEngineClass + **/ +diff --git a/src/pk-engine.h b/src/pk-engine.h +index c59b1f3..668451f 100644 +--- a/src/pk-engine.h ++++ b/src/pk-engine.h +@@ -57,9 +57,12 @@ typedef enum + { + PK_ENGINE_ERROR_DENIED, + PK_ENGINE_ERROR_INVALID_STATE, ++ PK_ENGINE_ERROR_REFUSED_BY_POLICY, ++ PK_ENGINE_ERROR_CANNOT_SET_PROXY, + PK_ENGINE_ERROR_LAST + } PkEngineError; + ++ + GQuark pk_engine_error_quark (void); + GType pk_engine_error_get_type (void) G_GNUC_CONST; + GType pk_engine_get_type (void) G_GNUC_CONST; +@@ -100,6 +103,10 @@ gboolean pk_engine_state_has_changed (PkEngine *engine, + GError **error); + gboolean pk_engine_suggest_daemon_quit (PkEngine *engine, + GError **error); ++void pk_engine_set_proxy (PkEngine *engine, ++ const gchar *proxy_http, ++ const gchar *proxy_ftp, ++ DBusGMethodInvocation *context); + + G_END_DECLS + +diff --git a/src/pk-interface.xml b/src/pk-interface.xml +index e9e74e1..7290bbe 100644 +--- a/src/pk-interface.xml ++++ b/src/pk-interface.xml +@@ -33,6 +33,11 @@ + <method name="GetNetworkState"> + <arg type="s" name="state" direction="out"/> + </method> ++ <method name="SetProxy"> ++ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> ++ <arg type="s" name="proxy_http" direction="in"/> ++ <arg type="s" name="proxy_ftp" direction="in"/> ++ </method> + + <signal name="TransactionListChanged"> + <arg type="as" name="transactions" direction="out"/> +diff --git a/src/pk-security-polkit.c b/src/pk-security-polkit.c +index 9abf992..81332d0 100644 +--- a/src/pk-security-polkit.c ++++ b/src/pk-security-polkit.c +@@ -128,6 +128,9 @@ pk_security_role_to_action (PkSecurity *security, gboolean trusted, PkRoleEnum r + policy = "org.freedesktop.packagekit.repo-change"; + } else if (role == PK_ROLE_ENUM_REFRESH_CACHE) { + policy = "org.freedesktop.packagekit.refresh-cache"; ++ /* PRIVATE: not actually roles */ ++ } else if (role == PK__ROLE_ENUM_SET_PROXY) { ++ policy = "org.freedesktop.packagekit.refresh-cache"; + } + return policy; + } +diff --git a/src/pk-security.h b/src/pk-security.h +index 3432095..eb55932 100644 +--- a/src/pk-security.h ++++ b/src/pk-security.h +@@ -34,6 +34,9 @@ G_BEGIN_DECLS + #define PK_IS_SECURITY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PK_TYPE_SECURITY)) + #define PK_SECURITY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), PK_TYPE_SECURITY, PkSecurityClass)) + ++/* FIXME: not actually a role */ ++#define PK__ROLE_ENUM_SET_PROXY 1 << 31 ++ + typedef struct PkSecurityPrivate PkSecurityPrivate; + + typedef struct +diff --git a/src/pk-transaction-db.c b/src/pk-transaction-db.c +index 7aa183f..d42bc7a 100644 +--- a/src/pk-transaction-db.c ++++ b/src/pk-transaction-db.c +@@ -46,7 +46,12 @@ static void pk_transaction_db_init (PkTransactionDb *tdb); + static void pk_transaction_db_finalize (GObject *object); + + #define PK_TRANSACTION_DB_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_TRANSACTION_DB, PkTransactionDbPrivate)) ++ ++#if PK_BUILD_LOCAL ++#define PK_TRANSACTION_DB_FILE "./transactions.db" ++#else + #define PK_TRANSACTION_DB_FILE PK_DB_DIR "/transactions.db" ++#endif + + struct PkTransactionDbPrivate + { +diff --git a/src/pk-transaction-list.c b/src/pk-transaction-list.c +index 0921c7c..f325f94 100644 +--- a/src/pk-transaction-list.c ++++ b/src/pk-transaction-list.c +@@ -89,7 +89,6 @@ pk_transaction_list_get_from_transaction (PkTransactionList *tlist, PkTransactio + + /* find the runner with the transaction ID */ + length = tlist->priv->array->len; +- pk_debug ("length = %i", length); + for (i=0; i<length; i++) { + item = (PkTransactionItem *) g_ptr_array_index (tlist->priv->array, i); + if (item->transaction == transaction) { +@@ -352,28 +351,29 @@ gchar ** + pk_transaction_list_get_array (PkTransactionList *tlist) + { + guint i; +- guint count = 0; + guint length; ++ GPtrArray *parray; + gchar **array; + PkTransactionItem *item; + + g_return_val_if_fail (PK_IS_TRANSACTION_LIST (tlist), NULL); + ++ /* use a temp array, as not all are in progress */ ++ parray = g_ptr_array_new (); ++ + /* find all the transactions in progress */ + length = tlist->priv->array->len; +- +- /* create new strv list */ +- array = g_new0 (gchar *, length + 1); +- +- pk_debug ("%i active transactions", length); + for (i=0; i<length; i++) { + item = (PkTransactionItem *) g_ptr_array_index (tlist->priv->array, i); +- /* only return in the list if it worked */ +- if (item->committed && item->finished == FALSE) { +- array[count] = g_strdup (item->tid); +- count++; ++ /* only return in the list if its committed and not finished */ ++ if (item->committed && !item->finished) { ++ g_ptr_array_add (parray, g_strdup (item->tid)); + } + } ++ pk_debug ("%i transactions in list, %i active", length, parray->len); ++ array = pk_ptr_array_to_argv (parray); ++ g_ptr_array_free (parray, TRUE); ++ + return array; + } + +diff --git a/src/pk-transaction.c b/src/pk-transaction.c +index 07ffdee..15faed3 100644 +--- a/src/pk-transaction.c ++++ b/src/pk-transaction.c +@@ -71,6 +71,7 @@ struct PkTransactionPrivate + PkStatusEnum status; + gboolean finished; + gboolean running; ++ gboolean has_been_run; + gboolean allow_cancel; + gboolean emit_eula_required; + gboolean emit_signature_required; +@@ -798,6 +799,7 @@ pk_transaction_set_running (PkTransaction *transaction) + + /* mark running */ + transaction->priv->running = TRUE; ++ transaction->priv->has_been_run = TRUE; + + /* set all possible arguments for backend */ + pk_backend_set_bool (priv->backend, "force", priv->cached_force); +@@ -1152,11 +1154,17 @@ pk_transaction_cancel (PkTransaction *transaction, GError **error) + g_return_val_if_fail (transaction->priv->tid != NULL, FALSE); + + pk_debug ("Cancel method called"); +- /* check to see if we are trying to cancel a non-running task */ +- if (!transaction->priv->running) { +- g_set_error (error, PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_NOT_RUNNING, +- "cancelling a non-running transaction"); +- return FALSE; ++ ++ /* if it's never been run, just remove this transaction from the list */ ++ if (!transaction->priv->has_been_run) { ++ pk_transaction_list_remove (transaction->priv->transaction_list, transaction); ++ return TRUE; ++ } ++ ++ /* if it's finished, cancelling will have no action */ ++ if (transaction->priv->finished) { ++ pk_warning ("No point trying to cancel a finished transaction, ignoring"); ++ return TRUE; + } + + /* not implemented yet */ +@@ -2871,7 +2879,7 @@ pk_transaction_what_provides (PkTransaction *transaction, const gchar *filter, c + return; + } + +- provides = pk_role_enum_from_text (type); ++ provides = pk_provides_enum_from_text (type); + if (provides == PK_PROVIDES_ENUM_UNKNOWN) { + error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_INVALID_PROVIDE, + "provide type '%s' not found", type); +@@ -3011,6 +3019,7 @@ pk_transaction_init (PkTransaction *transaction) + transaction->priv = PK_TRANSACTION_GET_PRIVATE (transaction); + transaction->priv->finished = FALSE; + transaction->priv->running = FALSE; ++ transaction->priv->has_been_run = FALSE; + transaction->priv->allow_cancel = FALSE; + transaction->priv->emit_eula_required = FALSE; + transaction->priv->emit_signature_required = FALSE; +diff --git a/tools/add-error-enum.sh b/tools/add-error-enum.sh +index f78c891..6521e69 100755 +--- a/tools/add-error-enum.sh ++++ b/tools/add-error-enum.sh +@@ -7,5 +7,5 @@ + # the Free Software Foundation; either version 2 of the License, or + # (at your option) any later version. + +-$EDITOR docs/spec/pk-introduction.xml libpackagekit/pk-enum.h libpackagekit/pk-enum.c ../gnome-packagekit/src/gpk-common.c ++$EDITOR docs/spec/pk-concepts.xml libpackagekit/pk-enum.h libpackagekit/pk-enum.c ../gnome-packagekit/src/gpk-common.c + +diff --git a/tools/rpmbuild.sh b/tools/rpmbuild.sh +deleted file mode 100755 +index ebbd8f7..0000000 +--- a/tools/rpmbuild.sh ++++ /dev/null +@@ -1,19 +0,0 @@ +-#!/bin/sh +-# Copyright (C) 2008 Richard Hughes <richard@hughsie.com> +-# +-# Licensed under the GNU General Public License Version 2 +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2 of the License, or +-# (at your option) any later version. +- +-sudo echo "Build!" +-#autobuild.sh all PolicyKit +-#sudo auto_refresh_from_repo.sh +-#autobuild.sh all PolicyKit-gnome +-#sudo auto_refresh_from_repo.sh +-autobuild.sh all PackageKit force +-sudo auto_refresh_from_repo.sh +-autobuild.sh all gnome-packagekit force +-sudo auto_refresh_from_repo.sh +- |