On Thu, 2008-09-11 at 00:20 +0200, Kay Sievers wrote:
> On Fri, 2008-08-29 at 22:39 +0200, Kay Sievers wrote:
> > To integrate DeviceKit properly with udev, udev provides a shared
> > library libudev now, wich is used by the DeviceKit daemon with this
> > patch, to retrieve udev device information and hook into device events.
> 
> Updated patch, which depends on the to-be-released udev 128. It replaces
> almost all sysfs and uevent details from DeviceKit code and uses libudev
> to retrieve device information, listen to events, and parse event
> messages.

Another update. I think we are pretty close now. It needs libudev from
the current git tree.

 configure.in            |    4 
 devkitd/Makefile.am     |    4 
 devkitd/devkit-daemon.c |  555 ++++++++++++++----------------------------------
 3 files changed, 176 insertions(+), 387 deletions(-)

Thanks,
Kay
diff --git a/configure.in b/configure.in
index edd0e26..76f7d31 100644
--- a/configure.in
+++ b/configure.in
@@ -116,6 +116,10 @@ PKG_CHECK_MODULES(DBUS_GLIB, [dbus-glib-1 >= 0.73])
 AC_SUBST(DBUS_GLIB_CFLAGS)
 AC_SUBST(DBUS_GLIB_LIBS)
 
+PKG_CHECK_MODULES(LIBUDEV, [libudev >= 129])
+AC_SUBST(LIBUDEV_CFLAGS)
+AC_SUBST(LIBUDEV_LIBS)
+
 if test "x$GCC" = "xyes"; then
   LDFLAGS="-Wl,--as-needed $LDFLAGS"
 fi
diff --git a/devkitd/Makefile.am b/devkitd/Makefile.am
index e58e14d..1df5701 100644
--- a/devkitd/Makefile.am
+++ b/devkitd/Makefile.am
@@ -39,10 +39,12 @@ devkit_daemon_CPPFLAGS = \
 	-DG_LOG_DOMAIN=\"devkit-daemon\" \
 	$(DISABLE_DEPRECATED) \
 	$(DBUS_GLIB_CFLAGS) \
+	$(LIBUDEV_CFLAGS) \
 	$(AM_CPPFLAGS)
 
 devkit_daemon_LDADD = \
-	$(DBUS_GLIB_LIBS)
+	$(DBUS_GLIB_LIBS) \
+	$(LIBUDEV_LIBS)
 
 dbusifdir = $(datadir)/dbus-1/interfaces
 dbusif_DATA = org.freedesktop.DeviceKit.xml
diff --git a/devkitd/devkit-daemon.c b/devkitd/devkit-daemon.c
index 608724f..43ba2cc 100644
--- a/devkitd/devkit-daemon.c
+++ b/devkitd/devkit-daemon.c
@@ -1,6 +1,7 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
  *
  * Copyright (C) 2008 David Zeuthen <[EMAIL PROTECTED]>
+ * Copyright (C) 2008 Kay Sievers <[EMAIL PROTECTED]>
  *
  * 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
@@ -47,6 +48,9 @@
 #include <dbus/dbus-glib.h>
 #include <dbus/dbus-glib-lowlevel.h>
 
+#define LIBUDEV_I_KNOW_THE_API_IS_SUBJECT_TO_CHANGE 1
+#include <libudev.h>
+
 #include "devkit-daemon.h"
 #include "devkit-daemon-glue.h"
 #include "devkit-marshal.h"
@@ -66,8 +70,9 @@ struct DevkitDaemonPrivate
         DBusGConnection   *system_bus_connection;
         DBusGProxy        *system_bus_proxy;
 
-	int                udev_socket;
-	GIOChannel        *udev_channel;
+        struct udev       *udev_ctx;
+        struct udev_monitor *udev_monitor;
+        GIOChannel        *udev_channel;
 
         GList             *inhibitors;
         guint              killtimer_id;
@@ -275,7 +280,6 @@ static void
 devkit_daemon_init (DevkitDaemon *daemon)
 {
         daemon->priv = DEVKIT_DAEMON_GET_PRIVATE (daemon);
-        daemon->priv->udev_socket = -1;
 }
 
 static void
