D-Bus 1.10.18

dbus-message.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-message.c DBusMessage object
3 *
4 * Copyright (C) 2002, 2003, 2004, 2005 Red Hat Inc.
5 * Copyright (C) 2002, 2003 CodeFactory AB
6 *
7 * Licensed under the Academic Free License version 2.1
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 *
23 */
24
25 #include <config.h>
26 #include "dbus-internals.h"
27 #include "dbus-marshal-recursive.h"
28 #include "dbus-marshal-validate.h"
29 #include "dbus-marshal-byteswap.h"
30 #include "dbus-marshal-header.h"
31 #include "dbus-signature.h"
32 #include "dbus-message-private.h"
33 #include "dbus-object-tree.h"
34 #include "dbus-memory.h"
35 #include "dbus-list.h"
36 #include "dbus-threads-internal.h"
37 #ifdef HAVE_UNIX_FD_PASSING
38 #include "dbus-sysdeps.h"
39 #include "dbus-sysdeps-unix.h"
40 #endif
41
42 #include <string.h>
43
44 #define _DBUS_TYPE_IS_STRINGLIKE(type) \
45 (type == DBUS_TYPE_STRING || type == DBUS_TYPE_SIGNATURE || \
46 type == DBUS_TYPE_OBJECT_PATH)
47
48 static void dbus_message_finalize (DBusMessage *message);
49
60 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
61 static dbus_bool_t
62 _dbus_enable_message_cache (void)
63 {
64 static int enabled = -1;
65
66 if (enabled < 0)
67 {
68 const char *s = _dbus_getenv ("DBUS_MESSAGE_CACHE");
69
70 enabled = TRUE;
71
72 if (s && *s)
73 {
74 if (*s == '0')
75 enabled = FALSE;
76 else if (*s == '1')
77 enabled = TRUE;
78 else
79 _dbus_warn ("DBUS_MESSAGE_CACHE should be 0 or 1 if set, not '%s'",
80 s);
81 }
82 }
83
84 return enabled;
85 }
86 #else
87 /* constant expression, should be optimized away */
88 # define _dbus_enable_message_cache() (TRUE)
89 #endif
90
91 #ifndef _dbus_message_trace_ref
92 void
93 _dbus_message_trace_ref (DBusMessage *message,
94 int old_refcount,
95 int new_refcount,
96 const char *why)
97 {
98 static int enabled = -1;
99
100 _dbus_trace_ref ("DBusMessage", message, old_refcount, new_refcount, why,
101 "DBUS_MESSAGE_TRACE", &enabled);
102 }
103 #endif
104
105 /* Not thread locked, but strictly const/read-only so should be OK
106 */
108 _DBUS_STRING_DEFINE_STATIC(_dbus_empty_signature_str, "");
109
110 /* these have wacky values to help trap uninitialized iterators;
111 * but has to fit in 3 bits
112 */
113 enum {
114 DBUS_MESSAGE_ITER_TYPE_READER = 3,
115 DBUS_MESSAGE_ITER_TYPE_WRITER = 7
116 };
117
119 typedef struct DBusMessageRealIter DBusMessageRealIter;
120
126 struct DBusMessageRealIter
127 {
128 DBusMessage *message;
129 dbus_uint32_t changed_stamp : CHANGED_STAMP_BITS;
130 dbus_uint32_t iter_type : 3;
131 dbus_uint32_t sig_refcount : 8;
132 union
133 {
134 DBusTypeWriter writer;
135 DBusTypeReader reader;
136 } u;
137 };
138
144 typedef struct
145 {
146 void *dummy1;
147 void *dummy2;
148 dbus_uint32_t dummy3;
149 int dummy4;
150 int dummy5;
151 int dummy6;
152 int dummy7;
153 int dummy8;
154 int dummy9;
155 int dummy10;
156 int dummy11;
157 int pad1;
158 int pad2;
159 void *pad3;
160 } DBusMessageIter_1_10_0;
161
162 static void
163 get_const_signature (DBusHeader *header,
164 const DBusString **type_str_p,
165 int *type_pos_p)
166 {
167 if (_dbus_header_get_field_raw (header,
168 DBUS_HEADER_FIELD_SIGNATURE,
169 type_str_p,
170 type_pos_p))
171 {
172 *type_pos_p += 1; /* skip the signature length which is 1 byte */
173 }
174 else
175 {
176 *type_str_p = &_dbus_empty_signature_str;
177 *type_pos_p = 0;
178 }
179 }
180
186 static void
187 _dbus_message_byteswap (DBusMessage *message)
188 {
189 const DBusString *type_str;
190 int type_pos;
191 char byte_order;
192
193 byte_order = _dbus_header_get_byte_order (&message->header);
194
195 if (byte_order == DBUS_COMPILER_BYTE_ORDER)
196 return;
197
198 _dbus_verbose ("Swapping message into compiler byte order\n");
199
200 get_const_signature (&message->header, &type_str, &type_pos);
201
202 _dbus_marshal_byteswap (type_str, type_pos,
203 byte_order,
204 DBUS_COMPILER_BYTE_ORDER,
205 &message->body, 0);
206
207 _dbus_header_byteswap (&message->header, DBUS_COMPILER_BYTE_ORDER);
208 _dbus_assert (_dbus_header_get_byte_order (&message->header) ==
209 DBUS_COMPILER_BYTE_ORDER);
210 }
211
218 #define ensure_byte_order(message) _dbus_message_byteswap (message)
219
230 void
231 _dbus_message_get_network_data (DBusMessage *message,
232 const DBusString **header,
233 const DBusString **body)
234 {
235 _dbus_assert (message->locked);
236
237 *header = &message->header.data;
238 *body = &message->body;
239 }
240
250 void _dbus_message_get_unix_fds(DBusMessage *message,
251 const int **fds,
252 unsigned *n_fds)
253 {
254 _dbus_assert (message->locked);
255
256 #ifdef HAVE_UNIX_FD_PASSING
257 *fds = message->unix_fds;
258 *n_fds = message->n_unix_fds;
259 #else
260 *fds = NULL;
261 *n_fds = 0;
262 #endif
263 }
264
276 void
277 dbus_message_set_serial (DBusMessage *message,
278 dbus_uint32_t serial)
279 {
280 _dbus_return_if_fail (message != NULL);
281 _dbus_return_if_fail (!message->locked);
282
283 _dbus_header_set_serial (&message->header, serial);
284 }
285
302 void
303 _dbus_message_add_counter_link (DBusMessage *message,
304 DBusList *link)
305 {
306 /* right now we don't recompute the delta when message
307 * size changes, and that's OK for current purposes
308 * I think, but could be important to change later.
309 * Do recompute it whenever there are no outstanding counters,
310 * since it's basically free.
311 */
312 if (message->counters == NULL)
313 {
314 message->size_counter_delta =
315 _dbus_string_get_length (&message->header.data) +
316 _dbus_string_get_length (&message->body);
317
318 #ifdef HAVE_UNIX_FD_PASSING
319 message->unix_fd_counter_delta = message->n_unix_fds;
320 #endif
321
322 #if 0
323 _dbus_verbose ("message has size %ld\n",
324 message->size_counter_delta);
325 #endif
326 }
327
328 _dbus_list_append_link (&message->counters, link);
329
330 _dbus_counter_adjust_size (link->data, message->size_counter_delta);
331
332 #ifdef HAVE_UNIX_FD_PASSING
333 _dbus_counter_adjust_unix_fd (link->data, message->unix_fd_counter_delta);
334 #endif
335 }
336
351 dbus_bool_t
352 _dbus_message_add_counter (DBusMessage *message,
353 DBusCounter *counter)
354 {
355 DBusList *link;
356
357 link = _dbus_list_alloc_link (counter);
358 if (link == NULL)
359 return FALSE;
360
361 _dbus_counter_ref (counter);
362 _dbus_message_add_counter_link (message, link);
363
364 return TRUE;
365 }
366
374 void
375 _dbus_message_remove_counter (DBusMessage *message,
376 DBusCounter *counter)
377 {
378 DBusList *link;
379
380 link = _dbus_list_find_last (&message->counters,
381 counter);
382 _dbus_assert (link != NULL);
383
384 _dbus_list_remove_link (&message->counters, link);
385
386 _dbus_counter_adjust_size (counter, - message->size_counter_delta);
387
388 #ifdef HAVE_UNIX_FD_PASSING
389 _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
390 #endif
391
392 _dbus_counter_notify (counter);
393 _dbus_counter_unref (counter);
394 }
395
406 void
407 dbus_message_lock (DBusMessage *message)
408 {
409 if (!message->locked)
410 {
411 _dbus_header_update_lengths (&message->header,
412 _dbus_string_get_length (&message->body));
413
414 /* must have a signature if you have a body */
415 _dbus_assert (_dbus_string_get_length (&message->body) == 0 ||
416 dbus_message_get_signature (message) != NULL);
417
418 message->locked = TRUE;
419 }
420 }
421
422 static dbus_bool_t
423 set_or_delete_string_field (DBusMessage *message,
424 int field,
425 int typecode,
426 const char *value)
427 {
428 if (value == NULL)
429 return _dbus_header_delete_field (&message->header, field);
430 else
431 return _dbus_header_set_field_basic (&message->header,
432 field,
433 typecode,
434 &value);
435 }
436
437 #if 0
438 /* Probably we don't need to use this */
462 static dbus_bool_t
463 _dbus_message_set_signature (DBusMessage *message,
464 const char *signature)
465 {
466 _dbus_return_val_if_fail (message != NULL, FALSE);
467 _dbus_return_val_if_fail (!message->locked, FALSE);
468 _dbus_return_val_if_fail (signature == NULL ||
469 _dbus_check_is_valid_signature (signature));
470 /* can't delete the signature if you have a message body */
471 _dbus_return_val_if_fail (_dbus_string_get_length (&message->body) == 0 ||
472 signature != NULL);
473
474 return set_or_delete_string_field (message,
475 DBUS_HEADER_FIELD_SIGNATURE,
476 DBUS_TYPE_SIGNATURE,
477 signature);
478 }
479 #endif
480
481 /* Message Cache
482 *
483 * We cache some DBusMessage to reduce the overhead of allocating
484 * them. In my profiling this consistently made about an 8%
485 * difference. It avoids the malloc for the message, the malloc for
486 * the slot list, the malloc for the header string and body string,
487 * and the associated free() calls. It does introduce another global
488 * lock which could be a performance issue in certain cases.
489 *
490 * For the echo client/server the round trip time goes from around
491 * .000077 to .000069 with the message cache on my laptop. The sysprof
492 * change is as follows (numbers are cumulative percentage):
493 *
494 * with message cache implemented as array as it is now (0.000069 per):
495 * new_empty_header 1.46
496 * mutex_lock 0.56 # i.e. _DBUS_LOCK(message_cache)
497 * mutex_unlock 0.25
498 * self 0.41
499 * unref 2.24
500 * self 0.68
501 * list_clear 0.43
502 * mutex_lock 0.33 # i.e. _DBUS_LOCK(message_cache)
503 * mutex_unlock 0.25
504 *
505 * with message cache implemented as list (0.000070 per roundtrip):
506 * new_empty_header 2.72
507 * list_pop_first 1.88
508 * unref 3.3
509 * list_prepend 1.63
510 *
511 * without cache (0.000077 per roundtrip):
512 * new_empty_header 6.7
513 * string_init_preallocated 3.43
514 * dbus_malloc 2.43
515 * dbus_malloc0 2.59
516 *
517 * unref 4.02
518 * string_free 1.82
519 * dbus_free 1.63
520 * dbus_free 0.71
521 *
522 * If you implement the message_cache with a list, the primary reason
523 * it's slower is that you add another thread lock (on the DBusList
524 * mempool).
525 */
526
528 #define MAX_MESSAGE_SIZE_TO_CACHE 10 * _DBUS_ONE_KILOBYTE
529
531 #define MAX_MESSAGE_CACHE_SIZE 5
532
533 /* Protected by _DBUS_LOCK (message_cache) */
534 static DBusMessage *message_cache[MAX_MESSAGE_CACHE_SIZE];
535 static int message_cache_count = 0;
536 static dbus_bool_t message_cache_shutdown_registered = FALSE;
537
538 static void
539 dbus_message_cache_shutdown (void *data)
540 {
541 int i;
542
543 if (!_DBUS_LOCK (message_cache))
544 _dbus_assert_not_reached ("we would have initialized global locks "
545 "before registering a shutdown function");
546
547 i = 0;
548 while (i < MAX_MESSAGE_CACHE_SIZE)
549 {
550 if (message_cache[i])
551 dbus_message_finalize (message_cache[i]);
552
553 ++i;
554 }
555
556 message_cache_count = 0;
557 message_cache_shutdown_registered = FALSE;
558
559 _DBUS_UNLOCK (message_cache);
560 }
561
569 static DBusMessage*
570 dbus_message_get_cached (void)
571 {
572 DBusMessage *message;
573 int i;
574
575 message = NULL;
576
577 if (!_DBUS_LOCK (message_cache))
578 {
579 /* we'd have initialized global locks before caching anything,
580 * so there can't be anything in the cache */
581 return NULL;
582 }
583
584 _dbus_assert (message_cache_count >= 0);
585
586 if (message_cache_count == 0)
587 {
588 _DBUS_UNLOCK (message_cache);
589 return NULL;
590 }
591
592 /* This is not necessarily true unless count > 0, and
593 * message_cache is uninitialized until the shutdown is
594 * registered
595 */
596 _dbus_assert (message_cache_shutdown_registered);
597
598 i = 0;
599 while (i < MAX_MESSAGE_CACHE_SIZE)
600 {
601 if (message_cache[i])
602 {
603 message = message_cache[i];
604 message_cache[i] = NULL;
605 message_cache_count -= 1;
606 break;
607 }
608 ++i;
609 }
610 _dbus_assert (message_cache_count >= 0);
611 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
612 _dbus_assert (message != NULL);
613
614 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
615
616 _dbus_assert (message->counters == NULL);
617
618 _DBUS_UNLOCK (message_cache);
619
620 return message;
621 }
622
623 #ifdef HAVE_UNIX_FD_PASSING
624 static void
625 close_unix_fds(int *fds, unsigned *n_fds)
626 {
627 DBusError e;
628 unsigned int i;
629
630 if (*n_fds <= 0)
631 return;
632
633 dbus_error_init(&e);
634
635 for (i = 0; i < *n_fds; i++)
636 {
637 if (!_dbus_close(fds[i], &e))
638 {
639 _dbus_warn("Failed to close file descriptor: %s\n", e.message);
640 dbus_error_free(&e);
641 }
642 }
643
644 *n_fds = 0;
645
646 /* We don't free the array here, in case we can recycle it later */
647 }
648 #endif
649
650 static void
651 free_counter (void *element,
652 void *data)
653 {
654 DBusCounter *counter = element;
655 DBusMessage *message = data;
656
657 _dbus_counter_adjust_size (counter, - message->size_counter_delta);
658 #ifdef HAVE_UNIX_FD_PASSING
659 _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
660 #endif
661
662 _dbus_counter_notify (counter);
663 _dbus_counter_unref (counter);
664 }
665
671 static void
672 dbus_message_cache_or_finalize (DBusMessage *message)
673 {
674 dbus_bool_t was_cached;
675 int i;
676
677 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
678
679 /* This calls application code and has to be done first thing
680 * without holding the lock
681 */
682 _dbus_data_slot_list_clear (&message->slot_list);
683
684 _dbus_list_foreach (&message->counters,
685 free_counter, message);
686 _dbus_list_clear (&message->counters);
687
688 #ifdef HAVE_UNIX_FD_PASSING
689 close_unix_fds(message->unix_fds, &message->n_unix_fds);
690 #endif
691
692 was_cached = FALSE;
693
694 if (!_DBUS_LOCK (message_cache))
695 {
696 /* The only way to get a non-null message goes through
697 * dbus_message_get_cached() which takes the lock. */
698 _dbus_assert_not_reached ("we would have initialized global locks "
699 "the first time we constructed a message");
700 }
701
702 if (!message_cache_shutdown_registered)
703 {
704 _dbus_assert (message_cache_count == 0);
705
706 if (!_dbus_register_shutdown_func (dbus_message_cache_shutdown, NULL))
707 goto out;
708
709 i = 0;
710 while (i < MAX_MESSAGE_CACHE_SIZE)
711 {
712 message_cache[i] = NULL;
713 ++i;
714 }
715
716 message_cache_shutdown_registered = TRUE;
717 }
718
719 _dbus_assert (message_cache_count >= 0);
720
721 if (!_dbus_enable_message_cache ())
722 goto out;
723
724 if ((_dbus_string_get_length (&message->header.data) +
725 _dbus_string_get_length (&message->body)) >
726 MAX_MESSAGE_SIZE_TO_CACHE)
727 goto out;
728
729 if (message_cache_count >= MAX_MESSAGE_CACHE_SIZE)
730 goto out;
731
732 /* Find empty slot */
733 i = 0;
734 while (message_cache[i] != NULL)
735 ++i;
736
737 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
738
739 _dbus_assert (message_cache[i] == NULL);
740 message_cache[i] = message;
741 message_cache_count += 1;
742 was_cached = TRUE;
743 #ifndef DBUS_DISABLE_CHECKS
744 message->in_cache = TRUE;
745 #endif
746
747 out:
748 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
749
750 _DBUS_UNLOCK (message_cache);
751
752 if (!was_cached)
753 dbus_message_finalize (message);
754 }
755
756 #if defined(DBUS_ENABLE_CHECKS) || defined(DBUS_ENABLE_ASSERT)
757 static dbus_bool_t
758 _dbus_message_iter_check (DBusMessageRealIter *iter)
759 {
760 char byte_order;
761
762 if (iter == NULL)
763 {
764 _dbus_warn_check_failed ("dbus message iterator is NULL\n");
765 return FALSE;
766 }
767
768 byte_order = _dbus_header_get_byte_order (&iter->message->header);
769
770 if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_READER)
771 {
772 if (iter->u.reader.byte_order != byte_order)
773 {
774 _dbus_warn_check_failed ("dbus message changed byte order since iterator was created\n");
775 return FALSE;
776 }
777 /* because we swap the message into compiler order when you init an iter */
778 _dbus_assert (iter->u.reader.byte_order == DBUS_COMPILER_BYTE_ORDER);
779 }
780 else if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER)
781 {
782 if (iter->u.writer.byte_order != byte_order)
783 {
784 _dbus_warn_check_failed ("dbus message changed byte order since append iterator was created\n");
785 return FALSE;
786 }
787 /* because we swap the message into compiler order when you init an iter */
788 _dbus_assert (iter->u.writer.byte_order == DBUS_COMPILER_BYTE_ORDER);
789 }
790 else
791 {
792 _dbus_warn_check_failed ("dbus message iterator looks uninitialized or corrupted\n");
793 return FALSE;
794 }
795
796 if (iter->changed_stamp != iter->message->changed_stamp)
797 {
798 _dbus_warn_check_failed ("dbus message iterator invalid because the message has been modified (or perhaps the iterator is just uninitialized)\n");
799 return FALSE;
800 }
801
802 return TRUE;
803 }
804 #endif /* DBUS_ENABLE_CHECKS || DBUS_ENABLE_ASSERT */
805
818 dbus_bool_t
819 _dbus_message_iter_get_args_valist (DBusMessageIter *iter,
820 DBusError *error,
821 int first_arg_type,
822 va_list var_args)
823 {
824 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
825 int spec_type, msg_type, i, j;
826 dbus_bool_t retval;
827 va_list copy_args;
828
829 _dbus_assert (_dbus_message_iter_check (real));
830
831 retval = FALSE;
832
833 spec_type = first_arg_type;
834 i = 0;
835
836 /* copy var_args first, then we can do another iteration over it to
837 * free memory and close unix fds if parse failed at some point.
838 */
839 DBUS_VA_COPY (copy_args, var_args);
840
841 while (spec_type != DBUS_TYPE_INVALID)
842 {
843 msg_type = dbus_message_iter_get_arg_type (iter);
844
845 if (msg_type != spec_type)
846 {
847 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
848 "Argument %d is specified to be of type \"%s\", but "
849 "is actually of type \"%s\"\n", i,
850 _dbus_type_to_string (spec_type),
851 _dbus_type_to_string (msg_type));
852
853 goto out;
854 }
855
856 if (spec_type == DBUS_TYPE_UNIX_FD)
857 {
858 #ifdef HAVE_UNIX_FD_PASSING
859 DBusBasicValue idx;
860 int *pfd, nfd;
861
862 pfd = va_arg (var_args, int*);
863 _dbus_assert(pfd);
864
865 _dbus_type_reader_read_basic(&real->u.reader, &idx);
866
867 if (idx.u32 >= real->message->n_unix_fds)
868 {
869 dbus_set_error (error, DBUS_ERROR_INCONSISTENT_MESSAGE,
870 "Message refers to file descriptor at index %i,"
871 "but has only %i descriptors attached.\n",
872 idx.u32,
873 real->message->n_unix_fds);
874 goto out;
875 }
876
877 if ((nfd = _dbus_dup(real->message->unix_fds[idx.u32], error)) < 0)
878 goto out;
879
880 *pfd = nfd;
881 #else
882 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
883 "Platform does not support file desciptor passing.\n");
884 goto out;
885 #endif
886 }
887 else if (dbus_type_is_basic (spec_type))
888 {
889 DBusBasicValue *ptr;
890
891 ptr = va_arg (var_args, DBusBasicValue*);
892
893 _dbus_assert (ptr != NULL);
894
895 _dbus_type_reader_read_basic (&real->u.reader,
896 ptr);
897 }
898 else if (spec_type == DBUS_TYPE_ARRAY)
899 {
900 int element_type;
901 int spec_element_type;
902 const DBusBasicValue **ptr;
903 int *n_elements_p;
904 DBusTypeReader array;
905
906 spec_element_type = va_arg (var_args, int);
907 element_type = _dbus_type_reader_get_element_type (&real->u.reader);
908
909 if (spec_element_type != element_type)
910 {
911 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
912 "Argument %d is specified to be an array of \"%s\", but "
913 "is actually an array of \"%s\"\n",
914 i,
915 _dbus_type_to_string (spec_element_type),
916 _dbus_type_to_string (element_type));
917
918 goto out;
919 }
920
921 if (dbus_type_is_fixed (spec_element_type) &&
922 element_type != DBUS_TYPE_UNIX_FD)
923 {
924 ptr = va_arg (var_args, const DBusBasicValue**);
925 n_elements_p = va_arg (var_args, int*);
926
927 _dbus_assert (ptr != NULL);
928 _dbus_assert (n_elements_p != NULL);
929
930 _dbus_type_reader_recurse (&real->u.reader, &array);
931
932 _dbus_type_reader_read_fixed_multi (&array,
933 (void *) ptr, n_elements_p);
934 }
935 else if (_DBUS_TYPE_IS_STRINGLIKE (spec_element_type))
936 {
937 char ***str_array_p;
938 int n_elements;
939 char **str_array;
940
941 str_array_p = va_arg (var_args, char***);
942 n_elements_p = va_arg (var_args, int*);
943
944 _dbus_assert (str_array_p != NULL);
945 _dbus_assert (n_elements_p != NULL);
946
947 /* Count elements in the array */
948 _dbus_type_reader_recurse (&real->u.reader, &array);
949
950 n_elements = 0;
951 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
952 {
953 ++n_elements;
954 _dbus_type_reader_next (&array);
955 }
956
957 str_array = dbus_new0 (char*, n_elements + 1);
958 if (str_array == NULL)
959 {
960 _DBUS_SET_OOM (error);
961 goto out;
962 }
963
964 /* Now go through and dup each string */
965 _dbus_type_reader_recurse (&real->u.reader, &array);
966
967 j = 0;
968 while (j < n_elements)
969 {
970 const char *s;
971 _dbus_type_reader_read_basic (&array,
972 (void *) &s);
973
974 str_array[j] = _dbus_strdup (s);
975 if (str_array[j] == NULL)
976 {
977 dbus_free_string_array (str_array);
978 _DBUS_SET_OOM (error);
979 goto out;
980 }
981
982 ++j;
983
984 if (!_dbus_type_reader_next (&array))
985 _dbus_assert (j == n_elements);
986 }
987
988 _dbus_assert (_dbus_type_reader_get_current_type (&array) == DBUS_TYPE_INVALID);
989 _dbus_assert (j == n_elements);
990 _dbus_assert (str_array[j] == NULL);
991
992 *str_array_p = str_array;
993 *n_elements_p = n_elements;
994 }
995 #ifndef DBUS_DISABLE_CHECKS
996 else
997 {
998 _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now\n",
999 _DBUS_FUNCTION_NAME);
1000 goto out;
1001 }
1002 #endif
1003 }
1004 #ifndef DBUS_DISABLE_CHECKS
1005 else
1006 {
1007 _dbus_warn ("you can only read arrays and basic types with %s for now\n",
1008 _DBUS_FUNCTION_NAME);
1009 goto out;
1010 }
1011 #endif
1012
1013 /* how many arguments already handled */
1014 i++;
1015
1016 spec_type = va_arg (var_args, int);
1017 if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID)
1018 {
1019 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1020 "Message has only %d arguments, but more were expected", i);
1021 goto out;
1022 }
1023 }
1024
1025 retval = TRUE;
1026
1027 out:
1028 /* there may memory or unix fd leak in the above iteration if parse failed.
1029 * so we have another iteration over copy_args to free memory and close
1030 * unix fds.
1031 */
1032 if (!retval)
1033 {
1034 spec_type = first_arg_type;
1035 j = 0;
1036
1037 while (j < i)
1038 {
1039 if (spec_type == DBUS_TYPE_UNIX_FD)
1040 {
1041 #ifdef HAVE_UNIX_FD_PASSING
1042 int *pfd;
1043
1044 pfd = va_arg (copy_args, int *);
1045 _dbus_assert(pfd);
1046 if (*pfd >= 0)
1047 {
1048 _dbus_close (*pfd, NULL);
1049 *pfd = -1;
1050 }
1051 #endif
1052 }
1053 else if (dbus_type_is_basic (spec_type))
1054 {
1055 /* move the index forward */
1056 va_arg (copy_args, DBusBasicValue *);
1057 }
1058 else if (spec_type == DBUS_TYPE_ARRAY)
1059 {
1060 int spec_element_type;
1061
1062 spec_element_type = va_arg (copy_args, int);
1063 if (dbus_type_is_fixed (spec_element_type))
1064 {
1065 /* move the index forward */
1066 va_arg (copy_args, const DBusBasicValue **);
1067 va_arg (copy_args, int *);
1068 }
1069 else if (_DBUS_TYPE_IS_STRINGLIKE (spec_element_type))
1070 {
1071 char ***str_array_p;
1072
1073 str_array_p = va_arg (copy_args, char ***);
1074 /* move the index forward */
1075 va_arg (copy_args, int *);
1076 _dbus_assert (str_array_p != NULL);
1077 dbus_free_string_array (*str_array_p);
1078 *str_array_p = NULL;
1079 }
1080 }
1081
1082 spec_type = va_arg (copy_args, int);
1083 j++;
1084 }
1085 }
1086
1087 va_end (copy_args);
1088 return retval;
1089 }
1090
1149 dbus_uint32_t
1150 dbus_message_get_serial (DBusMessage *message)
1151 {
1152 _dbus_return_val_if_fail (message != NULL, 0);
1153
1154 return _dbus_header_get_serial (&message->header);
1155 }
1156
1165 dbus_bool_t
1166 dbus_message_set_reply_serial (DBusMessage *message,
1167 dbus_uint32_t reply_serial)
1168 {
1169 DBusBasicValue value;
1170
1171 _dbus_return_val_if_fail (message != NULL, FALSE);
1172 _dbus_return_val_if_fail (!message->locked, FALSE);
1173 _dbus_return_val_if_fail (reply_serial != 0, FALSE); /* 0 is invalid */
1174
1175 value.u32 = reply_serial;
1176
1177 return _dbus_header_set_field_basic (&message->header,
1178 DBUS_HEADER_FIELD_REPLY_SERIAL,
1179 DBUS_TYPE_UINT32,
1180 &value);
1181 }
1182
1189 dbus_uint32_t
1190 dbus_message_get_reply_serial (DBusMessage *message)
1191 {
1192 dbus_uint32_t v_UINT32;
1193
1194 _dbus_return_val_if_fail (message != NULL, 0);
1195
1196 if (_dbus_header_get_field_basic (&message->header,
1197 DBUS_HEADER_FIELD_REPLY_SERIAL,
1198 DBUS_TYPE_UINT32,
1199 &v_UINT32))
1200 return v_UINT32;
1201 else
1202 return 0;
1203 }
1204
1205 static void
1206 dbus_message_finalize (DBusMessage *message)
1207 {
1208 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
1209
1210 /* This calls application callbacks! */
1211 _dbus_data_slot_list_free (&message->slot_list);
1212
1213 _dbus_list_foreach (&message->counters,
1214 free_counter, message);
1215 _dbus_list_clear (&message->counters);
1216
1217 _dbus_header_free (&message->header);
1218 _dbus_string_free (&message->body);
1219
1220 #ifdef HAVE_UNIX_FD_PASSING
1221 close_unix_fds(message->unix_fds, &message->n_unix_fds);
1222 dbus_free(message->unix_fds);
1223 #endif
1224
1225 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
1226
1227 dbus_free (message);
1228 }
1229
1230 static DBusMessage*
1231 dbus_message_new_empty_header (void)
1232 {
1233 DBusMessage *message;
1234 dbus_bool_t from_cache;
1235
1236 message = dbus_message_get_cached ();
1237
1238 if (message != NULL)
1239 {
1240 from_cache = TRUE;
1241 }
1242 else
1243 {
1244 from_cache = FALSE;
1245 message = dbus_new0 (DBusMessage, 1);
1246 if (message == NULL)
1247 return NULL;
1248 #ifndef DBUS_DISABLE_CHECKS
1249 message->generation = _dbus_current_generation;
1250 #endif
1251
1252 #ifdef HAVE_UNIX_FD_PASSING
1253 message->unix_fds = NULL;
1254 message->n_unix_fds_allocated = 0;
1255 #endif
1256 }
1257
1258 _dbus_atomic_inc (&message->refcount);
1259
1260 _dbus_message_trace_ref (message, 0, 1, "new_empty_header");
1261
1262 message->locked = FALSE;
1263 #ifndef DBUS_DISABLE_CHECKS
1264 message->in_cache = FALSE;
1265 #endif
1266 message->counters = NULL;
1267 message->size_counter_delta = 0;
1268 message->changed_stamp = 0;
1269
1270 #ifdef HAVE_UNIX_FD_PASSING
1271 message->n_unix_fds = 0;
1272 message->n_unix_fds_allocated = 0;
1273 message->unix_fd_counter_delta = 0;
1274 #endif
1275
1276 if (!from_cache)
1277 _dbus_data_slot_list_init (&message->slot_list);
1278
1279 if (from_cache)
1280 {
1281 _dbus_header_reinit (&message->header);
1282 _dbus_string_set_length (&message->body, 0);
1283 }
1284 else
1285 {
1286 if (!_dbus_header_init (&message->header))
1287 {
1288 dbus_free (message);
1289 return NULL;
1290 }
1291
1292 if (!_dbus_string_init_preallocated (&message->body, 32))
1293 {
1294 _dbus_header_free (&message->header);
1295 dbus_free (message);
1296 return NULL;
1297 }
1298 }
1299
1300 return message;
1301 }
1302
1315 DBusMessage*
1316 dbus_message_new (int message_type)
1317 {
1318 DBusMessage *message;
1319
1320 _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
1321
1322 message = dbus_message_new_empty_header ();
1323 if (message == NULL)
1324 return NULL;
1325
1326 if (!_dbus_header_create (&message->header,
1327 DBUS_COMPILER_BYTE_ORDER,
1328 message_type,
1329 NULL, NULL, NULL, NULL, NULL))
1330 {
1331 dbus_message_unref (message);
1332 return NULL;
1333 }
1334
1335 return message;
1336 }
1337
1359 DBusMessage*
1360 dbus_message_new_method_call (const char *destination,
1361 const char *path,
1362 const char *iface,
1363 const char *method)
1364 {
1365 DBusMessage *message;
1366
1367 _dbus_return_val_if_fail (path != NULL, NULL);
1368 _dbus_return_val_if_fail (method != NULL, NULL);
1369 _dbus_return_val_if_fail (destination == NULL ||
1370 _dbus_check_is_valid_bus_name (destination), NULL);
1371 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
1372 _dbus_return_val_if_fail (iface == NULL ||
1373 _dbus_check_is_valid_interface (iface), NULL);
1374 _dbus_return_val_if_fail (_dbus_check_is_valid_member (method), NULL);
1375
1376 message = dbus_message_new_empty_header ();
1377 if (message == NULL)
1378 return NULL;
1379
1380 if (!_dbus_header_create (&message->header,
1381 DBUS_COMPILER_BYTE_ORDER,
1382 DBUS_MESSAGE_TYPE_METHOD_CALL,
1383 destination, path, iface, method, NULL))
1384 {
1385 dbus_message_unref (message);
1386 return NULL;
1387 }
1388
1389 return message;
1390 }
1391
1399 DBusMessage*
1400 dbus_message_new_method_return (DBusMessage *method_call)
1401 {
1402 DBusMessage *message;
1403 const char *sender;
1404
1405 _dbus_return_val_if_fail (method_call != NULL, NULL);
1406
1407 sender = dbus_message_get_sender (method_call);
1408
1409 /* sender is allowed to be null here in peer-to-peer case */
1410
1411 message = dbus_message_new_empty_header ();
1412 if (message == NULL)
1413 return NULL;
1414
1415 if (!_dbus_header_create (&message->header,
1416 DBUS_COMPILER_BYTE_ORDER,
1417 DBUS_MESSAGE_TYPE_METHOD_RETURN,
1418 sender, NULL, NULL, NULL, NULL))
1419 {
1420 dbus_message_unref (message);
1421 return NULL;
1422 }
1423
1424 dbus_message_set_no_reply (message, TRUE);
1425
1426 if (!dbus_message_set_reply_serial (message,
1427 dbus_message_get_serial (method_call)))
1428 {
1429 dbus_message_unref (message);
1430 return NULL;
1431 }
1432
1433 return message;
1434 }
1435
1450 DBusMessage*
1451 dbus_message_new_signal (const char *path,
1452 const char *iface,
1453 const char *name)
1454 {
1455 DBusMessage *message;
1456
1457 _dbus_return_val_if_fail (path != NULL, NULL);
1458 _dbus_return_val_if_fail (iface != NULL, NULL);
1459 _dbus_return_val_if_fail (name != NULL, NULL);
1460 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
1461 _dbus_return_val_if_fail (_dbus_check_is_valid_interface (iface), NULL);
1462 _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);
1463
1464 message = dbus_message_new_empty_header ();
1465 if (message == NULL)
1466 return NULL;
1467
1468 if (!_dbus_header_create (&message->header,
1469 DBUS_COMPILER_BYTE_ORDER,
1470 DBUS_MESSAGE_TYPE_SIGNAL,
1471 NULL, path, iface, name, NULL))
1472 {
1473 dbus_message_unref (message);
1474 return NULL;
1475 }
1476
1477 dbus_message_set_no_reply (message, TRUE);
1478
1479 return message;
1480 }
1481
1496 DBusMessage*
1497 dbus_message_new_error (DBusMessage *reply_to,
1498 const char *error_name,
1499 const char *error_message)
1500 {
1501 DBusMessage *message;
1502 const char *sender;
1503 DBusMessageIter iter;
1504
1505 _dbus_return_val_if_fail (reply_to != NULL, NULL);
1506 _dbus_return_val_if_fail (error_name != NULL, NULL);
1507 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
1508
1509 sender = dbus_message_get_sender (reply_to);
1510
1511 /* sender may be NULL for non-message-bus case or
1512 * when the message bus is dealing with an unregistered
1513 * connection.
1514 */
1515 message = dbus_message_new_empty_header ();
1516 if (message == NULL)
1517 return NULL;
1518
1519 if (!_dbus_header_create (&message->header,
1520 DBUS_COMPILER_BYTE_ORDER,
1521 DBUS_MESSAGE_TYPE_ERROR,
1522 sender, NULL, NULL, NULL, error_name))
1523 {
1524 dbus_message_unref (message);
1525 return NULL;
1526 }
1527
1528 dbus_message_set_no_reply (message, TRUE);
1529
1530 if (!dbus_message_set_reply_serial (message,
1531 dbus_message_get_serial (reply_to)))
1532 {
1533 dbus_message_unref (message);
1534 return NULL;
1535 }
1536
1537 if (error_message != NULL)
1538 {
1539 dbus_message_iter_init_append (message, &iter);
1540 if (!dbus_message_iter_append_basic (&iter,
1541 DBUS_TYPE_STRING,
1542 &error_message))
1543 {
1544 dbus_message_unref (message);
1545 return NULL;
1546 }
1547 }
1548
1549 return message;
1550 }
1551
1568 DBusMessage*
1569 dbus_message_new_error_printf (DBusMessage *reply_to,
1570 const char *error_name,
1571 const char *error_format,
1572 ...)
1573 {
1574 va_list args;
1575 DBusString str;
1576 DBusMessage *message;
1577
1578 _dbus_return_val_if_fail (reply_to != NULL, NULL);
1579 _dbus_return_val_if_fail (error_name != NULL, NULL);
1580 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
1581
1582 if (!_dbus_string_init (&str))
1583 return NULL;
1584
1585 va_start (args, error_format);
1586
1587 if (_dbus_string_append_printf_valist (&str, error_format, args))
1588 message = dbus_message_new_error (reply_to, error_name,
1589 _dbus_string_get_const_data (&str));
1590 else
1591 message = NULL;
1592
1593 _dbus_string_free (&str);
1594
1595 va_end (args);
1596
1597 return message;
1598 }
1599
1600
1613 DBusMessage *
1614 dbus_message_copy (const DBusMessage *message)
1615 {
1616 DBusMessage *retval;
1617
1618 _dbus_return_val_if_fail (message != NULL, NULL);
1619
1620 retval = dbus_new0 (DBusMessage, 1);
1621 if (retval == NULL)
1622 return NULL;
1623
1624 _dbus_atomic_inc (&retval->refcount);
1625
1626 retval->locked = FALSE;
1627 #ifndef DBUS_DISABLE_CHECKS
1628 retval->generation = message->generation;
1629 #endif
1630
1631 if (!_dbus_header_copy (&message->header, &retval->header))
1632 {
1633 dbus_free (retval);
1634 return NULL;
1635 }
1636
1637 if (!_dbus_string_init_preallocated (&retval->body,
1638 _dbus_string_get_length (&message->body)))
1639 {
1640 _dbus_header_free (&retval->header);
1641 dbus_free (retval);
1642 return NULL;
1643 }
1644
1645 if (!_dbus_string_copy (&message->body, 0,
1646 &retval->body, 0))
1647 goto failed_copy;
1648
1649 #ifdef HAVE_UNIX_FD_PASSING
1650 retval->unix_fds = dbus_new(int, message->n_unix_fds);
1651 if (retval->unix_fds == NULL && message->n_unix_fds > 0)
1652 goto failed_copy;
1653
1654 retval->n_unix_fds_allocated = message->n_unix_fds;
1655
1656 for (retval->n_unix_fds = 0;
1657 retval->n_unix_fds < message->n_unix_fds;
1658 retval->n_unix_fds++)
1659 {
1660 retval->unix_fds[retval->n_unix_fds] = _dbus_dup(message->unix_fds[retval->n_unix_fds], NULL);
1661
1662 if (retval->unix_fds[retval->n_unix_fds] < 0)
1663 goto failed_copy;
1664 }
1665
1666 #endif
1667
1668 _dbus_message_trace_ref (retval, 0, 1, "copy");
1669 return retval;
1670
1671 failed_copy:
1672 _dbus_header_free (&retval->header);
1673 _dbus_string_free (&retval->body);
1674
1675 #ifdef HAVE_UNIX_FD_PASSING
1676 close_unix_fds(retval->unix_fds, &retval->n_unix_fds);
1677 dbus_free(retval->unix_fds);
1678 #endif
1679
1680 dbus_free (retval);
1681
1682 return NULL;
1683 }
1684
1685
1693 DBusMessage *
1694 dbus_message_ref (DBusMessage *message)
1695 {
1696 dbus_int32_t old_refcount;
1697
1698 _dbus_return_val_if_fail (message != NULL, NULL);
1699 _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
1700 _dbus_return_val_if_fail (!message->in_cache, NULL);
1701
1702 old_refcount = _dbus_atomic_inc (&message->refcount);
1703 _dbus_assert (old_refcount >= 1);
1704 _dbus_message_trace_ref (message, old_refcount, old_refcount + 1, "ref");
1705
1706 return message;
1707 }
1708
1716 void
1717 dbus_message_unref (DBusMessage *message)
1718 {
1719 dbus_int32_t old_refcount;
1720
1721 _dbus_return_if_fail (message != NULL);
1722 _dbus_return_if_fail (message->generation == _dbus_current_generation);
1723 _dbus_return_if_fail (!message->in_cache);
1724
1725 old_refcount = _dbus_atomic_dec (&message->refcount);
1726
1727 _dbus_assert (old_refcount >= 1);
1728
1729 _dbus_message_trace_ref (message, old_refcount, old_refcount - 1, "unref");
1730
1731 if (old_refcount == 1)
1732 {
1733 /* Calls application callbacks! */
1734 dbus_message_cache_or_finalize (message);
1735 }
1736 }
1737
1748 int
1749 dbus_message_get_type (DBusMessage *message)
1750 {
1751 _dbus_return_val_if_fail (message != NULL, DBUS_MESSAGE_TYPE_INVALID);
1752
1753 return _dbus_header_get_message_type (&message->header);
1754 }
1755
1818 dbus_bool_t
1819 dbus_message_append_args (DBusMessage *message,
1820 int first_arg_type,
1821 ...)
1822 {
1823 dbus_bool_t retval;
1824 va_list var_args;
1825
1826 _dbus_return_val_if_fail (message != NULL, FALSE);
1827
1828 va_start (var_args, first_arg_type);
1829 retval = dbus_message_append_args_valist (message,
1830 first_arg_type,
1831 var_args);
1832 va_end (var_args);
1833
1834 return retval;
1835 }
1836
1850 dbus_bool_t
1851 dbus_message_append_args_valist (DBusMessage *message,
1852 int first_arg_type,
1853 va_list var_args)
1854 {
1855 int type;
1856 DBusMessageIter iter;
1857
1858 _dbus_return_val_if_fail (message != NULL, FALSE);
1859
1860 type = first_arg_type;
1861
1862 dbus_message_iter_init_append (message, &iter);
1863
1864 while (type != DBUS_TYPE_INVALID)
1865 {
1866 if (dbus_type_is_basic (type))
1867 {
1868 const DBusBasicValue *value;
1869 value = va_arg (var_args, const DBusBasicValue*);
1870
1871 if (!dbus_message_iter_append_basic (&iter,
1872 type,
1873 value))
1874 goto failed;
1875 }
1876 else if (type == DBUS_TYPE_ARRAY)
1877 {
1878 int element_type;
1879 DBusMessageIter array;
1880 char buf[2];
1881
1882 element_type = va_arg (var_args, int);
1883
1884 buf[0] = element_type;
1885 buf[1] = '\0';
1886 if (!dbus_message_iter_open_container (&iter,
1887 DBUS_TYPE_ARRAY,
1888 buf,
1889 &array))
1890 goto failed;
1891
1892 if (dbus_type_is_fixed (element_type) &&
1893 element_type != DBUS_TYPE_UNIX_FD)
1894 {
1895 const DBusBasicValue **value;
1896 int n_elements;
1897
1898 value = va_arg (var_args, const DBusBasicValue**);
1899 n_elements = va_arg (var_args, int);
1900
1901 if (!dbus_message_iter_append_fixed_array (&array,
1902 element_type,
1903 value,
1904 n_elements)) {
1905 dbus_message_iter_abandon_container (&iter, &array);
1906 goto failed;
1907 }
1908 }
1909 else if (_DBUS_TYPE_IS_STRINGLIKE (element_type))
1910 {
1911 const char ***value_p;
1912 const char **value;
1913 int n_elements;
1914 int i;
1915
1916 value_p = va_arg (var_args, const char***);
1917 n_elements = va_arg (var_args, int);
1918
1919 value = *value_p;
1920
1921 i = 0;
1922 while (i < n_elements)
1923 {
1924 if (!dbus_message_iter_append_basic (&array,
1925 element_type,
1926 &value[i])) {
1927 dbus_message_iter_abandon_container (&iter, &array);
1928 goto failed;
1929 }
1930 ++i;
1931 }
1932 }
1933 else
1934 {
1935 _dbus_warn ("arrays of %s can't be appended with %s for now\n",
1936 _dbus_type_to_string (element_type),
1937 _DBUS_FUNCTION_NAME);
1938 goto failed;
1939 }
1940
1941 if (!dbus_message_iter_close_container (&iter, &array))
1942 goto failed;
1943 }
1944 #ifndef DBUS_DISABLE_CHECKS
1945 else
1946 {
1947 _dbus_warn ("type %s isn't supported yet in %s\n",
1948 _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
1949 goto failed;
1950 }
1951 #endif
1952
1953 type = va_arg (var_args, int);
1954 }
1955
1956 return TRUE;
1957
1958 failed:
1959 return FALSE;
1960 }
1961
2006 dbus_bool_t
2007 dbus_message_get_args (DBusMessage *message,
2008 DBusError *error,
2009 int first_arg_type,
2010 ...)
2011 {
2012 dbus_bool_t retval;
2013 va_list var_args;
2014
2015 _dbus_return_val_if_fail (message != NULL, FALSE);
2016 _dbus_return_val_if_error_is_set (error, FALSE);
2017
2018 va_start (var_args, first_arg_type);
2019 retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
2020 va_end (var_args);
2021
2022 return retval;
2023 }
2024
2035 dbus_bool_t
2036 dbus_message_get_args_valist (DBusMessage *message,
2037 DBusError *error,
2038 int first_arg_type,
2039 va_list var_args)
2040 {
2041 DBusMessageIter iter;
2042
2043 _dbus_return_val_if_fail (message != NULL, FALSE);
2044 _dbus_return_val_if_error_is_set (error, FALSE);
2045
2046 dbus_message_iter_init (message, &iter);
2047 return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
2048 }
2049
2050 static void
2051 _dbus_message_iter_init_common (DBusMessage *message,
2052 DBusMessageRealIter *real,
2053 int iter_type)
2054 {
2055 /* If these static assertions fail on your platform, report it as a bug. */
2056 _DBUS_STATIC_ASSERT (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
2057 _DBUS_STATIC_ASSERT (_DBUS_ALIGNOF (DBusMessageRealIter) <=
2058 _DBUS_ALIGNOF (DBusMessageIter));
2059 /* A failure of these two assertions would indicate that we've broken
2060 * ABI on this platform since 1.10.0. */
2061 _DBUS_STATIC_ASSERT (sizeof (DBusMessageIter_1_10_0) ==
2062 sizeof (DBusMessageIter));
2063 _DBUS_STATIC_ASSERT (_DBUS_ALIGNOF (DBusMessageIter_1_10_0) ==
2064 _DBUS_ALIGNOF (DBusMessageIter));
2065 /* If this static assertion fails, it means the DBusMessageIter struct
2066 * is not "packed", which might result in "iter = other_iter" not copying
2067 * every byte. */
2068 _DBUS_STATIC_ASSERT (sizeof (DBusMessageIter) ==
2069 4 * sizeof (void *) + sizeof (dbus_uint32_t) + 9 * sizeof (int));
2070
2071 /* Since the iterator will read or write who-knows-what from the
2072 * message, we need to get in the right byte order
2073 */
2074 ensure_byte_order (message);
2075
2076 real->message = message;
2077 real->changed_stamp = message->changed_stamp;
2078 real->iter_type = iter_type;
2079 real->sig_refcount = 0;
2080 }
2081
2104 dbus_bool_t
2105 dbus_message_iter_init (DBusMessage *message,
2106 DBusMessageIter *iter)
2107 {
2108 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2109 const DBusString *type_str;
2110 int type_pos;
2111
2112 _dbus_return_val_if_fail (message != NULL, FALSE);
2113 _dbus_return_val_if_fail (iter != NULL, FALSE);
2114
2115 get_const_signature (&message->header, &type_str, &type_pos);
2116
2117 _dbus_message_iter_init_common (message, real,
2118 DBUS_MESSAGE_ITER_TYPE_READER);
2119
2120 _dbus_type_reader_init (&real->u.reader,
2121 _dbus_header_get_byte_order (&message->header),
2122 type_str, type_pos,
2123 &message->body,
2124 0);
2125
2126 return _dbus_type_reader_get_current_type (&real->u.reader) != DBUS_TYPE_INVALID;
2127 }
2128
2135 dbus_bool_t
2136 dbus_message_iter_has_next (DBusMessageIter *iter)
2137 {
2138 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2139
2140 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
2141 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2142
2143 return _dbus_type_reader_has_next (&real->u.reader);
2144 }
2145
2154 dbus_bool_t
2155 dbus_message_iter_next (DBusMessageIter *iter)
2156 {
2157 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2158
2159 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
2160 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2161
2162 return _dbus_type_reader_next (&real->u.reader);
2163 }
2164
2179 int
2180 dbus_message_iter_get_arg_type (DBusMessageIter *iter)
2181 {
2182 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2183
2184 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2185 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2186
2187 return _dbus_type_reader_get_current_type (&real->u.reader);
2188 }
2189
2198 int
2199 dbus_message_iter_get_element_type (DBusMessageIter *iter)
2200 {
2201 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2202
2203 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2204 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
2205 _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
2206
2207 return _dbus_type_reader_get_element_type (&real->u.reader);
2208 }
2209
2235 void
2236 dbus_message_iter_recurse (DBusMessageIter *iter,
2237 DBusMessageIter *sub)
2238 {
2239 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2240 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2241
2242 _dbus_return_if_fail (_dbus_message_iter_check (real));
2243 _dbus_return_if_fail (sub != NULL);
2244
2245 *real_sub = *real;
2246 _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
2247 }
2248
2260 char *
2261 dbus_message_iter_get_signature (DBusMessageIter *iter)
2262 {
2263 const DBusString *sig;
2264 DBusString retstr;
2265 char *ret;
2266 int start, len;
2267 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2268
2269 _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
2270
2271 if (!_dbus_string_init (&retstr))
2272 return NULL;
2273
2274 _dbus_type_reader_get_signature (&real->u.reader, &sig,
2275 &start, &len);
2276 if (!_dbus_string_append_len (&retstr,
2277 _dbus_string_get_const_data (sig) + start,
2278 len))
2279 return NULL;
2280 if (!_dbus_string_steal_data (&retstr, &ret))
2281 return NULL;
2282 _dbus_string_free (&retstr);
2283 return ret;
2284 }
2285
2333 void
2334 dbus_message_iter_get_basic (DBusMessageIter *iter,
2335 void *value)
2336 {
2337 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2338
2339 _dbus_return_if_fail (_dbus_message_iter_check (real));
2340 _dbus_return_if_fail (value != NULL);
2341
2342 if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_UNIX_FD)
2343 {
2344 #ifdef HAVE_UNIX_FD_PASSING
2345 DBusBasicValue idx;
2346
2347 _dbus_type_reader_read_basic(&real->u.reader, &idx);
2348
2349 if (idx.u32 >= real->message->n_unix_fds) {
2350 /* Hmm, we cannot really signal an error here, so let's make
2351 sure to return an invalid fd. */
2352 *((int*) value) = -1;
2353 return;
2354 }
2355
2356 *((int*) value) = _dbus_dup(real->message->unix_fds[idx.u32], NULL);
2357 #else
2358 *((int*) value) = -1;
2359 #endif
2360 }
2361 else
2362 {
2363 _dbus_type_reader_read_basic (&real->u.reader,
2364 value);
2365 }
2366 }
2367
2378 int
2379 dbus_message_iter_get_element_count (DBusMessageIter *iter)
2380 {
2381 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2382 DBusTypeReader array;
2383 int element_type;
2384 int n_elements = 0;
2385
2386 _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
2387 _dbus_return_val_if_fail (_dbus_type_reader_get_current_type (&real->u.reader)
2388 == DBUS_TYPE_ARRAY, 0);
2389
2390 element_type = _dbus_type_reader_get_element_type (&real->u.reader);
2391 _dbus_type_reader_recurse (&real->u.reader, &array);
2392 if (dbus_type_is_fixed (element_type))
2393 {
2394 int alignment = _dbus_type_get_alignment (element_type);
2395 int total_len = _dbus_type_reader_get_array_length (&array);
2396 n_elements = total_len / alignment;
2397 }
2398 else
2399 {
2400 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
2401 {
2402 ++n_elements;
2403 _dbus_type_reader_next (&array);
2404 }
2405 }
2406
2407 return n_elements;
2408 }
2409
2422 int
2423 dbus_message_iter_get_array_len (DBusMessageIter *iter)
2424 {
2425 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2426
2427 _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
2428
2429 return _dbus_type_reader_get_array_length (&real->u.reader);
2430 }
2431
2467 void
2468 dbus_message_iter_get_fixed_array (DBusMessageIter *iter,
2469 void *value,
2470 int *n_elements)
2471 {
2472 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2473 #ifndef DBUS_DISABLE_CHECKS
2474 int subtype = _dbus_type_reader_get_current_type(&real->u.reader);
2475
2476 _dbus_return_if_fail (_dbus_message_iter_check (real));
2477 _dbus_return_if_fail (value != NULL);
2478 _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) ||
2479 (dbus_type_is_fixed (subtype) && subtype != DBUS_TYPE_UNIX_FD));
2480 #endif
2481
2482 _dbus_type_reader_read_fixed_multi (&real->u.reader,
2483 value, n_elements);
2484 }
2485
2497 void
2498 dbus_message_iter_init_append (DBusMessage *message,
2499 DBusMessageIter *iter)
2500 {
2501 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2502
2503 _dbus_return_if_fail (message != NULL);
2504 _dbus_return_if_fail (iter != NULL);
2505
2506 _dbus_message_iter_init_common (message, real,
2507 DBUS_MESSAGE_ITER_TYPE_WRITER);
2508
2509 /* We create the signature string and point iterators at it "on demand"
2510 * when a value is actually appended. That means that init() never fails
2511 * due to OOM.
2512 */
2513 _dbus_type_writer_init_types_delayed (&real->u.writer,
2514 _dbus_header_get_byte_order (&message->header),
2515 &message->body,
2516 _dbus_string_get_length (&message->body));
2517 }
2518
2527 static dbus_bool_t
2528 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
2529 {
2530 DBusString *str;
2531 const DBusString *current_sig;
2532 int current_sig_pos;
2533
2534 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2535
2536 if (real->u.writer.type_str != NULL)
2537 {
2538 _dbus_assert (real->sig_refcount > 0);
2539 real->sig_refcount += 1;
2540 return TRUE;
2541 }
2542
2543 str = dbus_new (DBusString, 1);
2544 if (str == NULL)
2545 return FALSE;
2546
2547 if (!_dbus_header_get_field_raw (&real->message->header,
2548 DBUS_HEADER_FIELD_SIGNATURE,
2549 &current_sig, &current_sig_pos))
2550 current_sig = NULL;
2551
2552 if (current_sig)
2553 {
2554 int current_len;
2555
2556 current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
2557 current_sig_pos += 1; /* move on to sig data */
2558
2559 if (!_dbus_string_init_preallocated (str, current_len + 4))
2560 {
2561 dbus_free (str);
2562 return FALSE;
2563 }
2564
2565 if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
2566 str, 0))
2567 {
2568 _dbus_string_free (str);
2569 dbus_free (str);
2570 return FALSE;
2571 }
2572 }
2573 else
2574 {
2575 if (!_dbus_string_init_preallocated (str, 4))
2576 {
2577 dbus_free (str);
2578 return FALSE;
2579 }
2580 }
2581
2582 real->sig_refcount = 1;
2583
2584 _dbus_type_writer_add_types (&real->u.writer,
2585 str, _dbus_string_get_length (str));
2586 return TRUE;
2587 }
2588
2598 static dbus_bool_t
2599 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
2600 {
2601 DBusString *str;
2602 const char *v_STRING;
2603 dbus_bool_t retval;
2604
2605 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2606 _dbus_assert (real->u.writer.type_str != NULL);
2607 _dbus_assert (real->sig_refcount > 0);
2608
2609 real->sig_refcount -= 1;
2610
2611 if (real->sig_refcount > 0)
2612 return TRUE;
2613 _dbus_assert (real->sig_refcount == 0);
2614
2615 retval = TRUE;
2616
2617 str = real->u.writer.type_str;
2618
2619 v_STRING = _dbus_string_get_const_data (str);
2620 if (!_dbus_header_set_field_basic (&real->message->header,
2621 DBUS_HEADER_FIELD_SIGNATURE,
2622 DBUS_TYPE_SIGNATURE,
2623 &v_STRING))
2624 retval = FALSE;
2625
2626 _dbus_type_writer_remove_types (&real->u.writer);
2627 _dbus_string_free (str);
2628 dbus_free (str);
2629
2630 return retval;
2631 }
2632
2640 static void
2641 _dbus_message_iter_abandon_signature (DBusMessageRealIter *real)
2642 {
2643 DBusString *str;
2644
2645 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2646 _dbus_assert (real->u.writer.type_str != NULL);
2647 _dbus_assert (real->sig_refcount > 0);
2648
2649 real->sig_refcount -= 1;
2650
2651 if (real->sig_refcount > 0)
2652 return;
2653 _dbus_assert (real->sig_refcount == 0);
2654
2655 str = real->u.writer.type_str;
2656
2657 _dbus_type_writer_remove_types (&real->u.writer);
2658 _dbus_string_free (str);
2659 dbus_free (str);
2660 }
2661
2662 #ifndef DBUS_DISABLE_CHECKS
2663 static dbus_bool_t
2664 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
2665 {
2666 if (!_dbus_message_iter_check (iter))
2667 return FALSE;
2668
2669 if (iter->message->locked)
2670 {
2671 _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)\n");
2672 return FALSE;
2673 }
2674
2675 return TRUE;
2676 }
2677 #endif /* DBUS_DISABLE_CHECKS */
2678
2679 #ifdef HAVE_UNIX_FD_PASSING
2680 static int *
2681 expand_fd_array(DBusMessage *m,
2682 unsigned n)
2683 {
2684 _dbus_assert(m);
2685
2686 /* This makes space for adding n new fds to the array and returns a
2687 pointer to the place were the first fd should be put. */
2688
2689 if (m->n_unix_fds + n > m->n_unix_fds_allocated)
2690 {
2691 unsigned k;
2692 int *p;
2693
2694 /* Make twice as much space as necessary */
2695 k = (m->n_unix_fds + n) * 2;
2696
2697 /* Allocate at least four */
2698 if (k < 4)
2699 k = 4;
2700
2701 p = dbus_realloc(m->unix_fds, k * sizeof(int));
2702 if (p == NULL)
2703 return NULL;
2704
2705 m->unix_fds = p;
2706 m->n_unix_fds_allocated = k;
2707 }
2708
2709 return m->unix_fds + m->n_unix_fds;
2710 }
2711 #endif
2712
2732 dbus_bool_t
2733 dbus_message_iter_append_basic (DBusMessageIter *iter,
2734 int type,
2735 const void *value)
2736 {
2737 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2738 dbus_bool_t ret;
2739
2740 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2741 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2742 _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
2743 _dbus_return_val_if_fail (value != NULL, FALSE);
2744
2745 #ifndef DBUS_DISABLE_CHECKS
2746 switch (type)
2747 {
2748 const char * const *string_p;
2749 const dbus_bool_t *bool_p;
2750
2751 case DBUS_TYPE_STRING:
2752 string_p = value;
2753 _dbus_return_val_if_fail (_dbus_check_is_valid_utf8 (*string_p), FALSE);
2754 break;
2755
2756 case DBUS_TYPE_OBJECT_PATH:
2757 string_p = value;
2758 _dbus_return_val_if_fail (_dbus_check_is_valid_path (*string_p), FALSE);
2759 break;
2760
2761 case DBUS_TYPE_SIGNATURE:
2762 string_p = value;
2763 _dbus_return_val_if_fail (_dbus_check_is_valid_signature (*string_p), FALSE);
2764 break;
2765
2766 case DBUS_TYPE_BOOLEAN:
2767 bool_p = value;
2768 _dbus_return_val_if_fail (*bool_p == 0 || *bool_p == 1, FALSE);
2769 break;
2770
2771 default:
2772 {
2773 /* nothing to check, all possible values are allowed */
2774 }
2775 }
2776 #endif
2777
2778 if (!_dbus_message_iter_open_signature (real))
2779 return FALSE;
2780
2781 if (type == DBUS_TYPE_UNIX_FD)
2782 {
2783 #ifdef HAVE_UNIX_FD_PASSING
2784 int *fds;
2785 dbus_uint32_t u;
2786
2787 /* First step, include the fd in the fd list of this message */
2788 if (!(fds = expand_fd_array(real->message, 1)))
2789 return FALSE;
2790
2791 *fds = _dbus_dup(*(int*) value, NULL);
2792 if (*fds < 0)
2793 return FALSE;
2794
2795 u = real->message->n_unix_fds;
2796
2797 /* Second step, write the index to the fd */
2798 if (!(ret = _dbus_type_writer_write_basic (&real->u.writer, DBUS_TYPE_UNIX_FD, &u))) {
2799 _dbus_close(*fds, NULL);
2800 return FALSE;
2801 }
2802
2803 real->message->n_unix_fds += 1;
2804 u += 1;
2805
2806 /* Final step, update the header accordingly */
2807 ret = _dbus_header_set_field_basic (&real->message->header,
2808 DBUS_HEADER_FIELD_UNIX_FDS,
2809 DBUS_TYPE_UINT32,
2810 &u);
2811
2812 /* If any of these operations fail the message is
2813 hosed. However, no memory or fds should be leaked since what
2814 has been added to message has been added to the message, and
2815 can hence be accounted for when the message is being
2816 freed. */
2817 #else
2818 ret = FALSE;
2819 #endif
2820 }
2821 else
2822 {
2823 ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
2824 }
2825
2826 if (!_dbus_message_iter_close_signature (real))
2827 ret = FALSE;
2828
2829 return ret;
2830 }
2831
2867 dbus_bool_t
2868 dbus_message_iter_append_fixed_array (DBusMessageIter *iter,
2869 int element_type,
2870 const void *value,
2871 int n_elements)
2872 {
2873 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2874 dbus_bool_t ret;
2875
2876 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2877 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2878 _dbus_return_val_if_fail (dbus_type_is_fixed (element_type) && element_type != DBUS_TYPE_UNIX_FD, FALSE);
2879 _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
2880 _dbus_return_val_if_fail (value != NULL, FALSE);
2881 _dbus_return_val_if_fail (n_elements >= 0, FALSE);
2882 _dbus_return_val_if_fail (n_elements <=
2883 DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type),
2884 FALSE);
2885
2886 #ifndef DBUS_DISABLE_CHECKS
2887 if (element_type == DBUS_TYPE_BOOLEAN)
2888 {
2889 const dbus_bool_t * const *bools = value;
2890 int i;
2891
2892 for (i = 0; i < n_elements; i++)
2893 {
2894 _dbus_return_val_if_fail ((*bools)[i] == 0 || (*bools)[i] == 1, FALSE);
2895 }
2896 }
2897 #endif
2898
2899 ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
2900
2901 return ret;
2902 }
2903
2925 dbus_bool_t
2926 dbus_message_iter_open_container (DBusMessageIter *iter,
2927 int type,
2928 const char *contained_signature,
2929 DBusMessageIter *sub)
2930 {
2931 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2932 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2933 DBusString contained_str;
2934
2935 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2936 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2937 _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
2938 _dbus_return_val_if_fail (sub != NULL, FALSE);
2939 _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
2940 contained_signature == NULL) ||
2941 (type == DBUS_TYPE_DICT_ENTRY &&
2942 contained_signature == NULL) ||
2943 (type == DBUS_TYPE_VARIANT &&
2944 contained_signature != NULL) ||
2945 (type == DBUS_TYPE_ARRAY &&
2946 contained_signature != NULL), FALSE);
2947
2948 /* this would fail if the contained_signature is a dict entry, since
2949 * dict entries are invalid signatures standalone (they must be in
2950 * an array)
2951 */
2952 _dbus_return_val_if_fail ((type == DBUS_TYPE_ARRAY && contained_signature && *contained_signature == DBUS_DICT_ENTRY_BEGIN_CHAR) ||
2953 (contained_signature == NULL ||
2954 _dbus_check_is_valid_signature (contained_signature)),
2955 FALSE);
2956
2957 if (!_dbus_message_iter_open_signature (real))
2958 return FALSE;
2959
2960 *real_sub = *real;
2961
2962 if (contained_signature != NULL)
2963 {
2964 _dbus_string_init_const (&contained_str, contained_signature);
2965
2966 return _dbus_type_writer_recurse (&real->u.writer,
2967 type,
2968 &contained_str, 0,
2969 &real_sub->u.writer);
2970 }
2971 else
2972 {
2973 return _dbus_type_writer_recurse (&real->u.writer,
2974 type,
2975 NULL, 0,
2976 &real_sub->u.writer);
2977 }
2978 }
2979
2980
2994 dbus_bool_t
2995 dbus_message_iter_close_container (DBusMessageIter *iter,
2996 DBusMessageIter *sub)
2997 {
2998 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2999 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
3000 dbus_bool_t ret;
3001
3002 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
3003 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
3004 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
3005 _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
3006
3007 ret = _dbus_type_writer_unrecurse (&real->u.writer,
3008 &real_sub->u.writer);
3009
3010 if (!_dbus_message_iter_close_signature (real))
3011 ret = FALSE;
3012
3013 return ret;
3014 }
3015
3027 void
3028 dbus_message_iter_abandon_container (DBusMessageIter *iter,
3029 DBusMessageIter *sub)
3030 {
3031 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3032 #ifndef DBUS_DISABLE_CHECKS
3033 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
3034
3035 _dbus_return_if_fail (_dbus_message_iter_append_check (real));
3036 _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
3037 _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
3038 _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
3039 #endif
3040
3041 _dbus_message_iter_abandon_signature (real);
3042 }
3043
3060 void
3061 dbus_message_set_no_reply (DBusMessage *message,
3062 dbus_bool_t no_reply)
3063 {
3064 _dbus_return_if_fail (message != NULL);
3065 _dbus_return_if_fail (!message->locked);
3066
3067 _dbus_header_toggle_flag (&message->header,
3068 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED,
3069 no_reply);
3070 }
3071
3079 dbus_bool_t
3080 dbus_message_get_no_reply (DBusMessage *message)
3081 {
3082 _dbus_return_val_if_fail (message != NULL, FALSE);
3083
3084 return _dbus_header_get_flag (&message->header,
3085 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED);
3086 }
3087
3102 void
3103 dbus_message_set_auto_start (DBusMessage *message,
3104 dbus_bool_t auto_start)
3105 {
3106 _dbus_return_if_fail (message != NULL);
3107 _dbus_return_if_fail (!message->locked);
3108
3109 _dbus_header_toggle_flag (&message->header,
3110 DBUS_HEADER_FLAG_NO_AUTO_START,
3111 !auto_start);
3112 }
3113
3121 dbus_bool_t
3122 dbus_message_get_auto_start (DBusMessage *message)
3123 {
3124 _dbus_return_val_if_fail (message != NULL, FALSE);
3125
3126 return !_dbus_header_get_flag (&message->header,
3127 DBUS_HEADER_FLAG_NO_AUTO_START);
3128 }
3129
3130
3143 dbus_bool_t
3144 dbus_message_set_path (DBusMessage *message,
3145 const char *object_path)
3146 {
3147 _dbus_return_val_if_fail (message != NULL, FALSE);
3148 _dbus_return_val_if_fail (!message->locked, FALSE);
3149 _dbus_return_val_if_fail (object_path == NULL ||
3150 _dbus_check_is_valid_path (object_path),
3151 FALSE);
3152
3153 return set_or_delete_string_field (message,
3154 DBUS_HEADER_FIELD_PATH,
3155 DBUS_TYPE_OBJECT_PATH,
3156 object_path);
3157 }
3158
3172 const char*
3173 dbus_message_get_path (DBusMessage *message)
3174 {
3175 const char *v;
3176
3177 _dbus_return_val_if_fail (message != NULL, NULL);
3178
3179 v = NULL; /* in case field doesn't exist */
3180 _dbus_header_get_field_basic (&message->header,
3181 DBUS_HEADER_FIELD_PATH,
3182 DBUS_TYPE_OBJECT_PATH,
3183 (void *) &v);
3184 return v;
3185 }
3186
3196 dbus_bool_t
3197 dbus_message_has_path (DBusMessage *message,
3198 const char *path)
3199 {
3200 const char *msg_path;
3201 msg_path = dbus_message_get_path (message);
3202
3203 if (msg_path == NULL)
3204 {
3205 if (path == NULL)
3206 return TRUE;
3207 else
3208 return FALSE;
3209 }
3210
3211 if (path == NULL)
3212 return FALSE;
3213
3214 if (strcmp (msg_path, path) == 0)
3215 return TRUE;
3216
3217 return FALSE;
3218 }
3219
3240 dbus_bool_t
3241 dbus_message_get_path_decomposed (DBusMessage *message,
3242 char ***path)
3243 {
3244 const char *v;
3245
3246 _dbus_return_val_if_fail (message != NULL, FALSE);
3247 _dbus_return_val_if_fail (path != NULL, FALSE);
3248
3249 *path = NULL;
3250
3251 v = dbus_message_get_path (message);
3252 if (v != NULL)
3253 {
3254 if (!_dbus_decompose_path (v, strlen (v),
3255 path, NULL))
3256 return FALSE;
3257 }
3258 return TRUE;
3259 }
3260
3274 dbus_bool_t
3275 dbus_message_set_interface (DBusMessage *message,
3276 const char *iface)
3277 {
3278 _dbus_return_val_if_fail (message != NULL, FALSE);
3279 _dbus_return_val_if_fail (!message->locked, FALSE);
3280 _dbus_return_val_if_fail (iface == NULL ||
3281 _dbus_check_is_valid_interface (iface),
3282 FALSE);
3283
3284 return set_or_delete_string_field (message,
3285 DBUS_HEADER_FIELD_INTERFACE,
3286 DBUS_TYPE_STRING,
3287 iface);
3288 }
3289
3303 const char*
3304 dbus_message_get_interface (DBusMessage *message)
3305 {
3306 const char *v;
3307
3308 _dbus_return_val_if_fail (message != NULL, NULL);
3309
3310 v = NULL; /* in case field doesn't exist */
3311 _dbus_header_get_field_basic (&message->header,
3312 DBUS_HEADER_FIELD_INTERFACE,
3313 DBUS_TYPE_STRING,
3314 (void *) &v);
3315 return v;
3316 }
3317
3325 dbus_bool_t
3326 dbus_message_has_interface (DBusMessage *message,
3327 const char *iface)
3328 {
3329 const char *msg_interface;
3330 msg_interface = dbus_message_get_interface (message);
3331
3332 if (msg_interface == NULL)
3333 {
3334 if (iface == NULL)
3335 return TRUE;
3336 else
3337 return FALSE;
3338 }
3339
3340 if (iface == NULL)
3341 return FALSE;
3342
3343 if (strcmp (msg_interface, iface) == 0)
3344 return TRUE;
3345
3346 return FALSE;
3347
3348 }
3349
3362 dbus_bool_t
3363 dbus_message_set_member (DBusMessage *message,
3364 const char *member)
3365 {
3366 _dbus_return_val_if_fail (message != NULL, FALSE);
3367 _dbus_return_val_if_fail (!message->locked, FALSE);
3368 _dbus_return_val_if_fail (member == NULL ||
3369 _dbus_check_is_valid_member (member),
3370 FALSE);
3371
3372 return set_or_delete_string_field (message,
3373 DBUS_HEADER_FIELD_MEMBER,
3374 DBUS_TYPE_STRING,
3375 member);
3376 }
3377
3389 const char*
3390 dbus_message_get_member (DBusMessage *message)
3391 {
3392 const char *v;
3393
3394 _dbus_return_val_if_fail (message != NULL, NULL);
3395
3396 v = NULL; /* in case field doesn't exist */
3397 _dbus_header_get_field_basic (&message->header,
3398 DBUS_HEADER_FIELD_MEMBER,
3399 DBUS_TYPE_STRING,
3400 (void *) &v);
3401 return v;
3402 }
3403
3411 dbus_bool_t
3412 dbus_message_has_member (DBusMessage *message,
3413 const char *member)
3414 {
3415 const char *msg_member;
3416 msg_member = dbus_message_get_member (message);
3417
3418 if (msg_member == NULL)
3419 {
3420 if (member == NULL)
3421 return TRUE;
3422 else
3423 return FALSE;
3424 }
3425
3426 if (member == NULL)
3427 return FALSE;
3428
3429 if (strcmp (msg_member, member) == 0)
3430 return TRUE;
3431
3432 return FALSE;
3433
3434 }
3435
3447 dbus_bool_t
3448 dbus_message_set_error_name (DBusMessage *message,
3449 const char *error_name)
3450 {
3451 _dbus_return_val_if_fail (message != NULL, FALSE);
3452 _dbus_return_val_if_fail (!message->locked, FALSE);
3453 _dbus_return_val_if_fail (error_name == NULL ||
3454 _dbus_check_is_valid_error_name (error_name),
3455 FALSE);
3456
3457 return set_or_delete_string_field (message,
3458 DBUS_HEADER_FIELD_ERROR_NAME,
3459 DBUS_TYPE_STRING,
3460 error_name);
3461 }
3462
3473 const char*
3474 dbus_message_get_error_name (DBusMessage *message)
3475 {
3476 const char *v;
3477
3478 _dbus_return_val_if_fail (message != NULL, NULL);
3479
3480 v = NULL; /* in case field doesn't exist */
3481 _dbus_header_get_field_basic (&message->header,
3482 DBUS_HEADER_FIELD_ERROR_NAME,
3483 DBUS_TYPE_STRING,
3484 (void *) &v);
3485 return v;
3486 }
3487
3501 dbus_bool_t
3502 dbus_message_set_destination (DBusMessage *message,
3503 const char *destination)
3504 {
3505 _dbus_return_val_if_fail (message != NULL, FALSE);
3506 _dbus_return_val_if_fail (!message->locked, FALSE);
3507 _dbus_return_val_if_fail (destination == NULL ||
3508 _dbus_check_is_valid_bus_name (destination),
3509 FALSE);
3510
3511 return set_or_delete_string_field (message,
3512 DBUS_HEADER_FIELD_DESTINATION,
3513 DBUS_TYPE_STRING,
3514 destination);
3515 }
3516
3526 const char*
3527 dbus_message_get_destination (DBusMessage *message)
3528 {
3529 const char *v;
3530
3531 _dbus_return_val_if_fail (message != NULL, NULL);
3532
3533 v = NULL; /* in case field doesn't exist */
3534 _dbus_header_get_field_basic (&message->header,
3535 DBUS_HEADER_FIELD_DESTINATION,
3536 DBUS_TYPE_STRING,
3537 (void *) &v);
3538 return v;
3539 }
3540
3555 dbus_bool_t
3556 dbus_message_set_sender (DBusMessage *message,
3557 const char *sender)
3558 {
3559 _dbus_return_val_if_fail (message != NULL, FALSE);
3560 _dbus_return_val_if_fail (!message->locked, FALSE);
3561 _dbus_return_val_if_fail (sender == NULL ||
3562 _dbus_check_is_valid_bus_name (sender),
3563 FALSE);
3564
3565 return set_or_delete_string_field (message,
3566 DBUS_HEADER_FIELD_SENDER,
3567 DBUS_TYPE_STRING,
3568 sender);
3569 }
3570
3586 const char*
3587 dbus_message_get_sender (DBusMessage *message)
3588 {
3589 const char *v;
3590
3591 _dbus_return_val_if_fail (message != NULL, NULL);
3592
3593 v = NULL; /* in case field doesn't exist */
3594 _dbus_header_get_field_basic (&message->header,
3595 DBUS_HEADER_FIELD_SENDER,
3596 DBUS_TYPE_STRING,
3597 (void *) &v);
3598 return v;
3599 }
3600
3619 const char*
3620 dbus_message_get_signature (DBusMessage *message)
3621 {
3622 const DBusString *type_str;
3623 int type_pos;
3624
3625 _dbus_return_val_if_fail (message != NULL, NULL);
3626
3627 get_const_signature (&message->header, &type_str, &type_pos);
3628
3629 return _dbus_string_get_const_data_len (type_str, type_pos, 0);
3630 }
3631
3632 static dbus_bool_t
3633 _dbus_message_has_type_interface_member (DBusMessage *message,
3634 int type,
3635 const char *iface,
3636 const char *member)
3637 {
3638 const char *n;
3639
3640 _dbus_assert (message != NULL);
3641 _dbus_assert (iface != NULL);
3642 _dbus_assert (member != NULL);
3643
3644 if (dbus_message_get_type (message) != type)
3645 return FALSE;
3646
3647 /* Optimize by checking the short member name first
3648 * instead of the longer interface name
3649 */
3650
3651 n = dbus_message_get_member (message);
3652
3653 if (n && strcmp (n, member) == 0)
3654 {
3655 n = dbus_message_get_interface (message);
3656
3657 if (n == NULL || strcmp (n, iface) == 0)
3658 return TRUE;
3659 }
3660
3661 return FALSE;
3662 }
3663
3678 dbus_bool_t
3679 dbus_message_is_method_call (DBusMessage *message,
3680 const char *iface,
3681 const char *method)
3682 {
3683 _dbus_return_val_if_fail (message != NULL, FALSE);
3684 _dbus_return_val_if_fail (iface != NULL, FALSE);
3685 _dbus_return_val_if_fail (method != NULL, FALSE);
3686 /* don't check that interface/method are valid since it would be
3687 * expensive, and not catch many common errors
3688 */
3689
3690 return _dbus_message_has_type_interface_member (message,
3691 DBUS_MESSAGE_TYPE_METHOD_CALL,
3692 iface, method);
3693 }
3694
3706 dbus_bool_t
3707 dbus_message_is_signal (DBusMessage *message,
3708 const char *iface,
3709 const char *signal_name)
3710 {
3711 _dbus_return_val_if_fail (message != NULL, FALSE);
3712 _dbus_return_val_if_fail (iface != NULL, FALSE);
3713 _dbus_return_val_if_fail (signal_name != NULL, FALSE);
3714 /* don't check that interface/name are valid since it would be
3715 * expensive, and not catch many common errors
3716 */
3717
3718 return _dbus_message_has_type_interface_member (message,
3719 DBUS_MESSAGE_TYPE_SIGNAL,
3720 iface, signal_name);
3721 }
3722
3733 dbus_bool_t
3734 dbus_message_is_error (DBusMessage *message,
3735 const char *error_name)
3736 {
3737 const char *n;
3738
3739 _dbus_return_val_if_fail (message != NULL, FALSE);
3740 _dbus_return_val_if_fail (error_name != NULL, FALSE);
3741 /* don't check that error_name is valid since it would be expensive,
3742 * and not catch many common errors
3743 */
3744
3745 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
3746 return FALSE;
3747
3748 n = dbus_message_get_error_name (message);
3749
3750 if (n && strcmp (n, error_name) == 0)
3751 return TRUE;
3752 else
3753 return FALSE;
3754 }
3755
3766 dbus_bool_t
3767 dbus_message_has_destination (DBusMessage *message,
3768 const char *name)
3769 {
3770 const char *s;
3771
3772 _dbus_return_val_if_fail (message != NULL, FALSE);
3773 _dbus_return_val_if_fail (name != NULL, FALSE);
3774 /* don't check that name is valid since it would be expensive, and
3775 * not catch many common errors
3776 */
3777
3778 s = dbus_message_get_destination (message);
3779
3780 if (s && strcmp (s, name) == 0)
3781 return TRUE;
3782 else
3783 return FALSE;
3784 }
3785
3801 dbus_bool_t
3802 dbus_message_has_sender (DBusMessage *message,
3803 const char *name)
3804 {
3805 const char *s;
3806
3807 _dbus_return_val_if_fail (message != NULL, FALSE);
3808 _dbus_return_val_if_fail (name != NULL, FALSE);
3809 /* don't check that name is valid since it would be expensive, and
3810 * not catch many common errors
3811 */
3812
3813 s = dbus_message_get_sender (message);
3814
3815 if (s && strcmp (s, name) == 0)
3816 return TRUE;
3817 else
3818 return FALSE;
3819 }
3820
3830 dbus_bool_t
3831 dbus_message_has_signature (DBusMessage *message,
3832 const char *signature)
3833 {
3834 const char *s;
3835
3836 _dbus_return_val_if_fail (message != NULL, FALSE);
3837 _dbus_return_val_if_fail (signature != NULL, FALSE);
3838 /* don't check that signature is valid since it would be expensive,
3839 * and not catch many common errors
3840 */
3841
3842 s = dbus_message_get_signature (message);
3843
3844 if (s && strcmp (s, signature) == 0)
3845 return TRUE;
3846 else
3847 return FALSE;
3848 }
3849
3872 dbus_bool_t
3873 dbus_set_error_from_message (DBusError *error,
3874 DBusMessage *message)
3875 {
3876 const char *str;
3877
3878 _dbus_return_val_if_fail (message != NULL, FALSE);
3879 _dbus_return_val_if_error_is_set (error, FALSE);
3880
3881 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
3882 return FALSE;
3883
3884 str = NULL;
3885 dbus_message_get_args (message, NULL,
3886 DBUS_TYPE_STRING, &str,
3887 DBUS_TYPE_INVALID);
3888
3889 dbus_set_error (error, dbus_message_get_error_name (message),
3890 str ? "%s" : NULL, str);
3891
3892 return TRUE;
3893 }
3894
3901 dbus_bool_t
3902 dbus_message_contains_unix_fds(DBusMessage *message)
3903 {
3904 #ifdef HAVE_UNIX_FD_PASSING
3905 _dbus_assert(message);
3906
3907 return message->n_unix_fds > 0;
3908 #else
3909 return FALSE;
3910 #endif
3911 }
3912
3931 #define INITIAL_LOADER_DATA_LEN 32
3932
3939 DBusMessageLoader*
3940 _dbus_message_loader_new (void)
3941 {
3942 DBusMessageLoader *loader;
3943
3944 loader = dbus_new0 (DBusMessageLoader, 1);
3945 if (loader == NULL)
3946 return NULL;
3947
3948 loader->refcount = 1;
3949
3950 loader->corrupted = FALSE;
3951 loader->corruption_reason = DBUS_VALID;
3952
3953 /* this can be configured by the app, but defaults to the protocol max */
3954 loader->max_message_size = DBUS_MAXIMUM_MESSAGE_LENGTH;
3955
3956 /* We set a very relatively conservative default here since due to how
3957 SCM_RIGHTS works we need to preallocate an fd array of the maximum
3958 number of unix fds we want to receive in advance. A
3959 try-and-reallocate loop is not possible. */
3960 loader->max_message_unix_fds = DBUS_DEFAULT_MESSAGE_UNIX_FDS;
3961
3962 if (!_dbus_string_init (&loader->data))
3963 {
3964 dbus_free (loader);
3965 return NULL;
3966 }
3967
3968 /* preallocate the buffer for speed, ignore failure */
3969 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
3970 _dbus_string_set_length (&loader->data, 0);
3971
3972 #ifdef HAVE_UNIX_FD_PASSING
3973 loader->unix_fds = NULL;
3974 loader->n_unix_fds = loader->n_unix_fds_allocated = 0;
3975 loader->unix_fds_outstanding = FALSE;
3976 #endif
3977
3978 return loader;
3979 }
3980
3987 DBusMessageLoader *
3988 _dbus_message_loader_ref (DBusMessageLoader *loader)
3989 {
3990 loader->refcount += 1;
3991
3992 return loader;
3993 }
3994
4001 void
4002 _dbus_message_loader_unref (DBusMessageLoader *loader)
4003 {
4004 loader->refcount -= 1;
4005 if (loader->refcount == 0)
4006 {
4007 #ifdef HAVE_UNIX_FD_PASSING
4008 close_unix_fds(loader->unix_fds, &loader->n_unix_fds);
4009 dbus_free(loader->unix_fds);
4010 #endif
4011 _dbus_list_foreach (&loader->messages,
4012 (DBusForeachFunction) dbus_message_unref,
4013 NULL);
4014 _dbus_list_clear (&loader->messages);
4015 _dbus_string_free (&loader->data);
4016 dbus_free (loader);
4017 }
4018 }
4019
4038 void
4039 _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
4040 DBusString **buffer)
4041 {
4042 _dbus_assert (!loader->buffer_outstanding);
4043
4044 *buffer = &loader->data;
4045
4046 loader->buffer_outstanding = TRUE;
4047 }
4048
4058 void
4059 _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
4060 DBusString *buffer)
4061 {
4062 _dbus_assert (loader->buffer_outstanding);
4063 _dbus_assert (buffer == &loader->data);
4064
4065 loader->buffer_outstanding = FALSE;
4066 }
4067
4078 dbus_bool_t
4079 _dbus_message_loader_get_unix_fds(DBusMessageLoader *loader,
4080 int **fds,
4081 unsigned *max_n_fds)
4082 {
4083 #ifdef HAVE_UNIX_FD_PASSING
4084 _dbus_assert (!loader->unix_fds_outstanding);
4085
4086 /* Allocate space where we can put the fds we read. We allocate
4087 space for max_message_unix_fds since this is an
4088 upper limit how many fds can be received within a single
4089 message. Since SCM_RIGHTS doesn't allow a reallocate+retry logic
4090 we are allocating the maximum possible array size right from the
4091 beginning. This sucks a bit, however unless SCM_RIGHTS is fixed
4092 there is no better way. */
4093
4094 if (loader->n_unix_fds_allocated < loader->max_message_unix_fds)
4095 {
4096 int *a = dbus_realloc(loader->unix_fds,
4097 loader->max_message_unix_fds * sizeof(loader->unix_fds[0]));
4098
4099 if (!a)
4100 return FALSE;
4101
4102 loader->unix_fds = a;
4103 loader->n_unix_fds_allocated = loader->max_message_unix_fds;
4104 }
4105
4106 *fds = loader->unix_fds + loader->n_unix_fds;
4107 *max_n_fds = loader->n_unix_fds_allocated - loader->n_unix_fds;
4108
4109 loader->unix_fds_outstanding = TRUE;
4110 return TRUE;
4111 #else
4112 _dbus_assert_not_reached("Platform doesn't support unix fd passing");
4113 return FALSE;
4114 #endif
4115 }
4116
4127 void
4128 _dbus_message_loader_return_unix_fds(DBusMessageLoader *loader,
4129 int *fds,
4130 unsigned n_fds)
4131 {
4132 #ifdef HAVE_UNIX_FD_PASSING
4133 _dbus_assert(loader->unix_fds_outstanding);
4134 _dbus_assert(loader->unix_fds + loader->n_unix_fds == fds);
4135 _dbus_assert(loader->n_unix_fds + n_fds <= loader->n_unix_fds_allocated);
4136
4137 loader->n_unix_fds += n_fds;
4138 loader->unix_fds_outstanding = FALSE;
4139
4140 if (n_fds && loader->unix_fds_change)
4141 loader->unix_fds_change (loader->unix_fds_change_data);
4142 #else
4143 _dbus_assert_not_reached("Platform doesn't support unix fd passing");
4144 #endif
4145 }
4146
4147 /*
4148 * FIXME when we move the header out of the buffer, that memmoves all
4149 * buffered messages. Kind of crappy.
4150 *
4151 * Also we copy the header and body, which is kind of crappy. To
4152 * avoid this, we have to allow header and body to be in a single
4153 * memory block, which is good for messages we read and bad for
4154 * messages we are creating. But we could move_len() the buffer into
4155 * this single memory block, and move_len() will just swap the buffers
4156 * if you're moving the entire buffer replacing the dest string.
4157 *
4158 * We could also have the message loader tell the transport how many
4159 * bytes to read; so it would first ask for some arbitrary number like
4160 * 256, then if the message was incomplete it would use the
4161 * header/body len to ask for exactly the size of the message (or
4162 * blocks the size of a typical kernel buffer for the socket). That
4163 * way we don't get trailing bytes in the buffer that have to be
4164 * memmoved. Though I suppose we also don't have a chance of reading a
4165 * bunch of small messages at once, so the optimization may be stupid.
4166 *
4167 * Another approach would be to keep a "start" index into
4168 * loader->data and only delete it occasionally, instead of after
4169 * each message is loaded.
4170 *
4171 * load_message() returns FALSE if not enough memory OR the loader was corrupted
4172 */
4173 static dbus_bool_t
4174 load_message (DBusMessageLoader *loader,
4175 DBusMessage *message,
4176 int byte_order,
4177 int fields_array_len,
4178 int header_len,
4179 int body_len)
4180 {
4181 dbus_bool_t oom;
4182 DBusValidity validity;
4183 const DBusString *type_str;
4184 int type_pos;
4185 DBusValidationMode mode;
4186 dbus_uint32_t n_unix_fds = 0;
4187
4188 mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
4189
4190 oom = FALSE;
4191
4192 #if 0
4193 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len /* + body_len */);
4194 #endif
4195
4196 /* 1. VALIDATE AND COPY OVER HEADER */
4197 _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
4198 _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
4199
4200 if (!_dbus_header_load (&message->header,
4201 mode,
4202 &validity,
4203 byte_order,
4204 fields_array_len,
4205 header_len,
4206 body_len,
4207 &loader->data, 0,
4208 _dbus_string_get_length (&loader->data)))
4209 {
4210 _dbus_verbose ("Failed to load header for new message code %d\n", validity);
4211
4212 /* assert here so we can catch any code that still uses DBUS_VALID to indicate
4213 oom errors. They should use DBUS_VALIDITY_UNKNOWN_OOM_ERROR instead */
4214 _dbus_assert (validity != DBUS_VALID);
4215
4216 if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
4217 oom = TRUE;
4218 else
4219 {
4220 loader->corrupted = TRUE;
4221 loader->corruption_reason = validity;
4222 }
4223 goto failed;
4224 }
4225
4226 _dbus_assert (validity == DBUS_VALID);
4227
4228 /* 2. VALIDATE BODY */
4229 if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
4230 {
4231 get_const_signature (&message->header, &type_str, &type_pos);
4232
4233 /* Because the bytes_remaining arg is NULL, this validates that the
4234 * body is the right length
4235 */
4236 validity = _dbus_validate_body_with_reason (type_str,
4237 type_pos,
4238 byte_order,
4239 NULL,
4240 &loader->data,
4241 header_len,
4242 body_len);
4243 if (validity != DBUS_VALID)
4244 {
4245 _dbus_verbose ("Failed to validate message body code %d\n", validity);
4246
4247 loader->corrupted = TRUE;
4248 loader->corruption_reason = validity;
4249
4250 goto failed;
4251 }
4252 }
4253
4254 /* 3. COPY OVER UNIX FDS */
4255 _dbus_header_get_field_basic(&message->header,
4256 DBUS_HEADER_FIELD_UNIX_FDS,
4257 DBUS_TYPE_UINT32,
4258 &n_unix_fds);
4259
4260 #ifdef HAVE_UNIX_FD_PASSING
4261
4262 if (n_unix_fds > loader->n_unix_fds)
4263 {
4264 _dbus_verbose("Message contains references to more unix fds than were sent %u != %u\n",
4265 n_unix_fds, loader->n_unix_fds);
4266
4267 loader->corrupted = TRUE;
4268 loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4269 goto failed;
4270 }
4271
4272 /* If this was a recycled message there might still be
4273 some memory allocated for the fds */
4274 dbus_free(message->unix_fds);
4275
4276 if (n_unix_fds > 0)
4277 {
4278 message->unix_fds = _dbus_memdup(loader->unix_fds, n_unix_fds * sizeof(message->unix_fds[0]));
4279 if (message->unix_fds == NULL)
4280 {
4281 _dbus_verbose ("Failed to allocate file descriptor array\n");
4282 oom = TRUE;
4283 goto failed;
4284 }
4285
4286 message->n_unix_fds_allocated = message->n_unix_fds = n_unix_fds;
4287 loader->n_unix_fds -= n_unix_fds;
4288 memmove (loader->unix_fds, loader->unix_fds + n_unix_fds, loader->n_unix_fds * sizeof (loader->unix_fds[0]));
4289
4290 if (loader->unix_fds_change)
4291 loader->unix_fds_change (loader->unix_fds_change_data);
4292 }
4293 else
4294 message->unix_fds = NULL;
4295
4296 #else
4297
4298 if (n_unix_fds > 0)
4299 {
4300 _dbus_verbose ("Hmm, message claims to come with file descriptors "
4301 "but that's not supported on our platform, disconnecting.\n");
4302
4303 loader->corrupted = TRUE;
4304 loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4305 goto failed;
4306 }
4307
4308 #endif
4309
4310 /* 3. COPY OVER BODY AND QUEUE MESSAGE */
4311
4312 if (!_dbus_list_append (&loader->messages, message))
4313 {
4314 _dbus_verbose ("Failed to append new message to loader queue\n");
4315 oom = TRUE;
4316 goto failed;
4317 }
4318
4319 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
4320 _dbus_assert (_dbus_string_get_length (&loader->data) >=
4321 (header_len + body_len));
4322
4323 if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
4324 {
4325 _dbus_verbose ("Failed to move body into new message\n");
4326 oom = TRUE;
4327 goto failed;
4328 }
4329
4330 _dbus_string_delete (&loader->data, 0, header_len + body_len);
4331
4332 /* don't waste more than 2k of memory */
4333 _dbus_string_compact (&loader->data, 2048);
4334
4335 _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
4336 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
4337
4338 _dbus_verbose ("Loaded message %p\n", message);
4339
4340 _dbus_assert (!oom);
4341 _dbus_assert (!loader->corrupted);
4342 _dbus_assert (loader->messages != NULL);
4343 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4344
4345 return TRUE;
4346
4347 failed:
4348
4349 /* Clean up */
4350
4351 /* does nothing if the message isn't in the list */
4352 _dbus_list_remove_last (&loader->messages, message);
4353
4354 if (oom)
4355 _dbus_assert (!loader->corrupted);
4356 else
4357 _dbus_assert (loader->corrupted);
4358
4359 _dbus_verbose_bytes_of_string (&loader->data, 0, _dbus_string_get_length (&loader->data));
4360
4361 return FALSE;
4362 }
4363
4378 dbus_bool_t
4379 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
4380 {
4381 while (!loader->corrupted &&
4382 _dbus_string_get_length (&loader->data) >= DBUS_MINIMUM_HEADER_SIZE)
4383 {
4384 DBusValidity validity;
4385 int byte_order, fields_array_len, header_len, body_len;
4386
4387 if (_dbus_header_have_message_untrusted (loader->max_message_size,
4388 &validity,
4389 &byte_order,
4390 &fields_array_len,
4391 &header_len,
4392 &body_len,
4393 &loader->data, 0,
4394 _dbus_string_get_length (&loader->data)))
4395 {
4396 DBusMessage *message;
4397
4398 _dbus_assert (validity == DBUS_VALID);
4399
4400 message = dbus_message_new_empty_header ();
4401 if (message == NULL)
4402 return FALSE;
4403
4404 if (!load_message (loader, message,
4405 byte_order, fields_array_len,
4406 header_len, body_len))
4407 {
4408 dbus_message_unref (message);
4409 /* load_message() returns false if corrupted or OOM; if
4410 * corrupted then return TRUE for not OOM
4411 */
4412 return loader->corrupted;
4413 }
4414
4415 _dbus_assert (loader->messages != NULL);
4416 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4417 }
4418 else
4419 {
4420 _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
4421 validity);
4422 if (validity != DBUS_VALID)
4423 {
4424 loader->corrupted = TRUE;
4425 loader->corruption_reason = validity;
4426 }
4427 return TRUE;
4428 }
4429 }
4430
4431 return TRUE;
4432 }
4433
4441 DBusMessage*
4442 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
4443 {
4444 if (loader->messages)
4445 return loader->messages->data;
4446 else
4447 return NULL;
4448 }
4449
4458 DBusMessage*
4459 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
4460 {
4461 return _dbus_list_pop_first (&loader->messages);
4462 }
4463
4472 DBusList*
4473 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
4474 {
4475 return _dbus_list_pop_first_link (&loader->messages);
4476 }
4477
4484 void
4485 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
4486 DBusList *link)
4487 {
4488 _dbus_list_prepend_link (&loader->messages, link);
4489 }
4490
4500 dbus_bool_t
4501 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
4502 {
4503 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
4504 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
4505 return loader->corrupted;
4506 }
4507
4514 DBusValidity
4515 _dbus_message_loader_get_corruption_reason (DBusMessageLoader *loader)
4516 {
4517 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
4518 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
4519
4520 return loader->corruption_reason;
4521 }
4522
4529 void
4530 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
4531 long size)
4532 {
4533 if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
4534 {
4535 _dbus_verbose ("clamping requested max message size %ld to %d\n",
4536 size, DBUS_MAXIMUM_MESSAGE_LENGTH);
4537 size = DBUS_MAXIMUM_MESSAGE_LENGTH;
4538 }
4539 loader->max_message_size = size;
4540 }
4541
4548 long
4549 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
4550 {
4551 return loader->max_message_size;
4552 }
4553
4560 void
4561 _dbus_message_loader_set_max_message_unix_fds (DBusMessageLoader *loader,
4562 long n)
4563 {
4564 if (n > DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
4565 {
4566 _dbus_verbose ("clamping requested max message unix_fds %ld to %d\n",
4567 n, DBUS_MAXIMUM_MESSAGE_UNIX_FDS);
4568 n = DBUS_MAXIMUM_MESSAGE_UNIX_FDS;
4569 }
4570 loader->max_message_unix_fds = n;
4571 }
4572
4579 long
4580 _dbus_message_loader_get_max_message_unix_fds (DBusMessageLoader *loader)
4581 {
4582 return loader->max_message_unix_fds;
4583 }
4584
4590 int
4591 _dbus_message_loader_get_pending_fds_count (DBusMessageLoader *loader)
4592 {
4593 #ifdef HAVE_UNIX_FD_PASSING
4594 return loader->n_unix_fds;
4595 #else
4596 return 0;
4597 #endif
4598 }
4599
4608 void
4609 _dbus_message_loader_set_pending_fds_function (DBusMessageLoader *loader,
4610 void (* callback) (void *),
4611 void *data)
4612 {
4613 #ifdef HAVE_UNIX_FD_PASSING
4614 loader->unix_fds_change = callback;
4615 loader->unix_fds_change_data = data;
4616 #endif
4617 }
4618
4619 static DBusDataSlotAllocator slot_allocator =
4620 _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (message_slots));
4621
4636 dbus_bool_t
4637 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
4638 {
4639 return _dbus_data_slot_allocator_alloc (&slot_allocator,
4640 slot_p);
4641 }
4642
4654 void
4655 dbus_message_free_data_slot (dbus_int32_t *slot_p)
4656 {
4657 _dbus_return_if_fail (*slot_p >= 0);
4658
4659 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
4660 }
4661
4675 dbus_bool_t
4676 dbus_message_set_data (DBusMessage *message,
4677 dbus_int32_t slot,
4678 void *data,
4679 DBusFreeFunction free_data_func)
4680 {
4681 DBusFreeFunction old_free_func;
4682 void *old_data;
4683 dbus_bool_t retval;
4684
4685 _dbus_return_val_if_fail (message != NULL, FALSE);
4686 _dbus_return_val_if_fail (slot >= 0, FALSE);
4687
4688 retval = _dbus_data_slot_list_set (&slot_allocator,
4689 &message->slot_list,
4690 slot, data, free_data_func,
4691 &old_free_func, &old_data);
4692
4693 if (retval)
4694 {
4695 /* Do the actual free outside the message lock */
4696 if (old_free_func)
4697 (* old_free_func) (old_data);
4698 }
4699
4700 return retval;
4701 }
4702
4711 void*
4712 dbus_message_get_data (DBusMessage *message,
4713 dbus_int32_t slot)
4714 {
4715 void *res;
4716
4717 _dbus_return_val_if_fail (message != NULL, NULL);
4718
4719 res = _dbus_data_slot_list_get (&slot_allocator,
4720 &message->slot_list,
4721 slot);
4722
4723 return res;
4724 }
4725
4739 int
4740 dbus_message_type_from_string (const char *type_str)
4741 {
4742 if (strcmp (type_str, "method_call") == 0)
4743 return DBUS_MESSAGE_TYPE_METHOD_CALL;
4744 if (strcmp (type_str, "method_return") == 0)
4745 return DBUS_MESSAGE_TYPE_METHOD_RETURN;
4746 else if (strcmp (type_str, "signal") == 0)
4747 return DBUS_MESSAGE_TYPE_SIGNAL;
4748 else if (strcmp (type_str, "error") == 0)
4749 return DBUS_MESSAGE_TYPE_ERROR;
4750 else
4751 return DBUS_MESSAGE_TYPE_INVALID;
4752 }
4753
4767 const char *
4768 dbus_message_type_to_string (int type)
4769 {
4770 switch (type)
4771 {
4772 case DBUS_MESSAGE_TYPE_METHOD_CALL:
4773 return "method_call";
4774 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
4775 return "method_return";
4776 case DBUS_MESSAGE_TYPE_SIGNAL:
4777 return "signal";
4778 case DBUS_MESSAGE_TYPE_ERROR:
4779 return "error";
4780 default:
4781 return "invalid";
4782 }
4783 }
4784
4797 dbus_bool_t
4798 dbus_message_marshal (DBusMessage *msg,
4799 char **marshalled_data_p,
4800 int *len_p)
4801 {
4802 DBusString tmp;
4803 dbus_bool_t was_locked;
4804
4805 _dbus_return_val_if_fail (msg != NULL, FALSE);
4806 _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
4807 _dbus_return_val_if_fail (len_p != NULL, FALSE);
4808
4809 if (!_dbus_string_init (&tmp))
4810 return FALSE;
4811
4812 /* Ensure the message is locked, to ensure the length header is filled in. */
4813 was_locked = msg->locked;
4814
4815 if (!was_locked)
4816 dbus_message_lock (msg);
4817
4818 if (!_dbus_string_copy (&(msg->header.data), 0, &tmp, 0))
4819 goto fail;
4820
4821 *len_p = _dbus_string_get_length (&tmp);
4822
4823 if (!_dbus_string_copy (&(msg->body), 0, &tmp, *len_p))
4824 goto fail;
4825
4826 *len_p = _dbus_string_get_length (&tmp);
4827
4828 if (!_dbus_string_steal_data (&tmp, marshalled_data_p))
4829 goto fail;
4830
4831 _dbus_string_free (&tmp);
4832
4833 if (!was_locked)
4834 msg->locked = FALSE;
4835
4836 return TRUE;
4837
4838 fail:
4839 _dbus_string_free (&tmp);
4840
4841 if (!was_locked)
4842 msg->locked = FALSE;
4843
4844 return FALSE;
4845 }
4846
4859 DBusMessage *
4860 dbus_message_demarshal (const char *str,
4861 int len,
4862 DBusError *error)
4863 {
4864 DBusMessageLoader *loader;
4865 DBusString *buffer;
4866 DBusMessage *msg;
4867
4868 _dbus_return_val_if_fail (str != NULL, NULL);
4869
4870 loader = _dbus_message_loader_new ();
4871
4872 if (loader == NULL)
4873 return NULL;
4874
4875 _dbus_message_loader_get_buffer (loader, &buffer);
4876
4877 if (!_dbus_string_append_len (buffer, str, len))
4878 goto fail_oom;
4879
4880 _dbus_message_loader_return_buffer (loader, buffer);
4881
4882 if (!_dbus_message_loader_queue_messages (loader))
4883 goto fail_oom;
4884
4885 if (_dbus_message_loader_get_is_corrupted (loader))
4886 goto fail_corrupt;
4887
4888 msg = _dbus_message_loader_pop_message (loader);
4889
4890 if (!msg)
4891 goto fail_oom;
4892
4893 _dbus_message_loader_unref (loader);
4894 return msg;
4895
4896 fail_corrupt:
4897 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted (%s)",
4898 _dbus_validity_to_error_message (loader->corruption_reason));
4899 _dbus_message_loader_unref (loader);
4900 return NULL;
4901
4902 fail_oom:
4903 _DBUS_SET_OOM (error);
4904 _dbus_message_loader_unref (loader);
4905 return NULL;
4906 }
4907
4920 int
4921 dbus_message_demarshal_bytes_needed(const char *buf,
4922 int len)
4923 {
4924 DBusString str;
4925 int byte_order, fields_array_len, header_len, body_len;
4926 DBusValidity validity = DBUS_VALID;
4927 int have_message;
4928
4929 if (!buf || len < DBUS_MINIMUM_HEADER_SIZE)
4930 return 0;
4931
4932 if (len > DBUS_MAXIMUM_MESSAGE_LENGTH)
4933 len = DBUS_MAXIMUM_MESSAGE_LENGTH;
4934 _dbus_string_init_const_len (&str, buf, len);
4935
4936 validity = DBUS_VALID;
4937 have_message
4938 = _dbus_header_have_message_untrusted(DBUS_MAXIMUM_MESSAGE_LENGTH,
4939 &validity, &byte_order,
4940 &fields_array_len,
4941 &header_len,
4942 &body_len,
4943 &str, 0,
4944 len);
4945 _dbus_string_free (&str);
4946
4947 if (validity == DBUS_VALID)
4948 {
4949 _dbus_assert (have_message || (header_len + body_len) > len);
4950 (void) have_message; /* unused unless asserting */
4951 return header_len + body_len;
4952 }
4953 else
4954 {
4955 return -1; /* broken! */
4956 }
4957 }
4958
4980 void
4981 dbus_message_set_allow_interactive_authorization (DBusMessage *message,
4982 dbus_bool_t allow)
4983 {
4984 _dbus_return_if_fail (message != NULL);
4985 _dbus_return_if_fail (!message->locked);
4986
4987 _dbus_header_toggle_flag (&message->header,
4988 DBUS_HEADER_FLAG_ALLOW_INTERACTIVE_AUTHORIZATION,
4989 allow);
4990 }
4991
4998 dbus_bool_t
4999 dbus_message_get_allow_interactive_authorization (DBusMessage *message)
5000 {
5001 _dbus_return_val_if_fail (message != NULL, FALSE);
5002
5003 return _dbus_header_get_flag (&message->header,
5004 DBUS_HEADER_FLAG_ALLOW_INTERACTIVE_AUTHORIZATION);
5005 }
5006
5009 /* tests in dbus-message-util.c */
dbus_type_is_fixed
dbus_bool_t dbus_type_is_fixed(int typecode)
Tells you whether values of this type can change length if you set them to some other value...
Definition: dbus-signature.c:349
_dbus_type_reader_read_fixed_multi
void _dbus_type_reader_read_fixed_multi(const DBusTypeReader *reader, void *value, int *n_elements)
Reads a block of fixed-length basic values, from the current point in an array to the end of the arra...
Definition: dbus-marshal-recursive.c:924
_dbus_validate_body_with_reason
DBusValidity _dbus_validate_body_with_reason(const DBusString *expected_signature, int expected_signature_start, int byte_order, int *bytes_remaining, const DBusString *value_str, int value_pos, int len)
Verifies that the range of value_str from value_pos to value_end is a legitimate value of type expect...
Definition: dbus-marshal-validate.c:703
dbus_message_type_from_string
int dbus_message_type_from_string(const char *type_str)
Utility function to convert a machine-readable (not translated) string into a D-Bus message type...
Definition: dbus-message.c:4740
dbus_uint32_t
unsigned int dbus_uint32_t
A 32-bit unsigned integer on all platforms.
Definition: dbus-arch-deps.h:43
dbus_message_ref
DBusMessage * dbus_message_ref(DBusMessage *message)
Increments the reference count of a DBusMessage.
Definition: dbus-message.c:1694
dbus_message_lock
void dbus_message_lock(DBusMessage *message)
Locks a message.
Definition: dbus-message.c:407
DBusError::message
const char * message
public error message field
Definition: dbus-errors.h:51
dbus_message_has_path
dbus_bool_t dbus_message_has_path(DBusMessage *message, const char *path)
Checks if the message has a particular object path.
Definition: dbus-message.c:3197
DBusMessage::changed_stamp
dbus_uint32_t changed_stamp
Incremented when iterators are invalidated.
Definition: dbus-message-private.h:116
NULL
#define NULL
A null pointer, defined appropriately for C or C++.
dbus_message_is_method_call
dbus_bool_t dbus_message_is_method_call(DBusMessage *message, const char *iface, const char *method)
Checks whether the message is a method call with the given interface and member fields.
Definition: dbus-message.c:3679
_dbus_header_load
dbus_bool_t _dbus_header_load(DBusHeader *header, DBusValidationMode mode, DBusValidity *validity, int byte_order, int fields_array_len, int header_len, int body_len, const DBusString *str, int start, int len)
Creates a message header from potentially-untrusted data.
Definition: dbus-marshal-header.c:970
DBusFreeFunction
void(* DBusFreeFunction)(void *memory)
The type of a function which frees a block of memory.
Definition: dbus-memory.h:64
_dbus_message_loader_get_max_message_size
long _dbus_message_loader_get_max_message_size(DBusMessageLoader *loader)
Gets the maximum allowed message size in bytes.
Definition: dbus-message.c:4549
dbus_message_set_no_reply
void dbus_message_set_no_reply(DBusMessage *message, dbus_bool_t no_reply)
Sets a flag indicating that the message does not want a reply; if this flag is set, the other end of the connection may (but is not required to) optimize by not sending method return or error replies.
Definition: dbus-message.c:3061
_dbus_message_loader_putback_message_link
void _dbus_message_loader_putback_message_link(DBusMessageLoader *loader, DBusList *link)
Returns a popped message link, used to undo a pop.
Definition: dbus-message.c:4485
_dbus_header_copy
dbus_bool_t _dbus_header_copy(const DBusHeader *header, DBusHeader *dest)
Initializes dest with a copy of the given header.
Definition: dbus-marshal-header.c:490
dbus_message_iter_get_arg_type
int dbus_message_iter_get_arg_type(DBusMessageIter *iter)
Returns the argument type of the argument that the message iterator points to.
Definition: dbus-message.c:2180
DBusMessageRealIter::sig_refcount
dbus_uint32_t sig_refcount
depth of open_signature()
Definition: dbus-message.c:131
_dbus_message_loader_return_buffer
void _dbus_message_loader_return_buffer(DBusMessageLoader *loader, DBusString *buffer)
Returns a buffer obtained from _dbus_message_loader_get_buffer(), indicating to the loader how many b...
Definition: dbus-message.c:4059
_dbus_type_writer_remove_types
void _dbus_type_writer_remove_types(DBusTypeWriter *writer)
Removes type string from the writer.
Definition: dbus-marshal-recursive.c:1563
dbus_realloc
void * dbus_realloc(void *memory, size_t bytes)
Resizes a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:601
dbus_free
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:701
_dbus_message_loader_return_unix_fds
void _dbus_message_loader_return_unix_fds(DBusMessageLoader *loader, int *fds, unsigned n_fds)
Returns a buffer obtained from _dbus_message_loader_get_unix_fds().
Definition: dbus-message.c:4128
dbus_message_get_serial
dbus_uint32_t dbus_message_get_serial(DBusMessage *message)
Returns the serial of a message or 0 if none has been specified.
Definition: dbus-message.c:1150
DBusMessageLoader::messages
DBusList * messages
Complete messages.
Definition: dbus-message-private.h:66
DBusTypeWriter
The type writer is an iterator for writing to a block of values.
Definition: dbus-marshal-recursive.h:64
dbus_message_iter_recurse
void dbus_message_iter_recurse(DBusMessageIter *iter, DBusMessageIter *sub)
Recurses into a container value when reading values from a message, initializing a sub-iterator to us...
Definition: dbus-message.c:2236
_dbus_type_reader_recurse
void _dbus_type_reader_recurse(DBusTypeReader *reader, DBusTypeReader *sub)
Initialize a new reader pointing to the first type and corresponding value that&#39;s a child of the curr...
Definition: dbus-marshal-recursive.c:989
_dbus_message_loader_pop_message
DBusMessage * _dbus_message_loader_pop_message(DBusMessageLoader *loader)
Pops a loaded message (passing ownership of the message to the caller).
Definition: dbus-message.c:4459
_dbus_list_find_last
DBusList * _dbus_list_find_last(DBusList **list, void *data)
Finds a value in the list.
Definition: dbus-list.c:472
dbus_message_set_interface
dbus_bool_t dbus_message_set_interface(DBusMessage *message, const char *iface)
Sets the interface this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or the interface...
Definition: dbus-message.c:3275
DBUS_ERROR_NOT_SUPPORTED
#define DBUS_ERROR_NOT_SUPPORTED
Requested operation isn&#39;t supported (like ENOSYS on UNIX).
Definition: dbus-protocol.h:369
dbus_new
#define dbus_new(type, count)
Safe macro for using dbus_malloc().
Definition: dbus-memory.h:58
dbus_message_free_data_slot
void dbus_message_free_data_slot(dbus_int32_t *slot_p)
Deallocates a global ID for message data slots.
Definition: dbus-message.c:4655
DBUS_HEADER_FIELD_SIGNATURE
#define DBUS_HEADER_FIELD_SIGNATURE
Header field code for the type signature of a message.
Definition: dbus-protocol.h:297
dbus_message_get_error_name
const char * dbus_message_get_error_name(DBusMessage *message)
Gets the error name (DBUS_MESSAGE_TYPE_ERROR only) or NULL if none.
Definition: dbus-message.c:3474
dbus_message_iter_close_container
dbus_bool_t dbus_message_iter_close_container(DBusMessageIter *iter, DBusMessageIter *sub)
Closes a container-typed value appended to the message; may write out more information to the message...
Definition: dbus-message.c:2995
dbus_message_is_error
dbus_bool_t dbus_message_is_error(DBusMessage *message, const char *error_name)
Checks whether the message is an error reply with the given error name.
Definition: dbus-message.c:3734
_dbus_list_remove_link
void _dbus_list_remove_link(DBusList **list, DBusList *link)
Removes a link from the list.
Definition: dbus-list.c:527
DBUS_TYPE_STRUCT
#define DBUS_TYPE_STRUCT
STRUCT and DICT_ENTRY are sort of special since their codes can&#39;t appear in a type string...
Definition: dbus-protocol.h:136
DBUS_TYPE_DICT_ENTRY
#define DBUS_TYPE_DICT_ENTRY
Type code used to represent a dict entry; however, this type code does not appear in type signatures...
Definition: dbus-protocol.h:143
dbus_message_get_sender
const char * dbus_message_get_sender(DBusMessage *message)
Gets the unique name of the connection which originated this message, or NULL if unknown or inapplica...
Definition: dbus-message.c:3587
_dbus_message_iter_get_args_valist
DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_message_iter_get_args_valist(DBusMessageIter *iter, DBusError *error, int first_arg_type, va_list var_args)
Implementation of the varargs arg-getting functions.
Definition: dbus-message.c:819
DBUS_TYPE_STRING
#define DBUS_TYPE_STRING
Type code marking a UTF-8 encoded, nul-terminated Unicode string.
Definition: dbus-protocol.h:102
DBusMessage::body
DBusString body
Body network data.
Definition: dbus-message-private.h:105
_dbus_header_get_serial
dbus_uint32_t _dbus_header_get_serial(DBusHeader *header)
See dbus_message_get_serial()
Definition: dbus-marshal-header.c:427
_dbus_header_get_flag
dbus_bool_t _dbus_header_get_flag(DBusHeader *header, dbus_uint32_t flag)
Gets a message flag bit, returning TRUE if the bit is set.
Definition: dbus-marshal-header.c:1479
_dbus_assert
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
Definition: dbus-internals.h:148
DBUS_HEADER_FLAG_NO_REPLY_EXPECTED
#define DBUS_HEADER_FLAG_NO_REPLY_EXPECTED
If set, this flag means that the sender of a message does not care about getting a reply...
Definition: dbus-protocol.h:249
_dbus_list_append_link
void _dbus_list_append_link(DBusList **list, DBusList *link)
Appends a link to the list.
Definition: dbus-list.c:315
DBusCounter
Internals of DBusCounter.
Definition: dbus-resources.c:54
dbus_message_allocate_data_slot
dbus_bool_t dbus_message_allocate_data_slot(dbus_int32_t *slot_p)
Allocates an integer ID to be used for storing application-specific data on any DBusMessage.
Definition: dbus-message.c:4637
DBusList::data
void * data
Data stored at this element.
Definition: dbus-list.h:38
MAX_MESSAGE_CACHE_SIZE
#define MAX_MESSAGE_CACHE_SIZE
Avoid caching too many messages.
Definition: dbus-message.c:531
dbus_message_new
DBusMessage * dbus_message_new(int message_type)
Constructs a new message of the given message type.
Definition: dbus-message.c:1316
DBUS_ERROR_INCONSISTENT_MESSAGE
#define DBUS_ERROR_INCONSISTENT_MESSAGE
The message meta data does not match the payload.
Definition: dbus-protocol.h:453
_dbus_header_init
dbus_bool_t _dbus_header_init(DBusHeader *header)
Initializes a header, but doesn&#39;t prepare it for use; to make the header valid, you have to call _dbu...
Definition: dbus-marshal-header.c:460
_dbus_warn_check_failed
void _dbus_warn_check_failed(const char *format,...)
Prints a "critical" warning to stderr when an assertion fails; differs from _dbus_warn primarily in t...
Definition: dbus-internals.c:258
dbus_message_get_signature
const char * dbus_message_get_signature(DBusMessage *message)
Gets the type signature of the message, i.e.
Definition: dbus-message.c:3620
dbus_message_iter_init_append
void dbus_message_iter_init_append(DBusMessage *message, DBusMessageIter *iter)
Initializes a DBusMessageIter for appending arguments to the end of a message.
Definition: dbus-message.c:2498
dbus_error_free
void dbus_error_free(DBusError *error)
Frees an error that&#39;s been set (or just initialized), then reinitializes the error as in dbus_error_i...
Definition: dbus-errors.c:211
dbus_message_set_auto_start
void dbus_message_set_auto_start(DBusMessage *message, dbus_bool_t auto_start)
Sets a flag indicating that an owner for the destination name will be automatically started before th...
Definition: dbus-message.c:3103
DBusMessageRealIter::u
union DBusMessageRealIter::@6 u
the type writer or reader that does all the work
DBusMessageIter_1_10_0
Layout of a DBusMessageIter on the stack in dbus 1.10.0.
Definition: dbus-message.c:144
dbus_message_get_allow_interactive_authorization
dbus_bool_t dbus_message_get_allow_interactive_authorization(DBusMessage *message)
Returns whether the flag controlled by dbus_message_set_allow_interactive_authorization() has been se...
Definition: dbus-message.c:4999
_dbus_message_loader_unref
void _dbus_message_loader_unref(DBusMessageLoader *loader)
Decrements the reference count of the loader and finalizes the loader when the count reaches zero...
Definition: dbus-message.c:4002
_dbus_counter_ref
DBusCounter * _dbus_counter_ref(DBusCounter *counter)
Increments refcount of the counter.
Definition: dbus-resources.c:116
DBusHeader::data
DBusString data
Header network data, stored separately from body so we can independently realloc it.
Definition: dbus-marshal-header.h:49
dbus_message_has_interface
dbus_bool_t dbus_message_has_interface(DBusMessage *message, const char *iface)
Checks if the message has an interface.
Definition: dbus-message.c:3326
_dbus_message_loader_get_corruption_reason
DBusValidity _dbus_message_loader_get_corruption_reason(DBusMessageLoader *loader)
Checks what kind of bad data confused the loader.
Definition: dbus-message.c:4515
_dbus_type_writer_write_basic
dbus_bool_t _dbus_type_writer_write_basic(DBusTypeWriter *writer, int type, const void *value)
Writes out a basic type.
Definition: dbus-marshal-recursive.c:2311
DBUS_MESSAGE_TYPE_ERROR
#define DBUS_MESSAGE_TYPE_ERROR
Message type of an error reply message, see dbus_message_get_type()
Definition: dbus-protocol.h:238
_dbus_list_alloc_link
DBusList * _dbus_list_alloc_link(void *data)
Allocates a linked list node.
Definition: dbus-list.c:242
DBUS_MAXIMUM_MESSAGE_UNIX_FDS
#define DBUS_MAXIMUM_MESSAGE_UNIX_FDS
The maximum total number of unix fds in a message.
Definition: dbus-protocol.h:218
dbus_message_get_path
const char * dbus_message_get_path(DBusMessage *message)
Gets the object path this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitt...
Definition: dbus-message.c:3173
_dbus_string_init
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
DBUS_MESSAGE_TYPE_METHOD_RETURN
#define DBUS_MESSAGE_TYPE_METHOD_RETURN
Message type of a method return message, see dbus_message_get_type()
Definition: dbus-protocol.h:236
dbus_message_new_signal
DBusMessage * dbus_message_new_signal(const char *path, const char *iface, const char *name)
Constructs a new message representing a signal emission.
Definition: dbus-message.c:1451
_DBUS_STRING_DEFINE_STATIC
_DBUS_STRING_DEFINE_STATIC(_dbus_empty_signature_str, "")
An static string representing an empty signature.
_dbus_string_append_printf_valist
dbus_bool_t _dbus_string_append_printf_valist(DBusString *str, const char *format, va_list args)
Appends a printf-style formatted string to the DBusString.
Definition: dbus-string.c:1072
_dbus_dup
int _dbus_dup(int fd, DBusError *error)
Duplicates a file descriptor.
Definition: dbus-sysdeps-unix.c:3241
DBusMessageRealIter::reader
DBusTypeReader reader
reader
Definition: dbus-message.c:135
DBusValidationMode
DBusValidationMode
This is used rather than a bool for high visibility.
Definition: dbus-marshal-validate.h:36
dbus_message_iter_has_next
dbus_bool_t dbus_message_iter_has_next(DBusMessageIter *iter)
Checks if an iterator has any more fields.
Definition: dbus-message.c:2136
DBusMessageRealIter::message
DBusMessage * message
Message used.
Definition: dbus-message.c:128
_dbus_string_copy
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that&#39;s copied to the d...
Definition: dbus-string.c:1283
DBUS_HEADER_FIELD_INTERFACE
#define DBUS_HEADER_FIELD_INTERFACE
Header field code for the interface containing a member (method or signal).
Definition: dbus-protocol.h:274
DBUS_DICT_ENTRY_BEGIN_CHAR
#define DBUS_DICT_ENTRY_BEGIN_CHAR
Code marking the start of a dict entry type in a type signature.
Definition: dbus-protocol.h:164
_dbus_list_pop_first_link
DBusList * _dbus_list_pop_first_link(DBusList **list)
Removes the first link in the list and returns it.
Definition: dbus-list.c:628
dbus_message_has_member
dbus_bool_t dbus_message_has_member(DBusMessage *message, const char *member)
Checks if the message has an interface member.
Definition: dbus-message.c:3412
DBusValidity
DBusValidity
This is primarily used in unit testing, so we can verify that each invalid message is invalid for the...
Definition: dbus-marshal-validate.h:49
DBusMessageIter
DBusMessageIter struct; contains no public fields.
Definition: dbus-message.h:51
dbus_message_iter_init
dbus_bool_t dbus_message_iter_init(DBusMessage *message, DBusMessageIter *iter)
Initializes a DBusMessageIter for reading the arguments of the message passed in. ...
Definition: dbus-message.c:2105
_dbus_message_add_counter
dbus_bool_t _dbus_message_add_counter(DBusMessage *message, DBusCounter *counter)
Adds a counter to be incremented immediately with the size/unix fds of this message, and decremented by the size/unix fds of this message when this message if finalized.
Definition: dbus-message.c:352
dbus_message_get_destination
const char * dbus_message_get_destination(DBusMessage *message)
Gets the destination of a message or NULL if there is none set.
Definition: dbus-message.c:3527
_dbus_message_add_counter_link
void _dbus_message_add_counter_link(DBusMessage *message, DBusList *link)
Adds a counter to be incremented immediately with the size/unix fds of this message, and decremented by the size/unix fds of this message when this message if finalized.
Definition: dbus-message.c:303
DBUS_TYPE_ARRAY
#define DBUS_TYPE_ARRAY
Type code marking a D-Bus array type.
Definition: dbus-protocol.h:120
DBusTypeWriter::type_str
DBusString * type_str
where to write typecodes (or read type expectations)
Definition: dbus-marshal-recursive.h:74
dbus_message_iter_append_fixed_array
dbus_bool_t dbus_message_iter_append_fixed_array(DBusMessageIter *iter, int element_type, const void *value, int n_elements)
Appends a block of fixed-length values to an array.
Definition: dbus-message.c:2868
dbus_message_set_error_name
dbus_bool_t dbus_message_set_error_name(DBusMessage *message, const char *error_name)
Sets the name of the error (DBUS_MESSAGE_TYPE_ERROR).
Definition: dbus-message.c:3448
dbus_message_get_member
const char * dbus_message_get_member(DBusMessage *message)
Gets the interface member being invoked (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted (DBUS_MESSAGE_TYPE...
Definition: dbus-message.c:3390
_dbus_list_remove_last
dbus_bool_t _dbus_list_remove_last(DBusList **list, void *data)
Removes a value from the list.
Definition: dbus-list.c:446
DBusMessage
Internals of DBusMessage.
Definition: dbus-message-private.h:99
DBusMessageRealIter
Internals of DBusMessageIter.
Definition: dbus-message.c:126
dbus_new0
#define dbus_new0(type, count)
Safe macro for using dbus_malloc0().
Definition: dbus-memory.h:59
DBusMessageRealIter::changed_stamp
dbus_uint32_t changed_stamp
stamp to detect invalid iters
Definition: dbus-message.c:129
_dbus_type_writer_init_types_delayed
void _dbus_type_writer_init_types_delayed(DBusTypeWriter *writer, int byte_order, DBusString *value_str, int value_pos)
Initialize a write iterator, with the signature to be provided later.
Definition: dbus-marshal-recursive.c:1528
_dbus_string_compact
dbus_bool_t _dbus_string_compact(DBusString *str, int max_waste)
Compacts the string to avoid wasted memory.
Definition: dbus-string.c:389
_dbus_header_get_message_type
int _dbus_header_get_message_type(DBusHeader *header)
Gets the type of the message.
Definition: dbus-marshal-header.c:386
DBUS_HEADER_FIELD_ERROR_NAME
#define DBUS_HEADER_FIELD_ERROR_NAME
Header field code for an error name (found in DBUS_MESSAGE_TYPE_ERROR messages).
Definition: dbus-protocol.h:280
DBusString
Definition: dbus-string.h:42
DBUS_MINIMUM_HEADER_SIZE
#define DBUS_MINIMUM_HEADER_SIZE
The smallest header size that can occur.
Definition: dbus-protocol.h:346
_dbus_type_writer_unrecurse
dbus_bool_t _dbus_type_writer_unrecurse(DBusTypeWriter *writer, DBusTypeWriter *sub)
Closes a container created by _dbus_type_writer_recurse() and writes any additional information to th...
Definition: dbus-marshal-recursive.c:2179
dbus_type_is_basic
dbus_bool_t dbus_type_is_basic(int typecode)
A "basic type" is a somewhat arbitrary concept, but the intent is to include those types that are ful...
Definition: dbus-signature.c:318
_dbus_message_loader_set_max_message_size
void _dbus_message_loader_set_max_message_size(DBusMessageLoader *loader, long size)
Sets the maximum size message we allow.
Definition: dbus-message.c:4530
dbus_bool_t
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
_dbus_string_init_const
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:190
DBusMessage::header
DBusHeader header
Header network data and associated cache.
Definition: dbus-message-private.h:103
dbus_message_set_sender
dbus_bool_t dbus_message_set_sender(DBusMessage *message, const char *sender)
Sets the message sender.
Definition: dbus-message.c:3556
dbus_message_is_signal
dbus_bool_t dbus_message_is_signal(DBusMessage *message, const char *iface, const char *signal_name)
Checks whether the message is a signal with the given interface and member fields.
Definition: dbus-message.c:3707
DBusMessageLoader::data
DBusString data
Buffered data.
Definition: dbus-message-private.h:64
_dbus_type_reader_read_basic
void _dbus_type_reader_read_basic(const DBusTypeReader *reader, void *value)
Reads a basic-typed value, as with _dbus_marshal_read_basic().
Definition: dbus-marshal-recursive.c:870
DBusMessage::locked
unsigned int locked
Message being sent, no modifications allowed.
Definition: dbus-message-private.h:107
ensure_byte_order
#define ensure_byte_order(message)
byte-swap the message if it doesn&#39;t match our byte order.
Definition: dbus-message.c:218
_dbus_message_loader_ref
DBusMessageLoader * _dbus_message_loader_ref(DBusMessageLoader *loader)
Increments the reference count of the loader.
Definition: dbus-message.c:3988
_dbus_header_get_field_basic
dbus_bool_t _dbus_header_get_field_basic(DBusHeader *header, int field, int type, void *value)
Gets the value of a field with basic type.
Definition: dbus-marshal-header.c:1351
dbus_message_get_path_decomposed
dbus_bool_t dbus_message_get_path_decomposed(DBusMessage *message, char ***path)
Gets the object path this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitt...
Definition: dbus-message.c:3241
DBUS_VALIDITY_UNKNOWN_OOM_ERROR
can&#39;t determine validity due to OOM
Definition: dbus-marshal-validate.h:52
_dbus_warn
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
Definition: dbus-internals.c:230
_dbus_string_delete
void _dbus_string_delete(DBusString *str, int start, int len)
Deletes a segment of a DBusString with length len starting at start.
Definition: dbus-string.c:1193
_dbus_string_init_preallocated
dbus_bool_t _dbus_string_init_preallocated(DBusString *str, int allocate_size)
Initializes a string that can be up to the given allocation size before it has to realloc...
Definition: dbus-string.c:132
_dbus_counter_unref
void _dbus_counter_unref(DBusCounter *counter)
Decrements refcount of the counter and possibly finalizes the counter.
Definition: dbus-resources.c:136
_dbus_atomic_inc
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
Definition: dbus-sysdeps-unix.c:2753
_dbus_message_remove_counter
void _dbus_message_remove_counter(DBusMessage *message, DBusCounter *counter)
Removes a counter tracking the size/unix fds of this message, and decrements the counter by the size/...
Definition: dbus-message.c:375
_dbus_list_append
dbus_bool_t _dbus_list_append(DBusList **list, void *data)
Appends a value to the list.
Definition: dbus-list.c:270
_dbus_decompose_path
dbus_bool_t _dbus_decompose_path(const char *data, int len, char ***path, int *path_len)
Decompose an object path.
Definition: dbus-object-tree.c:1244
_dbus_memdup
void * _dbus_memdup(const void *mem, size_t n_bytes)
Duplicates a block of memory.
Definition: dbus-internals.c:565
_dbus_data_slot_list_set
dbus_bool_t _dbus_data_slot_list_set(DBusDataSlotAllocator *allocator, DBusDataSlotList *list, int slot, void *data, DBusFreeFunction free_data_func, DBusFreeFunction *old_free_func, void **old_data)
Stores a pointer in the data slot list, along with an optional function to be used for freeing the da...
Definition: dbus-dataslot.c:221
dbus_message_set_path
dbus_bool_t dbus_message_set_path(DBusMessage *message, const char *object_path)
Sets the object path this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or the one a s...
Definition: dbus-message.c:3144
_dbus_list_foreach
void _dbus_list_foreach(DBusList **list, DBusForeachFunction function, void *data)
Calls the given function for each element in the list.
Definition: dbus-list.c:759
DBusMessageLoader::max_message_size
long max_message_size
Maximum size of a message.
Definition: dbus-message-private.h:68
_dbus_counter_adjust_unix_fd
void _dbus_counter_adjust_unix_fd(DBusCounter *counter, long delta)
Adjusts the value of the unix fd counter by the given delta which may be positive or negative...
Definition: dbus-resources.c:236
_dbus_type_reader_next
dbus_bool_t _dbus_type_reader_next(DBusTypeReader *reader)
Skip to the next value on this "level".
Definition: dbus-marshal-recursive.c:1054
DBusMessage::counters
DBusList * counters
0-N DBusCounter used to track message size/unix fds.
Definition: dbus-message-private.h:113
_dbus_message_loader_new
DBusMessageLoader * _dbus_message_loader_new(void)
Creates a new message loader.
Definition: dbus-message.c:3940
DBusMessage::size_counter_delta
long size_counter_delta
Size we incremented the size counters by.
Definition: dbus-message-private.h:114
CHANGED_STAMP_BITS
#define CHANGED_STAMP_BITS
How many bits are in the changed_stamp used to validate iterators.
Definition: dbus-message-private.h:90
_dbus_header_byteswap
void _dbus_header_byteswap(DBusHeader *header, int new_order)
Swaps the header into the given order if required.
Definition: dbus-marshal-header.c:1496
_dbus_header_have_message_untrusted
dbus_bool_t _dbus_header_have_message_untrusted(int max_message_length, DBusValidity *validity, int *byte_order, int *fields_array_len, int *header_len, int *body_len, const DBusString *str, int start, int len)
Given data long enough to contain the length of the message body and the fields array, check whether the data is long enough to contain the entire message (assuming the claimed lengths are accurate).
Definition: dbus-marshal-header.c:673
DBUS_MESSAGE_TYPE_METHOD_CALL
#define DBUS_MESSAGE_TYPE_METHOD_CALL
Message type of a method call message, see dbus_message_get_type()
Definition: dbus-protocol.h:234
DBUS_HEADER_FIELD_UNIX_FDS
#define DBUS_HEADER_FIELD_UNIX_FDS
Header field code for the number of unix file descriptors associated with this message.
Definition: dbus-protocol.h:302
_dbus_current_generation
int _dbus_current_generation
_dbus_current_generation is used to track each time that dbus_shutdown() is called, so we can reinit things after it&#39;s been called.
Definition: dbus-memory.c:781
dbus_message_get_args
dbus_bool_t dbus_message_get_args(DBusMessage *message, DBusError *error, int first_arg_type,...)
Gets arguments from a message given a variable argument list.
Definition: dbus-message.c:2007
DBusError
Object representing an exception.
Definition: dbus-errors.h:48
DBusMessage::in_cache
unsigned int in_cache
Has been "freed" since it&#39;s in the cache (this is a debug feature)
Definition: dbus-message-private.h:110
dbus_message_iter_get_element_count
int dbus_message_iter_get_element_count(DBusMessageIter *iter)
Returns the number of elements in the array-typed value pointed to by the iterator.
Definition: dbus-message.c:2379
_dbus_list_pop_first
void * _dbus_list_pop_first(DBusList **list)
Removes the first value in the list and returns it.
Definition: dbus-list.c:649
DBUS_TYPE_SIGNATURE
#define DBUS_TYPE_SIGNATURE
Type code marking a D-Bus type signature.
Definition: dbus-protocol.h:110
_dbus_message_loader_set_pending_fds_function
void _dbus_message_loader_set_pending_fds_function(DBusMessageLoader *loader, void(*callback)(void *), void *data)
Register a function to be called whenever the number of pending file descriptors in the loader change...
Definition: dbus-message.c:4609
dbus_message_append_args
dbus_bool_t dbus_message_append_args(DBusMessage *message, int first_arg_type,...)
Appends fields to a message given a variable argument list.
Definition: dbus-message.c:1819
DBUS_MESSAGE_TYPE_SIGNAL
#define DBUS_MESSAGE_TYPE_SIGNAL
Message type of a signal message, see dbus_message_get_type()
Definition: dbus-protocol.h:240
dbus_set_error
void dbus_set_error(DBusError *error, const char *name, const char *format,...)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:354
dbus_message_get_reply_serial
dbus_uint32_t dbus_message_get_reply_serial(DBusMessage *message)
Returns the serial that the message is a reply to or 0 if none.
Definition: dbus-message.c:1190
INITIAL_LOADER_DATA_LEN
#define INITIAL_LOADER_DATA_LEN
The initial buffer size of the message loader.
Definition: dbus-message.c:3931
dbus_message_has_signature
dbus_bool_t dbus_message_has_signature(DBusMessage *message, const char *signature)
Checks whether the message has the given signature; see dbus_message_get_signature() for more details...
Definition: dbus-message.c:3831
_dbus_data_slot_list_clear
void _dbus_data_slot_list_clear(DBusDataSlotList *list)
Frees all data slots contained in the list, calling application-provided free functions if they exist...
Definition: dbus-dataslot.c:317
_dbus_message_loader_get_is_corrupted
dbus_bool_t _dbus_message_loader_get_is_corrupted(DBusMessageLoader *loader)
Checks whether the loader is confused due to bad data.
Definition: dbus-message.c:4501
DBUS_TYPE_VARIANT
#define DBUS_TYPE_VARIANT
Type code marking a D-Bus variant type.
Definition: dbus-protocol.h:124
DBUS_TYPE_UINT32
#define DBUS_TYPE_UINT32
Type code marking a 32-bit unsigned integer.
Definition: dbus-protocol.h:86
_dbus_header_reinit
void _dbus_header_reinit(DBusHeader *header)
Re-initializes a header that was previously initialized and never freed.
Definition: dbus-marshal-header.c:443
DBUS_VALID
the data is valid
Definition: dbus-marshal-validate.h:56
dbus_message_new_method_call
DBusMessage * dbus_message_new_method_call(const char *destination, const char *path, const char *iface, const char *method)
Constructs a new message to invoke a method on a remote object.
Definition: dbus-message.c:1360
DBUS_HEADER_FIELD_DESTINATION
#define DBUS_HEADER_FIELD_DESTINATION
Header field code for the destination bus name of a message.
Definition: dbus-protocol.h:288
DBusTypeReader::byte_order
dbus_uint32_t byte_order
byte order of the block
Definition: dbus-marshal-recursive.h:41
_dbus_header_delete_field
dbus_bool_t _dbus_header_delete_field(DBusHeader *header, int field)
Deletes a field, if it exists.
Definition: dbus-marshal-header.c:1416
dbus_message_has_destination
dbus_bool_t dbus_message_has_destination(DBusMessage *message, const char *name)
Checks whether the message was sent to the given name.
Definition: dbus-message.c:3767
DBUS_MESSAGE_TYPE_INVALID
#define DBUS_MESSAGE_TYPE_INVALID
This value is never a valid message type, see dbus_message_get_type()
Definition: dbus-protocol.h:232
DBUS_HEADER_FLAG_ALLOW_INTERACTIVE_AUTHORIZATION
#define DBUS_HEADER_FLAG_ALLOW_INTERACTIVE_AUTHORIZATION
If set on a method call, this flag means that the caller is prepared to wait for interactive authoriz...
Definition: dbus-protocol.h:261
dbus_message_get_auto_start
dbus_bool_t dbus_message_get_auto_start(DBusMessage *message)
Returns TRUE if the message will cause an owner for destination name to be auto-started.
Definition: dbus-message.c:3122
DBusTypeWriter::byte_order
dbus_uint32_t byte_order
byte order to write values with
Definition: dbus-marshal-recursive.h:66
_DBUS_UNLOCK
#define _DBUS_UNLOCK(name)
Unlocks a global lock.
Definition: dbus-internals.h:369
_dbus_string_free
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:259
DBusTypeReader
The type reader is an iterator for reading values from a block of values.
Definition: dbus-marshal-recursive.h:39
_dbus_data_slot_list_get
void * _dbus_data_slot_list_get(DBusDataSlotAllocator *allocator, DBusDataSlotList *list, int slot)
Retrieves data previously set with _dbus_data_slot_list_set_data().
Definition: dbus-dataslot.c:285
_dbus_message_loader_get_max_message_unix_fds
long _dbus_message_loader_get_max_message_unix_fds(DBusMessageLoader *loader)
Gets the maximum allowed number of unix fds per message.
Definition: dbus-message.c:4580
TRUE
#define TRUE
Expands to "1".
dbus_message_marshal
dbus_bool_t dbus_message_marshal(DBusMessage *msg, char **marshalled_data_p, int *len_p)
Turn a DBusMessage into the marshalled form as described in the D-Bus specification.
Definition: dbus-message.c:4798
_dbus_header_set_field_basic
dbus_bool_t _dbus_header_set_field_basic(DBusHeader *header, int field, int type, const void *value)
Sets the value of a field with basic type.
Definition: dbus-marshal-header.c:1273
_dbus_data_slot_list_init
void _dbus_data_slot_list_init(DBusDataSlotList *list)
Initializes a slot list.
Definition: dbus-dataslot.c:197
_dbus_assert_not_reached
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
Definition: dbus-internals.h:159
dbus_message_copy
DBusMessage * dbus_message_copy(const DBusMessage *message)
Creates a new message that is an exact replica of the message specified, except that its refcount is ...
Definition: dbus-message.c:1614
dbus_message_iter_get_element_type
int dbus_message_iter_get_element_type(DBusMessageIter *iter)
Returns the element type of the array that the message iterator points to.
Definition: dbus-message.c:2199
_dbus_message_get_network_data
void _dbus_message_get_network_data(DBusMessage *message, const DBusString **header, const DBusString **body)
Gets the data to be sent over the network for this message.
Definition: dbus-message.c:231
DBUS_HEADER_FIELD_MEMBER
#define DBUS_HEADER_FIELD_MEMBER
Header field code for a member (method or signal).
Definition: dbus-protocol.h:276
DBusMessageLoader::max_message_unix_fds
long max_message_unix_fds
Maximum unix fds in a message.
Definition: dbus-message-private.h:69
DBusMessageLoader::corrupted
unsigned int corrupted
We got broken data, and are no longer working.
Definition: dbus-message-private.h:73
dbus_message_get_args_valist
dbus_bool_t dbus_message_get_args_valist(DBusMessage *message, DBusError *error, int first_arg_type, va_list var_args)
Like dbus_message_get_args but takes a va_list for use by language bindings.
Definition: dbus-message.c:2036
DBUS_HEADER_FIELD_SENDER
#define DBUS_HEADER_FIELD_SENDER
Header field code for the sender of a message; usually initialized by the message bus...
Definition: dbus-protocol.h:293
_dbus_type_writer_add_types
void _dbus_type_writer_add_types(DBusTypeWriter *writer, DBusString *type_str, int type_pos)
Adds type string to the writer, if it had none.
Definition: dbus-marshal-recursive.c:1546
DBUS_TYPE_OBJECT_PATH
#define DBUS_TYPE_OBJECT_PATH
Type code marking a D-Bus object path.
Definition: dbus-protocol.h:106
dbus_set_error_from_message
dbus_bool_t dbus_set_error_from_message(DBusError *error, DBusMessage *message)
Sets a DBusError based on the contents of the given message.
Definition: dbus-message.c:3873
dbus_message_demarshal
DBusMessage * dbus_message_demarshal(const char *str, int len, DBusError *error)
Demarshal a D-Bus message from the format described in the D-Bus specification.
Definition: dbus-message.c:4860
dbus_message_iter_get_fixed_array
void dbus_message_iter_get_fixed_array(DBusMessageIter *iter, void *value, int *n_elements)
Reads a block of fixed-length values from the message iterator.
Definition: dbus-message.c:2468
DBUS_TYPE_UNIX_FD
#define DBUS_TYPE_UNIX_FD
Type code marking a unix file descriptor.
Definition: dbus-protocol.h:114
_dbus_header_create
dbus_bool_t _dbus_header_create(DBusHeader *header, int byte_order, int message_type, const char *destination, const char *path, const char *interface, const char *member, const char *error_name)
Fills in the primary fields of the header, so the header is ready for use.
Definition: dbus-marshal-header.c:528
dbus_message_get_interface
const char * dbus_message_get_interface(DBusMessage *message)
Gets the interface this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitted...
Definition: dbus-message.c:3304
DBusDataSlotAllocator
An allocator that tracks a set of slot IDs.
Definition: dbus-dataslot.h:55
DBUS_TYPE_INVALID
#define DBUS_TYPE_INVALID
Type code that is never equal to a legitimate type code.
Definition: dbus-protocol.h:60
dbus_message_set_reply_serial
dbus_bool_t dbus_message_set_reply_serial(DBusMessage *message, dbus_uint32_t reply_serial)
Sets the reply serial of a message (the serial of the message this is a reply to).
Definition: dbus-message.c:1166
_dbus_counter_notify
void _dbus_counter_notify(DBusCounter *counter)
Calls the notify function from _dbus_counter_set_notify(), if that function has been specified and th...
Definition: dbus-resources.c:207
dbus_message_has_sender
dbus_bool_t dbus_message_has_sender(DBusMessage *message, const char *name)
Checks whether the message has the given unique name as its sender.
Definition: dbus-message.c:3802
dbus_message_iter_next
dbus_bool_t dbus_message_iter_next(DBusMessageIter *iter)
Moves the iterator to the next field, if any.
Definition: dbus-message.c:2155
dbus_message_iter_get_basic
void dbus_message_iter_get_basic(DBusMessageIter *iter, void *value)
Reads a basic-typed value from the message iterator.
Definition: dbus-message.c:2334
dbus_message_get_data
void * dbus_message_get_data(DBusMessage *message, dbus_int32_t slot)
Retrieves data previously set with dbus_message_set_data().
Definition: dbus-message.c:4712
_dbus_type_reader_init
void _dbus_type_reader_init(DBusTypeReader *reader, int byte_order, const DBusString *type_str, int type_pos, const DBusString *value_str, int value_pos)
Initializes a type reader.
Definition: dbus-marshal-recursive.c:733
_dbus_header_free
void _dbus_header_free(DBusHeader *header)
Frees a header.
Definition: dbus-marshal-header.c:476
_dbus_message_loader_pop_message_link
DBusList * _dbus_message_loader_pop_message_link(DBusMessageLoader *loader)
Pops a loaded message inside a list link (passing ownership of the message and link to the caller)...
Definition: dbus-message.c:4473
DBUS_MAXIMUM_ARRAY_LENGTH
#define DBUS_MAXIMUM_ARRAY_LENGTH
Max length of a marshaled array in bytes (64M, 2^26) We use signed int for lengths so must be INT_MAX...
Definition: dbus-protocol.h:203
dbus_message_set_destination
dbus_bool_t dbus_message_set_destination(DBusMessage *message, const char *destination)
Sets the message&#39;s destination.
Definition: dbus-message.c:3502
dbus_error_init
void dbus_error_init(DBusError *error)
Initializes a DBusError structure.
Definition: dbus-errors.c:188
_dbus_atomic_dec
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
Definition: dbus-sysdeps-unix.c:2776
DBusMessage::refcount
DBusAtomic refcount
Reference count.
Definition: dbus-message-private.h:101
dbus_message_get_no_reply
dbus_bool_t dbus_message_get_no_reply(DBusMessage *message)
Returns TRUE if the message does not expect a reply.
Definition: dbus-message.c:3080
DBusList
A node in a linked list.
Definition: dbus-list.h:34
_dbus_message_loader_get_unix_fds
dbus_bool_t _dbus_message_loader_get_unix_fds(DBusMessageLoader *loader, int **fds, unsigned *max_n_fds)
Gets the buffer to use for reading unix fds from the network.
Definition: dbus-message.c:4079
dbus_free_string_array
void dbus_free_string_array(char **str_array)
Frees a NULL-terminated array of strings.
Definition: dbus-memory.c:749
DBUS_TYPE_BOOLEAN
#define DBUS_TYPE_BOOLEAN
Type code marking a boolean.
Definition: dbus-protocol.h:70
_dbus_message_loader_get_buffer
void _dbus_message_loader_get_buffer(DBusMessageLoader *loader, DBusString **buffer)
Gets the buffer to use for reading data from the network.
Definition: dbus-message.c:4039
_dbus_string_append_len
dbus_bool_t _dbus_string_append_len(DBusString *str, const char *buffer, int len)
Appends block of bytes with the given length to a DBusString.
Definition: dbus-string.c:1137
DBusMessageRealIter::iter_type
dbus_uint32_t iter_type
whether this is a reader or writer iter
Definition: dbus-message.c:130
_dbus_header_set_serial
void _dbus_header_set_serial(DBusHeader *header, dbus_uint32_t serial)
Sets the serial number of a header.
Definition: dbus-marshal-header.c:404
_dbus_type_reader_get_element_type
int _dbus_type_reader_get_element_type(const DBusTypeReader *reader)
Gets the type of an element of the array the reader is currently pointing to.
Definition: dbus-marshal-recursive.c:821
_dbus_header_get_byte_order
char _dbus_header_get_byte_order(const DBusHeader *header)
Returns the header&#39;s byte order.
Definition: dbus-marshal-header.c:174
dbus_message_iter_open_container
dbus_bool_t dbus_message_iter_open_container(DBusMessageIter *iter, int type, const char *contained_signature, DBusMessageIter *sub)
Appends a container-typed value to the message; you are required to append the contents of the contai...
Definition: dbus-message.c:2926
_dbus_type_reader_has_next
dbus_bool_t _dbus_type_reader_has_next(const DBusTypeReader *reader)
Check whether there&#39;s another value on this "level".
Definition: dbus-marshal-recursive.c:1094
DBusBasicValue
A simple value union that lets you access bytes as if they were various types; useful when dealing wi...
Definition: dbus-types.h:137
DBusTypeWriter::container_type
dbus_uint32_t container_type
what are we inside? (e.g.
Definition: dbus-marshal-recursive.h:68
_dbus_type_reader_get_array_length
int _dbus_type_reader_get_array_length(const DBusTypeReader *reader)
Returns the number of bytes in the array.
Definition: dbus-marshal-recursive.c:900
_dbus_header_get_field_raw
dbus_bool_t _dbus_header_get_field_raw(DBusHeader *header, int field, const DBusString **str, int *pos)
Gets the raw marshaled data for a field.
Definition: dbus-marshal-header.c:1392
dbus_message_iter_append_basic
dbus_bool_t dbus_message_iter_append_basic(DBusMessageIter *iter, int type, const void *value)
Appends a basic-typed value to the message.
Definition: dbus-message.c:2733
_dbus_close
dbus_bool_t _dbus_close(int fd, DBusError *error)
Closes a file descriptor.
Definition: dbus-sysdeps-unix.c:3213
dbus_message_iter_get_array_len
int dbus_message_iter_get_array_len(DBusMessageIter *iter)
Returns the number of bytes in the array as marshaled in the wire protocol.
Definition: dbus-message.c:2423
DBusForeachFunction
void(* DBusForeachFunction)(void *element, void *data)
Used to iterate over each item in a collection, such as a DBusList.
Definition: dbus-internals.h:283
_dbus_type_reader_get_current_type
int _dbus_type_reader_get_current_type(const DBusTypeReader *reader)
Gets the type of the value the reader is currently pointing to; or for a types-only reader gets the t...
Definition: dbus-marshal-recursive.c:786
FALSE
#define FALSE
Expands to "0".
DBusHeader
Message header data and some cached details of it.
Definition: dbus-marshal-header.h:47
dbus_message_set_allow_interactive_authorization
void dbus_message_set_allow_interactive_authorization(DBusMessage *message, dbus_bool_t allow)
Sets a flag indicating that the caller of the method is prepared to wait for interactive authorizatio...
Definition: dbus-message.c:4981
DBUS_HEADER_FIELD_PATH
#define DBUS_HEADER_FIELD_PATH
Header field code for the path - the path is the object emitting a signal or the object receiving a m...
Definition: dbus-protocol.h:270
dbus_message_get_type
int dbus_message_get_type(DBusMessage *message)
Gets the type of a message.
Definition: dbus-message.c:1749
DBUS_HEADER_FIELD_REPLY_SERIAL
#define DBUS_HEADER_FIELD_REPLY_SERIAL
Header field code for a reply serial, used to match a DBUS_MESSAGE_TYPE_METHOD_RETURN message with th...
Definition: dbus-protocol.h:284
DBusMessageLoader::buffer_outstanding
unsigned int buffer_outstanding
Someone is using the buffer to read.
Definition: dbus-message-private.h:75
DBusMessage::generation
int generation
_dbus_current_generation when message was created
Definition: dbus-message-private.h:121
_dbus_list_prepend_link
void _dbus_list_prepend_link(DBusList **list, DBusList *link)
Prepends a link to the list.
Definition: dbus-list.c:333
_dbus_string_set_length
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:802
_dbus_register_shutdown_func
DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_register_shutdown_func(DBusShutdownFunction function, void *data)
Register a cleanup function to be called exactly once the next time dbus_shutdown() is called...
Definition: dbus-memory.c:810
_DBUS_LOCK
#define _DBUS_LOCK(name)
Locks a global lock, initializing it first if necessary.
Definition: dbus-internals.h:368
_DBUS_LOCK_NAME
#define _DBUS_LOCK_NAME(name)
Expands to name of a global lock variable.
Definition: dbus-internals.h:367
_dbus_type_to_string
const char * _dbus_type_to_string(int typecode)
Returns a string describing the given type.
Definition: dbus-marshal-basic.c:1219
_dbus_message_loader_peek_message
DBusMessage * _dbus_message_loader_peek_message(DBusMessageLoader *loader)
Peeks at first loaded message, returns NULL if no messages have been queued.
Definition: dbus-message.c:4442
_dbus_string_copy_len
dbus_bool_t _dbus_string_copy_len(const DBusString *source, int start, int len, DBusString *dest, int insert_at)
Like _dbus_string_copy(), but can copy a segment from the middle of the source string.
Definition: dbus-string.c:1375
_dbus_string_steal_data
dbus_bool_t _dbus_string_steal_data(DBusString *str, char **data_return)
Like _dbus_string_get_data(), but removes the gotten data from the original string.
Definition: dbus-string.c:641
_dbus_type_reader_get_signature
void _dbus_type_reader_get_signature(const DBusTypeReader *reader, const DBusString **str_p, int *start_p, int *len_p)
Gets the string and range of said string containing the signature of the current value.
Definition: dbus-marshal-recursive.c:1125
dbus_message_append_args_valist
dbus_bool_t dbus_message_append_args_valist(DBusMessage *message, int first_arg_type, va_list var_args)
Like dbus_message_append_args() but takes a va_list for use by language bindings. ...
Definition: dbus-message.c:1851
dbus_message_demarshal_bytes_needed
int dbus_message_demarshal_bytes_needed(const char *buf, int len)
Returns the number of bytes required to be in the buffer to demarshal a D-Bus message.
Definition: dbus-message.c:4921
_dbus_atomic_get
dbus_int32_t _dbus_atomic_get(DBusAtomic *atomic)
Atomically get the value of an integer.
Definition: dbus-sysdeps-unix.c:2800
dbus_message_iter_get_signature
char * dbus_message_iter_get_signature(DBusMessageIter *iter)
Returns the current signature of a message iterator.
Definition: dbus-message.c:2261
_dbus_type_writer_write_fixed_multi
dbus_bool_t _dbus_type_writer_write_fixed_multi(DBusTypeWriter *writer, int element_type, const void *value, int n_elements)
Writes a block of fixed-length basic values, i.e.
Definition: dbus-marshal-recursive.c:2359
dbus_message_iter_abandon_container
void dbus_message_iter_abandon_container(DBusMessageIter *iter, DBusMessageIter *sub)
Abandons creation of a contained-typed value and frees resources created by dbus_message_iter_open_co...
Definition: dbus-message.c:3028
_dbus_verbose_bytes_of_string
DBUS_PRIVATE_EXPORT void _dbus_verbose_bytes_of_string(const DBusString *str, int start, int len)
Dump the given part of the string to verbose log.
Definition: dbus-marshal-basic.c:1360
_dbus_data_slot_allocator_alloc
dbus_bool_t _dbus_data_slot_allocator_alloc(DBusDataSlotAllocator *allocator, dbus_int32_t *slot_id_p)
Allocates an integer ID to be used for storing data in a DBusDataSlotList.
Definition: dbus-dataslot.c:69
dbus_message_contains_unix_fds
dbus_bool_t dbus_message_contains_unix_fds(DBusMessage *message)
Checks whether a message contains unix fds.
Definition: dbus-message.c:3902
DBUS_HEADER_FLAG_NO_AUTO_START
#define DBUS_HEADER_FLAG_NO_AUTO_START
If set, this flag means that even if the message bus knows how to start an owner for the destination ...
Definition: dbus-protocol.h:256
_dbus_message_loader_queue_messages
dbus_bool_t _dbus_message_loader_queue_messages(DBusMessageLoader *loader)
Converts buffered data into messages, if we have enough data.
Definition: dbus-message.c:4379
_dbus_message_get_unix_fds
void _dbus_message_get_unix_fds(DBusMessage *message, const int **fds, unsigned *n_fds)
Gets the unix fds to be sent over the network for this message.
Definition: dbus-message.c:250
DBusMessageLoader::refcount
int refcount
Reference count.
Definition: dbus-message-private.h:62
dbus_int32_t
int dbus_int32_t
A 32-bit signed integer on all platforms.
Definition: dbus-arch-deps.h:42
_dbus_strdup
char * _dbus_strdup(const char *str)
Duplicates a string.
Definition: dbus-internals.c:537
MAX_MESSAGE_SIZE_TO_CACHE
#define MAX_MESSAGE_SIZE_TO_CACHE
Avoid caching huge messages.
Definition: dbus-message.c:528
_dbus_getenv
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:185
DBUS_ERROR_INVALID_ARGS
#define DBUS_ERROR_INVALID_ARGS
Invalid arguments passed to a method call.
Definition: dbus-protocol.h:391
_dbus_data_slot_allocator_free
void _dbus_data_slot_allocator_free(DBusDataSlotAllocator *allocator, dbus_int32_t *slot_id_p)
Deallocates an ID previously allocated with _dbus_data_slot_allocator_alloc().
Definition: dbus-dataslot.c:154
_dbus_type_get_alignment
int _dbus_type_get_alignment(int typecode)
Gets the alignment requirement for the given type; will be 1, 4, or 8.
Definition: dbus-marshal-basic.c:1173
DBusMessageLoader::corruption_reason
DBusValidity corruption_reason
why we were corrupted
Definition: dbus-message-private.h:71
_dbus_message_loader_set_max_message_unix_fds
void _dbus_message_loader_set_max_message_unix_fds(DBusMessageLoader *loader, long n)
Sets the maximum unix fds per message we allow.
Definition: dbus-message.c:4561
dbus_message_set_member
dbus_bool_t dbus_message_set_member(DBusMessage *message, const char *member)
Sets the interface member being invoked (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted (DBUS_MESSAGE_TYPE...
Definition: dbus-message.c:3363
dbus_message_type_to_string
const char * dbus_message_type_to_string(int type)
Utility function to convert a D-Bus message type into a machine-readable string (not translated)...
Definition: dbus-message.c:4768
dbus_message_unref
void dbus_message_unref(DBusMessage *message)
Decrements the reference count of a DBusMessage, freeing the message if the count reaches 0...
Definition: dbus-message.c:1717
_dbus_string_init_const_len
void _dbus_string_init_const_len(DBusString *str, const char *value, int len)
Initializes a constant string with a length.
Definition: dbus-string.c:210
DBusMessageLoader
Implementation details of DBusMessageLoader.
Definition: dbus-message-private.h:60
_dbus_type_writer_recurse
dbus_bool_t _dbus_type_writer_recurse(DBusTypeWriter *writer, int container_type, const DBusString *contained_type, int contained_type_start, DBusTypeWriter *sub)
Opens a new container and writes out the initial information for that container.
Definition: dbus-marshal-recursive.c:2109
DBusBasicValue::u32
dbus_uint32_t u32
as int32
Definition: dbus-types.h:143
dbus_message_new_error_printf
DBusMessage * dbus_message_new_error_printf(DBusMessage *reply_to, const char *error_name, const char *error_format,...)
Creates a new message that is an error reply to another message, allowing you to use printf formattin...
Definition: dbus-message.c:1569
dbus_message_set_data
dbus_bool_t dbus_message_set_data(DBusMessage *message, dbus_int32_t slot, void *data, DBusFreeFunction free_data_func)
Stores a pointer on a DBusMessage, along with an optional function to be used for freeing the data wh...
Definition: dbus-message.c:4676
dbus_message_set_serial
void dbus_message_set_serial(DBusMessage *message, dbus_uint32_t serial)
Sets the serial number of a message.
Definition: dbus-message.c:277
_dbus_header_toggle_flag
void _dbus_header_toggle_flag(DBusHeader *header, dbus_uint32_t flag, dbus_bool_t value)
Toggles a message flag bit, turning on the bit if value = TRUE and flipping it off if value = FALSE...
Definition: dbus-marshal-header.c:1457
_dbus_header_update_lengths
void _dbus_header_update_lengths(DBusHeader *header, int body_len)
Fills in the correct body length.
Definition: dbus-marshal-header.c:1196
dbus_message_new_method_return
DBusMessage * dbus_message_new_method_return(DBusMessage *method_call)
Constructs a message that is a reply to a method call.
Definition: dbus-message.c:1400
DBusMessageRealIter::writer
DBusTypeWriter writer
writer
Definition: dbus-message.c:134
_dbus_data_slot_list_free
void _dbus_data_slot_list_free(DBusDataSlotList *list)
Frees the data slot list and all data slots contained in it, calling application-provided free functi...
Definition: dbus-dataslot.c:340
DBUS_MAXIMUM_MESSAGE_LENGTH
#define DBUS_MAXIMUM_MESSAGE_LENGTH
The maximum total message size including header and body; similar rationale to max array size...
Definition: dbus-protocol.h:210
DBusMessage::slot_list
DBusDataSlotList slot_list
Data stored by allocated integer ID.
Definition: dbus-message-private.h:118
_dbus_list_clear
void _dbus_list_clear(DBusList **list)
Frees all links in the list and sets the list head to NULL.
Definition: dbus-list.c:542
_dbus_marshal_byteswap
void _dbus_marshal_byteswap(const DBusString *signature, int signature_start, int old_byte_order, int new_byte_order, DBusString *value_str, int value_pos)
Byteswaps the marshaled data in the given value_str.
Definition: dbus-marshal-byteswap.c:222
_dbus_message_loader_get_pending_fds_count
int _dbus_message_loader_get_pending_fds_count(DBusMessageLoader *loader)
Return how many file descriptors are pending in the loader.
Definition: dbus-message.c:4591
dbus_type_is_container
dbus_bool_t dbus_type_is_container(int typecode)
A "container type" can contain basic types, or nested container types.
Definition: dbus-signature.c:294
dbus_message_new_error
DBusMessage * dbus_message_new_error(DBusMessage *reply_to, const char *error_name, const char *error_message)
Creates a new message that is an error reply to another message.
Definition: dbus-message.c:1497
_dbus_counter_adjust_size
void _dbus_counter_adjust_size(DBusCounter *counter, long delta)
Adjusts the value of the size counter by the given delta which may be positive or negative...
Definition: dbus-resources.c:167