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 #include <config.h>
00026 #include "dbus-internals.h"
00027 #include "dbus-marshal-recursive.h"
00028 #include "dbus-marshal-validate.h"
00029 #include "dbus-marshal-byteswap.h"
00030 #include "dbus-marshal-header.h"
00031 #include "dbus-signature.h"
00032 #include "dbus-message-private.h"
00033 #include "dbus-object-tree.h"
00034 #include "dbus-memory.h"
00035 #include "dbus-list.h"
00036 #include "dbus-threads-internal.h"
00037 #ifdef HAVE_UNIX_FD_PASSING
00038 #include "dbus-sysdeps.h"
00039 #include "dbus-sysdeps-unix.h"
00040 #endif
00041
00042 #include <string.h>
00043
00044 #define _DBUS_TYPE_IS_STRINGLIKE(type) \
00045 (type == DBUS_TYPE_STRING || type == DBUS_TYPE_SIGNATURE || \
00046 type == DBUS_TYPE_OBJECT_PATH)
00047
00048 static void dbus_message_finalize (DBusMessage *message);
00049
00060 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
00061 static dbus_bool_t
00062 _dbus_enable_message_cache (void)
00063 {
00064 static int enabled = -1;
00065
00066 if (enabled < 0)
00067 {
00068 const char *s = _dbus_getenv ("DBUS_MESSAGE_CACHE");
00069
00070 enabled = TRUE;
00071
00072 if (s && *s)
00073 {
00074 if (*s == '0')
00075 enabled = FALSE;
00076 else if (*s == '1')
00077 enabled = TRUE;
00078 else
00079 _dbus_warn ("DBUS_MESSAGE_CACHE should be 0 or 1 if set, not '%s'",
00080 s);
00081 }
00082 }
00083
00084 return enabled;
00085 }
00086 #else
00087
00088 # define _dbus_enable_message_cache() (TRUE)
00089 #endif
00090
00091 #ifndef _dbus_message_trace_ref
00092 void
00093 _dbus_message_trace_ref (DBusMessage *message,
00094 int old_refcount,
00095 int new_refcount,
00096 const char *why)
00097 {
00098 static int enabled = -1;
00099
00100 _dbus_trace_ref ("DBusMessage", message, old_refcount, new_refcount, why,
00101 "DBUS_MESSAGE_TRACE", &enabled);
00102 }
00103 #endif
00104
00105
00106
00108 _DBUS_STRING_DEFINE_STATIC(_dbus_empty_signature_str, "");
00109
00110
00111
00112
00113 enum {
00114 DBUS_MESSAGE_ITER_TYPE_READER = 3,
00115 DBUS_MESSAGE_ITER_TYPE_WRITER = 7
00116 };
00117
00119 typedef struct DBusMessageRealIter DBusMessageRealIter;
00120
00126 struct DBusMessageRealIter
00127 {
00128 DBusMessage *message;
00129 dbus_uint32_t changed_stamp : CHANGED_STAMP_BITS;
00130 dbus_uint32_t iter_type : 3;
00131 dbus_uint32_t sig_refcount : 8;
00132 union
00133 {
00134 DBusTypeWriter writer;
00135 DBusTypeReader reader;
00136 } u;
00137 };
00138
00144 typedef struct
00145 {
00146 void *dummy1;
00147 void *dummy2;
00148 dbus_uint32_t dummy3;
00149 int dummy4;
00150 int dummy5;
00151 int dummy6;
00152 int dummy7;
00153 int dummy8;
00154 int dummy9;
00155 int dummy10;
00156 int dummy11;
00157 int pad1;
00158 int pad2;
00159 void *pad3;
00160 } DBusMessageIter_1_10_0;
00161
00162 static void
00163 get_const_signature (DBusHeader *header,
00164 const DBusString **type_str_p,
00165 int *type_pos_p)
00166 {
00167 if (_dbus_header_get_field_raw (header,
00168 DBUS_HEADER_FIELD_SIGNATURE,
00169 type_str_p,
00170 type_pos_p))
00171 {
00172 *type_pos_p += 1;
00173 }
00174 else
00175 {
00176 *type_str_p = &_dbus_empty_signature_str;
00177 *type_pos_p = 0;
00178 }
00179 }
00180
00186 static void
00187 _dbus_message_byteswap (DBusMessage *message)
00188 {
00189 const DBusString *type_str;
00190 int type_pos;
00191 char byte_order;
00192
00193 byte_order = _dbus_header_get_byte_order (&message->header);
00194
00195 if (byte_order == DBUS_COMPILER_BYTE_ORDER)
00196 return;
00197
00198 _dbus_verbose ("Swapping message into compiler byte order\n");
00199
00200 get_const_signature (&message->header, &type_str, &type_pos);
00201
00202 _dbus_marshal_byteswap (type_str, type_pos,
00203 byte_order,
00204 DBUS_COMPILER_BYTE_ORDER,
00205 &message->body, 0);
00206
00207 _dbus_header_byteswap (&message->header, DBUS_COMPILER_BYTE_ORDER);
00208 _dbus_assert (_dbus_header_get_byte_order (&message->header) ==
00209 DBUS_COMPILER_BYTE_ORDER);
00210 }
00211
00218 #define ensure_byte_order(message) _dbus_message_byteswap (message)
00219
00230 void
00231 _dbus_message_get_network_data (DBusMessage *message,
00232 const DBusString **header,
00233 const DBusString **body)
00234 {
00235 _dbus_assert (message->locked);
00236
00237 *header = &message->header.data;
00238 *body = &message->body;
00239 }
00240
00250 void _dbus_message_get_unix_fds(DBusMessage *message,
00251 const int **fds,
00252 unsigned *n_fds)
00253 {
00254 _dbus_assert (message->locked);
00255
00256 #ifdef HAVE_UNIX_FD_PASSING
00257 *fds = message->unix_fds;
00258 *n_fds = message->n_unix_fds;
00259 #else
00260 *fds = NULL;
00261 *n_fds = 0;
00262 #endif
00263 }
00264
00276 void
00277 dbus_message_set_serial (DBusMessage *message,
00278 dbus_uint32_t serial)
00279 {
00280 _dbus_return_if_fail (message != NULL);
00281 _dbus_return_if_fail (!message->locked);
00282
00283 _dbus_header_set_serial (&message->header, serial);
00284 }
00285
00302 void
00303 _dbus_message_add_counter_link (DBusMessage *message,
00304 DBusList *link)
00305 {
00306
00307
00308
00309
00310
00311
00312 if (message->counters == NULL)
00313 {
00314 message->size_counter_delta =
00315 _dbus_string_get_length (&message->header.data) +
00316 _dbus_string_get_length (&message->body);
00317
00318 #ifdef HAVE_UNIX_FD_PASSING
00319 message->unix_fd_counter_delta = message->n_unix_fds;
00320 #endif
00321
00322 #if 0
00323 _dbus_verbose ("message has size %ld\n",
00324 message->size_counter_delta);
00325 #endif
00326 }
00327
00328 _dbus_list_append_link (&message->counters, link);
00329
00330 _dbus_counter_adjust_size (link->data, message->size_counter_delta);
00331
00332 #ifdef HAVE_UNIX_FD_PASSING
00333 _dbus_counter_adjust_unix_fd (link->data, message->unix_fd_counter_delta);
00334 #endif
00335 }
00336
00351 dbus_bool_t
00352 _dbus_message_add_counter (DBusMessage *message,
00353 DBusCounter *counter)
00354 {
00355 DBusList *link;
00356
00357 link = _dbus_list_alloc_link (counter);
00358 if (link == NULL)
00359 return FALSE;
00360
00361 _dbus_counter_ref (counter);
00362 _dbus_message_add_counter_link (message, link);
00363
00364 return TRUE;
00365 }
00366
00374 void
00375 _dbus_message_remove_counter (DBusMessage *message,
00376 DBusCounter *counter)
00377 {
00378 DBusList *link;
00379
00380 link = _dbus_list_find_last (&message->counters,
00381 counter);
00382 _dbus_assert (link != NULL);
00383
00384 _dbus_list_remove_link (&message->counters, link);
00385
00386 _dbus_counter_adjust_size (counter, - message->size_counter_delta);
00387
00388 #ifdef HAVE_UNIX_FD_PASSING
00389 _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
00390 #endif
00391
00392 _dbus_counter_notify (counter);
00393 _dbus_counter_unref (counter);
00394 }
00395
00406 void
00407 dbus_message_lock (DBusMessage *message)
00408 {
00409 if (!message->locked)
00410 {
00411 _dbus_header_update_lengths (&message->header,
00412 _dbus_string_get_length (&message->body));
00413
00414
00415 _dbus_assert (_dbus_string_get_length (&message->body) == 0 ||
00416 dbus_message_get_signature (message) != NULL);
00417
00418 message->locked = TRUE;
00419 }
00420 }
00421
00422 static dbus_bool_t
00423 set_or_delete_string_field (DBusMessage *message,
00424 int field,
00425 int typecode,
00426 const char *value)
00427 {
00428 if (value == NULL)
00429 return _dbus_header_delete_field (&message->header, field);
00430 else
00431 return _dbus_header_set_field_basic (&message->header,
00432 field,
00433 typecode,
00434 &value);
00435 }
00436
00437 #if 0
00438
00462 static dbus_bool_t
00463 _dbus_message_set_signature (DBusMessage *message,
00464 const char *signature)
00465 {
00466 _dbus_return_val_if_fail (message != NULL, FALSE);
00467 _dbus_return_val_if_fail (!message->locked, FALSE);
00468 _dbus_return_val_if_fail (signature == NULL ||
00469 _dbus_check_is_valid_signature (signature));
00470
00471 _dbus_return_val_if_fail (_dbus_string_get_length (&message->body) == 0 ||
00472 signature != NULL);
00473
00474 return set_or_delete_string_field (message,
00475 DBUS_HEADER_FIELD_SIGNATURE,
00476 DBUS_TYPE_SIGNATURE,
00477 signature);
00478 }
00479 #endif
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00528 #define MAX_MESSAGE_SIZE_TO_CACHE 10 * _DBUS_ONE_KILOBYTE
00529
00531 #define MAX_MESSAGE_CACHE_SIZE 5
00532
00533
00534 static DBusMessage *message_cache[MAX_MESSAGE_CACHE_SIZE];
00535 static int message_cache_count = 0;
00536 static dbus_bool_t message_cache_shutdown_registered = FALSE;
00537
00538 static void
00539 dbus_message_cache_shutdown (void *data)
00540 {
00541 int i;
00542
00543 if (!_DBUS_LOCK (message_cache))
00544 _dbus_assert_not_reached ("we would have initialized global locks "
00545 "before registering a shutdown function");
00546
00547 i = 0;
00548 while (i < MAX_MESSAGE_CACHE_SIZE)
00549 {
00550 if (message_cache[i])
00551 dbus_message_finalize (message_cache[i]);
00552
00553 ++i;
00554 }
00555
00556 message_cache_count = 0;
00557 message_cache_shutdown_registered = FALSE;
00558
00559 _DBUS_UNLOCK (message_cache);
00560 }
00561
00569 static DBusMessage*
00570 dbus_message_get_cached (void)
00571 {
00572 DBusMessage *message;
00573 int i;
00574
00575 message = NULL;
00576
00577 if (!_DBUS_LOCK (message_cache))
00578 {
00579
00580
00581 return NULL;
00582 }
00583
00584 _dbus_assert (message_cache_count >= 0);
00585
00586 if (message_cache_count == 0)
00587 {
00588 _DBUS_UNLOCK (message_cache);
00589 return NULL;
00590 }
00591
00592
00593
00594
00595
00596 _dbus_assert (message_cache_shutdown_registered);
00597
00598 i = 0;
00599 while (i < MAX_MESSAGE_CACHE_SIZE)
00600 {
00601 if (message_cache[i])
00602 {
00603 message = message_cache[i];
00604 message_cache[i] = NULL;
00605 message_cache_count -= 1;
00606 break;
00607 }
00608 ++i;
00609 }
00610 _dbus_assert (message_cache_count >= 0);
00611 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
00612 _dbus_assert (message != NULL);
00613
00614 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
00615
00616 _dbus_assert (message->counters == NULL);
00617
00618 _DBUS_UNLOCK (message_cache);
00619
00620 return message;
00621 }
00622
00623 #ifdef HAVE_UNIX_FD_PASSING
00624 static void
00625 close_unix_fds(int *fds, unsigned *n_fds)
00626 {
00627 DBusError e;
00628 unsigned int i;
00629
00630 if (*n_fds <= 0)
00631 return;
00632
00633 dbus_error_init(&e);
00634
00635 for (i = 0; i < *n_fds; i++)
00636 {
00637 if (!_dbus_close(fds[i], &e))
00638 {
00639 _dbus_warn("Failed to close file descriptor: %s\n", e.message);
00640 dbus_error_free(&e);
00641 }
00642 }
00643
00644 *n_fds = 0;
00645
00646
00647 }
00648 #endif
00649
00650 static void
00651 free_counter (void *element,
00652 void *data)
00653 {
00654 DBusCounter *counter = element;
00655 DBusMessage *message = data;
00656
00657 _dbus_counter_adjust_size (counter, - message->size_counter_delta);
00658 #ifdef HAVE_UNIX_FD_PASSING
00659 _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
00660 #endif
00661
00662 _dbus_counter_notify (counter);
00663 _dbus_counter_unref (counter);
00664 }
00665
00671 static void
00672 dbus_message_cache_or_finalize (DBusMessage *message)
00673 {
00674 dbus_bool_t was_cached;
00675 int i;
00676
00677 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
00678
00679
00680
00681
00682 _dbus_data_slot_list_clear (&message->slot_list);
00683
00684 _dbus_list_foreach (&message->counters,
00685 free_counter, message);
00686 _dbus_list_clear (&message->counters);
00687
00688 #ifdef HAVE_UNIX_FD_PASSING
00689 close_unix_fds(message->unix_fds, &message->n_unix_fds);
00690 #endif
00691
00692 was_cached = FALSE;
00693
00694 if (!_DBUS_LOCK (message_cache))
00695 {
00696
00697
00698 _dbus_assert_not_reached ("we would have initialized global locks "
00699 "the first time we constructed a message");
00700 }
00701
00702 if (!message_cache_shutdown_registered)
00703 {
00704 _dbus_assert (message_cache_count == 0);
00705
00706 if (!_dbus_register_shutdown_func (dbus_message_cache_shutdown, NULL))
00707 goto out;
00708
00709 i = 0;
00710 while (i < MAX_MESSAGE_CACHE_SIZE)
00711 {
00712 message_cache[i] = NULL;
00713 ++i;
00714 }
00715
00716 message_cache_shutdown_registered = TRUE;
00717 }
00718
00719 _dbus_assert (message_cache_count >= 0);
00720
00721 if (!_dbus_enable_message_cache ())
00722 goto out;
00723
00724 if ((_dbus_string_get_length (&message->header.data) +
00725 _dbus_string_get_length (&message->body)) >
00726 MAX_MESSAGE_SIZE_TO_CACHE)
00727 goto out;
00728
00729 if (message_cache_count >= MAX_MESSAGE_CACHE_SIZE)
00730 goto out;
00731
00732
00733 i = 0;
00734 while (message_cache[i] != NULL)
00735 ++i;
00736
00737 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
00738
00739 _dbus_assert (message_cache[i] == NULL);
00740 message_cache[i] = message;
00741 message_cache_count += 1;
00742 was_cached = TRUE;
00743 #ifndef DBUS_DISABLE_CHECKS
00744 message->in_cache = TRUE;
00745 #endif
00746
00747 out:
00748 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
00749
00750 _DBUS_UNLOCK (message_cache);
00751
00752 if (!was_cached)
00753 dbus_message_finalize (message);
00754 }
00755
00756 #if defined(DBUS_ENABLE_CHECKS) || defined(DBUS_ENABLE_ASSERT)
00757 static dbus_bool_t
00758 _dbus_message_iter_check (DBusMessageRealIter *iter)
00759 {
00760 char byte_order;
00761
00762 if (iter == NULL)
00763 {
00764 _dbus_warn_check_failed ("dbus message iterator is NULL\n");
00765 return FALSE;
00766 }
00767
00768 byte_order = _dbus_header_get_byte_order (&iter->message->header);
00769
00770 if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_READER)
00771 {
00772 if (iter->u.reader.byte_order != byte_order)
00773 {
00774 _dbus_warn_check_failed ("dbus message changed byte order since iterator was created\n");
00775 return FALSE;
00776 }
00777
00778 _dbus_assert (iter->u.reader.byte_order == DBUS_COMPILER_BYTE_ORDER);
00779 }
00780 else if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER)
00781 {
00782 if (iter->u.writer.byte_order != byte_order)
00783 {
00784 _dbus_warn_check_failed ("dbus message changed byte order since append iterator was created\n");
00785 return FALSE;
00786 }
00787
00788 _dbus_assert (iter->u.writer.byte_order == DBUS_COMPILER_BYTE_ORDER);
00789 }
00790 else
00791 {
00792 _dbus_warn_check_failed ("dbus message iterator looks uninitialized or corrupted\n");
00793 return FALSE;
00794 }
00795
00796 if (iter->changed_stamp != iter->message->changed_stamp)
00797 {
00798 _dbus_warn_check_failed ("dbus message iterator invalid because the message has been modified (or perhaps the iterator is just uninitialized)\n");
00799 return FALSE;
00800 }
00801
00802 return TRUE;
00803 }
00804 #endif
00805
00818 dbus_bool_t
00819 _dbus_message_iter_get_args_valist (DBusMessageIter *iter,
00820 DBusError *error,
00821 int first_arg_type,
00822 va_list var_args)
00823 {
00824 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
00825 int spec_type, msg_type, i, j;
00826 dbus_bool_t retval;
00827 va_list copy_args;
00828
00829 _dbus_assert (_dbus_message_iter_check (real));
00830
00831 retval = FALSE;
00832
00833 spec_type = first_arg_type;
00834 i = 0;
00835
00836
00837
00838
00839 DBUS_VA_COPY (copy_args, var_args);
00840
00841 while (spec_type != DBUS_TYPE_INVALID)
00842 {
00843 msg_type = dbus_message_iter_get_arg_type (iter);
00844
00845 if (msg_type != spec_type)
00846 {
00847 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
00848 "Argument %d is specified to be of type \"%s\", but "
00849 "is actually of type \"%s\"\n", i,
00850 _dbus_type_to_string (spec_type),
00851 _dbus_type_to_string (msg_type));
00852
00853 goto out;
00854 }
00855
00856 if (spec_type == DBUS_TYPE_UNIX_FD)
00857 {
00858 #ifdef HAVE_UNIX_FD_PASSING
00859 DBusBasicValue idx;
00860 int *pfd, nfd;
00861
00862 pfd = va_arg (var_args, int*);
00863 _dbus_assert(pfd);
00864
00865 _dbus_type_reader_read_basic(&real->u.reader, &idx);
00866
00867 if (idx.u32 >= real->message->n_unix_fds)
00868 {
00869 dbus_set_error (error, DBUS_ERROR_INCONSISTENT_MESSAGE,
00870 "Message refers to file descriptor at index %i,"
00871 "but has only %i descriptors attached.\n",
00872 idx.u32,
00873 real->message->n_unix_fds);
00874 goto out;
00875 }
00876
00877 if ((nfd = _dbus_dup(real->message->unix_fds[idx.u32], error)) < 0)
00878 goto out;
00879
00880 *pfd = nfd;
00881 #else
00882 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00883 "Platform does not support file desciptor passing.\n");
00884 goto out;
00885 #endif
00886 }
00887 else if (dbus_type_is_basic (spec_type))
00888 {
00889 DBusBasicValue *ptr;
00890
00891 ptr = va_arg (var_args, DBusBasicValue*);
00892
00893 _dbus_assert (ptr != NULL);
00894
00895 _dbus_type_reader_read_basic (&real->u.reader,
00896 ptr);
00897 }
00898 else if (spec_type == DBUS_TYPE_ARRAY)
00899 {
00900 int element_type;
00901 int spec_element_type;
00902 const DBusBasicValue **ptr;
00903 int *n_elements_p;
00904 DBusTypeReader array;
00905
00906 spec_element_type = va_arg (var_args, int);
00907 element_type = _dbus_type_reader_get_element_type (&real->u.reader);
00908
00909 if (spec_element_type != element_type)
00910 {
00911 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
00912 "Argument %d is specified to be an array of \"%s\", but "
00913 "is actually an array of \"%s\"\n",
00914 i,
00915 _dbus_type_to_string (spec_element_type),
00916 _dbus_type_to_string (element_type));
00917
00918 goto out;
00919 }
00920
00921 if (dbus_type_is_fixed (spec_element_type) &&
00922 element_type != DBUS_TYPE_UNIX_FD)
00923 {
00924 ptr = va_arg (var_args, const DBusBasicValue**);
00925 n_elements_p = va_arg (var_args, int*);
00926
00927 _dbus_assert (ptr != NULL);
00928 _dbus_assert (n_elements_p != NULL);
00929
00930 _dbus_type_reader_recurse (&real->u.reader, &array);
00931
00932 _dbus_type_reader_read_fixed_multi (&array,
00933 (void *) ptr, n_elements_p);
00934 }
00935 else if (_DBUS_TYPE_IS_STRINGLIKE (spec_element_type))
00936 {
00937 char ***str_array_p;
00938 int n_elements;
00939 char **str_array;
00940
00941 str_array_p = va_arg (var_args, char***);
00942 n_elements_p = va_arg (var_args, int*);
00943
00944 _dbus_assert (str_array_p != NULL);
00945 _dbus_assert (n_elements_p != NULL);
00946
00947
00948 _dbus_type_reader_recurse (&real->u.reader, &array);
00949
00950 n_elements = 0;
00951 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
00952 {
00953 ++n_elements;
00954 _dbus_type_reader_next (&array);
00955 }
00956
00957 str_array = dbus_new0 (char*, n_elements + 1);
00958 if (str_array == NULL)
00959 {
00960 _DBUS_SET_OOM (error);
00961 goto out;
00962 }
00963
00964
00965 _dbus_type_reader_recurse (&real->u.reader, &array);
00966
00967 j = 0;
00968 while (j < n_elements)
00969 {
00970 const char *s;
00971 _dbus_type_reader_read_basic (&array,
00972 (void *) &s);
00973
00974 str_array[j] = _dbus_strdup (s);
00975 if (str_array[j] == NULL)
00976 {
00977 dbus_free_string_array (str_array);
00978 _DBUS_SET_OOM (error);
00979 goto out;
00980 }
00981
00982 ++j;
00983
00984 if (!_dbus_type_reader_next (&array))
00985 _dbus_assert (j == n_elements);
00986 }
00987
00988 _dbus_assert (_dbus_type_reader_get_current_type (&array) == DBUS_TYPE_INVALID);
00989 _dbus_assert (j == n_elements);
00990 _dbus_assert (str_array[j] == NULL);
00991
00992 *str_array_p = str_array;
00993 *n_elements_p = n_elements;
00994 }
00995 #ifndef DBUS_DISABLE_CHECKS
00996 else
00997 {
00998 _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now\n",
00999 _DBUS_FUNCTION_NAME);
01000 goto out;
01001 }
01002 #endif
01003 }
01004 #ifndef DBUS_DISABLE_CHECKS
01005 else
01006 {
01007 _dbus_warn ("you can only read arrays and basic types with %s for now\n",
01008 _DBUS_FUNCTION_NAME);
01009 goto out;
01010 }
01011 #endif
01012
01013
01014 i++;
01015
01016 spec_type = va_arg (var_args, int);
01017 if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID)
01018 {
01019 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
01020 "Message has only %d arguments, but more were expected", i);
01021 goto out;
01022 }
01023 }
01024
01025 retval = TRUE;
01026
01027 out:
01028
01029
01030
01031
01032 if (!retval)
01033 {
01034 spec_type = first_arg_type;
01035 j = 0;
01036
01037 while (j < i)
01038 {
01039 if (spec_type == DBUS_TYPE_UNIX_FD)
01040 {
01041 #ifdef HAVE_UNIX_FD_PASSING
01042 int *pfd;
01043
01044 pfd = va_arg (copy_args, int *);
01045 _dbus_assert(pfd);
01046 if (*pfd >= 0)
01047 {
01048 _dbus_close (*pfd, NULL);
01049 *pfd = -1;
01050 }
01051 #endif
01052 }
01053 else if (dbus_type_is_basic (spec_type))
01054 {
01055
01056 va_arg (copy_args, DBusBasicValue *);
01057 }
01058 else if (spec_type == DBUS_TYPE_ARRAY)
01059 {
01060 int spec_element_type;
01061
01062 spec_element_type = va_arg (copy_args, int);
01063 if (dbus_type_is_fixed (spec_element_type))
01064 {
01065
01066 va_arg (copy_args, const DBusBasicValue **);
01067 va_arg (copy_args, int *);
01068 }
01069 else if (_DBUS_TYPE_IS_STRINGLIKE (spec_element_type))
01070 {
01071 char ***str_array_p;
01072
01073 str_array_p = va_arg (copy_args, char ***);
01074
01075 va_arg (copy_args, int *);
01076 _dbus_assert (str_array_p != NULL);
01077 dbus_free_string_array (*str_array_p);
01078 *str_array_p = NULL;
01079 }
01080 }
01081
01082 spec_type = va_arg (copy_args, int);
01083 j++;
01084 }
01085 }
01086
01087 va_end (copy_args);
01088 return retval;
01089 }
01090
01149 dbus_uint32_t
01150 dbus_message_get_serial (DBusMessage *message)
01151 {
01152 _dbus_return_val_if_fail (message != NULL, 0);
01153
01154 return _dbus_header_get_serial (&message->header);
01155 }
01156
01165 dbus_bool_t
01166 dbus_message_set_reply_serial (DBusMessage *message,
01167 dbus_uint32_t reply_serial)
01168 {
01169 _dbus_return_val_if_fail (message != NULL, FALSE);
01170 _dbus_return_val_if_fail (!message->locked, FALSE);
01171 _dbus_return_val_if_fail (reply_serial != 0, FALSE);
01172
01173 return _dbus_header_set_field_basic (&message->header,
01174 DBUS_HEADER_FIELD_REPLY_SERIAL,
01175 DBUS_TYPE_UINT32,
01176 &reply_serial);
01177 }
01178
01185 dbus_uint32_t
01186 dbus_message_get_reply_serial (DBusMessage *message)
01187 {
01188 dbus_uint32_t v_UINT32;
01189
01190 _dbus_return_val_if_fail (message != NULL, 0);
01191
01192 if (_dbus_header_get_field_basic (&message->header,
01193 DBUS_HEADER_FIELD_REPLY_SERIAL,
01194 DBUS_TYPE_UINT32,
01195 &v_UINT32))
01196 return v_UINT32;
01197 else
01198 return 0;
01199 }
01200
01201 static void
01202 dbus_message_finalize (DBusMessage *message)
01203 {
01204 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
01205
01206
01207 _dbus_data_slot_list_free (&message->slot_list);
01208
01209 _dbus_list_foreach (&message->counters,
01210 free_counter, message);
01211 _dbus_list_clear (&message->counters);
01212
01213 _dbus_header_free (&message->header);
01214 _dbus_string_free (&message->body);
01215
01216 #ifdef HAVE_UNIX_FD_PASSING
01217 close_unix_fds(message->unix_fds, &message->n_unix_fds);
01218 dbus_free(message->unix_fds);
01219 #endif
01220
01221 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
01222
01223 dbus_free (message);
01224 }
01225
01226 static DBusMessage*
01227 dbus_message_new_empty_header (void)
01228 {
01229 DBusMessage *message;
01230 dbus_bool_t from_cache;
01231
01232 message = dbus_message_get_cached ();
01233
01234 if (message != NULL)
01235 {
01236 from_cache = TRUE;
01237 }
01238 else
01239 {
01240 from_cache = FALSE;
01241 message = dbus_new0 (DBusMessage, 1);
01242 if (message == NULL)
01243 return NULL;
01244 #ifndef DBUS_DISABLE_CHECKS
01245 message->generation = _dbus_current_generation;
01246 #endif
01247
01248 #ifdef HAVE_UNIX_FD_PASSING
01249 message->unix_fds = NULL;
01250 message->n_unix_fds_allocated = 0;
01251 #endif
01252 }
01253
01254 _dbus_atomic_inc (&message->refcount);
01255
01256 _dbus_message_trace_ref (message, 0, 1, "new_empty_header");
01257
01258 message->locked = FALSE;
01259 #ifndef DBUS_DISABLE_CHECKS
01260 message->in_cache = FALSE;
01261 #endif
01262 message->counters = NULL;
01263 message->size_counter_delta = 0;
01264 message->changed_stamp = 0;
01265
01266 #ifdef HAVE_UNIX_FD_PASSING
01267 message->n_unix_fds = 0;
01268 message->n_unix_fds_allocated = 0;
01269 message->unix_fd_counter_delta = 0;
01270 #endif
01271
01272 if (!from_cache)
01273 _dbus_data_slot_list_init (&message->slot_list);
01274
01275 if (from_cache)
01276 {
01277 _dbus_header_reinit (&message->header);
01278 _dbus_string_set_length (&message->body, 0);
01279 }
01280 else
01281 {
01282 if (!_dbus_header_init (&message->header))
01283 {
01284 dbus_free (message);
01285 return NULL;
01286 }
01287
01288 if (!_dbus_string_init_preallocated (&message->body, 32))
01289 {
01290 _dbus_header_free (&message->header);
01291 dbus_free (message);
01292 return NULL;
01293 }
01294 }
01295
01296 return message;
01297 }
01298
01311 DBusMessage*
01312 dbus_message_new (int message_type)
01313 {
01314 DBusMessage *message;
01315
01316 _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
01317
01318 message = dbus_message_new_empty_header ();
01319 if (message == NULL)
01320 return NULL;
01321
01322 if (!_dbus_header_create (&message->header,
01323 DBUS_COMPILER_BYTE_ORDER,
01324 message_type,
01325 NULL, NULL, NULL, NULL, NULL))
01326 {
01327 dbus_message_unref (message);
01328 return NULL;
01329 }
01330
01331 return message;
01332 }
01333
01355 DBusMessage*
01356 dbus_message_new_method_call (const char *destination,
01357 const char *path,
01358 const char *iface,
01359 const char *method)
01360 {
01361 DBusMessage *message;
01362
01363 _dbus_return_val_if_fail (path != NULL, NULL);
01364 _dbus_return_val_if_fail (method != NULL, NULL);
01365 _dbus_return_val_if_fail (destination == NULL ||
01366 _dbus_check_is_valid_bus_name (destination), NULL);
01367 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
01368 _dbus_return_val_if_fail (iface == NULL ||
01369 _dbus_check_is_valid_interface (iface), NULL);
01370 _dbus_return_val_if_fail (_dbus_check_is_valid_member (method), NULL);
01371
01372 message = dbus_message_new_empty_header ();
01373 if (message == NULL)
01374 return NULL;
01375
01376 if (!_dbus_header_create (&message->header,
01377 DBUS_COMPILER_BYTE_ORDER,
01378 DBUS_MESSAGE_TYPE_METHOD_CALL,
01379 destination, path, iface, method, NULL))
01380 {
01381 dbus_message_unref (message);
01382 return NULL;
01383 }
01384
01385 return message;
01386 }
01387
01395 DBusMessage*
01396 dbus_message_new_method_return (DBusMessage *method_call)
01397 {
01398 DBusMessage *message;
01399 const char *sender;
01400
01401 _dbus_return_val_if_fail (method_call != NULL, NULL);
01402
01403 sender = dbus_message_get_sender (method_call);
01404
01405
01406
01407 message = dbus_message_new_empty_header ();
01408 if (message == NULL)
01409 return NULL;
01410
01411 if (!_dbus_header_create (&message->header,
01412 DBUS_COMPILER_BYTE_ORDER,
01413 DBUS_MESSAGE_TYPE_METHOD_RETURN,
01414 sender, NULL, NULL, NULL, NULL))
01415 {
01416 dbus_message_unref (message);
01417 return NULL;
01418 }
01419
01420 dbus_message_set_no_reply (message, TRUE);
01421
01422 if (!dbus_message_set_reply_serial (message,
01423 dbus_message_get_serial (method_call)))
01424 {
01425 dbus_message_unref (message);
01426 return NULL;
01427 }
01428
01429 return message;
01430 }
01431
01446 DBusMessage*
01447 dbus_message_new_signal (const char *path,
01448 const char *iface,
01449 const char *name)
01450 {
01451 DBusMessage *message;
01452
01453 _dbus_return_val_if_fail (path != NULL, NULL);
01454 _dbus_return_val_if_fail (iface != NULL, NULL);
01455 _dbus_return_val_if_fail (name != NULL, NULL);
01456 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
01457 _dbus_return_val_if_fail (_dbus_check_is_valid_interface (iface), NULL);
01458 _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);
01459
01460 message = dbus_message_new_empty_header ();
01461 if (message == NULL)
01462 return NULL;
01463
01464 if (!_dbus_header_create (&message->header,
01465 DBUS_COMPILER_BYTE_ORDER,
01466 DBUS_MESSAGE_TYPE_SIGNAL,
01467 NULL, path, iface, name, NULL))
01468 {
01469 dbus_message_unref (message);
01470 return NULL;
01471 }
01472
01473 dbus_message_set_no_reply (message, TRUE);
01474
01475 return message;
01476 }
01477
01492 DBusMessage*
01493 dbus_message_new_error (DBusMessage *reply_to,
01494 const char *error_name,
01495 const char *error_message)
01496 {
01497 DBusMessage *message;
01498 const char *sender;
01499 DBusMessageIter iter;
01500
01501 _dbus_return_val_if_fail (reply_to != NULL, NULL);
01502 _dbus_return_val_if_fail (error_name != NULL, NULL);
01503 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
01504
01505 sender = dbus_message_get_sender (reply_to);
01506
01507
01508
01509
01510
01511 message = dbus_message_new_empty_header ();
01512 if (message == NULL)
01513 return NULL;
01514
01515 if (!_dbus_header_create (&message->header,
01516 DBUS_COMPILER_BYTE_ORDER,
01517 DBUS_MESSAGE_TYPE_ERROR,
01518 sender, NULL, NULL, NULL, error_name))
01519 {
01520 dbus_message_unref (message);
01521 return NULL;
01522 }
01523
01524 dbus_message_set_no_reply (message, TRUE);
01525
01526 if (!dbus_message_set_reply_serial (message,
01527 dbus_message_get_serial (reply_to)))
01528 {
01529 dbus_message_unref (message);
01530 return NULL;
01531 }
01532
01533 if (error_message != NULL)
01534 {
01535 dbus_message_iter_init_append (message, &iter);
01536 if (!dbus_message_iter_append_basic (&iter,
01537 DBUS_TYPE_STRING,
01538 &error_message))
01539 {
01540 dbus_message_unref (message);
01541 return NULL;
01542 }
01543 }
01544
01545 return message;
01546 }
01547
01564 DBusMessage*
01565 dbus_message_new_error_printf (DBusMessage *reply_to,
01566 const char *error_name,
01567 const char *error_format,
01568 ...)
01569 {
01570 va_list args;
01571 DBusString str;
01572 DBusMessage *message;
01573
01574 _dbus_return_val_if_fail (reply_to != NULL, NULL);
01575 _dbus_return_val_if_fail (error_name != NULL, NULL);
01576 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
01577
01578 if (!_dbus_string_init (&str))
01579 return NULL;
01580
01581 va_start (args, error_format);
01582
01583 if (_dbus_string_append_printf_valist (&str, error_format, args))
01584 message = dbus_message_new_error (reply_to, error_name,
01585 _dbus_string_get_const_data (&str));
01586 else
01587 message = NULL;
01588
01589 _dbus_string_free (&str);
01590
01591 va_end (args);
01592
01593 return message;
01594 }
01595
01596
01609 DBusMessage *
01610 dbus_message_copy (const DBusMessage *message)
01611 {
01612 DBusMessage *retval;
01613
01614 _dbus_return_val_if_fail (message != NULL, NULL);
01615
01616 retval = dbus_new0 (DBusMessage, 1);
01617 if (retval == NULL)
01618 return NULL;
01619
01620 _dbus_atomic_inc (&retval->refcount);
01621
01622 retval->locked = FALSE;
01623 #ifndef DBUS_DISABLE_CHECKS
01624 retval->generation = message->generation;
01625 #endif
01626
01627 if (!_dbus_header_copy (&message->header, &retval->header))
01628 {
01629 dbus_free (retval);
01630 return NULL;
01631 }
01632
01633 if (!_dbus_string_init_preallocated (&retval->body,
01634 _dbus_string_get_length (&message->body)))
01635 {
01636 _dbus_header_free (&retval->header);
01637 dbus_free (retval);
01638 return NULL;
01639 }
01640
01641 if (!_dbus_string_copy (&message->body, 0,
01642 &retval->body, 0))
01643 goto failed_copy;
01644
01645 #ifdef HAVE_UNIX_FD_PASSING
01646 retval->unix_fds = dbus_new(int, message->n_unix_fds);
01647 if (retval->unix_fds == NULL && message->n_unix_fds > 0)
01648 goto failed_copy;
01649
01650 retval->n_unix_fds_allocated = message->n_unix_fds;
01651
01652 for (retval->n_unix_fds = 0;
01653 retval->n_unix_fds < message->n_unix_fds;
01654 retval->n_unix_fds++)
01655 {
01656 retval->unix_fds[retval->n_unix_fds] = _dbus_dup(message->unix_fds[retval->n_unix_fds], NULL);
01657
01658 if (retval->unix_fds[retval->n_unix_fds] < 0)
01659 goto failed_copy;
01660 }
01661
01662 #endif
01663
01664 _dbus_message_trace_ref (retval, 0, 1, "copy");
01665 return retval;
01666
01667 failed_copy:
01668 _dbus_header_free (&retval->header);
01669 _dbus_string_free (&retval->body);
01670
01671 #ifdef HAVE_UNIX_FD_PASSING
01672 close_unix_fds(retval->unix_fds, &retval->n_unix_fds);
01673 dbus_free(retval->unix_fds);
01674 #endif
01675
01676 dbus_free (retval);
01677
01678 return NULL;
01679 }
01680
01681
01689 DBusMessage *
01690 dbus_message_ref (DBusMessage *message)
01691 {
01692 dbus_int32_t old_refcount;
01693
01694 _dbus_return_val_if_fail (message != NULL, NULL);
01695 _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
01696 _dbus_return_val_if_fail (!message->in_cache, NULL);
01697
01698 old_refcount = _dbus_atomic_inc (&message->refcount);
01699 _dbus_assert (old_refcount >= 1);
01700 _dbus_message_trace_ref (message, old_refcount, old_refcount + 1, "ref");
01701
01702 return message;
01703 }
01704
01712 void
01713 dbus_message_unref (DBusMessage *message)
01714 {
01715 dbus_int32_t old_refcount;
01716
01717 _dbus_return_if_fail (message != NULL);
01718 _dbus_return_if_fail (message->generation == _dbus_current_generation);
01719 _dbus_return_if_fail (!message->in_cache);
01720
01721 old_refcount = _dbus_atomic_dec (&message->refcount);
01722
01723 _dbus_assert (old_refcount >= 1);
01724
01725 _dbus_message_trace_ref (message, old_refcount, old_refcount - 1, "unref");
01726
01727 if (old_refcount == 1)
01728 {
01729
01730 dbus_message_cache_or_finalize (message);
01731 }
01732 }
01733
01744 int
01745 dbus_message_get_type (DBusMessage *message)
01746 {
01747 _dbus_return_val_if_fail (message != NULL, DBUS_MESSAGE_TYPE_INVALID);
01748
01749 return _dbus_header_get_message_type (&message->header);
01750 }
01751
01814 dbus_bool_t
01815 dbus_message_append_args (DBusMessage *message,
01816 int first_arg_type,
01817 ...)
01818 {
01819 dbus_bool_t retval;
01820 va_list var_args;
01821
01822 _dbus_return_val_if_fail (message != NULL, FALSE);
01823
01824 va_start (var_args, first_arg_type);
01825 retval = dbus_message_append_args_valist (message,
01826 first_arg_type,
01827 var_args);
01828 va_end (var_args);
01829
01830 return retval;
01831 }
01832
01846 dbus_bool_t
01847 dbus_message_append_args_valist (DBusMessage *message,
01848 int first_arg_type,
01849 va_list var_args)
01850 {
01851 int type;
01852 DBusMessageIter iter;
01853
01854 _dbus_return_val_if_fail (message != NULL, FALSE);
01855
01856 type = first_arg_type;
01857
01858 dbus_message_iter_init_append (message, &iter);
01859
01860 while (type != DBUS_TYPE_INVALID)
01861 {
01862 if (dbus_type_is_basic (type))
01863 {
01864 const DBusBasicValue *value;
01865 value = va_arg (var_args, const DBusBasicValue*);
01866
01867 if (!dbus_message_iter_append_basic (&iter,
01868 type,
01869 value))
01870 goto failed;
01871 }
01872 else if (type == DBUS_TYPE_ARRAY)
01873 {
01874 int element_type;
01875 DBusMessageIter array;
01876 char buf[2];
01877
01878 element_type = va_arg (var_args, int);
01879
01880 buf[0] = element_type;
01881 buf[1] = '\0';
01882 if (!dbus_message_iter_open_container (&iter,
01883 DBUS_TYPE_ARRAY,
01884 buf,
01885 &array))
01886 goto failed;
01887
01888 if (dbus_type_is_fixed (element_type) &&
01889 element_type != DBUS_TYPE_UNIX_FD)
01890 {
01891 const DBusBasicValue **value;
01892 int n_elements;
01893
01894 value = va_arg (var_args, const DBusBasicValue**);
01895 n_elements = va_arg (var_args, int);
01896
01897 if (!dbus_message_iter_append_fixed_array (&array,
01898 element_type,
01899 value,
01900 n_elements)) {
01901 dbus_message_iter_abandon_container (&iter, &array);
01902 goto failed;
01903 }
01904 }
01905 else if (_DBUS_TYPE_IS_STRINGLIKE (element_type))
01906 {
01907 const char ***value_p;
01908 const char **value;
01909 int n_elements;
01910 int i;
01911
01912 value_p = va_arg (var_args, const char***);
01913 n_elements = va_arg (var_args, int);
01914
01915 value = *value_p;
01916
01917 i = 0;
01918 while (i < n_elements)
01919 {
01920 if (!dbus_message_iter_append_basic (&array,
01921 element_type,
01922 &value[i])) {
01923 dbus_message_iter_abandon_container (&iter, &array);
01924 goto failed;
01925 }
01926 ++i;
01927 }
01928 }
01929 else
01930 {
01931 _dbus_warn ("arrays of %s can't be appended with %s for now\n",
01932 _dbus_type_to_string (element_type),
01933 _DBUS_FUNCTION_NAME);
01934 goto failed;
01935 }
01936
01937 if (!dbus_message_iter_close_container (&iter, &array))
01938 goto failed;
01939 }
01940 #ifndef DBUS_DISABLE_CHECKS
01941 else
01942 {
01943 _dbus_warn ("type %s isn't supported yet in %s\n",
01944 _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
01945 goto failed;
01946 }
01947 #endif
01948
01949 type = va_arg (var_args, int);
01950 }
01951
01952 return TRUE;
01953
01954 failed:
01955 return FALSE;
01956 }
01957
02002 dbus_bool_t
02003 dbus_message_get_args (DBusMessage *message,
02004 DBusError *error,
02005 int first_arg_type,
02006 ...)
02007 {
02008 dbus_bool_t retval;
02009 va_list var_args;
02010
02011 _dbus_return_val_if_fail (message != NULL, FALSE);
02012 _dbus_return_val_if_error_is_set (error, FALSE);
02013
02014 va_start (var_args, first_arg_type);
02015 retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
02016 va_end (var_args);
02017
02018 return retval;
02019 }
02020
02031 dbus_bool_t
02032 dbus_message_get_args_valist (DBusMessage *message,
02033 DBusError *error,
02034 int first_arg_type,
02035 va_list var_args)
02036 {
02037 DBusMessageIter iter;
02038
02039 _dbus_return_val_if_fail (message != NULL, FALSE);
02040 _dbus_return_val_if_error_is_set (error, FALSE);
02041
02042 dbus_message_iter_init (message, &iter);
02043 return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
02044 }
02045
02046 static void
02047 _dbus_message_iter_init_common (DBusMessage *message,
02048 DBusMessageRealIter *real,
02049 int iter_type)
02050 {
02051
02052 _DBUS_STATIC_ASSERT (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
02053 _DBUS_STATIC_ASSERT (_DBUS_ALIGNOF (DBusMessageRealIter) <=
02054 _DBUS_ALIGNOF (DBusMessageIter));
02055
02056
02057 _DBUS_STATIC_ASSERT (sizeof (DBusMessageIter_1_10_0) ==
02058 sizeof (DBusMessageIter));
02059 _DBUS_STATIC_ASSERT (_DBUS_ALIGNOF (DBusMessageIter_1_10_0) ==
02060 _DBUS_ALIGNOF (DBusMessageIter));
02061
02062
02063
02064 _DBUS_STATIC_ASSERT (sizeof (DBusMessageIter) ==
02065 4 * sizeof (void *) + sizeof (dbus_uint32_t) + 9 * sizeof (int));
02066
02067
02068
02069
02070 ensure_byte_order (message);
02071
02072 real->message = message;
02073 real->changed_stamp = message->changed_stamp;
02074 real->iter_type = iter_type;
02075 real->sig_refcount = 0;
02076 }
02077
02100 dbus_bool_t
02101 dbus_message_iter_init (DBusMessage *message,
02102 DBusMessageIter *iter)
02103 {
02104 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02105 const DBusString *type_str;
02106 int type_pos;
02107
02108 _dbus_return_val_if_fail (message != NULL, FALSE);
02109 _dbus_return_val_if_fail (iter != NULL, FALSE);
02110
02111 get_const_signature (&message->header, &type_str, &type_pos);
02112
02113 _dbus_message_iter_init_common (message, real,
02114 DBUS_MESSAGE_ITER_TYPE_READER);
02115
02116 _dbus_type_reader_init (&real->u.reader,
02117 _dbus_header_get_byte_order (&message->header),
02118 type_str, type_pos,
02119 &message->body,
02120 0);
02121
02122 return _dbus_type_reader_get_current_type (&real->u.reader) != DBUS_TYPE_INVALID;
02123 }
02124
02131 dbus_bool_t
02132 dbus_message_iter_has_next (DBusMessageIter *iter)
02133 {
02134 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02135
02136 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
02137 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
02138
02139 return _dbus_type_reader_has_next (&real->u.reader);
02140 }
02141
02150 dbus_bool_t
02151 dbus_message_iter_next (DBusMessageIter *iter)
02152 {
02153 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02154
02155 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
02156 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
02157
02158 return _dbus_type_reader_next (&real->u.reader);
02159 }
02160
02175 int
02176 dbus_message_iter_get_arg_type (DBusMessageIter *iter)
02177 {
02178 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02179
02180 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
02181 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
02182
02183 return _dbus_type_reader_get_current_type (&real->u.reader);
02184 }
02185
02194 int
02195 dbus_message_iter_get_element_type (DBusMessageIter *iter)
02196 {
02197 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02198
02199 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
02200 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
02201 _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
02202
02203 return _dbus_type_reader_get_element_type (&real->u.reader);
02204 }
02205
02231 void
02232 dbus_message_iter_recurse (DBusMessageIter *iter,
02233 DBusMessageIter *sub)
02234 {
02235 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02236 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02237
02238 _dbus_return_if_fail (_dbus_message_iter_check (real));
02239 _dbus_return_if_fail (sub != NULL);
02240
02241 *real_sub = *real;
02242 _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
02243 }
02244
02256 char *
02257 dbus_message_iter_get_signature (DBusMessageIter *iter)
02258 {
02259 const DBusString *sig;
02260 DBusString retstr;
02261 char *ret;
02262 int start, len;
02263 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02264
02265 _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
02266
02267 if (!_dbus_string_init (&retstr))
02268 return NULL;
02269
02270 _dbus_type_reader_get_signature (&real->u.reader, &sig,
02271 &start, &len);
02272 if (!_dbus_string_append_len (&retstr,
02273 _dbus_string_get_const_data (sig) + start,
02274 len))
02275 return NULL;
02276 if (!_dbus_string_steal_data (&retstr, &ret))
02277 return NULL;
02278 _dbus_string_free (&retstr);
02279 return ret;
02280 }
02281
02329 void
02330 dbus_message_iter_get_basic (DBusMessageIter *iter,
02331 void *value)
02332 {
02333 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02334
02335 _dbus_return_if_fail (_dbus_message_iter_check (real));
02336 _dbus_return_if_fail (value != NULL);
02337
02338 if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_UNIX_FD)
02339 {
02340 #ifdef HAVE_UNIX_FD_PASSING
02341 DBusBasicValue idx;
02342
02343 _dbus_type_reader_read_basic(&real->u.reader, &idx);
02344
02345 if (idx.u32 >= real->message->n_unix_fds) {
02346
02347
02348 *((int*) value) = -1;
02349 return;
02350 }
02351
02352 *((int*) value) = _dbus_dup(real->message->unix_fds[idx.u32], NULL);
02353 #else
02354 *((int*) value) = -1;
02355 #endif
02356 }
02357 else
02358 {
02359 _dbus_type_reader_read_basic (&real->u.reader,
02360 value);
02361 }
02362 }
02363
02374 int
02375 dbus_message_iter_get_element_count (DBusMessageIter *iter)
02376 {
02377 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02378 DBusTypeReader array;
02379 int element_type;
02380 int n_elements = 0;
02381
02382 _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
02383 _dbus_return_val_if_fail (_dbus_type_reader_get_current_type (&real->u.reader)
02384 == DBUS_TYPE_ARRAY, 0);
02385
02386 element_type = _dbus_type_reader_get_element_type (&real->u.reader);
02387 _dbus_type_reader_recurse (&real->u.reader, &array);
02388 if (dbus_type_is_fixed (element_type))
02389 {
02390 int alignment = _dbus_type_get_alignment (element_type);
02391 int total_len = _dbus_type_reader_get_array_length (&array);
02392 n_elements = total_len / alignment;
02393 }
02394 else
02395 {
02396 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
02397 {
02398 ++n_elements;
02399 _dbus_type_reader_next (&array);
02400 }
02401 }
02402
02403 return n_elements;
02404 }
02405
02418 int
02419 dbus_message_iter_get_array_len (DBusMessageIter *iter)
02420 {
02421 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02422
02423 _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
02424
02425 return _dbus_type_reader_get_array_length (&real->u.reader);
02426 }
02427
02463 void
02464 dbus_message_iter_get_fixed_array (DBusMessageIter *iter,
02465 void *value,
02466 int *n_elements)
02467 {
02468 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02469 #ifndef DBUS_DISABLE_CHECKS
02470 int subtype = _dbus_type_reader_get_current_type(&real->u.reader);
02471
02472 _dbus_return_if_fail (_dbus_message_iter_check (real));
02473 _dbus_return_if_fail (value != NULL);
02474 _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) ||
02475 (dbus_type_is_fixed (subtype) && subtype != DBUS_TYPE_UNIX_FD));
02476 #endif
02477
02478 _dbus_type_reader_read_fixed_multi (&real->u.reader,
02479 value, n_elements);
02480 }
02481
02493 void
02494 dbus_message_iter_init_append (DBusMessage *message,
02495 DBusMessageIter *iter)
02496 {
02497 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02498
02499 _dbus_return_if_fail (message != NULL);
02500 _dbus_return_if_fail (iter != NULL);
02501
02502 _dbus_message_iter_init_common (message, real,
02503 DBUS_MESSAGE_ITER_TYPE_WRITER);
02504
02505
02506
02507
02508
02509 _dbus_type_writer_init_types_delayed (&real->u.writer,
02510 _dbus_header_get_byte_order (&message->header),
02511 &message->body,
02512 _dbus_string_get_length (&message->body));
02513 }
02514
02523 static dbus_bool_t
02524 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
02525 {
02526 DBusString *str;
02527 const DBusString *current_sig;
02528 int current_sig_pos;
02529
02530 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02531
02532 if (real->u.writer.type_str != NULL)
02533 {
02534 _dbus_assert (real->sig_refcount > 0);
02535 real->sig_refcount += 1;
02536 return TRUE;
02537 }
02538
02539 str = dbus_new (DBusString, 1);
02540 if (str == NULL)
02541 return FALSE;
02542
02543 if (!_dbus_header_get_field_raw (&real->message->header,
02544 DBUS_HEADER_FIELD_SIGNATURE,
02545 ¤t_sig, ¤t_sig_pos))
02546 current_sig = NULL;
02547
02548 if (current_sig)
02549 {
02550 int current_len;
02551
02552 current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
02553 current_sig_pos += 1;
02554
02555 if (!_dbus_string_init_preallocated (str, current_len + 4))
02556 {
02557 dbus_free (str);
02558 return FALSE;
02559 }
02560
02561 if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
02562 str, 0))
02563 {
02564 _dbus_string_free (str);
02565 dbus_free (str);
02566 return FALSE;
02567 }
02568 }
02569 else
02570 {
02571 if (!_dbus_string_init_preallocated (str, 4))
02572 {
02573 dbus_free (str);
02574 return FALSE;
02575 }
02576 }
02577
02578 real->sig_refcount = 1;
02579
02580 _dbus_type_writer_add_types (&real->u.writer,
02581 str, _dbus_string_get_length (str));
02582 return TRUE;
02583 }
02584
02594 static dbus_bool_t
02595 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
02596 {
02597 DBusString *str;
02598 const char *v_STRING;
02599 dbus_bool_t retval;
02600
02601 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02602 _dbus_assert (real->u.writer.type_str != NULL);
02603 _dbus_assert (real->sig_refcount > 0);
02604
02605 real->sig_refcount -= 1;
02606
02607 if (real->sig_refcount > 0)
02608 return TRUE;
02609 _dbus_assert (real->sig_refcount == 0);
02610
02611 retval = TRUE;
02612
02613 str = real->u.writer.type_str;
02614
02615 v_STRING = _dbus_string_get_const_data (str);
02616 if (!_dbus_header_set_field_basic (&real->message->header,
02617 DBUS_HEADER_FIELD_SIGNATURE,
02618 DBUS_TYPE_SIGNATURE,
02619 &v_STRING))
02620 retval = FALSE;
02621
02622 _dbus_type_writer_remove_types (&real->u.writer);
02623 _dbus_string_free (str);
02624 dbus_free (str);
02625
02626 return retval;
02627 }
02628
02636 static void
02637 _dbus_message_iter_abandon_signature (DBusMessageRealIter *real)
02638 {
02639 DBusString *str;
02640
02641 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02642 _dbus_assert (real->u.writer.type_str != NULL);
02643 _dbus_assert (real->sig_refcount > 0);
02644
02645 real->sig_refcount -= 1;
02646
02647 if (real->sig_refcount > 0)
02648 return;
02649 _dbus_assert (real->sig_refcount == 0);
02650
02651 str = real->u.writer.type_str;
02652
02653 _dbus_type_writer_remove_types (&real->u.writer);
02654 _dbus_string_free (str);
02655 dbus_free (str);
02656 }
02657
02658 #ifndef DBUS_DISABLE_CHECKS
02659 static dbus_bool_t
02660 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
02661 {
02662 if (!_dbus_message_iter_check (iter))
02663 return FALSE;
02664
02665 if (iter->message->locked)
02666 {
02667 _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)\n");
02668 return FALSE;
02669 }
02670
02671 return TRUE;
02672 }
02673 #endif
02674
02675 #ifdef HAVE_UNIX_FD_PASSING
02676 static int *
02677 expand_fd_array(DBusMessage *m,
02678 unsigned n)
02679 {
02680 _dbus_assert(m);
02681
02682
02683
02684
02685 if (m->n_unix_fds + n > m->n_unix_fds_allocated)
02686 {
02687 unsigned k;
02688 int *p;
02689
02690
02691 k = (m->n_unix_fds + n) * 2;
02692
02693
02694 if (k < 4)
02695 k = 4;
02696
02697 p = dbus_realloc(m->unix_fds, k * sizeof(int));
02698 if (p == NULL)
02699 return NULL;
02700
02701 m->unix_fds = p;
02702 m->n_unix_fds_allocated = k;
02703 }
02704
02705 return m->unix_fds + m->n_unix_fds;
02706 }
02707 #endif
02708
02728 dbus_bool_t
02729 dbus_message_iter_append_basic (DBusMessageIter *iter,
02730 int type,
02731 const void *value)
02732 {
02733 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02734 dbus_bool_t ret;
02735
02736 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02737 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02738 _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
02739 _dbus_return_val_if_fail (value != NULL, FALSE);
02740
02741 #ifndef DBUS_DISABLE_CHECKS
02742 switch (type)
02743 {
02744 const char * const *string_p;
02745 const dbus_bool_t *bool_p;
02746
02747 case DBUS_TYPE_STRING:
02748 string_p = value;
02749 _dbus_return_val_if_fail (_dbus_check_is_valid_utf8 (*string_p), FALSE);
02750 break;
02751
02752 case DBUS_TYPE_OBJECT_PATH:
02753 string_p = value;
02754 _dbus_return_val_if_fail (_dbus_check_is_valid_path (*string_p), FALSE);
02755 break;
02756
02757 case DBUS_TYPE_SIGNATURE:
02758 string_p = value;
02759 _dbus_return_val_if_fail (_dbus_check_is_valid_signature (*string_p), FALSE);
02760 break;
02761
02762 case DBUS_TYPE_BOOLEAN:
02763 bool_p = value;
02764 _dbus_return_val_if_fail (*bool_p == 0 || *bool_p == 1, FALSE);
02765 break;
02766
02767 default:
02768 {
02769
02770 }
02771 }
02772 #endif
02773
02774 if (!_dbus_message_iter_open_signature (real))
02775 return FALSE;
02776
02777 if (type == DBUS_TYPE_UNIX_FD)
02778 {
02779 #ifdef HAVE_UNIX_FD_PASSING
02780 int *fds;
02781 dbus_uint32_t u;
02782
02783
02784 if (!(fds = expand_fd_array(real->message, 1)))
02785 return FALSE;
02786
02787 *fds = _dbus_dup(*(int*) value, NULL);
02788 if (*fds < 0)
02789 return FALSE;
02790
02791 u = real->message->n_unix_fds;
02792
02793
02794 if (!(ret = _dbus_type_writer_write_basic (&real->u.writer, DBUS_TYPE_UNIX_FD, &u))) {
02795 _dbus_close(*fds, NULL);
02796 return FALSE;
02797 }
02798
02799 real->message->n_unix_fds += 1;
02800 u += 1;
02801
02802
02803 ret = _dbus_header_set_field_basic (&real->message->header,
02804 DBUS_HEADER_FIELD_UNIX_FDS,
02805 DBUS_TYPE_UINT32,
02806 &u);
02807
02808
02809
02810
02811
02812
02813 #else
02814 ret = FALSE;
02815 #endif
02816 }
02817 else
02818 {
02819 ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
02820 }
02821
02822 if (!_dbus_message_iter_close_signature (real))
02823 ret = FALSE;
02824
02825 return ret;
02826 }
02827
02863 dbus_bool_t
02864 dbus_message_iter_append_fixed_array (DBusMessageIter *iter,
02865 int element_type,
02866 const void *value,
02867 int n_elements)
02868 {
02869 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02870 dbus_bool_t ret;
02871
02872 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02873 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02874 _dbus_return_val_if_fail (dbus_type_is_fixed (element_type) && element_type != DBUS_TYPE_UNIX_FD, FALSE);
02875 _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
02876 _dbus_return_val_if_fail (value != NULL, FALSE);
02877 _dbus_return_val_if_fail (n_elements >= 0, FALSE);
02878 _dbus_return_val_if_fail (n_elements <=
02879 DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type),
02880 FALSE);
02881
02882 #ifndef DBUS_DISABLE_CHECKS
02883 if (element_type == DBUS_TYPE_BOOLEAN)
02884 {
02885 const dbus_bool_t * const *bools = value;
02886 int i;
02887
02888 for (i = 0; i < n_elements; i++)
02889 {
02890 _dbus_return_val_if_fail ((*bools)[i] == 0 || (*bools)[i] == 1, FALSE);
02891 }
02892 }
02893 #endif
02894
02895 ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
02896
02897 return ret;
02898 }
02899
02921 dbus_bool_t
02922 dbus_message_iter_open_container (DBusMessageIter *iter,
02923 int type,
02924 const char *contained_signature,
02925 DBusMessageIter *sub)
02926 {
02927 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02928 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02929 DBusString contained_str;
02930
02931 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02932 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02933 _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
02934 _dbus_return_val_if_fail (sub != NULL, FALSE);
02935 _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
02936 contained_signature == NULL) ||
02937 (type == DBUS_TYPE_DICT_ENTRY &&
02938 contained_signature == NULL) ||
02939 (type == DBUS_TYPE_VARIANT &&
02940 contained_signature != NULL) ||
02941 (type == DBUS_TYPE_ARRAY &&
02942 contained_signature != NULL), FALSE);
02943
02944
02945
02946
02947
02948 _dbus_return_val_if_fail ((type == DBUS_TYPE_ARRAY && contained_signature && *contained_signature == DBUS_DICT_ENTRY_BEGIN_CHAR) ||
02949 (contained_signature == NULL ||
02950 _dbus_check_is_valid_signature (contained_signature)),
02951 FALSE);
02952
02953 if (!_dbus_message_iter_open_signature (real))
02954 return FALSE;
02955
02956 *real_sub = *real;
02957
02958 if (contained_signature != NULL)
02959 {
02960 _dbus_string_init_const (&contained_str, contained_signature);
02961
02962 return _dbus_type_writer_recurse (&real->u.writer,
02963 type,
02964 &contained_str, 0,
02965 &real_sub->u.writer);
02966 }
02967 else
02968 {
02969 return _dbus_type_writer_recurse (&real->u.writer,
02970 type,
02971 NULL, 0,
02972 &real_sub->u.writer);
02973 }
02974 }
02975
02976
02990 dbus_bool_t
02991 dbus_message_iter_close_container (DBusMessageIter *iter,
02992 DBusMessageIter *sub)
02993 {
02994 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02995 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02996 dbus_bool_t ret;
02997
02998 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02999 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
03000 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
03001 _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
03002
03003 ret = _dbus_type_writer_unrecurse (&real->u.writer,
03004 &real_sub->u.writer);
03005
03006 if (!_dbus_message_iter_close_signature (real))
03007 ret = FALSE;
03008
03009 return ret;
03010 }
03011
03023 void
03024 dbus_message_iter_abandon_container (DBusMessageIter *iter,
03025 DBusMessageIter *sub)
03026 {
03027 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03028 #ifndef DBUS_DISABLE_CHECKS
03029 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
03030
03031 _dbus_return_if_fail (_dbus_message_iter_append_check (real));
03032 _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
03033 _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
03034 _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
03035 #endif
03036
03037 _dbus_message_iter_abandon_signature (real);
03038 }
03039
03056 void
03057 dbus_message_set_no_reply (DBusMessage *message,
03058 dbus_bool_t no_reply)
03059 {
03060 _dbus_return_if_fail (message != NULL);
03061 _dbus_return_if_fail (!message->locked);
03062
03063 _dbus_header_toggle_flag (&message->header,
03064 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED,
03065 no_reply);
03066 }
03067
03075 dbus_bool_t
03076 dbus_message_get_no_reply (DBusMessage *message)
03077 {
03078 _dbus_return_val_if_fail (message != NULL, FALSE);
03079
03080 return _dbus_header_get_flag (&message->header,
03081 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED);
03082 }
03083
03098 void
03099 dbus_message_set_auto_start (DBusMessage *message,
03100 dbus_bool_t auto_start)
03101 {
03102 _dbus_return_if_fail (message != NULL);
03103 _dbus_return_if_fail (!message->locked);
03104
03105 _dbus_header_toggle_flag (&message->header,
03106 DBUS_HEADER_FLAG_NO_AUTO_START,
03107 !auto_start);
03108 }
03109
03117 dbus_bool_t
03118 dbus_message_get_auto_start (DBusMessage *message)
03119 {
03120 _dbus_return_val_if_fail (message != NULL, FALSE);
03121
03122 return !_dbus_header_get_flag (&message->header,
03123 DBUS_HEADER_FLAG_NO_AUTO_START);
03124 }
03125
03126
03139 dbus_bool_t
03140 dbus_message_set_path (DBusMessage *message,
03141 const char *object_path)
03142 {
03143 _dbus_return_val_if_fail (message != NULL, FALSE);
03144 _dbus_return_val_if_fail (!message->locked, FALSE);
03145 _dbus_return_val_if_fail (object_path == NULL ||
03146 _dbus_check_is_valid_path (object_path),
03147 FALSE);
03148
03149 return set_or_delete_string_field (message,
03150 DBUS_HEADER_FIELD_PATH,
03151 DBUS_TYPE_OBJECT_PATH,
03152 object_path);
03153 }
03154
03168 const char*
03169 dbus_message_get_path (DBusMessage *message)
03170 {
03171 const char *v;
03172
03173 _dbus_return_val_if_fail (message != NULL, NULL);
03174
03175 v = NULL;
03176 _dbus_header_get_field_basic (&message->header,
03177 DBUS_HEADER_FIELD_PATH,
03178 DBUS_TYPE_OBJECT_PATH,
03179 (void *) &v);
03180 return v;
03181 }
03182
03192 dbus_bool_t
03193 dbus_message_has_path (DBusMessage *message,
03194 const char *path)
03195 {
03196 const char *msg_path;
03197 msg_path = dbus_message_get_path (message);
03198
03199 if (msg_path == NULL)
03200 {
03201 if (path == NULL)
03202 return TRUE;
03203 else
03204 return FALSE;
03205 }
03206
03207 if (path == NULL)
03208 return FALSE;
03209
03210 if (strcmp (msg_path, path) == 0)
03211 return TRUE;
03212
03213 return FALSE;
03214 }
03215
03236 dbus_bool_t
03237 dbus_message_get_path_decomposed (DBusMessage *message,
03238 char ***path)
03239 {
03240 const char *v;
03241
03242 _dbus_return_val_if_fail (message != NULL, FALSE);
03243 _dbus_return_val_if_fail (path != NULL, FALSE);
03244
03245 *path = NULL;
03246
03247 v = dbus_message_get_path (message);
03248 if (v != NULL)
03249 {
03250 if (!_dbus_decompose_path (v, strlen (v),
03251 path, NULL))
03252 return FALSE;
03253 }
03254 return TRUE;
03255 }
03256
03270 dbus_bool_t
03271 dbus_message_set_interface (DBusMessage *message,
03272 const char *iface)
03273 {
03274 _dbus_return_val_if_fail (message != NULL, FALSE);
03275 _dbus_return_val_if_fail (!message->locked, FALSE);
03276 _dbus_return_val_if_fail (iface == NULL ||
03277 _dbus_check_is_valid_interface (iface),
03278 FALSE);
03279
03280 return set_or_delete_string_field (message,
03281 DBUS_HEADER_FIELD_INTERFACE,
03282 DBUS_TYPE_STRING,
03283 iface);
03284 }
03285
03299 const char*
03300 dbus_message_get_interface (DBusMessage *message)
03301 {
03302 const char *v;
03303
03304 _dbus_return_val_if_fail (message != NULL, NULL);
03305
03306 v = NULL;
03307 _dbus_header_get_field_basic (&message->header,
03308 DBUS_HEADER_FIELD_INTERFACE,
03309 DBUS_TYPE_STRING,
03310 (void *) &v);
03311 return v;
03312 }
03313
03321 dbus_bool_t
03322 dbus_message_has_interface (DBusMessage *message,
03323 const char *iface)
03324 {
03325 const char *msg_interface;
03326 msg_interface = dbus_message_get_interface (message);
03327
03328 if (msg_interface == NULL)
03329 {
03330 if (iface == NULL)
03331 return TRUE;
03332 else
03333 return FALSE;
03334 }
03335
03336 if (iface == NULL)
03337 return FALSE;
03338
03339 if (strcmp (msg_interface, iface) == 0)
03340 return TRUE;
03341
03342 return FALSE;
03343
03344 }
03345
03358 dbus_bool_t
03359 dbus_message_set_member (DBusMessage *message,
03360 const char *member)
03361 {
03362 _dbus_return_val_if_fail (message != NULL, FALSE);
03363 _dbus_return_val_if_fail (!message->locked, FALSE);
03364 _dbus_return_val_if_fail (member == NULL ||
03365 _dbus_check_is_valid_member (member),
03366 FALSE);
03367
03368 return set_or_delete_string_field (message,
03369 DBUS_HEADER_FIELD_MEMBER,
03370 DBUS_TYPE_STRING,
03371 member);
03372 }
03373
03385 const char*
03386 dbus_message_get_member (DBusMessage *message)
03387 {
03388 const char *v;
03389
03390 _dbus_return_val_if_fail (message != NULL, NULL);
03391
03392 v = NULL;
03393 _dbus_header_get_field_basic (&message->header,
03394 DBUS_HEADER_FIELD_MEMBER,
03395 DBUS_TYPE_STRING,
03396 (void *) &v);
03397 return v;
03398 }
03399
03407 dbus_bool_t
03408 dbus_message_has_member (DBusMessage *message,
03409 const char *member)
03410 {
03411 const char *msg_member;
03412 msg_member = dbus_message_get_member (message);
03413
03414 if (msg_member == NULL)
03415 {
03416 if (member == NULL)
03417 return TRUE;
03418 else
03419 return FALSE;
03420 }
03421
03422 if (member == NULL)
03423 return FALSE;
03424
03425 if (strcmp (msg_member, member) == 0)
03426 return TRUE;
03427
03428 return FALSE;
03429
03430 }
03431
03443 dbus_bool_t
03444 dbus_message_set_error_name (DBusMessage *message,
03445 const char *error_name)
03446 {
03447 _dbus_return_val_if_fail (message != NULL, FALSE);
03448 _dbus_return_val_if_fail (!message->locked, FALSE);
03449 _dbus_return_val_if_fail (error_name == NULL ||
03450 _dbus_check_is_valid_error_name (error_name),
03451 FALSE);
03452
03453 return set_or_delete_string_field (message,
03454 DBUS_HEADER_FIELD_ERROR_NAME,
03455 DBUS_TYPE_STRING,
03456 error_name);
03457 }
03458
03469 const char*
03470 dbus_message_get_error_name (DBusMessage *message)
03471 {
03472 const char *v;
03473
03474 _dbus_return_val_if_fail (message != NULL, NULL);
03475
03476 v = NULL;
03477 _dbus_header_get_field_basic (&message->header,
03478 DBUS_HEADER_FIELD_ERROR_NAME,
03479 DBUS_TYPE_STRING,
03480 (void *) &v);
03481 return v;
03482 }
03483
03497 dbus_bool_t
03498 dbus_message_set_destination (DBusMessage *message,
03499 const char *destination)
03500 {
03501 _dbus_return_val_if_fail (message != NULL, FALSE);
03502 _dbus_return_val_if_fail (!message->locked, FALSE);
03503 _dbus_return_val_if_fail (destination == NULL ||
03504 _dbus_check_is_valid_bus_name (destination),
03505 FALSE);
03506
03507 return set_or_delete_string_field (message,
03508 DBUS_HEADER_FIELD_DESTINATION,
03509 DBUS_TYPE_STRING,
03510 destination);
03511 }
03512
03522 const char*
03523 dbus_message_get_destination (DBusMessage *message)
03524 {
03525 const char *v;
03526
03527 _dbus_return_val_if_fail (message != NULL, NULL);
03528
03529 v = NULL;
03530 _dbus_header_get_field_basic (&message->header,
03531 DBUS_HEADER_FIELD_DESTINATION,
03532 DBUS_TYPE_STRING,
03533 (void *) &v);
03534 return v;
03535 }
03536
03551 dbus_bool_t
03552 dbus_message_set_sender (DBusMessage *message,
03553 const char *sender)
03554 {
03555 _dbus_return_val_if_fail (message != NULL, FALSE);
03556 _dbus_return_val_if_fail (!message->locked, FALSE);
03557 _dbus_return_val_if_fail (sender == NULL ||
03558 _dbus_check_is_valid_bus_name (sender),
03559 FALSE);
03560
03561 return set_or_delete_string_field (message,
03562 DBUS_HEADER_FIELD_SENDER,
03563 DBUS_TYPE_STRING,
03564 sender);
03565 }
03566
03582 const char*
03583 dbus_message_get_sender (DBusMessage *message)
03584 {
03585 const char *v;
03586
03587 _dbus_return_val_if_fail (message != NULL, NULL);
03588
03589 v = NULL;
03590 _dbus_header_get_field_basic (&message->header,
03591 DBUS_HEADER_FIELD_SENDER,
03592 DBUS_TYPE_STRING,
03593 (void *) &v);
03594 return v;
03595 }
03596
03615 const char*
03616 dbus_message_get_signature (DBusMessage *message)
03617 {
03618 const DBusString *type_str;
03619 int type_pos;
03620
03621 _dbus_return_val_if_fail (message != NULL, NULL);
03622
03623 get_const_signature (&message->header, &type_str, &type_pos);
03624
03625 return _dbus_string_get_const_data_len (type_str, type_pos, 0);
03626 }
03627
03628 static dbus_bool_t
03629 _dbus_message_has_type_interface_member (DBusMessage *message,
03630 int type,
03631 const char *iface,
03632 const char *member)
03633 {
03634 const char *n;
03635
03636 _dbus_assert (message != NULL);
03637 _dbus_assert (iface != NULL);
03638 _dbus_assert (member != NULL);
03639
03640 if (dbus_message_get_type (message) != type)
03641 return FALSE;
03642
03643
03644
03645
03646
03647 n = dbus_message_get_member (message);
03648
03649 if (n && strcmp (n, member) == 0)
03650 {
03651 n = dbus_message_get_interface (message);
03652
03653 if (n == NULL || strcmp (n, iface) == 0)
03654 return TRUE;
03655 }
03656
03657 return FALSE;
03658 }
03659
03674 dbus_bool_t
03675 dbus_message_is_method_call (DBusMessage *message,
03676 const char *iface,
03677 const char *method)
03678 {
03679 _dbus_return_val_if_fail (message != NULL, FALSE);
03680 _dbus_return_val_if_fail (iface != NULL, FALSE);
03681 _dbus_return_val_if_fail (method != NULL, FALSE);
03682
03683
03684
03685
03686 return _dbus_message_has_type_interface_member (message,
03687 DBUS_MESSAGE_TYPE_METHOD_CALL,
03688 iface, method);
03689 }
03690
03702 dbus_bool_t
03703 dbus_message_is_signal (DBusMessage *message,
03704 const char *iface,
03705 const char *signal_name)
03706 {
03707 _dbus_return_val_if_fail (message != NULL, FALSE);
03708 _dbus_return_val_if_fail (iface != NULL, FALSE);
03709 _dbus_return_val_if_fail (signal_name != NULL, FALSE);
03710
03711
03712
03713
03714 return _dbus_message_has_type_interface_member (message,
03715 DBUS_MESSAGE_TYPE_SIGNAL,
03716 iface, signal_name);
03717 }
03718
03729 dbus_bool_t
03730 dbus_message_is_error (DBusMessage *message,
03731 const char *error_name)
03732 {
03733 const char *n;
03734
03735 _dbus_return_val_if_fail (message != NULL, FALSE);
03736 _dbus_return_val_if_fail (error_name != NULL, FALSE);
03737
03738
03739
03740
03741 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
03742 return FALSE;
03743
03744 n = dbus_message_get_error_name (message);
03745
03746 if (n && strcmp (n, error_name) == 0)
03747 return TRUE;
03748 else
03749 return FALSE;
03750 }
03751
03762 dbus_bool_t
03763 dbus_message_has_destination (DBusMessage *message,
03764 const char *name)
03765 {
03766 const char *s;
03767
03768 _dbus_return_val_if_fail (message != NULL, FALSE);
03769 _dbus_return_val_if_fail (name != NULL, FALSE);
03770
03771
03772
03773
03774 s = dbus_message_get_destination (message);
03775
03776 if (s && strcmp (s, name) == 0)
03777 return TRUE;
03778 else
03779 return FALSE;
03780 }
03781
03797 dbus_bool_t
03798 dbus_message_has_sender (DBusMessage *message,
03799 const char *name)
03800 {
03801 const char *s;
03802
03803 _dbus_return_val_if_fail (message != NULL, FALSE);
03804 _dbus_return_val_if_fail (name != NULL, FALSE);
03805
03806
03807
03808
03809 s = dbus_message_get_sender (message);
03810
03811 if (s && strcmp (s, name) == 0)
03812 return TRUE;
03813 else
03814 return FALSE;
03815 }
03816
03826 dbus_bool_t
03827 dbus_message_has_signature (DBusMessage *message,
03828 const char *signature)
03829 {
03830 const char *s;
03831
03832 _dbus_return_val_if_fail (message != NULL, FALSE);
03833 _dbus_return_val_if_fail (signature != NULL, FALSE);
03834
03835
03836
03837
03838 s = dbus_message_get_signature (message);
03839
03840 if (s && strcmp (s, signature) == 0)
03841 return TRUE;
03842 else
03843 return FALSE;
03844 }
03845
03868 dbus_bool_t
03869 dbus_set_error_from_message (DBusError *error,
03870 DBusMessage *message)
03871 {
03872 const char *str;
03873
03874 _dbus_return_val_if_fail (message != NULL, FALSE);
03875 _dbus_return_val_if_error_is_set (error, FALSE);
03876
03877 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
03878 return FALSE;
03879
03880 str = NULL;
03881 dbus_message_get_args (message, NULL,
03882 DBUS_TYPE_STRING, &str,
03883 DBUS_TYPE_INVALID);
03884
03885 dbus_set_error (error, dbus_message_get_error_name (message),
03886 str ? "%s" : NULL, str);
03887
03888 return TRUE;
03889 }
03890
03897 dbus_bool_t
03898 dbus_message_contains_unix_fds(DBusMessage *message)
03899 {
03900 #ifdef HAVE_UNIX_FD_PASSING
03901 _dbus_assert(message);
03902
03903 return message->n_unix_fds > 0;
03904 #else
03905 return FALSE;
03906 #endif
03907 }
03908
03927 #define INITIAL_LOADER_DATA_LEN 32
03928
03935 DBusMessageLoader*
03936 _dbus_message_loader_new (void)
03937 {
03938 DBusMessageLoader *loader;
03939
03940 loader = dbus_new0 (DBusMessageLoader, 1);
03941 if (loader == NULL)
03942 return NULL;
03943
03944 loader->refcount = 1;
03945
03946 loader->corrupted = FALSE;
03947 loader->corruption_reason = DBUS_VALID;
03948
03949
03950 loader->max_message_size = DBUS_MAXIMUM_MESSAGE_LENGTH;
03951
03952
03953
03954
03955
03956 loader->max_message_unix_fds = DBUS_DEFAULT_MESSAGE_UNIX_FDS;
03957
03958 if (!_dbus_string_init (&loader->data))
03959 {
03960 dbus_free (loader);
03961 return NULL;
03962 }
03963
03964
03965 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
03966 _dbus_string_set_length (&loader->data, 0);
03967
03968 #ifdef HAVE_UNIX_FD_PASSING
03969 loader->unix_fds = NULL;
03970 loader->n_unix_fds = loader->n_unix_fds_allocated = 0;
03971 loader->unix_fds_outstanding = FALSE;
03972 #endif
03973
03974 return loader;
03975 }
03976
03983 DBusMessageLoader *
03984 _dbus_message_loader_ref (DBusMessageLoader *loader)
03985 {
03986 loader->refcount += 1;
03987
03988 return loader;
03989 }
03990
03997 void
03998 _dbus_message_loader_unref (DBusMessageLoader *loader)
03999 {
04000 loader->refcount -= 1;
04001 if (loader->refcount == 0)
04002 {
04003 #ifdef HAVE_UNIX_FD_PASSING
04004 close_unix_fds(loader->unix_fds, &loader->n_unix_fds);
04005 dbus_free(loader->unix_fds);
04006 #endif
04007 _dbus_list_foreach (&loader->messages,
04008 (DBusForeachFunction) dbus_message_unref,
04009 NULL);
04010 _dbus_list_clear (&loader->messages);
04011 _dbus_string_free (&loader->data);
04012 dbus_free (loader);
04013 }
04014 }
04015
04034 void
04035 _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
04036 DBusString **buffer)
04037 {
04038 _dbus_assert (!loader->buffer_outstanding);
04039
04040 *buffer = &loader->data;
04041
04042 loader->buffer_outstanding = TRUE;
04043 }
04044
04054 void
04055 _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
04056 DBusString *buffer)
04057 {
04058 _dbus_assert (loader->buffer_outstanding);
04059 _dbus_assert (buffer == &loader->data);
04060
04061 loader->buffer_outstanding = FALSE;
04062 }
04063
04074 dbus_bool_t
04075 _dbus_message_loader_get_unix_fds(DBusMessageLoader *loader,
04076 int **fds,
04077 unsigned *max_n_fds)
04078 {
04079 #ifdef HAVE_UNIX_FD_PASSING
04080 _dbus_assert (!loader->unix_fds_outstanding);
04081
04082
04083
04084
04085
04086
04087
04088
04089
04090 if (loader->n_unix_fds_allocated < loader->max_message_unix_fds)
04091 {
04092 int *a = dbus_realloc(loader->unix_fds,
04093 loader->max_message_unix_fds * sizeof(loader->unix_fds[0]));
04094
04095 if (!a)
04096 return FALSE;
04097
04098 loader->unix_fds = a;
04099 loader->n_unix_fds_allocated = loader->max_message_unix_fds;
04100 }
04101
04102 *fds = loader->unix_fds + loader->n_unix_fds;
04103 *max_n_fds = loader->n_unix_fds_allocated - loader->n_unix_fds;
04104
04105 loader->unix_fds_outstanding = TRUE;
04106 return TRUE;
04107 #else
04108 _dbus_assert_not_reached("Platform doesn't support unix fd passing");
04109 return FALSE;
04110 #endif
04111 }
04112
04123 void
04124 _dbus_message_loader_return_unix_fds(DBusMessageLoader *loader,
04125 int *fds,
04126 unsigned n_fds)
04127 {
04128 #ifdef HAVE_UNIX_FD_PASSING
04129 _dbus_assert(loader->unix_fds_outstanding);
04130 _dbus_assert(loader->unix_fds + loader->n_unix_fds == fds);
04131 _dbus_assert(loader->n_unix_fds + n_fds <= loader->n_unix_fds_allocated);
04132
04133 loader->n_unix_fds += n_fds;
04134 loader->unix_fds_outstanding = FALSE;
04135
04136 if (n_fds && loader->unix_fds_change)
04137 loader->unix_fds_change (loader->unix_fds_change_data);
04138 #else
04139 _dbus_assert_not_reached("Platform doesn't support unix fd passing");
04140 #endif
04141 }
04142
04143
04144
04145
04146
04147
04148
04149
04150
04151
04152
04153
04154
04155
04156
04157
04158
04159
04160
04161
04162
04163
04164
04165
04166
04167
04168
04169 static dbus_bool_t
04170 load_message (DBusMessageLoader *loader,
04171 DBusMessage *message,
04172 int byte_order,
04173 int fields_array_len,
04174 int header_len,
04175 int body_len)
04176 {
04177 dbus_bool_t oom;
04178 DBusValidity validity;
04179 const DBusString *type_str;
04180 int type_pos;
04181 DBusValidationMode mode;
04182 dbus_uint32_t n_unix_fds = 0;
04183
04184 mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
04185
04186 oom = FALSE;
04187
04188 #if 0
04189 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len );
04190 #endif
04191
04192
04193 _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
04194 _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
04195
04196 if (!_dbus_header_load (&message->header,
04197 mode,
04198 &validity,
04199 byte_order,
04200 fields_array_len,
04201 header_len,
04202 body_len,
04203 &loader->data, 0,
04204 _dbus_string_get_length (&loader->data)))
04205 {
04206 _dbus_verbose ("Failed to load header for new message code %d\n", validity);
04207
04208
04209
04210 _dbus_assert (validity != DBUS_VALID);
04211
04212 if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
04213 oom = TRUE;
04214 else
04215 {
04216 loader->corrupted = TRUE;
04217 loader->corruption_reason = validity;
04218 }
04219 goto failed;
04220 }
04221
04222 _dbus_assert (validity == DBUS_VALID);
04223
04224
04225 if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
04226 {
04227 get_const_signature (&message->header, &type_str, &type_pos);
04228
04229
04230
04231
04232 validity = _dbus_validate_body_with_reason (type_str,
04233 type_pos,
04234 byte_order,
04235 NULL,
04236 &loader->data,
04237 header_len,
04238 body_len);
04239 if (validity != DBUS_VALID)
04240 {
04241 _dbus_verbose ("Failed to validate message body code %d\n", validity);
04242
04243 loader->corrupted = TRUE;
04244 loader->corruption_reason = validity;
04245
04246 goto failed;
04247 }
04248 }
04249
04250
04251 _dbus_header_get_field_basic(&message->header,
04252 DBUS_HEADER_FIELD_UNIX_FDS,
04253 DBUS_TYPE_UINT32,
04254 &n_unix_fds);
04255
04256 #ifdef HAVE_UNIX_FD_PASSING
04257
04258 if (n_unix_fds > loader->n_unix_fds)
04259 {
04260 _dbus_verbose("Message contains references to more unix fds than were sent %u != %u\n",
04261 n_unix_fds, loader->n_unix_fds);
04262
04263 loader->corrupted = TRUE;
04264 loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
04265 goto failed;
04266 }
04267
04268
04269
04270 dbus_free(message->unix_fds);
04271
04272 if (n_unix_fds > 0)
04273 {
04274 message->unix_fds = _dbus_memdup(loader->unix_fds, n_unix_fds * sizeof(message->unix_fds[0]));
04275 if (message->unix_fds == NULL)
04276 {
04277 _dbus_verbose ("Failed to allocate file descriptor array\n");
04278 oom = TRUE;
04279 goto failed;
04280 }
04281
04282 message->n_unix_fds_allocated = message->n_unix_fds = n_unix_fds;
04283 loader->n_unix_fds -= n_unix_fds;
04284 memmove (loader->unix_fds, loader->unix_fds + n_unix_fds, loader->n_unix_fds * sizeof (loader->unix_fds[0]));
04285
04286 if (loader->unix_fds_change)
04287 loader->unix_fds_change (loader->unix_fds_change_data);
04288 }
04289 else
04290 message->unix_fds = NULL;
04291
04292 #else
04293
04294 if (n_unix_fds > 0)
04295 {
04296 _dbus_verbose ("Hmm, message claims to come with file descriptors "
04297 "but that's not supported on our platform, disconnecting.\n");
04298
04299 loader->corrupted = TRUE;
04300 loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
04301 goto failed;
04302 }
04303
04304 #endif
04305
04306
04307
04308 if (!_dbus_list_append (&loader->messages, message))
04309 {
04310 _dbus_verbose ("Failed to append new message to loader queue\n");
04311 oom = TRUE;
04312 goto failed;
04313 }
04314
04315 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
04316 _dbus_assert (_dbus_string_get_length (&loader->data) >=
04317 (header_len + body_len));
04318
04319 if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
04320 {
04321 _dbus_verbose ("Failed to move body into new message\n");
04322 oom = TRUE;
04323 goto failed;
04324 }
04325
04326 _dbus_string_delete (&loader->data, 0, header_len + body_len);
04327
04328
04329 _dbus_string_compact (&loader->data, 2048);
04330
04331 _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
04332 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
04333
04334 _dbus_verbose ("Loaded message %p\n", message);
04335
04336 _dbus_assert (!oom);
04337 _dbus_assert (!loader->corrupted);
04338 _dbus_assert (loader->messages != NULL);
04339 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
04340
04341 return TRUE;
04342
04343 failed:
04344
04345
04346
04347
04348 _dbus_list_remove_last (&loader->messages, message);
04349
04350 if (oom)
04351 _dbus_assert (!loader->corrupted);
04352 else
04353 _dbus_assert (loader->corrupted);
04354
04355 _dbus_verbose_bytes_of_string (&loader->data, 0, _dbus_string_get_length (&loader->data));
04356
04357 return FALSE;
04358 }
04359
04374 dbus_bool_t
04375 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
04376 {
04377 while (!loader->corrupted &&
04378 _dbus_string_get_length (&loader->data) >= DBUS_MINIMUM_HEADER_SIZE)
04379 {
04380 DBusValidity validity;
04381 int byte_order, fields_array_len, header_len, body_len;
04382
04383 if (_dbus_header_have_message_untrusted (loader->max_message_size,
04384 &validity,
04385 &byte_order,
04386 &fields_array_len,
04387 &header_len,
04388 &body_len,
04389 &loader->data, 0,
04390 _dbus_string_get_length (&loader->data)))
04391 {
04392 DBusMessage *message;
04393
04394 _dbus_assert (validity == DBUS_VALID);
04395
04396 message = dbus_message_new_empty_header ();
04397 if (message == NULL)
04398 return FALSE;
04399
04400 if (!load_message (loader, message,
04401 byte_order, fields_array_len,
04402 header_len, body_len))
04403 {
04404 dbus_message_unref (message);
04405
04406
04407
04408 return loader->corrupted;
04409 }
04410
04411 _dbus_assert (loader->messages != NULL);
04412 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
04413 }
04414 else
04415 {
04416 _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
04417 validity);
04418 if (validity != DBUS_VALID)
04419 {
04420 loader->corrupted = TRUE;
04421 loader->corruption_reason = validity;
04422 }
04423 return TRUE;
04424 }
04425 }
04426
04427 return TRUE;
04428 }
04429
04437 DBusMessage*
04438 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
04439 {
04440 if (loader->messages)
04441 return loader->messages->data;
04442 else
04443 return NULL;
04444 }
04445
04454 DBusMessage*
04455 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
04456 {
04457 return _dbus_list_pop_first (&loader->messages);
04458 }
04459
04468 DBusList*
04469 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
04470 {
04471 return _dbus_list_pop_first_link (&loader->messages);
04472 }
04473
04480 void
04481 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
04482 DBusList *link)
04483 {
04484 _dbus_list_prepend_link (&loader->messages, link);
04485 }
04486
04496 dbus_bool_t
04497 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
04498 {
04499 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
04500 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
04501 return loader->corrupted;
04502 }
04503
04510 DBusValidity
04511 _dbus_message_loader_get_corruption_reason (DBusMessageLoader *loader)
04512 {
04513 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
04514 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
04515
04516 return loader->corruption_reason;
04517 }
04518
04525 void
04526 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
04527 long size)
04528 {
04529 if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
04530 {
04531 _dbus_verbose ("clamping requested max message size %ld to %d\n",
04532 size, DBUS_MAXIMUM_MESSAGE_LENGTH);
04533 size = DBUS_MAXIMUM_MESSAGE_LENGTH;
04534 }
04535 loader->max_message_size = size;
04536 }
04537
04544 long
04545 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
04546 {
04547 return loader->max_message_size;
04548 }
04549
04556 void
04557 _dbus_message_loader_set_max_message_unix_fds (DBusMessageLoader *loader,
04558 long n)
04559 {
04560 if (n > DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
04561 {
04562 _dbus_verbose ("clamping requested max message unix_fds %ld to %d\n",
04563 n, DBUS_MAXIMUM_MESSAGE_UNIX_FDS);
04564 n = DBUS_MAXIMUM_MESSAGE_UNIX_FDS;
04565 }
04566 loader->max_message_unix_fds = n;
04567 }
04568
04575 long
04576 _dbus_message_loader_get_max_message_unix_fds (DBusMessageLoader *loader)
04577 {
04578 return loader->max_message_unix_fds;
04579 }
04580
04586 int
04587 _dbus_message_loader_get_pending_fds_count (DBusMessageLoader *loader)
04588 {
04589 #ifdef HAVE_UNIX_FD_PASSING
04590 return loader->n_unix_fds;
04591 #else
04592 return 0;
04593 #endif
04594 }
04595
04604 void
04605 _dbus_message_loader_set_pending_fds_function (DBusMessageLoader *loader,
04606 void (* callback) (void *),
04607 void *data)
04608 {
04609 #ifdef HAVE_UNIX_FD_PASSING
04610 loader->unix_fds_change = callback;
04611 loader->unix_fds_change_data = data;
04612 #endif
04613 }
04614
04615 static DBusDataSlotAllocator slot_allocator =
04616 _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (message_slots));
04617
04632 dbus_bool_t
04633 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
04634 {
04635 return _dbus_data_slot_allocator_alloc (&slot_allocator,
04636 slot_p);
04637 }
04638
04650 void
04651 dbus_message_free_data_slot (dbus_int32_t *slot_p)
04652 {
04653 _dbus_return_if_fail (*slot_p >= 0);
04654
04655 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
04656 }
04657
04671 dbus_bool_t
04672 dbus_message_set_data (DBusMessage *message,
04673 dbus_int32_t slot,
04674 void *data,
04675 DBusFreeFunction free_data_func)
04676 {
04677 DBusFreeFunction old_free_func;
04678 void *old_data;
04679 dbus_bool_t retval;
04680
04681 _dbus_return_val_if_fail (message != NULL, FALSE);
04682 _dbus_return_val_if_fail (slot >= 0, FALSE);
04683
04684 retval = _dbus_data_slot_list_set (&slot_allocator,
04685 &message->slot_list,
04686 slot, data, free_data_func,
04687 &old_free_func, &old_data);
04688
04689 if (retval)
04690 {
04691
04692 if (old_free_func)
04693 (* old_free_func) (old_data);
04694 }
04695
04696 return retval;
04697 }
04698
04707 void*
04708 dbus_message_get_data (DBusMessage *message,
04709 dbus_int32_t slot)
04710 {
04711 void *res;
04712
04713 _dbus_return_val_if_fail (message != NULL, NULL);
04714
04715 res = _dbus_data_slot_list_get (&slot_allocator,
04716 &message->slot_list,
04717 slot);
04718
04719 return res;
04720 }
04721
04735 int
04736 dbus_message_type_from_string (const char *type_str)
04737 {
04738 if (strcmp (type_str, "method_call") == 0)
04739 return DBUS_MESSAGE_TYPE_METHOD_CALL;
04740 if (strcmp (type_str, "method_return") == 0)
04741 return DBUS_MESSAGE_TYPE_METHOD_RETURN;
04742 else if (strcmp (type_str, "signal") == 0)
04743 return DBUS_MESSAGE_TYPE_SIGNAL;
04744 else if (strcmp (type_str, "error") == 0)
04745 return DBUS_MESSAGE_TYPE_ERROR;
04746 else
04747 return DBUS_MESSAGE_TYPE_INVALID;
04748 }
04749
04763 const char *
04764 dbus_message_type_to_string (int type)
04765 {
04766 switch (type)
04767 {
04768 case DBUS_MESSAGE_TYPE_METHOD_CALL:
04769 return "method_call";
04770 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
04771 return "method_return";
04772 case DBUS_MESSAGE_TYPE_SIGNAL:
04773 return "signal";
04774 case DBUS_MESSAGE_TYPE_ERROR:
04775 return "error";
04776 default:
04777 return "invalid";
04778 }
04779 }
04780
04793 dbus_bool_t
04794 dbus_message_marshal (DBusMessage *msg,
04795 char **marshalled_data_p,
04796 int *len_p)
04797 {
04798 DBusString tmp;
04799 dbus_bool_t was_locked;
04800
04801 _dbus_return_val_if_fail (msg != NULL, FALSE);
04802 _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
04803 _dbus_return_val_if_fail (len_p != NULL, FALSE);
04804
04805 if (!_dbus_string_init (&tmp))
04806 return FALSE;
04807
04808
04809 was_locked = msg->locked;
04810
04811 if (!was_locked)
04812 dbus_message_lock (msg);
04813
04814 if (!_dbus_string_copy (&(msg->header.data), 0, &tmp, 0))
04815 goto fail;
04816
04817 *len_p = _dbus_string_get_length (&tmp);
04818
04819 if (!_dbus_string_copy (&(msg->body), 0, &tmp, *len_p))
04820 goto fail;
04821
04822 *len_p = _dbus_string_get_length (&tmp);
04823
04824 if (!_dbus_string_steal_data (&tmp, marshalled_data_p))
04825 goto fail;
04826
04827 _dbus_string_free (&tmp);
04828
04829 if (!was_locked)
04830 msg->locked = FALSE;
04831
04832 return TRUE;
04833
04834 fail:
04835 _dbus_string_free (&tmp);
04836
04837 if (!was_locked)
04838 msg->locked = FALSE;
04839
04840 return FALSE;
04841 }
04842
04855 DBusMessage *
04856 dbus_message_demarshal (const char *str,
04857 int len,
04858 DBusError *error)
04859 {
04860 DBusMessageLoader *loader;
04861 DBusString *buffer;
04862 DBusMessage *msg;
04863
04864 _dbus_return_val_if_fail (str != NULL, NULL);
04865
04866 loader = _dbus_message_loader_new ();
04867
04868 if (loader == NULL)
04869 return NULL;
04870
04871 _dbus_message_loader_get_buffer (loader, &buffer);
04872
04873 if (!_dbus_string_append_len (buffer, str, len))
04874 goto fail_oom;
04875
04876 _dbus_message_loader_return_buffer (loader, buffer);
04877
04878 if (!_dbus_message_loader_queue_messages (loader))
04879 goto fail_oom;
04880
04881 if (_dbus_message_loader_get_is_corrupted (loader))
04882 goto fail_corrupt;
04883
04884 msg = _dbus_message_loader_pop_message (loader);
04885
04886 if (!msg)
04887 goto fail_oom;
04888
04889 _dbus_message_loader_unref (loader);
04890 return msg;
04891
04892 fail_corrupt:
04893 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted (%s)",
04894 _dbus_validity_to_error_message (loader->corruption_reason));
04895 _dbus_message_loader_unref (loader);
04896 return NULL;
04897
04898 fail_oom:
04899 _DBUS_SET_OOM (error);
04900 _dbus_message_loader_unref (loader);
04901 return NULL;
04902 }
04903
04916 int
04917 dbus_message_demarshal_bytes_needed(const char *buf,
04918 int len)
04919 {
04920 DBusString str;
04921 int byte_order, fields_array_len, header_len, body_len;
04922 DBusValidity validity = DBUS_VALID;
04923 int have_message;
04924
04925 if (!buf || len < DBUS_MINIMUM_HEADER_SIZE)
04926 return 0;
04927
04928 if (len > DBUS_MAXIMUM_MESSAGE_LENGTH)
04929 len = DBUS_MAXIMUM_MESSAGE_LENGTH;
04930 _dbus_string_init_const_len (&str, buf, len);
04931
04932 validity = DBUS_VALID;
04933 have_message
04934 = _dbus_header_have_message_untrusted(DBUS_MAXIMUM_MESSAGE_LENGTH,
04935 &validity, &byte_order,
04936 &fields_array_len,
04937 &header_len,
04938 &body_len,
04939 &str, 0,
04940 len);
04941 _dbus_string_free (&str);
04942
04943 if (validity == DBUS_VALID)
04944 {
04945 _dbus_assert (have_message || (header_len + body_len) > len);
04946 (void) have_message;
04947 return header_len + body_len;
04948 }
04949 else
04950 {
04951 return -1;
04952 }
04953 }
04954
04976 void
04977 dbus_message_set_allow_interactive_authorization (DBusMessage *message,
04978 dbus_bool_t allow)
04979 {
04980 _dbus_return_if_fail (message != NULL);
04981 _dbus_return_if_fail (!message->locked);
04982
04983 _dbus_header_toggle_flag (&message->header,
04984 DBUS_HEADER_FLAG_ALLOW_INTERACTIVE_AUTHORIZATION,
04985 allow);
04986 }
04987
04994 dbus_bool_t
04995 dbus_message_get_allow_interactive_authorization (DBusMessage *message)
04996 {
04997 _dbus_return_val_if_fail (message != NULL, FALSE);
04998
04999 return _dbus_header_get_flag (&message->header,
05000 DBUS_HEADER_FLAG_ALLOW_INTERACTIVE_AUTHORIZATION);
05001 }
05002
05005