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

Richard Hughes hughsient at kemper.freedesktop.org
Thu Jun 4 02:13:09 PDT 2009


 RELEASE                               |    6 
 backends/portage/pk-backend-portage.c |  107 +++++++--
 backends/portage/portageBackend.py    |  219 ++++++++++++++++++
 backends/yum/pk-backend-yum.c         |    2 
 backends/yum/yumBackend.py            |    4 
 configure.ac                          |   28 ++
 etc/PackageKit.conf.in                |   11 
 po/gu.po                              |   88 ++++---
 po/mr.po                              |   61 ++---
 po/te.po                              |   85 +++----
 src/Makefile.am                       |   20 +
 src/pk-engine.c                       |   12 -
 src/pk-marshal.list                   |    2 
 src/pk-network-nm-dummy.c             |  137 -----------
 src/pk-network-nm.c                   |  392 ----------------------------------
 src/pk-network-nm.h                   |   68 -----
 src/pk-network-stack-connman.c        |  317 +++++++++++++++++++++++++++
 src/pk-network-stack-connman.h        |   57 ++++
 src/pk-network-stack-nm.c             |  382 +++++++++++++++++++++++++++++++++
 src/pk-network-stack-nm.h             |   56 ++++
 src/pk-network-stack-unix.c           |  256 ++++++++++++++++++++++
 src/pk-network-stack-unix.h           |   56 ++++
 src/pk-network-stack.c                |  116 ++++++++++
 src/pk-network-stack.h                |   57 ++++
 src/pk-network-unix.c                 |  263 ----------------------
 src/pk-network-unix.h                 |   68 -----
 src/pk-network.c                      |  125 ++++------
 27 files changed, 1843 insertions(+), 1152 deletions(-)

New commits:
commit 677c70a2b6bfd3cb5b401cd35e700f0ba5ba0f48
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu Jun 4 10:08:06 2009 +0100

    Enable nice build output on automake1.11

diff --git a/configure.ac b/configure.ac
index 7353ba0..6e6c51d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -13,6 +13,9 @@ AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
 AM_CONFIG_HEADER(config.h)
 AC_CONFIG_MACRO_DIR([m4])
 
+# enable nice build output on automake1.11
+m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
+
 PK_MAJOR_VERSION=pk_major_version
 PK_MINOR_VERSION=pk_minor_version
 PK_MICRO_VERSION=pk_micro_version
commit d5e6fcf5983719bcb750c1337d73b9793262871c
Author: swkothar <swkothar at fedoraproject.org>
Date:   Thu Jun 4 05:54:41 2009 +0000

    Sending translation for Gujarati

diff --git a/po/gu.po b/po/gu.po
index e5389d2..4c74e98 100644
--- a/po/gu.po
+++ b/po/gu.po
@@ -1,4 +1,4 @@
-# translation of packagekit.master.gu.po to Gujarati
+# translation of gu.po to Gujarati
 # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
 # This file is distributed under the same license as the PACKAGE package.
 #
@@ -6,10 +6,10 @@
 # Sweta Kothari <swkothar at redhat.com>, 2009.
 msgid ""
 msgstr ""
-"Project-Id-Version: packagekit.master.gu\n"
+"Project-Id-Version: gu\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-04-14 02:09+0000\n"
-"PO-Revision-Date: 2009-04-14 11:20+0530\n"
+"POT-Creation-Date: 2009-06-04 02:24+0000\n"
+"PO-Revision-Date: 2009-06-04 11:24+0530\n"
 "Last-Translator: Sweta Kothari <swkothar at redhat.com>\n"
 "Language-Team: Gujarati\n"
 "MIME-Version: 1.0\n"
@@ -498,8 +498,8 @@ msgstr "ઉપઆદેશો:"
 #. TRANSLATORS: if we should show debugging data
 #: ../client/pk-console.c:1767 ../client/pk-generate-pack.c:185
 #: ../client/pk-monitor.c:125
-#: ../contrib/command-not-found/pk-command-not-found.c:518
-#: ../src/pk-main.c:199
+#: ../contrib/command-not-found/pk-command-not-found.c:520
+#: ../src/pk-main.c:211
 msgid "Show extra debugging information"
 msgstr "વધારાની ડિબગીંગ જાણકારી બતાવો"
 
@@ -704,55 +704,62 @@ msgstr "આઉટપુટ ડિરેક્ટરી અથવા ફાઇલ
 msgid "The package manager cannot perform this type of operation."
 msgstr "પેકેજ વ્યવસ્થાપક એ ક્રિયાનાં આ પ્રકારને ચલાવી શકતુ નથી."
 
+#. TRANSLATORS: This is when the distro didn't include libarchive support into PK
+#: ../client/pk-generate-pack.c:280
+msgid ""
+"Service packs cannot be created as PackageKit was not built with libarchive "
+"support."
+msgstr "PackageKit એ libarchive આધાર સાથે બિલ્ટ ન હતુ તે તરીકે સેવા પેકેજોને બનાવી શકાતા નથી."
+
 #. TRANSLATORS: the user specified an absolute path, but didn't get the extension correct
-#: ../client/pk-generate-pack.c:285
+#: ../client/pk-generate-pack.c:291
 msgid "If specifying a file, the service pack name must end with"
 msgstr "જો ફાઇલને સ્પષ્ટ કરી રહ્યા હોય ત્યારે, સેવા પેકેજ નામ એની સાથે છેલ્લે જ હોવુ જોઇએ"
 
 #. TRANSLATORS: This is when file already exists
-#: ../client/pk-generate-pack.c:301
+#: ../client/pk-generate-pack.c:307
 msgid "A pack with the same name already exists, do you want to overwrite it?"
 msgstr "એ જ નામ સાથેનું પેક પહેલાથી જ હાજર છે, શું તમે તેના પર ફરીથી લખવા માંગો છો?"
 
 #. TRANSLATORS: This is when the pack was not overwritten
-#: ../client/pk-generate-pack.c:304
+#: ../client/pk-generate-pack.c:310
 msgid "The pack was not overwritten."
 msgstr "પેક ઉપર ફરીથી લખાયેલ નથી."
 
 #. TRANSLATORS: This is when the temporary directory cannot be created, the directory name follows
-#: ../client/pk-generate-pack.c:317
+#: ../client/pk-generate-pack.c:323
 msgid "Failed to create directory:"
 msgstr "ડિરેક્ટરી બનાવવામાં નિષ્ફળ:"
 
 #. TRANSLATORS: This is when the list of packages from the remote computer cannot be opened
-#: ../client/pk-generate-pack.c:327
+#: ../client/pk-generate-pack.c:333
 msgid "Failed to open package list."
 msgstr "પેકેજ યાદી ખોલવામાં નિષ્ફળ."
 
 #. TRANSLATORS: The package name is being matched up to available packages
-#: ../client/pk-generate-pack.c:338
+#: ../client/pk-generate-pack.c:344
 msgid "Finding package name."
 msgstr "પેકેજ નામ શોધી રહ્યા છીએ."
 
 #. TRANSLATORS: This is when the package cannot be found in any software source. The detailed error follows
-#: ../client/pk-generate-pack.c:342
+#: ../client/pk-generate-pack.c:348
 #, c-format
 msgid "Failed to find package '%s': %s"
 msgstr "પેકેજ '%s' શોધવામાં નિષ્ફળ: %s"
 
 #. TRANSLATORS: This is telling the user we are in the process of making the pack
-#: ../client/pk-generate-pack.c:359
+#: ../client/pk-generate-pack.c:365
 msgid "Creating service pack..."
 msgstr "સેવા પેક બનાવી રહ્યા છીએ..."
 
 #. TRANSLATORS: we succeeded in making the file
-#: ../client/pk-generate-pack.c:366
+#: ../client/pk-generate-pack.c:372
 #, c-format
 msgid "Service pack created '%s'"
 msgstr "સેવા પેક બનાવાયું '%s'"
 
 #. TRANSLATORS: we failed to make te file
-#: ../client/pk-generate-pack.c:371
+#: ../client/pk-generate-pack.c:377
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "'%s' બનાવવામાં નિષ્ફળ: %s"
@@ -784,71 +791,71 @@ msgid "Please enter a number from 1 to %i: "
 msgstr "મહેરબાની કરીને ૧ થી %i સુધીનો નંબર દાખલ કરો: "
 
 #. TRANSLATORS: we failed to find the package, this shouldn't happen
-#: ../contrib/command-not-found/pk-command-not-found.c:369
+#: ../contrib/command-not-found/pk-command-not-found.c:371
 msgid "Failed to search for file"
 msgstr "ફાઇલ માટે શોધવાનું નિષ્ફળ"
 
 #. TRANSLATORS: we failed to launch the executable, the error follows
-#: ../contrib/command-not-found/pk-command-not-found.c:493
+#: ../contrib/command-not-found/pk-command-not-found.c:495
 msgid "Failed to launch:"
 msgstr "શરૂ કરવામાં નિષ્ફળ:"
 
 #. TRANSLATORS: tool that gets called when the command is not found
-#: ../contrib/command-not-found/pk-command-not-found.c:534
+#: ../contrib/command-not-found/pk-command-not-found.c:536
 msgid "PackageKit Command Not Found"
 msgstr "PackageKit આદેશ શોધાયો નહિં"
 
 #. TRANSLATORS: the prefix of all the output telling the user why it's not executing
-#: ../contrib/command-not-found/pk-command-not-found.c:556
+#: ../contrib/command-not-found/pk-command-not-found.c:559
 msgid "Command not found."
 msgstr "આદેશ શોધાયો નહિં."
 
 #. TRANSLATORS: tell the user what we think the command is
-#: ../contrib/command-not-found/pk-command-not-found.c:563
+#: ../contrib/command-not-found/pk-command-not-found.c:566
 msgid "Similar command is:"
 msgstr "સરખા આદેશો છે:"
 
 #. TRANSLATORS: Ask the user if we should run the similar command
-#: ../contrib/command-not-found/pk-command-not-found.c:572
+#: ../contrib/command-not-found/pk-command-not-found.c:575
 msgid "Run similar command:"
 msgstr "એજ આદેશને ચલાવો:"
 
 #. TRANSLATORS: show the user a list of commands that they could have meant
 #. TRANSLATORS: show the user a list of commands we could run
-#: ../contrib/command-not-found/pk-command-not-found.c:584
-#: ../contrib/command-not-found/pk-command-not-found.c:593
+#: ../contrib/command-not-found/pk-command-not-found.c:587
+#: ../contrib/command-not-found/pk-command-not-found.c:596
 msgid "Similar commands are:"
 msgstr "સરખા આદેશો છે:"
 
 #. TRANSLATORS: ask the user to choose a file to run
-#: ../contrib/command-not-found/pk-command-not-found.c:600
+#: ../contrib/command-not-found/pk-command-not-found.c:603
 msgid "Please choose a command to run"
 msgstr "મહેરબાની કરીને ચલાવવા માટે આદેશને પસંદ કરો"
 
 #. TRANSLATORS: tell the user what package provides the command
-#: ../contrib/command-not-found/pk-command-not-found.c:615
+#: ../contrib/command-not-found/pk-command-not-found.c:618
 msgid "The package providing this file is:"
 msgstr "પેકેજ આ ફાઇલને પૂરી પાડી રહ્યા છે:"
 
 #. TRANSLATORS: as the user if we want to install a package to provide the command
-#: ../contrib/command-not-found/pk-command-not-found.c:620
+#: ../contrib/command-not-found/pk-command-not-found.c:623
 #, c-format
 msgid "Install package '%s' to provide command '%s'?"
 msgstr "શું આદેશ '%s' પૂરા પાડવા માટે પેકેજ '%s' ને સ્થાપિત કરો?"
 
 #. TRANSLATORS: Show the user a list of packages that provide this command
-#: ../contrib/command-not-found/pk-command-not-found.c:641
+#: ../contrib/command-not-found/pk-command-not-found.c:644
 msgid "Packages providing this file are:"
 msgstr "પેકેજો એ આ ફાઇલને પૂરી પાડી રહી છે:"
 
 #. TRANSLATORS: Show the user a list of packages that they can install to provide this command
-#: ../contrib/command-not-found/pk-command-not-found.c:650
+#: ../contrib/command-not-found/pk-command-not-found.c:653
 msgid "Suitable packages are:"
 msgstr "સુસંગત પેકેજો છે:"
 
 #. get selection
 #. TRANSLATORS: ask the user to choose a file to install
-#: ../contrib/command-not-found/pk-command-not-found.c:658
+#: ../contrib/command-not-found/pk-command-not-found.c:661
 msgid "Please choose a package to install"
 msgstr "મહેરબાની કરીને સ્થાપિત કરવા માટે પેકેજને પસંદ કરો"
 
@@ -1035,48 +1042,47 @@ msgid ""
 msgstr "org.freedesktop.PackageKit.conf ફાઈલ સિસ્ટમ ડિરેક્ટરીમાં સ્થાપિત થયેલ નથી:"
 
 #. TRANSLATORS: a backend is the system package tool, e.g. yum, apt
-#: ../src/pk-main.c:193
+#: ../src/pk-main.c:205
 msgid "Packaging backend to use, e.g. dummy"
 msgstr "વાપરવા માટે બેકેન્ડ પેકેજ કરી રહ્યા છીએ, દા.ત. dummy"
 
 #. TRANSLATORS: if we should run in the background
-#: ../src/pk-main.c:196
+#: ../src/pk-main.c:208
 msgid "Daemonize and detach from the terminal"
 msgstr "ડિમનવાળું કરો અને ટર્મિનલમાંથી છોડો"
 
 #. TRANSLATORS: if we should not monitor how long we are inactive for
-#: ../src/pk-main.c:202
+#: ../src/pk-main.c:214
 msgid "Disable the idle timer"
 msgstr "ફાજલ સમય નિષ્ક્રિય કરો"
 
 #. TRANSLATORS: show version
-#: ../src/pk-main.c:205
+#: ../src/pk-main.c:217
 msgid "Show version and exit"
 msgstr "આવૃત્તિ બતાવો અને બહાર નીકળો"
 
 #. TRANSLATORS: exit after we've started up, used for user profiling
-#: ../src/pk-main.c:208
+#: ../src/pk-main.c:220
 msgid "Exit after a small delay"
 msgstr "નાના વિલંબ પછી બહાર નીકળો"
 
 #. TRANSLATORS: exit straight away, used for automatic profiling
-#: ../src/pk-main.c:211
+#: ../src/pk-main.c:223
 msgid "Exit after the engine has loaded"
 msgstr "એંજીન લવાઈ જાય પછી બહાર નીકળો"
 
 #. TRANSLATORS: describing the service that is running
-#: ../src/pk-main.c:226
+#: ../src/pk-main.c:238
 msgid "PackageKit service"
 msgstr "PackageKit સેવા"
 
 #. TRANSLATORS: fatal error, dbus is not running
-#: ../src/pk-main.c:263
+#: ../src/pk-main.c:275
 msgid "Cannot connect to the system bus"
 msgstr "સિસ્ટમ બસ સાથે જોડાઈ શકતા નથી"
 
-#. TRANSLATORS: cannot register on system bus, unknown reason
-#: ../src/pk-main.c:313
-#, c-format
+#. TRANSLATORS: cannot register on system bus, unknown reason -- geeky error follows
+#: ../src/pk-main.c:331
 msgid "Error trying to start:"
 msgstr "શરૂ કરવાનો પ્રયાસ કરવામાં ભૂલ:"
 
commit 48960dfb740b72779ef2fafcde7398902c7fdbe8
Author: Mounir Lamouri (volkmar) <mounir.lamouri at gmail.com>
Date:   Wed Jun 3 22:16:33 2009 +0200

    portage: add search-group function with a beginning table conversion from gentoo's category to packagekit's groups

diff --git a/backends/portage/pk-backend-portage.c b/backends/portage/pk-backend-portage.c
index 3126781..0f5ce03 100644
--- a/backends/portage/pk-backend-portage.c
+++ b/backends/portage/pk-backend-portage.c
@@ -278,6 +278,19 @@ backend_search_file (PkBackend *backend, PkBitfield filters, const gchar *search
 }
 
 /**
+ * pk_backend_search_group:
+ */
+static void
+backend_search_group (PkBackend *backend, PkBitfield filters, const gchar *search)
+{ 
+  gchar *filters_text;
+
+  filters_text = pk_filter_bitfield_to_text (filters);
+  pk_backend_spawn_helper (spawn, BACKEND_FILE, "search-group", filters_text, search, NULL);
+  g_free (filters_text);
+}
+
+/**
  * backend_search_name:
  */
 static void
