HAL: libhal.c Source File

Main Page | Modules | Data Structures | Directories | File List | Data Fields | Related Pages

# libhal.c

    00001 /***************************************************************************
    00002  * CVSID: $Id: libhal.c,v 1.55 2005/08/01 17:41:37 david Exp $
    00003  *
    00004  * libhal.c : HAL daemon C convenience library
    00005  *
    00006  * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
    00007  *
    00008  * Licensed under the Academic Free License version 2.0
    00009  *
    00010  * This program is free software; you can redistribute it and/or modify
    00011  * it under the terms of the GNU General Public License as published by
    00012  * the Free Software Foundation; either version 2 of the License, or
    00013  * (at your option) any later version.
    00014  *
    00015  * This program is distributed in the hope that it will be useful,
    00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00018  * GNU General Public License for more details.
    00019  *
    00020  * You should have received a copy of the GNU General Public License
    00021  * along with this program; if not, write to the Free Software
    00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    00023  *
    00024  **************************************************************************/
    00025
    00026 #ifdef HAVE_CONFIG_H
    00027 #  include <config.h>
    00028 #endif
    00029
    00030 #include <stdio.h>
    00031 #include <stdlib.h>
    00032 #include <string.h>
    00033 #include <dbus/dbus.h>
    00034
    00035 #include "libhal.h"
    00036
    00037 #ifdef ENABLE_NLS
    00038 # include <libintl.h>
    00039 # define _(String) dgettext (GETTEXT_PACKAGE, String)
    00040 # ifdef gettext_noop
    00041 #   define N_(String) gettext_noop (String)
    00042 # else
    00043 #   define N_(String) (String)
    00044 # endif
    00045 #else
    00046 /* Stubs that do something close enough.  */
    00047 # define textdomain(String) (String)
    00048 # define gettext(String) (String)
    00049 # define dgettext(Domain,Message) (Message)
    00050 # define dcgettext(Domain,Message,Type) (Message)
    00051 # define bindtextdomain(Domain,Directory) (Domain)
    00052 # define _(String)
    00053 # define N_(String) (String)
    00054 #endif
    00055
    00056 static char **libhal_get_string_array_from_iter (DBusMessageIter *iter, int *num_elements);
    00057
    00058 static dbus_bool_t libhal_property_fill_value_from_variant (LibHalProperty *p, DBusMessageIter *var_iter);
    00059
    00060
    00061
    00074 void
    00075 libhal_free_string_array (char **str_array)
    00076 {
    00077     if (str_array != NULL) {
    00078         int i;
    00079
    00080         for (i = 0; str_array[i] != NULL; i++) {
    00081             free (str_array[i]);
    00082         }
    00083         free (str_array);
    00084     }
    00085 }
    00086
    00087
    00094 static char **
    00095 libhal_get_string_array_from_iter (DBusMessageIter *iter, int *num_elements)
    00096 {
    00097     int count;
    00098     char **buffer;
    00099
    00100     count = 0;
    00101     buffer = (char **)malloc (sizeof (char *) * 8);
    00102
    00103     if (buffer == NULL)
    00104         goto oom;
    00105
    00106     buffer[0] = NULL;
    00107     while (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_STRING) {
    00108         const char *value;
    00109         char *str;
    00110
    00111         if ((count % 8) == 0 && count != 0) {
    00112             buffer = realloc (buffer, sizeof (char *) * (count + 8));
    00113             if (buffer == NULL)
    00114                 goto oom;
    00115         }
    00116
    00117         dbus_message_iter_get_basic (iter, &value);
    00118         str = strdup (value);
    00119         if (str == NULL)
    00120             goto oom;
    00121
    00122         buffer[count] = str;
    00123
    00124         dbus_message_iter_next(iter);
    00125         count++;
    00126     }
    00127
    00128     if ((count % 8) == 0) {
    00129         buffer = realloc (buffer, sizeof (char *) * (count + 1));
    00130         if (buffer == NULL)
    00131             goto oom;
    00132     }
    00133
    00134     buffer[count] = NULL;
    00135     if (num_elements != NULL)
    00136         *num_elements = count;
    00137     return buffer;
    00138
    00139 oom:
    00140     fprintf (stderr, "%s %d : error allocating memory\n", __FILE__, __LINE__);
    00141     return NULL;
    00142
    00143 }
    00144
    00149 void
    00150 libhal_free_string (char *str)
    00151 {
    00153     free (str);
    00154 }
    00155
    00156
    00158 struct LibHalPropertySet_s {
    00159     unsigned int num_properties;
    00160     LibHalProperty *properties_head;
    00163 };
    00164
    00166 struct LibHalProperty_s {
    00167     int type;
    00168     char *key;
    00171     union {
    00172         char *str_value;
    00173         dbus_int32_t int_value;
    00175         dbus_uint64_t uint64_value;
    00177         double double_value;
    00178         dbus_bool_t bool_value;
    00181         char **strlist_value;
    00182     };
    00183
    00184     LibHalProperty *next;
    00186 };
    00187
    00189 struct LibHalContext_s {
    00190     DBusConnection *connection;
    00191     dbus_bool_t is_initialized;
    00192     dbus_bool_t is_shutdown;
    00193     dbus_bool_t cache_enabled;
    00194     dbus_bool_t is_direct;
    00197     LibHalDeviceAdded device_added;
    00198
    00200     LibHalDeviceRemoved device_removed;
    00201
    00203     LibHalDeviceNewCapability device_new_capability;
    00204
    00206     LibHalDeviceLostCapability device_lost_capability;
    00207
    00209     LibHalDevicePropertyModified device_property_modified;
    00210
    00212     LibHalDeviceCondition device_condition;
    00213
    00214     void *user_data;
    00215 };
    00216
    00224 dbus_bool_t
    00225 libhal_ctx_set_user_data(LibHalContext *ctx, void *user_data)
    00226 {
    00227     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    00228     ctx->user_data = user_data;
    00229     return TRUE;
    00230 }
    00231
    00238 void*
    00239 libhal_ctx_get_user_data(LibHalContext *ctx)
    00240 {
    00241     LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
    00242     return ctx->user_data;
    00243 }
    00244
    00245
    00251 static dbus_bool_t
    00252 libhal_property_fill_value_from_variant (LibHalProperty *p, DBusMessageIter *var_iter)
    00253 {
    00254     DBusMessageIter iter_array;
    00255     switch (p->type) {
    00256     case DBUS_TYPE_ARRAY:
    00257         if (dbus_message_iter_get_element_type (var_iter) != DBUS_TYPE_STRING)
    00258             return FALSE;
    00259
    00260         dbus_message_iter_recurse (var_iter, &iter_array);
    00261         p->strlist_value = libhal_get_string_array_from_iter (&iter_array, NULL);
    00262
    00263         p->type = LIBHAL_PROPERTY_TYPE_STRLIST;
    00264
    00265         break;
    00266     case DBUS_TYPE_STRING:
    00267     {
    00268         const char *v;
    00269
    00270         dbus_message_iter_get_basic (var_iter, &v);
    00271
    00272         p->str_value = strdup (v);
    00273         if (p->str_value == NULL)
    00274             return FALSE;
    00275         p->type = LIBHAL_PROPERTY_TYPE_STRING;
    00276
    00277         break;
    00278     }
    00279     case DBUS_TYPE_INT32:
    00280     {
    00281         dbus_int32_t v;
    00282
    00283         dbus_message_iter_get_basic (var_iter, &v);
    00284
    00285         p->int_value = v;
    00286         p->type = LIBHAL_PROPERTY_TYPE_INT32;
    00287
    00288         break;
    00289     }
    00290     case DBUS_TYPE_UINT64:
    00291     {
    00292         dbus_uint64_t v;
    00293
    00294         dbus_message_iter_get_basic (var_iter, &v);
    00295
    00296         p->uint64_value = v;
    00297         p->type = LIBHAL_PROPERTY_TYPE_UINT64;
    00298
    00299         break;
    00300     }
    00301     case DBUS_TYPE_DOUBLE:
    00302     {
    00303         double v;
    00304
    00305         dbus_message_iter_get_basic (var_iter, &v);
    00306
    00307         p->double_value = v;
    00308         p->type = LIBHAL_PROPERTY_TYPE_DOUBLE;
    00309
    00310         break;
    00311     }
    00312     case DBUS_TYPE_BOOLEAN:
    00313     {
    00314         double v;
    00315
    00316         dbus_message_iter_get_basic (var_iter, &v);
    00317
    00318         p->double_value = v;
    00319         p->type = LIBHAL_PROPERTY_TYPE_BOOLEAN;
    00320
    00321         break;
    00322     }
    00323     default:
    00325         break;
    00326     }
    00327
    00328     return TRUE;
    00329 }
    00330
    00340 LibHalPropertySet *
    00341 libhal_device_get_all_properties (LibHalContext *ctx, const char *udi, DBusError *error)
    00342 {
    00343     DBusMessage *message;
    00344     DBusMessage *reply;
    00345     DBusMessageIter reply_iter;
    00346     DBusMessageIter dict_iter;
    00347     LibHalPropertySet *result;
    00348     LibHalProperty *p_last;
    00349     DBusError _error;
    00350
    00351     LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
    00352
    00353     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
    00354                         "org.freedesktop.Hal.Device",
    00355                         "GetAllProperties");
    00356
    00357     if (message == NULL) {
    00358         fprintf (stderr,
    00359              "%s %d : Couldn't allocate D-BUS message\n",
    00360              __FILE__, __LINE__);
    00361         return NULL;
    00362     }
    00363
    00364     dbus_error_init (&_error);
    00365     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    00366                                message, -1,
    00367                                &_error);
    00368
    00369     dbus_move_error (&_error, error);
    00370     if (error != NULL && dbus_error_is_set (error)) {
    00371         fprintf (stderr,
    00372              "%s %d : %s\n",
    00373              __FILE__, __LINE__, error->message);
    00374
    00375         dbus_message_unref (message);
    00376         return NULL;
    00377     }
    00378
    00379     if (reply == NULL) {
    00380         dbus_message_unref (message);
    00381         return NULL;
    00382     }
    00383
    00384     dbus_message_iter_init (reply, &reply_iter);
    00385
    00386     result = malloc (sizeof (LibHalPropertySet));
    00387     if (result == NULL)
    00388         goto oom;
    00389 /*
    00390     result->properties = malloc(sizeof(LibHalProperty)*result->num_properties);
    00391     if( result->properties==NULL )
    00392     {
    00394     return NULL;
    00395     }
    00396 */
    00397
    00398     result->properties_head = NULL;
    00399     result->num_properties = 0;
    00400
    00401     if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY  &&
    00402         dbus_message_iter_get_element_type (&reply_iter) != DBUS_TYPE_DICT_ENTRY) {
    00403         fprintf (stderr, "%s %d : error, expecting an array of dict entries\n",
    00404              __FILE__, __LINE__);
    00405         dbus_message_unref (message);
    00406         dbus_message_unref (reply);
    00407         return NULL;
    00408     }
    00409
    00410     dbus_message_iter_recurse (&reply_iter, &dict_iter);
    00411
    00412     p_last = NULL;
    00413
    00414     while (dbus_message_iter_get_arg_type (&dict_iter) == DBUS_TYPE_DICT_ENTRY)
    00415     {
    00416         DBusMessageIter dict_entry_iter, var_iter;
    00417         const char *key;
    00418         LibHalProperty *p;
    00419
    00420         dbus_message_iter_recurse (&dict_iter, &dict_entry_iter);
    00421
    00422         dbus_message_iter_get_basic (&dict_entry_iter, &key);
    00423
    00424         p = malloc (sizeof (LibHalProperty));
    00425         if (p == NULL)
    00426             goto oom;
    00427
    00428         p->next = NULL;
    00429
    00430         if (result->num_properties == 0)
    00431             result->properties_head = p;
    00432
    00433         if (p_last != NULL)
    00434             p_last->next = p;
    00435
    00436         p_last = p;
    00437
    00438         p->key = strdup (key);
    00439         if (p->key == NULL)
    00440             goto oom;
    00441
    00442         dbus_message_iter_next (&dict_entry_iter);
    00443
    00444         dbus_message_iter_recurse (&dict_entry_iter, &var_iter);
    00445
    00446
    00447         p->type = dbus_message_iter_get_arg_type (&var_iter);
    00448
    00449         result->num_properties++;
    00450
    00451         if(!libhal_property_fill_value_from_variant (p, &var_iter))
    00452             goto oom;
    00453
    00454         dbus_message_iter_next (&dict_iter);
    00455     }
    00456
    00457     dbus_message_unref (message);
    00458     dbus_message_unref (reply);
    00459
    00460     return result;
    00461
    00462 oom:
    00463     fprintf (stderr,
    00464         "%s %d : error allocating memory\n",
    00465          __FILE__, __LINE__);
    00467     return NULL;
    00468 }
    00469
    00474 void
    00475 libhal_free_property_set (LibHalPropertySet * set)
    00476 {
    00477     LibHalProperty *p;
    00478     LibHalProperty *q;
    00479
    00480     if (set == NULL)
    00481         return;
    00482
    00483     for (p = set->properties_head; p != NULL; p = q) {
    00484         free (p->key);
    00485         if (p->type == DBUS_TYPE_STRING)
    00486             free (p->str_value);
    00487         if (p->type == LIBHAL_PROPERTY_TYPE_STRLIST)
    00488             libhal_free_string_array (p->strlist_value);
    00489         q = p->next;
    00490         free (p);
    00491     }
    00492     free (set);
    00493 }
    00494
    00500 unsigned int
    00501 libhal_property_set_get_num_elems (LibHalPropertySet *set)
    00502 {
    00503     unsigned int num_elems;
    00504     LibHalProperty *p;
    00505
    00506     if (set == NULL)
    00507         return 0;
    00508
    00509     num_elems = 0;
    00510     for (p = set->properties_head; p != NULL; p = p->next)
    00511         num_elems++;
    00512
    00513     return num_elems;
    00514 }
    00515
    00516
    00522 void
    00523 libhal_psi_init (LibHalPropertySetIterator * iter, LibHalPropertySet * set)
    00524 {
    00525     if (set == NULL)
    00526         return;
    00527
    00528     iter->set = set;
    00529     iter->index = 0;
    00530     iter->cur_prop = set->properties_head;
    00531 }
    00532
    00533
    00540 dbus_bool_t
    00541 libhal_psi_has_more (LibHalPropertySetIterator * iter)
    00542 {
    00543     return iter->index < iter->set->num_properties;
    00544 }
    00545
    00550 void
    00551 libhal_psi_next (LibHalPropertySetIterator * iter)
    00552 {
    00553     iter->index++;
    00554     iter->cur_prop = iter->cur_prop->next;
    00555 }
    00556
    00562 LibHalPropertyType
    00563 libhal_psi_get_type (LibHalPropertySetIterator * iter)
    00564 {
    00565     return iter->cur_prop->type;
    00566 }
    00567
    00576 char *
    00577 libhal_psi_get_key (LibHalPropertySetIterator * iter)
    00578 {
    00579     return iter->cur_prop->key;
    00580 }
    00581
    00590 char *
    00591 libhal_psi_get_string (LibHalPropertySetIterator * iter)
    00592 {
    00593     return iter->cur_prop->str_value;
    00594 }
    00595
    00601 dbus_int32_t
    00602 libhal_psi_get_int (LibHalPropertySetIterator * iter)
    00603 {
    00604     return iter->cur_prop->int_value;
    00605 }
    00606
    00612 dbus_uint64_t
    00613 libhal_psi_get_uint64 (LibHalPropertySetIterator * iter)
    00614 {
    00615     return iter->cur_prop->uint64_value;
    00616 }
    00617
    00623 double
    00624 libhal_psi_get_double (LibHalPropertySetIterator * iter)
    00625 {
    00626     return iter->cur_prop->double_value;
    00627 }
    00628
    00634 dbus_bool_t
    00635 libhal_psi_get_bool (LibHalPropertySetIterator * iter)
    00636 {
    00637     return iter->cur_prop->bool_value;
    00638 }
    00639
    00645 char **
    00646 libhal_psi_get_strlist (LibHalPropertySetIterator * iter)
    00647 {
    00648     return iter->cur_prop->strlist_value;
    00649 }
    00650
    00651
    00652 #ifndef DOXYGEN_SHOULD_SKIP_THIS
    00653 static DBusHandlerResult
    00654 filter_func (DBusConnection * connection,
    00655          DBusMessage * message, void *user_data)
    00656 {
    00657     const char *object_path;
    00658     DBusError error;
    00659     LibHalContext *ctx = (LibHalContext *) user_data;
    00660
    00661     if (ctx->is_shutdown)
    00662         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    00663
    00664     dbus_error_init (&error);
    00665
    00666     object_path = dbus_message_get_path (message);
    00667
    00668     /*printf("*** in filter_func, object_path=%s\n", object_path);*/
    00669
    00670     if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager",
    00671                     "DeviceAdded")) {
    00672         char *udi;
    00673         if (dbus_message_get_args (message, &error,
    00674                        DBUS_TYPE_STRING, &udi,
    00675                        DBUS_TYPE_INVALID)) {
    00676             if (ctx->device_added != NULL) {
    00677                 ctx->device_added (ctx, udi);
    00678             }
    00679         }
    00680         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    00681     } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager", "DeviceRemoved")) {
    00682         char *udi;
    00683         if (dbus_message_get_args (message, &error,
    00684                        DBUS_TYPE_STRING, &udi,
    00685                        DBUS_TYPE_INVALID)) {
    00686             if (ctx->device_removed != NULL) {
    00687                 ctx->device_removed (ctx, udi);
    00688             }
    00689         }
    00690         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    00691     } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager","NewCapability")) {
    00692         char *udi;
    00693         char *capability;
    00694         if (dbus_message_get_args (message, &error,
    00695                        DBUS_TYPE_STRING, &udi,
    00696                        DBUS_TYPE_STRING, &capability,
    00697                        DBUS_TYPE_INVALID)) {
    00698             if (ctx->device_new_capability != NULL) {
    00699                 ctx->device_new_capability (ctx, udi, capability);
    00700             }
    00701         }
    00702         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    00703     } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Device", "Condition")) {
    00704         char *condition_name;
    00705         char *condition_detail;
    00706         if (dbus_message_get_args (message, &error,
    00707                        DBUS_TYPE_STRING, &condition_name,
    00708                        DBUS_TYPE_STRING, &condition_detail,
    00709                        DBUS_TYPE_INVALID)) {
    00710             if (ctx->device_condition != NULL) {
    00711                 ctx->device_condition (ctx, object_path, condition_name, condition_detail);
    00712             }
    00713         }
    00714         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    00715     } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Device", "PropertyModified")) {
    00716         if (ctx->device_property_modified != NULL) {
    00717             int i;
    00718             char *key;
    00719             dbus_bool_t removed;
    00720             dbus_bool_t added;
    00721             int num_modifications;
    00722             DBusMessageIter iter;
    00723             DBusMessageIter iter_array;
    00724
    00725             dbus_message_iter_init (message, &iter);
    00726             dbus_message_iter_get_basic (&iter, &num_modifications);
    00727             dbus_message_iter_next (&iter);
    00728
    00729             dbus_message_iter_recurse (&iter, &iter_array);
    00730
    00731             for (i = 0; i < num_modifications; i++) {
    00732                 DBusMessageIter iter_struct;
    00733
    00734                 dbus_message_iter_recurse (&iter_array, &iter_struct);
    00735
    00736                 dbus_message_iter_get_basic (&iter_struct, &key);
    00737                 dbus_message_iter_next (&iter_struct);
    00738                 dbus_message_iter_get_basic (&iter_struct, &removed);
    00739                 dbus_message_iter_next (&iter_struct);
    00740                 dbus_message_iter_get_basic (&iter_struct, &added);
    00741
    00742                 ctx->device_property_modified (ctx,
    00743                                    object_path,
    00744                                    key, removed,
    00745                                    added);
    00746
    00747                 dbus_message_iter_next (&iter_array);
    00748             }
    00749
    00750         }
    00751         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    00752     }
    00753
    00754     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    00755 }
    00756
    00757 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
    00758
    00759 /* for i18n purposes */
    00760 static dbus_bool_t libhal_already_initialized_once = FALSE;
    00761
    00762 #if 0
    00763
    00781 LibHalContext*
    00782 libhal_initialize (const LibHalFunctions * cb_functions,
    00783         dbus_bool_t use_cache)
    00784 {
    00785     DBusError error;
    00786     LibHalContext *ctx;
    00787
    00788     if (!libhal_already_initialized_once) {
    00789         bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
    00790         bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
    00791
    00792         libhal_already_initialized_once = TRUE;
    00793     }
    00794
    00795     ctx = malloc (sizeof (LibHalContext));
    00796     if (ctx == NULL) {
    00797         fprintf (stderr, "%s %d : Cannot allocated %d bytes!\n",
    00798              __FILE__, __LINE__, sizeof (LibHalContext));
    00799         return NULL;
    00800     }
    00801
    00802     ctx->is_initialized = FALSE;
    00803     ctx->is_shutdown = FALSE;
    00804
    00805     ctx->cache_enabled = use_cache;
    00806
    00807     ctx->functions = cb_functions;
    00808     /* allow caller to pass NULL */
    00809     if (ctx->functions == NULL)
    00810         ctx->functions = &libhal_null_functions;
    00811
    00812     /* connect to hald service on the system bus */
    00813
    00814     ctx->connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
    00815     if (ctx->connection == NULL) {
    00816         fprintf (stderr,
    00817              "%s %d : Error connecting to system bus: %s\n",
    00818              __FILE__, __LINE__, error.message);
    00819         dbus_error_free (&error);
    00820         return NULL;
    00821     }
    00822
    00823     if (ctx->main_loop_integration != NULL) {
    00824
    00825         ctx->main_loop_integration (ctx, ctx->connection);
    00826     }
    00827
    00828     if (!dbus_connection_add_filter
    00829         (ctx->connection, filter_func, ctx, NULL)) {
    00830         fprintf (stderr,
    00831              "%s %d : Error creating connection handler\r\n",
    00832              __FILE__, __LINE__);
    00834         return NULL;
    00835     }
    00836
    00837     dbus_bus_add_match (ctx->connection,
    00838                 "type='signal',"
    00839                 "interface='org.freedesktop.Hal.Manager',"
    00840                 "sender='org.freedesktop.Hal',"
    00841                 "path='/org/freedesktop/Hal/Manager'", &error);
    00842     if (dbus_error_is_set (&error)) {
    00843         fprintf (stderr, "%s %d : Error subscribing to signals, "
    00844              "error=%s\r\n",
    00845              __FILE__, __LINE__, error.message);
    00847         return NULL;
    00848     }
    00849
    00850     ctx->is_initialized = TRUE;
    00851     return ctx;
    00852 }
    00853
    00860 int
    00861 libhal_shutdown (LibHalContext *ctx)
    00862 {
    00863     DBusError error;
    00864
    00865     if (!ctx->is_initialized)
    00866         return 1;
    00867
    00868     /* unsubscribe the match rule we added in initialize; this is safe even with multiple
    00869      * instances of libhal running - see the dbus docs */
    00870
    00871     dbus_bus_remove_match (ctx->connection,
    00872                    "type='signal',"
    00873                    "interface='org.freedesktop.Hal.Manager',"
    00874                    "sender='org.freedesktop.Hal',"
    00875                    "path='/org/freedesktop/Hal/Manager'", &error);
    00876     if (dbus_error_is_set (&error)) {
    00877         fprintf (stderr, "%s %d : Error removing match rule, error=%s\r\n",
    00878              __FILE__, __LINE__, error.message);
    00879     }
    00880
    00881     /* TODO: remove all other match rules */
    00882
    00883     /* set a flag so we don't propagte callbacks from this context anymore */
    00884     ctx->is_shutdown = TRUE;
    00885
    00886     /* yikes, it's dangerous to unref the connection since it will terminate the process
    00887      * because this connection may be shared so we cannot set the exit_on_disconnect flag
    00888      *
    00889      * so we don't do that right now
    00890      *
    00891      */
    00892     /*dbus_connection_unref (ctx->connection);*/
    00893
    00894     /* we also refuse to free the resources as filter_function may reference these
    00895      *
    00896      * should free async when our connection goes away.
    00897      */
    00898     /* free (ctx); */
    00899     return 0;
    00900 }
    00901 #endif
    00902
    00914 char **
    00915 libhal_get_all_devices (LibHalContext *ctx, int *num_devices, DBusError *error)
    00916 {
    00917     DBusMessage *message;
    00918     DBusMessage *reply;
    00919     DBusMessageIter iter_array, reply_iter;
    00920     char **hal_device_names;
    00921     DBusError _error;
    00922
    00923     LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
    00924
    00925     *num_devices = 0;
    00926
    00927     message = dbus_message_new_method_call ("org.freedesktop.Hal",
    00928                         "/org/freedesktop/Hal/Manager",
    00929                         "org.freedesktop.Hal.Manager",
    00930                         "GetAllDevices");
    00931     if (message == NULL) {
    00932         fprintf (stderr, "%s %d : Could not allocate D-BUS message\n", __FILE__, __LINE__);
    00933         return NULL;
    00934     }
    00935
    00936     dbus_error_init (&_error);
    00937     reply = dbus_connection_send_with_reply_and_block (ctx->connection, message, -1, &_error);
    00938
    00939     dbus_move_error (&_error, error);
    00940     if (error != NULL && dbus_error_is_set (error)) {
    00941         dbus_message_unref (message);
    00942         return NULL;
    00943     }
    00944     if (reply == NULL) {
    00945         dbus_message_unref (message);
    00946         return NULL;
    00947     }
    00948
    00949     /* now analyze reply */
    00950     dbus_message_iter_init (reply, &reply_iter);
    00951
    00952     if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) {
    00953         fprintf (stderr, "%s %d : wrong reply from hald.  Expecting an array.\n", __FILE__, __LINE__);
    00954         return NULL;
    00955     }
    00956
    00957     dbus_message_iter_recurse (&reply_iter, &iter_array);
    00958
    00959     hal_device_names = libhal_get_string_array_from_iter (&iter_array, num_devices);
    00960
    00961     dbus_message_unref (reply);
    00962     dbus_message_unref (message);
    00963
    00964     return hal_device_names;
    00965 }
    00966
    00980 LibHalPropertyType
    00981 libhal_device_get_property_type (LibHalContext *ctx, const char *udi, const char *key, DBusError *error)
    00982 {
    00983     DBusMessage *message;
    00984     DBusMessage *reply;
    00985     DBusMessageIter iter, reply_iter;
    00986     int type;
    00987     DBusError _error;
    00988
    00989     LIBHAL_CHECK_LIBHALCONTEXT(ctx, LIBHAL_PROPERTY_TYPE_INVALID); // or return NULL?
    00990
    00991     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
    00992                         "org.freedesktop.Hal.Device",
    00993                         "GetPropertyType");
    00994     if (message == NULL) {
    00995         fprintf (stderr, "%s %d : Couldn't allocate D-BUS message\n", __FILE__, __LINE__);
    00996         return LIBHAL_PROPERTY_TYPE_INVALID;
    00997     }
    00998
    00999     dbus_message_iter_init_append (message, &iter);
    01000     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
    01001
    01002     dbus_error_init (&_error);
    01003     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    01004                                message, -1,
    01005                                &_error);
    01006
    01007     dbus_move_error (&_error, error);
    01008     if (error != NULL && dbus_error_is_set (error)) {
    01009         dbus_message_unref (message);
    01010         return LIBHAL_PROPERTY_TYPE_INVALID;
    01011     }
    01012     if (reply == NULL) {
    01013         dbus_message_unref (message);
    01014         return LIBHAL_PROPERTY_TYPE_INVALID;
    01015     }
    01016
    01017     dbus_message_iter_init (reply, &reply_iter);
    01018     dbus_message_iter_get_basic (&reply_iter, &type);
    01019
    01020     dbus_message_unref (message);
    01021     dbus_message_unref (reply);
    01022
    01023     return type;
    01024 }
    01025
    01041 char **
    01042 libhal_device_get_property_strlist (LibHalContext *ctx, const char *udi, const char *key, DBusError *error)
    01043 {
    01044     DBusMessage *message;
    01045     DBusMessage *reply;
    01046     DBusMessageIter iter, iter_array, reply_iter;
    01047     char **our_strings;
    01048     DBusError _error;
    01049
    01050     LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
    01051
    01052     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
    01053                         "org.freedesktop.Hal.Device",
    01054                         "GetPropertyStringList");
    01055     if (message == NULL) {
    01056         fprintf (stderr,
    01057              "%s %d : Couldn't allocate D-BUS message\n",
    01058              __FILE__, __LINE__);
    01059         return NULL;
    01060     }
    01061
    01062     dbus_message_iter_init_append (message, &iter);
    01063     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
    01064
    01065     dbus_error_init (&_error);
    01066     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    01067                                message, -1,
    01068                                &_error);
    01069
    01070     dbus_move_error (&_error, error);
    01071     if (error != NULL && dbus_error_is_set (error)) {
    01072         dbus_message_unref (message);
    01073         return NULL;
    01074     }
    01075     if (reply == NULL) {
    01076         dbus_message_unref (message);
    01077         return NULL;
    01078     }
    01079     /* now analyse reply */
    01080     dbus_message_iter_init (reply, &reply_iter);
    01081
    01082     if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) {
    01083         fprintf (stderr, "%s %d : wrong reply from hald.  Expecting an array.\n", __FILE__, __LINE__);
    01084         return NULL;
    01085     }
    01086
    01087     dbus_message_iter_recurse (&reply_iter, &iter_array);
    01088
    01089     our_strings = libhal_get_string_array_from_iter (&iter_array, NULL);
    01090
    01091     dbus_message_unref (reply);
    01092     dbus_message_unref (message);
    01093
    01094     return our_strings;
    01095 }
    01096
    01110 char *
    01111 libhal_device_get_property_string (LibHalContext *ctx,
    01112                    const char *udi, const char *key, DBusError *error)
    01113 {
    01114     DBusMessage *message;
    01115     DBusMessage *reply;
    01116     DBusMessageIter iter, reply_iter;
    01117     char *value;
    01118     char *dbus_str;
    01119     DBusError _error;
    01120
    01121     LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
    01122
    01123     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
    01124                         "org.freedesktop.Hal.Device",
    01125                         "GetPropertyString");
    01126
    01127     if (message == NULL) {
    01128         fprintf (stderr,
    01129              "%s %d : Couldn't allocate D-BUS message\n",
    01130              __FILE__, __LINE__);
    01131         return NULL;
    01132     }
    01133
    01134     dbus_message_iter_init_append (message, &iter);
    01135     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
    01136
    01137     dbus_error_init (&_error);
    01138     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    01139                                message, -1,
    01140                                &_error);
    01141
    01142     dbus_move_error (&_error, error);
    01143     if (error != NULL && dbus_error_is_set (error)) {
    01144         dbus_message_unref (message);
    01145         return NULL;
    01146     }
    01147     if (reply == NULL) {
    01148         dbus_message_unref (message);
    01149         return NULL;
    01150     }
    01151
    01152     dbus_message_iter_init (reply, &reply_iter);
    01153
    01154     /* now analyze reply */
    01155     if (dbus_message_iter_get_arg_type (&reply_iter) !=
    01156            DBUS_TYPE_STRING) {
    01157         dbus_message_unref (message);
    01158         dbus_message_unref (reply);
    01159         return NULL;
    01160     }
    01161
    01162     dbus_message_iter_get_basic (&reply_iter, &dbus_str);
    01163     value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL);
    01164     if (value == NULL) {
    01165         fprintf (stderr, "%s %d : error allocating memory\n",
    01166              __FILE__, __LINE__);
    01168         return NULL;
    01169     }
    01170
    01171     dbus_message_unref (message);
    01172     dbus_message_unref (reply);
    01173     return value;
    01174 }
    01175
    01185 dbus_int32_t
    01186 libhal_device_get_property_int (LibHalContext *ctx,
    01187                 const char *udi, const char *key, DBusError *error)
    01188 {
    01189     DBusMessage *message;
    01190     DBusMessage *reply;
    01191     DBusMessageIter iter, reply_iter;
    01192     dbus_int32_t value;
    01193     DBusError _error;
    01194
    01195     LIBHAL_CHECK_LIBHALCONTEXT(ctx, -1);
    01196
    01197     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
    01198                         "org.freedesktop.Hal.Device",
    01199                         "GetPropertyInteger");
    01200     if (message == NULL) {
    01201         fprintf (stderr,
    01202              "%s %d : Couldn't allocate D-BUS message\n",
    01203              __FILE__, __LINE__);
    01204         return -1;
    01205     }
    01206
    01207     dbus_message_iter_init_append (message, &iter);
    01208     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
    01209
    01210     dbus_error_init (&_error);
    01211     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    01212                                message, -1,
    01213                                &_error);
    01214
    01215     dbus_move_error (&_error, error);
    01216     if (error != NULL && dbus_error_is_set (error)) {
    01217         dbus_message_unref (message);
    01218         return -1;
    01219     }
    01220     if (reply == NULL) {
    01221         dbus_message_unref (message);
    01222         return -1;
    01223     }
    01224
    01225     dbus_message_iter_init (reply, &reply_iter);
    01226
    01227     /* now analyze reply */
    01228     if (dbus_message_iter_get_arg_type (&reply_iter) !=
    01229            DBUS_TYPE_INT32) {
    01230         fprintf (stderr,
    01231              "%s %d : property '%s' for device '%s' is not "
    01232              "of type integer\n", __FILE__, __LINE__, key,
    01233              udi);
    01234         dbus_message_unref (message);
    01235         dbus_message_unref (reply);
    01236         return -1;
    01237     }
    01238     dbus_message_iter_get_basic (&reply_iter, &value);
    01239
    01240     dbus_message_unref (message);
    01241     dbus_message_unref (reply);
    01242     return value;
    01243 }
    01244
    01254 dbus_uint64_t
    01255 libhal_device_get_property_uint64 (LibHalContext *ctx,
    01256                    const char *udi, const char *key, DBusError *error)
    01257 {
    01258     DBusMessage *message;
    01259     DBusMessage *reply;
    01260     DBusMessageIter iter, reply_iter;
    01261     dbus_uint64_t value;
    01262     DBusError _error;
    01263
    01264     LIBHAL_CHECK_LIBHALCONTEXT(ctx, -1);
    01265
    01266     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
    01267                         "org.freedesktop.Hal.Device",
    01268                         "GetPropertyInteger");
    01269     if (message == NULL) {
    01270         fprintf (stderr,
    01271              "%s %d : Couldn't allocate D-BUS message\n",
    01272              __FILE__, __LINE__);
    01273         return -1;
    01274     }
    01275
    01276     dbus_message_iter_init_append (message, &iter);
    01277     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
    01278
    01279     dbus_error_init (&_error);
    01280     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    01281                                message, -1,
    01282                                &_error);
    01283
    01284     dbus_move_error (&_error, error);
    01285     if (error != NULL && dbus_error_is_set (error)) {
    01286         dbus_message_unref (message);
    01287         return -1;
    01288     }
    01289     if (reply == NULL) {
    01290         dbus_message_unref (message);
    01291         return -1;
    01292     }
    01293
    01294     dbus_message_iter_init (reply, &reply_iter);
    01295     /* now analyze reply */
    01296     if (dbus_message_iter_get_arg_type (&reply_iter) !=
    01297            DBUS_TYPE_UINT64) {
    01298         fprintf (stderr,
    01299              "%s %d : property '%s' for device '%s' is not "
    01300              "of type integer\n", __FILE__, __LINE__, key,
    01301              udi);
    01302         dbus_message_unref (message);
    01303         dbus_message_unref (reply);
    01304         return -1;
    01305     }
    01306     dbus_message_iter_get_basic (&reply_iter, &value);
    01307
    01308     dbus_message_unref (message);
    01309     dbus_message_unref (reply);
    01310     return value;
    01311 }
    01312
    01322 double
    01323 libhal_device_get_property_double (LibHalContext *ctx,
    01324                    const char *udi, const char *key, DBusError *error)
    01325 {
    01326     DBusMessage *message;
    01327     DBusMessage *reply;
    01328     DBusMessageIter iter, reply_iter;
    01329     double value;
    01330     DBusError _error;
    01331
    01332     LIBHAL_CHECK_LIBHALCONTEXT(ctx, -1.0);
    01333
    01334     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
    01335                         "org.freedesktop.Hal.Device",
    01336                         "GetPropertyDouble");
    01337     if (message == NULL) {
    01338         fprintf (stderr,
    01339              "%s %d : Couldn't allocate D-BUS message\n",
    01340              __FILE__, __LINE__);
    01341         return -1.0f;
    01342     }
    01343
    01344     dbus_message_iter_init_append (message, &iter);
    01345     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
    01346
    01347     dbus_error_init (&_error);
    01348     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    01349                                message, -1,
    01350                                &_error);
    01351
    01352     dbus_move_error (&_error, error);
    01353     if (error != NULL && dbus_error_is_set (error)) {
    01354         dbus_message_unref (message);
    01355         return -1.0f;
    01356     }
    01357     if (reply == NULL) {
    01358         dbus_message_unref (message);
    01359         return -1.0f;
    01360     }
    01361
    01362     dbus_message_iter_init (reply, &reply_iter);
    01363
    01364     /* now analyze reply */
    01365     if (dbus_message_iter_get_arg_type (&reply_iter) !=
    01366            DBUS_TYPE_DOUBLE) {
    01367         fprintf (stderr,
    01368              "%s %d : property '%s' for device '%s' is not "
    01369              "of type double\n", __FILE__, __LINE__, key, udi);
    01370         dbus_message_unref (message);
    01371         dbus_message_unref (reply);
    01372         return -1.0f;
    01373     }
    01374     dbus_message_iter_get_basic (&reply_iter, &value);
    01375
    01376     dbus_message_unref (message);
    01377     dbus_message_unref (reply);
    01378     return (double) value;
    01379 }
    01380
    01390 dbus_bool_t
    01391 libhal_device_get_property_bool (LibHalContext *ctx,
    01392                  const char *udi, const char *key, DBusError *error)
    01393 {
    01394     DBusMessage *message;
    01395     DBusMessage *reply;
    01396     DBusMessageIter iter, reply_iter;
    01397     dbus_bool_t value;
    01398     DBusError _error;
    01399
    01400     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    01401
    01402     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
    01403                         "org.freedesktop.Hal.Device",
    01404                         "GetPropertyBoolean");
    01405     if (message == NULL) {
    01406         fprintf (stderr,
    01407              "%s %d : Couldn't allocate D-BUS message\n",
    01408              __FILE__, __LINE__);
    01409         return FALSE;
    01410     }
    01411
    01412     dbus_message_iter_init_append (message, &iter);
    01413     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
    01414
    01415     dbus_error_init (&_error);
    01416     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    01417                                message, -1,
    01418                                &_error);
    01419
    01420     dbus_move_error (&_error, error);
    01421     if (error != NULL && dbus_error_is_set (error)) {
    01422         dbus_message_unref (message);
    01423         return FALSE;
    01424     }
    01425     if (reply == NULL) {
    01426         dbus_message_unref (message);
    01427         return FALSE;
    01428     }
    01429
    01430     dbus_message_iter_init (reply, &reply_iter);
    01431
    01432     /* now analyze reply */
    01433     if (dbus_message_iter_get_arg_type (&reply_iter) !=
    01434            DBUS_TYPE_BOOLEAN) {
    01435         fprintf (stderr,
    01436              "%s %d : property '%s' for device '%s' is not "
    01437              "of type bool\n", __FILE__, __LINE__, key, udi);
    01438         dbus_message_unref (message);
    01439         dbus_message_unref (reply);
    01440         return FALSE;
    01441     }
    01442     dbus_message_iter_get_basic (&reply_iter, &value);
    01443
    01444     dbus_message_unref (message);
    01445     dbus_message_unref (reply);
    01446     return value;
    01447 }
    01448
    01449
    01450 /* generic helper */
    01451 static dbus_bool_t
    01452 libhal_device_set_property_helper (LibHalContext *ctx,
    01453                    const char *udi,
    01454                    const char *key,
    01455                    int type,
    01456                    const char *str_value,
    01457                    dbus_int32_t int_value,
    01458                    dbus_uint64_t uint64_value,
    01459                    double double_value,
    01460                    dbus_bool_t bool_value,
    01461                    DBusError *error)
    01462 {
    01463     DBusMessage *message;
    01464     DBusMessage *reply;
    01465     DBusMessageIter iter;
    01466     char *method_name = NULL;
    01467
    01468     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    01469
    01471     switch (type) {
    01472     case DBUS_TYPE_INVALID:
    01473         method_name = "RemoveProperty";
    01474         break;
    01475     case DBUS_TYPE_STRING:
    01476         method_name = "SetPropertyString";
    01477         break;
    01478     case DBUS_TYPE_INT32:
    01479     case DBUS_TYPE_UINT64:
    01480         method_name = "SetPropertyInteger";
    01481         break;
    01482     case DBUS_TYPE_DOUBLE:
    01483         method_name = "SetPropertyDouble";
    01484         break;
    01485     case DBUS_TYPE_BOOLEAN:
    01486         method_name = "SetPropertyBoolean";
    01487         break;
    01488
    01489     default:
    01490         /* cannot happen; is not callable from outside this file */
    01491         break;
    01492     }
    01493
    01494     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
    01495                         "org.freedesktop.Hal.Device",
    01496                         method_name);
    01497     if (message == NULL) {
    01498         fprintf (stderr,
    01499              "%s %d : Couldn't allocate D-BUS message\n",
    01500              __FILE__, __LINE__);
    01501         return FALSE;
    01502     }
    01503
    01504     dbus_message_iter_init_append (message, &iter);
    01505     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
    01506     switch (type) {
    01507     case DBUS_TYPE_STRING:
    01508         dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &str_value);
    01509         break;
    01510     case DBUS_TYPE_INT32:
    01511         dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &int_value);
    01512         break;
    01513     case DBUS_TYPE_UINT64:
    01514         dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT64, &uint64_value);
    01515         break;
    01516     case DBUS_TYPE_DOUBLE:
    01517         dbus_message_iter_append_basic (&iter, DBUS_TYPE_DOUBLE, &double_value);
    01518         break;
    01519     case DBUS_TYPE_BOOLEAN:
    01520         dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &bool_value);
    01521         break;
    01522     }
    01523
    01524
    01525     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    01526                                message, -1,
    01527                                error);
    01528     if (dbus_error_is_set (error)) {
    01529         dbus_message_unref (message);
    01530         return FALSE;
    01531     }
    01532
    01533     if (reply == NULL) {
    01534         dbus_message_unref (message);
    01535         return FALSE;
    01536     }
    01537
    01538     dbus_message_unref (message);
    01539     dbus_message_unref (reply);
    01540
    01541     return TRUE;
    01542 }
    01543
    01556 dbus_bool_t
    01557 libhal_device_set_property_string (LibHalContext *ctx,
    01558                    const char *udi,
    01559                    const char *key,
    01560                    const char *value,
    01561                    DBusError *error)
    01562 {
    01563     return libhal_device_set_property_helper (ctx, udi, key,
    01564                           DBUS_TYPE_STRING,
    01565                           value, 0, 0, 0.0f, FALSE, error);
    01566 }
    01567
    01580 dbus_bool_t
    01581 libhal_device_set_property_int (LibHalContext *ctx, const char *udi,
    01582                 const char *key, dbus_int32_t value, DBusError *error)
    01583 {
    01584     return libhal_device_set_property_helper (ctx, udi, key,
    01585                           DBUS_TYPE_INT32,
    01586                           NULL, value, 0, 0.0f, FALSE, error);
    01587 }
    01588
    01601 dbus_bool_t
    01602 libhal_device_set_property_uint64 (LibHalContext *ctx, const char *udi,
    01603                    const char *key, dbus_uint64_t value, DBusError *error)
    01604 {
    01605     return libhal_device_set_property_helper (ctx, udi, key,
    01606                           DBUS_TYPE_UINT64,
    01607                           NULL, 0, value, 0.0f, FALSE, error);
    01608 }
    01609
    01622 dbus_bool_t
    01623 libhal_device_set_property_double (LibHalContext *ctx, const char *udi,
    01624                    const char *key, double value, DBusError *error)
    01625 {
    01626     return libhal_device_set_property_helper (ctx, udi, key,
    01627                           DBUS_TYPE_DOUBLE,
    01628                           NULL, 0, 0, value, FALSE, error);
    01629 }
    01630
    01643 dbus_bool_t
    01644 libhal_device_set_property_bool (LibHalContext *ctx, const char *udi,
    01645                  const char *key, dbus_bool_t value, DBusError *error)
    01646 {
    01647     return libhal_device_set_property_helper (ctx, udi, key,
    01648                           DBUS_TYPE_BOOLEAN,
    01649                           NULL, 0, 0, 0.0f, value, error);
    01650 }
    01651
    01652
    01663 dbus_bool_t
    01664 libhal_device_remove_property (LibHalContext *ctx,
    01665                    const char *udi, const char *key, DBusError *error)
    01666 {
    01667     return libhal_device_set_property_helper (ctx, udi, key, DBUS_TYPE_INVALID,
    01668                           /* DBUS_TYPE_INVALID means remove */
    01669                           NULL, 0, 0, 0.0f, FALSE, error);
    01670 }
    01671
    01684 dbus_bool_t
    01685 libhal_device_property_strlist_append (LibHalContext *ctx,
    01686                        const char *udi,
    01687                        const char *key,
    01688                        const char *value,
    01689                        DBusError *error)
    01690 {
    01691     DBusMessage *message;
    01692     DBusMessage *reply;
    01693     DBusMessageIter iter;
    01694
    01695     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    01696
    01697     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
    01698                         "org.freedesktop.Hal.Device",
    01699                         "StringListAppend");
    01700     if (message == NULL) {
    01701         fprintf (stderr,
    01702              "%s %d : Couldn't allocate D-BUS message\n",
    01703              __FILE__, __LINE__);
    01704         return FALSE;
    01705     }
    01706     dbus_message_iter_init_append (message, &iter);
    01707     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
    01708     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
    01709
    01710     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    01711                                message, -1,
    01712                                error);
    01713     if (dbus_error_is_set (error)) {
    01714         dbus_message_unref (message);
    01715         return FALSE;
    01716     }
    01717     if (reply == NULL) {
    01718         dbus_message_unref (message);
    01719         return FALSE;
    01720     }
    01721     return TRUE;
    01722 }
    01723
    01736 dbus_bool_t
    01737 libhal_device_property_strlist_prepend (LibHalContext *ctx,
    01738                     const char *udi,
    01739                     const char *key,
    01740                     const char *value,
    01741                     DBusError *error)
    01742 {
    01743     DBusMessage *message;
    01744     DBusMessage *reply;
    01745     DBusMessageIter iter;
    01746
    01747     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    01748
    01749     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
    01750                         "org.freedesktop.Hal.Device",
    01751                         "StringListPrepend");
    01752     if (message == NULL) {
    01753         fprintf (stderr,
    01754              "%s %d : Couldn't allocate D-BUS message\n",
    01755              __FILE__, __LINE__);
    01756         return FALSE;
    01757     }
    01758     dbus_message_iter_init_append (message, &iter);
    01759     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
    01760     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
    01761
    01762     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    01763                                message, -1,
    01764                                error);
    01765     if (dbus_error_is_set (error)) {
    01766         dbus_message_unref (message);
    01767         return FALSE;
    01768     }
    01769     if (reply == NULL) {
    01770         dbus_message_unref (message);
    01771         return FALSE;
    01772     }
    01773     return TRUE;
    01774 }
    01775
    01788 dbus_bool_t
    01789 libhal_device_property_strlist_remove_index (LibHalContext *ctx,
    01790                          const char *udi,
    01791                          const char *key,
    01792                          unsigned int index,
    01793                          DBusError *error)
    01794 {
    01795     DBusMessage *message;
    01796     DBusMessage *reply;
    01797     DBusMessageIter iter;
    01798
    01799     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    01800
    01801     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
    01802                         "org.freedesktop.Hal.Device",
    01803                         "StringListRemoveIndex");
    01804     if (message == NULL) {
    01805         fprintf (stderr,
    01806              "%s %d : Couldn't allocate D-BUS message\n",
    01807              __FILE__, __LINE__);
    01808         return FALSE;
    01809     }
    01810     dbus_message_iter_init_append (message, &iter);
    01811     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
    01812     dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &index);
    01813
    01814     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    01815                                message, -1,
    01816                                error);
    01817     if (dbus_error_is_set (error)) {
    01818         dbus_message_unref (message);
    01819         return FALSE;
    01820     }
    01821     if (reply == NULL) {
    01822         dbus_message_unref (message);
    01823         return FALSE;
    01824     }
    01825     return TRUE;
    01826 }
    01827
    01840 dbus_bool_t
    01841 libhal_device_property_strlist_remove (LibHalContext *ctx,
    01842                        const char *udi,
    01843                        const char *key,
    01844                        const char *value, DBusError *error)
    01845 {
    01846     DBusMessage *message;
    01847     DBusMessage *reply;
    01848     DBusMessageIter iter;
    01849
    01850     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    01851
    01852     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
    01853                         "org.freedesktop.Hal.Device",
    01854                         "StringListRemove");
    01855     if (message == NULL) {
    01856         fprintf (stderr,
    01857              "%s %d : Couldn't allocate D-BUS message\n",
    01858              __FILE__, __LINE__);
    01859         return FALSE;
    01860     }
    01861     dbus_message_iter_init_append (message, &iter);
    01862     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
    01863     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
    01864
    01865     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    01866                                message, -1,
    01867                                error);
    01868     if (dbus_error_is_set (error)) {
    01869         dbus_message_unref (message);
    01870         return FALSE;
    01871     }
    01872     if (reply == NULL) {
    01873         dbus_message_unref (message);
    01874         return FALSE;
    01875     }
    01876     return TRUE;
    01877 }
    01878
    01879
    01894 dbus_bool_t
    01895 libhal_device_lock (LibHalContext *ctx,
    01896             const char *udi,
    01897             const char *reason_to_lock,
    01898             char **reason_why_locked, DBusError *error)
    01899 {
    01900     DBusMessage *message;
    01901     DBusMessageIter iter;
    01902     DBusMessage *reply;
    01903
    01904     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    01905
    01906     if (reason_why_locked != NULL)
    01907         *reason_why_locked = NULL;
    01908
    01909     message = dbus_message_new_method_call ("org.freedesktop.Hal",
    01910                         udi,
    01911                         "org.freedesktop.Hal.Device",
    01912                         "Lock");
    01913
    01914     if (message == NULL) {
    01915         fprintf (stderr,
    01916              "%s %d : Couldn't allocate D-BUS message\n",
    01917              __FILE__, __LINE__);
    01918         return FALSE;
    01919     }
    01920
    01921     dbus_message_iter_init_append (message, &iter);
    01922     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &reason_to_lock);
    01923
    01924
    01925     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    01926                                message, -1,
    01927                                error);
    01928
    01929     if (dbus_error_is_set (error)) {
    01930         if (strcmp (error->name,
    01931                 "org.freedesktop.Hal.DeviceAlreadyLocked") == 0) {
    01932             if (reason_why_locked != NULL) {
    01933                 *reason_why_locked =
    01934                     dbus_malloc0 (strlen (error->message) + 1);
    01935                 strcpy (*reason_why_locked, error->message);
    01936             }
    01937         }
    01938
    01939         dbus_message_unref (message);
    01940         return FALSE;
    01941     }
    01942
    01943     dbus_message_unref (message);
    01944
    01945     if (reply == NULL)
    01946         return FALSE;
    01947
    01948     dbus_message_unref (reply);
    01949
    01950     return TRUE;
    01951 }
    01952
    01962 dbus_bool_t
    01963 libhal_device_unlock (LibHalContext *ctx,
    01964               const char *udi, DBusError *error)
    01965 {
    01966     DBusMessage *message;
    01967     DBusMessage *reply;
    01968
    01969     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    01970
    01971     message = dbus_message_new_method_call ("org.freedesktop.Hal",
    01972                         udi,
    01973                         "org.freedesktop.Hal.Device",
    01974                         "Unlock");
    01975
    01976     if (message == NULL) {
    01977         fprintf (stderr,
    01978              "%s %d : Couldn't allocate D-BUS message\n",
    01979              __FILE__, __LINE__);
    01980         return FALSE;
    01981     }
    01982
    01983
    01984     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    01985                                message, -1,
    01986                                error);
    01987
    01988     if (dbus_error_is_set (error)) {
    01989         dbus_message_unref (message);
    01990         return FALSE;
    01991     }
    01992
    01993     dbus_message_unref (message);
    01994
    01995     if (reply == NULL)
    01996         return FALSE;
    01997
    01998     dbus_message_unref (reply);
    01999
    02000     return TRUE;
    02001 }
    02002
    02003
    02017 char *
    02018 libhal_new_device (LibHalContext *ctx, DBusError *error)
    02019 {
    02020     DBusMessage *message;
    02021     DBusMessage *reply;
    02022     DBusMessageIter reply_iter;
    02023     char *value;
    02024     char *dbus_str;
    02025
    02026     LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
    02027
    02028     message = dbus_message_new_method_call ("org.freedesktop.Hal",
    02029                         "/org/freedesktop/Hal/Manager",
    02030                         "org.freedesktop.Hal.Manager",
    02031                         "NewDevice");
    02032     if (message == NULL) {
    02033         fprintf (stderr,
    02034              "%s %d : Couldn't allocate D-BUS message\n",
    02035              __FILE__, __LINE__);
    02036         return NULL;
    02037     }
    02038
    02039
    02040     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    02041                                message, -1,
    02042                                error);
    02043     if (dbus_error_is_set (error)) {
    02044         dbus_message_unref (message);
    02045         return NULL;
    02046     }
    02047     if (reply == NULL) {
    02048         dbus_message_unref (message);
    02049         return NULL;
    02050     }
    02051
    02052     dbus_message_iter_init (reply, &reply_iter);
    02053
    02054     /* now analyze reply */
    02055     if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_STRING) {
    02056         fprintf (stderr,
    02057              "%s %d : expected a string in reply to NewDevice\n",
    02058              __FILE__, __LINE__);
    02059         dbus_message_unref (message);
    02060         dbus_message_unref (reply);
    02061         return NULL;
    02062     }
    02063
    02064     dbus_message_iter_get_basic (&reply_iter, &dbus_str);
    02065     value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL);
    02066     if (value == NULL) {
    02067         fprintf (stderr, "%s %d : error allocating memory\n",
    02068              __FILE__, __LINE__);
    02070         return NULL;
    02071     }
    02072
    02073     dbus_message_unref (message);
    02074     dbus_message_unref (reply);
    02075     return value;
    02076 }
    02077
    02078
    02099 dbus_bool_t
    02100 libhal_device_commit_to_gdl (LibHalContext *ctx,
    02101                  const char *temp_udi, const char *udi, DBusError *error)
    02102 {
    02103     DBusMessage *message;
    02104     DBusMessage *reply;
    02105     DBusMessageIter iter;
    02106
    02107     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    02108
    02109     message = dbus_message_new_method_call ("org.freedesktop.Hal",
    02110                         "/org/freedesktop/Hal/Manager",
    02111                         "org.freedesktop.Hal.Manager",
    02112                         "CommitToGdl");
    02113     if (message == NULL) {
    02114         fprintf (stderr,
    02115              "%s %d : Couldn't allocate D-BUS message\n",
    02116              __FILE__, __LINE__);
    02117         return FALSE;
    02118     }
    02119
    02120     dbus_message_iter_init_append (message, &iter);
    02121     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &temp_udi);
    02122     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi);
    02123
    02124
    02125     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    02126                                message, -1,
    02127                                error);
    02128     if (dbus_error_is_set (error)) {
    02129         dbus_message_unref (message);
    02130         return FALSE;
    02131     }
    02132     if (reply == NULL) {
    02133         dbus_message_unref (message);
    02134         return FALSE;
    02135     }
    02136
    02137     dbus_message_unref (message);
    02138     dbus_message_unref (reply);
    02139     return TRUE;
    02140 }
    02141
    02155 dbus_bool_t
    02156 libhal_remove_device (LibHalContext *ctx, const char *udi, DBusError *error)
    02157 {
    02158     DBusMessage *message;
    02159     DBusMessage *reply;
    02160     DBusMessageIter iter;
    02161
    02162     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    02163
    02164     message = dbus_message_new_method_call ("org.freedesktop.Hal",
    02165                         "/org/freedesktop/Hal/Manager",
    02166                         "org.freedesktop.Hal.Manager",
    02167                         "Remove");
    02168     if (message == NULL) {
    02169         fprintf (stderr,
    02170              "%s %d : Couldn't allocate D-BUS message\n",
    02171              __FILE__, __LINE__);
    02172         return FALSE;
    02173     }
    02174
    02175     dbus_message_iter_init_append (message, &iter);
    02176     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi);
    02177
    02178
    02179     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    02180                                message, -1,
    02181                                error);
    02182     if (dbus_error_is_set (error)) {
    02183         dbus_message_unref (message);
    02184         return FALSE;
    02185     }
    02186     if (reply == NULL) {
    02187         dbus_message_unref (message);
    02188         return FALSE;
    02189     }
    02190
    02191     dbus_message_unref (message);
    02192     dbus_message_unref (reply);
    02193     return TRUE;
    02194 }
    02195
    02204 dbus_bool_t
    02205 libhal_device_exists (LibHalContext *ctx, const char *udi, DBusError *error)
    02206 {
    02207     DBusMessage *message;
    02208     DBusMessage *reply;
    02209     DBusMessageIter iter, reply_iter;
    02210     dbus_bool_t value;
    02211     DBusError _error;
    02212
    02213     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    02214
    02215     message = dbus_message_new_method_call ("org.freedesktop.Hal",
    02216                         "/org/freedesktop/Hal/Manager",
    02217                         "org.freedesktop.Hal.Manager",
    02218                         "DeviceExists");
    02219     if (message == NULL) {
    02220         fprintf (stderr,
    02221              "%s %d : Couldn't allocate D-BUS message\n",
    02222              __FILE__, __LINE__);
    02223         return FALSE;
    02224     }
    02225
    02226     dbus_message_iter_init_append (message, &iter);
    02227     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi);
    02228
    02229     dbus_error_init (&_error);
    02230     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    02231                                message, -1,
    02232                                &_error);
    02233
    02234     dbus_move_error (&_error, error);
    02235     if (error != NULL && dbus_error_is_set (error)) {
    02236         dbus_message_unref (message);
    02237         return FALSE;
    02238     }
    02239     if (reply == NULL) {
    02240         dbus_message_unref (message);
    02241         return FALSE;
    02242     }
    02243
    02244     dbus_message_iter_init (reply, &reply_iter);
    02245
    02246     /* now analyze reply */
    02247     if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) {
    02248         fprintf (stderr,
    02249              "%s %d : expected a bool in reply to DeviceExists\n",
    02250              __FILE__, __LINE__);
    02251         dbus_message_unref (message);
    02252         dbus_message_unref (reply);
    02253         return FALSE;
    02254     }
    02255
    02256     dbus_message_iter_get_basic (&reply_iter, &value);
    02257
    02258     dbus_message_unref (message);
    02259     dbus_message_unref (reply);
    02260     return value;
    02261 }
    02262
    02272 dbus_bool_t
    02273 libhal_device_property_exists (LibHalContext *ctx,
    02274                    const char *udi, const char *key, DBusError *error)
    02275 {
    02276     DBusMessage *message;
    02277     DBusMessage *reply;
    02278     DBusMessageIter iter, reply_iter;
    02279     dbus_bool_t value;
    02280     DBusError _error;
    02281
    02282     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    02283
    02284     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
    02285                         "org.freedesktop.Hal.Device",
    02286                         "PropertyExists");
    02287     if (message == NULL) {
    02288         fprintf (stderr,
    02289              "%s %d : Couldn't allocate D-BUS message\n",
    02290              __FILE__, __LINE__);
    02291         return FALSE;
    02292     }
    02293
    02294     dbus_message_iter_init_append (message, &iter);
    02295     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
    02296
    02297     dbus_error_init (&_error);
    02298     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    02299                                message, -1,
    02300                                &_error);
    02301
    02302     dbus_move_error (&_error, error);
    02303     if (error != NULL && dbus_error_is_set (error)) {
    02304         dbus_message_unref (message);
    02305         return FALSE;
    02306     }
    02307     if (reply == NULL) {
    02308         dbus_message_unref (message);
    02309         return FALSE;
    02310     }
    02311
    02312     dbus_message_iter_init (reply, &reply_iter);
    02313
    02314     /* now analyse reply */
    02315     if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) {
    02316         fprintf (stderr, "%s %d : expected a bool in reply to "
    02317              "PropertyExists\n", __FILE__, __LINE__);
    02318         dbus_message_unref (message);
    02319         dbus_message_unref (reply);
    02320         return FALSE;
    02321     }
    02322
    02323     dbus_message_iter_get_basic (&reply_iter, &value);
    02324
    02325     dbus_message_unref (message);
    02326     dbus_message_unref (reply);
    02327     return value;
    02328 }
    02329
    02339 dbus_bool_t
    02340 libhal_merge_properties (LibHalContext *ctx,
    02341              const char *target_udi, const char *source_udi, DBusError *error)
    02342 {
    02343     DBusMessage *message;
    02344     DBusMessage *reply;
    02345     DBusMessageIter iter;
    02346
    02347     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    02348
    02349     message = dbus_message_new_method_call ("org.freedesktop.Hal",
    02350                         "/org/freedesktop/Hal/Manager",
    02351                         "org.freedesktop.Hal.Manager",
    02352                         "MergeProperties");
    02353     if (message == NULL) {
    02354         fprintf (stderr,
    02355              "%s %d : Couldn't allocate D-BUS message\n",
    02356              __FILE__, __LINE__);
    02357         return FALSE;
    02358     }
    02359
    02360     dbus_message_iter_init_append (message, &iter);
    02361     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &target_udi);
    02362     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &source_udi);
    02363
    02364
    02365     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    02366                                message, -1,
    02367                                error);
    02368     if (dbus_error_is_set (error)) {
    02369         dbus_message_unref (message);
    02370         return FALSE;
    02371     }
    02372     if (reply == NULL) {
    02373         dbus_message_unref (message);
    02374         return FALSE;
    02375     }
    02376
    02377     dbus_message_unref (message);
    02378     dbus_message_unref (reply);
    02379     return TRUE;
    02380 }
    02381
    02403 dbus_bool_t
    02404 libhal_device_matches (LibHalContext *ctx,
    02405                  const char *udi1, const char *udi2,
    02406                  const char *property_namespace, DBusError *error)
    02407 {
    02408     DBusMessage *message;
    02409     DBusMessage *reply;
    02410     DBusMessageIter iter, reply_iter;
    02411     dbus_bool_t value;
    02412     DBusError _error;
    02413
    02414     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    02415
    02416     message = dbus_message_new_method_call ("org.freedesktop.Hal",
    02417                         "/org/freedesktop/Hal/Manager",
    02418                         "org.freedesktop.Hal.Manager",
    02419                         "DeviceMatches");
    02420     if (message == NULL) {
    02421         fprintf (stderr,
    02422              "%s %d : Couldn't allocate D-BUS message\n",
    02423              __FILE__, __LINE__);
    02424         return FALSE;
    02425     }
    02426
    02427     dbus_message_iter_init_append (message, &iter);
    02428     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, udi1);
    02429     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, udi2);
    02430     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, property_namespace);
    02431
    02432     dbus_error_init (&_error);
    02433     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    02434                                message, -1,
    02435                                &_error);
    02436
    02437     dbus_move_error (&_error, error);
    02438     if (error != NULL && dbus_error_is_set (error)) {
    02439         dbus_message_unref (message);
    02440         return FALSE;
    02441     }
    02442     if (reply == NULL) {
    02443         dbus_message_unref (message);
    02444         return FALSE;
    02445     }
    02446     /* now analyse reply */
    02447     dbus_message_iter_init (reply, &reply_iter);
    02448
    02449     if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) {
    02450         fprintf (stderr,
    02451              "%s %d : expected a bool in reply to DeviceMatches\n",
    02452              __FILE__, __LINE__);
    02453         dbus_message_unref (message);
    02454         dbus_message_unref (reply);
    02455         return FALSE;
    02456     }
    02457
    02458     dbus_message_iter_get_basic (&reply_iter, &value);
    02459
    02460     dbus_message_unref (message);
    02461     dbus_message_unref (reply);
    02462     return value;
    02463 }
    02464
    02474 dbus_bool_t
    02475 libhal_device_print (LibHalContext *ctx, const char *udi, DBusError *error)
    02476 {
    02477     int type;
    02478     char *key;
    02479     LibHalPropertySet *pset;
    02480     LibHalPropertySetIterator i;
    02481
    02482     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    02483
    02484     printf ("device_id = %s\n", udi);
    02485
    02486     if ((pset = libhal_device_get_all_properties (ctx, udi, error)) == NULL)
    02487         return FALSE;
    02488
    02489     for (libhal_psi_init (&i, pset); libhal_psi_has_more (&i);
    02490          libhal_psi_next (&i)) {
    02491         type = libhal_psi_get_type (&i);
    02492         key = libhal_psi_get_key (&i);
    02493
    02494         switch (type) {
    02495         case LIBHAL_PROPERTY_TYPE_STRING:
    02496             printf ("    %s = '%s' (string)\n", key,
    02497                 libhal_psi_get_string (&i));
    02498             break;
    02499         case LIBHAL_PROPERTY_TYPE_INT32:
    02500             printf ("    %s = %d = 0x%x (int)\n", key,
    02501                 libhal_psi_get_int (&i),
    02502                 libhal_psi_get_int (&i));
    02503             break;
    02504         case LIBHAL_PROPERTY_TYPE_UINT64:
    02505             printf ("    %s = %lld = 0x%llx (uint64)\n", key,
    02506                 libhal_psi_get_uint64 (&i),
    02507                 libhal_psi_get_uint64 (&i));
    02508             break;
    02509         case LIBHAL_PROPERTY_TYPE_BOOLEAN:
    02510             printf ("    %s = %s (bool)\n", key,
    02511                 (libhal_psi_get_bool (&i) ? "true" :
    02512                  "false"));
    02513             break;
    02514         case LIBHAL_PROPERTY_TYPE_DOUBLE:
    02515             printf ("    %s = %g (double)\n", key,
    02516                 libhal_psi_get_double (&i));
    02517             break;
    02518         case LIBHAL_PROPERTY_TYPE_STRLIST:
    02519         {
    02520             unsigned int j;
    02521             char **str_list;
    02522
    02523             str_list = libhal_psi_get_strlist (&i);
    02524             printf ("    %s = [", key);
    02525             for (j = 0; str_list[j] != NULL; j++) {
    02526                 printf ("'%s'", str_list[j]);
    02527                 if (str_list[j+1] != NULL)
    02528                     printf (", ");
    02529             }
    02530             printf ("] (string list)\n");
    02531
    02532             break;
    02533         }
    02534         default:
    02535             printf ("    *** unknown type for key %s\n", key);
    02536             break;
    02537         }
    02538     }
    02539
    02540     libhal_free_property_set (pset);
    02541
    02542     return TRUE;
    02543 }
    02544
    02557 char **
    02558 libhal_manager_find_device_string_match (LibHalContext *ctx,
    02559                      const char *key,
    02560                      const char *value, int *num_devices, DBusError *error)
    02561 {
    02562     DBusMessage *message;
    02563     DBusMessage *reply;
    02564     DBusMessageIter iter, iter_array, reply_iter;
    02565     char **hal_device_names;
    02566     DBusError _error;
    02567
    02568     LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
    02569
    02570     message = dbus_message_new_method_call ("org.freedesktop.Hal",
    02571                         "/org/freedesktop/Hal/Manager",
    02572                         "org.freedesktop.Hal.Manager",
    02573                         "FindDeviceStringMatch");
    02574     if (message == NULL) {
    02575         fprintf (stderr,
    02576              "%s %d : Couldn't allocate D-BUS message\n",
    02577              __FILE__, __LINE__);
    02578         return NULL;
    02579     }
    02580
    02581     dbus_message_iter_init_append (message, &iter);
    02582     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
    02583     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
    02584
    02585     dbus_error_init (&_error);
    02586     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    02587                                message, -1,
    02588                                &_error);
    02589
    02590     dbus_move_error (&_error, error);
    02591     if (error != NULL && dbus_error_is_set (error)) {
    02592         dbus_message_unref (message);
    02593         return NULL;
    02594     }
    02595     if (reply == NULL) {
    02596         dbus_message_unref (message);
    02597         return NULL;
    02598     }
    02599     /* now analyse reply */
    02600     dbus_message_iter_init (reply, &reply_iter);
    02601
    02602     if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) {
    02603         fprintf (stderr, "%s %d : wrong reply from hald.  Expecting an array.\n", __FILE__, __LINE__);
    02604         return NULL;
    02605     }
    02606
    02607     dbus_message_iter_recurse (&reply_iter, &iter_array);
    02608
    02609     hal_device_names = libhal_get_string_array_from_iter (&iter_array, num_devices);
    02610
    02611     dbus_message_unref (reply);
    02612     dbus_message_unref (message);
    02613
    02614     return hal_device_names;
    02615 }
    02616
    02617
    02628 dbus_bool_t
    02629 libhal_device_add_capability (LibHalContext *ctx,
    02630                   const char *udi, const char *capability, DBusError *error)
    02631 {
    02632     DBusMessage *message;
    02633     DBusMessage *reply;
    02634     DBusMessageIter iter;
    02635
    02636     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    02637
    02638     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
    02639                         "org.freedesktop.Hal.Device",
    02640                         "AddCapability");
    02641     if (message == NULL) {
    02642         fprintf (stderr,
    02643              "%s %d : Couldn't allocate D-BUS message\n",
    02644              __FILE__, __LINE__);
    02645         return FALSE;
    02646     }
    02647
    02648     dbus_message_iter_init_append (message, &iter);
    02649     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &capability);
    02650
    02651
    02652     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    02653                                message, -1,
    02654                                error);
    02655     if (dbus_error_is_set (error)) {
    02656         dbus_message_unref (message);
    02657         return FALSE;
    02658     }
    02659
    02660     if (reply == NULL) {
    02661         dbus_message_unref (message);
    02662         return FALSE;
    02663     }
    02664
    02665     dbus_message_unref (reply);
    02666     dbus_message_unref (message);
    02667     return TRUE;
    02668 }
    02669
    02681 dbus_bool_t
    02682 libhal_device_query_capability (LibHalContext *ctx, const char *udi, const char *capability, DBusError *error)
    02683 {
    02684     char **caps;
    02685     unsigned int i;
    02686     dbus_bool_t ret;
    02687
    02688     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    02689
    02690     ret = FALSE;
    02691
    02692     caps = libhal_device_get_property_strlist (ctx, udi, "info.capabilities", error);
    02693     if (caps != NULL) {
    02694         for (i = 0; caps[i] != NULL; i++) {
    02695             if (strcmp (caps[i], capability) == 0) {
    02696                 ret = TRUE;
    02697                 break;
    02698             }
    02699         }
    02700         libhal_free_string_array (caps);
    02701     }
    02702
    02703     return ret;
    02704 }
    02705
    02716 char **
    02717 libhal_find_device_by_capability (LibHalContext *ctx,
    02718                   const char *capability, int *num_devices, DBusError *error)
    02719 {
    02720     DBusMessage *message;
    02721     DBusMessage *reply;
    02722     DBusMessageIter iter, iter_array, reply_iter;
    02723     char **hal_device_names;
    02724     DBusError _error;
    02725
    02726     LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
    02727
    02728     message = dbus_message_new_method_call ("org.freedesktop.Hal",
    02729                         "/org/freedesktop/Hal/Manager",
    02730                         "org.freedesktop.Hal.Manager",
    02731                         "FindDeviceByCapability");
    02732     if (message == NULL) {
    02733         fprintf (stderr,
    02734              "%s %d : Couldn't allocate D-BUS message\n",
    02735              __FILE__, __LINE__);
    02736         return NULL;
    02737     }
    02738
    02739     dbus_message_iter_init_append (message, &iter);
    02740     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &capability);
    02741
    02742     dbus_error_init (&_error);
    02743     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    02744                                message, -1,
    02745                                &_error);
    02746
    02747     dbus_move_error (&_error, error);
    02748     if (error != NULL && dbus_error_is_set (error)) {
    02749         dbus_message_unref (message);
    02750         return NULL;
    02751     }
    02752     if (reply == NULL) {
    02753         dbus_message_unref (message);
    02754         return NULL;
    02755     }
    02756     /* now analyse reply */
    02757     dbus_message_iter_init (reply, &reply_iter);
    02758
    02759     if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) {
    02760         fprintf (stderr, "%s %d : wrong reply from hald.  Expecting an array.\n", __FILE__, __LINE__);
    02761         return NULL;
    02762     }
    02763
    02764     dbus_message_iter_recurse (&reply_iter, &iter_array);
    02765
    02766     hal_device_names = libhal_get_string_array_from_iter (&iter_array, num_devices);
    02767
    02768     dbus_message_unref (reply);
    02769     dbus_message_unref (message);
    02770
    02771     return hal_device_names;
    02772 }
    02773
    02782 dbus_bool_t
    02783 libhal_device_property_watch_all (LibHalContext *ctx, DBusError *error)
    02784 {
    02785     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    02786
    02787     dbus_bus_add_match (ctx->connection,
    02788                 "type='signal',"
    02789                 "interface='org.freedesktop.Hal.Device',"
    02790                 "sender='org.freedesktop.Hal'", error);
    02791     if (dbus_error_is_set (error)) {
    02792         return FALSE;
    02793     }
    02794     return TRUE;
    02795 }
    02796
    02797
    02810 dbus_bool_t
    02811 libhal_device_add_property_watch (LibHalContext *ctx, const char *udi, DBusError *error)
    02812 {
    02813     char buf[512];
    02814
    02815     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    02816
    02817     snprintf (buf, 512,
    02818           "type='signal',"
    02819           "interface='org.freedesktop.Hal.Device',"
    02820           "sender='org.freedesktop.Hal'," "path=%s", udi);
    02821
    02822     dbus_bus_add_match (ctx->connection, buf, error);
    02823     if (dbus_error_is_set (error)) {
    02824         return FALSE;
    02825     }
    02826     return TRUE;
    02827 }
    02828
    02829
    02838 dbus_bool_t
    02839 libhal_device_remove_property_watch (LibHalContext *ctx, const char *udi, DBusError *error)
    02840 {
    02841     char buf[512];
    02842
    02843     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    02844
    02845     snprintf (buf, 512,
    02846           "type='signal',"
    02847           "interface='org.freedesktop.Hal.Device',"
    02848           "sender='org.freedesktop.Hal'," "path=%s", udi);
    02849
    02850     dbus_bus_remove_match (ctx->connection, buf, error);
    02851     if (dbus_error_is_set (error)) {
    02852         return FALSE;
    02853     }
    02854     return TRUE;
    02855 }
    02856
    02857
    02862 LibHalContext *
    02863 libhal_ctx_new (void)
    02864 {
    02865     LibHalContext *ctx;
    02866
    02867     if (!libhal_already_initialized_once) {
    02868         bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
    02869         bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
    02870
    02871         libhal_already_initialized_once = TRUE;
    02872     }
    02873
    02874     ctx = calloc (1, sizeof (LibHalContext));
    02875     if (ctx == NULL) {
    02876         fprintf (stderr,
    02877              "%s %d : Failed to allocate %d bytes\n",
    02878              __FILE__, __LINE__, sizeof (LibHalContext));
    02879         return NULL;
    02880     }
    02881
    02882     ctx->is_initialized = FALSE;
    02883     ctx->is_shutdown = FALSE;
    02884     ctx->connection = NULL;
    02885     ctx->is_direct = FALSE;
    02886
    02887     return ctx;
    02888 }
    02889
    02899 dbus_bool_t
    02900 libhal_ctx_set_cache (LibHalContext *ctx, dbus_bool_t use_cache)
    02901 {
    02902     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    02903
    02904     ctx->cache_enabled = use_cache;
    02905     return TRUE;
    02906 }
    02907
    02915 dbus_bool_t
    02916 libhal_ctx_set_dbus_connection (LibHalContext *ctx, DBusConnection *conn)
    02917 {
    02918     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    02919
    02920     if (conn == NULL)
    02921         return FALSE;
    02922
    02923     ctx->connection = conn;
    02924     return TRUE;
    02925 }
    02926
    02935 dbus_bool_t
    02936 libhal_ctx_init (LibHalContext *ctx, DBusError *error)
    02937 {
    02938     DBusError _error;
    02939     dbus_bool_t hald_exists;
    02940
    02941     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    02942
    02943     if (ctx->connection == NULL)
    02944         return FALSE;
    02945
    02946     dbus_error_init (&_error);
    02947     hald_exists = dbus_bus_name_has_owner (ctx->connection, "org.freedesktop.Hal", &_error);
    02948     dbus_move_error (&_error, error);
    02949     if (error != NULL && dbus_error_is_set (error)) {
    02950         return FALSE;
    02951     }
    02952
    02953     if (!hald_exists) {
    02954         return FALSE;
    02955     }
    02956
    02957
    02958     if (!dbus_connection_add_filter (ctx->connection, filter_func, ctx, NULL)) {
    02959         return FALSE;
    02960     }
    02961
    02962     dbus_bus_add_match (ctx->connection,
    02963                 "type='signal',"
    02964                 "interface='org.freedesktop.Hal.Manager',"
    02965                 "sender='org.freedesktop.Hal',"
    02966                 "path='/org/freedesktop/Hal/Manager'", &_error);
    02967     dbus_move_error (&_error, error);
    02968     if (error != NULL && dbus_error_is_set (error)) {
    02969         return FALSE;
    02970     }
    02971     ctx->is_initialized = TRUE;
    02972     ctx->is_direct = FALSE;
    02973
    02974     return TRUE;
    02975 }
    02976
    02983 LibHalContext *
    02984 libhal_ctx_init_direct (DBusError *error)
    02985 {
    02986     char *hald_addr;
    02987     LibHalContext *ctx;
    02988     DBusError _error;
    02989
    02990     ctx = libhal_ctx_new ();
    02991     if (ctx == NULL)
    02992         goto out;
    02993
    02994     if (((hald_addr = getenv ("HALD_DIRECT_ADDR"))) == NULL) {
    02995         libhal_ctx_free (ctx);
    02996         ctx = NULL;
    02997         goto out;
    02998     }
    02999
    03000     dbus_error_init (&_error);
    03001     ctx->connection = dbus_connection_open (hald_addr, &_error);
    03002     dbus_move_error (&_error, error);
    03003     if (error != NULL && dbus_error_is_set (error)) {
    03004         libhal_ctx_free (ctx);
    03005         ctx = NULL;
    03006         goto out;
    03007     }
    03008
    03009     ctx->is_initialized = TRUE;
    03010     ctx->is_direct = TRUE;
    03011
    03012 out:
    03013     return ctx;
    03014 }
    03015
    03024 dbus_bool_t
    03025 libhal_ctx_shutdown (LibHalContext *ctx, DBusError *error)
    03026 {
    03027     DBusError myerror;
    03028
    03029     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    03030
    03031     if (ctx->is_direct) {
    03032         /* for some reason dbus_connection_set_exit_on_disconnect doesn't work yet so don't unref */
    03033         /*dbus_connection_unref (ctx->connection);*/
    03034     } else {
    03035         dbus_error_init (&myerror);
    03036         dbus_bus_remove_match (ctx->connection,
    03037                        "type='signal',"
    03038                        "interface='org.freedesktop.Hal.Manager',"
    03039                        "sender='org.freedesktop.Hal',"
    03040                        "path='/org/freedesktop/Hal/Manager'", &myerror);
    03041         if (dbus_error_is_set (&myerror)) {
    03042             fprintf (stderr, "%s %d : Error unsubscribing to signals, error=%s\n",
    03043                  __FILE__, __LINE__, error->message);
    03045         }
    03046
    03047         /* TODO: remove other matches */
    03048
    03049         dbus_connection_remove_filter (ctx->connection, filter_func, ctx);
    03050     }
    03051
    03052     ctx->is_initialized = FALSE;
    03053
    03054     return TRUE;
    03055 }
    03056
    03062 dbus_bool_t
    03063 libhal_ctx_free (LibHalContext *ctx)
    03064 {
    03065     free (ctx);
    03066     return TRUE;
    03067 }
    03068
    03076 dbus_bool_t
    03077 libhal_ctx_set_device_added (LibHalContext *ctx, LibHalDeviceAdded callback)
    03078 {
    03079     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    03080
    03081     ctx->device_added = callback;
    03082     return TRUE;
    03083 }
    03084
    03092 dbus_bool_t
    03093 libhal_ctx_set_device_removed (LibHalContext *ctx, LibHalDeviceRemoved callback)
    03094 {
    03095     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    03096
    03097     ctx->device_removed = callback;
    03098     return TRUE;
    03099 }
    03100
    03109 dbus_bool_t
    03110 libhal_ctx_set_device_new_capability (LibHalContext *ctx, LibHalDeviceNewCapability callback)
    03111 {
    03112     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    03113
    03114     ctx->device_new_capability = callback;
    03115     return TRUE;
    03116 }
    03117
    03126 dbus_bool_t
    03127 libhal_ctx_set_device_lost_capability (LibHalContext *ctx, LibHalDeviceLostCapability callback)
    03128 {
    03129     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    03130
    03131     ctx->device_lost_capability = callback;
    03132     return TRUE;
    03133 }
    03134
    03143 dbus_bool_t
    03144 libhal_ctx_set_device_property_modified (LibHalContext *ctx, LibHalDevicePropertyModified callback)
    03145 {
    03146     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    03147
    03148     ctx->device_property_modified = callback;
    03149     return TRUE;
    03150 }
    03151
    03159 dbus_bool_t
    03160 libhal_ctx_set_device_condition (LibHalContext *ctx, LibHalDeviceCondition callback)
    03161 {
    03162     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    03163
    03164     ctx->device_condition = callback;
    03165     return TRUE;
    03166 }
    03167
    03173 unsigned int libhal_string_array_length (char **str_array)
    03174 {
    03175     unsigned int i;
    03176
    03177     if (str_array == NULL)
    03178         return 0;
    03179
    03180     for (i = 0; str_array[i] != NULL; i++)
    03181         ;
    03182
    03183     return i;
    03184 }
    03185
    03186
    03187 dbus_bool_t
    03188 libhal_device_rescan (LibHalContext *ctx, const char *udi, DBusError *error)
    03189 {
    03190     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    03191
    03192     DBusMessage *message;
    03193     DBusMessageIter reply_iter;
    03194     DBusMessage *reply;
    03195     dbus_bool_t result;
    03196
    03197     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
    03198                         "org.freedesktop.Hal.Device",
    03199                         "Rescan");
    03200
    03201     if (message == NULL) {
    03202         fprintf (stderr,
    03203              "%s %d : Couldn't allocate D-BUS message\n",
    03204              __FILE__, __LINE__);
    03205         return FALSE;
    03206     }
    03207
    03208     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    03209                                message, -1,
    03210                                error);
    03211
    03212     if (dbus_error_is_set (error)) {
    03213         dbus_message_unref (message);
    03214         return FALSE;
    03215     }
    03216
    03217     dbus_message_unref (message);
    03218
    03219     if (reply == NULL)
    03220         return FALSE;
    03221
    03222     dbus_message_iter_init (reply, &reply_iter);
    03223     if (dbus_message_iter_get_arg_type (&reply_iter) !=
    03224            DBUS_TYPE_BOOLEAN) {
    03225         dbus_message_unref (message);
    03226         dbus_message_unref (reply);
    03227         return FALSE;
    03228     }
    03229     dbus_message_iter_get_basic (&reply_iter, &result);
    03230
    03231     dbus_message_unref (reply);
    03232
    03233     return result;
    03234 }
    03235
    03236 dbus_bool_t
    03237 libhal_device_reprobe (LibHalContext *ctx, const char *udi, DBusError *error)
    03238 {
    03239     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    03240
    03241     DBusMessage *message;
    03242     DBusMessageIter reply_iter;
    03243     DBusMessage *reply;
    03244     dbus_bool_t result;
    03245
    03246     message = dbus_message_new_method_call ("org.freedesktop.Hal",
    03247                         udi,
    03248                         "org.freedesktop.Hal.Device",
    03249                         "Reprobe");
    03250
    03251     if (message == NULL) {
    03252         fprintf (stderr,
    03253              "%s %d : Couldn't allocate D-BUS message\n",
    03254              __FILE__, __LINE__);
    03255         return FALSE;
    03256     }
    03257
    03258     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    03259                                message, -1,
    03260                                error);
    03261
    03262     if (dbus_error_is_set (error)) {
    03263         dbus_message_unref (message);
    03264         return FALSE;
    03265     }
    03266
    03267     dbus_message_unref (message);
    03268
    03269     if (reply == NULL)
    03270         return FALSE;
    03271
    03272     dbus_message_iter_init (reply, &reply_iter);
    03273     if (dbus_message_iter_get_arg_type (&reply_iter) !=
    03274            DBUS_TYPE_BOOLEAN) {
    03275         dbus_message_unref (message);
    03276         dbus_message_unref (reply);
    03277         return FALSE;
    03278     }
    03279     dbus_message_iter_get_basic (&reply_iter, &result);
    03280
    03281     dbus_message_unref (reply);
    03282
    03283     return result;
    03284 }
    03285
    03297 dbus_bool_t libhal_device_emit_condition (LibHalContext *ctx,
    03298                       const char *udi,
    03299                       const char *condition_name,
    03300                       const char *condition_details,
    03301                       DBusError *error)
    03302 {
    03303     LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
    03304
    03305     DBusMessage *message;
    03306     DBusMessageIter iter;
    03307     DBusMessageIter reply_iter;
    03308     DBusMessage *reply;
    03309     dbus_bool_t result;
    03310
    03311     message = dbus_message_new_method_call ("org.freedesktop.Hal",
    03312                         udi,
    03313                         "org.freedesktop.Hal.Device",
    03314                         "EmitCondition");
    03315
    03316     if (message == NULL) {
    03317         fprintf (stderr,
    03318              "%s %d : Couldn't allocate D-BUS message\n",
    03319              __FILE__, __LINE__);
    03320         return FALSE;
    03321     }
    03322
    03323     dbus_message_iter_init_append (message, &iter);
    03324     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &condition_name);
    03325     dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &condition_details);
    03326
    03327     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
    03328                                message, -1,
    03329                                error);
    03330
    03331     if (dbus_error_is_set (error)) {
    03332         dbus_message_unref (message);
    03333         return FALSE;
    03334     }
    03335
    03336     dbus_message_unref (message);
    03337
    03338     if (reply == NULL)
    03339         return FALSE;
    03340
    03341     dbus_message_iter_init (reply, &reply_iter);
    03342     if (dbus_message_iter_get_arg_type (&reply_iter) !=
    03343            DBUS_TYPE_BOOLEAN) {
    03344         dbus_message_unref (message);
    03345         dbus_message_unref (reply);
    03346         return FALSE;
    03347     }
    03348     dbus_message_iter_get_basic (&reply_iter, &result);
    03349
    03350     dbus_message_unref (reply);
    03351
    03352     return result;
    03353 }
    03354