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 (message->refcount.value == 0);
00530 _dbus_assert (message->counters == NULL);
00531
00532 _DBUS_UNLOCK (message_cache);
00533
00534 return message;
00535 }
00536
00537 #ifdef HAVE_UNIX_FD_PASSING
00538 static void
00539 close_unix_fds(int *fds, unsigned *n_fds)
00540 {
00541 DBusError e;
00542 int i;
00543
00544 if (*n_fds <= 0)
00545 return;
00546
00547 dbus_error_init(&e);
00548
00549 for (i = 0; i < *n_fds; i++)
00550 {
00551 if (!_dbus_close(fds[i], &e))
00552 {
00553 _dbus_warn("Failed to close file descriptor: %s\n", e.message);
00554 dbus_error_free(&e);
00555 }
00556 }
00557
00558 *n_fds = 0;
00559
00560
00561 }
00562 #endif
00563
00564 static void
00565 free_counter (void *element,
00566 void *data)
00567 {
00568 DBusCounter *counter = element;
00569 DBusMessage *message = data;
00570
00571 _dbus_counter_adjust_size (counter, - message->size_counter_delta);
00572 #ifdef HAVE_UNIX_FD_PASSING
00573 _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
00574 #endif
00575
00576 _dbus_counter_unref (counter);
00577 }
00578
00584 static void
00585 dbus_message_cache_or_finalize (DBusMessage *message)
00586 {
00587 dbus_bool_t was_cached;
00588 int i;
00589
00590 _dbus_assert (message->refcount.value == 0);
00591
00592
00593
00594
00595 _dbus_data_slot_list_clear (&message->slot_list);
00596
00597 _dbus_list_foreach (&message->counters,
00598 free_counter, message);
00599 _dbus_list_clear (&message->counters);
00600
00601 #ifdef HAVE_UNIX_FD_PASSING
00602 close_unix_fds(message->unix_fds, &message->n_unix_fds);
00603 #endif
00604
00605 was_cached = FALSE;
00606
00607 _DBUS_LOCK (message_cache);
00608
00609 if (!message_cache_shutdown_registered)
00610 {
00611 _dbus_assert (message_cache_count == 0);
00612
00613 if (!_dbus_register_shutdown_func (dbus_message_cache_shutdown, NULL))
00614 goto out;
00615
00616 i = 0;
00617 while (i < MAX_MESSAGE_CACHE_SIZE)
00618 {
00619 message_cache[i] = NULL;
00620 ++i;
00621 }
00622
00623 message_cache_shutdown_registered = TRUE;
00624 }
00625
00626 _dbus_assert (message_cache_count >= 0);
00627
00628 if ((_dbus_string_get_length (&message->header.data) +
00629 _dbus_string_get_length (&message->body)) >
00630 MAX_MESSAGE_SIZE_TO_CACHE)
00631 goto out;
00632
00633 if (message_cache_count >= MAX_MESSAGE_CACHE_SIZE)
00634 goto out;
00635
00636
00637 i = 0;
00638 while (message_cache[i] != NULL)
00639 ++i;
00640
00641 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
00642
00643 _dbus_assert (message_cache[i] == NULL);
00644 message_cache[i] = message;
00645 message_cache_count += 1;
00646 was_cached = TRUE;
00647 #ifndef DBUS_DISABLE_CHECKS
00648 message->in_cache = TRUE;
00649 #endif
00650
00651 out:
00652 _dbus_assert (message->refcount.value == 0);
00653
00654 _DBUS_UNLOCK (message_cache);
00655
00656 if (!was_cached)
00657 dbus_message_finalize (message);
00658 }
00659
00660 #ifndef DBUS_DISABLE_CHECKS
00661 static dbus_bool_t
00662 _dbus_message_iter_check (DBusMessageRealIter *iter)
00663 {
00664 if (iter == NULL)
00665 {
00666 _dbus_warn_check_failed ("dbus message iterator is NULL\n");
00667 return FALSE;
00668 }
00669
00670 if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_READER)
00671 {
00672 if (iter->u.reader.byte_order != iter->message->byte_order)
00673 {
00674 _dbus_warn_check_failed ("dbus message changed byte order since iterator was created\n");
00675 return FALSE;
00676 }
00677
00678 _dbus_assert (iter->u.reader.byte_order == DBUS_COMPILER_BYTE_ORDER);
00679 }
00680 else if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER)
00681 {
00682 if (iter->u.writer.byte_order != iter->message->byte_order)
00683 {
00684 _dbus_warn_check_failed ("dbus message changed byte order since append iterator was created\n");
00685 return FALSE;
00686 }
00687
00688 _dbus_assert (iter->u.writer.byte_order == DBUS_COMPILER_BYTE_ORDER);
00689 }
00690 else
00691 {
00692 _dbus_warn_check_failed ("dbus message iterator looks uninitialized or corrupted\n");
00693 return FALSE;
00694 }
00695
00696 if (iter->changed_stamp != iter->message->changed_stamp)
00697 {
00698 _dbus_warn_check_failed ("dbus message iterator invalid because the message has been modified (or perhaps the iterator is just uninitialized)\n");
00699 return FALSE;
00700 }
00701
00702 return TRUE;
00703 }
00704 #endif
00705
00720 dbus_bool_t
00721 _dbus_message_iter_get_args_valist (DBusMessageIter *iter,
00722 DBusError *error,
00723 int first_arg_type,
00724 va_list var_args)
00725 {
00726 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
00727 int spec_type, msg_type, i;
00728 dbus_bool_t retval;
00729
00730 _dbus_assert (_dbus_message_iter_check (real));
00731
00732 retval = FALSE;
00733
00734 spec_type = first_arg_type;
00735 i = 0;
00736
00737 while (spec_type != DBUS_TYPE_INVALID)
00738 {
00739 msg_type = dbus_message_iter_get_arg_type (iter);
00740
00741 if (msg_type != spec_type)
00742 {
00743 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
00744 "Argument %d is specified to be of type \"%s\", but "
00745 "is actually of type \"%s\"\n", i,
00746 _dbus_type_to_string (spec_type),
00747 _dbus_type_to_string (msg_type));
00748
00749 goto out;
00750 }
00751
00752 if (spec_type == DBUS_TYPE_UNIX_FD)
00753 {
00754 #ifdef HAVE_UNIX_FD_PASSING
00755 DBusBasicValue idx;
00756 int *pfd, nfd;
00757
00758 pfd = va_arg (var_args, int*);
00759 _dbus_assert(pfd);
00760
00761 _dbus_type_reader_read_basic(&real->u.reader, &idx);
00762
00763 if (idx.u32 >= real->message->n_unix_fds)
00764 {
00765 dbus_set_error (error, DBUS_ERROR_INCONSISTENT_MESSAGE,
00766 "Message refers to file descriptor at index %i,"
00767 "but has only %i descriptors attached.\n",
00768 idx.u32,
00769 real->message->n_unix_fds);
00770 goto out;
00771 }
00772
00773 if ((nfd = _dbus_dup(real->message->unix_fds[idx.u32], error)) < 0)
00774 goto out;
00775
00776 *pfd = nfd;
00777 #else
00778 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00779 "Platform does not support file desciptor passing.\n");
00780 goto out;
00781 #endif
00782 }
00783 else if (dbus_type_is_basic (spec_type))
00784 {
00785 DBusBasicValue *ptr;
00786
00787 ptr = va_arg (var_args, DBusBasicValue*);
00788
00789 _dbus_assert (ptr != NULL);
00790
00791 _dbus_type_reader_read_basic (&real->u.reader,
00792 ptr);
00793 }
00794 else if (spec_type == DBUS_TYPE_ARRAY)
00795 {
00796 int element_type;
00797 int spec_element_type;
00798 const DBusBasicValue **ptr;
00799 int *n_elements_p;
00800 DBusTypeReader array;
00801
00802 spec_element_type = va_arg (var_args, int);
00803 element_type = _dbus_type_reader_get_element_type (&real->u.reader);
00804
00805 if (spec_element_type != element_type)
00806 {
00807 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
00808 "Argument %d is specified to be an array of \"%s\", but "
00809 "is actually an array of \"%s\"\n",
00810 i,
00811 _dbus_type_to_string (spec_element_type),
00812 _dbus_type_to_string (element_type));
00813
00814 goto out;
00815 }
00816
00817 if (dbus_type_is_fixed (spec_element_type) &&
00818 element_type != DBUS_TYPE_UNIX_FD)
00819 {
00820 ptr = va_arg (var_args, const DBusBasicValue**);
00821 n_elements_p = va_arg (var_args, int*);
00822
00823 _dbus_assert (ptr != NULL);
00824 _dbus_assert (n_elements_p != NULL);
00825
00826 _dbus_type_reader_recurse (&real->u.reader, &array);
00827
00828 _dbus_type_reader_read_fixed_multi (&array,
00829 (void *) ptr, n_elements_p);
00830 }
00831 else if (spec_element_type == DBUS_TYPE_STRING ||
00832 spec_element_type == DBUS_TYPE_SIGNATURE ||
00833 spec_element_type == DBUS_TYPE_OBJECT_PATH)
00834 {
00835 char ***str_array_p;
00836 int n_elements;
00837 char **str_array;
00838
00839 str_array_p = va_arg (var_args, char***);
00840 n_elements_p = va_arg (var_args, int*);
00841
00842 _dbus_assert (str_array_p != NULL);
00843 _dbus_assert (n_elements_p != NULL);
00844
00845
00846 _dbus_type_reader_recurse (&real->u.reader, &array);
00847
00848 n_elements = 0;
00849 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
00850 {
00851 ++n_elements;
00852 _dbus_type_reader_next (&array);
00853 }
00854
00855 str_array = dbus_new0 (char*, n_elements + 1);
00856 if (str_array == NULL)
00857 {
00858 _DBUS_SET_OOM (error);
00859 goto out;
00860 }
00861
00862
00863 _dbus_type_reader_recurse (&real->u.reader, &array);
00864
00865 i = 0;
00866 while (i < n_elements)
00867 {
00868 const char *s;
00869 _dbus_type_reader_read_basic (&array,
00870 (void *) &s);
00871
00872 str_array[i] = _dbus_strdup (s);
00873 if (str_array[i] == NULL)
00874 {
00875 dbus_free_string_array (str_array);
00876 _DBUS_SET_OOM (error);
00877 goto out;
00878 }
00879
00880 ++i;
00881
00882 if (!_dbus_type_reader_next (&array))
00883 _dbus_assert (i == n_elements);
00884 }
00885
00886 _dbus_assert (_dbus_type_reader_get_current_type (&array) == DBUS_TYPE_INVALID);
00887 _dbus_assert (i == n_elements);
00888 _dbus_assert (str_array[i] == NULL);
00889
00890 *str_array_p = str_array;
00891 *n_elements_p = n_elements;
00892 }
00893 #ifndef DBUS_DISABLE_CHECKS
00894 else
00895 {
00896 _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now\n",
00897 _DBUS_FUNCTION_NAME);
00898 goto out;
00899 }
00900 #endif
00901 }
00902 #ifndef DBUS_DISABLE_CHECKS
00903 else
00904 {
00905 _dbus_warn ("you can only read arrays and basic types with %s for now\n",
00906 _DBUS_FUNCTION_NAME);
00907 goto out;
00908 }
00909 #endif
00910
00911 spec_type = va_arg (var_args, int);
00912 if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID)
00913 {
00914 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
00915 "Message has only %d arguments, but more were expected", i);
00916 goto out;
00917 }
00918
00919 i++;
00920 }
00921
00922 retval = TRUE;
00923
00924 out:
00925
00926 return retval;
00927 }
00928
00987 dbus_uint32_t
00988 dbus_message_get_serial (DBusMessage *message)
00989 {
00990 _dbus_return_val_if_fail (message != NULL, 0);
00991
00992 return _dbus_header_get_serial (&message->header);
00993 }
00994
01003 dbus_bool_t
01004 dbus_message_set_reply_serial (DBusMessage *message,
01005 dbus_uint32_t reply_serial)
01006 {
01007 _dbus_return_val_if_fail (message != NULL, FALSE);
01008 _dbus_return_val_if_fail (!message->locked, FALSE);
01009 _dbus_return_val_if_fail (reply_serial != 0, FALSE);
01010
01011 return _dbus_header_set_field_basic (&message->header,
01012 DBUS_HEADER_FIELD_REPLY_SERIAL,
01013 DBUS_TYPE_UINT32,
01014 &reply_serial);
01015 }
01016
01023 dbus_uint32_t
01024 dbus_message_get_reply_serial (DBusMessage *message)
01025 {
01026 dbus_uint32_t v_UINT32;
01027
01028 _dbus_return_val_if_fail (message != NULL, 0);
01029
01030 if (_dbus_header_get_field_basic (&message->header,
01031 DBUS_HEADER_FIELD_REPLY_SERIAL,
01032 DBUS_TYPE_UINT32,
01033 &v_UINT32))
01034 return v_UINT32;
01035 else
01036 return 0;
01037 }
01038
01039 static void
01040 dbus_message_finalize (DBusMessage *message)
01041 {
01042 _dbus_assert (message->refcount.value == 0);
01043
01044
01045 _dbus_data_slot_list_free (&message->slot_list);
01046
01047 _dbus_list_foreach (&message->counters,
01048 free_counter, message);
01049 _dbus_list_clear (&message->counters);
01050
01051 _dbus_header_free (&message->header);
01052 _dbus_string_free (&message->body);
01053
01054 #ifdef HAVE_UNIX_FD_PASSING
01055 close_unix_fds(message->unix_fds, &message->n_unix_fds);
01056 dbus_free(message->unix_fds);
01057 #endif
01058
01059 _dbus_assert (message->refcount.value == 0);
01060
01061 dbus_free (message);
01062 }
01063
01064 static DBusMessage*
01065 dbus_message_new_empty_header (void)
01066 {
01067 DBusMessage *message;
01068 dbus_bool_t from_cache;
01069
01070 message = dbus_message_get_cached ();
01071
01072 if (message != NULL)
01073 {
01074 from_cache = TRUE;
01075 }
01076 else
01077 {
01078 from_cache = FALSE;
01079 message = dbus_new (DBusMessage, 1);
01080 if (message == NULL)
01081 return NULL;
01082 #ifndef DBUS_DISABLE_CHECKS
01083 message->generation = _dbus_current_generation;
01084 #endif
01085
01086 #ifdef HAVE_UNIX_FD_PASSING
01087 message->unix_fds = NULL;
01088 message->n_unix_fds_allocated = 0;
01089 #endif
01090 }
01091
01092 message->refcount.value = 1;
01093 message->byte_order = DBUS_COMPILER_BYTE_ORDER;
01094 message->locked = FALSE;
01095 #ifndef DBUS_DISABLE_CHECKS
01096 message->in_cache = FALSE;
01097 #endif
01098 message->counters = NULL;
01099 message->size_counter_delta = 0;
01100 message->changed_stamp = 0;
01101
01102 #ifdef HAVE_UNIX_FD_PASSING
01103 message->n_unix_fds = 0;
01104 message->n_unix_fds_allocated = 0;
01105 message->unix_fd_counter_delta = 0;
01106 #endif
01107
01108 if (!from_cache)
01109 _dbus_data_slot_list_init (&message->slot_list);
01110
01111 if (from_cache)
01112 {
01113 _dbus_header_reinit (&message->header, message->byte_order);
01114 _dbus_string_set_length (&message->body, 0);
01115 }
01116 else
01117 {
01118 if (!_dbus_header_init (&message->header, message->byte_order))
01119 {
01120 dbus_free (message);
01121 return NULL;
01122 }
01123
01124 if (!_dbus_string_init_preallocated (&message->body, 32))
01125 {
01126 _dbus_header_free (&message->header);
01127 dbus_free (message);
01128 return NULL;
01129 }
01130 }
01131
01132 return message;
01133 }
01134
01147 DBusMessage*
01148 dbus_message_new (int message_type)
01149 {
01150 DBusMessage *message;
01151
01152 _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
01153
01154 message = dbus_message_new_empty_header ();
01155 if (message == NULL)
01156 return NULL;
01157
01158 if (!_dbus_header_create (&message->header,
01159 message_type,
01160 NULL, NULL, NULL, NULL, NULL))
01161 {
01162 dbus_message_unref (message);
01163 return NULL;
01164 }
01165
01166 return message;
01167 }
01168
01190 DBusMessage*
01191 dbus_message_new_method_call (const char *destination,
01192 const char *path,
01193 const char *interface,
01194 const char *method)
01195 {
01196 DBusMessage *message;
01197
01198 _dbus_return_val_if_fail (path != NULL, NULL);
01199 _dbus_return_val_if_fail (method != NULL, NULL);
01200 _dbus_return_val_if_fail (destination == NULL ||
01201 _dbus_check_is_valid_bus_name (destination), NULL);
01202 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
01203 _dbus_return_val_if_fail (interface == NULL ||
01204 _dbus_check_is_valid_interface (interface), NULL);
01205 _dbus_return_val_if_fail (_dbus_check_is_valid_member (method), NULL);
01206
01207 message = dbus_message_new_empty_header ();
01208 if (message == NULL)
01209 return NULL;
01210
01211 if (!_dbus_header_create (&message->header,
01212 DBUS_MESSAGE_TYPE_METHOD_CALL,
01213 destination, path, interface, method, NULL))
01214 {
01215 dbus_message_unref (message);
01216 return NULL;
01217 }
01218
01219 return message;
01220 }
01221
01229 DBusMessage*
01230 dbus_message_new_method_return (DBusMessage *method_call)
01231 {
01232 DBusMessage *message;
01233 const char *sender;
01234
01235 _dbus_return_val_if_fail (method_call != NULL, NULL);
01236
01237 sender = dbus_message_get_sender (method_call);
01238
01239
01240
01241 message = dbus_message_new_empty_header ();
01242 if (message == NULL)
01243 return NULL;
01244
01245 if (!_dbus_header_create (&message->header,
01246 DBUS_MESSAGE_TYPE_METHOD_RETURN,
01247 sender, NULL, NULL, NULL, NULL))
01248 {
01249 dbus_message_unref (message);
01250 return NULL;
01251 }
01252
01253 dbus_message_set_no_reply (message, TRUE);
01254
01255 if (!dbus_message_set_reply_serial (message,
01256 dbus_message_get_serial (method_call)))
01257 {
01258 dbus_message_unref (message);
01259 return NULL;
01260 }
01261
01262 return message;
01263 }
01264
01279 DBusMessage*
01280 dbus_message_new_signal (const char *path,
01281 const char *interface,
01282 const char *name)
01283 {
01284 DBusMessage *message;
01285
01286 _dbus_return_val_if_fail (path != NULL, NULL);
01287 _dbus_return_val_if_fail (interface != NULL, NULL);
01288 _dbus_return_val_if_fail (name != NULL, NULL);
01289 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
01290 _dbus_return_val_if_fail (_dbus_check_is_valid_interface (interface), NULL);
01291 _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);
01292
01293 message = dbus_message_new_empty_header ();
01294 if (message == NULL)
01295 return NULL;
01296
01297 if (!_dbus_header_create (&message->header,
01298 DBUS_MESSAGE_TYPE_SIGNAL,
01299 NULL, path, interface, name, NULL))
01300 {
01301 dbus_message_unref (message);
01302 return NULL;
01303 }
01304
01305 dbus_message_set_no_reply (message, TRUE);
01306
01307 return message;
01308 }
01309
01324 DBusMessage*
01325 dbus_message_new_error (DBusMessage *reply_to,
01326 const char *error_name,
01327 const char *error_message)
01328 {
01329 DBusMessage *message;
01330 const char *sender;
01331 DBusMessageIter iter;
01332
01333 _dbus_return_val_if_fail (reply_to != NULL, NULL);
01334 _dbus_return_val_if_fail (error_name != NULL, NULL);
01335 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
01336
01337 sender = dbus_message_get_sender (reply_to);
01338
01339
01340
01341
01342
01343 message = dbus_message_new_empty_header ();
01344 if (message == NULL)
01345 return NULL;
01346
01347 if (!_dbus_header_create (&message->header,
01348 DBUS_MESSAGE_TYPE_ERROR,
01349 sender, NULL, NULL, NULL, error_name))
01350 {
01351 dbus_message_unref (message);
01352 return NULL;
01353 }
01354
01355 dbus_message_set_no_reply (message, TRUE);
01356
01357 if (!dbus_message_set_reply_serial (message,
01358 dbus_message_get_serial (reply_to)))
01359 {
01360 dbus_message_unref (message);
01361 return NULL;
01362 }
01363
01364 if (error_message != NULL)
01365 {
01366 dbus_message_iter_init_append (message, &iter);
01367 if (!dbus_message_iter_append_basic (&iter,
01368 DBUS_TYPE_STRING,
01369 &error_message))
01370 {
01371 dbus_message_unref (message);
01372 return NULL;
01373 }
01374 }
01375
01376 return message;
01377 }
01378
01395 DBusMessage*
01396 dbus_message_new_error_printf (DBusMessage *reply_to,
01397 const char *error_name,
01398 const char *error_format,
01399 ...)
01400 {
01401 va_list args;
01402 DBusString str;
01403 DBusMessage *message;
01404
01405 _dbus_return_val_if_fail (reply_to != NULL, NULL);
01406 _dbus_return_val_if_fail (error_name != NULL, NULL);
01407 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
01408
01409 if (!_dbus_string_init (&str))
01410 return NULL;
01411
01412 va_start (args, error_format);
01413
01414 if (_dbus_string_append_printf_valist (&str, error_format, args))
01415 message = dbus_message_new_error (reply_to, error_name,
01416 _dbus_string_get_const_data (&str));
01417 else
01418 message = NULL;
01419
01420 _dbus_string_free (&str);
01421
01422 va_end (args);
01423
01424 return message;
01425 }
01426
01427
01440 DBusMessage *
01441 dbus_message_copy (const DBusMessage *message)
01442 {
01443 DBusMessage *retval;
01444
01445 _dbus_return_val_if_fail (message != NULL, NULL);
01446
01447 retval = dbus_new0 (DBusMessage, 1);
01448 if (retval == NULL)
01449 return NULL;
01450
01451 retval->refcount.value = 1;
01452 retval->byte_order = message->byte_order;
01453 retval->locked = FALSE;
01454 #ifndef DBUS_DISABLE_CHECKS
01455 retval->generation = message->generation;
01456 #endif
01457
01458 if (!_dbus_header_copy (&message->header, &retval->header))
01459 {
01460 dbus_free (retval);
01461 return NULL;
01462 }
01463
01464 if (!_dbus_string_init_preallocated (&retval->body,
01465 _dbus_string_get_length (&message->body)))
01466 {
01467 _dbus_header_free (&retval->header);
01468 dbus_free (retval);
01469 return NULL;
01470 }
01471
01472 if (!_dbus_string_copy (&message->body, 0,
01473 &retval->body, 0))
01474 goto failed_copy;
01475
01476 #ifdef HAVE_UNIX_FD_PASSING
01477 retval->unix_fds = dbus_new(int, message->n_unix_fds);
01478 if (retval->unix_fds == NULL && message->n_unix_fds > 0)
01479 goto failed_copy;
01480
01481 retval->n_unix_fds_allocated = message->n_unix_fds;
01482
01483 for (retval->n_unix_fds = 0;
01484 retval->n_unix_fds < message->n_unix_fds;
01485 retval->n_unix_fds++)
01486 {
01487 retval->unix_fds[retval->n_unix_fds] = _dbus_dup(message->unix_fds[retval->n_unix_fds], NULL);
01488
01489 if (retval->unix_fds[retval->n_unix_fds] < 0)
01490 goto failed_copy;
01491 }
01492
01493 #endif
01494
01495 return retval;
01496
01497 failed_copy:
01498 _dbus_header_free (&retval->header);
01499 _dbus_string_free (&retval->body);
01500
01501 #ifdef HAVE_UNIX_FD_PASSING
01502 close_unix_fds(retval->unix_fds, &retval->n_unix_fds);
01503 dbus_free(retval->unix_fds);
01504 #endif
01505
01506 dbus_free (retval);
01507
01508 return NULL;
01509 }
01510
01511
01519 DBusMessage *
01520 dbus_message_ref (DBusMessage *message)
01521 {
01522 dbus_int32_t old_refcount;
01523
01524 _dbus_return_val_if_fail (message != NULL, NULL);
01525 _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
01526 _dbus_return_val_if_fail (!message->in_cache, NULL);
01527
01528 old_refcount = _dbus_atomic_inc (&message->refcount);
01529 _dbus_assert (old_refcount >= 1);
01530
01531 return message;
01532 }
01533
01541 void
01542 dbus_message_unref (DBusMessage *message)
01543 {
01544 dbus_int32_t old_refcount;
01545
01546 _dbus_return_if_fail (message != NULL);
01547 _dbus_return_if_fail (message->generation == _dbus_current_generation);
01548 _dbus_return_if_fail (!message->in_cache);
01549
01550 old_refcount = _dbus_atomic_dec (&message->refcount);
01551
01552 _dbus_assert (old_refcount >= 0);
01553
01554 if (old_refcount == 1)
01555 {
01556
01557 dbus_message_cache_or_finalize (message);
01558 }
01559 }
01560
01571 int
01572 dbus_message_get_type (DBusMessage *message)
01573 {
01574 _dbus_return_val_if_fail (message != NULL, DBUS_MESSAGE_TYPE_INVALID);
01575
01576 return _dbus_header_get_message_type (&message->header);
01577 }
01578
01641 dbus_bool_t
01642 dbus_message_append_args (DBusMessage *message,
01643 int first_arg_type,
01644 ...)
01645 {
01646 dbus_bool_t retval;
01647 va_list var_args;
01648
01649 _dbus_return_val_if_fail (message != NULL, FALSE);
01650
01651 va_start (var_args, first_arg_type);
01652 retval = dbus_message_append_args_valist (message,
01653 first_arg_type,
01654 var_args);
01655 va_end (var_args);
01656
01657 return retval;
01658 }
01659
01673 dbus_bool_t
01674 dbus_message_append_args_valist (DBusMessage *message,
01675 int first_arg_type,
01676 va_list var_args)
01677 {
01678 int type;
01679 DBusMessageIter iter;
01680
01681 _dbus_return_val_if_fail (message != NULL, FALSE);
01682
01683 type = first_arg_type;
01684
01685 dbus_message_iter_init_append (message, &iter);
01686
01687 while (type != DBUS_TYPE_INVALID)
01688 {
01689 if (dbus_type_is_basic (type))
01690 {
01691 const DBusBasicValue *value;
01692 value = va_arg (var_args, const DBusBasicValue*);
01693
01694 if (!dbus_message_iter_append_basic (&iter,
01695 type,
01696 value))
01697 goto failed;
01698 }
01699 else if (type == DBUS_TYPE_ARRAY)
01700 {
01701 int element_type;
01702 DBusMessageIter array;
01703 char buf[2];
01704
01705 element_type = va_arg (var_args, int);
01706
01707 buf[0] = element_type;
01708 buf[1] = '\0';
01709 if (!dbus_message_iter_open_container (&iter,
01710 DBUS_TYPE_ARRAY,
01711 buf,
01712 &array))
01713 goto failed;
01714
01715 if (dbus_type_is_fixed (element_type) &&
01716 element_type != DBUS_TYPE_UNIX_FD)
01717 {
01718 const DBusBasicValue **value;
01719 int n_elements;
01720
01721 value = va_arg (var_args, const DBusBasicValue**);
01722 n_elements = va_arg (var_args, int);
01723
01724 if (!dbus_message_iter_append_fixed_array (&array,
01725 element_type,
01726 value,
01727 n_elements)) {
01728 dbus_message_iter_abandon_container (&iter, &array);
01729 goto failed;
01730 }
01731 }
01732 else if (element_type == DBUS_TYPE_STRING ||
01733 element_type == DBUS_TYPE_SIGNATURE ||
01734 element_type == DBUS_TYPE_OBJECT_PATH)
01735 {
01736 const char ***value_p;
01737 const char **value;
01738 int n_elements;
01739 int i;
01740
01741 value_p = va_arg (var_args, const char***);
01742 n_elements = va_arg (var_args, int);
01743
01744 value = *value_p;
01745
01746 i = 0;
01747 while (i < n_elements)
01748 {
01749 if (!dbus_message_iter_append_basic (&array,
01750 element_type,
01751 &value[i])) {
01752 dbus_message_iter_abandon_container (&iter, &array);
01753 goto failed;
01754 }
01755 ++i;
01756 }
01757 }
01758 else
01759 {
01760 _dbus_warn ("arrays of %s can't be appended with %s for now\n",
01761 _dbus_type_to_string (element_type),
01762 _DBUS_FUNCTION_NAME);
01763 goto failed;
01764 }
01765
01766 if (!dbus_message_iter_close_container (&iter, &array))
01767 goto failed;
01768 }
01769 #ifndef DBUS_DISABLE_CHECKS
01770 else
01771 {
01772 _dbus_warn ("type %s isn't supported yet in %s\n",
01773 _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
01774 goto failed;
01775 }
01776 #endif
01777
01778 type = va_arg (var_args, int);
01779 }
01780
01781 return TRUE;
01782
01783 failed:
01784 return FALSE;
01785 }
01786
01831 dbus_bool_t
01832 dbus_message_get_args (DBusMessage *message,
01833 DBusError *error,
01834 int first_arg_type,
01835 ...)
01836 {
01837 dbus_bool_t retval;
01838 va_list var_args;
01839
01840 _dbus_return_val_if_fail (message != NULL, FALSE);
01841 _dbus_return_val_if_error_is_set (error, FALSE);
01842
01843 va_start (var_args, first_arg_type);
01844 retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
01845 va_end (var_args);
01846
01847 return retval;
01848 }
01849
01860 dbus_bool_t
01861 dbus_message_get_args_valist (DBusMessage *message,
01862 DBusError *error,
01863 int first_arg_type,
01864 va_list var_args)
01865 {
01866 DBusMessageIter iter;
01867
01868 _dbus_return_val_if_fail (message != NULL, FALSE);
01869 _dbus_return_val_if_error_is_set (error, FALSE);
01870
01871 dbus_message_iter_init (message, &iter);
01872 return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
01873 }
01874
01875 static void
01876 _dbus_message_iter_init_common (DBusMessage *message,
01877 DBusMessageRealIter *real,
01878 int iter_type)
01879 {
01880 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
01881
01882
01883
01884
01885 ensure_byte_order (message);
01886
01887 real->message = message;
01888 real->changed_stamp = message->changed_stamp;
01889 real->iter_type = iter_type;
01890 real->sig_refcount = 0;
01891 }
01892
01915 dbus_bool_t
01916 dbus_message_iter_init (DBusMessage *message,
01917 DBusMessageIter *iter)
01918 {
01919 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01920 const DBusString *type_str;
01921 int type_pos;
01922
01923 _dbus_return_val_if_fail (message != NULL, FALSE);
01924 _dbus_return_val_if_fail (iter != NULL, FALSE);
01925
01926 get_const_signature (&message->header, &type_str, &type_pos);
01927
01928 _dbus_message_iter_init_common (message, real,
01929 DBUS_MESSAGE_ITER_TYPE_READER);
01930
01931 _dbus_type_reader_init (&real->u.reader,
01932 message->byte_order,
01933 type_str, type_pos,
01934 &message->body,
01935 0);
01936
01937 return _dbus_type_reader_get_current_type (&real->u.reader) != DBUS_TYPE_INVALID;
01938 }
01939
01946 dbus_bool_t
01947 dbus_message_iter_has_next (DBusMessageIter *iter)
01948 {
01949 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01950
01951 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
01952 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
01953
01954 return _dbus_type_reader_has_next (&real->u.reader);
01955 }
01956
01965 dbus_bool_t
01966 dbus_message_iter_next (DBusMessageIter *iter)
01967 {
01968 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01969
01970 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
01971 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
01972
01973 return _dbus_type_reader_next (&real->u.reader);
01974 }
01975
01990 int
01991 dbus_message_iter_get_arg_type (DBusMessageIter *iter)
01992 {
01993 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01994
01995 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
01996 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
01997
01998 return _dbus_type_reader_get_current_type (&real->u.reader);
01999 }
02000
02009 int
02010 dbus_message_iter_get_element_type (DBusMessageIter *iter)
02011 {
02012 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02013
02014 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
02015 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
02016 _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
02017
02018 return _dbus_type_reader_get_element_type (&real->u.reader);
02019 }
02020
02046 void
02047 dbus_message_iter_recurse (DBusMessageIter *iter,
02048 DBusMessageIter *sub)
02049 {
02050 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02051 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02052
02053 _dbus_return_if_fail (_dbus_message_iter_check (real));
02054 _dbus_return_if_fail (sub != NULL);
02055
02056 *real_sub = *real;
02057 _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
02058 }
02059
02071 char *
02072 dbus_message_iter_get_signature (DBusMessageIter *iter)
02073 {
02074 const DBusString *sig;
02075 DBusString retstr;
02076 char *ret;
02077 int start, len;
02078 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02079
02080 _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
02081
02082 if (!_dbus_string_init (&retstr))
02083 return NULL;
02084
02085 _dbus_type_reader_get_signature (&real->u.reader, &sig,
02086 &start, &len);
02087 if (!_dbus_string_append_len (&retstr,
02088 _dbus_string_get_const_data (sig) + start,
02089 len))
02090 return NULL;
02091 if (!_dbus_string_steal_data (&retstr, &ret))
02092 return NULL;
02093 _dbus_string_free (&retstr);
02094 return ret;
02095 }
02096
02144 void
02145 dbus_message_iter_get_basic (DBusMessageIter *iter,
02146 void *value)
02147 {
02148 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02149
02150 _dbus_return_if_fail (_dbus_message_iter_check (real));
02151 _dbus_return_if_fail (value != NULL);
02152
02153 if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_UNIX_FD)
02154 {
02155 #ifdef HAVE_UNIX_FD_PASSING
02156 DBusBasicValue idx;
02157
02158 _dbus_type_reader_read_basic(&real->u.reader, &idx);
02159
02160 if (idx.u32 >= real->message->n_unix_fds) {
02161
02162
02163 *((int*) value) = -1;
02164 return;
02165 }
02166
02167 *((int*) value) = _dbus_dup(real->message->unix_fds[idx.u32], NULL);
02168 #else
02169 *((int*) value) = -1;
02170 #endif
02171 }
02172 else
02173 {
02174 _dbus_type_reader_read_basic (&real->u.reader,
02175 value);
02176 }
02177 }
02178
02197 int
02198 dbus_message_iter_get_array_len (DBusMessageIter *iter)
02199 {
02200 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02201
02202 _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
02203
02204 return _dbus_type_reader_get_array_length (&real->u.reader);
02205 }
02206
02242 void
02243 dbus_message_iter_get_fixed_array (DBusMessageIter *iter,
02244 void *value,
02245 int *n_elements)
02246 {
02247 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02248 int subtype = _dbus_type_reader_get_current_type(&real->u.reader);
02249
02250 _dbus_return_if_fail (_dbus_message_iter_check (real));
02251 _dbus_return_if_fail (value != NULL);
02252 _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) ||
02253 (dbus_type_is_fixed (subtype) && subtype != DBUS_TYPE_UNIX_FD));
02254
02255 _dbus_type_reader_read_fixed_multi (&real->u.reader,
02256 value, n_elements);
02257 }
02258
02270 void
02271 dbus_message_iter_init_append (DBusMessage *message,
02272 DBusMessageIter *iter)
02273 {
02274 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02275
02276 _dbus_return_if_fail (message != NULL);
02277 _dbus_return_if_fail (iter != NULL);
02278
02279 _dbus_message_iter_init_common (message, real,
02280 DBUS_MESSAGE_ITER_TYPE_WRITER);
02281
02282
02283
02284
02285
02286 _dbus_type_writer_init_types_delayed (&real->u.writer,
02287 message->byte_order,
02288 &message->body,
02289 _dbus_string_get_length (&message->body));
02290 }
02291
02300 static dbus_bool_t
02301 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
02302 {
02303 DBusString *str;
02304 const DBusString *current_sig;
02305 int current_sig_pos;
02306
02307 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02308
02309 if (real->u.writer.type_str != NULL)
02310 {
02311 _dbus_assert (real->sig_refcount > 0);
02312 real->sig_refcount += 1;
02313 return TRUE;
02314 }
02315
02316 str = dbus_new (DBusString, 1);
02317 if (str == NULL)
02318 return FALSE;
02319
02320 if (!_dbus_header_get_field_raw (&real->message->header,
02321 DBUS_HEADER_FIELD_SIGNATURE,
02322 ¤t_sig, ¤t_sig_pos))
02323 current_sig = NULL;
02324
02325 if (current_sig)
02326 {
02327 int current_len;
02328
02329 current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
02330 current_sig_pos += 1;
02331
02332 if (!_dbus_string_init_preallocated (str, current_len + 4))
02333 {
02334 dbus_free (str);
02335 return FALSE;
02336 }
02337
02338 if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
02339 str, 0))
02340 {
02341 _dbus_string_free (str);
02342 dbus_free (str);
02343 return FALSE;
02344 }
02345 }
02346 else
02347 {
02348 if (!_dbus_string_init_preallocated (str, 4))
02349 {
02350 dbus_free (str);
02351 return FALSE;
02352 }
02353 }
02354
02355 real->sig_refcount = 1;
02356
02357 _dbus_type_writer_add_types (&real->u.writer,
02358 str, _dbus_string_get_length (str));
02359 return TRUE;
02360 }
02361
02371 static dbus_bool_t
02372 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
02373 {
02374 DBusString *str;
02375 const char *v_STRING;
02376 dbus_bool_t retval;
02377
02378 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02379 _dbus_assert (real->u.writer.type_str != NULL);
02380 _dbus_assert (real->sig_refcount > 0);
02381
02382 real->sig_refcount -= 1;
02383
02384 if (real->sig_refcount > 0)
02385 return TRUE;
02386 _dbus_assert (real->sig_refcount == 0);
02387
02388 retval = TRUE;
02389
02390 str = real->u.writer.type_str;
02391
02392 v_STRING = _dbus_string_get_const_data (str);
02393 if (!_dbus_header_set_field_basic (&real->message->header,
02394 DBUS_HEADER_FIELD_SIGNATURE,
02395 DBUS_TYPE_SIGNATURE,
02396 &v_STRING))
02397 retval = FALSE;
02398
02399 _dbus_type_writer_remove_types (&real->u.writer);
02400 _dbus_string_free (str);
02401 dbus_free (str);
02402
02403 return retval;
02404 }
02405
02413 static void
02414 _dbus_message_iter_abandon_signature (DBusMessageRealIter *real)
02415 {
02416 DBusString *str;
02417
02418 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02419 _dbus_assert (real->u.writer.type_str != NULL);
02420 _dbus_assert (real->sig_refcount > 0);
02421
02422 real->sig_refcount -= 1;
02423
02424 if (real->sig_refcount > 0)
02425 return;
02426 _dbus_assert (real->sig_refcount == 0);
02427
02428 str = real->u.writer.type_str;
02429
02430 _dbus_type_writer_remove_types (&real->u.writer);
02431 _dbus_string_free (str);
02432 dbus_free (str);
02433 }
02434
02435 #ifndef DBUS_DISABLE_CHECKS
02436 static dbus_bool_t
02437 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
02438 {
02439 if (!_dbus_message_iter_check (iter))
02440 return FALSE;
02441
02442 if (iter->message->locked)
02443 {
02444 _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)\n");
02445 return FALSE;
02446 }
02447
02448 return TRUE;
02449 }
02450 #endif
02451
02452 #ifdef HAVE_UNIX_FD_PASSING
02453 static int *
02454 expand_fd_array(DBusMessage *m,
02455 unsigned n)
02456 {
02457 _dbus_assert(m);
02458
02459
02460
02461
02462 if (m->n_unix_fds + n > m->n_unix_fds_allocated)
02463 {
02464 unsigned k;
02465 int *p;
02466
02467
02468 k = (m->n_unix_fds + n) * 2;
02469
02470
02471 if (k < 4)
02472 k = 4;
02473
02474 p = dbus_realloc(m->unix_fds, k * sizeof(int));
02475 if (p == NULL)
02476 return NULL;
02477
02478 m->unix_fds = p;
02479 m->n_unix_fds_allocated = k;
02480 }
02481
02482 return m->unix_fds + m->n_unix_fds;
02483 }
02484 #endif
02485
02505 dbus_bool_t
02506 dbus_message_iter_append_basic (DBusMessageIter *iter,
02507 int type,
02508 const void *value)
02509 {
02510 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02511 dbus_bool_t ret;
02512
02513 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02514 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02515 _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
02516 _dbus_return_val_if_fail (value != NULL, FALSE);
02517
02518 if (!_dbus_message_iter_open_signature (real))
02519 return FALSE;
02520
02521 if (type == DBUS_TYPE_UNIX_FD)
02522 {
02523 #ifdef HAVE_UNIX_FD_PASSING
02524 int *fds;
02525 dbus_uint32_t u;
02526
02527
02528 if (!(fds = expand_fd_array(real->message, 1)))
02529 return FALSE;
02530
02531 *fds = _dbus_dup(*(int*) value, NULL);
02532 if (*fds < 0)
02533 return FALSE;
02534
02535 u = real->message->n_unix_fds;
02536
02537
02538 if (!(ret = _dbus_type_writer_write_basic (&real->u.writer, DBUS_TYPE_UNIX_FD, &u))) {
02539 _dbus_close(*fds, NULL);
02540 return FALSE;
02541 }
02542
02543 real->message->n_unix_fds += 1;
02544 u += 1;
02545
02546
02547 ret = _dbus_header_set_field_basic (&real->message->header,
02548 DBUS_HEADER_FIELD_UNIX_FDS,
02549 DBUS_TYPE_UINT32,
02550 &u);
02551
02552
02553
02554
02555
02556
02557 #else
02558 ret = FALSE;
02559 #endif
02560 }
02561 else
02562 {
02563 ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
02564 }
02565
02566 if (!_dbus_message_iter_close_signature (real))
02567 ret = FALSE;
02568
02569 return ret;
02570 }
02571
02611 dbus_bool_t
02612 dbus_message_iter_append_fixed_array (DBusMessageIter *iter,
02613 int element_type,
02614 const void *value,
02615 int n_elements)
02616 {
02617 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02618 dbus_bool_t ret;
02619
02620 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02621 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02622 _dbus_return_val_if_fail (dbus_type_is_fixed (element_type) && element_type != DBUS_TYPE_UNIX_FD, FALSE);
02623 _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
02624 _dbus_return_val_if_fail (value != NULL, FALSE);
02625 _dbus_return_val_if_fail (n_elements >= 0, FALSE);
02626 _dbus_return_val_if_fail (n_elements <=
02627 DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type),
02628 FALSE);
02629
02630 ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
02631
02632 return ret;
02633 }
02634
02656 dbus_bool_t
02657 dbus_message_iter_open_container (DBusMessageIter *iter,
02658 int type,
02659 const char *contained_signature,
02660 DBusMessageIter *sub)
02661 {
02662 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02663 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02664 DBusString contained_str;
02665
02666 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02667 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02668 _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
02669 _dbus_return_val_if_fail (sub != NULL, FALSE);
02670 _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
02671 contained_signature == NULL) ||
02672 (type == DBUS_TYPE_DICT_ENTRY &&
02673 contained_signature == NULL) ||
02674 (type == DBUS_TYPE_VARIANT &&
02675 contained_signature != NULL) ||
02676 (type == DBUS_TYPE_ARRAY &&
02677 contained_signature != NULL), FALSE);
02678
02679
02680
02681
02682
02683 _dbus_return_val_if_fail ((type == DBUS_TYPE_ARRAY && contained_signature && *contained_signature == DBUS_DICT_ENTRY_BEGIN_CHAR) ||
02684 (contained_signature == NULL ||
02685 _dbus_check_is_valid_signature (contained_signature)),
02686 FALSE);
02687
02688 if (!_dbus_message_iter_open_signature (real))
02689 return FALSE;
02690
02691 *real_sub = *real;
02692
02693 if (contained_signature != NULL)
02694 {
02695 _dbus_string_init_const (&contained_str, contained_signature);
02696
02697 return _dbus_type_writer_recurse (&real->u.writer,
02698 type,
02699 &contained_str, 0,
02700 &real_sub->u.writer);
02701 }
02702 else
02703 {
02704 return _dbus_type_writer_recurse (&real->u.writer,
02705 type,
02706 NULL, 0,
02707 &real_sub->u.writer);
02708 }
02709 }
02710
02711
02725 dbus_bool_t
02726 dbus_message_iter_close_container (DBusMessageIter *iter,
02727 DBusMessageIter *sub)
02728 {
02729 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02730 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02731 dbus_bool_t ret;
02732
02733 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02734 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02735 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
02736 _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02737
02738 ret = _dbus_type_writer_unrecurse (&real->u.writer,
02739 &real_sub->u.writer);
02740
02741 if (!_dbus_message_iter_close_signature (real))
02742 ret = FALSE;
02743
02744 return ret;
02745 }
02746
02758 void
02759 dbus_message_iter_abandon_container (DBusMessageIter *iter,
02760 DBusMessageIter *sub)
02761 {
02762 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02763 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02764
02765 _dbus_return_if_fail (_dbus_message_iter_append_check (real));
02766 _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02767 _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
02768 _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02769
02770 _dbus_message_iter_abandon_signature (real);
02771 }
02772
02789 void
02790 dbus_message_set_no_reply (DBusMessage *message,
02791 dbus_bool_t no_reply)
02792 {
02793 _dbus_return_if_fail (message != NULL);
02794 _dbus_return_if_fail (!message->locked);
02795
02796 _dbus_header_toggle_flag (&message->header,
02797 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED,
02798 no_reply);
02799 }
02800
02808 dbus_bool_t
02809 dbus_message_get_no_reply (DBusMessage *message)
02810 {
02811 _dbus_return_val_if_fail (message != NULL, FALSE);
02812
02813 return _dbus_header_get_flag (&message->header,
02814 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED);
02815 }
02816
02831 void
02832 dbus_message_set_auto_start (DBusMessage *message,
02833 dbus_bool_t auto_start)
02834 {
02835 _dbus_return_if_fail (message != NULL);
02836 _dbus_return_if_fail (!message->locked);
02837
02838 _dbus_header_toggle_flag (&message->header,
02839 DBUS_HEADER_FLAG_NO_AUTO_START,
02840 !auto_start);
02841 }
02842
02850 dbus_bool_t
02851 dbus_message_get_auto_start (DBusMessage *message)
02852 {
02853 _dbus_return_val_if_fail (message != NULL, FALSE);
02854
02855 return !_dbus_header_get_flag (&message->header,
02856 DBUS_HEADER_FLAG_NO_AUTO_START);
02857 }
02858
02859
02872 dbus_bool_t
02873 dbus_message_set_path (DBusMessage *message,
02874 const char *object_path)
02875 {
02876 _dbus_return_val_if_fail (message != NULL, FALSE);
02877 _dbus_return_val_if_fail (!message->locked, FALSE);
02878 _dbus_return_val_if_fail (object_path == NULL ||
02879 _dbus_check_is_valid_path (object_path),
02880 FALSE);
02881
02882 return set_or_delete_string_field (message,
02883 DBUS_HEADER_FIELD_PATH,
02884 DBUS_TYPE_OBJECT_PATH,
02885 object_path);
02886 }
02887
02901 const char*
02902 dbus_message_get_path (DBusMessage *message)
02903 {
02904 const char *v;
02905
02906 _dbus_return_val_if_fail (message != NULL, NULL);
02907
02908 v = NULL;
02909 _dbus_header_get_field_basic (&message->header,
02910 DBUS_HEADER_FIELD_PATH,
02911 DBUS_TYPE_OBJECT_PATH,
02912 (void *) &v);
02913 return v;
02914 }
02915
02925 dbus_bool_t
02926 dbus_message_has_path (DBusMessage *message,
02927 const char *path)
02928 {
02929 const char *msg_path;
02930 msg_path = dbus_message_get_path (message);
02931
02932 if (msg_path == NULL)
02933 {
02934 if (path == NULL)
02935 return TRUE;
02936 else
02937 return FALSE;
02938 }
02939
02940 if (path == NULL)
02941 return FALSE;
02942
02943 if (strcmp (msg_path, path) == 0)
02944 return TRUE;
02945
02946 return FALSE;
02947 }
02948
02969 dbus_bool_t
02970 dbus_message_get_path_decomposed (DBusMessage *message,
02971 char ***path)
02972 {
02973 const char *v;
02974
02975 _dbus_return_val_if_fail (message != NULL, FALSE);
02976 _dbus_return_val_if_fail (path != NULL, FALSE);
02977
02978 *path = NULL;
02979
02980 v = dbus_message_get_path (message);
02981 if (v != NULL)
02982 {
02983 if (!_dbus_decompose_path (v, strlen (v),
02984 path, NULL))
02985 return FALSE;
02986 }
02987 return TRUE;
02988 }
02989
03003 dbus_bool_t
03004 dbus_message_set_interface (DBusMessage *message,
03005 const char *interface)
03006 {
03007 _dbus_return_val_if_fail (message != NULL, FALSE);
03008 _dbus_return_val_if_fail (!message->locked, FALSE);
03009 _dbus_return_val_if_fail (interface == NULL ||
03010 _dbus_check_is_valid_interface (interface),
03011 FALSE);
03012
03013 return set_or_delete_string_field (message,
03014 DBUS_HEADER_FIELD_INTERFACE,
03015 DBUS_TYPE_STRING,
03016 interface);
03017 }
03018
03032 const char*
03033 dbus_message_get_interface (DBusMessage *message)
03034 {
03035 const char *v;
03036
03037 _dbus_return_val_if_fail (message != NULL, NULL);
03038
03039 v = NULL;
03040 _dbus_header_get_field_basic (&message->header,
03041 DBUS_HEADER_FIELD_INTERFACE,
03042 DBUS_TYPE_STRING,
03043 (void *) &v);
03044 return v;
03045 }
03046
03054 dbus_bool_t
03055 dbus_message_has_interface (DBusMessage *message,
03056 const char *interface)
03057 {
03058 const char *msg_interface;
03059 msg_interface = dbus_message_get_interface (message);
03060
03061 if (msg_interface == NULL)
03062 {
03063 if (interface == NULL)
03064 return TRUE;
03065 else
03066 return FALSE;
03067 }
03068
03069 if (interface == NULL)
03070 return FALSE;
03071
03072 if (strcmp (msg_interface, interface) == 0)
03073 return TRUE;
03074
03075 return FALSE;
03076
03077 }
03078
03091 dbus_bool_t
03092 dbus_message_set_member (DBusMessage *message,
03093 const char *member)
03094 {
03095 _dbus_return_val_if_fail (message != NULL, FALSE);
03096 _dbus_return_val_if_fail (!message->locked, FALSE);
03097 _dbus_return_val_if_fail (member == NULL ||
03098 _dbus_check_is_valid_member (member),
03099 FALSE);
03100
03101 return set_or_delete_string_field (message,
03102 DBUS_HEADER_FIELD_MEMBER,
03103 DBUS_TYPE_STRING,
03104 member);
03105 }
03106
03118 const char*
03119 dbus_message_get_member (DBusMessage *message)
03120 {
03121 const char *v;
03122
03123 _dbus_return_val_if_fail (message != NULL, NULL);
03124
03125 v = NULL;
03126 _dbus_header_get_field_basic (&message->header,
03127 DBUS_HEADER_FIELD_MEMBER,
03128 DBUS_TYPE_STRING,
03129 (void *) &v);
03130 return v;
03131 }
03132
03140 dbus_bool_t
03141 dbus_message_has_member (DBusMessage *message,
03142 const char *member)
03143 {
03144 const char *msg_member;
03145 msg_member = dbus_message_get_member (message);
03146
03147 if (msg_member == NULL)
03148 {
03149 if (member == NULL)
03150 return TRUE;
03151 else
03152 return FALSE;
03153 }
03154
03155 if (member == NULL)
03156 return FALSE;
03157
03158 if (strcmp (msg_member, member) == 0)
03159 return TRUE;
03160
03161 return FALSE;
03162
03163 }
03164
03176 dbus_bool_t
03177 dbus_message_set_error_name (DBusMessage *message,
03178 const char *error_name)
03179 {
03180 _dbus_return_val_if_fail (message != NULL, FALSE);
03181 _dbus_return_val_if_fail (!message->locked, FALSE);
03182 _dbus_return_val_if_fail (error_name == NULL ||
03183 _dbus_check_is_valid_error_name (error_name),
03184 FALSE);
03185
03186 return set_or_delete_string_field (message,
03187 DBUS_HEADER_FIELD_ERROR_NAME,
03188 DBUS_TYPE_STRING,
03189 error_name);
03190 }
03191
03202 const char*
03203 dbus_message_get_error_name (DBusMessage *message)
03204 {
03205 const char *v;
03206
03207 _dbus_return_val_if_fail (message != NULL, NULL);
03208
03209 v = NULL;
03210 _dbus_header_get_field_basic (&message->header,
03211 DBUS_HEADER_FIELD_ERROR_NAME,
03212 DBUS_TYPE_STRING,
03213 (void *) &v);
03214 return v;
03215 }
03216
03230 dbus_bool_t
03231 dbus_message_set_destination (DBusMessage *message,
03232 const char *destination)
03233 {
03234 _dbus_return_val_if_fail (message != NULL, FALSE);
03235 _dbus_return_val_if_fail (!message->locked, FALSE);
03236 _dbus_return_val_if_fail (destination == NULL ||
03237 _dbus_check_is_valid_bus_name (destination),
03238 FALSE);
03239
03240 return set_or_delete_string_field (message,
03241 DBUS_HEADER_FIELD_DESTINATION,
03242 DBUS_TYPE_STRING,
03243 destination);
03244 }
03245
03255 const char*
03256 dbus_message_get_destination (DBusMessage *message)
03257 {
03258 const char *v;
03259
03260 _dbus_return_val_if_fail (message != NULL, NULL);
03261
03262 v = NULL;
03263 _dbus_header_get_field_basic (&message->header,
03264 DBUS_HEADER_FIELD_DESTINATION,
03265 DBUS_TYPE_STRING,
03266 (void *) &v);
03267 return v;
03268 }
03269
03284 dbus_bool_t
03285 dbus_message_set_sender (DBusMessage *message,
03286 const char *sender)
03287 {
03288 _dbus_return_val_if_fail (message != NULL, FALSE);
03289 _dbus_return_val_if_fail (!message->locked, FALSE);
03290 _dbus_return_val_if_fail (sender == NULL ||
03291 _dbus_check_is_valid_bus_name (sender),
03292 FALSE);
03293
03294 return set_or_delete_string_field (message,
03295 DBUS_HEADER_FIELD_SENDER,
03296 DBUS_TYPE_STRING,
03297 sender);
03298 }
03299
03315 const char*
03316 dbus_message_get_sender (DBusMessage *message)
03317 {
03318 const char *v;
03319
03320 _dbus_return_val_if_fail (message != NULL, NULL);
03321
03322 v = NULL;
03323 _dbus_header_get_field_basic (&message->header,
03324 DBUS_HEADER_FIELD_SENDER,
03325 DBUS_TYPE_STRING,
03326 (void *) &v);
03327 return v;
03328 }
03329
03348 const char*
03349 dbus_message_get_signature (DBusMessage *message)
03350 {
03351 const DBusString *type_str;
03352 int type_pos;
03353
03354 _dbus_return_val_if_fail (message != NULL, NULL);
03355
03356 get_const_signature (&message->header, &type_str, &type_pos);
03357
03358 return _dbus_string_get_const_data_len (type_str, type_pos, 0);
03359 }
03360
03361 static dbus_bool_t
03362 _dbus_message_has_type_interface_member (DBusMessage *message,
03363 int type,
03364 const char *interface,
03365 const char *member)
03366 {
03367 const char *n;
03368
03369 _dbus_assert (message != NULL);
03370 _dbus_assert (interface != NULL);
03371 _dbus_assert (member != NULL);
03372
03373 if (dbus_message_get_type (message) != type)
03374 return FALSE;
03375
03376
03377
03378
03379
03380 n = dbus_message_get_member (message);
03381
03382 if (n && strcmp (n, member) == 0)
03383 {
03384 n = dbus_message_get_interface (message);
03385
03386 if (n == NULL || strcmp (n, interface) == 0)
03387 return TRUE;
03388 }
03389
03390 return FALSE;
03391 }
03392
03407 dbus_bool_t
03408 dbus_message_is_method_call (DBusMessage *message,
03409 const char *interface,
03410 const char *method)
03411 {
03412 _dbus_return_val_if_fail (message != NULL, FALSE);
03413 _dbus_return_val_if_fail (interface != NULL, FALSE);
03414 _dbus_return_val_if_fail (method != NULL, FALSE);
03415
03416
03417
03418
03419 return _dbus_message_has_type_interface_member (message,
03420 DBUS_MESSAGE_TYPE_METHOD_CALL,
03421 interface, method);
03422 }
03423
03435 dbus_bool_t
03436 dbus_message_is_signal (DBusMessage *message,
03437 const char *interface,
03438 const char *signal_name)
03439 {
03440 _dbus_return_val_if_fail (message != NULL, FALSE);
03441 _dbus_return_val_if_fail (interface != NULL, FALSE);
03442 _dbus_return_val_if_fail (signal_name != NULL, FALSE);
03443
03444
03445
03446
03447 return _dbus_message_has_type_interface_member (message,
03448 DBUS_MESSAGE_TYPE_SIGNAL,
03449 interface, signal_name);
03450 }
03451
03462 dbus_bool_t
03463 dbus_message_is_error (DBusMessage *message,
03464 const char *error_name)
03465 {
03466 const char *n;
03467
03468 _dbus_return_val_if_fail (message != NULL, FALSE);
03469 _dbus_return_val_if_fail (error_name != NULL, FALSE);
03470
03471
03472
03473
03474 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
03475 return FALSE;
03476
03477 n = dbus_message_get_error_name (message);
03478
03479 if (n && strcmp (n, error_name) == 0)
03480 return TRUE;
03481 else
03482 return FALSE;
03483 }
03484
03495 dbus_bool_t
03496 dbus_message_has_destination (DBusMessage *message,
03497 const char *name)
03498 {
03499 const char *s;
03500
03501 _dbus_return_val_if_fail (message != NULL, FALSE);
03502 _dbus_return_val_if_fail (name != NULL, FALSE);
03503
03504
03505
03506
03507 s = dbus_message_get_destination (message);
03508
03509 if (s && strcmp (s, name) == 0)
03510 return TRUE;
03511 else
03512 return FALSE;
03513 }
03514
03530 dbus_bool_t
03531 dbus_message_has_sender (DBusMessage *message,
03532 const char *name)
03533 {
03534 const char *s;
03535
03536 _dbus_return_val_if_fail (message != NULL, FALSE);
03537 _dbus_return_val_if_fail (name != NULL, FALSE);
03538
03539
03540
03541
03542 s = dbus_message_get_sender (message);
03543
03544 if (s && strcmp (s, name) == 0)
03545 return TRUE;
03546 else
03547 return FALSE;
03548 }
03549
03559 dbus_bool_t
03560 dbus_message_has_signature (DBusMessage *message,
03561 const char *signature)
03562 {
03563 const char *s;
03564
03565 _dbus_return_val_if_fail (message != NULL, FALSE);
03566 _dbus_return_val_if_fail (signature != NULL, FALSE);
03567
03568
03569
03570
03571 s = dbus_message_get_signature (message);
03572
03573 if (s && strcmp (s, signature) == 0)
03574 return TRUE;
03575 else
03576 return FALSE;
03577 }
03578
03601 dbus_bool_t
03602 dbus_set_error_from_message (DBusError *error,
03603 DBusMessage *message)
03604 {
03605 const char *str;
03606
03607 _dbus_return_val_if_fail (message != NULL, FALSE);
03608 _dbus_return_val_if_error_is_set (error, FALSE);
03609
03610 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
03611 return FALSE;
03612
03613 str = NULL;
03614 dbus_message_get_args (message, NULL,
03615 DBUS_TYPE_STRING, &str,
03616 DBUS_TYPE_INVALID);
03617
03618 dbus_set_error (error, dbus_message_get_error_name (message),
03619 str ? "%s" : NULL, str);
03620
03621 return TRUE;
03622 }
03623
03630 dbus_bool_t
03631 dbus_message_contains_unix_fds(DBusMessage *message)
03632 {
03633 #ifdef HAVE_UNIX_FD_PASSING
03634 _dbus_assert(message);
03635
03636 return message->n_unix_fds > 0;
03637 #else
03638 return FALSE;
03639 #endif
03640 }
03641
03660 #define INITIAL_LOADER_DATA_LEN 32
03661
03668 DBusMessageLoader*
03669 _dbus_message_loader_new (void)
03670 {
03671 DBusMessageLoader *loader;
03672
03673 loader = dbus_new0 (DBusMessageLoader, 1);
03674 if (loader == NULL)
03675 return NULL;
03676
03677 loader->refcount = 1;
03678
03679 loader->corrupted = FALSE;
03680 loader->corruption_reason = DBUS_VALID;
03681
03682
03683 loader->max_message_size = DBUS_MAXIMUM_MESSAGE_LENGTH;
03684
03685
03686
03687
03688
03689 loader->max_message_unix_fds = 1024;
03690
03691 if (!_dbus_string_init (&loader->data))
03692 {
03693 dbus_free (loader);
03694 return NULL;
03695 }
03696
03697
03698 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
03699 _dbus_string_set_length (&loader->data, 0);
03700
03701 #ifdef HAVE_UNIX_FD_PASSING
03702 loader->unix_fds = NULL;
03703 loader->n_unix_fds = loader->n_unix_fds_allocated = 0;
03704 loader->unix_fds_outstanding = FALSE;
03705 #endif
03706
03707 return loader;
03708 }
03709
03716 DBusMessageLoader *
03717 _dbus_message_loader_ref (DBusMessageLoader *loader)
03718 {
03719 loader->refcount += 1;
03720
03721 return loader;
03722 }
03723
03730 void
03731 _dbus_message_loader_unref (DBusMessageLoader *loader)
03732 {
03733 loader->refcount -= 1;
03734 if (loader->refcount == 0)
03735 {
03736 #ifdef HAVE_UNIX_FD_PASSING
03737 close_unix_fds(loader->unix_fds, &loader->n_unix_fds);
03738 dbus_free(loader->unix_fds);
03739 #endif
03740 _dbus_list_foreach (&loader->messages,
03741 (DBusForeachFunction) dbus_message_unref,
03742 NULL);
03743 _dbus_list_clear (&loader->messages);
03744 _dbus_string_free (&loader->data);
03745 dbus_free (loader);
03746 }
03747 }
03748
03767 void
03768 _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
03769 DBusString **buffer)
03770 {
03771 _dbus_assert (!loader->buffer_outstanding);
03772
03773 *buffer = &loader->data;
03774
03775 loader->buffer_outstanding = TRUE;
03776 }
03777
03788 void
03789 _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
03790 DBusString *buffer,
03791 int bytes_read)
03792 {
03793 _dbus_assert (loader->buffer_outstanding);
03794 _dbus_assert (buffer == &loader->data);
03795
03796 loader->buffer_outstanding = FALSE;
03797 }
03798
03809 dbus_bool_t
03810 _dbus_message_loader_get_unix_fds(DBusMessageLoader *loader,
03811 int **fds,
03812 unsigned *max_n_fds)
03813 {
03814 #ifdef HAVE_UNIX_FD_PASSING
03815 _dbus_assert (!loader->unix_fds_outstanding);
03816
03817
03818
03819
03820
03821
03822
03823
03824
03825 if (loader->n_unix_fds_allocated < loader->max_message_unix_fds)
03826 {
03827 int *a = dbus_realloc(loader->unix_fds,
03828 loader->max_message_unix_fds * sizeof(loader->unix_fds[0]));
03829
03830 if (!a)
03831 return FALSE;
03832
03833 loader->unix_fds = a;
03834 loader->n_unix_fds_allocated = loader->max_message_unix_fds;
03835 }
03836
03837 *fds = loader->unix_fds + loader->n_unix_fds;
03838 *max_n_fds = loader->n_unix_fds_allocated - loader->n_unix_fds;
03839
03840 loader->unix_fds_outstanding = TRUE;
03841 return TRUE;
03842 #else
03843 _dbus_assert_not_reached("Platform doesn't support unix fd passing");
03844 return FALSE;
03845 #endif
03846 }
03847
03858 void
03859 _dbus_message_loader_return_unix_fds(DBusMessageLoader *loader,
03860 int *fds,
03861 unsigned n_fds)
03862 {
03863 #ifdef HAVE_UNIX_FD_PASSING
03864 _dbus_assert(loader->unix_fds_outstanding);
03865 _dbus_assert(loader->unix_fds + loader->n_unix_fds == fds);
03866 _dbus_assert(loader->n_unix_fds + n_fds <= loader->n_unix_fds_allocated);
03867
03868 loader->n_unix_fds += n_fds;
03869 loader->unix_fds_outstanding = FALSE;
03870 #else
03871 _dbus_assert_not_reached("Platform doesn't support unix fd passing");
03872 #endif
03873 }
03874
03875
03876
03877
03878
03879
03880
03881
03882
03883
03884
03885
03886
03887
03888
03889
03890
03891
03892
03893
03894
03895
03896
03897
03898
03899
03900
03901 static dbus_bool_t
03902 load_message (DBusMessageLoader *loader,
03903 DBusMessage *message,
03904 int byte_order,
03905 int fields_array_len,
03906 int header_len,
03907 int body_len)
03908 {
03909 dbus_bool_t oom;
03910 DBusValidity validity;
03911 const DBusString *type_str;
03912 int type_pos;
03913 DBusValidationMode mode;
03914 dbus_uint32_t n_unix_fds = 0;
03915
03916 mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
03917
03918 oom = FALSE;
03919
03920 #if 0
03921 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len );
03922 #endif
03923
03924
03925 _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
03926 _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
03927
03928 if (!_dbus_header_load (&message->header,
03929 mode,
03930 &validity,
03931 byte_order,
03932 fields_array_len,
03933 header_len,
03934 body_len,
03935 &loader->data, 0,
03936 _dbus_string_get_length (&loader->data)))
03937 {
03938 _dbus_verbose ("Failed to load header for new message code %d\n", validity);
03939
03940
03941
03942 _dbus_assert (validity != DBUS_VALID);
03943
03944 if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
03945 oom = TRUE;
03946 else
03947 {
03948 loader->corrupted = TRUE;
03949 loader->corruption_reason = validity;
03950 }
03951 goto failed;
03952 }
03953
03954 _dbus_assert (validity == DBUS_VALID);
03955
03956 message->byte_order = byte_order;
03957
03958
03959 if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
03960 {
03961 get_const_signature (&message->header, &type_str, &type_pos);
03962
03963
03964
03965
03966 validity = _dbus_validate_body_with_reason (type_str,
03967 type_pos,
03968 byte_order,
03969 NULL,
03970 &loader->data,
03971 header_len,
03972 body_len);
03973 if (validity != DBUS_VALID)
03974 {
03975 _dbus_verbose ("Failed to validate message body code %d\n", validity);
03976
03977 loader->corrupted = TRUE;
03978 loader->corruption_reason = validity;
03979
03980 goto failed;
03981 }
03982 }
03983
03984
03985 _dbus_header_get_field_basic(&message->header,
03986 DBUS_HEADER_FIELD_UNIX_FDS,
03987 DBUS_TYPE_UINT32,
03988 &n_unix_fds);
03989
03990 #ifdef HAVE_UNIX_FD_PASSING
03991
03992 if (n_unix_fds > loader->n_unix_fds)
03993 {
03994 _dbus_verbose("Message contains references to more unix fds than were sent %u != %u\n",
03995 n_unix_fds, loader->n_unix_fds);
03996
03997 loader->corrupted = TRUE;
03998 loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
03999 goto failed;
04000 }
04001
04002
04003
04004 dbus_free(message->unix_fds);
04005
04006 if (n_unix_fds > 0)
04007 {
04008 message->unix_fds = _dbus_memdup(loader->unix_fds, n_unix_fds * sizeof(message->unix_fds[0]));
04009 if (message->unix_fds == NULL)
04010 {
04011 _dbus_verbose ("Failed to allocate file descriptor array\n");
04012 oom = TRUE;
04013 goto failed;
04014 }
04015
04016 message->n_unix_fds_allocated = message->n_unix_fds = n_unix_fds;
04017 loader->n_unix_fds -= n_unix_fds;
04018 memmove(loader->unix_fds + n_unix_fds, loader->unix_fds, loader->n_unix_fds);
04019 }
04020 else
04021 message->unix_fds = NULL;
04022
04023 #else
04024
04025 if (n_unix_fds > 0)
04026 {
04027 _dbus_verbose ("Hmm, message claims to come with file descriptors "
04028 "but that's not supported on our platform, disconnecting.\n");
04029
04030 loader->corrupted = TRUE;
04031 loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
04032 goto failed;
04033 }
04034
04035 #endif
04036
04037
04038
04039 if (!_dbus_list_append (&loader->messages, message))
04040 {
04041 _dbus_verbose ("Failed to append new message to loader queue\n");
04042 oom = TRUE;
04043 goto failed;
04044 }
04045
04046 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
04047 _dbus_assert (_dbus_string_get_length (&loader->data) >=
04048 (header_len + body_len));
04049
04050 if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
04051 {
04052 _dbus_verbose ("Failed to move body into new message\n");
04053 oom = TRUE;
04054 goto failed;
04055 }
04056
04057 _dbus_string_delete (&loader->data, 0, header_len + body_len);
04058
04059
04060 _dbus_string_compact (&loader->data, 2048);
04061
04062 _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
04063 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
04064
04065 _dbus_verbose ("Loaded message %p\n", message);
04066
04067 _dbus_assert (!oom);
04068 _dbus_assert (!loader->corrupted);
04069 _dbus_assert (loader->messages != NULL);
04070 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
04071
04072 return TRUE;
04073
04074 failed:
04075
04076
04077
04078
04079 _dbus_list_remove_last (&loader->messages, message);
04080
04081 if (oom)
04082 _dbus_assert (!loader->corrupted);
04083 else
04084 _dbus_assert (loader->corrupted);
04085
04086 _dbus_verbose_bytes_of_string (&loader->data, 0, _dbus_string_get_length (&loader->data));
04087
04088 return FALSE;
04089 }
04090
04105 dbus_bool_t
04106 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
04107 {
04108 while (!loader->corrupted &&
04109 _dbus_string_get_length (&loader->data) >= DBUS_MINIMUM_HEADER_SIZE)
04110 {
04111 DBusValidity validity;
04112 int byte_order, fields_array_len, header_len, body_len;
04113
04114 if (_dbus_header_have_message_untrusted (loader->max_message_size,
04115 &validity,
04116 &byte_order,
04117 &fields_array_len,
04118 &header_len,
04119 &body_len,
04120 &loader->data, 0,
04121 _dbus_string_get_length (&loader->data)))
04122 {
04123 DBusMessage *message;
04124
04125 _dbus_assert (validity == DBUS_VALID);
04126
04127 message = dbus_message_new_empty_header ();
04128 if (message == NULL)
04129 return FALSE;
04130
04131 if (!load_message (loader, message,
04132 byte_order, fields_array_len,
04133 header_len, body_len))
04134 {
04135 dbus_message_unref (message);
04136
04137
04138
04139 return loader->corrupted;
04140 }
04141
04142 _dbus_assert (loader->messages != NULL);
04143 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
04144 }
04145 else
04146 {
04147 _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
04148 validity);
04149 if (validity != DBUS_VALID)
04150 {
04151 loader->corrupted = TRUE;
04152 loader->corruption_reason = validity;
04153 }
04154 return TRUE;
04155 }
04156 }
04157
04158 return TRUE;
04159 }
04160
04168 DBusMessage*
04169 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
04170 {
04171 if (loader->messages)
04172 return loader->messages->data;
04173 else
04174 return NULL;
04175 }
04176
04185 DBusMessage*
04186 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
04187 {
04188 return _dbus_list_pop_first (&loader->messages);
04189 }
04190
04199 DBusList*
04200 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
04201 {
04202 return _dbus_list_pop_first_link (&loader->messages);
04203 }
04204
04211 void
04212 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
04213 DBusList *link)
04214 {
04215 _dbus_list_prepend_link (&loader->messages, link);
04216 }
04217
04227 dbus_bool_t
04228 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
04229 {
04230 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
04231 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
04232 return loader->corrupted;
04233 }
04234
04241 DBusValidity
04242 _dbus_message_loader_get_corruption_reason (DBusMessageLoader *loader)
04243 {
04244 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
04245 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
04246
04247 return loader->corruption_reason;
04248 }
04249
04256 void
04257 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
04258 long size)
04259 {
04260 if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
04261 {
04262 _dbus_verbose ("clamping requested max message size %ld to %d\n",
04263 size, DBUS_MAXIMUM_MESSAGE_LENGTH);
04264 size = DBUS_MAXIMUM_MESSAGE_LENGTH;
04265 }
04266 loader->max_message_size = size;
04267 }
04268
04275 long
04276 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
04277 {
04278 return loader->max_message_size;
04279 }
04280
04287 void
04288 _dbus_message_loader_set_max_message_unix_fds (DBusMessageLoader *loader,
04289 long n)
04290 {
04291 if (n > DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
04292 {
04293 _dbus_verbose ("clamping requested max message unix_fds %ld to %d\n",
04294 n, DBUS_MAXIMUM_MESSAGE_UNIX_FDS);
04295 n = DBUS_MAXIMUM_MESSAGE_UNIX_FDS;
04296 }
04297 loader->max_message_unix_fds = n;
04298 }
04299
04306 long
04307 _dbus_message_loader_get_max_message_unix_fds (DBusMessageLoader *loader)
04308 {
04309 return loader->max_message_unix_fds;
04310 }
04311
04312 static DBusDataSlotAllocator slot_allocator;
04313 _DBUS_DEFINE_GLOBAL_LOCK (message_slots);
04314
04329 dbus_bool_t
04330 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
04331 {
04332 return _dbus_data_slot_allocator_alloc (&slot_allocator,
04333 &_DBUS_LOCK_NAME (message_slots),
04334 slot_p);
04335 }
04336
04348 void
04349 dbus_message_free_data_slot (dbus_int32_t *slot_p)
04350 {
04351 _dbus_return_if_fail (*slot_p >= 0);
04352
04353 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
04354 }
04355
04369 dbus_bool_t
04370 dbus_message_set_data (DBusMessage *message,
04371 dbus_int32_t slot,
04372 void *data,
04373 DBusFreeFunction free_data_func)
04374 {
04375 DBusFreeFunction old_free_func;
04376 void *old_data;
04377 dbus_bool_t retval;
04378
04379 _dbus_return_val_if_fail (message != NULL, FALSE);
04380 _dbus_return_val_if_fail (slot >= 0, FALSE);
04381
04382 retval = _dbus_data_slot_list_set (&slot_allocator,
04383 &message->slot_list,
04384 slot, data, free_data_func,
04385 &old_free_func, &old_data);
04386
04387 if (retval)
04388 {
04389
04390 if (old_free_func)
04391 (* old_free_func) (old_data);
04392 }
04393
04394 return retval;
04395 }
04396
04405 void*
04406 dbus_message_get_data (DBusMessage *message,
04407 dbus_int32_t slot)
04408 {
04409 void *res;
04410
04411 _dbus_return_val_if_fail (message != NULL, NULL);
04412
04413 res = _dbus_data_slot_list_get (&slot_allocator,
04414 &message->slot_list,
04415 slot);
04416
04417 return res;
04418 }
04419
04433 int
04434 dbus_message_type_from_string (const char *type_str)
04435 {
04436 if (strcmp (type_str, "method_call") == 0)
04437 return DBUS_MESSAGE_TYPE_METHOD_CALL;
04438 if (strcmp (type_str, "method_return") == 0)
04439 return DBUS_MESSAGE_TYPE_METHOD_RETURN;
04440 else if (strcmp (type_str, "signal") == 0)
04441 return DBUS_MESSAGE_TYPE_SIGNAL;
04442 else if (strcmp (type_str, "error") == 0)
04443 return DBUS_MESSAGE_TYPE_ERROR;
04444 else
04445 return DBUS_MESSAGE_TYPE_INVALID;
04446 }
04447
04461 const char *
04462 dbus_message_type_to_string (int type)
04463 {
04464 switch (type)
04465 {
04466 case DBUS_MESSAGE_TYPE_METHOD_CALL:
04467 return "method_call";
04468 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
04469 return "method_return";
04470 case DBUS_MESSAGE_TYPE_SIGNAL:
04471 return "signal";
04472 case DBUS_MESSAGE_TYPE_ERROR:
04473 return "error";
04474 default:
04475 return "invalid";
04476 }
04477 }
04478
04491 dbus_bool_t
04492 dbus_message_marshal (DBusMessage *msg,
04493 char **marshalled_data_p,
04494 int *len_p)
04495 {
04496 DBusString tmp;
04497 dbus_bool_t was_locked;
04498
04499 _dbus_return_val_if_fail (msg != NULL, FALSE);
04500 _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
04501 _dbus_return_val_if_fail (len_p != NULL, FALSE);
04502
04503 if (!_dbus_string_init (&tmp))
04504 return FALSE;
04505
04506
04507 was_locked = msg->locked;
04508
04509 if (!was_locked)
04510 dbus_message_lock (msg);
04511
04512 if (!_dbus_string_copy (&(msg->header.data), 0, &tmp, 0))
04513 goto fail;
04514
04515 *len_p = _dbus_string_get_length (&tmp);
04516
04517 if (!_dbus_string_copy (&(msg->body), 0, &tmp, *len_p))
04518 goto fail;
04519
04520 *len_p = _dbus_string_get_length (&tmp);
04521
04522 if (!_dbus_string_steal_data (&tmp, marshalled_data_p))
04523 goto fail;
04524
04525 _dbus_string_free (&tmp);
04526
04527 if (!was_locked)
04528 msg->locked = FALSE;
04529
04530 return TRUE;
04531
04532 fail:
04533 _dbus_string_free (&tmp);
04534
04535 if (!was_locked)
04536 msg->locked = FALSE;
04537
04538 return FALSE;
04539 }
04540
04553 DBusMessage *
04554 dbus_message_demarshal (const char *str,
04555 int len,
04556 DBusError *error)
04557 {
04558 DBusMessageLoader *loader;
04559 DBusString *buffer;
04560 DBusMessage *msg;
04561
04562 _dbus_return_val_if_fail (str != NULL, NULL);
04563
04564 loader = _dbus_message_loader_new ();
04565
04566 if (loader == NULL)
04567 return NULL;
04568
04569 _dbus_message_loader_get_buffer (loader, &buffer);
04570 _dbus_string_append_len (buffer, str, len);
04571 _dbus_message_loader_return_buffer (loader, buffer, len);
04572
04573 if (!_dbus_message_loader_queue_messages (loader))
04574 goto fail_oom;
04575
04576 if (_dbus_message_loader_get_is_corrupted (loader))
04577 goto fail_corrupt;
04578
04579 msg = _dbus_message_loader_pop_message (loader);
04580
04581 if (!msg)
04582 goto fail_oom;
04583
04584 _dbus_message_loader_unref (loader);
04585 return msg;
04586
04587 fail_corrupt:
04588 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted (%s)",
04589 _dbus_validity_to_error_message (loader->corruption_reason));
04590 _dbus_message_loader_unref (loader);
04591 return NULL;
04592
04593 fail_oom:
04594 _DBUS_SET_OOM (error);
04595 _dbus_message_loader_unref (loader);
04596 return NULL;
04597 }
04598
04612 int
04613 dbus_message_demarshal_bytes_needed(const char *buf,
04614 int len)
04615 {
04616 DBusString str;
04617 int byte_order, fields_array_len, header_len, body_len;
04618 DBusValidity validity = DBUS_VALID;
04619 int have_message;
04620
04621 if (!buf || len < DBUS_MINIMUM_HEADER_SIZE)
04622 return 0;
04623
04624 if (len > DBUS_MAXIMUM_MESSAGE_LENGTH)
04625 len = DBUS_MAXIMUM_MESSAGE_LENGTH;
04626 _dbus_string_init_const_len (&str, buf, len);
04627
04628 validity = DBUS_VALID;
04629 have_message
04630 = _dbus_header_have_message_untrusted(DBUS_MAXIMUM_MESSAGE_LENGTH,
04631 &validity, &byte_order,
04632 &fields_array_len,
04633 &header_len,
04634 &body_len,
04635 &str, 0,
04636 len);
04637 _dbus_string_free (&str);
04638
04639 if (validity == DBUS_VALID)
04640 {
04641 _dbus_assert(have_message);
04642 return header_len + body_len;
04643 }
04644 else
04645 {
04646 return -1;
04647 }
04648 }
04649
04652