@@ -305,9 +309,6 @@ devkit_daemon_finalize (GObject *object)
                 g_source_remove (daemon->priv->killtimer_id);
         }
 
-        if (daemon->priv->udev_socket != -1)
-                close (daemon->priv->udev_socket);
-
         if (unlink (PACKAGE_LOCALSTATE_DIR "/run/devkit/udev_socket") != 0) {
                 g_warning ("Cannot delete udev socket file: %m");
         }
@@ -315,144 +316,90 @@ devkit_daemon_finalize (GObject *object)
         if (daemon->priv->udev_channel != NULL)
                 g_io_channel_unref (daemon->priv->udev_channel);
 
+       if (daemon->priv->udev_monitor != NULL)
+               udev_monitor_unref (daemon->priv->udev_monitor);
+
+       if (daemon->priv->udev_ctx != NULL)
+               udev_unref (daemon->priv->udev_ctx);
+
         G_OBJECT_CLASS (devkit_daemon_parent_class)->finalize (object);
 }
 
+static char *
+_dupv8 (const char *s)
+{
+        const char *end_valid;
+
+        if (s == NULL)
+                return NULL;
+
+        if (!g_utf8_validate (s,
+                             -1,
+                             &end_valid)) {
+                g_warning ("The string '%s' is not valid UTF-8. Invalid characters begins at '%s'", s, end_valid);
+                return g_strndup (s, end_valid - s);
+        } else {
+                return g_strdup (s);
+        }
+}
 
 static gboolean
 receive_udev_data (GIOChannel *source, GIOCondition condition, gpointer user_data)
 {
         DevkitDaemon *daemon = user_data;
-	int fd;
-	int retval;
-	struct msghdr smsg;
-	struct cmsghdr *cmsg;
-	struct iovec iov;
-	struct ucred *cred;
-	char cred_msg[CMSG_SPACE(sizeof(struct ucred))];
-	char buf[4096];
-	size_t bufpos = 0;
-	const char *action;
-	const char *devpath;
-	const char *subsystem;
-
-	memset(buf, 0x00, sizeof (buf));
-	iov.iov_base = &buf;
-	iov.iov_len = sizeof (buf);
-	memset (&smsg, 0x00, sizeof (struct msghdr));
-	smsg.msg_iov = &iov;
-	smsg.msg_iovlen = 1;
-	smsg.msg_control = cred_msg;
-	smsg.msg_controllen = sizeof (cred_msg);
-
-	fd = g_io_channel_unix_get_fd (source);
-
-	retval = recvmsg (fd, &smsg, 0);
-	if (retval <  0) {
-		if (errno != EINTR)
-			g_warning ("Unable to receive message: %m");
-		goto out;
-	}
-	cmsg = CMSG_FIRSTHDR (&smsg);
-	cred = (struct ucred *) CMSG_DATA (cmsg);
-
-	if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) {
-		g_warning ("No sender credentials received, message ignored");
-		goto out;
-	}
-
-	if (cred->uid != 0) {
-		g_warning ("Sender uid=%d, message ignored", cred->uid);
-		goto out;
-	}
-
-	if (!strstr(buf, "@/")) {
-		g_warning ("invalid message format");
-		goto out;
-	}
+        struct udev_device *device;
+        const char *action;
+        const char *subsystem;
+        GPtrArray *device_file_symlinks = NULL;
+        GHashTable *properties = NULL;
+        struct udev_list_entry *list_entry;
 
-        const char *device_file;
-        GPtrArray *symlinks;
-        GHashTable *properties;
+        device = udev_monitor_receive_device (daemon->priv->udev_monitor);
+        if (device == NULL)
+                goto out;
 
-        symlinks = g_ptr_array_new ();
-        properties = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+        action = udev_device_get_action (device);
+        if (action == NULL)
+                goto out;
 