@@ -354,7 +367,7 @@ PK_BACKEND_OPTIONS (
 	NULL,			/* rollback */
 	NULL, //TODO			/* search_details */
 	backend_search_file,			/* search_file */
-	NULL, //TODO			/* search_group */
+	backend_search_group,			/* search_group */
 	backend_search_name,			/* search_name */
 	backend_update_packages,		/* update_packages */
 	backend_update_system,			/* update_system */
diff --git a/backends/portage/portageBackend.py b/backends/portage/portageBackend.py
index 7827450..b39ac24 100755
--- a/backends/portage/portageBackend.py
+++ b/backends/portage/portageBackend.py
@@ -48,6 +48,166 @@ from itertools import izip
 # TODO:
 # print only found package or every ebuilds ?
 
+# Map Gentoo categories to the PackageKit group name space
+SECTION_GROUP_MAP = {
+		"app-accessibility" : GROUP_ACCESSIBILITY,
+		"app-admin" : GROUP_ADMIN_TOOLS,
+		"app-antivirus" : GROUP_OTHER,	#TODO
+		"app-arch" : GROUP_OTHER,
+		"app-backup" : GROUP_OTHER,
+		"app-benchmarks" : GROUP_OTHER,
+		"app-cdr" : GROUP_OTHER,
+		"app-crypt" : GROUP_OTHER,
+		"app-dicts" : GROUP_OTHER,
+		"app-doc" : GROUP_OTHER,
+		"app-editors" : GROUP_OTHER,
+		"app-emacs" : GROUP_OTHER,
+		"app-emulation" : GROUP_OTHER,
+		"app-forensics" : GROUP_OTHER,
+		"app-i18n" : GROUP_OTHER,
+		"app-laptop" : GROUP_OTHER,
+		"app-misc" : GROUP_OTHER,
+		"app-mobilephone" : GROUP_OTHER,
+		"app-office" : GROUP_OFFICE,
+		"app-pda" : GROUP_OTHER,
+		"app-portage" : GROUP_OTHER,
+		"app-shells" : GROUP_OTHER,
+		"app-text" : GROUP_OTHER,
+		"app-vim" : GROUP_OTHER,
+		"app-xemacs" : GROUP_OTHER,
+		"dev-ada" : GROUP_OTHER,
+		"dev-cpp" : GROUP_OTHER,
+		"dev-db" : GROUP_OTHER,
+		"dev-dotnet" : GROUP_OTHER,
+		"dev-embedded" : GROUP_OTHER,
+		"dev-games" : GROUP_OTHER,
+		"dev-haskell" : GROUP_OTHER,
+		"dev-java" : GROUP_OTHER,
+		"dev-lang" : GROUP_OTHER,
+		"dev-libs" : GROUP_OTHER,
+		"dev-lisp" : GROUP_OTHER,
+		"dev-ml" : GROUP_OTHER,
+		"dev-perl" : GROUP_OTHER,
+		"dev-php" : GROUP_OTHER,
+		"dev-php5" : GROUP_OTHER,
+		"dev-python" : GROUP_OTHER,
+		"dev-ruby" : GROUP_OTHER,
+		"dev-scheme" : GROUP_OTHER,
+		"dev-tcltk" : GROUP_OTHER,
+		"dev-tex" : GROUP_OTHER,
+		"dev-texlive" : GROUP_OTHER,
+		"dev-tinyos" : GROUP_OTHER,
+		"dev-util" : GROUP_OTHER,
+		"games-action" : GROUP_GAMES, # DONE from there
+		"games-arcade" : GROUP_GAMES,
+		"games-board" : GROUP_GAMES,
+		"games-emulation" : GROUP_GAMES,
+		"games-engines" : GROUP_GAMES,
+		"games-fps" : GROUP_GAMES,
+		"games-kids" : GROUP_GAMES,
+		"games-misc" : GROUP_GAMES,
+		"games-mud" : GROUP_GAMES,
+		"games-puzzle" : GROUP_GAMES,
+		"games-roguelike" : GROUP_GAMES,
+		"games-rpg" : GROUP_GAMES,
+		"games-server" : GROUP_GAMES,
+		"games-simulation" : GROUP_GAMES,
+		"games-sports" : GROUP_GAMES,
+		"games-strategy" : GROUP_GAMES,
+		"games-util" : GROUP_GAMES,
+		"gnome-base" : GROUP_DESKTOP_GNOME,
+		"gnome-extra" : GROUP_DESKTOP_GNOME,
+		"gnustep-apps" : GROUP_OTHER,	# TODO: from there
+		"gnustep-base" : GROUP_OTHER,
+		"gnustep-libs" : GROUP_OTHER,
+		"gpe-base" : GROUP_OTHER,
+		"gpe-utils" : GROUP_OTHER,
+		"java-virtuals" : GROUP_OTHER,
+		"kde-base" : GROUP_DESKTOP_KDE, # DONE from there
+		"kde-misc" : GROUP_DESKTOP_KDE,
+		"lxde-base" : GROUP_DESKTOP_OTHER,
+		"mail-client" : GROUP_COMMUNICATION, # TODO: or GROUP_INTERNET ?
+		"mail-filter" : GROUP_OTHER, # TODO: from there
+		"mail-mta" : GROUP_OTHER,
+		"media-fonts" : GROUP_FONTS, # DONE (only this one)
+		"media-gfx" : GROUP_OTHER,
+		"media-libs" : GROUP_OTHER,
+		"media-plugins" : GROUP_OTHER,
+		"media-radio" : GROUP_OTHER,
+		"media-sound" : GROUP_OTHER,
+		"media-tv" : GROUP_OTHER,
+		"media-video" : GROUP_OTHER,
+		"metadata" : GROUP_OTHER,
+		"net-analyzer" : GROUP_OTHER,
+		"net-dialup" : GROUP_OTHER,
+		"net-dns" : GROUP_OTHER,
+		"net-firewall" : GROUP_OTHER,
+		"net-fs" : GROUP_OTHER,
+		"net-ftp" : GROUP_OTHER,
+		"net-im" : GROUP_OTHER,
+		"net-irc" : GROUP_OTHER,
+		"net-libs" : GROUP_OTHER,
+		"net-mail" : GROUP_OTHER,
+		"net-misc" : GROUP_OTHER,
+		"net-nds" : GROUP_OTHER,
+		"net-news" : GROUP_OTHER,
+		"net-nntp" : GROUP_OTHER,
+		"net-p2p" : GROUP_OTHER,
+		"net-print" : GROUP_OTHER,
+		"net-proxy" : GROUP_OTHER,
+		"net-voip" : GROUP_OTHER,
+		"net-wireless" : GROUP_OTHER,
+		"net-zope" : GROUP_OTHER,
+		"perl-core" : GROUP_OTHER,
+		"profiles" : GROUP_OTHER,
+		"rox-base" : GROUP_OTHER,
+		"rox-extra" : GROUP_OTHER,
+		"sci-astronomy" : GROUP_SCIENCE, # DONE from there
+		"sci-biology" : GROUP_SCIENCE,
+		"sci-calculators" : GROUP_SCIENCE,
+		"sci-chemistry" : GROUP_SCIENCE,
+		"sci-electronics" : GROUP_SCIENCE,
+		"sci-geosciences" : GROUP_SCIENCE,
+		"sci-libs" : GROUP_SCIENCE,
+		"sci-mathematics" : GROUP_SCIENCE,
+		"sci-misc" : GROUP_SCIENCE,
+		"sci-physics" : GROUP_SCIENCE,
+		"sci-visualization" : GROUP_SCIENCE,
+		"sec-policy" : GROUP_OTHER, # TODO: from there
+		"sys-apps" : GROUP_OTHER,
+		"sys-auth" : GROUP_OTHER,
+		"sys-block" : GROUP_OTHER,
+		"sys-boot" : GROUP_OTHER,
+		"sys-cluster" : GROUP_OTHER,
+		"sys-devel" : GROUP_OTHER,
+		"sys-freebsd" : GROUP_OTHER,
+		"sys-fs" : GROUP_OTHER,
+		"sys-kernel" : GROUP_OTHER,
+		"sys-libs" : GROUP_OTHER,
+		"sys-power" : GROUP_OTHER,
+		"sys-process" : GROUP_OTHER,
+		"virtual" : GROUP_OTHER,
+		"www-apache" : GROUP_OTHER,
+		"www-apps" : GROUP_OTHER,
+		"www-client" : GROUP_OTHER,
+		"www-misc" : GROUP_OTHER,
+		"www-plugins" : GROUP_OTHER,
+		"www-servers" : GROUP_OTHER,
+		"x11-apps" : GROUP_OTHER,
+		"x11-base" : GROUP_OTHER,
+		"x11-drivers" : GROUP_OTHER,
+		"x11-libs" : GROUP_OTHER,
+		"x11-misc" : GROUP_OTHER,
+		"x11-plugins" : GROUP_OTHER,
+		"x11-proto" : GROUP_OTHER,
+		"x11-terms" : GROUP_OTHER,
+		"x11-themes" : GROUP_OTHER,
+		"x11-wm" : GROUP_OTHER,
+		"xfce-base" : GROUP_DESKTOP_XFCE, # DONE from there
+		"xfce-extra" : GROUP_DESKTOP_XFCE
+}
+
+
 def sigquit(signum, frame):
 	sys.exit(1)
 
@@ -311,6 +471,23 @@ class PackageKitPortageBackend(PackageKitBaseBackend, PackagekitPackage):
 		for cpv in cpvlist:
 			self.package(cpv)
 
+	def search_group(self, filters, group):
+		# TODO: filters
+		self.status(STATUS_QUERY)
+		self.allow_cancel(True)
+		self.percentage(None)
+
+		for cp in portage.portdb.cp_all():
+			category = portage.catsplit(cp)[0]
+			if SECTION_GROUP_MAP.has_key(category):
+				group_found = SECTION_GROUP_MAP[category]
+			else:
+				group_found = GROUP_UNKNOWN
+
+			if group_found == group:
+				for cpv in portage.portdb.match(cp):
+					self.package(cpv)
+
 	def search_name(self, filters, key):
 		# TODO: manage filters
 		# TODO: collections ?
commit 03d3dba2d0a8f2be864cc076cb1e8f6a6f9fe328
Author: Mounir Lamouri (volkmar) <mounir.lamouri at gmail.com>
Date:   Wed Jun 3 20:25:36 2009 +0200

    portage: working install-packages function

diff --git a/backends/portage/portageBackend.py b/backends/portage/portageBackend.py
index b773787..7827450 100755
--- a/backends/portage/portageBackend.py
+++ b/backends/portage/portageBackend.py
@@ -241,24 +241,35 @@ class PackageKitPortageBackend(PackageKitBaseBackend, PackagekitPackage):
 		settings, trees, mtimedb = _emerge.load_emerge_config()
 		spinner = _emerge.stdout_spinner()
 		rootconfig = _emerge.RootConfig(self.portage_settings, trees["/"], portage._sets.load_default_config(self.portage_settings, trees["/"]))
-		# setconfig ?
-		if "resume" not in mtimedb:
-			mtimedb["resume"] = mtimedb["resume_backup"]
-			del mtimedb["resume_backup"]
+
+		if "resume" in mtimedb and \
+		"mergelist" in mtimedb["resume"] and \
+		len(mtimedb["resume"]["mergelist"]) > 1:
+			mtimedb["resume_backup"] = mtimedb["resume"]
+			del mtimedb["resume"]
+			mtimedb.commit()
+
+		mtimedb["resume"]={}
+		mtimedb["resume"]["myopts"] = myopts.copy()
+		mtimedb["resume"]["favorites"] = [str(x) for x in favorites]
 
 		for pkg in pkgs:
 			# check for installed is not mandatory as there are a lot of reason
-			# to re-install a package (USE/LDFLAGS/CFLAGS change for example) (or live)
+			# to re-install a package (USE/{LD,C}FLAGS change for example) (or live)
 			# TODO: keep a final position
 			cpv = id_to_cpv(pkg)
 			db_keys = list(portage.portdb._aux_cache_keys)
 			metadata = izip(db_keys, portage.portdb.aux_get(cpv, db_keys))
-			package = _emerge.Package(type_name="ebuild", root_config=rootconfig, cpv=cpv, metadata=metadata)
+			package = _emerge.Package(type_name="ebuild", root_config=rootconfig, cpv=cpv, metadata=metadata, operation="merge")
+
+			# TODO: needed ?
+			pkgsettings = portage.config(clone=settings)
+			pkgsettings.setcpv(package)
+			package.metadata['USE'] = pkgsettings['PORTAGE_USE']
 
 			mergetask = _emerge.Scheduler(settings, trees, mtimedb, myopts, spinner, [package], favorites, package)
 			mergetask.merge()
 
-
 	def resolve(self, filters, pkgs):
 		# TODO: filters
 		self.status(STATUS_QUERY)
commit 893dd789e8dad584116e7e70f63491c15c873f9f
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Jun 3 09:56:31 2009 +0100

    Never return FALSE from StateHasChanged(). Fixes rh#483164

diff --git a/src/pk-engine.c b/src/pk-engine.c
index 164a84d..88c3e4b 100644
--- a/src/pk-engine.c
+++ b/src/pk-engine.c
@@ -374,10 +374,9 @@ pk_engine_state_has_changed (PkEngine *engine, const gchar *reason, GError **err
 
 	/* have we already scheduled priority? */
 	if (engine->priv->signal_state_priority_timeout != 0) {
-		g_set_error (error, PK_ENGINE_ERROR, PK_ENGINE_ERROR_INVALID_STATE,
-			     "Already asked to refresh priority state less than %i seconds ago",
+		egg_warning ("Already asked to refresh priority state less than %i seconds ago",
 			     PK_ENGINE_STATE_CHANGED_PRIORITY_TIMEOUT);
-		return FALSE;
+		goto out;
 	}
 
 	/* don't bombard the user 10 seconds after resuming */
@@ -386,10 +385,9 @@ pk_engine_state_has_changed (PkEngine *engine, const gchar *reason, GError **err
 
 	/* are we normal, and already scheduled normal? */
 	if (!is_priority && engine->priv->signal_state_normal_timeout != 0) {
-		g_set_error (error, PK_ENGINE_ERROR, PK_ENGINE_ERROR_INVALID_STATE,
-			     "Already asked to refresh normal state less than %i seconds ago",
+		egg_warning ("Already asked to refresh normal state less than %i seconds ago",
 			     PK_ENGINE_STATE_CHANGED_NORMAL_TIMEOUT);
-		return FALSE;
+		goto out;
 	}
 
 	/* are we priority, and already scheduled normal? */
@@ -408,7 +406,7 @@ pk_engine_state_has_changed (PkEngine *engine, const gchar *reason, GError **err
 
 	/* reset the timer */
 	pk_engine_reset_timer (engine);
-
+out:
 	return TRUE;
 }
 
commit 5057e64ebedf57f9cbf33d039fe664b62cba7e1f
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Jun 3 09:37:31 2009 +0100

    yum: Download the ChangeLog data when we get the update list. Fixes rh#499590

diff --git a/backends/yum/yumBackend.py b/backends/yum/yumBackend.py
index 76b567e..e735ce8 100755
--- a/backends/yum/yumBackend.py
+++ b/backends/yum/yumBackend.py
@@ -2201,6 +2201,10 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
         md = self.updateMetadata
         for pkg in unique(pkgs):
             if pkgfilter.pre_process(pkg):
+                # we pre-get the ChangeLog data so that the changes file is
+                # downloaded at GetUpdates time, not when we open the GUI
+                changelog = pkg.returnChangelog()
+
                 # Get info about package in updates info
                 notice = md.get_notice((pkg.name, pkg.version, pkg.release))
                 if notice:
commit 19d72c90750187f7ba035fac3e03e52f533679b5
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Jun 2 08:40:19 2009 +0100

    yum: We support application/x-servicepack, so advertise it

diff --git a/backends/yum/pk-backend-yum.c b/backends/yum/pk-backend-yum.c
index 436aaf9..3e27710 100644
--- a/backends/yum/pk-backend-yum.c
+++ b/backends/yum/pk-backend-yum.c
@@ -131,7 +131,7 @@ backend_get_filters (PkBackend *backend)
 static gchar *
 backend_get_mime_types (PkBackend *backend)
 {
-	return g_strdup ("application/x-rpm");
+	return g_strdup ("application/x-rpm;application/x-servicepack");
 }
 
 /**
commit 42fae258b9c4641fbddaac0a69625b5f558af230
Author: Mounir Lamouri (volkmar) <mounir.lamouri at gmail.com>
Date:   Wed Jun 3 00:23:17 2009 +0200

    portage: not yet working install-packages function

diff --git a/backends/portage/pk-backend-portage.c b/backends/portage/pk-backend-portage.c
index 4c42412..3126781 100644
--- a/backends/portage/pk-backend-portage.c
+++ b/backends/portage/pk-backend-portage.c
@@ -198,22 +198,22 @@ backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_id
 }
 
 /**
- * backend_get_updates:
+ * backend_get_update_detail:
  */
 static void
-backend_get_updates (PkBackend *backend, PkBitfield filters)
+backend_get_update_detail (PkBackend *backend, gchar **package_ids)
 {
-	egg_debug ("backend: updates");
+	egg_debug ("backend: update_detail");
 	pk_backend_finished (backend);
 }
 
 /**
- * backend_get_update_detail:
+ * backend_get_updates:
  */
 static void
-backend_get_update_detail (PkBackend *backend, gchar **package_ids)
+backend_get_updates (PkBackend *backend, PkBitfield filters)
 {
-	egg_debug ("backend: update_detail");
+	egg_debug ("backend: updates");
 	pk_backend_finished (backend);
 }
 
@@ -223,8 +223,19 @@ backend_get_update_detail (PkBackend *backend, gchar **package_ids)
 static void
 backend_install_packages (PkBackend *backend, gchar **package_ids)
 {
-	egg_debug ("backend: install");
-	pk_backend_finished (backend);
+	gchar *package_ids_temp;
+
+	/*
+	 * TODO: portage manage to install when offline
+	 * but maybe packagekit implementation will make this forbidden
+	 * (because of download funcion dir)
+	 * If needed, add something that will check for network _NOW_ (see yum)
+	 */
+
+	/* send the complete list as stdin */
+	package_ids_temp = pk_package_ids_to_text (package_ids);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "install-packages", package_ids_temp, NULL);
+	g_free (package_ids_temp);
 }
 
 /**
diff --git a/backends/portage/portageBackend.py b/backends/portage/portageBackend.py
index 0000a7c..b773787 100755
--- a/backends/portage/portageBackend.py
+++ b/backends/portage/portageBackend.py
@@ -32,7 +32,7 @@ import _emerge
 import sys
 import signal
 import re
-#from urlgrabber.progress import BaseMeter, format_number
+from itertools import izip
 
 # NOTES:
 #
@@ -230,6 +230,35 @@ class PackageKitPortageBackend(PackageKitBaseBackend, PackagekitPackage):
 			for cpv in portage.portdb.match(cp):
 				self.package(cpv)
 
+	def install_packages(self, pkgs):
+		self.status(STATUS_RUNNING)
+		self.allow_cancel(True) # TODO: sure ?
+		self.percentage(None)
+
+		myopts = {} # TODO: --nodepends ?
+		spinner = ""
+		favorites = []
+		settings, trees, mtimedb = _emerge.load_emerge_config()
+		spinner = _emerge.stdout_spinner()
+		rootconfig = _emerge.RootConfig(self.portage_settings, trees["/"], portage._sets.load_default_config(self.portage_settings, trees["/"]))
+		# setconfig ?
+		if "resume" not in mtimedb:
+			mtimedb["resume"] = mtimedb["resume_backup"]
+			del mtimedb["resume_backup"]
+
+		for pkg in pkgs:
+			# check for installed is not mandatory as there are a lot of reason
+			# to re-install a package (USE/LDFLAGS/CFLAGS change for example) (or live)
+			# TODO: keep a final position
+			cpv = id_to_cpv(pkg)
+			db_keys = list(portage.portdb._aux_cache_keys)
+			metadata = izip(db_keys, portage.portdb.aux_get(cpv, db_keys))
+			package = _emerge.Package(type_name="ebuild", root_config=rootconfig, cpv=cpv, metadata=metadata)
+
+			mergetask = _emerge.Scheduler(settings, trees, mtimedb, myopts, spinner, [package], favorites, package)
+			mergetask.merge()
+
+
 	def resolve(self, filters, pkgs):
 		# TODO: filters
 		self.status(STATUS_QUERY)
commit 0fcd7529e8e1d60f050e7840ed08c7013c7720db
Merge: 2a0ac60... b7e69bf...
Author: Mounir Lamouri (volkmar) <mounir.lamouri at gmail.com>
Date:   Wed Jun 3 00:21:07 2009 +0200

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

commit b7e69bf510c1874b069bd1faa37ac603bb3eddd5
Author: kkrothap <kkrothap at fedoraproject.org>
Date:   Tue Jun 2 11:51:39 2009 +0000

    Sending translation for Telugu

diff --git a/po/te.po b/po/te.po
index c06c97a..226d8d0 100644
--- a/po/te.po
+++ b/po/te.po
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: packagekit.master.te\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-04-14 02:09+0000\n"
-"PO-Revision-Date: 2009-04-14 15:06+0530\n"
+"POT-Creation-Date: 2009-06-02 08:19+0000\n"
+"PO-Revision-Date: 2009-06-02 17:20+0530\n"
 "Last-Translator: Krishna Babu K <kkrothap at redhat.com>\n"
 "Language-Team: Telugu <en at li.org>\n"
 "MIME-Version: 1.0\n"
@@ -17,6 +17,7 @@ msgstr ""
 "X-Generator: KBabel 1.11.4\n"
 "Plural-Forms: nplurals=2; plural=(n!=1);\n\n"
 "\n"
+"\n"
 
 #. TRANSLATORS: this is an atomic transaction
 #: ../client/pk-console.c:234
@@ -496,8 +497,8 @@ msgstr "ఉపఆదేశములు:"
 #. TRANSLATORS: if we should show debugging data
 #: ../client/pk-console.c:1767 ../client/pk-generate-pack.c:185
 #: ../client/pk-monitor.c:125
-#: ../contrib/command-not-found/pk-command-not-found.c:518
-#: ../src/pk-main.c:199
+#: ../contrib/command-not-found/pk-command-not-found.c:520
+#: ../src/pk-main.c:211
 msgid "Show extra debugging information"
 msgstr "అదనపు డీబగ్గింగ్ సమాచారమును చూపుము"
 
@@ -702,55 +703,62 @@ msgstr "ఒక అవుట్పుట్ డైరెక్టరీ లేద
 msgid "The package manager cannot perform this type of operation."
 msgstr "సంకలనము నిర్వాహిక ఈ రకమైన కార్యక్రమమును నిర్వహించలేదు."
 
+#. TRANSLATORS: This is when the distro didn't include libarchive support into PK
+#: ../client/pk-generate-pack.c:280
+msgid ""
+"Service packs cannot be created as PackageKit was not built with libarchive "
+"support."
+msgstr "ప్యాకేజ్‌కిట్ అనునది లిబ్ఆర్చివ్ మద్దతుతో నిర్మితం కాలేదు కనుక సర్వీస్ ప్యాక్‌లు సృష్టించబడలేవు."
+
 #. TRANSLATORS: the user specified an absolute path, but didn't get the extension correct
-#: ../client/pk-generate-pack.c:285
+#: ../client/pk-generate-pack.c:291
 msgid "If specifying a file, the service pack name must end with"
 msgstr "దస్త్రమును తెలుపుతుంటే, సేవా ప్యాక్ నామము దీనితో ముగియాలి"
 
 #. TRANSLATORS: This is when file already exists
-#: ../client/pk-generate-pack.c:301
+#: ../client/pk-generate-pack.c:307
 msgid "A pack with the same name already exists, do you want to overwrite it?"
 msgstr "ఒక పాక్ అదేనామముతో యిప్పటికే వుంది, మీరు దానిని తిరిగివ్రాద్దామని(వోవర్‌రైట్) అనుకొనుచున్నారా?"
 
 #. TRANSLATORS: This is when the pack was not overwritten
-#: ../client/pk-generate-pack.c:304
+#: ../client/pk-generate-pack.c:310
 msgid "The pack was not overwritten."
 msgstr "పాక్ తిరిగివ్రాయబడలేదు."
 
 #. TRANSLATORS: This is when the temporary directory cannot be created, the directory name follows
-#: ../client/pk-generate-pack.c:317
+#: ../client/pk-generate-pack.c:323
 msgid "Failed to create directory:"
 msgstr "డైరెక్టరీ సృష్టించుటకు విఫలమైంది:"
 
 #. TRANSLATORS: This is when the list of packages from the remote computer cannot be opened
-#: ../client/pk-generate-pack.c:327
+#: ../client/pk-generate-pack.c:333
 msgid "Failed to open package list."
 msgstr "సంకలన జాబితాను తెరువుటకు విఫలమైంది."
 
 #. TRANSLATORS: The package name is being matched up to available packages
-#: ../client/pk-generate-pack.c:338
+#: ../client/pk-generate-pack.c:344
 msgid "Finding package name."
 msgstr "సంకలనము నామము కనుగొనుచున్నది."
 
 #. TRANSLATORS: This is when the package cannot be found in any software source. The detailed error follows
-#: ../client/pk-generate-pack.c:342
+#: ../client/pk-generate-pack.c:348
 #, c-format
 msgid "Failed to find package '%s': %s"
 msgstr "సంకలనము '%s' కనుగొనుటలో విఫలమైంది: %s"
 
 #. TRANSLATORS: This is telling the user we are in the process of making the pack
-#: ../client/pk-generate-pack.c:359
+#: ../client/pk-generate-pack.c:365
 msgid "Creating service pack..."
 msgstr "సేవా పాక్‌ను సృష్టించుచున్నది..."
 
 #. TRANSLATORS: we succeeded in making the file
-#: ../client/pk-generate-pack.c:366
+#: ../client/pk-generate-pack.c:372
 #, c-format
 msgid "Service pack created '%s'"
 msgstr "సేవా పాక్ సృష్టించబడింది '%s'"
 
 #. TRANSLATORS: we failed to make te file
-#: ../client/pk-generate-pack.c:371
+#: ../client/pk-generate-pack.c:377
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "'%s' సృష్టించుటకు విఫలమైంది: %s"
@@ -782,71 +790,71 @@ msgid "Please enter a number from 1 to %i: "
 msgstr "దయచేసి సంఖ్యను 1 నుండి %iకు ప్రవేశపెట్టుము: "
 
 #. TRANSLATORS: we failed to find the package, this shouldn't happen
-#: ../contrib/command-not-found/pk-command-not-found.c:369
+#: ../contrib/command-not-found/pk-command-not-found.c:371
 msgid "Failed to search for file"
 msgstr "దస్త్రమును శోధించుటలో విఫలమైంది"
 
 #. TRANSLATORS: we failed to launch the executable, the error follows
-#: ../contrib/command-not-found/pk-command-not-found.c:493
+#: ../contrib/command-not-found/pk-command-not-found.c:495
 msgid "Failed to launch:"
 msgstr "ఆరంభించుటకు విఫలమైంది:"
 
 #. TRANSLATORS: tool that gets called when the command is not found
-#: ../contrib/command-not-found/pk-command-not-found.c:534
+#: ../contrib/command-not-found/pk-command-not-found.c:536
 msgid "PackageKit Command Not Found"
 msgstr "PackageKit ఆదేశము కనబడలేదు"
 
 #. TRANSLATORS: the prefix of all the output telling the user why it's not executing
-#: ../contrib/command-not-found/pk-command-not-found.c:556
+#: ../contrib/command-not-found/pk-command-not-found.c:559
 msgid "Command not found."
 msgstr "ఆదేశము కనబడలేదు"
 
 #. TRANSLATORS: tell the user what we think the command is
-#: ../contrib/command-not-found/pk-command-not-found.c:563
+#: ../contrib/command-not-found/pk-command-not-found.c:566
 msgid "Similar command is:"
 msgstr "అటువంటి ఆదేశము:"
 
 #. TRANSLATORS: Ask the user if we should run the similar command
-#: ../contrib/command-not-found/pk-command-not-found.c:572
+#: ../contrib/command-not-found/pk-command-not-found.c:575
 msgid "Run similar command:"
 msgstr "అటువంటి ఆదేశమును నడుపుము:"
 
 #. TRANSLATORS: show the user a list of commands that they could have meant
 #. TRANSLATORS: show the user a list of commands we could run
-#: ../contrib/command-not-found/pk-command-not-found.c:584
-#: ../contrib/command-not-found/pk-command-not-found.c:593
+#: ../contrib/command-not-found/pk-command-not-found.c:587
+#: ../contrib/command-not-found/pk-command-not-found.c:596
 msgid "Similar commands are:"
 msgstr "ఓకేతీరు ఆదేశములు:"
 
 #. TRANSLATORS: ask the user to choose a file to run
-#: ../contrib/command-not-found/pk-command-not-found.c:600
+#: ../contrib/command-not-found/pk-command-not-found.c:603
 msgid "Please choose a command to run"
 msgstr "నడుపుటకు దయచేసి ఆదేశమును యెంచుకొనుము"
 
 #. TRANSLATORS: tell the user what package provides the command
-#: ../contrib/command-not-found/pk-command-not-found.c:615
+#: ../contrib/command-not-found/pk-command-not-found.c:618
 msgid "The package providing this file is:"
 msgstr "సంకలనము అందించుచున్న ఈ దస్త్రము:"
 
 #. TRANSLATORS: as the user if we want to install a package to provide the command
-#: ../contrib/command-not-found/pk-command-not-found.c:620
+#: ../contrib/command-not-found/pk-command-not-found.c:623
 #, c-format
 msgid "Install package '%s' to provide command '%s'?"
 msgstr "సంకలనము '%s'ను ఆదేశము '%s' అందివ్వుటకు సంస్థాపించాలా?"
 
 #. TRANSLATORS: Show the user a list of packages that provide this command
-#: ../contrib/command-not-found/pk-command-not-found.c:641
+#: ../contrib/command-not-found/pk-command-not-found.c:644
 msgid "Packages providing this file are:"
 msgstr "ఈ దస్త్రమును అందించు సంకలనములు:"
 
 #. TRANSLATORS: Show the user a list of packages that they can install to provide this command
-#: ../contrib/command-not-found/pk-command-not-found.c:650
+#: ../contrib/command-not-found/pk-command-not-found.c:653
 msgid "Suitable packages are:"
 msgstr "సరితూగు సంకలనములు:"
 
 #. get selection
 #. TRANSLATORS: ask the user to choose a file to install
-#: ../contrib/command-not-found/pk-command-not-found.c:658
+#: ../contrib/command-not-found/pk-command-not-found.c:661
 msgid "Please choose a package to install"
 msgstr "సంస్థాపించుటకు దయచేసి సంకలనమును యెంచుకొనుము"
 
@@ -1031,48 +1039,47 @@ msgid ""
 msgstr "org.freedesktop.PackageKit.conf దస్త్రము సిస్టమ్ డైరెక్టరీనందు సంస్థాపించబడలేదు:"
 
 #. TRANSLATORS: a backend is the system package tool, e.g. yum, apt
-#: ../src/pk-main.c:193
+#: ../src/pk-main.c:205
 msgid "Packaging backend to use, e.g. dummy"
 msgstr "ఉపయోగించుటకు సంకలనీకరణ బ్యాకెండ్, ఉ.దా. dummy"
 
 #. TRANSLATORS: if we should run in the background
-#: ../src/pk-main.c:196
+#: ../src/pk-main.c:208
 msgid "Daemonize and detach from the terminal"
 msgstr "టెర్మినల్ నుండి డెమొనైజ్ చేసి మరియు వేరుచేయుము"
 
 #. TRANSLATORS: if we should not monitor how long we are inactive for
-#: ../src/pk-main.c:202
+#: ../src/pk-main.c:214
 msgid "Disable the idle timer"
 msgstr "వృధాగావున్న సమయగణనిని అచేతనముచేయి"
 
 #. TRANSLATORS: show version
-#: ../src/pk-main.c:205
+#: ../src/pk-main.c:217
 msgid "Show version and exit"
 msgstr "వర్షన్ చూపుము మరియు నిష్క్రమించుము"
 
 #. TRANSLATORS: exit after we've started up, used for user profiling
-#: ../src/pk-main.c:208
+#: ../src/pk-main.c:220
 msgid "Exit after a small delay"
 msgstr "ఒక చిన్న విరామం తర్వాత నిష్క్రమించుము"
 
 #. TRANSLATORS: exit straight away, used for automatic profiling
-#: ../src/pk-main.c:211
+#: ../src/pk-main.c:223
 msgid "Exit after the engine has loaded"
 msgstr "ఇంజన్ లోడైన తర్వాత నిష్క్రమించుము"
 
 #. TRANSLATORS: describing the service that is running
-#: ../src/pk-main.c:226
+#: ../src/pk-main.c:238
 msgid "PackageKit service"
 msgstr "PackageKit సేవ"
 
 #. TRANSLATORS: fatal error, dbus is not running
-#: ../src/pk-main.c:263
+#: ../src/pk-main.c:275
 msgid "Cannot connect to the system bus"
 msgstr "సిస్టమ్ బస్‌నకు అనుసంధానము కాలేదు"
 
-#. TRANSLATORS: cannot register on system bus, unknown reason
-#: ../src/pk-main.c:313
-#, c-format
+#. TRANSLATORS: cannot register on system bus, unknown reason -- geeky error follows
+#: ../src/pk-main.c:331
 msgid "Error trying to start:"
 msgstr "ప్రారంభించుటలో దోషము:"
 
commit 32fb4b2d0eb97d82d2b143a8cf5567eace45fec3
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Jun 1 20:34:07 2009 +0100

    Rewrite the networking stack GObjects to derive from a common PkNetworkStack object

diff --git a/src/Makefile.am b/src/Makefile.am
index 5dca9c9..937b23b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -63,12 +63,14 @@ shared_SOURCES =					\
 	pk-shared.h					\
 	pk-post-trans.c					\
 	pk-post-trans.h					\
-	pk-network-nm.h					\
-	pk-network-connman.h				\
-	pk-network-unix.c				\
-	pk-network-unix.h				\
 	pk-time.h					\
 	pk-time.c					\
+	pk-network-stack.h				\
+	pk-network-stack.c				\
+	pk-network-stack-unix.c				\
+	pk-network-stack-unix.h				\
+	pk-network-stack-nm.h				\
+	pk-network-stack-connman.h			\
 	pk-syslog.h					\
 	pk-syslog.c					\
 	pk-conf.c					\
@@ -98,18 +100,12 @@ shared_SOURCES =					\
 
 if PK_BUILD_NETWORKMANAGER
 shared_SOURCES +=					\
-	pk-network-nm.c
-else
-shared_SOURCES +=					\
-	pk-network-nm-dummy.c
+	pk-network-stack-nm.c
 endif
 
 if PK_BUILD_CONNMAN
 shared_SOURCES +=					\
-	pk-network-connman.c
-else
-shared_SOURCES +=					\
-	pk-network-connman-dummy.c
+	pk-network-stack-connman.c
 endif
 
 if PK_BUILD_GIO
diff --git a/src/pk-network-connman-dummy.c b/src/pk-network-connman-dummy.c
deleted file mode 100644
index 0d132ea..0000000
--- a/src/pk-network-connman-dummy.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2007-2009  Intel Corporation. All rights reserved.
- *
- * 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 "config.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-#include <errno.h>
-
-#include <string.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#include <sys/wait.h>
-#include <fcntl.h>
-
-#include <glib/gi18n.h>
-
-#include "egg-debug.h"
-#include "pk-network-connman.h"
-#include "pk-marshal.h"
-
-static void	pk_network_connman_finalize		(GObject	*object);
-
-#define PK_NETWORK_CONNMAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_NETWORK_CONNMAN, PkNetworkConnmanPrivate))
-
-/**
- * PkNetworkConnmanPrivate:
- *
- * Private #PkNetworkConnman data
- **/
-struct _PkNetworkConnmanPrivate
-{
-	gpointer		 dummy;
-};
-
-enum {
-	PK_NETWORK_CONNMAN_STATE_CHANGED,
-	PK_NETWORK_CONNMAN_LAST_SIGNAL
-};
-
-static guint signals [PK_NETWORK_CONNMAN_LAST_SIGNAL] = { 0 };
-
-G_DEFINE_TYPE (PkNetworkConnman, pk_network_connman, G_TYPE_OBJECT)
-
-/**
- * pk_network_connman_get_network_state:
- * @network_connman: a valid #PkNetworkConnman instance
- *
- * Return value: always %TRUE - this method should never be called
- **/
-PkNetworkEnum
-pk_network_connman_get_network_state (PkNetworkConnman *network_connman)
-{
-	g_return_val_if_fail (PK_IS_NETWORK_CONNMAN (network_connman), PK_NETWORK_ENUM_UNKNOWN);
-	/* don't do any checks */
-	return PK_NETWORK_ENUM_ONLINE;
-}
-
-/**
- * pk_network_connman_class_init:
- * @klass: The PkNetworkConnmanClass
- **/
-static void
-pk_network_connman_class_init (PkNetworkConnmanClass *klass)
-{
-	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-	object_class->finalize = pk_network_connman_finalize;
-	signals [PK_NETWORK_CONNMAN_STATE_CHANGED] =
-		g_signal_new ("state-changed",
-			     G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
-			     0, NULL, NULL, g_cclosure_marshal_VOID__UINT,
-			     G_TYPE_NONE, 1, G_TYPE_UINT);
-	g_type_class_add_private (klass, sizeof (PkNetworkConnmanPrivate));
-}
-
-/**
- * pk_network_connman_init:
- * @network_connman: This class instance
- **/
-static void
-pk_network_connman_init (PkNetworkConnman *network_connman)
-{
-	network_connman->priv = PK_NETWORK_CONNMAN_GET_PRIVATE (network_connman);
-}
-
-/**
- * pk_network_connman_finalize:
- * @object: The object to finalize
- **/
-static void
-pk_network_connman_finalize (GObject *object)
-{
-	PkNetworkConnman *network_connman;
-	g_return_if_fail (object != NULL);
-	g_return_if_fail (PK_IS_NETWORK_CONNMAN (object));
-	network_connman = PK_NETWORK_CONNMAN (object);
-
-	g_return_if_fail (network_connman->priv != NULL);
-	G_OBJECT_CLASS (pk_network_connman_parent_class)->finalize (object);
-}
-
-/**
- * pk_network_connman_new:
- *
- * Return value: a new PkNetworkConnman object.
- **/
-PkNetworkConnman *
-pk_network_connman_new (void)
-{
-	PkNetworkConnman *network_connman;
-	network_connman = g_object_new (PK_TYPE_NETWORK_CONNMAN, NULL);
-	return PK_NETWORK_CONNMAN (network_connman);
-}
-
diff --git a/src/pk-network-connman.c b/src/pk-network-connman.c
deleted file mode 100644
index aa7583e..0000000
--- a/src/pk-network-connman.c
+++ /dev/null
@@ -1,310 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2007-2009  Intel Corporation. All rights reserved.
- *
- * 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 "config.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-#include <errno.h>
-
-#include <string.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#include <sys/wait.h>
-#include <fcntl.h>
-
-#include <glib/gi18n.h>
-#include <glib.h>
-#include <dbus/dbus-glib.h>
-
-#include "egg-debug.h"
-#include "pk-network-connman.h"
-#include "pk-marshal.h"
-
-static void	pk_network_connman_finalize		(GObject	*object);
-
-#define PK_NETWORK_CONNMAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_NETWORK_CONNMAN, PkNetworkConnmanPrivate))
-
-/**
- * PkNetworkConnmanPrivate:
- *
- * Private #PkNetworkConnman data
- **/
-struct _PkNetworkConnmanPrivate
-{
-	DBusGConnection		*bus;
-	DBusGProxy		*proxy_connman;
-};
-
-enum {
-	PK_NETWORK_CONNMAN_STATE_CHANGED,
-	PK_NETWORK_CONNMAN_LAST_SIGNAL
-};
-
-static guint signals [PK_NETWORK_CONNMAN_LAST_SIGNAL] = { 0 };
-
-G_DEFINE_TYPE (PkNetworkConnman, pk_network_connman, G_TYPE_OBJECT)
-
-#define CONNMAN_DBUS_NAME "org.moblin.connman"
-
-#define CONNMAN_MANAGER_DBUS_INTERFACE CONNMAN_DBUS_NAME ".Manager"
-#define CONNMAN_SERVICE_DBUS_INTERFACE CONNMAN_DBUS_NAME ".Service"
-#define CONNMAN_MANAGER_DBUS_PATH "/"
-
-static void
-iterate_list(const GValue *value, gpointer user_data)
-{
-	GSList **list = user_data;
-	gchar *path = g_value_dup_boxed(value);
-
-	if (path == NULL)
-		return;
-
-	*list = g_slist_append(*list, path);
-}
-
-/**
- * pk_network_nm_get_active_connection_type_for_device:
- **/
-static PkNetworkEnum
-pk_network_connman_get_connection_type (const GValue *value)
-{
-	const char *type = value ? g_value_get_string(value) : NULL;
-
-	if (type == NULL)
-		return PK_NETWORK_ENUM_UNKNOWN;
-	else if (g_str_equal (type, "ethernet") == TRUE)
-		return PK_NETWORK_ENUM_WIRED;
-	else if (g_str_equal (type, "wifi") == TRUE)
-		return PK_NETWORK_ENUM_WIFI;
-	else if (g_str_equal (type, "wimax") == TRUE)
-		return PK_NETWORK_ENUM_MOBILE;
-
-	return PK_NETWORK_ENUM_UNKNOWN;
-}
-
-/**
- * pk_network_connman_get_network_state:
- * @network_connman: a valid #PkNetworkConnman instance
- *
- * Return value: %TRUE if the network_connman is online
- **/
-PkNetworkEnum
-pk_network_connman_get_network_state (PkNetworkConnman *network_connman)
-{
-	DBusGProxy *proxy, *proxy_service;
-	GError *error = NULL;
-	GHashTable *hash_manager = NULL, *hash_service = NULL;
-	GValue *value;
-	GSList *list, *services_list = NULL;
-	DBusGConnection *connection = network_connman->priv->bus;
-	gchar *state;
-	PkNetworkEnum type;
-
-	g_return_val_if_fail (PK_IS_NETWORK_CONNMAN (network_connman), PK_NETWORK_ENUM_UNKNOWN);
-	proxy = network_connman->priv->proxy_connman;
-	proxy_service = NULL;
-
-	/* get services */
-	dbus_g_proxy_call (proxy, "GetProperties", &error, G_TYPE_INVALID,
-		dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &hash_manager, G_TYPE_INVALID);
-
-	if (error != NULL || hash_manager == NULL) {
-		if (error)
-			g_clear_error (&error);
-		return PK_NETWORK_ENUM_UNKNOWN;
-	}
-
-	value = g_hash_table_lookup (hash_manager, "State");
-	state = value ? g_value_dup_string(value) : NULL;
-
-	if (g_str_equal (state, "online") == FALSE)
-		return PK_NETWORK_ENUM_OFFLINE;
-
-	value = g_hash_table_lookup (hash_manager, "Services");
-	if (value == NULL)
-		return PK_NETWORK_ENUM_UNKNOWN;
-
-	dbus_g_type_collection_value_iterate (value, iterate_list, &services_list);
-
-	for (list = services_list; list; list = list->next) {
-		gchar *path = list->data;
-
-		egg_debug ("service path is %s", path);
-
-		proxy_service = dbus_g_proxy_new_for_name (connection,
-							   CONNMAN_DBUS_NAME,
-							   path,
-							   CONNMAN_SERVICE_DBUS_INTERFACE);
-		if (proxy_service != NULL)
-			break;
-	}
-
-	for (list = services_list; list; list = list->next) {
-		gchar *path = list->data;
-		g_free (path);
-	}
-	g_slist_free (services_list);
-
-	if (proxy_service == NULL)
-		return PK_NETWORK_ENUM_UNKNOWN;
-
-	/* now proxy_service point to first available service*/
-	/* get connection type for it*/
-	dbus_g_proxy_call (proxy_service, "GetProperties", &error, G_TYPE_INVALID,
-		dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &hash_service, G_TYPE_INVALID);
-
-	if (error != NULL || hash_service == NULL) {
-		if (error)
-			g_clear_error (&error);
-		return PK_NETWORK_ENUM_OFFLINE;
-	}
-
-	value = g_hash_table_lookup (hash_service, "Type");
-	type = pk_network_connman_get_connection_type (value);
-
-	egg_debug ("network type is %s", pk_network_enum_to_text (type));
-	g_object_unref (proxy_service);
-	return type;
-}
-
-/**
- * pk_network_connman_state_changed
- **/
-static void
-pk_network_connman_state_changed (DBusGProxy *proxy, const char *property,
-					GValue *value, gpointer user_data)
-{
-	gboolean ret;
-	PkNetworkConnman *network_connman = (PkNetworkConnman *) user_data;
-
-	g_return_if_fail (PK_IS_NETWORK_CONNMAN (network_connman));
-
-	if (g_str_equal (property, "State") == TRUE) {
-		gchar *state;
-
-		state = g_value_dup_string (value);
-		if (g_str_equal (state, "online") == TRUE)
-			ret = TRUE;
-		else
-			ret = FALSE;
-		g_signal_emit (network_connman, signals [PK_NETWORK_CONNMAN_STATE_CHANGED], 0, ret);
-	}
-
-}
-
-/**
- * pk_network_connman_class_init:
- * @klass: The PkNetworkConnmanClass
- **/
-static void
-pk_network_connman_class_init (PkNetworkConnmanClass *klass)
-{
-	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-	object_class->finalize = pk_network_connman_finalize;
-	signals [PK_NETWORK_CONNMAN_STATE_CHANGED] =
-		g_signal_new ("state-changed",
-			     G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
-			     0, NULL, NULL, g_cclosure_marshal_VOID__UINT,
-			     G_TYPE_NONE, 1, G_TYPE_UINT);
-	g_type_class_add_private (klass, sizeof (PkNetworkConnmanPrivate));
-}
-
-/**
- * pk_network_connman_init:
- * @network_connman: This class instance
- **/
-static void
-pk_network_connman_init (PkNetworkConnman *network_connman)
-{
-	GError *error = NULL;
-	DBusGProxy *proxy;
-
-	network_connman->priv = PK_NETWORK_CONNMAN_GET_PRIVATE (network_connman);
-
-	network_connman->priv->proxy_connman = NULL;
-
-	dbus_g_object_register_marshaller(pk_marshal_VOID__STRING_BOXED,
-					  G_TYPE_NONE, G_TYPE_STRING,
-					  G_TYPE_VALUE, G_TYPE_INVALID);
-
-	/* get system connection */
-	network_connman->priv->bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
-	if (network_connman->priv->bus == NULL) {
-		egg_warning ("Couldn't connect to system bus: %s", error->message);
-		g_error_free (error);
-		return;
-	}
-
-	proxy = dbus_g_proxy_new_for_name_owner (network_connman->priv->bus,
-			CONNMAN_DBUS_NAME, CONNMAN_MANAGER_DBUS_PATH, CONNMAN_MANAGER_DBUS_INTERFACE, &error);
-	network_connman->priv->proxy_connman = proxy;
-
-	if (error != NULL) {
-		egg_warning ("Cannot connect to connman: %s", error->message);
-		g_error_free (error);
-		return;
-	}
-	dbus_g_proxy_add_signal (proxy, "PropertyChanged",
-				 G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID);
-	dbus_g_proxy_connect_signal (proxy, "PropertyChanged",
-				     G_CALLBACK(pk_network_connman_state_changed), network_connman, NULL);
-
-}
-
-/**
- * pk_network_connman_finalize:
- * @object: The object to finalize
- **/
-static void
-pk_network_connman_finalize (GObject *object)
-{
-	PkNetworkConnman *network_connman;
-	g_return_if_fail (object != NULL);
-	g_return_if_fail (PK_IS_NETWORK_CONNMAN (object));
-	network_connman = PK_NETWORK_CONNMAN (object);
-
-	g_return_if_fail (network_connman->priv != NULL);
-
-	if (network_connman->priv->proxy_connman != NULL)
-		g_object_unref (network_connman->priv->proxy_connman);
-
-	G_OBJECT_CLASS (pk_network_connman_parent_class)->finalize (object);
-}
-
-/**
- * pk_network_connman_new:
- *
- * Return value: a new PkNetworkConnman object.
- **/
-PkNetworkConnman *
-pk_network_connman_new (void)
-{
-	PkNetworkConnman *network_connman;
-	network_connman = g_object_new (PK_TYPE_NETWORK_CONNMAN, NULL);
-	return PK_NETWORK_CONNMAN (network_connman);
-}
-
diff --git a/src/pk-network-connman.h b/src/pk-network-connman.h
deleted file mode 100644
index da5f55b..0000000
--- a/src/pk-network-connman.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2007-2009  Intel Corporation. All rights reserved.
- *
- * Licensed under the GNU General Public License Version 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:pk-network-connman
- * @short_description: An ConnmMan access GObject
- *
- * This allows a switchable network backend.
- */
-
-#ifndef __PK_NETWORK_CONNMAN_H
-#define __PK_NETWORK_CONNMAN_H
-
-#include <glib-object.h>
-#include <packagekit-glib/packagekit.h>
-
-G_BEGIN_DECLS
-
-#define PK_TYPE_NETWORK_CONNMAN		(pk_network_connman_get_type ())
-#define PK_NETWORK_CONNMAN(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), PK_TYPE_NETWORK_CONNMAN, PkNetworkConnman))
-#define PK_NETWORK_CONNMAN_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), PK_TYPE_NETWORK_CONNMAN, PkNetworkConnmanClass))
-#define PK_IS_NETWORK_CONNMAN(o)	(G_TYPE_CHECK_INSTANCE_TYPE ((o), PK_TYPE_NETWORK_CONNMAN))
-#define PK_IS_NETWORK_CONNMAN_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), PK_TYPE_NETWORK_CONNMAN))
-#define PK_NETWORK_CONNMAN_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), PK_TYPE_NETWORK_CONNMAN, PkNetworkConnmanClass))
-#define PK_NETWORK_CONNMAN_ERROR	(pk_network_connman_error_quark ())
-#define PK_NETWORK_CONNMAN_TYPE_ERROR	(pk_network_connman_error_get_type ())
-
-typedef struct _PkNetworkConnmanPrivate	PkNetworkConnmanPrivate;
-typedef struct _PkNetworkConnman	PkNetworkConnman;
-typedef struct _PkNetworkConnmanClass  PkNetworkConnmanClass;
-
-struct _PkNetworkConnman
-{
-	GObject			 parent;
-	PkNetworkConnmanPrivate	*priv;
-};
-
-struct _PkNetworkConnmanClass
-{
-	GObjectClass		 parent_class;
-};
-
-GType			 pk_network_connman_get_type		(void);
-PkNetworkConnman	*pk_network_connman_new			(void);
-PkNetworkEnum		 pk_network_connman_get_network_state	(PkNetworkConnman	*network_connman);
-
-G_END_DECLS
-
-#endif /* __PK_NETWORK_CONNMAN_H */
-
diff --git a/src/pk-network-nm-dummy.c b/src/pk-network-nm-dummy.c
deleted file mode 100644
index 3091941..0000000
--- a/src/pk-network-nm-dummy.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2007-2008 Richard Hughes <richard at hughsie.com>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-#include <errno.h>
-
-#include <string.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#include <sys/wait.h>
-#include <fcntl.h>
-
-#include <glib/gi18n.h>
-
-#include "egg-debug.h"
-#include "pk-network-nm.h"
-#include "pk-marshal.h"
-
-static void     pk_network_nm_finalize		(GObject          *object);
-
-#define PK_NETWORK_NM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_NETWORK_NM, PkNetworkNmPrivate))
-
-/**
- * PkNetworkNmPrivate:
- *
- * Private #PkNetworkNm data
- **/
-struct _PkNetworkNmPrivate
-{
-	guint			 callback_id;
-};
-
-enum {
-	PK_NETWORK_NM_STATE_CHANGED,
-	PK_NETWORK_NM_LAST_SIGNAL
-};
-
-static guint signals [PK_NETWORK_NM_LAST_SIGNAL] = { 0 };
-
-G_DEFINE_TYPE (PkNetworkNm, pk_network_nm, G_TYPE_OBJECT)
-
-/**
- * pk_network_nm_get_network_state:
- * @network_nm: a valid #PkNetworkNm instance
- *
- * Return value: always %TRUE - this method should never be called
- **/
-PkNetworkEnum
-pk_network_nm_get_network_state (PkNetworkNm *network_nm)
-{
-	g_return_val_if_fail (PK_IS_NETWORK_NM (network_nm), PK_NETWORK_ENUM_UNKNOWN);
-	/* don't do any checks */
-	return PK_NETWORK_ENUM_ONLINE;
-}
-
-/**
- * pk_network_nm_class_init:
- * @klass: The PkNetworkNmClass
- **/
-static void
-pk_network_nm_class_init (PkNetworkNmClass *klass)
-{
-	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-	object_class->finalize = pk_network_nm_finalize;
-	signals [PK_NETWORK_NM_STATE_CHANGED] =
-		g_signal_new ("state-changed",
-			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
-			      0, NULL, NULL, g_cclosure_marshal_VOID__UINT,
-			      G_TYPE_NONE, 1, G_TYPE_UINT);
-	g_type_class_add_private (klass, sizeof (PkNetworkNmPrivate));
-}
-
-/**
- * pk_network_nm_init:
- * @network_nm: This class instance
- **/
-static void
-pk_network_nm_init (PkNetworkNm *network_nm)
-{
-	network_nm->priv = PK_NETWORK_NM_GET_PRIVATE (network_nm);
-}
-
-/**
- * pk_network_nm_finalize:
- * @object: The object to finalize
- **/
-static void
-pk_network_nm_finalize (GObject *object)
-{
-	PkNetworkNm *network_nm;
-	g_return_if_fail (object != NULL);
-	g_return_if_fail (PK_IS_NETWORK_NM (object));
-	network_nm = PK_NETWORK_NM (object);
-
-	g_return_if_fail (network_nm->priv != NULL);
-	G_OBJECT_CLASS (pk_network_nm_parent_class)->finalize (object);
-}
-
-/**
- * pk_network_nm_new:
- *
- * Return value: a new PkNetworkNm object.
- **/
-PkNetworkNm *
-pk_network_nm_new (void)
-{
-	PkNetworkNm *network_nm;
-	network_nm = g_object_new (PK_TYPE_NETWORK_NM, NULL);
-	return PK_NETWORK_NM (network_nm);
-}
-
diff --git a/src/pk-network-nm.c b/src/pk-network-nm.c
deleted file mode 100644
index 372f03b..0000000
--- a/src/pk-network-nm.c
+++ /dev/null
@@ -1,392 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2007-2008 Richard Hughes <richard at hughsie.com>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-#include <errno.h>
-
-#include <string.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#include <sys/wait.h>
-#include <fcntl.h>
-
-#include <glib/gi18n.h>
-#include <dbus/dbus-glib.h>
-#include <NetworkManager.h>
-#include <libnm_glib.h>
-
-#include "egg-debug.h"
-#include "pk-network-nm.h"
-#include "pk-marshal.h"
-
-static void     pk_network_nm_finalize		(GObject          *object);
-
-#define PK_NETWORK_NM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_NETWORK_NM, PkNetworkNmPrivate))
-
-/* experimental code */
-#define PK_NETWORK_NM_GET_CONNECTION_TYPE	1
-
-/**
- * PkNetworkNmPrivate:
- *
- * Private #PkNetworkNm data
- **/
-struct _PkNetworkNmPrivate
-{
-	libnm_glib_ctx		*ctx;
-	guint			 callback_id;
-	DBusGConnection		*bus;
-};
-
-enum {
-	PK_NETWORK_NM_STATE_CHANGED,
-	PK_NETWORK_NM_LAST_SIGNAL
-};
-
-static guint signals [PK_NETWORK_NM_LAST_SIGNAL] = { 0 };
-
-G_DEFINE_TYPE (PkNetworkNm, pk_network_nm, G_TYPE_OBJECT)
-
-/**
- * pk_network_nm_prioritise_connection_type:
- *
- * GSM is more important than ethernet, so if we are using an
- * important connection even bridged we should prioritise it
- **/
-static NMDeviceType
-pk_network_nm_prioritise_connection_type (NMDeviceType type_old, NMDeviceType type_new)
-{
-	NMDeviceType type = type_old;
-	/* by sheer fluke we can use the enum ordering */
-	if (type_new > type_old)
-		type = type_new;
-	return type;
-}
-
-/**
- * pk_network_nm_get_active_connection_type_for_device:
- **/
-static NMDeviceType
-pk_network_nm_get_active_connection_type_for_device (PkNetworkNm *network_nm, const gchar *device)
-{
-	gboolean ret;
-	GError *error = NULL;
-	DBusGProxy *proxy;
-	GValue value = { 0 };
-	NMDeviceType type = NM_DEVICE_TYPE_UNKNOWN;
-
-	/* get if the device is default */
-	proxy = dbus_g_proxy_new_for_name (network_nm->priv->bus, "org.freedesktop.NetworkManager",
-					   device, "org.freedesktop.DBus.Properties");
-	ret = dbus_g_proxy_call (proxy, "Get", &error,
-				 G_TYPE_STRING, "org.freedesktop.NetworkManager.Device",
-				 G_TYPE_STRING, "DeviceType",
-				 G_TYPE_INVALID,
-				 G_TYPE_VALUE, &value,
-				 G_TYPE_INVALID);
-	if (!ret) {
-		g_warning ("Error getting DeviceType: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-	type = g_value_get_uint (&value);
-	egg_debug ("type: %i", type);
-out:
-	g_object_unref (proxy);
-	return type;
-}
-
-/**
- * pk_network_nm_get_active_connection_type_for_connection:
- **/
-static NMDeviceType
-pk_network_nm_get_active_connection_type_for_connection (PkNetworkNm *network_nm, const gchar *active_connection)
-{
-	guint i;
-	gboolean ret;
-	GError *error = NULL;
-	DBusGProxy *proxy;
-	const gchar *device;
-	GValue value_default = { 0 };
-	GValue value_devices = { 0 };
-	gboolean is_default;
-	GPtrArray *devices;
-	NMDeviceType type_tmp;
-	NMDeviceType type = NM_DEVICE_TYPE_UNKNOWN;
-
-
-	/* get if the device is default */
-	proxy = dbus_g_proxy_new_for_name (network_nm->priv->bus, "org.freedesktop.NetworkManager",
-					   active_connection, "org.freedesktop.DBus.Properties");
-	ret = dbus_g_proxy_call (proxy, "Get", &error,
-				 G_TYPE_STRING, "org.freedesktop.NetworkManager.Connection.Active",
-				 G_TYPE_STRING, "Default",
-				 G_TYPE_INVALID,
-				 G_TYPE_VALUE, &value_default,
-				 G_TYPE_INVALID);
-	if (!ret) {
-		g_warning ("Error getting Default: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-	is_default = g_value_get_boolean (&value_default);
-	egg_debug ("is_default: %i", is_default);
-	if (!is_default) {
-		egg_debug ("not default, skipping");
-		goto out;
-	}
-
-	/* get the physical devices for the connection */
-	ret = dbus_g_proxy_call (proxy, "Get", &error,
-				 G_TYPE_STRING, "org.freedesktop.NetworkManager.Connection.Active",
-				 G_TYPE_STRING, "Devices",
-				 G_TYPE_INVALID,
-				 G_TYPE_VALUE, &value_devices,
-				 G_TYPE_INVALID);
-	if (!ret) {
-		g_warning ("Error getting Devices: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-	devices = g_value_get_boxed (&value_devices);
-	egg_debug ("number of devices: %i", devices->len);
-	if (devices->len == 0)
-		goto out;
-
-	/* find the types of the active connection */
-	for (i=0; i<devices->len; i++) {
-		device = g_ptr_array_index (devices, i);
-		type_tmp = pk_network_nm_get_active_connection_type_for_device (network_nm, device);
-		type = pk_network_nm_prioritise_connection_type (type, type_tmp);
-	}
-
-out:
-	g_object_unref (proxy);
-	return type;
-}
-
-/**
- * pk_network_nm_get_active_connection_type:
- **/
-static NMDeviceType
-pk_network_nm_get_active_connection_type (PkNetworkNm *network_nm)
-{
-	guint i;
-	gboolean ret;
-	DBusGProxy *proxy;
-	GError *error = NULL;
-	GPtrArray *active_connections = NULL;
-	const gchar *active_connection;
-	GValue value = { 0 };
-	NMDeviceType type_tmp;
-	NMDeviceType type = NM_DEVICE_TYPE_UNKNOWN;
-
-	/* get proxy */
-	proxy = dbus_g_proxy_new_for_name (network_nm->priv->bus, "org.freedesktop.NetworkManager",
-					   "/org/freedesktop/NetworkManager",
-					   "org.freedesktop.DBus.Properties");
-	ret = dbus_g_proxy_call (proxy, "Get", &error,
-				 G_TYPE_STRING, "org.freedesktop.NetworkManager",
-				 G_TYPE_STRING, "ActiveConnections",
-				 G_TYPE_INVALID,
-				 G_TYPE_VALUE, &value,
-				 G_TYPE_INVALID);
-	if (!ret) {
-		g_warning ("Error getting ActiveConnections: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-	active_connections = g_value_get_boxed (&value);
-	egg_debug ("active connections: %i", active_connections->len);
-	if (active_connections->len == 0)
-		goto out;
-
-	/* find the active connection */
-	for (i=0; i<active_connections->len; i++) {
-		active_connection = g_ptr_array_index (active_connections, i);
-		type_tmp = pk_network_nm_get_active_connection_type_for_connection (network_nm, active_connection);
-		type = pk_network_nm_prioritise_connection_type (type, type_tmp);
-	}
-
-out:
-	g_object_unref (proxy);
-	g_ptr_array_foreach (active_connections, (GFunc) g_free, NULL);
-	g_ptr_array_free (active_connections, TRUE);
-	return type;
-}
-
-/**
- * pk_network_nm_get_network_state:
- * @network_nm: a valid #PkNetworkNm instance
- *
- * Return value: %TRUE if the network_nm is online
- **/
-PkNetworkEnum
-pk_network_nm_get_network_state (PkNetworkNm *network_nm)
-{
-	PkNetworkEnum ret;
-#ifdef PK_NETWORK_NM_GET_CONNECTION_TYPE
-	NMDeviceType type;
-#else
-	libnm_glib_state state;
-#endif
-
-	g_return_val_if_fail (PK_IS_NETWORK_NM (network_nm), PK_NETWORK_ENUM_UNKNOWN);
-
-#ifdef PK_NETWORK_NM_GET_CONNECTION_TYPE
-	/* get connection type */
-	type = pk_network_nm_get_active_connection_type (network_nm);
-	switch (type) {
-	case NM_DEVICE_TYPE_UNKNOWN:
-		ret = PK_NETWORK_ENUM_OFFLINE;
-		break;
-	case NM_DEVICE_TYPE_ETHERNET:
-		ret = PK_NETWORK_ENUM_WIRED;
-		break;
-	case NM_DEVICE_TYPE_WIFI:
-		ret = PK_NETWORK_ENUM_WIFI;
-		break;
-	case NM_DEVICE_TYPE_GSM:
-	case NM_DEVICE_TYPE_CDMA:
-		ret = PK_NETWORK_ENUM_MOBILE;
-		break;
-	default:
-		ret = PK_NETWORK_ENUM_ONLINE;
-	}
-#else
-	state = libnm_glib_get_network_state (network_nm->priv->ctx);
-	switch (state) {
-	case LIBNM_NO_NETWORK_CONNECTION:
-		ret = PK_NETWORK_ENUM_OFFLINE;
-		break;
-	default:
-		ret = PK_NETWORK_ENUM_ONLINE;
-	}
-#endif
-	egg_debug ("network state is %s", pk_network_enum_to_text (ret));
-	return ret;
-}
-
-/**
- * pk_network_nm_nm_changed_cb:
- **/
-static void
-pk_network_nm_nm_changed_cb (libnm_glib_ctx *libnm_ctx, gpointer data)
-{
-	PkNetworkEnum state;
-	PkNetworkNm *network_nm = (PkNetworkNm *) data;
-
-	g_return_if_fail (PK_IS_NETWORK_NM (network_nm));
-
-	state = pk_network_nm_get_network_state (network_nm);
-	g_signal_emit (network_nm, signals [PK_NETWORK_NM_STATE_CHANGED], 0, state);
-}
-
-/**
- * pk_network_nm_class_init:
- * @klass: The PkNetworkNmClass
- **/
-static void
-pk_network_nm_class_init (PkNetworkNmClass *klass)
-{
-	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-	object_class->finalize = pk_network_nm_finalize;
-	signals [PK_NETWORK_NM_STATE_CHANGED] =
-		g_signal_new ("state-changed",
-			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
-			      0, NULL, NULL, g_cclosure_marshal_VOID__UINT,
-			      G_TYPE_NONE, 1, G_TYPE_UINT);
-	g_type_class_add_private (klass, sizeof (PkNetworkNmPrivate));
-}
-
-/**
- * pk_network_nm_init:
- * @network_nm: This class instance
- **/
-static void
-pk_network_nm_init (PkNetworkNm *network_nm)
-{
-	GError *error = NULL;
-	GMainContext *context;
-
-	network_nm->priv = PK_NETWORK_NM_GET_PRIVATE (network_nm);
-	context = g_main_context_default ();
-	network_nm->priv->ctx = libnm_glib_init ();
-	network_nm->priv->callback_id =
-		libnm_glib_register_callback (network_nm->priv->ctx,
-					      pk_network_nm_nm_changed_cb,
-					      network_nm, context);
-
-	/* get system connection */
-	network_nm->priv->bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
-	if (network_nm->priv->bus == NULL) {
-		egg_warning ("Couldn't connect to system bus: %s", error->message);
-		g_error_free (error);
-	}
-}
-
-/**
- * pk_network_nm_finalize:
- * @object: The object to finalize
- **/
-static void
-pk_network_nm_finalize (GObject *object)
-{
-	PkNetworkNm *network_nm;
-	g_return_if_fail (object != NULL);
-	g_return_if_fail (PK_IS_NETWORK_NM (object));
-	network_nm = PK_NETWORK_NM (object);
-
-	g_return_if_fail (network_nm->priv != NULL);
-
-	libnm_glib_unregister_callback (network_nm->priv->ctx, network_nm->priv->callback_id);
-	libnm_glib_shutdown (network_nm->priv->ctx);
-
-	/* be paranoid */
-	network_nm->priv->ctx = NULL;
-	network_nm->priv->callback_id = 0;
-
-	G_OBJECT_CLASS (pk_network_nm_parent_class)->finalize (object);
-}
-
-/**
- * pk_network_nm_new:
- *
- * Return value: a new PkNetworkNm object.
- **/
-PkNetworkNm *
-pk_network_nm_new (void)
-{
-	PkNetworkNm *network_nm;
-	network_nm = g_object_new (PK_TYPE_NETWORK_NM, NULL);
-	return PK_NETWORK_NM (network_nm);
-}
-
diff --git a/src/pk-network-nm.h b/src/pk-network-nm.h
deleted file mode 100644
index a05ba8d..0000000
--- a/src/pk-network-nm.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2007-2008 Richard Hughes <richard at hughsie.com>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:pk-network-nm
- * @short_description: An NetworkManager access GObject
- *
- * This allows a switchable network backend.
- */
-
-#ifndef __PK_NETWORK_NM_H
-#define __PK_NETWORK_NM_H
-
-#include <glib-object.h>
-#include <packagekit-glib/packagekit.h>
-
-G_BEGIN_DECLS
-
-#define PK_TYPE_NETWORK_NM		(pk_network_nm_get_type ())
-#define PK_NETWORK_NM(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), PK_TYPE_NETWORK_NM, PkNetworkNm))
-#define PK_NETWORK_NM_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST((k), PK_TYPE_NETWORK_NM, PkNetworkNmClass))
-#define PK_IS_NETWORK_NM(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), PK_TYPE_NETWORK_NM))
-#define PK_IS_NETWORK_NM_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), PK_TYPE_NETWORK_NM))
-#define PK_NETWORK_NM_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), PK_TYPE_NETWORK_NM, PkNetworkNmClass))
-#define PK_NETWORK_NM_ERROR		(pk_network_nm_error_quark ())
-#define PK_NETWORK_NM_TYPE_ERROR	(pk_network_nm_error_get_type ())
-
-typedef struct _PkNetworkNmPrivate	PkNetworkNmPrivate;
-typedef struct _PkNetworkNm		PkNetworkNm;
-typedef struct _PkNetworkNmClass	PkNetworkNmClass;
-
-struct _PkNetworkNm
-{
-	 GObject		 parent;
-	 PkNetworkNmPrivate	*priv;
-};
-
-struct _PkNetworkNmClass
-{
-	GObjectClass	parent_class;
-};
-
-GType		 pk_network_nm_get_type		  	(void);
-PkNetworkNm	*pk_network_nm_new			(void);
-PkNetworkEnum	 pk_network_nm_get_network_state	(PkNetworkNm	*network_nm);
-
-G_END_DECLS
-
-#endif /* __PK_NETWORK_NM_H */
-
diff --git a/src/pk-network-stack-connman.c b/src/pk-network-stack-connman.c
new file mode 100644
index 0000000..4dffd05
--- /dev/null
+++ b/src/pk-network-stack-connman.c
@@ -0,0 +1,317 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2009  Intel Corporation. All rights reserved.
+ * Copyright (C) 2009 Richard Hughes <richard at hughsie.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+#include <dbus/dbus-glib.h>
+
+#include "egg-debug.h"
+#include "egg-dbus-monitor.h"
+
+#include "pk-network-stack-connman.h"
+#include "pk-conf.h"
+#include "pk-marshal.h"
+
+struct PkNetworkStackConnmanPrivate
+{
+	EggDbusMonitor		*dbus_monitor;
+	PkConf			*conf;
+	gboolean		 is_enabled;
+	DBusGConnection		*bus;
+	DBusGProxy		*proxy;
+};
+
+G_DEFINE_TYPE (PkNetworkStackConnman, pk_network_stack_connman, PK_TYPE_NETWORK_STACK)
+#define PK_NETWORK_STACK_CONNMAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_NETWORK_STACK_CONNMAN, PkNetworkStackConnmanPrivate))
+
+#define CONNMAN_DBUS_NAME			"org.moblin.connman"
+#define CONNMAN_MANAGER_DBUS_INTERFACE		CONNMAN_DBUS_NAME ".Manager"
+#define CONNMAN_SERVICE_DBUS_INTERFACE		CONNMAN_DBUS_NAME ".Service"
+#define CONNMAN_MANAGER_DBUS_PATH		"/"
+
+/**
+ * pk_network_stack_connman_iterate_list:
+ **/
+static void
+pk_network_stack_connman_iterate_list (const GValue *value, gpointer user_data)
+{
+	GSList **list = user_data;
+	gchar *path = g_value_dup_boxed (value);
+
+	if (path == NULL)
+		return;
+
+	*list = g_slist_append (*list, path);
+}
+
+/**
+ * pk_network_stack_connman_get_connection_type:
+ **/
+static PkNetworkEnum
+pk_network_stack_connman_get_connection_type (const GValue *value)
+{
+	const char *type = value ? g_value_get_string(value) : NULL;
+
+	if (type == NULL)
+		return PK_NETWORK_ENUM_UNKNOWN;
+	else if (g_str_equal (type, "ethernet"))
+		return PK_NETWORK_ENUM_WIRED;
+	else if (g_str_equal (type, "wifi"))
+		return PK_NETWORK_ENUM_WIFI;
+	else if (g_str_equal (type, "wimax"))
+		return PK_NETWORK_ENUM_MOBILE;
+
+	return PK_NETWORK_ENUM_UNKNOWN;
+}
+
+/**
+ * pk_network_stack_connman_get_state:
+ **/
+static PkNetworkEnum
+pk_network_stack_connman_get_state (PkNetworkStack *nstack)
+{
+	DBusGProxy *proxy, *proxy_service;
+	GError *error = NULL;
+	GHashTable *hash_manager = NULL;
+	GHashTable *hash_service = NULL;
+	GValue *value;
+	GSList *list;
+	GSList *services_list = NULL;
+	gchar *state;
+	PkNetworkEnum type;
+	PkNetworkStackConnman *nstack_connman = PK_NETWORK_STACK_CONNMAN (nstack);
+	DBusGConnection *connection = nstack_connman->priv->bus;
+
+	proxy = nstack_connman->priv->proxy;
+	proxy_service = NULL;
+
+	/* get services */
+	dbus_g_proxy_call (proxy, "GetProperties", &error,
+			   G_TYPE_INVALID,
+			   dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &hash_manager,
+			   G_TYPE_INVALID);
+	if (error != NULL || hash_manager == NULL) {
+		if (error)
+			g_clear_error (&error);
+		return PK_NETWORK_ENUM_UNKNOWN;
+	}
+
+	value = g_hash_table_lookup (hash_manager, "State");
+	state = value ? g_value_dup_string (value) : NULL;
+
+	if (g_str_equal (state, "online") == FALSE)
+		return PK_NETWORK_ENUM_OFFLINE;
+
+	value = g_hash_table_lookup (hash_manager, "Services");
+	if (value == NULL)
+		return PK_NETWORK_ENUM_UNKNOWN;
+
+	dbus_g_type_collection_value_iterate (value, pk_network_stack_connman_iterate_list, &services_list);
+
+	for (list = services_list; list; list = list->next) {
+		gchar *path = list->data;
+
+		egg_debug ("service path is %s", path);
+
+		proxy_service = dbus_g_proxy_new_for_name (connection,
+							   CONNMAN_DBUS_NAME,
+							   path,
+							   CONNMAN_SERVICE_DBUS_INTERFACE);
+		if (proxy_service != NULL)
+			break;
+	}
+
+	/* free service list */
+	for (list = services_list; list; list = list->next) {
+		gchar *path = list->data;
+		g_free (path);
+	}
+	g_slist_free (services_list);
+
+	if (proxy_service == NULL)
+		return PK_NETWORK_ENUM_UNKNOWN;
+
+	/* now proxy_service point to first available service */
+	/* get connection type for i t*/
+	dbus_g_proxy_call (proxy_service, "GetProperties", &error,
+			   G_TYPE_INVALID,
+			   dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &hash_service,
+			   G_TYPE_INVALID);
+	if (error != NULL || hash_service == NULL) {
+		if (error)
+			g_clear_error (&error);
+		return PK_NETWORK_ENUM_OFFLINE;
+	}
+
+	value = g_hash_table_lookup (hash_service, "Type");
+	type = pk_network_stack_connman_get_connection_type (value);
+
+	egg_debug ("network type is %s", pk_network_enum_to_text (type));
+	g_object_unref (proxy_service);
+	return type;
+}
+
+/**
+ * pk_network_stack_connman_state_changed
+ **/
+static void
+pk_network_stack_connman_state_changed (DBusGProxy *proxy, const char *property,
+					GValue *value, gpointer user_data)
+{
+	gboolean ret;
+	PkNetworkStackConnman *nstack_connman = (PkNetworkStackConnman *) user_data;
+
+	g_return_if_fail (PK_IS_NETWORK_STACK_CONNMAN (nstack_connman));
+
+	if (g_str_equal (property, "State") == TRUE) {
+		gchar *state;
+
+		state = g_value_dup_string (value);
+		if (g_str_equal (state, "online") == TRUE)
+			ret = TRUE;
+		else
+			ret = FALSE;
+		/* TODO: this is a PkNetworkState, not a gboolean */
+		egg_debug ("emitting network-state-changed: %s", pk_network_enum_to_text (ret));
+		g_signal_emit_by_name (PK_NETWORK_STACK (nstack_connman), "state-changed", ret);
+	}
+
+}
+
+/**
+ * pk_network_stack_connman_is_enabled:
+ *
+ * Return %TRUE on success, %FALSE if we failed to is_enabled or no data
+ **/
+static gboolean
+pk_network_stack_connman_is_enabled (PkNetworkStack *nstack)
+{
+	PkNetworkStackConnman *nstack_connman = PK_NETWORK_STACK_CONNMAN (nstack);
+	return nstack_connman->priv->is_enabled;
+}
+
+/**
+ * pk_network_stack_connman_init:
+ **/
+static void
+pk_network_stack_connman_init (PkNetworkStackConnman *nstack_connman)
+{
+	GError *error = NULL;
+	DBusGProxy *proxy;
+	gboolean service_alive;
+
+	nstack_connman->priv = PK_NETWORK_STACK_CONNMAN_GET_PRIVATE (nstack_connman);
+	nstack_connman->priv->conf = pk_conf_new ();
+
+	/* do we use this code? */
+	nstack_connman->priv->is_enabled = pk_conf_get_bool (nstack_connman->priv->conf, "UseNetworkConnman");
+	nstack_connman->priv->proxy = NULL;
+
+	dbus_g_object_register_marshaller (pk_marshal_VOID__STRING_BOXED,
+					   G_TYPE_NONE, G_TYPE_STRING,
+					   G_TYPE_VALUE, G_TYPE_INVALID);
+
+	/* get system connection */
+	nstack_connman->priv->bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+	if (nstack_connman->priv->bus == NULL) {
+		egg_warning ("Couldn't connect to system bus: %s", error->message);
+		g_error_free (error);
+		return;
+	}
+
+	/* check if ConnMan is on the bus */
+	nstack_connman->priv->dbus_monitor = egg_dbus_monitor_new ();
+	egg_dbus_monitor_assign (nstack_connman->priv->dbus_monitor, EGG_DBUS_MONITOR_SYSTEM, CONNMAN_DBUS_NAME);
+	service_alive = egg_dbus_monitor_is_connected (nstack_connman->priv->dbus_monitor);
+
+	/* ConnMan isn't up, so we can't use it */
+	if (nstack_connman->priv->is_enabled && !service_alive) {
+		egg_warning ("UseNetworkConnman true, but %s not up", CONNMAN_DBUS_NAME);
+		nstack_connman->priv->is_enabled = FALSE;
+	}
+
+	proxy = dbus_g_proxy_new_for_name_owner (nstack_connman->priv->bus,
+						 CONNMAN_DBUS_NAME,
+						 CONNMAN_MANAGER_DBUS_PATH,
+						 CONNMAN_MANAGER_DBUS_INTERFACE, &error);
+	nstack_connman->priv->proxy = proxy;
+
+	if (error != NULL) {
+		egg_warning ("Cannot connect to connman: %s", error->message);
+		g_error_free (error);
+		return;
+	}
+	dbus_g_proxy_add_signal (proxy, "PropertyChanged",
+				 G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID);
+	dbus_g_proxy_connect_signal (proxy, "PropertyChanged",
+				     G_CALLBACK(pk_network_stack_connman_state_changed), nstack_connman, NULL);
+}
+
+/**
+ * pk_network_stack_connman_finalize:
+ **/
+static void
+pk_network_stack_connman_finalize (GObject *object)
+{
+	PkNetworkStackConnman *nstack_connman;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (PK_IS_NETWORK_STACK_CONNMAN (object));
+
+	nstack_connman = PK_NETWORK_STACK_CONNMAN (object);
+	g_return_if_fail (nstack_connman->priv != NULL);
+
+	g_object_unref (nstack_connman->priv->dbus_monitor);
+	g_object_unref (nstack_connman->priv->conf);
+	if (nstack_connman->priv->proxy != NULL)
+		g_object_unref (nstack_connman->priv->proxy);
+
+	G_OBJECT_CLASS (pk_network_stack_connman_parent_class)->finalize (object);
+}
+
+/**
+ * pk_network_stack_connman_class_init:
+ **/
+static void
+pk_network_stack_connman_class_init (PkNetworkStackConnmanClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	PkNetworkStackClass *nstack_class = PK_NETWORK_STACK_CLASS (klass);
+
+	object_class->finalize = pk_network_stack_connman_finalize;
+	nstack_class->get_state = pk_network_stack_connman_get_state;
+	nstack_class->is_enabled = pk_network_stack_connman_is_enabled;
+
+	g_type_class_add_private (klass, sizeof (PkNetworkStackConnmanPrivate));
+}
+
+/**
+ * pk_network_stack_connman_new:
+ **/
+PkNetworkStackConnman *
+pk_network_stack_connman_new (void)
+{
+	return g_object_new (PK_TYPE_NETWORK_STACK_CONNMAN, NULL);
+}
+
diff --git a/src/pk-network-stack-connman.h b/src/pk-network-stack-connman.h
new file mode 100644
index 0000000..64b37b2
--- /dev/null
+++ b/src/pk-network-stack-connman.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2009  Intel Corporation. All rights reserved.
+ * Copyright (C) 2009 Richard Hughes <richard at hughsie.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifndef __PK_NETWORK_STACK_CONNMAN_H__
+#define __PK_NETWORK_STACK_CONNMAN_H__
+
+#include <glib-object.h>
+
+#include "pk-network-stack.h"
+
+G_BEGIN_DECLS
+
+#define PK_TYPE_NETWORK_STACK_CONNMAN  		(pk_network_stack_connman_get_type ())
+#define PK_NETWORK_STACK_CONNMAN(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), PK_TYPE_NETWORK_STACK_CONNMAN, PkNetworkStackConnman))
+#define PK_NETWORK_STACK_CONNMAN_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), PK_TYPE_NETWORK_STACK_CONNMAN, PkNetworkStackConnmanClass))
+#define PK_IS_NETWORK_STACK_CONNMAN(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), PK_TYPE_NETWORK_STACK_CONNMAN))
+#define PK_IS_NETWORK_STACK_CONNMAN_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), PK_TYPE_NETWORK_STACK_CONNMAN))
+#define PK_NETWORK_STACK_CONNMAN_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), PK_TYPE_NETWORK_STACK_CONNMAN, PkNetworkStackConnmanClass))
+
+typedef struct PkNetworkStackConnmanPrivate PkNetworkStackConnmanPrivate;
+
+typedef struct
+{
+	PkNetworkStack			 parent;
+	PkNetworkStackConnmanPrivate	*priv;
+} PkNetworkStackConnman;
+
+typedef struct
+{
+	PkNetworkStackClass		 parent_class;
+} PkNetworkStackConnmanClass;
+
+GType			 pk_network_stack_connman_get_type	(void);
+PkNetworkStackConnman	*pk_network_stack_connman_new		(void);
+
+G_END_DECLS
+
+#endif /* __PK_NETWORK_STACK_CONNMAN_H__ */
+
diff --git a/src/pk-network-stack-nm.c b/src/pk-network-stack-nm.c
new file mode 100644
index 0000000..16cce0f
--- /dev/null
+++ b/src/pk-network-stack-nm.c
@@ -0,0 +1,382 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2009 Richard Hughes <richard at hughsie.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+#include <dbus/dbus-glib.h>
+#include <NetworkManager.h>
+#include <libnm_glib.h>
+
+#include "egg-debug.h"
+#include "egg-dbus-monitor.h"
+
+#include "pk-network-stack-nm.h"
+#include "pk-conf.h"
+#include "pk-marshal.h"
+
+struct PkNetworkStackNmPrivate
+{
+	EggDbusMonitor		*dbus_monitor;
+	PkConf			*conf;
+	libnm_glib_ctx		*ctx;
+	guint			 callback_id;
+	DBusGConnection		*bus;
+	gboolean		 is_enabled;
+};
+
+G_DEFINE_TYPE (PkNetworkStackNm, pk_network_stack_nm, PK_TYPE_NETWORK_STACK)
+#define PK_NETWORK_STACK_NM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_NETWORK_STACK_NM, PkNetworkStackNmPrivate))
+
+/**
+ * pk_network_stack_nm_prioritise_connection_type:
+ *
+ * GSM is more important than ethernet, so if we are using an
+ * important connection even bridged we should prioritise it
+ **/
+static NMDeviceType
+pk_network_stack_nm_prioritise_connection_type (NMDeviceType type_old, NMDeviceType type_new)
+{
+	NMDeviceType type = type_old;
+	/* by sheer fluke we can use the enum ordering */
+	if (type_new > type_old)
+		type = type_new;
+	return type;
+}
+
+/**
+ * pk_network_stack_nm_get_active_connection_type_for_device:
+ **/
+static NMDeviceType
+pk_network_stack_nm_get_active_connection_type_for_device (PkNetworkStackNm *nstack_nm, const gchar *device)
+{
+	gboolean ret;
+	GError *error = NULL;
+	DBusGProxy *proxy;
+	GValue value = { 0 };
+	NMDeviceType type = NM_DEVICE_TYPE_UNKNOWN;
+
+	/* get if the device is default */
+	proxy = dbus_g_proxy_new_for_name (nstack_nm->priv->bus, "org.freedesktop.NetworkManager",
+					   device, "org.freedesktop.DBus.Properties");
+	ret = dbus_g_proxy_call (proxy, "Get", &error,
+				 G_TYPE_STRING, "org.freedesktop.NetworkManager.Device",
+				 G_TYPE_STRING, "DeviceType",
+				 G_TYPE_INVALID,
+				 G_TYPE_VALUE, &value,
+				 G_TYPE_INVALID);
+	if (!ret) {
+		g_warning ("Error getting DeviceType: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+	type = g_value_get_uint (&value);
+	egg_debug ("type: %i", type);
+out:
+	g_object_unref (proxy);
+	return type;
+}
+
+/**
+ * pk_network_stack_nm_get_active_connection_type_for_connection:
+ **/
+static NMDeviceType
+pk_network_stack_nm_get_active_connection_type_for_connection (PkNetworkStackNm *nstack_nm, const gchar *active_connection)
+{
+	guint i;
+	gboolean ret;
+	GError *error = NULL;
+	DBusGProxy *proxy;
+	const gchar *device;
+	GValue value_default = { 0 };
+	GValue value_devices = { 0 };
+	gboolean is_default;
+	GPtrArray *devices;
+	NMDeviceType type_tmp;
+	NMDeviceType type = NM_DEVICE_TYPE_UNKNOWN;
+
+
+	/* get if the device is default */
+	proxy = dbus_g_proxy_new_for_name (nstack_nm->priv->bus, "org.freedesktop.NetworkManager",
+					   active_connection, "org.freedesktop.DBus.Properties");
+	ret = dbus_g_proxy_call (proxy, "Get", &error,
+				 G_TYPE_STRING, "org.freedesktop.NetworkManager.Connection.Active",
+				 G_TYPE_STRING, "Default",
+				 G_TYPE_INVALID,
+				 G_TYPE_VALUE, &value_default,
+				 G_TYPE_INVALID);
+	if (!ret) {
+		g_warning ("Error getting Default: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+	is_default = g_value_get_boolean (&value_default);
+	egg_debug ("is_default: %i", is_default);
+	if (!is_default) {
+		egg_debug ("not default, skipping");
+		goto out;
+	}
+
+	/* get the physical devices for the connection */
+	ret = dbus_g_proxy_call (proxy, "Get", &error,
+				 G_TYPE_STRING, "org.freedesktop.NetworkManager.Connection.Active",
+				 G_TYPE_STRING, "Devices",
+				 G_TYPE_INVALID,
+				 G_TYPE_VALUE, &value_devices,
+				 G_TYPE_INVALID);
+	if (!ret) {
+		g_warning ("Error getting Devices: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	devices = g_value_get_boxed (&value_devices);
+	egg_debug ("number of devices: %i", devices->len);
+	if (devices->len == 0)
+		goto out;
+
+	/* find the types of the active connection */
+	for (i=0; i<devices->len; i++) {
+		device = g_ptr_array_index (devices, i);
+		type_tmp = pk_network_stack_nm_get_active_connection_type_for_device (nstack_nm, device);
+		type = pk_network_stack_nm_prioritise_connection_type (type, type_tmp);
+	}
+
+out:
+	g_object_unref (proxy);
+	return type;
+}
+
+/**
+ * pk_network_stack_nm_get_active_connection_type:
+ **/
+static NMDeviceType
+pk_network_stack_nm_get_active_connection_type (PkNetworkStackNm *nstack_nm)
+{
+	guint i;
+	gboolean ret;
+	DBusGProxy *proxy;
+	GError *error = NULL;
+	GPtrArray *active_connections = NULL;
+	const gchar *active_connection;
+	GValue value = { 0 };
+	NMDeviceType type_tmp;
+	NMDeviceType type = NM_DEVICE_TYPE_UNKNOWN;
+
+	/* get proxy */
+	proxy = dbus_g_proxy_new_for_name (nstack_nm->priv->bus, "org.freedesktop.NetworkManager",
+					   "/org/freedesktop/NetworkManager",
+					   "org.freedesktop.DBus.Properties");
+	ret = dbus_g_proxy_call (proxy, "Get", &error,
+				 G_TYPE_STRING, "org.freedesktop.NetworkManager",
+				 G_TYPE_STRING, "ActiveConnections",
+				 G_TYPE_INVALID,
+				 G_TYPE_VALUE, &value,
+				 G_TYPE_INVALID);
+	if (!ret) {
+		g_warning ("Error getting ActiveConnections: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	active_connections = g_value_get_boxed (&value);
+	egg_debug ("active connections: %i", active_connections->len);
+	if (active_connections->len == 0)
+		goto out;
+
+	/* find the active connection */
+	for (i=0; i<active_connections->len; i++) {
+		active_connection = g_ptr_array_index (active_connections, i);
+		type_tmp = pk_network_stack_nm_get_active_connection_type_for_connection (nstack_nm, active_connection);
+		type = pk_network_stack_nm_prioritise_connection_type (type, type_tmp);
+	}
+
+out:
+	g_object_unref (proxy);
+	g_ptr_array_foreach (active_connections, (GFunc) g_free, NULL);
+	g_ptr_array_free (active_connections, TRUE);
+	return type;
+}
+
+/**
+ * pk_network_stack_nm_get_state:
+ **/
+static PkNetworkEnum
+pk_network_stack_nm_get_state (PkNetworkStack *nstack)
+{
+	PkNetworkEnum ret;
+	NMDeviceType type;
+
+	PkNetworkStackNm *nstack_nm = PK_NETWORK_STACK_NM (nstack);
+
+	/* get connection type */
+	type = pk_network_stack_nm_get_active_connection_type (nstack_nm);
+	switch (type) {
+	case NM_DEVICE_TYPE_UNKNOWN:
+		ret = PK_NETWORK_ENUM_OFFLINE;
+		break;
+	case NM_DEVICE_TYPE_ETHERNET:
+		ret = PK_NETWORK_ENUM_WIRED;
+		break;
+	case NM_DEVICE_TYPE_WIFI:
+		ret = PK_NETWORK_ENUM_WIFI;
+		break;
+	case NM_DEVICE_TYPE_GSM:
+	case NM_DEVICE_TYPE_CDMA:
+		ret = PK_NETWORK_ENUM_MOBILE;
+		break;
+	default:
+		ret = PK_NETWORK_ENUM_ONLINE;
+	}
+
+	egg_debug ("network state is %s", pk_network_enum_to_text (ret));
+	return ret;
+}
+
+/**
+ * pk_network_stack_nm_nm_changed_cb:
+ **/
+static void
+pk_network_stack_nm_nm_changed_cb (libnm_glib_ctx *libnm_ctx, gpointer data)
+{
+	PkNetworkEnum state;
+	PkNetworkStackNm *nstack_nm = (PkNetworkStackNm *) data;
+
+	g_return_if_fail (PK_IS_NETWORK_STACK_NM (nstack_nm));
+
+	/* do not use */
+	if (!nstack_nm->priv->is_enabled) {
+		egg_debug ("not enabled, so ignoring");
+		return;
+	}
+
+	state = pk_network_stack_nm_get_state (PK_NETWORK_STACK (nstack_nm));
+	egg_debug ("emitting network-state-changed: %s", pk_network_enum_to_text (state));
+	g_signal_emit_by_name (PK_NETWORK_STACK (nstack_nm), "state-changed", state);
+}
+
+/**
+ * pk_network_stack_nm_is_enabled:
+ *
+ * Return %TRUE on success, %FALSE if we failed to is_enabled or no data
+ **/
+static gboolean
+pk_network_stack_nm_is_enabled (PkNetworkStack *nstack)
+{
+	PkNetworkStackNm *nstack_nm = PK_NETWORK_STACK_NM (nstack);
+	return nstack_nm->priv->is_enabled;
+}
+
+/**
+ * pk_network_stack_nm_init:
+ **/
+static void
+pk_network_stack_nm_init (PkNetworkStackNm *nstack_nm)
+{
+	GError *error = NULL;
+	GMainContext *context;
+	gboolean service_alive;
+
+	nstack_nm->priv = PK_NETWORK_STACK_NM_GET_PRIVATE (nstack_nm);
+	nstack_nm->priv->conf = pk_conf_new ();
+
+	/* do we use this code? */
+	nstack_nm->priv->is_enabled = pk_conf_get_bool (nstack_nm->priv->conf, "UseNetworkManager");
+
+	/* register with callback */
+	context = g_main_context_default ();
+	nstack_nm->priv->ctx = libnm_glib_init ();
+	nstack_nm->priv->callback_id =
+		libnm_glib_register_callback (nstack_nm->priv->ctx,
+					      pk_network_stack_nm_nm_changed_cb,
+					      nstack_nm, context);
+
+	/* get system connection */
+	nstack_nm->priv->bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+	if (nstack_nm->priv->bus == NULL) {
+		egg_warning ("Couldn't connect to system bus: %s", error->message);
+		g_error_free (error);
+	}
+
+	/* check if NM is on the bus */
+	nstack_nm->priv->dbus_monitor = egg_dbus_monitor_new ();
+	egg_dbus_monitor_assign (nstack_nm->priv->dbus_monitor, EGG_DBUS_MONITOR_SYSTEM, "org.freedesktop.NetworkManager");
+	service_alive = egg_dbus_monitor_is_connected (nstack_nm->priv->dbus_monitor);
+
+	/* NetworkManager isn't up, so we can't use it */
+	if (nstack_nm->priv->is_enabled && !service_alive) {
+		egg_warning ("UseNetworkManager true, but org.freedesktop.NetworkManager not up");
+		nstack_nm->priv->is_enabled = FALSE;
+	}
+}
+
+/**
+ * pk_network_stack_nm_finalize:
+ **/
+static void
+pk_network_stack_nm_finalize (GObject *object)
+{
+	PkNetworkStackNm *nstack_nm;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (PK_IS_NETWORK_STACK_NM (object));
+
+	nstack_nm = PK_NETWORK_STACK_NM (object);
+	g_return_if_fail (nstack_nm->priv != NULL);
+
+	g_object_unref (nstack_nm->priv->conf);
+	g_object_unref (nstack_nm->priv->dbus_monitor);
+	libnm_glib_unregister_callback (nstack_nm->priv->ctx, nstack_nm->priv->callback_id);
+	libnm_glib_shutdown (nstack_nm->priv->ctx);
+
+	/* be paranoid */
+	nstack_nm->priv->ctx = NULL;
+	nstack_nm->priv->callback_id = 0;
+
+	G_OBJECT_CLASS (pk_network_stack_nm_parent_class)->finalize (object);
+}
+
+/**
+ * pk_network_stack_nm_class_init:
+ **/
+static void
+pk_network_stack_nm_class_init (PkNetworkStackNmClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	PkNetworkStackClass *nstack_class = PK_NETWORK_STACK_CLASS (klass);
+
+	object_class->finalize = pk_network_stack_nm_finalize;
+	nstack_class->get_state = pk_network_stack_nm_get_state;
+	nstack_class->is_enabled = pk_network_stack_nm_is_enabled;
+
+	g_type_class_add_private (klass, sizeof (PkNetworkStackNmPrivate));
+}
+
+/**
+ * pk_network_stack_nm_new:
+ **/
+PkNetworkStackNm *
+pk_network_stack_nm_new (void)
+{
+	return g_object_new (PK_TYPE_NETWORK_STACK_NM, NULL);
+}
+
diff --git a/src/pk-network-stack-nm.h b/src/pk-network-stack-nm.h
new file mode 100644
index 0000000..b31911c
--- /dev/null
+++ b/src/pk-network-stack-nm.h
@@ -0,0 +1,56 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2009 Richard Hughes <richard at hughsie.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifndef __PK_NETWORK_STACK_NM_H__
+#define __PK_NETWORK_STACK_NM_H__
+
+#include <glib-object.h>
+
+#include "pk-network-stack.h"
+
+G_BEGIN_DECLS
+
+#define PK_TYPE_NETWORK_STACK_NM  		(pk_network_stack_nm_get_type ())
+#define PK_NETWORK_STACK_NM(o)			(G_TYPE_CHECK_INSTANCE_CAST ((o), PK_TYPE_NETWORK_STACK_NM, PkNetworkStackNm))
+#define PK_NETWORK_STACK_NM_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST((k), PK_TYPE_NETWORK_STACK_NM, PkNetworkStackNmClass))
+#define PK_IS_NETWORK_STACK_NM(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), PK_TYPE_NETWORK_STACK_NM))
+#define PK_IS_NETWORK_STACK_NM_CLASS(k)		(G_TYPE_CHECK_CLASS_TYPE ((k), PK_TYPE_NETWORK_STACK_NM))
+#define PK_NETWORK_STACK_NM_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), PK_TYPE_NETWORK_STACK_NM, PkNetworkStackNmClass))
+
+typedef struct PkNetworkStackNmPrivate PkNetworkStackNmPrivate;
+
+typedef struct
+{
+	PkNetworkStack			 parent;
+	PkNetworkStackNmPrivate		*priv;
+} PkNetworkStackNm;
+
+typedef struct
+{
+	PkNetworkStackClass		 parent_class;
+} PkNetworkStackNmClass;
+
+GType			 pk_network_stack_nm_get_type		(void);
+PkNetworkStackNm	*pk_network_stack_nm_new		(void);
+
+G_END_DECLS
+
+#endif /* __PK_NETWORK_STACK_NM_H__ */
+
diff --git a/src/pk-network-stack-unix.c b/src/pk-network-stack-unix.c
new file mode 100644
index 0000000..3b961c3
--- /dev/null
+++ b/src/pk-network-stack-unix.c
@@ -0,0 +1,256 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2009 Richard Hughes <richard at hughsie.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "egg-debug.h"
+#include "egg-string.h"
+
+#include "pk-network-stack-unix.h"
+#include "pk-marshal.h"
+#include "pk-conf.h"
+#include "pk-file-monitor.h"
+
+struct PkNetworkStackUnixPrivate
+{
+	PkConf			*conf;
+	PkNetworkEnum		 state_old;
+	PkFileMonitor		*file_monitor;
+	gboolean		 is_enabled;
+};
+
+G_DEFINE_TYPE (PkNetworkStackUnix, pk_network_stack_unix, PK_TYPE_NETWORK_STACK)
+#define PK_NETWORK_STACK_UNIX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_NETWORK_STACK_UNIX, PkNetworkStackUnixPrivate))
+
+#define PK_NETWORK_PROC_ROUTE	"/proc/net/route"
+
+/**
+ * pk_network_stack_unix_get_state:
+ **/
+static PkNetworkEnum
+pk_network_stack_unix_get_state (PkNetworkStack *nstack)
+{
+	gchar *contents = NULL;
+	gboolean ret;
+	GError *error = NULL;
+	gchar **lines;
+	gchar **sections;
+	guint number_lines;
+	guint number_sections;
+	guint i;
+	gboolean online = FALSE;
+
+	/* hack, because netlink is teh suck */
+	ret = g_file_get_contents (PK_NETWORK_PROC_ROUTE, &contents, NULL, &error);
+	if (!ret) {
+		egg_warning ("could not open %s: %s", PK_NETWORK_PROC_ROUTE, error->message);
+		g_error_free (error);
+		/* no idea whatsoever! */
+		return PK_NETWORK_ENUM_ONLINE;
+	}
+
+	/* something insane */
+	if (contents == NULL) {
+		egg_warning ("insane contents of %s", PK_NETWORK_PROC_ROUTE);
+		return PK_NETWORK_ENUM_ONLINE;
+	}
+
+	/* one line per interface */
+	lines = g_strsplit (contents, "\n", 0);
+	if (lines == NULL) {
+		egg_warning ("unable to split %s", PK_NETWORK_PROC_ROUTE);
+		return PK_NETWORK_ENUM_ONLINE;
+	}
+
+	number_lines = g_strv_length (lines);
+	for (i=0; i<number_lines; i++) {
+		/* empty line */
+		if (egg_strzero (lines[i])) {
+			continue;
+		}
+
+		/* tab delimited */
+		sections = g_strsplit (lines[i], "\t", 0);
+		if (sections == NULL) {
+			egg_warning ("unable to split %s", PK_NETWORK_PROC_ROUTE);
+			continue;
+		}
+
+		/* is header? */
+		if (egg_strequal (sections[0], "Iface")) {
+			continue;
+		}
+
+		/* is loopback? */
+		if (egg_strequal (sections[0], "lo")) {
+			continue;
+		}
+
+		/* is correct parameters? */
+		number_sections = g_strv_length (sections);
+		if (number_sections != 11) {
+			egg_warning ("invalid line '%s' (%i)", lines[i], number_sections);
+			continue;
+		}
+
+		/* is destination zero (default route)? */
+		if (egg_strequal (sections[1], "00000000")) {
+			egg_debug ("destination %s is valid", sections[0]);
+			online = TRUE;
+		}
+
+		/* is gateway nonzero? */
+		if (!egg_strequal (sections[2], "00000000")) {
+			egg_debug ("interface %s is valid", sections[0]);
+			online = TRUE;
+		}
+		g_strfreev (sections);
+	}
+	g_strfreev (lines);
+
+	if (online) {
+		return PK_NETWORK_ENUM_ONLINE;
+	}
+
+	return PK_NETWORK_ENUM_OFFLINE;
+}
+
+/**
+ * pk_network_stack_unix_file_monitor_changed_cb:
+ **/
+static void
+pk_network_stack_unix_file_monitor_changed_cb (PkFileMonitor *file_monitor, PkNetworkStackUnix *nstack_unix)
+{
+	PkNetworkEnum state;
+
+	g_return_if_fail (PK_IS_NETWORK_STACK_UNIX (nstack_unix));
+
+	/* do not use */
+	if (!nstack_unix->priv->is_enabled) {
+		egg_debug ("not enabled, so ignoring");
+		return;
+	}
+
+	/* same state? */
+	state = pk_network_stack_unix_get_state (PK_NETWORK_STACK (nstack_unix));
+	if (state == nstack_unix->priv->state_old) {
+		egg_debug ("same state");
+		return;
+	}
+
+	/* new state */
+	nstack_unix->priv->state_old = state;
+	egg_debug ("emitting network-state-changed: %s", pk_network_enum_to_text (state));
+	g_signal_emit_by_name (PK_NETWORK_STACK (nstack_unix), "state-changed", state);
+}
+
+/**
+ * pk_network_stack_unix_is_enabled:
+ *
+ * Return %TRUE on success, %FALSE if we failed to is_enabled or no data
+ **/
+static gboolean
+pk_network_stack_unix_is_enabled (PkNetworkStack *nstack)
+{
+	PkNetworkStackUnix *nstack_unix = PK_NETWORK_STACK_UNIX (nstack);
+	return nstack_unix->priv->is_enabled;
+}
+
+/**
+ * pk_network_stack_unix_init:
+ **/
+static void
+pk_network_stack_unix_init (PkNetworkStackUnix *nstack_unix)
+{
+	nstack_unix->priv = PK_NETWORK_STACK_UNIX_GET_PRIVATE (nstack_unix);
+	nstack_unix->priv->state_old = PK_NETWORK_ENUM_UNKNOWN;
+	nstack_unix->priv->conf = pk_conf_new ();
+
+	/* do we use this code? */
+	nstack_unix->priv->is_enabled = pk_conf_get_bool (nstack_unix->priv->conf, "UseNetworkHeuristic");
+
+	/* monitor the config file for changes */
+	nstack_unix->priv->file_monitor = pk_file_monitor_new ();
+	pk_file_monitor_set_file (nstack_unix->priv->file_monitor, PK_NETWORK_PROC_ROUTE);
+	g_signal_connect (nstack_unix->priv->file_monitor, "file-changed",
+			  G_CALLBACK (pk_network_stack_unix_file_monitor_changed_cb), nstack_unix);
+}
+
+/**
+ * pk_network_stack_unix_finalize:
+ **/
+static void
+pk_network_stack_unix_finalize (GObject *object)
+{
+	PkNetworkStackUnix *nstack_unix;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (PK_IS_NETWORK_STACK_UNIX (object));
+
+	nstack_unix = PK_NETWORK_STACK_UNIX (object);
+	g_return_if_fail (nstack_unix->priv != NULL);
+
+	g_object_unref (nstack_unix->priv->conf);
+	g_object_unref (nstack_unix->priv->file_monitor);
+
+	G_OBJECT_CLASS (pk_network_stack_unix_parent_class)->finalize (object);
+}
+
+/**
+ * pk_network_stack_unix_class_init:
+ **/
+static void
+pk_network_stack_unix_class_init (PkNetworkStackUnixClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	PkNetworkStackClass *nstack_class = PK_NETWORK_STACK_CLASS (klass);
+
+	object_class->finalize = pk_network_stack_unix_finalize;
+	nstack_class->get_state = pk_network_stack_unix_get_state;
+	nstack_class->is_enabled = pk_network_stack_unix_is_enabled;
+
+	g_type_class_add_private (klass, sizeof (PkNetworkStackUnixPrivate));
+}
+
+/**
+ * pk_network_stack_unix_new:
+ **/
+PkNetworkStackUnix *
+pk_network_stack_unix_new (void)
+{
+	return g_object_new (PK_TYPE_NETWORK_STACK_UNIX, NULL);
+}
+
diff --git a/src/pk-network-stack-unix.h b/src/pk-network-stack-unix.h
new file mode 100644
index 0000000..09d2aee
--- /dev/null
+++ b/src/pk-network-stack-unix.h
@@ -0,0 +1,56 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2009 Richard Hughes <richard at hughsie.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifndef __PK_NETWORK_STACK_UNIX_H__
+#define __PK_NETWORK_STACK_UNIX_H__
+
+#include <glib-object.h>
+
+#include "pk-network-stack.h"
+
+G_BEGIN_DECLS
+
+#define PK_TYPE_NETWORK_STACK_UNIX  		(pk_network_stack_unix_get_type ())
+#define PK_NETWORK_STACK_UNIX(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), PK_TYPE_NETWORK_STACK_UNIX, PkNetworkStackUnix))
+#define PK_NETWORK_STACK_UNIX_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST((k), PK_TYPE_NETWORK_STACK_UNIX, PkNetworkStackUnixClass))
+#define PK_IS_NETWORK_STACK_UNIX(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), PK_TYPE_NETWORK_STACK_UNIX))
+#define PK_IS_NETWORK_STACK_UNIX_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), PK_TYPE_NETWORK_STACK_UNIX))
+#define PK_NETWORK_STACK_UNIX_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), PK_TYPE_NETWORK_STACK_UNIX, PkNetworkStackUnixClass))
+
+typedef struct PkNetworkStackUnixPrivate PkNetworkStackUnixPrivate;
+
+typedef struct
+{
+	PkNetworkStack			 parent;
+	PkNetworkStackUnixPrivate	*priv;
+} PkNetworkStackUnix;
+
+typedef struct
+{
+	PkNetworkStackClass		 parent_class;
+} PkNetworkStackUnixClass;
+
+GType			 pk_network_stack_unix_get_type		(void);
+PkNetworkStackUnix	*pk_network_stack_unix_new		(void);
+
+G_END_DECLS
+
+#endif /* __PK_NETWORK_STACK_UNIX_H__ */
+
diff --git a/src/pk-network-stack.c b/src/pk-network-stack.c
new file mode 100644
index 0000000..419e7bf
--- /dev/null
+++ b/src/pk-network-stack.c
@@ -0,0 +1,116 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2009 Richard Hughes <richard at hughsie.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <string.h>
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "pk-network-stack.h"
+
+enum
+{
+	STATE_CHANGED,
+	LAST_SIGNAL,
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (PkNetworkStack, pk_network_stack, G_TYPE_OBJECT)
+
+/**
+ * pk_network_stack_is_enabled:
+ **/
+gboolean
+pk_network_stack_is_enabled (PkNetworkStack *nstack)
+{
+	PkNetworkStackClass *klass = PK_NETWORK_STACK_GET_CLASS (nstack);
+
+	g_return_val_if_fail (PK_IS_NETWORK_STACK (nstack), FALSE);
+
+	/* no support */
+	if (klass->is_enabled == NULL)
+		return FALSE;
+
+	return klass->is_enabled (nstack);
+}
+
+/**
+ * pk_network_stack_get_state:
+ **/
+PkNetworkEnum
+pk_network_stack_get_state (PkNetworkStack *nstack)
+{
+	PkNetworkStackClass *klass = PK_NETWORK_STACK_GET_CLASS (nstack);
+
+	g_return_val_if_fail (PK_IS_NETWORK_STACK (nstack), PK_NETWORK_ENUM_UNKNOWN);
+
+	/* no support */
+	if (klass->get_state == NULL)
+		return PK_NETWORK_ENUM_UNKNOWN;
+
+	return klass->get_state (nstack);
+}
+
+/**
+ * pk_network_stack_init:
+ **/
+static void
+pk_network_stack_init (PkNetworkStack *nstack)
+{
+}
+
+/**
+ * pk_network_stack_finalize:
+ **/
+static void
+pk_network_stack_finalize (GObject *object)
+{
+	PkNetworkStack *nstack;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (PK_IS_NETWORK_STACK (object));
+
+	nstack = PK_NETWORK_STACK (object);
+
+	G_OBJECT_CLASS (pk_network_stack_parent_class)->finalize (object);
+}
+
+/**
+ * pk_network_stack_class_init:
+ **/
+static void
+pk_network_stack_class_init (PkNetworkStackClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	object_class->finalize = pk_network_stack_finalize;
+
+	signals[STATE_CHANGED] =
+		g_signal_new ("state-changed",
+			      G_OBJECT_CLASS_TYPE (klass),
+			      G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
+			      0, NULL, NULL,
+			      g_cclosure_marshal_VOID__UINT,
+			      G_TYPE_NONE, 1, G_TYPE_UINT);
+}
+
diff --git a/src/pk-network-stack.h b/src/pk-network-stack.h
new file mode 100644
index 0000000..fa5d161
--- /dev/null
+++ b/src/pk-network-stack.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2009 Richard Hughes <richard at hughsie.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __PK_NETWORK_STACK_H__
+#define __PK_NETWORK_STACK_H__
+
+#include <glib-object.h>
+#include <dbus/dbus-glib.h>
+#include <packagekit-glib/packagekit.h>
+
+G_BEGIN_DECLS
+
+#define PK_TYPE_NETWORK_STACK		(pk_network_stack_get_type ())
+#define PK_NETWORK_STACK(o)	   	(G_TYPE_CHECK_INSTANCE_CAST ((o), PK_TYPE_NETWORK_STACK, PkNetworkStack))
+#define PK_NETWORK_STACK_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), PK_TYPE_NETWORK_STACK, PkNetworkStackClass))
+#define PK_IS_NETWORK_STACK(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), PK_TYPE_NETWORK_STACK))
+#define PK_IS_NETWORK_STACK_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), PK_TYPE_NETWORK_STACK))
+#define PK_NETWORK_STACK_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), PK_TYPE_NETWORK_STACK, PkNetworkStackClass))
+
+typedef struct PkNetworkStackPrivate PkNetworkStackPrivate;
+
+typedef struct
+{
+	GObject			 parent;
+} PkNetworkStack;
+
+typedef struct
+{
+	GObjectClass	 parent_class;
+	/* vtable */
+	PkNetworkEnum	 (*get_state)			(PkNetworkStack	*nstack);
+	gboolean	 (*is_enabled)			(PkNetworkStack	*nstack);
+} PkNetworkStackClass;
+
+GType		 pk_network_stack_get_type		(void);
+PkNetworkEnum	 pk_network_stack_get_state		(PkNetworkStack	*nstack);
+gboolean	 pk_network_stack_is_enabled		(PkNetworkStack	*nstack);
+
+G_END_DECLS
+
+#endif /* __PK_NETWORK_STACK_H__ */
diff --git a/src/pk-network-unix.c b/src/pk-network-unix.c
deleted file mode 100644
index 1590ead..0000000
--- a/src/pk-network-unix.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2007-2008 Richard Hughes <richard at hughsie.com>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:pk-network_unix-dummy
- * @short_description: Dummy network_unix detection code
- *
- * This file contains a unix network implimentation.
- * It is designed for people that don't have NetworkUnixManager installed.
- * It polls the network to wait to see if it's up
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-#include <errno.h>
-
-#include <string.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#include <glib/gi18n.h>
-
-#include "egg-debug.h"
-#include "egg-string.h"
-
-#include "pk-network-unix.h"
-#include "pk-marshal.h"
-#include "pk-file-monitor.h"
-
-static void     pk_network_unix_finalize	(GObject        *object);
-
-#define PK_NETWORK_UNIX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_NETWORK_UNIX, PkNetworkUnixPrivate))
-
-/**
- * _PkNetworkUnixPrivate:
- *
- * Private #PkNetworkUnix data
- **/
-struct _PkNetworkUnixPrivate
-{
-	PkNetworkEnum		 state_old;
-	PkFileMonitor		*file_monitor;
-};
-
-enum {
-	PK_NETWORK_UNIX_STATE_CHANGED,
-	PK_NETWORK_UNIX_LAST_SIGNAL
-};
-
-static guint signals [PK_NETWORK_UNIX_LAST_SIGNAL] = { 0 };
-
-G_DEFINE_TYPE (PkNetworkUnix, pk_network_unix, G_TYPE_OBJECT)
-#define PK_NETWORK_PROC_ROUTE	"/proc/net/route"
-
-
-/**
- * pk_network_unix_get_network_state:
- * @network_unix: a valid #PkNetworkUnix instance
- *
- * Return value: %TRUE if the network is online
- **/
-PkNetworkEnum
-pk_network_unix_get_network_state (PkNetworkUnix *network_unix)
-{
-	gchar *contents = NULL;
-	gboolean ret;
-	GError *error = NULL;
-	gchar **lines;
-	gchar **sections;
-	guint number_lines;
-	guint number_sections;
-	guint i;
-	gboolean online = FALSE;
-
-	g_return_val_if_fail (PK_IS_NETWORK_UNIX (network_unix), PK_NETWORK_ENUM_UNKNOWN);
-
-	/* hack, because netlink is teh suck */
-	ret = g_file_get_contents (PK_NETWORK_PROC_ROUTE, &contents, NULL, &error);
-	if (!ret) {
-		egg_warning ("could not open %s: %s", PK_NETWORK_PROC_ROUTE, error->message);
-		g_error_free (error);
-		/* no idea whatsoever! */
-		return PK_NETWORK_ENUM_ONLINE;
-	}
-
-	/* something insane */
-	if (contents == NULL) {
-		egg_warning ("insane contents of %s", PK_NETWORK_PROC_ROUTE);
-		return PK_NETWORK_ENUM_ONLINE;
-	}
-
-	/* one line per interface */
-	lines = g_strsplit (contents, "\n", 0);
-	if (lines == NULL) {
-		egg_warning ("unable to split %s", PK_NETWORK_PROC_ROUTE);
-		return PK_NETWORK_ENUM_ONLINE;
-	}
-
-	number_lines = g_strv_length (lines);
-	for (i=0; i<number_lines; i++) {
-		/* empty line */
-		if (egg_strzero (lines[i])) {
-			continue;
-		}
-
-		/* tab delimited */
-		sections = g_strsplit (lines[i], "\t", 0);
-		if (sections == NULL) {
-			egg_warning ("unable to split %s", PK_NETWORK_PROC_ROUTE);
-			continue;
-		}
-
-		/* is header? */
-		if (egg_strequal (sections[0], "Iface")) {
-			continue;
-		}
-
-		/* is loopback? */
-		if (egg_strequal (sections[0], "lo")) {
-			continue;
-		}
-
-		/* is correct parameters? */
-		number_sections = g_strv_length (sections);
-		if (number_sections != 11) {
-			egg_warning ("invalid line '%s' (%i)", lines[i], number_sections);
-			continue;
-		}
-
-		/* is destination zero (default route)? */
-		if (egg_strequal (sections[1], "00000000")) {
-			egg_debug ("destination %s is valid", sections[0]);
-			online = TRUE;
-		}
-
-		/* is gateway nonzero? */
-		if (!egg_strequal (sections[2], "00000000")) {
-			egg_debug ("interface %s is valid", sections[0]);
-			online = TRUE;
-		}
-		g_strfreev (sections);
-	}
-	g_strfreev (lines);
-
-	if (online) {
-		return PK_NETWORK_ENUM_ONLINE;
-	}
-
-	return PK_NETWORK_ENUM_OFFLINE;
-}
-
-/**
- * pk_network_unix_file_monitor_changed_cb:
- **/
-static void
-pk_network_unix_file_monitor_changed_cb (PkFileMonitor *file_monitor, PkNetworkUnix *network_unix)
-{
-	PkNetworkEnum state;
-
-	g_return_if_fail (PK_IS_NETWORK_UNIX (network_unix));
-
-	/* same state? */
-	state = pk_network_unix_get_network_state (network_unix);
-	if (state == network_unix->priv->state_old) {
-		egg_debug ("same state");
-		return;
-	}
-
-	/* new state */
-	network_unix->priv->state_old = state;
-	g_signal_emit (network_unix, signals [PK_NETWORK_UNIX_STATE_CHANGED], 0, state);
-}
-
-/**
- * pk_network_unix_class_init:
- * @klass: The PkNetworkUnixClass
- **/
-static void
-pk_network_unix_class_init (PkNetworkUnixClass *klass)
-{
-	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-	object_class->finalize = pk_network_unix_finalize;
-	signals [PK_NETWORK_UNIX_STATE_CHANGED] =
-		g_signal_new ("state-changed",
-			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
-			      0, NULL, NULL, g_cclosure_marshal_VOID__UINT,
-			      G_TYPE_NONE, 1, G_TYPE_UINT);
-	g_type_class_add_private (klass, sizeof (PkNetworkUnixPrivate));
-}
-
-/**
- * pk_network_unix_init:
- * @network_unix: This class instance
- **/
-static void
-pk_network_unix_init (PkNetworkUnix *network_unix)
-{
-	network_unix->priv = PK_NETWORK_UNIX_GET_PRIVATE (network_unix);
-	network_unix->priv->state_old = PK_NETWORK_ENUM_UNKNOWN;
-
-	/* monitor the config file for changes */
-	network_unix->priv->file_monitor = pk_file_monitor_new ();
-	pk_file_monitor_set_file (network_unix->priv->file_monitor, PK_NETWORK_PROC_ROUTE);
-	g_signal_connect (network_unix->priv->file_monitor, "file-changed",
-			  G_CALLBACK (pk_network_unix_file_monitor_changed_cb), network_unix);
-}
-
-/**
- * pk_network_unix_finalize:
- * @object: The object to finalize
- **/
-static void
-pk_network_unix_finalize (GObject *object)
-{
-	PkNetworkUnix *network_unix;
-	g_return_if_fail (object != NULL);
-	g_return_if_fail (PK_IS_NETWORK_UNIX (object));
-	network_unix = PK_NETWORK_UNIX (object);
-
-	g_return_if_fail (network_unix->priv != NULL);
-
-	g_object_unref (network_unix->priv->file_monitor);
-
-	G_OBJECT_CLASS (pk_network_unix_parent_class)->finalize (object);
-}
-
-/**
- * pk_network_unix_new:
- *
- * Return value: a new PkNetworkUnix object.
- **/
-PkNetworkUnix *
-pk_network_unix_new (void)
-{
-	PkNetworkUnix *network_unix;
-	network_unix = g_object_new (PK_TYPE_NETWORK_UNIX, NULL);
-	return PK_NETWORK_UNIX (network_unix);
-}
-
diff --git a/src/pk-network-unix.h b/src/pk-network-unix.h
deleted file mode 100644
index a37dc5a..0000000
--- a/src/pk-network-unix.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2007-2008 Richard Hughes <richard at hughsie.com>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:pk-network-unix
- * @short_description: An abstract unix network access GObject
- *
- * This allows a switchable network backend.
- */
-
-#ifndef __PK_NETWORK_UNIX_H
-#define __PK_NETWORK_UNIX_H
-
-#include <glib-object.h>
-#include <packagekit-glib/packagekit.h>
-
-G_BEGIN_DECLS
-
-#define PK_TYPE_NETWORK_UNIX		(pk_network_unix_get_type ())
-#define PK_NETWORK_UNIX(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), PK_TYPE_NETWORK_UNIX, PkNetworkUnix))
-#define PK_NETWORK_UNIX_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), PK_TYPE_NETWORK_UNIX, PkNetworkUnixClass))
-#define PK_IS_NETWORK_UNIX(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), PK_TYPE_NETWORK_UNIX))
-#define PK_IS_NETWORK_UNIX_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), PK_TYPE_NETWORK_UNIX))
-#define PK_NETWORK_UNIX_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), PK_TYPE_NETWORK_UNIX, PkNetworkUnixClass))
-#define PK_NETWORK_UNIX_ERROR		(pk_network_unix_error_quark ())
-#define PK_NETWORK_UNIX_TYPE_ERROR	(pk_network_unix_error_get_type ())
-
-typedef struct _PkNetworkUnixPrivate	PkNetworkUnixPrivate;
-typedef struct _PkNetworkUnix		PkNetworkUnix;
-typedef struct _PkNetworkUnixClass	PkNetworkUnixClass;
-
-struct _PkNetworkUnix
-{
-	 GObject		 parent;
-	 PkNetworkUnixPrivate	*priv;
-};
-
-struct _PkNetworkUnixClass
-{
-	GObjectClass	parent_class;
-};
-
-GType		 pk_network_unix_get_type		  	(void);
-PkNetworkUnix	*pk_network_unix_new				(void);
-PkNetworkEnum	 pk_network_unix_get_network_state		(PkNetworkUnix	*network_unix);
-
-G_END_DECLS
-
-#endif /* __PK_NETWORK_UNIX_H */
-
diff --git a/src/pk-network.c b/src/pk-network.c
index 13c7e8a..6661a3e 100644
--- a/src/pk-network.c
+++ b/src/pk-network.c
@@ -1,6 +1,6 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  *
- * Copyright (C) 2007-2008 Richard Hughes <richard at hughsie.com>
+ * Copyright (C) 2007-2009 Richard Hughes <richard at hughsie.com>
  *
  * Licensed under the GNU General Public License Version 2
  *
@@ -19,13 +19,6 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-/**
- * SECTION:pk-network
- * @short_description: network detection code
- *
- * This file contains a network checker.
- */
-
 #include "config.h"
 
 #include <stdlib.h>
@@ -45,9 +38,10 @@
 #include "egg-debug.h"
 #include "egg-dbus-monitor.h"
 #include "pk-network.h"
-#include "pk-network-nm.h"
-#include "pk-network-connman.h"
-#include "pk-network-unix.h"
+#include "pk-network-stack.h"
+#include "pk-network-stack-unix.h"
+#include "pk-network-stack-connman.h"
+#include "pk-network-stack-nm.h"
 #include "pk-marshal.h"
 #include "pk-conf.h"
 
@@ -62,15 +56,8 @@ static void     pk_network_finalize	(GObject        *object);
  **/
 struct _PkNetworkPrivate
 {
-	gboolean		 use_nm;
-	gboolean		 use_connman;
-	gboolean		 use_unix;
-	PkNetworkNm		*net_nm;
-	PkNetworkConnman	*net_connman;
-	PkNetworkUnix		*net_unix;
 	PkConf			*conf;
-	EggDbusMonitor		*nm_bus;
-	EggDbusMonitor		*connman_bus;
+	GPtrArray		*nstacks;
 };
 
 enum {
@@ -93,57 +80,43 @@ G_DEFINE_TYPE (PkNetwork, pk_network, G_TYPE_OBJECT)
 PkNetworkEnum
 pk_network_get_network_state (PkNetwork *network)
 {
-	g_return_val_if_fail (PK_IS_NETWORK (network), PK_NETWORK_ENUM_UNKNOWN);
-	/* use the correct backend */
-	if (network->priv->use_nm)
-		return pk_network_nm_get_network_state (network->priv->net_nm);
-	if (network->priv->use_connman)
-		return pk_network_connman_get_network_state (network->priv->net_connman);
-	if (network->priv->use_unix)
-		return pk_network_unix_get_network_state (network->priv->net_unix);
-	return PK_NETWORK_ENUM_ONLINE;
-}
-
-/**
- * pk_network_nm_network_changed_cb:
- **/
-static void
-pk_network_nm_network_changed_cb (PkNetworkNm *net_nm, gboolean online, PkNetwork *network)
-{
 	PkNetworkEnum state;
+	GPtrArray *nstacks;
+	PkNetworkStack *nstack;
+	guint i;
 
-	g_return_if_fail (PK_IS_NETWORK (network));
+	g_return_val_if_fail (PK_IS_NETWORK (network), PK_NETWORK_ENUM_UNKNOWN);
 
-	state = pk_network_get_network_state (network);
-	g_signal_emit (network, signals [PK_NETWORK_STATE_CHANGED], 0, state);
+	/* try each networking stack in order of preference */
+	nstacks = network->priv->nstacks;
+	for (i=0; i<nstacks->len; i++) {
+		nstack = g_ptr_array_index (nstacks, i);
+		if (pk_network_stack_is_enabled (nstack)) {
+			state = pk_network_stack_get_state (nstack);
+			if (state != PK_NETWORK_ENUM_UNKNOWN)
+				goto out;
+		}
+	}
+
+	/* no valid data providers */
+	state = PK_NETWORK_ENUM_ONLINE;
+out:
+	return state;
 }
 
 /**
- * pk_network_connman_network_changed_cb:
+ * pk_network_stack_state_changed_cb:
  **/
 static void
-pk_network_connman_network_changed_cb (PkNetworkConnman *net_connman, gboolean online, PkNetwork *network)
+pk_network_stack_state_changed_cb (PkNetworkStack *nstack, PkNetworkEnum state, PkNetwork *network)
 {
-	PkNetworkEnum state;
-
 	g_return_if_fail (PK_IS_NETWORK (network));
 
-	state = pk_network_get_network_state (network);
+	egg_debug ("emitting network-state-changed: %s", pk_network_enum_to_text (state));
 	g_signal_emit (network, signals [PK_NETWORK_STATE_CHANGED], 0, state);
 }
 
 /**
- * pk_network_unix_network_changed_cb:
- **/
-static void
-pk_network_unix_network_changed_cb (PkNetworkUnix *net_unix, gboolean online, PkNetwork *network)
-{
-	g_return_if_fail (PK_IS_NETWORK (network));
-	if (network->priv->use_unix)
-		g_signal_emit (network, signals [PK_NETWORK_STATE_CHANGED], 0, online);
-}
-
-/**
  * pk_network_class_init:
  * @klass: The PkNetworkClass
  **/
@@ -167,63 +140,32 @@ pk_network_class_init (PkNetworkClass *klass)
 static void
 pk_network_init (PkNetwork *network)
 {
-	gboolean nm_alive;
-	gboolean connman_alive;
-
+	PkNetworkStack *nstack;
 	network->priv = PK_NETWORK_GET_PRIVATE (network);
 	network->priv->conf = pk_conf_new ();
-	network->priv->net_nm = pk_network_nm_new ();
-	g_signal_connect (network->priv->net_nm, "state-changed",
-			  G_CALLBACK (pk_network_nm_network_changed_cb), network);
-	network->priv->net_connman = pk_network_connman_new ();
-	g_signal_connect (network->priv->net_connman, "state-changed",
-			 G_CALLBACK (pk_network_connman_network_changed_cb), network);
-	network->priv->net_unix = pk_network_unix_new ();
-	g_signal_connect (network->priv->net_unix, "state-changed",
-			  G_CALLBACK (pk_network_unix_network_changed_cb), network);
-
-	/* get the defaults from the config file */
-	network->priv->use_nm = pk_conf_get_bool (network->priv->conf, "UseNetworkManager");
-	network->priv->use_connman = pk_conf_get_bool (network->priv->conf, "UseNetworkConnman");
-	network->priv->use_unix = pk_conf_get_bool (network->priv->conf, "UseNetworkHeuristic");
 
-	/* check if NM is on the bus */
-	network->priv->nm_bus = egg_dbus_monitor_new ();
-	egg_dbus_monitor_assign (network->priv->nm_bus, EGG_DBUS_MONITOR_SYSTEM, "org.freedesktop.NetworkManager");
-	nm_alive = egg_dbus_monitor_is_connected (network->priv->nm_bus);
+	/* array of PkNetworkStacks, in order of preference */
+	network->priv->nstacks = g_ptr_array_new ();
 
-	/* NetworkManager isn't up, so we can't use it */
-	if (network->priv->use_nm && !nm_alive) {
-		egg_warning ("UseNetworkManager true, but org.freedesktop.NetworkManager not up");
-		network->priv->use_nm = FALSE;
-	}
-
-#if !PK_BUILD_NETWORKMANAGER
-	/* check we can actually use the default */
-	if (network->priv->use_nm) {
-		egg_warning ("UseNetworkManager true, but not built with NM support");
-		network->priv->use_nm = FALSE;
-	}
+#if PK_BUILD_NETWORKMANAGER
+	nstack = PK_NETWORK_STACK (pk_network_stack_nm_new ());
+	g_signal_connect (nstack, "state-changed",
+			  G_CALLBACK (pk_network_stack_state_changed_cb), network);
+	g_ptr_array_add (network->priv->nstacks, nstack);
 #endif
-	/* check if ConnMan is on the bus */
-	network->priv->connman_bus = egg_dbus_monitor_new ();
-	egg_dbus_monitor_assign (network->priv->connman_bus, EGG_DBUS_MONITOR_SYSTEM, "org.moblin.connman");
-	connman_alive = egg_dbus_monitor_is_connected (network->priv->connman_bus);
-
-	/* ConnMan isn't up, so we can't use it */
-	if (network->priv->use_connman && !connman_alive) {
-		egg_warning ("UseNetworkConnman true, but org.moblin.connman not up");
-		network->priv->use_connman = FALSE;
-	}
 
-#if !PK_BUILD_CONNMAN
-	/* check we can actually use the default */
-	if (network->priv->use_connman) {
-		egg_warning ("UseNetworkConnman true, but not built with ConnMan support");
-		network->priv->use_connman = FALSE;
-	}
+#if PK_BUILD_CONNMAN
+	nstack = PK_NETWORK_STACK (pk_network_stack_connman_new ());
+	g_signal_connect (nstack, "state-changed",
+			  G_CALLBACK (pk_network_stack_state_changed_cb), network);
+	g_ptr_array_add (network->priv->nstacks, nstack);
 #endif
 
+	/* always build UNIX fallback */
+	nstack = PK_NETWORK_STACK (pk_network_stack_unix_new ());
+	g_signal_connect (nstack, "state-changed",
+			  G_CALLBACK (pk_network_stack_state_changed_cb), network);
+	g_ptr_array_add (network->priv->nstacks, nstack);
 }
 
 /**
@@ -240,11 +182,11 @@ pk_network_finalize (GObject *object)
 
 	g_return_if_fail (network->priv != NULL);
 	g_object_unref (network->priv->conf);
-	g_object_unref (network->priv->nm_bus);
-	g_object_unref (network->priv->connman_bus);
-	g_object_unref (network->priv->net_nm);
-	g_object_unref (network->priv->net_connman);
-	g_object_unref (network->priv->net_unix);
+
+	/* free all network stacks in use */
+	g_ptr_array_foreach (network->priv->nstacks, (GFunc) g_object_unref, NULL);
+	g_ptr_array_free (network->priv->nstacks, TRUE);
+
 	G_OBJECT_CLASS (pk_network_parent_class)->finalize (object);
 }
 
commit 2a0ac60bc04660166fd2e1f310f537876cf0d3c4
Author: Mounir Lamouri (volkmar) <mounir.lamouri at gmail.com>
Date:   Mon Jun 1 20:38:51 2009 +0200

    portage: update groups/filters list

diff --git a/backends/portage/pk-backend-portage.c b/backends/portage/pk-backend-portage.c
index 02ffbee..4c42412 100644
--- a/backends/portage/pk-backend-portage.c
+++ b/backends/portage/pk-backend-portage.c
@@ -54,15 +54,43 @@ backend_destroy (PkBackend *backend)
 static PkBitfield
 backend_get_groups (PkBackend *backend)
 {
-	/*
-	 * TODO: set group list
-	 */
-	egg_debug ("backend: get_groups");
-
-	return pk_bitfield_from_enums (PK_GROUP_ENUM_ACCESSIBILITY,
-		PK_GROUP_ENUM_GAMES,
-		PK_GROUP_ENUM_SYSTEM,
-		-1);
+	return pk_bitfield_from_enums (
+			PK_GROUP_ENUM_ACCESSIBILITY,
+			PK_GROUP_ENUM_ACCESSORIES,
+			PK_GROUP_ENUM_ADMIN_TOOLS,
+			PK_GROUP_ENUM_COMMUNICATION,
+			PK_GROUP_ENUM_DESKTOP_GNOME,
+			PK_GROUP_ENUM_DESKTOP_KDE,
+			PK_GROUP_ENUM_DESKTOP_OTHER,
+			PK_GROUP_ENUM_DESKTOP_XFCE,
+			//PK_GROUP_ENUM_EDUCATION,
+			PK_GROUP_ENUM_FONTS,
+			PK_GROUP_ENUM_GAMES,
+			PK_GROUP_ENUM_GRAPHICS,
+			PK_GROUP_ENUM_INTERNET,
+			PK_GROUP_ENUM_LEGACY,
+			PK_GROUP_ENUM_LOCALIZATION,
+			//PK_GROUP_ENUM_MAPS,
+			PK_GROUP_ENUM_MULTIMEDIA,
+			PK_GROUP_ENUM_NETWORK,
+			PK_GROUP_ENUM_OFFICE,
+			PK_GROUP_ENUM_OTHER,
+			PK_GROUP_ENUM_POWER_MANAGEMENT,
+			PK_GROUP_ENUM_PROGRAMMING,
+			//PK_GROUP_ENUM_PUBLISHING,
+			PK_GROUP_ENUM_REPOS,
+			PK_GROUP_ENUM_SECURITY,
+			PK_GROUP_ENUM_SERVERS,
+			PK_GROUP_ENUM_SYSTEM,
+			PK_GROUP_ENUM_VIRTUALIZATION,
+			PK_GROUP_ENUM_SCIENCE,
+			PK_GROUP_ENUM_DOCUMENTATION,
+			//PK_GROUP_ENUM_ELECTRONICS,
+			//PK_GROUP_ENUM_COLLECTIONS,
+			//PK_GROUP_ENUM_VENDOR,
+			//PK_GROUP_ENUM_NEWEST,
+			//PK_GROUP_ENUM_UNKNOWN,
+			-1);
 }
 
 /**
@@ -76,9 +104,22 @@ backend_get_filters (PkBackend *backend)
 	 */
 	egg_debug ("backend: get_filters");
 
-	return pk_bitfield_from_enums (PK_FILTER_ENUM_GUI,
-		PK_FILTER_ENUM_INSTALLED,
-		-1);
+	return pk_bitfield_from_enums (
+			//PK_FILTER_ENUM_NONE,
+			PK_FILTER_ENUM_INSTALLED,
+			//PK_FILTER_ENUM_DEVELOPMENT,
+			//PK_FILTER_ENUM_GUI,
+			//PK_FILTER_ENUM_FREE,
+			//PK_FILTER_ENUM_VISIBLE,
+			//PK_FILTER_ENUM_SUPPORTED,
+			//PK_FILTER_ENUM_BASENAME,
+			//PK_FILTER_ENUM_NEWEST,
+			//PK_FILTER_ENUM_ARCH,
+			//PK_FILTER_ENUM_SOURCE,
+			//PK_FILTER_ENUM_COLLECTIONS,
+			//PK_FILTER_ENUM_APPLICATION,
+			//PK_FILTER_ENUM_UNKNOWN
+			-1);
 }
 
 /**
commit 7bf303b104c07767a2927b3743e153f5b4c8b615
Author: sandeeps <sandeeps at fedoraproject.org>
Date:   Mon Jun 1 12:08:15 2009 +0000

    Sending translation for Marathi

diff --git a/po/mr.po b/po/mr.po
index caa9461..e8d2dd4 100644
--- a/po/mr.po
+++ b/po/mr.po
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: packagekit.master.mr\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-05-29 08:27+0000\n"
-"PO-Revision-Date: 2009-05-29 16:02+0530\n"
+"POT-Creation-Date: 2009-06-01 08:18+0000\n"
+"PO-Revision-Date: 2009-06-01 17:34+0530\n"
 "Last-Translator: Sandeep Shedmake <sandeep.shedmake at gmail.com>\n"
 "Language-Team: marathi\n"
 "MIME-Version: 1.0\n"
@@ -532,116 +532,121 @@ msgstr "शोध प्रकार आवश्यक, उ.दा. नाव"
 
 #. TRANSLATORS: the user needs to provide a search term
 #: ../client/pk-console.c:1918 ../client/pk-console.c:1926
-#: ../client/pk-console.c:1934 ../client/pk-console.c:1942
+#: ../client/pk-console.c:1941
 msgid "A search term is required"
 msgstr "शोध संज्ञा आवश्यक"
 
+#: ../client/pk-console.c:1933
+msgctxt "A search term is required"
+msgid "the user needs to provide a search term"
+msgstr "वापरकर्त्याला शोध संज्ञा पुरवण्याची आवश्यकता आहे"
+
 #. TRANSLATORS: the search type was provided, but invalid
-#: ../client/pk-console.c:1948
+#: ../client/pk-console.c:1947
 msgid "Invalid search type"
 msgstr "अवैध शोध प्रकार"
 
 #. TRANSLATORS: the user did not specify what they wanted to install
-#: ../client/pk-console.c:1954
+#: ../client/pk-console.c:1953
 msgid "A package name or filename to install is required"
 msgstr "प्रतिष्ठपन करीता संकुल नाव किंवा फाइलनाव आवश्यक आहे"
 
 #. TRANSLATORS: geeky error, 99.9999% of users won't see this
-#: ../client/pk-console.c:1962
+#: ../client/pk-console.c:1961
 msgid "A type, key_id and package_id are required"
 msgstr "प्रकार, key_id व package_id आवश्यक आहे"
 
 #. TRANSLATORS: the user did not specify what they wanted to remove
-#: ../client/pk-console.c:1970
+#: ../client/pk-console.c:1969
 msgid "A package name to remove is required"
 msgstr "काढूण टाकण्याजोगी संकुल नाव"
 
 #. TRANSLATORS: the user did not specify anything about what to download or where
-#: ../client/pk-console.c:1977
+#: ../client/pk-console.c:1976
 msgid "A destination directory and then the package names to download are required"
 msgstr "लक्ष्य डिरेक्ट्री व त्यानंतर डाऊनलोड करीता संकुल नाव आवश्यक आहे"
 
 #. TRANSLATORS: the directory does not exist, so we can't continue
-#: ../client/pk-console.c:1983
+#: ../client/pk-console.c:1982
 msgid "Directory not found"
 msgstr "डिरेक्ट्री आढळली नाही"
 
 #. TRANSLATORS: geeky error, 99.9999% of users won't see this
-#: ../client/pk-console.c:1990
+#: ../client/pk-console.c:1989
 msgid "A licence identifier (eula-id) is required"
 msgstr "परवाना ओळख (eula-id) आवश्यक आहे"
 
 #. TRANSLATORS: geeky error, 99.9999% of users won't see this
-#: ../client/pk-console.c:1999
+#: ../client/pk-console.c:1998
 msgid "A transaction identifier (tid) is required"
 msgstr "transaction identifier (tid) आवश्यक आहे"
 
 #. TRANSLATORS: The user did not specify a package name
-#: ../client/pk-console.c:2015
+#: ../client/pk-console.c:2014
 msgid "A package name to resolve is required"
 msgstr "निर्धारण करीता संकुल नाव आवश्यक आहे"
 
 #. TRANSLATORS: The user did not specify a repository (software source) name
-#: ../client/pk-console.c:2023 ../client/pk-console.c:2031
+#: ../client/pk-console.c:2022 ../client/pk-console.c:2030
 msgid "A repository name is required"
 msgstr "रेपॉजिटरी नाव आवश्यक आहे"
 
 #. TRANSLATORS: The user didn't provide any data
-#: ../client/pk-console.c:2039
+#: ../client/pk-console.c:2038
 msgid "A repo name, parameter and value are required"
 msgstr "रेपो नाव, बाब व मूल्य आवश्यक आहे"
 
 #. TRANSLATORS: The user didn't specify what action to use
-#: ../client/pk-console.c:2052
+#: ../client/pk-console.c:2051
 msgid "An action, e.g. 'update-system' is required"
 msgstr "कृती, उ.दा. 'update-system' आवश्यक आहे"
 
 #. TRANSLATORS: The user specified an invalid action
-#: ../client/pk-console.c:2058
+#: ../client/pk-console.c:2057
 msgid "A correct role is required"
 msgstr "वर्तमान भूमिका आवश्यक आहे"
 
 #. TRANSLATORS: we keep a database updated with the time that an action was last executed
-#: ../client/pk-console.c:2064
+#: ../client/pk-console.c:2063
 msgid "Failed to get the time since this action was last completed"
 msgstr "शेवटच्यावेळी पूर्ण केलेली कृतीचे वेळ प्राप्त करण्यास अपयशी"
 
 #. TRANSLATORS: The user did not provide a package name
 #. TRANSLATORS: This is when the user fails to supply the package name
-#: ../client/pk-console.c:2073 ../client/pk-console.c:2084
-#: ../client/pk-console.c:2092 ../client/pk-console.c:2108
-#: ../client/pk-console.c:2116 ../client/pk-generate-pack.c:241
+#: ../client/pk-console.c:2072 ../client/pk-console.c:2083
+#: ../client/pk-console.c:2091 ../client/pk-console.c:2107
+#: ../client/pk-console.c:2115 ../client/pk-generate-pack.c:241
 msgid "A package name is required"
 msgstr "संकुल नाव आवश्यक आहे"
 
 #. TRANSLATORS: each package "provides" certain things, e.g. mime(gstreamer-decoder-mp3), the user didn't specify it
-#: ../client/pk-console.c:2100
+#: ../client/pk-console.c:2099
 msgid "A package provide string is required"
 msgstr "संकुल द्वारे पुरविलेली अक्षरमाळा आवश्यक आहे"
 
 #. TRANSLATORS: The user didn't specify a filename to create as a list
-#: ../client/pk-console.c:2124
+#: ../client/pk-console.c:2123
 msgid "A list file name to create is required"
 msgstr "बनविण्याकरीता यादी फाइल नाव आवश्यक आहे"
 
 #. TRANSLATORS: The user didn't specify a filename to open as a list
-#: ../client/pk-console.c:2133 ../client/pk-console.c:2142
+#: ../client/pk-console.c:2132 ../client/pk-console.c:2141
 msgid "A list file to open is required"
 msgstr "उघडण्याकरीता यादी फाइल आवश्यक आहे"
 
 #. TRANSLATORS: The user tried to use an unsupported option on the command line
-#: ../client/pk-console.c:2195
+#: ../client/pk-console.c:2194
 #, c-format
 msgid "Option '%s' is not supported"
 msgstr "पर्याय '%s' समर्थीत नाही"
 
 #. TRANSLATORS: User does not have permission to do this
-#: ../client/pk-console.c:2208
+#: ../client/pk-console.c:2207
 msgid "Incorrect privileges for this operation"
 msgstr "या क्रिया करीता अयोग्य परवानगी"
 
 #. TRANSLATORS: Generic failure of what they asked to do
-#: ../client/pk-console.c:2211
+#: ../client/pk-console.c:2210
 msgid "Command failed"
 msgstr "आदेश अपयशी"
 
@@ -706,9 +711,7 @@ msgstr "संकुल व्यवस्थापक या प्रकार
 msgid ""
 "Service packs cannot be created as PackageKit was not built with libarchive "
 "support."
-msgstr ""
-"PackageKit ला libarchive समर्थन सह बिल्ट न केल्यामुळे Service पैक बनवणे शक्य नाही"
-"."
+msgstr "PackageKit ला libarchive समर्थन सह बिल्ट न केल्यामुळे Service पैक बनवणे शक्य नाही."
 
 #. TRANSLATORS: the user specified an absolute path, but didn't get the extension correct
 #: ../client/pk-generate-pack.c:291
commit 4ddc4fad20991b0f97b432380524794772896744
Merge: 5032b7f... 3416e05...
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Jun 1 10:59:43 2009 +0100

    Merge branch 'connman'

commit 5032b7fd37b5107c0c9d27a4ebd77aab7f68abaf
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Jun 1 10:58:19 2009 +0100

    trivial: post release version bump

diff --git a/RELEASE b/RELEASE
index e4707a0..a0a9f55 100644
--- a/RELEASE
+++ b/RELEASE
@@ -2,7 +2,7 @@ PackageKit Release Notes
 
 1. Write NEWS entries for PackageKit in the same format as usual.
 
-git shortlog PACKAGEKIT_0_4_7.. | grep -i -v trivial | grep -v Merge > NEWS.new
+git shortlog PACKAGEKIT_0_4_8.. | grep -i -v trivial | grep -v Merge > NEWS.new
 
 2. Add download date to docs/html/pk-download.html, save file.
 
@@ -35,9 +35,9 @@ git push
 10. Send an email to packagekit at lists.freedesktop.org
 
 =================================================
-Subject: PackageKit 0.4.8 released!
+Subject: PackageKit 0.4.9 released!
 
-Today I released PackageKit 0.4.8.
+Today I released PackageKit 0.4.9.
 
 PackageKit release notes: http://cgit.freedesktop.org/packagekit/tree/NEWS
 
diff --git a/configure.ac b/configure.ac
index 8e5642e..9203c83 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3,7 +3,7 @@ AC_PREREQ(2.52)
 
 m4_define([pk_major_version], [0])
 m4_define([pk_minor_version], [4])
-m4_define([pk_micro_version], [8])
+m4_define([pk_micro_version], [9])
 m4_define([pk_version],
           [pk_major_version.pk_minor_version.pk_micro_version])
 
commit 3416e0531f5512d8827d2b62d54016fc18eecf40
Author: Peter J Zhu <peter.j.zhu at intel.com>
Date:   Mon Jun 1 10:14:11 2009 +0100

    Add ConnMan networking stack support

diff --git a/configure.ac b/configure.ac
index 2593215..db3ae20 100644
--- a/configure.ac
+++ b/configure.ac
@@ -271,15 +271,17 @@ AM_CONDITIONAL(PK_BUILD_GIO, test x$PK_BUILD_GIO = xyes)
 AC_SUBST(GIO_CFLAGS)
 AC_SUBST(GIO_LIBS)
 
+# unix networking stack always available
+networking_apis="unix"
+
 dnl ---------------------------------------------------------------------------
 dnl - Is NetworkManager available?
 dnl ---------------------------------------------------------------------------
 PKG_CHECK_MODULES(LIBNM, libnm_glib >= $LIBNM_GLIB_REQUIRED, PK_BUILD_NETWORKMANAGER="yes", PK_BUILD_NETWORKMANAGER="no")
 if test "x$PK_BUILD_NETWORKMANAGER" = "xyes"; then
-	with_networking_stack="NetworkManager"
+	networking_apis="${networking_apis},NetworkManager"
 	AC_DEFINE(PK_BUILD_NETWORKMANAGER, 1, [define if NetworkManager is installed])
 else
-	with_networking_stack="dummy"
 	PK_BUILD_NETWORKMANAGER=no
 fi
 
@@ -288,6 +290,21 @@ AC_SUBST(LIBNM_CFLAGS)
 AC_SUBST(LIBNM_LIBS)
 
 dnl ---------------------------------------------------------------------------
+dnl - Is ConnMan available?
+dnl ---------------------------------------------------------------------------
+PKG_CHECK_MODULES(CONNMAN, connman, PK_BUILD_CONNMAN="yes", PK_BUILD_CONNMAN="no")
+if test "x$PK_BUILD_CONNMAN" = "xyes"; then
+	networking_apis="${networking_apis},ConnMan"
+	AC_DEFINE(PK_BUILD_CONNMAN, 1, [define if Connection Manager is installed])
+else
+	PK_BUILD_CONNMAN=no
+fi
+
+AM_CONDITIONAL(PK_BUILD_CONNMAN, test x$PK_BUILD_CONNMAN = xyes)
+AC_SUBST(CONNMAN_CFLAGS)
+AC_SUBST(CONNMAN_LIBS)
+
+dnl ---------------------------------------------------------------------------
 dnl - Is docbook2man available?
 dnl ---------------------------------------------------------------------------
 AC_PATH_PROG(DOCBOOK2MAN, docbook2man, no)
@@ -763,7 +780,7 @@ echo "
         Able to run locally:       ${enable_local}
         Developer warnings:        ${enable_developer}
         Security framework:        ${with_security_framework}
-        Networking stack:          ${with_networking_stack}
+        Networking stacks:         ${networking_apis}
         GIO support:               ${with_gio}
         Browser plugin:            ${build_browser_plugin}
         GStreamer plugin:          ${build_gstreamer_plugin}
diff --git a/etc/PackageKit.conf.in b/etc/PackageKit.conf.in
index 9c0fc19..6e8fe42 100644
--- a/etc/PackageKit.conf.in
+++ b/etc/PackageKit.conf.in
@@ -13,9 +13,14 @@ TransactionLogging=true
 # default=true
 UseNetworkManager=true
 
-# If NetworkManager is not available, then use the presence of a default
-# route to indicate a viable network connection.
-# If disabled, and no NM, then the network is assumed to be always online.
+# Use Connman where available. If disabled, then Connman state will be ignored.
+#
+# default=false
+UseNetworkConnman=false
+
+# If neither NetworkManager nor ConnMan is not available, then use the presence
+# of default route to indicate a viable network connection.
+# If disabled, and no NM or CM, then the network is assumed to be always online.
 #
 # default=true
 UseNetworkHeuristic=true
diff --git a/src/Makefile.am b/src/Makefile.am
index 7c78d03..5dca9c9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -15,6 +15,7 @@ INCLUDES =						\
 	$(POLKIT_CFLAGS)				\
 	$(PYTHON_CFLAGS)				\
 	$(LIBNM_CFLAGS)					\
+	$(CONNMAN_CFLAGS)				\
 	-DPACKAGE_LOCALE_DIR=\"$(localedir)\"		\
 	-DBINDIR=\"$(bindir)\"			 	\
 	-DSBINDIR=\"$(sbindir)\"		 	\
@@ -63,6 +64,7 @@ shared_SOURCES =					\
 	pk-post-trans.c					\
 	pk-post-trans.h					\
 	pk-network-nm.h					\
+	pk-network-connman.h				\
 	pk-network-unix.c				\
 	pk-network-unix.h				\
 	pk-time.h					\
@@ -102,6 +104,14 @@ shared_SOURCES +=					\
 	pk-network-nm-dummy.c
 endif
 
+if PK_BUILD_CONNMAN
+shared_SOURCES +=					\
+	pk-network-connman.c
+else
+shared_SOURCES +=					\
+	pk-network-connman-dummy.c
+endif
+
 if PK_BUILD_GIO
 shared_SOURCES +=					\
 	pk-file-monitor-gio.c				\
@@ -133,6 +143,7 @@ packagekitd_LDADD =					\
 	$(GLIB_LIBS)					\
 	$(GMODULE_LIBS)					\
 	$(LIBNM_LIBS)					\
+	$(CONNMAN_LIBS)					\
 	$(DBUS_LIBS)					\
 	$(SQLITE_LIBS)					\
 	$(PK_GLIB_LIBS)					\
@@ -207,6 +218,7 @@ pk_self_test_LDADD =					\
 	$(DBUS_LIBS)					\
 	$(SQLITE_LIBS)					\
 	$(LIBNM_LIBS)					\
+	$(CONNMAN_LIBS)					\
 	$(PK_GLIB_LIBS)					\
 	$(POLKIT_LIBS)					\
 	$(GIO_LIBS)					\
diff --git a/src/pk-marshal.list b/src/pk-marshal.list
index 8fba37b..0cb77b2 100644
--- a/src/pk-marshal.list
+++ b/src/pk-marshal.list
@@ -35,4 +35,4 @@ VOID:STRING,STRING,STRING,BOOL,STRING,UINT,STRING,UINT,STRING
 VOID:STRING,STRING,BOOL,STRING,UINT,STRING,UINT,STRING
 VOID:POINTER,UINT,STRING
 VOID:POINTER,UINT,UINT
-
+VOID:STRING,BOXED
diff --git a/src/pk-network-connman-dummy.c b/src/pk-network-connman-dummy.c
new file mode 100644
index 0000000..0d132ea
--- /dev/null
+++ b/src/pk-network-connman-dummy.c
@@ -0,0 +1,137 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2009  Intel Corporation. All rights reserved.
+ *
+ * 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 "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <sys/wait.h>
+#include <fcntl.h>
+
+#include <glib/gi18n.h>
+
+#include "egg-debug.h"
+#include "pk-network-connman.h"
+#include "pk-marshal.h"
+
+static void	pk_network_connman_finalize		(GObject	*object);
+
+#define PK_NETWORK_CONNMAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_NETWORK_CONNMAN, PkNetworkConnmanPrivate))
+
+/**
+ * PkNetworkConnmanPrivate:
+ *
+ * Private #PkNetworkConnman data
+ **/
+struct _PkNetworkConnmanPrivate
+{
+	gpointer		 dummy;
+};
+
+enum {
+	PK_NETWORK_CONNMAN_STATE_CHANGED,
+	PK_NETWORK_CONNMAN_LAST_SIGNAL
+};
+
+static guint signals [PK_NETWORK_CONNMAN_LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (PkNetworkConnman, pk_network_connman, G_TYPE_OBJECT)
+
+/**
+ * pk_network_connman_get_network_state:
+ * @network_connman: a valid #PkNetworkConnman instance
+ *
+ * Return value: always %TRUE - this method should never be called
+ **/
+PkNetworkEnum
+pk_network_connman_get_network_state (PkNetworkConnman *network_connman)
+{
+	g_return_val_if_fail (PK_IS_NETWORK_CONNMAN (network_connman), PK_NETWORK_ENUM_UNKNOWN);
+	/* don't do any checks */
+	return PK_NETWORK_ENUM_ONLINE;
+}
+
+/**
+ * pk_network_connman_class_init:
+ * @klass: The PkNetworkConnmanClass
+ **/
+static void
+pk_network_connman_class_init (PkNetworkConnmanClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	object_class->finalize = pk_network_connman_finalize;
+	signals [PK_NETWORK_CONNMAN_STATE_CHANGED] =
+		g_signal_new ("state-changed",
+			     G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+			     0, NULL, NULL, g_cclosure_marshal_VOID__UINT,
+			     G_TYPE_NONE, 1, G_TYPE_UINT);
+	g_type_class_add_private (klass, sizeof (PkNetworkConnmanPrivate));
+}
+
+/**
+ * pk_network_connman_init:
+ * @network_connman: This class instance
+ **/
+static void
+pk_network_connman_init (PkNetworkConnman *network_connman)
+{
+	network_connman->priv = PK_NETWORK_CONNMAN_GET_PRIVATE (network_connman);
+}
+
+/**
+ * pk_network_connman_finalize:
+ * @object: The object to finalize
+ **/
+static void
+pk_network_connman_finalize (GObject *object)
+{
+	PkNetworkConnman *network_connman;
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (PK_IS_NETWORK_CONNMAN (object));
+	network_connman = PK_NETWORK_CONNMAN (object);
+
+	g_return_if_fail (network_connman->priv != NULL);
+	G_OBJECT_CLASS (pk_network_connman_parent_class)->finalize (object);
+}
+
+/**
+ * pk_network_connman_new:
+ *
+ * Return value: a new PkNetworkConnman object.
+ **/
+PkNetworkConnman *
+pk_network_connman_new (void)
+{
+	PkNetworkConnman *network_connman;
+	network_connman = g_object_new (PK_TYPE_NETWORK_CONNMAN, NULL);
+	return PK_NETWORK_CONNMAN (network_connman);
+}
+
diff --git a/src/pk-network-connman.c b/src/pk-network-connman.c
new file mode 100644
index 0000000..aa7583e
--- /dev/null
+++ b/src/pk-network-connman.c
@@ -0,0 +1,310 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2009  Intel Corporation. All rights reserved.
+ *
+ * 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 "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <sys/wait.h>
+#include <fcntl.h>
+
+#include <glib/gi18n.h>
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+
+#include "egg-debug.h"
+#include "pk-network-connman.h"
+#include "pk-marshal.h"
+
+static void	pk_network_connman_finalize		(GObject	*object);
+
+#define PK_NETWORK_CONNMAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_NETWORK_CONNMAN, PkNetworkConnmanPrivate))
+
+/**
+ * PkNetworkConnmanPrivate:
+ *
+ * Private #PkNetworkConnman data
+ **/
+struct _PkNetworkConnmanPrivate
+{
+	DBusGConnection		*bus;
+	DBusGProxy		*proxy_connman;
+};
+
+enum {
+	PK_NETWORK_CONNMAN_STATE_CHANGED,
+	PK_NETWORK_CONNMAN_LAST_SIGNAL
+};
+
+static guint signals [PK_NETWORK_CONNMAN_LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (PkNetworkConnman, pk_network_connman, G_TYPE_OBJECT)
+
+#define CONNMAN_DBUS_NAME "org.moblin.connman"
+
+#define CONNMAN_MANAGER_DBUS_INTERFACE CONNMAN_DBUS_NAME ".Manager"
+#define CONNMAN_SERVICE_DBUS_INTERFACE CONNMAN_DBUS_NAME ".Service"
+#define CONNMAN_MANAGER_DBUS_PATH "/"
+
+static void
+iterate_list(const GValue *value, gpointer user_data)
+{
+	GSList **list = user_data;
+	gchar *path = g_value_dup_boxed(value);
+
+	if (path == NULL)
+		return;
+
+	*list = g_slist_append(*list, path);
+}
+
+/**
+ * pk_network_nm_get_active_connection_type_for_device:
+ **/
+static PkNetworkEnum
+pk_network_connman_get_connection_type (const GValue *value)
+{
+	const char *type = value ? g_value_get_string(value) : NULL;
+
+	if (type == NULL)
+		return PK_NETWORK_ENUM_UNKNOWN;
+	else if (g_str_equal (type, "ethernet") == TRUE)
+		return PK_NETWORK_ENUM_WIRED;
+	else if (g_str_equal (type, "wifi") == TRUE)
+		return PK_NETWORK_ENUM_WIFI;
+	else if (g_str_equal (type, "wimax") == TRUE)
+		return PK_NETWORK_ENUM_MOBILE;
+
+	return PK_NETWORK_ENUM_UNKNOWN;
+}
+
+/**
+ * pk_network_connman_get_network_state:
+ * @network_connman: a valid #PkNetworkConnman instance
+ *
+ * Return value: %TRUE if the network_connman is online
+ **/
+PkNetworkEnum
+pk_network_connman_get_network_state (PkNetworkConnman *network_connman)
+{
+	DBusGProxy *proxy, *proxy_service;
+	GError *error = NULL;
+	GHashTable *hash_manager = NULL, *hash_service = NULL;
+	GValue *value;
+	GSList *list, *services_list = NULL;
+	DBusGConnection *connection = network_connman->priv->bus;
+	gchar *state;
+	PkNetworkEnum type;
+
+	g_return_val_if_fail (PK_IS_NETWORK_CONNMAN (network_connman), PK_NETWORK_ENUM_UNKNOWN);
+	proxy = network_connman->priv->proxy_connman;
+	proxy_service = NULL;
+
+	/* get services */
+	dbus_g_proxy_call (proxy, "GetProperties", &error, G_TYPE_INVALID,
+		dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &hash_manager, G_TYPE_INVALID);
+
+	if (error != NULL || hash_manager == NULL) {
+		if (error)
+			g_clear_error (&error);
+		return PK_NETWORK_ENUM_UNKNOWN;
+	}
+
+	value = g_hash_table_lookup (hash_manager, "State");
+	state = value ? g_value_dup_string(value) : NULL;
+
+	if (g_str_equal (state, "online") == FALSE)
+		return PK_NETWORK_ENUM_OFFLINE;
+
+	value = g_hash_table_lookup (hash_manager, "Services");
+	if (value == NULL)
+		return PK_NETWORK_ENUM_UNKNOWN;
+
+	dbus_g_type_collection_value_iterate (value, iterate_list, &services_list);
+
+	for (list = services_list; list; list = list->next) {
+		gchar *path = list->data;
+
+		egg_debug ("service path is %s", path);
+
+		proxy_service = dbus_g_proxy_new_for_name (connection,
+							   CONNMAN_DBUS_NAME,
+							   path,
+							   CONNMAN_SERVICE_DBUS_INTERFACE);
+		if (proxy_service != NULL)
+			break;
+	}
+
+	for (list = services_list; list; list = list->next) {
+		gchar *path = list->data;
+		g_free (path);
+	}
+	g_slist_free (services_list);
+
+	if (proxy_service == NULL)
+		return PK_NETWORK_ENUM_UNKNOWN;
+
+	/* now proxy_service point to first available service*/
+	/* get connection type for it*/
+	dbus_g_proxy_call (proxy_service, "GetProperties", &error, G_TYPE_INVALID,
+		dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &hash_service, G_TYPE_INVALID);
+
+	if (error != NULL || hash_service == NULL) {
+		if (error)
+			g_clear_error (&error);
+		return PK_NETWORK_ENUM_OFFLINE;
+	}
+
+	value = g_hash_table_lookup (hash_service, "Type");
+	type = pk_network_connman_get_connection_type (value);
+
+	egg_debug ("network type is %s", pk_network_enum_to_text (type));
+	g_object_unref (proxy_service);
+	return type;
+}
+
+/**
+ * pk_network_connman_state_changed
+ **/
+static void
+pk_network_connman_state_changed (DBusGProxy *proxy, const char *property,
+					GValue *value, gpointer user_data)
+{
+	gboolean ret;
+	PkNetworkConnman *network_connman = (PkNetworkConnman *) user_data;
+
+	g_return_if_fail (PK_IS_NETWORK_CONNMAN (network_connman));
+
+	if (g_str_equal (property, "State") == TRUE) {
+		gchar *state;
+
+		state = g_value_dup_string (value);
+		if (g_str_equal (state, "online") == TRUE)
+			ret = TRUE;
+		else
+			ret = FALSE;
+		g_signal_emit (network_connman, signals [PK_NETWORK_CONNMAN_STATE_CHANGED], 0, ret);
+	}
+
+}
+
+/**
+ * pk_network_connman_class_init:
+ * @klass: The PkNetworkConnmanClass
+ **/
+static void
+pk_network_connman_class_init (PkNetworkConnmanClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	object_class->finalize = pk_network_connman_finalize;
+	signals [PK_NETWORK_CONNMAN_STATE_CHANGED] =
+		g_signal_new ("state-changed",
+			     G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+			     0, NULL, NULL, g_cclosure_marshal_VOID__UINT,
+			     G_TYPE_NONE, 1, G_TYPE_UINT);
+	g_type_class_add_private (klass, sizeof (PkNetworkConnmanPrivate));
+}
+
+/**
+ * pk_network_connman_init:
+ * @network_connman: This class instance
+ **/
+static void
+pk_network_connman_init (PkNetworkConnman *network_connman)
+{
+	GError *error = NULL;
+	DBusGProxy *proxy;
+
+	network_connman->priv = PK_NETWORK_CONNMAN_GET_PRIVATE (network_connman);
+
+	network_connman->priv->proxy_connman = NULL;
+
+	dbus_g_object_register_marshaller(pk_marshal_VOID__STRING_BOXED,
+					  G_TYPE_NONE, G_TYPE_STRING,
+					  G_TYPE_VALUE, G_TYPE_INVALID);
+
+	/* get system connection */
+	network_connman->priv->bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+	if (network_connman->priv->bus == NULL) {
+		egg_warning ("Couldn't connect to system bus: %s", error->message);
+		g_error_free (error);
+		return;
+	}
+
+	proxy = dbus_g_proxy_new_for_name_owner (network_connman->priv->bus,
+			CONNMAN_DBUS_NAME, CONNMAN_MANAGER_DBUS_PATH, CONNMAN_MANAGER_DBUS_INTERFACE, &error);
+	network_connman->priv->proxy_connman = proxy;
+
+	if (error != NULL) {
+		egg_warning ("Cannot connect to connman: %s", error->message);
+		g_error_free (error);
+		return;
+	}
+	dbus_g_proxy_add_signal (proxy, "PropertyChanged",
+				 G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID);
+	dbus_g_proxy_connect_signal (proxy, "PropertyChanged",
+				     G_CALLBACK(pk_network_connman_state_changed), network_connman, NULL);
+
+}
+
+/**
+ * pk_network_connman_finalize:
+ * @object: The object to finalize
+ **/
+static void
+pk_network_connman_finalize (GObject *object)
+{
+	PkNetworkConnman *network_connman;
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (PK_IS_NETWORK_CONNMAN (object));
+	network_connman = PK_NETWORK_CONNMAN (object);
+
+	g_return_if_fail (network_connman->priv != NULL);
+
+	if (network_connman->priv->proxy_connman != NULL)
+		g_object_unref (network_connman->priv->proxy_connman);
+
+	G_OBJECT_CLASS (pk_network_connman_parent_class)->finalize (object);
+}
+
+/**
+ * pk_network_connman_new:
+ *
+ * Return value: a new PkNetworkConnman object.
+ **/
+PkNetworkConnman *
+pk_network_connman_new (void)
+{
+	PkNetworkConnman *network_connman;
+	network_connman = g_object_new (PK_TYPE_NETWORK_CONNMAN, NULL);
+	return PK_NETWORK_CONNMAN (network_connman);
+}
+
diff --git a/src/pk-network-connman.h b/src/pk-network-connman.h
new file mode 100644
index 0000000..da5f55b
--- /dev/null
+++ b/src/pk-network-connman.h
@@ -0,0 +1,68 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2009  Intel Corporation. All rights reserved.
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:pk-network-connman
+ * @short_description: An ConnmMan access GObject
+ *
+ * This allows a switchable network backend.
+ */
+
+#ifndef __PK_NETWORK_CONNMAN_H
+#define __PK_NETWORK_CONNMAN_H
+
+#include <glib-object.h>
+#include <packagekit-glib/packagekit.h>
+
+G_BEGIN_DECLS
+
+#define PK_TYPE_NETWORK_CONNMAN		(pk_network_connman_get_type ())
+#define PK_NETWORK_CONNMAN(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), PK_TYPE_NETWORK_CONNMAN, PkNetworkConnman))
+#define PK_NETWORK_CONNMAN_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), PK_TYPE_NETWORK_CONNMAN, PkNetworkConnmanClass))
+#define PK_IS_NETWORK_CONNMAN(o)	(G_TYPE_CHECK_INSTANCE_TYPE ((o), PK_TYPE_NETWORK_CONNMAN))
+#define PK_IS_NETWORK_CONNMAN_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), PK_TYPE_NETWORK_CONNMAN))
+#define PK_NETWORK_CONNMAN_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), PK_TYPE_NETWORK_CONNMAN, PkNetworkConnmanClass))
+#define PK_NETWORK_CONNMAN_ERROR	(pk_network_connman_error_quark ())
+#define PK_NETWORK_CONNMAN_TYPE_ERROR	(pk_network_connman_error_get_type ())
+
+typedef struct _PkNetworkConnmanPrivate	PkNetworkConnmanPrivate;
+typedef struct _PkNetworkConnman	PkNetworkConnman;
+typedef struct _PkNetworkConnmanClass  PkNetworkConnmanClass;
+
+struct _PkNetworkConnman
+{
+	GObject			 parent;
+	PkNetworkConnmanPrivate	*priv;
+};
+
+struct _PkNetworkConnmanClass
+{
+	GObjectClass		 parent_class;
+};
+
+GType			 pk_network_connman_get_type		(void);
+PkNetworkConnman	*pk_network_connman_new			(void);
+PkNetworkEnum		 pk_network_connman_get_network_state	(PkNetworkConnman	*network_connman);
+
+G_END_DECLS
+
+#endif /* __PK_NETWORK_CONNMAN_H */
+
diff --git a/src/pk-network.c b/src/pk-network.c
index fc1771f..13c7e8a 100644
--- a/src/pk-network.c
+++ b/src/pk-network.c
@@ -46,6 +46,7 @@
 #include "egg-dbus-monitor.h"
 #include "pk-network.h"
 #include "pk-network-nm.h"
+#include "pk-network-connman.h"
 #include "pk-network-unix.h"
 #include "pk-marshal.h"
 #include "pk-conf.h"
@@ -62,11 +63,14 @@ static void     pk_network_finalize	(GObject        *object);
 struct _PkNetworkPrivate
 {
 	gboolean		 use_nm;
+	gboolean		 use_connman;
 	gboolean		 use_unix;
 	PkNetworkNm		*net_nm;
+	PkNetworkConnman	*net_connman;
 	PkNetworkUnix		*net_unix;
 	PkConf			*conf;
 	EggDbusMonitor		*nm_bus;
+	EggDbusMonitor		*connman_bus;
 };
 
 enum {
@@ -93,6 +97,8 @@ pk_network_get_network_state (PkNetwork *network)
 	/* use the correct backend */
 	if (network->priv->use_nm)
 		return pk_network_nm_get_network_state (network->priv->net_nm);
+	if (network->priv->use_connman)
+		return pk_network_connman_get_network_state (network->priv->net_connman);
 	if (network->priv->use_unix)
 		return pk_network_unix_get_network_state (network->priv->net_unix);
 	return PK_NETWORK_ENUM_ONLINE;
@@ -113,6 +119,20 @@ pk_network_nm_network_changed_cb (PkNetworkNm *net_nm, gboolean online, PkNetwor
 }
 
 /**
+ * pk_network_connman_network_changed_cb:
+ **/
+static void
+pk_network_connman_network_changed_cb (PkNetworkConnman *net_connman, gboolean online, PkNetwork *network)
+{
+	PkNetworkEnum state;
+
+	g_return_if_fail (PK_IS_NETWORK (network));
+
+	state = pk_network_get_network_state (network);
+	g_signal_emit (network, signals [PK_NETWORK_STATE_CHANGED], 0, state);
+}
+
+/**
  * pk_network_unix_network_changed_cb:
  **/
 static void
@@ -148,17 +168,23 @@ static void
 pk_network_init (PkNetwork *network)
 {
 	gboolean nm_alive;
+	gboolean connman_alive;
+
 	network->priv = PK_NETWORK_GET_PRIVATE (network);
 	network->priv->conf = pk_conf_new ();
 	network->priv->net_nm = pk_network_nm_new ();
 	g_signal_connect (network->priv->net_nm, "state-changed",
 			  G_CALLBACK (pk_network_nm_network_changed_cb), network);
+	network->priv->net_connman = pk_network_connman_new ();
+	g_signal_connect (network->priv->net_connman, "state-changed",
+			 G_CALLBACK (pk_network_connman_network_changed_cb), network);
 	network->priv->net_unix = pk_network_unix_new ();
 	g_signal_connect (network->priv->net_unix, "state-changed",
 			  G_CALLBACK (pk_network_unix_network_changed_cb), network);
 
 	/* get the defaults from the config file */
 	network->priv->use_nm = pk_conf_get_bool (network->priv->conf, "UseNetworkManager");
+	network->priv->use_connman = pk_conf_get_bool (network->priv->conf, "UseNetworkConnman");
 	network->priv->use_unix = pk_conf_get_bool (network->priv->conf, "UseNetworkHeuristic");
 
 	/* check if NM is on the bus */
@@ -179,6 +205,25 @@ pk_network_init (PkNetwork *network)
 		network->priv->use_nm = FALSE;
 	}
 #endif
+	/* check if ConnMan is on the bus */
+	network->priv->connman_bus = egg_dbus_monitor_new ();
+	egg_dbus_monitor_assign (network->priv->connman_bus, EGG_DBUS_MONITOR_SYSTEM, "org.moblin.connman");
+	connman_alive = egg_dbus_monitor_is_connected (network->priv->connman_bus);
+
+	/* ConnMan isn't up, so we can't use it */
+	if (network->priv->use_connman && !connman_alive) {
+		egg_warning ("UseNetworkConnman true, but org.moblin.connman not up");
+		network->priv->use_connman = FALSE;
+	}
+
+#if !PK_BUILD_CONNMAN
+	/* check we can actually use the default */
+	if (network->priv->use_connman) {
+		egg_warning ("UseNetworkConnman true, but not built with ConnMan support");
+		network->priv->use_connman = FALSE;
+	}
+#endif
+
 }
 
 /**
@@ -196,7 +241,9 @@ pk_network_finalize (GObject *object)
 	g_return_if_fail (network->priv != NULL);
 	g_object_unref (network->priv->conf);
 	g_object_unref (network->priv->nm_bus);
+	g_object_unref (network->priv->connman_bus);
 	g_object_unref (network->priv->net_nm);
+	g_object_unref (network->priv->net_connman);
 	g_object_unref (network->priv->net_unix);
 	G_OBJECT_CLASS (pk_network_parent_class)->finalize (object);
 }


More information about the PackageKit-commit mailing list