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 DBusBasicValue value;
01170
01171 _dbus_return_val_if_fail (message != NULL, FALSE);
01172 _dbus_return_val_if_fail (!message->locked, FALSE);
01173 _dbus_return_val_if_fail (reply_serial != 0, FALSE);
01174
01175 value.u32 = reply_serial;
01176
01177 return _dbus_header_set_field_basic (&message->header,
01178 DBUS_HEADER_FIELD_REPLY_SERIAL,
01179 DBUS_TYPE_UINT32,
01180 &value);
01181 }
01182
01189 dbus_uint32_t
01190 dbus_message_get_reply_serial (DBusMessage *message)
01191 {
01192 dbus_uint32_t v_UINT32;
01193
01194 _dbus_return_val_if_fail (message != NULL, 0);
01195
01196 if (_dbus_header_get_field_basic (&message->header,
01197 DBUS_HEADER_FIELD_REPLY_SERIAL,
01198 DBUS_TYPE_UINT32,
01199 &v_UINT32))
01200 return v_UINT32;
01201 else
01202 return 0;
01203 }
01204
01205 static void
01206 dbus_message_finalize (DBusMessage *message)
01207 {
01208 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
01209
01210
01211 _dbus_data_slot_list_free (&message->slot_list);
01212
01213 _dbus_list_foreach (&message->counters,
01214 free_counter, message);
01215 _dbus_list_clear (&message->counters);
01216
01217 _dbus_header_free (&message->header);
01218 _dbus_string_free (&message->body);
01219
01220 #ifdef HAVE_UNIX_FD_PASSING
01221 close_unix_fds(message->unix_fds, &message->n_unix_fds);
01222 dbus_free(message->unix_fds);
01223 #endif
01224
01225 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
01226
01227 dbus_free (message);
01228 }
01229
01230 static DBusMessage*
01231 dbus_message_new_empty_header (void)
01232 {
01233 DBusMessage *message;
01234 dbus_bool_t from_cache;
01235
01236 message = dbus_message_get_cached ();
01237
01238 if (message != NULL)
01239 {
01240 from_cache = TRUE;
01241 }
01242 else
01243 {
01244 from_cache = FALSE;
01245 message = dbus_new0 (DBusMessage, 1);
01246 if (message == NULL)
01247 return NULL;
01248 #ifndef DBUS_DISABLE_CHECKS
01249 message->generation = _dbus_current_generation;
01250 #endif
01251
01252 #ifdef HAVE_UNIX_FD_PASSING
01253 message->unix_fds = NULL;
01254 message->n_unix_fds_allocated = 0;
01255 #endif
01256 }
01257
01258 _dbus_atomic_inc (&message->refcount);
01259
01260 _dbus_message_trace_ref (message, 0, 1, "new_empty_header");
01261
01262 message->locked = FALSE;
01263 #ifndef DBUS_DISABLE_CHECKS
01264 message->in_cache = FALSE;
01265 #endif
01266 message->counters = NULL;
01267 message->size_counter_delta = 0;
01268 message->changed_stamp = 0;
01269
01270 #ifdef HAVE_UNIX_FD_PASSING
01271 message->n_unix_fds = 0;
01272 message->n_unix_fds_allocated = 0;
01273 message->unix_fd_counter_delta = 0;
01274 #endif
01275
01276 if (!from_cache)
01277 _dbus_data_slot_list_init (&message->slot_list);
01278
01279 if (from_cache)
01280 {
01281 _dbus_header_reinit (&message->header);
01282 _dbus_string_set_length (&message->body, 0);
01283 }
01284 else
01285 {
01286 if (!_dbus_header_init (&message->header))
01287 {
01288 dbus_free (message);
01289 return NULL;
01290 }
01291
01292 if (!_dbus_string_init_preallocated (&message->body, 32))
01293 {
01294 _dbus_header_free (&message->header);
01295 dbus_free (message);
01296 return NULL;
01297 }
01298 }
01299
01300 return message;
01301 }
01302
01315 DBusMessage*
01316 dbus_message_new (int message_type)
01317 {
01318 DBusMessage *message;
01319
01320 _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
01321
01322 message = dbus_message_new_empty_header ();
01323 if (message == NULL)
01324 return NULL;
01325
01326 if (!_dbus_header_create (&message->header,
01327 DBUS_COMPILER_BYTE_ORDER,
01328 message_type,
01329 NULL, NULL, NULL, NULL, NULL))
01330 {
01331 dbus_message_unref (message);
01332 return NULL;
01333 }
01334
01335 return message;
01336 }
01337
01359 DBusMessage*
01360 dbus_message_new_method_call (const char *destination,
01361 const char *path,
01362 const char *iface,
01363 const char *method)
01364 {
01365 DBusMessage *message;
01366
01367 _dbus_return_val_if_fail (path != NULL, NULL);
01368 _dbus_return_val_if_fail (method != NULL, NULL);
01369 _dbus_return_val_if_fail (destination == NULL ||
01370 _dbus_check_is_valid_bus_name (destination), NULL);
01371 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
01372 _dbus_return_val_if_fail (iface == NULL ||
01373 _dbus_check_is_valid_interface (iface), NULL);
01374 _dbus_return_val_if_fail (_dbus_check_is_valid_member (method), NULL);
01375
01376 message = dbus_message_new_empty_header ();
01377 if (message == NULL)
01378 return NULL;
01379
01380 if (!_dbus_header_create (&message->header,
01381 DBUS_COMPILER_BYTE_ORDER,
01382 DBUS_MESSAGE_TYPE_METHOD_CALL,
01383 destination, path, iface, method, NULL))
01384 {
01385 dbus_message_unref (message);
01386 return NULL;
01387 }
01388
01389 return message;
01390 }
01391
01399 DBusMessage*
01400 dbus_message_new_method_return (DBusMessage *method_call)
01401 {
01402 DBusMessage *message;
01403 const char *sender;
01404
01405 _dbus_return_val_if_fail (method_call != NULL, NULL);
01406
01407 sender = dbus_message_get_sender (method_call);
01408
01409
01410
01411 message = dbus_message_new_empty_header ();
01412 if (message == NULL)
01413 return NULL;
01414
01415 if (!_dbus_header_create (&message->header,
01416 DBUS_COMPILER_BYTE_ORDER,
01417 DBUS_MESSAGE_TYPE_METHOD_RETURN,
01418 sender, NULL, NULL, NULL, NULL))
01419 {
01420 dbus_message_unref (message);
01421 return NULL;
01422 }
01423
01424 dbus_message_set_no_reply (message, TRUE);
01425
01426 if (!dbus_message_set_reply_serial (message,
01427 dbus_message_get_serial (method_call)))
01428 {
01429 dbus_message_unref (message);
01430 return NULL;
01431 }
01432
01433 return message;
01434 }
01435
01450 DBusMessage*
01451 dbus_message_new_signal (const char *path,
01452 const char *iface,
01453 const char *name)
01454 {
01455 DBusMessage *message;
01456
01457 _dbus_return_val_if_fail (path != NULL, NULL);
01458 _dbus_return_val_if_fail (iface != NULL, NULL);
01459 _dbus_return_val_if_fail (name != NULL, NULL);
01460 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
01461 _dbus_return_val_if_fail (_dbus_check_is_valid_interface (iface), NULL);
01462 _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);
01463
01464 message = dbus_message_new_empty_header ();
01465 if (message == NULL)
01466 return NULL;
01467
01468 if (!_dbus_header_create (&message->header,
01469 DBUS_COMPILER_BYTE_ORDER,
01470 DBUS_MESSAGE_TYPE_SIGNAL,
01471 NULL, path, iface, name, NULL))
01472 {
01473 dbus_message_unref (message);
01474 return NULL;
01475 }
01476
01477 dbus_message_set_no_reply (message, TRUE);
01478
01479 return message;
01480 }
01481
01496 DBusMessage*
01497 dbus_message_new_error (DBusMessage *reply_to,
01498 const char *error_name,
01499 const char *error_message)
01500 {
01501 DBusMessage *message;
01502 const char *sender;
01503 DBusMessageIter iter;
01504
01505 _dbus_return_val_if_fail (reply_to != NULL, NULL);
01506 _dbus_return_val_if_fail (error_name != NULL, NULL);
01507 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
01508
01509 sender = dbus_message_get_sender (reply_to);
01510
01511
01512
01513
01514
01515 message = dbus_message_new_empty_header ();
01516 if (message == NULL)
01517 return NULL;
01518
01519 if (!_dbus_header_create (&message->header,
01520 DBUS_COMPILER_BYTE_ORDER,
01521 DBUS_MESSAGE_TYPE_ERROR,
01522 sender, NULL, NULL, NULL, error_name))
01523 {
01524 dbus_message_unref (message);
01525 return NULL;
01526 }
01527
01528 dbus_message_set_no_reply (message, TRUE);
01529
01530 if (!dbus_message_set_reply_serial (message,
01531 dbus_message_get_serial (reply_to)))
01532 {
01533 dbus_message_unref (message);
01534 return NULL;
01535 }
01536
01537 if (error_message != NULL)
01538 {
01539 dbus_message_iter_init_append (message, &iter);
01540 if (!dbus_message_iter_append_basic (&iter,
01541 DBUS_TYPE_STRING,
01542 &error_message))
01543 {
01544 dbus_message_unref (message);
01545 return NULL;
01546 }
01547 }
01548
01549 return message;
01550 }
01551
01568 DBusMessage*
01569 dbus_message_new_error_printf (DBusMessage *reply_to,
01570 const char *error_name,
01571 const char *error_format,
01572 ...)
01573 {
01574 va_list args;
01575 DBusString str;
01576 DBusMessage *message;
01577
01578 _dbus_return_val_if_fail (reply_to != NULL, NULL);
01579 _dbus_return_val_if_fail (error_name != NULL, NULL);
01580 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
01581
01582 if (!_dbus_string_init (&str))
01583 return NULL;
01584
01585 va_start (args, error_format);
01586
01587 if (_dbus_string_append_printf_valist (&str, error_format, args))
01588 message = dbus_message_new_error (reply_to, error_name,
01589 _dbus_string_get_const_data (&str));
01590 else
01591 message = NULL;
01592
01593 _dbus_string_free (&str);
01594
01595 va_end (args);
01596
01597 return message;
01598 }
01599
01600
01613 DBusMessage *
01614 dbus_message_copy (const DBusMessage *message)
01615 {
01616 DBusMessage *retval;
01617
01618 _dbus_return_val_if_fail (message != NULL, NULL);
01619
01620 retval = dbus_new0 (DBusMessage, 1);
01621 if (retval == NULL)
01622 return NULL;
01623
01624 _dbus_atomic_inc (&retval->refcount);
01625
01626 retval->locked = FALSE;
01627 #ifndef DBUS_DISABLE_CHECKS
01628 retval->generation = message->generation;
01629 #endif
01630
01631 if (!_dbus_header_copy (&message->header, &retval->header))
01632 {
01633 dbus_free (retval);
01634 return NULL;
01635 }
01636
01637 if (!_dbus_string_init_preallocated (&retval->body,
01638 _dbus_string_get_length (&message->body)))
01639 {
01640 _dbus_header_free (&retval->header);
01641 dbus_free (retval);
01642 return NULL;
01643 }
01644
01645 if (!_dbus_string_copy (&message->body, 0,
01646 &retval->body, 0))
01647 goto failed_copy;
01648
01649 #ifdef HAVE_UNIX_FD_PASSING
01650 retval->unix_fds = dbus_new(int, message->n_unix_fds);
01651 if (retval->unix_fds == NULL && message->n_unix_fds > 0)
01652 goto failed_copy;
01653
01654 retval->n_unix_fds_allocated = message->n_unix_fds;
01655
01656 for (retval->n_unix_fds = 0;
01657 retval->n_unix_fds < message->n_unix_fds;
01658 retval->n_unix_fds++)
01659 {
01660 retval->unix_fds[retval->n_unix_fds] = _dbus_dup(message->unix_fds[retval->n_unix_fds], NULL);
01661
01662 if (retval->unix_fds[retval->n_unix_fds] < 0)
01663 goto failed_copy;
01664 }
01665
01666 #endif
01667
01668 _dbus_message_trace_ref (retval, 0, 1, "copy");
01669 return retval;
01670
01671 failed_copy:
01672 _dbus_header_free (&retval->header);
01673 _dbus_string_free (&retval->body);
01674
01675 #ifdef HAVE_UNIX_FD_PASSING
01676 close_unix_fds(retval->unix_fds, &retval->n_unix_fds);
01677 dbus_free(retval->unix_fds);
01678 #endif
01679
01680 dbus_free (retval);
01681
01682 return NULL;
01683 }
01684
01685
01693 DBusMessage *
01694 dbus_message_ref (DBusMessage *message)
01695 {
01696 dbus_int32_t old_refcount;
01697
01698 _dbus_return_val_if_fail (message != NULL, NULL);
01699 _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
01700 _dbus_return_val_if_fail (!message->in_cache, NULL);
01701
01702 old_refcount = _dbus_atomic_inc (&message->refcount);
01703 _dbus_assert (old_refcount >= 1);
01704 _dbus_message_trace_ref (message, old_refcount, old_refcount + 1, "ref");
01705
01706 return message;
01707 }
01708
01716 void
01717 dbus_message_unref (DBusMessage *message)
01718 {
01719 dbus_int32_t old_refcount;
01720
01721 _dbus_return_if_fail (message != NULL);
01722 _dbus_return_if_fail (message->generation == _dbus_current_generation);
01723 _dbus_return_if_fail (!message->in_cache);
01724
01725 old_refcount = _dbus_atomic_dec (&message->refcount);
01726
01727 _dbus_assert (old_refcount >= 1);
01728
01729 _dbus_message_trace_ref (message, old_refcount, old_refcount - 1, "unref");
01730
01731 if (old_refcount == 1)
01732 {
01733
01734 dbus_message_cache_or_finalize (message);
01735 }
01736 }
01737
01748 int
01749 dbus_message_get_type (DBusMessage *message)
01750 {
01751 _dbus_return_val_if_fail (message != NULL, DBUS_MESSAGE_TYPE_INVALID);
01752
01753 return _dbus_header_get_message_type (&message->header);
01754 }
01755
01818 dbus_bool_t
01819 dbus_message_append_args (DBusMessage *message,
01820 int first_arg_type,
01821 ...)
01822 {
01823 dbus_bool_t retval;
01824 va_list var_args;
01825
01826 _dbus_return_val_if_fail (message != NULL, FALSE);
01827
01828 va_start (var_args, first_arg_type);
01829 retval = dbus_message_append_args_valist (message,
01830 first_arg_type,
01831 var_args);
01832 va_end (var_args);
01833
01834 return retval;
01835 }
01836
01850 dbus_bool_t
01851 dbus_message_append_args_valist (DBusMessage *message,
01852 int first_arg_type,
01853 va_list var_args)
01854 {
01855 int type;
01856 DBusMessageIter iter;
01857
01858 _dbus_return_val_if_fail (message != NULL, FALSE);
01859
01860 type = first_arg_type;
01861
01862 dbus_message_iter_init_append (message, &iter);
01863
01864 while (type != DBUS_TYPE_INVALID)
01865 {
01866 if (dbus_type_is_basic (type))
01867 {
01868 const DBusBasicValue *value;
01869 value = va_arg (var_args, const DBusBasicValue*);
01870
01871 if (!dbus_message_iter_append_basic (&iter,
01872 type,
01873 value))
01874 goto failed;
01875 }
01876 else if (type == DBUS_TYPE_ARRAY)
01877 {
01878 int element_type;
01879 DBusMessageIter array;
01880 char buf[2];
01881
01882 element_type = va_arg (var_args, int);
01883
01884 buf[0] = element_type;
01885 buf[1] = '\0';
01886 if (!dbus_message_iter_open_container (&iter,
01887 DBUS_TYPE_ARRAY,
01888 buf,
01889 &array))
01890 goto failed;
01891
01892 if (dbus_type_is_fixed (element_type) &&
01893 element_type != DBUS_TYPE_UNIX_FD)
01894 {
01895 const DBusBasicValue **value;
01896 int n_elements;
01897
01898 value = va_arg (var_args, const DBusBasicValue**);
01899 n_elements = va_arg (var_args, int);
01900
01901 if (!dbus_message_iter_append_fixed_array (&array,
01902 element_type,
01903 value,
01904 n_elements)) {
01905 dbus_message_iter_abandon_container (&iter, &array);
01906 goto failed;
01907 }
01908 }
01909 else if (_DBUS_TYPE_IS_STRINGLIKE (element_type))
01910 {
01911 const char ***value_p;
01912 const char **value;
01913 int n_elements;
01914 int i;
01915
01916 value_p = va_arg (var_args, const char***);
01917 n_elements = va_arg (var_args, int);
01918
01919 value = *value_p;
01920
01921 i = 0;
01922 while (i < n_elements)
01923 {
01924 if (!dbus_message_iter_append_basic (&array,
01925 element_type,
01926 &value[i])) {
01927 dbus_message_iter_abandon_container (&iter, &array);
01928 goto failed;
01929 }
01930 ++i;
01931 }
01932 }
01933 else
01934 {
01935 _dbus_warn ("arrays of %s can't be appended with %s for now\n",
01936 _dbus_type_to_string (element_type),
01937 _DBUS_FUNCTION_NAME);
01938 goto failed;
01939 }
01940
01941 if (!dbus_message_iter_close_container (&iter, &array))
01942 goto failed;
01943 }
01944 #ifndef DBUS_DISABLE_CHECKS
01945 else
01946 {
01947 _dbus_warn ("type %s isn't supported yet in %s\n",
01948 _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
01949 goto failed;
01950 }
01951 #endif
01952
01953 type = va_arg (var_args, int);
01954 }
01955
01956 return TRUE;
01957
01958 failed:
01959 return FALSE;
01960 }
01961
02006 dbus_bool_t
02007 dbus_message_get_args (DBusMessage *message,
02008 DBusError *error,
02009 int first_arg_type,
02010 ...)
02011 {
02012 dbus_bool_t retval;
02013 va_list var_args;
02014
02015 _dbus_return_val_if_fail (message != NULL, FALSE);
02016 _dbus_return_val_if_error_is_set (error, FALSE);
02017
02018 va_start (var_args, first_arg_type);
02019 retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
02020 va_end (var_args);
02021
02022 return retval;
02023 }
02024
02035 dbus_bool_t
02036 dbus_message_get_args_valist (DBusMessage *message,
02037 DBusError *error,
02038 int first_arg_type,
02039 va_list var_args)
02040 {
02041 DBusMessageIter iter;
02042
02043 _dbus_return_val_if_fail (message != NULL, FALSE);
02044 _dbus_return_val_if_error_is_set (error, FALSE);
02045
02046 dbus_message_iter_init (message, &iter);
02047 return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
02048 }
02049
02050 static void
02051 _dbus_message_iter_init_common (DBusMessage *message,
02052 DBusMessageRealIter *real,
02053 int iter_type)
02054 {
02055
02056 _DBUS_STATIC_ASSERT (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
02057 _DBUS_STATIC_ASSERT (_DBUS_ALIGNOF (DBusMessageRealIter) <=
02058 _DBUS_ALIGNOF (DBusMessageIter));
02059
02060
02061 _DBUS_STATIC_ASSERT (sizeof (DBusMessageIter_1_10_0) ==
02062 sizeof (DBusMessageIter));
02063 _DBUS_STATIC_ASSERT (_DBUS_ALIGNOF (DBusMessageIter_1_10_0) ==
02064 _DBUS_ALIGNOF (DBusMessageIter));
02065
02066
02067
02068 _DBUS_STATIC_ASSERT (sizeof (DBusMessageIter) ==
02069 4 * sizeof (void *) + sizeof (dbus_uint32_t) + 9 * sizeof (int));
02070
02071
02072
02073
02074 ensure_byte_order (message);
02075
02076 real->message = message;
02077 real->changed_stamp = message->changed_stamp;
02078 real->iter_type = iter_type;
02079 real->sig_refcount = 0;
02080 }
02081
02104 dbus_bool_t
02105 dbus_message_iter_init (DBusMessage *message,
02106 DBusMessageIter *iter)
02107 {
02108 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02109 const DBusString *type_str;
02110 int type_pos;
02111
02112 _dbus_return_val_if_fail (message != NULL, FALSE);
02113 _dbus_return_val_if_fail (iter != NULL, FALSE);
02114
02115 get_const_signature (&message->header, &type_str, &type_pos);
02116
02117 _dbus_message_iter_init_common (message, real,
02118 DBUS_MESSAGE_ITER_TYPE_READER);
02119
02120 _dbus_type_reader_init (&real->u.reader,
02121 _dbus_header_get_byte_order (&message->header),
02122 type_str, type_pos,
02123 &message->body,
02124 0);
02125
02126 return _dbus_type_reader_get_current_type (&real->u.reader) != DBUS_TYPE_INVALID;
02127 }
02128
02135 dbus_bool_t
02136 dbus_message_iter_has_next (DBusMessageIter *iter)
02137 {
02138 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02139
02140 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
02141 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
02142
02143 return _dbus_type_reader_has_next (&real->u.reader);
02144 }
02145
02154 dbus_bool_t
02155 dbus_message_iter_next (DBusMessageIter *iter)
02156 {
02157 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02158
02159 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
02160 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
02161
02162 return _dbus_type_reader_next (&real->u.reader);
02163 }
02164
02179 int
02180 dbus_message_iter_get_arg_type (DBusMessageIter *iter)
02181 {
02182 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02183
02184 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
02185 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
02186
02187 return _dbus_type_reader_get_current_type (&real->u.reader);
02188 }
02189
02198 int
02199 dbus_message_iter_get_element_type (DBusMessageIter *iter)
02200 {
02201 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02202
02203 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
02204 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
02205 _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
02206
02207 return _dbus_type_reader_get_element_type (&real->u.reader);
02208 }
02209
02235 void
02236 dbus_message_iter_recurse (DBusMessageIter *iter,
02237 DBusMessageIter *sub)
02238 {
02239 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02240 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02241
02242 _dbus_return_if_fail (_dbus_message_iter_check (real));
02243 _dbus_return_if_fail (sub != NULL);
02244
02245 *real_sub = *real;
02246 _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
02247 }
02248
02260 char *
02261 dbus_message_iter_get_signature (DBusMessageIter *iter)
02262 {
02263 const DBusString *sig;
02264 DBusString retstr;
02265 char *ret;
02266 int start, len;
02267 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02268
02269 _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
02270
02271 if (!_dbus_string_init (&retstr))
02272 return NULL;
02273
02274 _dbus_type_reader_get_signature (&real->u.reader, &sig,
02275 &start, &len);
02276 if (!_dbus_string_append_len (&retstr,
02277 _dbus_string_get_const_data (sig) + start,
02278 len))
02279 return NULL;
02280 if (!_dbus_string_steal_data (&retstr, &ret))
02281 return NULL;
02282 _dbus_string_free (&retstr);
02283 return ret;
02284 }
02285
02333 void
02334 dbus_message_iter_get_basic (DBusMessageIter *iter,
02335 void *value)
02336 {
02337 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02338
02339 _dbus_return_if_fail (_dbus_message_iter_check (real));
02340 _dbus_return_if_fail (value != NULL);
02341
02342 if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_UNIX_FD)
02343 {
02344 #ifdef HAVE_UNIX_FD_PASSING
02345 DBusBasicValue idx;
02346
02347 _dbus_type_reader_read_basic(&real->u.reader, &idx);
02348
02349 if (idx.u32 >= real->message->n_unix_fds) {
02350
02351
02352 *((int*) value) = -1;
02353 return;
02354 }
02355
02356 *((int*) value) = _dbus_dup(real->message->unix_fds[idx.u32], NULL);
02357 #else
02358 *((int*) value) = -1;
02359 #endif
02360 }
02361 else
02362 {
02363 _dbus_type_reader_read_basic (&real->u.reader,
02364 value);
02365 }
02366 }
02367
02378 int
02379 dbus_message_iter_get_element_count (DBusMessageIter *iter)
02380 {
02381 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02382 DBusTypeReader array;
02383 int element_type;
02384 int n_elements = 0;
02385
02386 _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
02387 _dbus_return_val_if_fail (_dbus_type_reader_get_current_type (&real->u.reader)
02388 == DBUS_TYPE_ARRAY, 0);
02389
02390 element_type = _dbus_type_reader_get_element_type (&real->u.reader);
02391 _dbus_type_reader_recurse (&real->u.reader, &array);
02392 if (dbus_type_is_fixed (element_type))
02393 {
02394 int alignment = _dbus_type_get_alignment (element_type);
02395 int total_len = _dbus_type_reader_get_array_length (&array);
02396 n_elements = total_len / alignment;
02397 }
02398 else
02399 {
02400 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
02401 {
02402 ++n_elements;
02403 _dbus_type_reader_next (&array);
02404 }
02405 }
02406
02407 return n_elements;
02408 }
02409
02422 int
02423 dbus_message_iter_get_array_len (DBusMessageIter *iter)
02424 {
02425 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02426
02427 _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
02428
02429 return _dbus_type_reader_get_array_length (&real->u.reader);
02430 }
02431
02467 void
02468 dbus_message_iter_get_fixed_array (DBusMessageIter *iter,
02469 void *value,
02470 int *n_elements)
02471 {
02472 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02473 #ifndef DBUS_DISABLE_CHECKS
02474 int subtype = _dbus_type_reader_get_current_type(&real->u.reader);
02475
02476 _dbus_return_if_fail (_dbus_message_iter_check (real));
02477 _dbus_return_if_fail (value != NULL);
02478 _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) ||
02479 (dbus_type_is_fixed (subtype) && subtype != DBUS_TYPE_UNIX_FD));
02480 #endif
02481
02482 _dbus_type_reader_read_fixed_multi (&real->u.reader,
02483 value, n_elements);
02484 }
02485
02497 void
02498 dbus_message_iter_init_append (DBusMessage *message,
02499 DBusMessageIter *iter)
02500 {
02501 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02502
02503 _dbus_return_if_fail (message != NULL);
02504 _dbus_return_if_fail (iter != NULL);
02505
02506 _dbus_message_iter_init_common (message, real,
02507 DBUS_MESSAGE_ITER_TYPE_WRITER);
02508
02509
02510
02511
02512
02513 _dbus_type_writer_init_types_delayed (&real->u.writer,
02514 _dbus_header_get_byte_order (&message->header),
02515 &message->body,
02516 _dbus_string_get_length (&message->body));
02517 }
02518
02527 static dbus_bool_t
02528 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
02529 {
02530 DBusString *str;
02531 const DBusString *current_sig;
02532 int current_sig_pos;
02533
02534 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02535
02536 if (real->u.writer.type_str != NULL)
02537 {
02538 _dbus_assert (real->sig_refcount > 0);
02539 real->sig_refcount += 1;
02540 return TRUE;
02541 }
02542
02543 str = dbus_new (DBusString, 1);
02544 if (str == NULL)
02545 return FALSE;
02546
02547 if (!_dbus_header_get_field_raw (&real->message->header,
02548 DBUS_HEADER_FIELD_SIGNATURE,
02549 ¤t_sig, ¤t_sig_pos))
02550 current_sig = NULL;
02551
02552 if (current_sig)
02553 {
02554 int current_len;
02555
02556 current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
02557 current_sig_pos += 1;
02558
02559 if (!_dbus_string_init_preallocated (str, current_len + 4))
02560 {
02561 dbus_free (str);
02562 return FALSE;
02563 }
02564
02565 if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
02566 str, 0))
02567 {
02568 _dbus_string_free (str);
02569 dbus_free (str);
02570 return FALSE;
02571 }
02572 }
02573 else
02574 {
02575 if (!_dbus_string_init_preallocated (str, 4))
02576 {
02577 dbus_free (str);
02578 return FALSE;
02579 }
02580 }
02581
02582 real->sig_refcount = 1;
02583
02584 _dbus_type_writer_add_types (&real->u.writer,
02585 str, _dbus_string_get_length (str));
02586 return TRUE;
02587 }
02588
02598 static dbus_bool_t
02599 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
02600 {
02601 DBusString *str;
02602 const char *v_STRING;
02603 dbus_bool_t retval;
02604
02605 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02606 _dbus_assert (real->u.writer.type_str != NULL);
02607 _dbus_assert (real->sig_refcount > 0);
02608
02609 real->sig_refcount -= 1;
02610
02611 if (real->sig_refcount > 0)
02612 return TRUE;
02613 _dbus_assert (real->sig_refcount == 0);
02614
02615 retval = TRUE;
02616
02617 str = real->u.writer.type_str;
02618
02619 v_STRING = _dbus_string_get_const_data (str);
02620 if (!_dbus_header_set_field_basic (&real->message->header,
02621 DBUS_HEADER_FIELD_SIGNATURE,
02622 DBUS_TYPE_SIGNATURE,
02623 &v_STRING))
02624 retval = FALSE;
02625
02626 _dbus_type_writer_remove_types (&real->u.writer);
02627 _dbus_string_free (str);
02628 dbus_free (str);
02629
02630 return retval;
02631 }
02632
02640 static void
02641 _dbus_message_iter_abandon_signature (DBusMessageRealIter *real)
02642 {
02643 DBusString *str;
02644
02645 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02646 _dbus_assert (real->u.writer.type_str != NULL);
02647 _dbus_assert (real->sig_refcount > 0);
02648
02649 real->sig_refcount -= 1;
02650
02651 if (real->sig_refcount > 0)
02652 return;
02653 _dbus_assert (real->sig_refcount == 0);
02654
02655 str = real->u.writer.type_str;
02656
02657 _dbus_type_writer_remove_types (&real->u.writer);
02658 _dbus_string_free (str);
02659 dbus_free (str);
02660 }
02661
02662 #ifndef DBUS_DISABLE_CHECKS
02663 static dbus_bool_t
02664 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
02665 {
02666 if (!_dbus_message_iter_check (iter))
02667 return FALSE;
02668
02669 if (iter->message->locked)
02670 {
02671 _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)\n");
02672 return FALSE;
02673 }
02674
02675 return TRUE;
02676 }
02677 #endif
02678
02679 #ifdef HAVE_UNIX_FD_PASSING
02680 static int *
02681 expand_fd_array(DBusMessage *m,
02682 unsigned n)
02683 {
02684 _dbus_assert(m);
02685
02686
02687
02688
02689 if (m->n_unix_fds + n > m->n_unix_fds_allocated)
02690 {
02691 unsigned k;
02692 int *p;
02693
02694
02695 k = (m->n_unix_fds + n) * 2;
02696
02697
02698 if (k < 4)
02699 k = 4;
02700
02701 p = dbus_realloc(m->unix_fds, k * sizeof(int));
02702 if (p == NULL)
02703 return NULL;
02704
02705 m->unix_fds = p;
02706 m->n_unix_fds_allocated = k;
02707 }
02708
02709 return m->unix_fds + m->n_unix_fds;
02710 }
02711 #endif
02712
02732 dbus_bool_t
02733 dbus_message_iter_append_basic (DBusMessageIter *iter,
02734 int type,
02735 const void *value)
02736 {
02737 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02738 dbus_bool_t ret;
02739
02740 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02741 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02742 _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
02743 _dbus_return_val_if_fail (value != NULL, FALSE);
02744
02745 #ifndef DBUS_DISABLE_CHECKS
02746 switch (type)
02747 {
02748 const char * const *string_p;
02749 const dbus_bool_t *bool_p;
02750
02751 case DBUS_TYPE_STRING:
02752 string_p = value;
02753 _dbus_return_val_if_fail (_dbus_check_is_valid_utf8 (*string_p), FALSE);
02754 break;
02755
02756 case DBUS_TYPE_OBJECT_PATH:
02757 string_p = value;
02758 _dbus_return_val_if_fail (_dbus_check_is_valid_path (*string_p), FALSE);
02759 break;
02760
02761 case DBUS_TYPE_SIGNATURE:
02762 string_p = value;
02763 _dbus_return_val_if_fail (_dbus_check_is_valid_signature (*string_p), FALSE);
02764 break;
02765
02766 case DBUS_TYPE_BOOLEAN:
02767 bool_p = value;
02768 _dbus_return_val_if_fail (*bool_p == 0 || *bool_p == 1, FALSE);
02769 break;
02770
02771 default:
02772 {
02773
02774 }
02775 }
02776 #endif
02777
02778 if (!_dbus_message_iter_open_signature (real))
02779 return FALSE;
02780
02781 if (type == DBUS_TYPE_UNIX_FD)
02782 {
02783 #ifdef HAVE_UNIX_FD_PASSING
02784 int *fds;
02785 dbus_uint32_t u;
02786
02787
02788 if (!(fds = expand_fd_array(real->message, 1)))
02789 return FALSE;
02790
02791 *fds = _dbus_dup(*(int*) value, NULL);
02792 if (*fds < 0)
02793 return FALSE;
02794
02795 u = real->message->n_unix_fds;
02796
02797
02798 if (!(ret = _dbus_type_writer_write_basic (&real->u.writer, DBUS_TYPE_UNIX_FD, &u))) {
02799 _dbus_close(*fds, NULL);
02800 return FALSE;
02801 }
02802
02803 real->message->n_unix_fds += 1;
02804 u += 1;
02805
02806
02807 ret = _dbus_header_set_field_basic (&real->message->header,
02808 DBUS_HEADER_FIELD_UNIX_FDS,
02809 DBUS_TYPE_UINT32,
02810 &u);
02811
02812
02813
02814
02815
02816
02817 #else
02818 ret = FALSE;
02819 #endif
02820 }
02821 else
02822 {
02823 ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
02824 }
02825
02826 if (!_dbus_message_iter_close_signature (real))
02827 ret = FALSE;
02828
02829 return ret;
02830 }
02831
02867 dbus_bool_t
02868 dbus_message_iter_append_fixed_array (DBusMessageIter *iter,
02869 int element_type,
02870 const void *value,
02871 int n_elements)
02872 {
02873 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02874 dbus_bool_t ret;
02875
02876 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02877 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02878 _dbus_return_val_if_fail (dbus_type_is_fixed (element_type) && element_type != DBUS_TYPE_UNIX_FD, FALSE);
02879 _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
02880 _dbus_return_val_if_fail (value != NULL, FALSE);
02881 _dbus_return_val_if_fail (n_elements >= 0, FALSE);
02882 _dbus_return_val_if_fail (n_elements <=
02883 DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type),
02884 FALSE);
02885
02886 #ifndef DBUS_DISABLE_CHECKS
02887 if (element_type == DBUS_TYPE_BOOLEAN)
02888 {
02889 const dbus_bool_t * const *bools = value;
02890 int i;
02891
02892 for (i = 0; i < n_elements; i++)
02893 {
02894 _dbus_return_val_if_fail ((*bools)[i] == 0 || (*bools)[i] == 1, FALSE);
02895 }
02896 }
02897 #endif
02898
02899 ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
02900
02901 return ret;
02902 }
02903
02925 dbus_bool_t
02926 dbus_message_iter_open_container (DBusMessageIter *iter,
02927 int type,
02928 const char *contained_signature,
02929 DBusMessageIter *sub)
02930 {
02931 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02932 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02933 DBusString contained_str;
02934
02935 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02936 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02937 _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
02938 _dbus_return_val_if_fail (sub != NULL, FALSE);
02939 _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
02940 contained_signature == NULL) ||
02941 (type == DBUS_TYPE_DICT_ENTRY &&
02942 contained_signature == NULL) ||
02943 (type == DBUS_TYPE_VARIANT &&
02944 contained_signature != NULL) ||
02945 (type == DBUS_TYPE_ARRAY &&
02946 contained_signature != NULL), FALSE);
02947
02948
02949
02950
02951
02952 _dbus_return_val_if_fail ((type == DBUS_TYPE_ARRAY && contained_signature && *contained_signature == DBUS_DICT_ENTRY_BEGIN_CHAR) ||
02953 (contained_signature == NULL ||
02954 _dbus_check_is_valid_signature (contained_signature)),
02955 FALSE);
02956
02957 if (!_dbus_message_iter_open_signature (real))
02958 return FALSE;
02959
02960 *real_sub = *real;
02961
02962 if (contained_signature != NULL)
02963 {
02964 _dbus_string_init_const (&contained_str, contained_signature);
02965
02966 return _dbus_type_writer_recurse (&real->u.writer,
02967 type,
02968 &contained_str, 0,
02969 &real_sub->u.writer);
02970 }
02971 else
02972 {
02973 return _dbus_type_writer_recurse (&real->u.writer,
02974 type,
02975 NULL, 0,
02976 &real_sub->u.writer);
02977 }
02978 }
02979
02980
02994 dbus_bool_t
02995 dbus_message_iter_close_container (DBusMessageIter *iter,
02996 DBusMessageIter *sub)
02997 {
02998 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02999 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
03000 dbus_bool_t ret;
03001
03002 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
03003 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
03004 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
03005 _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
03006
03007 ret = _dbus_type_writer_unrecurse (&real->u.writer,
03008 &real_sub->u.writer);
03009
03010 if (!_dbus_message_iter_close_signature (real))
03011 ret = FALSE;
03012
03013 return ret;
03014 }
03015
03027 void
03028 dbus_message_iter_abandon_container (DBusMessageIter *iter,
03029 DBusMessageIter *sub)
03030 {
03031 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03032 #ifndef DBUS_DISABLE_CHECKS
03033 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
03034
03035 _dbus_return_if_fail (_dbus_message_iter_append_check (real));
03036 _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
03037 _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
03038 _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
03039 #endif
03040
03041 _dbus_message_iter_abandon_signature (real);
03042 }
03043
03060 void
03061 dbus_message_set_no_reply (DBusMessage *message,
03062 dbus_bool_t no_reply)
03063 {
03064 _dbus_return_if_fail (message != NULL);
03065 _dbus_return_if_fail (!message->locked);
03066
03067 _dbus_header_toggle_flag (&message->header,
03068 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED,
03069 no_reply);
03070 }
03071
03079 dbus_bool_t
03080 dbus_message_get_no_reply (DBusMessage *message)
03081 {
03082 _dbus_return_val_if_fail (message != NULL, FALSE);
03083
03084 return _dbus_header_get_flag (&message->header,
03085 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED);
03086 }
03087
03102 void
03103 dbus_message_set_auto_start (DBusMessage *message,
03104 dbus_bool_t auto_start)
03105 {
03106 _dbus_return_if_fail (message != NULL);
03107 _dbus_return_if_fail (!message->locked);
03108
03109 _dbus_header_toggle_flag (&message->header,
03110 DBUS_HEADER_FLAG_NO_AUTO_START,
03111 !auto_start);
03112 }
03113
03121 dbus_bool_t
03122 dbus_message_get_auto_start (DBusMessage *message)
03123 {
03124 _dbus_return_val_if_fail (message != NULL, FALSE);
03125
03126 return !_dbus_header_get_flag (&message->header,
03127 DBUS_HEADER_FLAG_NO_AUTO_START);
03128 }
03129
03130
03143 dbus_bool_t
03144 dbus_message_set_path (DBusMessage *message,
03145 const char *object_path)
03146 {
03147 _dbus_return_val_if_fail (message != NULL, FALSE);
03148 _dbus_return_val_if_fail (!message->locked, FALSE);
03149 _dbus_return_val_if_fail (object_path == NULL ||
03150 _dbus_check_is_valid_path (object_path),
03151 FALSE);
03152
03153 return set_or_delete_string_field (message,
03154 DBUS_HEADER_FIELD_PATH,
03155 DBUS_TYPE_OBJECT_PATH,
03156 object_path);
03157 }
03158
03172 const char*
03173 dbus_message_get_path (DBusMessage *message)
03174 {
03175 const char *v;
03176
03177 _dbus_return_val_if_fail (message != NULL, NULL);
03178
03179 v = NULL;
03180 _dbus_header_get_field_basic (&message->header,
03181 DBUS_HEADER_FIELD_PATH,
03182 DBUS_TYPE_OBJECT_PATH,
03183 (void *) &v);
03184 return v;
03185 }
03186
03196 dbus_bool_t
03197 dbus_message_has_path (DBusMessage *message,
03198 const char *path)
03199 {
03200 const char *msg_path;
03201 msg_path = dbus_message_get_path (message);
03202
03203 if (msg_path == NULL)
03204 {
03205 if (path == NULL)
03206 return TRUE;
03207 else
03208 return FALSE;
03209 }
03210
03211 if (path == NULL)
03212 return FALSE;
03213
03214 if (strcmp (msg_path, path) == 0)
03215 return TRUE;
03216
03217 return FALSE;
03218 }
03219
03240 dbus_bool_t
03241 dbus_message_get_path_decomposed (DBusMessage *message,
03242 char ***path)
03243 {
03244 const char *v;
03245
03246 _dbus_return_val_if_fail (message != NULL, FALSE);
03247 _dbus_return_val_if_fail (path != NULL, FALSE);
03248
03249 *path = NULL;
03250
03251 v = dbus_message_get_path (message);
03252 if (v != NULL)
03253 {
03254 if (!_dbus_decompose_path (v, strlen (v),
03255 path, NULL))
03256 return FALSE;
03257 }
03258 return TRUE;
03259 }
03260
03274 dbus_bool_t
03275 dbus_message_set_interface (DBusMessage *message,
03276 const char *iface)
03277 {
03278 _dbus_return_val_if_fail (message != NULL, FALSE);
03279 _dbus_return_val_if_fail (!message->locked, FALSE);
03280 _dbus_return_val_if_fail (iface == NULL ||
03281 _dbus_check_is_valid_interface (iface),
03282 FALSE);
03283
03284 return set_or_delete_string_field (message,
03285 DBUS_HEADER_FIELD_INTERFACE,
03286 DBUS_TYPE_STRING,
03287 iface);
03288 }
03289
03303 const char*
03304 dbus_message_get_interface (DBusMessage *message)
03305 {
03306 const char *v;
03307
03308 _dbus_return_val_if_fail (message != NULL, NULL);
03309
03310 v = NULL;
03311 _dbus_header_get_field_basic (&message->header,
03312 DBUS_HEADER_FIELD_INTERFACE,
03313 DBUS_TYPE_STRING,
03314 (void *) &v);
03315 return v;
03316 }
03317
03325 dbus_bool_t
03326 dbus_message_has_interface (DBusMessage *message,
03327 const char *iface)
03328 {
03329 const char *msg_interface;
03330 msg_interface = dbus_message_get_interface (message);
03331
03332 if (msg_interface == NULL)
03333 {
03334 if (iface == NULL)
03335 return TRUE;
03336 else
03337 return FALSE;
03338 }
03339
03340 if (iface == NULL)
03341 return FALSE;
03342
03343 if (strcmp (msg_interface, iface) == 0)
03344 return TRUE;
03345
03346 return FALSE;
03347
03348 }
03349
03362 dbus_bool_t
03363 dbus_message_set_member (DBusMessage *message,
03364 const char *member)
03365 {
03366 _dbus_return_val_if_fail (message != NULL, FALSE);
03367 _dbus_return_val_if_fail (!message->locked, FALSE);
03368 _dbus_return_val_if_fail (member == NULL ||
03369 _dbus_check_is_valid_member (member),
03370 FALSE);
03371
03372 return set_or_delete_string_field (message,
03373 DBUS_HEADER_FIELD_MEMBER,
03374 DBUS_TYPE_STRING,
03375 member);
03376 }
03377
03389 const char*
03390 dbus_message_get_member (DBusMessage *message)
03391 {
03392 const char *v;
03393
03394 _dbus_return_val_if_fail (message != NULL, NULL);
03395
03396 v = NULL;
03397 _dbus_header_get_field_basic (&message->header,
03398 DBUS_HEADER_FIELD_MEMBER,
03399 DBUS_TYPE_STRING,
03400 (void *) &v);
03401 return v;
03402 }
03403
03411 dbus_bool_t
03412 dbus_message_has_member (DBusMessage *message,
03413 const char *member)
03414 {
03415 const char *msg_member;
03416 msg_member = dbus_message_get_member (message);
03417
03418 if (msg_member == NULL)
03419 {
03420 if (member == NULL)
03421 return TRUE;
03422 else
03423 return FALSE;
03424 }
03425
03426 if (member == NULL)
03427 return FALSE;
03428
03429 if (strcmp (msg_member, member) == 0)
03430 return TRUE;
03431
03432 return FALSE;
03433
03434 }
03435
03447 dbus_bool_t
03448 dbus_message_set_error_name (DBusMessage *message,
03449 const char *error_name)
03450 {
03451 _dbus_return_val_if_fail (message != NULL, FALSE);
03452 _dbus_return_val_if_fail (!message->locked, FALSE);
03453 _dbus_return_val_if_fail (error_name == NULL ||
03454 _dbus_check_is_valid_error_name (error_name),
03455 FALSE);
03456
03457 return set_or_delete_string_field (message,
03458 DBUS_HEADER_FIELD_ERROR_NAME,
03459 DBUS_TYPE_STRING,
03460 error_name);
03461 }
03462
03473 const char*
03474 dbus_message_get_error_name (DBusMessage *message)
03475 {
03476 const char *v;
03477
03478 _dbus_return_val_if_fail (message != NULL, NULL);
03479
03480 v = NULL;
03481 _dbus_header_get_field_basic (&message->header,
03482 DBUS_HEADER_FIELD_ERROR_NAME,
03483 DBUS_TYPE_STRING,
03484 (void *) &v);
03485 return v;
03486 }
03487
03501 dbus_bool_t
03502 dbus_message_set_destination (DBusMessage *message,
03503 const char *destination)
03504 {
03505 _dbus_return_val_if_fail (message != NULL, FALSE);
03506 _dbus_return_val_if_fail (!message->locked, FALSE);
03507 _dbus_return_val_if_fail (destination == NULL ||
03508 _dbus_check_is_valid_bus_name (destination),
03509 FALSE);
03510
03511 return set_or_delete_string_field (message,
03512 DBUS_HEADER_FIELD_DESTINATION,
03513 DBUS_TYPE_STRING,
03514 destination);
03515 }
03516
03526 const char*
03527 dbus_message_get_destination (DBusMessage *message)
03528 {
03529 const char *v;
03530
03531 _dbus_return_val_if_fail (message != NULL, NULL);
03532
03533 v = NULL;
03534 _dbus_header_get_field_basic (&message->header,
03535 DBUS_HEADER_FIELD_DESTINATION,
03536 DBUS_TYPE_STRING,
03537 (void *) &v);
03538 return v;
03539 }
03540
03555 dbus_bool_t
03556 dbus_message_set_sender (DBusMessage *message,
03557 const char *sender)
03558 {
03559 _dbus_return_val_if_fail (message != NULL, FALSE);
03560 _dbus_return_val_if_fail (!message->locked, FALSE);
03561 _dbus_return_val_if_fail (sender == NULL ||
03562 _dbus_check_is_valid_bus_name (sender),
03563 FALSE);
03564
03565 return set_or_delete_string_field (message,
03566 DBUS_HEADER_FIELD_SENDER,
03567 DBUS_TYPE_STRING,
03568 sender);
03569 }
03570
03586 const char*
03587 dbus_message_get_sender (DBusMessage *message)
03588 {
03589 const char *v;
03590
03591 _dbus_return_val_if_fail (message != NULL, NULL);
03592
03593 v = NULL;
03594 _dbus_header_get_field_basic (&message->header,
03595 DBUS_HEADER_FIELD_SENDER,
03596 DBUS_TYPE_STRING,
03597 (void *) &v);
03598 return v;
03599 }
03600
03619 const char*
03620 dbus_message_get_signature (DBusMessage *message)
03621 {
03622 const DBusString *type_str;
03623 int type_pos;
03624
03625 _dbus_return_val_if_fail (message != NULL, NULL);
03626
03627 get_const_signature (&message->header, &type_str, &type_pos);
03628
03629 return _dbus_string_get_const_data_len (type_str, type_pos, 0);
03630 }
03631
03632 static dbus_bool_t
03633 _dbus_message_has_type_interface_member (DBusMessage *message,
03634 int type,
03635 const char *iface,
03636 const char *member)
03637 {
03638 const char *n;
03639
03640 _dbus_assert (message != NULL);
03641 _dbus_assert (iface != NULL);
03642 _dbus_assert (member != NULL);
03643
03644 if (dbus_message_get_type (message) != type)
03645 return FALSE;
03646
03647
03648
03649
03650
03651 n = dbus_message_get_member (message);
03652
03653 if (n && strcmp (n, member) == 0)
03654 {
03655 n = dbus_message_get_interface (message);
03656
03657 if (n == NULL || strcmp (n, iface) == 0)
03658 return TRUE;
03659 }
03660
03661 return FALSE;
03662 }
03663
03678 dbus_bool_t
03679 dbus_message_is_method_call (DBusMessage *message,
03680 const char *iface,
03681 const char *method)
03682 {
03683 _dbus_return_val_if_fail (message != NULL, FALSE);
03684 _dbus_return_val_if_fail (iface != NULL, FALSE);
03685 _dbus_return_val_if_fail (method != NULL, FALSE);
03686
03687
03688
03689
03690 return _dbus_message_has_type_interface_member (message,
03691 DBUS_MESSAGE_TYPE_METHOD_CALL,
03692 iface, method);
03693 }
03694
03706 dbus_bool_t
03707 dbus_message_is_signal (DBusMessage *message,
03708 const char *iface,
03709 const char *signal_name)
03710 {
03711 _dbus_return_val_if_fail (message != NULL, FALSE);
03712 _dbus_return_val_if_fail (iface != NULL, FALSE);
03713 _dbus_return_val_if_fail (signal_name != NULL, FALSE);
03714
03715
03716
03717
03718 return _dbus_message_has_type_interface_member (message,
03719 DBUS_MESSAGE_TYPE_SIGNAL,
03720 iface, signal_name);
03721 }
03722
03733 dbus_bool_t
03734 dbus_message_is_error (DBusMessage *message,
03735 const char *error_name)
03736 {
03737 const char *n;
03738
03739 _dbus_return_val_if_fail (message != NULL, FALSE);
03740 _dbus_return_val_if_fail (error_name != NULL, FALSE);
03741
03742
03743
03744
03745 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
03746 return FALSE;
03747
03748 n = dbus_message_get_error_name (message);
03749
03750 if (n && strcmp (n, error_name) == 0)
03751 return TRUE;
03752 else
03753 return FALSE;
03754 }
03755
03766 dbus_bool_t
03767 dbus_message_has_destination (DBusMessage *message,
03768 const char *name)
03769 {
03770 const char *s;
03771
03772 _dbus_return_val_if_fail (message != NULL, FALSE);
03773 _dbus_return_val_if_fail (name != NULL, FALSE);
03774
03775
03776
03777
03778 s = dbus_message_get_destination (message);
03779
03780 if (s && strcmp (s, name) == 0)
03781 return TRUE;
03782 else
03783 return FALSE;
03784 }
03785
03801 dbus_bool_t
03802 dbus_message_has_sender (DBusMessage *message,
03803 const char *name)
03804 {
03805 const char *s;
03806
03807 _dbus_return_val_if_fail (message != NULL, FALSE);
03808 _dbus_return_val_if_fail (name != NULL, FALSE);
03809
03810
03811
03812
03813 s = dbus_message_get_sender (message);
03814
03815 if (s && strcmp (s, name) == 0)
03816 return TRUE;
03817 else
03818 return FALSE;
03819 }
03820
03830 dbus_bool_t
03831 dbus_message_has_signature (DBusMessage *message,
03832 const char *signature)
03833 {
03834 const char *s;
03835
03836 _dbus_return_val_if_fail (message != NULL, FALSE);
03837 _dbus_return_val_if_fail (signature != NULL, FALSE);
03838
03839
03840
03841
03842 s = dbus_message_get_signature (message);
03843
03844 if (s && strcmp (s, signature) == 0)
03845 return TRUE;
03846 else
03847 return FALSE;
03848 }
03849
03872 dbus_bool_t
03873 dbus_set_error_from_message (DBusError *error,
03874 DBusMessage *message)
03875 {
03876 const char *str;
03877
03878 _dbus_return_val_if_fail (message != NULL, FALSE);
03879 _dbus_return_val_if_error_is_set (error, FALSE);
03880
03881 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
03882 return FALSE;
03883
03884 str = NULL;
03885 dbus_message_get_args (message, NULL,
03886 DBUS_TYPE_STRING, &str,
03887 DBUS_TYPE_INVALID);
03888
03889 dbus_set_error (error, dbus_message_get_error_name (message),
03890 str ? "%s" : NULL, str);
03891
03892 return TRUE;
03893 }
03894
03901 dbus_bool_t
03902 dbus_message_contains_unix_fds(DBusMessage *message)
03903 {
03904 #ifdef HAVE_UNIX_FD_PASSING
03905 _dbus_assert(message);
03906
03907 return message->n_unix_fds > 0;
03908 #else
03909 return FALSE;
03910 #endif
03911 }
03912
03931 #define INITIAL_LOADER_DATA_LEN 32
03932
03939 DBusMessageLoader*
03940 _dbus_message_loader_new (void)
03941 {
03942 DBusMessageLoader *loader;
03943
03944 loader = dbus_new0 (DBusMessageLoader, 1);
03945 if (loader == NULL)
03946 return NULL;
03947
03948 loader->refcount = 1;
03949
03950 loader->corrupted = FALSE;
03951 loader->corruption_reason = DBUS_VALID;
03952
03953
03954 loader->max_message_size = DBUS_MAXIMUM_MESSAGE_LENGTH;
03955
03956
03957
03958
03959
03960 loader->max_message_unix_fds = DBUS_DEFAULT_MESSAGE_UNIX_FDS;
03961
03962 if (!_dbus_string_init (&loader->data))
03963 {
03964 dbus_free (loader);
03965 return NULL;
03966 }
03967
03968
03969 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
03970 _dbus_string_set_length (&loader->data, 0);
03971
03972 #ifdef HAVE_UNIX_FD_PASSING
03973 loader->unix_fds = NULL;
03974 loader->n_unix_fds = loader->n_unix_fds_allocated = 0;
03975 loader->unix_fds_outstanding = FALSE;
03976 #endif
03977
03978 return loader;
03979 }
03980
03987 DBusMessageLoader *
03988 _dbus_message_loader_ref (DBusMessageLoader *loader)
03989 {
03990 loader->refcount += 1;
03991
03992 return loader;
03993 }
03994
04001 void
04002 _dbus_message_loader_unref (DBusMessageLoader *loader)
04003 {
04004 loader->refcount -= 1;
04005 if (loader->refcount == 0)
04006 {
04007 #ifdef HAVE_UNIX_FD_PASSING
04008 close_unix_fds(loader->unix_fds, &loader->n_unix_fds);
04009 dbus_free(loader->unix_fds);
04010 #endif
04011 _dbus_list_foreach (&loader->messages,
04012 (DBusForeachFunction) dbus_message_unref,
04013 NULL);
04014 _dbus_list_clear (&loader->messages);
04015 _dbus_string_free (&loader->data);
04016 dbus_free (loader);
04017 }
04018 }
04019
04038 void
04039 _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
04040 DBusString **buffer)
04041 {
04042 _dbus_assert (!loader->buffer_outstanding);
04043
04044 *buffer = &loader->data;
04045
04046 loader->buffer_outstanding = TRUE;
04047 }
04048
04058 void
04059 _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
04060 DBusString *buffer)
04061 {
04062 _dbus_assert (loader->buffer_outstanding);
04063 _dbus_assert (buffer == &loader->data);
04064
04065 loader->buffer_outstanding = FALSE;
04066 }
04067
04078 dbus_bool_t
04079 _dbus_message_loader_get_unix_fds(DBusMessageLoader *loader,
04080 int **fds,
04081 unsigned *max_n_fds)
04082 {
04083 #ifdef HAVE_UNIX_FD_PASSING
04084 _dbus_assert (!loader->unix_fds_outstanding);
04085
04086
04087
04088
04089
04090
04091
04092
04093
04094 if (loader->n_unix_fds_allocated < loader->max_message_unix_fds)
04095 {
04096 int *a = dbus_realloc(loader->unix_fds,
04097 loader->max_message_unix_fds * sizeof(loader->unix_fds[0]));
04098
04099 if (!a)
04100 return FALSE;
04101
04102 loader->unix_fds = a;
04103 loader->n_unix_fds_allocated = loader->max_message_unix_fds;
04104 }
04105
04106 *fds = loader->unix_fds + loader->n_unix_fds;
04107 *max_n_fds = loader->n_unix_fds_allocated - loader->n_unix_fds;
04108
04109 loader->unix_fds_outstanding = TRUE;
04110 return TRUE;
04111 #else
04112 _dbus_assert_not_reached("Platform doesn't support unix fd passing");
04113 return FALSE;
04114 #endif
04115 }
04116
04127 void
04128 _dbus_message_loader_return_unix_fds(DBusMessageLoader *loader,
04129 int *fds,
04130 unsigned n_fds)
04131 {
04132 #ifdef HAVE_UNIX_FD_PASSING
04133 _dbus_assert(loader->unix_fds_outstanding);
04134 _dbus_assert(loader->unix_fds + loader->n_unix_fds == fds);
04135 _dbus_assert(loader->n_unix_fds + n_fds <= loader->n_unix_fds_allocated);
04136
04137 loader->n_unix_fds += n_fds;
04138 loader->unix_fds_outstanding = FALSE;
04139
04140 if (n_fds && loader->unix_fds_change)
04141 loader->unix_fds_change (loader->unix_fds_change_data);
04142 #else
04143 _dbus_assert_not_reached("Platform doesn't support unix fd passing");
04144 #endif
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
04170
04171
04172
04173 static dbus_bool_t
04174 load_message (DBusMessageLoader *loader,
04175 DBusMessage *message,
04176 int byte_order,
04177 int fields_array_len,
04178 int header_len,
04179 int body_len)
04180 {
04181 dbus_bool_t oom;
04182 DBusValidity validity;
04183 const DBusString *type_str;
04184 int type_pos;
04185 DBusValidationMode mode;
04186 dbus_uint32_t n_unix_fds = 0;
04187
04188 mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
04189
04190 oom = FALSE;
04191
04192 #if 0
04193 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len );
04194 #endif
04195
04196
04197 _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
04198 _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
04199
04200 if (!_dbus_header_load (&message->header,
04201 mode,
04202 &validity,
04203 byte_order,
04204 fields_array_len,
04205 header_len,
04206 body_len,
04207 &loader->data, 0,
04208 _dbus_string_get_length (&loader->data)))
04209 {
04210 _dbus_verbose ("Failed to load header for new message code %d\n", validity);
04211
04212
04213
04214 _dbus_assert (validity != DBUS_VALID);
04215
04216 if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
04217 oom = TRUE;
04218 else
04219 {
04220 loader->corrupted = TRUE;
04221 loader->corruption_reason = validity;
04222 }
04223 goto failed;
04224 }
04225
04226 _dbus_assert (validity == DBUS_VALID);
04227
04228
04229 if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
04230 {
04231 get_const_signature (&message->header, &type_str, &type_pos);
04232
04233
04234
04235
04236 validity = _dbus_validate_body_with_reason (type_str,
04237 type_pos,
04238 byte_order,
04239 NULL,
04240 &loader->data,
04241 header_len,
04242 body_len);
04243 if (validity != DBUS_VALID)
04244 {
04245 _dbus_verbose ("Failed to validate message body code %d\n", validity);
04246
04247 loader->corrupted = TRUE;
04248 loader->corruption_reason = validity;
04249
04250 goto failed;
04251 }
04252 }
04253
04254
04255 _dbus_header_get_field_basic(&message->header,
04256 DBUS_HEADER_FIELD_UNIX_FDS,
04257 DBUS_TYPE_UINT32,
04258 &n_unix_fds);
04259
04260 #ifdef HAVE_UNIX_FD_PASSING
04261
04262 if (n_unix_fds > loader->n_unix_fds)
04263 {
04264 _dbus_verbose("Message contains references to more unix fds than were sent %u != %u\n",
04265 n_unix_fds, loader->n_unix_fds);
04266
04267 loader->corrupted = TRUE;
04268 loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
04269 goto failed;
04270 }
04271
04272
04273
04274 dbus_free(message->unix_fds);
04275
04276 if (n_unix_fds > 0)
04277 {
04278 message->unix_fds = _dbus_memdup(loader->unix_fds, n_unix_fds * sizeof(message->unix_fds[0]));
04279 if (message->unix_fds == NULL)
04280 {
04281 _dbus_verbose ("Failed to allocate file descriptor array\n");
04282 oom = TRUE;
04283 goto failed;
04284 }
04285
04286 message->n_unix_fds_allocated = message->n_unix_fds = n_unix_fds;
04287 loader->n_unix_fds -= n_unix_fds;
04288 memmove (loader->unix_fds, loader->unix_fds + n_unix_fds, loader->n_unix_fds * sizeof (loader->unix_fds[0]));
04289
04290 if (loader->unix_fds_change)
04291 loader->unix_fds_change (loader->unix_fds_change_data);
04292 }
04293 else
04294 message->unix_fds = NULL;
04295
04296 #else
04297
04298 if (n_unix_fds > 0)
04299 {
04300 _dbus_verbose ("Hmm, message claims to come with file descriptors "
04301 "but that's not supported on our platform, disconnecting.\n");
04302
04303 loader->corrupted = TRUE;
04304 loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
04305 goto failed;
04306 }
04307
04308 #endif
04309
04310
04311
04312 if (!_dbus_list_append (&loader->messages, message))
04313 {
04314 _dbus_verbose ("Failed to append new message to loader queue\n");
04315 oom = TRUE;
04316 goto failed;
04317 }
04318
04319 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
04320 _dbus_assert (_dbus_string_get_length (&loader->data) >=
04321 (header_len + body_len));
04322
04323 if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
04324 {
04325 _dbus_verbose ("Failed to move body into new message\n");
04326 oom = TRUE;
04327 goto failed;
04328 }
04329
04330 _dbus_string_delete (&loader->data, 0, header_len + body_len);
04331
04332
04333 _dbus_string_compact (&loader->data, 2048);
04334
04335 _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
04336 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
04337
04338 _dbus_verbose ("Loaded message %p\n", message);
04339
04340 _dbus_assert (!oom);
04341 _dbus_assert (!loader->corrupted);
04342 _dbus_assert (loader->messages != NULL);
04343 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
04344
04345 return TRUE;
04346
04347 failed:
04348
04349
04350
04351
04352 _dbus_list_remove_last (&loader->messages, message);
04353
04354 if (oom)
04355 _dbus_assert (!loader->corrupted);
04356 else
04357 _dbus_assert (loader->corrupted);
04358
04359 _dbus_verbose_bytes_of_string (&loader->data, 0, _dbus_string_get_length (&loader->data));
04360
04361 return FALSE;
04362 }
04363
04378 dbus_bool_t
04379 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
04380 {
04381 while (!loader->corrupted &&
04382 _dbus_string_get_length (&loader->data) >= DBUS_MINIMUM_HEADER_SIZE)
04383 {
04384 DBusValidity validity;
04385 int byte_order, fields_array_len, header_len, body_len;
04386
04387 if (_dbus_header_have_message_untrusted (loader->max_message_size,
04388 &validity,
04389 &byte_order,
04390 &fields_array_len,
04391 &header_len,
04392 &body_len,
04393 &loader->data, 0,
04394 _dbus_string_get_length (&loader->data)))
04395 {
04396 DBusMessage *message;
04397
04398 _dbus_assert (validity == DBUS_VALID);
04399
04400 message = dbus_message_new_empty_header ();
04401 if (message == NULL)
04402 return FALSE;
04403
04404 if (!load_message (loader, message,
04405 byte_order, fields_array_len,
04406 header_len, body_len))
04407 {
04408 dbus_message_unref (message);
04409
04410
04411
04412 return loader->corrupted;
04413 }
04414
04415 _dbus_assert (loader->messages != NULL);
04416 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
04417 }
04418 else
04419 {
04420 _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
04421 validity);
04422 if (validity != DBUS_VALID)
04423 {
04424 loader->corrupted = TRUE;
04425 loader->corruption_reason = validity;
04426 }
04427 return TRUE;
04428 }
04429 }
04430
04431 return TRUE;
04432 }
04433
04441 DBusMessage*
04442 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
04443 {
04444 if (loader->messages)
04445 return loader->messages->data;
04446 else
04447 return NULL;
04448 }
04449
04458 DBusMessage*
04459 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
04460 {
04461 return _dbus_list_pop_first (&loader->messages);
04462 }
04463
04472 DBusList*
04473 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
04474 {
04475 return _dbus_list_pop_first_link (&loader->messages);
04476 }
04477
04484 void
04485 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
04486 DBusList *link)
04487 {
04488 _dbus_list_prepend_link (&loader->messages, link);
04489 }
04490
04500 dbus_bool_t
04501 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
04502 {
04503 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
04504 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
04505 return loader->corrupted;
04506 }
04507
04514 DBusValidity
04515 _dbus_message_loader_get_corruption_reason (DBusMessageLoader *loader)
04516 {
04517 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
04518 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
04519
04520 return loader->corruption_reason;
04521 }
04522
04529 void
04530 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
04531 long size)
04532 {
04533 if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
04534 {
04535 _dbus_verbose ("clamping requested max message size %ld to %d\n",
04536 size, DBUS_MAXIMUM_MESSAGE_LENGTH);
04537 size = DBUS_MAXIMUM_MESSAGE_LENGTH;
04538 }
04539 loader->max_message_size = size;
04540 }
04541
04548 long
04549 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
04550 {
04551 return loader->max_message_size;
04552 }
04553
04560 void
04561 _dbus_message_loader_set_max_message_unix_fds (DBusMessageLoader *loader,
04562 long n)
04563 {
04564 if (n > DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
04565 {
04566 _dbus_verbose ("clamping requested max message unix_fds %ld to %d\n",
04567 n, DBUS_MAXIMUM_MESSAGE_UNIX_FDS);
04568 n = DBUS_MAXIMUM_MESSAGE_UNIX_FDS;
04569 }
04570 loader->max_message_unix_fds = n;
04571 }
04572
04579 long
04580 _dbus_message_loader_get_max_message_unix_fds (DBusMessageLoader *loader)
04581 {
04582 return loader->max_message_unix_fds;
04583 }
04584
04590 int
04591 _dbus_message_loader_get_pending_fds_count (DBusMessageLoader *loader)
04592 {
04593 #ifdef HAVE_UNIX_FD_PASSING
04594 return loader->n_unix_fds;
04595 #else
04596 return 0;
04597 #endif
04598 }
04599
04608 void
04609 _dbus_message_loader_set_pending_fds_function (DBusMessageLoader *loader,
04610 void (* callback) (void *),
04611 void *data)
04612 {
04613 #ifdef HAVE_UNIX_FD_PASSING
04614 loader->unix_fds_change = callback;
04615 loader->unix_fds_change_data = data;
04616 #endif
04617 }
04618
04619 static DBusDataSlotAllocator slot_allocator =
04620 _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (message_slots));
04621
04636 dbus_bool_t
04637 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
04638 {
04639 return _dbus_data_slot_allocator_alloc (&slot_allocator,
04640 slot_p);
04641 }
04642
04654 void
04655 dbus_message_free_data_slot (dbus_int32_t *slot_p)
04656 {
04657 _dbus_return_if_fail (*slot_p >= 0);
04658
04659 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
04660 }
04661
04675 dbus_bool_t
04676 dbus_message_set_data (DBusMessage *message,
04677 dbus_int32_t slot,
04678 void *data,
04679 DBusFreeFunction free_data_func)
04680 {
04681 DBusFreeFunction old_free_func;
04682 void *old_data;
04683 dbus_bool_t retval;
04684
04685 _dbus_return_val_if_fail (message != NULL, FALSE);
04686 _dbus_return_val_if_fail (slot >= 0, FALSE);
04687
04688 retval = _dbus_data_slot_list_set (&slot_allocator,
04689 &message->slot_list,
04690 slot, data, free_data_func,
04691 &old_free_func, &old_data);
04692
04693 if (retval)
04694 {
04695
04696 if (old_free_func)
04697 (* old_free_func) (old_data);
04698 }
04699
04700 return retval;
04701 }
04702
04711 void*
04712 dbus_message_get_data (DBusMessage *message,
04713 dbus_int32_t slot)
04714 {
04715 void *res;
04716
04717 _dbus_return_val_if_fail (message != NULL, NULL);
04718
04719 res = _dbus_data_slot_list_get (&slot_allocator,
04720 &message->slot_list,
04721 slot);
04722
04723 return res;
04724 }
04725
04739 int
04740 dbus_message_type_from_string (const char *type_str)
04741 {
04742 if (strcmp (type_str, "method_call") == 0)
04743 return DBUS_MESSAGE_TYPE_METHOD_CALL;
04744 if (strcmp (type_str, "method_return") == 0)
04745 return DBUS_MESSAGE_TYPE_METHOD_RETURN;
04746 else if (strcmp (type_str, "signal") == 0)
04747 return DBUS_MESSAGE_TYPE_SIGNAL;
04748 else if (strcmp (type_str, "error") == 0)
04749 return DBUS_MESSAGE_TYPE_ERROR;
04750 else
04751 return DBUS_MESSAGE_TYPE_INVALID;
04752 }
04753
04767 const char *
04768 dbus_message_type_to_string (int type)
04769 {
04770 switch (type)
04771 {
04772 case DBUS_MESSAGE_TYPE_METHOD_CALL:
04773 return "method_call";
04774 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
04775 return "method_return";
04776 case DBUS_MESSAGE_TYPE_SIGNAL:
04777 return "signal";
04778 case DBUS_MESSAGE_TYPE_ERROR:
04779 return "error";
04780 default:
04781 return "invalid";
04782 }
04783 }
04784
04797 dbus_bool_t
04798 dbus_message_marshal (DBusMessage *msg,
04799 char **marshalled_data_p,
04800 int *len_p)
04801 {
04802 DBusString tmp;
04803 dbus_bool_t was_locked;
04804
04805 _dbus_return_val_if_fail (msg != NULL, FALSE);
04806 _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
04807 _dbus_return_val_if_fail (len_p != NULL, FALSE);
04808
04809 if (!_dbus_string_init (&tmp))
04810 return FALSE;
04811
04812
04813 was_locked = msg->locked;
04814
04815 if (!was_locked)
04816 dbus_message_lock (msg);
04817
04818 if (!_dbus_string_copy (&(msg->header.data), 0, &tmp, 0))
04819 goto fail;
04820
04821 *len_p = _dbus_string_get_length (&tmp);
04822
04823 if (!_dbus_string_copy (&(msg->body), 0, &tmp, *len_p))
04824 goto fail;
04825
04826 *len_p = _dbus_string_get_length (&tmp);
04827
04828 if (!_dbus_string_steal_data (&tmp, marshalled_data_p))
04829 goto fail;
04830
04831 _dbus_string_free (&tmp);
04832
04833 if (!was_locked)
04834 msg->locked = FALSE;
04835
04836 return TRUE;
04837
04838 fail:
04839 _dbus_string_free (&tmp);
04840
04841 if (!was_locked)
04842 msg->locked = FALSE;
04843
04844 return FALSE;
04845 }
04846
04859 DBusMessage *
04860 dbus_message_demarshal (const char *str,
04861 int len,
04862 DBusError *error)
04863 {
04864 DBusMessageLoader *loader;
04865 DBusString *buffer;
04866 DBusMessage *msg;
04867
04868 _dbus_return_val_if_fail (str != NULL, NULL);
04869
04870 loader = _dbus_message_loader_new ();
04871
04872 if (loader == NULL)
04873 return NULL;
04874
04875 _dbus_message_loader_get_buffer (loader, &buffer);
04876
04877 if (!_dbus_string_append_len (buffer, str, len))
04878 goto fail_oom;
04879
04880 _dbus_message_loader_return_buffer (loader, buffer);
04881
04882 if (!_dbus_message_loader_queue_messages (loader))
04883 goto fail_oom;
04884
04885 if (_dbus_message_loader_get_is_corrupted (loader))
04886 goto fail_corrupt;
04887
04888 msg = _dbus_message_loader_pop_message (loader);
04889
04890 if (!msg)
04891 goto fail_oom;
04892
04893 _dbus_message_loader_unref (loader);
04894 return msg;
04895
04896 fail_corrupt:
04897 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted (%s)",
04898 _dbus_validity_to_error_message (loader->corruption_reason));
04899 _dbus_message_loader_unref (loader);
04900 return NULL;
04901
04902 fail_oom:
04903 _DBUS_SET_OOM (error);
04904 _dbus_message_loader_unref (loader);
04905 return NULL;
04906 }
04907
04920 int
04921 dbus_message_demarshal_bytes_needed(const char *buf,
04922 int len)
04923 {
04924 DBusString str;
04925 int byte_order, fields_array_len, header_len, body_len;
04926 DBusValidity validity = DBUS_VALID;
04927 int have_message;
04928
04929 if (!buf || len < DBUS_MINIMUM_HEADER_SIZE)
04930 return 0;
04931
04932 if (len > DBUS_MAXIMUM_MESSAGE_LENGTH)
04933 len = DBUS_MAXIMUM_MESSAGE_LENGTH;
04934 _dbus_string_init_const_len (&str, buf, len);
04935
04936 validity = DBUS_VALID;
04937 have_message
04938 = _dbus_header_have_message_untrusted(DBUS_MAXIMUM_MESSAGE_LENGTH,
04939 &validity, &byte_order,
04940 &fields_array_len,
04941 &header_len,
04942 &body_len,
04943 &str, 0,
04944 len);
04945 _dbus_string_free (&str);
04946
04947 if (validity == DBUS_VALID)
04948 {
04949 _dbus_assert (have_message || (header_len + body_len) > len);
04950 (void) have_message;
04951 return header_len + body_len;
04952 }
04953 else
04954 {
04955 return -1;
04956 }
04957 }
04958
04980 void
04981 dbus_message_set_allow_interactive_authorization (DBusMessage *message,
04982 dbus_bool_t allow)
04983 {
04984 _dbus_return_if_fail (message != NULL);
04985 _dbus_return_if_fail (!message->locked);
04986
04987 _dbus_header_toggle_flag (&message->header,
04988 DBUS_HEADER_FLAG_ALLOW_INTERACTIVE_AUTHORIZATION,
04989 allow);
04990 }
04991
04998 dbus_bool_t
04999 dbus_message_get_allow_interactive_authorization (DBusMessage *message)
05000 {
05001 _dbus_return_val_if_fail (message != NULL, FALSE);
05002
05003 return _dbus_header_get_flag (&message->header,
05004 DBUS_HEADER_FLAG_ALLOW_INTERACTIVE_AUTHORIZATION);
05005 }
05006
05009