-        action = NULL;
-        devpath = NULL;
-        subsystem = NULL;
-        device_file = NULL;
-
-	while (bufpos < sizeof (buf)) {
-		size_t keylen;
-		char *key;
-
-		key = &buf[bufpos];
-		keylen = strlen(key);
-		if (keylen == 0)
-			break;
-		bufpos += keylen + 1;
-
-		if (strncmp (key, "ACTION=", 7) == 0) {
-			action = key + 7;
-		} else if (strncmp (key, "DEVPATH=", 8) == 0) {
-                        devpath = key + 8;
-		} else if (strncmp(key, "SUBSYSTEM=", 10) == 0) {
-                        subsystem = key + 10;
-		} else if (strncmp(key, "DEVNAME=", 8) == 0) {
-                        device_file = key + 8;
-		} else if (strncmp(key, "DEVLINKS=", 9) == 0) {
-                        char **tokens;
-                        int n;
-                        tokens = g_strsplit (key + 9, " ", 0);
-                        for (n = 0; tokens[n] != NULL; n++) {
-                                g_ptr_array_add (symlinks, g_strdup (tokens[n]));
-                        }
-                        g_strfreev (tokens);
-                } else {
-                        char *value;
-                        value = strchr (key, '=');
-                        if (value == NULL) {
-                                g_warning ("line '%s' is malformed; ignoring", key);
-                        } else {
-                                g_hash_table_insert (properties,
-                                                     g_strndup (key, value - key),
-                                                     g_strdup (value + 1));
-                        }
-                }
-	}
+        subsystem = udev_device_get_subsystem (device);
+        if (subsystem == NULL)
+                goto out;
 
-	if (action != NULL && devpath != NULL && subsystem != NULL) {
-                char *native_path;
-
-                native_path = g_build_filename ("/sys", devpath, NULL);
-
-                g_signal_emit (daemon, signals[DEVICE_EVENT_SIGNAL], 0,
-                               action,
-                               subsystem,
-                               native_path,
-                               device_file != NULL ? device_file : "",
-                               symlinks,
-                               properties,
-                               NULL);
-
-                g_free (native_path);
-	} else {
-                g_warning ("malformed message");
-        }
-
-        g_hash_table_destroy (properties);
-        g_ptr_array_foreach (symlinks, (GFunc) g_free, NULL);
+        properties = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+        if (properties == NULL)
+                goto out;
+        udev_list_entry_foreach (list_entry, udev_device_get_properties_list_entry (device))
+               g_hash_table_insert (properties,
+                                    _dupv8 (udev_list_entry_get_name (list_entry)),
+                                    _dupv8 (udev_list_entry_get_value (list_entry)));
+
+        device_file_symlinks = g_ptr_array_new ();
+        if (device_file_symlinks == NULL)
+                goto out;
+        udev_list_entry_foreach (list_entry, udev_device_get_devlinks_list_entry (device))
+                g_ptr_array_add (device_file_symlinks,
+                                 _dupv8 (udev_list_entry_get_name (list_entry)));
+
+        g_signal_emit (daemon, signals[DEVICE_EVENT_SIGNAL], 0,
+                       action,
+                       subsystem,
+                       g_strdup (udev_device_get_syspath (device)),
+                       udev_device_get_devnode (device) != NULL ? udev_device_get_devnode (device) : "",
+                       device_file_symlinks,
+                       properties,
+                       NULL);
 out:
-	return TRUE;
+        g_ptr_array_foreach (device_file_symlinks, (GFunc) g_free, NULL);
+        g_ptr_array_free (device_file_symlinks, TRUE);
+        g_hash_table_destroy (properties);
+        udev_device_unref (device);
+        return TRUE;
 }
 
 static gboolean
 register_daemon (DevkitDaemon *daemon)
 {
-	struct sockaddr_un saddr;
-	socklen_t addrlen;
-	const int on = 1;
         DBusConnection *connection;
         GError *error = NULL;
         DBusError dbus_error;
@@ -505,27 +452,27 @@ register_daemon (DevkitDaemon *daemon)
                 }
         }
 
