diff options
-rw-r--r-- | ChangeLog | 25 | ||||
-rw-r--r-- | configure.in | 4 | ||||
-rw-r--r-- | hald/hald_dbus.c | 25 | ||||
-rw-r--r-- | hald/linux2/coldplug.c | 207 | ||||
-rw-r--r-- | hald/linux2/osspec.c | 104 | ||||
-rw-r--r-- | hald/linux2/osspec_linux.h | 2 | ||||
-rw-r--r-- | libhal/libhal.c | 3 |
7 files changed, 231 insertions, 139 deletions
@@ -1,3 +1,28 @@ +2005-04-27 David Zeuthen <davidz@redhat.com> + + * hald/linux2/osspec_linux.h: Remove prototype for the function + hal_util_get_device_file(). + + * hald/linux2/osspec.c (hal_util_get_udevinfo_path): Remove + (hal_util_get_device_file): Remove + + * hald/linux2/coldplug.c (hal_util_get_udevinfo_path): Move from + osspec.c + (hal_util_get_sysfs_to_dev_map): New function + (coldplug_synthesize_events): Get the sysfs->dev map in one go using + 'udevinfo -d' available in udev since at least version 057. + + * configure.in: Bump dbus requirement to 0.33 since the new dbus is + out. + +2005-04-27 David Zeuthen <davidz@redhat.com> + + * libhal/libhal.c (libhal_device_set_property_helper): Don't leak the + DBusMessage objects + + * hald/hald_dbus.c (sender_has_privileges): Don't leak the error and + actually return FALSE if sender is unprivileged. Also fix up spelling. + 2005-04-18 David Zeuthen <davidz@redhat.com> * configure.in: Bump glib-2.0 requirement to 2.6.0; change dbus-1 and diff --git a/configure.in b/configure.in index 2fcdbb90..db69fb28 100644 --- a/configure.in +++ b/configure.in @@ -188,8 +188,8 @@ else fi fi -dbus_module="dbus-1 >= 0.32" -pkg_modules="glib-2.0 >= 2.6.0, gobject-2.0 >= 2.6.0, dbus-glib-1 >= 0.32, $dbus_module" +dbus_module="dbus-1 >= 0.33" +pkg_modules="glib-2.0 >= 2.6.0, gobject-2.0 >= 2.6.0, dbus-glib-1 >= 0.33, $dbus_module" PKG_CHECK_MODULES(PACKAGE, [$pkg_modules]) EXPAT_LIB="" diff --git a/hald/hald_dbus.c b/hald/hald_dbus.c index 2232f3a8..67b0fd34 100644 --- a/hald/hald_dbus.c +++ b/hald/hald_dbus.c @@ -1132,22 +1132,24 @@ sender_has_privileges (DBusConnection *connection, DBusMessage *message) HAL_DEBUG (("base_svc = %s", user_base_svc)); dbus_error_init (&error); - if ((user_uid = dbus_bus_get_unix_user (connection, user_base_svc, &error)) == (unsigned long) -1) { - HAL_WARNING (("Could not get uid for connection")); + user_uid = dbus_bus_get_unix_user (connection, user_base_svc, &error); + if (user_uid == (unsigned long) -1 || dbus_error_is_set (&error)) { + HAL_WARNING (("Could not get uid for connection: %s %s", error.name, error.message)); + dbus_error_free (&error); goto out; } HAL_INFO (("uid for caller is %ld", user_uid)); if (user_uid != 0 && user_uid != geteuid()) { - HAL_WARNING (("uid %d is doesn't have the right priviledges", user_uid)); + HAL_WARNING (("uid %d is not privileged", user_uid)); goto out; } ret = TRUE; out: - return TRUE; + return ret; } /** Set a property on a device. @@ -1217,51 +1219,36 @@ device_set_property (DBusConnection * connection, DBusMessage * message, dbus_bo case DBUS_TYPE_STRING: { const char *v; - dbus_message_iter_get_basic (&iter, &v); - rc = hal_device_property_set_string (device, key, v); - break; } case DBUS_TYPE_INT32: { dbus_int32_t v; - dbus_message_iter_get_basic (&iter, &v); - rc = hal_device_property_set_int (device, key, v); - break; } case DBUS_TYPE_UINT64: { dbus_uint64_t v; - dbus_message_iter_get_basic (&iter, &v); - rc = hal_device_property_set_uint64 (device, key, v); - break; } case DBUS_TYPE_DOUBLE: { double v; - dbus_message_iter_get_basic (&iter, &v); - rc = hal_device_property_set_double (device, key, v); - break; } case DBUS_TYPE_BOOLEAN: { dbus_bool_t v; - dbus_message_iter_get_basic (&iter, &v); - rc = hal_device_property_set_bool (device, key, v); - break; } default: diff --git a/hald/linux2/coldplug.c b/hald/linux2/coldplug.c index 71e512b0..baac1d2a 100644 --- a/hald/linux2/coldplug.c +++ b/hald/linux2/coldplug.c @@ -52,13 +52,164 @@ #define DMPREFIX "dm-" + + +/* Returns the path of the udevinfo program + * + * @return Path or NULL if udevinfo program is not found + */ +static const gchar * +hal_util_get_udevinfo_path (void) +{ + guint i; + struct stat s; + static gchar *path = NULL; + gchar *possible_paths[] = { + "/sbin/udevinfo", + "/usr/bin/udevinfo", + "/usr/sbin/udevinfo", + "/usr/local/sbin/udevinfo" + }; + + if (path != NULL) + return path; + + for (i = 0; i < sizeof (possible_paths) / sizeof (char *); i++) { + if (stat (possible_paths[i], &s) == 0 && S_ISREG (s.st_mode)) { + path = possible_paths[i]; + break; + } + } + return path; +} + +static GHashTable * +hal_util_get_sysfs_to_dev_map (void) +{ + GHashTable *sysfs_to_dev_map; + char *udevinfo_argv[7] = {NULL, "-d", NULL}; + char *udevinfo_stdout; + char *udevinfo_stderr; + int udevinfo_exitcode; + char *p; + char *q; + char *r; + int len; + char sysfs_path[PATH_MAX + 1]; + char device_file[PATH_MAX + 1]; + const char *sysfs_mount_path; + gboolean has_more_lines; + + sysfs_mount_path = get_hal_sysfs_path (); + + sysfs_to_dev_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + /* get path to udevinfo */ + udevinfo_argv[0] = (char *) hal_util_get_udevinfo_path (); + if (udevinfo_argv[0] == NULL) + goto error; + + + /* Invoke udevinfo */ + if (udevinfo_argv[0] == NULL || g_spawn_sync ("/", + udevinfo_argv, + NULL, + 0, + NULL, + NULL, + &udevinfo_stdout, + &udevinfo_stderr, + &udevinfo_exitcode, + NULL) != TRUE) { + HAL_ERROR (("Couldn't invoke %s", udevinfo_argv[0])); + goto error; + } + + if (udevinfo_exitcode != 0) { + HAL_ERROR (("%s returned %d", udevinfo_argv[0], udevinfo_exitcode)); + goto error; + } + + has_more_lines = TRUE; + + p = udevinfo_stdout; + + do { + if (*p == '\0') { + has_more_lines = FALSE; + break; + } + + for (q = p; *q != '\n' && *q != '\0' && *q != '='; q++) + ; + + len = q - p; + switch (*q) { + case '=': + strncpy (sysfs_path, p, len > PATH_MAX ? PATH_MAX : len); + sysfs_path [len > PATH_MAX ? PATH_MAX : len] = '\0'; + break; + + case '\n': + HAL_ERROR (("Expected '=', not '\\n' in line '%s'", p)); + goto error; + + case '\0': + HAL_ERROR (("Expected '=', not '\\0' in line '%s'", p)); + goto error; + + default: + HAL_ERROR (("Expected '=', not '%c' in line '%s'", *q, p)); + goto error; + } + + q++; + r = q; + for ( ; *q != '\n' && *q != '\0'; q++) + ; + + len = q - r; + switch (*q) { + case '\0': + has_more_lines = FALSE; + /* explicit fallthrough */ + + case '\n': + strncpy (device_file, r, len > PATH_MAX ? PATH_MAX : len); + device_file [len > PATH_MAX ? PATH_MAX : len] = '\0'; + break; + + default: + HAL_ERROR (("Expected '\\n' or '\\0', not '%c' in line '%s'", *q, p)); + goto error; + } + + g_hash_table_insert (sysfs_to_dev_map, g_strdup_printf ("%s%s", sysfs_mount_path, sysfs_path), + g_strdup(device_file)); + +#ifdef HAL_COLDPLUG_VERBOSE + printf ("Got '%s' -> '%s'\n", sysfs_path, device_file); +#endif + p = q + 1; + + } while (has_more_lines); + + return sysfs_to_dev_map; + +error: + g_hash_table_destroy (sysfs_to_dev_map); + return NULL; +} + + static gboolean -coldplug_synthesize_block_event(const gchar *f); +coldplug_synthesize_block_event(const gchar *f, GHashTable *sysfs_to_dev_map); static void coldplug_compute_visit_device (const gchar *path, GHashTable *sysfs_to_bus_map, - GHashTable *sysfs_to_class_in_devices_map); + GHashTable *sysfs_to_class_in_devices_map, + GHashTable *sysfs_to_dev_map); /* For debugging */ /*#define HAL_COLDPLUG_VERBOSE*/ @@ -146,6 +297,15 @@ coldplug_synthesize_events (void) */ GSList *sysfs_dm_dev = NULL; + GHashTable *sysfs_to_dev_map = NULL; + + + if ((sysfs_to_dev_map = hal_util_get_sysfs_to_dev_map ()) == NULL) { + HAL_ERROR (("Unable to get sysfs to dev map")); + goto error; + } + + /* build bus map */ sysfs_to_bus_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); g_snprintf (path, HAL_PATH_MAX, "%s/bus", get_hal_sysfs_path ()); @@ -271,7 +431,7 @@ coldplug_synthesize_events (void) while ((f1 = g_dir_read_name (dir1)) != NULL) { g_snprintf (path, HAL_PATH_MAX, "%s/devices/%s/%s", get_hal_sysfs_path (), f, f1); - coldplug_compute_visit_device (path, sysfs_to_bus_map, sysfs_to_class_in_devices_map); + coldplug_compute_visit_device (path, sysfs_to_bus_map, sysfs_to_class_in_devices_map, sysfs_to_dev_map); } g_dir_close (dir1); } @@ -287,6 +447,7 @@ coldplug_synthesize_events (void) gchar *sysfs_path; gchar *subsystem; HotplugEvent *hotplug_event; + gchar *device_file; sysfs_path = (gchar *) li->data; subsystem = (gchar *) li->next->data; @@ -299,7 +460,11 @@ coldplug_synthesize_events (void) hotplug_event->type = HOTPLUG_EVENT_SYSFS; g_strlcpy (hotplug_event->sysfs.subsystem, subsystem, sizeof (hotplug_event->sysfs.subsystem)); g_strlcpy (hotplug_event->sysfs.sysfs_path, sysfs_path, sizeof (hotplug_event->sysfs.sysfs_path)); - hal_util_get_device_file (sysfs_path, hotplug_event->sysfs.device_file, sizeof (hotplug_event->sysfs.device_file)); + + device_file = (gchar *) g_hash_table_lookup (sysfs_to_dev_map, sysfs_path); + if (device_file != NULL) { + strncpy (hotplug_event->sysfs.device_file, device_file, sizeof (hotplug_event->sysfs.device_file)); + } hotplug_event->sysfs.net_ifindex = -1; hotplug_event_enqueue (hotplug_event); @@ -322,17 +487,19 @@ coldplug_synthesize_events (void) sysfs_dm_dev = g_slist_append(sysfs_dm_dev, g_strdup(f)); continue; } - if (coldplug_synthesize_block_event(f) == FALSE) + if (coldplug_synthesize_block_event(f, sysfs_to_dev_map) == FALSE) goto error; } /* process all dm devices last so that their backing devices exist */ for (li = sysfs_dm_dev; li != NULL; li = g_slist_next (g_slist_next (li))) { - if (coldplug_synthesize_block_event(li->data) == FALSE) + if (coldplug_synthesize_block_event (li->data, sysfs_to_dev_map) == FALSE) goto error; g_free (li->data); } g_slist_free (sysfs_dm_dev); g_dir_close (dir); + + g_hash_table_destroy (sysfs_to_dev_map); return TRUE; error: @@ -341,7 +508,7 @@ error: } static gboolean -coldplug_synthesize_block_event(const gchar *f) +coldplug_synthesize_block_event(const gchar *f, GHashTable *sysfs_to_dev_map) { GDir *dir1; gsize flen; @@ -352,6 +519,7 @@ coldplug_synthesize_block_event(const gchar *f) gchar path[HAL_PATH_MAX]; gchar path1[HAL_PATH_MAX]; const gchar *f1; + gchar *device_file; g_snprintf (path, HAL_PATH_MAX, "%s/block/%s", get_hal_sysfs_path (), f); #ifdef HAL_COLDPLUG_VERBOSE @@ -371,7 +539,12 @@ coldplug_synthesize_block_event(const gchar *f) hotplug_event->type = HOTPLUG_EVENT_SYSFS; g_strlcpy (hotplug_event->sysfs.subsystem, "block", sizeof (hotplug_event->sysfs.subsystem)); g_strlcpy (hotplug_event->sysfs.sysfs_path, path, sizeof (hotplug_event->sysfs.sysfs_path)); - hal_util_get_device_file (path, hotplug_event->sysfs.device_file, sizeof (hotplug_event->sysfs.device_file)); + + device_file = (gchar *) g_hash_table_lookup (sysfs_to_dev_map, path); + if (device_file != NULL) { + strncpy (hotplug_event->sysfs.device_file, device_file, sizeof (hotplug_event->sysfs.device_file)); + } + if (normalized_target != NULL) g_strlcpy (hotplug_event->sysfs.wait_for_sysfs_path, normalized_target, sizeof (hotplug_event->sysfs.wait_for_sysfs_path)); else @@ -400,7 +573,10 @@ coldplug_synthesize_block_event(const gchar *f) g_strlcpy (hotplug_event->sysfs.subsystem, "block", sizeof (hotplug_event->sysfs.subsystem)); g_strlcpy (hotplug_event->sysfs.sysfs_path, path1, sizeof (hotplug_event->sysfs.sysfs_path)); g_strlcpy (hotplug_event->sysfs.wait_for_sysfs_path, path, sizeof (hotplug_event->sysfs.wait_for_sysfs_path)); - hal_util_get_device_file (path1, hotplug_event->sysfs.device_file, sizeof (hotplug_event->sysfs.device_file)); + device_file = (gchar *) g_hash_table_lookup (sysfs_to_dev_map, path1); + if (device_file != NULL) { + strncpy (hotplug_event->sysfs.device_file, device_file, sizeof (hotplug_event->sysfs.device_file)); + } hotplug_event->sysfs.net_ifindex = -1; hotplug_event_enqueue (hotplug_event); } @@ -416,7 +592,8 @@ error: static void coldplug_compute_visit_device (const gchar *path, GHashTable *sysfs_to_bus_map, - GHashTable *sysfs_to_class_in_devices_map) + GHashTable *sysfs_to_class_in_devices_map, + GHashTable *sysfs_to_dev_map) { gchar *bus; GError *err = NULL; @@ -455,6 +632,7 @@ coldplug_compute_visit_device (const gchar *path, for (i = class_devs; i != NULL; i = g_slist_next (g_slist_next (i))) { gchar *sysfs_path; gchar *subsystem; + gchar *device_file; HotplugEvent *hotplug_event; sysfs_path = (gchar *) i->data; @@ -468,7 +646,11 @@ coldplug_compute_visit_device (const gchar *path, hotplug_event->type = HOTPLUG_EVENT_SYSFS; g_strlcpy (hotplug_event->sysfs.subsystem, subsystem, sizeof (hotplug_event->sysfs.subsystem)); g_strlcpy (hotplug_event->sysfs.sysfs_path, sysfs_path, sizeof (hotplug_event->sysfs.sysfs_path)); - hal_util_get_device_file (sysfs_path, hotplug_event->sysfs.device_file, sizeof (hotplug_event->sysfs.device_file)); + + device_file = (gchar *) g_hash_table_lookup (sysfs_to_dev_map, sysfs_path); + if (device_file != NULL) { + strncpy (hotplug_event->sysfs.device_file, device_file, sizeof (hotplug_event->sysfs.device_file)); + } if (path != NULL) g_strlcpy (hotplug_event->sysfs.wait_for_sysfs_path, path, sizeof (hotplug_event->sysfs.wait_for_sysfs_path)); else @@ -496,7 +678,8 @@ coldplug_compute_visit_device (const gchar *path, /* recursion fun */ coldplug_compute_visit_device (path_child, sysfs_to_bus_map, - sysfs_to_class_in_devices_map); + sysfs_to_class_in_devices_map, + sysfs_to_dev_map); } } } diff --git a/hald/linux2/osspec.c b/hald/linux2/osspec.c index c229ecca..82c33ab3 100644 --- a/hald/linux2/osspec.c +++ b/hald/linux2/osspec.c @@ -522,110 +522,6 @@ osspec_device_reprobe (HalDevice *d) return hotplug_reprobe_tree (d); } -/* Returns the path of the udevinfo program - * - * @return Path or NULL if udevinfo program is not found - */ -static const gchar * -hal_util_get_udevinfo_path (void) -{ - guint i; - struct stat s; - static gchar *path = NULL; - gchar *possible_paths[] = { - "/sbin/udevinfo", - "/usr/bin/udevinfo", - "/usr/sbin/udevinfo", - "/usr/local/sbin/udevinfo" - }; - - if (path != NULL) - return path; - - for (i = 0; i < sizeof (possible_paths) / sizeof (char *); i++) { - if (stat (possible_paths[i], &s) == 0 && S_ISREG (s.st_mode)) { - path = possible_paths[i]; - break; - } - } - return path; -} - -/** Get the name of the special device file given the sysfs path. - * - * @param sysfs_path Path to class device in sysfs - * @param dev_file Where the special device file name should be stored - * @param dev_file_length Size of dev_file character array - * @return TRUE only if the device file could be found - */ -gboolean -hal_util_get_device_file (const gchar *sysfs_path, gchar *dev_file, gsize dev_file_length) -{ - int i; - gsize sysfs_path_len; - gsize sysfs_mount_path_len; - gchar sysfs_path_trunc[HAL_PATH_MAX]; - gchar sysfs_path_dev_trunc[HAL_PATH_MAX + 4]; - char *udev_argv[7] = { NULL, - "-r", "-q", "name", "-p", - sysfs_path_trunc, NULL }; - char *udev_stdout; - char *udev_stderr; - int udev_exitcode; - struct stat statbuf; - - /* check for dev file in sysfs path */ - sysfs_path_len = strlen (sysfs_path); - strncpy (sysfs_path_dev_trunc, sysfs_path, HAL_PATH_MAX); - strncat (sysfs_path_dev_trunc + sysfs_path_len, "/dev", 4); - if (stat (sysfs_path_dev_trunc, &statbuf) != 0) - return FALSE; - - /* get path to udevinfo */ - udev_argv[0] = (char *) hal_util_get_udevinfo_path (); - if (udev_argv[0] == NULL) - return FALSE; - - /* compute truncated sysfs path as udevinfo doesn't want the sysfs_mount_path (e.g. /sys) prefix */ - sysfs_mount_path_len = strlen (hal_sysfs_path); - if (strlen (sysfs_path) > sysfs_mount_path_len) { - strncpy (sysfs_path_trunc, sysfs_path + sysfs_mount_path_len, HAL_PATH_MAX - sysfs_mount_path_len); - } - - /* Now invoke udevinfo */ - if (udev_argv[0] == NULL || g_spawn_sync ("/", - udev_argv, - NULL, - 0, - NULL, - NULL, - &udev_stdout, - &udev_stderr, - &udev_exitcode, - NULL) != TRUE) { - HAL_ERROR (("Couldn't invoke %s", udev_argv[0])); - return FALSE; - } - - if (udev_exitcode != 0) { - HAL_ERROR (("%s returned %d for %s", udev_argv[0], udev_exitcode, sysfs_path_trunc)); - return FALSE; - } - - /* sanitize string returned by udev */ - for (i = 0; udev_stdout[i] != 0; i++) { - if (udev_stdout[i] == '\r' || udev_stdout[i] == '\n') { - udev_stdout[i] = 0; - break; - } - } - - /*HAL_INFO (("got device file %s for %s", udev_stdout, sysfs_path));*/ - - strncpy (dev_file, udev_stdout, dev_file_length); - return TRUE; -} - gboolean hal_util_set_driver (HalDevice *d, const char *property_name, const char *sysfs_path) { diff --git a/hald/linux2/osspec_linux.h b/hald/linux2/osspec_linux.h index a4eb21c1..e5ee9d64 100644 --- a/hald/linux2/osspec_linux.h +++ b/hald/linux2/osspec_linux.h @@ -33,8 +33,6 @@ const gchar *get_hal_sysfs_path (void); const gchar *get_hal_proc_path (void); -gboolean hal_util_get_device_file (const gchar *sysfs_path, gchar *dev_file, gsize dev_file_length); - gboolean hal_util_set_driver (HalDevice *d, const char *property_name, const char *sysfs_path); HalDevice *hal_util_find_closest_ancestor (const gchar *sysfs_path); diff --git a/libhal/libhal.c b/libhal/libhal.c index 669e02e6..e3707829 100644 --- a/libhal/libhal.c +++ b/libhal/libhal.c @@ -1499,6 +1499,9 @@ libhal_device_set_property_helper (LibHalContext *ctx, return FALSE; } + dbus_message_unref (message); + dbus_message_unref (reply); + return TRUE; } |