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