Hi,

Enclosed are two patches.

One is the updated (and hopefully final) version of the udisks/upower
implementation for e_dbus.  All of the issues that you had mentioned
previously have been fixed, with one exception: dbus type
detection in two functions must remain a string, as there are only dbus
types for outer container return types and not for the entire return; I
have explicitly documented these types in the code for easier reading.
I have also made some changes to the udev test app which I hope will
make the usage a little more clear.  Overall, it should be much easier
to use and maintain than the e_hal module.

The second patch contains fixes for the e_hal module which fixes
some broken return types, adds stringshares to avoid dbus
stealing pointers, and removes some unnecessary strdups. This
essentially causes it to mirror e_udev, though the file layout is still
unnecessarily complex; I may alter it to a similar structure as e_udev
in the future.

-Mike (zmike/discomfitor)
Index: src/lib/hal/e_hal_manager.c
===================================================================
--- src/lib/hal/e_hal_manager.c	(revision 48026)
+++ src/lib/hal/e_hal_manager.c	(working copy)
@@ -44,9 +44,11 @@
 free_string_list(void *data)
 {
   E_Hal_String_List_Return *ret = data;
+  const char *x;
 
   if (!ret) return;
-  eina_list_free(ret->strings);
+  EINA_LIST_FREE(ret->strings, x)
+    eina_stringshare_del(x);
   free(ret);
 }
 
Index: src/lib/hal/e_hal_util.c
===================================================================
--- src/lib/hal/e_hal_util.c	(revision 48026)
+++ src/lib/hal/e_hal_util.c	(working copy)
@@ -21,20 +21,20 @@
  * @param key the key of the property to retrieve
  * @param err a pointer to an int, which if supplied, will be set to 0 on success and 1 on an error
  */
-EAPI char *
+EAPI const char *
 e_hal_property_string_get(E_Hal_Properties *properties, const char *key, int *err)
 {
   E_Hal_Property *prop;
   if (err) *err = 0;
   if (!properties->properties) return NULL;
   prop = eina_hash_find(properties->properties, key);
-  if (prop) return strdup(prop->val.s);
+  if (prop) return prop->val.s;
 
   if (err) *err = 1;
   return NULL;
 }
 
-EAPI char
+EAPI Eina_Bool
 e_hal_property_bool_get(E_Hal_Properties *properties, const char *key, int *err)
 {
   E_Hal_Property *prop;
@@ -86,7 +86,7 @@
   return 0;
 }
 
-EAPI Eina_List *
+EAPI const Eina_List *
 e_hal_property_strlist_get(E_Hal_Properties *properties, const char *key, int *err)
 {
   E_Hal_Property *prop;
Index: src/lib/hal/e_hal_device.c
===================================================================
--- src/lib/hal/e_hal_device.c	(revision 48026)
+++ src/lib/hal/e_hal_device.c	(working copy)
@@ -17,6 +17,7 @@
   E_Hal_Device_Get_Property_Return *ret = NULL;
   DBusMessageIter iter;
   int type;
+  char *tmp;
 
   ret = calloc(1, sizeof(E_Hal_Device_Get_Property_Return));
   if (!ret) 
@@ -29,16 +30,17 @@
   type = dbus_message_iter_get_arg_type(&iter);
   switch(type)
   {
-    case 's':
-      dbus_message_iter_get_basic(&iter, &(ret->val.s));
+    case DBUS_TYPE_STRING:
+      dbus_message_iter_get_basic(&iter, &tmp);
+      ret->val.s = (char*)eina_stringshare_add(tmp);
       break;
-    case 'i':
+    case DBUS_TYPE_INT32:
       dbus_message_iter_get_basic(&iter, &(ret->val.i));
       break;
-    case 'b':
+    case DBUS_TYPE_BOOLEAN:
       dbus_message_iter_get_basic(&iter, &(ret->val.b));
       break;
-    case 'd':
+    case DBUS_TYPE_DOUBLE:
       dbus_message_iter_get_basic(&iter, &(ret->val.d));
       break;
   }
@@ -52,6 +54,14 @@
   E_Hal_Device_Get_Property_Return *ret = data;
 
   if (!ret) return;
+  if (ret->type == E_HAL_PROPERTY_TYPE_STRLIST)
+    {
+       const char *s;
+       EINA_LIST_FREE(ret->val.strlist, s)
+         eina_stringshare_del(s);
+    }
+  else if (ret->type == E_HAL_PROPERTY_TYPE_STRING)
+    eina_stringshare_del(ret->val.s);
   free(ret);
 }
 