-	/* setup socket for listening from messages from udev */
-	memset (&saddr, 0x00, sizeof(saddr));
-	saddr.sun_family = AF_LOCAL;
-	/* socket path */
-	strcpy (saddr.sun_path, PACKAGE_LOCALSTATE_DIR "/run/devkit/udev_socket");
-	addrlen = offsetof (struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1;
-	daemon->priv->udev_socket = socket (AF_LOCAL, SOCK_DGRAM, 0);
-	if (daemon->priv->udev_socket == -1) {
-		g_warning ("Couldn't open udev event socket: %m");
+        daemon->priv->udev_ctx = udev_new ();
+        if (daemon->priv->udev_ctx == NULL) {
+                g_warning ("Error creating libudev context: %m");
                 goto error;
-	}
+        }
+        if (getenv("LIBUDEV_DEBUG") != NULL)
+                udev_set_log_priority(daemon->priv->udev_ctx, 7);
 
-	if (bind (daemon->priv->udev_socket, (struct sockaddr *) &saddr, addrlen) < 0) {
-		g_warning ("Error binding to udev event socket: %m");
+        daemon->priv->udev_monitor = udev_monitor_new_from_socket (daemon->priv->udev_ctx,
+                                                                   PACKAGE_LOCALSTATE_DIR "/run/devkit/udev_socket");
+        if (daemon->priv->udev_monitor == NULL) {
+                g_warning ("Error creating udev monitor: %m");
                 goto error;
-	}
-	/* enable receiving of the sender credentials */
-	setsockopt (daemon->priv->udev_socket, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
-	daemon->priv->udev_channel = g_io_channel_unix_new (daemon->priv->udev_socket);
-	g_io_add_watch (daemon->priv->udev_channel, G_IO_IN, receive_udev_data, daemon);
-	g_io_channel_unref (daemon->priv->udev_channel);
+        }
+        if (udev_monitor_enable_receiving (daemon->priv->udev_monitor) < 0) {
+                g_warning ("Error binding to monitor socket: %m");
+                goto error;
+        }
+        daemon->priv->udev_channel = g_io_channel_unix_new (udev_monitor_get_fd (daemon->priv->udev_monitor));
+        g_io_add_watch (daemon->priv->udev_channel, G_IO_IN, receive_udev_data, daemon);
+        g_io_channel_unref (daemon->priv->udev_channel);
 
         devkit_daemon_reset_killtimer (daemon);
 
@@ -660,280 +607,116 @@ out:
                                              G_TYPE_INVALID))
 
 static void
-enumerate_add_device (const char *subsystem,
-                      const char *native_path,
-                      const char *device_file,
-                      GPtrArray *device_file_symlinks,
-                      GHashTable *properties,
-                      GPtrArray *devices)
+add_udev_device (GPtrArray *devices, struct udev_device *udev_device)
 {
+        const char *subsystem;
+        const char *native_path;
+        const char *device_file;
+        struct udev_list_entry *list_entry;
+        GPtrArray *device_file_symlinks;
+        GHashTable *properties;
         GValue elem = {0};
 
-        if (subsystem != NULL && native_path != NULL) {
-                g_value_init (&elem, STRUCT_TYPE);
-                g_value_take_boxed (&elem, dbus_g_type_specialized_construct (STRUCT_TYPE));
-                dbus_g_type_struct_set (&elem,
-                                        0, subsystem,
-                                        1, native_path,
-                                        2, device_file != NULL ? device_file : "",
-                                        3, device_file_symlinks->pdata,
-                                        4, properties,
-                                        G_MAXUINT);
-                g_ptr_array_add (devices, g_value_get_boxed (&elem));
-        } else {
-                g_warning ("either subsytem or native_path is NULL");
-        }
-}
+        g_return_if_fail (udev_device != NULL);
+        subsystem = udev_device_get_subsystem (udev_device);
+        g_return_if_fail (subsystem != NULL);
+        native_path = udev_device_get_syspath (udev_device);
+        g_return_if_fail (native_path != NULL);
 
