D-Bus: dbus-message.c Source File

D-Bus 1.10.22

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 dbus_message_iter_abandon_container (&iter, &array);
1939 goto failed;
1940 }
1941
1942 if (!dbus_message_iter_close_container (&iter, &array))
1943 goto failed;
1944 }
1945 #ifndef DBUS_DISABLE_CHECKS
1946 else
1947 {
1948 _dbus_warn ("type %s isn't supported yet in %s\n",
1949 _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
1950 goto failed;
1951 }
1952 #endif
1953
1954 type = va_arg (var_args, int);
1955 }
1956
1957 return TRUE;
1958
1959 failed:
1960 return FALSE;
1961 }
1962
2007 dbus_bool_t
2008 dbus_message_get_args (DBusMessage *message,
2009 DBusError *error,
2010 int first_arg_type,
2011 ...)
2012 {
2013 dbus_bool_t retval;
2014 va_list var_args;
2015
2016 _dbus_return_val_if_fail (message != NULL, FALSE);
2017 _dbus_return_val_if_error_is_set (error, FALSE);
2018
2019 va_start (var_args, first_arg_type);
2020 retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
2021 va_end (var_args);
2022
2023 return retval;
2024 }
2025
2036 dbus_bool_t
2037 dbus_message_get_args_valist (DBusMessage *message,
2038 DBusError *error,
2039 int first_arg_type,
2040 va_list var_args)
2041 {
2042 DBusMessageIter iter;
2043
2044 _dbus_return_val_if_fail (message != NULL, FALSE);
2045 _dbus_return_val_if_error_is_set (error, FALSE);
2046
2047 dbus_message_iter_init (message, &iter);
2048 return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
2049 }
2050
2051 static void
2052 _dbus_message_iter_init_common (DBusMessage *message,
2053 DBusMessageRealIter *real,
2054 int iter_type)
2055 {
2056 /* If these static assertions fail on your platform, report it as a bug. */
2057 _DBUS_STATIC_ASSERT (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
2058 _DBUS_STATIC_ASSERT (_DBUS_ALIGNOF (DBusMessageRealIter) <=
2059 _DBUS_ALIGNOF (DBusMessageIter));
2060 /* A failure of these two assertions would indicate that we've broken
2061 * ABI on this platform since 1.10.0. */
2062 _DBUS_STATIC_ASSERT (sizeof (DBusMessageIter_1_10_0) ==
2063 sizeof (DBusMessageIter));
2064 _DBUS_STATIC_ASSERT (_DBUS_ALIGNOF (DBusMessageIter_1_10_0) ==
2065 _DBUS_ALIGNOF (DBusMessageIter));
2066 /* If this static assertion fails, it means the DBusMessageIter struct
2067 * is not "packed", which might result in "iter = other_iter" not copying
2068 * every byte. */
2069 _DBUS_STATIC_ASSERT (sizeof (DBusMessageIter) ==
2070 4 * sizeof (void *) + sizeof (dbus_uint32_t) + 9 * sizeof (int));
2071
2072 /* Since the iterator will read or write who-knows-what from the
2073 * message, we need to get in the right byte order
2074 */
2075 ensure_byte_order (message);
2076
2077 real->message = message;
2078 real->changed_stamp = message->changed_stamp;
2079 real->iter_type = iter_type;
2080 real->sig_refcount = 0;
2081 }
2082
2105 dbus_bool_t
2106 dbus_message_iter_init (DBusMessage *message,
2107 DBusMessageIter *iter)
2108 {
2109 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2110 const DBusString *type_str;
2111 int type_pos;
2112
2113 _dbus_return_val_if_fail (message != NULL, FALSE);
2114 _dbus_return_val_if_fail (iter != NULL, FALSE);
2115
2116 get_const_signature (&message->header, &type_str, &type_pos);
2117
2118 _dbus_message_iter_init_common (message, real,
2119 DBUS_MESSAGE_ITER_TYPE_READER);
2120
2121 _dbus_type_reader_init (&real->u.reader,
2122 _dbus_header_get_byte_order (&message->header),
2123 type_str, type_pos,
2124 &message->body,
2125 0);
2126
2127 return _dbus_type_reader_get_current_type (&real->u.reader) != DBUS_TYPE_INVALID;
2128 }
2129
2136 dbus_bool_t
2137 dbus_message_iter_has_next (DBusMessageIter *iter)
2138 {
2139 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2140
2141 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
2142 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2143
2144 return _dbus_type_reader_has_next (&real->u.reader);
2145 }
2146
2155 dbus_bool_t
2156 dbus_message_iter_next (DBusMessageIter *iter)
2157 {
2158 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2159
2160 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
2161 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2162
2163 return _dbus_type_reader_next (&real->u.reader);
2164 }
2165
2180 int
2181 dbus_message_iter_get_arg_type (DBusMessageIter *iter)
2182 {
2183 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2184
2185 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2186 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2187
2188 return _dbus_type_reader_get_current_type (&real->u.reader);
2189 }
2190
2199 int
2200 dbus_message_iter_get_element_type (DBusMessageIter *iter)
2201 {
2202 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2203
2204 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2205 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
2206 _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
2207
2208 return _dbus_type_reader_get_element_type (&real->u.reader);
2209 }
2210
2236 void
2237 dbus_message_iter_recurse (DBusMessageIter *iter,
2238 DBusMessageIter *sub)
2239 {
2240 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2241 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2242
2243 _dbus_return_if_fail (_dbus_message_iter_check (real));
2244 _dbus_return_if_fail (sub != NULL);
2245
2246 *real_sub = *real;
2247 _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
2248 }
2249
2261 char *
2262 dbus_message_iter_get_signature (DBusMessageIter *iter)
2263 {
2264 const DBusString *sig;
2265 DBusString retstr;
2266 char *ret;
2267 int start, len;
2268 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2269
2270 _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
2271
2272 if (!_dbus_string_init (&retstr))
2273 return NULL;
2274
2275 _dbus_type_reader_get_signature (&real->u.reader, &sig,
2276 &start, &len);
2277 if (!_dbus_string_append_len (&retstr,
2278 _dbus_string_get_const_data (sig) + start,
2279 len))
2280 return NULL;
2281 if (!_dbus_string_steal_data (&retstr, &ret))
2282 return NULL;
2283 _dbus_string_free (&retstr);
2284 return ret;
2285 }
2286
2334 void
2335 dbus_message_iter_get_basic (DBusMessageIter *iter,
2336 void *value)
2337 {
2338 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2339
2340 _dbus_return_if_fail (_dbus_message_iter_check (real));
2341 _dbus_return_if_fail (value != NULL);
2342
2343 if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_UNIX_FD)
2344 {
2345 #ifdef HAVE_UNIX_FD_PASSING
2346 DBusBasicValue idx;
2347
2348 _dbus_type_reader_read_basic(&real->u.reader, &idx);
2349
2350 if (idx.u32 >= real->message->n_unix_fds) {
2351 /* Hmm, we cannot really signal an error here, so let's make
2352 sure to return an invalid fd. */
2353 *((int*) value) = -1;
2354 return;
2355 }
2356
2357 *((int*) value) = _dbus_dup(real->message->unix_fds[idx.u32], NULL);
2358 #else
2359 *((int*) value) = -1;
2360 #endif
2361 }
2362 else
2363 {
2364 _dbus_type_reader_read_basic (&real->u.reader,
2365 value);
2366 }
2367 }
2368
2379 int
2380 dbus_message_iter_get_element_count (DBusMessageIter *iter)
2381 {
2382 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2383 DBusTypeReader array;
2384 int element_type;
2385 int n_elements = 0;
2386
2387 _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
2388 _dbus_return_val_if_fail (_dbus_type_reader_get_current_type (&real->u.reader)
2389 == DBUS_TYPE_ARRAY, 0);
2390
2391 element_type = _dbus_type_reader_get_element_type (&real->u.reader);
2392 _dbus_type_reader_recurse (&real->u.reader, &array);
2393 if (dbus_type_is_fixed (element_type))
2394 {
2395 int alignment = _dbus_type_get_alignment (element_type);
2396 int total_len = _dbus_type_reader_get_array_length (&array);
2397 n_elements = total_len / alignment;
2398 }
2399 else
2400 {
2401 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
2402 {
2403 ++n_elements;
2404 _dbus_type_reader_next (&array);
2405 }
2406 }
2407
2408 return n_elements;
2409 }
2410
2423 int
2424 dbus_message_iter_get_array_len (DBusMessageIter *iter)
2425 {
2426 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2427
2428 _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
2429
2430 return _dbus_type_reader_get_array_length (&real->u.reader);
2431 }
2432
2468 void
2469 dbus_message_iter_get_fixed_array (DBusMessageIter *iter,
2470 void *value,
2471 int *n_elements)
2472 {
2473 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2474 #ifndef DBUS_DISABLE_CHECKS
2475 int subtype = _dbus_type_reader_get_current_type(&real->u.reader);
2476
2477 _dbus_return_if_fail (_dbus_message_iter_check (real));
2478 _dbus_return_if_fail (value != NULL);
2479 _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) ||
2480 (dbus_type_is_fixed (subtype) && subtype != DBUS_TYPE_UNIX_FD));
2481 #endif
2482
2483 _dbus_type_reader_read_fixed_multi (&real->u.reader,
2484 value, n_elements);
2485 }
2486
2498 void
2499 dbus_message_iter_init_append (DBusMessage *message,
2500 DBusMessageIter *iter)
2501 {
2502 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2503
2504 _dbus_return_if_fail (message != NULL);
2505 _dbus_return_if_fail (iter != NULL);
2506
2507 _dbus_message_iter_init_common (message, real,
2508 DBUS_MESSAGE_ITER_TYPE_WRITER);
2509
2510 /* We create the signature string and point iterators at it "on demand"
2511 * when a value is actually appended. That means that init() never fails
2512 * due to OOM.
2513 */
2514 _dbus_type_writer_init_types_delayed (&real->u.writer,
2515 _dbus_header_get_byte_order (&message->header),
2516 &message->body,
2517 _dbus_string_get_length (&message->body));
2518 }
2519
2528 static dbus_bool_t
2529 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
2530 {
2531 DBusString *str;
2532 const DBusString *current_sig;
2533 int current_sig_pos;
2534
2535 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2536
2537 if (real->u.writer.type_str != NULL)
2538 {
2539 _dbus_assert (real->sig_refcount > 0);
2540 real->sig_refcount += 1;
2541 return TRUE;
2542 }
2543
2544 str = dbus_new (DBusString, 1);
2545 if (str == NULL)
2546 return FALSE;
2547
2548 if (!_dbus_header_get_field_raw (&real->message->header,
2549 DBUS_HEADER_FIELD_SIGNATURE,
2550 &current_sig, &current_sig_pos))
2551 current_sig = NULL;
2552
2553 if (current_sig)
2554 {
2555 int current_len;
2556
2557 current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
2558 current_sig_pos += 1; /* move on to sig data */
2559
2560 if (!_dbus_string_init_preallocated (str, current_len + 4))
2561 {
2562 dbus_free (str);
2563 return FALSE;
2564 }
2565
2566 if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
2567 str, 0))
2568 {
2569 _dbus_string_free (str);
2570 dbus_free (str);
2571 return FALSE;
2572 }
2573 }
2574 else
2575 {
2576 if (!_dbus_string_init_preallocated (str, 4))
2577 {
2578 dbus_free (str);
2579 return FALSE;
2580 }
2581 }
2582
2583 real->sig_refcount = 1;
2584
2585 _dbus_type_writer_add_types (&real->u.writer,
2586 str, _dbus_string_get_length (str));
2587 return TRUE;
2588 }
2589
2599 static dbus_bool_t
2600 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
2601 {
2602 DBusString *str;
2603 const char *v_STRING;
2604 dbus_bool_t retval;
2605
2606 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2607 _dbus_assert (real->u.writer.type_str != NULL);
2608 _dbus_assert (real->sig_refcount > 0);
2609
2610 real->sig_refcount -= 1;
2611
2612 if (real->sig_refcount > 0)
2613 return TRUE;
2614 _dbus_assert (real->sig_refcount == 0);
2615
2616 retval = TRUE;
2617
2618 str = real->u.writer.type_str;
2619
2620 v_STRING = _dbus_string_get_const_data (str);
2621 if (!_dbus_header_set_field_basic (&real->message->header,
2622 DBUS_HEADER_FIELD_SIGNATURE,
2623 DBUS_TYPE_SIGNATURE,
2624 &v_STRING))
2625 retval = FALSE;
2626
2627 _dbus_type_writer_remove_types (&real->u.writer);
2628 _dbus_string_free (str);
2629 dbus_free (str);
2630
2631 return retval;
2632 }
2633
2641 static void
2642 _dbus_message_iter_abandon_signature (DBusMessageRealIter *real)
2643 {
2644 DBusString *str;
2645
2646 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2647 _dbus_assert (real->u.writer.type_str != NULL);
2648 _dbus_assert (real->sig_refcount > 0);
2649
2650 real->sig_refcount -= 1;
2651
2652 if (real->sig_refcount > 0)
2653 return;
2654 _dbus_assert (real->sig_refcount == 0);
2655
2656 str = real->u.writer.type_str;
2657
2658 _dbus_type_writer_remove_types (&real->u.writer);
2659 _dbus_string_free (str);
2660 dbus_free (str);
2661 }
2662
2663 #ifndef DBUS_DISABLE_CHECKS
2664 static dbus_bool_t
2665 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
2666 {
2667 if (!_dbus_message_iter_check (iter))
2668 return FALSE;
2669
2670 if (iter->message->locked)
2671 {
2672 _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)\n");
2673 return FALSE;
2674 }
2675
2676 return TRUE;
2677 }
2678 #endif /* DBUS_DISABLE_CHECKS */
2679
2680 #ifdef HAVE_UNIX_FD_PASSING
2681 static int *
2682 expand_fd_array(DBusMessage *m,
2683 unsigned n)
2684 {
2685 _dbus_assert(m);
2686
2687 /* This makes space for adding n new fds to the array and returns a
2688 pointer to the place were the first fd should be put. */
2689
2690 if (m->n_unix_fds + n > m->n_unix_fds_allocated)
2691 {
2692 unsigned k;
2693 int *p;
2694
2695 /* Make twice as much space as necessary */
2696 k = (m->n_unix_fds + n) * 2;
2697
2698 /* Allocate at least four */
2699 if (k < 4)
2700 k = 4;
2701
2702 p = dbus_realloc(m->unix_fds, k * sizeof(int));
2703 if (p == NULL)
2704 return NULL;
2705
2706 m->unix_fds = p;
2707 m->n_unix_fds_allocated = k;
2708 }
2709
2710 return m->unix_fds + m->n_unix_fds;
2711 }
2712 #endif
2713
2733 dbus_bool_t
2734 dbus_message_iter_append_basic (DBusMessageIter *iter,
2735 int type,
2736 const void *value)
2737 {
2738 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2739 dbus_bool_t ret;
2740
2741 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2742 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2743 _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
2744 _dbus_return_val_if_fail (value != NULL, FALSE);
2745
2746 #ifndef DBUS_DISABLE_CHECKS
2747 switch (type)
2748 {
2749 const char * const *string_p;
2750 const dbus_bool_t *bool_p;
2751
2752 case DBUS_TYPE_STRING:
2753 string_p = value;
2754 _dbus_return_val_if_fail (_dbus_check_is_valid_utf8 (*string_p), FALSE);
2755 break;
2756
2757 case DBUS_TYPE_OBJECT_PATH:
2758 string_p = value;
2759 _dbus_return_val_if_fail (_dbus_check_is_valid_path (*string_p), FALSE);
2760 break;
2761
2762 case DBUS_TYPE_SIGNATURE:
2763 string_p = value;
2764 _dbus_return_val_if_fail (_dbus_check_is_valid_signature (*string_p), FALSE);
2765 break;
2766
2767 case DBUS_TYPE_BOOLEAN:
2768 bool_p = value;
2769 _dbus_return_val_if_fail (*bool_p == 0 || *bool_p == 1, FALSE);
2770 break;
2771
2772 default:
2773 {
2774 /* nothing to check, all possible values are allowed */
2775 }
2776 }
2777 #endif
2778
2779 if (!_dbus_message_iter_open_signature (real))
2780 return FALSE;
2781
2782 if (type == DBUS_TYPE_UNIX_FD)
2783 {
2784 #ifdef HAVE_UNIX_FD_PASSING
2785 int *fds;
2786 dbus_uint32_t u;
2787
2788 ret = FALSE;
2789
2790 /* First step, include the fd in the fd list of this message */
2791 if (!(fds = expand_fd_array(real->message, 1)))
2792 goto out;
2793
2794 *fds = _dbus_dup(*(int*) value, NULL);
2795 if (*fds < 0)
2796 goto out;
2797
2798 u = real->message->n_unix_fds;
2799
2800 /* Second step, write the index to the fd */
2801 if (!(ret = _dbus_type_writer_write_basic (&real->u.writer, DBUS_TYPE_UNIX_FD, &u))) {
2802 _dbus_close(*fds, NULL);
2803 goto out;
2804 }
2805
2806 real->message->n_unix_fds += 1;
2807 u += 1;
2808
2809 /* Final step, update the header accordingly */
2810 ret = _dbus_header_set_field_basic (&real->message->header,
2811 DBUS_HEADER_FIELD_UNIX_FDS,
2812 DBUS_TYPE_UINT32,
2813 &u);
2814
2815 /* If any of these operations fail the message is
2816 hosed. However, no memory or fds should be leaked since what
2817 has been added to message has been added to the message, and
2818 can hence be accounted for when the message is being
2819 freed. */
2820 #else
2821 ret = FALSE;
2822 /* This is redundant (we could just fall through), but it avoids
2823 * -Wunused-label in builds that don't HAVE_UNIX_FD_PASSING */
2824 goto out;
2825 #endif
2826 }
2827 else
2828 {
2829 ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
2830 }
2831
2832 out:
2833 if (!_dbus_message_iter_close_signature (real))
2834 ret = FALSE;
2835
2836 return ret;
2837 }
2838
2874 dbus_bool_t
2875 dbus_message_iter_append_fixed_array (DBusMessageIter *iter,
2876 int element_type,
2877 const void *value,
2878 int n_elements)
2879 {
2880 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2881 dbus_bool_t ret;
2882
2883 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2884 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2885 _dbus_return_val_if_fail (dbus_type_is_fixed (element_type) && element_type != DBUS_TYPE_UNIX_FD, FALSE);
2886 _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
2887 _dbus_return_val_if_fail (value != NULL, FALSE);
2888 _dbus_return_val_if_fail (n_elements >= 0, FALSE);
2889 _dbus_return_val_if_fail (n_elements <=
2890 DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type),
2891 FALSE);
2892
2893 #ifndef DBUS_DISABLE_CHECKS
2894 if (element_type == DBUS_TYPE_BOOLEAN)
2895 {
2896 const dbus_bool_t * const *bools = value;
2897 int i;
2898
2899 for (i = 0; i < n_elements; i++)
2900 {
2901 _dbus_return_val_if_fail ((*bools)[i] == 0 || (*bools)[i] == 1, FALSE);
2902 }
2903 }
2904 #endif
2905
2906 ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
2907
2908 return ret;
2909 }
2910
2932 dbus_bool_t
2933 dbus_message_iter_open_container (DBusMessageIter *iter,
2934 int type,
2935 const char *contained_signature,
2936 DBusMessageIter *sub)
2937 {
2938 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2939 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2940 DBusString contained_str;
2941 dbus_bool_t ret;
2942
2943 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2944 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2945 _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
2946 _dbus_return_val_if_fail (sub != NULL, FALSE);
2947 _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
2948 contained_signature == NULL) ||
2949 (type == DBUS_TYPE_DICT_ENTRY &&
2950 contained_signature == NULL) ||
2951 (type == DBUS_TYPE_VARIANT &&
2952 contained_signature != NULL) ||
2953 (type == DBUS_TYPE_ARRAY &&
2954 contained_signature != NULL), FALSE);
2955
2956 /* this would fail if the contained_signature is a dict entry, since
2957 * dict entries are invalid signatures standalone (they must be in
2958 * an array)
2959 */
2960 _dbus_return_val_if_fail ((type == DBUS_TYPE_ARRAY && contained_signature && *contained_signature == DBUS_DICT_ENTRY_BEGIN_CHAR) ||
2961 (contained_signature == NULL ||
2962 _dbus_check_is_valid_signature (contained_signature)),
2963 FALSE);
2964
2965 if (!_dbus_message_iter_open_signature (real))
2966 return FALSE;
2967
2968 ret = FALSE;
2969 *real_sub = *real;
2970
2971 if (contained_signature != NULL)
2972 {
2973 _dbus_string_init_const (&contained_str, contained_signature);
2974
2975 ret = _dbus_type_writer_recurse (&real->u.writer,
2976 type,
2977 &contained_str, 0,
2978 &real_sub->u.writer);
2979 }
2980 else
2981 {
2982 ret = _dbus_type_writer_recurse (&real->u.writer,
2983 type,
2984 NULL, 0,
2985 &real_sub->u.writer);
2986 }
2987
2988 if (!ret)
2989 _dbus_message_iter_abandon_signature (real);
2990
2991 return ret;
2992 }
2993
2994
3008 dbus_bool_t
3009 dbus_message_iter_close_container (DBusMessageIter *iter,
3010 DBusMessageIter *sub)
3011 {
3012 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3013 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
3014 dbus_bool_t ret;
3015
3016 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
3017 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
3018 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
3019 _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
3020
3021 ret = _dbus_type_writer_unrecurse (&real->u.writer,
3022 &real_sub->u.writer);
3023
3024 if (!_dbus_message_iter_close_signature (real))
3025 ret = FALSE;
3026
3027 return ret;
3028 }
3029
3041 void
3042 dbus_message_iter_abandon_container (DBusMessageIter *iter,
3043 DBusMessageIter *sub)
3044 {
3045 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3046 #ifndef DBUS_DISABLE_CHECKS
3047 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
3048
3049 _dbus_return_if_fail (_dbus_message_iter_append_check (real));
3050 _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
3051 _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
3052 _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
3053 #endif
3054
3055 _dbus_message_iter_abandon_signature (real);
3056 }
3057
3074 void
3075 dbus_message_set_no_reply (DBusMessage *message,
3076 dbus_bool_t no_reply)
3077 {
3078 _dbus_return_if_fail (message != NULL);
3079 _dbus_return_if_fail (!message->locked);
3080
3081 _dbus_header_toggle_flag (&message->header,
3082 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED,
3083 no_reply);
3084 }
3085
3093 dbus_bool_t
3094 dbus_message_get_no_reply (DBusMessage *message)
3095 {
3096 _dbus_return_val_if_fail (message != NULL, FALSE);
3097
3098 return _dbus_header_get_flag (&message->header,
3099 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED);
3100 }
3101
3116 void
3117 dbus_message_set_auto_start (DBusMessage *message,
3118 dbus_bool_t auto_start)
3119 {
3120 _dbus_return_if_fail (message != NULL);
3121 _dbus_return_if_fail (!message->locked);
3122
3123 _dbus_header_toggle_flag (&message->header,
3124 DBUS_HEADER_FLAG_NO_AUTO_START,
3125 !auto_start);
3126 }
3127
3135 dbus_bool_t
3136 dbus_message_get_auto_start (DBusMessage *message)
3137 {
3138 _dbus_return_val_if_fail (message != NULL, FALSE);
3139
3140 return !_dbus_header_get_flag (&message->header,
3141 DBUS_HEADER_FLAG_NO_AUTO_START);
3142 }
3143
3144
3157 dbus_bool_t
3158 dbus_message_set_path (DBusMessage *message,
3159 const char *object_path)
3160 {
3161 _dbus_return_val_if_fail (message != NULL, FALSE);
3162 _dbus_return_val_if_fail (!message->locked, FALSE);
3163 _dbus_return_val_if_fail (object_path == NULL ||
3164 _dbus_check_is_valid_path (object_path),
3165 FALSE);
3166
3167 return set_or_delete_string_field (message,
3168 DBUS_HEADER_FIELD_PATH,
3169 DBUS_TYPE_OBJECT_PATH,
3170 object_path);
3171 }
3172
3186 const char*
3187 dbus_message_get_path (DBusMessage *message)
3188 {
3189 const char *v;
3190
3191 _dbus_return_val_if_fail (message != NULL, NULL);
3192
3193 v = NULL; /* in case field doesn't exist */
3194 _dbus_header_get_field_basic (&message->header,
3195 DBUS_HEADER_FIELD_PATH,
3196 DBUS_TYPE_OBJECT_PATH,
3197 (void *) &v);
3198 return v;
3199 }
3200
3210 dbus_bool_t
3211 dbus_message_has_path (DBusMessage *message,
3212 const char *path)
3213 {
3214 const char *msg_path;
3215 msg_path = dbus_message_get_path (message);
3216
3217 if (msg_path == NULL)
3218 {
3219 if (path == NULL)
3220 return TRUE;
3221 else
3222 return FALSE;
3223 }
3224
3225 if (path == NULL)
3226 return FALSE;
3227
3228 if (strcmp (msg_path, path) == 0)
3229 return TRUE;
3230
3231 return FALSE;
3232 }
3233
3254 dbus_bool_t
3255 dbus_message_get_path_decomposed (DBusMessage *message,
3256 char ***path)
3257 {
3258 const char *v;
3259
3260 _dbus_return_val_if_fail (message != NULL, FALSE);
3261 _dbus_return_val_if_fail (path != NULL, FALSE);
3262
3263 *path = NULL;
3264
3265 v = dbus_message_get_path (message);
3266 if (v != NULL)
3267 {
3268 if (!_dbus_decompose_path (v, strlen (v),
3269 path, NULL))
3270 return FALSE;
3271 }
3272 return TRUE;
3273 }
3274
3288 dbus_bool_t
3289 dbus_message_set_interface (DBusMessage *message,
3290 const char *iface)
3291 {
3292 _dbus_return_val_if_fail (message != NULL, FALSE);
3293 _dbus_return_val_if_fail (!message->locked, FALSE);
3294 _dbus_return_val_if_fail (iface == NULL ||
3295 _dbus_check_is_valid_interface (iface),
3296 FALSE);
3297
3298 return set_or_delete_string_field (message,
3299 DBUS_HEADER_FIELD_INTERFACE,
3300 DBUS_TYPE_STRING,
3301 iface);
3302 }
3303
3317 const char*
3318 dbus_message_get_interface (DBusMessage *message)
3319 {
3320 const char *v;
3321
3322 _dbus_return_val_if_fail (message != NULL, NULL);
3323
3324 v = NULL; /* in case field doesn't exist */
3325 _dbus_header_get_field_basic (&message->header,
3326 DBUS_HEADER_FIELD_INTERFACE,
3327 DBUS_TYPE_STRING,
3328 (void *) &v);
3329 return v;
3330 }
3331
3339 dbus_bool_t
3340 dbus_message_has_interface (DBusMessage *message,
3341 const char *iface)
3342 {
3343 const char *msg_interface;
3344 msg_interface = dbus_message_get_interface (message);
3345
3346 if (msg_interface == NULL)
3347 {
3348 if (iface == NULL)
3349 return TRUE;
3350 else
3351 return FALSE;
3352 }
3353
3354 if (iface == NULL)
3355 return FALSE;
3356
3357 if (strcmp (msg_interface, iface) == 0)
3358 return TRUE;
3359
3360 return FALSE;
3361
3362 }
3363
3376 dbus_bool_t
3377 dbus_message_set_member (DBusMessage *message,
3378 const char *member)
3379 {
3380 _dbus_return_val_if_fail (message != NULL, FALSE);
3381 _dbus_return_val_if_fail (!message->locked, FALSE);
3382 _dbus_return_val_if_fail (member == NULL ||
3383 _dbus_check_is_valid_member (member),
3384 FALSE);
3385
3386 return set_or_delete_string_field (message,
3387 DBUS_HEADER_FIELD_MEMBER,
3388 DBUS_TYPE_STRING,
3389 member);
3390 }
3391
3403 const char*
3404 dbus_message_get_member (DBusMessage *message)
3405 {
3406 const char *v;
3407
3408 _dbus_return_val_if_fail (message != NULL, NULL);
3409
3410 v = NULL; /* in case field doesn't exist */
3411 _dbus_header_get_field_basic (&message->header,
3412 DBUS_HEADER_FIELD_MEMBER,
3413 DBUS_TYPE_STRING,
3414 (void *) &v);
3415 return v;
3416 }
3417
3425 dbus_bool_t
3426 dbus_message_has_member (DBusMessage *message,
3427 const char *member)
3428 {
3429 const char *msg_member;
3430 msg_member = dbus_message_get_member (message);
3431
3432 if (msg_member == NULL)
3433 {
3434 if (member == NULL)
3435 return TRUE;
3436 else
3437 return FALSE;
3438 }
3439
3440 if (member == NULL)
3441 return FALSE;
3442
3443 if (strcmp (msg_member, member) == 0)
3444 return TRUE;
3445
3446 return FALSE;
3447
3448 }
3449
3461 dbus_bool_t
3462 dbus_message_set_error_name (DBusMessage *message,
3463 const char *error_name)
3464 {
3465 _dbus_return_val_if_fail (message != NULL, FALSE);
3466 _dbus_return_val_if_fail (!message->locked, FALSE);
3467 _dbus_return_val_if_fail (error_name == NULL ||
3468 _dbus_check_is_valid_error_name (error_name),
3469 FALSE);
3470
3471 return set_or_delete_string_field (message,
3472 DBUS_HEADER_FIELD_ERROR_NAME,
3473 DBUS_TYPE_STRING,
3474 error_name);
3475 }
3476
3487 const char*
3488 dbus_message_get_error_name (DBusMessage *message)
3489 {
3490 const char *v;
3491
3492 _dbus_return_val_if_fail (message != NULL, NULL);
3493
3494 v = NULL; /* in case field doesn't exist */
3495 _dbus_header_get_field_basic (&message->header,
3496 DBUS_HEADER_FIELD_ERROR_NAME,
3497 DBUS_TYPE_STRING,
3498 (void *) &v);
3499 return v;
3500 }
3501
3515 dbus_bool_t
3516 dbus_message_set_destination (DBusMessage *message,
3517 const char *destination)
3518 {
3519 _dbus_return_val_if_fail (message != NULL, FALSE);
3520 _dbus_return_val_if_fail (!message->locked, FALSE);
3521 _dbus_return_val_if_fail (destination == NULL ||
3522 _dbus_check_is_valid_bus_name (destination),
3523 FALSE);
3524
3525 return set_or_delete_string_field (message,
3526 DBUS_HEADER_FIELD_DESTINATION,
3527 DBUS_TYPE_STRING,
3528 destination);
3529 }
3530
3540 const char*
3541 dbus_message_get_destination (DBusMessage *message)
3542 {
3543 const char *v;
3544
3545 _dbus_return_val_if_fail (message != NULL, NULL);
3546
3547 v = NULL; /* in case field doesn't exist */
3548 _dbus_header_get_field_basic (&message->header,
3549 DBUS_HEADER_FIELD_DESTINATION,
3550 DBUS_TYPE_STRING,
3551 (void *) &v);
3552 return v;
3553 }
3554
3569 dbus_bool_t
3570 dbus_message_set_sender (DBusMessage *message,
3571 const char *sender)
3572 {
3573 _dbus_return_val_if_fail (message != NULL, FALSE);
3574 _dbus_return_val_if_fail (!message->locked, FALSE);
3575 _dbus_return_val_if_fail (sender == NULL ||
3576 _dbus_check_is_valid_bus_name (sender),
3577 FALSE);
3578
3579 return set_or_delete_string_field (message,
3580 DBUS_HEADER_FIELD_SENDER,
3581 DBUS_TYPE_STRING,
3582 sender);
3583 }
3584
3600 const char*
3601 dbus_message_get_sender (DBusMessage *message)
3602 {
3603 const char *v;
3604
3605 _dbus_return_val_if_fail (message != NULL, NULL);
3606
3607 v = NULL; /* in case field doesn't exist */
3608 _dbus_header_get_field_basic (&message->header,
3609 DBUS_HEADER_FIELD_SENDER,
3610 DBUS_TYPE_STRING,
3611 (void *) &v);
3612 return v;
3613 }
3614
3633 const char*
3634 dbus_message_get_signature (DBusMessage *message)
3635 {
3636 const DBusString *type_str;
3637 int type_pos;
3638
3639 _dbus_return_val_if_fail (message != NULL, NULL);
3640
3641 get_const_signature (&message->header, &type_str, &type_pos);
3642
3643 return _dbus_string_get_const_data_len (type_str, type_pos, 0);
3644 }
3645
3646 static dbus_bool_t
3647 _dbus_message_has_type_interface_member (DBusMessage *message,
3648 int type,
3649 const char *iface,
3650 const char *member)
3651 {
3652 const char *n;
3653
3654 _dbus_assert (message != NULL);
3655 _dbus_assert (iface != NULL);
3656 _dbus_assert (member != NULL);
3657
3658 if (dbus_message_get_type (message) != type)
3659 return FALSE;
3660
3661 /* Optimize by checking the short member name first
3662 * instead of the longer interface name
3663 */
3664
3665 n = dbus_message_get_member (message);
3666
3667 if (n && strcmp (n, member) == 0)
3668 {
3669 n = dbus_message_get_interface (message);
3670
3671 if (n == NULL || strcmp (n, iface) == 0)
3672 return TRUE;
3673 }
3674
3675 return FALSE;
3676 }
3677
3692 dbus_bool_t
3693 dbus_message_is_method_call (DBusMessage *message,
3694 const char *iface,
3695 const char *method)
3696 {
3697 _dbus_return_val_if_fail (message != NULL, FALSE);
3698 _dbus_return_val_if_fail (iface != NULL, FALSE);
3699 _dbus_return_val_if_fail (method != NULL, FALSE);
3700 /* don't check that interface/method are valid since it would be
3701 * expensive, and not catch many common errors
3702 */
3703
3704 return _dbus_message_has_type_interface_member (message,
3705 DBUS_MESSAGE_TYPE_METHOD_CALL,
3706 iface, method);
3707 }
3708
3720 dbus_bool_t
3721 dbus_message_is_signal (DBusMessage *message,
3722 const char *iface,
3723 const char *signal_name)
3724 {
3725 _dbus_return_val_if_fail (message != NULL, FALSE);
3726 _dbus_return_val_if_fail (iface != NULL, FALSE);
3727 _dbus_return_val_if_fail (signal_name != NULL, FALSE);
3728 /* don't check that interface/name are valid since it would be
3729 * expensive, and not catch many common errors
3730 */
3731
3732 return _dbus_message_has_type_interface_member (message,
3733 DBUS_MESSAGE_TYPE_SIGNAL,
3734 iface, signal_name);
3735 }
3736
3747 dbus_bool_t
3748 dbus_message_is_error (DBusMessage *message,
3749 const char *error_name)
3750 {
3751 const char *n;
3752
3753 _dbus_return_val_if_fail (message != NULL, FALSE);
3754 _dbus_return_val_if_fail (error_name != NULL, FALSE);
3755 /* don't check that error_name is valid since it would be expensive,
3756 * and not catch many common errors
3757 */
3758
3759 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
3760 return FALSE;
3761
3762 n = dbus_message_get_error_name (message);
3763
3764 if (n && strcmp (n, error_name) == 0)
3765 return TRUE;
3766 else
3767 return FALSE;
3768 }
3769
3780 dbus_bool_t
3781 dbus_message_has_destination (DBusMessage *message,
3782 const char *name)
3783 {
3784 const char *s;
3785
3786 _dbus_return_val_if_fail (message != NULL, FALSE);
3787 _dbus_return_val_if_fail (name != NULL, FALSE);
3788 /* don't check that name is valid since it would be expensive, and
3789 * not catch many common errors
3790 */
3791
3792 s = dbus_message_get_destination (message);
3793
3794 if (s && strcmp (s, name) == 0)
3795 return TRUE;
3796 else
3797 return FALSE;
3798 }
3799
3815 dbus_bool_t
3816 dbus_message_has_sender (DBusMessage *message,
3817 const char *name)
3818 {
3819 const char *s;
3820
3821 _dbus_return_val_if_fail (message != NULL, FALSE);
3822 _dbus_return_val_if_fail (name != NULL, FALSE);
3823 /* don't check that name is valid since it would be expensive, and
3824 * not catch many common errors
3825 */
3826
3827 s = dbus_message_get_sender (message);
3828
3829 if (s && strcmp (s, name) == 0)
3830 return TRUE;
3831 else
3832 return FALSE;
3833 }
3834
3844 dbus_bool_t
3845 dbus_message_has_signature (DBusMessage *message,
3846 const char *signature)
3847 {
3848 const char *s;
3849
3850 _dbus_return_val_if_fail (message != NULL, FALSE);
3851 _dbus_return_val_if_fail (signature != NULL, FALSE);
3852 /* don't check that signature is valid since it would be expensive,
3853 * and not catch many common errors
3854 */
3855
3856 s = dbus_message_get_signature (message);
3857
3858 if (s && strcmp (s, signature) == 0)
3859 return TRUE;
3860 else
3861 return FALSE;
3862 }
3863
3886 dbus_bool_t
3887 dbus_set_error_from_message (DBusError *error,
3888 DBusMessage *message)
3889 {
3890 const char *str;
3891
3892 _dbus_return_val_if_fail (message != NULL, FALSE);
3893 _dbus_return_val_if_error_is_set (error, FALSE);
3894
3895 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
3896 return FALSE;
3897
3898 str = NULL;
3899 dbus_message_get_args (message, NULL,
3900 DBUS_TYPE_STRING, &str,
3901 DBUS_TYPE_INVALID);
3902
3903 dbus_set_error (error, dbus_message_get_error_name (message),
3904 str ? "%s" : NULL, str);
3905
3906 return TRUE;
3907 }
3908
3915 dbus_bool_t
3916 dbus_message_contains_unix_fds(DBusMessage *message)
3917 {
3918 #ifdef HAVE_UNIX_FD_PASSING
3919 _dbus_assert(message);
3920
3921 return message->n_unix_fds > 0;
3922 #else
3923 return FALSE;
3924 #endif
3925 }
3926
3945 #define INITIAL_LOADER_DATA_LEN 32
3946
3953 DBusMessageLoader*
3954 _dbus_message_loader_new (void)
3955 {
3956 DBusMessageLoader *loader;
3957
3958 loader = dbus_new0 (DBusMessageLoader, 1);
3959 if (loader == NULL)
3960 return NULL;
3961
3962 loader->refcount = 1;
3963
3964 loader->corrupted = FALSE;
3965 loader->corruption_reason = DBUS_VALID;
3966
3967 /* this can be configured by the app, but defaults to the protocol max */
3968 loader->max_message_size = DBUS_MAXIMUM_MESSAGE_LENGTH;
3969
3970 /* We set a very relatively conservative default here since due to how
3971 SCM_RIGHTS works we need to preallocate an fd array of the maximum
3972 number of unix fds we want to receive in advance. A
3973 try-and-reallocate loop is not possible. */
3974 loader->max_message_unix_fds = DBUS_DEFAULT_MESSAGE_UNIX_FDS;
3975
3976 if (!_dbus_string_init (&loader->data))
3977 {
3978 dbus_free (loader);
3979 return NULL;
3980 }
3981
3982 /* preallocate the buffer for speed, ignore failure */
3983 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
3984 _dbus_string_set_length (&loader->data, 0);
3985
3986 #ifdef HAVE_UNIX_FD_PASSING
3987 loader->unix_fds = NULL;
3988 loader->n_unix_fds = loader->n_unix_fds_allocated = 0;
3989 loader->unix_fds_outstanding = FALSE;
3990 #endif
3991
3992 return loader;
3993 }
3994
4001 DBusMessageLoader *
4002 _dbus_message_loader_ref (DBusMessageLoader *loader)
4003 {
4004 loader->refcount += 1;
4005
4006 return loader;
4007 }
4008
4015 void
4016 _dbus_message_loader_unref (DBusMessageLoader *loader)
4017 {
4018 loader->refcount -= 1;
4019 if (loader->refcount == 0)
4020 {
4021 #ifdef HAVE_UNIX_FD_PASSING
4022 close_unix_fds(loader->unix_fds, &loader->n_unix_fds);
4023 dbus_free(loader->unix_fds);
4024 #endif
4025 _dbus_list_foreach (&loader->messages,
4026 (DBusForeachFunction) dbus_message_unref,
4027 NULL);
4028 _dbus_list_clear (&loader->messages);
4029 _dbus_string_free (&loader->data);
4030 dbus_free (loader);
4031 }
4032 }
4033
4052 void
4053 _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
4054 DBusString **buffer)
4055 {
4056 _dbus_assert (!loader->buffer_outstanding);
4057
4058 *buffer = &loader->data;
4059
4060 loader->buffer_outstanding = TRUE;
4061 }
4062
4072 void
4073 _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
4074 DBusString *buffer)
4075 {
4076 _dbus_assert (loader->buffer_outstanding);
4077 _dbus_assert (buffer == &loader->data);
4078
4079 loader->buffer_outstanding = FALSE;
4080 }
4081
4092 dbus_bool_t
4093 _dbus_message_loader_get_unix_fds(DBusMessageLoader *loader,
4094 int **fds,
4095 unsigned *max_n_fds)
4096 {
4097 #ifdef HAVE_UNIX_FD_PASSING
4098 _dbus_assert (!loader->unix_fds_outstanding);
4099
4100 /* Allocate space where we can put the fds we read. We allocate
4101 space for max_message_unix_fds since this is an
4102 upper limit how many fds can be received within a single
4103 message. Since SCM_RIGHTS doesn't allow a reallocate+retry logic
4104 we are allocating the maximum possible array size right from the
4105 beginning. This sucks a bit, however unless SCM_RIGHTS is fixed
4106 there is no better way. */
4107
4108 if (loader->n_unix_fds_allocated < loader->max_message_unix_fds)
4109 {
4110 int *a = dbus_realloc(loader->unix_fds,
4111 loader->max_message_unix_fds * sizeof(loader->unix_fds[0]));
4112
4113 if (!a)
4114 return FALSE;
4115
4116 loader->unix_fds = a;
4117 loader->n_unix_fds_allocated = loader->max_message_unix_fds;
4118 }
4119
4120 *fds = loader->unix_fds + loader->n_unix_fds;
4121 *max_n_fds = loader->n_unix_fds_allocated - loader->n_unix_fds;
4122
4123 loader->unix_fds_outstanding = TRUE;
4124 return TRUE;
4125 #else
4126 _dbus_assert_not_reached("Platform doesn't support unix fd passing");
4127 return FALSE;
4128 #endif
4129 }
4130
4141 void
4142 _dbus_message_loader_return_unix_fds(DBusMessageLoader *loader,
4143 int *fds,
4144 unsigned n_fds)
4145 {
4146 #ifdef HAVE_UNIX_FD_PASSING
4147 _dbus_assert(loader->unix_fds_outstanding);
4148 _dbus_assert(loader->unix_fds + loader->n_unix_fds == fds);
4149 _dbus_assert(loader->n_unix_fds + n_fds <= loader->n_unix_fds_allocated);
4150
4151 loader->n_unix_fds += n_fds;
4152 loader->unix_fds_outstanding = FALSE;
4153
4154 if (n_fds && loader->unix_fds_change)
4155 loader->unix_fds_change (loader->unix_fds_change_data);
4156 #else
4157 _dbus_assert_not_reached("Platform doesn't support unix fd passing");
4158 #endif
4159 }
4160
4161 /*
4162 * FIXME when we move the header out of the buffer, that memmoves all
4163 * buffered messages. Kind of crappy.
4164 *
4165 * Also we copy the header and body, which is kind of crappy. To
4166 * avoid this, we have to allow header and body to be in a single
4167 * memory block, which is good for messages we read and bad for
4168 * messages we are creating. But we could move_len() the buffer into
4169 * this single memory block, and move_len() will just swap the buffers
4170 * if you're moving the entire buffer replacing the dest string.
4171 *
4172 * We could also have the message loader tell the transport how many
4173 * bytes to read; so it would first ask for some arbitrary number like
4174 * 256, then if the message was incomplete it would use the
4175 * header/body len to ask for exactly the size of the message (or
4176 * blocks the size of a typical kernel buffer for the socket). That
4177 * way we don't get trailing bytes in the buffer that have to be
4178 * memmoved. Though I suppose we also don't have a chance of reading a
4179 * bunch of small messages at once, so the optimization may be stupid.
4180 *
4181 * Another approach would be to keep a "start" index into
4182 * loader->data and only delete it occasionally, instead of after
4183 * each message is loaded.
4184 *
4185 * load_message() returns FALSE if not enough memory OR the loader was corrupted
4186 */
4187 static dbus_bool_t
4188 load_message (DBusMessageLoader *loader,
4189 DBusMessage *message,
4190 int byte_order,
4191 int fields_array_len,
4192 int header_len,
4193 int body_len)
4194 {
4195 dbus_bool_t oom;
4196 DBusValidity validity;
4197 const DBusString *type_str;
4198 int type_pos;
4199 DBusValidationMode mode;
4200 dbus_uint32_t n_unix_fds = 0;
4201
4202 mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
4203
4204 oom = FALSE;
4205
4206 #if 0
4207 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len /* + body_len */);
4208 #endif
4209
4210 /* 1. VALIDATE AND COPY OVER HEADER */
4211 _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
4212 _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
4213
4214 if (!_dbus_header_load (&message->header,
4215 mode,
4216 &validity,
4217 byte_order,
4218 fields_array_len,
4219 header_len,
4220 body_len,
4221 &loader->data, 0,
4222 _dbus_string_get_length (&loader->data)))
4223 {
4224 _dbus_verbose ("Failed to load header for new message code %d\n", validity);
4225
4226 /* assert here so we can catch any code that still uses DBUS_VALID to indicate
4227 oom errors. They should use DBUS_VALIDITY_UNKNOWN_OOM_ERROR instead */
4228 _dbus_assert (validity != DBUS_VALID);
4229
4230 if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
4231 oom = TRUE;
4232 else
4233 {
4234 loader->corrupted = TRUE;
4235 loader->corruption_reason = validity;
4236 }
4237 goto failed;
4238 }
4239
4240 _dbus_assert (validity == DBUS_VALID);
4241
4242 /* 2. VALIDATE BODY */
4243 if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
4244 {
4245 get_const_signature (&message->header, &type_str, &type_pos);
4246
4247 /* Because the bytes_remaining arg is NULL, this validates that the
4248 * body is the right length
4249 */
4250 validity = _dbus_validate_body_with_reason (type_str,
4251 type_pos,
4252 byte_order,
4253 NULL,
4254 &loader->data,
4255 header_len,
4256 body_len);
4257 if (validity != DBUS_VALID)
4258 {
4259 _dbus_verbose ("Failed to validate message body code %d\n", validity);
4260
4261 loader->corrupted = TRUE;
4262 loader->corruption_reason = validity;
4263
4264 goto failed;
4265 }
4266 }
4267
4268 /* 3. COPY OVER UNIX FDS */
4269 _dbus_header_get_field_basic(&message->header,
4270 DBUS_HEADER_FIELD_UNIX_FDS,
4271 DBUS_TYPE_UINT32,
4272 &n_unix_fds);
4273
4274 #ifdef HAVE_UNIX_FD_PASSING
4275
4276 if (n_unix_fds > loader->n_unix_fds)
4277 {
4278 _dbus_verbose("Message contains references to more unix fds than were sent %u != %u\n",
4279 n_unix_fds, loader->n_unix_fds);
4280
4281 loader->corrupted = TRUE;
4282 loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4283 goto failed;
4284 }
4285
4286 /* If this was a recycled message there might still be
4287 some memory allocated for the fds */
4288 dbus_free(message->unix_fds);
4289
4290 if (n_unix_fds > 0)
4291 {
4292 message->unix_fds = _dbus_memdup(loader->unix_fds, n_unix_fds * sizeof(message->unix_fds[0]));
4293 if (message->unix_fds == NULL)
4294 {
4295 _dbus_verbose ("Failed to allocate file descriptor array\n");
4296 oom = TRUE;
4297 goto failed;
4298 }
4299
4300 message->n_unix_fds_allocated = message->n_unix_fds = n_unix_fds;
4301 loader->n_unix_fds -= n_unix_fds;
4302 memmove (loader->unix_fds, loader->unix_fds + n_unix_fds, loader->n_unix_fds * sizeof (loader->unix_fds[0]));
4303
4304 if (loader->unix_fds_change)
4305 loader->unix_fds_change (loader->unix_fds_change_data);
4306 }
4307 else
4308 message->unix_fds = NULL;
4309
4310 #else
4311
4312 if (n_unix_fds > 0)
4313 {
4314 _dbus_verbose ("Hmm, message claims to come with file descriptors "
4315 "but that's not supported on our platform, disconnecting.\n");
4316
4317 loader->corrupted = TRUE;
4318 loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4319 goto failed;
4320 }
4321
4322 #endif
4323
4324 /* 3. COPY OVER BODY AND QUEUE MESSAGE */
4325
4326 if (!_dbus_list_append (&loader->messages, message))
4327 {
4328 _dbus_verbose ("Failed to append new message to loader queue\n");
4329 oom = TRUE;
4330 goto failed;
4331 }
4332
4333 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
4334 _dbus_assert (_dbus_string_get_length (&loader->data) >=
4335 (header_len + body_len));
4336
4337 if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
4338 {
4339 _dbus_verbose ("Failed to move body into new message\n");
4340 oom = TRUE;
4341 goto failed;
4342 }
4343
4344 _dbus_string_delete (&loader->data, 0, header_len + body_len);
4345
4346 /* don't waste more than 2k of memory */
4347 _dbus_string_compact (&loader->data, 2048);
4348
4349 _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
4350 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
4351
4352 _dbus_verbose ("Loaded message %p\n", message);
4353
4354 _dbus_assert (!oom);
4355 _dbus_assert (!loader->corrupted);
4356 _dbus_assert (loader->messages != NULL);
4357 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4358
4359 return TRUE;
4360
4361 failed:
4362
4363 /* Clean up */
4364
4365 /* does nothing if the message isn't in the list */
4366 _dbus_list_remove_last (&loader->messages, message);
4367
4368 if (oom)
4369 _dbus_assert (!loader->corrupted);
4370 else
4371 _dbus_assert (loader->corrupted);
4372
4373 _dbus_verbose_bytes_of_string (&loader->data, 0, _dbus_string_get_length (&loader->data));
4374
4375 return FALSE;
4376 }
4377
4392 dbus_bool_t
4393 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
4394 {
4395 while (!loader->corrupted &&
4396 _dbus_string_get_length (&loader->data) >= DBUS_MINIMUM_HEADER_SIZE)
4397 {
4398 DBusValidity validity;
4399 int byte_order, fields_array_len, header_len, body_len;
4400
4401 if (_dbus_header_have_message_untrusted (loader->max_message_size,
4402 &validity,
4403 &byte_order,
4404 &fields_array_len,
4405 &header_len,
4406 &body_len,
4407 &loader->data, 0,
4408 _dbus_string_get_length (&loader->data)))
4409 {
4410 DBusMessage *message;
4411
4412 _dbus_assert (validity == DBUS_VALID);
4413
4414 message = dbus_message_new_empty_header ();
4415 if (message == NULL)
4416 return FALSE;
4417
4418 if (!load_message (loader, message,
4419 byte_order, fields_array_len,
4420 header_len, body_len))
4421 {
4422 dbus_message_unref (message);
4423 /* load_message() returns false if corrupted or OOM; if
4424 * corrupted then return TRUE for not OOM
4425 */
4426 return loader->corrupted;
4427 }
4428
4429 _dbus_assert (loader->messages != NULL);
4430 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4431 }
4432 else
4433 {
4434 _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
4435 validity);
4436 if (validity != DBUS_VALID)
4437 {
4438 loader->corrupted = TRUE;
4439 loader->corruption_reason = validity;
4440 }
4441 return TRUE;
4442 }
4443 }
4444
4445 return TRUE;
4446 }
4447
4455 DBusMessage*
4456 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
4457 {
4458 if (loader->messages)
4459 return loader->messages->data;
4460 else
4461 return NULL;
4462 }
4463
4472 DBusMessage*
4473 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
4474 {
4475 return _dbus_list_pop_first (&loader->messages);
4476 }
4477
4486 DBusList*
4487 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
4488 {
4489 return _dbus_list_pop_first_link (&loader->messages);
4490 }
4491
4498 void
4499 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
4500 DBusList *link)
4501 {
4502 _dbus_list_prepend_link (&loader->messages, link);
4503 }
4504
4514 dbus_bool_t
4515 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
4516 {
4517 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
4518 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
4519 return loader->corrupted;
4520 }
4521
4528 DBusValidity
4529 _dbus_message_loader_get_corruption_reason (DBusMessageLoader *loader)
4530 {
4531 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
4532 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
4533
4534 return loader->corruption_reason;
4535 }
4536
4543 void
4544 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
4545 long size)
4546 {
4547 if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
4548 {
4549 _dbus_verbose ("clamping requested max message size %ld to %d\n",
4550 size, DBUS_MAXIMUM_MESSAGE_LENGTH);
4551 size = DBUS_MAXIMUM_MESSAGE_LENGTH;
4552 }
4553 loader->max_message_size = size;
4554 }
4555
4562 long
4563 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
4564 {
4565 return loader->max_message_size;
4566 }
4567
4574 void
4575 _dbus_message_loader_set_max_message_unix_fds (DBusMessageLoader *loader,
4576 long n)
4577 {
4578 if (n > DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
4579 {
4580 _dbus_verbose ("clamping requested max message unix_fds %ld to %d\n",
4581 n, DBUS_MAXIMUM_MESSAGE_UNIX_FDS);
4582 n = DBUS_MAXIMUM_MESSAGE_UNIX_FDS;
4583 }
4584 loader->max_message_unix_fds = n;
4585 }
4586
4593 long
4594 _dbus_message_loader_get_max_message_unix_fds (DBusMessageLoader *loader)
4595 {
4596 return loader->max_message_unix_fds;
4597 }
4598
4604 int
4605 _dbus_message_loader_get_pending_fds_count (DBusMessageLoader *loader)
4606 {
4607 #ifdef HAVE_UNIX_FD_PASSING
4608 return loader->n_unix_fds;
4609 #else
4610 return 0;
4611 #endif
4612 }
4613
4622 void
4623 _dbus_message_loader_set_pending_fds_function (DBusMessageLoader *loader,
4624 void (* callback) (void *),
4625 void *data)
4626 {
4627 #ifdef HAVE_UNIX_FD_PASSING
4628 loader->unix_fds_change = callback;
4629 loader->unix_fds_change_data = data;
4630 #endif
4631 }
4632
4633 static DBusDataSlotAllocator slot_allocator =
4634 _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (message_slots));
4635
4650 dbus_bool_t
4651 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
4652 {
4653 return _dbus_data_slot_allocator_alloc (&slot_allocator,
4654 slot_p);
4655 }
4656
4668 void
4669 dbus_message_free_data_slot (dbus_int32_t *slot_p)
4670 {
4671 _dbus_return_if_fail (*slot_p >= 0);
4672
4673 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
4674 }
4675
4689 dbus_bool_t
4690 dbus_message_set_data (DBusMessage *message,
4691 dbus_int32_t slot,
4692 void *data,
4693 DBusFreeFunction free_data_func)
4694 {
4695 DBusFreeFunction old_free_func;
4696 void *old_data;
4697 dbus_bool_t retval;
4698
4699 _dbus_return_val_if_fail (message != NULL, FALSE);
4700 _dbus_return_val_if_fail (slot >= 0, FALSE);
4701
4702 retval = _dbus_data_slot_list_set (&slot_allocator,
4703 &message->slot_list,
4704 slot, data, free_data_func,
4705 &old_free_func, &old_data);
4706
4707 if (retval)
4708 {
4709 /* Do the actual free outside the message lock */
4710 if (old_free_func)
4711 (* old_free_func) (old_data);
4712 }
4713
4714 return retval;
4715 }
4716
4725 void*
4726 dbus_message_get_data (DBusMessage *message,
4727 dbus_int32_t slot)
4728 {
4729 void *res;
4730
4731 _dbus_return_val_if_fail (message != NULL, NULL);
4732
4733 res = _dbus_data_slot_list_get (&slot_allocator,
4734 &message->slot_list,
4735 slot);
4736
4737 return res;
4738 }
4739
4753 int
4754 dbus_message_type_from_string (const char *type_str)
4755 {
4756 if (strcmp (type_str, "method_call") == 0)
4757 return DBUS_MESSAGE_TYPE_METHOD_CALL;
4758 if (strcmp (type_str, "method_return") == 0)
4759 return DBUS_MESSAGE_TYPE_METHOD_RETURN;
4760 else if (strcmp (type_str, "signal") == 0)
4761 return DBUS_MESSAGE_TYPE_SIGNAL;
4762 else if (strcmp (type_str, "error") == 0)
4763 return DBUS_MESSAGE_TYPE_ERROR;
4764 else
4765 return DBUS_MESSAGE_TYPE_INVALID;
4766 }
4767
4781 const char *
4782 dbus_message_type_to_string (int type)
4783 {
4784 switch (type)
4785 {
4786 case DBUS_MESSAGE_TYPE_METHOD_CALL:
4787 return "method_call";
4788 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
4789 return "method_return";
4790 case DBUS_MESSAGE_TYPE_SIGNAL:
4791 return "signal";
4792 case DBUS_MESSAGE_TYPE_ERROR:
4793 return "error";
4794 default:
4795 return "invalid";
4796 }
4797 }
4798
4811 dbus_bool_t
4812 dbus_message_marshal (DBusMessage *msg,
4813 char **marshalled_data_p,
4814 int *len_p)
4815 {
4816 DBusString tmp;
4817 dbus_bool_t was_locked;
4818
4819 _dbus_return_val_if_fail (msg != NULL, FALSE);
4820 _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
4821 _dbus_return_val_if_fail (len_p != NULL, FALSE);
4822
4823 if (!_dbus_string_init (&tmp))
4824 return FALSE;
4825
4826 /* Ensure the message is locked, to ensure the length header is filled in. */
4827 was_locked = msg->locked;
4828
4829 if (!was_locked)
4830 dbus_message_lock (msg);
4831
4832 if (!_dbus_string_copy (&(msg->header.data), 0, &tmp, 0))
4833 goto fail;
4834
4835 *len_p = _dbus_string_get_length (&tmp);
4836
4837 if (!_dbus_string_copy (&(msg->body), 0, &tmp, *len_p))
4838 goto fail;
4839
4840 *len_p = _dbus_string_get_length (&tmp);
4841
4842 if (!_dbus_string_steal_data (&tmp, marshalled_data_p))
4843 goto fail;
4844
4845 _dbus_string_free (&tmp);
4846
4847 if (!was_locked)
4848 msg->locked = FALSE;
4849
4850 return TRUE;
4851
4852 fail:
4853 _dbus_string_free (&tmp);
4854
4855 if (!was_locked)
4856 msg->locked = FALSE;
4857
4858 return FALSE;
4859 }
4860
4873 DBusMessage *
4874 dbus_message_demarshal (const char *str,
4875 int len,
4876 DBusError *error)
4877 {
4878 DBusMessageLoader *loader;
4879 DBusString *buffer;
4880 DBusMessage *msg;
4881
4882 _dbus_return_val_if_fail (str != NULL, NULL);
4883
4884 loader = _dbus_message_loader_new ();
4885
4886 if (loader == NULL)
4887 return NULL;
4888
4889 _dbus_message_loader_get_buffer (loader, &buffer);
4890
4891 if (!_dbus_string_append_len (buffer, str, len))
4892 goto fail_oom;
4893
4894 _dbus_message_loader_return_buffer (loader, buffer);
4895
4896 if (!_dbus_message_loader_queue_messages (loader))
4897 goto fail_oom;
4898
4899 if (_dbus_message_loader_get_is_corrupted (loader))
4900 goto fail_corrupt;
4901
4902 msg = _dbus_message_loader_pop_message (loader);
4903
4904 if (!msg)
4905 goto fail_oom;
4906
4907 _dbus_message_loader_unref (loader);
4908 return msg;
4909
4910 fail_corrupt:
4911 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted (%s)",
4912 _dbus_validity_to_error_message (loader->corruption_reason));
4913 _dbus_message_loader_unref (loader);
4914 return NULL;
4915
4916 fail_oom:
4917 _DBUS_SET_OOM (error);
4918 _dbus_message_loader_unref (loader);
4919 return NULL;
4920 }
4921
4934 int
4935 dbus_message_demarshal_bytes_needed(const char *buf,
4936 int len)
4937 {
4938 DBusString str;
4939 int byte_order, fields_array_len, header_len, body_len;
4940 DBusValidity validity = DBUS_VALID;
4941 int have_message;
4942
4943 if (!buf || len < DBUS_MINIMUM_HEADER_SIZE)
4944 return 0;
4945
4946 if (len > DBUS_MAXIMUM_MESSAGE_LENGTH)
4947 len = DBUS_MAXIMUM_MESSAGE_LENGTH;
4948 _dbus_string_init_const_len (&str, buf, len);
4949
4950 validity = DBUS_VALID;
4951 have_message
4952 = _dbus_header_have_message_untrusted(DBUS_MAXIMUM_MESSAGE_LENGTH,
4953 &validity, &byte_order,
4954 &fields_array_len,
4955 &header_len,
4956 &body_len,
4957 &str, 0,
4958 len);
4959 _dbus_string_free (&str);
4960
4961 if (validity == DBUS_VALID)
4962 {
4963 _dbus_assert (have_message || (header_len + body_len) > len);
4964 (void) have_message; /* unused unless asserting */
4965 return header_len + body_len;
4966 }
4967 else
4968 {
4969 return -1; /* broken! */
4970 }
4971 }
4972
4994 void
4995 dbus_message_set_allow_interactive_authorization (DBusMessage *message,
4996 dbus_bool_t allow)
4997 {
4998 _dbus_return_if_fail (message != NULL);
4999 _dbus_return_if_fail (!message->locked);
5000
5001 _dbus_header_toggle_flag (&message->header,
5002 DBUS_HEADER_FLAG_ALLOW_INTERACTIVE_AUTHORIZATION,
5003 allow);
5004 }
5005
5012 dbus_bool_t
5013 dbus_message_get_allow_interactive_authorization (DBusMessage *message)
5014 {
5015 _dbus_return_val_if_fail (message != NULL, FALSE);
5016
5017 return _dbus_header_get_flag (&message->header,
5018 DBUS_HEADER_FLAG_ALLOW_INTERACTIVE_AUTHORIZATION);
5019 }
5020
5023 /* 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:4754
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:3211
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:3693
_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:4563
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:3075
_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:4499
_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:2181
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:4073
_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:4142
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:2237
_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:4473
_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:3289
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:4669
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:3488
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:3009
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:3748
_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:3601
_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:4651
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:3634
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:2499
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:3117
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:5013
_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:4016
_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:3340
_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:4529
_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:3187
_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:2137
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:3426
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:2106
_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:3541
_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:2875
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:3462
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:3404
_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:4544
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:3570
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:3721
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:4002
_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:3255
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:3158
_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:3954
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:2008
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:2380
_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:4623
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:3945
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:3845
_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:4515
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:3781
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:3136
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:4594
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:4812
_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:2200
_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:2037
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:3887
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:4874
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:2469
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:3318
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:3816
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:2156
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:2335
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:4726
_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:4487
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:3516
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:3094
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:4093
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:4053
_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:2933
_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:2734
_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:2424
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:4995
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:4456
_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:4935
_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:2262
_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:3042
_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:3916
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:4393
_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_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:4575
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:3377
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:4782
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:4690
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:4605
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