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
00228 void
00229 _dbus_message_add_counter_link (DBusMessage *message,
00230 DBusList *link)
00231 {
00232
00233
00234
00235
00236
00237
00238 if (message->counters == NULL)
00239 {
00240 message->size_counter_delta =
00241 _dbus_string_get_length (&message->header.data) +
00242 _dbus_string_get_length (&message->body);
00243
00244 #ifdef HAVE_UNIX_FD_PASSING
00245 message->unix_fd_counter_delta = message->n_unix_fds;
00246 #endif
00247
00248 #if 0
00249 _dbus_verbose ("message has size %ld\n",
00250 message->size_counter_delta);
00251 #endif
00252 }
00253
00254 _dbus_list_append_link (&message->counters, link);
00255
00256 _dbus_counter_adjust_size (link->data, message->size_counter_delta);
00257
00258 #ifdef HAVE_UNIX_FD_PASSING
00259 _dbus_counter_adjust_unix_fd (link->data, message->unix_fd_counter_delta);
00260 #endif
00261 }
00262
00277 dbus_bool_t
00278 _dbus_message_add_counter (DBusMessage *message,
00279 DBusCounter *counter)
00280 {
00281 DBusList *link;
00282
00283 link = _dbus_list_alloc_link (counter);
00284 if (link == NULL)
00285 return FALSE;
00286
00287 _dbus_counter_ref (counter);
00288 _dbus_message_add_counter_link (message, link);
00289
00290 return TRUE;
00291 }
00292
00301 void
00302 _dbus_message_remove_counter (DBusMessage *message,
00303 DBusCounter *counter,
00304 DBusList **link_return)
00305 {
00306 DBusList *link;
00307
00308 link = _dbus_list_find_last (&message->counters,
00309 counter);
00310 _dbus_assert (link != NULL);
00311
00312 _dbus_list_unlink (&message->counters,
00313 link);
00314 if (link_return)
00315 *link_return = link;
00316 else
00317 _dbus_list_free_link (link);
00318
00319 _dbus_counter_adjust_size (counter, - message->size_counter_delta);
00320
00321 #ifdef HAVE_UNIX_FD_PASSING
00322 _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
00323 #endif
00324
00325 _dbus_counter_notify (counter);
00326 _dbus_counter_unref (counter);
00327 }
00328
00339 void
00340 dbus_message_lock (DBusMessage *message)
00341 {
00342 if (!message->locked)
00343 {
00344 _dbus_header_update_lengths (&message->header,
00345 _dbus_string_get_length (&message->body));
00346
00347
00348 _dbus_assert (_dbus_string_get_length (&message->body) == 0 ||
00349 dbus_message_get_signature (message) != NULL);
00350
00351 message->locked = TRUE;
00352 }
00353 }
00354
00355 static dbus_bool_t
00356 set_or_delete_string_field (DBusMessage *message,
00357 int field,
00358 int typecode,
00359 const char *value)
00360 {
00361 if (value == NULL)
00362 return _dbus_header_delete_field (&message->header, field);
00363 else
00364 return _dbus_header_set_field_basic (&message->header,
00365 field,
00366 typecode,
00367 &value);
00368 }
00369
00370 #if 0
00371
00395 static dbus_bool_t
00396 _dbus_message_set_signature (DBusMessage *message,
00397 const char *signature)
00398 {
00399 _dbus_return_val_if_fail (message != NULL, FALSE);
00400 _dbus_return_val_if_fail (!message->locked, FALSE);
00401 _dbus_return_val_if_fail (signature == NULL ||
00402 _dbus_check_is_valid_signature (signature));
00403
00404 _dbus_return_val_if_fail (_dbus_string_get_length (&message->body) == 0 ||
00405 signature != NULL);
00406
00407 return set_or_delete_string_field (message,
00408 DBUS_HEADER_FIELD_SIGNATURE,
00409 DBUS_TYPE_SIGNATURE,
00410 signature);
00411 }
00412 #endif
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
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00461 #define MAX_MESSAGE_SIZE_TO_CACHE 10 * _DBUS_ONE_KILOBYTE
00462
00464 #define MAX_MESSAGE_CACHE_SIZE 5
00465
00466 _DBUS_DEFINE_GLOBAL_LOCK (message_cache);
00467 static DBusMessage *message_cache[MAX_MESSAGE_CACHE_SIZE];
00468 static int message_cache_count = 0;
00469 static dbus_bool_t message_cache_shutdown_registered = FALSE;
00470
00471 static void
00472 dbus_message_cache_shutdown (void *data)
00473 {
00474 int i;
00475
00476 _DBUS_LOCK (message_cache);
00477
00478 i = 0;
00479 while (i < MAX_MESSAGE_CACHE_SIZE)
00480 {
00481 if (message_cache[i])
00482 dbus_message_finalize (message_cache[i]);
00483
00484 ++i;
00485 }
00486
00487 message_cache_count = 0;
00488 message_cache_shutdown_registered = FALSE;
00489
00490 _DBUS_UNLOCK (message_cache);
00491 }
00492
00500 static DBusMessage*
00501 dbus_message_get_cached (void)
00502 {
00503 DBusMessage *message;
00504 int i;
00505
00506 message = NULL;
00507
00508 _DBUS_LOCK (message_cache);
00509
00510 _dbus_assert (message_cache_count >= 0);
00511
00512 if (message_cache_count == 0)
00513 {
00514 _DBUS_UNLOCK (message_cache);
00515 return NULL;
00516 }
00517
00518
00519
00520
00521
00522 _dbus_assert (message_cache_shutdown_registered);
00523
00524 i = 0;
00525 while (i < MAX_MESSAGE_CACHE_SIZE)
00526 {
00527 if (message_cache[i])
00528 {
00529 message = message_cache[i];
00530 message_cache[i] = NULL;
00531 message_cache_count -= 1;
00532 break;
00533 }
00534 ++i;
00535 }
00536 _dbus_assert (message_cache_count >= 0);
00537 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
00538 _dbus_assert (message != NULL);
00539
00540 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
00541
00542 _dbus_assert (message->counters == NULL);
00543
00544 _DBUS_UNLOCK (message_cache);
00545
00546 return message;
00547 }
00548
00549 #ifdef HAVE_UNIX_FD_PASSING
00550 static void
00551 close_unix_fds(int *fds, unsigned *n_fds)
00552 {
00553 DBusError e;
00554 int i;
00555
00556 if (*n_fds <= 0)
00557 return;
00558
00559 dbus_error_init(&e);
00560
00561 for (i = 0; i < *n_fds; i++)
00562 {
00563 if (!_dbus_close(fds[i], &e))
00564 {
00565 _dbus_warn("Failed to close file descriptor: %s\n", e.message);
00566 dbus_error_free(&e);
00567 }
00568 }
00569
00570 *n_fds = 0;
00571
00572
00573 }
00574 #endif
00575
00576 static void
00577 free_counter (void *element,
00578 void *data)
00579 {
00580 DBusCounter *counter = element;
00581 DBusMessage *message = data;
00582
00583 _dbus_counter_adjust_size (counter, - message->size_counter_delta);
00584 #ifdef HAVE_UNIX_FD_PASSING
00585 _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
00586 #endif
00587
00588 _dbus_counter_notify (counter);
00589 _dbus_counter_unref (counter);
00590 }
00591
00597 static void
00598 dbus_message_cache_or_finalize (DBusMessage *message)
00599 {
00600 dbus_bool_t was_cached;
00601 int i;
00602
00603 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
00604
00605
00606
00607
00608 _dbus_data_slot_list_clear (&message->slot_list);
00609
00610 _dbus_list_foreach (&message->counters,
00611 free_counter, message);
00612 _dbus_list_clear (&message->counters);
00613
00614 #ifdef HAVE_UNIX_FD_PASSING
00615 close_unix_fds(message->unix_fds, &message->n_unix_fds);
00616 #endif
00617
00618 was_cached = FALSE;
00619
00620 _DBUS_LOCK (message_cache);
00621
00622 if (!message_cache_shutdown_registered)
00623 {
00624 _dbus_assert (message_cache_count == 0);
00625
00626 if (!_dbus_register_shutdown_func (dbus_message_cache_shutdown, NULL))
00627 goto out;
00628
00629 i = 0;
00630 while (i < MAX_MESSAGE_CACHE_SIZE)
00631 {
00632 message_cache[i] = NULL;
00633 ++i;
00634 }
00635
00636 message_cache_shutdown_registered = TRUE;
00637 }
00638
00639 _dbus_assert (message_cache_count >= 0);
00640
00641 if ((_dbus_string_get_length (&message->header.data) +
00642 _dbus_string_get_length (&message->body)) >
00643 MAX_MESSAGE_SIZE_TO_CACHE)
00644 goto out;
00645
00646 if (message_cache_count >= MAX_MESSAGE_CACHE_SIZE)
00647 goto out;
00648
00649
00650 i = 0;
00651 while (message_cache[i] != NULL)
00652 ++i;
00653
00654 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
00655
00656 _dbus_assert (message_cache[i] == NULL);
00657 message_cache[i] = message;
00658 message_cache_count += 1;
00659 was_cached = TRUE;
00660 #ifndef DBUS_DISABLE_CHECKS
00661 message->in_cache = TRUE;
00662 #endif
00663
00664 out:
00665 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
00666
00667 _DBUS_UNLOCK (message_cache);
00668
00669 if (!was_cached)
00670 dbus_message_finalize (message);
00671 }
00672
00673 #ifndef DBUS_DISABLE_CHECKS
00674 static dbus_bool_t
00675 _dbus_message_iter_check (DBusMessageRealIter *iter)
00676 {
00677 if (iter == NULL)
00678 {
00679 _dbus_warn_check_failed ("dbus message iterator is NULL\n");
00680 return FALSE;
00681 }
00682
00683 if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_READER)
00684 {
00685 if (iter->u.reader.byte_order != iter->message->byte_order)
00686 {
00687 _dbus_warn_check_failed ("dbus message changed byte order since iterator was created\n");
00688 return FALSE;
00689 }
00690
00691 _dbus_assert (iter->u.reader.byte_order == DBUS_COMPILER_BYTE_ORDER);
00692 }
00693 else if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER)
00694 {
00695 if (iter->u.writer.byte_order != iter->message->byte_order)
00696 {
00697 _dbus_warn_check_failed ("dbus message changed byte order since append iterator was created\n");
00698 return FALSE;
00699 }
00700
00701 _dbus_assert (iter->u.writer.byte_order == DBUS_COMPILER_BYTE_ORDER);
00702 }
00703 else
00704 {
00705 _dbus_warn_check_failed ("dbus message iterator looks uninitialized or corrupted\n");
00706 return FALSE;
00707 }
00708
00709 if (iter->changed_stamp != iter->message->changed_stamp)
00710 {
00711 _dbus_warn_check_failed ("dbus message iterator invalid because the message has been modified (or perhaps the iterator is just uninitialized)\n");
00712 return FALSE;
00713 }
00714
00715 return TRUE;
00716 }
00717 #endif
00718
00733 dbus_bool_t
00734 _dbus_message_iter_get_args_valist (DBusMessageIter *iter,
00735 DBusError *error,
00736 int first_arg_type,
00737 va_list var_args)
00738 {
00739 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
00740 int spec_type, msg_type, i;
00741 dbus_bool_t retval;
00742
00743 _dbus_assert (_dbus_message_iter_check (real));
00744
00745 retval = FALSE;
00746
00747 spec_type = first_arg_type;
00748 i = 0;
00749
00750 while (spec_type != DBUS_TYPE_INVALID)
00751 {
00752 msg_type = dbus_message_iter_get_arg_type (iter);
00753
00754 if (msg_type != spec_type)
00755 {
00756 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
00757 "Argument %d is specified to be of type \"%s\", but "
00758 "is actually of type \"%s\"\n", i,
00759 _dbus_type_to_string (spec_type),
00760 _dbus_type_to_string (msg_type));
00761
00762 goto out;
00763 }
00764
00765 if (spec_type == DBUS_TYPE_UNIX_FD)
00766 {
00767 #ifdef HAVE_UNIX_FD_PASSING
00768 DBusBasicValue idx;
00769 int *pfd, nfd;
00770
00771 pfd = va_arg (var_args, int*);
00772 _dbus_assert(pfd);
00773
00774 _dbus_type_reader_read_basic(&real->u.reader, &idx);
00775
00776 if (idx.u32 >= real->message->n_unix_fds)
00777 {
00778 dbus_set_error (error, DBUS_ERROR_INCONSISTENT_MESSAGE,
00779 "Message refers to file descriptor at index %i,"
00780 "but has only %i descriptors attached.\n",
00781 idx.u32,
00782 real->message->n_unix_fds);
00783 goto out;
00784 }
00785
00786 if ((nfd = _dbus_dup(real->message->unix_fds[idx.u32], error)) < 0)
00787 goto out;
00788
00789 *pfd = nfd;
00790 #else
00791 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00792 "Platform does not support file desciptor passing.\n");
00793 goto out;
00794 #endif
00795 }
00796 else if (dbus_type_is_basic (spec_type))
00797 {
00798 DBusBasicValue *ptr;
00799
00800 ptr = va_arg (var_args, DBusBasicValue*);
00801
00802 _dbus_assert (ptr != NULL);
00803
00804 _dbus_type_reader_read_basic (&real->u.reader,
00805 ptr);
00806 }
00807 else if (spec_type == DBUS_TYPE_ARRAY)
00808 {
00809 int element_type;
00810 int spec_element_type;
00811 const DBusBasicValue **ptr;
00812 int *n_elements_p;
00813 DBusTypeReader array;
00814
00815 spec_element_type = va_arg (var_args, int);
00816 element_type = _dbus_type_reader_get_element_type (&real->u.reader);
00817
00818 if (spec_element_type != element_type)
00819 {
00820 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
00821 "Argument %d is specified to be an array of \"%s\", but "
00822 "is actually an array of \"%s\"\n",
00823 i,
00824 _dbus_type_to_string (spec_element_type),
00825 _dbus_type_to_string (element_type));
00826
00827 goto out;
00828 }
00829
00830 if (dbus_type_is_fixed (spec_element_type) &&
00831 element_type != DBUS_TYPE_UNIX_FD)
00832 {
00833 ptr = va_arg (var_args, const DBusBasicValue**);
00834 n_elements_p = va_arg (var_args, int*);
00835
00836 _dbus_assert (ptr != NULL);
00837 _dbus_assert (n_elements_p != NULL);
00838
00839 _dbus_type_reader_recurse (&real->u.reader, &array);
00840
00841 _dbus_type_reader_read_fixed_multi (&array,
00842 (void *) ptr, n_elements_p);
00843 }
00844 else if (spec_element_type == DBUS_TYPE_STRING ||
00845 spec_element_type == DBUS_TYPE_SIGNATURE ||
00846 spec_element_type == DBUS_TYPE_OBJECT_PATH)
00847 {
00848 char ***str_array_p;
00849 int n_elements;
00850 char **str_array;
00851
00852 str_array_p = va_arg (var_args, char***);
00853 n_elements_p = va_arg (var_args, int*);
00854
00855 _dbus_assert (str_array_p != NULL);
00856 _dbus_assert (n_elements_p != NULL);
00857
00858
00859 _dbus_type_reader_recurse (&real->u.reader, &array);
00860
00861 n_elements = 0;
00862 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
00863 {
00864 ++n_elements;
00865 _dbus_type_reader_next (&array);
00866 }
00867
00868 str_array = dbus_new0 (char*, n_elements + 1);
00869 if (str_array == NULL)
00870 {
00871 _DBUS_SET_OOM (error);
00872 goto out;
00873 }
00874
00875
00876 _dbus_type_reader_recurse (&real->u.reader, &array);
00877
00878 i = 0;
00879 while (i < n_elements)
00880 {
00881 const char *s;
00882 _dbus_type_reader_read_basic (&array,
00883 (void *) &s);
00884
00885 str_array[i] = _dbus_strdup (s);
00886 if (str_array[i] == NULL)
00887 {
00888 dbus_free_string_array (str_array);
00889 _DBUS_SET_OOM (error);
00890 goto out;
00891 }
00892
00893 ++i;
00894
00895 if (!_dbus_type_reader_next (&array))
00896 _dbus_assert (i == n_elements);
00897 }
00898
00899 _dbus_assert (_dbus_type_reader_get_current_type (&array) == DBUS_TYPE_INVALID);
00900 _dbus_assert (i == n_elements);
00901 _dbus_assert (str_array[i] == NULL);
00902
00903 *str_array_p = str_array;
00904 *n_elements_p = n_elements;
00905 }
00906 #ifndef DBUS_DISABLE_CHECKS
00907 else
00908 {
00909 _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now\n",
00910 _DBUS_FUNCTION_NAME);
00911 goto out;
00912 }
00913 #endif
00914 }
00915 #ifndef DBUS_DISABLE_CHECKS
00916 else
00917 {
00918 _dbus_warn ("you can only read arrays and basic types with %s for now\n",
00919 _DBUS_FUNCTION_NAME);
00920 goto out;
00921 }
00922 #endif
00923
00924 spec_type = va_arg (var_args, int);
00925 if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID)
00926 {
00927 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
00928 "Message has only %d arguments, but more were expected", i);
00929 goto out;
00930 }
00931
00932 i++;
00933 }
00934
00935 retval = TRUE;
00936
00937 out:
00938
00939 return retval;
00940 }
00941
01000 dbus_uint32_t
01001 dbus_message_get_serial (DBusMessage *message)
01002 {
01003 _dbus_return_val_if_fail (message != NULL, 0);
01004
01005 return _dbus_header_get_serial (&message->header);
01006 }
01007
01016 dbus_bool_t
01017 dbus_message_set_reply_serial (DBusMessage *message,
01018 dbus_uint32_t reply_serial)
01019 {
01020 _dbus_return_val_if_fail (message != NULL, FALSE);
01021 _dbus_return_val_if_fail (!message->locked, FALSE);
01022 _dbus_return_val_if_fail (reply_serial != 0, FALSE);
01023
01024 return _dbus_header_set_field_basic (&message->header,
01025 DBUS_HEADER_FIELD_REPLY_SERIAL,
01026 DBUS_TYPE_UINT32,
01027 &reply_serial);
01028 }
01029
01036 dbus_uint32_t
01037 dbus_message_get_reply_serial (DBusMessage *message)
01038 {
01039 dbus_uint32_t v_UINT32;
01040
01041 _dbus_return_val_if_fail (message != NULL, 0);
01042
01043 if (_dbus_header_get_field_basic (&message->header,
01044 DBUS_HEADER_FIELD_REPLY_SERIAL,
01045 DBUS_TYPE_UINT32,
01046 &v_UINT32))
01047 return v_UINT32;
01048 else
01049 return 0;
01050 }
01051
01052 static void
01053 dbus_message_finalize (DBusMessage *message)
01054 {
01055 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
01056
01057
01058 _dbus_data_slot_list_free (&message->slot_list);
01059
01060 _dbus_list_foreach (&message->counters,
01061 free_counter, message);
01062 _dbus_list_clear (&message->counters);
01063
01064 _dbus_header_free (&message->header);
01065 _dbus_string_free (&message->body);
01066
01067 #ifdef HAVE_UNIX_FD_PASSING
01068 close_unix_fds(message->unix_fds, &message->n_unix_fds);
01069 dbus_free(message->unix_fds);
01070 #endif
01071
01072 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
01073
01074 dbus_free (message);
01075 }
01076
01077 static DBusMessage*
01078 dbus_message_new_empty_header (void)
01079 {
01080 DBusMessage *message;
01081 dbus_bool_t from_cache;
01082
01083 message = dbus_message_get_cached ();
01084
01085 if (message != NULL)
01086 {
01087 from_cache = TRUE;
01088 }
01089 else
01090 {
01091 from_cache = FALSE;
01092 message = dbus_new0 (DBusMessage, 1);
01093 if (message == NULL)
01094 return NULL;
01095 #ifndef DBUS_DISABLE_CHECKS
01096 message->generation = _dbus_current_generation;
01097 #endif
01098
01099 #ifdef HAVE_UNIX_FD_PASSING
01100 message->unix_fds = NULL;
01101 message->n_unix_fds_allocated = 0;
01102 #endif
01103 }
01104
01105 _dbus_atomic_inc (&message->refcount);
01106
01107 message->byte_order = DBUS_COMPILER_BYTE_ORDER;
01108 message->locked = FALSE;
01109 #ifndef DBUS_DISABLE_CHECKS
01110 message->in_cache = FALSE;
01111 #endif
01112 message->counters = NULL;
01113 message->size_counter_delta = 0;
01114 message->changed_stamp = 0;
01115
01116 #ifdef HAVE_UNIX_FD_PASSING
01117 message->n_unix_fds = 0;
01118 message->n_unix_fds_allocated = 0;
01119 message->unix_fd_counter_delta = 0;
01120 #endif
01121
01122 if (!from_cache)
01123 _dbus_data_slot_list_init (&message->slot_list);
01124
01125 if (from_cache)
01126 {
01127 _dbus_header_reinit (&message->header, message->byte_order);
01128 _dbus_string_set_length (&message->body, 0);
01129 }
01130 else
01131 {
01132 if (!_dbus_header_init (&message->header, message->byte_order))
01133 {
01134 dbus_free (message);
01135 return NULL;
01136 }
01137
01138 if (!_dbus_string_init_preallocated (&message->body, 32))
01139 {
01140 _dbus_header_free (&message->header);
01141 dbus_free (message);
01142 return NULL;
01143 }
01144 }
01145
01146 return message;
01147 }
01148
01161 DBusMessage*
01162 dbus_message_new (int message_type)
01163 {
01164 DBusMessage *message;
01165
01166 _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
01167
01168 message = dbus_message_new_empty_header ();
01169 if (message == NULL)
01170 return NULL;
01171
01172 if (!_dbus_header_create (&message->header,
01173 message_type,
01174 NULL, NULL, NULL, NULL, NULL))
01175 {
01176 dbus_message_unref (message);
01177 return NULL;
01178 }
01179
01180 return message;
01181 }
01182
01204 DBusMessage*
01205 dbus_message_new_method_call (const char *destination,
01206 const char *path,
01207 const char *interface,
01208 const char *method)
01209 {
01210 DBusMessage *message;
01211
01212 _dbus_return_val_if_fail (path != NULL, NULL);
01213 _dbus_return_val_if_fail (method != NULL, NULL);
01214 _dbus_return_val_if_fail (destination == NULL ||
01215 _dbus_check_is_valid_bus_name (destination), NULL);
01216 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
01217 _dbus_return_val_if_fail (interface == NULL ||
01218 _dbus_check_is_valid_interface (interface), NULL);
01219 _dbus_return_val_if_fail (_dbus_check_is_valid_member (method), NULL);
01220
01221 message = dbus_message_new_empty_header ();
01222 if (message == NULL)
01223 return NULL;
01224
01225 if (!_dbus_header_create (&message->header,
01226 DBUS_MESSAGE_TYPE_METHOD_CALL,
01227 destination, path, interface, method, NULL))
01228 {
01229 dbus_message_unref (message);
01230 return NULL;
01231 }
01232
01233 return message;
01234 }
01235
01243 DBusMessage*
01244 dbus_message_new_method_return (DBusMessage *method_call)
01245 {
01246 DBusMessage *message;
01247 const char *sender;
01248
01249 _dbus_return_val_if_fail (method_call != NULL, NULL);
01250
01251 sender = dbus_message_get_sender (method_call);
01252
01253
01254
01255 message = dbus_message_new_empty_header ();
01256 if (message == NULL)
01257 return NULL;
01258
01259 if (!_dbus_header_create (&message->header,
01260 DBUS_MESSAGE_TYPE_METHOD_RETURN,
01261 sender, NULL, NULL, NULL, NULL))
01262 {
01263 dbus_message_unref (message);
01264 return NULL;
01265 }
01266
01267 dbus_message_set_no_reply (message, TRUE);
01268
01269 if (!dbus_message_set_reply_serial (message,
01270 dbus_message_get_serial (method_call)))
01271 {
01272 dbus_message_unref (message);
01273 return NULL;
01274 }
01275
01276 return message;
01277 }
01278
01293 DBusMessage*
01294 dbus_message_new_signal (const char *path,
01295 const char *interface,
01296 const char *name)
01297 {
01298 DBusMessage *message;
01299
01300 _dbus_return_val_if_fail (path != NULL, NULL);
01301 _dbus_return_val_if_fail (interface != NULL, NULL);
01302 _dbus_return_val_if_fail (name != NULL, NULL);
01303 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
01304 _dbus_return_val_if_fail (_dbus_check_is_valid_interface (interface), NULL);
01305 _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);
01306
01307 message = dbus_message_new_empty_header ();
01308 if (message == NULL)
01309 return NULL;
01310
01311 if (!_dbus_header_create (&message->header,
01312 DBUS_MESSAGE_TYPE_SIGNAL,
01313 NULL, path, interface, name, NULL))
01314 {
01315 dbus_message_unref (message);
01316 return NULL;
01317 }
01318
01319 dbus_message_set_no_reply (message, TRUE);
01320
01321 return message;
01322 }
01323
01338 DBusMessage*
01339 dbus_message_new_error (DBusMessage *reply_to,
01340 const char *error_name,
01341 const char *error_message)
01342 {
01343 DBusMessage *message;
01344 const char *sender;
01345 DBusMessageIter iter;
01346
01347 _dbus_return_val_if_fail (reply_to != NULL, NULL);
01348 _dbus_return_val_if_fail (error_name != NULL, NULL);
01349 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
01350
01351 sender = dbus_message_get_sender (reply_to);
01352
01353
01354
01355
01356
01357 message = dbus_message_new_empty_header ();
01358 if (message == NULL)
01359 return NULL;
01360
01361 if (!_dbus_header_create (&message->header,
01362 DBUS_MESSAGE_TYPE_ERROR,
01363 sender, NULL, NULL, NULL, error_name))
01364 {
01365 dbus_message_unref (message);
01366 return NULL;
01367 }
01368
01369 dbus_message_set_no_reply (message, TRUE);
01370
01371 if (!dbus_message_set_reply_serial (message,
01372 dbus_message_get_serial (reply_to)))
01373 {
01374 dbus_message_unref (message);
01375 return NULL;
01376 }
01377
01378 if (error_message != NULL)
01379 {
01380 dbus_message_iter_init_append (message, &iter);
01381 if (!dbus_message_iter_append_basic (&iter,
01382 DBUS_TYPE_STRING,
01383 &error_message))
01384 {
01385 dbus_message_unref (message);
01386 return NULL;
01387 }
01388 }
01389
01390 return message;
01391 }
01392
01409 DBusMessage*
01410 dbus_message_new_error_printf (DBusMessage *reply_to,
01411 const char *error_name,
01412 const char *error_format,
01413 ...)
01414 {
01415 va_list args;
01416 DBusString str;
01417 DBusMessage *message;
01418
01419 _dbus_return_val_if_fail (reply_to != NULL, NULL);
01420 _dbus_return_val_if_fail (error_name != NULL, NULL);
01421 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
01422
01423 if (!_dbus_string_init (&str))
01424 return NULL;
01425
01426 va_start (args, error_format);
01427
01428 if (_dbus_string_append_printf_valist (&str, error_format, args))
01429 message = dbus_message_new_error (reply_to, error_name,
01430 _dbus_string_get_const_data (&str));
01431 else
01432 message = NULL;
01433
01434 _dbus_string_free (&str);
01435
01436 va_end (args);
01437
01438 return message;
01439 }
01440
01441
01454 DBusMessage *
01455 dbus_message_copy (const DBusMessage *message)
01456 {
01457 DBusMessage *retval;
01458
01459 _dbus_return_val_if_fail (message != NULL, NULL);
01460
01461 retval = dbus_new0 (DBusMessage, 1);
01462 if (retval == NULL)
01463 return NULL;
01464
01465 _dbus_atomic_inc (&retval->refcount);
01466 retval->byte_order = message->byte_order;
01467 retval->locked = FALSE;
01468 #ifndef DBUS_DISABLE_CHECKS
01469 retval->generation = message->generation;
01470 #endif
01471
01472 if (!_dbus_header_copy (&message->header, &retval->header))
01473 {
01474 dbus_free (retval);
01475 return NULL;
01476 }
01477
01478 if (!_dbus_string_init_preallocated (&retval->body,
01479 _dbus_string_get_length (&message->body)))
01480 {
01481 _dbus_header_free (&retval->header);
01482 dbus_free (retval);
01483 return NULL;
01484 }
01485
01486 if (!_dbus_string_copy (&message->body, 0,
01487 &retval->body, 0))
01488 goto failed_copy;
01489
01490 #ifdef HAVE_UNIX_FD_PASSING
01491 retval->unix_fds = dbus_new(int, message->n_unix_fds);
01492 if (retval->unix_fds == NULL && message->n_unix_fds > 0)
01493 goto failed_copy;
01494
01495 retval->n_unix_fds_allocated = message->n_unix_fds;
01496
01497 for (retval->n_unix_fds = 0;
01498 retval->n_unix_fds < message->n_unix_fds;
01499 retval->n_unix_fds++)
01500 {
01501 retval->unix_fds[retval->n_unix_fds] = _dbus_dup(message->unix_fds[retval->n_unix_fds], NULL);
01502
01503 if (retval->unix_fds[retval->n_unix_fds] < 0)
01504 goto failed_copy;
01505 }
01506
01507 #endif
01508
01509 return retval;
01510
01511 failed_copy:
01512 _dbus_header_free (&retval->header);
01513 _dbus_string_free (&retval->body);
01514
01515 #ifdef HAVE_UNIX_FD_PASSING
01516 close_unix_fds(retval->unix_fds, &retval->n_unix_fds);
01517 dbus_free(retval->unix_fds);
01518 #endif
01519
01520 dbus_free (retval);
01521
01522 return NULL;
01523 }
01524
01525
01533 DBusMessage *
01534 dbus_message_ref (DBusMessage *message)
01535 {
01536 #ifndef DBUS_DISABLE_ASSERT
01537 dbus_int32_t old_refcount;
01538 #endif
01539
01540 _dbus_return_val_if_fail (message != NULL, NULL);
01541 _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
01542 _dbus_return_val_if_fail (!message->in_cache, NULL);
01543
01544 #ifdef DBUS_DISABLE_ASSERT
01545 _dbus_atomic_inc (&message->refcount);
01546 #else
01547 old_refcount = _dbus_atomic_inc (&message->refcount);
01548 _dbus_assert (old_refcount >= 1);
01549 #endif
01550
01551 return message;
01552 }
01553
01561 void
01562 dbus_message_unref (DBusMessage *message)
01563 {
01564 dbus_int32_t old_refcount;
01565
01566 _dbus_return_if_fail (message != NULL);
01567 _dbus_return_if_fail (message->generation == _dbus_current_generation);
01568 _dbus_return_if_fail (!message->in_cache);
01569
01570 old_refcount = _dbus_atomic_dec (&message->refcount);
01571
01572 _dbus_assert (old_refcount >= 1);
01573
01574 if (old_refcount == 1)
01575 {
01576
01577 dbus_message_cache_or_finalize (message);
01578 }
01579 }
01580
01591 int
01592 dbus_message_get_type (DBusMessage *message)
01593 {
01594 _dbus_return_val_if_fail (message != NULL, DBUS_MESSAGE_TYPE_INVALID);
01595
01596 return _dbus_header_get_message_type (&message->header);
01597 }
01598
01661 dbus_bool_t
01662 dbus_message_append_args (DBusMessage *message,
01663 int first_arg_type,
01664 ...)
01665 {
01666 dbus_bool_t retval;
01667 va_list var_args;
01668
01669 _dbus_return_val_if_fail (message != NULL, FALSE);
01670
01671 va_start (var_args, first_arg_type);
01672 retval = dbus_message_append_args_valist (message,
01673 first_arg_type,
01674 var_args);
01675 va_end (var_args);
01676
01677 return retval;
01678 }
01679
01693 dbus_bool_t
01694 dbus_message_append_args_valist (DBusMessage *message,
01695 int first_arg_type,
01696 va_list var_args)
01697 {
01698 int type;
01699 DBusMessageIter iter;
01700
01701 _dbus_return_val_if_fail (message != NULL, FALSE);
01702
01703 type = first_arg_type;
01704
01705 dbus_message_iter_init_append (message, &iter);
01706
01707 while (type != DBUS_TYPE_INVALID)
01708 {
01709 if (dbus_type_is_basic (type))
01710 {
01711 const DBusBasicValue *value;
01712 value = va_arg (var_args, const DBusBasicValue*);
01713
01714 if (!dbus_message_iter_append_basic (&iter,
01715 type,
01716 value))
01717 goto failed;
01718 }
01719 else if (type == DBUS_TYPE_ARRAY)
01720 {
01721 int element_type;
01722 DBusMessageIter array;
01723 char buf[2];
01724
01725 element_type = va_arg (var_args, int);
01726
01727 buf[0] = element_type;
01728 buf[1] = '\0';
01729 if (!dbus_message_iter_open_container (&iter,
01730 DBUS_TYPE_ARRAY,
01731 buf,
01732 &array))
01733 goto failed;
01734
01735 if (dbus_type_is_fixed (element_type) &&
01736 element_type != DBUS_TYPE_UNIX_FD)
01737 {
01738 const DBusBasicValue **value;
01739 int n_elements;
01740
01741 value = va_arg (var_args, const DBusBasicValue**);
01742 n_elements = va_arg (var_args, int);
01743
01744 if (!dbus_message_iter_append_fixed_array (&array,
01745 element_type,
01746 value,
01747 n_elements)) {
01748 dbus_message_iter_abandon_container (&iter, &array);
01749 goto failed;
01750 }
01751 }
01752 else if (element_type == DBUS_TYPE_STRING ||
01753 element_type == DBUS_TYPE_SIGNATURE ||
01754 element_type == DBUS_TYPE_OBJECT_PATH)
01755 {
01756 const char ***value_p;
01757 const char **value;
01758 int n_elements;
01759 int i;
01760
01761 value_p = va_arg (var_args, const char***);
01762 n_elements = va_arg (var_args, int);
01763
01764 value = *value_p;
01765
01766 i = 0;
01767 while (i < n_elements)
01768 {
01769 if (!dbus_message_iter_append_basic (&array,
01770 element_type,
01771 &value[i])) {
01772 dbus_message_iter_abandon_container (&iter, &array);
01773 goto failed;
01774 }
01775 ++i;
01776 }
01777 }
01778 else
01779 {
01780 _dbus_warn ("arrays of %s can't be appended with %s for now\n",
01781 _dbus_type_to_string (element_type),
01782 _DBUS_FUNCTION_NAME);
01783 goto failed;
01784 }
01785
01786 if (!dbus_message_iter_close_container (&iter, &array))
01787 goto failed;
01788 }
01789 #ifndef DBUS_DISABLE_CHECKS
01790 else
01791 {
01792 _dbus_warn ("type %s isn't supported yet in %s\n",
01793 _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
01794 goto failed;
01795 }
01796 #endif
01797
01798 type = va_arg (var_args, int);
01799 }
01800
01801 return TRUE;
01802
01803 failed:
01804 return FALSE;
01805 }
01806
01851 dbus_bool_t
01852 dbus_message_get_args (DBusMessage *message,
01853 DBusError *error,
01854 int first_arg_type,
01855 ...)
01856 {
01857 dbus_bool_t retval;
01858 va_list var_args;
01859
01860 _dbus_return_val_if_fail (message != NULL, FALSE);
01861 _dbus_return_val_if_error_is_set (error, FALSE);
01862
01863 va_start (var_args, first_arg_type);
01864 retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
01865 va_end (var_args);
01866
01867 return retval;
01868 }
01869
01880 dbus_bool_t
01881 dbus_message_get_args_valist (DBusMessage *message,
01882 DBusError *error,
01883 int first_arg_type,
01884 va_list var_args)
01885 {
01886 DBusMessageIter iter;
01887
01888 _dbus_return_val_if_fail (message != NULL, FALSE);
01889 _dbus_return_val_if_error_is_set (error, FALSE);
01890
01891 dbus_message_iter_init (message, &iter);
01892 return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
01893 }
01894
01895 static void
01896 _dbus_message_iter_init_common (DBusMessage *message,
01897 DBusMessageRealIter *real,
01898 int iter_type)
01899 {
01900 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
01901
01902
01903
01904
01905 ensure_byte_order (message);
01906
01907 real->message = message;
01908 real->changed_stamp = message->changed_stamp;
01909 real->iter_type = iter_type;
01910 real->sig_refcount = 0;
01911 }
01912
01935 dbus_bool_t
01936 dbus_message_iter_init (DBusMessage *message,
01937 DBusMessageIter *iter)
01938 {
01939 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01940 const DBusString *type_str;
01941 int type_pos;
01942
01943 _dbus_return_val_if_fail (message != NULL, FALSE);
01944 _dbus_return_val_if_fail (iter != NULL, FALSE);
01945
01946 get_const_signature (&message->header, &type_str, &type_pos);
01947
01948 _dbus_message_iter_init_common (message, real,
01949 DBUS_MESSAGE_ITER_TYPE_READER);
01950
01951 _dbus_type_reader_init (&real->u.reader,
01952 message->byte_order,
01953 type_str, type_pos,
01954 &message->body,
01955 0);
01956
01957 return _dbus_type_reader_get_current_type (&real->u.reader) != DBUS_TYPE_INVALID;
01958 }
01959
01966 dbus_bool_t
01967 dbus_message_iter_has_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_has_next (&real->u.reader);
01975 }
01976
01985 dbus_bool_t
01986 dbus_message_iter_next (DBusMessageIter *iter)
01987 {
01988 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01989
01990 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
01991 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
01992
01993 return _dbus_type_reader_next (&real->u.reader);
01994 }
01995
02010 int
02011 dbus_message_iter_get_arg_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, FALSE);
02017
02018 return _dbus_type_reader_get_current_type (&real->u.reader);
02019 }
02020
02029 int
02030 dbus_message_iter_get_element_type (DBusMessageIter *iter)
02031 {
02032 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02033
02034 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
02035 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
02036 _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
02037
02038 return _dbus_type_reader_get_element_type (&real->u.reader);
02039 }
02040
02066 void
02067 dbus_message_iter_recurse (DBusMessageIter *iter,
02068 DBusMessageIter *sub)
02069 {
02070 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02071 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02072
02073 _dbus_return_if_fail (_dbus_message_iter_check (real));
02074 _dbus_return_if_fail (sub != NULL);
02075
02076 *real_sub = *real;
02077 _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
02078 }
02079
02091 char *
02092 dbus_message_iter_get_signature (DBusMessageIter *iter)
02093 {
02094 const DBusString *sig;
02095 DBusString retstr;
02096 char *ret;
02097 int start, len;
02098 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02099
02100 _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
02101
02102 if (!_dbus_string_init (&retstr))
02103 return NULL;
02104
02105 _dbus_type_reader_get_signature (&real->u.reader, &sig,
02106 &start, &len);
02107 if (!_dbus_string_append_len (&retstr,
02108 _dbus_string_get_const_data (sig) + start,
02109 len))
02110 return NULL;
02111 if (!_dbus_string_steal_data (&retstr, &ret))
02112 return NULL;
02113 _dbus_string_free (&retstr);
02114 return ret;
02115 }
02116
02164 void
02165 dbus_message_iter_get_basic (DBusMessageIter *iter,
02166 void *value)
02167 {
02168 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02169
02170 _dbus_return_if_fail (_dbus_message_iter_check (real));
02171 _dbus_return_if_fail (value != NULL);
02172
02173 if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_UNIX_FD)
02174 {
02175 #ifdef HAVE_UNIX_FD_PASSING
02176 DBusBasicValue idx;
02177
02178 _dbus_type_reader_read_basic(&real->u.reader, &idx);
02179
02180 if (idx.u32 >= real->message->n_unix_fds) {
02181
02182
02183 *((int*) value) = -1;
02184 return;
02185 }
02186
02187 *((int*) value) = _dbus_dup(real->message->unix_fds[idx.u32], NULL);
02188 #else
02189 *((int*) value) = -1;
02190 #endif
02191 }
02192 else
02193 {
02194 _dbus_type_reader_read_basic (&real->u.reader,
02195 value);
02196 }
02197 }
02198
02217 int
02218 dbus_message_iter_get_array_len (DBusMessageIter *iter)
02219 {
02220 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02221
02222 _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
02223
02224 return _dbus_type_reader_get_array_length (&real->u.reader);
02225 }
02226
02262 void
02263 dbus_message_iter_get_fixed_array (DBusMessageIter *iter,
02264 void *value,
02265 int *n_elements)
02266 {
02267 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02268 int subtype = _dbus_type_reader_get_current_type(&real->u.reader);
02269
02270 _dbus_return_if_fail (_dbus_message_iter_check (real));
02271 _dbus_return_if_fail (value != NULL);
02272 _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) ||
02273 (dbus_type_is_fixed (subtype) && subtype != DBUS_TYPE_UNIX_FD));
02274
02275 _dbus_type_reader_read_fixed_multi (&real->u.reader,
02276 value, n_elements);
02277 }
02278
02290 void
02291 dbus_message_iter_init_append (DBusMessage *message,
02292 DBusMessageIter *iter)
02293 {
02294 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02295
02296 _dbus_return_if_fail (message != NULL);
02297 _dbus_return_if_fail (iter != NULL);
02298
02299 _dbus_message_iter_init_common (message, real,
02300 DBUS_MESSAGE_ITER_TYPE_WRITER);
02301
02302
02303
02304
02305
02306 _dbus_type_writer_init_types_delayed (&real->u.writer,
02307 message->byte_order,
02308 &message->body,
02309 _dbus_string_get_length (&message->body));
02310 }
02311
02320 static dbus_bool_t
02321 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
02322 {
02323 DBusString *str;
02324 const DBusString *current_sig;
02325 int current_sig_pos;
02326
02327 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02328
02329 if (real->u.writer.type_str != NULL)
02330 {
02331 _dbus_assert (real->sig_refcount > 0);
02332 real->sig_refcount += 1;
02333 return TRUE;
02334 }
02335
02336 str = dbus_new (DBusString, 1);
02337 if (str == NULL)
02338 return FALSE;
02339
02340 if (!_dbus_header_get_field_raw (&real->message->header,
02341 DBUS_HEADER_FIELD_SIGNATURE,
02342 ¤t_sig, ¤t_sig_pos))
02343 current_sig = NULL;
02344
02345 if (current_sig)
02346 {
02347 int current_len;
02348
02349 current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
02350 current_sig_pos += 1;
02351
02352 if (!_dbus_string_init_preallocated (str, current_len + 4))
02353 {
02354 dbus_free (str);
02355 return FALSE;
02356 }
02357
02358 if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
02359 str, 0))
02360 {
02361 _dbus_string_free (str);
02362 dbus_free (str);
02363 return FALSE;
02364 }
02365 }
02366 else
02367 {
02368 if (!_dbus_string_init_preallocated (str, 4))
02369 {
02370 dbus_free (str);
02371 return FALSE;
02372 }
02373 }
02374
02375 real->sig_refcount = 1;
02376
02377 _dbus_type_writer_add_types (&real->u.writer,
02378 str, _dbus_string_get_length (str));
02379 return TRUE;
02380 }
02381
02391 static dbus_bool_t
02392 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
02393 {
02394 DBusString *str;
02395 const char *v_STRING;
02396 dbus_bool_t retval;
02397
02398 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02399 _dbus_assert (real->u.writer.type_str != NULL);
02400 _dbus_assert (real->sig_refcount > 0);
02401
02402 real->sig_refcount -= 1;
02403
02404 if (real->sig_refcount > 0)
02405 return TRUE;
02406 _dbus_assert (real->sig_refcount == 0);
02407
02408 retval = TRUE;
02409
02410 str = real->u.writer.type_str;
02411
02412 v_STRING = _dbus_string_get_const_data (str);
02413 if (!_dbus_header_set_field_basic (&real->message->header,
02414 DBUS_HEADER_FIELD_SIGNATURE,
02415 DBUS_TYPE_SIGNATURE,
02416 &v_STRING))
02417 retval = FALSE;
02418
02419 _dbus_type_writer_remove_types (&real->u.writer);
02420 _dbus_string_free (str);
02421 dbus_free (str);
02422
02423 return retval;
02424 }
02425
02433 static void
02434 _dbus_message_iter_abandon_signature (DBusMessageRealIter *real)
02435 {
02436 DBusString *str;
02437
02438 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02439 _dbus_assert (real->u.writer.type_str != NULL);
02440 _dbus_assert (real->sig_refcount > 0);
02441
02442 real->sig_refcount -= 1;
02443
02444 if (real->sig_refcount > 0)
02445 return;
02446 _dbus_assert (real->sig_refcount == 0);
02447
02448 str = real->u.writer.type_str;
02449
02450 _dbus_type_writer_remove_types (&real->u.writer);
02451 _dbus_string_free (str);
02452 dbus_free (str);
02453 }
02454
02455 #ifndef DBUS_DISABLE_CHECKS
02456 static dbus_bool_t
02457 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
02458 {
02459 if (!_dbus_message_iter_check (iter))
02460 return FALSE;
02461
02462 if (iter->message->locked)
02463 {
02464 _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)\n");
02465 return FALSE;
02466 }
02467
02468 return TRUE;
02469 }
02470 #endif
02471
02472 #ifdef HAVE_UNIX_FD_PASSING
02473 static int *
02474 expand_fd_array(DBusMessage *m,
02475 unsigned n)
02476 {
02477 _dbus_assert(m);
02478
02479
02480
02481
02482 if (m->n_unix_fds + n > m->n_unix_fds_allocated)
02483 {
02484 unsigned k;
02485 int *p;
02486
02487
02488 k = (m->n_unix_fds + n) * 2;
02489
02490
02491 if (k < 4)
02492 k = 4;
02493
02494 p = dbus_realloc(m->unix_fds, k * sizeof(int));
02495 if (p == NULL)
02496 return NULL;
02497
02498 m->unix_fds = p;
02499 m->n_unix_fds_allocated = k;
02500 }
02501
02502 return m->unix_fds + m->n_unix_fds;
02503 }
02504 #endif
02505
02525 dbus_bool_t
02526 dbus_message_iter_append_basic (DBusMessageIter *iter,
02527 int type,
02528 const void *value)
02529 {
02530 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02531 dbus_bool_t ret;
02532
02533 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02534 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02535 _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
02536 _dbus_return_val_if_fail (value != NULL, FALSE);
02537
02538 #ifndef DBUS_DISABLE_CHECKS
02539 switch (type)
02540 {
02541 const char * const *string_p;
02542 const dbus_bool_t *bool_p;
02543
02544 case DBUS_TYPE_STRING:
02545 string_p = value;
02546 _dbus_return_val_if_fail (_dbus_check_is_valid_utf8 (*string_p), FALSE);
02547 break;
02548
02549 case DBUS_TYPE_OBJECT_PATH:
02550 string_p = value;
02551 _dbus_return_val_if_fail (_dbus_check_is_valid_path (*string_p), FALSE);
02552 break;
02553
02554 case DBUS_TYPE_SIGNATURE:
02555 string_p = value;
02556 _dbus_return_val_if_fail (_dbus_check_is_valid_signature (*string_p), FALSE);
02557 break;
02558
02559 case DBUS_TYPE_BOOLEAN:
02560 bool_p = value;
02561 _dbus_return_val_if_fail (*bool_p == 0 || *bool_p == 1, FALSE);
02562 break;
02563
02564 default:
02565 {
02566
02567 }
02568 }
02569 #endif
02570
02571 if (!_dbus_message_iter_open_signature (real))
02572 return FALSE;
02573
02574 if (type == DBUS_TYPE_UNIX_FD)
02575 {
02576 #ifdef HAVE_UNIX_FD_PASSING
02577 int *fds;
02578 dbus_uint32_t u;
02579
02580
02581 if (!(fds = expand_fd_array(real->message, 1)))
02582 return FALSE;
02583
02584 *fds = _dbus_dup(*(int*) value, NULL);
02585 if (*fds < 0)
02586 return FALSE;
02587
02588 u = real->message->n_unix_fds;
02589
02590
02591 if (!(ret = _dbus_type_writer_write_basic (&real->u.writer, DBUS_TYPE_UNIX_FD, &u))) {
02592 _dbus_close(*fds, NULL);
02593 return FALSE;
02594 }
02595
02596 real->message->n_unix_fds += 1;
02597 u += 1;
02598
02599
02600 ret = _dbus_header_set_field_basic (&real->message->header,
02601 DBUS_HEADER_FIELD_UNIX_FDS,
02602 DBUS_TYPE_UINT32,
02603 &u);
02604
02605
02606
02607
02608
02609
02610 #else
02611 ret = FALSE;
02612 #endif
02613 }
02614 else
02615 {
02616 ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
02617 }
02618
02619 if (!_dbus_message_iter_close_signature (real))
02620 ret = FALSE;
02621
02622 return ret;
02623 }
02624
02664 dbus_bool_t
02665 dbus_message_iter_append_fixed_array (DBusMessageIter *iter,
02666 int element_type,
02667 const void *value,
02668 int n_elements)
02669 {
02670 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02671 dbus_bool_t ret;
02672
02673 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02674 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02675 _dbus_return_val_if_fail (dbus_type_is_fixed (element_type) && element_type != DBUS_TYPE_UNIX_FD, FALSE);
02676 _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
02677 _dbus_return_val_if_fail (value != NULL, FALSE);
02678 _dbus_return_val_if_fail (n_elements >= 0, FALSE);
02679 _dbus_return_val_if_fail (n_elements <=
02680 DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type),
02681 FALSE);
02682
02683 #ifndef DBUS_DISABLE_CHECKS
02684 if (element_type == DBUS_TYPE_BOOLEAN)
02685 {
02686 const dbus_bool_t * const *bools = value;
02687 int i;
02688
02689 for (i = 0; i < n_elements; i++)
02690 {
02691 _dbus_return_val_if_fail ((*bools)[i] == 0 || (*bools)[i] == 1, FALSE);
02692 }
02693 }
02694 #endif
02695
02696 ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
02697
02698 return ret;
02699 }
02700
02722 dbus_bool_t
02723 dbus_message_iter_open_container (DBusMessageIter *iter,
02724 int type,
02725 const char *contained_signature,
02726 DBusMessageIter *sub)
02727 {
02728 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02729 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02730 DBusString contained_str;
02731
02732 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02733 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02734 _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
02735 _dbus_return_val_if_fail (sub != NULL, FALSE);
02736 _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
02737 contained_signature == NULL) ||
02738 (type == DBUS_TYPE_DICT_ENTRY &&
02739 contained_signature == NULL) ||
02740 (type == DBUS_TYPE_VARIANT &&
02741 contained_signature != NULL) ||
02742 (type == DBUS_TYPE_ARRAY &&
02743 contained_signature != NULL), FALSE);
02744
02745
02746
02747
02748
02749 _dbus_return_val_if_fail ((type == DBUS_TYPE_ARRAY && contained_signature && *contained_signature == DBUS_DICT_ENTRY_BEGIN_CHAR) ||
02750 (contained_signature == NULL ||
02751 _dbus_check_is_valid_signature (contained_signature)),
02752 FALSE);
02753
02754 if (!_dbus_message_iter_open_signature (real))
02755 return FALSE;
02756
02757 *real_sub = *real;
02758
02759 if (contained_signature != NULL)
02760 {
02761 _dbus_string_init_const (&contained_str, contained_signature);
02762
02763 return _dbus_type_writer_recurse (&real->u.writer,
02764 type,
02765 &contained_str, 0,
02766 &real_sub->u.writer);
02767 }
02768 else
02769 {
02770 return _dbus_type_writer_recurse (&real->u.writer,
02771 type,
02772 NULL, 0,
02773 &real_sub->u.writer);
02774 }
02775 }
02776
02777
02791 dbus_bool_t
02792 dbus_message_iter_close_container (DBusMessageIter *iter,
02793 DBusMessageIter *sub)
02794 {
02795 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02796 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02797 dbus_bool_t ret;
02798
02799 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02800 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02801 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
02802 _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02803
02804 ret = _dbus_type_writer_unrecurse (&real->u.writer,
02805 &real_sub->u.writer);
02806
02807 if (!_dbus_message_iter_close_signature (real))
02808 ret = FALSE;
02809
02810 return ret;
02811 }
02812
02824 void
02825 dbus_message_iter_abandon_container (DBusMessageIter *iter,
02826 DBusMessageIter *sub)
02827 {
02828 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02829 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02830
02831 _dbus_return_if_fail (_dbus_message_iter_append_check (real));
02832 _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02833 _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
02834 _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02835
02836 _dbus_message_iter_abandon_signature (real);
02837 }
02838
02855 void
02856 dbus_message_set_no_reply (DBusMessage *message,
02857 dbus_bool_t no_reply)
02858 {
02859 _dbus_return_if_fail (message != NULL);
02860 _dbus_return_if_fail (!message->locked);
02861
02862 _dbus_header_toggle_flag (&message->header,
02863 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED,
02864 no_reply);
02865 }
02866
02874 dbus_bool_t
02875 dbus_message_get_no_reply (DBusMessage *message)
02876 {
02877 _dbus_return_val_if_fail (message != NULL, FALSE);
02878
02879 return _dbus_header_get_flag (&message->header,
02880 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED);
02881 }
02882
02897 void
02898 dbus_message_set_auto_start (DBusMessage *message,
02899 dbus_bool_t auto_start)
02900 {
02901 _dbus_return_if_fail (message != NULL);
02902 _dbus_return_if_fail (!message->locked);
02903
02904 _dbus_header_toggle_flag (&message->header,
02905 DBUS_HEADER_FLAG_NO_AUTO_START,
02906 !auto_start);
02907 }
02908
02916 dbus_bool_t
02917 dbus_message_get_auto_start (DBusMessage *message)
02918 {
02919 _dbus_return_val_if_fail (message != NULL, FALSE);
02920
02921 return !_dbus_header_get_flag (&message->header,
02922 DBUS_HEADER_FLAG_NO_AUTO_START);
02923 }
02924
02925
02938 dbus_bool_t
02939 dbus_message_set_path (DBusMessage *message,
02940 const char *object_path)
02941 {
02942 _dbus_return_val_if_fail (message != NULL, FALSE);
02943 _dbus_return_val_if_fail (!message->locked, FALSE);
02944 _dbus_return_val_if_fail (object_path == NULL ||
02945 _dbus_check_is_valid_path (object_path),
02946 FALSE);
02947
02948 return set_or_delete_string_field (message,
02949 DBUS_HEADER_FIELD_PATH,
02950 DBUS_TYPE_OBJECT_PATH,
02951 object_path);
02952 }
02953
02967 const char*
02968 dbus_message_get_path (DBusMessage *message)
02969 {
02970 const char *v;
02971
02972 _dbus_return_val_if_fail (message != NULL, NULL);
02973
02974 v = NULL;
02975 _dbus_header_get_field_basic (&message->header,
02976 DBUS_HEADER_FIELD_PATH,
02977 DBUS_TYPE_OBJECT_PATH,
02978 (void *) &v);
02979 return v;
02980 }
02981
02991 dbus_bool_t
02992 dbus_message_has_path (DBusMessage *message,
02993 const char *path)
02994 {
02995 const char *msg_path;
02996 msg_path = dbus_message_get_path (message);
02997
02998 if (msg_path == NULL)
02999 {
03000 if (path == NULL)
03001 return TRUE;
03002 else
03003 return FALSE;
03004 }
03005
03006 if (path == NULL)
03007 return FALSE;
03008
03009 if (strcmp (msg_path, path) == 0)
03010 return TRUE;
03011
03012 return FALSE;
03013 }
03014
03035 dbus_bool_t
03036 dbus_message_get_path_decomposed (DBusMessage *message,
03037 char ***path)
03038 {
03039 const char *v;
03040
03041 _dbus_return_val_if_fail (message != NULL, FALSE);
03042 _dbus_return_val_if_fail (path != NULL, FALSE);
03043
03044 *path = NULL;
03045
03046 v = dbus_message_get_path (message);
03047 if (v != NULL)
03048 {
03049 if (!_dbus_decompose_path (v, strlen (v),
03050 path, NULL))
03051 return FALSE;
03052 }
03053 return TRUE;
03054 }
03055
03069 dbus_bool_t
03070 dbus_message_set_interface (DBusMessage *message,
03071 const char *interface)
03072 {
03073 _dbus_return_val_if_fail (message != NULL, FALSE);
03074 _dbus_return_val_if_fail (!message->locked, FALSE);
03075 _dbus_return_val_if_fail (interface == NULL ||
03076 _dbus_check_is_valid_interface (interface),
03077 FALSE);
03078
03079 return set_or_delete_string_field (message,
03080 DBUS_HEADER_FIELD_INTERFACE,
03081 DBUS_TYPE_STRING,
03082 interface);
03083 }
03084
03098 const char*
03099 dbus_message_get_interface (DBusMessage *message)
03100 {
03101 const char *v;
03102
03103 _dbus_return_val_if_fail (message != NULL, NULL);
03104
03105 v = NULL;
03106 _dbus_header_get_field_basic (&message->header,
03107 DBUS_HEADER_FIELD_INTERFACE,
03108 DBUS_TYPE_STRING,
03109 (void *) &v);
03110 return v;
03111 }
03112
03120 dbus_bool_t
03121 dbus_message_has_interface (DBusMessage *message,
03122 const char *interface)
03123 {
03124 const char *msg_interface;
03125 msg_interface = dbus_message_get_interface (message);
03126
03127 if (msg_interface == NULL)
03128 {
03129 if (interface == NULL)
03130 return TRUE;
03131 else
03132 return FALSE;
03133 }
03134
03135 if (interface == NULL)
03136 return FALSE;
03137
03138 if (strcmp (msg_interface, interface) == 0)
03139 return TRUE;
03140
03141 return FALSE;
03142
03143 }
03144
03157 dbus_bool_t
03158 dbus_message_set_member (DBusMessage *message,
03159 const char *member)
03160 {
03161 _dbus_return_val_if_fail (message != NULL, FALSE);
03162 _dbus_return_val_if_fail (!message->locked, FALSE);
03163 _dbus_return_val_if_fail (member == NULL ||
03164 _dbus_check_is_valid_member (member),
03165 FALSE);
03166
03167 return set_or_delete_string_field (message,
03168 DBUS_HEADER_FIELD_MEMBER,
03169 DBUS_TYPE_STRING,
03170 member);
03171 }
03172
03184 const char*
03185 dbus_message_get_member (DBusMessage *message)
03186 {
03187 const char *v;
03188
03189 _dbus_return_val_if_fail (message != NULL, NULL);
03190
03191 v = NULL;
03192 _dbus_header_get_field_basic (&message->header,
03193 DBUS_HEADER_FIELD_MEMBER,
03194 DBUS_TYPE_STRING,
03195 (void *) &v);
03196 return v;
03197 }
03198
03206 dbus_bool_t
03207 dbus_message_has_member (DBusMessage *message,
03208 const char *member)
03209 {
03210 const char *msg_member;
03211 msg_member = dbus_message_get_member (message);
03212
03213 if (msg_member == NULL)
03214 {
03215 if (member == NULL)
03216 return TRUE;
03217 else
03218 return FALSE;
03219 }
03220
03221 if (member == NULL)
03222 return FALSE;
03223
03224 if (strcmp (msg_member, member) == 0)
03225 return TRUE;
03226
03227 return FALSE;
03228
03229 }
03230
03242 dbus_bool_t
03243 dbus_message_set_error_name (DBusMessage *message,
03244 const char *error_name)
03245 {
03246 _dbus_return_val_if_fail (message != NULL, FALSE);
03247 _dbus_return_val_if_fail (!message->locked, FALSE);
03248 _dbus_return_val_if_fail (error_name == NULL ||
03249 _dbus_check_is_valid_error_name (error_name),
03250 FALSE);
03251
03252 return set_or_delete_string_field (message,
03253 DBUS_HEADER_FIELD_ERROR_NAME,
03254 DBUS_TYPE_STRING,
03255 error_name);
03256 }
03257
03268 const char*
03269 dbus_message_get_error_name (DBusMessage *message)
03270 {
03271 const char *v;
03272
03273 _dbus_return_val_if_fail (message != NULL, NULL);
03274
03275 v = NULL;
03276 _dbus_header_get_field_basic (&message->header,
03277 DBUS_HEADER_FIELD_ERROR_NAME,
03278 DBUS_TYPE_STRING,
03279 (void *) &v);
03280 return v;
03281 }
03282
03296 dbus_bool_t
03297 dbus_message_set_destination (DBusMessage *message,
03298 const char *destination)
03299 {
03300 _dbus_return_val_if_fail (message != NULL, FALSE);
03301 _dbus_return_val_if_fail (!message->locked, FALSE);
03302 _dbus_return_val_if_fail (destination == NULL ||
03303 _dbus_check_is_valid_bus_name (destination),
03304 FALSE);
03305
03306 return set_or_delete_string_field (message,
03307 DBUS_HEADER_FIELD_DESTINATION,
03308 DBUS_TYPE_STRING,
03309 destination);
03310 }
03311
03321 const char*
03322 dbus_message_get_destination (DBusMessage *message)
03323 {
03324 const char *v;
03325
03326 _dbus_return_val_if_fail (message != NULL, NULL);
03327
03328 v = NULL;
03329 _dbus_header_get_field_basic (&message->header,
03330 DBUS_HEADER_FIELD_DESTINATION,
03331 DBUS_TYPE_STRING,
03332 (void *) &v);
03333 return v;
03334 }
03335
03350 dbus_bool_t
03351 dbus_message_set_sender (DBusMessage *message,
03352 const char *sender)
03353 {
03354 _dbus_return_val_if_fail (message != NULL, FALSE);
03355 _dbus_return_val_if_fail (!message->locked, FALSE);
03356 _dbus_return_val_if_fail (sender == NULL ||
03357 _dbus_check_is_valid_bus_name (sender),
03358 FALSE);
03359
03360 return set_or_delete_string_field (message,
03361 DBUS_HEADER_FIELD_SENDER,
03362 DBUS_TYPE_STRING,
03363 sender);
03364 }
03365
03381 const char*
03382 dbus_message_get_sender (DBusMessage *message)
03383 {
03384 const char *v;
03385
03386 _dbus_return_val_if_fail (message != NULL, NULL);
03387
03388 v = NULL;
03389 _dbus_header_get_field_basic (&message->header,
03390 DBUS_HEADER_FIELD_SENDER,
03391 DBUS_TYPE_STRING,
03392 (void *) &v);
03393 return v;
03394 }
03395
03414 const char*
03415 dbus_message_get_signature (DBusMessage *message)
03416 {
03417 const DBusString *type_str;
03418 int type_pos;
03419
03420 _dbus_return_val_if_fail (message != NULL, NULL);
03421
03422 get_const_signature (&message->header, &type_str, &type_pos);
03423
03424 return _dbus_string_get_const_data_len (type_str, type_pos, 0);
03425 }
03426
03427 static dbus_bool_t
03428 _dbus_message_has_type_interface_member (DBusMessage *message,
03429 int type,
03430 const char *interface,
03431 const char *member)
03432 {
03433 const char *n;
03434
03435 _dbus_assert (message != NULL);
03436 _dbus_assert (interface != NULL);
03437 _dbus_assert (member != NULL);
03438
03439 if (dbus_message_get_type (message) != type)
03440 return FALSE;
03441
03442
03443
03444
03445
03446 n = dbus_message_get_member (message);
03447
03448 if (n && strcmp (n, member) == 0)
03449 {
03450 n = dbus_message_get_interface (message);
03451
03452 if (n == NULL || strcmp (n, interface) == 0)
03453 return TRUE;
03454 }
03455
03456 return FALSE;
03457 }
03458
03473 dbus_bool_t
03474 dbus_message_is_method_call (DBusMessage *message,
03475 const char *interface,
03476 const char *method)
03477 {
03478 _dbus_return_val_if_fail (message != NULL, FALSE);
03479 _dbus_return_val_if_fail (interface != NULL, FALSE);
03480 _dbus_return_val_if_fail (method != NULL, FALSE);
03481
03482
03483
03484
03485 return _dbus_message_has_type_interface_member (message,
03486 DBUS_MESSAGE_TYPE_METHOD_CALL,
03487 interface, method);
03488 }
03489
03501 dbus_bool_t
03502 dbus_message_is_signal (DBusMessage *message,
03503 const char *interface,
03504 const char *signal_name)
03505 {
03506 _dbus_return_val_if_fail (message != NULL, FALSE);
03507 _dbus_return_val_if_fail (interface != NULL, FALSE);
03508 _dbus_return_val_if_fail (signal_name != NULL, FALSE);
03509
03510
03511
03512
03513 return _dbus_message_has_type_interface_member (message,
03514 DBUS_MESSAGE_TYPE_SIGNAL,
03515 interface, signal_name);
03516 }
03517
03528 dbus_bool_t
03529 dbus_message_is_error (DBusMessage *message,
03530 const char *error_name)
03531 {
03532 const char *n;
03533
03534 _dbus_return_val_if_fail (message != NULL, FALSE);
03535 _dbus_return_val_if_fail (error_name != NULL, FALSE);
03536
03537
03538
03539
03540 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
03541 return FALSE;
03542
03543 n = dbus_message_get_error_name (message);
03544
03545 if (n && strcmp (n, error_name) == 0)
03546 return TRUE;
03547 else
03548 return FALSE;
03549 }
03550
03561 dbus_bool_t
03562 dbus_message_has_destination (DBusMessage *message,
03563 const char *name)
03564 {
03565 const char *s;
03566
03567 _dbus_return_val_if_fail (message != NULL, FALSE);
03568 _dbus_return_val_if_fail (name != NULL, FALSE);
03569
03570
03571
03572
03573 s = dbus_message_get_destination (message);
03574
03575 if (s && strcmp (s, name) == 0)
03576 return TRUE;
03577 else
03578 return FALSE;
03579 }
03580
03596 dbus_bool_t
03597 dbus_message_has_sender (DBusMessage *message,
03598 const char *name)
03599 {
03600 const char *s;
03601
03602 _dbus_return_val_if_fail (message != NULL, FALSE);
03603 _dbus_return_val_if_fail (name != NULL, FALSE);
03604
03605
03606
03607
03608 s = dbus_message_get_sender (message);
03609
03610 if (s && strcmp (s, name) == 0)
03611 return TRUE;
03612 else
03613 return FALSE;
03614 }
03615
03625 dbus_bool_t
03626 dbus_message_has_signature (DBusMessage *message,
03627 const char *signature)
03628 {
03629 const char *s;
03630
03631 _dbus_return_val_if_fail (message != NULL, FALSE);
03632 _dbus_return_val_if_fail (signature != NULL, FALSE);
03633
03634
03635
03636
03637 s = dbus_message_get_signature (message);
03638
03639 if (s && strcmp (s, signature) == 0)
03640 return TRUE;
03641 else
03642 return FALSE;
03643 }
03644
03667 dbus_bool_t
03668 dbus_set_error_from_message (DBusError *error,
03669 DBusMessage *message)
03670 {
03671 const char *str;
03672
03673 _dbus_return_val_if_fail (message != NULL, FALSE);
03674 _dbus_return_val_if_error_is_set (error, FALSE);
03675
03676 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
03677 return FALSE;
03678
03679 str = NULL;
03680 dbus_message_get_args (message, NULL,
03681 DBUS_TYPE_STRING, &str,
03682 DBUS_TYPE_INVALID);
03683
03684 dbus_set_error (error, dbus_message_get_error_name (message),
03685 str ? "%s" : NULL, str);
03686
03687 return TRUE;
03688 }
03689
03696 dbus_bool_t
03697 dbus_message_contains_unix_fds(DBusMessage *message)
03698 {
03699 #ifdef HAVE_UNIX_FD_PASSING
03700 _dbus_assert(message);
03701
03702 return message->n_unix_fds > 0;
03703 #else
03704 return FALSE;
03705 #endif
03706 }
03707
03726 #define INITIAL_LOADER_DATA_LEN 32
03727
03734 DBusMessageLoader*
03735 _dbus_message_loader_new (void)
03736 {
03737 DBusMessageLoader *loader;
03738
03739 loader = dbus_new0 (DBusMessageLoader, 1);
03740 if (loader == NULL)
03741 return NULL;
03742
03743 loader->refcount = 1;
03744
03745 loader->corrupted = FALSE;
03746 loader->corruption_reason = DBUS_VALID;
03747
03748
03749 loader->max_message_size = DBUS_MAXIMUM_MESSAGE_LENGTH;
03750
03751
03752
03753
03754
03755 loader->max_message_unix_fds = 1024;
03756
03757 if (!_dbus_string_init (&loader->data))
03758 {
03759 dbus_free (loader);
03760 return NULL;
03761 }
03762
03763
03764 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
03765 _dbus_string_set_length (&loader->data, 0);
03766
03767 #ifdef HAVE_UNIX_FD_PASSING
03768 loader->unix_fds = NULL;
03769 loader->n_unix_fds = loader->n_unix_fds_allocated = 0;
03770 loader->unix_fds_outstanding = FALSE;
03771 #endif
03772
03773 return loader;
03774 }
03775
03782 DBusMessageLoader *
03783 _dbus_message_loader_ref (DBusMessageLoader *loader)
03784 {
03785 loader->refcount += 1;
03786
03787 return loader;
03788 }
03789
03796 void
03797 _dbus_message_loader_unref (DBusMessageLoader *loader)
03798 {
03799 loader->refcount -= 1;
03800 if (loader->refcount == 0)
03801 {
03802 #ifdef HAVE_UNIX_FD_PASSING
03803 close_unix_fds(loader->unix_fds, &loader->n_unix_fds);
03804 dbus_free(loader->unix_fds);
03805 #endif
03806 _dbus_list_foreach (&loader->messages,
03807 (DBusForeachFunction) dbus_message_unref,
03808 NULL);
03809 _dbus_list_clear (&loader->messages);
03810 _dbus_string_free (&loader->data);
03811 dbus_free (loader);
03812 }
03813 }
03814
03833 void
03834 _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
03835 DBusString **buffer)
03836 {
03837 _dbus_assert (!loader->buffer_outstanding);
03838
03839 *buffer = &loader->data;
03840
03841 loader->buffer_outstanding = TRUE;
03842 }
03843
03854 void
03855 _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
03856 DBusString *buffer,
03857 int bytes_read)
03858 {
03859 _dbus_assert (loader->buffer_outstanding);
03860 _dbus_assert (buffer == &loader->data);
03861
03862 loader->buffer_outstanding = FALSE;
03863 }
03864
03875 dbus_bool_t
03876 _dbus_message_loader_get_unix_fds(DBusMessageLoader *loader,
03877 int **fds,
03878 unsigned *max_n_fds)
03879 {
03880 #ifdef HAVE_UNIX_FD_PASSING
03881 _dbus_assert (!loader->unix_fds_outstanding);
03882
03883
03884
03885
03886
03887
03888
03889
03890
03891 if (loader->n_unix_fds_allocated < loader->max_message_unix_fds)
03892 {
03893 int *a = dbus_realloc(loader->unix_fds,
03894 loader->max_message_unix_fds * sizeof(loader->unix_fds[0]));
03895
03896 if (!a)
03897 return FALSE;
03898
03899 loader->unix_fds = a;
03900 loader->n_unix_fds_allocated = loader->max_message_unix_fds;
03901 }
03902
03903 *fds = loader->unix_fds + loader->n_unix_fds;
03904 *max_n_fds = loader->n_unix_fds_allocated - loader->n_unix_fds;
03905
03906 loader->unix_fds_outstanding = TRUE;
03907 return TRUE;
03908 #else
03909 _dbus_assert_not_reached("Platform doesn't support unix fd passing");
03910 return FALSE;
03911 #endif
03912 }
03913
03924 void
03925 _dbus_message_loader_return_unix_fds(DBusMessageLoader *loader,
03926 int *fds,
03927 unsigned n_fds)
03928 {
03929 #ifdef HAVE_UNIX_FD_PASSING
03930 _dbus_assert(loader->unix_fds_outstanding);
03931 _dbus_assert(loader->unix_fds + loader->n_unix_fds == fds);
03932 _dbus_assert(loader->n_unix_fds + n_fds <= loader->n_unix_fds_allocated);
03933
03934 loader->n_unix_fds += n_fds;
03935 loader->unix_fds_outstanding = FALSE;
03936 #else
03937 _dbus_assert_not_reached("Platform doesn't support unix fd passing");
03938 #endif
03939 }
03940
03941
03942
03943
03944
03945
03946
03947
03948
03949
03950
03951
03952
03953
03954
03955
03956
03957
03958
03959
03960
03961
03962
03963
03964
03965
03966
03967 static dbus_bool_t
03968 load_message (DBusMessageLoader *loader,
03969 DBusMessage *message,
03970 int byte_order,
03971 int fields_array_len,
03972 int header_len,
03973 int body_len)
03974 {
03975 dbus_bool_t oom;
03976 DBusValidity validity;
03977 const DBusString *type_str;
03978 int type_pos;
03979 DBusValidationMode mode;
03980 dbus_uint32_t n_unix_fds = 0;
03981
03982 mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
03983
03984 oom = FALSE;
03985
03986 #if 0
03987 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len );
03988 #endif
03989
03990
03991 _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
03992 _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
03993
03994 if (!_dbus_header_load (&message->header,
03995 mode,
03996 &validity,
03997 byte_order,
03998 fields_array_len,
03999 header_len,
04000 body_len,
04001 &loader->data, 0,
04002 _dbus_string_get_length (&loader->data)))
04003 {
04004 _dbus_verbose ("Failed to load header for new message code %d\n", validity);
04005
04006
04007
04008 _dbus_assert (validity != DBUS_VALID);
04009
04010 if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
04011 oom = TRUE;
04012 else
04013 {
04014 loader->corrupted = TRUE;
04015 loader->corruption_reason = validity;
04016 }
04017 goto failed;
04018 }
04019
04020 _dbus_assert (validity == DBUS_VALID);
04021
04022 message->byte_order = byte_order;
04023
04024
04025 if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
04026 {
04027 get_const_signature (&message->header, &type_str, &type_pos);
04028
04029
04030
04031
04032 validity = _dbus_validate_body_with_reason (type_str,
04033 type_pos,
04034 byte_order,
04035 NULL,
04036 &loader->data,
04037 header_len,
04038 body_len);
04039 if (validity != DBUS_VALID)
04040 {
04041 _dbus_verbose ("Failed to validate message body code %d\n", validity);
04042
04043 loader->corrupted = TRUE;
04044 loader->corruption_reason = validity;
04045
04046 goto failed;
04047 }
04048 }
04049
04050
04051 _dbus_header_get_field_basic(&message->header,
04052 DBUS_HEADER_FIELD_UNIX_FDS,
04053 DBUS_TYPE_UINT32,
04054 &n_unix_fds);
04055
04056 #ifdef HAVE_UNIX_FD_PASSING
04057
04058 if (n_unix_fds > loader->n_unix_fds)
04059 {
04060 _dbus_verbose("Message contains references to more unix fds than were sent %u != %u\n",
04061 n_unix_fds, loader->n_unix_fds);
04062
04063 loader->corrupted = TRUE;
04064 loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
04065 goto failed;
04066 }
04067
04068
04069
04070 dbus_free(message->unix_fds);
04071
04072 if (n_unix_fds > 0)
04073 {
04074 message->unix_fds = _dbus_memdup(loader->unix_fds, n_unix_fds * sizeof(message->unix_fds[0]));
04075 if (message->unix_fds == NULL)
04076 {
04077 _dbus_verbose ("Failed to allocate file descriptor array\n");
04078 oom = TRUE;
04079 goto failed;
04080 }
04081
04082 message->n_unix_fds_allocated = message->n_unix_fds = n_unix_fds;
04083 loader->n_unix_fds -= n_unix_fds;
04084 memmove(loader->unix_fds + n_unix_fds, loader->unix_fds, loader->n_unix_fds);
04085 }
04086 else
04087 message->unix_fds = NULL;
04088
04089 #else
04090
04091 if (n_unix_fds > 0)
04092 {
04093 _dbus_verbose ("Hmm, message claims to come with file descriptors "
04094 "but that's not supported on our platform, disconnecting.\n");
04095
04096 loader->corrupted = TRUE;
04097 loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
04098 goto failed;
04099 }
04100
04101 #endif
04102
04103
04104
04105 if (!_dbus_list_append (&loader->messages, message))
04106 {
04107 _dbus_verbose ("Failed to append new message to loader queue\n");
04108 oom = TRUE;
04109 goto failed;
04110 }
04111
04112 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
04113 _dbus_assert (_dbus_string_get_length (&loader->data) >=
04114 (header_len + body_len));
04115
04116 if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
04117 {
04118 _dbus_verbose ("Failed to move body into new message\n");
04119 oom = TRUE;
04120 goto failed;
04121 }
04122
04123 _dbus_string_delete (&loader->data, 0, header_len + body_len);
04124
04125
04126 _dbus_string_compact (&loader->data, 2048);
04127
04128 _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
04129 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
04130
04131 _dbus_verbose ("Loaded message %p\n", message);
04132
04133 _dbus_assert (!oom);
04134 _dbus_assert (!loader->corrupted);
04135 _dbus_assert (loader->messages != NULL);
04136 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
04137
04138 return TRUE;
04139
04140 failed:
04141
04142
04143
04144
04145 _dbus_list_remove_last (&loader->messages, message);
04146
04147 if (oom)
04148 _dbus_assert (!loader->corrupted);
04149 else
04150 _dbus_assert (loader->corrupted);
04151
04152 _dbus_verbose_bytes_of_string (&loader->data, 0, _dbus_string_get_length (&loader->data));
04153
04154 return FALSE;
04155 }
04156
04171 dbus_bool_t
04172 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
04173 {
04174 while (!loader->corrupted &&
04175 _dbus_string_get_length (&loader->data) >= DBUS_MINIMUM_HEADER_SIZE)
04176 {
04177 DBusValidity validity;
04178 int byte_order, fields_array_len, header_len, body_len;
04179
04180 if (_dbus_header_have_message_untrusted (loader->max_message_size,
04181 &validity,
04182 &byte_order,
04183 &fields_array_len,
04184 &header_len,
04185 &body_len,
04186 &loader->data, 0,
04187 _dbus_string_get_length (&loader->data)))
04188 {
04189 DBusMessage *message;
04190
04191 _dbus_assert (validity == DBUS_VALID);
04192
04193 message = dbus_message_new_empty_header ();
04194 if (message == NULL)
04195 return FALSE;
04196
04197 if (!load_message (loader, message,
04198 byte_order, fields_array_len,
04199 header_len, body_len))
04200 {
04201 dbus_message_unref (message);
04202
04203
04204
04205 return loader->corrupted;
04206 }
04207
04208 _dbus_assert (loader->messages != NULL);
04209 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
04210 }
04211 else
04212 {
04213 _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
04214 validity);
04215 if (validity != DBUS_VALID)
04216 {
04217 loader->corrupted = TRUE;
04218 loader->corruption_reason = validity;
04219 }
04220 return TRUE;
04221 }
04222 }
04223
04224 return TRUE;
04225 }
04226
04234 DBusMessage*
04235 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
04236 {
04237 if (loader->messages)
04238 return loader->messages->data;
04239 else
04240 return NULL;
04241 }
04242
04251 DBusMessage*
04252 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
04253 {
04254 return _dbus_list_pop_first (&loader->messages);
04255 }
04256
04265 DBusList*
04266 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
04267 {
04268 return _dbus_list_pop_first_link (&loader->messages);
04269 }
04270
04277 void
04278 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
04279 DBusList *link)
04280 {
04281 _dbus_list_prepend_link (&loader->messages, link);
04282 }
04283
04293 dbus_bool_t
04294 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
04295 {
04296 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
04297 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
04298 return loader->corrupted;
04299 }
04300
04307 DBusValidity
04308 _dbus_message_loader_get_corruption_reason (DBusMessageLoader *loader)
04309 {
04310 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
04311 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
04312
04313 return loader->corruption_reason;
04314 }
04315
04322 void
04323 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
04324 long size)
04325 {
04326 if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
04327 {
04328 _dbus_verbose ("clamping requested max message size %ld to %d\n",
04329 size, DBUS_MAXIMUM_MESSAGE_LENGTH);
04330 size = DBUS_MAXIMUM_MESSAGE_LENGTH;
04331 }
04332 loader->max_message_size = size;
04333 }
04334
04341 long
04342 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
04343 {
04344 return loader->max_message_size;
04345 }
04346
04353 void
04354 _dbus_message_loader_set_max_message_unix_fds (DBusMessageLoader *loader,
04355 long n)
04356 {
04357 if (n > DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
04358 {
04359 _dbus_verbose ("clamping requested max message unix_fds %ld to %d\n",
04360 n, DBUS_MAXIMUM_MESSAGE_UNIX_FDS);
04361 n = DBUS_MAXIMUM_MESSAGE_UNIX_FDS;
04362 }
04363 loader->max_message_unix_fds = n;
04364 }
04365
04372 long
04373 _dbus_message_loader_get_max_message_unix_fds (DBusMessageLoader *loader)
04374 {
04375 return loader->max_message_unix_fds;
04376 }
04377
04378 static DBusDataSlotAllocator slot_allocator;
04379 _DBUS_DEFINE_GLOBAL_LOCK (message_slots);
04380
04395 dbus_bool_t
04396 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
04397 {
04398 return _dbus_data_slot_allocator_alloc (&slot_allocator,
04399 &_DBUS_LOCK_NAME (message_slots),
04400 slot_p);
04401 }
04402
04414 void
04415 dbus_message_free_data_slot (dbus_int32_t *slot_p)
04416 {
04417 _dbus_return_if_fail (*slot_p >= 0);
04418
04419 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
04420 }
04421
04435 dbus_bool_t
04436 dbus_message_set_data (DBusMessage *message,
04437 dbus_int32_t slot,
04438 void *data,
04439 DBusFreeFunction free_data_func)
04440 {
04441 DBusFreeFunction old_free_func;
04442 void *old_data;
04443 dbus_bool_t retval;
04444
04445 _dbus_return_val_if_fail (message != NULL, FALSE);
04446 _dbus_return_val_if_fail (slot >= 0, FALSE);
04447
04448 retval = _dbus_data_slot_list_set (&slot_allocator,
04449 &message->slot_list,
04450 slot, data, free_data_func,
04451 &old_free_func, &old_data);
04452
04453 if (retval)
04454 {
04455
04456 if (old_free_func)
04457 (* old_free_func) (old_data);
04458 }
04459
04460 return retval;
04461 }
04462
04471 void*
04472 dbus_message_get_data (DBusMessage *message,
04473 dbus_int32_t slot)
04474 {
04475 void *res;
04476
04477 _dbus_return_val_if_fail (message != NULL, NULL);
04478
04479 res = _dbus_data_slot_list_get (&slot_allocator,
04480 &message->slot_list,
04481 slot);
04482
04483 return res;
04484 }
04485
04499 int
04500 dbus_message_type_from_string (const char *type_str)
04501 {
04502 if (strcmp (type_str, "method_call") == 0)
04503 return DBUS_MESSAGE_TYPE_METHOD_CALL;
04504 if (strcmp (type_str, "method_return") == 0)
04505 return DBUS_MESSAGE_TYPE_METHOD_RETURN;
04506 else if (strcmp (type_str, "signal") == 0)
04507 return DBUS_MESSAGE_TYPE_SIGNAL;
04508 else if (strcmp (type_str, "error") == 0)
04509 return DBUS_MESSAGE_TYPE_ERROR;
04510 else
04511 return DBUS_MESSAGE_TYPE_INVALID;
04512 }
04513
04527 const char *
04528 dbus_message_type_to_string (int type)
04529 {
04530 switch (type)
04531 {
04532 case DBUS_MESSAGE_TYPE_METHOD_CALL:
04533 return "method_call";
04534 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
04535 return "method_return";
04536 case DBUS_MESSAGE_TYPE_SIGNAL:
04537 return "signal";
04538 case DBUS_MESSAGE_TYPE_ERROR:
04539 return "error";
04540 default:
04541 return "invalid";
04542 }
04543 }
04544
04557 dbus_bool_t
04558 dbus_message_marshal (DBusMessage *msg,
04559 char **marshalled_data_p,
04560 int *len_p)
04561 {
04562 DBusString tmp;
04563 dbus_bool_t was_locked;
04564
04565 _dbus_return_val_if_fail (msg != NULL, FALSE);
04566 _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
04567 _dbus_return_val_if_fail (len_p != NULL, FALSE);
04568
04569 if (!_dbus_string_init (&tmp))
04570 return FALSE;
04571
04572
04573 was_locked = msg->locked;
04574
04575 if (!was_locked)
04576 dbus_message_lock (msg);
04577
04578 if (!_dbus_string_copy (&(msg->header.data), 0, &tmp, 0))
04579 goto fail;
04580
04581 *len_p = _dbus_string_get_length (&tmp);
04582
04583 if (!_dbus_string_copy (&(msg->body), 0, &tmp, *len_p))
04584 goto fail;
04585
04586 *len_p = _dbus_string_get_length (&tmp);
04587
04588 if (!_dbus_string_steal_data (&tmp, marshalled_data_p))
04589 goto fail;
04590
04591 _dbus_string_free (&tmp);
04592
04593 if (!was_locked)
04594 msg->locked = FALSE;
04595
04596 return TRUE;
04597
04598 fail:
04599 _dbus_string_free (&tmp);
04600
04601 if (!was_locked)
04602 msg->locked = FALSE;
04603
04604 return FALSE;
04605 }
04606
04619 DBusMessage *
04620 dbus_message_demarshal (const char *str,
04621 int len,
04622 DBusError *error)
04623 {
04624 DBusMessageLoader *loader;
04625 DBusString *buffer;
04626 DBusMessage *msg;
04627
04628 _dbus_return_val_if_fail (str != NULL, NULL);
04629
04630 loader = _dbus_message_loader_new ();
04631
04632 if (loader == NULL)
04633 return NULL;
04634
04635 _dbus_message_loader_get_buffer (loader, &buffer);
04636 _dbus_string_append_len (buffer, str, len);
04637 _dbus_message_loader_return_buffer (loader, buffer, len);
04638
04639 if (!_dbus_message_loader_queue_messages (loader))
04640 goto fail_oom;
04641
04642 if (_dbus_message_loader_get_is_corrupted (loader))
04643 goto fail_corrupt;
04644
04645 msg = _dbus_message_loader_pop_message (loader);
04646
04647 if (!msg)
04648 goto fail_oom;
04649
04650 _dbus_message_loader_unref (loader);
04651 return msg;
04652
04653 fail_corrupt:
04654 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted (%s)",
04655 _dbus_validity_to_error_message (loader->corruption_reason));
04656 _dbus_message_loader_unref (loader);
04657 return NULL;
04658
04659 fail_oom:
04660 _DBUS_SET_OOM (error);
04661 _dbus_message_loader_unref (loader);
04662 return NULL;
04663 }
04664
04678 int
04679 dbus_message_demarshal_bytes_needed(const char *buf,
04680 int len)
04681 {
04682 DBusString str;
04683 int byte_order, fields_array_len, header_len, body_len;
04684 DBusValidity validity = DBUS_VALID;
04685 int have_message;
04686
04687 if (!buf || len < DBUS_MINIMUM_HEADER_SIZE)
04688 return 0;
04689
04690 if (len > DBUS_MAXIMUM_MESSAGE_LENGTH)
04691 len = DBUS_MAXIMUM_MESSAGE_LENGTH;
04692 _dbus_string_init_const_len (&str, buf, len);
04693
04694 validity = DBUS_VALID;
04695 have_message
04696 = _dbus_header_have_message_untrusted(DBUS_MAXIMUM_MESSAGE_LENGTH,
04697 &validity, &byte_order,
04698 &fields_array_len,
04699 &header_len,
04700 &body_len,
04701 &str, 0,
04702 len);
04703 _dbus_string_free (&str);
04704
04705 if (validity == DBUS_VALID)
04706 {
04707 _dbus_assert (have_message || (header_len + body_len) > len);
04708 return header_len + body_len;
04709 }
04710 else
04711 {
04712 return -1;
04713 }
04714 }
04715
04718