-static char *
-_dupv8 (const char *s)
-{
-        const char *end_valid;
+        device_file = udev_device_get_devnode (udev_device);
+        device_file_symlinks = g_ptr_array_new ();
+        g_value_init (&elem, STRUCT_TYPE);
+        g_value_take_boxed (&elem, dbus_g_type_specialized_construct (STRUCT_TYPE));
 
-        if (!g_utf8_validate (s,
-                             -1,
-                             &end_valid)) {
-                g_warning ("The string '%s' is not valid UTF-8. Invalid characters begins at '%s'", s, end_valid);
-                return g_strndup (s, end_valid - s);
-        } else {
-                return g_strdup (s);
-        }
-}
-
-static void
-retrieve_data_from_udev (const char  *sysfs_path,
-                         char       **device_file,
-                         GPtrArray   *device_file_symlinks,
-                         GHashTable  *properties)
-{
-        int n;
-        char *s;
-        const char *p;
-        char *db_path;
-        char *db_file_path;
-        char *contents;
-        char **lines;
-
-        g_return_if_fail (g_str_has_prefix (sysfs_path, "/sys"));
-        g_return_if_fail (device_file != NULL);
-        g_return_if_fail (device_file_symlinks != NULL);
-        g_return_if_fail (properties != NULL);
-
-        db_file_path = NULL;
-        db_path = g_new0 (char, 3 * (strlen (sysfs_path) - 4) + 1);
-
-        for (p = sysfs_path + 4, n = 0; *p != '\0'; p++) {
-                switch (*p) {
-                case '/':
-                        db_path[n++] = '\\';
-                        db_path[n++] = 'x';
-                        db_path[n++] = '2';
-                        db_path[n++] = 'f';
-                        break;
-                case '\\':
-                        db_path[n++] = '\\';
-                        db_path[n++] = 'x';
-                        db_path[n++] = '5';
-                        db_path[n++] = 'c';
-                        break;
-                default:
-                        db_path[n++] = *p;
-                        break;
-                }
-        }
-        db_path[n++] = '\0';
-
-        db_file_path = g_build_filename ("/dev", ".udev", "db", db_path, NULL);
-
-        if (g_file_test (db_file_path, G_FILE_TEST_IS_SYMLINK)) {
-                char target[512];
-                ssize_t target_len;
-
-                target_len = readlink (db_file_path, target, sizeof target - 1);
-                if (target_len == -1) {
-                        g_warning ("Cannot resolve link %s: %m", db_file_path);
-                        goto out;
-                }
-                target[target_len] = '\0';
-
-                if (*device_file != NULL)
-                        g_free (*device_file);
-                s = _dupv8 (target);
-                *device_file = g_build_filename ("/dev", s, NULL);
-                g_free (s);
-
-        } else {
-                if (!g_file_get_contents (db_file_path, &contents, NULL, NULL)) {
-                        /* not necessary fatal; there may not be anything in the database for this path */
-                        goto out;
-                }
-                lines = g_strsplit (contents, "\n", 0);
-                for (n = 0; lines[n] != NULL; n++) {
-                        const char *line = lines[n];
-
-                        if (g_str_has_prefix (line, "N:")) {
-                                if (*device_file != NULL)
-                                        g_free (*device_file);
-                                s = _dupv8 (line + 2);
-                                *device_file = g_build_filename ("/dev", s, NULL);
-                                g_free (s);
-                        } else if (g_str_has_prefix (line, "S:")) {
-                                s = _dupv8 (line + 2);
-                                g_ptr_array_add (device_file_symlinks, g_build_filename ("/dev", s, NULL));
-                                g_free (s);
-                        } else if (g_str_has_prefix (line, "E:")) {
-                                char *key;
-                                key = strchr (line + 2, '=');
-                                if (key != NULL) {
-                                        *key = '\0';
-                                        g_hash_table_insert (properties, _dupv8 (line + 2), _dupv8 (key + 1));
-                                } else {
-                                        g_warning ("malformed property line '%s'", line + 2);
-                                }
-                        }
-                }
-
-                g_strfreev (lines);
-                g_free (contents);
-        }
+        udev_list_entry_foreach (list_entry, udev_device_get_devlinks_list_entry (udev_device))
+                g_ptr_array_add (device_file_symlinks,
+                                 _dupv8 (udev_list_entry_get_name (list_entry)));
+        g_ptr_array_add (device_file_symlinks, NULL);
 
-out:
-        g_free (db_file_path);
-        g_free (db_path);
+        properties = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+        udev_list_entry_foreach (list_entry, udev_device_get_properties_list_entry (udev_device))
+               g_hash_table_insert (properties,
+                                    _dupv8 (udev_list_entry_get_name (list_entry)),
+                                    _dupv8 (udev_list_entry_get_value (list_entry)));
+
+        dbus_g_type_struct_set (&elem,
+                                0, subsystem,
+                                1, native_path,
+                                2, device_file != NULL ? device_file : "",
+                                3, device_file_symlinks->pdata,
+                                4, properties,
+                                G_MAXUINT);
+        g_ptr_array_add (devices, g_value_get_boxed (&elem));
+
+        g_ptr_array_foreach (device_file_symlinks, (GFunc) g_free, NULL);
+        g_ptr_array_free (device_file_symlinks, TRUE);
+        g_hash_table_destroy (properties);
 }
 
 gboolean
