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 static void dbus_message_finalize (DBusMessage *message);
00045
00056
00057
00059 _DBUS_STRING_DEFINE_STATIC(_dbus_empty_signature_str, "");
00060
00061
00062
00063
00064 enum {
00065 DBUS_MESSAGE_ITER_TYPE_READER = 3,
00066 DBUS_MESSAGE_ITER_TYPE_WRITER = 7
00067 };
00068
00070 typedef struct DBusMessageRealIter DBusMessageRealIter;
00071
00077 struct DBusMessageRealIter
00078 {
00079 DBusMessage *message;
00080 dbus_uint32_t changed_stamp : CHANGED_STAMP_BITS;
00081 dbus_uint32_t iter_type : 3;
00082 dbus_uint32_t sig_refcount : 8;
00083 union
00084 {
00085 DBusTypeWriter writer;
00086 DBusTypeReader reader;
00087 } u;
00088 };
00089
00090 static void
00091 get_const_signature (DBusHeader *header,
00092 const DBusString **type_str_p,
00093 int *type_pos_p)
00094 {
00095 if (_dbus_header_get_field_raw (header,
00096 DBUS_HEADER_FIELD_SIGNATURE,
00097 type_str_p,
00098 type_pos_p))
00099 {
00100 *type_pos_p += 1;
00101 }
00102 else
00103 {
00104 *type_str_p = &_dbus_empty_signature_str;
00105 *type_pos_p = 0;
00106 }
00107 }
00108
00114 static void
00115 _dbus_message_byteswap (DBusMessage *message)
00116 {
00117 const DBusString *type_str;
00118 int type_pos;
00119
00120 if (message->byte_order == DBUS_COMPILER_BYTE_ORDER)
00121 return;
00122
00123 _dbus_verbose ("Swapping message into compiler byte order\n");
00124
00125 get_const_signature (&message->header, &type_str, &type_pos);
00126
00127 _dbus_marshal_byteswap (type_str, type_pos,
00128 message->byte_order,
00129 DBUS_COMPILER_BYTE_ORDER,
00130 &message->body, 0);
00131
00132 message->byte_order = DBUS_COMPILER_BYTE_ORDER;
00133
00134 _dbus_header_byteswap (&message->header, DBUS_COMPILER_BYTE_ORDER);
00135 }
00136
00143 #define ensure_byte_order(message) \
00144 if (message->byte_order != DBUS_COMPILER_BYTE_ORDER) \
00145 _dbus_message_byteswap (message)
00146
00157 void
00158 _dbus_message_get_network_data (DBusMessage *message,
00159 const DBusString **header,
00160 const DBusString **body)
00161 {
00162 _dbus_assert (message->locked);
00163
00164 *header = &message->header.data;
00165 *body = &message->body;
00166 }
00167
00177 void _dbus_message_get_unix_fds(DBusMessage *message,
00178 const int **fds,
00179 unsigned *n_fds)
00180 {
00181 _dbus_assert (message->locked);
00182
00183 #ifdef HAVE_UNIX_FD_PASSING
00184 *fds = message->unix_fds;
00185 *n_fds = message->n_unix_fds;
00186 #else
00187 *fds = NULL;
00188 *n_fds = 0;
00189 #endif
00190 }
00191
00203 void
00204 dbus_message_set_serial (DBusMessage *message,
00205 dbus_uint32_t serial)
00206 {
00207 _dbus_return_if_fail (message != NULL);
00208 _dbus_return_if_fail (!message->locked);
00209
00210 _dbus_header_set_serial (&message->header, serial);
00211 }
00212
00224 void
00225 _dbus_message_add_counter_link (DBusMessage *message,
00226 DBusList *link)
00227 {
00228
00229
00230
00231
00232
00233
00234 if (message->counters == NULL)
00235 {
00236 message->size_counter_delta =
00237 _dbus_string_get_length (&message->header.data) +
00238 _dbus_string_get_length (&message->body);
00239
00240 #ifdef HAVE_UNIX_FD_PASSING
00241 message->unix_fd_counter_delta = message->n_unix_fds;
00242 #endif
00243
00244 #if 0
00245 _dbus_verbose ("message has size %ld\n",
00246 message->size_counter_delta);
00247 #endif
00248 }
00249
00250 _dbus_list_append_link (&message->counters, link);
00251
00252 _dbus_counter_adjust_size (link->data, message->size_counter_delta);
00253
00254 #ifdef HAVE_UNIX_FD_PASSING
00255 _dbus_counter_adjust_unix_fd (link->data, message->unix_fd_counter_delta);
00256 #endif
00257 }
00258
00268 dbus_bool_t
00269 _dbus_message_add_counter (DBusMessage *message,
00270 DBusCounter *counter)
00271 {
00272 DBusList *link;
00273
00274 link = _dbus_list_alloc_link (counter);
00275 if (link == NULL)
00276 return FALSE;
00277
00278 _dbus_counter_ref (counter);
00279 _dbus_message_add_counter_link (message, link);
00280
00281 return TRUE;
00282 }
00283
00292 void
00293 _dbus_message_remove_counter (DBusMessage *message,
00294 DBusCounter *counter,
00295 DBusList **link_return)
00296 {
00297 DBusList *link;
00298
00299 link = _dbus_list_find_last (&message->counters,
00300 counter);
00301 _dbus_assert (link != NULL);
00302
00303 _dbus_list_unlink (&message->counters,
00304 link);
00305 if (link_return)
00306 *link_return = link;
00307 else
00308 _dbus_list_free_link (link);
00309
00310 _dbus_counter_adjust_size (counter, - message->size_counter_delta);
00311
00312 #ifdef HAVE_UNIX_FD_PASSING
00313 _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
00314 #endif
00315
00316 _dbus_counter_unref (counter);
00317 }
00318
00329 void
00330 dbus_message_lock (DBusMessage *message)
00331 {
00332 if (!message->locked)
00333 {
00334 _dbus_header_update_lengths (&message->header,
00335 _dbus_string_get_length (&message->body));
00336
00337
00338 _dbus_assert (_dbus_string_get_length (&message->body) == 0 ||
00339 dbus_message_get_signature (message) != NULL);
00340
00341 message->locked = TRUE;
00342 }
00343 }
00344
00345 static dbus_bool_t
00346 set_or_delete_string_field (DBusMessage *message,
00347 int field,
00348 int typecode,
00349 const char *value)
00350 {
00351 if (value == NULL)
00352 return _dbus_header_delete_field (&message->header, field);
00353 else
00354 return _dbus_header_set_field_basic (&message->header,
00355 field,
00356 typecode,
00357 &value);
00358 }
00359
00360 #if 0
00361
00385 static dbus_bool_t
00386 _dbus_message_set_signature (DBusMessage *message,
00387 const char *signature)
00388 {
00389 _dbus_return_val_if_fail (message != NULL, FALSE);
00390 _dbus_return_val_if_fail (!message->locked, FALSE);
00391 _dbus_return_val_if_fail (signature == NULL ||
00392 _dbus_check_is_valid_signature (signature));
00393
00394 _dbus_return_val_if_fail (_dbus_string_get_length (&message->body) == 0 ||
00395 signature != NULL);
00396
00397 return set_or_delete_string_field (message,
00398 DBUS_HEADER_FIELD_SIGNATURE,
00399 DBUS_TYPE_SIGNATURE,
00400 signature);
00401 }
00402 #endif
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00451 #define MAX_MESSAGE_SIZE_TO_CACHE 10 * _DBUS_ONE_KILOBYTE
00452
00454 #define MAX_MESSAGE_CACHE_SIZE 5
00455
00456 _DBUS_DEFINE_GLOBAL_LOCK (message_cache);
00457 static DBusMessage *message_cache[MAX_MESSAGE_CACHE_SIZE];
00458 static int message_cache_count = 0;
00459 static dbus_bool_t message_cache_shutdown_registered = FALSE;
00460
00461 static void
00462 dbus_message_cache_shutdown (void *data)
00463 {
00464 int i;
00465
00466 _DBUS_LOCK (message_cache);
00467
00468 i = 0;
00469 while (i < MAX_MESSAGE_CACHE_SIZE)
00470 {
00471 if (message_cache[i])
00472 dbus_message_finalize (message_cache[i]);
00473
00474 ++i;
00475 }
00476
00477 message_cache_count = 0;
00478 message_cache_shutdown_registered = FALSE;
00479
00480 _DBUS_UNLOCK (message_cache);
00481 }
00482
00490 static DBusMessage*
00491 dbus_message_get_cached (void)
00492 {
00493 DBusMessage *message;
00494 int i;
00495
00496 message = NULL;
00497
00498 _DBUS_LOCK (message_cache);
00499
00500 _dbus_assert (message_cache_count >= 0);
00501
00502 if (message_cache_count == 0)
00503 {
00504 _DBUS_UNLOCK (message_cache);
00505 return NULL;
00506 }
00507
00508
00509
00510
00511
00512 _dbus_assert (message_cache_shutdown_registered);
00513
00514 i = 0;
00515 while (i < MAX_MESSAGE_CACHE_SIZE)
00516 {
00517 if (message_cache[i])
00518 {
00519 message = message_cache[i];
00520 message_cache[i] = NULL;
00521 message_cache_count -= 1;
00522 break;
00523 }
00524 ++i;
00525 }
00526 _dbus_assert (message_cache_count >= 0);
00527 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
00528 _dbus_assert (message != NULL);
00529
00530 _dbus_assert (message->refcount.value == 0);
00531 _dbus_assert (message->counters == NULL);
00532
00533 _DBUS_UNLOCK (message_cache);
00534
00535 return message;
00536 }
00537
00538 #ifdef HAVE_UNIX_FD_PASSING
00539 static void
00540 close_unix_fds(int *fds, unsigned *n_fds)
00541 {
00542 DBusError e;
00543 int i;
00544
00545 if (*n_fds <= 0)
00546 return;
00547
00548 dbus_error_init(&e);
00549
00550 for (i = 0; i < *n_fds; i++)
00551 {
00552 if (!_dbus_close(fds[i], &e))
00553 {
00554 _dbus_warn("Failed to close file descriptor: %s\n", e.message);
00555 dbus_error_free(&e);
00556 }
00557 }
00558
00559 *n_fds = 0;
00560
00561
00562 }
00563 #endif
00564
00565 static void
00566 free_counter (void *element,
00567 void *data)
00568 {
00569 DBusCounter *counter = element;
00570 DBusMessage *message = data;
00571
00572 _dbus_counter_adjust_size (counter, - message->size_counter_delta);
00573 #ifdef HAVE_UNIX_FD_PASSING
00574 _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
00575 #endif
00576
00577 _dbus_counter_unref (counter);
00578 }
00579
00585 static void
00586 dbus_message_cache_or_finalize (DBusMessage *message)
00587 {
00588 dbus_bool_t was_cached;
00589 int i;
00590
00591 _dbus_assert (message->refcount.value == 0);
00592
00593
00594
00595
00596 _dbus_data_slot_list_clear (&message->slot_list);
00597
00598 _dbus_list_foreach (&message->counters,
00599 free_counter, message);
00600 _dbus_list_clear (&message->counters);
00601
00602 #ifdef HAVE_UNIX_FD_PASSING
00603 close_unix_fds(message->unix_fds, &message->n_unix_fds);
00604 #endif
00605
00606 was_cached = FALSE;
00607
00608 _DBUS_LOCK (message_cache);
00609
00610 if (!message_cache_shutdown_registered)
00611 {
00612 _dbus_assert (message_cache_count == 0);
00613
00614 if (!_dbus_register_shutdown_func (dbus_message_cache_shutdown, NULL))
00615 goto out;
00616
00617 i = 0;
00618 while (i < MAX_MESSAGE_CACHE_SIZE)
00619 {
00620 message_cache[i] = NULL;
00621 ++i;
00622 }
00623
00624 message_cache_shutdown_registered = TRUE;
00625 }
00626
00627 _dbus_assert (message_cache_count >= 0);
00628
00629 if ((_dbus_string_get_length (&message->header.data) +
00630 _dbus_string_get_length (&message->body)) >
00631 MAX_MESSAGE_SIZE_TO_CACHE)
00632 goto out;
00633
00634 if (message_cache_count >= MAX_MESSAGE_CACHE_SIZE)
00635 goto out;
00636
00637
00638 i = 0;
00639 while (message_cache[i] != NULL)
00640 ++i;
00641
00642 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
00643
00644 _dbus_assert (message_cache[i] == NULL);
00645 message_cache[i] = message;
00646 message_cache_count += 1;
00647 was_cached = TRUE;
00648 #ifndef DBUS_DISABLE_CHECKS
00649 message->in_cache = TRUE;
00650 #endif
00651
00652 out:
00653 _dbus_assert (message->refcount.value == 0);
00654
00655 _DBUS_UNLOCK (message_cache);
00656
00657 if (!was_cached)
00658 dbus_message_finalize (message);
00659 }
00660
00661 #ifndef DBUS_DISABLE_CHECKS
00662 static dbus_bool_t
00663 _dbus_message_iter_check (DBusMessageRealIter *iter)
00664 {
00665 if (iter == NULL)
00666 {
00667 _dbus_warn_check_failed ("dbus message iterator is NULL\n");
00668 return FALSE;
00669 }
00670
00671 if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_READER)
00672 {
00673 if (iter->u.reader.byte_order != iter->message->byte_order)
00674 {
00675 _dbus_warn_check_failed ("dbus message changed byte order since iterator was created\n");
00676 return FALSE;
00677 }
00678
00679 _dbus_assert (iter->u.reader.byte_order == DBUS_COMPILER_BYTE_ORDER);
00680 }
00681 else if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER)
00682 {
00683 if (iter->u.writer.byte_order != iter->message->byte_order)
00684 {
00685 _dbus_warn_check_failed ("dbus message changed byte order since append iterator was created\n");
00686 return FALSE;
00687 }
00688
00689 _dbus_assert (iter->u.writer.byte_order == DBUS_COMPILER_BYTE_ORDER);
00690 }
00691 else
00692 {
00693 _dbus_warn_check_failed ("dbus message iterator looks uninitialized or corrupted\n");
00694 return FALSE;
00695 }
00696
00697 if (iter->changed_stamp != iter->message->changed_stamp)
00698 {
00699 _dbus_warn_check_failed ("dbus message iterator invalid because the message has been modified (or perhaps the iterator is just uninitialized)\n");
00700 return FALSE;
00701 }
00702
00703 return TRUE;
00704 }
00705 #endif
00706
00721 dbus_bool_t
00722 _dbus_message_iter_get_args_valist (DBusMessageIter *iter,
00723 DBusError *error,
00724 int first_arg_type,
00725 va_list var_args)
00726 {
00727 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
00728 int spec_type, msg_type, i;
00729 dbus_bool_t retval;
00730
00731 _dbus_assert (_dbus_message_iter_check (real));
00732
00733 retval = FALSE;
00734
00735 spec_type = first_arg_type;
00736 i = 0;
00737
00738 while (spec_type != DBUS_TYPE_INVALID)
00739 {
00740 msg_type = dbus_message_iter_get_arg_type (iter);
00741
00742 if (msg_type != spec_type)
00743 {
00744 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
00745 "Argument %d is specified to be of type \"%s\", but "
00746 "is actually of type \"%s\"\n", i,
00747 _dbus_type_to_string (spec_type),
00748 _dbus_type_to_string (msg_type));
00749
00750 goto out;
00751 }
00752
00753 if (spec_type == DBUS_TYPE_UNIX_FD)
00754 {
00755 #ifdef HAVE_UNIX_FD_PASSING
00756 DBusBasicValue idx;
00757 int *pfd, nfd;
00758
00759 pfd = va_arg (var_args, int*);
00760 _dbus_assert(pfd);
00761
00762 _dbus_type_reader_read_basic(&real->u.reader, &idx);
00763
00764 if (idx.u32 >= real->message->n_unix_fds)
00765 {
00766 dbus_set_error (error, DBUS_ERROR_INCONSISTENT_MESSAGE,
00767 "Message refers to file descriptor at index %i,"
00768 "but has only %i descriptors attached.\n",
00769 idx.u32,
00770 real->message->n_unix_fds);
00771 goto out;
00772 }
00773
00774 if ((nfd = _dbus_dup(real->message->unix_fds[idx.u32], error)) < 0)
00775 goto out;
00776
00777 *pfd = nfd;
00778 #else
00779 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00780 "Platform does not support file desciptor passing.\n");
00781 goto out;
00782 #endif
00783 }
00784 else if (dbus_type_is_basic (spec_type))
00785 {
00786 DBusBasicValue *ptr;
00787
00788 ptr = va_arg (var_args, DBusBasicValue*);
00789
00790 _dbus_assert (ptr != NULL);
00791
00792 _dbus_type_reader_read_basic (&real->u.reader,
00793 ptr);
00794 }
00795 else if (spec_type == DBUS_TYPE_ARRAY)
00796 {
00797 int element_type;
00798 int spec_element_type;
00799 const DBusBasicValue **ptr;
00800 int *n_elements_p;
00801 DBusTypeReader array;
00802
00803 spec_element_type = va_arg (var_args, int);
00804 element_type = _dbus_type_reader_get_element_type (&real->u.reader);
00805
00806 if (spec_element_type != element_type)
00807 {
00808 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
00809 "Argument %d is specified to be an array of \"%s\", but "
00810 "is actually an array of \"%s\"\n",
00811 i,
00812 _dbus_type_to_string (spec_element_type),
00813 _dbus_type_to_string (element_type));
00814
00815 goto out;
00816 }
00817
00818 if (dbus_type_is_fixed (spec_element_type) &&
00819 element_type != DBUS_TYPE_UNIX_FD)
00820 {
00821 ptr = va_arg (var_args, const DBusBasicValue**);
00822 n_elements_p = va_arg (var_args, int*);
00823
00824 _dbus_assert (ptr != NULL);
00825 _dbus_assert (n_elements_p != NULL);
00826
00827 _dbus_type_reader_recurse (&real->u.reader, &array);
00828
00829 _dbus_type_reader_read_fixed_multi (&array,
00830 (void *) ptr, n_elements_p);
00831 }
00832 else if (spec_element_type == DBUS_TYPE_STRING ||
00833 spec_element_type == DBUS_TYPE_SIGNATURE ||
00834 spec_element_type == DBUS_TYPE_OBJECT_PATH)
00835 {
00836 char ***str_array_p;
00837 int n_elements;
00838 char **str_array;
00839
00840 str_array_p = va_arg (var_args, char***);
00841 n_elements_p = va_arg (var_args, int*);
00842
00843 _dbus_assert (str_array_p != NULL);
00844 _dbus_assert (n_elements_p != NULL);
00845
00846
00847 _dbus_type_reader_recurse (&real->u.reader, &array);
00848
00849 n_elements = 0;
00850 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
00851 {
00852 ++n_elements;
00853 _dbus_type_reader_next (&array);
00854 }
00855
00856 str_array = dbus_new0 (char*, n_elements + 1);
00857 if (str_array == NULL)
00858 {
00859 _DBUS_SET_OOM (error);
00860 goto out;
00861 }
00862
00863
00864 _dbus_type_reader_recurse (&real->u.reader, &array);
00865
00866 i = 0;
00867 while (i < n_elements)
00868 {
00869 const char *s;
00870 _dbus_type_reader_read_basic (&array,
00871 (void *) &s);
00872
00873 str_array[i] = _dbus_strdup (s);
00874 if (str_array[i] == NULL)
00875 {
00876 dbus_free_string_array (str_array);
00877 _DBUS_SET_OOM (error);
00878 goto out;
00879 }
00880
00881 ++i;
00882
00883 if (!_dbus_type_reader_next (&array))
00884 _dbus_assert (i == n_elements);
00885 }
00886
00887 _dbus_assert (_dbus_type_reader_get_current_type (&array) == DBUS_TYPE_INVALID);
00888 _dbus_assert (i == n_elements);
00889 _dbus_assert (str_array[i] == NULL);
00890
00891 *str_array_p = str_array;
00892 *n_elements_p = n_elements;
00893 }
00894 #ifndef DBUS_DISABLE_CHECKS
00895 else
00896 {
00897 _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now\n",
00898 _DBUS_FUNCTION_NAME);
00899 goto out;
00900 }
00901 #endif
00902 }
00903 #ifndef DBUS_DISABLE_CHECKS
00904 else
00905 {
00906 _dbus_warn ("you can only read arrays and basic types with %s for now\n",
00907 _DBUS_FUNCTION_NAME);
00908 goto out;
00909 }
00910 #endif
00911
00912 spec_type = va_arg (var_args, int);
00913 if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID)
00914 {
00915 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
00916 "Message has only %d arguments, but more were expected", i);
00917 goto out;
00918 }
00919
00920 i++;
00921 }
00922
00923 retval = TRUE;
00924
00925 out:
00926
00927 return retval;
00928 }
00929
00988 dbus_uint32_t
00989 dbus_message_get_serial (DBusMessage *message)
00990 {
00991 _dbus_return_val_if_fail (message != NULL, 0);
00992
00993 return _dbus_header_get_serial (&message->header);
00994 }
00995
01004 dbus_bool_t
01005 dbus_message_set_reply_serial (DBusMessage *message,
01006 dbus_uint32_t reply_serial)
01007 {
01008 _dbus_return_val_if_fail (message != NULL, FALSE);
01009 _dbus_return_val_if_fail (!message->locked, FALSE);
01010 _dbus_return_val_if_fail (reply_serial != 0, FALSE);
01011
01012 return _dbus_header_set_field_basic (&message->header,
01013 DBUS_HEADER_FIELD_REPLY_SERIAL,
01014 DBUS_TYPE_UINT32,
01015 &reply_serial);
01016 }
01017
01024 dbus_uint32_t
01025 dbus_message_get_reply_serial (DBusMessage *message)
01026 {
01027 dbus_uint32_t v_UINT32;
01028
01029 _dbus_return_val_if_fail (message != NULL, 0);
01030
01031 if (_dbus_header_get_field_basic (&message->header,
01032 DBUS_HEADER_FIELD_REPLY_SERIAL,
01033 DBUS_TYPE_UINT32,
01034 &v_UINT32))
01035 return v_UINT32;
01036 else
01037 return 0;
01038 }
01039
01040 static void
01041 dbus_message_finalize (DBusMessage *message)
01042 {
01043 _dbus_assert (message->refcount.value == 0);
01044
01045
01046 _dbus_data_slot_list_free (&message->slot_list);
01047
01048 _dbus_list_foreach (&message->counters,
01049 free_counter, message);
01050 _dbus_list_clear (&message->counters);
01051
01052 _dbus_header_free (&message->header);
01053 _dbus_string_free (&message->body);
01054
01055 #ifdef HAVE_UNIX_FD_PASSING
01056 close_unix_fds(message->unix_fds, &message->n_unix_fds);
01057 dbus_free(message->unix_fds);
01058 #endif
01059
01060 _dbus_assert (message->refcount.value == 0);
01061
01062 dbus_free (message);
01063 }
01064
01065 static DBusMessage*
01066 dbus_message_new_empty_header (void)
01067 {
01068 DBusMessage *message;
01069 dbus_bool_t from_cache;
01070
01071 message = dbus_message_get_cached ();
01072
01073 if (message != NULL)
01074 {
01075 from_cache = TRUE;
01076 }
01077 else
01078 {
01079 from_cache = FALSE;
01080 message = dbus_new (DBusMessage, 1);
01081 if (message == NULL)
01082 return NULL;
01083 #ifndef DBUS_DISABLE_CHECKS
01084 message->generation = _dbus_current_generation;
01085 #endif
01086
01087 #ifdef HAVE_UNIX_FD_PASSING
01088 message->unix_fds = NULL;
01089 message->n_unix_fds_allocated = 0;
01090 #endif
01091 }
01092
01093 message->refcount.value = 1;
01094 message->byte_order = DBUS_COMPILER_BYTE_ORDER;
01095 message->locked = FALSE;
01096 #ifndef DBUS_DISABLE_CHECKS
01097 message->in_cache = FALSE;
01098 #endif
01099 message->counters = NULL;
01100 message->size_counter_delta = 0;
01101 message->changed_stamp = 0;
01102
01103 #ifdef HAVE_UNIX_FD_PASSING
01104 message->n_unix_fds = 0;
01105 message->n_unix_fds_allocated = 0;
01106 message->unix_fd_counter_delta = 0;
01107 #endif
01108
01109 if (!from_cache)
01110 _dbus_data_slot_list_init (&message->slot_list);
01111
01112 if (from_cache)
01113 {
01114 _dbus_header_reinit (&message->header, message->byte_order);
01115 _dbus_string_set_length (&message->body, 0);
01116 }
01117 else
01118 {
01119 if (!_dbus_header_init (&message->header, message->byte_order))
01120 {
01121 dbus_free (message);
01122 return NULL;
01123 }
01124
01125 if (!_dbus_string_init_preallocated (&message->body, 32))
01126 {
01127 _dbus_header_free (&message->header);
01128 dbus_free (message);
01129 return NULL;
01130 }
01131 }
01132
01133 return message;
01134 }
01135
01148 DBusMessage*
01149 dbus_message_new (int message_type)
01150 {
01151 DBusMessage *message;
01152
01153 _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
01154
01155 message = dbus_message_new_empty_header ();
01156 if (message == NULL)
01157 return NULL;
01158
01159 if (!_dbus_header_create (&message->header,
01160 message_type,
01161 NULL, NULL, NULL, NULL, NULL))
01162 {
01163 dbus_message_unref (message);
01164 return NULL;
01165 }
01166
01167 return message;
01168 }
01169
01191 DBusMessage*
01192 dbus_message_new_method_call (const char *destination,
01193 const char *path,
01194 const char *interface,
01195 const char *method)
01196 {
01197 DBusMessage *message;
01198
01199 _dbus_return_val_if_fail (path != NULL, NULL);
01200 _dbus_return_val_if_fail (method != NULL, NULL);
01201 _dbus_return_val_if_fail (destination == NULL ||
01202 _dbus_check_is_valid_bus_name (destination), NULL);
01203 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
01204 _dbus_return_val_if_fail (interface == NULL ||
01205 _dbus_check_is_valid_interface (interface), NULL);
01206 _dbus_return_val_if_fail (_dbus_check_is_valid_member (method), NULL);
01207
01208 message = dbus_message_new_empty_header ();
01209 if (message == NULL)
01210 return NULL;
01211
01212 if (!_dbus_header_create (&message->header,
01213 DBUS_MESSAGE_TYPE_METHOD_CALL,
01214 destination, path, interface, method, NULL))
01215 {
01216 dbus_message_unref (message);
01217 return NULL;
01218 }
01219
01220 return message;
01221 }
01222
01230 DBusMessage*
01231 dbus_message_new_method_return (DBusMessage *method_call)
01232 {
01233 DBusMessage *message;
01234 const char *sender;
01235
01236 _dbus_return_val_if_fail (method_call != NULL, NULL);
01237
01238 sender = dbus_message_get_sender (method_call);
01239
01240
01241
01242 message = dbus_message_new_empty_header ();
01243 if (message == NULL)
01244 return NULL;
01245
01246 if (!_dbus_header_create (&message->header,
01247 DBUS_MESSAGE_TYPE_METHOD_RETURN,
01248 sender, NULL, NULL, NULL, NULL))
01249 {
01250 dbus_message_unref (message);
01251 return NULL;
01252 }
01253
01254 dbus_message_set_no_reply (message, TRUE);
01255
01256 if (!dbus_message_set_reply_serial (message,
01257 dbus_message_get_serial (method_call)))
01258 {
01259 dbus_message_unref (message);
01260 return NULL;
01261 }
01262
01263 return message;
01264 }
01265
01280 DBusMessage*
01281 dbus_message_new_signal (const char *path,
01282 const char *interface,
01283 const char *name)
01284 {
01285 DBusMessage *message;
01286
01287 _dbus_return_val_if_fail (path != NULL, NULL);
01288 _dbus_return_val_if_fail (interface != NULL, NULL);
01289 _dbus_return_val_if_fail (name != NULL, NULL);
01290 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
01291 _dbus_return_val_if_fail (_dbus_check_is_valid_interface (interface), NULL);
01292 _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);
01293
01294 message = dbus_message_new_empty_header ();
01295 if (message == NULL)
01296 return NULL;
01297
01298 if (!_dbus_header_create (&message->header,
01299 DBUS_MESSAGE_TYPE_SIGNAL,
01300 NULL, path, interface, name, NULL))
01301 {
01302 dbus_message_unref (message);
01303 return NULL;
01304 }
01305
01306 dbus_message_set_no_reply (message, TRUE);
01307
01308 return message;
01309 }
01310
01325 DBusMessage*
01326 dbus_message_new_error (DBusMessage *reply_to,
01327 const char *error_name,
01328 const char *error_message)
01329 {
01330 DBusMessage *message;
01331 const char *sender;
01332 DBusMessageIter iter;
01333
01334 _dbus_return_val_if_fail (reply_to != NULL, NULL);
01335 _dbus_return_val_if_fail (error_name != NULL, NULL);
01336 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
01337
01338 sender = dbus_message_get_sender (reply_to);
01339
01340
01341
01342
01343
01344 message = dbus_message_new_empty_header ();
01345 if (message == NULL)
01346 return NULL;
01347
01348 if (!_dbus_header_create (&message->header,
01349 DBUS_MESSAGE_TYPE_ERROR,
01350 sender, NULL, NULL, NULL, error_name))
01351 {
01352 dbus_message_unref (message);
01353 return NULL;
01354 }
01355
01356 dbus_message_set_no_reply (message, TRUE);
01357
01358 if (!dbus_message_set_reply_serial (message,
01359 dbus_message_get_serial (reply_to)))
01360 {
01361 dbus_message_unref (message);
01362 return NULL;
01363 }
01364
01365 if (error_message != NULL)
01366 {
01367 dbus_message_iter_init_append (message, &iter);
01368 if (!dbus_message_iter_append_basic (&iter,
01369 DBUS_TYPE_STRING,
01370 &error_message))
01371 {
01372 dbus_message_unref (message);
01373 return NULL;
01374 }
01375 }
01376
01377 return message;
01378 }
01379
01396 DBusMessage*
01397 dbus_message_new_error_printf (DBusMessage *reply_to,
01398 const char *error_name,
01399 const char *error_format,
01400 ...)
01401 {
01402 va_list args;
01403 DBusString str;
01404 DBusMessage *message;
01405
01406 _dbus_return_val_if_fail (reply_to != NULL, NULL);
01407 _dbus_return_val_if_fail (error_name != NULL, NULL);
01408 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
01409
01410 if (!_dbus_string_init (&str))
01411 return NULL;
01412
01413 va_start (args, error_format);
01414
01415 if (_dbus_string_append_printf_valist (&str, error_format, args))
01416 message = dbus_message_new_error (reply_to, error_name,
01417 _dbus_string_get_const_data (&str));
01418 else
01419 message = NULL;
01420
01421 _dbus_string_free (&str);
01422
01423 va_end (args);
01424
01425 return message;
01426 }
01427
01428
01441 DBusMessage *
01442 dbus_message_copy (const DBusMessage *message)
01443 {
01444 DBusMessage *retval;
01445
01446 _dbus_return_val_if_fail (message != NULL, NULL);
01447
01448 retval = dbus_new0 (DBusMessage, 1);
01449 if (retval == NULL)
01450 return NULL;
01451
01452 retval->refcount.value = 1;
01453 retval->byte_order = message->byte_order;
01454 retval->locked = FALSE;
01455 #ifndef DBUS_DISABLE_CHECKS
01456 retval->generation = message->generation;
01457 #endif
01458
01459 if (!_dbus_header_copy (&message->header, &retval->header))
01460 {
01461 dbus_free (retval);
01462 return NULL;
01463 }
01464
01465 if (!_dbus_string_init_preallocated (&retval->body,
01466 _dbus_string_get_length (&message->body)))
01467 {
01468 _dbus_header_free (&retval->header);
01469 dbus_free (retval);
01470 return NULL;
01471 }
01472
01473 if (!_dbus_string_copy (&message->body, 0,
01474 &retval->body, 0))
01475 goto failed_copy;
01476
01477 #ifdef HAVE_UNIX_FD_PASSING
01478 retval->unix_fds = dbus_new(int, message->n_unix_fds);
01479 if (retval->unix_fds == NULL && message->n_unix_fds > 0)
01480 goto failed_copy;
01481
01482 retval->n_unix_fds_allocated = message->n_unix_fds;
01483
01484 for (retval->n_unix_fds = 0;
01485 retval->n_unix_fds < message->n_unix_fds;
01486 retval->n_unix_fds++)
01487 {
01488 retval->unix_fds[retval->n_unix_fds] = _dbus_dup(message->unix_fds[retval->n_unix_fds], NULL);
01489
01490 if (retval->unix_fds[retval->n_unix_fds] < 0)
01491 goto failed_copy;
01492 }
01493
01494 #endif
01495
01496 return retval;
01497
01498 failed_copy:
01499 _dbus_header_free (&retval->header);
01500 _dbus_string_free (&retval->body);
01501
01502 #ifdef HAVE_UNIX_FD_PASSING
01503 close_unix_fds(retval->unix_fds, &retval->n_unix_fds);
01504 dbus_free(retval->unix_fds);
01505 #endif
01506
01507 dbus_free (retval);
01508
01509 return NULL;
01510 }
01511
01512
01520 DBusMessage *
01521 dbus_message_ref (DBusMessage *message)
01522 {
01523 dbus_int32_t old_refcount;
01524
01525 _dbus_return_val_if_fail (message != NULL, NULL);
01526 _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
01527 _dbus_return_val_if_fail (!message->in_cache, NULL);
01528
01529 old_refcount = _dbus_atomic_inc (&message->refcount);
01530 _dbus_assert (old_refcount >= 1);
01531
01532 return message;
01533 }
01534
01542 void
01543 dbus_message_unref (DBusMessage *message)
01544 {
01545 dbus_int32_t old_refcount;
01546
01547 _dbus_return_if_fail (message != NULL);
01548 _dbus_return_if_fail (message->generation == _dbus_current_generation);
01549 _dbus_return_if_fail (!message->in_cache);
01550
01551 old_refcount = _dbus_atomic_dec (&message->refcount);
01552
01553 _dbus_assert (old_refcount >= 0);
01554
01555 if (old_refcount == 1)
01556 {
01557
01558 dbus_message_cache_or_finalize (message);
01559 }
01560 }
01561
01572 int
01573 dbus_message_get_type (DBusMessage *message)
01574 {
01575 _dbus_return_val_if_fail (message != NULL, DBUS_MESSAGE_TYPE_INVALID);
01576
01577 return _dbus_header_get_message_type (&message->header);
01578 }
01579
01642 dbus_bool_t
01643 dbus_message_append_args (DBusMessage *message,
01644 int first_arg_type,
01645 ...)
01646 {
01647 dbus_bool_t retval;
01648 va_list var_args;
01649
01650 _dbus_return_val_if_fail (message != NULL, FALSE);
01651
01652 va_start (var_args, first_arg_type);
01653 retval = dbus_message_append_args_valist (message,
01654 first_arg_type,
01655 var_args);
01656 va_end (var_args);
01657
01658 return retval;
01659 }
01660
01674 dbus_bool_t
01675 dbus_message_append_args_valist (DBusMessage *message,
01676 int first_arg_type,
01677 va_list var_args)
01678 {
01679 int type;
01680 DBusMessageIter iter;
01681
01682 _dbus_return_val_if_fail (message != NULL, FALSE);
01683
01684 type = first_arg_type;
01685
01686 dbus_message_iter_init_append (message, &iter);
01687
01688 while (type != DBUS_TYPE_INVALID)
01689 {
01690 if (dbus_type_is_basic (type))
01691 {
01692 const DBusBasicValue *value;
01693 value = va_arg (var_args, const DBusBasicValue*);
01694
01695 if (!dbus_message_iter_append_basic (&iter,
01696 type,
01697 value))
01698 goto failed;
01699 }
01700 else if (type == DBUS_TYPE_ARRAY)
01701 {
01702 int element_type;
01703 DBusMessageIter array;
01704 char buf[2];
01705
01706 element_type = va_arg (var_args, int);
01707
01708 buf[0] = element_type;
01709 buf[1] = '\0';
01710 if (!dbus_message_iter_open_container (&iter,
01711 DBUS_TYPE_ARRAY,
01712 buf,
01713 &array))
01714 goto failed;
01715
01716 if (dbus_type_is_fixed (element_type) &&
01717 element_type != DBUS_TYPE_UNIX_FD)
01718 {
01719 const DBusBasicValue **value;
01720 int n_elements;
01721
01722 value = va_arg (var_args, const DBusBasicValue**);
01723 n_elements = va_arg (var_args, int);
01724
01725 if (!dbus_message_iter_append_fixed_array (&array,
01726 element_type,
01727 value,
01728 n_elements)) {
01729 dbus_message_iter_abandon_container (&iter, &array);
01730 goto failed;
01731 }
01732 }
01733 else if (element_type == DBUS_TYPE_STRING ||
01734 element_type == DBUS_TYPE_SIGNATURE ||
01735 element_type == DBUS_TYPE_OBJECT_PATH)
01736 {
01737 const char ***value_p;
01738 const char **value;
01739 int n_elements;
01740 int i;
01741
01742 value_p = va_arg (var_args, const char***);
01743 n_elements = va_arg (var_args, int);
01744
01745 value = *value_p;
01746
01747 i = 0;
01748 while (i < n_elements)
01749 {
01750 if (!dbus_message_iter_append_basic (&array,
01751 element_type,
01752 &value[i])) {
01753 dbus_message_iter_abandon_container (&iter, &array);
01754 goto failed;
01755 }
01756 ++i;
01757 }
01758 }
01759 else
01760 {
01761 _dbus_warn ("arrays of %s can't be appended with %s for now\n",
01762 _dbus_type_to_string (element_type),
01763 _DBUS_FUNCTION_NAME);
01764 goto failed;
01765 }
01766
01767 if (!dbus_message_iter_close_container (&iter, &array))
01768 goto failed;
01769 }
01770 #ifndef DBUS_DISABLE_CHECKS
01771 else
01772 {
01773 _dbus_warn ("type %s isn't supported yet in %s\n",
01774 _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
01775 goto failed;
01776 }
01777 #endif
01778
01779 type = va_arg (var_args, int);
01780 }
01781
01782 return TRUE;
01783
01784 failed:
01785 return FALSE;
01786 }
01787
01832 dbus_bool_t
01833 dbus_message_get_args (DBusMessage *message,
01834 DBusError *error,
01835 int first_arg_type,
01836 ...)
01837 {
01838 dbus_bool_t retval;
01839 va_list var_args;
01840
01841 _dbus_return_val_if_fail (message != NULL, FALSE);
01842 _dbus_return_val_if_error_is_set (error, FALSE);
01843
01844 va_start (var_args, first_arg_type);
01845 retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
01846 va_end (var_args);
01847
01848 return retval;
01849 }
01850
01861 dbus_bool_t
01862 dbus_message_get_args_valist (DBusMessage *message,
01863 DBusError *error,
01864 int first_arg_type,
01865 va_list var_args)
01866 {
01867 DBusMessageIter iter;
01868
01869 _dbus_return_val_if_fail (message != NULL, FALSE);
01870 _dbus_return_val_if_error_is_set (error, FALSE);
01871
01872 dbus_message_iter_init (message, &iter);
01873 return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
01874 }
01875
01876 static void
01877 _dbus_message_iter_init_common (DBusMessage *message,
01878 DBusMessageRealIter *real,
01879 int iter_type)
01880 {
01881 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
01882
01883
01884
01885
01886 ensure_byte_order (message);
01887
01888 real->message = message;
01889 real->changed_stamp = message->changed_stamp;
01890 real->iter_type = iter_type;
01891 real->sig_refcount = 0;
01892 }
01893
01916 dbus_bool_t
01917 dbus_message_iter_init (DBusMessage *message,
01918 DBusMessageIter *iter)
01919 {
01920 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01921 const DBusString *type_str;
01922 int type_pos;
01923
01924 _dbus_return_val_if_fail (message != NULL, FALSE);
01925 _dbus_return_val_if_fail (iter != NULL, FALSE);
01926
01927 get_const_signature (&message->header, &type_str, &type_pos);
01928
01929 _dbus_message_iter_init_common (message, real,
01930 DBUS_MESSAGE_ITER_TYPE_READER);
01931
01932 _dbus_type_reader_init (&real->u.reader,
01933 message->byte_order,
01934 type_str, type_pos,
01935 &message->body,
01936 0);
01937
01938 return _dbus_type_reader_get_current_type (&real->u.reader) != DBUS_TYPE_INVALID;
01939 }
01940
01947 dbus_bool_t
01948 dbus_message_iter_has_next (DBusMessageIter *iter)
01949 {
01950 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01951
01952 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
01953 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
01954
01955 return _dbus_type_reader_has_next (&real->u.reader);
01956 }
01957
01966 dbus_bool_t
01967 dbus_message_iter_next (DBusMessageIter *iter)
01968 {
01969 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01970
01971 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
01972 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
01973
01974 return _dbus_type_reader_next (&real->u.reader);
01975 }
01976
01991 int
01992 dbus_message_iter_get_arg_type (DBusMessageIter *iter)
01993 {
01994 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01995
01996 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
01997 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
01998
01999 return _dbus_type_reader_get_current_type (&real->u.reader);
02000 }
02001
02010 int
02011 dbus_message_iter_get_element_type (DBusMessageIter *iter)
02012 {
02013 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02014
02015 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
02016 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
02017 _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
02018
02019 return _dbus_type_reader_get_element_type (&real->u.reader);
02020 }
02021
02047 void
02048 dbus_message_iter_recurse (DBusMessageIter *iter,
02049 DBusMessageIter *sub)
02050 {
02051 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02052 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02053
02054 _dbus_return_if_fail (_dbus_message_iter_check (real));
02055 _dbus_return_if_fail (sub != NULL);
02056
02057 *real_sub = *real;
02058 _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
02059 }
02060
02072 char *
02073 dbus_message_iter_get_signature (DBusMessageIter *iter)
02074 {
02075 const DBusString *sig;
02076 DBusString retstr;
02077 char *ret;
02078 int start, len;
02079 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02080
02081 _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
02082
02083 if (!_dbus_string_init (&retstr))
02084 return NULL;
02085
02086 _dbus_type_reader_get_signature (&real->u.reader, &sig,
02087 &start, &len);
02088 if (!_dbus_string_append_len (&retstr,
02089 _dbus_string_get_const_data (sig) + start,
02090 len))
02091 return NULL;
02092 if (!_dbus_string_steal_data (&retstr, &ret))
02093 return NULL;
02094 _dbus_string_free (&retstr);
02095 return ret;
02096 }
02097
02145 void
02146 dbus_message_iter_get_basic (DBusMessageIter *iter,
02147 void *value)
02148 {
02149 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02150
02151 _dbus_return_if_fail (_dbus_message_iter_check (real));
02152 _dbus_return_if_fail (value != NULL);
02153
02154 if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_UNIX_FD)
02155 {
02156 #ifdef HAVE_UNIX_FD_PASSING
02157 DBusBasicValue idx;
02158
02159 _dbus_type_reader_read_basic(&real->u.reader, &idx);
02160
02161 if (idx.u32 >= real->message->n_unix_fds) {
02162
02163
02164 *((int*) value) = -1;
02165 return;
02166 }
02167
02168 *((int*) value) = _dbus_dup(real->message->unix_fds[idx.u32], NULL);
02169 #else
02170 *((int*) value) = -1;
02171 #endif
02172 }
02173 else
02174 {
02175 _dbus_type_reader_read_basic (&real->u.reader,
02176 value);
02177 }
02178 }
02179
02198 int
02199 dbus_message_iter_get_array_len (DBusMessageIter *iter)
02200 {
02201 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02202
02203 _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
02204
02205 return _dbus_type_reader_get_array_length (&real->u.reader);
02206 }
02207
02243 void
02244 dbus_message_iter_get_fixed_array (DBusMessageIter *iter,
02245 void *value,
02246 int *n_elements)
02247 {
02248 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02249 int subtype = _dbus_type_reader_get_current_type(&real->u.reader);
02250
02251 _dbus_return_if_fail (_dbus_message_iter_check (real));
02252 _dbus_return_if_fail (value != NULL);
02253 _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) ||
02254 (dbus_type_is_fixed (subtype) && subtype != DBUS_TYPE_UNIX_FD));
02255
02256 _dbus_type_reader_read_fixed_multi (&real->u.reader,
02257 value, n_elements);
02258 }
02259
02271 void
02272 dbus_message_iter_init_append (DBusMessage *message,
02273 DBusMessageIter *iter)
02274 {
02275 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02276
02277 _dbus_return_if_fail (message != NULL);
02278 _dbus_return_if_fail (iter != NULL);
02279
02280 _dbus_message_iter_init_common (message, real,
02281 DBUS_MESSAGE_ITER_TYPE_WRITER);
02282
02283
02284
02285
02286
02287 _dbus_type_writer_init_types_delayed (&real->u.writer,
02288 message->byte_order,
02289 &message->body,
02290 _dbus_string_get_length (&message->body));
02291 }
02292
02301 static dbus_bool_t
02302 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
02303 {
02304 DBusString *str;
02305 const DBusString *current_sig;
02306 int current_sig_pos;
02307
02308 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02309
02310 if (real->u.writer.type_str != NULL)
02311 {
02312 _dbus_assert (real->sig_refcount > 0);
02313 real->sig_refcount += 1;
02314 return TRUE;
02315 }
02316
02317 str = dbus_new (DBusString, 1);
02318 if (str == NULL)
02319 return FALSE;
02320
02321 if (!_dbus_header_get_field_raw (&real->message->header,
02322 DBUS_HEADER_FIELD_SIGNATURE,
02323 ¤t_sig, ¤t_sig_pos))
02324 current_sig = NULL;
02325
02326 if (current_sig)
02327 {
02328 int current_len;
02329
02330 current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
02331 current_sig_pos += 1;
02332
02333 if (!_dbus_string_init_preallocated (str, current_len + 4))
02334 {
02335 dbus_free (str);
02336 return FALSE;
02337 }
02338
02339 if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
02340 str, 0))
02341 {
02342 _dbus_string_free (str);
02343 dbus_free (str);
02344 return FALSE;
02345 }
02346 }
02347 else
02348 {
02349 if (!_dbus_string_init_preallocated (str, 4))
02350 {
02351 dbus_free (str);
02352 return FALSE;
02353 }
02354 }
02355
02356 real->sig_refcount = 1;
02357
02358 _dbus_type_writer_add_types (&real->u.writer,
02359 str, _dbus_string_get_length (str));
02360 return TRUE;
02361 }
02362
02372 static dbus_bool_t
02373 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
02374 {
02375 DBusString *str;
02376 const char *v_STRING;
02377 dbus_bool_t retval;
02378
02379 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02380 _dbus_assert (real->u.writer.type_str != NULL);
02381 _dbus_assert (real->sig_refcount > 0);
02382
02383 real->sig_refcount -= 1;
02384
02385 if (real->sig_refcount > 0)
02386 return TRUE;
02387 _dbus_assert (real->sig_refcount == 0);
02388
02389 retval = TRUE;
02390
02391 str = real->u.writer.type_str;
02392
02393 v_STRING = _dbus_string_get_const_data (str);
02394 if (!_dbus_header_set_field_basic (&real->message->header,
02395 DBUS_HEADER_FIELD_SIGNATURE,
02396 DBUS_TYPE_SIGNATURE,
02397 &v_STRING))
02398 retval = FALSE;
02399
02400 _dbus_type_writer_remove_types (&real->u.writer);
02401 _dbus_string_free (str);
02402 dbus_free (str);
02403
02404 return retval;
02405 }
02406
02414 static void
02415 _dbus_message_iter_abandon_signature (DBusMessageRealIter *real)
02416 {
02417 DBusString *str;
02418
02419 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02420 _dbus_assert (real->u.writer.type_str != NULL);
02421 _dbus_assert (real->sig_refcount > 0);
02422
02423 real->sig_refcount -= 1;
02424
02425 if (real->sig_refcount > 0)
02426 return;
02427 _dbus_assert (real->sig_refcount == 0);
02428
02429 str = real->u.writer.type_str;
02430
02431 _dbus_type_writer_remove_types (&real->u.writer);
02432 _dbus_string_free (str);
02433 dbus_free (str);
02434 }
02435
02436 #ifndef DBUS_DISABLE_CHECKS
02437 static dbus_bool_t
02438 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
02439 {
02440 if (!_dbus_message_iter_check (iter))
02441 return FALSE;
02442
02443 if (iter->message->locked)
02444 {
02445 _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)\n");
02446 return FALSE;
02447 }
02448
02449 return TRUE;
02450 }
02451 #endif
02452
02453 #ifdef HAVE_UNIX_FD_PASSING
02454 static int *
02455 expand_fd_array(DBusMessage *m,
02456 unsigned n)
02457 {
02458 _dbus_assert(m);
02459
02460
02461
02462
02463 if (m->n_unix_fds + n > m->n_unix_fds_allocated)
02464 {
02465 unsigned k;
02466 int *p;
02467
02468
02469 k = (m->n_unix_fds + n) * 2;
02470
02471
02472 if (k < 4)
02473 k = 4;
02474
02475 p = dbus_realloc(m->unix_fds, k * sizeof(int));
02476 if (p == NULL)
02477 return NULL;
02478
02479 m->unix_fds = p;
02480 m->n_unix_fds_allocated = k;
02481 }
02482
02483 return m->unix_fds + m->n_unix_fds;
02484 }
02485 #endif
02486
02506 dbus_bool_t
02507 dbus_message_iter_append_basic (DBusMessageIter *iter,
02508 int type,
02509 const void *value)
02510 {
02511 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02512 dbus_bool_t ret;
02513
02514 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02515 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02516 _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
02517 _dbus_return_val_if_fail (value != NULL, FALSE);
02518
02519 if (!_dbus_message_iter_open_signature (real))
02520 return FALSE;
02521
02522 if (type == DBUS_TYPE_UNIX_FD)
02523 {
02524 #ifdef HAVE_UNIX_FD_PASSING
02525 int *fds;
02526 dbus_uint32_t u;
02527
02528
02529 if (!(fds = expand_fd_array(real->message, 1)))
02530 return FALSE;
02531
02532 *fds = _dbus_dup(*(int*) value, NULL);
02533 if (*fds < 0)
02534 return FALSE;
02535
02536 u = real->message->n_unix_fds;
02537
02538
02539 if (!(ret = _dbus_type_writer_write_basic (&real->u.writer, DBUS_TYPE_UNIX_FD, &u))) {
02540 _dbus_close(*fds, NULL);
02541 return FALSE;
02542 }
02543
02544 real->message->n_unix_fds += 1;
02545 u += 1;
02546
02547
02548 ret = _dbus_header_set_field_basic (&real->message->header,
02549 DBUS_HEADER_FIELD_UNIX_FDS,
02550 DBUS_TYPE_UINT32,
02551 &u);
02552
02553
02554
02555
02556
02557
02558 #else
02559 ret = FALSE;
02560 #endif
02561 }
02562 else
02563 {
02564 ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
02565 }
02566
02567 if (!_dbus_message_iter_close_signature (real))
02568 ret = FALSE;
02569
02570 return ret;
02571 }
02572
02612 dbus_bool_t
02613 dbus_message_iter_append_fixed_array (DBusMessageIter *iter,
02614 int element_type,
02615 const void *value,
02616 int n_elements)
02617 {
02618 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02619 dbus_bool_t ret;
02620
02621 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02622 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02623 _dbus_return_val_if_fail (dbus_type_is_fixed (element_type) && element_type != DBUS_TYPE_UNIX_FD, FALSE);
02624 _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
02625 _dbus_return_val_if_fail (value != NULL, FALSE);
02626 _dbus_return_val_if_fail (n_elements >= 0, FALSE);
02627 _dbus_return_val_if_fail (n_elements <=
02628 DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type),
02629 FALSE);
02630
02631 ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
02632
02633 return ret;
02634 }
02635
02657 dbus_bool_t
02658 dbus_message_iter_open_container (DBusMessageIter *iter,
02659 int type,
02660 const char *contained_signature,
02661 DBusMessageIter *sub)
02662 {
02663 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02664 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02665 DBusString contained_str;
02666
02667 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02668 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02669 _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
02670 _dbus_return_val_if_fail (sub != NULL, FALSE);
02671 _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
02672 contained_signature == NULL) ||
02673 (type == DBUS_TYPE_DICT_ENTRY &&
02674 contained_signature == NULL) ||
02675 (type == DBUS_TYPE_VARIANT &&
02676 contained_signature != NULL) ||
02677 (type == DBUS_TYPE_ARRAY &&
02678 contained_signature != NULL), FALSE);
02679
02680
02681
02682
02683
02684 _dbus_return_val_if_fail ((type == DBUS_TYPE_ARRAY && contained_signature && *contained_signature == DBUS_DICT_ENTRY_BEGIN_CHAR) ||
02685 (contained_signature == NULL ||
02686 _dbus_check_is_valid_signature (contained_signature)),
02687 FALSE);
02688
02689 if (!_dbus_message_iter_open_signature (real))
02690 return FALSE;
02691
02692 *real_sub = *real;
02693
02694 if (contained_signature != NULL)
02695 {
02696 _dbus_string_init_const (&contained_str, contained_signature);
02697
02698 return _dbus_type_writer_recurse (&real->u.writer,
02699 type,
02700 &contained_str, 0,
02701 &real_sub->u.writer);
02702 }
02703 else
02704 {
02705 return _dbus_type_writer_recurse (&real->u.writer,
02706 type,
02707 NULL, 0,
02708 &real_sub->u.writer);
02709 }
02710 }
02711
02712
02726 dbus_bool_t
02727 dbus_message_iter_close_container (DBusMessageIter *iter,
02728 DBusMessageIter *sub)
02729 {
02730 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02731 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02732 dbus_bool_t ret;
02733
02734 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02735 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02736 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
02737 _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02738
02739 ret = _dbus_type_writer_unrecurse (&real->u.writer,
02740 &real_sub->u.writer);
02741
02742 if (!_dbus_message_iter_close_signature (real))
02743 ret = FALSE;
02744
02745 return ret;
02746 }
02747
02759 void
02760 dbus_message_iter_abandon_container (DBusMessageIter *iter,
02761 DBusMessageIter *sub)
02762 {
02763 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02764 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02765
02766 _dbus_return_if_fail (_dbus_message_iter_append_check (real));
02767 _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02768 _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
02769 _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02770
02771 _dbus_message_iter_abandon_signature (real);
02772 }
02773
02790 void
02791 dbus_message_set_no_reply (DBusMessage *message,
02792 dbus_bool_t no_reply)
02793 {
02794 _dbus_return_if_fail (message != NULL);
02795 _dbus_return_if_fail (!message->locked);
02796
02797 _dbus_header_toggle_flag (&message->header,
02798 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED,
02799 no_reply);
02800 }
02801
02809 dbus_bool_t
02810 dbus_message_get_no_reply (DBusMessage *message)
02811 {
02812 _dbus_return_val_if_fail (message != NULL, FALSE);
02813
02814 return _dbus_header_get_flag (&message->header,
02815 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED);
02816 }
02817
02832 void
02833 dbus_message_set_auto_start (DBusMessage *message,
02834 dbus_bool_t auto_start)
02835 {
02836 _dbus_return_if_fail (message != NULL);
02837 _dbus_return_if_fail (!message->locked);
02838
02839 _dbus_header_toggle_flag (&message->header,
02840 DBUS_HEADER_FLAG_NO_AUTO_START,
02841 !auto_start);
02842 }
02843
02851 dbus_bool_t
02852 dbus_message_get_auto_start (DBusMessage *message)
02853 {
02854 _dbus_return_val_if_fail (message != NULL, FALSE);
02855
02856 return !_dbus_header_get_flag (&message->header,
02857 DBUS_HEADER_FLAG_NO_AUTO_START);
02858 }
02859
02860
02873 dbus_bool_t
02874 dbus_message_set_path (DBusMessage *message,
02875 const char *object_path)
02876 {
02877 _dbus_return_val_if_fail (message != NULL, FALSE);
02878 _dbus_return_val_if_fail (!message->locked, FALSE);
02879 _dbus_return_val_if_fail (object_path == NULL ||
02880 _dbus_check_is_valid_path (object_path),
02881 FALSE);
02882
02883 return set_or_delete_string_field (message,
02884 DBUS_HEADER_FIELD_PATH,
02885 DBUS_TYPE_OBJECT_PATH,
02886 object_path);
02887 }
02888
02902 const char*
02903 dbus_message_get_path (DBusMessage *message)
02904 {
02905 const char *v;
02906
02907 _dbus_return_val_if_fail (message != NULL, NULL);
02908
02909 v = NULL;
02910 _dbus_header_get_field_basic (&message->header,
02911 DBUS_HEADER_FIELD_PATH,
02912 DBUS_TYPE_OBJECT_PATH,
02913 (void *) &v);
02914 return v;
02915 }
02916
02926 dbus_bool_t
02927 dbus_message_has_path (DBusMessage *message,
02928 const char *path)
02929 {
02930 const char *msg_path;
02931 msg_path = dbus_message_get_path (message);
02932
02933 if (msg_path == NULL)
02934 {
02935 if (path == NULL)
02936 return TRUE;
02937 else
02938 return FALSE;
02939 }
02940
02941 if (path == NULL)
02942 return FALSE;
02943
02944 if (strcmp (msg_path, path) == 0)
02945 return TRUE;
02946
02947 return FALSE;
02948 }
02949
02970 dbus_bool_t
02971 dbus_message_get_path_decomposed (DBusMessage *message,
02972 char ***path)
02973 {
02974 const char *v;
02975
02976 _dbus_return_val_if_fail (message != NULL, FALSE);
02977 _dbus_return_val_if_fail (path != NULL, FALSE);
02978
02979 *path = NULL;
02980
02981 v = dbus_message_get_path (message);
02982 if (v != NULL)
02983 {
02984 if (!_dbus_decompose_path (v, strlen (v),
02985 path, NULL))
02986 return FALSE;
02987 }
02988 return TRUE;
02989 }
02990
03004 dbus_bool_t
03005 dbus_message_set_interface (DBusMessage *message,
03006 const char *interface)
03007 {
03008 _dbus_return_val_if_fail (message != NULL, FALSE);
03009 _dbus_return_val_if_fail (!message->locked, FALSE);
03010 _dbus_return_val_if_fail (interface == NULL ||
03011 _dbus_check_is_valid_interface (interface),
03012 FALSE);
03013
03014 return set_or_delete_string_field (message,
03015 DBUS_HEADER_FIELD_INTERFACE,
03016 DBUS_TYPE_STRING,
03017 interface);
03018 }
03019
03033 const char*
03034 dbus_message_get_interface (DBusMessage *message)
03035 {
03036 const char *v;
03037
03038 _dbus_return_val_if_fail (message != NULL, NULL);
03039
03040 v = NULL;
03041 _dbus_header_get_field_basic (&message->header,
03042 DBUS_HEADER_FIELD_INTERFACE,
03043 DBUS_TYPE_STRING,
03044 (void *) &v);
03045 return v;
03046 }
03047
03055 dbus_bool_t
03056 dbus_message_has_interface (DBusMessage *message,
03057 const char *interface)
03058 {
03059 const char *msg_interface;
03060 msg_interface = dbus_message_get_interface (message);
03061
03062 if (msg_interface == NULL)
03063 {
03064 if (interface == NULL)
03065 return TRUE;
03066 else
03067 return FALSE;
03068 }
03069
03070 if (interface == NULL)
03071 return FALSE;
03072
03073 if (strcmp (msg_interface, interface) == 0)
03074 return TRUE;
03075
03076 return FALSE;
03077
03078 }
03079
03092 dbus_bool_t
03093 dbus_message_set_member (DBusMessage *message,
03094 const char *member)
03095 {
03096 _dbus_return_val_if_fail (message != NULL, FALSE);
03097 _dbus_return_val_if_fail (!message->locked, FALSE);
03098 _dbus_return_val_if_fail (member == NULL ||
03099 _dbus_check_is_valid_member (member),
03100 FALSE);
03101
03102 return set_or_delete_string_field (message,
03103 DBUS_HEADER_FIELD_MEMBER,
03104 DBUS_TYPE_STRING,
03105 member);
03106 }
03107
03119 const char*
03120 dbus_message_get_member (DBusMessage *message)
03121 {
03122 const char *v;
03123
03124 _dbus_return_val_if_fail (message != NULL, NULL);
03125
03126 v = NULL;
03127 _dbus_header_get_field_basic (&message->header,
03128 DBUS_HEADER_FIELD_MEMBER,
03129 DBUS_TYPE_STRING,
03130 (void *) &v);
03131 return v;
03132 }
03133
03141 dbus_bool_t
03142 dbus_message_has_member (DBusMessage *message,
03143 const char *member)
03144 {
03145 const char *msg_member;
03146 msg_member = dbus_message_get_member (message);
03147
03148 if (msg_member == NULL)
03149 {
03150 if (member == NULL)
03151 return TRUE;
03152 else
03153 return FALSE;
03154 }
03155
03156 if (member == NULL)
03157 return FALSE;
03158
03159 if (strcmp (msg_member, member) == 0)
03160 return TRUE;
03161
03162 return FALSE;
03163
03164 }
03165
03177 dbus_bool_t
03178 dbus_message_set_error_name (DBusMessage *message,
03179 const char *error_name)
03180 {
03181 _dbus_return_val_if_fail (message != NULL, FALSE);
03182 _dbus_return_val_if_fail (!message->locked, FALSE);
03183 _dbus_return_val_if_fail (error_name == NULL ||
03184 _dbus_check_is_valid_error_name (error_name),
03185 FALSE);
03186
03187 return set_or_delete_string_field (message,
03188 DBUS_HEADER_FIELD_ERROR_NAME,
03189 DBUS_TYPE_STRING,
03190 error_name);
03191 }
03192
03203 const char*
03204 dbus_message_get_error_name (DBusMessage *message)
03205 {
03206 const char *v;
03207
03208 _dbus_return_val_if_fail (message != NULL, NULL);
03209
03210 v = NULL;
03211 _dbus_header_get_field_basic (&message->header,
03212 DBUS_HEADER_FIELD_ERROR_NAME,
03213 DBUS_TYPE_STRING,
03214 (void *) &v);
03215 return v;
03216 }
03217
03231 dbus_bool_t
03232 dbus_message_set_destination (DBusMessage *message,
03233 const char *destination)
03234 {
03235 _dbus_return_val_if_fail (message != NULL, FALSE);
03236 _dbus_return_val_if_fail (!message->locked, FALSE);
03237 _dbus_return_val_if_fail (destination == NULL ||
03238 _dbus_check_is_valid_bus_name (destination),
03239 FALSE);
03240
03241 return set_or_delete_string_field (message,
03242 DBUS_HEADER_FIELD_DESTINATION,
03243 DBUS_TYPE_STRING,
03244 destination);
03245 }
03246
03256 const char*
03257 dbus_message_get_destination (DBusMessage *message)
03258 {
03259 const char *v;
03260
03261 _dbus_return_val_if_fail (message != NULL, NULL);
03262
03263 v = NULL;
03264 _dbus_header_get_field_basic (&message->header,
03265 DBUS_HEADER_FIELD_DESTINATION,
03266 DBUS_TYPE_STRING,
03267 (void *) &v);
03268 return v;
03269 }
03270
03285 dbus_bool_t
03286 dbus_message_set_sender (DBusMessage *message,
03287 const char *sender)
03288 {
03289 _dbus_return_val_if_fail (message != NULL, FALSE);
03290 _dbus_return_val_if_fail (!message->locked, FALSE);
03291 _dbus_return_val_if_fail (sender == NULL ||
03292 _dbus_check_is_valid_bus_name (sender),
03293 FALSE);
03294
03295 return set_or_delete_string_field (message,
03296 DBUS_HEADER_FIELD_SENDER,
03297 DBUS_TYPE_STRING,
03298 sender);
03299 }
03300
03316 const char*
03317 dbus_message_get_sender (DBusMessage *message)
03318 {
03319 const char *v;
03320
03321 _dbus_return_val_if_fail (message != NULL, NULL);
03322
03323 v = NULL;
03324 _dbus_header_get_field_basic (&message->header,
03325 DBUS_HEADER_FIELD_SENDER,
03326 DBUS_TYPE_STRING,
03327 (void *) &v);
03328 return v;
03329 }
03330
03349 const char*
03350 dbus_message_get_signature (DBusMessage *message)
03351 {
03352 const DBusString *type_str;
03353 int type_pos;
03354
03355 _dbus_return_val_if_fail (message != NULL, NULL);
03356
03357 get_const_signature (&message->header, &type_str, &type_pos);
03358
03359 return _dbus_string_get_const_data_len (type_str, type_pos, 0);
03360 }
03361
03362 static dbus_bool_t
03363 _dbus_message_has_type_interface_member (DBusMessage *message,
03364 int type,
03365 const char *interface,
03366 const char *member)
03367 {
03368 const char *n;
03369
03370 _dbus_assert (message != NULL);
03371 _dbus_assert (interface != NULL);
03372 _dbus_assert (member != NULL);
03373
03374 if (dbus_message_get_type (message) != type)
03375 return FALSE;
03376
03377
03378
03379
03380
03381 n = dbus_message_get_member (message);
03382
03383 if (n && strcmp (n, member) == 0)
03384 {
03385 n = dbus_message_get_interface (message);
03386
03387 if (n == NULL || strcmp (n, interface) == 0)
03388 return TRUE;
03389 }
03390
03391 return FALSE;
03392 }
03393
03408 dbus_bool_t
03409 dbus_message_is_method_call (DBusMessage *message,
03410 const char *interface,
03411 const char *method)
03412 {
03413 _dbus_return_val_if_fail (message != NULL, FALSE);
03414 _dbus_return_val_if_fail (interface != NULL, FALSE);
03415 _dbus_return_val_if_fail (method != NULL, FALSE);
03416
03417
03418
03419
03420 return _dbus_message_has_type_interface_member (message,
03421 DBUS_MESSAGE_TYPE_METHOD_CALL,
03422 interface, method);
03423 }
03424
03436 dbus_bool_t
03437 dbus_message_is_signal (DBusMessage *message,
03438 const char *interface,
03439 const char *signal_name)
03440 {
03441 _dbus_return_val_if_fail (message != NULL, FALSE);
03442 _dbus_return_val_if_fail (interface != NULL, FALSE);
03443 _dbus_return_val_if_fail (signal_name != NULL, FALSE);
03444
03445
03446
03447
03448 return _dbus_message_has_type_interface_member (message,
03449 DBUS_MESSAGE_TYPE_SIGNAL,
03450 interface, signal_name);
03451 }
03452
03463 dbus_bool_t
03464 dbus_message_is_error (DBusMessage *message,
03465 const char *error_name)
03466 {
03467 const char *n;
03468
03469 _dbus_return_val_if_fail (message != NULL, FALSE);
03470 _dbus_return_val_if_fail (error_name != NULL, FALSE);
03471
03472
03473
03474
03475 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
03476 return FALSE;
03477
03478 n = dbus_message_get_error_name (message);
03479
03480 if (n && strcmp (n, error_name) == 0)
03481 return TRUE;
03482 else
03483 return FALSE;
03484 }
03485
03496 dbus_bool_t
03497 dbus_message_has_destination (DBusMessage *message,
03498 const char *name)
03499 {
03500 const char *s;
03501
03502 _dbus_return_val_if_fail (message != NULL, FALSE);
03503 _dbus_return_val_if_fail (name != NULL, FALSE);
03504
03505
03506
03507
03508 s = dbus_message_get_destination (message);
03509
03510 if (s && strcmp (s, name) == 0)
03511 return TRUE;
03512 else
03513 return FALSE;
03514 }
03515
03531 dbus_bool_t
03532 dbus_message_has_sender (DBusMessage *message,
03533 const char *name)
03534 {
03535 const char *s;
03536
03537 _dbus_return_val_if_fail (message != NULL, FALSE);
03538 _dbus_return_val_if_fail (name != NULL, FALSE);
03539
03540
03541
03542
03543 s = dbus_message_get_sender (message);
03544
03545 if (s && strcmp (s, name) == 0)
03546 return TRUE;
03547 else
03548 return FALSE;
03549 }
03550
03560 dbus_bool_t
03561 dbus_message_has_signature (DBusMessage *message,
03562 const char *signature)
03563 {
03564 const char *s;
03565
03566 _dbus_return_val_if_fail (message != NULL, FALSE);
03567 _dbus_return_val_if_fail (signature != NULL, FALSE);
03568
03569
03570
03571
03572 s = dbus_message_get_signature (message);
03573
03574 if (s && strcmp (s, signature) == 0)
03575 return TRUE;
03576 else
03577 return FALSE;
03578 }
03579
03602 dbus_bool_t
03603 dbus_set_error_from_message (DBusError *error,
03604 DBusMessage *message)
03605 {
03606 const char *str;
03607
03608 _dbus_return_val_if_fail (message != NULL, FALSE);
03609 _dbus_return_val_if_error_is_set (error, FALSE);
03610
03611 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
03612 return FALSE;
03613
03614 str = NULL;
03615 dbus_message_get_args (message, NULL,
03616 DBUS_TYPE_STRING, &str,
03617 DBUS_TYPE_INVALID);
03618
03619 dbus_set_error (error, dbus_message_get_error_name (message),
03620 str ? "%s" : NULL, str);
03621
03622 return TRUE;
03623 }
03624
03631 dbus_bool_t
03632 dbus_message_contains_unix_fds(DBusMessage *message)
03633 {
03634 #ifdef HAVE_UNIX_FD_PASSING
03635 _dbus_assert(message);
03636
03637 return message->n_unix_fds > 0;
03638 #else
03639 return FALSE;
03640 #endif
03641 }
03642
03661 #define INITIAL_LOADER_DATA_LEN 32
03662
03669 DBusMessageLoader*
03670 _dbus_message_loader_new (void)
03671 {
03672 DBusMessageLoader *loader;
03673
03674 loader = dbus_new0 (DBusMessageLoader, 1);
03675 if (loader == NULL)
03676 return NULL;
03677
03678 loader->refcount = 1;
03679
03680 loader->corrupted = FALSE;
03681 loader->corruption_reason = DBUS_VALID;
03682
03683
03684 loader->max_message_size = DBUS_MAXIMUM_MESSAGE_LENGTH;
03685
03686
03687
03688
03689
03690 loader->max_message_unix_fds = DBUS_DEFAULT_MESSAGE_UNIX_FDS;
03691
03692 if (!_dbus_string_init (&loader->data))
03693 {
03694 dbus_free (loader);
03695 return NULL;
03696 }
03697
03698
03699 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
03700 _dbus_string_set_length (&loader->data, 0);
03701
03702 #ifdef HAVE_UNIX_FD_PASSING
03703 loader->unix_fds = NULL;
03704 loader->n_unix_fds = loader->n_unix_fds_allocated = 0;
03705 loader->unix_fds_outstanding = FALSE;
03706 #endif
03707
03708 return loader;
03709 }
03710
03717 DBusMessageLoader *
03718 _dbus_message_loader_ref (DBusMessageLoader *loader)
03719 {
03720 loader->refcount += 1;
03721
03722 return loader;
03723 }
03724
03731 void
03732 _dbus_message_loader_unref (DBusMessageLoader *loader)
03733 {
03734 loader->refcount -= 1;
03735 if (loader->refcount == 0)
03736 {
03737 #ifdef HAVE_UNIX_FD_PASSING
03738 close_unix_fds(loader->unix_fds, &loader->n_unix_fds);
03739 dbus_free(loader->unix_fds);
03740 #endif
03741 _dbus_list_foreach (&loader->messages,
03742 (DBusForeachFunction) dbus_message_unref,
03743 NULL);
03744 _dbus_list_clear (&loader->messages);
03745 _dbus_string_free (&loader->data);
03746 dbus_free (loader);
03747 }
03748 }
03749
03768 void
03769 _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
03770 DBusString **buffer)
03771 {
03772 _dbus_assert (!loader->buffer_outstanding);
03773
03774 *buffer = &loader->data;
03775
03776 loader->buffer_outstanding = TRUE;
03777 }
03778
03789 void
03790 _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
03791 DBusString *buffer,
03792 int bytes_read)
03793 {
03794 _dbus_assert (loader->buffer_outstanding);
03795 _dbus_assert (buffer == &loader->data);
03796
03797 loader->buffer_outstanding = FALSE;
03798 }
03799
03810 dbus_bool_t
03811 _dbus_message_loader_get_unix_fds(DBusMessageLoader *loader,
03812 int **fds,
03813 unsigned *max_n_fds)
03814 {
03815 #ifdef HAVE_UNIX_FD_PASSING
03816 _dbus_assert (!loader->unix_fds_outstanding);
03817
03818
03819
03820
03821
03822
03823
03824
03825
03826 if (loader->n_unix_fds_allocated < loader->max_message_unix_fds)
03827 {
03828 int *a = dbus_realloc(loader->unix_fds,
03829 loader->max_message_unix_fds * sizeof(loader->unix_fds[0]));
03830
03831 if (!a)
03832 return FALSE;
03833
03834 loader->unix_fds = a;
03835 loader->n_unix_fds_allocated = loader->max_message_unix_fds;
03836 }
03837
03838 *fds = loader->unix_fds + loader->n_unix_fds;
03839 *max_n_fds = loader->n_unix_fds_allocated - loader->n_unix_fds;
03840
03841 loader->unix_fds_outstanding = TRUE;
03842 return TRUE;
03843 #else
03844 _dbus_assert_not_reached("Platform doesn't support unix fd passing");
03845 return FALSE;
03846 #endif
03847 }
03848
03859 void
03860 _dbus_message_loader_return_unix_fds(DBusMessageLoader *loader,
03861 int *fds,
03862 unsigned n_fds)
03863 {
03864 #ifdef HAVE_UNIX_FD_PASSING
03865 _dbus_assert(loader->unix_fds_outstanding);
03866 _dbus_assert(loader->unix_fds + loader->n_unix_fds == fds);
03867 _dbus_assert(loader->n_unix_fds + n_fds <= loader->n_unix_fds_allocated);
03868
03869 loader->n_unix_fds += n_fds;
03870 loader->unix_fds_outstanding = FALSE;
03871
03872 if (n_fds && loader->unix_fds_change)
03873 loader->unix_fds_change (loader->unix_fds_change_data);
03874 #else
03875 _dbus_assert_not_reached("Platform doesn't support unix fd passing");
03876 #endif
03877 }
03878
03879
03880
03881
03882
03883
03884
03885
03886
03887
03888
03889
03890
03891
03892
03893
03894
03895
03896
03897
03898
03899
03900
03901
03902
03903
03904
03905 static dbus_bool_t
03906 load_message (DBusMessageLoader *loader,
03907 DBusMessage *message,
03908 int byte_order,
03909 int fields_array_len,
03910 int header_len,
03911 int body_len)
03912 {
03913 dbus_bool_t oom;
03914 DBusValidity validity;
03915 const DBusString *type_str;
03916 int type_pos;
03917 DBusValidationMode mode;
03918 dbus_uint32_t n_unix_fds = 0;
03919
03920 mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
03921
03922 oom = FALSE;
03923
03924 #if 0
03925 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len );
03926 #endif
03927
03928
03929 _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
03930 _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
03931
03932 if (!_dbus_header_load (&message->header,
03933 mode,
03934 &validity,
03935 byte_order,
03936 fields_array_len,
03937 header_len,
03938 body_len,
03939 &loader->data, 0,
03940 _dbus_string_get_length (&loader->data)))
03941 {
03942 _dbus_verbose ("Failed to load header for new message code %d\n", validity);
03943
03944
03945
03946 _dbus_assert (validity != DBUS_VALID);
03947
03948 if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
03949 oom = TRUE;
03950 else
03951 {
03952 loader->corrupted = TRUE;
03953 loader->corruption_reason = validity;
03954 }
03955 goto failed;
03956 }
03957
03958 _dbus_assert (validity == DBUS_VALID);
03959
03960 message->byte_order = byte_order;
03961
03962
03963 if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
03964 {
03965 get_const_signature (&message->header, &type_str, &type_pos);
03966
03967
03968
03969
03970 validity = _dbus_validate_body_with_reason (type_str,
03971 type_pos,
03972 byte_order,
03973 NULL,
03974 &loader->data,
03975 header_len,
03976 body_len);
03977 if (validity != DBUS_VALID)
03978 {
03979 _dbus_verbose ("Failed to validate message body code %d\n", validity);
03980
03981 loader->corrupted = TRUE;
03982 loader->corruption_reason = validity;
03983
03984 goto failed;
03985 }
03986 }
03987
03988
03989 _dbus_header_get_field_basic(&message->header,
03990 DBUS_HEADER_FIELD_UNIX_FDS,
03991 DBUS_TYPE_UINT32,
03992 &n_unix_fds);
03993
03994 #ifdef HAVE_UNIX_FD_PASSING
03995
03996 if (n_unix_fds > loader->n_unix_fds)
03997 {
03998 _dbus_verbose("Message contains references to more unix fds than were sent %u != %u\n",
03999 n_unix_fds, loader->n_unix_fds);
04000
04001 loader->corrupted = TRUE;
04002 loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
04003 goto failed;
04004 }
04005
04006
04007
04008 dbus_free(message->unix_fds);
04009
04010 if (n_unix_fds > 0)
04011 {
04012 message->unix_fds = _dbus_memdup(loader->unix_fds, n_unix_fds * sizeof(message->unix_fds[0]));
04013 if (message->unix_fds == NULL)
04014 {
04015 _dbus_verbose ("Failed to allocate file descriptor array\n");
04016 oom = TRUE;
04017 goto failed;
04018 }
04019
04020 message->n_unix_fds_allocated = message->n_unix_fds = n_unix_fds;
04021 loader->n_unix_fds -= n_unix_fds;
04022 memmove (loader->unix_fds, loader->unix_fds + n_unix_fds, loader->n_unix_fds * sizeof (loader->unix_fds[0]));
04023
04024 if (loader->unix_fds_change)
04025 loader->unix_fds_change (loader->unix_fds_change_data);
04026 }
04027 else
04028 message->unix_fds = NULL;
04029
04030 #else
04031
04032 if (n_unix_fds > 0)
04033 {
04034 _dbus_verbose ("Hmm, message claims to come with file descriptors "
04035 "but that's not supported on our platform, disconnecting.\n");
04036
04037 loader->corrupted = TRUE;
04038 loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
04039 goto failed;
04040 }
04041
04042 #endif
04043
04044
04045
04046 if (!_dbus_list_append (&loader->messages, message))
04047 {
04048 _dbus_verbose ("Failed to append new message to loader queue\n");
04049 oom = TRUE;
04050 goto failed;
04051 }
04052
04053 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
04054 _dbus_assert (_dbus_string_get_length (&loader->data) >=
04055 (header_len + body_len));
04056
04057 if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
04058 {
04059 _dbus_verbose ("Failed to move body into new message\n");
04060 oom = TRUE;
04061 goto failed;
04062 }
04063
04064 _dbus_string_delete (&loader->data, 0, header_len + body_len);
04065
04066
04067 _dbus_string_compact (&loader->data, 2048);
04068
04069 _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
04070 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
04071
04072 _dbus_verbose ("Loaded message %p\n", message);
04073
04074 _dbus_assert (!oom);
04075 _dbus_assert (!loader->corrupted);
04076 _dbus_assert (loader->messages != NULL);
04077 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
04078
04079 return TRUE;
04080
04081 failed:
04082
04083
04084
04085
04086 _dbus_list_remove_last (&loader->messages, message);
04087
04088 if (oom)
04089 _dbus_assert (!loader->corrupted);
04090 else
04091 _dbus_assert (loader->corrupted);
04092
04093 _dbus_verbose_bytes_of_string (&loader->data, 0, _dbus_string_get_length (&loader->data));
04094
04095 return FALSE;
04096 }
04097
04112 dbus_bool_t
04113 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
04114 {
04115 while (!loader->corrupted &&
04116 _dbus_string_get_length (&loader->data) >= DBUS_MINIMUM_HEADER_SIZE)
04117 {
04118 DBusValidity validity;
04119 int byte_order, fields_array_len, header_len, body_len;
04120
04121 if (_dbus_header_have_message_untrusted (loader->max_message_size,
04122 &validity,
04123 &byte_order,
04124 &fields_array_len,
04125 &header_len,
04126 &body_len,
04127 &loader->data, 0,
04128 _dbus_string_get_length (&loader->data)))
04129 {
04130 DBusMessage *message;
04131
04132 _dbus_assert (validity == DBUS_VALID);
04133
04134 message = dbus_message_new_empty_header ();
04135 if (message == NULL)
04136 return FALSE;
04137
04138 if (!load_message (loader, message,
04139 byte_order, fields_array_len,
04140 header_len, body_len))
04141 {
04142 dbus_message_unref (message);
04143
04144
04145
04146 return loader->corrupted;
04147 }
04148
04149 _dbus_assert (loader->messages != NULL);
04150 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
04151 }
04152 else
04153 {
04154 _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
04155 validity);
04156 if (validity != DBUS_VALID)
04157 {
04158 loader->corrupted = TRUE;
04159 loader->corruption_reason = validity;
04160 }
04161 return TRUE;
04162 }
04163 }
04164
04165 return TRUE;
04166 }
04167
04175 DBusMessage*
04176 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
04177 {
04178 if (loader->messages)
04179 return loader->messages->data;
04180 else
04181 return NULL;
04182 }
04183
04192 DBusMessage*
04193 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
04194 {
04195 return _dbus_list_pop_first (&loader->messages);
04196 }
04197
04206 DBusList*
04207 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
04208 {
04209 return _dbus_list_pop_first_link (&loader->messages);
04210 }
04211
04218 void
04219 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
04220 DBusList *link)
04221 {
04222 _dbus_list_prepend_link (&loader->messages, link);
04223 }
04224
04234 dbus_bool_t
04235 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
04236 {
04237 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
04238 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
04239 return loader->corrupted;
04240 }
04241
04248 DBusValidity
04249 _dbus_message_loader_get_corruption_reason (DBusMessageLoader *loader)
04250 {
04251 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
04252 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
04253
04254 return loader->corruption_reason;
04255 }
04256
04263 void
04264 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
04265 long size)
04266 {
04267 if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
04268 {
04269 _dbus_verbose ("clamping requested max message size %ld to %d\n",
04270 size, DBUS_MAXIMUM_MESSAGE_LENGTH);
04271 size = DBUS_MAXIMUM_MESSAGE_LENGTH;
04272 }
04273 loader->max_message_size = size;
04274 }
04275
04282 long
04283 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
04284 {
04285 return loader->max_message_size;
04286 }
04287
04294 void
04295 _dbus_message_loader_set_max_message_unix_fds (DBusMessageLoader *loader,
04296 long n)
04297 {
04298 if (n > DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
04299 {
04300 _dbus_verbose ("clamping requested max message unix_fds %ld to %d\n",
04301 n, DBUS_MAXIMUM_MESSAGE_UNIX_FDS);
04302 n = DBUS_MAXIMUM_MESSAGE_UNIX_FDS;
04303 }
04304 loader->max_message_unix_fds = n;
04305 }
04306
04313 long
04314 _dbus_message_loader_get_max_message_unix_fds (DBusMessageLoader *loader)
04315 {
04316 return loader->max_message_unix_fds;
04317 }
04318
04319 static DBusDataSlotAllocator slot_allocator;
04320 _DBUS_DEFINE_GLOBAL_LOCK (message_slots);
04321
04327 int
04328 _dbus_message_loader_get_pending_fds_count (DBusMessageLoader *loader)
04329 {
04330 #ifdef HAVE_UNIX_FD_PASSING
04331 return loader->n_unix_fds;
04332 #else
04333 return 0;
04334 #endif
04335 }
04336
04345 void
04346 _dbus_message_loader_set_pending_fds_function (DBusMessageLoader *loader,
04347 void (* callback) (void *),
04348 void *data)
04349 {
04350 #ifdef HAVE_UNIX_FD_PASSING
04351 loader->unix_fds_change = callback;
04352 loader->unix_fds_change_data = data;
04353 #endif
04354 }
04355
04370 dbus_bool_t
04371 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
04372 {
04373 return _dbus_data_slot_allocator_alloc (&slot_allocator,
04374 &_DBUS_LOCK_NAME (message_slots),
04375 slot_p);
04376 }
04377
04389 void
04390 dbus_message_free_data_slot (dbus_int32_t *slot_p)
04391 {
04392 _dbus_return_if_fail (*slot_p >= 0);
04393
04394 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
04395 }
04396
04410 dbus_bool_t
04411 dbus_message_set_data (DBusMessage *message,
04412 dbus_int32_t slot,
04413 void *data,
04414 DBusFreeFunction free_data_func)
04415 {
04416 DBusFreeFunction old_free_func;
04417 void *old_data;
04418 dbus_bool_t retval;
04419
04420 _dbus_return_val_if_fail (message != NULL, FALSE);
04421 _dbus_return_val_if_fail (slot >= 0, FALSE);
04422
04423 retval = _dbus_data_slot_list_set (&slot_allocator,
04424 &message->slot_list,
04425 slot, data, free_data_func,
04426 &old_free_func, &old_data);
04427
04428 if (retval)
04429 {
04430
04431 if (old_free_func)
04432 (* old_free_func) (old_data);
04433 }
04434
04435 return retval;
04436 }
04437
04446 void*
04447 dbus_message_get_data (DBusMessage *message,
04448 dbus_int32_t slot)
04449 {
04450 void *res;
04451
04452 _dbus_return_val_if_fail (message != NULL, NULL);
04453
04454 res = _dbus_data_slot_list_get (&slot_allocator,
04455 &message->slot_list,
04456 slot);
04457
04458 return res;
04459 }
04460
04474 int
04475 dbus_message_type_from_string (const char *type_str)
04476 {
04477 if (strcmp (type_str, "method_call") == 0)
04478 return DBUS_MESSAGE_TYPE_METHOD_CALL;
04479 if (strcmp (type_str, "method_return") == 0)
04480 return DBUS_MESSAGE_TYPE_METHOD_RETURN;
04481 else if (strcmp (type_str, "signal") == 0)
04482 return DBUS_MESSAGE_TYPE_SIGNAL;
04483 else if (strcmp (type_str, "error") == 0)
04484 return DBUS_MESSAGE_TYPE_ERROR;
04485 else
04486 return DBUS_MESSAGE_TYPE_INVALID;
04487 }
04488
04502 const char *
04503 dbus_message_type_to_string (int type)
04504 {
04505 switch (type)
04506 {
04507 case DBUS_MESSAGE_TYPE_METHOD_CALL:
04508 return "method_call";
04509 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
04510 return "method_return";
04511 case DBUS_MESSAGE_TYPE_SIGNAL:
04512 return "signal";
04513 case DBUS_MESSAGE_TYPE_ERROR:
04514 return "error";
04515 default:
04516 return "invalid";
04517 }
04518 }
04519
04532 dbus_bool_t
04533 dbus_message_marshal (DBusMessage *msg,
04534 char **marshalled_data_p,
04535 int *len_p)
04536 {
04537 DBusString tmp;
04538 dbus_bool_t was_locked;
04539
04540 _dbus_return_val_if_fail (msg != NULL, FALSE);
04541 _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
04542 _dbus_return_val_if_fail (len_p != NULL, FALSE);
04543
04544 if (!_dbus_string_init (&tmp))
04545 return FALSE;
04546
04547
04548 was_locked = msg->locked;
04549
04550 if (!was_locked)
04551 dbus_message_lock (msg);
04552
04553 if (!_dbus_string_copy (&(msg->header.data), 0, &tmp, 0))
04554 goto fail;
04555
04556 *len_p = _dbus_string_get_length (&tmp);
04557
04558 if (!_dbus_string_copy (&(msg->body), 0, &tmp, *len_p))
04559 goto fail;
04560
04561 *len_p = _dbus_string_get_length (&tmp);
04562
04563 if (!_dbus_string_steal_data (&tmp, marshalled_data_p))
04564 goto fail;
04565
04566 _dbus_string_free (&tmp);
04567
04568 if (!was_locked)
04569 msg->locked = FALSE;
04570
04571 return TRUE;
04572
04573 fail:
04574 _dbus_string_free (&tmp);
04575
04576 if (!was_locked)
04577 msg->locked = FALSE;
04578
04579 return FALSE;
04580 }
04581
04594 DBusMessage *
04595 dbus_message_demarshal (const char *str,
04596 int len,
04597 DBusError *error)
04598 {
04599 DBusMessageLoader *loader;
04600 DBusString *buffer;
04601 DBusMessage *msg;
04602
04603 _dbus_return_val_if_fail (str != NULL, NULL);
04604
04605 loader = _dbus_message_loader_new ();
04606
04607 if (loader == NULL)
04608 return NULL;
04609
04610 _dbus_message_loader_get_buffer (loader, &buffer);
04611 _dbus_string_append_len (buffer, str, len);
04612 _dbus_message_loader_return_buffer (loader, buffer, len);
04613
04614 if (!_dbus_message_loader_queue_messages (loader))
04615 goto fail_oom;
04616
04617 if (_dbus_message_loader_get_is_corrupted (loader))
04618 goto fail_corrupt;
04619
04620 msg = _dbus_message_loader_pop_message (loader);
04621
04622 if (!msg)
04623 goto fail_oom;
04624
04625 _dbus_message_loader_unref (loader);
04626 return msg;
04627
04628 fail_corrupt:
04629 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted (%s)",
04630 _dbus_validity_to_error_message (loader->corruption_reason));
04631 _dbus_message_loader_unref (loader);
04632 return NULL;
04633
04634 fail_oom:
04635 _DBUS_SET_OOM (error);
04636 _dbus_message_loader_unref (loader);
04637 return NULL;
04638 }
04639
04653 int
04654 dbus_message_demarshal_bytes_needed(const char *buf,
04655 int len)
04656 {
04657 DBusString str;
04658 int byte_order, fields_array_len, header_len, body_len;
04659 DBusValidity validity = DBUS_VALID;
04660 int have_message;
04661
04662 if (!buf || len < DBUS_MINIMUM_HEADER_SIZE)
04663 return 0;
04664
04665 if (len > DBUS_MAXIMUM_MESSAGE_LENGTH)
04666 len = DBUS_MAXIMUM_MESSAGE_LENGTH;
04667 _dbus_string_init_const_len (&str, buf, len);
04668
04669 validity = DBUS_VALID;
04670 have_message
04671 = _dbus_header_have_message_untrusted(DBUS_MAXIMUM_MESSAGE_LENGTH,
04672 &validity, &byte_order,
04673 &fields_array_len,
04674 &header_len,
04675 &body_len,
04676 &str, 0,
04677 len);
04678 _dbus_string_free (&str);
04679
04680 if (validity == DBUS_VALID)
04681 {
04682 _dbus_assert(have_message);
04683 return header_len + body_len;
04684 }
04685 else
04686 {
04687 return -1;
04688 }
04689 }
04690
04693