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-unix.h"
00039 #endif
00040
00041 #include <string.h>
00042
00043 static void dbus_message_finalize (DBusMessage *message);
00044
00055
00056
00058 _DBUS_STRING_DEFINE_STATIC(_dbus_empty_signature_str, "");
00059
00060
00061
00062
00063 enum {
00064 DBUS_MESSAGE_ITER_TYPE_READER = 3,
00065 DBUS_MESSAGE_ITER_TYPE_WRITER = 7
00066 };
00067
00069 typedef struct DBusMessageRealIter DBusMessageRealIter;
00070
00076 struct DBusMessageRealIter
00077 {
00078 DBusMessage *message;
00079 dbus_uint32_t changed_stamp : CHANGED_STAMP_BITS;
00080 dbus_uint32_t iter_type : 3;
00081 dbus_uint32_t sig_refcount : 8;
00082 union
00083 {
00084 DBusTypeWriter writer;
00085 DBusTypeReader reader;
00086 } u;
00087 };
00088
00089 static void
00090 get_const_signature (DBusHeader *header,
00091 const DBusString **type_str_p,
00092 int *type_pos_p)
00093 {
00094 if (_dbus_header_get_field_raw (header,
00095 DBUS_HEADER_FIELD_SIGNATURE,
00096 type_str_p,
00097 type_pos_p))
00098 {
00099 *type_pos_p += 1;
00100 }
00101 else
00102 {
00103 *type_str_p = &_dbus_empty_signature_str;
00104 *type_pos_p = 0;
00105 }
00106 }
00107
00113 static void
00114 _dbus_message_byteswap (DBusMessage *message)
00115 {
00116 const DBusString *type_str;
00117 int type_pos;
00118
00119 if (message->byte_order == DBUS_COMPILER_BYTE_ORDER)
00120 return;
00121
00122 _dbus_verbose ("Swapping message into compiler byte order\n");
00123
00124 get_const_signature (&message->header, &type_str, &type_pos);
00125
00126 _dbus_marshal_byteswap (type_str, type_pos,
00127 message->byte_order,
00128 DBUS_COMPILER_BYTE_ORDER,
00129 &message->body, 0);
00130
00131 message->byte_order = DBUS_COMPILER_BYTE_ORDER;
00132
00133 _dbus_header_byteswap (&message->header, DBUS_COMPILER_BYTE_ORDER);
00134 }
00135
00142 #define ensure_byte_order(message) \
00143 if (message->byte_order != DBUS_COMPILER_BYTE_ORDER) \
00144 _dbus_message_byteswap (message)
00145
00156 void
00157 _dbus_message_get_network_data (DBusMessage *message,
00158 const DBusString **header,
00159 const DBusString **body)
00160 {
00161 _dbus_assert (message->locked);
00162
00163 *header = &message->header.data;
00164 *body = &message->body;
00165 }
00166
00176 void _dbus_message_get_unix_fds(DBusMessage *message,
00177 const int **fds,
00178 unsigned *n_fds)
00179 {
00180 _dbus_assert (message->locked);
00181
00182 #ifdef HAVE_UNIX_FD_PASSING
00183 *fds = message->unix_fds;
00184 *n_fds = message->n_unix_fds;
00185 #else
00186 *fds = NULL;
00187 *n_fds = 0;
00188 #endif
00189 }
00190
00202 void
00203 dbus_message_set_serial (DBusMessage *message,
00204 dbus_uint32_t serial)
00205 {
00206 _dbus_return_if_fail (message != NULL);
00207 _dbus_return_if_fail (!message->locked);
00208
00209 _dbus_header_set_serial (&message->header, serial);
00210 }
00211
00223 void
00224 _dbus_message_add_counter_link (DBusMessage *message,
00225 DBusList *link)
00226 {
00227
00228
00229
00230
00231
00232
00233 if (message->counters == NULL)
00234 {
00235 message->size_counter_delta =
00236 _dbus_string_get_length (&message->header.data) +
00237 _dbus_string_get_length (&message->body);
00238
00239 #ifdef HAVE_UNIX_FD_PASSING
00240 message->unix_fd_counter_delta = message->n_unix_fds;
00241 #endif
00242
00243 #if 0
00244 _dbus_verbose ("message has size %ld\n",
00245 message->size_counter_delta);
00246 #endif
00247 }
00248
00249 _dbus_list_append_link (&message->counters, link);
00250
00251 _dbus_counter_adjust_size (link->data, message->size_counter_delta);
00252
00253 #ifdef HAVE_UNIX_FD_PASSING
00254 _dbus_counter_adjust_unix_fd (link->data, message->unix_fd_counter_delta);
00255 #endif
00256 }
00257
00267 dbus_bool_t
00268 _dbus_message_add_counter (DBusMessage *message,
00269 DBusCounter *counter)
00270 {
00271 DBusList *link;
00272
00273 link = _dbus_list_alloc_link (counter);
00274 if (link == NULL)
00275 return FALSE;
00276
00277 _dbus_counter_ref (counter);
00278 _dbus_message_add_counter_link (message, link);
00279
00280 return TRUE;
00281 }
00282
00291 void
00292 _dbus_message_remove_counter (DBusMessage *message,
00293 DBusCounter *counter,
00294 DBusList **link_return)
00295 {
00296 DBusList *link;
00297
00298 link = _dbus_list_find_last (&message->counters,
00299 counter);
00300 _dbus_assert (link != NULL);
00301
00302 _dbus_list_unlink (&message->counters,
00303 link);
00304 if (link_return)
00305 *link_return = link;
00306 else
00307 _dbus_list_free_link (link);
00308
00309 _dbus_counter_adjust_size (counter, - message->size_counter_delta);
00310
00311 #ifdef HAVE_UNIX_FD_PASSING
00312 _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
00313 #endif
00314
00315 _dbus_counter_unref (counter);
00316 }
00317
00328 void
00329 dbus_message_lock (DBusMessage *message)
00330 {
00331 if (!message->locked)
00332 {
00333 _dbus_header_update_lengths (&message->header,
00334 _dbus_string_get_length (&message->body));
00335
00336
00337 _dbus_assert (_dbus_string_get_length (&message->body) == 0 ||
00338 dbus_message_get_signature (message) != NULL);
00339
00340 message->locked = TRUE;
00341 }
00342 }
00343
00344 static dbus_bool_t
00345 set_or_delete_string_field (DBusMessage *message,
00346 int field,
00347 int typecode,
00348 const char *value)
00349 {
00350 if (value == NULL)
00351 return _dbus_header_delete_field (&message->header, field);
00352 else
00353 return _dbus_header_set_field_basic (&message->header,
00354 field,
00355 typecode,
00356 &value);
00357 }
00358
00359 #if 0
00360
00384 static dbus_bool_t
00385 _dbus_message_set_signature (DBusMessage *message,
00386 const char *signature)
00387 {
00388 _dbus_return_val_if_fail (message != NULL, FALSE);
00389 _dbus_return_val_if_fail (!message->locked, FALSE);
00390 _dbus_return_val_if_fail (signature == NULL ||
00391 _dbus_check_is_valid_signature (signature));
00392
00393 _dbus_return_val_if_fail (_dbus_string_get_length (&message->body) == 0 ||
00394 signature != NULL);
00395
00396 return set_or_delete_string_field (message,
00397 DBUS_HEADER_FIELD_SIGNATURE,
00398 DBUS_TYPE_SIGNATURE,
00399 signature);
00400 }
00401 #endif
00402
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
00450 #define MAX_MESSAGE_SIZE_TO_CACHE 10 * _DBUS_ONE_KILOBYTE
00451
00453 #define MAX_MESSAGE_CACHE_SIZE 5
00454
00455 _DBUS_DEFINE_GLOBAL_LOCK (message_cache);
00456 static DBusMessage *message_cache[MAX_MESSAGE_CACHE_SIZE];
00457 static int message_cache_count = 0;
00458 static dbus_bool_t message_cache_shutdown_registered = FALSE;
00459
00460 static void
00461 dbus_message_cache_shutdown (void *data)
00462 {
00463 int i;
00464
00465 _DBUS_LOCK (message_cache);
00466
00467 i = 0;
00468 while (i < MAX_MESSAGE_CACHE_SIZE)
00469 {
00470 if (message_cache[i])
00471 dbus_message_finalize (message_cache[i]);
00472
00473 ++i;
00474 }
00475
00476 message_cache_count = 0;
00477 message_cache_shutdown_registered = FALSE;
00478
00479 _DBUS_UNLOCK (message_cache);
00480 }
00481
00489 static DBusMessage*
00490 dbus_message_get_cached (void)
00491 {
00492 DBusMessage *message;
00493 int i;
00494
00495 message = NULL;
00496
00497 _DBUS_LOCK (message_cache);
00498
00499 _dbus_assert (message_cache_count >= 0);
00500
00501 if (message_cache_count == 0)
00502 {
00503 _DBUS_UNLOCK (message_cache);
00504 return NULL;
00505 }
00506
00507
00508
00509
00510
00511 _dbus_assert (message_cache_shutdown_registered);
00512
00513 i = 0;
00514 while (i < MAX_MESSAGE_CACHE_SIZE)
00515 {
00516 if (message_cache[i])
00517 {
00518 message = message_cache[i];
00519 message_cache[i] = NULL;
00520 message_cache_count -= 1;
00521 break;
00522 }
00523 ++i;
00524 }
00525 _dbus_assert (message_cache_count >= 0);
00526 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
00527 _dbus_assert (message != NULL);
00528
00529 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
00530
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 (_dbus_atomic_get (&message->refcount) == 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 (_dbus_atomic_get (&message->refcount) == 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 (_dbus_atomic_get (&message->refcount) == 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 (_dbus_atomic_get (&message->refcount) == 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_new0 (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 _dbus_atomic_inc (&message->refcount);
01094
01095 message->byte_order = DBUS_COMPILER_BYTE_ORDER;
01096 message->locked = FALSE;
01097 #ifndef DBUS_DISABLE_CHECKS
01098 message->in_cache = FALSE;
01099 #endif
01100 message->counters = NULL;
01101 message->size_counter_delta = 0;
01102 message->changed_stamp = 0;
01103
01104 #ifdef HAVE_UNIX_FD_PASSING
01105 message->n_unix_fds = 0;
01106 message->n_unix_fds_allocated = 0;
01107 message->unix_fd_counter_delta = 0;
01108 #endif
01109
01110 if (!from_cache)
01111 _dbus_data_slot_list_init (&message->slot_list);
01112
01113 if (from_cache)
01114 {
01115 _dbus_header_reinit (&message->header, message->byte_order);
01116 _dbus_string_set_length (&message->body, 0);
01117 }
01118 else
01119 {
01120 if (!_dbus_header_init (&message->header, message->byte_order))
01121 {
01122 dbus_free (message);
01123 return NULL;
01124 }
01125
01126 if (!_dbus_string_init_preallocated (&message->body, 32))
01127 {
01128 _dbus_header_free (&message->header);
01129 dbus_free (message);
01130 return NULL;
01131 }
01132 }
01133
01134 return message;
01135 }
01136
01149 DBusMessage*
01150 dbus_message_new (int message_type)
01151 {
01152 DBusMessage *message;
01153
01154 _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
01155
01156 message = dbus_message_new_empty_header ();
01157 if (message == NULL)
01158 return NULL;
01159
01160 if (!_dbus_header_create (&message->header,
01161 message_type,
01162 NULL, NULL, NULL, NULL, NULL))
01163 {
01164 dbus_message_unref (message);
01165 return NULL;
01166 }
01167
01168 return message;
01169 }
01170
01192 DBusMessage*
01193 dbus_message_new_method_call (const char *destination,
01194 const char *path,
01195 const char *interface,
01196 const char *method)
01197 {
01198 DBusMessage *message;
01199
01200 _dbus_return_val_if_fail (path != NULL, NULL);
01201 _dbus_return_val_if_fail (method != NULL, NULL);
01202 _dbus_return_val_if_fail (destination == NULL ||
01203 _dbus_check_is_valid_bus_name (destination), NULL);
01204 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
01205 _dbus_return_val_if_fail (interface == NULL ||
01206 _dbus_check_is_valid_interface (interface), NULL);
01207 _dbus_return_val_if_fail (_dbus_check_is_valid_member (method), NULL);
01208
01209 message = dbus_message_new_empty_header ();
01210 if (message == NULL)
01211 return NULL;
01212
01213 if (!_dbus_header_create (&message->header,
01214 DBUS_MESSAGE_TYPE_METHOD_CALL,
01215 destination, path, interface, method, NULL))
01216 {
01217 dbus_message_unref (message);
01218 return NULL;
01219 }
01220
01221 return message;
01222 }
01223
01231 DBusMessage*
01232 dbus_message_new_method_return (DBusMessage *method_call)
01233 {
01234 DBusMessage *message;
01235 const char *sender;
01236
01237 _dbus_return_val_if_fail (method_call != NULL, NULL);
01238
01239 sender = dbus_message_get_sender (method_call);
01240
01241
01242
01243 message = dbus_message_new_empty_header ();
01244 if (message == NULL)
01245 return NULL;
01246
01247 if (!_dbus_header_create (&message->header,
01248 DBUS_MESSAGE_TYPE_METHOD_RETURN,
01249 sender, NULL, NULL, NULL, NULL))
01250 {
01251 dbus_message_unref (message);
01252 return NULL;
01253 }
01254
01255 dbus_message_set_no_reply (message, TRUE);
01256
01257 if (!dbus_message_set_reply_serial (message,
01258 dbus_message_get_serial (method_call)))
01259 {
01260 dbus_message_unref (message);
01261 return NULL;
01262 }
01263
01264 return message;
01265 }
01266
01281 DBusMessage*
01282 dbus_message_new_signal (const char *path,
01283 const char *interface,
01284 const char *name)
01285 {
01286 DBusMessage *message;
01287
01288 _dbus_return_val_if_fail (path != NULL, NULL);
01289 _dbus_return_val_if_fail (interface != NULL, NULL);
01290 _dbus_return_val_if_fail (name != NULL, NULL);
01291 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
01292 _dbus_return_val_if_fail (_dbus_check_is_valid_interface (interface), NULL);
01293 _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);
01294
01295 message = dbus_message_new_empty_header ();
01296 if (message == NULL)
01297 return NULL;
01298
01299 if (!_dbus_header_create (&message->header,
01300 DBUS_MESSAGE_TYPE_SIGNAL,
01301 NULL, path, interface, name, NULL))
01302 {
01303 dbus_message_unref (message);
01304 return NULL;
01305 }
01306
01307 dbus_message_set_no_reply (message, TRUE);
01308
01309 return message;
01310 }
01311
01326 DBusMessage*
01327 dbus_message_new_error (DBusMessage *reply_to,
01328 const char *error_name,
01329 const char *error_message)
01330 {
01331 DBusMessage *message;
01332 const char *sender;
01333 DBusMessageIter iter;
01334
01335 _dbus_return_val_if_fail (reply_to != NULL, NULL);
01336 _dbus_return_val_if_fail (error_name != NULL, NULL);
01337 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
01338
01339 sender = dbus_message_get_sender (reply_to);
01340
01341
01342
01343
01344
01345 message = dbus_message_new_empty_header ();
01346 if (message == NULL)
01347 return NULL;
01348
01349 if (!_dbus_header_create (&message->header,
01350 DBUS_MESSAGE_TYPE_ERROR,
01351 sender, NULL, NULL, NULL, error_name))
01352 {
01353 dbus_message_unref (message);
01354 return NULL;
01355 }
01356
01357 dbus_message_set_no_reply (message, TRUE);
01358
01359 if (!dbus_message_set_reply_serial (message,
01360 dbus_message_get_serial (reply_to)))
01361 {
01362 dbus_message_unref (message);
01363 return NULL;
01364 }
01365
01366 if (error_message != NULL)
01367 {
01368 dbus_message_iter_init_append (message, &iter);
01369 if (!dbus_message_iter_append_basic (&iter,
01370 DBUS_TYPE_STRING,
01371 &error_message))
01372 {
01373 dbus_message_unref (message);
01374 return NULL;
01375 }
01376 }
01377
01378 return message;
01379 }
01380
01397 DBusMessage*
01398 dbus_message_new_error_printf (DBusMessage *reply_to,
01399 const char *error_name,
01400 const char *error_format,
01401 ...)
01402 {
01403 va_list args;
01404 DBusString str;
01405 DBusMessage *message;
01406
01407 _dbus_return_val_if_fail (reply_to != NULL, NULL);
01408 _dbus_return_val_if_fail (error_name != NULL, NULL);
01409 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
01410
01411 if (!_dbus_string_init (&str))
01412 return NULL;
01413
01414 va_start (args, error_format);
01415
01416 if (_dbus_string_append_printf_valist (&str, error_format, args))
01417 message = dbus_message_new_error (reply_to, error_name,
01418 _dbus_string_get_const_data (&str));
01419 else
01420 message = NULL;
01421
01422 _dbus_string_free (&str);
01423
01424 va_end (args);
01425
01426 return message;
01427 }
01428
01429
01442 DBusMessage *
01443 dbus_message_copy (const DBusMessage *message)
01444 {
01445 DBusMessage *retval;
01446
01447 _dbus_return_val_if_fail (message != NULL, NULL);
01448
01449 retval = dbus_new0 (DBusMessage, 1);
01450 if (retval == NULL)
01451 return NULL;
01452
01453 _dbus_atomic_inc (&retval->refcount);
01454 retval->byte_order = message->byte_order;
01455 retval->locked = FALSE;
01456 #ifndef DBUS_DISABLE_CHECKS
01457 retval->generation = message->generation;
01458 #endif
01459
01460 if (!_dbus_header_copy (&message->header, &retval->header))
01461 {
01462 dbus_free (retval);
01463 return NULL;
01464 }
01465
01466 if (!_dbus_string_init_preallocated (&retval->body,
01467 _dbus_string_get_length (&message->body)))
01468 {
01469 _dbus_header_free (&retval->header);
01470 dbus_free (retval);
01471 return NULL;
01472 }
01473
01474 if (!_dbus_string_copy (&message->body, 0,
01475 &retval->body, 0))
01476 goto failed_copy;
01477
01478 #ifdef HAVE_UNIX_FD_PASSING
01479 retval->unix_fds = dbus_new(int, message->n_unix_fds);
01480 if (retval->unix_fds == NULL && message->n_unix_fds > 0)
01481 goto failed_copy;
01482
01483 retval->n_unix_fds_allocated = message->n_unix_fds;
01484
01485 for (retval->n_unix_fds = 0;
01486 retval->n_unix_fds < message->n_unix_fds;
01487 retval->n_unix_fds++)
01488 {
01489 retval->unix_fds[retval->n_unix_fds] = _dbus_dup(message->unix_fds[retval->n_unix_fds], NULL);
01490
01491 if (retval->unix_fds[retval->n_unix_fds] < 0)
01492 goto failed_copy;
01493 }
01494
01495 #endif
01496
01497 return retval;
01498
01499 failed_copy:
01500 _dbus_header_free (&retval->header);
01501 _dbus_string_free (&retval->body);
01502
01503 #ifdef HAVE_UNIX_FD_PASSING
01504 close_unix_fds(retval->unix_fds, &retval->n_unix_fds);
01505 dbus_free(retval->unix_fds);
01506 #endif
01507
01508 dbus_free (retval);
01509
01510 return NULL;
01511 }
01512
01513
01521 DBusMessage *
01522 dbus_message_ref (DBusMessage *message)
01523 {
01524 #ifndef DBUS_DISABLE_ASSERT
01525 dbus_int32_t old_refcount;
01526 #endif
01527
01528 _dbus_return_val_if_fail (message != NULL, NULL);
01529 _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
01530 _dbus_return_val_if_fail (!message->in_cache, NULL);
01531
01532 #ifdef DBUS_DISABLE_ASSERT
01533 _dbus_atomic_inc (&message->refcount);
01534 #else
01535 old_refcount = _dbus_atomic_inc (&message->refcount);
01536 _dbus_assert (old_refcount >= 1);
01537 #endif
01538
01539 return message;
01540 }
01541
01549 void
01550 dbus_message_unref (DBusMessage *message)
01551 {
01552 dbus_int32_t old_refcount;
01553
01554 _dbus_return_if_fail (message != NULL);
01555 _dbus_return_if_fail (message->generation == _dbus_current_generation);
01556 _dbus_return_if_fail (!message->in_cache);
01557
01558 old_refcount = _dbus_atomic_dec (&message->refcount);
01559
01560 _dbus_assert (old_refcount >= 1);
01561
01562 if (old_refcount == 1)
01563 {
01564
01565 dbus_message_cache_or_finalize (message);
01566 }
01567 }
01568
01579 int
01580 dbus_message_get_type (DBusMessage *message)
01581 {
01582 _dbus_return_val_if_fail (message != NULL, DBUS_MESSAGE_TYPE_INVALID);
01583
01584 return _dbus_header_get_message_type (&message->header);
01585 }
01586
01649 dbus_bool_t
01650 dbus_message_append_args (DBusMessage *message,
01651 int first_arg_type,
01652 ...)
01653 {
01654 dbus_bool_t retval;
01655 va_list var_args;
01656
01657 _dbus_return_val_if_fail (message != NULL, FALSE);
01658
01659 va_start (var_args, first_arg_type);
01660 retval = dbus_message_append_args_valist (message,
01661 first_arg_type,
01662 var_args);
01663 va_end (var_args);
01664
01665 return retval;
01666 }
01667
01681 dbus_bool_t
01682 dbus_message_append_args_valist (DBusMessage *message,
01683 int first_arg_type,
01684 va_list var_args)
01685 {
01686 int type;
01687 DBusMessageIter iter;
01688
01689 _dbus_return_val_if_fail (message != NULL, FALSE);
01690
01691 type = first_arg_type;
01692
01693 dbus_message_iter_init_append (message, &iter);
01694
01695 while (type != DBUS_TYPE_INVALID)
01696 {
01697 if (dbus_type_is_basic (type))
01698 {
01699 const DBusBasicValue *value;
01700 value = va_arg (var_args, const DBusBasicValue*);
01701
01702 if (!dbus_message_iter_append_basic (&iter,
01703 type,
01704 value))
01705 goto failed;
01706 }
01707 else if (type == DBUS_TYPE_ARRAY)
01708 {
01709 int element_type;
01710 DBusMessageIter array;
01711 char buf[2];
01712
01713 element_type = va_arg (var_args, int);
01714
01715 buf[0] = element_type;
01716 buf[1] = '\0';
01717 if (!dbus_message_iter_open_container (&iter,
01718 DBUS_TYPE_ARRAY,
01719 buf,
01720 &array))
01721 goto failed;
01722
01723 if (dbus_type_is_fixed (element_type) &&
01724 element_type != DBUS_TYPE_UNIX_FD)
01725 {
01726 const DBusBasicValue **value;
01727 int n_elements;
01728
01729 value = va_arg (var_args, const DBusBasicValue**);
01730 n_elements = va_arg (var_args, int);
01731
01732 if (!dbus_message_iter_append_fixed_array (&array,
01733 element_type,
01734 value,
01735 n_elements)) {
01736 dbus_message_iter_abandon_container (&iter, &array);
01737 goto failed;
01738 }
01739 }
01740 else if (element_type == DBUS_TYPE_STRING ||
01741 element_type == DBUS_TYPE_SIGNATURE ||
01742 element_type == DBUS_TYPE_OBJECT_PATH)
01743 {
01744 const char ***value_p;
01745 const char **value;
01746 int n_elements;
01747 int i;
01748
01749 value_p = va_arg (var_args, const char***);
01750 n_elements = va_arg (var_args, int);
01751
01752 value = *value_p;
01753
01754 i = 0;
01755 while (i < n_elements)
01756 {
01757 if (!dbus_message_iter_append_basic (&array,
01758 element_type,
01759 &value[i])) {
01760 dbus_message_iter_abandon_container (&iter, &array);
01761 goto failed;
01762 }
01763 ++i;
01764 }
01765 }
01766 else
01767 {
01768 _dbus_warn ("arrays of %s can't be appended with %s for now\n",
01769 _dbus_type_to_string (element_type),
01770 _DBUS_FUNCTION_NAME);
01771 goto failed;
01772 }
01773
01774 if (!dbus_message_iter_close_container (&iter, &array))
01775 goto failed;
01776 }
01777 #ifndef DBUS_DISABLE_CHECKS
01778 else
01779 {
01780 _dbus_warn ("type %s isn't supported yet in %s\n",
01781 _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
01782 goto failed;
01783 }
01784 #endif
01785
01786 type = va_arg (var_args, int);
01787 }
01788
01789 return TRUE;
01790
01791 failed:
01792 return FALSE;
01793 }
01794
01839 dbus_bool_t
01840 dbus_message_get_args (DBusMessage *message,
01841 DBusError *error,
01842 int first_arg_type,
01843 ...)
01844 {
01845 dbus_bool_t retval;
01846 va_list var_args;
01847
01848 _dbus_return_val_if_fail (message != NULL, FALSE);
01849 _dbus_return_val_if_error_is_set (error, FALSE);
01850
01851 va_start (var_args, first_arg_type);
01852 retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
01853 va_end (var_args);
01854
01855 return retval;
01856 }
01857
01868 dbus_bool_t
01869 dbus_message_get_args_valist (DBusMessage *message,
01870 DBusError *error,
01871 int first_arg_type,
01872 va_list var_args)
01873 {
01874 DBusMessageIter iter;
01875
01876 _dbus_return_val_if_fail (message != NULL, FALSE);
01877 _dbus_return_val_if_error_is_set (error, FALSE);
01878
01879 dbus_message_iter_init (message, &iter);
01880 return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
01881 }
01882
01883 static void
01884 _dbus_message_iter_init_common (DBusMessage *message,
01885 DBusMessageRealIter *real,
01886 int iter_type)
01887 {
01888 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
01889
01890
01891
01892
01893 ensure_byte_order (message);
01894
01895 real->message = message;
01896 real->changed_stamp = message->changed_stamp;
01897 real->iter_type = iter_type;
01898 real->sig_refcount = 0;
01899 }
01900
01923 dbus_bool_t
01924 dbus_message_iter_init (DBusMessage *message,
01925 DBusMessageIter *iter)
01926 {
01927 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01928 const DBusString *type_str;
01929 int type_pos;
01930
01931 _dbus_return_val_if_fail (message != NULL, FALSE);
01932 _dbus_return_val_if_fail (iter != NULL, FALSE);
01933
01934 get_const_signature (&message->header, &type_str, &type_pos);
01935
01936 _dbus_message_iter_init_common (message, real,
01937 DBUS_MESSAGE_ITER_TYPE_READER);
01938
01939 _dbus_type_reader_init (&real->u.reader,
01940 message->byte_order,
01941 type_str, type_pos,
01942 &message->body,
01943 0);
01944
01945 return _dbus_type_reader_get_current_type (&real->u.reader) != DBUS_TYPE_INVALID;
01946 }
01947
01954 dbus_bool_t
01955 dbus_message_iter_has_next (DBusMessageIter *iter)
01956 {
01957 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01958
01959 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
01960 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
01961
01962 return _dbus_type_reader_has_next (&real->u.reader);
01963 }
01964
01973 dbus_bool_t
01974 dbus_message_iter_next (DBusMessageIter *iter)
01975 {
01976 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01977
01978 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
01979 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
01980
01981 return _dbus_type_reader_next (&real->u.reader);
01982 }
01983
01998 int
01999 dbus_message_iter_get_arg_type (DBusMessageIter *iter)
02000 {
02001 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02002
02003 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
02004 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
02005
02006 return _dbus_type_reader_get_current_type (&real->u.reader);
02007 }
02008
02017 int
02018 dbus_message_iter_get_element_type (DBusMessageIter *iter)
02019 {
02020 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02021
02022 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
02023 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
02024 _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
02025
02026 return _dbus_type_reader_get_element_type (&real->u.reader);
02027 }
02028
02054 void
02055 dbus_message_iter_recurse (DBusMessageIter *iter,
02056 DBusMessageIter *sub)
02057 {
02058 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02059 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02060
02061 _dbus_return_if_fail (_dbus_message_iter_check (real));
02062 _dbus_return_if_fail (sub != NULL);
02063
02064 *real_sub = *real;
02065 _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
02066 }
02067
02079 char *
02080 dbus_message_iter_get_signature (DBusMessageIter *iter)
02081 {
02082 const DBusString *sig;
02083 DBusString retstr;
02084 char *ret;
02085 int start, len;
02086 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02087
02088 _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
02089
02090 if (!_dbus_string_init (&retstr))
02091 return NULL;
02092
02093 _dbus_type_reader_get_signature (&real->u.reader, &sig,
02094 &start, &len);
02095 if (!_dbus_string_append_len (&retstr,
02096 _dbus_string_get_const_data (sig) + start,
02097 len))
02098 return NULL;
02099 if (!_dbus_string_steal_data (&retstr, &ret))
02100 return NULL;
02101 _dbus_string_free (&retstr);
02102 return ret;
02103 }
02104
02152 void
02153 dbus_message_iter_get_basic (DBusMessageIter *iter,
02154 void *value)
02155 {
02156 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02157
02158 _dbus_return_if_fail (_dbus_message_iter_check (real));
02159 _dbus_return_if_fail (value != NULL);
02160
02161 if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_UNIX_FD)
02162 {
02163 #ifdef HAVE_UNIX_FD_PASSING
02164 DBusBasicValue idx;
02165
02166 _dbus_type_reader_read_basic(&real->u.reader, &idx);
02167
02168 if (idx.u32 >= real->message->n_unix_fds) {
02169
02170
02171 *((int*) value) = -1;
02172 return;
02173 }
02174
02175 *((int*) value) = _dbus_dup(real->message->unix_fds[idx.u32], NULL);
02176 #else
02177 *((int*) value) = -1;
02178 #endif
02179 }
02180 else
02181 {
02182 _dbus_type_reader_read_basic (&real->u.reader,
02183 value);
02184 }
02185 }
02186
02205 int
02206 dbus_message_iter_get_array_len (DBusMessageIter *iter)
02207 {
02208 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02209
02210 _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
02211
02212 return _dbus_type_reader_get_array_length (&real->u.reader);
02213 }
02214
02250 void
02251 dbus_message_iter_get_fixed_array (DBusMessageIter *iter,
02252 void *value,
02253 int *n_elements)
02254 {
02255 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02256 int subtype = _dbus_type_reader_get_current_type(&real->u.reader);
02257
02258 _dbus_return_if_fail (_dbus_message_iter_check (real));
02259 _dbus_return_if_fail (value != NULL);
02260 _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) ||
02261 (dbus_type_is_fixed (subtype) && subtype != DBUS_TYPE_UNIX_FD));
02262
02263 _dbus_type_reader_read_fixed_multi (&real->u.reader,
02264 value, n_elements);
02265 }
02266
02278 void
02279 dbus_message_iter_init_append (DBusMessage *message,
02280 DBusMessageIter *iter)
02281 {
02282 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02283
02284 _dbus_return_if_fail (message != NULL);
02285 _dbus_return_if_fail (iter != NULL);
02286
02287 _dbus_message_iter_init_common (message, real,
02288 DBUS_MESSAGE_ITER_TYPE_WRITER);
02289
02290
02291
02292
02293
02294 _dbus_type_writer_init_types_delayed (&real->u.writer,
02295 message->byte_order,
02296 &message->body,
02297 _dbus_string_get_length (&message->body));
02298 }
02299
02308 static dbus_bool_t
02309 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
02310 {
02311 DBusString *str;
02312 const DBusString *current_sig;
02313 int current_sig_pos;
02314
02315 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02316
02317 if (real->u.writer.type_str != NULL)
02318 {
02319 _dbus_assert (real->sig_refcount > 0);
02320 real->sig_refcount += 1;
02321 return TRUE;
02322 }
02323
02324 str = dbus_new (DBusString, 1);
02325 if (str == NULL)
02326 return FALSE;
02327
02328 if (!_dbus_header_get_field_raw (&real->message->header,
02329 DBUS_HEADER_FIELD_SIGNATURE,
02330 ¤t_sig, ¤t_sig_pos))
02331 current_sig = NULL;
02332
02333 if (current_sig)
02334 {
02335 int current_len;
02336
02337 current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
02338 current_sig_pos += 1;
02339
02340 if (!_dbus_string_init_preallocated (str, current_len + 4))
02341 {
02342 dbus_free (str);
02343 return FALSE;
02344 }
02345
02346 if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
02347 str, 0))
02348 {
02349 _dbus_string_free (str);
02350 dbus_free (str);
02351 return FALSE;
02352 }
02353 }
02354 else
02355 {
02356 if (!_dbus_string_init_preallocated (str, 4))
02357 {
02358 dbus_free (str);
02359 return FALSE;
02360 }
02361 }
02362
02363 real->sig_refcount = 1;
02364
02365 _dbus_type_writer_add_types (&real->u.writer,
02366 str, _dbus_string_get_length (str));
02367 return TRUE;
02368 }
02369
02379 static dbus_bool_t
02380 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
02381 {
02382 DBusString *str;
02383 const char *v_STRING;
02384 dbus_bool_t retval;
02385
02386 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02387 _dbus_assert (real->u.writer.type_str != NULL);
02388 _dbus_assert (real->sig_refcount > 0);
02389
02390 real->sig_refcount -= 1;
02391
02392 if (real->sig_refcount > 0)
02393 return TRUE;
02394 _dbus_assert (real->sig_refcount == 0);
02395
02396 retval = TRUE;
02397
02398 str = real->u.writer.type_str;
02399
02400 v_STRING = _dbus_string_get_const_data (str);
02401 if (!_dbus_header_set_field_basic (&real->message->header,
02402 DBUS_HEADER_FIELD_SIGNATURE,
02403 DBUS_TYPE_SIGNATURE,
02404 &v_STRING))
02405 retval = FALSE;
02406
02407 _dbus_type_writer_remove_types (&real->u.writer);
02408 _dbus_string_free (str);
02409 dbus_free (str);
02410
02411 return retval;
02412 }
02413
02421 static void
02422 _dbus_message_iter_abandon_signature (DBusMessageRealIter *real)
02423 {
02424 DBusString *str;
02425
02426 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02427 _dbus_assert (real->u.writer.type_str != NULL);
02428 _dbus_assert (real->sig_refcount > 0);
02429
02430 real->sig_refcount -= 1;
02431
02432 if (real->sig_refcount > 0)
02433 return;
02434 _dbus_assert (real->sig_refcount == 0);
02435
02436 str = real->u.writer.type_str;
02437
02438 _dbus_type_writer_remove_types (&real->u.writer);
02439 _dbus_string_free (str);
02440 dbus_free (str);
02441 }
02442
02443 #ifndef DBUS_DISABLE_CHECKS
02444 static dbus_bool_t
02445 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
02446 {
02447 if (!_dbus_message_iter_check (iter))
02448 return FALSE;
02449
02450 if (iter->message->locked)
02451 {
02452 _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)\n");
02453 return FALSE;
02454 }
02455
02456 return TRUE;
02457 }
02458 #endif
02459
02460 #ifdef HAVE_UNIX_FD_PASSING
02461 static int *
02462 expand_fd_array(DBusMessage *m,
02463 unsigned n)
02464 {
02465 _dbus_assert(m);
02466
02467
02468
02469
02470 if (m->n_unix_fds + n > m->n_unix_fds_allocated)
02471 {
02472 unsigned k;
02473 int *p;
02474
02475
02476 k = (m->n_unix_fds + n) * 2;
02477
02478
02479 if (k < 4)
02480 k = 4;
02481
02482 p = dbus_realloc(m->unix_fds, k * sizeof(int));
02483 if (p == NULL)
02484 return NULL;
02485
02486 m->unix_fds = p;
02487 m->n_unix_fds_allocated = k;
02488 }
02489
02490 return m->unix_fds + m->n_unix_fds;
02491 }
02492 #endif
02493
02513 dbus_bool_t
02514 dbus_message_iter_append_basic (DBusMessageIter *iter,
02515 int type,
02516 const void *value)
02517 {
02518 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02519 dbus_bool_t ret;
02520
02521 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02522 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02523 _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
02524 _dbus_return_val_if_fail (value != NULL, FALSE);
02525
02526 #ifndef DBUS_DISABLE_CHECKS
02527 switch (type)
02528 {
02529 const char * const *string_p;
02530 const dbus_bool_t *bool_p;
02531
02532 case DBUS_TYPE_STRING:
02533 string_p = value;
02534 _dbus_return_val_if_fail (_dbus_check_is_valid_utf8 (*string_p), FALSE);
02535 break;
02536
02537 case DBUS_TYPE_OBJECT_PATH:
02538 string_p = value;
02539 _dbus_return_val_if_fail (_dbus_check_is_valid_path (*string_p), FALSE);
02540 break;
02541
02542 case DBUS_TYPE_SIGNATURE:
02543 string_p = value;
02544 _dbus_return_val_if_fail (_dbus_check_is_valid_signature (*string_p), FALSE);
02545 break;
02546
02547 case DBUS_TYPE_BOOLEAN:
02548 bool_p = value;
02549 _dbus_return_val_if_fail (*bool_p == 0 || *bool_p == 1, FALSE);
02550 break;
02551
02552 default:
02553 {
02554
02555 }
02556 }
02557 #endif
02558
02559 if (!_dbus_message_iter_open_signature (real))
02560 return FALSE;
02561
02562 if (type == DBUS_TYPE_UNIX_FD)
02563 {
02564 #ifdef HAVE_UNIX_FD_PASSING
02565 int *fds;
02566 dbus_uint32_t u;
02567
02568
02569 if (!(fds = expand_fd_array(real->message, 1)))
02570 return FALSE;
02571
02572 *fds = _dbus_dup(*(int*) value, NULL);
02573 if (*fds < 0)
02574 return FALSE;
02575
02576 u = real->message->n_unix_fds;
02577
02578
02579 if (!(ret = _dbus_type_writer_write_basic (&real->u.writer, DBUS_TYPE_UNIX_FD, &u))) {
02580 _dbus_close(*fds, NULL);
02581 return FALSE;
02582 }
02583
02584 real->message->n_unix_fds += 1;
02585 u += 1;
02586
02587
02588 ret = _dbus_header_set_field_basic (&real->message->header,
02589 DBUS_HEADER_FIELD_UNIX_FDS,
02590 DBUS_TYPE_UINT32,
02591 &u);
02592
02593
02594
02595
02596
02597
02598 #else
02599 ret = FALSE;
02600 #endif
02601 }
02602 else
02603 {
02604 ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
02605 }
02606
02607 if (!_dbus_message_iter_close_signature (real))
02608 ret = FALSE;
02609
02610 return ret;
02611 }
02612
02648 dbus_bool_t
02649 dbus_message_iter_append_fixed_array (DBusMessageIter *iter,
02650 int element_type,
02651 const void *value,
02652 int n_elements)
02653 {
02654 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02655 dbus_bool_t ret;
02656
02657 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02658 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02659 _dbus_return_val_if_fail (dbus_type_is_fixed (element_type) && element_type != DBUS_TYPE_UNIX_FD, FALSE);
02660 _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
02661 _dbus_return_val_if_fail (value != NULL, FALSE);
02662 _dbus_return_val_if_fail (n_elements >= 0, FALSE);
02663 _dbus_return_val_if_fail (n_elements <=
02664 DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type),
02665 FALSE);
02666
02667 #ifndef DBUS_DISABLE_CHECKS
02668 if (element_type == DBUS_TYPE_BOOLEAN)
02669 {
02670 const dbus_bool_t * const *bools = value;
02671 int i;
02672
02673 for (i = 0; i < n_elements; i++)
02674 {
02675 _dbus_return_val_if_fail ((*bools)[i] == 0 || (*bools)[i] == 1, FALSE);
02676 }
02677 }
02678 #endif
02679
02680 ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
02681
02682 return ret;
02683 }
02684
02706 dbus_bool_t
02707 dbus_message_iter_open_container (DBusMessageIter *iter,
02708 int type,
02709 const char *contained_signature,
02710 DBusMessageIter *sub)
02711 {
02712 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02713 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02714 DBusString contained_str;
02715
02716 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02717 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02718 _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
02719 _dbus_return_val_if_fail (sub != NULL, FALSE);
02720 _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
02721 contained_signature == NULL) ||
02722 (type == DBUS_TYPE_DICT_ENTRY &&
02723 contained_signature == NULL) ||
02724 (type == DBUS_TYPE_VARIANT &&
02725 contained_signature != NULL) ||
02726 (type == DBUS_TYPE_ARRAY &&
02727 contained_signature != NULL), FALSE);
02728
02729
02730
02731
02732
02733 _dbus_return_val_if_fail ((type == DBUS_TYPE_ARRAY && contained_signature && *contained_signature == DBUS_DICT_ENTRY_BEGIN_CHAR) ||
02734 (contained_signature == NULL ||
02735 _dbus_check_is_valid_signature (contained_signature)),
02736 FALSE);
02737
02738 if (!_dbus_message_iter_open_signature (real))
02739 return FALSE;
02740
02741 *real_sub = *real;
02742
02743 if (contained_signature != NULL)
02744 {
02745 _dbus_string_init_const (&contained_str, contained_signature);
02746
02747 return _dbus_type_writer_recurse (&real->u.writer,
02748 type,
02749 &contained_str, 0,
02750 &real_sub->u.writer);
02751 }
02752 else
02753 {
02754 return _dbus_type_writer_recurse (&real->u.writer,
02755 type,
02756 NULL, 0,
02757 &real_sub->u.writer);
02758 }
02759 }
02760
02761
02775 dbus_bool_t
02776 dbus_message_iter_close_container (DBusMessageIter *iter,
02777 DBusMessageIter *sub)
02778 {
02779 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02780 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02781 dbus_bool_t ret;
02782
02783 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02784 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02785 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
02786 _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02787
02788 ret = _dbus_type_writer_unrecurse (&real->u.writer,
02789 &real_sub->u.writer);
02790
02791 if (!_dbus_message_iter_close_signature (real))
02792 ret = FALSE;
02793
02794 return ret;
02795 }
02796
02808 void
02809 dbus_message_iter_abandon_container (DBusMessageIter *iter,
02810 DBusMessageIter *sub)
02811 {
02812 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02813 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02814
02815 _dbus_return_if_fail (_dbus_message_iter_append_check (real));
02816 _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02817 _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
02818 _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02819
02820 _dbus_message_iter_abandon_signature (real);
02821 }
02822
02839 void
02840 dbus_message_set_no_reply (DBusMessage *message,
02841 dbus_bool_t no_reply)
02842 {
02843 _dbus_return_if_fail (message != NULL);
02844 _dbus_return_if_fail (!message->locked);
02845
02846 _dbus_header_toggle_flag (&message->header,
02847 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED,
02848 no_reply);
02849 }
02850
02858 dbus_bool_t
02859 dbus_message_get_no_reply (DBusMessage *message)
02860 {
02861 _dbus_return_val_if_fail (message != NULL, FALSE);
02862
02863 return _dbus_header_get_flag (&message->header,
02864 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED);
02865 }
02866
02881 void
02882 dbus_message_set_auto_start (DBusMessage *message,
02883 dbus_bool_t auto_start)
02884 {
02885 _dbus_return_if_fail (message != NULL);
02886 _dbus_return_if_fail (!message->locked);
02887
02888 _dbus_header_toggle_flag (&message->header,
02889 DBUS_HEADER_FLAG_NO_AUTO_START,
02890 !auto_start);
02891 }
02892
02900 dbus_bool_t
02901 dbus_message_get_auto_start (DBusMessage *message)
02902 {
02903 _dbus_return_val_if_fail (message != NULL, FALSE);
02904
02905 return !_dbus_header_get_flag (&message->header,
02906 DBUS_HEADER_FLAG_NO_AUTO_START);
02907 }
02908
02909
02922 dbus_bool_t
02923 dbus_message_set_path (DBusMessage *message,
02924 const char *object_path)
02925 {
02926 _dbus_return_val_if_fail (message != NULL, FALSE);
02927 _dbus_return_val_if_fail (!message->locked, FALSE);
02928 _dbus_return_val_if_fail (object_path == NULL ||
02929 _dbus_check_is_valid_path (object_path),
02930 FALSE);
02931
02932 return set_or_delete_string_field (message,
02933 DBUS_HEADER_FIELD_PATH,
02934 DBUS_TYPE_OBJECT_PATH,
02935 object_path);
02936 }
02937
02951 const char*
02952 dbus_message_get_path (DBusMessage *message)
02953 {
02954 const char *v;
02955
02956 _dbus_return_val_if_fail (message != NULL, NULL);
02957
02958 v = NULL;
02959 _dbus_header_get_field_basic (&message->header,
02960 DBUS_HEADER_FIELD_PATH,
02961 DBUS_TYPE_OBJECT_PATH,
02962 (void *) &v);
02963 return v;
02964 }
02965
02975 dbus_bool_t
02976 dbus_message_has_path (DBusMessage *message,
02977 const char *path)
02978 {
02979 const char *msg_path;
02980 msg_path = dbus_message_get_path (message);
02981
02982 if (msg_path == NULL)
02983 {
02984 if (path == NULL)
02985 return TRUE;
02986 else
02987 return FALSE;
02988 }
02989
02990 if (path == NULL)
02991 return FALSE;
02992
02993 if (strcmp (msg_path, path) == 0)
02994 return TRUE;
02995
02996 return FALSE;
02997 }
02998
03019 dbus_bool_t
03020 dbus_message_get_path_decomposed (DBusMessage *message,
03021 char ***path)
03022 {
03023 const char *v;
03024
03025 _dbus_return_val_if_fail (message != NULL, FALSE);
03026 _dbus_return_val_if_fail (path != NULL, FALSE);
03027
03028 *path = NULL;
03029
03030 v = dbus_message_get_path (message);
03031 if (v != NULL)
03032 {
03033 if (!_dbus_decompose_path (v, strlen (v),
03034 path, NULL))
03035 return FALSE;
03036 }
03037 return TRUE;
03038 }
03039
03053 dbus_bool_t
03054 dbus_message_set_interface (DBusMessage *message,
03055 const char *interface)
03056 {
03057 _dbus_return_val_if_fail (message != NULL, FALSE);
03058 _dbus_return_val_if_fail (!message->locked, FALSE);
03059 _dbus_return_val_if_fail (interface == NULL ||
03060 _dbus_check_is_valid_interface (interface),
03061 FALSE);
03062
03063 return set_or_delete_string_field (message,
03064 DBUS_HEADER_FIELD_INTERFACE,
03065 DBUS_TYPE_STRING,
03066 interface);
03067 }
03068
03082 const char*
03083 dbus_message_get_interface (DBusMessage *message)
03084 {
03085 const char *v;
03086
03087 _dbus_return_val_if_fail (message != NULL, NULL);
03088
03089 v = NULL;
03090 _dbus_header_get_field_basic (&message->header,
03091 DBUS_HEADER_FIELD_INTERFACE,
03092 DBUS_TYPE_STRING,
03093 (void *) &v);
03094 return v;
03095 }
03096
03104 dbus_bool_t
03105 dbus_message_has_interface (DBusMessage *message,
03106 const char *interface)
03107 {
03108 const char *msg_interface;
03109 msg_interface = dbus_message_get_interface (message);
03110
03111 if (msg_interface == NULL)
03112 {
03113 if (interface == NULL)
03114 return TRUE;
03115 else
03116 return FALSE;
03117 }
03118
03119 if (interface == NULL)
03120 return FALSE;
03121
03122 if (strcmp (msg_interface, interface) == 0)
03123 return TRUE;
03124
03125 return FALSE;
03126
03127 }
03128
03141 dbus_bool_t
03142 dbus_message_set_member (DBusMessage *message,
03143 const char *member)
03144 {
03145 _dbus_return_val_if_fail (message != NULL, FALSE);
03146 _dbus_return_val_if_fail (!message->locked, FALSE);
03147 _dbus_return_val_if_fail (member == NULL ||
03148 _dbus_check_is_valid_member (member),
03149 FALSE);
03150
03151 return set_or_delete_string_field (message,
03152 DBUS_HEADER_FIELD_MEMBER,
03153 DBUS_TYPE_STRING,
03154 member);
03155 }
03156
03168 const char*
03169 dbus_message_get_member (DBusMessage *message)
03170 {
03171 const char *v;
03172
03173 _dbus_return_val_if_fail (message != NULL, NULL);
03174
03175 v = NULL;
03176 _dbus_header_get_field_basic (&message->header,
03177 DBUS_HEADER_FIELD_MEMBER,
03178 DBUS_TYPE_STRING,
03179 (void *) &v);
03180 return v;
03181 }
03182
03190 dbus_bool_t
03191 dbus_message_has_member (DBusMessage *message,
03192 const char *member)
03193 {
03194 const char *msg_member;
03195 msg_member = dbus_message_get_member (message);
03196
03197 if (msg_member == NULL)
03198 {
03199 if (member == NULL)
03200 return TRUE;
03201 else
03202 return FALSE;
03203 }
03204
03205 if (member == NULL)
03206 return FALSE;
03207
03208 if (strcmp (msg_member, member) == 0)
03209 return TRUE;
03210
03211 return FALSE;
03212
03213 }
03214
03226 dbus_bool_t
03227 dbus_message_set_error_name (DBusMessage *message,
03228 const char *error_name)
03229 {
03230 _dbus_return_val_if_fail (message != NULL, FALSE);
03231 _dbus_return_val_if_fail (!message->locked, FALSE);
03232 _dbus_return_val_if_fail (error_name == NULL ||
03233 _dbus_check_is_valid_error_name (error_name),
03234 FALSE);
03235
03236 return set_or_delete_string_field (message,
03237 DBUS_HEADER_FIELD_ERROR_NAME,
03238 DBUS_TYPE_STRING,
03239 error_name);
03240 }
03241
03252 const char*
03253 dbus_message_get_error_name (DBusMessage *message)
03254 {
03255 const char *v;
03256
03257 _dbus_return_val_if_fail (message != NULL, NULL);
03258
03259 v = NULL;
03260 _dbus_header_get_field_basic (&message->header,
03261 DBUS_HEADER_FIELD_ERROR_NAME,
03262 DBUS_TYPE_STRING,
03263 (void *) &v);
03264 return v;
03265 }
03266
03280 dbus_bool_t
03281 dbus_message_set_destination (DBusMessage *message,
03282 const char *destination)
03283 {
03284 _dbus_return_val_if_fail (message != NULL, FALSE);
03285 _dbus_return_val_if_fail (!message->locked, FALSE);
03286 _dbus_return_val_if_fail (destination == NULL ||
03287 _dbus_check_is_valid_bus_name (destination),
03288 FALSE);
03289
03290 return set_or_delete_string_field (message,
03291 DBUS_HEADER_FIELD_DESTINATION,
03292 DBUS_TYPE_STRING,
03293 destination);
03294 }
03295
03305 const char*
03306 dbus_message_get_destination (DBusMessage *message)
03307 {
03308 const char *v;
03309
03310 _dbus_return_val_if_fail (message != NULL, NULL);
03311
03312 v = NULL;
03313 _dbus_header_get_field_basic (&message->header,
03314 DBUS_HEADER_FIELD_DESTINATION,
03315 DBUS_TYPE_STRING,
03316 (void *) &v);
03317 return v;
03318 }
03319
03334 dbus_bool_t
03335 dbus_message_set_sender (DBusMessage *message,
03336 const char *sender)
03337 {
03338 _dbus_return_val_if_fail (message != NULL, FALSE);
03339 _dbus_return_val_if_fail (!message->locked, FALSE);
03340 _dbus_return_val_if_fail (sender == NULL ||
03341 _dbus_check_is_valid_bus_name (sender),
03342 FALSE);
03343
03344 return set_or_delete_string_field (message,
03345 DBUS_HEADER_FIELD_SENDER,
03346 DBUS_TYPE_STRING,
03347 sender);
03348 }
03349
03365 const char*
03366 dbus_message_get_sender (DBusMessage *message)
03367 {
03368 const char *v;
03369
03370 _dbus_return_val_if_fail (message != NULL, NULL);
03371
03372 v = NULL;
03373 _dbus_header_get_field_basic (&message->header,
03374 DBUS_HEADER_FIELD_SENDER,
03375 DBUS_TYPE_STRING,
03376 (void *) &v);
03377 return v;
03378 }
03379
03398 const char*
03399 dbus_message_get_signature (DBusMessage *message)
03400 {
03401 const DBusString *type_str;
03402 int type_pos;
03403
03404 _dbus_return_val_if_fail (message != NULL, NULL);
03405
03406 get_const_signature (&message->header, &type_str, &type_pos);
03407
03408 return _dbus_string_get_const_data_len (type_str, type_pos, 0);
03409 }
03410
03411 static dbus_bool_t
03412 _dbus_message_has_type_interface_member (DBusMessage *message,
03413 int type,
03414 const char *interface,
03415 const char *member)
03416 {
03417 const char *n;
03418
03419 _dbus_assert (message != NULL);
03420 _dbus_assert (interface != NULL);
03421 _dbus_assert (member != NULL);
03422
03423 if (dbus_message_get_type (message) != type)
03424 return FALSE;
03425
03426
03427
03428
03429
03430 n = dbus_message_get_member (message);
03431
03432 if (n && strcmp (n, member) == 0)
03433 {
03434 n = dbus_message_get_interface (message);
03435
03436 if (n == NULL || strcmp (n, interface) == 0)
03437 return TRUE;
03438 }
03439
03440 return FALSE;
03441 }
03442
03457 dbus_bool_t
03458 dbus_message_is_method_call (DBusMessage *message,
03459 const char *interface,
03460 const char *method)
03461 {
03462 _dbus_return_val_if_fail (message != NULL, FALSE);
03463 _dbus_return_val_if_fail (interface != NULL, FALSE);
03464 _dbus_return_val_if_fail (method != NULL, FALSE);
03465
03466
03467
03468
03469 return _dbus_message_has_type_interface_member (message,
03470 DBUS_MESSAGE_TYPE_METHOD_CALL,
03471 interface, method);
03472 }
03473
03485 dbus_bool_t
03486 dbus_message_is_signal (DBusMessage *message,
03487 const char *interface,
03488 const char *signal_name)
03489 {
03490 _dbus_return_val_if_fail (message != NULL, FALSE);
03491 _dbus_return_val_if_fail (interface != NULL, FALSE);
03492 _dbus_return_val_if_fail (signal_name != NULL, FALSE);
03493
03494
03495
03496
03497 return _dbus_message_has_type_interface_member (message,
03498 DBUS_MESSAGE_TYPE_SIGNAL,
03499 interface, signal_name);
03500 }
03501
03512 dbus_bool_t
03513 dbus_message_is_error (DBusMessage *message,
03514 const char *error_name)
03515 {
03516 const char *n;
03517
03518 _dbus_return_val_if_fail (message != NULL, FALSE);
03519 _dbus_return_val_if_fail (error_name != NULL, FALSE);
03520
03521
03522
03523
03524 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
03525 return FALSE;
03526
03527 n = dbus_message_get_error_name (message);
03528
03529 if (n && strcmp (n, error_name) == 0)
03530 return TRUE;
03531 else
03532 return FALSE;
03533 }
03534
03545 dbus_bool_t
03546 dbus_message_has_destination (DBusMessage *message,
03547 const char *name)
03548 {
03549 const char *s;
03550
03551 _dbus_return_val_if_fail (message != NULL, FALSE);
03552 _dbus_return_val_if_fail (name != NULL, FALSE);
03553
03554
03555
03556
03557 s = dbus_message_get_destination (message);
03558
03559 if (s && strcmp (s, name) == 0)
03560 return TRUE;
03561 else
03562 return FALSE;
03563 }
03564
03580 dbus_bool_t
03581 dbus_message_has_sender (DBusMessage *message,
03582 const char *name)
03583 {
03584 const char *s;
03585
03586 _dbus_return_val_if_fail (message != NULL, FALSE);
03587 _dbus_return_val_if_fail (name != NULL, FALSE);
03588
03589
03590
03591
03592 s = dbus_message_get_sender (message);
03593
03594 if (s && strcmp (s, name) == 0)
03595 return TRUE;
03596 else
03597 return FALSE;
03598 }
03599
03609 dbus_bool_t
03610 dbus_message_has_signature (DBusMessage *message,
03611 const char *signature)
03612 {
03613 const char *s;
03614
03615 _dbus_return_val_if_fail (message != NULL, FALSE);
03616 _dbus_return_val_if_fail (signature != NULL, FALSE);
03617
03618
03619
03620
03621 s = dbus_message_get_signature (message);
03622
03623 if (s && strcmp (s, signature) == 0)
03624 return TRUE;
03625 else
03626 return FALSE;
03627 }
03628
03651 dbus_bool_t
03652 dbus_set_error_from_message (DBusError *error,
03653 DBusMessage *message)
03654 {
03655 const char *str;
03656
03657 _dbus_return_val_if_fail (message != NULL, FALSE);
03658 _dbus_return_val_if_error_is_set (error, FALSE);
03659
03660 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
03661 return FALSE;
03662
03663 str = NULL;
03664 dbus_message_get_args (message, NULL,
03665 DBUS_TYPE_STRING, &str,
03666 DBUS_TYPE_INVALID);
03667
03668 dbus_set_error (error, dbus_message_get_error_name (message),
03669 str ? "%s" : NULL, str);
03670
03671 return TRUE;
03672 }
03673
03680 dbus_bool_t
03681 dbus_message_contains_unix_fds(DBusMessage *message)
03682 {
03683 #ifdef HAVE_UNIX_FD_PASSING
03684 _dbus_assert(message);
03685
03686 return message->n_unix_fds > 0;
03687 #else
03688 return FALSE;
03689 #endif
03690 }
03691
03710 #define INITIAL_LOADER_DATA_LEN 32
03711
03718 DBusMessageLoader*
03719 _dbus_message_loader_new (void)
03720 {
03721 DBusMessageLoader *loader;
03722
03723 loader = dbus_new0 (DBusMessageLoader, 1);
03724 if (loader == NULL)
03725 return NULL;
03726
03727 loader->refcount = 1;
03728
03729 loader->corrupted = FALSE;
03730 loader->corruption_reason = DBUS_VALID;
03731
03732
03733 loader->max_message_size = DBUS_MAXIMUM_MESSAGE_LENGTH;
03734
03735
03736
03737
03738
03739 loader->max_message_unix_fds = 1024;
03740
03741 if (!_dbus_string_init (&loader->data))
03742 {
03743 dbus_free (loader);
03744 return NULL;
03745 }
03746
03747
03748 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
03749 _dbus_string_set_length (&loader->data, 0);
03750
03751 #ifdef HAVE_UNIX_FD_PASSING
03752 loader->unix_fds = NULL;
03753 loader->n_unix_fds = loader->n_unix_fds_allocated = 0;
03754 loader->unix_fds_outstanding = FALSE;
03755 #endif
03756
03757 return loader;
03758 }
03759
03766 DBusMessageLoader *
03767 _dbus_message_loader_ref (DBusMessageLoader *loader)
03768 {
03769 loader->refcount += 1;
03770
03771 return loader;
03772 }
03773
03780 void
03781 _dbus_message_loader_unref (DBusMessageLoader *loader)
03782 {
03783 loader->refcount -= 1;
03784 if (loader->refcount == 0)
03785 {
03786 #ifdef HAVE_UNIX_FD_PASSING
03787 close_unix_fds(loader->unix_fds, &loader->n_unix_fds);
03788 dbus_free(loader->unix_fds);
03789 #endif
03790 _dbus_list_foreach (&loader->messages,
03791 (DBusForeachFunction) dbus_message_unref,
03792 NULL);
03793 _dbus_list_clear (&loader->messages);
03794 _dbus_string_free (&loader->data);
03795 dbus_free (loader);
03796 }
03797 }
03798
03817 void
03818 _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
03819 DBusString **buffer)
03820 {
03821 _dbus_assert (!loader->buffer_outstanding);
03822
03823 *buffer = &loader->data;
03824
03825 loader->buffer_outstanding = TRUE;
03826 }
03827
03838 void
03839 _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
03840 DBusString *buffer,
03841 int bytes_read)
03842 {
03843 _dbus_assert (loader->buffer_outstanding);
03844 _dbus_assert (buffer == &loader->data);
03845
03846 loader->buffer_outstanding = FALSE;
03847 }
03848
03859 dbus_bool_t
03860 _dbus_message_loader_get_unix_fds(DBusMessageLoader *loader,
03861 int **fds,
03862 unsigned *max_n_fds)
03863 {
03864 #ifdef HAVE_UNIX_FD_PASSING
03865 _dbus_assert (!loader->unix_fds_outstanding);
03866
03867
03868
03869
03870
03871
03872
03873
03874
03875 if (loader->n_unix_fds_allocated < loader->max_message_unix_fds)
03876 {
03877 int *a = dbus_realloc(loader->unix_fds,
03878 loader->max_message_unix_fds * sizeof(loader->unix_fds[0]));
03879
03880 if (!a)
03881 return FALSE;
03882
03883 loader->unix_fds = a;
03884 loader->n_unix_fds_allocated = loader->max_message_unix_fds;
03885 }
03886
03887 *fds = loader->unix_fds + loader->n_unix_fds;
03888 *max_n_fds = loader->n_unix_fds_allocated - loader->n_unix_fds;
03889
03890 loader->unix_fds_outstanding = TRUE;
03891 return TRUE;
03892 #else
03893 _dbus_assert_not_reached("Platform doesn't support unix fd passing");
03894 return FALSE;
03895 #endif
03896 }
03897
03908 void
03909 _dbus_message_loader_return_unix_fds(DBusMessageLoader *loader,
03910 int *fds,
03911 unsigned n_fds)
03912 {
03913 #ifdef HAVE_UNIX_FD_PASSING
03914 _dbus_assert(loader->unix_fds_outstanding);
03915 _dbus_assert(loader->unix_fds + loader->n_unix_fds == fds);
03916 _dbus_assert(loader->n_unix_fds + n_fds <= loader->n_unix_fds_allocated);
03917
03918 loader->n_unix_fds += n_fds;
03919 loader->unix_fds_outstanding = FALSE;
03920 #else
03921 _dbus_assert_not_reached("Platform doesn't support unix fd passing");
03922 #endif
03923 }
03924
03925
03926
03927
03928
03929
03930
03931
03932
03933
03934
03935
03936
03937
03938
03939
03940
03941
03942
03943
03944
03945
03946
03947
03948
03949
03950
03951 static dbus_bool_t
03952 load_message (DBusMessageLoader *loader,
03953 DBusMessage *message,
03954 int byte_order,
03955 int fields_array_len,
03956 int header_len,
03957 int body_len)
03958 {
03959 dbus_bool_t oom;
03960 DBusValidity validity;
03961 const DBusString *type_str;
03962 int type_pos;
03963 DBusValidationMode mode;
03964 dbus_uint32_t n_unix_fds = 0;
03965
03966 mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
03967
03968 oom = FALSE;
03969
03970 #if 0
03971 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len );
03972 #endif
03973
03974
03975 _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
03976 _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
03977
03978 if (!_dbus_header_load (&message->header,
03979 mode,
03980 &validity,
03981 byte_order,
03982 fields_array_len,
03983 header_len,
03984 body_len,
03985 &loader->data, 0,
03986 _dbus_string_get_length (&loader->data)))
03987 {
03988 _dbus_verbose ("Failed to load header for new message code %d\n", validity);
03989
03990
03991
03992 _dbus_assert (validity != DBUS_VALID);
03993
03994 if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
03995 oom = TRUE;
03996 else
03997 {
03998 loader->corrupted = TRUE;
03999 loader->corruption_reason = validity;
04000 }
04001 goto failed;
04002 }
04003
04004 _dbus_assert (validity == DBUS_VALID);
04005
04006 message->byte_order = byte_order;
04007
04008
04009 if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
04010 {
04011 get_const_signature (&message->header, &type_str, &type_pos);
04012
04013
04014
04015
04016 validity = _dbus_validate_body_with_reason (type_str,
04017 type_pos,
04018 byte_order,
04019 NULL,
04020 &loader->data,
04021 header_len,
04022 body_len);
04023 if (validity != DBUS_VALID)
04024 {
04025 _dbus_verbose ("Failed to validate message body code %d\n", validity);
04026
04027 loader->corrupted = TRUE;
04028 loader->corruption_reason = validity;
04029
04030 goto failed;
04031 }
04032 }
04033
04034
04035 _dbus_header_get_field_basic(&message->header,
04036 DBUS_HEADER_FIELD_UNIX_FDS,
04037 DBUS_TYPE_UINT32,
04038 &n_unix_fds);
04039
04040 #ifdef HAVE_UNIX_FD_PASSING
04041
04042 if (n_unix_fds > loader->n_unix_fds)
04043 {
04044 _dbus_verbose("Message contains references to more unix fds than were sent %u != %u\n",
04045 n_unix_fds, loader->n_unix_fds);
04046
04047 loader->corrupted = TRUE;
04048 loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
04049 goto failed;
04050 }
04051
04052
04053
04054 dbus_free(message->unix_fds);
04055
04056 if (n_unix_fds > 0)
04057 {
04058 message->unix_fds = _dbus_memdup(loader->unix_fds, n_unix_fds * sizeof(message->unix_fds[0]));
04059 if (message->unix_fds == NULL)
04060 {
04061 _dbus_verbose ("Failed to allocate file descriptor array\n");
04062 oom = TRUE;
04063 goto failed;
04064 }
04065
04066 message->n_unix_fds_allocated = message->n_unix_fds = n_unix_fds;
04067 loader->n_unix_fds -= n_unix_fds;
04068 memmove(loader->unix_fds + n_unix_fds, loader->unix_fds, loader->n_unix_fds);
04069 }
04070 else
04071 message->unix_fds = NULL;
04072
04073 #else
04074
04075 if (n_unix_fds > 0)
04076 {
04077 _dbus_verbose ("Hmm, message claims to come with file descriptors "
04078 "but that's not supported on our platform, disconnecting.\n");
04079
04080 loader->corrupted = TRUE;
04081 loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
04082 goto failed;
04083 }
04084
04085 #endif
04086
04087
04088
04089 if (!_dbus_list_append (&loader->messages, message))
04090 {
04091 _dbus_verbose ("Failed to append new message to loader queue\n");
04092 oom = TRUE;
04093 goto failed;
04094 }
04095
04096 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
04097 _dbus_assert (_dbus_string_get_length (&loader->data) >=
04098 (header_len + body_len));
04099
04100 if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
04101 {
04102 _dbus_verbose ("Failed to move body into new message\n");
04103 oom = TRUE;
04104 goto failed;
04105 }
04106
04107 _dbus_string_delete (&loader->data, 0, header_len + body_len);
04108
04109
04110 _dbus_string_compact (&loader->data, 2048);
04111
04112 _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
04113 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
04114
04115 _dbus_verbose ("Loaded message %p\n", message);
04116
04117 _dbus_assert (!oom);
04118 _dbus_assert (!loader->corrupted);
04119 _dbus_assert (loader->messages != NULL);
04120 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
04121
04122 return TRUE;
04123
04124 failed:
04125
04126
04127
04128
04129 _dbus_list_remove_last (&loader->messages, message);
04130
04131 if (oom)
04132 _dbus_assert (!loader->corrupted);
04133 else
04134 _dbus_assert (loader->corrupted);
04135
04136 _dbus_verbose_bytes_of_string (&loader->data, 0, _dbus_string_get_length (&loader->data));
04137
04138 return FALSE;
04139 }
04140
04155 dbus_bool_t
04156 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
04157 {
04158 while (!loader->corrupted &&
04159 _dbus_string_get_length (&loader->data) >= DBUS_MINIMUM_HEADER_SIZE)
04160 {
04161 DBusValidity validity;
04162 int byte_order, fields_array_len, header_len, body_len;
04163
04164 if (_dbus_header_have_message_untrusted (loader->max_message_size,
04165 &validity,
04166 &byte_order,
04167 &fields_array_len,
04168 &header_len,
04169 &body_len,
04170 &loader->data, 0,
04171 _dbus_string_get_length (&loader->data)))
04172 {
04173 DBusMessage *message;
04174
04175 _dbus_assert (validity == DBUS_VALID);
04176
04177 message = dbus_message_new_empty_header ();
04178 if (message == NULL)
04179 return FALSE;
04180
04181 if (!load_message (loader, message,
04182 byte_order, fields_array_len,
04183 header_len, body_len))
04184 {
04185 dbus_message_unref (message);
04186
04187
04188
04189 return loader->corrupted;
04190 }
04191
04192 _dbus_assert (loader->messages != NULL);
04193 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
04194 }
04195 else
04196 {
04197 _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
04198 validity);
04199 if (validity != DBUS_VALID)
04200 {
04201 loader->corrupted = TRUE;
04202 loader->corruption_reason = validity;
04203 }
04204 return TRUE;
04205 }
04206 }
04207
04208 return TRUE;
04209 }
04210
04218 DBusMessage*
04219 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
04220 {
04221 if (loader->messages)
04222 return loader->messages->data;
04223 else
04224 return NULL;
04225 }
04226
04235 DBusMessage*
04236 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
04237 {
04238 return _dbus_list_pop_first (&loader->messages);
04239 }
04240
04249 DBusList*
04250 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
04251 {
04252 return _dbus_list_pop_first_link (&loader->messages);
04253 }
04254
04261 void
04262 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
04263 DBusList *link)
04264 {
04265 _dbus_list_prepend_link (&loader->messages, link);
04266 }
04267
04277 dbus_bool_t
04278 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
04279 {
04280 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
04281 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
04282 return loader->corrupted;
04283 }
04284
04291 DBusValidity
04292 _dbus_message_loader_get_corruption_reason (DBusMessageLoader *loader)
04293 {
04294 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
04295 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
04296
04297 return loader->corruption_reason;
04298 }
04299
04306 void
04307 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
04308 long size)
04309 {
04310 if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
04311 {
04312 _dbus_verbose ("clamping requested max message size %ld to %d\n",
04313 size, DBUS_MAXIMUM_MESSAGE_LENGTH);
04314 size = DBUS_MAXIMUM_MESSAGE_LENGTH;
04315 }
04316 loader->max_message_size = size;
04317 }
04318
04325 long
04326 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
04327 {
04328 return loader->max_message_size;
04329 }
04330
04337 void
04338 _dbus_message_loader_set_max_message_unix_fds (DBusMessageLoader *loader,
04339 long n)
04340 {
04341 if (n > DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
04342 {
04343 _dbus_verbose ("clamping requested max message unix_fds %ld to %d\n",
04344 n, DBUS_MAXIMUM_MESSAGE_UNIX_FDS);
04345 n = DBUS_MAXIMUM_MESSAGE_UNIX_FDS;
04346 }
04347 loader->max_message_unix_fds = n;
04348 }
04349
04356 long
04357 _dbus_message_loader_get_max_message_unix_fds (DBusMessageLoader *loader)
04358 {
04359 return loader->max_message_unix_fds;
04360 }
04361
04362 static DBusDataSlotAllocator slot_allocator;
04363 _DBUS_DEFINE_GLOBAL_LOCK (message_slots);
04364
04379 dbus_bool_t
04380 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
04381 {
04382 return _dbus_data_slot_allocator_alloc (&slot_allocator,
04383 &_DBUS_LOCK_NAME (message_slots),
04384 slot_p);
04385 }
04386
04398 void
04399 dbus_message_free_data_slot (dbus_int32_t *slot_p)
04400 {
04401 _dbus_return_if_fail (*slot_p >= 0);
04402
04403 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
04404 }
04405
04419 dbus_bool_t
04420 dbus_message_set_data (DBusMessage *message,
04421 dbus_int32_t slot,
04422 void *data,
04423 DBusFreeFunction free_data_func)
04424 {
04425 DBusFreeFunction old_free_func;
04426 void *old_data;
04427 dbus_bool_t retval;
04428
04429 _dbus_return_val_if_fail (message != NULL, FALSE);
04430 _dbus_return_val_if_fail (slot >= 0, FALSE);
04431
04432 retval = _dbus_data_slot_list_set (&slot_allocator,
04433 &message->slot_list,
04434 slot, data, free_data_func,
04435 &old_free_func, &old_data);
04436
04437 if (retval)
04438 {
04439
04440 if (old_free_func)
04441 (* old_free_func) (old_data);
04442 }
04443
04444 return retval;
04445 }
04446
04455 void*
04456 dbus_message_get_data (DBusMessage *message,
04457 dbus_int32_t slot)
04458 {
04459 void *res;
04460
04461 _dbus_return_val_if_fail (message != NULL, NULL);
04462
04463 res = _dbus_data_slot_list_get (&slot_allocator,
04464 &message->slot_list,
04465 slot);
04466
04467 return res;
04468 }
04469
04483 int
04484 dbus_message_type_from_string (const char *type_str)
04485 {
04486 if (strcmp (type_str, "method_call") == 0)
04487 return DBUS_MESSAGE_TYPE_METHOD_CALL;
04488 if (strcmp (type_str, "method_return") == 0)
04489 return DBUS_MESSAGE_TYPE_METHOD_RETURN;
04490 else if (strcmp (type_str, "signal") == 0)
04491 return DBUS_MESSAGE_TYPE_SIGNAL;
04492 else if (strcmp (type_str, "error") == 0)
04493 return DBUS_MESSAGE_TYPE_ERROR;
04494 else
04495 return DBUS_MESSAGE_TYPE_INVALID;
04496 }
04497
04511 const char *
04512 dbus_message_type_to_string (int type)
04513 {
04514 switch (type)
04515 {
04516 case DBUS_MESSAGE_TYPE_METHOD_CALL:
04517 return "method_call";
04518 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
04519 return "method_return";
04520 case DBUS_MESSAGE_TYPE_SIGNAL:
04521 return "signal";
04522 case DBUS_MESSAGE_TYPE_ERROR:
04523 return "error";
04524 default:
04525 return "invalid";
04526 }
04527 }
04528
04541 dbus_bool_t
04542 dbus_message_marshal (DBusMessage *msg,
04543 char **marshalled_data_p,
04544 int *len_p)
04545 {
04546 DBusString tmp;
04547 dbus_bool_t was_locked;
04548
04549 _dbus_return_val_if_fail (msg != NULL, FALSE);
04550 _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
04551 _dbus_return_val_if_fail (len_p != NULL, FALSE);
04552
04553 if (!_dbus_string_init (&tmp))
04554 return FALSE;
04555
04556
04557 was_locked = msg->locked;
04558
04559 if (!was_locked)
04560 dbus_message_lock (msg);
04561
04562 if (!_dbus_string_copy (&(msg->header.data), 0, &tmp, 0))
04563 goto fail;
04564
04565 *len_p = _dbus_string_get_length (&tmp);
04566
04567 if (!_dbus_string_copy (&(msg->body), 0, &tmp, *len_p))
04568 goto fail;
04569
04570 *len_p = _dbus_string_get_length (&tmp);
04571
04572 if (!_dbus_string_steal_data (&tmp, marshalled_data_p))
04573 goto fail;
04574
04575 _dbus_string_free (&tmp);
04576
04577 if (!was_locked)
04578 msg->locked = FALSE;
04579
04580 return TRUE;
04581
04582 fail:
04583 _dbus_string_free (&tmp);
04584
04585 if (!was_locked)
04586 msg->locked = FALSE;
04587
04588 return FALSE;
04589 }
04590
04603 DBusMessage *
04604 dbus_message_demarshal (const char *str,
04605 int len,
04606 DBusError *error)
04607 {
04608 DBusMessageLoader *loader;
04609 DBusString *buffer;
04610 DBusMessage *msg;
04611
04612 _dbus_return_val_if_fail (str != NULL, NULL);
04613
04614 loader = _dbus_message_loader_new ();
04615
04616 if (loader == NULL)
04617 return NULL;
04618
04619 _dbus_message_loader_get_buffer (loader, &buffer);
04620 _dbus_string_append_len (buffer, str, len);
04621 _dbus_message_loader_return_buffer (loader, buffer, len);
04622
04623 if (!_dbus_message_loader_queue_messages (loader))
04624 goto fail_oom;
04625
04626 if (_dbus_message_loader_get_is_corrupted (loader))
04627 goto fail_corrupt;
04628
04629 msg = _dbus_message_loader_pop_message (loader);
04630
04631 if (!msg)
04632 goto fail_oom;
04633
04634 _dbus_message_loader_unref (loader);
04635 return msg;
04636
04637 fail_corrupt:
04638 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted (%s)",
04639 _dbus_validity_to_error_message (loader->corruption_reason));
04640 _dbus_message_loader_unref (loader);
04641 return NULL;
04642
04643 fail_oom:
04644 _DBUS_SET_OOM (error);
04645 _dbus_message_loader_unref (loader);
04646 return NULL;
04647 }
04648
04662 int
04663 dbus_message_demarshal_bytes_needed(const char *buf,
04664 int len)
04665 {
04666 DBusString str;
04667 int byte_order, fields_array_len, header_len, body_len;
04668 DBusValidity validity = DBUS_VALID;
04669 int have_message;
04670
04671 if (!buf || len < DBUS_MINIMUM_HEADER_SIZE)
04672 return 0;
04673
04674 if (len > DBUS_MAXIMUM_MESSAGE_LENGTH)
04675 len = DBUS_MAXIMUM_MESSAGE_LENGTH;
04676 _dbus_string_init_const_len (&str, buf, len);
04677
04678 validity = DBUS_VALID;
04679 have_message
04680 = _dbus_header_have_message_untrusted(DBUS_MAXIMUM_MESSAGE_LENGTH,
04681 &validity, &byte_order,
04682 &fields_array_len,
04683 &header_len,
04684 &body_len,
04685 &str, 0,
04686 len);
04687 _dbus_string_free (&str);
04688
04689 if (validity == DBUS_VALID)
04690 {
04691 _dbus_assert (have_message || (header_len + body_len) > len);
04692 return header_len + body_len;
04693 }
04694 else
04695 {
04696 return -1;
04697 }
04698 }
04699
04702