-devkit_daemon_enumerate_by_subsystem  (DevkitDaemon           *daemon,
-                                       const char            **subsystems,
-                                       DBusGMethodInvocation  *context)
+devkit_daemon_enumerate_by_subsystem  (DevkitDaemon          *daemon,
+                                       const char           **subsystems,
+                                       DBusGMethodInvocation *context)
 {
-        int n, m;
+        struct udev_enumerate *udev_enumerate;
+        struct udev_list_entry *list_entry;
         GPtrArray *devices;
+        int n;
 
         devices = dbus_g_type_specialized_construct (dbus_g_type_get_collection ("GPtrArray", STRUCT_TYPE));
 
-        for (n = 0; subsystems[n] != NULL; n++) {
-                char *dirname;
-                GDir *dir;
-                const char *name;
-
-                /* collect devices from both /sys/class and /sys/buss */
-                for (m = 0; m < 2; m++) {
-                        switch (m) {
-                        case 0:
-                                dirname = g_build_filename ("/sys/class", subsystems[n], NULL);
-                                break;
-                        case 1:
-                                dirname = g_build_filename ("/sys/bus", subsystems[n], "devices", NULL);
-                                break;
-                        default:
-                                g_assert_not_reached ();
-                                break;
-                        }
-
-                        dir = g_dir_open (dirname, 0, NULL);
-                        while (dir != NULL && (name = g_dir_read_name (dir)) != NULL) {
-                                char *s;
-                                char sysfs_path[PATH_MAX];
-                                char *device_file;
-                                GPtrArray *device_file_symlinks;
-                                GHashTable *properties;
-
-                                s = g_build_filename (dirname, name, NULL);
-                                if (realpath (s, sysfs_path) == NULL) {
-                                        g_warning ("path '%s' is malformed", s);
-                                        g_free (s);
-                                        continue;
-                                }
-                                g_free (s);
-
-                                device_file = NULL;
-                                device_file_symlinks = g_ptr_array_new ();
-                                properties = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
-
-                                retrieve_data_from_udev (sysfs_path, &device_file, device_file_symlinks, properties);
-
-                                g_ptr_array_add (device_file_symlinks, NULL);
+        udev_enumerate = udev_enumerate_new (daemon->priv->udev_ctx);
+        if (udev_enumerate == NULL)
+                return FALSE;
 
-                                enumerate_add_device (subsystems[n],
-                                                      sysfs_path,
-                                                      device_file,
-                                                      device_file_symlinks,
-                                                      properties,
-                                                      devices);
+        for (n = 0; subsystems[n] != NULL; n++)
+               udev_enumerate_add_match_subsystem (udev_enumerate, subsystems[n]);
+        udev_enumerate_scan_devices (udev_enumerate);
+        udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(udev_enumerate)) {
+                struct udev_device *udev_device;
 
-                                g_free (device_file);
-                                g_ptr_array_foreach (device_file_symlinks, (GFunc) g_free, NULL);
-                                g_ptr_array_free (device_file_symlinks, TRUE);
-                                g_hash_table_destroy (properties);
-                        }
-                        if (dir != NULL)
-                                g_dir_close (dir);
-                }
-                g_free (dirname);
+                udev_device = udev_device_new_from_syspath (daemon->priv->udev_ctx,
+                                                            udev_list_entry_get_name(list_entry));
+                if (udev_device == NULL)
+                        continue;
+                add_udev_device (devices, udev_device);
+                udev_device_unref (udev_device);
         }
-
+        udev_enumerate_unref (udev_enumerate);
         dbus_g_method_return (context, devices);
         return TRUE;
 }
 
 gboolean
