00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
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
00391
00392
00394
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
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
00758
00759
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
00809 if (ctx->functions == NULL)
00810 ctx->functions = &libhal_null_functions;
00811
00812
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
00869
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
00882
00883
00884 ctx->is_shutdown = TRUE;
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
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
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);
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
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
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
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
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
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
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
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
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 (error != NULL && 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
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 (error != NULL && 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 (error != NULL && 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 (error != NULL && 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 (error != NULL && 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 (error != NULL && 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 (error != NULL && 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 (error != NULL && 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
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 (error != NULL && 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 (error != NULL && 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
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
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 (error != NULL && 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
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
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 (error != NULL && 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
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 (error != NULL && 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 (error != NULL && 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 (error != NULL && 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
02932 DBusConnection *
02933 libhal_ctx_get_dbus_connection (LibHalContext *ctx)
02934 {
02935 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
02936
02937 return ctx->connection;
02938 }
02939
02940
02949 dbus_bool_t
02950 libhal_ctx_init (LibHalContext *ctx, DBusError *error)
02951 {
02952 DBusError _error;
02953 dbus_bool_t hald_exists;
02954
02955 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
02956
02957 if (ctx->connection == NULL)
02958 return FALSE;
02959
02960 dbus_error_init (&_error);
02961 hald_exists = dbus_bus_name_has_owner (ctx->connection, "org.freedesktop.Hal", &_error);
02962 dbus_move_error (&_error, error);
02963 if (error != NULL && dbus_error_is_set (error)) {
02964 return FALSE;
02965 }
02966
02967 if (!hald_exists) {
02968 return FALSE;
02969 }
02970
02971
02972 if (!dbus_connection_add_filter (ctx->connection, filter_func, ctx, NULL)) {
02973 return FALSE;
02974 }
02975
02976 dbus_bus_add_match (ctx->connection,
02977 "type='signal',"
02978 "interface='org.freedesktop.Hal.Manager',"
02979 "sender='org.freedesktop.Hal',"
02980 "path='/org/freedesktop/Hal/Manager'", &_error);
02981 dbus_move_error (&_error, error);
02982 if (error != NULL && dbus_error_is_set (error)) {
02983 return FALSE;
02984 }
02985 ctx->is_initialized = TRUE;
02986 ctx->is_direct = FALSE;
02987
02988 return TRUE;
02989 }
02990
02997 LibHalContext *
02998 libhal_ctx_init_direct (DBusError *error)
02999 {
03000 char *hald_addr;
03001 LibHalContext *ctx;
03002 DBusError _error;
03003
03004 ctx = libhal_ctx_new ();
03005 if (ctx == NULL)
03006 goto out;
03007
03008 if (((hald_addr = getenv ("HALD_DIRECT_ADDR"))) == NULL) {
03009 libhal_ctx_free (ctx);
03010 ctx = NULL;
03011 goto out;
03012 }
03013
03014 dbus_error_init (&_error);
03015 ctx->connection = dbus_connection_open (hald_addr, &_error);
03016 dbus_move_error (&_error, error);
03017 if (error != NULL && dbus_error_is_set (error)) {
03018 libhal_ctx_free (ctx);
03019 ctx = NULL;
03020 goto out;
03021 }
03022
03023 ctx->is_initialized = TRUE;
03024 ctx->is_direct = TRUE;
03025
03026 out:
03027 return ctx;
03028 }
03029
03038 dbus_bool_t
03039 libhal_ctx_shutdown (LibHalContext *ctx, DBusError *error)
03040 {
03041 DBusError myerror;
03042
03043 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
03044
03045 if (ctx->is_direct) {
03046
03047
03048 } else {
03049 dbus_error_init (&myerror);
03050 dbus_bus_remove_match (ctx->connection,
03051 "type='signal',"
03052 "interface='org.freedesktop.Hal.Manager',"
03053 "sender='org.freedesktop.Hal',"
03054 "path='/org/freedesktop/Hal/Manager'", &myerror);
03055 if (dbus_error_is_set (&myerror)) {
03056 fprintf (stderr, "%s %d : Error unsubscribing to signals, error=%s\n",
03057 __FILE__, __LINE__, error->message);
03059 }
03060
03061
03062
03063 dbus_connection_remove_filter (ctx->connection, filter_func, ctx);
03064 }
03065
03066 ctx->is_initialized = FALSE;
03067
03068 return TRUE;
03069 }
03070
03076 dbus_bool_t
03077 libhal_ctx_free (LibHalContext *ctx)
03078 {
03079 free (ctx);
03080 return TRUE;
03081 }
03082
03090 dbus_bool_t
03091 libhal_ctx_set_device_added (LibHalContext *ctx, LibHalDeviceAdded callback)
03092 {
03093 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
03094
03095 ctx->device_added = callback;
03096 return TRUE;
03097 }
03098
03106 dbus_bool_t
03107 libhal_ctx_set_device_removed (LibHalContext *ctx, LibHalDeviceRemoved callback)
03108 {
03109 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
03110
03111 ctx->device_removed = callback;
03112 return TRUE;
03113 }
03114
03123 dbus_bool_t
03124 libhal_ctx_set_device_new_capability (LibHalContext *ctx, LibHalDeviceNewCapability callback)
03125 {
03126 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
03127
03128 ctx->device_new_capability = callback;
03129 return TRUE;
03130 }
03131
03140 dbus_bool_t
03141 libhal_ctx_set_device_lost_capability (LibHalContext *ctx, LibHalDeviceLostCapability callback)
03142 {
03143 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
03144
03145 ctx->device_lost_capability = callback;
03146 return TRUE;
03147 }
03148
03157 dbus_bool_t
03158 libhal_ctx_set_device_property_modified (LibHalContext *ctx, LibHalDevicePropertyModified callback)
03159 {
03160 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
03161
03162 ctx->device_property_modified = callback;
03163 return TRUE;
03164 }
03165
03173 dbus_bool_t
03174 libhal_ctx_set_device_condition (LibHalContext *ctx, LibHalDeviceCondition callback)
03175 {
03176 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
03177
03178 ctx->device_condition = callback;
03179 return TRUE;
03180 }
03181
03187 unsigned int libhal_string_array_length (char **str_array)
03188 {
03189 unsigned int i;
03190
03191 if (str_array == NULL)
03192 return 0;
03193
03194 for (i = 0; str_array[i] != NULL; i++)
03195 ;
03196
03197 return i;
03198 }
03199
03200
03201 dbus_bool_t
03202 libhal_device_rescan (LibHalContext *ctx, const char *udi, DBusError *error)
03203 {
03204 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
03205
03206 DBusMessage *message;
03207 DBusMessageIter reply_iter;
03208 DBusMessage *reply;
03209 dbus_bool_t result;
03210
03211 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
03212 "org.freedesktop.Hal.Device",
03213 "Rescan");
03214
03215 if (message == NULL) {
03216 fprintf (stderr,
03217 "%s %d : Couldn't allocate D-BUS message\n",
03218 __FILE__, __LINE__);
03219 return FALSE;
03220 }
03221
03222 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
03223 message, -1,
03224 error);
03225
03226 if (error != NULL && dbus_error_is_set (error)) {
03227 dbus_message_unref (message);
03228 return FALSE;
03229 }
03230
03231 dbus_message_unref (message);
03232
03233 if (reply == NULL)
03234 return FALSE;
03235
03236 dbus_message_iter_init (reply, &reply_iter);
03237 if (dbus_message_iter_get_arg_type (&reply_iter) !=
03238 DBUS_TYPE_BOOLEAN) {
03239 dbus_message_unref (message);
03240 dbus_message_unref (reply);
03241 return FALSE;
03242 }
03243 dbus_message_iter_get_basic (&reply_iter, &result);
03244
03245 dbus_message_unref (reply);
03246
03247 return result;
03248 }
03249
03250 dbus_bool_t
03251 libhal_device_reprobe (LibHalContext *ctx, const char *udi, DBusError *error)
03252 {
03253 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
03254
03255 DBusMessage *message;
03256 DBusMessageIter reply_iter;
03257 DBusMessage *reply;
03258 dbus_bool_t result;
03259
03260 message = dbus_message_new_method_call ("org.freedesktop.Hal",
03261 udi,
03262 "org.freedesktop.Hal.Device",
03263 "Reprobe");
03264
03265 if (message == NULL) {
03266 fprintf (stderr,
03267 "%s %d : Couldn't allocate D-BUS message\n",
03268 __FILE__, __LINE__);
03269 return FALSE;
03270 }
03271
03272 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
03273 message, -1,
03274 error);
03275
03276 if (error != NULL && dbus_error_is_set (error)) {
03277 dbus_message_unref (message);
03278 return FALSE;
03279 }
03280
03281 dbus_message_unref (message);
03282
03283 if (reply == NULL)
03284 return FALSE;
03285
03286 dbus_message_iter_init (reply, &reply_iter);
03287 if (dbus_message_iter_get_arg_type (&reply_iter) !=
03288 DBUS_TYPE_BOOLEAN) {
03289 dbus_message_unref (message);
03290 dbus_message_unref (reply);
03291 return FALSE;
03292 }
03293 dbus_message_iter_get_basic (&reply_iter, &result);
03294
03295 dbus_message_unref (reply);
03296
03297 return result;
03298 }
03299
03311 dbus_bool_t libhal_device_emit_condition (LibHalContext *ctx,
03312 const char *udi,
03313 const char *condition_name,
03314 const char *condition_details,
03315 DBusError *error)
03316 {
03317 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
03318
03319 DBusMessage *message;
03320 DBusMessageIter iter;
03321 DBusMessageIter reply_iter;
03322 DBusMessage *reply;
03323 dbus_bool_t result;
03324
03325 message = dbus_message_new_method_call ("org.freedesktop.Hal",
03326 udi,
03327 "org.freedesktop.Hal.Device",
03328 "EmitCondition");
03329
03330 if (message == NULL) {
03331 fprintf (stderr,
03332 "%s %d : Couldn't allocate D-BUS message\n",
03333 __FILE__, __LINE__);
03334 return FALSE;
03335 }
03336
03337 dbus_message_iter_init_append (message, &iter);
03338 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &condition_name);
03339 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &condition_details);
03340
03341 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
03342 message, -1,
03343 error);
03344
03345 if (error != NULL && dbus_error_is_set (error)) {
03346 dbus_message_unref (message);
03347 return FALSE;
03348 }
03349
03350 dbus_message_unref (message);
03351
03352 if (reply == NULL)
03353 return FALSE;
03354
03355 dbus_message_iter_init (reply, &reply_iter);
03356 if (dbus_message_iter_get_arg_type (&reply_iter) !=
03357 DBUS_TYPE_BOOLEAN) {
03358 dbus_message_unref (message);
03359 dbus_message_unref (reply);
03360 return FALSE;
03361 }
03362 dbus_message_iter_get_basic (&reply_iter, &result);
03363
03364 dbus_message_unref (reply);
03365
03366 return result;
03367 }
03368