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 if (ctx == NULL)
00228 return FALSE;
00229 ctx->user_data = user_data;
00230 return TRUE;
00231 }
00232
00239 void*
00240 libhal_ctx_get_user_data(LibHalContext *ctx)
00241 {
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 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
00352 "org.freedesktop.Hal.Device",
00353 "GetAllProperties");
00354
00355 if (message == NULL) {
00356 fprintf (stderr,
00357 "%s %d : Couldn't allocate D-BUS message\n",
00358 __FILE__, __LINE__);
00359 return NULL;
00360 }
00361
00362 dbus_error_init (&_error);
00363 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
00364 message, -1,
00365 &_error);
00366
00367 dbus_move_error (&_error, error);
00368 if (error != NULL && dbus_error_is_set (error)) {
00369 fprintf (stderr,
00370 "%s %d : %s\n",
00371 __FILE__, __LINE__, error->message);
00372
00373 dbus_message_unref (message);
00374 return NULL;
00375 }
00376
00377 if (reply == NULL) {
00378 dbus_message_unref (message);
00379 return NULL;
00380 }
00381
00382 dbus_message_iter_init (reply, &reply_iter);
00383
00384 result = malloc (sizeof (LibHalPropertySet));
00385 if (result == NULL)
00386 goto oom;
00387
00388
00389
00390
00392
00393
00394
00395
00396 result->properties_head = NULL;
00397 result->num_properties = 0;
00398
00399 if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY &&
00400 dbus_message_iter_get_element_type (&reply_iter) != DBUS_TYPE_DICT_ENTRY) {
00401 fprintf (stderr, "%s %d : error, expecting an array of dict entries\n",
00402 __FILE__, __LINE__);
00403 dbus_message_unref (message);
00404 dbus_message_unref (reply);
00405 return NULL;
00406 }
00407
00408 dbus_message_iter_recurse (&reply_iter, &dict_iter);
00409
00410 p_last = NULL;
00411
00412 while (dbus_message_iter_get_arg_type (&dict_iter) == DBUS_TYPE_DICT_ENTRY)
00413 {
00414 DBusMessageIter dict_entry_iter, var_iter;
00415 const char *key;
00416 LibHalProperty *p;
00417
00418 dbus_message_iter_recurse (&dict_iter, &dict_entry_iter);
00419
00420 dbus_message_iter_get_basic (&dict_entry_iter, &key);
00421
00422 p = malloc (sizeof (LibHalProperty));
00423 if (p == NULL)
00424 goto oom;
00425
00426 p->next = NULL;
00427
00428 if (result->num_properties == 0)
00429 result->properties_head = p;
00430
00431 if (p_last != NULL)
00432 p_last->next = p;
00433
00434 p_last = p;
00435
00436 p->key = strdup (key);
00437 if (p->key == NULL)
00438 goto oom;
00439
00440 dbus_message_iter_next (&dict_entry_iter);
00441
00442 dbus_message_iter_recurse (&dict_entry_iter, &var_iter);
00443
00444
00445 p->type = dbus_message_iter_get_arg_type (&var_iter);
00446
00447 result->num_properties++;
00448
00449 if(!libhal_property_fill_value_from_variant (p, &var_iter))
00450 goto oom;
00451
00452 dbus_message_iter_next (&dict_iter);
00453 }
00454
00455 dbus_message_unref (message);
00456 dbus_message_unref (reply);
00457
00458 return result;
00459
00460 oom:
00461 fprintf (stderr,
00462 "%s %d : error allocating memory\n",
00463 __FILE__, __LINE__);
00465 return NULL;
00466 }
00467
00472 void
00473 libhal_free_property_set (LibHalPropertySet * set)
00474 {
00475 LibHalProperty *p;
00476 LibHalProperty *q;
00477
00478 if (set == NULL)
00479 return;
00480
00481 for (p = set->properties_head; p != NULL; p = q) {
00482 free (p->key);
00483 if (p->type == DBUS_TYPE_STRING)
00484 free (p->str_value);
00485 if (p->type == LIBHAL_PROPERTY_TYPE_STRLIST)
00486 libhal_free_string_array (p->strlist_value);
00487 q = p->next;
00488 free (p);
00489 }
00490 free (set);
00491 }
00492
00498 unsigned int
00499 libhal_property_set_get_num_elems (LibHalPropertySet *set)
00500 {
00501 unsigned int num_elems;
00502 LibHalProperty *p;
00503
00504 num_elems = 0;
00505 for (p = set->properties_head; p != NULL; p = p->next)
00506 num_elems++;
00507
00508 return num_elems;
00509 }
00510
00511
00517 void
00518 libhal_psi_init (LibHalPropertySetIterator * iter, LibHalPropertySet * set)
00519 {
00520 iter->set = set;
00521 iter->index = 0;
00522 iter->cur_prop = set->properties_head;
00523 }
00524
00525
00532 dbus_bool_t
00533 libhal_psi_has_more (LibHalPropertySetIterator * iter)
00534 {
00535 return iter->index < iter->set->num_properties;
00536 }
00537
00542 void
00543 libhal_psi_next (LibHalPropertySetIterator * iter)
00544 {
00545 iter->index++;
00546 iter->cur_prop = iter->cur_prop->next;
00547 }
00548
00554 LibHalPropertyType
00555 libhal_psi_get_type (LibHalPropertySetIterator * iter)
00556 {
00557 return iter->cur_prop->type;
00558 }
00559
00568 char *
00569 libhal_psi_get_key (LibHalPropertySetIterator * iter)
00570 {
00571 return iter->cur_prop->key;
00572 }
00573
00582 char *
00583 libhal_psi_get_string (LibHalPropertySetIterator * iter)
00584 {
00585 return iter->cur_prop->str_value;
00586 }
00587
00593 dbus_int32_t
00594 libhal_psi_get_int (LibHalPropertySetIterator * iter)
00595 {
00596 return iter->cur_prop->int_value;
00597 }
00598
00604 dbus_uint64_t
00605 libhal_psi_get_uint64 (LibHalPropertySetIterator * iter)
00606 {
00607 return iter->cur_prop->uint64_value;
00608 }
00609
00615 double
00616 libhal_psi_get_double (LibHalPropertySetIterator * iter)
00617 {
00618 return iter->cur_prop->double_value;
00619 }
00620
00626 dbus_bool_t
00627 libhal_psi_get_bool (LibHalPropertySetIterator * iter)
00628 {
00629 return iter->cur_prop->bool_value;
00630 }
00631
00637 char **
00638 libhal_psi_get_strlist (LibHalPropertySetIterator * iter)
00639 {
00640 return iter->cur_prop->strlist_value;
00641 }
00642
00643
00644 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00645 static DBusHandlerResult
00646 filter_func (DBusConnection * connection,
00647 DBusMessage * message, void *user_data)
00648 {
00649 const char *object_path;
00650 DBusError error;
00651 LibHalContext *ctx = (LibHalContext *) user_data;
00652
00653 if (ctx->is_shutdown)
00654 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00655
00656 dbus_error_init (&error);
00657
00658 object_path = dbus_message_get_path (message);
00659
00660
00661
00662 if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager",
00663 "DeviceAdded")) {
00664 char *udi;
00665 if (dbus_message_get_args (message, &error,
00666 DBUS_TYPE_STRING, &udi,
00667 DBUS_TYPE_INVALID)) {
00668 if (ctx->device_added != NULL) {
00669 ctx->device_added (ctx, udi);
00670 }
00671 }
00672 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00673 } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager", "DeviceRemoved")) {
00674 char *udi;
00675 if (dbus_message_get_args (message, &error,
00676 DBUS_TYPE_STRING, &udi,
00677 DBUS_TYPE_INVALID)) {
00678 if (ctx->device_removed != NULL) {
00679 ctx->device_removed (ctx, udi);
00680 }
00681 }
00682 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00683 } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager","NewCapability")) {
00684 char *udi;
00685 char *capability;
00686 if (dbus_message_get_args (message, &error,
00687 DBUS_TYPE_STRING, &udi,
00688 DBUS_TYPE_STRING, &capability,
00689 DBUS_TYPE_INVALID)) {
00690 if (ctx->device_new_capability != NULL) {
00691 ctx->device_new_capability (ctx, udi, capability);
00692 }
00693 }
00694 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00695 } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Device", "Condition")) {
00696 char *condition_name;
00697 char *condition_detail;
00698 if (dbus_message_get_args (message, &error,
00699 DBUS_TYPE_STRING, &condition_name,
00700 DBUS_TYPE_STRING, &condition_detail,
00701 DBUS_TYPE_INVALID)) {
00702 if (ctx->device_condition != NULL) {
00703 ctx->device_condition (ctx, object_path, condition_name, condition_detail);
00704 }
00705 }
00706 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00707 } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Device", "PropertyModified")) {
00708 if (ctx->device_property_modified != NULL) {
00709 int i;
00710 char *key;
00711 dbus_bool_t removed;
00712 dbus_bool_t added;
00713 int num_modifications;
00714 DBusMessageIter iter;
00715 DBusMessageIter iter_array;
00716
00717 dbus_message_iter_init (message, &iter);
00718 dbus_message_iter_get_basic (&iter, &num_modifications);
00719 dbus_message_iter_next (&iter);
00720
00721 dbus_message_iter_recurse (&iter, &iter_array);
00722
00723 for (i = 0; i < num_modifications; i++) {
00724 DBusMessageIter iter_struct;
00725
00726 dbus_message_iter_recurse (&iter_array, &iter_struct);
00727
00728 dbus_message_iter_get_basic (&iter_struct, &key);
00729 dbus_message_iter_next (&iter_struct);
00730 dbus_message_iter_get_basic (&iter_struct, &removed);
00731 dbus_message_iter_next (&iter_struct);
00732 dbus_message_iter_get_basic (&iter_struct, &added);
00733
00734 ctx->device_property_modified (ctx,
00735 object_path,
00736 key, removed,
00737 added);
00738
00739 dbus_message_iter_next (&iter_array);
00740 }
00741
00742 }
00743 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00744 }
00745
00746 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00747 }
00748
00749 #endif
00750
00751
00752 static dbus_bool_t libhal_already_initialized_once = FALSE;
00753
00754 #if 0
00755
00773 LibHalContext*
00774 libhal_initialize (const LibHalFunctions * cb_functions,
00775 dbus_bool_t use_cache)
00776 {
00777 DBusError error;
00778 LibHalContext *ctx;
00779
00780 if (!libhal_already_initialized_once) {
00781 bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
00782 bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
00783
00784 libhal_already_initialized_once = TRUE;
00785 }
00786
00787 ctx = malloc (sizeof (LibHalContext));
00788 if (ctx == NULL) {
00789 fprintf (stderr, "%s %d : Cannot allocated %d bytes!\n",
00790 __FILE__, __LINE__, sizeof (LibHalContext));
00791 return NULL;
00792 }
00793
00794 ctx->is_initialized = FALSE;
00795 ctx->is_shutdown = FALSE;
00796
00797 ctx->cache_enabled = use_cache;
00798
00799 ctx->functions = cb_functions;
00800
00801 if (ctx->functions == NULL)
00802 ctx->functions = &libhal_null_functions;
00803
00804
00805
00806 ctx->connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
00807 if (ctx->connection == NULL) {
00808 fprintf (stderr,
00809 "%s %d : Error connecting to system bus: %s\n",
00810 __FILE__, __LINE__, error.message);
00811 dbus_error_free (&error);
00812 return NULL;
00813 }
00814
00815 if (ctx->main_loop_integration != NULL) {
00816
00817 ctx->main_loop_integration (ctx, ctx->connection);
00818 }
00819
00820 if (!dbus_connection_add_filter
00821 (ctx->connection, filter_func, ctx, NULL)) {
00822 fprintf (stderr,
00823 "%s %d : Error creating connection handler\r\n",
00824 __FILE__, __LINE__);
00826 return NULL;
00827 }
00828
00829 dbus_bus_add_match (ctx->connection,
00830 "type='signal',"
00831 "interface='org.freedesktop.Hal.Manager',"
00832 "sender='org.freedesktop.Hal',"
00833 "path='/org/freedesktop/Hal/Manager'", &error);
00834 if (dbus_error_is_set (&error)) {
00835 fprintf (stderr, "%s %d : Error subscribing to signals, "
00836 "error=%s\r\n",
00837 __FILE__, __LINE__, error.message);
00839 return NULL;
00840 }
00841
00842 ctx->is_initialized = TRUE;
00843 return ctx;
00844 }
00845
00852 int
00853 libhal_shutdown (LibHalContext *ctx)
00854 {
00855 DBusError error;
00856
00857 if (!ctx->is_initialized)
00858 return 1;
00859
00860
00861
00862
00863 dbus_bus_remove_match (ctx->connection,
00864 "type='signal',"
00865 "interface='org.freedesktop.Hal.Manager',"
00866 "sender='org.freedesktop.Hal',"
00867 "path='/org/freedesktop/Hal/Manager'", &error);
00868 if (dbus_error_is_set (&error)) {
00869 fprintf (stderr, "%s %d : Error removing match rule, error=%s\r\n",
00870 __FILE__, __LINE__, error.message);
00871 }
00872
00873
00874
00875
00876 ctx->is_shutdown = TRUE;
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891 return 0;
00892 }
00893 #endif
00894
00906 char **
00907 libhal_get_all_devices (LibHalContext *ctx, int *num_devices, DBusError *error)
00908 {
00909 DBusMessage *message;
00910 DBusMessage *reply;
00911 DBusMessageIter iter_array, reply_iter;
00912 char **hal_device_names;
00913 DBusError _error;
00914
00915 *num_devices = 0;
00916
00917 message = dbus_message_new_method_call ("org.freedesktop.Hal",
00918 "/org/freedesktop/Hal/Manager",
00919 "org.freedesktop.Hal.Manager",
00920 "GetAllDevices");
00921 if (message == NULL) {
00922 fprintf (stderr, "%s %d : Could not allocate D-BUS message\n", __FILE__, __LINE__);
00923 return NULL;
00924 }
00925
00926 dbus_error_init (&_error);
00927 reply = dbus_connection_send_with_reply_and_block (ctx->connection, message, -1, &_error);
00928
00929 dbus_move_error (&_error, error);
00930 if (error != NULL && dbus_error_is_set (error)) {
00931 dbus_message_unref (message);
00932 return NULL;
00933 }
00934 if (reply == NULL) {
00935 dbus_message_unref (message);
00936 return NULL;
00937 }
00938
00939
00940 dbus_message_iter_init (reply, &reply_iter);
00941
00942 if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) {
00943 fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__);
00944 return NULL;
00945 }
00946
00947 dbus_message_iter_recurse (&reply_iter, &iter_array);
00948
00949 hal_device_names = libhal_get_string_array_from_iter (&iter_array, num_devices);
00950
00951 dbus_message_unref (reply);
00952 dbus_message_unref (message);
00953
00954 return hal_device_names;
00955 }
00956
00970 LibHalPropertyType
00971 libhal_device_get_property_type (LibHalContext *ctx, const char *udi, const char *key, DBusError *error)
00972 {
00973 DBusMessage *message;
00974 DBusMessage *reply;
00975 DBusMessageIter iter, reply_iter;
00976 int type;
00977 DBusError _error;
00978
00979 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
00980 "org.freedesktop.Hal.Device",
00981 "GetPropertyType");
00982 if (message == NULL) {
00983 fprintf (stderr, "%s %d : Couldn't allocate D-BUS message\n", __FILE__, __LINE__);
00984 return LIBHAL_PROPERTY_TYPE_INVALID;
00985 }
00986
00987 dbus_message_iter_init_append (message, &iter);
00988 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
00989
00990 dbus_error_init (&_error);
00991 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
00992 message, -1,
00993 &_error);
00994
00995 dbus_move_error (&_error, error);
00996 if (error != NULL && dbus_error_is_set (error)) {
00997 dbus_message_unref (message);
00998 return LIBHAL_PROPERTY_TYPE_INVALID;
00999 }
01000 if (reply == NULL) {
01001 dbus_message_unref (message);
01002 return LIBHAL_PROPERTY_TYPE_INVALID;
01003 }
01004
01005 dbus_message_iter_init (reply, &reply_iter);
01006 dbus_message_iter_get_basic (&reply_iter, &type);
01007
01008 dbus_message_unref (message);
01009 dbus_message_unref (reply);
01010
01011 return type;
01012 }
01013
01029 char **
01030 libhal_device_get_property_strlist (LibHalContext *ctx, const char *udi, const char *key, DBusError *error)
01031 {
01032 DBusMessage *message;
01033 DBusMessage *reply;
01034 DBusMessageIter iter, iter_array, reply_iter;
01035 char **our_strings;
01036 DBusError _error;
01037
01038 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01039 "org.freedesktop.Hal.Device",
01040 "GetPropertyStringList");
01041 if (message == NULL) {
01042 fprintf (stderr,
01043 "%s %d : Couldn't allocate D-BUS message\n",
01044 __FILE__, __LINE__);
01045 return NULL;
01046 }
01047
01048 dbus_message_iter_init_append (message, &iter);
01049 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
01050
01051 dbus_error_init (&_error);
01052 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01053 message, -1,
01054 &_error);
01055
01056 dbus_move_error (&_error, error);
01057 if (error != NULL && dbus_error_is_set (error)) {
01058 dbus_message_unref (message);
01059 return NULL;
01060 }
01061 if (reply == NULL) {
01062 dbus_message_unref (message);
01063 return NULL;
01064 }
01065
01066 dbus_message_iter_init (reply, &reply_iter);
01067
01068 if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) {
01069 fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__);
01070 return NULL;
01071 }
01072
01073 dbus_message_iter_recurse (&reply_iter, &iter_array);
01074
01075 our_strings = libhal_get_string_array_from_iter (&iter_array, NULL);
01076
01077 dbus_message_unref (reply);
01078 dbus_message_unref (message);
01079
01080 return our_strings;
01081 }
01082
01096 char *
01097 libhal_device_get_property_string (LibHalContext *ctx,
01098 const char *udi, const char *key, DBusError *error)
01099 {
01100 DBusMessage *message;
01101 DBusMessage *reply;
01102 DBusMessageIter iter, reply_iter;
01103 char *value;
01104 char *dbus_str;
01105 DBusError _error;
01106
01107 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01108 "org.freedesktop.Hal.Device",
01109 "GetPropertyString");
01110
01111 if (message == NULL) {
01112 fprintf (stderr,
01113 "%s %d : Couldn't allocate D-BUS message\n",
01114 __FILE__, __LINE__);
01115 return NULL;
01116 }
01117
01118 dbus_message_iter_init_append (message, &iter);
01119 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
01120
01121 dbus_error_init (&_error);
01122 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01123 message, -1,
01124 &_error);
01125
01126 dbus_move_error (&_error, error);
01127 if (error != NULL && dbus_error_is_set (error)) {
01128 dbus_message_unref (message);
01129 return NULL;
01130 }
01131 if (reply == NULL) {
01132 dbus_message_unref (message);
01133 return NULL;
01134 }
01135
01136 dbus_message_iter_init (reply, &reply_iter);
01137
01138
01139 if (dbus_message_iter_get_arg_type (&reply_iter) !=
01140 DBUS_TYPE_STRING) {
01141 dbus_message_unref (message);
01142 dbus_message_unref (reply);
01143 return NULL;
01144 }
01145
01146 dbus_message_iter_get_basic (&reply_iter, &dbus_str);
01147 value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL);
01148 if (value == NULL) {
01149 fprintf (stderr, "%s %d : error allocating memory\n",
01150 __FILE__, __LINE__);
01152 return NULL;
01153 }
01154
01155 dbus_message_unref (message);
01156 dbus_message_unref (reply);
01157 return value;
01158 }
01159
01169 dbus_int32_t
01170 libhal_device_get_property_int (LibHalContext *ctx,
01171 const char *udi, const char *key, DBusError *error)
01172 {
01173 DBusMessage *message;
01174 DBusMessage *reply;
01175 DBusMessageIter iter, reply_iter;
01176 dbus_int32_t value;
01177 DBusError _error;
01178
01179 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01180 "org.freedesktop.Hal.Device",
01181 "GetPropertyInteger");
01182 if (message == NULL) {
01183 fprintf (stderr,
01184 "%s %d : Couldn't allocate D-BUS message\n",
01185 __FILE__, __LINE__);
01186 return -1;
01187 }
01188
01189 dbus_message_iter_init_append (message, &iter);
01190 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
01191
01192 dbus_error_init (&_error);
01193 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01194 message, -1,
01195 &_error);
01196
01197 dbus_move_error (&_error, error);
01198 if (error != NULL && dbus_error_is_set (error)) {
01199 dbus_message_unref (message);
01200 return -1;
01201 }
01202 if (reply == NULL) {
01203 dbus_message_unref (message);
01204 return -1;
01205 }
01206
01207 dbus_message_iter_init (reply, &reply_iter);
01208
01209
01210 if (dbus_message_iter_get_arg_type (&reply_iter) !=
01211 DBUS_TYPE_INT32) {
01212 fprintf (stderr,
01213 "%s %d : property '%s' for device '%s' is not "
01214 "of type integer\n", __FILE__, __LINE__, key,
01215 udi);
01216 dbus_message_unref (message);
01217 dbus_message_unref (reply);
01218 return -1;
01219 }
01220 dbus_message_iter_get_basic (&reply_iter, &value);
01221
01222 dbus_message_unref (message);
01223 dbus_message_unref (reply);
01224 return value;
01225 }
01226
01236 dbus_uint64_t
01237 libhal_device_get_property_uint64 (LibHalContext *ctx,
01238 const char *udi, const char *key, DBusError *error)
01239 {
01240 DBusMessage *message;
01241 DBusMessage *reply;
01242 DBusMessageIter iter, reply_iter;
01243 dbus_uint64_t value;
01244 DBusError _error;
01245
01246 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01247 "org.freedesktop.Hal.Device",
01248 "GetPropertyInteger");
01249 if (message == NULL) {
01250 fprintf (stderr,
01251 "%s %d : Couldn't allocate D-BUS message\n",
01252 __FILE__, __LINE__);
01253 return -1;
01254 }
01255
01256 dbus_message_iter_init_append (message, &iter);
01257 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
01258
01259 dbus_error_init (&_error);
01260 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01261 message, -1,
01262 &_error);
01263
01264 dbus_move_error (&_error, error);
01265 if (error != NULL && dbus_error_is_set (error)) {
01266 dbus_message_unref (message);
01267 return -1;
01268 }
01269 if (reply == NULL) {
01270 dbus_message_unref (message);
01271 return -1;
01272 }
01273
01274 dbus_message_iter_init (reply, &reply_iter);
01275
01276 if (dbus_message_iter_get_arg_type (&reply_iter) !=
01277 DBUS_TYPE_UINT64) {
01278 fprintf (stderr,
01279 "%s %d : property '%s' for device '%s' is not "
01280 "of type integer\n", __FILE__, __LINE__, key,
01281 udi);
01282 dbus_message_unref (message);
01283 dbus_message_unref (reply);
01284 return -1;
01285 }
01286 dbus_message_iter_get_basic (&reply_iter, &value);
01287
01288 dbus_message_unref (message);
01289 dbus_message_unref (reply);
01290 return value;
01291 }
01292
01302 double
01303 libhal_device_get_property_double (LibHalContext *ctx,
01304 const char *udi, const char *key, DBusError *error)
01305 {
01306 DBusMessage *message;
01307 DBusMessage *reply;
01308 DBusMessageIter iter, reply_iter;
01309 double value;
01310 DBusError _error;
01311
01312 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01313 "org.freedesktop.Hal.Device",
01314 "GetPropertyDouble");
01315 if (message == NULL) {
01316 fprintf (stderr,
01317 "%s %d : Couldn't allocate D-BUS message\n",
01318 __FILE__, __LINE__);
01319 return -1.0f;
01320 }
01321
01322 dbus_message_iter_init_append (message, &iter);
01323 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
01324
01325 dbus_error_init (&_error);
01326 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01327 message, -1,
01328 &_error);
01329
01330 dbus_move_error (&_error, error);
01331 if (error != NULL && dbus_error_is_set (error)) {
01332 dbus_message_unref (message);
01333 return -1.0f;
01334 }
01335 if (reply == NULL) {
01336 dbus_message_unref (message);
01337 return -1.0f;
01338 }
01339
01340 dbus_message_iter_init (reply, &reply_iter);
01341
01342
01343 if (dbus_message_iter_get_arg_type (&reply_iter) !=
01344 DBUS_TYPE_DOUBLE) {
01345 fprintf (stderr,
01346 "%s %d : property '%s' for device '%s' is not "
01347 "of type double\n", __FILE__, __LINE__, key, udi);
01348 dbus_message_unref (message);
01349 dbus_message_unref (reply);
01350 return -1.0f;
01351 }
01352 dbus_message_iter_get_basic (&reply_iter, &value);
01353
01354 dbus_message_unref (message);
01355 dbus_message_unref (reply);
01356 return (double) value;
01357 }
01358
01368 dbus_bool_t
01369 libhal_device_get_property_bool (LibHalContext *ctx,
01370 const char *udi, const char *key, DBusError *error)
01371 {
01372 DBusMessage *message;
01373 DBusMessage *reply;
01374 DBusMessageIter iter, reply_iter;
01375 dbus_bool_t value;
01376 DBusError _error;
01377
01378 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01379 "org.freedesktop.Hal.Device",
01380 "GetPropertyBoolean");
01381 if (message == NULL) {
01382 fprintf (stderr,
01383 "%s %d : Couldn't allocate D-BUS message\n",
01384 __FILE__, __LINE__);
01385 return FALSE;
01386 }
01387
01388 dbus_message_iter_init_append (message, &iter);
01389 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
01390
01391 dbus_error_init (&_error);
01392 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01393 message, -1,
01394 &_error);
01395
01396 dbus_move_error (&_error, error);
01397 if (error != NULL && dbus_error_is_set (error)) {
01398 dbus_message_unref (message);
01399 return FALSE;
01400 }
01401 if (reply == NULL) {
01402 dbus_message_unref (message);
01403 return FALSE;
01404 }
01405
01406 dbus_message_iter_init (reply, &reply_iter);
01407
01408
01409 if (dbus_message_iter_get_arg_type (&reply_iter) !=
01410 DBUS_TYPE_BOOLEAN) {
01411 fprintf (stderr,
01412 "%s %d : property '%s' for device '%s' is not "
01413 "of type bool\n", __FILE__, __LINE__, key, udi);
01414 dbus_message_unref (message);
01415 dbus_message_unref (reply);
01416 return FALSE;
01417 }
01418 dbus_message_iter_get_basic (&reply_iter, &value);
01419
01420 dbus_message_unref (message);
01421 dbus_message_unref (reply);
01422 return value;
01423 }
01424
01425
01426
01427 static dbus_bool_t
01428 libhal_device_set_property_helper (LibHalContext *ctx,
01429 const char *udi,
01430 const char *key,
01431 int type,
01432 const char *str_value,
01433 dbus_int32_t int_value,
01434 dbus_uint64_t uint64_value,
01435 double double_value,
01436 dbus_bool_t bool_value,
01437 DBusError *error)
01438 {
01439 DBusMessage *message;
01440 DBusMessage *reply;
01441 DBusMessageIter iter;
01442 char *method_name = NULL;
01443
01445 switch (type) {
01446 case DBUS_TYPE_INVALID:
01447 method_name = "RemoveProperty";
01448 break;
01449 case DBUS_TYPE_STRING:
01450 method_name = "SetPropertyString";
01451 break;
01452 case DBUS_TYPE_INT32:
01453 case DBUS_TYPE_UINT64:
01454 method_name = "SetPropertyInteger";
01455 break;
01456 case DBUS_TYPE_DOUBLE:
01457 method_name = "SetPropertyDouble";
01458 break;
01459 case DBUS_TYPE_BOOLEAN:
01460 method_name = "SetPropertyBoolean";
01461 break;
01462
01463 default:
01464
01465 break;
01466 }
01467
01468 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01469 "org.freedesktop.Hal.Device",
01470 method_name);
01471 if (message == NULL) {
01472 fprintf (stderr,
01473 "%s %d : Couldn't allocate D-BUS message\n",
01474 __FILE__, __LINE__);
01475 return FALSE;
01476 }
01477
01478 dbus_message_iter_init_append (message, &iter);
01479 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
01480 switch (type) {
01481 case DBUS_TYPE_STRING:
01482 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &str_value);
01483 break;
01484 case DBUS_TYPE_INT32:
01485 dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &int_value);
01486 break;
01487 case DBUS_TYPE_UINT64:
01488 dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT64, &uint64_value);
01489 break;
01490 case DBUS_TYPE_DOUBLE:
01491 dbus_message_iter_append_basic (&iter, DBUS_TYPE_DOUBLE, &double_value);
01492 break;
01493 case DBUS_TYPE_BOOLEAN:
01494 dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &bool_value);
01495 break;
01496 }
01497
01498
01499 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01500 message, -1,
01501 error);
01502 if (dbus_error_is_set (error)) {
01503 dbus_message_unref (message);
01504 return FALSE;
01505 }
01506
01507 if (reply == NULL) {
01508 dbus_message_unref (message);
01509 return FALSE;
01510 }
01511
01512 dbus_message_unref (message);
01513 dbus_message_unref (reply);
01514
01515 return TRUE;
01516 }
01517
01530 dbus_bool_t
01531 libhal_device_set_property_string (LibHalContext *ctx,
01532 const char *udi,
01533 const char *key,
01534 const char *value,
01535 DBusError *error)
01536 {
01537 return libhal_device_set_property_helper (ctx, udi, key,
01538 DBUS_TYPE_STRING,
01539 value, 0, 0, 0.0f, FALSE, error);
01540 }
01541
01554 dbus_bool_t
01555 libhal_device_set_property_int (LibHalContext *ctx, const char *udi,
01556 const char *key, dbus_int32_t value, DBusError *error)
01557 {
01558 return libhal_device_set_property_helper (ctx, udi, key,
01559 DBUS_TYPE_INT32,
01560 NULL, value, 0, 0.0f, FALSE, error);
01561 }
01562
01575 dbus_bool_t
01576 libhal_device_set_property_uint64 (LibHalContext *ctx, const char *udi,
01577 const char *key, dbus_uint64_t value, DBusError *error)
01578 {
01579 return libhal_device_set_property_helper (ctx, udi, key,
01580 DBUS_TYPE_UINT64,
01581 NULL, 0, value, 0.0f, FALSE, error);
01582 }
01583
01596 dbus_bool_t
01597 libhal_device_set_property_double (LibHalContext *ctx, const char *udi,
01598 const char *key, double value, DBusError *error)
01599 {
01600 return libhal_device_set_property_helper (ctx, udi, key,
01601 DBUS_TYPE_DOUBLE,
01602 NULL, 0, 0, value, FALSE, error);
01603 }
01604
01617 dbus_bool_t
01618 libhal_device_set_property_bool (LibHalContext *ctx, const char *udi,
01619 const char *key, dbus_bool_t value, DBusError *error)
01620 {
01621 return libhal_device_set_property_helper (ctx, udi, key,
01622 DBUS_TYPE_BOOLEAN,
01623 NULL, 0, 0, 0.0f, value, error);
01624 }
01625
01626
01637 dbus_bool_t
01638 libhal_device_remove_property (LibHalContext *ctx,
01639 const char *udi, const char *key, DBusError *error)
01640 {
01641 return libhal_device_set_property_helper (ctx, udi, key, DBUS_TYPE_INVALID,
01642
01643 NULL, 0, 0, 0.0f, FALSE, error);
01644 }
01645
01658 dbus_bool_t
01659 libhal_device_property_strlist_append (LibHalContext *ctx,
01660 const char *udi,
01661 const char *key,
01662 const char *value,
01663 DBusError *error)
01664 {
01665 DBusMessage *message;
01666 DBusMessage *reply;
01667 DBusMessageIter iter;
01668
01669 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01670 "org.freedesktop.Hal.Device",
01671 "StringListAppend");
01672 if (message == NULL) {
01673 fprintf (stderr,
01674 "%s %d : Couldn't allocate D-BUS message\n",
01675 __FILE__, __LINE__);
01676 return FALSE;
01677 }
01678 dbus_message_iter_init_append (message, &iter);
01679 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
01680 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
01681
01682 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01683 message, -1,
01684 error);
01685 if (dbus_error_is_set (error)) {
01686 dbus_message_unref (message);
01687 return FALSE;
01688 }
01689 if (reply == NULL) {
01690 dbus_message_unref (message);
01691 return FALSE;
01692 }
01693 return TRUE;
01694 }
01695
01708 dbus_bool_t
01709 libhal_device_property_strlist_prepend (LibHalContext *ctx,
01710 const char *udi,
01711 const char *key,
01712 const char *value,
01713 DBusError *error)
01714 {
01715 DBusMessage *message;
01716 DBusMessage *reply;
01717 DBusMessageIter iter;
01718
01719 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01720 "org.freedesktop.Hal.Device",
01721 "StringListPrepend");
01722 if (message == NULL) {
01723 fprintf (stderr,
01724 "%s %d : Couldn't allocate D-BUS message\n",
01725 __FILE__, __LINE__);
01726 return FALSE;
01727 }
01728 dbus_message_iter_init_append (message, &iter);
01729 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
01730 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
01731
01732 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01733 message, -1,
01734 error);
01735 if (dbus_error_is_set (error)) {
01736 dbus_message_unref (message);
01737 return FALSE;
01738 }
01739 if (reply == NULL) {
01740 dbus_message_unref (message);
01741 return FALSE;
01742 }
01743 return TRUE;
01744 }
01745
01758 dbus_bool_t
01759 libhal_device_property_strlist_remove_index (LibHalContext *ctx,
01760 const char *udi,
01761 const char *key,
01762 unsigned int index,
01763 DBusError *error)
01764 {
01765 DBusMessage *message;
01766 DBusMessage *reply;
01767 DBusMessageIter iter;
01768
01769 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01770 "org.freedesktop.Hal.Device",
01771 "StringListRemoveIndex");
01772 if (message == NULL) {
01773 fprintf (stderr,
01774 "%s %d : Couldn't allocate D-BUS message\n",
01775 __FILE__, __LINE__);
01776 return FALSE;
01777 }
01778 dbus_message_iter_init_append (message, &iter);
01779 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
01780 dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &index);
01781
01782 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01783 message, -1,
01784 error);
01785 if (dbus_error_is_set (error)) {
01786 dbus_message_unref (message);
01787 return FALSE;
01788 }
01789 if (reply == NULL) {
01790 dbus_message_unref (message);
01791 return FALSE;
01792 }
01793 return TRUE;
01794 }
01795
01808 dbus_bool_t
01809 libhal_device_property_strlist_remove (LibHalContext *ctx,
01810 const char *udi,
01811 const char *key,
01812 const char *value, DBusError *error)
01813 {
01814 DBusMessage *message;
01815 DBusMessage *reply;
01816 DBusMessageIter iter;
01817
01818 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01819 "org.freedesktop.Hal.Device",
01820 "StringListRemove");
01821 if (message == NULL) {
01822 fprintf (stderr,
01823 "%s %d : Couldn't allocate D-BUS message\n",
01824 __FILE__, __LINE__);
01825 return FALSE;
01826 }
01827 dbus_message_iter_init_append (message, &iter);
01828 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
01829 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
01830
01831 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01832 message, -1,
01833 error);
01834 if (dbus_error_is_set (error)) {
01835 dbus_message_unref (message);
01836 return FALSE;
01837 }
01838 if (reply == NULL) {
01839 dbus_message_unref (message);
01840 return FALSE;
01841 }
01842 return TRUE;
01843 }
01844
01845
01860 dbus_bool_t
01861 libhal_device_lock (LibHalContext *ctx,
01862 const char *udi,
01863 const char *reason_to_lock,
01864 char **reason_why_locked, DBusError *error)
01865 {
01866 DBusMessage *message;
01867 DBusMessageIter iter;
01868 DBusMessage *reply;
01869
01870 if (reason_why_locked != NULL)
01871 *reason_why_locked = NULL;
01872
01873 message = dbus_message_new_method_call ("org.freedesktop.Hal",
01874 udi,
01875 "org.freedesktop.Hal.Device",
01876 "Lock");
01877
01878 if (message == NULL) {
01879 fprintf (stderr,
01880 "%s %d : Couldn't allocate D-BUS message\n",
01881 __FILE__, __LINE__);
01882 return FALSE;
01883 }
01884
01885 dbus_message_iter_init_append (message, &iter);
01886 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &reason_to_lock);
01887
01888
01889 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01890 message, -1,
01891 error);
01892
01893 if (dbus_error_is_set (error)) {
01894 if (strcmp (error->name,
01895 "org.freedesktop.Hal.DeviceAlreadyLocked") == 0) {
01896 if (reason_why_locked != NULL) {
01897 *reason_why_locked =
01898 dbus_malloc0 (strlen (error->message) + 1);
01899 strcpy (*reason_why_locked, error->message);
01900 }
01901 }
01902
01903 dbus_message_unref (message);
01904 return FALSE;
01905 }
01906
01907 dbus_message_unref (message);
01908
01909 if (reply == NULL)
01910 return FALSE;
01911
01912 dbus_message_unref (reply);
01913
01914 return TRUE;
01915 }
01916
01926 dbus_bool_t
01927 libhal_device_unlock (LibHalContext *ctx,
01928 const char *udi, DBusError *error)
01929 {
01930 DBusMessage *message;
01931 DBusMessage *reply;
01932
01933 message = dbus_message_new_method_call ("org.freedesktop.Hal",
01934 udi,
01935 "org.freedesktop.Hal.Device",
01936 "Unlock");
01937
01938 if (message == NULL) {
01939 fprintf (stderr,
01940 "%s %d : Couldn't allocate D-BUS message\n",
01941 __FILE__, __LINE__);
01942 return FALSE;
01943 }
01944
01945
01946 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01947 message, -1,
01948 error);
01949
01950 if (dbus_error_is_set (error)) {
01951 dbus_message_unref (message);
01952 return FALSE;
01953 }
01954
01955 dbus_message_unref (message);
01956
01957 if (reply == NULL)
01958 return FALSE;
01959
01960 dbus_message_unref (reply);
01961
01962 return TRUE;
01963 }
01964
01965
01979 char *
01980 libhal_agent_new_device (LibHalContext *ctx, DBusError *error)
01981 {
01982 DBusMessage *message;
01983 DBusMessage *reply;
01984 DBusMessageIter reply_iter;
01985 char *value;
01986 char *dbus_str;
01987
01988 message = dbus_message_new_method_call ("org.freedesktop.Hal",
01989 "/org/freedesktop/Hal/Manager",
01990 "org.freedesktop.Hal.AgentManager",
01991 "NewDevice");
01992 if (message == NULL) {
01993 fprintf (stderr,
01994 "%s %d : Couldn't allocate D-BUS message\n",
01995 __FILE__, __LINE__);
01996 return NULL;
01997 }
01998
01999
02000 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
02001 message, -1,
02002 error);
02003 if (dbus_error_is_set (error)) {
02004 dbus_message_unref (message);
02005 return NULL;
02006 }
02007 if (reply == NULL) {
02008 dbus_message_unref (message);
02009 return NULL;
02010 }
02011
02012 dbus_message_iter_init (reply, &reply_iter);
02013
02014
02015 if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_STRING) {
02016 fprintf (stderr,
02017 "%s %d : expected a string in reply to NewDevice\n",
02018 __FILE__, __LINE__);
02019 dbus_message_unref (message);
02020 dbus_message_unref (reply);
02021 return NULL;
02022 }
02023
02024 dbus_message_iter_get_basic (&reply_iter, &dbus_str);
02025 value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL);
02026 if (value == NULL) {
02027 fprintf (stderr, "%s %d : error allocating memory\n",
02028 __FILE__, __LINE__);
02030 return NULL;
02031 }
02032
02033 dbus_message_unref (message);
02034 dbus_message_unref (reply);
02035 return value;
02036 }
02037
02038
02059 dbus_bool_t
02060 libhal_agent_commit_to_gdl (LibHalContext *ctx,
02061 const char *temp_udi, const char *udi, DBusError *error)
02062 {
02063 DBusMessage *message;
02064 DBusMessage *reply;
02065 DBusMessageIter iter;
02066
02067 message = dbus_message_new_method_call ("org.freedesktop.Hal",
02068 "/org/freedesktop/Hal/Manager",
02069 "org.freedesktop.Hal.AgentManager",
02070 "CommitToGdl");
02071 if (message == NULL) {
02072 fprintf (stderr,
02073 "%s %d : Couldn't allocate D-BUS message\n",
02074 __FILE__, __LINE__);
02075 return FALSE;
02076 }
02077
02078 dbus_message_iter_init_append (message, &iter);
02079 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &temp_udi);
02080 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi);
02081
02082
02083 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
02084 message, -1,
02085 error);
02086 if (dbus_error_is_set (error)) {
02087 dbus_message_unref (message);
02088 return FALSE;
02089 }
02090 if (reply == NULL) {
02091 dbus_message_unref (message);
02092 return FALSE;
02093 }
02094
02095 dbus_message_unref (message);
02096 dbus_message_unref (reply);
02097 return TRUE;
02098 }
02099
02113 dbus_bool_t
02114 libhal_agent_remove_device (LibHalContext *ctx, const char *udi, DBusError *error)
02115 {
02116 DBusMessage *message;
02117 DBusMessage *reply;
02118 DBusMessageIter iter;
02119
02120 message = dbus_message_new_method_call ("org.freedesktop.Hal",
02121 "/org/freedesktop/Hal/Manager",
02122 "org.freedesktop.Hal.AgentManager",
02123 "Remove");
02124 if (message == NULL) {
02125 fprintf (stderr,
02126 "%s %d : Couldn't allocate D-BUS message\n",
02127 __FILE__, __LINE__);
02128 return FALSE;
02129 }
02130
02131 dbus_message_iter_init_append (message, &iter);
02132 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi);
02133
02134
02135 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
02136 message, -1,
02137 error);
02138 if (dbus_error_is_set (error)) {
02139 dbus_message_unref (message);
02140 return FALSE;
02141 }
02142 if (reply == NULL) {
02143 dbus_message_unref (message);
02144 return FALSE;
02145 }
02146
02147 dbus_message_unref (message);
02148 dbus_message_unref (reply);
02149 return TRUE;
02150 }
02151
02160 dbus_bool_t
02161 libhal_device_exists (LibHalContext *ctx, const char *udi, DBusError *error)
02162 {
02163 DBusMessage *message;
02164 DBusMessage *reply;
02165 DBusMessageIter iter, reply_iter;
02166 dbus_bool_t value;
02167 DBusError _error;
02168
02169 message = dbus_message_new_method_call ("org.freedesktop.Hal",
02170 "/org/freedesktop/Hal/Manager",
02171 "org.freedesktop.Hal.Manager",
02172 "DeviceExists");
02173 if (message == NULL) {
02174 fprintf (stderr,
02175 "%s %d : Couldn't allocate D-BUS message\n",
02176 __FILE__, __LINE__);
02177 return FALSE;
02178 }
02179
02180 dbus_message_iter_init_append (message, &iter);
02181 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi);
02182
02183 dbus_error_init (&_error);
02184 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
02185 message, -1,
02186 &_error);
02187
02188 dbus_move_error (&_error, error);
02189 if (error != NULL && dbus_error_is_set (error)) {
02190 dbus_message_unref (message);
02191 return FALSE;
02192 }
02193 if (reply == NULL) {
02194 dbus_message_unref (message);
02195 return FALSE;
02196 }
02197
02198 dbus_message_iter_init (reply, &reply_iter);
02199
02200
02201 if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) {
02202 fprintf (stderr,
02203 "%s %d : expected a bool in reply to DeviceExists\n",
02204 __FILE__, __LINE__);
02205 dbus_message_unref (message);
02206 dbus_message_unref (reply);
02207 return FALSE;
02208 }
02209
02210 dbus_message_iter_get_basic (&reply_iter, &value);
02211
02212 dbus_message_unref (message);
02213 dbus_message_unref (reply);
02214 return value;
02215 }
02216
02226 dbus_bool_t
02227 libhal_device_property_exists (LibHalContext *ctx,
02228 const char *udi, const char *key, DBusError *error)
02229 {
02230 DBusMessage *message;
02231 DBusMessage *reply;
02232 DBusMessageIter iter, reply_iter;
02233 dbus_bool_t value;
02234 DBusError _error;
02235
02236 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
02237 "org.freedesktop.Hal.Device",
02238 "PropertyExists");
02239 if (message == NULL) {
02240 fprintf (stderr,
02241 "%s %d : Couldn't allocate D-BUS message\n",
02242 __FILE__, __LINE__);
02243 return FALSE;
02244 }
02245
02246 dbus_message_iter_init_append (message, &iter);
02247 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
02248
02249 dbus_error_init (&_error);
02250 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
02251 message, -1,
02252 &_error);
02253
02254 dbus_move_error (&_error, error);
02255 if (error != NULL && dbus_error_is_set (error)) {
02256 dbus_message_unref (message);
02257 return FALSE;
02258 }
02259 if (reply == NULL) {
02260 dbus_message_unref (message);
02261 return FALSE;
02262 }
02263
02264 dbus_message_iter_init (reply, &reply_iter);
02265
02266
02267 if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) {
02268 fprintf (stderr, "%s %d : expected a bool in reply to "
02269 "PropertyExists\n", __FILE__, __LINE__);
02270 dbus_message_unref (message);
02271 dbus_message_unref (reply);
02272 return FALSE;
02273 }
02274
02275 dbus_message_iter_get_basic (&reply_iter, &value);
02276
02277 dbus_message_unref (message);
02278 dbus_message_unref (reply);
02279 return value;
02280 }
02281
02291 dbus_bool_t
02292 libhal_agent_merge_properties (LibHalContext *ctx,
02293 const char *target_udi, const char *source_udi, DBusError *error)
02294 {
02295 DBusMessage *message;
02296 DBusMessage *reply;
02297 DBusMessageIter iter;
02298
02299 message = dbus_message_new_method_call ("org.freedesktop.Hal",
02300 "/org/freedesktop/Hal/Manager",
02301 "org.freedesktop.Hal.AgentManager",
02302 "MergeProperties");
02303 if (message == NULL) {
02304 fprintf (stderr,
02305 "%s %d : Couldn't allocate D-BUS message\n",
02306 __FILE__, __LINE__);
02307 return FALSE;
02308 }
02309
02310 dbus_message_iter_init_append (message, &iter);
02311 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &target_udi);
02312 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &source_udi);
02313
02314
02315 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
02316 message, -1,
02317 error);
02318 if (dbus_error_is_set (error)) {
02319 dbus_message_unref (message);
02320 return FALSE;
02321 }
02322 if (reply == NULL) {
02323 dbus_message_unref (message);
02324 return FALSE;
02325 }
02326
02327 dbus_message_unref (message);
02328 dbus_message_unref (reply);
02329 return TRUE;
02330 }
02331
02353 dbus_bool_t
02354 libhal_agent_device_matches (LibHalContext *ctx,
02355 const char *udi1, const char *udi2,
02356 const char *property_namespace, DBusError *error)
02357 {
02358 DBusMessage *message;
02359 DBusMessage *reply;
02360 DBusMessageIter iter, reply_iter;
02361 dbus_bool_t value;
02362 DBusError _error;
02363
02364 message = dbus_message_new_method_call ("org.freedesktop.Hal",
02365 "/org/freedesktop/Hal/Manager",
02366 "org.freedesktop.Hal.AgentManager",
02367 "DeviceMatches");
02368 if (message == NULL) {
02369 fprintf (stderr,
02370 "%s %d : Couldn't allocate D-BUS message\n",
02371 __FILE__, __LINE__);
02372 return FALSE;
02373 }
02374
02375 dbus_message_iter_init_append (message, &iter);
02376 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, udi1);
02377 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, udi2);
02378 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, property_namespace);
02379
02380 dbus_error_init (&_error);
02381 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
02382 message, -1,
02383 &_error);
02384
02385 dbus_move_error (&_error, error);
02386 if (error != NULL && dbus_error_is_set (error)) {
02387 dbus_message_unref (message);
02388 return FALSE;
02389 }
02390 if (reply == NULL) {
02391 dbus_message_unref (message);
02392 return FALSE;
02393 }
02394
02395 dbus_message_iter_init (reply, &reply_iter);
02396
02397 if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) {
02398 fprintf (stderr,
02399 "%s %d : expected a bool in reply to DeviceMatches\n",
02400 __FILE__, __LINE__);
02401 dbus_message_unref (message);
02402 dbus_message_unref (reply);
02403 return FALSE;
02404 }
02405
02406 dbus_message_iter_get_basic (&reply_iter, &value);
02407
02408 dbus_message_unref (message);
02409 dbus_message_unref (reply);
02410 return value;
02411 }
02412
02422 dbus_bool_t
02423 libhal_device_print (LibHalContext *ctx, const char *udi, DBusError *error)
02424 {
02425 int type;
02426 char *key;
02427 LibHalPropertySet *pset;
02428 LibHalPropertySetIterator i;
02429
02430 printf ("device_id = %s\n", udi);
02431
02432 if ((pset = libhal_device_get_all_properties (ctx, udi, error)) == NULL)
02433 return FALSE;
02434
02435 for (libhal_psi_init (&i, pset); libhal_psi_has_more (&i);
02436 libhal_psi_next (&i)) {
02437 type = libhal_psi_get_type (&i);
02438 key = libhal_psi_get_key (&i);
02439
02440 switch (type) {
02441 case LIBHAL_PROPERTY_TYPE_STRING:
02442 printf (" %s = '%s' (string)\n", key,
02443 libhal_psi_get_string (&i));
02444 break;
02445 case LIBHAL_PROPERTY_TYPE_INT32:
02446 printf (" %s = %d = 0x%x (int)\n", key,
02447 libhal_psi_get_int (&i),
02448 libhal_psi_get_int (&i));
02449 break;
02450 case LIBHAL_PROPERTY_TYPE_UINT64:
02451 printf (" %s = %lld = 0x%llx (uint64)\n", key,
02452 libhal_psi_get_uint64 (&i),
02453 libhal_psi_get_uint64 (&i));
02454 break;
02455 case LIBHAL_PROPERTY_TYPE_BOOLEAN:
02456 printf (" %s = %s (bool)\n", key,
02457 (libhal_psi_get_bool (&i) ? "true" :
02458 "false"));
02459 break;
02460 case LIBHAL_PROPERTY_TYPE_DOUBLE:
02461 printf (" %s = %g (double)\n", key,
02462 libhal_psi_get_double (&i));
02463 break;
02464 case LIBHAL_PROPERTY_TYPE_STRLIST:
02465 {
02466 unsigned int j;
02467 char **str_list;
02468
02469 str_list = libhal_psi_get_strlist (&i);
02470 printf (" %s = [", key);
02471 for (j = 0; str_list[j] != NULL; j++) {
02472 printf ("'%s'", str_list[j]);
02473 if (str_list[j+1] != NULL)
02474 printf (", ");
02475 }
02476 printf ("] (string list)\n");
02477
02478 break;
02479 }
02480 default:
02481 printf (" *** unknown type for key %s\n", key);
02482 break;
02483 }
02484 }
02485
02486 libhal_free_property_set (pset);
02487
02488 return TRUE;
02489 }
02490
02503 char **
02504 libhal_manager_find_device_string_match (LibHalContext *ctx,
02505 const char *key,
02506 const char *value, int *num_devices, DBusError *error)
02507 {
02508 DBusMessage *message;
02509 DBusMessage *reply;
02510 DBusMessageIter iter, iter_array, reply_iter;
02511 char **hal_device_names;
02512 DBusError _error;
02513
02514 message = dbus_message_new_method_call ("org.freedesktop.Hal",
02515 "/org/freedesktop/Hal/Manager",
02516 "org.freedesktop.Hal.Manager",
02517 "FindDeviceStringMatch");
02518 if (message == NULL) {
02519 fprintf (stderr,
02520 "%s %d : Couldn't allocate D-BUS message\n",
02521 __FILE__, __LINE__);
02522 return NULL;
02523 }
02524
02525 dbus_message_iter_init_append (message, &iter);
02526 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
02527 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
02528
02529 dbus_error_init (&_error);
02530 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
02531 message, -1,
02532 &_error);
02533
02534 dbus_move_error (&_error, error);
02535 if (error != NULL && dbus_error_is_set (error)) {
02536 dbus_message_unref (message);
02537 return NULL;
02538 }
02539 if (reply == NULL) {
02540 dbus_message_unref (message);
02541 return NULL;
02542 }
02543
02544 dbus_message_iter_init (reply, &reply_iter);
02545
02546 if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) {
02547 fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__);
02548 return NULL;
02549 }
02550
02551 dbus_message_iter_recurse (&reply_iter, &iter_array);
02552
02553 hal_device_names = libhal_get_string_array_from_iter (&iter_array, num_devices);
02554
02555 dbus_message_unref (reply);
02556 dbus_message_unref (message);
02557
02558 return hal_device_names;
02559 }
02560
02561
02572 dbus_bool_t
02573 libhal_device_add_capability (LibHalContext *ctx,
02574 const char *udi, const char *capability, DBusError *error)
02575 {
02576 DBusMessage *message;
02577 DBusMessage *reply;
02578 DBusMessageIter iter;
02579
02580 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
02581 "org.freedesktop.Hal.Device",
02582 "AddCapability");
02583 if (message == NULL) {
02584 fprintf (stderr,
02585 "%s %d : Couldn't allocate D-BUS message\n",
02586 __FILE__, __LINE__);
02587 return FALSE;
02588 }
02589
02590 dbus_message_iter_init_append (message, &iter);
02591 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &capability);
02592
02593
02594 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
02595 message, -1,
02596 error);
02597 if (dbus_error_is_set (error)) {
02598 dbus_message_unref (message);
02599 return FALSE;
02600 }
02601
02602 if (reply == NULL) {
02603 dbus_message_unref (message);
02604 return FALSE;
02605 }
02606
02607 dbus_message_unref (reply);
02608 dbus_message_unref (message);
02609 return TRUE;
02610 }
02611
02623 dbus_bool_t
02624 libhal_device_query_capability (LibHalContext *ctx, const char *udi, const char *capability, DBusError *error)
02625 {
02626 char **caps;
02627 unsigned int i;
02628 dbus_bool_t ret;
02629
02630 ret = FALSE;
02631
02632 caps = libhal_device_get_property_strlist (ctx, udi, "info.capabilities", error);
02633 if (caps != NULL) {
02634 for (i = 0; caps[i] != NULL; i++) {
02635 if (strcmp (caps[i], capability) == 0) {
02636 ret = TRUE;
02637 break;
02638 }
02639 }
02640 libhal_free_string_array (caps);
02641 }
02642
02643 return ret;
02644 }
02645
02656 char **
02657 libhal_find_device_by_capability (LibHalContext *ctx,
02658 const char *capability, int *num_devices, DBusError *error)
02659 {
02660 DBusMessage *message;
02661 DBusMessage *reply;
02662 DBusMessageIter iter, iter_array, reply_iter;
02663 char **hal_device_names;
02664 DBusError _error;
02665
02666 message = dbus_message_new_method_call ("org.freedesktop.Hal",
02667 "/org/freedesktop/Hal/Manager",
02668 "org.freedesktop.Hal.Manager",
02669 "FindDeviceByCapability");
02670 if (message == NULL) {
02671 fprintf (stderr,
02672 "%s %d : Couldn't allocate D-BUS message\n",
02673 __FILE__, __LINE__);
02674 return NULL;
02675 }
02676
02677 dbus_message_iter_init_append (message, &iter);
02678 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &capability);
02679
02680 dbus_error_init (&_error);
02681 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
02682 message, -1,
02683 &_error);
02684
02685 dbus_move_error (&_error, error);
02686 if (error != NULL && dbus_error_is_set (error)) {
02687 dbus_message_unref (message);
02688 return NULL;
02689 }
02690 if (reply == NULL) {
02691 dbus_message_unref (message);
02692 return NULL;
02693 }
02694
02695 dbus_message_iter_init (reply, &reply_iter);
02696
02697 if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) {
02698 fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__);
02699 return NULL;
02700 }
02701
02702 dbus_message_iter_recurse (&reply_iter, &iter_array);
02703
02704 hal_device_names = libhal_get_string_array_from_iter (&iter_array, num_devices);
02705
02706 dbus_message_unref (reply);
02707 dbus_message_unref (message);
02708
02709 return hal_device_names;
02710 }
02711
02720 dbus_bool_t
02721 libhal_device_property_watch_all (LibHalContext *ctx, DBusError *error)
02722 {
02723 dbus_bus_add_match (ctx->connection,
02724 "type='signal',"
02725 "interface='org.freedesktop.Hal.Device',"
02726 "sender='org.freedesktop.Hal'", error);
02727 if (dbus_error_is_set (error)) {
02728 return FALSE;
02729 }
02730 return TRUE;
02731 }
02732
02733
02746 dbus_bool_t
02747 libhal_device_add_property_watch (LibHalContext *ctx, const char *udi, DBusError *error)
02748 {
02749 char buf[512];
02750
02751 snprintf (buf, 512,
02752 "type='signal',"
02753 "interface='org.freedesktop.Hal.Device',"
02754 "sender='org.freedesktop.Hal'," "path=%s", udi);
02755
02756 dbus_bus_add_match (ctx->connection, buf, error);
02757 if (dbus_error_is_set (error)) {
02758 return FALSE;
02759 }
02760 return TRUE;
02761 }
02762
02763
02772 dbus_bool_t
02773 libhal_device_remove_property_watch (LibHalContext *ctx, const char *udi, DBusError *error)
02774 {
02775 char buf[512];
02776
02777 snprintf (buf, 512,
02778 "type='signal',"
02779 "interface='org.freedesktop.Hal.Device',"
02780 "sender='org.freedesktop.Hal'," "path=%s", udi);
02781
02782 dbus_bus_remove_match (ctx->connection, buf, error);
02783 if (dbus_error_is_set (error)) {
02784 return FALSE;
02785 }
02786 return TRUE;
02787 }
02788
02789
02794 LibHalContext *
02795 libhal_ctx_new (void)
02796 {
02797 LibHalContext *ctx;
02798
02799 if (!libhal_already_initialized_once) {
02800 bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
02801 bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
02802
02803 libhal_already_initialized_once = TRUE;
02804 }
02805
02806 ctx = calloc (1, sizeof (LibHalContext));
02807 if (ctx == NULL) {
02808 fprintf (stderr, "%s %d : Failed to allocate %d bytes\n", __FILE__, __LINE__, sizeof (LibHalContext));
02809 return NULL;
02810 }
02811
02812 ctx->is_initialized = FALSE;
02813 ctx->is_shutdown = FALSE;
02814 ctx->connection = NULL;
02815 ctx->is_direct = FALSE;
02816
02817 return ctx;
02818 }
02819
02829 dbus_bool_t
02830 libhal_ctx_set_cache (LibHalContext *ctx, dbus_bool_t use_cache)
02831 {
02832 if (ctx == NULL)
02833 return FALSE;
02834
02835 ctx->cache_enabled = use_cache;
02836 return TRUE;
02837 }
02838
02846 dbus_bool_t
02847 libhal_ctx_set_dbus_connection (LibHalContext *ctx, DBusConnection *conn)
02848 {
02849 if (ctx == NULL)
02850 return FALSE;
02851
02852 if (conn == NULL)
02853 return FALSE;
02854
02855 ctx->connection = conn;
02856 return TRUE;
02857 }
02858
02867 dbus_bool_t
02868 libhal_ctx_init (LibHalContext *ctx, DBusError *error)
02869 {
02870 DBusError _error;
02871
02872 if (ctx == NULL)
02873 return FALSE;
02874
02875 if (ctx->connection == NULL)
02876 return FALSE;
02877
02878
02879 if (!dbus_connection_add_filter (ctx->connection, filter_func, ctx, NULL)) {
02880 return FALSE;
02881 }
02882
02883 dbus_error_init (&_error);
02884 dbus_bus_add_match (ctx->connection,
02885 "type='signal',"
02886 "interface='org.freedesktop.Hal.Manager',"
02887 "sender='org.freedesktop.Hal',"
02888 "path='/org/freedesktop/Hal/Manager'", &_error);
02889 dbus_move_error (&_error, error);
02890 if (error != NULL && dbus_error_is_set (error)) {
02891 return FALSE;
02892 }
02893 ctx->is_initialized = TRUE;
02894 ctx->is_direct = FALSE;
02895
02896 return TRUE;
02897 }
02898
02905 LibHalContext *
02906 libhal_ctx_init_direct (DBusError *error)
02907 {
02908 char *hald_addr;
02909 LibHalContext *ctx;
02910 DBusError _error;
02911
02912 ctx = libhal_ctx_new ();
02913 if (ctx == NULL)
02914 goto out;
02915
02916 if (((hald_addr = getenv ("HALD_DIRECT_ADDR"))) == NULL) {
02917 libhal_ctx_free (ctx);
02918 ctx = NULL;
02919 goto out;
02920 }
02921
02922 dbus_error_init (&_error);
02923 ctx->connection = dbus_connection_open (hald_addr, &_error);
02924 dbus_move_error (&_error, error);
02925 if (error != NULL && dbus_error_is_set (error)) {
02926 libhal_ctx_free (ctx);
02927 ctx = NULL;
02928 goto out;
02929 }
02930
02931 ctx->is_initialized = TRUE;
02932 ctx->is_direct = TRUE;
02933
02934 out:
02935 return ctx;
02936 }
02937
02946 dbus_bool_t
02947 libhal_ctx_shutdown (LibHalContext *ctx, DBusError *error)
02948 {
02949 DBusError myerror;
02950
02951 if (ctx->is_direct) {
02952
02953
02954 } else {
02955 dbus_error_init (&myerror);
02956 dbus_bus_remove_match (ctx->connection,
02957 "type='signal',"
02958 "interface='org.freedesktop.Hal.Manager',"
02959 "sender='org.freedesktop.Hal',"
02960 "path='/org/freedesktop/Hal/Manager'", &myerror);
02961 if (dbus_error_is_set (&myerror)) {
02962 fprintf (stderr, "%s %d : Error unsubscribing to signals, error=%s\n",
02963 __FILE__, __LINE__, error->message);
02965 }
02966
02967
02968
02969 dbus_connection_remove_filter (ctx->connection, filter_func, ctx);
02970 }
02971
02972 ctx->is_initialized = FALSE;
02973
02974 return TRUE;
02975 }
02976
02982 dbus_bool_t
02983 libhal_ctx_free (LibHalContext *ctx)
02984 {
02985 free (ctx);
02986 return TRUE;
02987 }
02988
02996 dbus_bool_t
02997 libhal_ctx_set_device_added (LibHalContext *ctx, LibHalDeviceAdded callback)
02998 {
02999 if (ctx == NULL)
03000 return FALSE;
03001 ctx->device_added = callback;
03002 return TRUE;
03003 }
03004
03012 dbus_bool_t
03013 libhal_ctx_set_device_removed (LibHalContext *ctx, LibHalDeviceRemoved callback)
03014 {
03015 if (ctx == NULL)
03016 return FALSE;
03017 ctx->device_removed = callback;
03018 return TRUE;
03019 }
03020
03029 dbus_bool_t
03030 libhal_ctx_set_device_new_capability (LibHalContext *ctx, LibHalDeviceNewCapability callback)
03031 {
03032 if (ctx == NULL)
03033 return FALSE;
03034 ctx->device_new_capability = callback;
03035 return TRUE;
03036 }
03037
03046 dbus_bool_t
03047 libhal_ctx_set_device_lost_capability (LibHalContext *ctx, LibHalDeviceLostCapability callback)
03048 {
03049 if (ctx == NULL)
03050 return FALSE;
03051 ctx->device_lost_capability = callback;
03052 return TRUE;
03053 }
03054
03063 dbus_bool_t
03064 libhal_ctx_set_device_property_modified (LibHalContext *ctx, LibHalDevicePropertyModified callback)
03065 {
03066 if (ctx == NULL)
03067 return FALSE;
03068 ctx->device_property_modified = callback;
03069 return TRUE;
03070 }
03071
03079 dbus_bool_t
03080 libhal_ctx_set_device_condition (LibHalContext *ctx, LibHalDeviceCondition callback)
03081 {
03082 if (ctx == NULL)
03083 return FALSE;
03084 ctx->device_condition = callback;
03085 return TRUE;
03086 }
03087
03093 unsigned int libhal_string_array_length (char **str_array)
03094 {
03095 unsigned int i;
03096
03097 if (str_array == NULL)
03098 return 0;
03099
03100 for (i = 0; str_array[i] != NULL; i++)
03101 ;
03102
03103 return i;
03104 }
03105
03106
03107 dbus_bool_t
03108 libhal_device_rescan (LibHalContext *ctx, const char *udi, DBusError *error)
03109 {
03110 DBusMessage *message;
03111 DBusMessageIter reply_iter;
03112 DBusMessage *reply;
03113 dbus_bool_t result;
03114
03115 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
03116 "org.freedesktop.Hal.Device",
03117 "Rescan");
03118
03119 if (message == NULL) {
03120 fprintf (stderr,
03121 "%s %d : Couldn't allocate D-BUS message\n",
03122 __FILE__, __LINE__);
03123 return FALSE;
03124 }
03125
03126 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
03127 message, -1,
03128 error);
03129
03130 if (dbus_error_is_set (error)) {
03131 dbus_message_unref (message);
03132 return FALSE;
03133 }
03134
03135 dbus_message_unref (message);
03136
03137 if (reply == NULL)
03138 return FALSE;
03139
03140 dbus_message_iter_init (reply, &reply_iter);
03141 if (dbus_message_iter_get_arg_type (&reply_iter) !=
03142 DBUS_TYPE_BOOLEAN) {
03143 dbus_message_unref (message);
03144 dbus_message_unref (reply);
03145 return FALSE;
03146 }
03147 dbus_message_iter_get_basic (&reply_iter, &result);
03148
03149 dbus_message_unref (reply);
03150
03151 return result;
03152 }
03153
03154 dbus_bool_t
03155 libhal_device_reprobe (LibHalContext *ctx, const char *udi, DBusError *error)
03156 {
03157 DBusMessage *message;
03158 DBusMessageIter reply_iter;
03159 DBusMessage *reply;
03160 dbus_bool_t result;
03161
03162 message = dbus_message_new_method_call ("org.freedesktop.Hal",
03163 udi,
03164 "org.freedesktop.Hal.Device",
03165 "Reprobe");
03166
03167 if (message == NULL) {
03168 fprintf (stderr,
03169 "%s %d : Couldn't allocate D-BUS message\n",
03170 __FILE__, __LINE__);
03171 return FALSE;
03172 }
03173
03174 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
03175 message, -1,
03176 error);
03177
03178 if (dbus_error_is_set (error)) {
03179 dbus_message_unref (message);
03180 return FALSE;
03181 }
03182
03183 dbus_message_unref (message);
03184
03185 if (reply == NULL)
03186 return FALSE;
03187
03188 dbus_message_iter_init (reply, &reply_iter);
03189 if (dbus_message_iter_get_arg_type (&reply_iter) !=
03190 DBUS_TYPE_BOOLEAN) {
03191 dbus_message_unref (message);
03192 dbus_message_unref (reply);
03193 return FALSE;
03194 }
03195 dbus_message_iter_get_basic (&reply_iter, &result);
03196
03197 dbus_message_unref (reply);
03198
03199 return result;
03200 }
03201
03213 dbus_bool_t libhal_device_emit_condition (LibHalContext *ctx,
03214 const char *udi,
03215 const char *condition_name,
03216 const char *condition_details,
03217 DBusError *error)
03218 {
03219 DBusMessage *message;
03220 DBusMessageIter iter;
03221 DBusMessageIter reply_iter;
03222 DBusMessage *reply;
03223 dbus_bool_t result;
03224
03225 message = dbus_message_new_method_call ("org.freedesktop.Hal",
03226 udi,
03227 "org.freedesktop.Hal.Device",
03228 "EmitCondition");
03229
03230 if (message == NULL) {
03231 fprintf (stderr,
03232 "%s %d : Couldn't allocate D-BUS message\n",
03233 __FILE__, __LINE__);
03234 return FALSE;
03235 }
03236
03237 dbus_message_iter_init_append (message, &iter);
03238 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &condition_name);
03239 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &condition_details);
03240
03241 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
03242 message, -1,
03243 error);
03244
03245 if (dbus_error_is_set (error)) {
03246 dbus_message_unref (message);
03247 return FALSE;
03248 }
03249
03250 dbus_message_unref (message);
03251
03252 if (reply == NULL)
03253 return FALSE;
03254
03255 dbus_message_iter_init (reply, &reply_iter);
03256 if (dbus_message_iter_get_arg_type (&reply_iter) !=
03257 DBUS_TYPE_BOOLEAN) {
03258 dbus_message_unref (message);
03259 dbus_message_unref (reply);
03260 return FALSE;
03261 }
03262 dbus_message_iter_get_basic (&reply_iter, &result);
03263
03264 dbus_message_unref (reply);
03265
03266 return result;
03267 }
03268