@@ -75,7 +85,9 @@
 {
   E_Hal_Device_Get_All_Properties_Return *ret = NULL;
   DBusMessageIter iter, a_iter, s_iter, v_iter;
+  char *tmp;
 
+  /* a{sv} = array of string+variant */
   if (!dbus_message_has_signature(msg, "a{sv}")) 
   {
     dbus_set_error(err, DBUS_ERROR_INVALID_SIGNATURE, "");
@@ -104,27 +116,28 @@
     
     switch(dbus_message_iter_get_arg_type(&v_iter))
     {
-      case 's':
+      case DBUS_TYPE_STRING:
         prop->type = E_HAL_PROPERTY_TYPE_STRING;
-        dbus_message_iter_get_basic(&v_iter, &(prop->val.s));
+        dbus_message_iter_get_basic(&v_iter, &tmp);
+        prop->val.s = (char*)eina_stringshare_add(tmp);
         break;
-      case 'i':
+      case DBUS_TYPE_INT32:
         prop->type = E_HAL_PROPERTY_TYPE_INT;
         dbus_message_iter_get_basic(&v_iter, &(prop->val.i));
         break;
-      case 't':
+      case DBUS_TYPE_UINT64:
         prop->type = E_HAL_PROPERTY_TYPE_UINT64;
         dbus_message_iter_get_basic(&v_iter, &(prop->val.u64));
         break;
-      case 'b':
+      case DBUS_TYPE_BOOLEAN:
         prop->type = E_HAL_PROPERTY_TYPE_BOOL;
         dbus_message_iter_get_basic(&v_iter, &(prop->val.b));
         break;
-      case 'd':
+      case DBUS_TYPE_DOUBLE:
         prop->type = E_HAL_PROPERTY_TYPE_DOUBLE;
         dbus_message_iter_get_basic(&v_iter, &(prop->val.d));
         break;
-      case 'a':
+      case DBUS_TYPE_ARRAY:
         prop->type = E_HAL_PROPERTY_TYPE_STRLIST;
         {
           DBusMessageIter list_iter;
@@ -134,7 +147,8 @@
           {
             char *str;
             dbus_message_iter_get_basic(&list_iter, &str);
-            prop->val.strlist = eina_list_append(prop->val.strlist, str);
+            tmp = (char*)eina_stringshare_add(str);
+            prop->val.strlist = eina_list_append(prop->val.strlist, tmp);
             dbus_message_iter_next(&list_iter);
           }
         }
@@ -253,7 +267,7 @@
   dbus_message_iter_init_append(msg, &iter);
   dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &mount_point);
   dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &fstype);
-  dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &subiter);
+  dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &subiter);
 
   if (options)
   {
@@ -293,7 +307,7 @@
   msg = e_hal_device_volume_call_new(udi, "Unmount");
 
   dbus_message_iter_init_append(msg, &iter);
-  dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &subiter);
+  dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &subiter);
   if (options)
   {
     const char *opt;
@@ -330,7 +344,7 @@
   msg = e_hal_device_volume_call_new(udi, "Eject");
 
   dbus_message_iter_init_append(msg, &iter);
-  dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &subiter);
+  dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &subiter);
   if (options)
   {
     const char *opt;
Index: src/lib/hal/E_Hal.h
===================================================================
--- src/lib/hal/E_Hal.h	(revision 48026)
+++ src/lib/hal/E_Hal.h	(working copy)
@@ -42,7 +42,7 @@
 
 struct E_Hal_Bool_Return
 {
-  char boolean;
+  Eina_Bool boolean;
 };
 
 struct E_Hal_UDI_Return
@@ -118,13 +118,13 @@
    EAPI DBusPendingCall *e_hal_manager_find_device_by_capability(E_DBus_Connection *conn, const char *capability, E_DBus_Callback_Func cb_func, void *data);
 
 /* utility functions */
-   EAPI void           e_hal_property_free(E_Hal_Property *prop);
-   EAPI char          *e_hal_property_string_get(E_Hal_Properties *properties, const char *key, int *err);
-   EAPI char           e_hal_property_bool_get(E_Hal_Properties *properties, const char *key, int *err);
-   EAPI int            e_hal_property_int_get(E_Hal_Properties *properties, const char *key, int *err);
-   EAPI dbus_uint64_t  e_hal_property_uint64_get(E_Hal_Properties *properties, const char *key, int *err);
-   EAPI double         e_hal_property_double_get(E_Hal_Properties *properties, const char *key, int *err);
-   EAPI Eina_List     *e_hal_property_strlist_get(E_Hal_Properties *properties, const char *key, int *err);
+   EAPI void                e_hal_property_free(E_Hal_Property *prop);
+   EAPI const char          *e_hal_property_string_get(E_Hal_Properties *properties, const char *key, int *err);
+   EAPI Eina_Bool           e_hal_property_bool_get(E_Hal_Properties *properties, const char *key, int *err);
+   EAPI int                 e_hal_property_int_get(E_Hal_Properties *properties, const char *key, int *err);
+   EAPI dbus_uint64_t       e_hal_property_uint64_get(E_Hal_Properties *properties, const char *key, int *err);
+   EAPI double              e_hal_property_double_get(E_Hal_Properties *properties, const char *key, int *err);
+   EAPI const Eina_List     *e_hal_property_strlist_get(E_Hal_Properties *properties, const char *key, int *err);
 
 /* (un)mount */
    EAPI DBusPendingCall *e_hal_device_volume_mount(E_DBus_Connection *conn, const char *udi, const char *mount_point, const char *fstype, Eina_List *options, E_DBus_Callback_Func cb_func, void *data);
Index: AUTHORS
===================================================================
--- AUTHORS	(revision 47995)
+++ AUTHORS	(working copy)
@@ -1,2 +1,3 @@
 Brian Mattern <[email protected]>
 Mathieu Taillefumier <[email protected]>
+Mike Blumenkrantz (zmike) [email protected]
Index: src/lib/udev/e_udev_util.c
===================================================================
--- src/lib/udev/e_udev_util.c	(revision 0)
+++ src/lib/udev/e_udev_util.c	(revision 0)
@@ -0,0 +1,112 @@
+#include <E_Udev.h>
+#include "e_udev_private.h"
+
+/**
+ * @internal
+ * @brief free a property structure
+ * @param prop the property to free
+ */
+EAPI void
+e_udev_property_free(E_Udev_Property *prop)
+{
+   if (prop->type == E_UDEV_PROPERTY_TYPE_STRLIST)
+     eina_list_free(prop->val.strlist);
+   free(prop);
+}
+
+/**
+ * @brief Retrive a string from an element of a property hash
+ * @param properties the E_Udev_Properties structure
+ * @param key the key of the property to retrieve
+ * @param err a pointer to an int, which if supplied, will be set to 0 on success and 1 on an error
+ */
+EAPI const char *
+e_udev_property_string_get(E_Udev_Properties *properties, const char *key, int *err)
+{
+   E_Udev_Property *prop;
+   if (err) *err = 0;
+   if (!properties->properties) return NULL;
+   prop = eina_hash_find(properties->properties, key);
+   if (prop) return prop->val.s;
+
+   if (err) *err = 1;
+   return NULL;
+}
+
+EAPI Eina_Bool
+e_udev_property_bool_get(E_Udev_Properties *properties, const char *key, int *err)
+{
+   E_Udev_Property *prop;
+   if (err) *err = 0;
+   if (!properties->properties) return 0;
+   prop = eina_hash_find(properties->properties, key);
+   if (prop) return prop->val.b;
+   
+   if (err) *err = 1;
+   return 0;
+}
+
+EAPI int
+e_udev_property_int_get(E_Udev_Properties *properties, const char *key, int *err)
+{
+   E_Udev_Property *prop;
+   if (err) *err = 0;
+   if (!properties->properties) return 0;
+   prop = eina_hash_find(properties->properties, key);
+   if (prop) return prop->val.i;
+
+   if (err) *err = 1;
+   return 0;
+}
+
+EAPI dbus_uint64_t
+e_udev_property_uint64_get(E_Udev_Properties *properties, const char *key, int *err)
+{
+   E_Udev_Property *prop;
+   if (err) *err = 0;
+   if (!properties->properties) return 0;
+   prop = eina_hash_find(properties->properties, key);
+   if (prop) return prop->val.u64;
+
+   if (err) *err = 1;
+   return 0;
+}
+
+EAPI dbus_uint64_t
+e_udev_property_int64_get(E_Udev_Properties *properties, const char *key, int *err)
+{
+   E_Udev_Property *prop;
+   if (err) *err = 0;
+   if (!properties->properties) return 0;
+   prop = eina_hash_find(properties->properties, key);
+   if (prop) return prop->val.i64;
+
+   if (err) *err = 1;
+   return 0;
+}
+
+EAPI double
+e_udev_property_double_get(E_Udev_Properties *properties, const char *key, int *err)
+{
+   E_Udev_Property *prop;
+   if (err) *err = 0;
+   if (!properties->properties) return 0;
+   prop = eina_hash_find(properties->properties, key);
+   if (prop) return prop->val.d;
+
+   if (err) *err = 1;
+   return 0;
+}
+
+EAPI const Eina_List *
+e_udev_property_strlist_get(E_Udev_Properties *properties, const char *key, int *err)
+{
+   E_Udev_Property *prop;
+   if (err) *err = 0;
+   if (!properties->properties) return NULL;
+   prop = eina_hash_find(properties->properties, key);
+   if (prop) return prop->val.strlist;
+
+   if (err) *err = 1;
+   return NULL;
+}
Index: src/lib/udev/e_upower.c
===================================================================
--- src/lib/udev/e_upower.c	(revision 0)
+++ src/lib/udev/e_upower.c	(revision 0)
@@ -0,0 +1,127 @@
+#include <E_Udev.h>
+#include "e_udev_private.h"
+
+#define E_UDEV_BUS E_UPOWER_BUS
+#define E_UDEV_PATH E_UPOWER_PATH
+#define E_UDEV_INTERFACE E_UPOWER_INTERFACE
+
+const char *e_upower_iface="org.freedesktop.UPower.Device";
+
+#if 0
+static void cb_device_get_property(void *data, DBusMessage *msg, DBusError *err);
+static void cb_device_get_all_properties(void *data, DBusMessage *msg, DBusError *err);
+static void cb_device_query_capability(void *data, DBusMessage *msg, DBusError *err);
+#endif
+
+/* Properties.Get */
+EAPI DBusPendingCall *
+e_upower_get_property(E_DBus_Connection *conn, const char *udi, const char *property, E_DBus_Callback_Func cb_func, void *data)
+{
+   DBusMessage *msg;
+   DBusPendingCall *ret;
+
+   msg = e_udev_property_call_new(udi, "Get");
+   dbus_message_append_args(msg, DBUS_TYPE_STRING, &e_upower_iface, DBUS_TYPE_STRING, &property, DBUS_TYPE_INVALID);
+   ret = e_dbus_method_call_send(conn, msg, unmarshal_property, cb_func, free_property, -1, data);
+   dbus_message_unref(msg);
+   return ret;
+}
+
+/* Properties.GetAll */
+EAPI DBusPendingCall *
+e_upower_get_all_properties(E_DBus_Connection *conn, const char *udi, E_DBus_Callback_Func cb_func, void *data)
+{
+   DBusMessage *msg;
+   DBusPendingCall *ret;
+
+   msg = e_udev_property_call_new(udi, "GetAll");
+   dbus_message_append_args(msg, DBUS_TYPE_STRING, &e_upower_iface, DBUS_TYPE_INVALID);
+   ret = e_dbus_method_call_send(conn, msg, unmarshal_device_get_all_properties, cb_func, free_device_get_all_properties, -1, data);
+   dbus_message_unref(msg);
+   return ret;
+}
+
+
+EAPI DBusPendingCall *
+e_upower_hibernate(E_DBus_Connection *conn, E_DBus_Callback_Func cb_func, void *data)
+{
+   DBusMessage *msg;
+   DBusPendingCall *ret;
+
+   msg = e_udev_call_new(E_UDEV_PATH, "Hibernate");
+
+   ret = e_dbus_method_call_send(conn, msg, NULL, cb_func, NULL, -1, data);
+   dbus_message_unref(msg);
+   return ret;
+}
+
+EAPI DBusPendingCall *
+e_upower_suspend(E_DBus_Connection *conn, E_DBus_Callback_Func cb_func, void *data)
+{
+   DBusMessage *msg;
+   DBusPendingCall *ret;
+
+   msg = e_udev_call_new(E_UDEV_PATH, "Suspend");
+
+   ret = e_dbus_method_call_send(conn, msg, NULL, cb_func, NULL, -1, data);
+   dbus_message_unref(msg);
+   return ret;
+}
+
+EAPI DBusPendingCall *
+e_upower_hibernate_allowed(E_DBus_Connection *conn, E_DBus_Callback_Func cb_func, void *data)
+{
+   DBusMessage *msg;
+   DBusPendingCall *ret;
+
+   msg = e_udev_call_new(E_UDEV_PATH, "HibernateAllowed");
+
+   ret = e_dbus_method_call_send(conn, msg, unmarshal_property, cb_func, free_property, -1, data);
+   dbus_message_unref(msg);
+   return ret;
+}
+
+EAPI DBusPendingCall *
+e_upower_suspend_allowed(E_DBus_Connection *conn, E_DBus_Callback_Func cb_func, void *data)
+{
+   DBusMessage *msg;
+   DBusPendingCall *ret;
+
+   msg = e_udev_call_new(E_UDEV_PATH, "SuspendAllowed");
+
+   ret = e_dbus_method_call_send(conn, msg, unmarshal_property, cb_func, free_property, -1, data);
+   dbus_message_unref(msg);
+   return ret;
+}
+
+/* EnumerateDevices */
+EAPI DBusPendingCall *
+e_upower_get_all_devices(E_DBus_Connection *conn, E_DBus_Callback_Func cb_func, void *data)
+{
+   DBusMessage *msg;
+   DBusPendingCall *ret;
+
+   msg = e_udev_call_new(E_UDEV_PATH, "EnumerateDevices");
+   ret = e_dbus_method_call_send(conn, msg, unmarshal_string_list, cb_func, free_string_list, -1, data);
+   dbus_message_unref(msg);
+   return ret;
+}
+
+
+/* Manager.FindDeviceByCapability */
+/*
+ * not implemented in upower yet...
+ * 
+EAPI DBusPendingCall *
+e_upower_find_device_by_capability(E_DBus_Connection *conn, const char *capability, E_DBus_Callback_Func cb_func, void *data)
+{
+   DBusMessage *msg;
+   DBusPendingCall *ret;
+
+   msg = e_upower_call_new("FindDeviceByCapability");
+   dbus_message_append_args(msg, DBUS_TYPE_STRING, &capability, DBUS_TYPE_INVALID);
+   ret = e_dbus_method_call_send(conn, msg, unmarshal_string_list, cb_func, free_string_list, -1, data);
+   dbus_message_unref(msg);
+   return ret;
+}
+*/
Index: src/lib/udev/e_udev_private.h
===================================================================
--- src/lib/udev/e_udev_private.h	(revision 0)
+++ src/lib/udev/e_udev_private.h	(revision 0)
@@ -0,0 +1,32 @@
+#ifndef E_UDEV_PRIVATE_H
+#define E_UDEV_PRIVATE_H
+
+#ifndef E_DBUS_COLOR_DEFAULT
+#define E_DBUS_COLOR_DEFAULT EINA_COLOR_CYAN
+#endif
+extern int _e_dbus_udev_log_dom;
+#ifdef ERR
+#undef ERR
+#endif
+#ifdef INF
+#undef INF
+#endif
+#ifdef WARN
+#undef WARN
+#endif
+#ifdef DBG
+#undef DBG
+#endif
+
+#define e_udev_call_new(udi, member) dbus_message_new_method_call(E_UDEV_BUS, udi, E_UDEV_BUS, member)
+#define e_udev_device_call_new(udi, member) dbus_message_new_method_call(E_UDEV_BUS, udi, E_UDEV_INTERFACE, member)
+#define e_udev_property_call_new(udi, member) dbus_message_new_method_call(E_UDEV_BUS, udi, E_UDEV_PROP_INTERFACE, member)
+
+#define DBG(...)   EINA_LOG_DOM_DBG(_e_dbus_udev_log_dom, __VA_ARGS__)
+#define INFO(...)    EINA_LOG_DOM_INFO(_e_dbus_udev_log_dom, __VA_ARGS__)
+#define WARN(...) EINA_LOG_DOM_WARN(_e_dbus_udev_log_dom, __VA_ARGS__)
+#define ERR(...)   EINA_LOG_DOM_ERR(_e_dbus_udev_log_dom, __VA_ARGS__)
+
+#include "e_udev_privfunc.h"
+
+#endif
Index: src/lib/udev/e_udisks.c
===================================================================
--- src/lib/udev/e_udisks.c	(revision 0)
+++ src/lib/udev/e_udisks.c	(revision 0)
@@ -0,0 +1,190 @@
+#include <E_Udev.h>
+#include "e_udev_private.h"
+
+#define E_UDEV_BUS E_UDISKS_BUS
+#define E_UDEV_PATH E_UDISKS_PATH
+#define E_UDEV_INTERFACE E_UDISKS_INTERFACE
+
+const char *e_udisks_iface="org.freedesktop.UDisks.Device";
+
+#if 0
+static void cb_device_get_property(void *data, DBusMessage *msg, DBusError *err);
+static void cb_device_get_all_properties(void *data, DBusMessage *msg, DBusError *err);
+static void cb_device_query_capability(void *data, DBusMessage *msg, DBusError *err);
+#endif
+
+/* Properties.Get */
+EAPI DBusPendingCall *
+e_udisks_get_property(E_DBus_Connection *conn, const char *udi, const char *property, E_DBus_Callback_Func cb_func, void *data)
+{
+   DBusMessage *msg;
+   DBusPendingCall *ret;
+
+   msg = e_udev_property_call_new(udi, "Get");
+   dbus_message_append_args(msg, DBUS_TYPE_STRING, &e_udisks_iface, DBUS_TYPE_STRING, &property, DBUS_TYPE_INVALID);
+   ret = e_dbus_method_call_send(conn, msg, unmarshal_property, cb_func, free_property, -1, data);
+   dbus_message_unref(msg);
+   return ret;
+}
+
+/* Properties.GetAll */
+EAPI DBusPendingCall *
+e_udisks_get_all_properties(E_DBus_Connection *conn, const char *udi, E_DBus_Callback_Func cb_func, void *data)
+{
+   DBusMessage *msg;
+   DBusPendingCall *ret;
+
+   msg = e_udev_property_call_new(udi, "GetAll");
+   dbus_message_append_args(msg, DBUS_TYPE_STRING, &e_udisks_iface, DBUS_TYPE_INVALID);
+   ret = e_dbus_method_call_send(conn, msg, unmarshal_device_get_all_properties, cb_func, free_device_get_all_properties, -1, data);
+   dbus_message_unref(msg);
+   return ret;
+}
+
+
+
+/* void FilesystemMount(string fstype, array{string}options) */
+
+/**
+ * @brief Mount a Filesystem
+ *
+ * @param conn the E_DBus_Connection
+ * @param udi the udi of the device object
+ * @param fstype the fstype of the device (e.g. volume.fstype property)
+ * @param options a list of additional options (not sure... fstype dependant?)
+ * @param cb_func an optional callback to call when the mount is done
+ * @param data custom data pointer for the callback function
+ *
+ * @return mount point of fs or error
+ */
+EAPI DBusPendingCall *
+e_udisks_volume_mount(E_DBus_Connection *conn, const char *udi, const char *fstype, Eina_List *options, E_DBus_Callback_Func cb_func, void *data)
+{
+   DBusMessage *msg;
+   DBusMessageIter iter, subiter;
+   Eina_List *l;
+   DBusPendingCall *ret;
+
+   msg = e_udev_device_call_new(udi, "FilesystemMount");
+
+   dbus_message_iter_init_append(msg, &iter);
+   dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &fstype);
+   dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &subiter);
+
+   if (options)
+     {
+        const char *opt;
+
+        EINA_LIST_FOREACH(options, l, opt)
+          dbus_message_iter_append_basic(&subiter, DBUS_TYPE_STRING, &opt);
+     }
+   dbus_message_iter_close_container(&iter, &subiter) ;
+
+   ret = e_dbus_method_call_send(conn, msg, unmarshal_property, cb_func, free_property, -1, data);
+   dbus_message_unref(msg);
+   return ret;
+}
+
+/* void Unmount(array{string} options) */
+
+/**
+ * @brief Unmount a Volume
+ *
+ * @param conn the E_DBus_Connection
+ * @param udi the udi of the device object
+ * @param options a list of additional options (currently only 'force' is supported)
+ * @param cb_func an optional callback to call when the unmount is done
+ * @param data custom data pointer for the callback function
+ */
+EAPI DBusPendingCall *
+e_udisks_volume_unmount(E_DBus_Connection *conn, const char *udi, Eina_List *options, E_DBus_Callback_Func cb_func, void *data)
+{
+   DBusMessage *msg;
+   DBusMessageIter iter, subiter;
+   Eina_List *l;
+   DBusPendingCall *ret;
+
+   msg = e_udev_device_call_new(udi, "FilesystemUnmount");
+
+   dbus_message_iter_init_append(msg, &iter);
+   dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &subiter);
+   if (options)
+     {
+        const char *opt;
+
+        EINA_LIST_FOREACH(options, l, opt)
+          dbus_message_iter_append_basic(&subiter, DBUS_TYPE_STRING, &opt);
+     }
+   dbus_message_iter_close_container(&iter, &subiter) ;
+
+   ret = e_dbus_method_call_send(conn, msg, NULL, cb_func, NULL, -1, data);
+   dbus_message_unref(msg);
+   return ret;
+}
+
+/**
+ * @brief Eject a Volume
+ *
+ * @param conn the E_DBus_Connection
+ * @param udi the udi of the device object
+ * @param options a list of additional options (none currently supported)
+ * @param cb_func an optional callback to call when the eject is done
+ * @param data cuatom data pointer for the callback function
+ */
+EAPI DBusPendingCall *
+e_udisks_volume_eject(E_DBus_Connection *conn, const char *udi, Eina_List *options, E_DBus_Callback_Func cb_func, void *data)
+{
+   DBusMessage *msg;
+   DBusMessageIter iter, subiter;
+   Eina_List *l;
+   DBusPendingCall *ret;
+
+   msg = e_udev_device_call_new(udi, "DriveEject");
+
+   dbus_message_iter_init_append(msg, &iter);
+   dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &subiter);
+   if (options)
+     {
+        const char *opt;
+
+        EINA_LIST_FOREACH(options, l, opt)
+          dbus_message_iter_append_basic(&subiter, DBUS_TYPE_STRING, &opt);
+     }
+   dbus_message_iter_close_container(&iter, &subiter) ;
+
+   ret = e_dbus_method_call_send(conn, msg, NULL, cb_func, NULL, -1, data);
+   dbus_message_unref(msg);
+   return ret;
+}
+
+/* EnumerateDevices */
+EAPI DBusPendingCall *
+e_udisks_get_all_devices(E_DBus_Connection *conn, E_DBus_Callback_Func cb_func, void *data)
+{
+   DBusMessage *msg;
+   DBusPendingCall *ret;
+
+   msg = e_udev_call_new(E_UDEV_PATH, "EnumerateDevices");
+   ret = e_dbus_method_call_send(conn, msg, unmarshal_string_list, cb_func, free_string_list, -1, data);
+   dbus_message_unref(msg);
+   return ret;
+}
+
+
+/* Manager.FindDeviceByCapability */
+/*
+ * not implemented in udisks yet...
+ * 
+EAPI DBusPendingCall *
+e_udisks_find_device_by_capability(E_DBus_Connection *conn, const char *capability, E_DBus_Callback_Func cb_func, void *data)
+{
+   DBusMessage *msg;
+   DBusPendingCall *ret;
+
+   msg = e_udisks_call_new("FindDeviceByCapability");
+   dbus_message_append_args(msg, DBUS_TYPE_STRING, &capability, DBUS_TYPE_INVALID);
+   ret = e_dbus_method_call_send(conn, msg, unmarshal_string_list, cb_func, free_string_list, -1, data);
+   dbus_message_unref(msg);
+   return ret;
+}
+*/
Index: src/lib/udev/Makefile.am
===================================================================
--- src/lib/udev/Makefile.am	(revision 0)
+++ src/lib/udev/Makefile.am	(revision 0)
@@ -0,0 +1,27 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I $(top_srcdir)/src/lib/dbus \
+...@edbus_cflags@ @EINA_CFLAGS@
+
+if BUILD_EUDEV
+
+lib_LTLIBRARIES = libeudev.la
+include_HEADERS = E_Udev.h
+
+noinst_HEADERS = e_udev_private.h e_udev_privfunc.h
+
+libeudev_la_SOURCES = \
+E_Udev.h \
+e_udisks.c  \
+e_upower.c  \
+e_udev_util.c \
+e_udev_main.c
+
+libeudev_la_LIBADD = \
+...@edbus_libs@ \
+$(top_builddir)/src/lib/dbus/libedbus.la \
+...@eina_libs@
+libeudev_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @eudev_release_info@
+
+endif
Index: src/lib/udev/e_udev_privfunc.h
===================================================================
--- src/lib/udev/e_udev_privfunc.h	(revision 0)
+++ src/lib/udev/e_udev_privfunc.h	(revision 0)
@@ -0,0 +1,248 @@
+#ifndef E_UDEV_PRIVFUNC_H
+#define E_UDEV_PRIVFUNC_H
+
+
+static void *
+unmarshal_property(DBusMessage *msg, DBusError *err)
+{
+   E_Udev_Get_Property_Return *ret = NULL;
+   DBusMessageIter iter, a_iter;
+   int type;
+   char *tmp;
+
+   ret = calloc(1, sizeof(E_Udev_Get_Property_Return));
+   if (!ret) 
+     {
+        dbus_set_error(err, DBUS_ERROR_NO_MEMORY, "");
+        return NULL;
+     }
+
+   dbus_message_iter_init(msg, &iter);
+   dbus_message_iter_recurse(&iter, &a_iter);
+   if (dbus_message_iter_get_arg_type(&a_iter) != DBUS_TYPE_INVALID)
+     {
+        type = dbus_message_iter_get_arg_type(&a_iter);    
+
+        switch(type)
+          {
+             case DBUS_TYPE_STRING:
+               ret->type = E_UDEV_PROPERTY_TYPE_STRING;
+               dbus_message_iter_get_basic(&a_iter, &tmp);
+               ret->val.s = eina_stringshare_add(tmp);
+               break;
+             case DBUS_TYPE_INT32:
+               ret->type = E_UDEV_PROPERTY_TYPE_INT;
+               dbus_message_iter_get_basic(&a_iter, &(ret->val.i));
+               break;
+             case DBUS_TYPE_UINT64:
+               ret->type = E_UDEV_PROPERTY_TYPE_UINT64;
+               dbus_message_iter_get_basic(&a_iter, &(ret->val.u64));
+               break;
+             case DBUS_TYPE_INT64:
+               ret->type = E_UDEV_PROPERTY_TYPE_INT64;
+               dbus_message_iter_get_basic(&a_iter, &(ret->val.i64));
+               break;
+             case DBUS_TYPE_BOOLEAN:
+               ret->type = E_UDEV_PROPERTY_TYPE_BOOL;
+               dbus_message_iter_get_basic(&a_iter, &(ret->val.b));
+               break;
+             case DBUS_TYPE_DOUBLE:
+               ret->type = E_UDEV_PROPERTY_TYPE_DOUBLE;
+               dbus_message_iter_get_basic(&a_iter, &(ret->val.d));
+               break;
+             case DBUS_TYPE_ARRAY:
+               ret->type = E_UDEV_PROPERTY_TYPE_STRLIST;
+               {
+                  DBusMessageIter list_iter;
+                  ret->val.strlist = NULL;
+                  dbus_message_iter_recurse(&a_iter, &list_iter);
+                  while (dbus_message_iter_get_arg_type(&list_iter) != DBUS_TYPE_INVALID)
+                    {
+                       char *str;
+                       dbus_message_iter_get_basic(&list_iter, &str);
+                       tmp = (char*)eina_stringshare_add(str);
+                       ret->val.strlist = eina_list_append(ret->val.strlist, tmp);
+                       dbus_message_iter_next(&list_iter);
+                    }
+                }
+                break;
+             default:
+               break;
+          }
+     }
+
+   return ret;
+}
+
+
+
+static void 
+free_property(void *data)
+{
+   E_Udev_Get_Property_Return *ret = data;
+
+   if (!ret) return;
+   if (ret->type == E_UDEV_PROPERTY_TYPE_STRLIST)
+     {
+        const char *s;
+        EINA_LIST_FREE(ret->val.strlist, s)
+          eina_stringshare_del(s);
+     }
+   else if (ret->type == E_UDEV_PROPERTY_TYPE_STRING)
+     eina_stringshare_del(ret->val.s);
+   free(ret);
+}
+
+static void *
+unmarshal_device_get_all_properties(DBusMessage *msg, DBusError *err)
+{
+   E_Udev_Get_All_Properties_Return *ret = NULL;
+   DBusMessageIter iter, a_iter, s_iter, v_iter;
+   int type;
+   char *tmp;
+
+   /* a{sv} = array of string+variants */
+   if (!dbus_message_has_signature(msg, "a{sv}")) 
+     {
+        dbus_set_error(err, DBUS_ERROR_INVALID_SIGNATURE, "");
+        return NULL;
+     }
+
+   ret = calloc(1, sizeof(E_Udev_Get_All_Properties_Return));
+   if (!ret) 
+     {
+         dbus_set_error(err, DBUS_ERROR_NO_MEMORY, "");
+         return NULL;
+     }
+
+   ret->properties = eina_hash_string_small_new(EINA_FREE_CB(e_udev_property_free));
+
+   dbus_message_iter_init(msg, &iter);
+   dbus_message_iter_recurse(&iter, &a_iter);
+   while (dbus_message_iter_get_arg_type(&a_iter) != DBUS_TYPE_INVALID)
+   {
+      const char *name;
+      E_Udev_Property *prop = calloc(1, sizeof(E_Udev_Property));
+      dbus_message_iter_recurse(&a_iter, &s_iter);
+      dbus_message_iter_get_basic(&s_iter, &name);
+      dbus_message_iter_next(&s_iter);
+      dbus_message_iter_recurse(&s_iter, &v_iter);
+      
+      type = dbus_message_iter_get_arg_type(&v_iter);
+      switch(type)
+        {
+           case DBUS_TYPE_STRING:
+             prop->type = E_UDEV_PROPERTY_TYPE_STRING;
+             dbus_message_iter_get_basic(&v_iter, &tmp);
+             prop->val.s = eina_stringshare_add(tmp);
+             break;
+           case DBUS_TYPE_INT32:
+             prop->type = E_UDEV_PROPERTY_TYPE_INT;
+             dbus_message_iter_get_basic(&v_iter, &(prop->val.i));
+             break;
+           case DBUS_TYPE_UINT64:
+             prop->type = E_UDEV_PROPERTY_TYPE_UINT64;
+             dbus_message_iter_get_basic(&v_iter, &(prop->val.u64));
+             break;
+           case DBUS_TYPE_INT64:
+             prop->type = E_UDEV_PROPERTY_TYPE_INT64;
+             dbus_message_iter_get_basic(&v_iter, &(prop->val.i64));
+             break;
+           case DBUS_TYPE_BOOLEAN:
+             prop->type = E_UDEV_PROPERTY_TYPE_BOOL;
+             dbus_message_iter_get_basic(&v_iter, &(prop->val.b));
+             break;
+           case DBUS_TYPE_DOUBLE:
+             prop->type = E_UDEV_PROPERTY_TYPE_DOUBLE;
+             dbus_message_iter_get_basic(&v_iter, &(prop->val.d));
+             break;
+           case DBUS_TYPE_ARRAY:
+             prop->type = E_UDEV_PROPERTY_TYPE_STRLIST;
+             {
+                DBusMessageIter list_iter;
+                prop->val.strlist = NULL;
+                dbus_message_iter_recurse(&v_iter, &list_iter);
+                while (dbus_message_iter_get_arg_type(&list_iter) != DBUS_TYPE_INVALID)
+                {
+                   char *str;
+                   dbus_message_iter_get_basic(&list_iter, &str);
+                   tmp = (char*)eina_stringshare_add(str);
+                   prop->val.strlist = eina_list_append(prop->val.strlist, tmp);
+                   dbus_message_iter_next(&list_iter);
+                }
+             }
+             break;
+           default:
+             WARN("EUdev Error: unexpected property type (%s): %c", name, dbus_message_iter_get_arg_type(&v_iter));
+             break;
+        }
+      eina_hash_add(ret->properties, name, prop);
+
+      dbus_message_iter_next(&a_iter);
+   }
+
+   return ret;
+}
+
+static void
+free_device_get_all_properties(void *data)
+{
+   E_Udev_Get_All_Properties_Return *ret = data;
+
+   if (!ret) return;
+   eina_hash_free(ret->properties);
+   free(ret);
+}
+
+static void *
+unmarshal_string_list(DBusMessage *msg, DBusError *err)
+{
+   E_Udev_String_List_Return *ret = NULL;
+   DBusMessageIter iter, sub;
+   char *tmp;
+
+   /* ao = array of object strings */
+   if (!dbus_message_has_signature(msg, "ao")) 
+     {
+        dbus_set_error(err, DBUS_ERROR_INVALID_SIGNATURE, "");
+        return NULL;
+     }
+
+   ret = calloc(1, sizeof(E_Udev_String_List_Return));
+   if (!ret) 
+     {
+        dbus_set_error(err, DBUS_ERROR_NO_MEMORY, "");
+        return NULL;
+     }
+
+   ret->strings = NULL;
+
+   dbus_message_iter_init(msg, &iter);
+   dbus_message_iter_recurse(&iter, &sub);
+   while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID)
+     {
+        char *dev = NULL;
+
+        dbus_message_iter_get_basic(&sub, &dev);
+        tmp = (char*)eina_stringshare_add(dev);
+        if (dev) ret->strings = eina_list_append(ret->strings, tmp);
+        dbus_message_iter_next(&sub);
+     }
+
+   return ret;
+}
+
+static void
+free_string_list(void *data)
+{
+   E_Udev_String_List_Return *ret = data;
+   const char *x;
+
+   if (!ret) return;
+   EINA_LIST_FREE(ret->strings, x)
+     eina_stringshare_del(x);
+   free(ret);
+}
+
+
+#endif
Index: src/lib/udev/e_udev_main.c
===================================================================
--- src/lib/udev/e_udev_main.c	(revision 0)
+++ src/lib/udev/e_udev_main.c	(revision 0)
@@ -0,0 +1,54 @@
+#include <E_Udev.h>
+#include "e_udev_private.h"
+
+int _e_dbus_udev_log_dom = -1;
+int _e_dbus_udev_init_count = 0;
+
+EAPI int
+e_udev_init(void)
+{
+   if (++_e_dbus_udev_init_count != 1)
+     return _e_dbus_udev_init_count;
+
+   if (!eina_init())
+     return --_e_dbus_udev_init_count;
+
+   _e_dbus_udev_log_dom = eina_log_domain_register
+     ("e_udev", E_DBUS_COLOR_DEFAULT);
+   if (_e_dbus_udev_log_dom < 0)
+     {
+        EINA_LOG_ERR("Could not register 'e_udev' log domain.");
+        goto shutdown_eina;
+     }
+
+   if (!e_dbus_init())
+     {
+        ERR("Could not initialize E_DBus.");
+        goto unregister_log_domain;
+     }
+
+   return _e_dbus_udev_init_count;
+
+   unregister_log_domain:
+     eina_log_domain_unregister(_e_dbus_udev_log_dom);
+     _e_dbus_udev_log_dom = -1;
+   shutdown_eina:
+     eina_shutdown();
+
+   return _e_dbus_udev_init_count;
+}
+
+EAPI int
+e_udev_shutdown(void)
+{
+   if (--_e_dbus_udev_init_count != 0)
+     return _e_dbus_udev_init_count;
+
+   e_dbus_shutdown();
+
+   eina_log_domain_unregister(_e_dbus_udev_log_dom);
+   _e_dbus_udev_log_dom = -1;
+   eina_shutdown();
+
+   return _e_dbus_udev_init_count;
+}
Index: src/lib/udev/E_Udev.h
===================================================================
--- src/lib/udev/E_Udev.h	(revision 0)
+++ src/lib/udev/E_Udev.h	(revision 0)
@@ -0,0 +1,136 @@
+#ifndef E_UDEV_H
+#define E_UDEV_H
+#include <E_DBus.h>
+#include <eina_stringshare.h>
+
+#ifdef EAPI
+#undef EAPI
+#endif
+#ifdef _MSC_VER
+# ifdef BUILDING_DLL
+#  define EAPI __declspec(dllexport)
+# else
+#  define EAPI __declspec(dllimport)
+# endif
+#else
+# ifdef __GNUC__
+#  if __GNUC__ >= 4
+#   define EAPI __attribute__ ((visibility("default")))
+#  else
+#   define EAPI
+#  endif
+# else
+#  define EAPI
+# endif
+#endif
+
+#define E_UDEV_PROP_INTERFACE "org.freedesktop.DBus.Properties"
+
+#define E_UDISKS_BUS "org.freedesktop.UDisks"
+#define E_UDISKS_PATH "/org/freedesktop/UDisks"
+#define E_UDISKS_INTERFACE "org.freedesktop.UDisks.Device"
+
+#define E_UPOWER_BUS "org.freedesktop.UPower"
+#define E_UPOWER_PATH "/org/freedesktop/UPower"
+#define E_UPOWER_INTERFACE "org.freedesktop.UPower.Device"
+
+/* message return types */
+
+typedef struct E_Udev_Property E_Udev_Property;
+typedef struct E_Udev_Properties E_Udev_Properties;
+
+struct E_Udev_String_List_Return
+{
+   Eina_List *strings; /* list of const char * */
+};
+
+struct E_Udev_Bool_Return
+{
+   Eina_Bool boolean;
+};
+
+struct E_Udev_UDI_Return
+{
+   const char *udi;
+};
+
+struct E_Udev_Capability
+{
+   const char *udi;
+   const char *capability;
+};
+
+typedef enum
+{
+   E_UDEV_PROPERTY_TYPE_STRING,
+   E_UDEV_PROPERTY_TYPE_INT,
+   E_UDEV_PROPERTY_TYPE_UINT64,
+   E_UDEV_PROPERTY_TYPE_INT64,
+   E_UDEV_PROPERTY_TYPE_BOOL,
+   E_UDEV_PROPERTY_TYPE_DOUBLE,
+   E_UDEV_PROPERTY_TYPE_STRLIST
+} E_Udev_Property_Type;
+
+struct E_Udev_Property
+{
+   E_Udev_Property_Type type;
+   union 
+     {
+        const char *s;
+        int i;
+        dbus_bool_t b;
+        double d;
+        dbus_uint64_t u64;
+        dbus_int64_t i64;
+        Eina_List *strlist;
+     } val;
+};
+
+struct E_Udev_Properties
+{
+   Eina_Hash *properties;
+};
+
+typedef struct E_Udev_Properties E_Udev_Get_All_Properties_Return;
+typedef struct E_Udev_Property E_Udev_Get_Property_Return;
+typedef struct E_Udev_String_List_Return E_Udev_String_List_Return;
+typedef struct E_Udev_String_List_Return E_Udev_Get_All_Devices_Return;
+
+typedef struct E_Udev_UDI_Return E_Udev_Device_Added;
+typedef struct E_Udev_UDI_Return E_Udev_Device_Removed;
+typedef struct E_Udev_Capability E_Udev_New_Capability;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+   EAPI int e_udev_init(void);
+   EAPI int e_udev_shutdown(void);
+
+   EAPI DBusPendingCall *e_udisks_get_property(E_DBus_Connection *conn, const char *udi, const char *property, E_DBus_Callback_Func cb_func, void *data);
+   EAPI DBusPendingCall *e_udisks_get_all_properties(E_DBus_Connection *conn, const char *udi, E_DBus_Callback_Func cb_func, void *data);
+   EAPI DBusPendingCall *e_udisks_get_all_devices(E_DBus_Connection *conn, E_DBus_Callback_Func cb_func, void *data);
+
+   EAPI DBusPendingCall *e_upower_get_property(E_DBus_Connection *conn, const char *udi, const char *property, E_DBus_Callback_Func cb_func, void *data);
+   EAPI DBusPendingCall *e_upower_get_all_properties(E_DBus_Connection *conn, const char *udi, E_DBus_Callback_Func cb_func, void *data);
+   EAPI DBusPendingCall *e_upower_get_all_devices(E_DBus_Connection *conn, E_DBus_Callback_Func cb_func, void *data);
+
+/* utility functions */
+   EAPI void                e_udev_property_free(E_Udev_Property *prop);
+   EAPI const char          *e_udev_property_string_get(E_Udev_Properties *properties, const char *key, int *err);
+   EAPI Eina_Bool           e_udev_property_bool_get(E_Udev_Properties *properties, const char *key, int *err);
+   EAPI int                 e_udev_property_int_get(E_Udev_Properties *properties, const char *key, int *err);
+   EAPI dbus_uint64_t       e_udev_property_uint64_get(E_Udev_Properties *properties, const char *key, int *err);
+   EAPI double              e_udev_property_double_get(E_Udev_Properties *properties, const char *key, int *err);
+   EAPI const Eina_List     *e_udev_property_strlist_get(E_Udev_Properties *properties, const char *key, int *err);
+
+/* (un)mount */
+   EAPI DBusPendingCall *e_udisks_volume_mount(E_DBus_Connection *conn, const char *udi, const char *fstype, Eina_List *options, E_DBus_Callback_Func cb_func, void *data);
+   EAPI DBusPendingCall *e_udisks_volume_unmount(E_DBus_Connection *conn, const char *udi, Eina_List *options, E_DBus_Callback_Func cb_func, void *data);
+   EAPI DBusPendingCall *e_udisks_volume_eject(E_DBus_Connection *conn, const char *udi, Eina_List *options, E_DBus_Callback_Func cb_func, void *data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: src/lib/Makefile.am
===================================================================
--- src/lib/Makefile.am	(revision 47995)
+++ src/lib/Makefile.am	(working copy)
@@ -1,3 +1,3 @@
 MAINTAINERCLEANFILES = Makefile.in
 
-SUBDIRS=dbus hal notification connman bluez ofono
+SUBDIRS=dbus hal notification connman bluez ofono udev
Index: src/bin/e_dbus_udev_test.c
===================================================================
--- src/bin/e_dbus_udev_test.c	(revision 0)
+++ src/bin/e_dbus_udev_test.c	(revision 0)
@@ -0,0 +1,143 @@
+#include <E_Udev.h>
+#include <E_DBus.h>
+#include <Ecore.h>
+#include <stdio.h>
+
+static E_DBus_Connection *econ = NULL;
+
+Eina_Bool
+print_prop(const Eina_Hash *hash, const void *key, void *data, void *fdata)
+{
+   const Eina_List *strlist, *l;
+   char *y;
+   E_Udev_Property *p = data;
+   E_Udev_Properties props;
+   int err = 0;
+
+   props.properties = (Eina_Hash*)hash;   
+   switch (p->type)
+     {
+        case E_UDEV_PROPERTY_TYPE_STRING:
+          printf("\t%s = [%s]\n", (char*)key, e_udev_property_string_get(&props, key, &err));
+          break;
+        case E_UDEV_PROPERTY_TYPE_INT:
+          printf("\t%s = [%d]\n", (char*)key, e_udev_property_int_get(&props, key, &err));
+          break;
+        case E_UDEV_PROPERTY_TYPE_UINT64:
+          printf("\t%s = [%llu]\n", (char*)key, (long long unsigned)e_udev_property_uint64_get(&props, key, &err));
+          break;
+        case E_UDEV_PROPERTY_TYPE_INT64:
+          printf("\t%s = [%lld]\n", (char*)key, (long long int)e_udev_property_int64_get(&props, key, &err));
+          break;
+        case E_UDEV_PROPERTY_TYPE_BOOL:
+          printf("\t%s = [%d]\n", (char*)key, e_udev_property_bool_get(&props, key, &err));
+          break;
+        case E_UDEV_PROPERTY_TYPE_DOUBLE:
+          printf("\t%s = [%f]\n", (char*)key, e_udev_property_double_get(&props, key, &err));
+          break;
+        case E_UDEV_PROPERTY_TYPE_STRLIST:
+          printf("\t%s = [", (char*)key);
+          strlist = e_udev_property_strlist_get(&props, key, &err);
+          EINA_LIST_FOREACH(strlist, l, y)
+           printf("%s%s", y, (l->next) ? " " : "");
+          printf("]\n");
+          break;
+     }
+   
+   return 1;
+}
+
+static void
+hash_props(void *user_data, void *reply_data, DBusError *error)
+{
+   printf("%s:\n", (char*)user_data);
+   E_Udev_Get_All_Properties_Return *ret = reply_data;
+
+   if (!ret || dbus_error_is_set(error))
+     {
+        free(user_data);
+        dbus_error_free(error);
+        return;
+     }
+
+   eina_hash_foreach(ret->properties, print_prop, NULL);
+   printf("\n");
+   free(user_data);
+}
+
+static void
+test_mount(void *user_data, void *reply_data, DBusError *error)
+{
+   E_Udev_Get_Property_Return *ret = reply_data;
+
+   if (!ret || dbus_error_is_set(error))
+     {
+        free(user_data);
+        dbus_error_free(error);
+        return;
+     }
+        
+   if (ret->val.b)
+     {
+        printf("[%s] is mounted!\n\tGrabbing more stats to fill your screen...\n", (char*)user_data);
+        e_udisks_get_all_properties(econ, user_data, hash_props, strdup(user_data));
+     }
+   else printf("[%s] is not mounted!\n", (char*)user_data);
+   free(user_data);
+}
+
+static void
+print_devs(void *user_data, void *reply_data, DBusError *error)
+{
+   E_Udev_Get_All_Devices_Return *ret = reply_data;
+   Eina_List *l;
+   char *udi;
+   
+   if (!ret || !ret->strings || dbus_error_is_set(error))
+     {
+        free(user_data);
+        dbus_error_free(error);
+        return;
+     }
+
+   EINA_LIST_FOREACH(ret->strings, l, udi)
+     {
+        if (!strcmp((char*)user_data, "disks"))
+          e_udisks_get_property(econ, udi, "DeviceIsMounted", test_mount, strdup(udi));
+        else
+          e_upower_get_all_properties(econ, udi, hash_props, strdup(udi));
+     }
+   free(user_data);
+}
+static int
+my_quit(void *data)
+{
+   ecore_main_loop_quit();
+   return 0;
+}
+
+int main(void)
+{
+   ecore_init();
+   eina_init();
+   e_dbus_init();
+   e_udev_init();
+   
+   econ = e_dbus_bus_get(DBUS_BUS_SYSTEM);
+   if (econ)
+     {
+        e_udisks_get_all_devices(econ, print_devs, strdup("disks"));
+        e_upower_get_all_devices(econ, print_devs, strdup("power"));
+     }
+   /*add a short timer to quit to try and ensure that all the tests run*/
+   ecore_timer_add(2, my_quit, NULL);
+   ecore_main_loop_begin();
+   
+   if (econ) e_dbus_connection_close(econ);
+   e_udev_shutdown();
+   e_dbus_shutdown();
+   eina_shutdown();
+   ecore_shutdown();
+   
+   return 0;
+}
Index: src/bin/Makefile.am
===================================================================
--- src/bin/Makefile.am	(revision 47995)
+++ src/bin/Makefile.am	(working copy)
@@ -6,6 +6,7 @@
 -I$(top_srcdir)/src/lib/connman \
 -I$(top_srcdir)/src/lib/bluez \
 -I$(top_srcdir)/src/lib/ofono \
+-I$(top_srcdir)/src/lib/udev \
 @EDBUS_CFLAGS@ \
 @EINA_CFLAGS@
 
@@ -27,13 +28,17 @@
 if BUILD_EOFONO
 EOFONO_PROG = e_dbus_ofono_test
 endif
+if BUILD_EUDEV
+EUDEV_PROG = e_dbus_udev_test
+endif
 
 bin_PROGRAMS = \
 $(EDBUS_PROG) \
 $(ENOTIFY_PROG) \
 $(ECONNMAN_PROG) \
 $(EBLUEZ_PROG) \
-$(EOFONO_PROG)
+$(EOFONO_PROG) \
+$(EUDEV_PROG)
 
 noinst_PROGRAMS = \
 $(ECONNMAN_PROG_NOINST)
@@ -91,3 +96,9 @@
 e_dbus_ofono_test_CPPFLAGS = $(EDBUS_CPPFLAGS)
 e_dbus_ofono_test_LDADD = $(top_builddir)/src/lib/ofono/libeofono.la
 endif
+
+if BUILD_EUDEV
+e_dbus_udev_test_SOURCES = e_dbus_udev_test.c
+e_dbus_udev_test_CPPFLAGS = $(EDBUS_CPPFLAGS)
+e_dbus_udev_test_LDADD = $(top_builddir)/src/lib/udev/libeudev.la
+endif
Index: configure.ac
===================================================================
--- configure.ac	(revision 47995)
+++ configure.ac	(working copy)
@@ -33,6 +33,7 @@
 eofono_release_info="-release $release"
 edbus_release_info="-release $release"
 ehal_release_info="-release $release"
+eudev_release_info="-release $release"
 enotify_release_info="-release $release"
 AC_SUBST(version_info)
 AC_SUBST(econnman_release_info)
@@ -40,6 +41,7 @@
 AC_SUBST(eofono_release_info)
 AC_SUBST(edbus_release_info)
 AC_SUBST(ehal_release_info)
+AC_SUBST(eudev_release_info)
 AC_SUBST(enotify_release_info)
 
 dnl Check enabled modules to build
@@ -48,6 +50,11 @@
    [enable_ehal=$enableval],
    [enable_ehal="yes"])
 
