1N/A/***************************************************************************
1N/A * CVSID: $Id$
1N/A *
1N/A * libhal.c : HAL daemon C convenience library
1N/A *
1N/A * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
1N/A * Copyright (C) 2007 Codethink Ltd. Author Rob Taylor <rob.taylor@codethink.co.uk>
1N/A *
1N/A * Licensed under the Academic Free License version 2.1
1N/A *
1N/A * This program is free software; you can redistribute it and/or modify
1N/A * it under the terms of the GNU General Public License as published by
1N/A * the Free Software Foundation; either version 2 of the License, or
1N/A * (at your option) any later version.
1N/A *
1N/A * This program is distributed in the hope that it will be useful,
1N/A * but WITHOUT ANY WARRANTY; without even the implied warranty of
1N/A * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1N/A * GNU General Public License for more details.
1N/A *
1N/A * You should have received a copy of the GNU General Public License
1N/A * along with this program; if not, write to the Free Software
1N/A * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1N/A *
1N/A **************************************************************************/
1N/A
1N/A#ifdef HAVE_CONFIG_H
1N/A# include <config.h>
1N/A#endif
1N/A
1N/A#include <stdio.h>
1N/A#include <stdlib.h>
1N/A#include <string.h>
1N/A#include <dbus/dbus.h>
1N/A
1N/A#include "libhal.h"
1N/A
1N/A#ifdef ENABLE_NLS
1N/A# include <libintl.h>
1N/A# define _(String) dgettext (GETTEXT_PACKAGE, String)
1N/A# ifdef gettext_noop
1N/A# define N_(String) gettext_noop (String)
1N/A# else
1N/A# define N_(String) (String)
1N/A# endif
1N/A#else
1N/A/* Stubs that do something close enough. */
1N/A# define textdomain(String) (String)
1N/A# define gettext(String) (String)
1N/A# define dgettext(Domain,Message) (Message)
1N/A# define dcgettext(Domain,Message,Type) (Message)
1N/A# define bindtextdomain(Domain,Directory) (Domain)
1N/A# define _(String)
1N/A# define N_(String) (String)
1N/A#endif
1N/A
1N/A/**
1N/A * LIBHAL_CHECK_PARAM_VALID:
1N/A * @_param_: the prameter to check for
1N/A * @_name_: the name of the prameter (for debug output)
1N/A * @_ret_: what to use for return value if the prameter is NULL
1N/A *
1N/A * Handy macro for checking whether a parameter is valid and not NULL.
1N/A */
1N/A#define LIBHAL_CHECK_PARAM_VALID(_param_,_name_,_ret_) \
1N/A do { \
1N/A if (_param_ == NULL) { \
1N/A fprintf (stderr, \
1N/A "%s %d : invalid parameter. %s is NULL.\n", \
1N/A __FILE__, __LINE__, _name_); \
1N/A return _ret_; \
1N/A } \
1N/A } while(0)
1N/A
1N/A
1N/Astatic char **libhal_get_string_array_from_iter (DBusMessageIter *iter, int *num_elements);
1N/A
1N/Astatic dbus_bool_t libhal_property_fill_value_from_variant (LibHalProperty *p, DBusMessageIter *var_iter);
1N/A
1N/A
1N/A
1N/A/**
1N/A * libhal_free_string_array:
1N/A * @str_array: the array to be freed
1N/A *
1N/A * Frees a NULL-terminated array of strings. If passed NULL, does nothing.
1N/A */
1N/Avoid
1N/Alibhal_free_string_array (char **str_array)
1N/A{
1N/A if (str_array != NULL) {
1N/A int i;
1N/A
1N/A for (i = 0; str_array[i] != NULL; i++) {
1N/A free (str_array[i]);
1N/A str_array[i] = NULL;
1N/A }
1N/A free (str_array);
1N/A str_array = NULL;
1N/A }
1N/A}
1N/A
1N/A
1N/A/**
1N/A * libhal_get_string_array_from_iter:
1N/A * @iter: the message iterator to extract the strings from
1N/A * @num_elements: pointer to an integer where to store number of elements (can be NULL)
1N/A *
1N/A * Creates a NULL terminated array of strings from a dbus message iterator.
1N/A *
1N/A * Returns: pointer to the string array
1N/A */
1N/Astatic char **
1N/Alibhal_get_string_array_from_iter (DBusMessageIter *iter, int *num_elements)
1N/A{
1N/A int count;
1N/A char **buffer;
1N/A
1N/A count = 0;
1N/A buffer = (char **)malloc (sizeof (char *) * 8);
1N/A
1N/A if (buffer == NULL)
1N/A goto oom;
1N/A
1N/A buffer[0] = NULL;
1N/A while (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_STRING) {
1N/A const char *value;
1N/A char *str;
1N/A
1N/A if ((count % 8) == 0 && count != 0) {
1N/A buffer = realloc (buffer, sizeof (char *) * (count + 8));
1N/A if (buffer == NULL)
1N/A goto oom;
1N/A }
1N/A
1N/A dbus_message_iter_get_basic (iter, &value);
1N/A str = strdup (value);
1N/A if (str == NULL)
1N/A goto oom;
1N/A
1N/A buffer[count] = str;
1N/A
1N/A dbus_message_iter_next(iter);
1N/A count++;
1N/A }
1N/A
1N/A if ((count % 8) == 0) {
1N/A buffer = realloc (buffer, sizeof (char *) * (count + 1));
1N/A if (buffer == NULL)
1N/A goto oom;
1N/A }
1N/A
1N/A buffer[count] = NULL;
1N/A if (num_elements != NULL)
1N/A *num_elements = count;
1N/A return buffer;
1N/A
1N/Aoom:
1N/A fprintf (stderr, "%s %d : error allocating memory\n", __FILE__, __LINE__);
1N/A return NULL;
1N/A
1N/A}
1N/A
1N/A/**
1N/A * libhal_free_string:
1N/A * @str: the nul-terminated sting to free
1N/A *
1N/A * Used to free strings returned by libhal.
1N/A */
1N/Avoid
1N/Alibhal_free_string (char *str)
1N/A{
1N/A if (str != NULL) {
1N/A free (str);
1N/A str = NULL;
1N/A }
1N/A}
1N/A
1N/A
1N/A/**
1N/A * LibHalPropertySet:
1N/A *
1N/A * Represents a set of properties. Opaque; use the
1N/A * libhal_property_set_*() family of functions to access it.
1N/A */
1N/Astruct LibHalPropertySet_s {
1N/A unsigned int num_properties; /**< Number of properties in set */
1N/A LibHalProperty *properties_head;
1N/A /**< Pointer to first property or NULL
1N/A * if there are no properties */
1N/A};
1N/A
1N/A/**
1N/A * LibHalProperty:
1N/A *
1N/A * Represents a property. Opaque.
1N/A */
1N/Astruct LibHalProperty_s {
1N/A int type; /**< Type of property */
1N/A char *key; /**< ASCII string */
1N/A
1N/A /** Possible values of the property */
1N/A union {
1N/A char *str_value; /**< UTF-8 zero-terminated string */
1N/A dbus_int32_t int_value;
1N/A /**< 32-bit signed integer */
1N/A dbus_uint64_t uint64_value;
1N/A /**< 64-bit unsigned integer */
1N/A double double_value; /**< IEEE754 double precision float */
1N/A dbus_bool_t bool_value;
1N/A /**< Truth value */
1N/A
1N/A char **strlist_value; /**< List of UTF-8 zero-terminated strings */
1N/A } v;
1N/A
1N/A LibHalProperty *next; /**< Next property or NULL if this is
1N/A * the last */
1N/A};
1N/A
1N/A/**
1N/A * LibHalContext:
1N/A *
1N/A * Context for connection to the HAL daemon. Opaque, use the
1N/A * libhal_ctx_*() family of functions to access it.
1N/A */
1N/Astruct LibHalContext_s {
1N/A DBusConnection *connection; /**< D-BUS connection */
1N/A dbus_bool_t is_initialized; /**< Are we initialised */
1N/A dbus_bool_t is_shutdown; /**< Have we been shutdown */
1N/A dbus_bool_t cache_enabled; /**< Is the cache enabled */
1N/A dbus_bool_t is_direct; /**< Whether the connection to hald is direct */
1N/A
1N/A /** Device added */
1N/A LibHalDeviceAdded device_added;
1N/A
1N/A /** Device removed */
1N/A LibHalDeviceRemoved device_removed;
1N/A
1N/A /** Device got a new capability */
1N/A LibHalDeviceNewCapability device_new_capability;
1N/A
1N/A /** Device got a new capability */
1N/A LibHalDeviceLostCapability device_lost_capability;
1N/A
1N/A /** A property of a device changed */
1N/A LibHalDevicePropertyModified device_property_modified;
1N/A
1N/A /** A non-continous event on the device occured */
1N/A LibHalDeviceCondition device_condition;
1N/A
1N/A void *user_data; /**< User data */
1N/A};
1N/A
1N/A/**
1N/A * libhal_ctx_set_user_data:
1N/A * @ctx: the context for the connection to hald
1N/A * @user_data: user data
1N/A *
1N/A * Set user data for the context.
1N/A *
1N/A * Returns: TRUE if user data was successfully set, FALSE if otherwise
1N/A */
1N/Adbus_bool_t
1N/Alibhal_ctx_set_user_data(LibHalContext *ctx, void *user_data)
1N/A{
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A ctx->user_data = user_data;
1N/A return TRUE;
1N/A}
1N/A
1N/A/**
1N/A * libhal_ctx_get_user_data:
1N/A * @ctx: the context for the connection to hald
1N/A *
1N/A * Get user data for the context.
1N/A *
1N/A * Returns: opaque pointer stored through libhal_ctx_set_user_data() or NULL if not set.
1N/A */
1N/Avoid*
1N/Alibhal_ctx_get_user_data(LibHalContext *ctx)
1N/A{
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
1N/A return ctx->user_data;
1N/A}
1N/A
1N/A
1N/A/**
1N/A * libhal_property_fill_value_from_variant:
1N/A * @p: the property to fill in
1N/A * @var_iter: variant iterator to extract the value from
1N/A *
1N/A * Fills in the value for the LibHalProperty given a variant iterator.
1N/A *
1N/A * Returns: Whether the value was put in.
1N/A */
1N/Astatic dbus_bool_t
1N/Alibhal_property_fill_value_from_variant (LibHalProperty *p, DBusMessageIter *var_iter)
1N/A{
1N/A DBusMessageIter iter_array;
1N/A switch (p->type) {
1N/A case DBUS_TYPE_ARRAY:
1N/A if (dbus_message_iter_get_element_type (var_iter) != DBUS_TYPE_STRING)
1N/A return FALSE;
1N/A
1N/A dbus_message_iter_recurse (var_iter, &iter_array);
1N/A p->v.strlist_value = libhal_get_string_array_from_iter (&iter_array, NULL);
1N/A
1N/A p->type = LIBHAL_PROPERTY_TYPE_STRLIST;
1N/A
1N/A break;
1N/A case DBUS_TYPE_STRING:
1N/A {
1N/A const char *v;
1N/A
1N/A dbus_message_iter_get_basic (var_iter, &v);
1N/A
1N/A p->v.str_value = strdup (v);
1N/A if (p->v.str_value == NULL)
1N/A return FALSE;
1N/A p->type = LIBHAL_PROPERTY_TYPE_STRING;
1N/A
1N/A break;
1N/A }
1N/A case DBUS_TYPE_INT32:
1N/A {
1N/A dbus_int32_t v;
1N/A
1N/A dbus_message_iter_get_basic (var_iter, &v);
1N/A
1N/A p->v.int_value = v;
1N/A p->type = LIBHAL_PROPERTY_TYPE_INT32;
1N/A
1N/A break;
1N/A }
1N/A case DBUS_TYPE_UINT64:
1N/A {
1N/A dbus_uint64_t v;
1N/A
1N/A dbus_message_iter_get_basic (var_iter, &v);
1N/A
1N/A p->v.uint64_value = v;
1N/A p->type = LIBHAL_PROPERTY_TYPE_UINT64;
1N/A
1N/A break;
1N/A }
1N/A case DBUS_TYPE_DOUBLE:
1N/A {
1N/A double v;
1N/A
1N/A dbus_message_iter_get_basic (var_iter, &v);
1N/A
1N/A p->v.double_value = v;
1N/A p->type = LIBHAL_PROPERTY_TYPE_DOUBLE;
1N/A
1N/A break;
1N/A }
1N/A case DBUS_TYPE_BOOLEAN:
1N/A {
1N/A double v;
1N/A
1N/A dbus_message_iter_get_basic (var_iter, &v);
1N/A
1N/A p->v.double_value = v;
1N/A p->type = LIBHAL_PROPERTY_TYPE_BOOLEAN;
1N/A
1N/A break;
1N/A }
1N/A default:
1N/A /** @todo report error */
1N/A break;
1N/A }
1N/A
1N/A return TRUE;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_get_all_properties:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique id of device
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Retrieve all the properties on a device.
1N/A *
1N/A * Returns: An object represent all properties. Must be freed with libhal_free_property_set().
1N/A */
1N/ALibHalPropertySet *
1N/Alibhal_device_get_all_properties (LibHalContext *ctx, const char *udi, DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A DBusMessageIter reply_iter;
1N/A DBusMessageIter dict_iter;
1N/A LibHalPropertySet *result;
1N/A LibHalProperty *p_last;
1N/A DBusError _error;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
1N/A "org.freedesktop.Hal.Device",
1N/A "GetAllProperties");
1N/A
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return NULL;
1N/A }
1N/A
1N/A dbus_error_init (&_error);
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A &_error);
1N/A
1N/A dbus_move_error (&_error, error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A fprintf (stderr,
1N/A "%s %d : %s\n",
1N/A __FILE__, __LINE__, error->message);
1N/A
1N/A dbus_message_unref (message);
1N/A return NULL;
1N/A }
1N/A
1N/A if (reply == NULL) {
1N/A dbus_message_unref (message);
1N/A return NULL;
1N/A }
1N/A
1N/A dbus_message_iter_init (reply, &reply_iter);
1N/A
1N/A result = malloc (sizeof (LibHalPropertySet));
1N/A if (result == NULL)
1N/A goto oom;
1N/A/*
1N/A result->properties = malloc(sizeof(LibHalProperty)*result->num_properties);
1N/A if( result->properties==NULL )
1N/A {
1N/A /// @todo cleanup
1N/A return NULL;
1N/A }
1N/A*/
1N/A
1N/A result->properties_head = NULL;
1N/A result->num_properties = 0;
1N/A
1N/A if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY &&
1N/A dbus_message_iter_get_element_type (&reply_iter) != DBUS_TYPE_DICT_ENTRY) {
1N/A fprintf (stderr, "%s %d : error, expecting an array of dict entries\n",
1N/A __FILE__, __LINE__);
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return NULL;
1N/A }
1N/A
1N/A dbus_message_iter_recurse (&reply_iter, &dict_iter);
1N/A
1N/A p_last = NULL;
1N/A
1N/A while (dbus_message_iter_get_arg_type (&dict_iter) == DBUS_TYPE_DICT_ENTRY)
1N/A {
1N/A DBusMessageIter dict_entry_iter, var_iter;
1N/A const char *key;
1N/A LibHalProperty *p;
1N/A
1N/A dbus_message_iter_recurse (&dict_iter, &dict_entry_iter);
1N/A
1N/A dbus_message_iter_get_basic (&dict_entry_iter, &key);
1N/A
1N/A p = malloc (sizeof (LibHalProperty));
1N/A if (p == NULL)
1N/A goto oom;
1N/A
1N/A p->next = NULL;
1N/A
1N/A if (result->num_properties == 0)
1N/A result->properties_head = p;
1N/A
1N/A if (p_last != NULL)
1N/A p_last->next = p;
1N/A
1N/A p_last = p;
1N/A
1N/A p->key = strdup (key);
1N/A if (p->key == NULL)
1N/A goto oom;
1N/A
1N/A dbus_message_iter_next (&dict_entry_iter);
1N/A
1N/A dbus_message_iter_recurse (&dict_entry_iter, &var_iter);
1N/A
1N/A
1N/A p->type = dbus_message_iter_get_arg_type (&var_iter);
1N/A
1N/A result->num_properties++;
1N/A
1N/A if(!libhal_property_fill_value_from_variant (p, &var_iter))
1N/A goto oom;
1N/A
1N/A dbus_message_iter_next (&dict_iter);
1N/A }
1N/A
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A
1N/A return result;
1N/A
1N/Aoom:
1N/A fprintf (stderr,
1N/A "%s %d : error allocating memory\n",
1N/A __FILE__, __LINE__);
1N/A /** @todo FIXME cleanup */
1N/A return NULL;
1N/A}
1N/A
1N/A/**
1N/A * libhal_free_property_set:
1N/A * @set: property-set to free
1N/A *
1N/A * Free a property set earlier obtained with libhal_device_get_all_properties().
1N/A */
1N/Avoid
1N/Alibhal_free_property_set (LibHalPropertySet * set)
1N/A{
1N/A LibHalProperty *p;
1N/A LibHalProperty *q;
1N/A
1N/A if (set == NULL)
1N/A return;
1N/A
1N/A for (p = set->properties_head; p != NULL; p = q) {
1N/A free (p->key);
1N/A if (p->type == DBUS_TYPE_STRING)
1N/A free (p->v.str_value);
1N/A if (p->type == LIBHAL_PROPERTY_TYPE_STRLIST)
1N/A libhal_free_string_array (p->v.strlist_value);
1N/A q = p->next;
1N/A free (p);
1N/A }
1N/A free (set);
1N/A}
1N/A
1N/A/**
1N/A * libhal_property_set_get_num_elems:
1N/A * @set: property set to consider
1N/A *
1N/A * Get the number of properties in a property set.
1N/A *
1N/A * Returns: number of properties in given property set
1N/A */
1N/Aunsigned int
1N/Alibhal_property_set_get_num_elems (LibHalPropertySet *set)
1N/A{
1N/A unsigned int num_elems;
1N/A LibHalProperty *p;
1N/A
1N/A if (set == NULL)
1N/A return 0;
1N/A
1N/A num_elems = 0;
1N/A for (p = set->properties_head; p != NULL; p = p->next)
1N/A num_elems++;
1N/A
1N/A return num_elems;
1N/A}
1N/A
1N/Astatic LibHalProperty *
1N/Aproperty_set_lookup (const LibHalPropertySet *set, const char *key)
1N/A{
1N/A LibHalProperty *p;
1N/A
1N/A LIBHAL_CHECK_PARAM_VALID(set, "*set", NULL);
1N/A LIBHAL_CHECK_PARAM_VALID(key, "*key", NULL);
1N/A
1N/A for (p = set->properties_head; p != NULL; p = p->next)
1N/A if (strcmp (key, p->key) == 0)
1N/A return p;
1N/A
1N/A return NULL;
1N/A}
1N/A
1N/A/**
1N/A * libhal_ps_get_type:
1N/A * @set: property set
1N/A * @key: name of property to inspect
1N/A *
1N/A * Get the type of a given property.
1N/A *
1N/A * Returns: the #LibHalPropertyType of the given property,
1N/A * LIBHAL_PROPERTY_TYPE_INVALID if property is not in the set
1N/A */
1N/ALibHalPropertyType
1N/Alibhal_ps_get_type (const LibHalPropertySet *set, const char *key)
1N/A{
1N/A LibHalProperty *p = property_set_lookup (set, key);
1N/A
1N/A LIBHAL_CHECK_PARAM_VALID(set, "*set", LIBHAL_PROPERTY_TYPE_INVALID);
1N/A LIBHAL_CHECK_PARAM_VALID(key, "*key", LIBHAL_PROPERTY_TYPE_INVALID);
1N/A
1N/A p = property_set_lookup (set, key);
1N/A if (p) return p->type;
1N/A else return LIBHAL_PROPERTY_TYPE_INVALID;
1N/A}
1N/A
1N/A/**
1N/A * libhal_ps_get_string:
1N/A * @set: property set
1N/A * @key: name of property to inspect
1N/A *
1N/A * Get the value of a property of type string.
1N/A *
1N/A * Returns: UTF8 nul-terminated string. This pointer is only valid
1N/A * until libhal_free_property_set() is invoked on the property set
1N/A * this property belongs to. NULL if property is not in the set or not a string
1N/A */
1N/Aconst char *
1N/Alibhal_ps_get_string (const LibHalPropertySet *set, const char *key)
1N/A{
1N/A LibHalProperty *p;
1N/A
1N/A LIBHAL_CHECK_PARAM_VALID(set, "*set", NULL);
1N/A LIBHAL_CHECK_PARAM_VALID(key, "*key", NULL);
1N/A
1N/A p = property_set_lookup (set, key);
1N/A if (p && p->type == LIBHAL_PROPERTY_TYPE_STRING)
1N/A return p->v.str_value;
1N/A else return NULL;
1N/A}
1N/A
1N/A/**
1N/A * libhal_ps_get_int:
1N/A * @set: property set
1N/A * @key: name of property to inspect
1N/A *
1N/A * Get the value of a property of type signed integer.
1N/A *
1N/A * Returns: property value (32-bit signed integer)
1N/A */
1N/Adbus_int32_t
1N/Alibhal_ps_get_int32 (const LibHalPropertySet *set, const char *key)
1N/A{
1N/A LibHalProperty *p;
1N/A
1N/A LIBHAL_CHECK_PARAM_VALID(set, "*set", 0);
1N/A LIBHAL_CHECK_PARAM_VALID(key, "*key", 0);
1N/A
1N/A p = property_set_lookup (set, key);
1N/A if (p && p->type == LIBHAL_PROPERTY_TYPE_INT32)
1N/A return p->v.int_value;
1N/A else return 0;
1N/A}
1N/A
1N/A/**
1N/A * libhal_ps_get_uint64:
1N/A * @set: property set
1N/A * @key: name of property to inspect
1N/A *
1N/A * Get the value of a property of type unsigned integer.
1N/A *
1N/A * Returns: property value (64-bit unsigned integer)
1N/A */
1N/Adbus_uint64_t
1N/Alibhal_ps_get_uint64 (const LibHalPropertySet *set, const char *key)
1N/A{
1N/A LibHalProperty *p;
1N/A
1N/A LIBHAL_CHECK_PARAM_VALID(set, "*set", 0);
1N/A LIBHAL_CHECK_PARAM_VALID(key, "*key", 0);
1N/A
1N/A p = property_set_lookup (set, key);
1N/A if (p && p->type == LIBHAL_PROPERTY_TYPE_UINT64)
1N/A return p->v.uint64_value;
1N/A else return 0;
1N/A}
1N/A
1N/A/**
1N/A * libhal_ps_get_double:
1N/A * @set: property set
1N/A * @key: name of property to inspect
1N/A *
1N/A * Get the value of a property of type double.
1N/A *
1N/A * Returns: property value (IEEE754 double precision float)
1N/A */
1N/Adouble
1N/Alibhal_ps_get_double (const LibHalPropertySet *set, const char *key)
1N/A{
1N/A LibHalProperty *p;
1N/A
1N/A LIBHAL_CHECK_PARAM_VALID(set, "*set", 0.0);
1N/A LIBHAL_CHECK_PARAM_VALID(key, "*key", 0.0);
1N/A
1N/A p = property_set_lookup (set, key);
1N/A if (p && p->type == LIBHAL_PROPERTY_TYPE_DOUBLE)
1N/A return p->v.double_value;
1N/A else return 0.0;
1N/A}
1N/A
1N/A/**
1N/A * libhal_ps_get_bool:
1N/A * @set: property set
1N/A * @key: name of property to inspect
1N/A *
1N/A * Get the value of a property of type bool.
1N/A *
1N/A * Returns: property value (bool)
1N/A */
1N/Adbus_bool_t
1N/Alibhal_ps_get_bool (const LibHalPropertySet *set, const char *key)
1N/A{
1N/A LibHalProperty *p;
1N/A
1N/A LIBHAL_CHECK_PARAM_VALID(set, "*set", FALSE);
1N/A LIBHAL_CHECK_PARAM_VALID(key, "*key", FALSE);
1N/A
1N/A p = property_set_lookup (set, key);
1N/A if (p && p->type == LIBHAL_PROPERTY_TYPE_BOOLEAN)
1N/A return p->v.bool_value;
1N/A else return FALSE;
1N/A}
1N/A
1N/A/**
1N/A * libhal_ps_get_strlist:
1N/A * @set: property set
1N/A * @key: name of property to inspect
1N/A *
1N/A * Get the value of a property of type string list.
1N/A *
1N/A * Returns: pointer to array of strings, this is owned by the property set
1N/A */
1N/Aconst char *const *
1N/Alibhal_ps_get_strlist (const LibHalPropertySet *set, const char *key)
1N/A{
1N/A LibHalProperty *p;
1N/A
1N/A LIBHAL_CHECK_PARAM_VALID(set, "*set", NULL);
1N/A LIBHAL_CHECK_PARAM_VALID(key, "*key", NULL);
1N/A
1N/A p = property_set_lookup (set, key);
1N/A if (p && p->type == LIBHAL_PROPERTY_TYPE_STRLIST)
1N/A return (const char *const *) p->v.strlist_value;
1N/A else return NULL;
1N/A}
1N/A
1N/A
1N/A/**
1N/A * libhal_psi_init:
1N/A * @iter: iterator object
1N/A * @set: property set to iterate over
1N/A *
1N/A * Initialize a property set iterator.
1N/A *
1N/A */
1N/Avoid
1N/Alibhal_psi_init (LibHalPropertySetIterator * iter, LibHalPropertySet * set)
1N/A{
1N/A if (set == NULL)
1N/A return;
1N/A
1N/A iter->set = set;
1N/A iter->idx = 0;
1N/A iter->cur_prop = set->properties_head;
1N/A}
1N/A
1N/A
1N/A/**
1N/A * libhal_psi_has_more:
1N/A * @iter: iterator object
1N/A *
1N/A * Determine whether there are more properties to iterate over.
1N/A *
1N/A * Returns: TRUE if there are more properties, FALSE otherwise.
1N/A */
1N/Adbus_bool_t
1N/Alibhal_psi_has_more (LibHalPropertySetIterator * iter)
1N/A{
1N/A return iter->idx < iter->set->num_properties;
1N/A}
1N/A
1N/A/**
1N/A * libhal_psi_next:
1N/A * @iter: iterator object
1N/A *
1N/A * Advance iterator to next property.
1N/A */
1N/Avoid
1N/Alibhal_psi_next (LibHalPropertySetIterator * iter)
1N/A{
1N/A iter->idx++;
1N/A iter->cur_prop = iter->cur_prop->next;
1N/A}
1N/A
1N/A/**
1N/A * libhal_psi_get_type:
1N/A * @iter: iterator object
1N/A *
1N/A * Get type of property.
1N/A *
1N/A * Returns: the property type at the iterator's position
1N/A */
1N/ALibHalPropertyType
1N/Alibhal_psi_get_type (LibHalPropertySetIterator * iter)
1N/A{
1N/A return iter->cur_prop->type;
1N/A}
1N/A
1N/A/**
1N/A * libhal_psi_get_key:
1N/A * @iter: iterator object
1N/A *
1N/A * Get the key of a property.
1N/A *
1N/A * Returns: ASCII nul-terminated string. This pointer is only valid
1N/A * until libhal_free_property_set() is invoked on the property set
1N/A * this property belongs to.
1N/A */
1N/Achar *
1N/Alibhal_psi_get_key (LibHalPropertySetIterator * iter)
1N/A{
1N/A return iter->cur_prop->key;
1N/A}
1N/A
1N/A/**
1N/A * libhal_psi_get_string:
1N/A * @iter: iterator object
1N/A *
1N/A * Get the value of a property of type string.
1N/A *
1N/A * Returns: UTF8 nul-terminated string. This pointer is only valid
1N/A * until libhal_free_property_set() is invoked on the property set
1N/A * this property belongs to.
1N/A */
1N/Achar *
1N/Alibhal_psi_get_string (LibHalPropertySetIterator * iter)
1N/A{
1N/A return iter->cur_prop->v.str_value;
1N/A}
1N/A
1N/A/**
1N/A * libhal_psi_get_int:
1N/A * @iter: iterator object
1N/A *
1N/A * Get the value of a property of type signed integer.
1N/A *
1N/A * Returns: property value (32-bit signed integer)
1N/A */
1N/Adbus_int32_t
1N/Alibhal_psi_get_int (LibHalPropertySetIterator * iter)
1N/A{
1N/A return iter->cur_prop->v.int_value;
1N/A}
1N/A
1N/A/**
1N/A * libhal_psi_get_uint64:
1N/A * @iter: iterator object
1N/A *
1N/A * Get the value of a property of type unsigned integer.
1N/A *
1N/A * Returns: property value (64-bit unsigned integer)
1N/A */
1N/Adbus_uint64_t
1N/Alibhal_psi_get_uint64 (LibHalPropertySetIterator * iter)
1N/A{
1N/A return iter->cur_prop->v.uint64_value;
1N/A}
1N/A
1N/A/**
1N/A * libhal_psi_get_double:
1N/A * @iter: iterator object
1N/A *
1N/A * Get the value of a property of type double.
1N/A *
1N/A * Returns: property value (IEEE754 double precision float)
1N/A */
1N/Adouble
1N/Alibhal_psi_get_double (LibHalPropertySetIterator * iter)
1N/A{
1N/A return iter->cur_prop->v.double_value;
1N/A}
1N/A
1N/A/**
1N/A * libhal_psi_get_bool:
1N/A * @iter: iterator object
1N/A *
1N/A * Get the value of a property of type bool.
1N/A *
1N/A * Returns: property value (bool)
1N/A */
1N/Adbus_bool_t
1N/Alibhal_psi_get_bool (LibHalPropertySetIterator * iter)
1N/A{
1N/A return iter->cur_prop->v.bool_value;
1N/A}
1N/A
1N/A/**
1N/A * libhal_psi_get_strlist:
1N/A * @iter: iterator object
1N/A *
1N/A * Get the value of a property of type string list.
1N/A *
1N/A * Returns: pointer to array of strings
1N/A */
1N/Achar **
1N/Alibhal_psi_get_strlist (LibHalPropertySetIterator * iter)
1N/A{
1N/A return iter->cur_prop->v.strlist_value;
1N/A}
1N/A
1N/A
1N/Astatic DBusHandlerResult
1N/Afilter_func (DBusConnection * connection,
1N/A DBusMessage * message, void *user_data)
1N/A{
1N/A const char *object_path;
1N/A DBusError error;
1N/A LibHalContext *ctx = (LibHalContext *) user_data;
1N/A
1N/A if (ctx->is_shutdown)
1N/A return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1N/A
1N/A dbus_error_init (&error);
1N/A
1N/A object_path = dbus_message_get_path (message);
1N/A
1N/A /*printf("*** in filter_func, object_path=%s\n", object_path);*/
1N/A
1N/A if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager",
1N/A "DeviceAdded")) {
1N/A char *udi;
1N/A if (dbus_message_get_args (message, &error,
1N/A DBUS_TYPE_STRING, &udi,
1N/A DBUS_TYPE_INVALID)) {
1N/A if (ctx->device_added != NULL) {
1N/A ctx->device_added (ctx, udi);
1N/A }
1N/A } else {
1N/A LIBHAL_FREE_DBUS_ERROR(&error);
1N/A }
1N/A return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1N/A } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager", "DeviceRemoved")) {
1N/A char *udi;
1N/A if (dbus_message_get_args (message, &error,
1N/A DBUS_TYPE_STRING, &udi,
1N/A DBUS_TYPE_INVALID)) {
1N/A if (ctx->device_removed != NULL) {
1N/A ctx->device_removed (ctx, udi);
1N/A }
1N/A } else {
1N/A LIBHAL_FREE_DBUS_ERROR(&error);
1N/A }
1N/A return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1N/A } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager","NewCapability")) {
1N/A char *udi;
1N/A char *capability;
1N/A if (dbus_message_get_args (message, &error,
1N/A DBUS_TYPE_STRING, &udi,
1N/A DBUS_TYPE_STRING, &capability,
1N/A DBUS_TYPE_INVALID)) {
1N/A if (ctx->device_new_capability != NULL) {
1N/A ctx->device_new_capability (ctx, udi, capability);
1N/A }
1N/A } else {
1N/A LIBHAL_FREE_DBUS_ERROR(&error);
1N/A }
1N/A return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1N/A } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Device", "Condition")) {
1N/A char *condition_name;
1N/A char *condition_detail;
1N/A if (dbus_message_get_args (message, &error,
1N/A DBUS_TYPE_STRING, &condition_name,
1N/A DBUS_TYPE_STRING, &condition_detail,
1N/A DBUS_TYPE_INVALID)) {
1N/A if (ctx->device_condition != NULL) {
1N/A ctx->device_condition (ctx, object_path, condition_name, condition_detail);
1N/A }
1N/A } else {
1N/A LIBHAL_FREE_DBUS_ERROR(&error);
1N/A }
1N/A return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1N/A } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Device", "PropertyModified")) {
1N/A if (ctx->device_property_modified != NULL) {
1N/A int i;
1N/A char *key;
1N/A dbus_bool_t removed;
1N/A dbus_bool_t added;
1N/A int num_modifications;
1N/A DBusMessageIter iter;
1N/A DBusMessageIter iter_array;
1N/A
1N/A dbus_message_iter_init (message, &iter);
1N/A dbus_message_iter_get_basic (&iter, &num_modifications);
1N/A dbus_message_iter_next (&iter);
1N/A
1N/A dbus_message_iter_recurse (&iter, &iter_array);
1N/A
1N/A for (i = 0; i < num_modifications; i++) {
1N/A DBusMessageIter iter_struct;
1N/A
1N/A dbus_message_iter_recurse (&iter_array, &iter_struct);
1N/A
1N/A dbus_message_iter_get_basic (&iter_struct, &key);
1N/A dbus_message_iter_next (&iter_struct);
1N/A dbus_message_iter_get_basic (&iter_struct, &removed);
1N/A dbus_message_iter_next (&iter_struct);
1N/A dbus_message_iter_get_basic (&iter_struct, &added);
1N/A
1N/A ctx->device_property_modified (ctx,
1N/A object_path,
1N/A key, removed,
1N/A added);
1N/A
1N/A dbus_message_iter_next (&iter_array);
1N/A }
1N/A
1N/A }
1N/A return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1N/A }
1N/A
1N/A return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1N/A}
1N/A
1N/A/* for i18n purposes */
1N/Astatic dbus_bool_t libhal_already_initialized_once = FALSE;
1N/A
1N/A
1N/A/**
1N/A * libhal_get_all_devices:
1N/A * @ctx: the context for the connection to hald
1N/A * @num_devices: the number of devices will be stored here
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Get all devices in the Global Device List (GDL).
1N/A *
1N/A * Returns: An array of device identifiers terminated with NULL. It is
1N/A * the responsibility of the caller to free with
1N/A * libhal_free_string_array(). If an error occurs NULL is returned.
1N/A */
1N/Achar **
1N/Alibhal_get_all_devices (LibHalContext *ctx, int *num_devices, DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A DBusMessageIter iter_array, reply_iter;
1N/A char **hal_device_names;
1N/A DBusError _error;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
1N/A
1N/A *num_devices = 0;
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal",
1N/A "/org/freedesktop/Hal/Manager",
1N/A "org.freedesktop.Hal.Manager",
1N/A "GetAllDevices");
1N/A if (message == NULL) {
1N/A fprintf (stderr, "%s %d : Could not allocate D-BUS message\n", __FILE__, __LINE__);
1N/A return NULL;
1N/A }
1N/A
1N/A dbus_error_init (&_error);
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection, message, -1, &_error);
1N/A
1N/A dbus_move_error (&_error, error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return NULL;
1N/A }
1N/A if (reply == NULL) {
1N/A dbus_message_unref (message);
1N/A return NULL;
1N/A }
1N/A
1N/A /* now analyze reply */
1N/A dbus_message_iter_init (reply, &reply_iter);
1N/A
1N/A if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) {
1N/A fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__);
1N/A return NULL;
1N/A }
1N/A
1N/A dbus_message_iter_recurse (&reply_iter, &iter_array);
1N/A
1N/A hal_device_names = libhal_get_string_array_from_iter (&iter_array, num_devices);
1N/A
1N/A dbus_message_unref (reply);
1N/A dbus_message_unref (message);
1N/A
1N/A return hal_device_names;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_get_property_type:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @key: name of the property
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Query a property type of a device.
1N/A *
1N/A * Returns: A LibHalPropertyType. LIBHAL_PROPERTY_TYPE_INVALID is
1N/A * return if the property doesn't exist.
1N/A */
1N/ALibHalPropertyType
1N/Alibhal_device_get_property_type (LibHalContext *ctx, const char *udi, const char *key, DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A DBusMessageIter iter, reply_iter;
1N/A int type;
1N/A DBusError _error;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, LIBHAL_PROPERTY_TYPE_INVALID); /* or return NULL? */
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
1N/A "org.freedesktop.Hal.Device",
1N/A "GetPropertyType");
1N/A if (message == NULL) {
1N/A fprintf (stderr, "%s %d : Couldn't allocate D-BUS message\n", __FILE__, __LINE__);
1N/A return LIBHAL_PROPERTY_TYPE_INVALID;
1N/A }
1N/A
1N/A dbus_message_iter_init_append (message, &iter);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
1N/A
1N/A dbus_error_init (&_error);
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A &_error);
1N/A
1N/A dbus_move_error (&_error, error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return LIBHAL_PROPERTY_TYPE_INVALID;
1N/A }
1N/A if (reply == NULL) {
1N/A dbus_message_unref (message);
1N/A return LIBHAL_PROPERTY_TYPE_INVALID;
1N/A }
1N/A
1N/A dbus_message_iter_init (reply, &reply_iter);
1N/A dbus_message_iter_get_basic (&reply_iter, &type);
1N/A
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A
1N/A return type;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_get_property_strlist:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: unique Device Id
1N/A * @key: name of the property
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Get the value of a property of type string list.
1N/A *
1N/A * Returns: Array of pointers to UTF8 nul-terminated strings
1N/A * terminated by NULL. The caller is responsible for freeing this
1N/A * string array with the function libhal_free_string_array(). Returns
1N/A * NULL if the property didn't exist or we are OOM
1N/A */
1N/Achar **
1N/Alibhal_device_get_property_strlist (LibHalContext *ctx, const char *udi, const char *key, DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A DBusMessageIter iter, iter_array, reply_iter;
1N/A char **our_strings;
1N/A DBusError _error;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
1N/A "org.freedesktop.Hal.Device",
1N/A "GetPropertyStringList");
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return NULL;
1N/A }
1N/A
1N/A dbus_message_iter_init_append (message, &iter);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
1N/A
1N/A dbus_error_init (&_error);
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A &_error);
1N/A
1N/A dbus_move_error (&_error, error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return NULL;
1N/A }
1N/A if (reply == NULL) {
1N/A dbus_message_unref (message);
1N/A return NULL;
1N/A }
1N/A /* now analyse reply */
1N/A dbus_message_iter_init (reply, &reply_iter);
1N/A
1N/A if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) {
1N/A fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__);
1N/A return NULL;
1N/A }
1N/A
1N/A dbus_message_iter_recurse (&reply_iter, &iter_array);
1N/A
1N/A our_strings = libhal_get_string_array_from_iter (&iter_array, NULL);
1N/A
1N/A dbus_message_unref (reply);
1N/A dbus_message_unref (message);
1N/A
1N/A return our_strings;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_get_property_string:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @key: the name of the property
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Get the value of a property of type string.
1N/A *
1N/A * Returns: UTF8 nul-terminated string. The caller is responsible for
1N/A * freeing this string with the function libhal_free_string(). Returns
1N/A * NULL if the property didn't exist or we are OOM.
1N/A */
1N/Achar *
1N/Alibhal_device_get_property_string (LibHalContext *ctx,
1N/A const char *udi, const char *key, DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A DBusMessageIter iter, reply_iter;
1N/A char *value;
1N/A char *dbus_str;
1N/A DBusError _error;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
1N/A "org.freedesktop.Hal.Device",
1N/A "GetPropertyString");
1N/A
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return NULL;
1N/A }
1N/A
1N/A dbus_message_iter_init_append (message, &iter);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
1N/A
1N/A dbus_error_init (&_error);
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A &_error);
1N/A
1N/A dbus_move_error (&_error, error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return NULL;
1N/A }
1N/A if (reply == NULL) {
1N/A dbus_message_unref (message);
1N/A return NULL;
1N/A }
1N/A
1N/A dbus_message_iter_init (reply, &reply_iter);
1N/A
1N/A /* now analyze reply */
1N/A if (dbus_message_iter_get_arg_type (&reply_iter) !=
1N/A DBUS_TYPE_STRING) {
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return NULL;
1N/A }
1N/A
1N/A dbus_message_iter_get_basic (&reply_iter, &dbus_str);
1N/A value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL);
1N/A if (value == NULL) {
1N/A fprintf (stderr, "%s %d : error allocating memory\n",
1N/A __FILE__, __LINE__);
1N/A /** @todo FIXME cleanup */
1N/A return NULL;
1N/A }
1N/A
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return value;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_get_property_int:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @key: name of the property
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Get the value of a property of type integer.
1N/A *
1N/A * Returns: Property value (32-bit signed integer)
1N/A */
1N/Adbus_int32_t
1N/Alibhal_device_get_property_int (LibHalContext *ctx,
1N/A const char *udi, const char *key, DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A DBusMessageIter iter, reply_iter;
1N/A dbus_int32_t value;
1N/A DBusError _error;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, -1);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
1N/A "org.freedesktop.Hal.Device",
1N/A "GetPropertyInteger");
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return -1;
1N/A }
1N/A
1N/A dbus_message_iter_init_append (message, &iter);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
1N/A
1N/A dbus_error_init (&_error);
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A &_error);
1N/A
1N/A dbus_move_error (&_error, error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return -1;
1N/A }
1N/A if (reply == NULL) {
1N/A dbus_message_unref (message);
1N/A return -1;
1N/A }
1N/A
1N/A dbus_message_iter_init (reply, &reply_iter);
1N/A
1N/A /* now analyze reply */
1N/A if (dbus_message_iter_get_arg_type (&reply_iter) !=
1N/A DBUS_TYPE_INT32) {
1N/A fprintf (stderr,
1N/A "%s %d : property '%s' for device '%s' is not "
1N/A "of type integer\n", __FILE__, __LINE__, key,
1N/A udi);
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return -1;
1N/A }
1N/A dbus_message_iter_get_basic (&reply_iter, &value);
1N/A
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return value;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_get_property_uint64:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @key: name of the property
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Get the value of a property of type signed integer.
1N/A *
1N/A * Returns: Property value (64-bit unsigned integer)
1N/A */
1N/Adbus_uint64_t
1N/Alibhal_device_get_property_uint64 (LibHalContext *ctx,
1N/A const char *udi, const char *key, DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A DBusMessageIter iter, reply_iter;
1N/A dbus_uint64_t value;
1N/A DBusError _error;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, -1);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
1N/A "org.freedesktop.Hal.Device",
1N/A "GetPropertyInteger");
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return -1;
1N/A }
1N/A
1N/A dbus_message_iter_init_append (message, &iter);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
1N/A
1N/A dbus_error_init (&_error);
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A &_error);
1N/A
1N/A dbus_move_error (&_error, error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return -1;
1N/A }
1N/A if (reply == NULL) {
1N/A dbus_message_unref (message);
1N/A return -1;
1N/A }
1N/A
1N/A dbus_message_iter_init (reply, &reply_iter);
1N/A /* now analyze reply */
1N/A if (dbus_message_iter_get_arg_type (&reply_iter) !=
1N/A DBUS_TYPE_UINT64) {
1N/A fprintf (stderr,
1N/A "%s %d : property '%s' for device '%s' is not "
1N/A "of type integer\n", __FILE__, __LINE__, key,
1N/A udi);
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return -1;
1N/A }
1N/A dbus_message_iter_get_basic (&reply_iter, &value);
1N/A
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return value;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_get_property_double:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @key: name of the property
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Get the value of a property of type double.
1N/A *
1N/A * Returns: Property value (IEEE754 double precision float)
1N/A */
1N/Adouble
1N/Alibhal_device_get_property_double (LibHalContext *ctx,
1N/A const char *udi, const char *key, DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A DBusMessageIter iter, reply_iter;
1N/A double value;
1N/A DBusError _error;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, -1.0);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
1N/A "org.freedesktop.Hal.Device",
1N/A "GetPropertyDouble");
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return -1.0f;
1N/A }
1N/A
1N/A dbus_message_iter_init_append (message, &iter);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
1N/A
1N/A dbus_error_init (&_error);
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A &_error);
1N/A
1N/A dbus_move_error (&_error, error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return -1.0f;
1N/A }
1N/A if (reply == NULL) {
1N/A dbus_message_unref (message);
1N/A return -1.0f;
1N/A }
1N/A
1N/A dbus_message_iter_init (reply, &reply_iter);
1N/A
1N/A /* now analyze reply */
1N/A if (dbus_message_iter_get_arg_type (&reply_iter) !=
1N/A DBUS_TYPE_DOUBLE) {
1N/A fprintf (stderr,
1N/A "%s %d : property '%s' for device '%s' is not "
1N/A "of type double\n", __FILE__, __LINE__, key, udi);
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return -1.0f;
1N/A }
1N/A dbus_message_iter_get_basic (&reply_iter, &value);
1N/A
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return (double) value;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_get_property_bool:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @key: name of the property
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Get the value of a property of type bool.
1N/A *
1N/A * Returns: Property value (boolean)
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_get_property_bool (LibHalContext *ctx,
1N/A const char *udi, const char *key, DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A DBusMessageIter iter, reply_iter;
1N/A dbus_bool_t value;
1N/A DBusError _error;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
1N/A "org.freedesktop.Hal.Device",
1N/A "GetPropertyBoolean");
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_iter_init_append (message, &iter);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
1N/A
1N/A dbus_error_init (&_error);
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A &_error);
1N/A
1N/A dbus_move_error (&_error, error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A if (reply == NULL) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_iter_init (reply, &reply_iter);
1N/A
1N/A /* now analyze reply */
1N/A if (dbus_message_iter_get_arg_type (&reply_iter) !=
1N/A DBUS_TYPE_BOOLEAN) {
1N/A fprintf (stderr,
1N/A "%s %d : property '%s' for device '%s' is not "
1N/A "of type bool\n", __FILE__, __LINE__, key, udi);
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return FALSE;
1N/A }
1N/A dbus_message_iter_get_basic (&reply_iter, &value);
1N/A
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return value;
1N/A}
1N/A
1N/A
1N/A/* generic helper */
1N/Astatic dbus_bool_t
1N/Alibhal_device_set_property_helper (LibHalContext *ctx,
1N/A const char *udi,
1N/A const char *key,
1N/A int type,
1N/A const char *str_value,
1N/A dbus_int32_t int_value,
1N/A dbus_uint64_t uint64_value,
1N/A double double_value,
1N/A dbus_bool_t bool_value,
1N/A DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A DBusMessageIter iter;
1N/A char *method_name = NULL;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A /** @todo sanity check incoming params */
1N/A switch (type) {
1N/A case DBUS_TYPE_INVALID:
1N/A method_name = "RemoveProperty";
1N/A break;
1N/A case DBUS_TYPE_STRING:
1N/A method_name = "SetPropertyString";
1N/A break;
1N/A case DBUS_TYPE_INT32:
1N/A case DBUS_TYPE_UINT64:
1N/A method_name = "SetPropertyInteger";
1N/A break;
1N/A case DBUS_TYPE_DOUBLE:
1N/A method_name = "SetPropertyDouble";
1N/A break;
1N/A case DBUS_TYPE_BOOLEAN:
1N/A method_name = "SetPropertyBoolean";
1N/A break;
1N/A
1N/A default:
1N/A /* cannot happen; is not callable from outside this file */
1N/A break;
1N/A }
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
1N/A "org.freedesktop.Hal.Device",
1N/A method_name);
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_iter_init_append (message, &iter);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
1N/A switch (type) {
1N/A case DBUS_TYPE_STRING:
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &str_value);
1N/A break;
1N/A case DBUS_TYPE_INT32:
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &int_value);
1N/A break;
1N/A case DBUS_TYPE_UINT64:
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT64, &uint64_value);
1N/A break;
1N/A case DBUS_TYPE_DOUBLE:
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_DOUBLE, &double_value);
1N/A break;
1N/A case DBUS_TYPE_BOOLEAN:
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &bool_value);
1N/A break;
1N/A }
1N/A
1N/A
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A
1N/A if (reply == NULL) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A
1N/A return TRUE;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_set_property_string:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @key: name of the property
1N/A * @value: value of the property; a UTF8 string
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Set a property of type string.
1N/A *
1N/A * Returns: TRUE if the property was set, FALSE if the device didn't
1N/A * exist or the property had a different type.
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_set_property_string (LibHalContext *ctx,
1N/A const char *udi,
1N/A const char *key,
1N/A const char *value,
1N/A DBusError *error)
1N/A{
1N/A return libhal_device_set_property_helper (ctx, udi, key,
1N/A DBUS_TYPE_STRING,
1N/A value, 0, 0, 0.0f, FALSE, error);
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_set_property_int:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @key: name of the property
1N/A * @value: value of the property
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Set a property of type signed integer.
1N/A *
1N/A * Returns: TRUE if the property was set, FALSE if the device didn't
1N/A * exist or the property had a different type.
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_set_property_int (LibHalContext *ctx, const char *udi,
1N/A const char *key, dbus_int32_t value, DBusError *error)
1N/A{
1N/A return libhal_device_set_property_helper (ctx, udi, key,
1N/A DBUS_TYPE_INT32,
1N/A NULL, value, 0, 0.0f, FALSE, error);
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_set_property_uint64:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @key: name of the property
1N/A * @value: value of the property
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Set a property of type unsigned integer.
1N/A *
1N/A * Returns: TRUE if the property was set, FALSE if the device didn't
1N/A * exist or the property had a different type.
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_set_property_uint64 (LibHalContext *ctx, const char *udi,
1N/A const char *key, dbus_uint64_t value, DBusError *error)
1N/A{
1N/A return libhal_device_set_property_helper (ctx, udi, key,
1N/A DBUS_TYPE_UINT64,
1N/A NULL, 0, value, 0.0f, FALSE, error);
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_set_property_double:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @key: name of the property
1N/A * @value: value of the property
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Set a property of type double.
1N/A *
1N/A * Returns: TRUE if the property was set, FALSE if the device didn't
1N/A * exist or the property had a different type.
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_set_property_double (LibHalContext *ctx, const char *udi,
1N/A const char *key, double value, DBusError *error)
1N/A{
1N/A return libhal_device_set_property_helper (ctx, udi, key,
1N/A DBUS_TYPE_DOUBLE,
1N/A NULL, 0, 0, value, FALSE, error);
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_set_property_bool:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @key: name of the property
1N/A * @value: value of the property
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Set a property of type bool.
1N/A *
1N/A * Returns: TRUE if the property was set, FALSE if the device didn't
1N/A * exist or the property had a different type.
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_set_property_bool (LibHalContext *ctx, const char *udi,
1N/A const char *key, dbus_bool_t value, DBusError *error)
1N/A{
1N/A return libhal_device_set_property_helper (ctx, udi, key,
1N/A DBUS_TYPE_BOOLEAN,
1N/A NULL, 0, 0, 0.0f, value, error);
1N/A}
1N/A
1N/A
1N/A/**
1N/A * libhal_device_remove_property:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @key: name of the property
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Remove a property.
1N/A *
1N/A * Returns: TRUE if the property was set, FALSE if the device didn't
1N/A * exist
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_remove_property (LibHalContext *ctx,
1N/A const char *udi, const char *key, DBusError *error)
1N/A{
1N/A return libhal_device_set_property_helper (ctx, udi, key, DBUS_TYPE_INVALID,
1N/A /* DBUS_TYPE_INVALID means remove */
1N/A NULL, 0, 0, 0.0f, FALSE, error);
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_property_strlist_append:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @key: name of the property
1N/A * @value: value to append to property
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Append to a property of type strlist.
1N/A *
1N/A * Returns: TRUE if the value was appended, FALSE if the device didn't
1N/A * exist or the property had a different type.
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_property_strlist_append (LibHalContext *ctx,
1N/A const char *udi,
1N/A const char *key,
1N/A const char *value,
1N/A DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A DBusMessageIter iter;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
1N/A "org.freedesktop.Hal.Device",
1N/A "StringListAppend");
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return FALSE;
1N/A }
1N/A dbus_message_iter_init_append (message, &iter);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
1N/A
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A if (reply == NULL) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A return TRUE;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_property_strlist_prepend:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @key: name of the property
1N/A * @value: value to prepend to property
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Prepend to a property of type strlist.
1N/A *
1N/A * Returns: TRUE if the value was prepended, FALSE if the device
1N/A * didn't exist or the property had a different type.
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_property_strlist_prepend (LibHalContext *ctx,
1N/A const char *udi,
1N/A const char *key,
1N/A const char *value,
1N/A DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A DBusMessageIter iter;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
1N/A "org.freedesktop.Hal.Device",
1N/A "StringListPrepend");
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return FALSE;
1N/A }
1N/A dbus_message_iter_init_append (message, &iter);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
1N/A
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A if (reply == NULL) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A return TRUE;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_property_strlist_remove_index:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @key: name of the property
1N/A * @idx: index of string to remove in the strlist
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Remove a specified string from a property of type strlist.
1N/A *
1N/A * Returns: TRUE if the string was removed, FALSE if the device didn't
1N/A * exist or the property had a different type.
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_property_strlist_remove_index (LibHalContext *ctx,
1N/A const char *udi,
1N/A const char *key,
1N/A unsigned int idx,
1N/A DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A DBusMessageIter iter;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
1N/A "org.freedesktop.Hal.Device",
1N/A "StringListRemoveIndex");
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return FALSE;
1N/A }
1N/A dbus_message_iter_init_append (message, &iter);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &idx);
1N/A
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A if (reply == NULL) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A return TRUE;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_property_strlist_remove:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @key: name of the property
1N/A * @value: the string to remove
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Remove a specified string from a property of type strlist.
1N/A *
1N/A * Returns: TRUE if the string was removed, FALSE if the device didn't
1N/A * exist or the property had a different type.
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_property_strlist_remove (LibHalContext *ctx,
1N/A const char *udi,
1N/A const char *key,
1N/A const char *value, DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A DBusMessageIter iter;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
1N/A "org.freedesktop.Hal.Device",
1N/A "StringListRemove");
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return FALSE;
1N/A }
1N/A dbus_message_iter_init_append (message, &iter);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
1N/A
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A if (reply == NULL) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A return TRUE;
1N/A}
1N/A
1N/A
1N/A/**
1N/A * libhal_device_lock:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @reason_to_lock: a user-presentable reason why the device is locked.
1N/A * @reason_why_locked: a pointer to store the reason why the device cannot be locked on failure, or NULL
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Take an advisory lock on the device.
1N/A *
1N/A * Returns: TRUE if the lock was obtained, FALSE otherwise
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_lock (LibHalContext *ctx,
1N/A const char *udi,
1N/A const char *reason_to_lock,
1N/A char **reason_why_locked, DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessageIter iter;
1N/A DBusMessage *reply;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A if (reason_why_locked != NULL)
1N/A *reason_why_locked = NULL;
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal",
1N/A udi,
1N/A "org.freedesktop.Hal.Device",
1N/A "Lock");
1N/A
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_iter_init_append (message, &iter);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &reason_to_lock);
1N/A
1N/A
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A error);
1N/A
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A if (strcmp (error->name,
1N/A "org.freedesktop.Hal.DeviceAlreadyLocked") == 0) {
1N/A if (reason_why_locked != NULL) {
1N/A *reason_why_locked =
1N/A dbus_malloc0 (strlen (error->message) + 1);
1N/A strcpy (*reason_why_locked, error->message);
1N/A }
1N/A }
1N/A
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_unref (message);
1N/A
1N/A if (reply == NULL)
1N/A return FALSE;
1N/A
1N/A dbus_message_unref (reply);
1N/A
1N/A return TRUE;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_unlock:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Release an advisory lock on the device.
1N/A *
1N/A * Returns: TRUE if the device was successfully unlocked,
1N/A * FALSE otherwise
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_unlock (LibHalContext *ctx,
1N/A const char *udi, DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal",
1N/A udi,
1N/A "org.freedesktop.Hal.Device",
1N/A "Unlock");
1N/A
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return FALSE;
1N/A }
1N/A
1N/A
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A error);
1N/A
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_unref (message);
1N/A
1N/A if (reply == NULL)
1N/A return FALSE;
1N/A
1N/A dbus_message_unref (reply);
1N/A
1N/A return TRUE;
1N/A}
1N/A
1N/A
1N/A/**
1N/A * libhal_new_device:
1N/A * @ctx: the context for the connection to hald
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Create a new device object which will be hidden from applications
1N/A * until the CommitToGdl(), ie. libhal_device_commit_to_gdl(), method
1N/A * is called. Note that the program invoking this method needs to run
1N/A * with super user privileges.
1N/A *
1N/A * Returns: Temporary device unique id or NULL if there was a
1N/A * problem. This string must be freed by the caller.
1N/A */
1N/Achar *
1N/Alibhal_new_device (LibHalContext *ctx, DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A DBusMessageIter reply_iter;
1N/A char *value;
1N/A char *dbus_str;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal",
1N/A "/org/freedesktop/Hal/Manager",
1N/A "org.freedesktop.Hal.Manager",
1N/A "NewDevice");
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return NULL;
1N/A }
1N/A
1N/A
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return NULL;
1N/A }
1N/A if (reply == NULL) {
1N/A dbus_message_unref (message);
1N/A return NULL;
1N/A }
1N/A
1N/A dbus_message_iter_init (reply, &reply_iter);
1N/A
1N/A /* now analyze reply */
1N/A if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_STRING) {
1N/A fprintf (stderr,
1N/A "%s %d : expected a string in reply to NewDevice\n",
1N/A __FILE__, __LINE__);
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return NULL;
1N/A }
1N/A
1N/A dbus_message_iter_get_basic (&reply_iter, &dbus_str);
1N/A value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL);
1N/A if (value == NULL) {
1N/A fprintf (stderr, "%s %d : error allocating memory\n",
1N/A __FILE__, __LINE__);
1N/A }
1N/A
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return value;
1N/A}
1N/A
1N/A
1N/A/**
1N/A * libhal_device_commit_to_gdl:
1N/A * @ctx: the context for the connection to hald
1N/A * @temp_udi: the temporary unique device id as returned by libhal_new_device()
1N/A * @udi: the new unique device id.
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * When a hidden device has been built using the NewDevice method,
1N/A * ie. libhal_new_device(), and the org.freedesktop.Hal.Device
1N/A * interface this function will commit it to the global device list.
1N/A *
1N/A * This means that the device object will be visible to applications
1N/A * and the HAL daemon will possibly attempt to boot the device
1N/A * (depending on the property RequireEnable).
1N/A *
1N/A * Note that the program invoking this method needs to run with super
1N/A * user privileges.
1N/A *
1N/A * Returns: FALSE if the given unique device id is already in use.
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_commit_to_gdl (LibHalContext *ctx,
1N/A const char *temp_udi, const char *udi, DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A DBusMessageIter iter;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal",
1N/A "/org/freedesktop/Hal/Manager",
1N/A "org.freedesktop.Hal.Manager",
1N/A "CommitToGdl");
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_iter_init_append (message, &iter);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &temp_udi);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi);
1N/A
1N/A
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A if (reply == NULL) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return TRUE;
1N/A}
1N/A
1N/A/**
1N/A * libhal_remove_device:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique device id.
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * This method can be invoked when a device is removed. The HAL daemon
1N/A * will shut down the device. Note that the device may still be in the
1N/A * device list if the Persistent property is set to true.
1N/A *
1N/A * Note that the program invoking this method needs to run with super
1N/A * user privileges.
1N/A *
1N/A * Returns: TRUE if the device was removed, FALSE otherwise
1N/A */
1N/Adbus_bool_t
1N/Alibhal_remove_device (LibHalContext *ctx, const char *udi, DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A DBusMessageIter iter;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal",
1N/A "/org/freedesktop/Hal/Manager",
1N/A "org.freedesktop.Hal.Manager",
1N/A "Remove");
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_iter_init_append (message, &iter);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi);
1N/A
1N/A
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A if (reply == NULL) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return TRUE;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_exists:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique device id.
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Determine if a device exists.
1N/A *
1N/A * Returns: TRUE if the device exists
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_exists (LibHalContext *ctx, const char *udi, DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A DBusMessageIter iter, reply_iter;
1N/A dbus_bool_t value;
1N/A DBusError _error;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal",
1N/A "/org/freedesktop/Hal/Manager",
1N/A "org.freedesktop.Hal.Manager",
1N/A "DeviceExists");
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_iter_init_append (message, &iter);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi);
1N/A
1N/A dbus_error_init (&_error);
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A &_error);
1N/A
1N/A dbus_move_error (&_error, error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A if (reply == NULL) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_iter_init (reply, &reply_iter);
1N/A
1N/A /* now analyze reply */
1N/A if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) {
1N/A fprintf (stderr,
1N/A "%s %d : expected a bool in reply to DeviceExists\n",
1N/A __FILE__, __LINE__);
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_iter_get_basic (&reply_iter, &value);
1N/A
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return value;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_property_exists:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique device id.
1N/A * @key: name of the property
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Determine if a property on a device exists.
1N/A *
1N/A * Returns: TRUE if the device exists, FALSE otherwise
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_property_exists (LibHalContext *ctx,
1N/A const char *udi, const char *key, DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A DBusMessageIter iter, reply_iter;
1N/A dbus_bool_t value;
1N/A DBusError _error;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
1N/A "org.freedesktop.Hal.Device",
1N/A "PropertyExists");
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_iter_init_append (message, &iter);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
1N/A
1N/A dbus_error_init (&_error);
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A &_error);
1N/A
1N/A dbus_move_error (&_error, error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A if (reply == NULL) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_iter_init (reply, &reply_iter);
1N/A
1N/A /* now analyse reply */
1N/A if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) {
1N/A fprintf (stderr, "%s %d : expected a bool in reply to "
1N/A "PropertyExists\n", __FILE__, __LINE__);
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_iter_get_basic (&reply_iter, &value);
1N/A
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return value;
1N/A}
1N/A
1N/A/**
1N/A * libhal_merge_properties:
1N/A * @ctx: the context for the connection to hald
1N/A * @target_udi: the Unique device id of target device to merge to
1N/A * @source_udi: the Unique device id of device to merge from
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Merge properties from one device to another.
1N/A *
1N/A * Returns: TRUE if the properties were merged, FALSE otherwise
1N/A */
1N/Adbus_bool_t
1N/Alibhal_merge_properties (LibHalContext *ctx,
1N/A const char *target_udi, const char *source_udi, DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A DBusMessageIter iter;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal",
1N/A "/org/freedesktop/Hal/Manager",
1N/A "org.freedesktop.Hal.Manager",
1N/A "MergeProperties");
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_iter_init_append (message, &iter);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &target_udi);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &source_udi);
1N/A
1N/A
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A if (reply == NULL) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return TRUE;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_matches:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi1: the Unique Device Id for device 1
1N/A * @udi2: the Unique Device Id for device 2
1N/A * @property_namespace: the namespace for set of devices, e.g. "usb"
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Check a set of properties for two devices matches.
1N/A *
1N/A * Checks that all properties where keys, starting with a given value
1N/A * (namespace), of the first device is in the second device and that
1N/A * they got the same value and type.
1N/A *
1N/A * Note that the other inclusion isn't tested, so there could be
1N/A * properties (from the given namespace) in the second device not
1N/A * present in the first device.
1N/A *
1N/A * Returns: TRUE if all properties starting with the given namespace
1N/A * parameter from one device is in the other and have the same value.
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_matches (LibHalContext *ctx,
1N/A const char *udi1, const char *udi2,
1N/A const char *property_namespace, DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A DBusMessageIter iter, reply_iter;
1N/A dbus_bool_t value;
1N/A DBusError _error;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal",
1N/A "/org/freedesktop/Hal/Manager",
1N/A "org.freedesktop.Hal.Manager",
1N/A "DeviceMatches");
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_iter_init_append (message, &iter);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, udi1);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, udi2);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, property_namespace);
1N/A
1N/A dbus_error_init (&_error);
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A &_error);
1N/A
1N/A dbus_move_error (&_error, error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A if (reply == NULL) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A /* now analyse reply */
1N/A dbus_message_iter_init (reply, &reply_iter);
1N/A
1N/A if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) {
1N/A fprintf (stderr,
1N/A "%s %d : expected a bool in reply to DeviceMatches\n",
1N/A __FILE__, __LINE__);
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_iter_get_basic (&reply_iter, &value);
1N/A
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return value;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_print:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Print a device to stdout; useful for debugging.
1N/A *
1N/A * Returns: TRUE if device's information could be obtained, FALSE otherwise
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_print (LibHalContext *ctx, const char *udi, DBusError *error)
1N/A{
1N/A int type;
1N/A char *key;
1N/A LibHalPropertySet *pset;
1N/A LibHalPropertySetIterator i;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A printf ("device_id = %s\n", udi);
1N/A
1N/A if ((pset = libhal_device_get_all_properties (ctx, udi, error)) == NULL)
1N/A return FALSE;
1N/A
1N/A for (libhal_psi_init (&i, pset); libhal_psi_has_more (&i);
1N/A libhal_psi_next (&i)) {
1N/A type = libhal_psi_get_type (&i);
1N/A key = libhal_psi_get_key (&i);
1N/A
1N/A switch (type) {
1N/A case LIBHAL_PROPERTY_TYPE_STRING:
1N/A printf (" %s = '%s' (string)\n", key,
1N/A libhal_psi_get_string (&i));
1N/A break;
1N/A case LIBHAL_PROPERTY_TYPE_INT32:
1N/A printf (" %s = %d = 0x%x (int)\n", key,
1N/A libhal_psi_get_int (&i),
1N/A libhal_psi_get_int (&i));
1N/A break;
1N/A case LIBHAL_PROPERTY_TYPE_UINT64:
1N/A printf (" %s = %llu = 0x%llx (uint64)\n", key,
1N/A (long long unsigned int) libhal_psi_get_uint64 (&i),
1N/A (long long unsigned int) libhal_psi_get_uint64 (&i));
1N/A break;
1N/A case LIBHAL_PROPERTY_TYPE_BOOLEAN:
1N/A printf (" %s = %s (bool)\n", key,
1N/A (libhal_psi_get_bool (&i) ? "true" :
1N/A "false"));
1N/A break;
1N/A case LIBHAL_PROPERTY_TYPE_DOUBLE:
1N/A printf (" %s = %g (double)\n", key,
1N/A libhal_psi_get_double (&i));
1N/A break;
1N/A case LIBHAL_PROPERTY_TYPE_STRLIST:
1N/A {
1N/A unsigned int j;
1N/A char **str_list;
1N/A
1N/A str_list = libhal_psi_get_strlist (&i);
1N/A printf (" %s = [", key);
1N/A for (j = 0; str_list[j] != NULL; j++) {
1N/A printf ("'%s'", str_list[j]);
1N/A if (str_list[j+1] != NULL)
1N/A printf (", ");
1N/A }
1N/A printf ("] (string list)\n");
1N/A
1N/A break;
1N/A }
1N/A default:
1N/A printf (" *** unknown type for key %s\n", key);
1N/A break;
1N/A }
1N/A }
1N/A
1N/A libhal_free_property_set (pset);
1N/A
1N/A return TRUE;
1N/A}
1N/A
1N/A/**
1N/A * libhal_manager_find_device_string_match:
1N/A * @ctx: the context for the connection to hald
1N/A * @key: name of the property
1N/A * @value: the value to match
1N/A * @num_devices: pointer to store number of devices
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Find a device in the GDL where a single string property matches a
1N/A * given value.
1N/A *
1N/A * Returns: UDI of devices; free with libhal_free_string_array()
1N/A */
1N/Achar **
1N/Alibhal_manager_find_device_string_match (LibHalContext *ctx,
1N/A const char *key,
1N/A const char *value, int *num_devices, DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A DBusMessageIter iter, iter_array, reply_iter;
1N/A char **hal_device_names;
1N/A DBusError _error;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal",
1N/A "/org/freedesktop/Hal/Manager",
1N/A "org.freedesktop.Hal.Manager",
1N/A "FindDeviceStringMatch");
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return NULL;
1N/A }
1N/A
1N/A dbus_message_iter_init_append (message, &iter);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
1N/A
1N/A dbus_error_init (&_error);
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A &_error);
1N/A
1N/A dbus_move_error (&_error, error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return NULL;
1N/A }
1N/A if (reply == NULL) {
1N/A dbus_message_unref (message);
1N/A return NULL;
1N/A }
1N/A /* now analyse reply */
1N/A dbus_message_iter_init (reply, &reply_iter);
1N/A
1N/A if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) {
1N/A fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__);
1N/A return NULL;
1N/A }
1N/A
1N/A dbus_message_iter_recurse (&reply_iter, &iter_array);
1N/A
1N/A hal_device_names = libhal_get_string_array_from_iter (&iter_array, num_devices);
1N/A
1N/A dbus_message_unref (reply);
1N/A dbus_message_unref (message);
1N/A
1N/A return hal_device_names;
1N/A}
1N/A
1N/A
1N/A/**
1N/A * libhal_device_add_capability:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @capability: the capability name to add
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Assign a capability to a device.
1N/A *
1N/A * Returns: TRUE if the capability was added, FALSE if the device didn't exist
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_add_capability (LibHalContext *ctx,
1N/A const char *udi, const char *capability, DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A DBusMessageIter iter;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
1N/A "org.freedesktop.Hal.Device",
1N/A "AddCapability");
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_iter_init_append (message, &iter);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &capability);
1N/A
1N/A
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A
1N/A if (reply == NULL) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_unref (reply);
1N/A dbus_message_unref (message);
1N/A return TRUE;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_query_capability:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @capability: the capability name
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Check if a device has a capability. The result is undefined if the
1N/A * device doesn't exist.
1N/A *
1N/A * Returns: TRUE if the device has the capability, otherwise FALSE
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_query_capability (LibHalContext *ctx, const char *udi, const char *capability, DBusError *error)
1N/A{
1N/A char **caps;
1N/A unsigned int i;
1N/A dbus_bool_t ret;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A ret = FALSE;
1N/A
1N/A caps = libhal_device_get_property_strlist (ctx, udi, "info.capabilities", error);
1N/A if (caps != NULL) {
1N/A for (i = 0; caps[i] != NULL; i++) {
1N/A if (strcmp (caps[i], capability) == 0) {
1N/A ret = TRUE;
1N/A break;
1N/A }
1N/A }
1N/A libhal_free_string_array (caps);
1N/A }
1N/A
1N/A return ret;
1N/A}
1N/A
1N/A/**
1N/A * libhal_find_device_by_capability:
1N/A * @ctx: the context for the connection to hald
1N/A * @capability: the capability name
1N/A * @num_devices: pointer to store number of devices
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Find devices with a given capability.
1N/A *
1N/A * Returns: UDI of devices; free with libhal_free_string_array()
1N/A */
1N/Achar **
1N/Alibhal_find_device_by_capability (LibHalContext *ctx,
1N/A const char *capability, int *num_devices, DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A DBusMessageIter iter, iter_array, reply_iter;
1N/A char **hal_device_names;
1N/A DBusError _error;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal",
1N/A "/org/freedesktop/Hal/Manager",
1N/A "org.freedesktop.Hal.Manager",
1N/A "FindDeviceByCapability");
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return NULL;
1N/A }
1N/A
1N/A dbus_message_iter_init_append (message, &iter);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &capability);
1N/A
1N/A dbus_error_init (&_error);
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A &_error);
1N/A
1N/A dbus_move_error (&_error, error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return NULL;
1N/A }
1N/A if (reply == NULL) {
1N/A dbus_message_unref (message);
1N/A return NULL;
1N/A }
1N/A /* now analyse reply */
1N/A dbus_message_iter_init (reply, &reply_iter);
1N/A
1N/A if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) {
1N/A fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__);
1N/A return NULL;
1N/A }
1N/A
1N/A dbus_message_iter_recurse (&reply_iter, &iter_array);
1N/A
1N/A hal_device_names = libhal_get_string_array_from_iter (&iter_array, num_devices);
1N/A
1N/A dbus_message_unref (reply);
1N/A dbus_message_unref (message);
1N/A
1N/A return hal_device_names;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_property_watch_all:
1N/A * @ctx: the context for the connection to hald
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Watch all devices, ie. the device_property_changed callback is
1N/A * invoked when the properties on any device changes.
1N/A *
1N/A * Returns: TRUE only if the operation succeeded
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_property_watch_all (LibHalContext *ctx, DBusError *error)
1N/A{
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A dbus_bus_add_match (ctx->connection,
1N/A "type='signal',"
1N/A "interface='org.freedesktop.Hal.Device',"
1N/A "sender='org.freedesktop.Hal'", error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A return FALSE;
1N/A }
1N/A return TRUE;
1N/A}
1N/A
1N/A
1N/A/**
1N/A * libhal_device_add_property_watch:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Add a watch on a device, so the device_property_changed callback is
1N/A * invoked when the properties on the given device changes.
1N/A *
1N/A * The application itself is responsible for deleting the watch, using
1N/A * libhal_device_remove_property_watch, if the device is removed.
1N/A *
1N/A * Returns: TRUE only if the operation succeeded
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_add_property_watch (LibHalContext *ctx, const char *udi, DBusError *error)
1N/A{
1N/A char buf[512];
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A snprintf (buf, 512,
1N/A "type='signal',"
1N/A "interface='org.freedesktop.Hal.Device',"
1N/A "sender='org.freedesktop.Hal'," "path=%s", udi);
1N/A
1N/A dbus_bus_add_match (ctx->connection, buf, error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A return FALSE;
1N/A }
1N/A return TRUE;
1N/A}
1N/A
1N/A
1N/A/**
1N/A * libhal_device_remove_property_watch:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Remove a watch on a device.
1N/A *
1N/A * Returns: TRUE only if the operation succeeded
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_remove_property_watch (LibHalContext *ctx, const char *udi, DBusError *error)
1N/A{
1N/A char buf[512];
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A snprintf (buf, 512,
1N/A "type='signal',"
1N/A "interface='org.freedesktop.Hal.Device',"
1N/A "sender='org.freedesktop.Hal'," "path=%s", udi);
1N/A
1N/A dbus_bus_remove_match (ctx->connection, buf, error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A return FALSE;
1N/A }
1N/A return TRUE;
1N/A}
1N/A
1N/A
1N/A/**
1N/A * libhal_ctx_new:
1N/A *
1N/A * Create a new LibHalContext
1N/A *
1N/A * Returns: a new uninitialized LibHalContext object
1N/A */
1N/ALibHalContext *
1N/Alibhal_ctx_new (void)
1N/A{
1N/A LibHalContext *ctx;
1N/A
1N/A if (!libhal_already_initialized_once) {
1N/A bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
1N/A bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
1N/A
1N/A libhal_already_initialized_once = TRUE;
1N/A }
1N/A
1N/A ctx = calloc (1, sizeof (LibHalContext));
1N/A if (ctx == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Failed to allocate %d bytes\n",
1N/A __FILE__, __LINE__, sizeof (LibHalContext));
1N/A return NULL;
1N/A }
1N/A
1N/A ctx->is_initialized = FALSE;
1N/A ctx->is_shutdown = FALSE;
1N/A ctx->connection = NULL;
1N/A ctx->is_direct = FALSE;
1N/A
1N/A return ctx;
1N/A}
1N/A
1N/A/**
1N/A * libhal_ctx_set_cache:
1N/A * @ctx: context to enable/disable cache for
1N/A * @use_cache: whether or not to use cache
1N/A *
1N/A * Enable or disable caching. Note: Caching is not actually
1N/A * implemented yet.
1N/A *
1N/A * Returns: TRUE if cache was successfully enabled/disabled, FALSE otherwise
1N/A */
1N/Adbus_bool_t
1N/Alibhal_ctx_set_cache (LibHalContext *ctx, dbus_bool_t use_cache)
1N/A{
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A ctx->cache_enabled = use_cache;
1N/A return TRUE;
1N/A}
1N/A
1N/A/**
1N/A * libhal_ctx_set_dbus_connection:
1N/A * @ctx: context to set connection for
1N/A * @conn: DBus connection to use
1N/A *
1N/A * Set DBus connection to use to talk to hald.
1N/A *
1N/A * Returns: TRUE if connection was successfully set, FALSE otherwise
1N/A */
1N/Adbus_bool_t
1N/Alibhal_ctx_set_dbus_connection (LibHalContext *ctx, DBusConnection *conn)
1N/A{
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A if (conn == NULL)
1N/A return FALSE;
1N/A
1N/A ctx->connection = conn;
1N/A return TRUE;
1N/A}
1N/A
1N/A/**
1N/A * libhal_ctx_get_dbus_connection:
1N/A * @ctx: context to get connection for
1N/A *
1N/A * Get DBus connection used for talking to hald.
1N/A *
1N/A * Returns: DBus connection to use or NULL
1N/A */
1N/ADBusConnection *
1N/Alibhal_ctx_get_dbus_connection (LibHalContext *ctx)
1N/A{
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A return ctx->connection;
1N/A}
1N/A
1N/A
1N/A/**
1N/A * libhal_ctx_init:
1N/A * @ctx: Context for connection to hald (D-BUS connection should be set with libhal_ctx_set_dbus_connection)
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Initialize the connection to hald.
1N/A *
1N/A * Returns: TRUE if initialization succeeds, FALSE otherwise
1N/A */
1N/Adbus_bool_t
1N/Alibhal_ctx_init (LibHalContext *ctx, DBusError *error)
1N/A{
1N/A DBusError _error;
1N/A dbus_bool_t hald_exists;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A if (ctx->connection == NULL)
1N/A return FALSE;
1N/A
1N/A dbus_error_init (&_error);
1N/A hald_exists = dbus_bus_name_has_owner (ctx->connection, "org.freedesktop.Hal", &_error);
1N/A dbus_move_error (&_error, error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A return FALSE;
1N/A }
1N/A
1N/A if (!hald_exists) {
1N/A return FALSE;
1N/A }
1N/A
1N/A
1N/A if (!dbus_connection_add_filter (ctx->connection, filter_func, ctx, NULL)) {
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_bus_add_match (ctx->connection,
1N/A "type='signal',"
1N/A "interface='org.freedesktop.Hal.Manager',"
1N/A "sender='org.freedesktop.Hal',"
1N/A "path='/org/freedesktop/Hal/Manager'", &_error);
1N/A dbus_move_error (&_error, error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A return FALSE;
1N/A }
1N/A ctx->is_initialized = TRUE;
1N/A ctx->is_direct = FALSE;
1N/A
1N/A return TRUE;
1N/A}
1N/A
1N/A/**
1N/A * libhal_ctx_init_direct:
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Create an already initialized connection to hald. This function should only be used by HAL helpers.
1N/A *
1N/A * Returns: A pointer to an already initialized LibHalContext
1N/A */
1N/ALibHalContext *
1N/Alibhal_ctx_init_direct (DBusError *error)
1N/A{
1N/A char *hald_addr;
1N/A LibHalContext *ctx;
1N/A DBusError _error;
1N/A
1N/A ctx = libhal_ctx_new ();
1N/A if (ctx == NULL)
1N/A goto out;
1N/A
1N/A if (((hald_addr = getenv ("HALD_DIRECT_ADDR"))) == NULL) {
1N/A libhal_ctx_free (ctx);
1N/A ctx = NULL;
1N/A goto out;
1N/A }
1N/A
1N/A dbus_error_init (&_error);
1N/A ctx->connection = dbus_connection_open (hald_addr, &_error);
1N/A dbus_move_error (&_error, error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A libhal_ctx_free (ctx);
1N/A ctx = NULL;
1N/A goto out;
1N/A }
1N/A
1N/A ctx->is_initialized = TRUE;
1N/A ctx->is_direct = TRUE;
1N/A
1N/Aout:
1N/A return ctx;
1N/A}
1N/A
1N/A/**
1N/A * libhal_ctx_shutdown:
1N/A * @ctx: the context for the connection to hald
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Shut down a connection to hald.
1N/A *
1N/A * Returns: TRUE if connection successfully shut down, FALSE otherwise
1N/A */
1N/Adbus_bool_t
1N/Alibhal_ctx_shutdown (LibHalContext *ctx, DBusError *error)
1N/A{
1N/A DBusError myerror;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A if (ctx->is_direct) {
1N/A /* for some reason dbus_connection_set_exit_on_disconnect doesn't work yet so don't unref */
1N/A /*dbus_connection_unref (ctx->connection);*/
1N/A } else {
1N/A dbus_error_init (&myerror);
1N/A dbus_bus_remove_match (ctx->connection,
1N/A "type='signal',"
1N/A "interface='org.freedesktop.Hal.Manager',"
1N/A "sender='org.freedesktop.Hal',"
1N/A "path='/org/freedesktop/Hal/Manager'", &myerror);
1N/A dbus_move_error(&myerror, error);
1N/A if (error != NULL && dbus_error_is_set(error)) {
1N/A fprintf (stderr, "%s %d : Error unsubscribing to signals, error=%s\n",
1N/A __FILE__, __LINE__, error->message);
1N/A /** @todo clean up */
1N/A }
1N/A
1N/A /* TODO: remove other matches */
1N/A
1N/A dbus_connection_remove_filter (ctx->connection, filter_func, ctx);
1N/A }
1N/A
1N/A ctx->is_initialized = FALSE;
1N/A
1N/A return TRUE;
1N/A}
1N/A
1N/A/**
1N/A * libhal_ctx_free:
1N/A * @ctx: pointer to a LibHalContext
1N/A *
1N/A * Free a LibHalContext resource.
1N/A *
1N/A * Returns: TRUE
1N/A */
1N/Adbus_bool_t
1N/Alibhal_ctx_free (LibHalContext *ctx)
1N/A{
1N/A free (ctx);
1N/A return TRUE;
1N/A}
1N/A
1N/A/**
1N/A * libhal_ctx_set_device_added:
1N/A * @ctx: the context for the connection to hald
1N/A * @callback: the function to call when a device is added
1N/A *
1N/A * Set the callback for when a device is added
1N/A *
1N/A * Returns: TRUE if callback was successfully set, FALSE otherwise
1N/A */
1N/Adbus_bool_t
1N/Alibhal_ctx_set_device_added (LibHalContext *ctx, LibHalDeviceAdded callback)
1N/A{
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A ctx->device_added = callback;
1N/A return TRUE;
1N/A}
1N/A
1N/A/**
1N/A * libhal_ctx_set_device_removed:
1N/A * @ctx: the context for the connection to hald
1N/A * @callback: the function to call when a device is removed
1N/A *
1N/A * Set the callback for when a device is removed.
1N/A *
1N/A * Returns: TRUE if callback was successfully set, FALSE otherwise
1N/A */
1N/Adbus_bool_t
1N/Alibhal_ctx_set_device_removed (LibHalContext *ctx, LibHalDeviceRemoved callback)
1N/A{
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A ctx->device_removed = callback;
1N/A return TRUE;
1N/A}
1N/A
1N/A/**
1N/A * libhal_ctx_set_device_new_capability:
1N/A * @ctx: the context for the connection to hald
1N/A * @callback: the function to call when a device gains a new capability
1N/A *
1N/A * Set the callback for when a device gains a new capability.
1N/A *
1N/A * Returns: TRUE if callback was successfully set, FALSE otherwise
1N/A */
1N/Adbus_bool_t
1N/Alibhal_ctx_set_device_new_capability (LibHalContext *ctx, LibHalDeviceNewCapability callback)
1N/A{
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A ctx->device_new_capability = callback;
1N/A return TRUE;
1N/A}
1N/A
1N/A/**
1N/A * libhal_ctx_set_device_lost_capability:
1N/A * @ctx: the context for the connection to hald
1N/A * @callback: the function to call when a device loses a capability
1N/A *
1N/A * Set the callback for when a device loses a capability
1N/A *
1N/A * Returns: TRUE if callback was successfully set, FALSE otherwise
1N/A */
1N/Adbus_bool_t
1N/Alibhal_ctx_set_device_lost_capability (LibHalContext *ctx, LibHalDeviceLostCapability callback)
1N/A{
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A ctx->device_lost_capability = callback;
1N/A return TRUE;
1N/A}
1N/A
1N/A/**
1N/A * libhal_ctx_set_device_property_modified:
1N/A * @ctx: the context for the connection to hald
1N/A * @callback: the function to call when a property is modified on a device
1N/A *
1N/A * Set the callback for when a property is modified on a device.
1N/A *
1N/A * Returns: TRUE if callback was successfully set, FALSE otherwise
1N/A */
1N/Adbus_bool_t
1N/Alibhal_ctx_set_device_property_modified (LibHalContext *ctx, LibHalDevicePropertyModified callback)
1N/A{
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A ctx->device_property_modified = callback;
1N/A return TRUE;
1N/A}
1N/A
1N/A/**
1N/A * libhal_ctx_set_device_condition:
1N/A * @ctx: the context for the connection to hald
1N/A * @callback: the function to call when a device emits a condition
1N/A *
1N/A * Set the callback for when a device emits a condition
1N/A *
1N/A * Returns: TRUE if callback was successfully set, FALSE otherwise
1N/A */
1N/Adbus_bool_t
1N/Alibhal_ctx_set_device_condition (LibHalContext *ctx, LibHalDeviceCondition callback)
1N/A{
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A ctx->device_condition = callback;
1N/A return TRUE;
1N/A}
1N/A
1N/A/**
1N/A * libhal_string_array_length:
1N/A * @str_array: array of strings to consider
1N/A *
1N/A * Get the length of an array of strings.
1N/A *
1N/A * Returns: Number of strings in array
1N/A */
1N/Aunsigned int
1N/Alibhal_string_array_length (char **str_array)
1N/A{
1N/A unsigned int i;
1N/A
1N/A if (str_array == NULL)
1N/A return 0;
1N/A
1N/A for (i = 0; str_array[i] != NULL; i++)
1N/A ;
1N/A
1N/A return i;
1N/A}
1N/A
1N/A
1N/A/**
1N/A * libhal_device_rescan:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique id of device
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * TODO document me.
1N/A *
1N/A * Returns: Whether the operation succeeded
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_rescan (LibHalContext *ctx, const char *udi, DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessageIter reply_iter;
1N/A DBusMessage *reply;
1N/A dbus_bool_t result;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
1N/A "org.freedesktop.Hal.Device",
1N/A "Rescan");
1N/A
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return FALSE;
1N/A }
1N/A
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A error);
1N/A
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_unref (message);
1N/A
1N/A if (reply == NULL)
1N/A return FALSE;
1N/A
1N/A dbus_message_iter_init (reply, &reply_iter);
1N/A if (dbus_message_iter_get_arg_type (&reply_iter) !=
1N/A DBUS_TYPE_BOOLEAN) {
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return FALSE;
1N/A }
1N/A dbus_message_iter_get_basic (&reply_iter, &result);
1N/A
1N/A dbus_message_unref (reply);
1N/A
1N/A return result;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_reprobe:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique id of device
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * TODO document me.
1N/A *
1N/A * Returns: Whether the operation succeeded
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_reprobe (LibHalContext *ctx, const char *udi, DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessageIter reply_iter;
1N/A DBusMessage *reply;
1N/A dbus_bool_t result;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal",
1N/A udi,
1N/A "org.freedesktop.Hal.Device",
1N/A "Reprobe");
1N/A
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return FALSE;
1N/A }
1N/A
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A error);
1N/A
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_unref (message);
1N/A
1N/A if (reply == NULL)
1N/A return FALSE;
1N/A
1N/A dbus_message_iter_init (reply, &reply_iter);
1N/A if (dbus_message_iter_get_arg_type (&reply_iter) !=
1N/A DBUS_TYPE_BOOLEAN) {
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return FALSE;
1N/A }
1N/A dbus_message_iter_get_basic (&reply_iter, &result);
1N/A
1N/A dbus_message_unref (reply);
1N/A
1N/A return result;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_emit_condition:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @condition_name: user-readable name of condition
1N/A * @condition_details: user-readable details of condition
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Emit a condition from a device. Can only be used from hald helpers.
1N/A *
1N/A * Returns: TRUE if condition successfully emitted,
1N/A * FALSE otherwise
1N/A */
1N/Adbus_bool_t libhal_device_emit_condition (LibHalContext *ctx,
1N/A const char *udi,
1N/A const char *condition_name,
1N/A const char *condition_details,
1N/A DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessageIter iter;
1N/A DBusMessageIter reply_iter;
1N/A DBusMessage *reply;
1N/A dbus_bool_t result;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal",
1N/A udi,
1N/A "org.freedesktop.Hal.Device",
1N/A "EmitCondition");
1N/A
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_iter_init_append (message, &iter);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &condition_name);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &condition_details);
1N/A
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A error);
1N/A
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_unref (message);
1N/A
1N/A if (reply == NULL)
1N/A return FALSE;
1N/A
1N/A dbus_message_iter_init (reply, &reply_iter);
1N/A if (dbus_message_iter_get_arg_type (&reply_iter) !=
1N/A DBUS_TYPE_BOOLEAN) {
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return FALSE;
1N/A }
1N/A dbus_message_iter_get_basic (&reply_iter, &result);
1N/A
1N/A dbus_message_unref (reply);
1N/A
1N/A return result;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_addon_is_ready:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * HAL addon's must call this method when they are done initializing the device object. The HAL
1N/A * daemon will wait for all addon's to call this.
1N/A *
1N/A * Can only be used from hald helpers.
1N/A *
1N/A * Returns: TRUE if the HAL daemon received the message, FALSE otherwise
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_addon_is_ready (LibHalContext *ctx, const char *udi, DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessageIter iter;
1N/A DBusMessageIter reply_iter;
1N/A DBusMessage *reply;
1N/A dbus_bool_t result;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal",
1N/A udi,
1N/A "org.freedesktop.Hal.Device",
1N/A "AddonIsReady");
1N/A
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_iter_init_append (message, &iter);
1N/A
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A error);
1N/A
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_unref (message);
1N/A
1N/A if (reply == NULL)
1N/A return FALSE;
1N/A
1N/A dbus_message_iter_init (reply, &reply_iter);
1N/A if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) {
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return FALSE;
1N/A }
1N/A dbus_message_iter_get_basic (&reply_iter, &result);
1N/A
1N/A dbus_message_unref (reply);
1N/A return result;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_claim_interface:
1N/A * @ctx: the context for the connection to hald
1N/A * @udi: the Unique Device Id
1N/A * @interface_name: Name of interface to claim, e.g. org.freedesktop.Hal.Device.FoobarKindOfThing
1N/A * @introspection_xml: Introspection XML containing what would be inside the interface XML tag
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Claim an interface for a device. All messages to this interface
1N/A * will be forwarded to the helper. Can only be used from hald
1N/A * helpers.
1N/A *
1N/A * Returns: TRUE if interface was claimed, FALSE otherwise
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_claim_interface (LibHalContext *ctx,
1N/A const char *udi,
1N/A const char *interface_name,
1N/A const char *introspection_xml,
1N/A DBusError *error)
1N/A{
1N/A DBusMessage *message;
1N/A DBusMessageIter iter;
1N/A DBusMessageIter reply_iter;
1N/A DBusMessage *reply;
1N/A dbus_bool_t result;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal",
1N/A udi,
1N/A "org.freedesktop.Hal.Device",
1N/A "ClaimInterface");
1N/A
1N/A if (message == NULL) {
1N/A fprintf (stderr,
1N/A "%s %d : Couldn't allocate D-BUS message\n",
1N/A __FILE__, __LINE__);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_iter_init_append (message, &iter);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &interface_name);
1N/A dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &introspection_xml);
1N/A
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A error);
1N/A
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_unref (message);
1N/A
1N/A if (reply == NULL)
1N/A return FALSE;
1N/A
1N/A dbus_message_iter_init (reply, &reply_iter);
1N/A if (dbus_message_iter_get_arg_type (&reply_iter) !=
1N/A DBUS_TYPE_BOOLEAN) {
1N/A dbus_message_unref (message);
1N/A dbus_message_unref (reply);
1N/A return FALSE;
1N/A }
1N/A dbus_message_iter_get_basic (&reply_iter, &result);
1N/A
1N/A dbus_message_unref (reply);
1N/A
1N/A return result;
1N/A}
1N/A
1N/A
1N/A
1N/Astruct LibHalChangeSetElement_s;
1N/A
1N/Atypedef struct LibHalChangeSetElement_s LibHalChangeSetElement;
1N/A
1N/Astruct LibHalChangeSetElement_s {
1N/A char *key;
1N/A int change_type;
1N/A union {
1N/A char *val_str;
1N/A dbus_int32_t val_int;
1N/A dbus_uint64_t val_uint64;
1N/A double val_double;
1N/A dbus_bool_t val_bool;
1N/A char **val_strlist;
1N/A } value;
1N/A LibHalChangeSetElement *next;
1N/A LibHalChangeSetElement *prev;
1N/A};
1N/A
1N/Astruct LibHalChangeSet_s {
1N/A char *udi;
1N/A LibHalChangeSetElement *head;
1N/A LibHalChangeSetElement *tail;
1N/A};
1N/A
1N/A/**
1N/A * libhal_device_new_changeset:
1N/A * @udi: unique device identifier
1N/A *
1N/A * Request a new changeset object. Used for changing multiple properties at once. Useful when
1N/A * performance is critical and also for atomically updating several properties.
1N/A *
1N/A * Returns: A new changeset object or NULL on error
1N/A */
1N/ALibHalChangeSet *
1N/Alibhal_device_new_changeset (const char *udi)
1N/A{
1N/A LibHalChangeSet *changeset;
1N/A
1N/A changeset = calloc (1, sizeof (LibHalChangeSet));
1N/A if (changeset == NULL)
1N/A goto out;
1N/A
1N/A changeset->udi = strdup (udi);
1N/A if (changeset->udi == NULL) {
1N/A free (changeset);
1N/A changeset = NULL;
1N/A goto out;
1N/A }
1N/A
1N/A changeset->head = NULL;
1N/A changeset->tail = NULL;
1N/A
1N/Aout:
1N/A return changeset;
1N/A}
1N/A
1N/Astatic void
1N/Alibhal_changeset_append (LibHalChangeSet *changeset, LibHalChangeSetElement *elem)
1N/A{
1N/A if (changeset->head == NULL) {
1N/A changeset->head = elem;
1N/A changeset->tail = elem;
1N/A elem->next = NULL;
1N/A elem->prev = NULL;
1N/A } else {
1N/A elem->prev = changeset->tail;
1N/A elem->next = NULL;
1N/A elem->prev->next = elem;
1N/A changeset->tail = elem;
1N/A }
1N/A}
1N/A
1N/A
1N/A/**
1N/A * libhal_device_set_property_string:
1N/A * @changeset: the changeset
1N/A * @key: key of property
1N/A * @value: the value to set
1N/A *
1N/A * Set a property.
1N/A *
1N/A * Returns: FALSE on OOM
1N/A */
1N/Adbus_bool_t
1N/Alibhal_changeset_set_property_string (LibHalChangeSet *changeset, const char *key, const char *value)
1N/A{
1N/A LibHalChangeSetElement *elem;
1N/A
1N/A elem = calloc (1, sizeof (LibHalChangeSetElement));
1N/A if (elem == NULL)
1N/A goto out;
1N/A elem->key = strdup (key);
1N/A if (elem->key == NULL) {
1N/A free (elem);
1N/A elem = NULL;
1N/A goto out;
1N/A }
1N/A
1N/A elem->change_type = LIBHAL_PROPERTY_TYPE_STRING;
1N/A elem->value.val_str = strdup (value);
1N/A if (elem->value.val_str == NULL) {
1N/A free (elem->key);
1N/A free (elem);
1N/A elem = NULL;
1N/A goto out;
1N/A }
1N/A
1N/A libhal_changeset_append (changeset, elem);
1N/Aout:
1N/A return elem != NULL;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_set_property_int:
1N/A * @changeset: the changeset
1N/A * @key: key of property
1N/A * @value: the value to set
1N/A *
1N/A * Set a property.
1N/A *
1N/A * Returns: FALSE on OOM
1N/A */
1N/Adbus_bool_t
1N/Alibhal_changeset_set_property_int (LibHalChangeSet *changeset, const char *key, dbus_int32_t value)
1N/A{
1N/A LibHalChangeSetElement *elem;
1N/A
1N/A elem = calloc (1, sizeof (LibHalChangeSetElement));
1N/A if (elem == NULL)
1N/A goto out;
1N/A elem->key = strdup (key);
1N/A if (elem->key == NULL) {
1N/A free (elem);
1N/A elem = NULL;
1N/A goto out;
1N/A }
1N/A
1N/A elem->change_type = LIBHAL_PROPERTY_TYPE_INT32;
1N/A elem->value.val_int = value;
1N/A
1N/A libhal_changeset_append (changeset, elem);
1N/Aout:
1N/A return elem != NULL;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_set_property_uint64:
1N/A * @changeset: the changeset
1N/A * @key: key of property
1N/A * @value: the value to set
1N/A *
1N/A * Set a property.
1N/A *
1N/A * Returns: FALSE on OOM
1N/A */
1N/Adbus_bool_t
1N/Alibhal_changeset_set_property_uint64 (LibHalChangeSet *changeset, const char *key, dbus_uint64_t value)
1N/A{
1N/A LibHalChangeSetElement *elem;
1N/A
1N/A elem = calloc (1, sizeof (LibHalChangeSetElement));
1N/A if (elem == NULL)
1N/A goto out;
1N/A elem->key = strdup (key);
1N/A if (elem->key == NULL) {
1N/A free (elem);
1N/A elem = NULL;
1N/A goto out;
1N/A }
1N/A
1N/A elem->change_type = LIBHAL_PROPERTY_TYPE_UINT64;
1N/A elem->value.val_uint64 = value;
1N/A
1N/A libhal_changeset_append (changeset, elem);
1N/Aout:
1N/A return elem != NULL;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_set_property_double:
1N/A * @changeset: the changeset
1N/A * @key: key of property
1N/A * @value: the value to set
1N/A *
1N/A * Set a property.
1N/A *
1N/A * Returns: FALSE on OOM
1N/A */
1N/Adbus_bool_t
1N/Alibhal_changeset_set_property_double (LibHalChangeSet *changeset, const char *key, double value)
1N/A{
1N/A LibHalChangeSetElement *elem;
1N/A
1N/A elem = calloc (1, sizeof (LibHalChangeSetElement));
1N/A if (elem == NULL)
1N/A goto out;
1N/A elem->key = strdup (key);
1N/A if (elem->key == NULL) {
1N/A free (elem);
1N/A elem = NULL;
1N/A goto out;
1N/A }
1N/A
1N/A elem->change_type = LIBHAL_PROPERTY_TYPE_DOUBLE;
1N/A elem->value.val_double = value;
1N/A
1N/A libhal_changeset_append (changeset, elem);
1N/Aout:
1N/A return elem != NULL;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_set_property_bool:
1N/A * @changeset: the changeset
1N/A * @key: key of property
1N/A * @value: the value to set
1N/A *
1N/A * Set a property.
1N/A *
1N/A * Returns: FALSE on OOM
1N/A */
1N/Adbus_bool_t
1N/Alibhal_changeset_set_property_bool (LibHalChangeSet *changeset, const char *key, dbus_bool_t value)
1N/A{
1N/A LibHalChangeSetElement *elem;
1N/A
1N/A elem = calloc (1, sizeof (LibHalChangeSetElement));
1N/A if (elem == NULL)
1N/A goto out;
1N/A elem->key = strdup (key);
1N/A if (elem->key == NULL) {
1N/A free (elem);
1N/A elem = NULL;
1N/A goto out;
1N/A }
1N/A
1N/A elem->change_type = LIBHAL_PROPERTY_TYPE_BOOLEAN;
1N/A elem->value.val_bool = value;
1N/A
1N/A libhal_changeset_append (changeset, elem);
1N/Aout:
1N/A return elem != NULL;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_set_property_strlist:
1N/A * @changeset: the changeset
1N/A * @key: key of property
1N/A * @value: the value to set - NULL terminated array of strings
1N/A *
1N/A * Set a property.
1N/A *
1N/A * Returns: FALSE on OOM
1N/A */
1N/Adbus_bool_t
1N/Alibhal_changeset_set_property_strlist (LibHalChangeSet *changeset, const char *key, const char **value)
1N/A{
1N/A LibHalChangeSetElement *elem;
1N/A char **value_copy;
1N/A int len;
1N/A int i, j;
1N/A
1N/A elem = calloc (1, sizeof (LibHalChangeSetElement));
1N/A if (elem == NULL)
1N/A goto out;
1N/A elem->key = strdup (key);
1N/A if (elem->key == NULL) {
1N/A free (elem);
1N/A elem = NULL;
1N/A goto out;
1N/A }
1N/A
1N/A for (i = 0; value[i] != NULL; i++)
1N/A ;
1N/A len = i;
1N/A
1N/A value_copy = calloc (len + 1, sizeof (char *));
1N/A if (value_copy == NULL) {
1N/A free (elem->key);
1N/A free (elem);
1N/A elem = NULL;
1N/A goto out;
1N/A }
1N/A
1N/A for (i = 0; i < len; i++) {
1N/A value_copy[i] = strdup (value[i]);
1N/A if (value_copy[i] == NULL) {
1N/A for (j = 0; j < i; j++) {
1N/A free (value_copy[j]);
1N/A }
1N/A free (value_copy);
1N/A free (elem->key);
1N/A free (elem);
1N/A elem = NULL;
1N/A goto out;
1N/A }
1N/A }
1N/A value_copy[i] = NULL;
1N/A
1N/A elem->change_type = LIBHAL_PROPERTY_TYPE_STRLIST;
1N/A elem->value.val_strlist = value_copy;
1N/A
1N/A libhal_changeset_append (changeset, elem);
1N/Aout:
1N/A return elem != NULL;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_commit_changeset:
1N/A * @ctx: the context for the connection to hald
1N/A * @changeset: the changeset to commit
1N/A * @error: pointer to an initialized dbus error object for returning errors or NULL
1N/A *
1N/A * Commit a changeset to the daemon.
1N/A *
1N/A * Returns: True if the changeset was committed on the daemon side
1N/A */
1N/Adbus_bool_t
1N/Alibhal_device_commit_changeset (LibHalContext *ctx, LibHalChangeSet *changeset, DBusError *error)
1N/A{
1N/A LibHalChangeSetElement *elem;
1N/A DBusMessage *message;
1N/A DBusMessage *reply;
1N/A DBusError _error;
1N/A DBusMessageIter iter;
1N/A DBusMessageIter sub;
1N/A DBusMessageIter sub2;
1N/A DBusMessageIter sub3;
1N/A DBusMessageIter sub4;
1N/A int i;
1N/A
1N/A LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
1N/A
1N/A if (changeset->head == NULL) {
1N/A return TRUE;
1N/A }
1N/A
1N/A message = dbus_message_new_method_call ("org.freedesktop.Hal", changeset->udi,
1N/A "org.freedesktop.Hal.Device",
1N/A "SetMultipleProperties");
1N/A
1N/A if (message == NULL) {
1N/A fprintf (stderr, "%s %d : Couldn't allocate D-BUS message\n", __FILE__, __LINE__);
1N/A return FALSE;
1N/A }
1N/A
1N/A dbus_message_iter_init_append (message, &iter);
1N/A
1N/A dbus_message_iter_open_container (&iter,
1N/A DBUS_TYPE_ARRAY,
1N/A DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1N/A DBUS_TYPE_STRING_AS_STRING
1N/A DBUS_TYPE_VARIANT_AS_STRING
1N/A DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
1N/A &sub);
1N/A
1N/A for (elem = changeset->head; elem != NULL; elem = elem->next) {
1N/A dbus_message_iter_open_container (&sub,
1N/A DBUS_TYPE_DICT_ENTRY,
1N/A NULL,
1N/A &sub2);
1N/A dbus_message_iter_append_basic (&sub2, DBUS_TYPE_STRING, &(elem->key));
1N/A
1N/A switch (elem->change_type) {
1N/A case LIBHAL_PROPERTY_TYPE_STRING:
1N/A dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &sub3);
1N/A dbus_message_iter_append_basic (&sub3, DBUS_TYPE_STRING, &(elem->value.val_str));
1N/A dbus_message_iter_close_container (&sub2, &sub3);
1N/A break;
1N/A case LIBHAL_PROPERTY_TYPE_STRLIST:
1N/A dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT,
1N/A DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING, &sub3);
1N/A dbus_message_iter_open_container (&sub3, DBUS_TYPE_ARRAY,
1N/A DBUS_TYPE_STRING_AS_STRING, &sub4);
1N/A for (i = 0; elem->value.val_strlist[i] != NULL; i++) {
1N/A dbus_message_iter_append_basic (&sub4, DBUS_TYPE_STRING,
1N/A &(elem->value.val_strlist[i]));
1N/A }
1N/A dbus_message_iter_close_container (&sub3, &sub4);
1N/A dbus_message_iter_close_container (&sub2, &sub3);
1N/A break;
1N/A case LIBHAL_PROPERTY_TYPE_INT32:
1N/A dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, DBUS_TYPE_INT32_AS_STRING, &sub3);
1N/A dbus_message_iter_append_basic (&sub3, DBUS_TYPE_INT32, &(elem->value.val_int));
1N/A dbus_message_iter_close_container (&sub2, &sub3);
1N/A break;
1N/A case LIBHAL_PROPERTY_TYPE_UINT64:
1N/A dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, DBUS_TYPE_UINT64_AS_STRING, &sub3);
1N/A dbus_message_iter_append_basic (&sub3, DBUS_TYPE_UINT64, &(elem->value.val_uint64));
1N/A dbus_message_iter_close_container (&sub2, &sub3);
1N/A break;
1N/A case LIBHAL_PROPERTY_TYPE_DOUBLE:
1N/A dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, DBUS_TYPE_DOUBLE_AS_STRING, &sub3);
1N/A dbus_message_iter_append_basic (&sub3, DBUS_TYPE_DOUBLE, &(elem->value.val_double));
1N/A dbus_message_iter_close_container (&sub2, &sub3);
1N/A break;
1N/A case LIBHAL_PROPERTY_TYPE_BOOLEAN:
1N/A dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, DBUS_TYPE_BOOLEAN_AS_STRING,&sub3);
1N/A dbus_message_iter_append_basic (&sub3, DBUS_TYPE_BOOLEAN, &(elem->value.val_bool));
1N/A dbus_message_iter_close_container (&sub2, &sub3);
1N/A break;
1N/A default:
1N/A fprintf (stderr, "%s %d : unknown change_type %d\n", __FILE__, __LINE__, elem->change_type);
1N/A break;
1N/A }
1N/A dbus_message_iter_close_container (&sub, &sub2);
1N/A }
1N/A
1N/A dbus_message_iter_close_container (&iter, &sub);
1N/A
1N/A
1N/A dbus_error_init (&_error);
1N/A reply = dbus_connection_send_with_reply_and_block (ctx->connection,
1N/A message, -1,
1N/A &_error);
1N/A
1N/A dbus_move_error (&_error, error);
1N/A if (error != NULL && dbus_error_is_set (error)) {
1N/A fprintf (stderr,
1N/A "%s %d : %s\n",
1N/A __FILE__, __LINE__, error->message);
1N/A
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A
1N/A if (reply == NULL) {
1N/A dbus_message_unref (message);
1N/A return FALSE;
1N/A }
1N/A
1N/A return TRUE;
1N/A}
1N/A
1N/A/**
1N/A * libhal_device_free_changeset:
1N/A * @changeset: the changeset to free
1N/A *
1N/A * Free a changeset.
1N/A */
1N/Avoid
1N/Alibhal_device_free_changeset (LibHalChangeSet *changeset)
1N/A{
1N/A LibHalChangeSetElement *elem;
1N/A LibHalChangeSetElement *elem2;
1N/A
1N/A for (elem = changeset->head; elem != NULL; elem = elem2) {
1N/A elem2 = elem->next;
1N/A
1N/A switch (elem->change_type) {
1N/A case LIBHAL_PROPERTY_TYPE_STRING:
1N/A free (elem->value.val_str);
1N/A break;
1N/A case LIBHAL_PROPERTY_TYPE_STRLIST:
1N/A libhal_free_string_array (elem->value.val_strlist);
1N/A break;
1N/A /* explicit fallthrough */
1N/A case LIBHAL_PROPERTY_TYPE_INT32:
1N/A case LIBHAL_PROPERTY_TYPE_UINT64:
1N/A case LIBHAL_PROPERTY_TYPE_DOUBLE:
1N/A case LIBHAL_PROPERTY_TYPE_BOOLEAN:
1N/A break;
1N/A default:
1N/A fprintf (stderr, "%s %d : unknown change_type %d\n", __FILE__, __LINE__, elem->change_type);
1N/A break;
1N/A }
1N/A free (elem);
1N/A }
1N/A
1N/A free (changeset->udi);
1N/A free (changeset);
1N/A}