-devkit_daemon_enumerate_by_native_path  (DevkitDaemon           *daemon,
-                                         const char            **native_paths,
-                                         DBusGMethodInvocation  *context)
+devkit_daemon_enumerate_by_native_path (DevkitDaemon          *daemon,
+                                        const char           **native_paths,
+                                        DBusGMethodInvocation *context)
 {
+        struct udev_enumerate *udev_enumerate;
+        struct udev_list_entry *list_entry;
         int n;
         GPtrArray *devices;
-        char *s;
-        char sysfs_path[PATH_MAX];
-        char subsystem_path[PATH_MAX];
-        char *device_file;
-        char *subsystem;
-        GPtrArray *device_file_symlinks;
-        GHashTable *properties;
-        ssize_t len;
 
         devices = dbus_g_type_specialized_construct (dbus_g_type_get_collection ("GPtrArray", STRUCT_TYPE));
 
-        for (n = 0; native_paths[n] != NULL; n++) {
-                device_file = NULL;
-                subsystem = NULL;
-                device_file_symlinks = g_ptr_array_new ();
-                properties = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+        udev_enumerate = udev_enumerate_new (daemon->priv->udev_ctx);
+        if (udev_enumerate == NULL)
+                return FALSE;
 
-                if (realpath (native_paths[n], sysfs_path) == NULL) {
-                        g_warning ("path '%s' is malformed", native_paths[n]);
-                        continue;
-                }
+        for (n = 0; native_paths[n] != NULL; n++)
+                udev_enumerate_add_syspath (udev_enumerate, native_paths[n]);
 
-                s = g_build_filename (sysfs_path, "subsystem", NULL);
-                len = readlink (s, subsystem_path, sizeof subsystem_path - 1);
-                if (len < 0) {
-                        g_warning ("Cannot resolve symlink '%s'", s);
-                        g_free (s);
+        udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(udev_enumerate)) {
+                struct udev_device *udev_device;
+
+                udev_device = udev_device_new_from_syspath (daemon->priv->udev_ctx,
+                                                            udev_list_entry_get_name(list_entry));
+                if (udev_device == NULL)
                         continue;
-                }
-                subsystem_path[len] = '\0';
-                subsystem = g_path_get_basename (subsystem_path);
-                g_free (s);
-
-                retrieve_data_from_udev (sysfs_path, &device_file, device_file_symlinks, properties);
-                g_ptr_array_add (device_file_symlinks, NULL);
-
-                enumerate_add_device (subsystem,
-                                      sysfs_path,
-                                      device_file,
-                                      device_file_symlinks,
-                                      properties,
-                                      devices);
-
-                g_free (device_file);
-                g_free (subsystem);
-                g_ptr_array_foreach (device_file_symlinks, (GFunc) g_free, NULL);
-                g_ptr_array_free (device_file_symlinks, TRUE);
-                g_hash_table_destroy (properties);
+                add_udev_device (devices, udev_device);
+                udev_device_unref (udev_device);
         }
-
+        udev_enumerate_unref (udev_enumerate);
         dbus_g_method_return (context, devices);
         return TRUE;
 }
_______________________________________________
devkit-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/devkit-devel

Reply via email to