+AC_ARG_ENABLE([eudev],
+   [AC_HELP_STRING([--disable-eudev], [Disable eudev build])],
+   [enable_eudev=$enableval],
+   [enable_eudev="no"])
+
 AC_ARG_ENABLE([econnman],
    [AC_HELP_STRING([--enable-econnman], [Enable econnman build])],
    [enable_econnman=$enableval],
@@ -113,6 +120,7 @@
 fi
 
 AM_CONDITIONAL([BUILD_EHAL],     [test "x${enable_ehal}"     = "xyes"])
+AM_CONDITIONAL([BUILD_EUDEV],     [test "x${enable_eudev}"     = "xyes"])
 AM_CONDITIONAL([BUILD_ENOTIFY],  [test "x${enable_enotify}"  = "xyes"])
 AM_CONDITIONAL([BUILD_ECONNMAN], [test "x${enable_econnman}" = "xyes"])
 AM_CONDITIONAL([BUILD_EBLUEZ], [test "x${enable_ebluez}" = "xyes"])
@@ -136,6 +144,7 @@
 src/lib/Makefile
 src/lib/dbus/Makefile
 src/lib/hal/Makefile
+src/lib/udev/Makefile
 src/lib/notification/Makefile
 src/lib/connman/Makefile
 src/lib/bluez/Makefile
@@ -143,6 +152,7 @@
 src/bin/Makefile
 edbus.pc
 ehal.pc
+eudev.pc
 enotify.pc
 econnman.pc
 ebluez.pc
@@ -165,6 +175,7 @@
 echo "  Modules:"
 echo
 echo "    EHal...............: $enable_ehal"
+echo "    EUdev..............: $enable_eudev"
 echo "    EConnman...........: $enable_econnman"
 echo "    EBluez.............: $enable_ebluez"
 echo "    EOfono.............: $enable_eofono"
Index: TODO
===================================================================
--- TODO	(revision 0)
+++ TODO	(revision 0)
@@ -0,0 +1,4 @@
+e_dbus: fix up dox
+
+udev: add more functions
+
Index: Makefile.am
===================================================================
--- Makefile.am	(revision 47995)
+++ Makefile.am	(working copy)
@@ -23,6 +23,9 @@
 if BUILD_EOFONO
 EOFONO_PC = eofono.pc
 endif
-pkgconfig_DATA = edbus.pc $(EHAL_PC) $(ENOTIFY_PC) $(ECONNMAN_PC) $(EBLUEZ_PC) $(EOFONO_PC)
+if BUILD_EUDEV
+EUDEV_PC = eudev.pc
+endif
+pkgconfig_DATA = edbus.pc $(EHAL_PC) $(ENOTIFY_PC) $(ECONNMAN_PC) $(EBLUEZ_PC) $(EOFONO_PC) $(EUDEV_PC)
 
 EXTRA_DIST = e_dbus.spec
------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
enlightenment-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to