diff options
author | David Zeuthen <davidz@redhat.com> | 2008-03-03 15:57:06 -0500 |
---|---|---|
committer | David Zeuthen <davidz@redhat.com> | 2008-03-03 15:57:06 -0500 |
commit | 1f567f93c6ad23371cd75ed5507e24b7d707ca1d (patch) | |
tree | 15b596b6b9e3e242f94b967bb39f6bb8594c469f /libhal | |
parent | 71e114164819eaf0f9259236cc4ee9bae177b931 (diff) |
add methods and libhal api to get all devices in properties in one call
This is optionally used by the gvfs hal volume monitor.
Diffstat (limited to 'libhal')
-rw-r--r-- | libhal/libhal.c | 155 | ||||
-rw-r--r-- | libhal/libhal.h | 6 |
2 files changed, 161 insertions, 0 deletions
diff --git a/libhal/libhal.c b/libhal/libhal.c index 8ad8d494..4318485e 100644 --- a/libhal/libhal.c +++ b/libhal/libhal.c @@ -5113,3 +5113,158 @@ libhal_device_is_caller_privileged (LibHalContext *ctx, dbus_message_unref (reply); return value; } + +/** + * libhal_get_all_devices_with_properties: + * @out_num_devices: Return location for number of devices + * @out_udi: Return location for array of of udi's. Caller should free this with libhal_free_string_array() when done with it. + * @out_properties: Return location for array of #LibHalPropertySet objects. Caller should free each one of them with libhal_free_property_set() when done with it + * @error: Return location for error + * + * Get all devices in the hal database as well as all properties for each device. + * + * Return: %TRUE if success; %FALSE and @error will be set. + **/ +dbus_bool_t libhal_get_all_devices_with_properties (LibHalContext *ctx, + int *out_num_devices, + char ***out_udi, + LibHalPropertySet ***out_properties, + DBusError *error) +{ + + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter_array, reply_iter; + DBusError _error; + char **udi_array; + char **_udi_array; + LibHalPropertySet **prop_array; + LibHalPropertySet **_prop_array; + size_t count; + unsigned int n; + + LIBHAL_CHECK_LIBHALCONTEXT (ctx, FALSE); + LIBHAL_CHECK_LIBHALCONTEXT (out_num_devices, FALSE); + LIBHAL_CHECK_LIBHALCONTEXT (out_udi, FALSE); + LIBHAL_CHECK_LIBHALCONTEXT (out_properties, FALSE); + + *out_num_devices = 0; + *out_udi = NULL; + *out_properties = NULL; + + count = 0; + udi_array = NULL; + prop_array = NULL; + + message = dbus_message_new_method_call ("org.freedesktop.Hal", + "/org/freedesktop/Hal/Manager", + "org.freedesktop.Hal.Manager", + "GetAllDevicesWithProperties"); + if (message == NULL) { + fprintf (stderr, "%s %d : Could not allocate D-BUS message\n", __FILE__, __LINE__); + goto fail; + } + + dbus_error_init (&_error); + reply = dbus_connection_send_with_reply_and_block (ctx->connection, message, -1, &_error); + + dbus_move_error (&_error, error); + if (error != NULL && dbus_error_is_set (error)) { + dbus_message_unref (message); + goto fail; + } + if (reply == NULL) { + dbus_message_unref (message); + goto fail; + } + + /* now analyze reply */ + dbus_message_iter_init (reply, &reply_iter); + + if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) { + fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__); + goto fail; + } + + dbus_message_iter_recurse (&reply_iter, &iter_array); + + #define _BLOCK_SIZE 32 + + udi_array = (char **) malloc (sizeof (char*) * _BLOCK_SIZE); + if (udi_array == NULL) + goto fail; + + prop_array = (LibHalPropertySet **) malloc (sizeof (void*) * _BLOCK_SIZE); + if (prop_array == NULL) + goto fail; + + while (dbus_message_iter_get_arg_type (&iter_array) == DBUS_TYPE_STRUCT) { + DBusMessageIter iter_struct; + const char *value; + LibHalPropertySet *pset; + char *udi; + + if ((count % _BLOCK_SIZE) == 0 && count > 0) { + _udi_array = (char **) realloc (udi_array, sizeof (char*) * (count + _BLOCK_SIZE)); + _prop_array = (LibHalPropertySet **) realloc (prop_array, sizeof (void*) * (count+_BLOCK_SIZE)); + if (_udi_array == NULL || _prop_array == NULL) + goto fail; + udi_array = _udi_array; + prop_array = _prop_array; + } + + dbus_message_iter_recurse (&iter_array, &iter_struct); + + dbus_message_iter_get_basic (&iter_struct, &value); + udi = strdup (value); + if (udi == NULL) + goto fail; + + dbus_message_iter_next(&iter_struct); + + pset = get_property_set (&iter_struct); + + udi_array[count] = udi; + prop_array[count] = pset; + count++; + + dbus_message_iter_next (&iter_array); + } + + if ((count % _BLOCK_SIZE) == 0 && count > 0) { + _udi_array = (char **) realloc (udi_array, sizeof (char*) * (count + _BLOCK_SIZE)); + _prop_array = (LibHalPropertySet **) realloc (prop_array, sizeof (void*) * (count + _BLOCK_SIZE)); + if (_udi_array == NULL || _prop_array == NULL) + goto fail; + udi_array = _udi_array; + prop_array = _prop_array; + } + udi_array[count] = NULL; + prop_array[count] = NULL; + + *out_num_devices = count; + *out_udi = udi_array; + *out_properties = prop_array; + + dbus_message_unref (reply); + dbus_message_unref (message); + + return TRUE; + +fail: + if (udi_array != NULL) { + for (n = 0; n < count; n++) { + free (udi_array[n]); + } + free (udi_array); + } + + if (prop_array != NULL) { + for (n = 0; n < count; n++) { + free (prop_array[n]); + } + free (prop_array); + } + + return FALSE; +} diff --git a/libhal/libhal.h b/libhal/libhal.h index f5e3b54f..99ba191a 100644 --- a/libhal/libhal.h +++ b/libhal/libhal.h @@ -518,6 +518,12 @@ LibHalPropertySet *libhal_device_get_all_properties (LibHalContext *ctx, const char *udi, DBusError *error); +/* Get all devices and their properties */ +dbus_bool_t libhal_get_all_devices_with_properties (LibHalContext *ctx, + int *out_num_devices, + char ***out_udi, + LibHalPropertySet ***out_properties, + DBusError *error); /* sort all properties according to property name */ void libhal_property_set_sort (LibHalPropertySet *set); |