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 #define _DBUS_TYPE_IS_STRINGLIKE(type) \
00044 (type == DBUS_TYPE_STRING || type == DBUS_TYPE_SIGNATURE || \
00045 type == DBUS_TYPE_OBJECT_PATH)
00046
00047 static void dbus_message_finalize (DBusMessage *message);
00048
00059 #ifdef DBUS_BUILD_TESTS
00060 static dbus_bool_t
00061 _dbus_enable_message_cache (void)
00062 {
00063 static int enabled = -1;
00064
00065 if (enabled < 0)
00066 {
00067 const char *s = _dbus_getenv ("DBUS_MESSAGE_CACHE");
00068
00069 enabled = TRUE;
00070
00071 if (s && *s)
00072 {
00073 if (*s == '0')
00074 enabled = FALSE;
00075 else if (*s == '1')
00076 enabled = TRUE;
00077 else
00078 _dbus_warn ("DBUS_MESSAGE_CACHE should be 0 or 1 if set, not '%s'",
00079 s);
00080 }
00081 }
00082
00083 return enabled;
00084 }
00085 #else
00086
00087 # define _dbus_enable_message_cache() (TRUE)
00088 #endif
00089
00090 #ifndef _dbus_message_trace_ref
00091 void
00092 _dbus_message_trace_ref (DBusMessage *message,
00093 int old_refcount,
00094 int new_refcount,
00095 const char *why)
00096 {
00097 static int enabled = -1;
00098
00099 _dbus_trace_ref ("DBusMessage", message, old_refcount, new_refcount, why,
00100 "DBUS_MESSAGE_TRACE", &enabled);
00101 }
00102 #endif
00103
00104
00105
00107 _DBUS_STRING_DEFINE_STATIC(_dbus_empty_signature_str, "");
00108
00109
00110
00111
00112 enum {
00113 DBUS_MESSAGE_ITER_TYPE_READER = 3,
00114 DBUS_MESSAGE_ITER_TYPE_WRITER = 7
00115 };
00116
00118 typedef struct DBusMessageRealIter DBusMessageRealIter;
00119
00125 struct DBusMessageRealIter
00126 {
00127 DBusMessage *message;
00128 dbus_uint32_t changed_stamp : CHANGED_STAMP_BITS;
00129 dbus_uint32_t iter_type : 3;
00130 dbus_uint32_t sig_refcount : 8;
00131 union
00132 {
00133 DBusTypeWriter writer;
00134 DBusTypeReader reader;
00135 } u;
00136 };
00137
00138 static void
00139 get_const_signature (DBusHeader *header,
00140 const DBusString **type_str_p,
00141 int *type_pos_p)
00142 {
00143 if (_dbus_header_get_field_raw (header,
00144 DBUS_HEADER_FIELD_SIGNATURE,
00145 type_str_p,
00146 type_pos_p))
00147 {
00148 *type_pos_p += 1;
00149 }
00150 else
00151 {
00152 *type_str_p = &_dbus_empty_signature_str;
00153 *type_pos_p = 0;
00154 }
00155 }
00156
00162 static void
00163 _dbus_message_byteswap (DBusMessage *message)
00164 {
00165 const DBusString *type_str;
00166 int type_pos;
00167 char byte_order;
00168
00169 byte_order = _dbus_header_get_byte_order (&message->header);
00170
00171 if (byte_order == DBUS_COMPILER_BYTE_ORDER)
00172 return;
00173
00174 _dbus_verbose ("Swapping message into compiler byte order\n");
00175
00176 get_const_signature (&message->header, &type_str, &type_pos);
00177
00178 _dbus_marshal_byteswap (type_str, type_pos,
00179 byte_order,
00180 DBUS_COMPILER_BYTE_ORDER,
00181 &message->body, 0);
00182
00183 _dbus_header_byteswap (&message->header, DBUS_COMPILER_BYTE_ORDER);
00184 _dbus_assert (_dbus_header_get_byte_order (&message->header) ==
00185 DBUS_COMPILER_BYTE_ORDER);
00186 }
00187
00194 #define ensure_byte_order(message) _dbus_message_byteswap (message)
00195
00206 void
00207 _dbus_message_get_network_data (DBusMessage *message,
00208 const DBusString **header,
00209 const DBusString **body)
00210 {
00211 _dbus_assert (message->locked);
00212
00213 *header = &message->header.data;
00214 *body = &message->body;
00215 }
00216
00226 void _dbus_message_get_unix_fds(DBusMessage *message,
00227 const int **fds,
00228 unsigned *n_fds)
00229 {
00230 _dbus_assert (message->locked);
00231
00232 #ifdef HAVE_UNIX_FD_PASSING
00233 *fds = message->unix_fds;
00234 *n_fds = message->n_unix_fds;
00235 #else
00236 *fds = NULL;
00237 *n_fds = 0;
00238 #endif
00239 }
00240
00252 void
00253 dbus_message_set_serial (DBusMessage *message,
00254 dbus_uint32_t serial)
00255 {
00256 _dbus_return_if_fail (message != NULL);
00257 _dbus_return_if_fail (!message->locked);
00258
00259 _dbus_header_set_serial (&message->header, serial);
00260 }
00261
00278 void
00279 _dbus_message_add_counter_link (DBusMessage *message,
00280 DBusList *link)
00281 {
00282
00283
00284
00285
00286
00287
00288 if (message->counters == NULL)
00289 {
00290 message->size_counter_delta =
00291 _dbus_string_get_length (&message->header.data) +
00292 _dbus_string_get_length (&message->body);
00293
00294 #ifdef HAVE_UNIX_FD_PASSING
00295 message->unix_fd_counter_delta = message->n_unix_fds;
00296 #endif
00297
00298 #if 0
00299 _dbus_verbose ("message has size %ld\n",
00300 message->size_counter_delta);
00301 #endif
00302 }
00303
00304 _dbus_list_append_link (&message->counters, link);
00305
00306 _dbus_counter_adjust_size (link->data, message->size_counter_delta);
00307
00308 #ifdef HAVE_UNIX_FD_PASSING
00309 _dbus_counter_adjust_unix_fd (link->data, message->unix_fd_counter_delta);
00310 #endif
00311 }
00312
00327 dbus_bool_t
00328 _dbus_message_add_counter (DBusMessage *message,
00329 DBusCounter *counter)
00330 {
00331 DBusList *link;
00332
00333 link = _dbus_list_alloc_link (counter);
00334 if (link == NULL)
00335 return FALSE;
00336
00337 _dbus_counter_ref (counter);
00338 _dbus_message_add_counter_link (message, link);
00339
00340 return TRUE;
00341 }
00342
00350 void
00351 _dbus_message_remove_counter (DBusMessage *message,
00352 DBusCounter *counter)
00353 {
00354 DBusList *link;
00355
00356 link = _dbus_list_find_last (&message->counters,
00357 counter);
00358 _dbus_assert (link != NULL);
00359
00360 _dbus_list_remove_link (&message->counters, link);
00361
00362 _dbus_counter_adjust_size (counter, - message->size_counter_delta);
00363
00364 #ifdef HAVE_UNIX_FD_PASSING
00365 _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
00366 #endif
00367
00368 _dbus_counter_notify (counter);
00369 _dbus_counter_unref (counter);
00370 }
00371
00382 void
00383 dbus_message_lock (DBusMessage *message)
00384 {
00385 if (!message->locked)
00386 {
00387 _dbus_header_update_lengths (&message->header,
00388 _dbus_string_get_length (&message->body));
00389
00390
00391 _dbus_assert (_dbus_string_get_length (&message->body) == 0 ||
00392 dbus_message_get_signature (message) != NULL);
00393
00394 message->locked = TRUE;
00395 }
00396 }
00397
00398 static dbus_bool_t
00399 set_or_delete_string_field (DBusMessage *message,
00400 int field,
00401 int typecode,
00402 const char *value)
00403 {
00404 if (value == NULL)
00405 return _dbus_header_delete_field (&message->header, field);
00406 else
00407 return _dbus_header_set_field_basic (&message->header,
00408 field,
00409 typecode,
00410 &value);
00411 }
00412
00413 #if 0
00414
00438 static dbus_bool_t
00439 _dbus_message_set_signature (DBusMessage *message,
00440 const char *signature)
00441 {
00442 _dbus_return_val_if_fail (message != NULL, FALSE);
00443 _dbus_return_val_if_fail (!message->locked, FALSE);
00444 _dbus_return_val_if_fail (signature == NULL ||
00445 _dbus_check_is_valid_signature (signature));
00446
00447 _dbus_return_val_if_fail (_dbus_string_get_length (&message->body) == 0 ||
00448 signature != NULL);
00449
00450 return set_or_delete_string_field (message,
00451 DBUS_HEADER_FIELD_SIGNATURE,
00452 DBUS_TYPE_SIGNATURE,
00453 signature);
00454 }
00455 #endif
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00504 #define MAX_MESSAGE_SIZE_TO_CACHE 10 * _DBUS_ONE_KILOBYTE
00505
00507 #define MAX_MESSAGE_CACHE_SIZE 5
00508
00509 _DBUS_DEFINE_GLOBAL_LOCK (message_cache);
00510 static DBusMessage *message_cache[MAX_MESSAGE_CACHE_SIZE];
00511 static int message_cache_count = 0;
00512 static dbus_bool_t message_cache_shutdown_registered = FALSE;
00513
00514 static void
00515 dbus_message_cache_shutdown (void *data)
00516 {
00517 int i;
00518
00519 _DBUS_LOCK (message_cache);
00520
00521 i = 0;
00522 while (i < MAX_MESSAGE_CACHE_SIZE)
00523 {
00524 if (message_cache[i])
00525 dbus_message_finalize (message_cache[i]);
00526
00527 ++i;
00528 }
00529
00530 message_cache_count = 0;
00531 message_cache_shutdown_registered = FALSE;
00532
00533 _DBUS_UNLOCK (message_cache);
00534 }
00535
00543 static DBusMessage*
00544 dbus_message_get_cached (void)
00545 {
00546 DBusMessage *message;
00547 int i;
00548
00549 message = NULL;
00550
00551 _DBUS_LOCK (message_cache);
00552
00553 _dbus_assert (message_cache_count >= 0);
00554
00555 if (message_cache_count == 0)
00556 {
00557 _DBUS_UNLOCK (message_cache);
00558 return NULL;
00559 }
00560
00561
00562
00563
00564
00565 _dbus_assert (message_cache_shutdown_registered);
00566
00567 i = 0;
00568 while (i < MAX_MESSAGE_CACHE_SIZE)
00569 {
00570 if (message_cache[i])
00571 {
00572 message = message_cache[i];
00573 message_cache[i] = NULL;
00574 message_cache_count -= 1;
00575 break;
00576 }
00577 ++i;
00578 }
00579 _dbus_assert (message_cache_count >= 0);
00580 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
00581 _dbus_assert (message != NULL);
00582
00583 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
00584
00585 _dbus_assert (message->counters == NULL);
00586
00587 _DBUS_UNLOCK (message_cache);
00588
00589 return message;
00590 }
00591
00592 #ifdef HAVE_UNIX_FD_PASSING
00593 static void
00594 close_unix_fds(int *fds, unsigned *n_fds)
00595 {
00596 DBusError e;
00597 int i;
00598
00599 if (*n_fds <= 0)
00600 return;
00601
00602 dbus_error_init(&e);
00603
00604 for (i = 0; i < *n_fds; i++)
00605 {
00606 if (!_dbus_close(fds[i], &e))
00607 {
00608 _dbus_warn("Failed to close file descriptor: %s\n", e.message);
00609 dbus_error_free(&e);
00610 }
00611 }
00612
00613 *n_fds = 0;
00614
00615
00616 }
00617 #endif
00618
00619 static void
00620 free_counter (void *element,
00621 void *data)
00622 {
00623 DBusCounter *counter = element;
00624 DBusMessage *message = data;
00625
00626 _dbus_counter_adjust_size (counter, - message->size_counter_delta);
00627 #ifdef HAVE_UNIX_FD_PASSING
00628 _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
00629 #endif
00630
00631 _dbus_counter_notify (counter);
00632 _dbus_counter_unref (counter);
00633 }
00634
00640 static void
00641 dbus_message_cache_or_finalize (DBusMessage *message)
00642 {
00643 dbus_bool_t was_cached;
00644 int i;
00645
00646 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
00647
00648
00649
00650
00651 _dbus_data_slot_list_clear (&message->slot_list);
00652
00653 _dbus_list_foreach (&message->counters,
00654 free_counter, message);
00655 _dbus_list_clear (&message->counters);
00656
00657 #ifdef HAVE_UNIX_FD_PASSING
00658 close_unix_fds(message->unix_fds, &message->n_unix_fds);
00659 #endif
00660
00661 was_cached = FALSE;
00662
00663 _DBUS_LOCK (message_cache);
00664
00665 if (!message_cache_shutdown_registered)
00666 {
00667 _dbus_assert (message_cache_count == 0);
00668
00669 if (!_dbus_register_shutdown_func (dbus_message_cache_shutdown, NULL))
00670 goto out;
00671
00672 i = 0;
00673 while (i < MAX_MESSAGE_CACHE_SIZE)
00674 {
00675 message_cache[i] = NULL;
00676 ++i;
00677 }
00678
00679 message_cache_shutdown_registered = TRUE;
00680 }
00681
00682 _dbus_assert (message_cache_count >= 0);
00683
00684 if (!_dbus_enable_message_cache ())
00685 goto out;
00686
00687 if ((_dbus_string_get_length (&message->header.data) +
00688 _dbus_string_get_length (&message->body)) >
00689 MAX_MESSAGE_SIZE_TO_CACHE)
00690 goto out;
00691
00692 if (message_cache_count >= MAX_MESSAGE_CACHE_SIZE)
00693 goto out;
00694
00695
00696 i = 0;
00697 while (message_cache[i] != NULL)
00698 ++i;
00699
00700 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
00701
00702 _dbus_assert (message_cache[i] == NULL);
00703 message_cache[i] = message;
00704 message_cache_count += 1;
00705 was_cached = TRUE;
00706 #ifndef DBUS_DISABLE_CHECKS
00707 message->in_cache = TRUE;
00708 #endif
00709
00710 out:
00711 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
00712
00713 _DBUS_UNLOCK (message_cache);
00714
00715 if (!was_cached)
00716 dbus_message_finalize (message);
00717 }
00718
00719 #ifndef DBUS_DISABLE_CHECKS
00720 static dbus_bool_t
00721 _dbus_message_iter_check (DBusMessageRealIter *iter)
00722 {
00723 char byte_order;
00724
00725 if (iter == NULL)
00726 {
00727 _dbus_warn_check_failed ("dbus message iterator is NULL\n");
00728 return FALSE;
00729 }
00730
00731 byte_order = _dbus_header_get_byte_order (&iter->message->header);
00732
00733 if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_READER)
00734 {
00735 if (iter->u.reader.byte_order != byte_order)
00736 {
00737 _dbus_warn_check_failed ("dbus message changed byte order since iterator was created\n");
00738 return FALSE;
00739 }
00740
00741 _dbus_assert (iter->u.reader.byte_order == DBUS_COMPILER_BYTE_ORDER);
00742 }
00743 else if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER)
00744 {
00745 if (iter->u.writer.byte_order != byte_order)
00746 {
00747 _dbus_warn_check_failed ("dbus message changed byte order since append iterator was created\n");
00748 return FALSE;
00749 }
00750
00751 _dbus_assert (iter->u.writer.byte_order == DBUS_COMPILER_BYTE_ORDER);
00752 }
00753 else
00754 {
00755 _dbus_warn_check_failed ("dbus message iterator looks uninitialized or corrupted\n");
00756 return FALSE;
00757 }
00758
00759 if (iter->changed_stamp != iter->message->changed_stamp)
00760 {
00761 _dbus_warn_check_failed ("dbus message iterator invalid because the message has been modified (or perhaps the iterator is just uninitialized)\n");
00762 return FALSE;
00763 }
00764
00765 return TRUE;
00766 }
00767 #endif
00768
00783 dbus_bool_t
00784 _dbus_message_iter_get_args_valist (DBusMessageIter *iter,
00785 DBusError *error,
00786 int first_arg_type,
00787 va_list var_args)
00788 {
00789 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
00790 int spec_type, msg_type, i;
00791 dbus_bool_t retval;
00792
00793 _dbus_assert (_dbus_message_iter_check (real));
00794
00795 retval = FALSE;
00796
00797 spec_type = first_arg_type;
00798 i = 0;
00799
00800 while (spec_type != DBUS_TYPE_INVALID)
00801 {
00802 msg_type = dbus_message_iter_get_arg_type (iter);
00803
00804 if (msg_type != spec_type)
00805 {
00806 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
00807 "Argument %d is specified to be of type \"%s\", but "
00808 "is actually of type \"%s\"\n", i,
00809 _dbus_type_to_string (spec_type),
00810 _dbus_type_to_string (msg_type));
00811
00812 goto out;
00813 }
00814
00815 if (spec_type == DBUS_TYPE_UNIX_FD)
00816 {
00817 #ifdef HAVE_UNIX_FD_PASSING
00818 DBusBasicValue idx;
00819 int *pfd, nfd;
00820
00821 pfd = va_arg (var_args, int*);
00822 _dbus_assert(pfd);
00823
00824 _dbus_type_reader_read_basic(&real->u.reader, &idx);
00825
00826 if (idx.u32 >= real->message->n_unix_fds)
00827 {
00828 dbus_set_error (error, DBUS_ERROR_INCONSISTENT_MESSAGE,
00829 "Message refers to file descriptor at index %i,"
00830 "but has only %i descriptors attached.\n",
00831 idx.u32,
00832 real->message->n_unix_fds);
00833 goto out;
00834 }
00835
00836 if ((nfd = _dbus_dup(real->message->unix_fds[idx.u32], error)) < 0)
00837 goto out;
00838
00839 *pfd = nfd;
00840 #else
00841 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00842 "Platform does not support file desciptor passing.\n");
00843 goto out;
00844 #endif
00845 }
00846 else if (dbus_type_is_basic (spec_type))
00847 {
00848 DBusBasicValue *ptr;
00849
00850 ptr = va_arg (var_args, DBusBasicValue*);
00851
00852 _dbus_assert (ptr != NULL);
00853
00854 _dbus_type_reader_read_basic (&real->u.reader,
00855 ptr);
00856 }
00857 else if (spec_type == DBUS_TYPE_ARRAY)
00858 {
00859 int element_type;
00860 int spec_element_type;
00861 const DBusBasicValue **ptr;
00862 int *n_elements_p;
00863 DBusTypeReader array;
00864
00865 spec_element_type = va_arg (var_args, int);
00866 element_type = _dbus_type_reader_get_element_type (&real->u.reader);
00867
00868 if (spec_element_type != element_type)
00869 {
00870 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
00871 "Argument %d is specified to be an array of \"%s\", but "
00872 "is actually an array of \"%s\"\n",
00873 i,
00874 _dbus_type_to_string (spec_element_type),
00875 _dbus_type_to_string (element_type));
00876
00877 goto out;
00878 }
00879
00880 if (dbus_type_is_fixed (spec_element_type) &&
00881 element_type != DBUS_TYPE_UNIX_FD)
00882 {
00883 ptr = va_arg (var_args, const DBusBasicValue**);
00884 n_elements_p = va_arg (var_args, int*);
00885
00886 _dbus_assert (ptr != NULL);
00887 _dbus_assert (n_elements_p != NULL);
00888
00889 _dbus_type_reader_recurse (&real->u.reader, &array);
00890
00891 _dbus_type_reader_read_fixed_multi (&array,
00892 (void *) ptr, n_elements_p);
00893 }
00894 else if (_DBUS_TYPE_IS_STRINGLIKE (spec_element_type))
00895 {
00896 char ***str_array_p;
00897 int n_elements;
00898 char **str_array;
00899
00900 str_array_p = va_arg (var_args, char***);
00901 n_elements_p = va_arg (var_args, int*);
00902
00903 _dbus_assert (str_array_p != NULL);
00904 _dbus_assert (n_elements_p != NULL);
00905
00906
00907 _dbus_type_reader_recurse (&real->u.reader, &array);
00908
00909 n_elements = 0;
00910 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
00911 {
00912 ++n_elements;
00913 _dbus_type_reader_next (&array);
00914 }
00915
00916 str_array = dbus_new0 (char*, n_elements + 1);
00917 if (str_array == NULL)
00918 {
00919 _DBUS_SET_OOM (error);
00920 goto out;
00921 }
00922
00923
00924 _dbus_type_reader_recurse (&real->u.reader, &array);
00925
00926 i = 0;
00927 while (i < n_elements)
00928 {
00929 const char *s;
00930 _dbus_type_reader_read_basic (&array,
00931 (void *) &s);
00932
00933 str_array[i] = _dbus_strdup (s);
00934 if (str_array[i] == NULL)
00935 {
00936 dbus_free_string_array (str_array);
00937 _DBUS_SET_OOM (error);
00938 goto out;
00939 }
00940
00941 ++i;
00942
00943 if (!_dbus_type_reader_next (&array))
00944 _dbus_assert (i == n_elements);
00945 }
00946
00947 _dbus_assert (_dbus_type_reader_get_current_type (&array) == DBUS_TYPE_INVALID);
00948 _dbus_assert (i == n_elements);
00949 _dbus_assert (str_array[i] == NULL);
00950
00951 *str_array_p = str_array;
00952 *n_elements_p = n_elements;
00953 }
00954 #ifndef DBUS_DISABLE_CHECKS
00955 else
00956 {
00957 _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now\n",
00958 _DBUS_FUNCTION_NAME);
00959 goto out;
00960 }
00961 #endif
00962 }
00963 #ifndef DBUS_DISABLE_CHECKS
00964 else
00965 {
00966 _dbus_warn ("you can only read arrays and basic types with %s for now\n",
00967 _DBUS_FUNCTION_NAME);
00968 goto out;
00969 }
00970 #endif
00971
00972 spec_type = va_arg (var_args, int);
00973 if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID)
00974 {
00975 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
00976 "Message has only %d arguments, but more were expected", i);
00977 goto out;
00978 }
00979
00980 i++;
00981 }
00982
00983 retval = TRUE;
00984
00985 out:
00986
00987 return retval;
00988 }
00989
01048 dbus_uint32_t
01049 dbus_message_get_serial (DBusMessage *message)
01050 {
01051 _dbus_return_val_if_fail (message != NULL, 0);
01052
01053 return _dbus_header_get_serial (&message->header);
01054 }
01055
01064 dbus_bool_t
01065 dbus_message_set_reply_serial (DBusMessage *message,
01066 dbus_uint32_t reply_serial)
01067 {
01068 _dbus_return_val_if_fail (message != NULL, FALSE);
01069 _dbus_return_val_if_fail (!message->locked, FALSE);
01070 _dbus_return_val_if_fail (reply_serial != 0, FALSE);
01071
01072 return _dbus_header_set_field_basic (&message->header,
01073 DBUS_HEADER_FIELD_REPLY_SERIAL,
01074 DBUS_TYPE_UINT32,
01075 &reply_serial);
01076 }
01077
01084 dbus_uint32_t
01085 dbus_message_get_reply_serial (DBusMessage *message)
01086 {
01087 dbus_uint32_t v_UINT32;
01088
01089 _dbus_return_val_if_fail (message != NULL, 0);
01090
01091 if (_dbus_header_get_field_basic (&message->header,
01092 DBUS_HEADER_FIELD_REPLY_SERIAL,
01093 DBUS_TYPE_UINT32,
01094 &v_UINT32))
01095 return v_UINT32;
01096 else
01097 return 0;
01098 }
01099
01100 static void
01101 dbus_message_finalize (DBusMessage *message)
01102 {
01103 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
01104
01105
01106 _dbus_data_slot_list_free (&message->slot_list);
01107
01108 _dbus_list_foreach (&message->counters,
01109 free_counter, message);
01110 _dbus_list_clear (&message->counters);
01111
01112 _dbus_header_free (&message->header);
01113 _dbus_string_free (&message->body);
01114
01115 #ifdef HAVE_UNIX_FD_PASSING
01116 close_unix_fds(message->unix_fds, &message->n_unix_fds);
01117 dbus_free(message->unix_fds);
01118 #endif
01119
01120 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
01121
01122 dbus_free (message);
01123 }
01124
01125 static DBusMessage*
01126 dbus_message_new_empty_header (void)
01127 {
01128 DBusMessage *message;
01129 dbus_bool_t from_cache;
01130
01131 message = dbus_message_get_cached ();
01132
01133 if (message != NULL)
01134 {
01135 from_cache = TRUE;
01136 }
01137 else
01138 {
01139 from_cache = FALSE;
01140 message = dbus_new0 (DBusMessage, 1);
01141 if (message == NULL)
01142 return NULL;
01143 #ifndef DBUS_DISABLE_CHECKS
01144 message->generation = _dbus_current_generation;
01145 #endif
01146
01147 #ifdef HAVE_UNIX_FD_PASSING
01148 message->unix_fds = NULL;
01149 message->n_unix_fds_allocated = 0;
01150 #endif
01151 }
01152
01153 _dbus_atomic_inc (&message->refcount);
01154
01155 _dbus_message_trace_ref (message, 0, 1, "new_empty_header");
01156
01157 message->locked = FALSE;
01158 #ifndef DBUS_DISABLE_CHECKS
01159 message->in_cache = FALSE;
01160 #endif
01161 message->counters = NULL;
01162 message->size_counter_delta = 0;
01163 message->changed_stamp = 0;
01164
01165 #ifdef HAVE_UNIX_FD_PASSING
01166 message->n_unix_fds = 0;
01167 message->n_unix_fds_allocated = 0;
01168 message->unix_fd_counter_delta = 0;
01169 #endif
01170
01171 if (!from_cache)
01172 _dbus_data_slot_list_init (&message->slot_list);
01173
01174 if (from_cache)
01175 {
01176 _dbus_header_reinit (&message->header);
01177 _dbus_string_set_length (&message->body, 0);
01178 }
01179 else
01180 {
01181 if (!_dbus_header_init (&message->header))
01182 {
01183 dbus_free (message);
01184 return NULL;
01185 }
01186
01187 if (!_dbus_string_init_preallocated (&message->body, 32))
01188 {
01189 _dbus_header_free (&message->header);
01190 dbus_free (message);
01191 return NULL;
01192 }
01193 }
01194
01195 return message;
01196 }
01197
01210 DBusMessage*
01211 dbus_message_new (int message_type)
01212 {
01213 DBusMessage *message;
01214
01215 _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
01216
01217 message = dbus_message_new_empty_header ();
01218 if (message == NULL)
01219 return NULL;
01220
01221 if (!_dbus_header_create (&message->header,
01222 DBUS_COMPILER_BYTE_ORDER,
01223 message_type,
01224 NULL, NULL, NULL, NULL, NULL))
01225 {
01226 dbus_message_unref (message);
01227 return NULL;
01228 }
01229
01230 return message;
01231 }
01232
01254 DBusMessage*
01255 dbus_message_new_method_call (const char *destination,
01256 const char *path,
01257 const char *interface,
01258 const char *method)
01259 {
01260 DBusMessage *message;
01261
01262 _dbus_return_val_if_fail (path != NULL, NULL);
01263 _dbus_return_val_if_fail (method != NULL, NULL);
01264 _dbus_return_val_if_fail (destination == NULL ||
01265 _dbus_check_is_valid_bus_name (destination), NULL);
01266 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
01267 _dbus_return_val_if_fail (interface == NULL ||
01268 _dbus_check_is_valid_interface (interface), NULL);
01269 _dbus_return_val_if_fail (_dbus_check_is_valid_member (method), NULL);
01270
01271 message = dbus_message_new_empty_header ();
01272 if (message == NULL)
01273 return NULL;
01274
01275 if (!_dbus_header_create (&message->header,
01276 DBUS_COMPILER_BYTE_ORDER,
01277 DBUS_MESSAGE_TYPE_METHOD_CALL,
01278 destination, path, interface, method, NULL))
01279 {
01280 dbus_message_unref (message);
01281 return NULL;
01282 }
01283
01284 return message;
01285 }
01286
01294 DBusMessage*
01295 dbus_message_new_method_return (DBusMessage *method_call)
01296 {
01297 DBusMessage *message;
01298 const char *sender;
01299
01300 _dbus_return_val_if_fail (method_call != NULL, NULL);
01301
01302 sender = dbus_message_get_sender (method_call);
01303
01304
01305
01306 message = dbus_message_new_empty_header ();
01307 if (message == NULL)
01308 return NULL;
01309
01310 if (!_dbus_header_create (&message->header,
01311 DBUS_COMPILER_BYTE_ORDER,
01312 DBUS_MESSAGE_TYPE_METHOD_RETURN,
01313 sender, NULL, NULL, NULL, NULL))
01314 {
01315 dbus_message_unref (message);
01316 return NULL;
01317 }
01318
01319 dbus_message_set_no_reply (message, TRUE);
01320
01321 if (!dbus_message_set_reply_serial (message,
01322 dbus_message_get_serial (method_call)))
01323 {
01324 dbus_message_unref (message);
01325 return NULL;
01326 }
01327
01328 return message;
01329 }
01330
01345 DBusMessage*
01346 dbus_message_new_signal (const char *path,
01347 const char *interface,
01348 const char *name)
01349 {
01350 DBusMessage *message;
01351
01352 _dbus_return_val_if_fail (path != NULL, NULL);
01353 _dbus_return_val_if_fail (interface != NULL, NULL);
01354 _dbus_return_val_if_fail (name != NULL, NULL);
01355 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
01356 _dbus_return_val_if_fail (_dbus_check_is_valid_interface (interface), NULL);
01357 _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);
01358
01359 message = dbus_message_new_empty_header ();
01360 if (message == NULL)
01361 return NULL;
01362
01363 if (!_dbus_header_create (&message->header,
01364 DBUS_COMPILER_BYTE_ORDER,
01365 DBUS_MESSAGE_TYPE_SIGNAL,
01366 NULL, path, interface, name, NULL))
01367 {
01368 dbus_message_unref (message);
01369 return NULL;
01370 }
01371
01372 dbus_message_set_no_reply (message, TRUE);
01373
01374 return message;
01375 }
01376
01391 DBusMessage*
01392 dbus_message_new_error (DBusMessage *reply_to,
01393 const char *error_name,
01394 const char *error_message)
01395 {
01396 DBusMessage *message;
01397 const char *sender;
01398 DBusMessageIter iter;
01399
01400 _dbus_return_val_if_fail (reply_to != NULL, NULL);
01401 _dbus_return_val_if_fail (error_name != NULL, NULL);
01402 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
01403
01404 sender = dbus_message_get_sender (reply_to);
01405
01406
01407
01408
01409
01410 message = dbus_message_new_empty_header ();
01411 if (message == NULL)
01412 return NULL;
01413
01414 if (!_dbus_header_create (&message->header,
01415 DBUS_COMPILER_BYTE_ORDER,
01416 DBUS_MESSAGE_TYPE_ERROR,
01417 sender, NULL, NULL, NULL, error_name))
01418 {
01419 dbus_message_unref (message);
01420 return NULL;
01421 }
01422
01423 dbus_message_set_no_reply (message, TRUE);
01424
01425 if (!dbus_message_set_reply_serial (message,
01426 dbus_message_get_serial (reply_to)))
01427 {
01428 dbus_message_unref (message);
01429 return NULL;
01430 }
01431
01432 if (error_message != NULL)
01433 {
01434 dbus_message_iter_init_append (message, &iter);
01435 if (!dbus_message_iter_append_basic (&iter,
01436 DBUS_TYPE_STRING,
01437 &error_message))
01438 {
01439 dbus_message_unref (message);
01440 return NULL;
01441 }
01442 }
01443
01444 return message;
01445 }
01446
01463 DBusMessage*
01464 dbus_message_new_error_printf (DBusMessage *reply_to,
01465 const char *error_name,
01466 const char *error_format,
01467 ...)
01468 {
01469 va_list args;
01470 DBusString str;
01471 DBusMessage *message;
01472
01473 _dbus_return_val_if_fail (reply_to != NULL, NULL);
01474 _dbus_return_val_if_fail (error_name != NULL, NULL);
01475 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
01476
01477 if (!_dbus_string_init (&str))
01478 return NULL;
01479
01480 va_start (args, error_format);
01481
01482 if (_dbus_string_append_printf_valist (&str, error_format, args))
01483 message = dbus_message_new_error (reply_to, error_name,
01484 _dbus_string_get_const_data (&str));
01485 else
01486 message = NULL;
01487
01488 _dbus_string_free (&str);
01489
01490 va_end (args);
01491
01492 return message;
01493 }
01494
01495
01508 DBusMessage *
01509 dbus_message_copy (const DBusMessage *message)
01510 {
01511 DBusMessage *retval;
01512
01513 _dbus_return_val_if_fail (message != NULL, NULL);
01514
01515 retval = dbus_new0 (DBusMessage, 1);
01516 if (retval == NULL)
01517 return NULL;
01518
01519 _dbus_atomic_inc (&retval->refcount);
01520
01521 retval->locked = FALSE;
01522 #ifndef DBUS_DISABLE_CHECKS
01523 retval->generation = message->generation;
01524 #endif
01525
01526 if (!_dbus_header_copy (&message->header, &retval->header))
01527 {
01528 dbus_free (retval);
01529 return NULL;
01530 }
01531
01532 if (!_dbus_string_init_preallocated (&retval->body,
01533 _dbus_string_get_length (&message->body)))
01534 {
01535 _dbus_header_free (&retval->header);
01536 dbus_free (retval);
01537 return NULL;
01538 }
01539
01540 if (!_dbus_string_copy (&message->body, 0,
01541 &retval->body, 0))
01542 goto failed_copy;
01543
01544 #ifdef HAVE_UNIX_FD_PASSING
01545 retval->unix_fds = dbus_new(int, message->n_unix_fds);
01546 if (retval->unix_fds == NULL && message->n_unix_fds > 0)
01547 goto failed_copy;
01548
01549 retval->n_unix_fds_allocated = message->n_unix_fds;
01550
01551 for (retval->n_unix_fds = 0;
01552 retval->n_unix_fds < message->n_unix_fds;
01553 retval->n_unix_fds++)
01554 {
01555 retval->unix_fds[retval->n_unix_fds] = _dbus_dup(message->unix_fds[retval->n_unix_fds], NULL);
01556
01557 if (retval->unix_fds[retval->n_unix_fds] < 0)
01558 goto failed_copy;
01559 }
01560
01561 #endif
01562
01563 _dbus_message_trace_ref (retval, 0, 1, "copy");
01564 return retval;
01565
01566 failed_copy:
01567 _dbus_header_free (&retval->header);
01568 _dbus_string_free (&retval->body);
01569
01570 #ifdef HAVE_UNIX_FD_PASSING
01571 close_unix_fds(retval->unix_fds, &retval->n_unix_fds);
01572 dbus_free(retval->unix_fds);
01573 #endif
01574
01575 dbus_free (retval);
01576
01577 return NULL;
01578 }
01579
01580
01588 DBusMessage *
01589 dbus_message_ref (DBusMessage *message)
01590 {
01591 dbus_int32_t old_refcount;
01592
01593 _dbus_return_val_if_fail (message != NULL, NULL);
01594 _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
01595 _dbus_return_val_if_fail (!message->in_cache, NULL);
01596
01597 old_refcount = _dbus_atomic_inc (&message->refcount);
01598 _dbus_assert (old_refcount >= 1);
01599 _dbus_message_trace_ref (message, old_refcount, old_refcount + 1, "ref");
01600
01601 return message;
01602 }
01603
01611 void
01612 dbus_message_unref (DBusMessage *message)
01613 {
01614 dbus_int32_t old_refcount;
01615
01616 _dbus_return_if_fail (message != NULL);
01617 _dbus_return_if_fail (message->generation == _dbus_current_generation);
01618 _dbus_return_if_fail (!message->in_cache);
01619
01620 old_refcount = _dbus_atomic_dec (&message->refcount);
01621
01622 _dbus_assert (old_refcount >= 1);
01623
01624 _dbus_message_trace_ref (message, old_refcount, old_refcount - 1, "unref");
01625
01626 if (old_refcount == 1)
01627 {
01628
01629 dbus_message_cache_or_finalize (message);
01630 }
01631 }
01632
01643 int
01644 dbus_message_get_type (DBusMessage *message)
01645 {
01646 _dbus_return_val_if_fail (message != NULL, DBUS_MESSAGE_TYPE_INVALID);
01647
01648 return _dbus_header_get_message_type (&message->header);
01649 }
01650
01713 dbus_bool_t
01714 dbus_message_append_args (DBusMessage *message,
01715 int first_arg_type,
01716 ...)
01717 {
01718 dbus_bool_t retval;
01719 va_list var_args;
01720
01721 _dbus_return_val_if_fail (message != NULL, FALSE);
01722
01723 va_start (var_args, first_arg_type);
01724 retval = dbus_message_append_args_valist (message,
01725 first_arg_type,
01726 var_args);
01727 va_end (var_args);
01728
01729 return retval;
01730 }
01731
01745 dbus_bool_t
01746 dbus_message_append_args_valist (DBusMessage *message,
01747 int first_arg_type,
01748 va_list var_args)
01749 {
01750 int type;
01751 DBusMessageIter iter;
01752
01753 _dbus_return_val_if_fail (message != NULL, FALSE);
01754
01755 type = first_arg_type;
01756
01757 dbus_message_iter_init_append (message, &iter);
01758
01759 while (type != DBUS_TYPE_INVALID)
01760 {
01761 if (dbus_type_is_basic (type))
01762 {
01763 const DBusBasicValue *value;
01764 value = va_arg (var_args, const DBusBasicValue*);
01765
01766 if (!dbus_message_iter_append_basic (&iter,
01767 type,
01768 value))
01769 goto failed;
01770 }
01771 else if (type == DBUS_TYPE_ARRAY)
01772 {
01773 int element_type;
01774 DBusMessageIter array;
01775 char buf[2];
01776
01777 element_type = va_arg (var_args, int);
01778
01779 buf[0] = element_type;
01780 buf[1] = '\0';
01781 if (!dbus_message_iter_open_container (&iter,
01782 DBUS_TYPE_ARRAY,
01783 buf,
01784 &array))
01785 goto failed;
01786
01787 if (dbus_type_is_fixed (element_type) &&
01788 element_type != DBUS_TYPE_UNIX_FD)
01789 {
01790 const DBusBasicValue **value;
01791 int n_elements;
01792
01793 value = va_arg (var_args, const DBusBasicValue**);
01794 n_elements = va_arg (var_args, int);
01795
01796 if (!dbus_message_iter_append_fixed_array (&array,
01797 element_type,
01798 value,
01799 n_elements)) {
01800 dbus_message_iter_abandon_container (&iter, &array);
01801 goto failed;
01802 }
01803 }
01804 else if (_DBUS_TYPE_IS_STRINGLIKE (element_type))
01805 {
01806 const char ***value_p;
01807 const char **value;
01808 int n_elements;
01809 int i;
01810
01811 value_p = va_arg (var_args, const char***);
01812 n_elements = va_arg (var_args, int);
01813
01814 value = *value_p;
01815
01816 i = 0;
01817 while (i < n_elements)
01818 {
01819 if (!dbus_message_iter_append_basic (&array,
01820 element_type,
01821 &value[i])) {
01822 dbus_message_iter_abandon_container (&iter, &array);
01823 goto failed;
01824 }
01825 ++i;
01826 }
01827 }
01828 else
01829 {
01830 _dbus_warn ("arrays of %s can't be appended with %s for now\n",
01831 _dbus_type_to_string (element_type),
01832 _DBUS_FUNCTION_NAME);
01833 goto failed;
01834 }
01835
01836 if (!dbus_message_iter_close_container (&iter, &array))
01837 goto failed;
01838 }
01839 #ifndef DBUS_DISABLE_CHECKS
01840 else
01841 {
01842 _dbus_warn ("type %s isn't supported yet in %s\n",
01843 _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
01844 goto failed;
01845 }
01846 #endif
01847
01848 type = va_arg (var_args, int);
01849 }
01850
01851 return TRUE;
01852
01853 failed:
01854 return FALSE;
01855 }
01856
01901 dbus_bool_t
01902 dbus_message_get_args (DBusMessage *message,
01903 DBusError *error,
01904 int first_arg_type,
01905 ...)
01906 {
01907 dbus_bool_t retval;
01908 va_list var_args;
01909
01910 _dbus_return_val_if_fail (message != NULL, FALSE);
01911 _dbus_return_val_if_error_is_set (error, FALSE);
01912
01913 va_start (var_args, first_arg_type);
01914 retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
01915 va_end (var_args);
01916
01917 return retval;
01918 }
01919
01930 dbus_bool_t
01931 dbus_message_get_args_valist (DBusMessage *message,
01932 DBusError *error,
01933 int first_arg_type,
01934 va_list var_args)
01935 {
01936 DBusMessageIter iter;
01937
01938 _dbus_return_val_if_fail (message != NULL, FALSE);
01939 _dbus_return_val_if_error_is_set (error, FALSE);
01940
01941 dbus_message_iter_init (message, &iter);
01942 return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
01943 }
01944
01945 static void
01946 _dbus_message_iter_init_common (DBusMessage *message,
01947 DBusMessageRealIter *real,
01948 int iter_type)
01949 {
01950 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
01951
01952
01953
01954
01955 ensure_byte_order (message);
01956
01957 real->message = message;
01958 real->changed_stamp = message->changed_stamp;
01959 real->iter_type = iter_type;
01960 real->sig_refcount = 0;
01961 }
01962
01985 dbus_bool_t
01986 dbus_message_iter_init (DBusMessage *message,
01987 DBusMessageIter *iter)
01988 {
01989 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01990 const DBusString *type_str;
01991 int type_pos;
01992
01993 _dbus_return_val_if_fail (message != NULL, FALSE);
01994 _dbus_return_val_if_fail (iter != NULL, FALSE);
01995
01996 get_const_signature (&message->header, &type_str, &type_pos);
01997
01998 _dbus_message_iter_init_common (message, real,
01999 DBUS_MESSAGE_ITER_TYPE_READER);
02000
02001 _dbus_type_reader_init (&real->u.reader,
02002 _dbus_header_get_byte_order (&message->header),
02003 type_str, type_pos,
02004 &message->body,
02005 0);
02006
02007 return _dbus_type_reader_get_current_type (&real->u.reader) != DBUS_TYPE_INVALID;
02008 }
02009
02016 dbus_bool_t
02017 dbus_message_iter_has_next (DBusMessageIter *iter)
02018 {
02019 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02020
02021 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
02022 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
02023
02024 return _dbus_type_reader_has_next (&real->u.reader);
02025 }
02026
02035 dbus_bool_t
02036 dbus_message_iter_next (DBusMessageIter *iter)
02037 {
02038 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02039
02040 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
02041 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
02042
02043 return _dbus_type_reader_next (&real->u.reader);
02044 }
02045
02060 int
02061 dbus_message_iter_get_arg_type (DBusMessageIter *iter)
02062 {
02063 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02064
02065 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
02066 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
02067
02068 return _dbus_type_reader_get_current_type (&real->u.reader);
02069 }
02070
02079 int
02080 dbus_message_iter_get_element_type (DBusMessageIter *iter)
02081 {
02082 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02083
02084 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
02085 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
02086 _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
02087
02088 return _dbus_type_reader_get_element_type (&real->u.reader);
02089 }
02090
02116 void
02117 dbus_message_iter_recurse (DBusMessageIter *iter,
02118 DBusMessageIter *sub)
02119 {
02120 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02121 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02122
02123 _dbus_return_if_fail (_dbus_message_iter_check (real));
02124 _dbus_return_if_fail (sub != NULL);
02125
02126 *real_sub = *real;
02127 _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
02128 }
02129
02141 char *
02142 dbus_message_iter_get_signature (DBusMessageIter *iter)
02143 {
02144 const DBusString *sig;
02145 DBusString retstr;
02146 char *ret;
02147 int start, len;
02148 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02149
02150 _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
02151
02152 if (!_dbus_string_init (&retstr))
02153 return NULL;
02154
02155 _dbus_type_reader_get_signature (&real->u.reader, &sig,
02156 &start, &len);
02157 if (!_dbus_string_append_len (&retstr,
02158 _dbus_string_get_const_data (sig) + start,
02159 len))
02160 return NULL;
02161 if (!_dbus_string_steal_data (&retstr, &ret))
02162 return NULL;
02163 _dbus_string_free (&retstr);
02164 return ret;
02165 }
02166
02214 void
02215 dbus_message_iter_get_basic (DBusMessageIter *iter,
02216 void *value)
02217 {
02218 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02219
02220 _dbus_return_if_fail (_dbus_message_iter_check (real));
02221 _dbus_return_if_fail (value != NULL);
02222
02223 if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_UNIX_FD)
02224 {
02225 #ifdef HAVE_UNIX_FD_PASSING
02226 DBusBasicValue idx;
02227
02228 _dbus_type_reader_read_basic(&real->u.reader, &idx);
02229
02230 if (idx.u32 >= real->message->n_unix_fds) {
02231
02232
02233 *((int*) value) = -1;
02234 return;
02235 }
02236
02237 *((int*) value) = _dbus_dup(real->message->unix_fds[idx.u32], NULL);
02238 #else
02239 *((int*) value) = -1;
02240 #endif
02241 }
02242 else
02243 {
02244 _dbus_type_reader_read_basic (&real->u.reader,
02245 value);
02246 }
02247 }
02248
02267 int
02268 dbus_message_iter_get_array_len (DBusMessageIter *iter)
02269 {
02270 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02271
02272 _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
02273
02274 return _dbus_type_reader_get_array_length (&real->u.reader);
02275 }
02276
02312 void
02313 dbus_message_iter_get_fixed_array (DBusMessageIter *iter,
02314 void *value,
02315 int *n_elements)
02316 {
02317 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02318 #ifndef DBUS_DISABLE_CHECKS
02319 int subtype = _dbus_type_reader_get_current_type(&real->u.reader);
02320
02321 _dbus_return_if_fail (_dbus_message_iter_check (real));
02322 _dbus_return_if_fail (value != NULL);
02323 _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) ||
02324 (dbus_type_is_fixed (subtype) && subtype != DBUS_TYPE_UNIX_FD));
02325 #endif
02326
02327 _dbus_type_reader_read_fixed_multi (&real->u.reader,
02328 value, n_elements);
02329 }
02330
02342 void
02343 dbus_message_iter_init_append (DBusMessage *message,
02344 DBusMessageIter *iter)
02345 {
02346 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02347
02348 _dbus_return_if_fail (message != NULL);
02349 _dbus_return_if_fail (iter != NULL);
02350
02351 _dbus_message_iter_init_common (message, real,
02352 DBUS_MESSAGE_ITER_TYPE_WRITER);
02353
02354
02355
02356
02357
02358 _dbus_type_writer_init_types_delayed (&real->u.writer,
02359 _dbus_header_get_byte_order (&message->header),
02360 &message->body,
02361 _dbus_string_get_length (&message->body));
02362 }
02363
02372 static dbus_bool_t
02373 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
02374 {
02375 DBusString *str;
02376 const DBusString *current_sig;
02377 int current_sig_pos;
02378
02379 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02380
02381 if (real->u.writer.type_str != NULL)
02382 {
02383 _dbus_assert (real->sig_refcount > 0);
02384 real->sig_refcount += 1;
02385 return TRUE;
02386 }
02387
02388 str = dbus_new (DBusString, 1);
02389 if (str == NULL)
02390 return FALSE;
02391
02392 if (!_dbus_header_get_field_raw (&real->message->header,
02393 DBUS_HEADER_FIELD_SIGNATURE,
02394 ¤t_sig, ¤t_sig_pos))
02395 current_sig = NULL;
02396
02397 if (current_sig)
02398 {
02399 int current_len;
02400
02401 current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
02402 current_sig_pos += 1;
02403
02404 if (!_dbus_string_init_preallocated (str, current_len + 4))
02405 {
02406 dbus_free (str);
02407 return FALSE;
02408 }
02409
02410 if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
02411 str, 0))
02412 {
02413 _dbus_string_free (str);
02414 dbus_free (str);
02415 return FALSE;
02416 }
02417 }
02418 else
02419 {
02420 if (!_dbus_string_init_preallocated (str, 4))
02421 {
02422 dbus_free (str);
02423 return FALSE;
02424 }
02425 }
02426
02427 real->sig_refcount = 1;
02428
02429 _dbus_type_writer_add_types (&real->u.writer,
02430 str, _dbus_string_get_length (str));
02431 return TRUE;
02432 }
02433
02443 static dbus_bool_t
02444 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
02445 {
02446 DBusString *str;
02447 const char *v_STRING;
02448 dbus_bool_t retval;
02449
02450 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02451 _dbus_assert (real->u.writer.type_str != NULL);
02452 _dbus_assert (real->sig_refcount > 0);
02453
02454 real->sig_refcount -= 1;
02455
02456 if (real->sig_refcount > 0)
02457 return TRUE;
02458 _dbus_assert (real->sig_refcount == 0);
02459
02460 retval = TRUE;
02461
02462 str = real->u.writer.type_str;
02463
02464 v_STRING = _dbus_string_get_const_data (str);
02465 if (!_dbus_header_set_field_basic (&real->message->header,
02466 DBUS_HEADER_FIELD_SIGNATURE,
02467 DBUS_TYPE_SIGNATURE,
02468 &v_STRING))
02469 retval = FALSE;
02470
02471 _dbus_type_writer_remove_types (&real->u.writer);
02472 _dbus_string_free (str);
02473 dbus_free (str);
02474
02475 return retval;
02476 }
02477
02485 static void
02486 _dbus_message_iter_abandon_signature (DBusMessageRealIter *real)
02487 {
02488 DBusString *str;
02489
02490 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02491 _dbus_assert (real->u.writer.type_str != NULL);
02492 _dbus_assert (real->sig_refcount > 0);
02493
02494 real->sig_refcount -= 1;
02495
02496 if (real->sig_refcount > 0)
02497 return;
02498 _dbus_assert (real->sig_refcount == 0);
02499
02500 str = real->u.writer.type_str;
02501
02502 _dbus_type_writer_remove_types (&real->u.writer);
02503 _dbus_string_free (str);
02504 dbus_free (str);
02505 }
02506
02507 #ifndef DBUS_DISABLE_CHECKS
02508 static dbus_bool_t
02509 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
02510 {
02511 if (!_dbus_message_iter_check (iter))
02512 return FALSE;
02513
02514 if (iter->message->locked)
02515 {
02516 _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)\n");
02517 return FALSE;
02518 }
02519
02520 return TRUE;
02521 }
02522 #endif
02523
02524 #ifdef HAVE_UNIX_FD_PASSING
02525 static int *
02526 expand_fd_array(DBusMessage *m,
02527 unsigned n)
02528 {
02529 _dbus_assert(m);
02530
02531
02532
02533
02534 if (m->n_unix_fds + n > m->n_unix_fds_allocated)
02535 {
02536 unsigned k;
02537 int *p;
02538
02539
02540 k = (m->n_unix_fds + n) * 2;
02541
02542
02543 if (k < 4)
02544 k = 4;
02545
02546 p = dbus_realloc(m->unix_fds, k * sizeof(int));
02547 if (p == NULL)
02548 return NULL;
02549
02550 m->unix_fds = p;
02551 m->n_unix_fds_allocated = k;
02552 }
02553
02554 return m->unix_fds + m->n_unix_fds;
02555 }
02556 #endif
02557
02577 dbus_bool_t
02578 dbus_message_iter_append_basic (DBusMessageIter *iter,
02579 int type,
02580 const void *value)
02581 {
02582 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02583 dbus_bool_t ret;
02584
02585 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02586 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02587 _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
02588 _dbus_return_val_if_fail (value != NULL, FALSE);
02589
02590 #ifndef DBUS_DISABLE_CHECKS
02591 switch (type)
02592 {
02593 const char * const *string_p;
02594 const dbus_bool_t *bool_p;
02595
02596 case DBUS_TYPE_STRING:
02597 string_p = value;
02598 _dbus_return_val_if_fail (_dbus_check_is_valid_utf8 (*string_p), FALSE);
02599 break;
02600
02601 case DBUS_TYPE_OBJECT_PATH:
02602 string_p = value;
02603 _dbus_return_val_if_fail (_dbus_check_is_valid_path (*string_p), FALSE);
02604 break;
02605
02606 case DBUS_TYPE_SIGNATURE:
02607 string_p = value;
02608 _dbus_return_val_if_fail (_dbus_check_is_valid_signature (*string_p), FALSE);
02609 break;
02610
02611 case DBUS_TYPE_BOOLEAN:
02612 bool_p = value;
02613 _dbus_return_val_if_fail (*bool_p == 0 || *bool_p == 1, FALSE);
02614 break;
02615
02616 default:
02617 {
02618
02619 }
02620 }
02621 #endif
02622
02623 if (!_dbus_message_iter_open_signature (real))
02624 return FALSE;
02625
02626 if (type == DBUS_TYPE_UNIX_FD)
02627 {
02628 #ifdef HAVE_UNIX_FD_PASSING
02629 int *fds;
02630 dbus_uint32_t u;
02631
02632
02633 if (!(fds = expand_fd_array(real->message, 1)))
02634 return FALSE;
02635
02636 *fds = _dbus_dup(*(int*) value, NULL);
02637 if (*fds < 0)
02638 return FALSE;
02639
02640 u = real->message->n_unix_fds;
02641
02642
02643 if (!(ret = _dbus_type_writer_write_basic (&real->u.writer, DBUS_TYPE_UNIX_FD, &u))) {
02644 _dbus_close(*fds, NULL);
02645 return FALSE;
02646 }
02647
02648 real->message->n_unix_fds += 1;
02649 u += 1;
02650
02651
02652 ret = _dbus_header_set_field_basic (&real->message->header,
02653 DBUS_HEADER_FIELD_UNIX_FDS,
02654 DBUS_TYPE_UINT32,
02655 &u);
02656
02657
02658
02659
02660
02661
02662 #else
02663 ret = FALSE;
02664 #endif
02665 }
02666 else
02667 {
02668 ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
02669 }
02670
02671 if (!_dbus_message_iter_close_signature (real))
02672 ret = FALSE;
02673
02674 return ret;
02675 }
02676
02712 dbus_bool_t
02713 dbus_message_iter_append_fixed_array (DBusMessageIter *iter,
02714 int element_type,
02715 const void *value,
02716 int n_elements)
02717 {
02718 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02719 dbus_bool_t ret;
02720
02721 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02722 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02723 _dbus_return_val_if_fail (dbus_type_is_fixed (element_type) && element_type != DBUS_TYPE_UNIX_FD, FALSE);
02724 _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
02725 _dbus_return_val_if_fail (value != NULL, FALSE);
02726 _dbus_return_val_if_fail (n_elements >= 0, FALSE);
02727 _dbus_return_val_if_fail (n_elements <=
02728 DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type),
02729 FALSE);
02730
02731 #ifndef DBUS_DISABLE_CHECKS
02732 if (element_type == DBUS_TYPE_BOOLEAN)
02733 {
02734 const dbus_bool_t * const *bools = value;
02735 int i;
02736
02737 for (i = 0; i < n_elements; i++)
02738 {
02739 _dbus_return_val_if_fail ((*bools)[i] == 0 || (*bools)[i] == 1, FALSE);
02740 }
02741 }
02742 #endif
02743
02744 ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
02745
02746 return ret;
02747 }
02748
02770 dbus_bool_t
02771 dbus_message_iter_open_container (DBusMessageIter *iter,
02772 int type,
02773 const char *contained_signature,
02774 DBusMessageIter *sub)
02775 {
02776 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02777 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02778 DBusString contained_str;
02779
02780 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02781 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02782 _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
02783 _dbus_return_val_if_fail (sub != NULL, FALSE);
02784 _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
02785 contained_signature == NULL) ||
02786 (type == DBUS_TYPE_DICT_ENTRY &&
02787 contained_signature == NULL) ||
02788 (type == DBUS_TYPE_VARIANT &&
02789 contained_signature != NULL) ||
02790 (type == DBUS_TYPE_ARRAY &&
02791 contained_signature != NULL), FALSE);
02792
02793
02794
02795
02796
02797 _dbus_return_val_if_fail ((type == DBUS_TYPE_ARRAY && contained_signature && *contained_signature == DBUS_DICT_ENTRY_BEGIN_CHAR) ||
02798 (contained_signature == NULL ||
02799 _dbus_check_is_valid_signature (contained_signature)),
02800 FALSE);
02801
02802 if (!_dbus_message_iter_open_signature (real))
02803 return FALSE;
02804
02805 *real_sub = *real;
02806
02807 if (contained_signature != NULL)
02808 {
02809 _dbus_string_init_const (&contained_str, contained_signature);
02810
02811 return _dbus_type_writer_recurse (&real->u.writer,
02812 type,
02813 &contained_str, 0,
02814 &real_sub->u.writer);
02815 }
02816 else
02817 {
02818 return _dbus_type_writer_recurse (&real->u.writer,
02819 type,
02820 NULL, 0,
02821 &real_sub->u.writer);
02822 }
02823 }
02824
02825
02839 dbus_bool_t
02840 dbus_message_iter_close_container (DBusMessageIter *iter,
02841 DBusMessageIter *sub)
02842 {
02843 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02844 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02845 dbus_bool_t ret;
02846
02847 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02848 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02849 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
02850 _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02851
02852 ret = _dbus_type_writer_unrecurse (&real->u.writer,
02853 &real_sub->u.writer);
02854
02855 if (!_dbus_message_iter_close_signature (real))
02856 ret = FALSE;
02857
02858 return ret;
02859 }
02860
02872 void
02873 dbus_message_iter_abandon_container (DBusMessageIter *iter,
02874 DBusMessageIter *sub)
02875 {
02876 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02877 #ifndef DBUS_DISABLE_CHECKS
02878 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02879
02880 _dbus_return_if_fail (_dbus_message_iter_append_check (real));
02881 _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02882 _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
02883 _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02884 #endif
02885
02886 _dbus_message_iter_abandon_signature (real);
02887 }
02888
02905 void
02906 dbus_message_set_no_reply (DBusMessage *message,
02907 dbus_bool_t no_reply)
02908 {
02909 _dbus_return_if_fail (message != NULL);
02910 _dbus_return_if_fail (!message->locked);
02911
02912 _dbus_header_toggle_flag (&message->header,
02913 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED,
02914 no_reply);
02915 }
02916
02924 dbus_bool_t
02925 dbus_message_get_no_reply (DBusMessage *message)
02926 {
02927 _dbus_return_val_if_fail (message != NULL, FALSE);
02928
02929 return _dbus_header_get_flag (&message->header,
02930 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED);
02931 }
02932
02947 void
02948 dbus_message_set_auto_start (DBusMessage *message,
02949 dbus_bool_t auto_start)
02950 {
02951 _dbus_return_if_fail (message != NULL);
02952 _dbus_return_if_fail (!message->locked);
02953
02954 _dbus_header_toggle_flag (&message->header,
02955 DBUS_HEADER_FLAG_NO_AUTO_START,
02956 !auto_start);
02957 }
02958
02966 dbus_bool_t
02967 dbus_message_get_auto_start (DBusMessage *message)
02968 {
02969 _dbus_return_val_if_fail (message != NULL, FALSE);
02970
02971 return !_dbus_header_get_flag (&message->header,
02972 DBUS_HEADER_FLAG_NO_AUTO_START);
02973 }
02974
02975
02988 dbus_bool_t
02989 dbus_message_set_path (DBusMessage *message,
02990 const char *object_path)
02991 {
02992 _dbus_return_val_if_fail (message != NULL, FALSE);
02993 _dbus_return_val_if_fail (!message->locked, FALSE);
02994 _dbus_return_val_if_fail (object_path == NULL ||
02995 _dbus_check_is_valid_path (object_path),
02996 FALSE);
02997
02998 return set_or_delete_string_field (message,
02999 DBUS_HEADER_FIELD_PATH,
03000 DBUS_TYPE_OBJECT_PATH,
03001 object_path);
03002 }
03003
03017 const char*
03018 dbus_message_get_path (DBusMessage *message)
03019 {
03020 const char *v;
03021
03022 _dbus_return_val_if_fail (message != NULL, NULL);
03023
03024 v = NULL;
03025 _dbus_header_get_field_basic (&message->header,
03026 DBUS_HEADER_FIELD_PATH,
03027 DBUS_TYPE_OBJECT_PATH,
03028 (void *) &v);
03029 return v;
03030 }
03031
03041 dbus_bool_t
03042 dbus_message_has_path (DBusMessage *message,
03043 const char *path)
03044 {
03045 const char *msg_path;
03046 msg_path = dbus_message_get_path (message);
03047
03048 if (msg_path == NULL)
03049 {
03050 if (path == NULL)
03051 return TRUE;
03052 else
03053 return FALSE;
03054 }
03055
03056 if (path == NULL)
03057 return FALSE;
03058
03059 if (strcmp (msg_path, path) == 0)
03060 return TRUE;
03061
03062 return FALSE;
03063 }
03064
03085 dbus_bool_t
03086 dbus_message_get_path_decomposed (DBusMessage *message,
03087 char ***path)
03088 {
03089 const char *v;
03090
03091 _dbus_return_val_if_fail (message != NULL, FALSE);
03092 _dbus_return_val_if_fail (path != NULL, FALSE);
03093
03094 *path = NULL;
03095
03096 v = dbus_message_get_path (message);
03097 if (v != NULL)
03098 {
03099 if (!_dbus_decompose_path (v, strlen (v),
03100 path, NULL))
03101 return FALSE;
03102 }
03103 return TRUE;
03104 }
03105
03119 dbus_bool_t
03120 dbus_message_set_interface (DBusMessage *message,
03121 const char *interface)
03122 {
03123 _dbus_return_val_if_fail (message != NULL, FALSE);
03124 _dbus_return_val_if_fail (!message->locked, FALSE);
03125 _dbus_return_val_if_fail (interface == NULL ||
03126 _dbus_check_is_valid_interface (interface),
03127 FALSE);
03128
03129 return set_or_delete_string_field (message,
03130 DBUS_HEADER_FIELD_INTERFACE,
03131 DBUS_TYPE_STRING,
03132 interface);
03133 }
03134
03148 const char*
03149 dbus_message_get_interface (DBusMessage *message)
03150 {
03151 const char *v;
03152
03153 _dbus_return_val_if_fail (message != NULL, NULL);
03154
03155 v = NULL;
03156 _dbus_header_get_field_basic (&message->header,
03157 DBUS_HEADER_FIELD_INTERFACE,
03158 DBUS_TYPE_STRING,
03159 (void *) &v);
03160 return v;
03161 }
03162
03170 dbus_bool_t
03171 dbus_message_has_interface (DBusMessage *message,
03172 const char *interface)
03173 {
03174 const char *msg_interface;
03175 msg_interface = dbus_message_get_interface (message);
03176
03177 if (msg_interface == NULL)
03178 {
03179 if (interface == NULL)
03180 return TRUE;
03181 else
03182 return FALSE;
03183 }
03184
03185 if (interface == NULL)
03186 return FALSE;
03187
03188 if (strcmp (msg_interface, interface) == 0)
03189 return TRUE;
03190
03191 return FALSE;
03192
03193 }
03194
03207 dbus_bool_t
03208 dbus_message_set_member (DBusMessage *message,
03209 const char *member)
03210 {
03211 _dbus_return_val_if_fail (message != NULL, FALSE);
03212 _dbus_return_val_if_fail (!message->locked, FALSE);
03213 _dbus_return_val_if_fail (member == NULL ||
03214 _dbus_check_is_valid_member (member),
03215 FALSE);
03216
03217 return set_or_delete_string_field (message,
03218 DBUS_HEADER_FIELD_MEMBER,
03219 DBUS_TYPE_STRING,
03220 member);
03221 }
03222
03234 const char*
03235 dbus_message_get_member (DBusMessage *message)
03236 {
03237 const char *v;
03238
03239 _dbus_return_val_if_fail (message != NULL, NULL);
03240
03241 v = NULL;
03242 _dbus_header_get_field_basic (&message->header,
03243 DBUS_HEADER_FIELD_MEMBER,
03244 DBUS_TYPE_STRING,
03245 (void *) &v);
03246 return v;
03247 }
03248
03256 dbus_bool_t
03257 dbus_message_has_member (DBusMessage *message,
03258 const char *member)
03259 {
03260 const char *msg_member;
03261 msg_member = dbus_message_get_member (message);
03262
03263 if (msg_member == NULL)
03264 {
03265 if (member == NULL)
03266 return TRUE;
03267 else
03268 return FALSE;
03269 }
03270
03271 if (member == NULL)
03272 return FALSE;
03273
03274 if (strcmp (msg_member, member) == 0)
03275 return TRUE;
03276
03277 return FALSE;
03278
03279 }
03280
03292 dbus_bool_t
03293 dbus_message_set_error_name (DBusMessage *message,
03294 const char *error_name)
03295 {
03296 _dbus_return_val_if_fail (message != NULL, FALSE);
03297 _dbus_return_val_if_fail (!message->locked, FALSE);
03298 _dbus_return_val_if_fail (error_name == NULL ||
03299 _dbus_check_is_valid_error_name (error_name),
03300 FALSE);
03301
03302 return set_or_delete_string_field (message,
03303 DBUS_HEADER_FIELD_ERROR_NAME,
03304 DBUS_TYPE_STRING,
03305 error_name);
03306 }
03307
03318 const char*
03319 dbus_message_get_error_name (DBusMessage *message)
03320 {
03321 const char *v;
03322
03323 _dbus_return_val_if_fail (message != NULL, NULL);
03324
03325 v = NULL;
03326 _dbus_header_get_field_basic (&message->header,
03327 DBUS_HEADER_FIELD_ERROR_NAME,
03328 DBUS_TYPE_STRING,
03329 (void *) &v);
03330 return v;
03331 }
03332
03346 dbus_bool_t
03347 dbus_message_set_destination (DBusMessage *message,
03348 const char *destination)
03349 {
03350 _dbus_return_val_if_fail (message != NULL, FALSE);
03351 _dbus_return_val_if_fail (!message->locked, FALSE);
03352 _dbus_return_val_if_fail (destination == NULL ||
03353 _dbus_check_is_valid_bus_name (destination),
03354 FALSE);
03355
03356 return set_or_delete_string_field (message,
03357 DBUS_HEADER_FIELD_DESTINATION,
03358 DBUS_TYPE_STRING,
03359 destination);
03360 }
03361
03371 const char*
03372 dbus_message_get_destination (DBusMessage *message)
03373 {
03374 const char *v;
03375
03376 _dbus_return_val_if_fail (message != NULL, NULL);
03377
03378 v = NULL;
03379 _dbus_header_get_field_basic (&message->header,
03380 DBUS_HEADER_FIELD_DESTINATION,
03381 DBUS_TYPE_STRING,
03382 (void *) &v);
03383 return v;
03384 }
03385
03400 dbus_bool_t
03401 dbus_message_set_sender (DBusMessage *message,
03402 const char *sender)
03403 {
03404 _dbus_return_val_if_fail (message != NULL, FALSE);
03405 _dbus_return_val_if_fail (!message->locked, FALSE);
03406 _dbus_return_val_if_fail (sender == NULL ||
03407 _dbus_check_is_valid_bus_name (sender),
03408 FALSE);
03409
03410 return set_or_delete_string_field (message,
03411 DBUS_HEADER_FIELD_SENDER,
03412 DBUS_TYPE_STRING,
03413 sender);
03414 }
03415
03431 const char*
03432 dbus_message_get_sender (DBusMessage *message)
03433 {
03434 const char *v;
03435
03436 _dbus_return_val_if_fail (message != NULL, NULL);
03437
03438 v = NULL;
03439 _dbus_header_get_field_basic (&message->header,
03440 DBUS_HEADER_FIELD_SENDER,
03441 DBUS_TYPE_STRING,
03442 (void *) &v);
03443 return v;
03444 }
03445
03464 const char*
03465 dbus_message_get_signature (DBusMessage *message)
03466 {
03467 const DBusString *type_str;
03468 int type_pos;
03469
03470 _dbus_return_val_if_fail (message != NULL, NULL);
03471
03472 get_const_signature (&message->header, &type_str, &type_pos);
03473
03474 return _dbus_string_get_const_data_len (type_str, type_pos, 0);
03475 }
03476
03477 static dbus_bool_t
03478 _dbus_message_has_type_interface_member (DBusMessage *message,
03479 int type,
03480 const char *interface,
03481 const char *member)
03482 {
03483 const char *n;
03484
03485 _dbus_assert (message != NULL);
03486 _dbus_assert (interface != NULL);
03487 _dbus_assert (member != NULL);
03488
03489 if (dbus_message_get_type (message) != type)
03490 return FALSE;
03491
03492
03493
03494
03495
03496 n = dbus_message_get_member (message);
03497
03498 if (n && strcmp (n, member) == 0)
03499 {
03500 n = dbus_message_get_interface (message);
03501
03502 if (n == NULL || strcmp (n, interface) == 0)
03503 return TRUE;
03504 }
03505
03506 return FALSE;
03507 }
03508
03523 dbus_bool_t
03524 dbus_message_is_method_call (DBusMessage *message,
03525 const char *interface,
03526 const char *method)
03527 {
03528 _dbus_return_val_if_fail (message != NULL, FALSE);
03529 _dbus_return_val_if_fail (interface != NULL, FALSE);
03530 _dbus_return_val_if_fail (method != NULL, FALSE);
03531
03532
03533
03534
03535 return _dbus_message_has_type_interface_member (message,
03536 DBUS_MESSAGE_TYPE_METHOD_CALL,
03537 interface, method);
03538 }
03539
03551 dbus_bool_t
03552 dbus_message_is_signal (DBusMessage *message,
03553 const char *interface,
03554 const char *signal_name)
03555 {
03556 _dbus_return_val_if_fail (message != NULL, FALSE);
03557 _dbus_return_val_if_fail (interface != NULL, FALSE);
03558 _dbus_return_val_if_fail (signal_name != NULL, FALSE);
03559
03560
03561
03562
03563 return _dbus_message_has_type_interface_member (message,
03564 DBUS_MESSAGE_TYPE_SIGNAL,
03565 interface, signal_name);
03566 }
03567
03578 dbus_bool_t
03579 dbus_message_is_error (DBusMessage *message,
03580 const char *error_name)
03581 {
03582 const char *n;
03583
03584 _dbus_return_val_if_fail (message != NULL, FALSE);
03585 _dbus_return_val_if_fail (error_name != NULL, FALSE);
03586
03587
03588
03589
03590 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
03591 return FALSE;
03592
03593 n = dbus_message_get_error_name (message);
03594
03595 if (n && strcmp (n, error_name) == 0)
03596 return TRUE;
03597 else
03598 return FALSE;
03599 }
03600
03611 dbus_bool_t
03612 dbus_message_has_destination (DBusMessage *message,
03613 const char *name)
03614 {
03615 const char *s;
03616
03617 _dbus_return_val_if_fail (message != NULL, FALSE);
03618 _dbus_return_val_if_fail (name != NULL, FALSE);
03619
03620
03621
03622
03623 s = dbus_message_get_destination (message);
03624
03625 if (s && strcmp (s, name) == 0)
03626 return TRUE;
03627 else
03628 return FALSE;
03629 }
03630
03646 dbus_bool_t
03647 dbus_message_has_sender (DBusMessage *message,
03648 const char *name)
03649 {
03650 const char *s;
03651
03652 _dbus_return_val_if_fail (message != NULL, FALSE);
03653 _dbus_return_val_if_fail (name != NULL, FALSE);
03654
03655
03656
03657
03658 s = dbus_message_get_sender (message);
03659
03660 if (s && strcmp (s, name) == 0)
03661 return TRUE;
03662 else
03663 return FALSE;
03664 }
03665
03675 dbus_bool_t
03676 dbus_message_has_signature (DBusMessage *message,
03677 const char *signature)
03678 {
03679 const char *s;
03680
03681 _dbus_return_val_if_fail (message != NULL, FALSE);
03682 _dbus_return_val_if_fail (signature != NULL, FALSE);
03683
03684
03685
03686
03687 s = dbus_message_get_signature (message);
03688
03689 if (s && strcmp (s, signature) == 0)
03690 return TRUE;
03691 else
03692 return FALSE;
03693 }
03694
03717 dbus_bool_t
03718 dbus_set_error_from_message (DBusError *error,
03719 DBusMessage *message)
03720 {
03721 const char *str;
03722
03723 _dbus_return_val_if_fail (message != NULL, FALSE);
03724 _dbus_return_val_if_error_is_set (error, FALSE);
03725
03726 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
03727 return FALSE;
03728
03729 str = NULL;
03730 dbus_message_get_args (message, NULL,
03731 DBUS_TYPE_STRING, &str,
03732 DBUS_TYPE_INVALID);
03733
03734 dbus_set_error (error, dbus_message_get_error_name (message),
03735 str ? "%s" : NULL, str);
03736
03737 return TRUE;
03738 }
03739
03746 dbus_bool_t
03747 dbus_message_contains_unix_fds(DBusMessage *message)
03748 {
03749 #ifdef HAVE_UNIX_FD_PASSING
03750 _dbus_assert(message);
03751
03752 return message->n_unix_fds > 0;
03753 #else
03754 return FALSE;
03755 #endif
03756 }
03757
03776 #define INITIAL_LOADER_DATA_LEN 32
03777
03784 DBusMessageLoader*
03785 _dbus_message_loader_new (void)
03786 {
03787 DBusMessageLoader *loader;
03788
03789 loader = dbus_new0 (DBusMessageLoader, 1);
03790 if (loader == NULL)
03791 return NULL;
03792
03793 loader->refcount = 1;
03794
03795 loader->corrupted = FALSE;
03796 loader->corruption_reason = DBUS_VALID;
03797
03798
03799 loader->max_message_size = DBUS_MAXIMUM_MESSAGE_LENGTH;
03800
03801
03802
03803
03804
03805 loader->max_message_unix_fds = 1024;
03806
03807 if (!_dbus_string_init (&loader->data))
03808 {
03809 dbus_free (loader);
03810 return NULL;
03811 }
03812
03813
03814 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
03815 _dbus_string_set_length (&loader->data, 0);
03816
03817 #ifdef HAVE_UNIX_FD_PASSING
03818 loader->unix_fds = NULL;
03819 loader->n_unix_fds = loader->n_unix_fds_allocated = 0;
03820 loader->unix_fds_outstanding = FALSE;
03821 #endif
03822
03823 return loader;
03824 }
03825
03832 DBusMessageLoader *
03833 _dbus_message_loader_ref (DBusMessageLoader *loader)
03834 {
03835 loader->refcount += 1;
03836
03837 return loader;
03838 }
03839
03846 void
03847 _dbus_message_loader_unref (DBusMessageLoader *loader)
03848 {
03849 loader->refcount -= 1;
03850 if (loader->refcount == 0)
03851 {
03852 #ifdef HAVE_UNIX_FD_PASSING
03853 close_unix_fds(loader->unix_fds, &loader->n_unix_fds);
03854 dbus_free(loader->unix_fds);
03855 #endif
03856 _dbus_list_foreach (&loader->messages,
03857 (DBusForeachFunction) dbus_message_unref,
03858 NULL);
03859 _dbus_list_clear (&loader->messages);
03860 _dbus_string_free (&loader->data);
03861 dbus_free (loader);
03862 }
03863 }
03864
03883 void
03884 _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
03885 DBusString **buffer)
03886 {
03887 _dbus_assert (!loader->buffer_outstanding);
03888
03889 *buffer = &loader->data;
03890
03891 loader->buffer_outstanding = TRUE;
03892 }
03893
03904 void
03905 _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
03906 DBusString *buffer,
03907 int bytes_read)
03908 {
03909 _dbus_assert (loader->buffer_outstanding);
03910 _dbus_assert (buffer == &loader->data);
03911
03912 loader->buffer_outstanding = FALSE;
03913 }
03914
03925 dbus_bool_t
03926 _dbus_message_loader_get_unix_fds(DBusMessageLoader *loader,
03927 int **fds,
03928 unsigned *max_n_fds)
03929 {
03930 #ifdef HAVE_UNIX_FD_PASSING
03931 _dbus_assert (!loader->unix_fds_outstanding);
03932
03933
03934
03935
03936
03937
03938
03939
03940
03941 if (loader->n_unix_fds_allocated < loader->max_message_unix_fds)
03942 {
03943 int *a = dbus_realloc(loader->unix_fds,
03944 loader->max_message_unix_fds * sizeof(loader->unix_fds[0]));
03945
03946 if (!a)
03947 return FALSE;
03948
03949 loader->unix_fds = a;
03950 loader->n_unix_fds_allocated = loader->max_message_unix_fds;
03951 }
03952
03953 *fds = loader->unix_fds + loader->n_unix_fds;
03954 *max_n_fds = loader->n_unix_fds_allocated - loader->n_unix_fds;
03955
03956 loader->unix_fds_outstanding = TRUE;
03957 return TRUE;
03958 #else
03959 _dbus_assert_not_reached("Platform doesn't support unix fd passing");
03960 return FALSE;
03961 #endif
03962 }
03963
03974 void
03975 _dbus_message_loader_return_unix_fds(DBusMessageLoader *loader,
03976 int *fds,
03977 unsigned n_fds)
03978 {
03979 #ifdef HAVE_UNIX_FD_PASSING
03980 _dbus_assert(loader->unix_fds_outstanding);
03981 _dbus_assert(loader->unix_fds + loader->n_unix_fds == fds);
03982 _dbus_assert(loader->n_unix_fds + n_fds <= loader->n_unix_fds_allocated);
03983
03984 loader->n_unix_fds += n_fds;
03985 loader->unix_fds_outstanding = FALSE;
03986 #else
03987 _dbus_assert_not_reached("Platform doesn't support unix fd passing");
03988 #endif
03989 }
03990
03991
03992
03993
03994
03995
03996
03997
03998
03999
04000
04001
04002
04003
04004
04005
04006
04007
04008
04009
04010
04011
04012
04013
04014
04015
04016
04017 static dbus_bool_t
04018 load_message (DBusMessageLoader *loader,
04019 DBusMessage *message,
04020 int byte_order,
04021 int fields_array_len,
04022 int header_len,
04023 int body_len)
04024 {
04025 dbus_bool_t oom;
04026 DBusValidity validity;
04027 const DBusString *type_str;
04028 int type_pos;
04029 DBusValidationMode mode;
04030 dbus_uint32_t n_unix_fds = 0;
04031
04032 mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
04033
04034 oom = FALSE;
04035
04036 #if 0
04037 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len );
04038 #endif
04039
04040
04041 _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
04042 _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
04043
04044 if (!_dbus_header_load (&message->header,
04045 mode,
04046 &validity,
04047 byte_order,
04048 fields_array_len,
04049 header_len,
04050 body_len,
04051 &loader->data, 0,
04052 _dbus_string_get_length (&loader->data)))
04053 {
04054 _dbus_verbose ("Failed to load header for new message code %d\n", validity);
04055
04056
04057
04058 _dbus_assert (validity != DBUS_VALID);
04059
04060 if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
04061 oom = TRUE;
04062 else
04063 {
04064 loader->corrupted = TRUE;
04065 loader->corruption_reason = validity;
04066 }
04067 goto failed;
04068 }
04069
04070 _dbus_assert (validity == DBUS_VALID);
04071
04072
04073 if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
04074 {
04075 get_const_signature (&message->header, &type_str, &type_pos);
04076
04077
04078
04079
04080 validity = _dbus_validate_body_with_reason (type_str,
04081 type_pos,
04082 byte_order,
04083 NULL,
04084 &loader->data,
04085 header_len,
04086 body_len);
04087 if (validity != DBUS_VALID)
04088 {
04089 _dbus_verbose ("Failed to validate message body code %d\n", validity);
04090
04091 loader->corrupted = TRUE;
04092 loader->corruption_reason = validity;
04093
04094 goto failed;
04095 }
04096 }
04097
04098
04099 _dbus_header_get_field_basic(&message->header,
04100 DBUS_HEADER_FIELD_UNIX_FDS,
04101 DBUS_TYPE_UINT32,
04102 &n_unix_fds);
04103
04104 #ifdef HAVE_UNIX_FD_PASSING
04105
04106 if (n_unix_fds > loader->n_unix_fds)
04107 {
04108 _dbus_verbose("Message contains references to more unix fds than were sent %u != %u\n",
04109 n_unix_fds, loader->n_unix_fds);
04110
04111 loader->corrupted = TRUE;
04112 loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
04113 goto failed;
04114 }
04115
04116
04117
04118 dbus_free(message->unix_fds);
04119
04120 if (n_unix_fds > 0)
04121 {
04122 message->unix_fds = _dbus_memdup(loader->unix_fds, n_unix_fds * sizeof(message->unix_fds[0]));
04123 if (message->unix_fds == NULL)
04124 {
04125 _dbus_verbose ("Failed to allocate file descriptor array\n");
04126 oom = TRUE;
04127 goto failed;
04128 }
04129
04130 message->n_unix_fds_allocated = message->n_unix_fds = n_unix_fds;
04131 loader->n_unix_fds -= n_unix_fds;
04132 memmove(loader->unix_fds + n_unix_fds, loader->unix_fds, loader->n_unix_fds);
04133 }
04134 else
04135 message->unix_fds = NULL;
04136
04137 #else
04138
04139 if (n_unix_fds > 0)
04140 {
04141 _dbus_verbose ("Hmm, message claims to come with file descriptors "
04142 "but that's not supported on our platform, disconnecting.\n");
04143
04144 loader->corrupted = TRUE;
04145 loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
04146 goto failed;
04147 }
04148
04149 #endif
04150
04151
04152
04153 if (!_dbus_list_append (&loader->messages, message))
04154 {
04155 _dbus_verbose ("Failed to append new message to loader queue\n");
04156 oom = TRUE;
04157 goto failed;
04158 }
04159
04160 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
04161 _dbus_assert (_dbus_string_get_length (&loader->data) >=
04162 (header_len + body_len));
04163
04164 if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
04165 {
04166 _dbus_verbose ("Failed to move body into new message\n");
04167 oom = TRUE;
04168 goto failed;
04169 }
04170
04171 _dbus_string_delete (&loader->data, 0, header_len + body_len);
04172
04173
04174 _dbus_string_compact (&loader->data, 2048);
04175
04176 _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
04177 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
04178
04179 _dbus_verbose ("Loaded message %p\n", message);
04180
04181 _dbus_assert (!oom);
04182 _dbus_assert (!loader->corrupted);
04183 _dbus_assert (loader->messages != NULL);
04184 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
04185
04186 return TRUE;
04187
04188 failed:
04189
04190
04191
04192
04193 _dbus_list_remove_last (&loader->messages, message);
04194
04195 if (oom)
04196 _dbus_assert (!loader->corrupted);
04197 else
04198 _dbus_assert (loader->corrupted);
04199
04200 _dbus_verbose_bytes_of_string (&loader->data, 0, _dbus_string_get_length (&loader->data));
04201
04202 return FALSE;
04203 }
04204
04219 dbus_bool_t
04220 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
04221 {
04222 while (!loader->corrupted &&
04223 _dbus_string_get_length (&loader->data) >= DBUS_MINIMUM_HEADER_SIZE)
04224 {
04225 DBusValidity validity;
04226 int byte_order, fields_array_len, header_len, body_len;
04227
04228 if (_dbus_header_have_message_untrusted (loader->max_message_size,
04229 &validity,
04230 &byte_order,
04231 &fields_array_len,
04232 &header_len,
04233 &body_len,
04234 &loader->data, 0,
04235 _dbus_string_get_length (&loader->data)))
04236 {
04237 DBusMessage *message;
04238
04239 _dbus_assert (validity == DBUS_VALID);
04240
04241 message = dbus_message_new_empty_header ();
04242 if (message == NULL)
04243 return FALSE;
04244
04245 if (!load_message (loader, message,
04246 byte_order, fields_array_len,
04247 header_len, body_len))
04248 {
04249 dbus_message_unref (message);
04250
04251
04252
04253 return loader->corrupted;
04254 }
04255
04256 _dbus_assert (loader->messages != NULL);
04257 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
04258 }
04259 else
04260 {
04261 _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
04262 validity);
04263 if (validity != DBUS_VALID)
04264 {
04265 loader->corrupted = TRUE;
04266 loader->corruption_reason = validity;
04267 }
04268 return TRUE;
04269 }
04270 }
04271
04272 return TRUE;
04273 }
04274
04282 DBusMessage*
04283 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
04284 {
04285 if (loader->messages)
04286 return loader->messages->data;
04287 else
04288 return NULL;
04289 }
04290
04299 DBusMessage*
04300 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
04301 {
04302 return _dbus_list_pop_first (&loader->messages);
04303 }
04304
04313 DBusList*
04314 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
04315 {
04316 return _dbus_list_pop_first_link (&loader->messages);
04317 }
04318
04325 void
04326 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
04327 DBusList *link)
04328 {
04329 _dbus_list_prepend_link (&loader->messages, link);
04330 }
04331
04341 dbus_bool_t
04342 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
04343 {
04344 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
04345 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
04346 return loader->corrupted;
04347 }
04348
04355 DBusValidity
04356 _dbus_message_loader_get_corruption_reason (DBusMessageLoader *loader)
04357 {
04358 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
04359 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
04360
04361 return loader->corruption_reason;
04362 }
04363
04370 void
04371 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
04372 long size)
04373 {
04374 if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
04375 {
04376 _dbus_verbose ("clamping requested max message size %ld to %d\n",
04377 size, DBUS_MAXIMUM_MESSAGE_LENGTH);
04378 size = DBUS_MAXIMUM_MESSAGE_LENGTH;
04379 }
04380 loader->max_message_size = size;
04381 }
04382
04389 long
04390 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
04391 {
04392 return loader->max_message_size;
04393 }
04394
04401 void
04402 _dbus_message_loader_set_max_message_unix_fds (DBusMessageLoader *loader,
04403 long n)
04404 {
04405 if (n > DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
04406 {
04407 _dbus_verbose ("clamping requested max message unix_fds %ld to %d\n",
04408 n, DBUS_MAXIMUM_MESSAGE_UNIX_FDS);
04409 n = DBUS_MAXIMUM_MESSAGE_UNIX_FDS;
04410 }
04411 loader->max_message_unix_fds = n;
04412 }
04413
04420 long
04421 _dbus_message_loader_get_max_message_unix_fds (DBusMessageLoader *loader)
04422 {
04423 return loader->max_message_unix_fds;
04424 }
04425
04426 static DBusDataSlotAllocator slot_allocator;
04427 _DBUS_DEFINE_GLOBAL_LOCK (message_slots);
04428
04443 dbus_bool_t
04444 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
04445 {
04446 return _dbus_data_slot_allocator_alloc (&slot_allocator,
04447 &_DBUS_LOCK_NAME (message_slots),
04448 slot_p);
04449 }
04450
04462 void
04463 dbus_message_free_data_slot (dbus_int32_t *slot_p)
04464 {
04465 _dbus_return_if_fail (*slot_p >= 0);
04466
04467 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
04468 }
04469
04483 dbus_bool_t
04484 dbus_message_set_data (DBusMessage *message,
04485 dbus_int32_t slot,
04486 void *data,
04487 DBusFreeFunction free_data_func)
04488 {
04489 DBusFreeFunction old_free_func;
04490 void *old_data;
04491 dbus_bool_t retval;
04492
04493 _dbus_return_val_if_fail (message != NULL, FALSE);
04494 _dbus_return_val_if_fail (slot >= 0, FALSE);
04495
04496 retval = _dbus_data_slot_list_set (&slot_allocator,
04497 &message->slot_list,
04498 slot, data, free_data_func,
04499 &old_free_func, &old_data);
04500
04501 if (retval)
04502 {
04503
04504 if (old_free_func)
04505 (* old_free_func) (old_data);
04506 }
04507
04508 return retval;
04509 }
04510
04519 void*
04520 dbus_message_get_data (DBusMessage *message,
04521 dbus_int32_t slot)
04522 {
04523 void *res;
04524
04525 _dbus_return_val_if_fail (message != NULL, NULL);
04526
04527 res = _dbus_data_slot_list_get (&slot_allocator,
04528 &message->slot_list,
04529 slot);
04530
04531 return res;
04532 }
04533
04547 int
04548 dbus_message_type_from_string (const char *type_str)
04549 {
04550 if (strcmp (type_str, "method_call") == 0)
04551 return DBUS_MESSAGE_TYPE_METHOD_CALL;
04552 if (strcmp (type_str, "method_return") == 0)
04553 return DBUS_MESSAGE_TYPE_METHOD_RETURN;
04554 else if (strcmp (type_str, "signal") == 0)
04555 return DBUS_MESSAGE_TYPE_SIGNAL;
04556 else if (strcmp (type_str, "error") == 0)
04557 return DBUS_MESSAGE_TYPE_ERROR;
04558 else
04559 return DBUS_MESSAGE_TYPE_INVALID;
04560 }
04561
04575 const char *
04576 dbus_message_type_to_string (int type)
04577 {
04578 switch (type)
04579 {
04580 case DBUS_MESSAGE_TYPE_METHOD_CALL:
04581 return "method_call";
04582 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
04583 return "method_return";
04584 case DBUS_MESSAGE_TYPE_SIGNAL:
04585 return "signal";
04586 case DBUS_MESSAGE_TYPE_ERROR:
04587 return "error";
04588 default:
04589 return "invalid";
04590 }
04591 }
04592
04605 dbus_bool_t
04606 dbus_message_marshal (DBusMessage *msg,
04607 char **marshalled_data_p,
04608 int *len_p)
04609 {
04610 DBusString tmp;
04611 dbus_bool_t was_locked;
04612
04613 _dbus_return_val_if_fail (msg != NULL, FALSE);
04614 _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
04615 _dbus_return_val_if_fail (len_p != NULL, FALSE);
04616
04617 if (!_dbus_string_init (&tmp))
04618 return FALSE;
04619
04620
04621 was_locked = msg->locked;
04622
04623 if (!was_locked)
04624 dbus_message_lock (msg);
04625
04626 if (!_dbus_string_copy (&(msg->header.data), 0, &tmp, 0))
04627 goto fail;
04628
04629 *len_p = _dbus_string_get_length (&tmp);
04630
04631 if (!_dbus_string_copy (&(msg->body), 0, &tmp, *len_p))
04632 goto fail;
04633
04634 *len_p = _dbus_string_get_length (&tmp);
04635
04636 if (!_dbus_string_steal_data (&tmp, marshalled_data_p))
04637 goto fail;
04638
04639 _dbus_string_free (&tmp);
04640
04641 if (!was_locked)
04642 msg->locked = FALSE;
04643
04644 return TRUE;
04645
04646 fail:
04647 _dbus_string_free (&tmp);
04648
04649 if (!was_locked)
04650 msg->locked = FALSE;
04651
04652 return FALSE;
04653 }
04654
04667 DBusMessage *
04668 dbus_message_demarshal (const char *str,
04669 int len,
04670 DBusError *error)
04671 {
04672 DBusMessageLoader *loader;
04673 DBusString *buffer;
04674 DBusMessage *msg;
04675
04676 _dbus_return_val_if_fail (str != NULL, NULL);
04677
04678 loader = _dbus_message_loader_new ();
04679
04680 if (loader == NULL)
04681 return NULL;
04682
04683 _dbus_message_loader_get_buffer (loader, &buffer);
04684 _dbus_string_append_len (buffer, str, len);
04685 _dbus_message_loader_return_buffer (loader, buffer, len);
04686
04687 if (!_dbus_message_loader_queue_messages (loader))
04688 goto fail_oom;
04689
04690 if (_dbus_message_loader_get_is_corrupted (loader))
04691 goto fail_corrupt;
04692
04693 msg = _dbus_message_loader_pop_message (loader);
04694
04695 if (!msg)
04696 goto fail_oom;
04697
04698 _dbus_message_loader_unref (loader);
04699 return msg;
04700
04701 fail_corrupt:
04702 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted (%s)",
04703 _dbus_validity_to_error_message (loader->corruption_reason));
04704 _dbus_message_loader_unref (loader);
04705 return NULL;
04706
04707 fail_oom:
04708 _DBUS_SET_OOM (error);
04709 _dbus_message_loader_unref (loader);
04710 return NULL;
04711 }
04712
04726 int
04727 dbus_message_demarshal_bytes_needed(const char *buf,
04728 int len)
04729 {
04730 DBusString str;
04731 int byte_order, fields_array_len, header_len, body_len;
04732 DBusValidity validity = DBUS_VALID;
04733 int have_message;
04734
04735 if (!buf || len < DBUS_MINIMUM_HEADER_SIZE)
04736 return 0;
04737
04738 if (len > DBUS_MAXIMUM_MESSAGE_LENGTH)
04739 len = DBUS_MAXIMUM_MESSAGE_LENGTH;
04740 _dbus_string_init_const_len (&str, buf, len);
04741
04742 validity = DBUS_VALID;
04743 have_message
04744 = _dbus_header_have_message_untrusted(DBUS_MAXIMUM_MESSAGE_LENGTH,
04745 &validity, &byte_order,
04746 &fields_array_len,
04747 &header_len,
04748 &body_len,
04749 &str, 0,
04750 len);
04751 _dbus_string_free (&str);
04752
04753 if (validity == DBUS_VALID)
04754 {
04755 _dbus_assert (have_message || (header_len + body_len) > len);
04756 (void) have_message;
04757 return header_len + body_len;
04758 }
04759 else
04760 {
04761 return -1;
04762 }
04763 }
04764
04767