D-Bus: dbus-message.c Source File

D-Bus 1.14.10

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
48static void dbus_message_finalize (DBusMessage *message);
49
60#ifdef DBUS_ENABLE_EMBEDDED_TESTS
61static 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
92void
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 */
113enum {
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
162static void
163get_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
186static 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
230void
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
271dbus_bool_t
272_dbus_message_remove_unknown_fields (DBusMessage *message)
273{
274 return _dbus_header_remove_unknown_fields (&message->header);
275}
276
288void
289dbus_message_set_serial (DBusMessage *message,
290 dbus_uint32_t serial)
291{
292 _dbus_return_if_fail (message != NULL);
293 _dbus_return_if_fail (!message->locked);
294
295 _dbus_header_set_serial (&message->header, serial);
296}
297
314void
315_dbus_message_add_counter_link (DBusMessage *message,
316 DBusList *link)
317{
318 /* right now we don't recompute the delta when message
319 * size changes, and that's OK for current purposes
320 * I think, but could be important to change later.
321 * Do recompute it whenever there are no outstanding counters,
322 * since it's basically free.
323 */
324 if (message->counters == NULL)
325 {
326 message->size_counter_delta =
327 _dbus_string_get_length (&message->header.data) +
328 _dbus_string_get_length (&message->body);
329
330#ifdef HAVE_UNIX_FD_PASSING
331 message->unix_fd_counter_delta = message->n_unix_fds;
332#endif
333
334#if 0
335 _dbus_verbose ("message has size %ld\n",
336 message->size_counter_delta);
337#endif
338 }
339
340 _dbus_list_append_link (&message->counters, link);
341
342 _dbus_counter_adjust_size (link->data, message->size_counter_delta);
343
344#ifdef HAVE_UNIX_FD_PASSING
345 _dbus_counter_adjust_unix_fd (link->data, message->unix_fd_counter_delta);
346#endif
347}
348
363dbus_bool_t
364_dbus_message_add_counter (DBusMessage *message,
365 DBusCounter *counter)
366{
367 DBusList *link;
368
369 link = _dbus_list_alloc_link (counter);
370 if (link == NULL)
371 return FALSE;
372
373 _dbus_counter_ref (counter);
374 _dbus_message_add_counter_link (message, link);
375
376 return TRUE;
377}
378
386void
387_dbus_message_remove_counter (DBusMessage *message,
388 DBusCounter *counter)
389{
390 DBusList *link;
391
392 link = _dbus_list_find_last (&message->counters,
393 counter);
394 _dbus_assert (link != NULL);
395
396 _dbus_list_remove_link (&message->counters, link);
397
398 _dbus_counter_adjust_size (counter, - message->size_counter_delta);
399
400#ifdef HAVE_UNIX_FD_PASSING
401 _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
402#endif
403
404 _dbus_counter_notify (counter);
405 _dbus_counter_unref (counter);
406}
407
418void
419dbus_message_lock (DBusMessage *message)
420{
421 if (!message->locked)
422 {
423 _dbus_header_update_lengths (&message->header,
424 _dbus_string_get_length (&message->body));
425
426 /* must have a signature if you have a body */
427 _dbus_assert (_dbus_string_get_length (&message->body) == 0 ||
428 dbus_message_get_signature (message) != NULL);
429
430 message->locked = TRUE;
431 }
432}
433
434static dbus_bool_t
435set_or_delete_string_field (DBusMessage *message,
436 int field,
437 int typecode,
438 const char *value)
439{
440 if (value == NULL)
441 return _dbus_header_delete_field (&message->header, field);
442 else
443 return _dbus_header_set_field_basic (&message->header,
444 field,
445 typecode,
446 &value);
447}
448
449/* Message Cache
450 *
451 * We cache some DBusMessage to reduce the overhead of allocating
452 * them. In my profiling this consistently made about an 8%
453 * difference. It avoids the malloc for the message, the malloc for
454 * the slot list, the malloc for the header string and body string,
455 * and the associated free() calls. It does introduce another global
456 * lock which could be a performance issue in certain cases.
457 *
458 * For the echo client/server the round trip time goes from around
459 * .000077 to .000069 with the message cache on my laptop. The sysprof
460 * change is as follows (numbers are cumulative percentage):
461 *
462 * with message cache implemented as array as it is now (0.000069 per):
463 * new_empty_header 1.46
464 * mutex_lock 0.56 # i.e. _DBUS_LOCK(message_cache)
465 * mutex_unlock 0.25
466 * self 0.41
467 * unref 2.24
468 * self 0.68
469 * list_clear 0.43
470 * mutex_lock 0.33 # i.e. _DBUS_LOCK(message_cache)
471 * mutex_unlock 0.25
472 *
473 * with message cache implemented as list (0.000070 per roundtrip):
474 * new_empty_header 2.72
475 * list_pop_first 1.88
476 * unref 3.3
477 * list_prepend 1.63
478 *
479 * without cache (0.000077 per roundtrip):
480 * new_empty_header 6.7
481 * string_init_preallocated 3.43
482 * dbus_malloc 2.43
483 * dbus_malloc0 2.59
484 *
485 * unref 4.02
486 * string_free 1.82
487 * dbus_free 1.63
488 * dbus_free 0.71
489 *
490 * If you implement the message_cache with a list, the primary reason
491 * it's slower is that you add another thread lock (on the DBusList
492 * mempool).
493 */
494
496#define MAX_MESSAGE_SIZE_TO_CACHE 10 * _DBUS_ONE_KILOBYTE
497
499#define MAX_MESSAGE_CACHE_SIZE 5
500
501/* Protected by _DBUS_LOCK (message_cache) */
502static DBusMessage *message_cache[MAX_MESSAGE_CACHE_SIZE];
503static int message_cache_count = 0;
504static dbus_bool_t message_cache_shutdown_registered = FALSE;
505
506static void
507dbus_message_cache_shutdown (void *data)
508{
509 int i;
510
511 if (!_DBUS_LOCK (message_cache))
512 _dbus_assert_not_reached ("we would have initialized global locks "
513 "before registering a shutdown function");
514
515 i = 0;
516 while (i < MAX_MESSAGE_CACHE_SIZE)
517 {
518 if (message_cache[i])
519 dbus_message_finalize (message_cache[i]);
520
521 ++i;
522 }
523
524 message_cache_count = 0;
525 message_cache_shutdown_registered = FALSE;
526
527 _DBUS_UNLOCK (message_cache);
528}
529
537static DBusMessage*
538dbus_message_get_cached (void)
539{
540 DBusMessage *message;
541 int i;
542
543 message = NULL;
544
545 if (!_DBUS_LOCK (message_cache))
546 {
547 /* we'd have initialized global locks before caching anything,
548 * so there can't be anything in the cache */
549 return NULL;
550 }
551
552 _dbus_assert (message_cache_count >= 0);
553
554 if (message_cache_count == 0)
555 {
556 _DBUS_UNLOCK (message_cache);
557 return NULL;
558 }
559
560 /* This is not necessarily true unless count > 0, and
561 * message_cache is uninitialized until the shutdown is
562 * registered
563 */
564 _dbus_assert (message_cache_shutdown_registered);
565
566 i = 0;
567 while (i < MAX_MESSAGE_CACHE_SIZE)
568 {
569 if (message_cache[i])
570 {
571 message = message_cache[i];
572 message_cache[i] = NULL;
573 message_cache_count -= 1;
574 break;
575 }
576 ++i;
577 }
578 _dbus_assert (message_cache_count >= 0);
579 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
580 _dbus_assert (message != NULL);
581
582 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
583
584 _dbus_assert (message->counters == NULL);
585
586 _DBUS_UNLOCK (message_cache);
587
588 return message;
589}
590
591#ifdef HAVE_UNIX_FD_PASSING
592static void
593close_unix_fds(int *fds, unsigned *n_fds)
594{
595 DBusError e;
596 unsigned int i;
597
598 if (*n_fds <= 0)
599 return;
600
601 dbus_error_init(&e);
602
603 for (i = 0; i < *n_fds; i++)
604 {
605 if (!_dbus_close(fds[i], &e))
606 {
607 _dbus_warn("Failed to close file descriptor: %s", e.message);
608 dbus_error_free(&e);
609 }
610 }
611
612 *n_fds = 0;
613
614 /* We don't free the array here, in case we can recycle it later */
615}
616#endif
617
618static void
619free_counter (void *element,
620 void *data)
621{
622 DBusCounter *counter = element;
623 DBusMessage *message = data;
624
625 _dbus_counter_adjust_size (counter, - message->size_counter_delta);
626#ifdef HAVE_UNIX_FD_PASSING
627 _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
628#endif
629
630 _dbus_counter_notify (counter);
631 _dbus_counter_unref (counter);
632}
633
639static void
640dbus_message_cache_or_finalize (DBusMessage *message)
641{
642 dbus_bool_t was_cached;
643 int i;
644
645 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
646
647 /* This calls application code and has to be done first thing
648 * without holding the lock
649 */
650 _dbus_data_slot_list_clear (&message->slot_list);
651
652 _dbus_list_foreach (&message->counters,
653 free_counter, message);
654 _dbus_list_clear (&message->counters);
655
656#ifdef HAVE_UNIX_FD_PASSING
657 close_unix_fds(message->unix_fds, &message->n_unix_fds);
658#endif
659
660 was_cached = FALSE;
661
662 if (!_DBUS_LOCK (message_cache))
663 {
664 /* The only way to get a non-null message goes through
665 * dbus_message_get_cached() which takes the lock. */
666 _dbus_assert_not_reached ("we would have initialized global locks "
667 "the first time we constructed a message");
668 }
669
670 if (!message_cache_shutdown_registered)
671 {
672 _dbus_assert (message_cache_count == 0);
673
674 if (!_dbus_register_shutdown_func (dbus_message_cache_shutdown, NULL))
675 goto out;
676
677 i = 0;
678 while (i < MAX_MESSAGE_CACHE_SIZE)
679 {
680 message_cache[i] = NULL;
681 ++i;
682 }
683
684 message_cache_shutdown_registered = TRUE;
685 }
686
687 _dbus_assert (message_cache_count >= 0);
688
689 if (!_dbus_enable_message_cache ())
690 goto out;
691
692 if ((_dbus_string_get_length (&message->header.data) +
693 _dbus_string_get_length (&message->body)) >
694 MAX_MESSAGE_SIZE_TO_CACHE)
695 goto out;
696
697 if (message_cache_count >= MAX_MESSAGE_CACHE_SIZE)
698 goto out;
699
700 /* Find empty slot */
701 i = 0;
702 while (message_cache[i] != NULL)
703 ++i;
704
705 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
706
707 _dbus_assert (message_cache[i] == NULL);
708 message_cache[i] = message;
709 message_cache_count += 1;
710 was_cached = TRUE;
711#ifndef DBUS_DISABLE_CHECKS
712 message->in_cache = TRUE;
713#endif
714
715 out:
716 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
717
718 _DBUS_UNLOCK (message_cache);
719
720 if (!was_cached)
721 dbus_message_finalize (message);
722}
723
724/*
725 * Arrange for iter to be something that _dbus_message_iter_check() would
726 * reject as not a valid iterator.
727 */
728static void
729_dbus_message_real_iter_zero (DBusMessageRealIter *iter)
730{
731 _dbus_assert (iter != NULL);
732 _DBUS_ZERO (*iter);
733 /* NULL is not, strictly speaking, guaranteed to be all-bits-zero */
734 iter->message = NULL;
735}
736
742void
743dbus_message_iter_init_closed (DBusMessageIter *iter)
744{
745 _dbus_return_if_fail (iter != NULL);
746 _dbus_message_real_iter_zero ((DBusMessageRealIter *) iter);
747}
748
749static dbus_bool_t
750_dbus_message_real_iter_is_zeroed (DBusMessageRealIter *iter)
751{
752 return (iter != NULL && iter->message == NULL && iter->changed_stamp == 0 &&
753 iter->iter_type == 0 && iter->sig_refcount == 0);
754}
755
756#if defined(DBUS_ENABLE_CHECKS) || defined(DBUS_ENABLE_ASSERT)
757static 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");
765 return FALSE;
766 }
767
768 if (iter->message == NULL || iter->iter_type == 0)
769 {
770 _dbus_warn_check_failed ("dbus message iterator has already been "
771 "closed, or is uninitialized or corrupt");
772 return FALSE;
773 }
774
775 byte_order = _dbus_header_get_byte_order (&iter->message->header);
776
777 if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_READER)
778 {
779 if (iter->u.reader.byte_order != byte_order)
780 {
781 _dbus_warn_check_failed ("dbus message changed byte order since iterator was created");
782 return FALSE;
783 }
784 /* because we swap the message into compiler order when you init an iter */
785 _dbus_assert (iter->u.reader.byte_order == DBUS_COMPILER_BYTE_ORDER);
786 }
787 else if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER)
788 {
789 if (iter->u.writer.byte_order != byte_order)
790 {
791 _dbus_warn_check_failed ("dbus message changed byte order since append iterator was created");
792 return FALSE;
793 }
794 /* because we swap the message into compiler order when you init an iter */
795 _dbus_assert (iter->u.writer.byte_order == DBUS_COMPILER_BYTE_ORDER);
796 }
797 else
798 {
799 _dbus_warn_check_failed ("dbus message iterator looks uninitialized or corrupted");
800 return FALSE;
801 }
802
803 if (iter->changed_stamp != iter->message->changed_stamp)
804 {
805 _dbus_warn_check_failed ("dbus message iterator invalid because the message has been modified (or perhaps the iterator is just uninitialized)");
806 return FALSE;
807 }
808
809 return TRUE;
810}
811#endif /* DBUS_ENABLE_CHECKS || DBUS_ENABLE_ASSERT */
812
825dbus_bool_t
826_dbus_message_iter_get_args_valist (DBusMessageIter *iter,
827 DBusError *error,
828 int first_arg_type,
829 va_list var_args)
830{
831 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
832 int spec_type, msg_type, i, j;
833 dbus_bool_t retval;
834 va_list copy_args;
835
836 _dbus_assert (_dbus_message_iter_check (real));
837
838 retval = FALSE;
839
840 spec_type = first_arg_type;
841 i = 0;
842
843 /* copy var_args first, then we can do another iteration over it to
844 * free memory and close unix fds if parse failed at some point.
845 */
846 DBUS_VA_COPY (copy_args, var_args);
847
848 while (spec_type != DBUS_TYPE_INVALID)
849 {
850 msg_type = dbus_message_iter_get_arg_type (iter);
851
852 if (msg_type != spec_type)
853 {
854 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
855 "Argument %d is specified to be of type \"%s\", but "
856 "is actually of type \"%s\"\n", i,
857 _dbus_type_to_string (spec_type),
858 _dbus_type_to_string (msg_type));
859
860 goto out;
861 }
862
863 if (spec_type == DBUS_TYPE_UNIX_FD)
864 {
865#ifdef HAVE_UNIX_FD_PASSING
866 DBusBasicValue idx;
867 int *pfd, nfd;
868
869 pfd = va_arg (var_args, int*);
870 _dbus_assert(pfd);
871
872 _dbus_type_reader_read_basic(&real->u.reader, &idx);
873
874 if (idx.u32 >= real->message->n_unix_fds)
875 {
876 dbus_set_error (error, DBUS_ERROR_INCONSISTENT_MESSAGE,
877 "Message refers to file descriptor at index %i,"
878 "but has only %i descriptors attached.\n",
879 idx.u32,
880 real->message->n_unix_fds);
881 goto out;
882 }
883
884 if ((nfd = _dbus_dup(real->message->unix_fds[idx.u32], error)) < 0)
885 goto out;
886
887 *pfd = nfd;
888#else
889 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
890 "Platform does not support file desciptor passing.\n");
891 goto out;
892#endif
893 }
894 else if (dbus_type_is_basic (spec_type))
895 {
896 void *ptr;
897
898 ptr = va_arg (var_args, void *);
899
900 _dbus_assert (ptr != NULL);
901
902 _dbus_type_reader_read_basic (&real->u.reader,
903 ptr);
904 }
905 else if (spec_type == DBUS_TYPE_ARRAY)
906 {
907 int element_type;
908 int spec_element_type;
909 const void **ptr;
910 int *n_elements_p;
911 DBusTypeReader array;
912
913 spec_element_type = va_arg (var_args, int);
914 element_type = _dbus_type_reader_get_element_type (&real->u.reader);
915
916 if (spec_element_type != element_type)
917 {
918 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
919 "Argument %d is specified to be an array of \"%s\", but "
920 "is actually an array of \"%s\"\n",
921 i,
922 _dbus_type_to_string (spec_element_type),
923 _dbus_type_to_string (element_type));
924
925 goto out;
926 }
927
928 if (dbus_type_is_fixed (spec_element_type) &&
929 element_type != DBUS_TYPE_UNIX_FD)
930 {
931 ptr = va_arg (var_args, const void **);
932 n_elements_p = va_arg (var_args, int*);
933
934 _dbus_assert (ptr != NULL);
935 _dbus_assert (n_elements_p != NULL);
936
937 _dbus_type_reader_recurse (&real->u.reader, &array);
938
939 _dbus_type_reader_read_fixed_multi (&array, ptr, n_elements_p);
940 }
941 else if (_DBUS_TYPE_IS_STRINGLIKE (spec_element_type))
942 {
943 char ***str_array_p;
944 int n_elements;
945 char **str_array;
946
947 str_array_p = va_arg (var_args, char***);
948 n_elements_p = va_arg (var_args, int*);
949
950 _dbus_assert (str_array_p != NULL);
951 _dbus_assert (n_elements_p != NULL);
952
953 /* Count elements in the array */
954 _dbus_type_reader_recurse (&real->u.reader, &array);
955
956 n_elements = 0;
957 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
958 {
959 ++n_elements;
960 _dbus_type_reader_next (&array);
961 }
962
963 str_array = dbus_new0 (char*, n_elements + 1);
964 if (str_array == NULL)
965 {
966 _DBUS_SET_OOM (error);
967 goto out;
968 }
969
970 /* Now go through and dup each string */
971 _dbus_type_reader_recurse (&real->u.reader, &array);
972
973 j = 0;
974 while (j < n_elements)
975 {
976 const char *s;
977 _dbus_type_reader_read_basic (&array,
978 (void *) &s);
979
980 str_array[j] = _dbus_strdup (s);
981 if (str_array[j] == NULL)
982 {
983 dbus_free_string_array (str_array);
984 _DBUS_SET_OOM (error);
985 goto out;
986 }
987
988 ++j;
989
990 if (!_dbus_type_reader_next (&array))
991 _dbus_assert (j == n_elements);
992 }
993
994 _dbus_assert (_dbus_type_reader_get_current_type (&array) == DBUS_TYPE_INVALID);
995 _dbus_assert (j == n_elements);
996 _dbus_assert (str_array[j] == NULL);
997
998 *str_array_p = str_array;
999 *n_elements_p = n_elements;
1000 }
1001#ifndef DBUS_DISABLE_CHECKS
1002 else
1003 {
1004 _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now",
1005 _DBUS_FUNCTION_NAME);
1006 goto out;
1007 }
1008#endif
1009 }
1010#ifndef DBUS_DISABLE_CHECKS
1011 else
1012 {
1013 _dbus_warn ("you can only read arrays and basic types with %s for now",
1014 _DBUS_FUNCTION_NAME);
1015 goto out;
1016 }
1017#endif
1018
1019 /* how many arguments already handled */
1020 i++;
1021
1022 spec_type = va_arg (var_args, int);
1023 if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID)
1024 {
1025 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1026 "Message has only %d arguments, but more were expected", i);
1027 goto out;
1028 }
1029 }
1030
1031 retval = TRUE;
1032
1033 out:
1034 /* there may memory or unix fd leak in the above iteration if parse failed.
1035 * so we have another iteration over copy_args to free memory and close
1036 * unix fds.
1037 */
1038 if (!retval)
1039 {
1040 spec_type = first_arg_type;
1041 j = 0;
1042
1043 while (j < i)
1044 {
1045 if (spec_type == DBUS_TYPE_UNIX_FD)
1046 {
1047#ifdef HAVE_UNIX_FD_PASSING
1048 int *pfd;
1049
1050 pfd = va_arg (copy_args, int *);
1051 _dbus_assert(pfd);
1052 if (*pfd >= 0)
1053 {
1054 _dbus_close (*pfd, NULL);
1055 *pfd = -1;
1056 }
1057#endif
1058 }
1059 else if (dbus_type_is_basic (spec_type))
1060 {
1061 /* move the index forward */
1062 va_arg (copy_args, const void *);
1063 }
1064 else if (spec_type == DBUS_TYPE_ARRAY)
1065 {
1066 int spec_element_type;
1067
1068 spec_element_type = va_arg (copy_args, int);
1069 if (dbus_type_is_fixed (spec_element_type))
1070 {
1071 /* move the index forward */
1072 va_arg (copy_args, const void **);
1073 va_arg (copy_args, int *);
1074 }
1075 else if (_DBUS_TYPE_IS_STRINGLIKE (spec_element_type))
1076 {
1077 char ***str_array_p;
1078
1079 str_array_p = va_arg (copy_args, char ***);
1080 /* move the index forward */
1081 va_arg (copy_args, int *);
1082 _dbus_assert (str_array_p != NULL);
1083 dbus_free_string_array (*str_array_p);
1084 *str_array_p = NULL;
1085 }
1086 }
1087
1088 spec_type = va_arg (copy_args, int);
1089 j++;
1090 }
1091 }
1092
1093 va_end (copy_args);
1094 return retval;
1095}
1096
1155dbus_uint32_t
1156dbus_message_get_serial (DBusMessage *message)
1157{
1158 _dbus_return_val_if_fail (message != NULL, 0);
1159
1160 return _dbus_header_get_serial (&message->header);
1161}
1162
1171dbus_bool_t
1172dbus_message_set_reply_serial (DBusMessage *message,
1173 dbus_uint32_t reply_serial)
1174{
1175 DBusBasicValue value;
1176
1177 _dbus_return_val_if_fail (message != NULL, FALSE);
1178 _dbus_return_val_if_fail (!message->locked, FALSE);
1179 _dbus_return_val_if_fail (reply_serial != 0, FALSE); /* 0 is invalid */
1180
1181 value.u32 = reply_serial;
1182
1183 return _dbus_header_set_field_basic (&message->header,
1184 DBUS_HEADER_FIELD_REPLY_SERIAL,
1185 DBUS_TYPE_UINT32,
1186 &value);
1187}
1188
1195dbus_uint32_t
1196dbus_message_get_reply_serial (DBusMessage *message)
1197{
1198 dbus_uint32_t v_UINT32;
1199
1200 _dbus_return_val_if_fail (message != NULL, 0);
1201
1202 if (_dbus_header_get_field_basic (&message->header,
1203 DBUS_HEADER_FIELD_REPLY_SERIAL,
1204 DBUS_TYPE_UINT32,
1205 &v_UINT32))
1206 return v_UINT32;
1207 else
1208 return 0;
1209}
1210
1211static void
1212dbus_message_finalize (DBusMessage *message)
1213{
1214 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
1215
1216 /* This calls application callbacks! */
1217 _dbus_data_slot_list_free (&message->slot_list);
1218
1219 _dbus_list_foreach (&message->counters,
1220 free_counter, message);
1221 _dbus_list_clear (&message->counters);
1222
1223 _dbus_header_free (&message->header);
1224 _dbus_string_free (&message->body);
1225
1226#ifdef HAVE_UNIX_FD_PASSING
1227 close_unix_fds(message->unix_fds, &message->n_unix_fds);
1228 dbus_free(message->unix_fds);
1229#endif
1230
1231 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
1232
1233 dbus_free (message);
1234}
1235
1236static DBusMessage*
1237dbus_message_new_empty_header (void)
1238{
1239 DBusMessage *message;
1240 dbus_bool_t from_cache;
1241
1242 message = dbus_message_get_cached ();
1243
1244 if (message != NULL)
1245 {
1246 from_cache = TRUE;
1247 }
1248 else
1249 {
1250 from_cache = FALSE;
1251 message = dbus_new0 (DBusMessage, 1);
1252 if (message == NULL)
1253 return NULL;
1254#ifndef DBUS_DISABLE_CHECKS
1255 message->generation = _dbus_current_generation;
1256#endif
1257
1258#ifdef HAVE_UNIX_FD_PASSING
1259 message->unix_fds = NULL;
1260 message->n_unix_fds_allocated = 0;
1261#endif
1262 }
1263
1264 _dbus_atomic_inc (&message->refcount);
1265
1266 _dbus_message_trace_ref (message, 0, 1, "new_empty_header");
1267
1268 message->locked = FALSE;
1269#ifndef DBUS_DISABLE_CHECKS
1270 message->in_cache = FALSE;
1271#endif
1272 message->counters = NULL;
1273 message->size_counter_delta = 0;
1274 message->changed_stamp = 0;
1275
1276#ifdef HAVE_UNIX_FD_PASSING
1277 message->n_unix_fds = 0;
1278 message->n_unix_fds_allocated = 0;
1279 message->unix_fd_counter_delta = 0;
1280#endif
1281
1282 if (!from_cache)
1283 _dbus_data_slot_list_init (&message->slot_list);
1284
1285 if (from_cache)
1286 {
1287 _dbus_header_reinit (&message->header);
1288 _dbus_string_set_length (&message->body, 0);
1289 }
1290 else
1291 {
1292 if (!_dbus_header_init (&message->header))
1293 {
1294 dbus_free (message);
1295 return NULL;
1296 }
1297
1298 if (!_dbus_string_init_preallocated (&message->body, 32))
1299 {
1300 _dbus_header_free (&message->header);
1301 dbus_free (message);
1302 return NULL;
1303 }
1304 }
1305
1306 return message;
1307}
1308
1321 DBusMessage*
1322dbus_message_new (int message_type)
1323{
1324 DBusMessage *message;
1325
1326 _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
1327
1328 message = dbus_message_new_empty_header ();
1329 if (message == NULL)
1330 return NULL;
1331
1332 if (!_dbus_header_create (&message->header,
1333 DBUS_COMPILER_BYTE_ORDER,
1334 message_type,
1335 NULL, NULL, NULL, NULL, NULL))
1336 {
1337 dbus_message_unref (message);
1338 return NULL;
1339 }
1340
1341 return message;
1342}
1343
1365 DBusMessage*
1366dbus_message_new_method_call (const char *destination,
1367 const char *path,
1368 const char *iface,
1369 const char *method)
1370{
1371 DBusMessage *message;
1372
1373 _dbus_return_val_if_fail (path != NULL, NULL);
1374 _dbus_return_val_if_fail (method != NULL, NULL);
1375 _dbus_return_val_if_fail (destination == NULL ||
1376 _dbus_check_is_valid_bus_name (destination), NULL);
1377 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
1378 _dbus_return_val_if_fail (iface == NULL ||
1379 _dbus_check_is_valid_interface (iface), NULL);
1380 _dbus_return_val_if_fail (_dbus_check_is_valid_member (method), NULL);
1381
1382 message = dbus_message_new_empty_header ();
1383 if (message == NULL)
1384 return NULL;
1385
1386 if (!_dbus_header_create (&message->header,
1387 DBUS_COMPILER_BYTE_ORDER,
1388 DBUS_MESSAGE_TYPE_METHOD_CALL,
1389 destination, path, iface, method, NULL))
1390 {
1391 dbus_message_unref (message);
1392 return NULL;
1393 }
1394
1395 return message;
1396}
1397
1405 DBusMessage*
1406dbus_message_new_method_return (DBusMessage *method_call)
1407{
1408 DBusMessage *message;
1409 const char *sender;
1410
1411 _dbus_return_val_if_fail (method_call != NULL, NULL);
1412
1413 sender = dbus_message_get_sender (method_call);
1414
1415 /* sender is allowed to be null here in peer-to-peer case */
1416
1417 message = dbus_message_new_empty_header ();
1418 if (message == NULL)
1419 return NULL;
1420
1421 if (!_dbus_header_create (&message->header,
1422 DBUS_COMPILER_BYTE_ORDER,
1423 DBUS_MESSAGE_TYPE_METHOD_RETURN,
1424 sender, NULL, NULL, NULL, NULL))
1425 {
1426 dbus_message_unref (message);
1427 return NULL;
1428 }
1429
1430 dbus_message_set_no_reply (message, TRUE);
1431
1432 if (!dbus_message_set_reply_serial (message,
1433 dbus_message_get_serial (method_call)))
1434 {
1435 dbus_message_unref (message);
1436 return NULL;
1437 }
1438
1439 return message;
1440}
1441
1456 DBusMessage*
1457dbus_message_new_signal (const char *path,
1458 const char *iface,
1459 const char *name)
1460{
1461 DBusMessage *message;
1462
1463 _dbus_return_val_if_fail (path != NULL, NULL);
1464 _dbus_return_val_if_fail (iface != NULL, NULL);
1465 _dbus_return_val_if_fail (name != NULL, NULL);
1466 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
1467 _dbus_return_val_if_fail (_dbus_check_is_valid_interface (iface), NULL);
1468 _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);
1469
1470 message = dbus_message_new_empty_header ();
1471 if (message == NULL)
1472 return NULL;
1473
1474 if (!_dbus_header_create (&message->header,
1475 DBUS_COMPILER_BYTE_ORDER,
1476 DBUS_MESSAGE_TYPE_SIGNAL,
1477 NULL, path, iface, name, NULL))
1478 {
1479 dbus_message_unref (message);
1480 return NULL;
1481 }
1482
1483 dbus_message_set_no_reply (message, TRUE);
1484
1485 return message;
1486}
1487
1502 DBusMessage*
1503dbus_message_new_error (DBusMessage *reply_to,
1504 const char *error_name,
1505 const char *error_message)
1506{
1507 DBusMessage *message;
1508 const char *sender;
1509 DBusMessageIter iter;
1510
1511 _dbus_return_val_if_fail (reply_to != NULL, NULL);
1512 _dbus_return_val_if_fail (error_name != NULL, NULL);
1513 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
1514
1515 sender = dbus_message_get_sender (reply_to);
1516
1517 /* sender may be NULL for non-message-bus case or
1518 * when the message bus is dealing with an unregistered
1519 * connection.
1520 */
1521 message = dbus_message_new_empty_header ();
1522 if (message == NULL)
1523 return NULL;
1524
1525 if (!_dbus_header_create (&message->header,
1526 DBUS_COMPILER_BYTE_ORDER,
1527 DBUS_MESSAGE_TYPE_ERROR,
1528 sender, NULL, NULL, NULL, error_name))
1529 {
1530 dbus_message_unref (message);
1531 return NULL;
1532 }
1533
1534 dbus_message_set_no_reply (message, TRUE);
1535
1536 if (!dbus_message_set_reply_serial (message,
1537 dbus_message_get_serial (reply_to)))
1538 {
1539 dbus_message_unref (message);
1540 return NULL;
1541 }
1542
1543 if (error_message != NULL)
1544 {
1545 dbus_message_iter_init_append (message, &iter);
1546 if (!dbus_message_iter_append_basic (&iter,
1547 DBUS_TYPE_STRING,
1548 &error_message))
1549 {
1550 dbus_message_unref (message);
1551 return NULL;
1552 }
1553 }
1554
1555 return message;
1556}
1557
1574 DBusMessage*
1575dbus_message_new_error_printf (DBusMessage *reply_to,
1576 const char *error_name,
1577 const char *error_format,
1578 ...)
1579{
1580 va_list args;
1581 DBusString str;
1582 DBusMessage *message;
1583
1584 _dbus_return_val_if_fail (reply_to != NULL, NULL);
1585 _dbus_return_val_if_fail (error_name != NULL, NULL);
1586 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
1587
1588 if (!_dbus_string_init (&str))
1589 return NULL;
1590
1591 va_start (args, error_format);
1592
1593 if (_dbus_string_append_printf_valist (&str, error_format, args))
1594 message = dbus_message_new_error (reply_to, error_name,
1595 _dbus_string_get_const_data (&str));
1596 else
1597 message = NULL;
1598
1599 _dbus_string_free (&str);
1600
1601 va_end (args);
1602
1603 return message;
1604}
1605
1606
1619 DBusMessage *
1620dbus_message_copy (const DBusMessage *message)
1621{
1622 DBusMessage *retval;
1623
1624 _dbus_return_val_if_fail (message != NULL, NULL);
1625
1626 retval = dbus_new0 (DBusMessage, 1);
1627 if (retval == NULL)
1628 return NULL;
1629
1630 _dbus_atomic_inc (&retval->refcount);
1631
1632 retval->locked = FALSE;
1633#ifndef DBUS_DISABLE_CHECKS
1634 retval->generation = message->generation;
1635#endif
1636
1637 if (!_dbus_header_copy (&message->header, &retval->header))
1638 {
1639 dbus_free (retval);
1640 return NULL;
1641 }
1642
1643 if (!_dbus_string_init_preallocated (&retval->body,
1644 _dbus_string_get_length (&message->body)))
1645 {
1646 _dbus_header_free (&retval->header);
1647 dbus_free (retval);
1648 return NULL;
1649 }
1650
1651 if (!_dbus_string_copy (&message->body, 0,
1652 &retval->body, 0))
1653 goto failed_copy;
1654
1655#ifdef HAVE_UNIX_FD_PASSING
1656 retval->unix_fds = dbus_new(int, message->n_unix_fds);
1657 if (retval->unix_fds == NULL && message->n_unix_fds > 0)
1658 goto failed_copy;
1659
1660 retval->n_unix_fds_allocated = message->n_unix_fds;
1661
1662 for (retval->n_unix_fds = 0;
1663 retval->n_unix_fds < message->n_unix_fds;
1664 retval->n_unix_fds++)
1665 {
1666 retval->unix_fds[retval->n_unix_fds] = _dbus_dup(message->unix_fds[retval->n_unix_fds], NULL);
1667
1668 if (retval->unix_fds[retval->n_unix_fds] < 0)
1669 goto failed_copy;
1670 }
1671
1672#endif
1673
1674 _dbus_message_trace_ref (retval, 0, 1, "copy");
1675 return retval;
1676
1677 failed_copy:
1678 _dbus_header_free (&retval->header);
1679 _dbus_string_free (&retval->body);
1680
1681#ifdef HAVE_UNIX_FD_PASSING
1682 close_unix_fds(retval->unix_fds, &retval->n_unix_fds);
1683 dbus_free(retval->unix_fds);
1684#endif
1685
1686 dbus_free (retval);
1687
1688 return NULL;
1689}
1690
1691
1699 DBusMessage *
1700dbus_message_ref (DBusMessage *message)
1701{
1702 dbus_int32_t old_refcount;
1703
1704 _dbus_return_val_if_fail (message != NULL, NULL);
1705 _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
1706 _dbus_return_val_if_fail (!message->in_cache, NULL);
1707
1708 old_refcount = _dbus_atomic_inc (&message->refcount);
1709 _dbus_assert (old_refcount >= 1);
1710 _dbus_message_trace_ref (message, old_refcount, old_refcount + 1, "ref");
1711
1712 return message;
1713}
1714
1722void
1723dbus_message_unref (DBusMessage *message)
1724{
1725 dbus_int32_t old_refcount;
1726
1727 _dbus_return_if_fail (message != NULL);
1728 _dbus_return_if_fail (message->generation == _dbus_current_generation);
1729 _dbus_return_if_fail (!message->in_cache);
1730
1731 old_refcount = _dbus_atomic_dec (&message->refcount);
1732
1733 _dbus_assert (old_refcount >= 1);
1734
1735 _dbus_message_trace_ref (message, old_refcount, old_refcount - 1, "unref");
1736
1737 if (old_refcount == 1)
1738 {
1739 /* Calls application callbacks! */
1740 dbus_message_cache_or_finalize (message);
1741 }
1742}
1743
1754int
1755dbus_message_get_type (DBusMessage *message)
1756{
1757 _dbus_return_val_if_fail (message != NULL, DBUS_MESSAGE_TYPE_INVALID);
1758
1759 return _dbus_header_get_message_type (&message->header);
1760}
1761
1830dbus_bool_t
1831dbus_message_append_args (DBusMessage *message,
1832 int first_arg_type,
1833 ...)
1834{
1835 dbus_bool_t retval;
1836 va_list var_args;
1837
1838 _dbus_return_val_if_fail (message != NULL, FALSE);
1839
1840 va_start (var_args, first_arg_type);
1841 retval = dbus_message_append_args_valist (message,
1842 first_arg_type,
1843 var_args);
1844 va_end (var_args);
1845
1846 return retval;
1847}
1848
1862dbus_bool_t
1863dbus_message_append_args_valist (DBusMessage *message,
1864 int first_arg_type,
1865 va_list var_args)
1866{
1867 int type;
1868 DBusMessageIter iter;
1869
1870 _dbus_return_val_if_fail (message != NULL, FALSE);
1871
1872 type = first_arg_type;
1873
1874 dbus_message_iter_init_append (message, &iter);
1875
1876 while (type != DBUS_TYPE_INVALID)
1877 {
1878 if (dbus_type_is_basic (type))
1879 {
1880 const void *value;
1881 value = va_arg (var_args, const void *);
1882
1883 if (!dbus_message_iter_append_basic (&iter,
1884 type,
1885 value))
1886 goto failed;
1887 }
1888 else if (type == DBUS_TYPE_ARRAY)
1889 {
1890 int element_type;
1891 DBusMessageIter array;
1892 char buf[2];
1893
1894 element_type = va_arg (var_args, int);
1895
1896 buf[0] = element_type;
1897 buf[1] = '\0';
1898 if (!dbus_message_iter_open_container (&iter,
1899 DBUS_TYPE_ARRAY,
1900 buf,
1901 &array))
1902 goto failed;
1903
1904 if (dbus_type_is_fixed (element_type) &&
1905 element_type != DBUS_TYPE_UNIX_FD)
1906 {
1907 const void **value;
1908 int n_elements;
1909
1910 value = va_arg (var_args, const void **);
1911 n_elements = va_arg (var_args, int);
1912
1913 if (!dbus_message_iter_append_fixed_array (&array,
1914 element_type,
1915 value,
1916 n_elements)) {
1917 dbus_message_iter_abandon_container (&iter, &array);
1918 goto failed;
1919 }
1920 }
1921 else if (_DBUS_TYPE_IS_STRINGLIKE (element_type))
1922 {
1923 const char ***value_p;
1924 const char **value;
1925 int n_elements;
1926 int i;
1927
1928 value_p = va_arg (var_args, const char***);
1929 n_elements = va_arg (var_args, int);
1930
1931 value = *value_p;
1932
1933 i = 0;
1934 while (i < n_elements)
1935 {
1936 if (!dbus_message_iter_append_basic (&array,
1937 element_type,
1938 &value[i])) {
1939 dbus_message_iter_abandon_container (&iter, &array);
1940 goto failed;
1941 }
1942 ++i;
1943 }
1944 }
1945 else
1946 {
1947 _dbus_warn ("arrays of %s can't be appended with %s for now",
1948 _dbus_type_to_string (element_type),
1949 _DBUS_FUNCTION_NAME);
1950 dbus_message_iter_abandon_container (&iter, &array);
1951 goto failed;
1952 }
1953
1954 if (!dbus_message_iter_close_container (&iter, &array))
1955 goto failed;
1956 }
1957#ifndef DBUS_DISABLE_CHECKS
1958 else
1959 {
1960 _dbus_warn ("type %s isn't supported yet in %s",
1961 _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
1962 goto failed;
1963 }
1964#endif
1965
1966 type = va_arg (var_args, int);
1967 }
1968
1969 return TRUE;
1970
1971 failed:
1972 return FALSE;
1973}
1974
2019dbus_bool_t
2020dbus_message_get_args (DBusMessage *message,
2021 DBusError *error,
2022 int first_arg_type,
2023 ...)
2024{
2025 dbus_bool_t retval;
2026 va_list var_args;
2027
2028 _dbus_return_val_if_fail (message != NULL, FALSE);
2029 _dbus_return_val_if_error_is_set (error, FALSE);
2030
2031 va_start (var_args, first_arg_type);
2032 retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
2033 va_end (var_args);
2034
2035 return retval;
2036}
2037
2048dbus_bool_t
2049dbus_message_get_args_valist (DBusMessage *message,
2050 DBusError *error,
2051 int first_arg_type,
2052 va_list var_args)
2053{
2054 DBusMessageIter iter;
2055
2056 _dbus_return_val_if_fail (message != NULL, FALSE);
2057 _dbus_return_val_if_error_is_set (error, FALSE);
2058
2059 dbus_message_iter_init (message, &iter);
2060 return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
2061}
2062
2063static void
2064_dbus_message_iter_init_common (DBusMessage *message,
2065 DBusMessageRealIter *real,
2066 int iter_type)
2067{
2068 /* If these static assertions fail on your platform, report it as a bug. */
2069 _DBUS_STATIC_ASSERT (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
2070 _DBUS_STATIC_ASSERT (_DBUS_ALIGNOF (DBusMessageRealIter) <=
2071 _DBUS_ALIGNOF (DBusMessageIter));
2072 /* A failure of these two assertions would indicate that we've broken
2073 * ABI on this platform since 1.10.0. */
2074 _DBUS_STATIC_ASSERT (sizeof (DBusMessageIter_1_10_0) ==
2075 sizeof (DBusMessageIter));
2076 _DBUS_STATIC_ASSERT (_DBUS_ALIGNOF (DBusMessageIter_1_10_0) ==
2077 _DBUS_ALIGNOF (DBusMessageIter));
2078 /* If this static assertion fails, it means the DBusMessageIter struct
2079 * is not "packed", which might result in "iter = other_iter" not copying
2080 * every byte. */
2081 _DBUS_STATIC_ASSERT (sizeof (DBusMessageIter) ==
2082 4 * sizeof (void *) + sizeof (dbus_uint32_t) + 9 * sizeof (int));
2083
2084 /* Since the iterator will read or write who-knows-what from the
2085 * message, we need to get in the right byte order
2086 */
2087 ensure_byte_order (message);
2088
2089 real->message = message;
2090 real->changed_stamp = message->changed_stamp;
2091 real->iter_type = iter_type;
2092 real->sig_refcount = 0;
2093}
2094
2117dbus_bool_t
2118dbus_message_iter_init (DBusMessage *message,
2119 DBusMessageIter *iter)
2120{
2121 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2122 const DBusString *type_str;
2123 int type_pos;
2124
2125 _dbus_return_val_if_fail (message != NULL, FALSE);
2126 _dbus_return_val_if_fail (iter != NULL, FALSE);
2127
2128 get_const_signature (&message->header, &type_str, &type_pos);
2129
2130 _dbus_message_iter_init_common (message, real,
2131 DBUS_MESSAGE_ITER_TYPE_READER);
2132
2133 _dbus_type_reader_init (&real->u.reader,
2134 _dbus_header_get_byte_order (&message->header),
2135 type_str, type_pos,
2136 &message->body,
2137 0);
2138
2139 return _dbus_type_reader_get_current_type (&real->u.reader) != DBUS_TYPE_INVALID;
2140}
2141
2148dbus_bool_t
2149dbus_message_iter_has_next (DBusMessageIter *iter)
2150{
2151 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2152
2153 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
2154 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2155
2156 return _dbus_type_reader_has_next (&real->u.reader);
2157}
2158
2167dbus_bool_t
2168dbus_message_iter_next (DBusMessageIter *iter)
2169{
2170 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2171
2172 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
2173 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2174
2175 return _dbus_type_reader_next (&real->u.reader);
2176}
2177
2192int
2193dbus_message_iter_get_arg_type (DBusMessageIter *iter)
2194{
2195 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2196
2197 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2198 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2199
2200 return _dbus_type_reader_get_current_type (&real->u.reader);
2201}
2202
2211int
2212dbus_message_iter_get_element_type (DBusMessageIter *iter)
2213{
2214 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2215
2216 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2217 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
2218 _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
2219
2220 return _dbus_type_reader_get_element_type (&real->u.reader);
2221}
2222
2248void
2249dbus_message_iter_recurse (DBusMessageIter *iter,
2250 DBusMessageIter *sub)
2251{
2252 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2253 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2254
2255 _dbus_return_if_fail (_dbus_message_iter_check (real));
2256 _dbus_return_if_fail (sub != NULL);
2257
2258 *real_sub = *real;
2259 _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
2260}
2261
2273char *
2274dbus_message_iter_get_signature (DBusMessageIter *iter)
2275{
2276 const DBusString *sig;
2277 DBusString retstr;
2278 char *ret = NULL;
2279 int start, len;
2280 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2281
2282 _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
2283
2284 if (!_dbus_string_init (&retstr))
2285 return NULL;
2286
2287 _dbus_type_reader_get_signature (&real->u.reader, &sig,
2288 &start, &len);
2289 if (!_dbus_string_append_len (&retstr,
2290 _dbus_string_get_const_data (sig) + start,
2291 len))
2292 goto oom;
2293
2294 /* This is correct whether it succeeds or fails: on success it sets `ret`,
2295 * and on failure it leaves `ret` set to NULL. */
2296 _dbus_string_steal_data (&retstr, &ret);
2297
2298oom:
2299 _dbus_string_free (&retstr);
2300 return ret;
2301}
2302
2350void
2351dbus_message_iter_get_basic (DBusMessageIter *iter,
2352 void *value)
2353{
2354 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2355
2356 _dbus_return_if_fail (_dbus_message_iter_check (real));
2357 _dbus_return_if_fail (value != NULL);
2358
2359 if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_UNIX_FD)
2360 {
2361#ifdef HAVE_UNIX_FD_PASSING
2362 DBusBasicValue idx;
2363
2364 _dbus_type_reader_read_basic(&real->u.reader, &idx);
2365
2366 if (idx.u32 >= real->message->n_unix_fds) {
2367 /* Hmm, we cannot really signal an error here, so let's make
2368 sure to return an invalid fd. */
2369 *((int*) value) = -1;
2370 return;
2371 }
2372
2373 *((int*) value) = _dbus_dup(real->message->unix_fds[idx.u32], NULL);
2374#else
2375 *((int*) value) = -1;
2376#endif
2377 }
2378 else
2379 {
2380 _dbus_type_reader_read_basic (&real->u.reader,
2381 value);
2382 }
2383}
2384
2395int
2396dbus_message_iter_get_element_count (DBusMessageIter *iter)
2397{
2398 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2399 DBusTypeReader array;
2400 int element_type;
2401 int n_elements = 0;
2402
2403 _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
2404 _dbus_return_val_if_fail (_dbus_type_reader_get_current_type (&real->u.reader)
2405 == DBUS_TYPE_ARRAY, 0);
2406
2407 element_type = _dbus_type_reader_get_element_type (&real->u.reader);
2408 _dbus_type_reader_recurse (&real->u.reader, &array);
2409 if (dbus_type_is_fixed (element_type))
2410 {
2411 int alignment = _dbus_type_get_alignment (element_type);
2412 int total_len = _dbus_type_reader_get_array_length (&array);
2413 n_elements = total_len / alignment;
2414 }
2415 else
2416 {
2417 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
2418 {
2419 ++n_elements;
2420 _dbus_type_reader_next (&array);
2421 }
2422 }
2423
2424 return n_elements;
2425}
2426
2439int
2440dbus_message_iter_get_array_len (DBusMessageIter *iter)
2441{
2442 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2443
2444 _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
2445
2446 return _dbus_type_reader_get_array_length (&real->u.reader);
2447}
2448
2484void
2485dbus_message_iter_get_fixed_array (DBusMessageIter *iter,
2486 void *value,
2487 int *n_elements)
2488{
2489 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2490#ifndef DBUS_DISABLE_CHECKS
2491 int subtype = _dbus_type_reader_get_current_type(&real->u.reader);
2492
2493 _dbus_return_if_fail (_dbus_message_iter_check (real));
2494 _dbus_return_if_fail (value != NULL);
2495 _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) ||
2496 (dbus_type_is_fixed (subtype) && subtype != DBUS_TYPE_UNIX_FD));
2497#endif
2498
2499 _dbus_type_reader_read_fixed_multi (&real->u.reader,
2500 value, n_elements);
2501}
2502
2514void
2515dbus_message_iter_init_append (DBusMessage *message,
2516 DBusMessageIter *iter)
2517{
2518 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2519
2520 _dbus_return_if_fail (message != NULL);
2521 _dbus_return_if_fail (iter != NULL);
2522
2523 _dbus_message_iter_init_common (message, real,
2524 DBUS_MESSAGE_ITER_TYPE_WRITER);
2525
2526 /* We create the signature string and point iterators at it "on demand"
2527 * when a value is actually appended. That means that init() never fails
2528 * due to OOM.
2529 */
2530 _dbus_type_writer_init_types_delayed (&real->u.writer,
2531 _dbus_header_get_byte_order (&message->header),
2532 &message->body,
2533 _dbus_string_get_length (&message->body));
2534}
2535
2544static dbus_bool_t
2545_dbus_message_iter_open_signature (DBusMessageRealIter *real)
2546{
2547 DBusString *str;
2548 const DBusString *current_sig;
2549 int current_sig_pos;
2550
2551 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2552
2553 if (real->u.writer.type_str != NULL)
2554 {
2555 _dbus_assert (real->sig_refcount > 0);
2556 real->sig_refcount += 1;
2557 return TRUE;
2558 }
2559
2560 str = dbus_new (DBusString, 1);
2561 if (str == NULL)
2562 return FALSE;
2563
2564 if (!_dbus_header_get_field_raw (&real->message->header,
2565 DBUS_HEADER_FIELD_SIGNATURE,
2566 &current_sig, &current_sig_pos))
2567 current_sig = NULL;
2568
2569 if (current_sig)
2570 {
2571 int current_len;
2572
2573 current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
2574 current_sig_pos += 1; /* move on to sig data */
2575
2576 if (!_dbus_string_init_preallocated (str, current_len + 4))
2577 {
2578 dbus_free (str);
2579 return FALSE;
2580 }
2581
2582 if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
2583 str, 0))
2584 {
2585 _dbus_string_free (str);
2586 dbus_free (str);
2587 return FALSE;
2588 }
2589 }
2590 else
2591 {
2592 if (!_dbus_string_init_preallocated (str, 4))
2593 {
2594 dbus_free (str);
2595 return FALSE;
2596 }
2597 }
2598
2599 real->sig_refcount = 1;
2600
2601 /* If this assertion failed, then str would be neither stored in u.writer
2602 * nor freed by this function, resulting in a memory leak. */
2603 _dbus_assert (real->u.writer.type_str == NULL);
2604 _dbus_type_writer_add_types (&real->u.writer,
2605 str, _dbus_string_get_length (str));
2606 return TRUE;
2607}
2608
2618static dbus_bool_t
2619_dbus_message_iter_close_signature (DBusMessageRealIter *real)
2620{
2621 DBusString *str;
2622 const char *v_STRING;
2623 dbus_bool_t retval;
2624
2625 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2626 _dbus_assert (real->u.writer.type_str != NULL);
2627 _dbus_assert (real->sig_refcount > 0);
2628
2629 real->sig_refcount -= 1;
2630
2631 if (real->sig_refcount > 0)
2632 return TRUE;
2633 _dbus_assert (real->sig_refcount == 0);
2634
2635 retval = TRUE;
2636
2637 str = real->u.writer.type_str;
2638
2639 v_STRING = _dbus_string_get_const_data (str);
2640 if (!_dbus_header_set_field_basic (&real->message->header,
2641 DBUS_HEADER_FIELD_SIGNATURE,
2642 DBUS_TYPE_SIGNATURE,
2643 &v_STRING))
2644 retval = FALSE;
2645
2646 _dbus_type_writer_remove_types (&real->u.writer);
2647 _dbus_string_free (str);
2648 dbus_free (str);
2649
2650 return retval;
2651}
2652
2660static void
2661_dbus_message_iter_abandon_signature (DBusMessageRealIter *real)
2662{
2663 DBusString *str;
2664
2665 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2666 _dbus_assert (real->u.writer.type_str != NULL);
2667 _dbus_assert (real->sig_refcount > 0);
2668
2669 real->sig_refcount -= 1;
2670
2671 if (real->sig_refcount > 0)
2672 return;
2673 _dbus_assert (real->sig_refcount == 0);
2674
2675 str = real->u.writer.type_str;
2676
2677 _dbus_type_writer_remove_types (&real->u.writer);
2678 _dbus_string_free (str);
2679 dbus_free (str);
2680}
2681
2682#ifndef DBUS_DISABLE_CHECKS
2683static dbus_bool_t
2684_dbus_message_iter_append_check (DBusMessageRealIter *iter)
2685{
2686 if (!_dbus_message_iter_check (iter))
2687 return FALSE;
2688
2689 if (iter->message->locked)
2690 {
2691 _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)");
2692 return FALSE;
2693 }
2694
2695 return TRUE;
2696}
2697#endif /* DBUS_DISABLE_CHECKS */
2698
2699#ifdef HAVE_UNIX_FD_PASSING
2700static int *
2701expand_fd_array(DBusMessage *m,
2702 unsigned n)
2703{
2704 _dbus_assert(m);
2705
2706 /* This makes space for adding n new fds to the array and returns a
2707 pointer to the place were the first fd should be put. */
2708
2709 if (m->n_unix_fds + n > m->n_unix_fds_allocated)
2710 {
2711 unsigned k;
2712 int *p;
2713
2714 /* Make twice as much space as necessary */
2715 k = (m->n_unix_fds + n) * 2;
2716
2717 /* Allocate at least four */
2718 if (k < 4)
2719 k = 4;
2720
2721 p = dbus_realloc(m->unix_fds, k * sizeof(int));
2722 if (p == NULL)
2723 return NULL;
2724
2725 m->unix_fds = p;
2726 m->n_unix_fds_allocated = k;
2727 }
2728
2729 return m->unix_fds + m->n_unix_fds;
2730}
2731#endif
2732
2752dbus_bool_t
2753dbus_message_iter_append_basic (DBusMessageIter *iter,
2754 int type,
2755 const void *value)
2756{
2757 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2758 dbus_bool_t ret;
2759
2760 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2761 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2762 _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
2763 _dbus_return_val_if_fail (value != NULL, FALSE);
2764
2765#ifndef DBUS_DISABLE_CHECKS
2766 switch (type)
2767 {
2768 DBusString str;
2769 DBusValidity signature_validity;
2770 const char * const *string_p;
2771 const dbus_bool_t *bool_p;
2772
2773 case DBUS_TYPE_STRING:
2774 string_p = value;
2775 _dbus_return_val_if_fail (_dbus_check_is_valid_utf8 (*string_p), FALSE);
2776 break;
2777
2778 case DBUS_TYPE_OBJECT_PATH:
2779 string_p = value;
2780 _dbus_return_val_if_fail (_dbus_check_is_valid_path (*string_p), FALSE);
2781 break;
2782
2783 case DBUS_TYPE_SIGNATURE:
2784 string_p = value;
2785 _dbus_string_init_const (&str, *string_p);
2786 signature_validity = _dbus_validate_signature_with_reason (&str,
2787 0,
2788 _dbus_string_get_length (&str));
2789
2790 if (signature_validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
2791 return FALSE;
2792
2793 _dbus_return_val_if_fail (signature_validity == DBUS_VALID, FALSE);
2794 break;
2795
2796 case DBUS_TYPE_BOOLEAN:
2797 bool_p = value;
2798 _dbus_return_val_if_fail (*bool_p == 0 || *bool_p == 1, FALSE);
2799 break;
2800
2801 default:
2802 {
2803 /* nothing to check, all possible values are allowed */
2804 }
2805 }
2806#endif
2807
2808 if (!_dbus_message_iter_open_signature (real))
2809 return FALSE;
2810
2811 if (type == DBUS_TYPE_UNIX_FD)
2812 {
2813#ifdef HAVE_UNIX_FD_PASSING
2814 int *fds;
2815 dbus_uint32_t u;
2816
2817 ret = FALSE;
2818
2819 /* First step, include the fd in the fd list of this message */
2820 if (!(fds = expand_fd_array(real->message, 1)))
2821 goto out;
2822
2823 *fds = _dbus_dup(*(int*) value, NULL);
2824 if (*fds < 0)
2825 goto out;
2826
2827 u = real->message->n_unix_fds;
2828
2829 /* Second step, write the index to the fd */
2830 if (!(ret = _dbus_type_writer_write_basic (&real->u.writer, DBUS_TYPE_UNIX_FD, &u))) {
2831 _dbus_close(*fds, NULL);
2832 goto out;
2833 }
2834
2835 real->message->n_unix_fds += 1;
2836 u += 1;
2837
2838 /* Final step, update the header accordingly */
2839 ret = _dbus_header_set_field_basic (&real->message->header,
2840 DBUS_HEADER_FIELD_UNIX_FDS,
2841 DBUS_TYPE_UINT32,
2842 &u);
2843
2844 /* If any of these operations fail the message is
2845 hosed. However, no memory or fds should be leaked since what
2846 has been added to message has been added to the message, and
2847 can hence be accounted for when the message is being
2848 freed. */
2849#else
2850 ret = FALSE;
2851 /* This is redundant (we could just fall through), but it avoids
2852 * -Wunused-label in builds that don't HAVE_UNIX_FD_PASSING */
2853 goto out;
2854#endif
2855 }
2856 else
2857 {
2858 ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
2859 }
2860
2861out:
2862 if (!_dbus_message_iter_close_signature (real))
2863 ret = FALSE;
2864
2865 return ret;
2866}
2867
2903dbus_bool_t
2904dbus_message_iter_append_fixed_array (DBusMessageIter *iter,
2905 int element_type,
2906 const void *value,
2907 int n_elements)
2908{
2909 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2910 dbus_bool_t ret;
2911
2912 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2913 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2914 _dbus_return_val_if_fail (dbus_type_is_fixed (element_type) && element_type != DBUS_TYPE_UNIX_FD, FALSE);
2915 _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
2916 _dbus_return_val_if_fail (value != NULL, FALSE);
2917 _dbus_return_val_if_fail (n_elements >= 0, FALSE);
2918 _dbus_return_val_if_fail (n_elements <=
2919 DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type),
2920 FALSE);
2921
2922#ifndef DBUS_DISABLE_CHECKS
2923 if (element_type == DBUS_TYPE_BOOLEAN)
2924 {
2925 const dbus_bool_t * const *bools = value;
2926 int i;
2927
2928 for (i = 0; i < n_elements; i++)
2929 {
2930 _dbus_return_val_if_fail ((*bools)[i] == 0 || (*bools)[i] == 1, FALSE);
2931 }
2932 }
2933#endif
2934
2935 ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
2936
2937 return ret;
2938}
2939
2967dbus_bool_t
2968dbus_message_iter_open_container (DBusMessageIter *iter,
2969 int type,
2970 const char *contained_signature,
2971 DBusMessageIter *sub)
2972{
2973 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2974 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2975 DBusString contained_str;
2976 DBusValidity contained_signature_validity;
2977 dbus_bool_t ret;
2978
2979 _dbus_return_val_if_fail (sub != NULL, FALSE);
2980 /* Do our best to make sure the sub-iterator doesn't contain something
2981 * valid-looking on failure */
2982 _dbus_message_real_iter_zero (real_sub);
2983
2984 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2985 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2986 _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
2987 _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
2988 contained_signature == NULL) ||
2989 (type == DBUS_TYPE_DICT_ENTRY &&
2990 contained_signature == NULL) ||
2991 (type == DBUS_TYPE_VARIANT &&
2992 contained_signature != NULL) ||
2993 (type == DBUS_TYPE_ARRAY &&
2994 contained_signature != NULL), FALSE);
2995
2996 /* this would fail if the contained_signature is a dict entry, since
2997 * dict entries are invalid signatures standalone (they must be in
2998 * an array)
2999 */
3000 if (contained_signature != NULL)
3001 {
3002 _dbus_string_init_const (&contained_str, contained_signature);
3003 contained_signature_validity = _dbus_validate_signature_with_reason (&contained_str,
3004 0,
3005 _dbus_string_get_length (&contained_str));
3006
3007 if (contained_signature_validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
3008 return FALSE;
3009 }
3010 else
3011 {
3012 /* just some placeholder value */
3013 contained_signature_validity = DBUS_VALID_BUT_INCOMPLETE;
3014 }
3015
3016 _dbus_return_val_if_fail ((type == DBUS_TYPE_ARRAY && contained_signature && *contained_signature == DBUS_DICT_ENTRY_BEGIN_CHAR) ||
3017 contained_signature == NULL ||
3018 contained_signature_validity == DBUS_VALID,
3019 FALSE);
3020
3021 if (!_dbus_message_iter_open_signature (real))
3022 return FALSE;
3023
3024 ret = FALSE;
3025 *real_sub = *real;
3026
3027 if (contained_signature != NULL)
3028 {
3029 _dbus_string_init_const (&contained_str, contained_signature);
3030
3031 ret = _dbus_type_writer_recurse (&real->u.writer,
3032 type,
3033 &contained_str, 0,
3034 &real_sub->u.writer);
3035 }
3036 else
3037 {
3038 ret = _dbus_type_writer_recurse (&real->u.writer,
3039 type,
3040 NULL, 0,
3041 &real_sub->u.writer);
3042 }
3043
3044 if (!ret)
3045 _dbus_message_iter_abandon_signature (real);
3046
3047 return ret;
3048}
3049
3050
3070dbus_bool_t
3071dbus_message_iter_close_container (DBusMessageIter *iter,
3072 DBusMessageIter *sub)
3073{
3074 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3075 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
3076 dbus_bool_t ret;
3077
3078 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
3079 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
3080 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
3081 _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
3082
3083 ret = _dbus_type_writer_unrecurse (&real->u.writer,
3084 &real_sub->u.writer);
3085 _dbus_message_real_iter_zero (real_sub);
3086
3087 if (!_dbus_message_iter_close_signature (real))
3088 ret = FALSE;
3089
3090 return ret;
3091}
3092
3104void
3105dbus_message_iter_abandon_container (DBusMessageIter *iter,
3106 DBusMessageIter *sub)
3107{
3108 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3109 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
3110
3111#ifndef DBUS_DISABLE_CHECKS
3112 _dbus_return_if_fail (_dbus_message_iter_append_check (real));
3113 _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
3114 _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
3115 _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
3116#endif
3117
3118 _dbus_message_iter_abandon_signature (real);
3119 _dbus_message_real_iter_zero (real_sub);
3120}
3121
3163void
3164dbus_message_iter_abandon_container_if_open (DBusMessageIter *iter,
3165 DBusMessageIter *sub)
3166{
3167 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3168 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
3169
3170 /* If both the parent and the child are zeroed out, then either we didn't
3171 * even get as far as successfully recursing into the parent, or we already
3172 * closed both the child and the parent. For example, in the code sample
3173 * in the doc-comment above, this happens for
3174 * abandon_container_if_open (&outer, &inner) if the first open_container
3175 * call failed, or if we reached result = TRUE and fell through. */
3176 if (_dbus_message_real_iter_is_zeroed (real) &&
3177 _dbus_message_real_iter_is_zeroed (real_sub))
3178 return;
3179
3180#ifndef DBUS_DISABLE_CHECKS
3181 /* If the child is not zeroed out, but the parent is, then something has
3182 * gone horribly wrong (in practice that would probably mean both are
3183 * uninitialized or corrupt, and the parent happens to have ended up
3184 * all-bytes-zero). */
3185 _dbus_return_if_fail (_dbus_message_iter_append_check (real));
3186 _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
3187#endif
3188
3189 /* If the parent is not zeroed out, but the child is, then either we did
3190 * not successfully open the child, or we already closed the child. This
3191 * means we do not own a reference to the parent's signature, so it would
3192 * be wrong to release it; so we must not call abandon_signature() here.
3193 * In the code sample in the doc-comment above, this happens for
3194 * abandon_container_if_open (&outer, &inner) if the second open_container
3195 * call failed, or if the second close_container call failed. */
3196 if (_dbus_message_real_iter_is_zeroed (real_sub))
3197 return;
3198
3199#ifndef DBUS_DISABLE_CHECKS
3200 _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
3201 _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
3202#endif
3203
3204 /* If neither the parent nor the child is zeroed out, then we genuinely
3205 * have an open container; close it. In the code sample in the doc-comment,
3206 * this happens for abandon_container_if_open (&outer, &inner) if the
3207 * append_basic call failed. */
3208 _dbus_message_iter_abandon_signature (real);
3209 _dbus_message_real_iter_zero (real_sub);
3210}
3211
3228void
3229dbus_message_set_no_reply (DBusMessage *message,
3230 dbus_bool_t no_reply)
3231{
3232 _dbus_return_if_fail (message != NULL);
3233 _dbus_return_if_fail (!message->locked);
3234
3235 _dbus_header_toggle_flag (&message->header,
3236 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED,
3237 no_reply);
3238}
3239
3247dbus_bool_t
3248dbus_message_get_no_reply (DBusMessage *message)
3249{
3250 _dbus_return_val_if_fail (message != NULL, FALSE);
3251
3252 return _dbus_header_get_flag (&message->header,
3253 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED);
3254}
3255
3270void
3271dbus_message_set_auto_start (DBusMessage *message,
3272 dbus_bool_t auto_start)
3273{
3274 _dbus_return_if_fail (message != NULL);
3275 _dbus_return_if_fail (!message->locked);
3276
3277 _dbus_header_toggle_flag (&message->header,
3278 DBUS_HEADER_FLAG_NO_AUTO_START,
3279 !auto_start);
3280}
3281
3289dbus_bool_t
3290dbus_message_get_auto_start (DBusMessage *message)
3291{
3292 _dbus_return_val_if_fail (message != NULL, FALSE);
3293
3294 return !_dbus_header_get_flag (&message->header,
3295 DBUS_HEADER_FLAG_NO_AUTO_START);
3296}
3297
3298
3311dbus_bool_t
3312dbus_message_set_path (DBusMessage *message,
3313 const char *object_path)
3314{
3315 _dbus_return_val_if_fail (message != NULL, FALSE);
3316 _dbus_return_val_if_fail (!message->locked, FALSE);
3317 _dbus_return_val_if_fail (object_path == NULL ||
3318 _dbus_check_is_valid_path (object_path),
3319 FALSE);
3320
3321 return set_or_delete_string_field (message,
3322 DBUS_HEADER_FIELD_PATH,
3323 DBUS_TYPE_OBJECT_PATH,
3324 object_path);
3325}
3326
3340const char*
3341dbus_message_get_path (DBusMessage *message)
3342{
3343 const char *v;
3344
3345 _dbus_return_val_if_fail (message != NULL, NULL);
3346
3347 v = NULL; /* in case field doesn't exist */
3348 _dbus_header_get_field_basic (&message->header,
3349 DBUS_HEADER_FIELD_PATH,
3350 DBUS_TYPE_OBJECT_PATH,
3351 (void *) &v);
3352 return v;
3353}
3354
3364dbus_bool_t
3365dbus_message_has_path (DBusMessage *message,
3366 const char *path)
3367{
3368 const char *msg_path;
3369 msg_path = dbus_message_get_path (message);
3370
3371 if (msg_path == NULL)
3372 {
3373 if (path == NULL)
3374 return TRUE;
3375 else
3376 return FALSE;
3377 }
3378
3379 if (path == NULL)
3380 return FALSE;
3381
3382 if (strcmp (msg_path, path) == 0)
3383 return TRUE;
3384
3385 return FALSE;
3386}
3387
3408dbus_bool_t
3409dbus_message_get_path_decomposed (DBusMessage *message,
3410 char ***path)
3411{
3412 const char *v;
3413
3414 _dbus_return_val_if_fail (message != NULL, FALSE);
3415 _dbus_return_val_if_fail (path != NULL, FALSE);
3416
3417 *path = NULL;
3418
3419 v = dbus_message_get_path (message);
3420 if (v != NULL)
3421 {
3422 if (!_dbus_decompose_path (v, strlen (v),
3423 path, NULL))
3424 return FALSE;
3425 }
3426 return TRUE;
3427}
3428
3442dbus_bool_t
3443dbus_message_set_interface (DBusMessage *message,
3444 const char *iface)
3445{
3446 _dbus_return_val_if_fail (message != NULL, FALSE);
3447 _dbus_return_val_if_fail (!message->locked, FALSE);
3448 _dbus_return_val_if_fail (iface == NULL ||
3449 _dbus_check_is_valid_interface (iface),
3450 FALSE);
3451
3452 return set_or_delete_string_field (message,
3453 DBUS_HEADER_FIELD_INTERFACE,
3454 DBUS_TYPE_STRING,
3455 iface);
3456}
3457
3471const char*
3472dbus_message_get_interface (DBusMessage *message)
3473{
3474 const char *v;
3475
3476 _dbus_return_val_if_fail (message != NULL, NULL);
3477
3478 v = NULL; /* in case field doesn't exist */
3479 _dbus_header_get_field_basic (&message->header,
3480 DBUS_HEADER_FIELD_INTERFACE,
3481 DBUS_TYPE_STRING,
3482 (void *) &v);
3483 return v;
3484}
3485
3493dbus_bool_t
3494dbus_message_has_interface (DBusMessage *message,
3495 const char *iface)
3496{
3497 const char *msg_interface;
3498 msg_interface = dbus_message_get_interface (message);
3499
3500 if (msg_interface == NULL)
3501 {
3502 if (iface == NULL)
3503 return TRUE;
3504 else
3505 return FALSE;
3506 }
3507
3508 if (iface == NULL)
3509 return FALSE;
3510
3511 if (strcmp (msg_interface, iface) == 0)
3512 return TRUE;
3513
3514 return FALSE;
3515
3516}
3517
3530dbus_bool_t
3531dbus_message_set_member (DBusMessage *message,
3532 const char *member)
3533{
3534 _dbus_return_val_if_fail (message != NULL, FALSE);
3535 _dbus_return_val_if_fail (!message->locked, FALSE);
3536 _dbus_return_val_if_fail (member == NULL ||
3537 _dbus_check_is_valid_member (member),
3538 FALSE);
3539
3540 return set_or_delete_string_field (message,
3541 DBUS_HEADER_FIELD_MEMBER,
3542 DBUS_TYPE_STRING,
3543 member);
3544}
3545
3557const char*
3558dbus_message_get_member (DBusMessage *message)
3559{
3560 const char *v;
3561
3562 _dbus_return_val_if_fail (message != NULL, NULL);
3563
3564 v = NULL; /* in case field doesn't exist */
3565 _dbus_header_get_field_basic (&message->header,
3566 DBUS_HEADER_FIELD_MEMBER,
3567 DBUS_TYPE_STRING,
3568 (void *) &v);
3569 return v;
3570}
3571
3579dbus_bool_t
3580dbus_message_has_member (DBusMessage *message,
3581 const char *member)
3582{
3583 const char *msg_member;
3584 msg_member = dbus_message_get_member (message);
3585
3586 if (msg_member == NULL)
3587 {
3588 if (member == NULL)
3589 return TRUE;
3590 else
3591 return FALSE;
3592 }
3593
3594 if (member == NULL)
3595 return FALSE;
3596
3597 if (strcmp (msg_member, member) == 0)
3598 return TRUE;
3599
3600 return FALSE;
3601
3602}
3603
3615dbus_bool_t
3616dbus_message_set_error_name (DBusMessage *message,
3617 const char *error_name)
3618{
3619 _dbus_return_val_if_fail (message != NULL, FALSE);
3620 _dbus_return_val_if_fail (!message->locked, FALSE);
3621 _dbus_return_val_if_fail (error_name == NULL ||
3622 _dbus_check_is_valid_error_name (error_name),
3623 FALSE);
3624
3625 return set_or_delete_string_field (message,
3626 DBUS_HEADER_FIELD_ERROR_NAME,
3627 DBUS_TYPE_STRING,
3628 error_name);
3629}
3630
3641const char*
3642dbus_message_get_error_name (DBusMessage *message)
3643{
3644 const char *v;
3645
3646 _dbus_return_val_if_fail (message != NULL, NULL);
3647
3648 v = NULL; /* in case field doesn't exist */
3649 _dbus_header_get_field_basic (&message->header,
3650 DBUS_HEADER_FIELD_ERROR_NAME,
3651 DBUS_TYPE_STRING,
3652 (void *) &v);
3653 return v;
3654}
3655
3669dbus_bool_t
3670dbus_message_set_destination (DBusMessage *message,
3671 const char *destination)
3672{
3673 _dbus_return_val_if_fail (message != NULL, FALSE);
3674 _dbus_return_val_if_fail (!message->locked, FALSE);
3675 _dbus_return_val_if_fail (destination == NULL ||
3676 _dbus_check_is_valid_bus_name (destination),
3677 FALSE);
3678
3679 return set_or_delete_string_field (message,
3680 DBUS_HEADER_FIELD_DESTINATION,
3681 DBUS_TYPE_STRING,
3682 destination);
3683}
3684
3694const char*
3695dbus_message_get_destination (DBusMessage *message)
3696{
3697 const char *v;
3698
3699 _dbus_return_val_if_fail (message != NULL, NULL);
3700
3701 v = NULL; /* in case field doesn't exist */
3702 _dbus_header_get_field_basic (&message->header,
3703 DBUS_HEADER_FIELD_DESTINATION,
3704 DBUS_TYPE_STRING,
3705 (void *) &v);
3706 return v;
3707}
3708
3723dbus_bool_t
3724dbus_message_set_sender (DBusMessage *message,
3725 const char *sender)
3726{
3727 _dbus_return_val_if_fail (message != NULL, FALSE);
3728 _dbus_return_val_if_fail (!message->locked, FALSE);
3729 _dbus_return_val_if_fail (sender == NULL ||
3730 _dbus_check_is_valid_bus_name (sender),
3731 FALSE);
3732
3733 return set_or_delete_string_field (message,
3734 DBUS_HEADER_FIELD_SENDER,
3735 DBUS_TYPE_STRING,
3736 sender);
3737}
3738
3754const char*
3755dbus_message_get_sender (DBusMessage *message)
3756{
3757 const char *v;
3758
3759 _dbus_return_val_if_fail (message != NULL, NULL);
3760
3761 v = NULL; /* in case field doesn't exist */
3762 _dbus_header_get_field_basic (&message->header,
3763 DBUS_HEADER_FIELD_SENDER,
3764 DBUS_TYPE_STRING,
3765 (void *) &v);
3766 return v;
3767}
3768
3787const char*
3788dbus_message_get_signature (DBusMessage *message)
3789{
3790 const DBusString *type_str;
3791 int type_pos;
3792
3793 _dbus_return_val_if_fail (message != NULL, NULL);
3794
3795 get_const_signature (&message->header, &type_str, &type_pos);
3796
3797 return _dbus_string_get_const_data_len (type_str, type_pos, 0);
3798}
3799
3800static dbus_bool_t
3801_dbus_message_has_type_interface_member (DBusMessage *message,
3802 int type,
3803 const char *iface,
3804 const char *member)
3805{
3806 const char *n;
3807
3808 _dbus_assert (message != NULL);
3809 _dbus_assert (iface != NULL);
3810 _dbus_assert (member != NULL);
3811
3812 if (dbus_message_get_type (message) != type)
3813 return FALSE;
3814
3815 /* Optimize by checking the short member name first
3816 * instead of the longer interface name
3817 */
3818
3819 n = dbus_message_get_member (message);
3820
3821 if (n && strcmp (n, member) == 0)
3822 {
3823 n = dbus_message_get_interface (message);
3824
3825 if (n == NULL || strcmp (n, iface) == 0)
3826 return TRUE;
3827 }
3828
3829 return FALSE;
3830}
3831
3846dbus_bool_t
3847dbus_message_is_method_call (DBusMessage *message,
3848 const char *iface,
3849 const char *method)
3850{
3851 _dbus_return_val_if_fail (message != NULL, FALSE);
3852 _dbus_return_val_if_fail (iface != NULL, FALSE);
3853 _dbus_return_val_if_fail (method != NULL, FALSE);
3854 /* don't check that interface/method are valid since it would be
3855 * expensive, and not catch many common errors
3856 */
3857
3858 return _dbus_message_has_type_interface_member (message,
3859 DBUS_MESSAGE_TYPE_METHOD_CALL,
3860 iface, method);
3861}
3862
3874dbus_bool_t
3875dbus_message_is_signal (DBusMessage *message,
3876 const char *iface,
3877 const char *signal_name)
3878{
3879 _dbus_return_val_if_fail (message != NULL, FALSE);
3880 _dbus_return_val_if_fail (iface != NULL, FALSE);
3881 _dbus_return_val_if_fail (signal_name != NULL, FALSE);
3882 /* don't check that interface/name are valid since it would be
3883 * expensive, and not catch many common errors
3884 */
3885
3886 return _dbus_message_has_type_interface_member (message,
3887 DBUS_MESSAGE_TYPE_SIGNAL,
3888 iface, signal_name);
3889}
3890
3901dbus_bool_t
3902dbus_message_is_error (DBusMessage *message,
3903 const char *error_name)
3904{
3905 const char *n;
3906
3907 _dbus_return_val_if_fail (message != NULL, FALSE);
3908 _dbus_return_val_if_fail (error_name != NULL, FALSE);
3909 /* don't check that error_name is valid since it would be expensive,
3910 * and not catch many common errors
3911 */
3912
3913 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
3914 return FALSE;
3915
3916 n = dbus_message_get_error_name (message);
3917
3918 if (n && strcmp (n, error_name) == 0)
3919 return TRUE;
3920 else
3921 return FALSE;
3922}
3923
3934dbus_bool_t
3935dbus_message_has_destination (DBusMessage *message,
3936 const char *name)
3937{
3938 const char *s;
3939
3940 _dbus_return_val_if_fail (message != NULL, FALSE);
3941 _dbus_return_val_if_fail (name != NULL, FALSE);
3942 /* don't check that name is valid since it would be expensive, and
3943 * not catch many common errors
3944 */
3945
3946 s = dbus_message_get_destination (message);
3947
3948 if (s && strcmp (s, name) == 0)
3949 return TRUE;
3950 else
3951 return FALSE;
3952}
3953
3969dbus_bool_t
3970dbus_message_has_sender (DBusMessage *message,
3971 const char *name)
3972{
3973 const char *s;
3974
3975 _dbus_return_val_if_fail (message != NULL, FALSE);
3976 _dbus_return_val_if_fail (name != NULL, FALSE);
3977 /* don't check that name is valid since it would be expensive, and
3978 * not catch many common errors
3979 */
3980
3981 s = dbus_message_get_sender (message);
3982
3983 if (s && strcmp (s, name) == 0)
3984 return TRUE;
3985 else
3986 return FALSE;
3987}
3988
3998dbus_bool_t
3999dbus_message_has_signature (DBusMessage *message,
4000 const char *signature)
4001{
4002 const char *s;
4003
4004 _dbus_return_val_if_fail (message != NULL, FALSE);
4005 _dbus_return_val_if_fail (signature != NULL, FALSE);
4006 /* don't check that signature is valid since it would be expensive,
4007 * and not catch many common errors
4008 */
4009
4010 s = dbus_message_get_signature (message);
4011
4012 if (s && strcmp (s, signature) == 0)
4013 return TRUE;
4014 else
4015 return FALSE;
4016}
4017
4040dbus_bool_t
4041dbus_set_error_from_message (DBusError *error,
4042 DBusMessage *message)
4043{
4044 const char *str;
4045
4046 _dbus_return_val_if_fail (message != NULL, FALSE);
4047 _dbus_return_val_if_error_is_set (error, FALSE);
4048
4049 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
4050 return FALSE;
4051
4052 str = NULL;
4053 dbus_message_get_args (message, NULL,
4054 DBUS_TYPE_STRING, &str,
4055 DBUS_TYPE_INVALID);
4056
4057 dbus_set_error (error, dbus_message_get_error_name (message),
4058 str ? "%s" : NULL, str);
4059
4060 return TRUE;
4061}
4062
4069dbus_bool_t
4070dbus_message_contains_unix_fds(DBusMessage *message)
4071{
4072#ifdef HAVE_UNIX_FD_PASSING
4073 _dbus_assert(message);
4074
4075 return message->n_unix_fds > 0;
4076#else
4077 return FALSE;
4078#endif
4079}
4080
4091dbus_bool_t
4092dbus_message_set_container_instance (DBusMessage *message,
4093 const char *object_path)
4094{
4095 _dbus_return_val_if_fail (message != NULL, FALSE);
4096 _dbus_return_val_if_fail (!message->locked, FALSE);
4097 _dbus_return_val_if_fail (object_path == NULL ||
4098 _dbus_check_is_valid_path (object_path),
4099 FALSE);
4100
4101 return set_or_delete_string_field (message,
4102 DBUS_HEADER_FIELD_CONTAINER_INSTANCE,
4103 DBUS_TYPE_OBJECT_PATH,
4104 object_path);
4105}
4106
4117const char *
4118dbus_message_get_container_instance (DBusMessage *message)
4119{
4120 const char *v;
4121
4122 _dbus_return_val_if_fail (message != NULL, NULL);
4123
4124 v = NULL; /* in case field doesn't exist */
4125 _dbus_header_get_field_basic (&message->header,
4126 DBUS_HEADER_FIELD_CONTAINER_INSTANCE,
4127 DBUS_TYPE_OBJECT_PATH,
4128 (void *) &v);
4129 return v;
4130}
4131
4150#define INITIAL_LOADER_DATA_LEN 32
4151
4158 DBusMessageLoader*
4159_dbus_message_loader_new (void)
4160{
4161 DBusMessageLoader *loader;
4162
4163 loader = dbus_new0 (DBusMessageLoader, 1);
4164 if (loader == NULL)
4165 return NULL;
4166
4167 loader->refcount = 1;
4168
4169 loader->corrupted = FALSE;
4170 loader->corruption_reason = DBUS_VALID;
4171
4172 /* this can be configured by the app, but defaults to the protocol max */
4173 loader->max_message_size = DBUS_MAXIMUM_MESSAGE_LENGTH;
4174
4175 /* We set a very relatively conservative default here since due to how
4176 SCM_RIGHTS works we need to preallocate an fd array of the maximum
4177 number of unix fds we want to receive in advance. A
4178 try-and-reallocate loop is not possible. */
4179 loader->max_message_unix_fds = DBUS_DEFAULT_MESSAGE_UNIX_FDS;
4180
4181 if (!_dbus_string_init (&loader->data))
4182 {
4183 dbus_free (loader);
4184 return NULL;
4185 }
4186
4187 /* preallocate the buffer for speed, ignore failure */
4188 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
4189 _dbus_string_set_length (&loader->data, 0);
4190
4191#ifdef HAVE_UNIX_FD_PASSING
4192 loader->unix_fds = NULL;
4193 loader->n_unix_fds = loader->n_unix_fds_allocated = 0;
4194 loader->unix_fds_outstanding = FALSE;
4195#endif
4196
4197 return loader;
4198}
4199
4206 DBusMessageLoader *
4207_dbus_message_loader_ref (DBusMessageLoader *loader)
4208{
4209 loader->refcount += 1;
4210
4211 return loader;
4212}
4213
4220void
4221_dbus_message_loader_unref (DBusMessageLoader *loader)
4222{
4223 loader->refcount -= 1;
4224 if (loader->refcount == 0)
4225 {
4226#ifdef HAVE_UNIX_FD_PASSING
4227 close_unix_fds(loader->unix_fds, &loader->n_unix_fds);
4228 dbus_free(loader->unix_fds);
4229#endif
4230 _dbus_list_clear_full (&loader->messages,
4231 (DBusFreeFunction) dbus_message_unref);
4232 _dbus_string_free (&loader->data);
4233 dbus_free (loader);
4234 }
4235}
4236
4255void
4256_dbus_message_loader_get_buffer (DBusMessageLoader *loader,
4257 DBusString **buffer,
4258 int *max_to_read,
4259 dbus_bool_t *may_read_fds)
4260{
4261 _dbus_assert (!loader->buffer_outstanding);
4262
4263 *buffer = &loader->data;
4264
4265 loader->buffer_outstanding = TRUE;
4266
4267 if (max_to_read != NULL)
4268 {
4269#ifdef HAVE_UNIX_FD_PASSING
4270 int offset = 0;
4271 int remain;
4272 int byte_order;
4273 int fields_array_len;
4274 int header_len;
4275 int body_len;
4276#endif
4277
4278 *max_to_read = DBUS_MAXIMUM_MESSAGE_LENGTH;
4279 *may_read_fds = TRUE;
4280
4281#ifdef HAVE_UNIX_FD_PASSING
4282 /* If we aren't holding onto any fds, we can read as much as we want
4283 * (fast path). */
4284 if (loader->n_unix_fds == 0)
4285 return;
4286
4287 /* Slow path: we have a message with some fds in it. We don't want
4288 * to start on the next message until this one is out of the way;
4289 * otherwise a legitimate sender can keep us processing messages
4290 * containing fds, until we disconnect it for having had fds pending
4291 * for too long, a limit that is in place to stop malicious senders
4292 * from setting up recursive fd-passing that takes up our quota and
4293 * will never go away. */
4294
4295 remain = _dbus_string_get_length (&loader->data);
4296
4297 while (remain > 0)
4298 {
4299 DBusValidity validity = DBUS_VALIDITY_UNKNOWN;
4300 int needed;
4301
4302 /* If 0 < remain < DBUS_MINIMUM_HEADER_SIZE, then we've had at
4303 * least the first byte of a message, but we don't know how
4304 * much more to read. Only read the rest of the
4305 * DBUS_MINIMUM_HEADER_SIZE for now; then we'll know. */
4306 if (remain < DBUS_MINIMUM_HEADER_SIZE)
4307 {
4308 *max_to_read = DBUS_MINIMUM_HEADER_SIZE - remain;
4309 *may_read_fds = FALSE;
4310 return;
4311 }
4312
4313 if (!_dbus_header_have_message_untrusted (loader->max_message_size,
4314 &validity,
4315 &byte_order,
4316 &fields_array_len,
4317 &header_len,
4318 &body_len,
4319 &loader->data,
4320 offset,
4321 remain))
4322 {
4323 /* If a message in the buffer is invalid, we're going to
4324 * disconnect the sender anyway, so reading an arbitrary amount
4325 * is fine. */
4326 if (validity != DBUS_VALID)
4327 return;
4328
4329 /* We have a partial message, with the
4330 * DBUS_MINIMUM_HEADER_SIZE-byte fixed part of the header (which
4331 * lets us work out how much more we need), but no more. Read
4332 * the rest of the message. */
4333 needed = header_len + body_len;
4334 _dbus_assert (needed > remain);
4335 *max_to_read = needed - remain;
4336 *may_read_fds = FALSE;
4337 return;
4338 }
4339
4340 /* Skip over entire messages until we have less than a message
4341 * remaining. */
4342 needed = header_len + body_len;
4343 _dbus_assert (needed > DBUS_MINIMUM_HEADER_SIZE);
4344 _dbus_assert (remain >= needed);
4345 remain -= needed;
4346 offset += needed;
4347 }
4348#endif
4349 }
4350}
4351
4361void
4362_dbus_message_loader_return_buffer (DBusMessageLoader *loader,
4363 DBusString *buffer)
4364{
4365 _dbus_assert (loader->buffer_outstanding);
4366 _dbus_assert (buffer == &loader->data);
4367
4368 loader->buffer_outstanding = FALSE;
4369}
4370
4371#ifdef HAVE_UNIX_FD_PASSING
4382dbus_bool_t
4383_dbus_message_loader_get_unix_fds(DBusMessageLoader *loader,
4384 int **fds,
4385 unsigned *max_n_fds)
4386{
4387 _dbus_assert (!loader->unix_fds_outstanding);
4388
4389 /* Allocate space where we can put the fds we read. We allocate
4390 space for max_message_unix_fds since this is an
4391 upper limit how many fds can be received within a single
4392 message. Since SCM_RIGHTS doesn't allow a reallocate+retry logic
4393 we are allocating the maximum possible array size right from the
4394 beginning. This sucks a bit, however unless SCM_RIGHTS is fixed
4395 there is no better way. */
4396
4397 if (loader->n_unix_fds_allocated < loader->max_message_unix_fds)
4398 {
4399 int *a = dbus_realloc(loader->unix_fds,
4400 loader->max_message_unix_fds * sizeof(loader->unix_fds[0]));
4401
4402 if (!a)
4403 return FALSE;
4404
4405 loader->unix_fds = a;
4406 loader->n_unix_fds_allocated = loader->max_message_unix_fds;
4407 }
4408
4409 *fds = loader->unix_fds + loader->n_unix_fds;
4410 *max_n_fds = loader->n_unix_fds_allocated - loader->n_unix_fds;
4411
4412 loader->unix_fds_outstanding = TRUE;
4413 return TRUE;
4414}
4415
4426void
4427_dbus_message_loader_return_unix_fds(DBusMessageLoader *loader,
4428 int *fds,
4429 unsigned n_fds)
4430{
4431 _dbus_assert(loader->unix_fds_outstanding);
4432 _dbus_assert(loader->unix_fds + loader->n_unix_fds == fds);
4433 _dbus_assert(loader->n_unix_fds + n_fds <= loader->n_unix_fds_allocated);
4434
4435 loader->n_unix_fds += n_fds;
4436 loader->unix_fds_outstanding = FALSE;
4437
4438 if (n_fds && loader->unix_fds_change)
4439 loader->unix_fds_change (loader->unix_fds_change_data);
4440}
4441#endif
4442
4443/*
4444 * FIXME when we move the header out of the buffer, that memmoves all
4445 * buffered messages. Kind of crappy.
4446 *
4447 * Also we copy the header and body, which is kind of crappy. To
4448 * avoid this, we have to allow header and body to be in a single
4449 * memory block, which is good for messages we read and bad for
4450 * messages we are creating. But we could move_len() the buffer into
4451 * this single memory block, and move_len() will just swap the buffers
4452 * if you're moving the entire buffer replacing the dest string.
4453 *
4454 * We could also have the message loader tell the transport how many
4455 * bytes to read; so it would first ask for some arbitrary number like
4456 * 256, then if the message was incomplete it would use the
4457 * header/body len to ask for exactly the size of the message (or
4458 * blocks the size of a typical kernel buffer for the socket). That
4459 * way we don't get trailing bytes in the buffer that have to be
4460 * memmoved. Though I suppose we also don't have a chance of reading a
4461 * bunch of small messages at once, so the optimization may be stupid.
4462 *
4463 * Another approach would be to keep a "start" index into
4464 * loader->data and only delete it occasionally, instead of after
4465 * each message is loaded.
4466 *
4467 * load_message() returns FALSE if not enough memory OR the loader was corrupted
4468 */
4469static dbus_bool_t
4470load_message (DBusMessageLoader *loader,
4471 DBusMessage *message,
4472 int byte_order,
4473 int fields_array_len,
4474 int header_len,
4475 int body_len)
4476{
4477 dbus_bool_t oom;
4478 DBusValidity validity;
4479 const DBusString *type_str;
4480 int type_pos;
4481 DBusValidationMode mode;
4482 dbus_uint32_t n_unix_fds = 0;
4483
4484 mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
4485
4486 oom = FALSE;
4487
4488#if 0
4489 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len /* + body_len */);
4490#endif
4491
4492 /* 1. VALIDATE AND COPY OVER HEADER */
4493 _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
4494 _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
4495
4496 if (!_dbus_header_load (&message->header,
4497 mode,
4498 &validity,
4499 byte_order,
4500 fields_array_len,
4501 header_len,
4502 body_len,
4503 &loader->data))
4504 {
4505 _dbus_verbose ("Failed to load header for new message code %d\n", validity);
4506
4507 /* assert here so we can catch any code that still uses DBUS_VALID to indicate
4508 oom errors. They should use DBUS_VALIDITY_UNKNOWN_OOM_ERROR instead */
4509 _dbus_assert (validity != DBUS_VALID);
4510
4511 if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
4512 oom = TRUE;
4513 else
4514 {
4515 loader->corrupted = TRUE;
4516 loader->corruption_reason = validity;
4517 }
4518 goto failed;
4519 }
4520
4521 _dbus_assert (validity == DBUS_VALID);
4522
4523 /* 2. VALIDATE BODY */
4524 if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
4525 {
4526 get_const_signature (&message->header, &type_str, &type_pos);
4527
4528 /* Because the bytes_remaining arg is NULL, this validates that the
4529 * body is the right length
4530 */
4531 validity = _dbus_validate_body_with_reason (type_str,
4532 type_pos,
4533 byte_order,
4534 NULL,
4535 &loader->data,
4536 header_len,
4537 body_len);
4538 if (validity != DBUS_VALID)
4539 {
4540 _dbus_verbose ("Failed to validate message body code %d\n", validity);
4541
4542 loader->corrupted = TRUE;
4543 loader->corruption_reason = validity;
4544
4545 goto failed;
4546 }
4547 }
4548
4549 /* 3. COPY OVER UNIX FDS */
4550 _dbus_header_get_field_basic(&message->header,
4551 DBUS_HEADER_FIELD_UNIX_FDS,
4552 DBUS_TYPE_UINT32,
4553 &n_unix_fds);
4554
4555#ifdef HAVE_UNIX_FD_PASSING
4556
4557 if (n_unix_fds > loader->n_unix_fds)
4558 {
4559 _dbus_verbose("Message contains references to more unix fds than were sent %u != %u\n",
4560 n_unix_fds, loader->n_unix_fds);
4561
4562 loader->corrupted = TRUE;
4563 loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4564 goto failed;
4565 }
4566
4567 /* If this was a recycled message there might still be
4568 some memory allocated for the fds */
4569 dbus_free(message->unix_fds);
4570
4571 if (n_unix_fds > 0)
4572 {
4573 message->unix_fds = _dbus_memdup(loader->unix_fds, n_unix_fds * sizeof(message->unix_fds[0]));
4574 if (message->unix_fds == NULL)
4575 {
4576 _dbus_verbose ("Failed to allocate file descriptor array\n");
4577 oom = TRUE;
4578 goto failed;
4579 }
4580
4581 message->n_unix_fds_allocated = message->n_unix_fds = n_unix_fds;
4582 loader->n_unix_fds -= n_unix_fds;
4583 memmove (loader->unix_fds, loader->unix_fds + n_unix_fds, loader->n_unix_fds * sizeof (loader->unix_fds[0]));
4584
4585 if (loader->unix_fds_change)
4586 loader->unix_fds_change (loader->unix_fds_change_data);
4587 }
4588 else
4589 message->unix_fds = NULL;
4590
4591#else
4592
4593 if (n_unix_fds > 0)
4594 {
4595 _dbus_verbose ("Hmm, message claims to come with file descriptors "
4596 "but that's not supported on our platform, disconnecting.\n");
4597
4598 loader->corrupted = TRUE;
4599 loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4600 goto failed;
4601 }
4602
4603#endif
4604
4605 /* 3. COPY OVER BODY AND QUEUE MESSAGE */
4606
4607 if (!_dbus_list_append (&loader->messages, message))
4608 {
4609 _dbus_verbose ("Failed to append new message to loader queue\n");
4610 oom = TRUE;
4611 goto failed;
4612 }
4613
4614 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
4615 _dbus_assert (_dbus_string_get_length (&loader->data) >=
4616 (header_len + body_len));
4617
4618 if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
4619 {
4620 _dbus_verbose ("Failed to move body into new message\n");
4621 oom = TRUE;
4622 goto failed;
4623 }
4624
4625 _dbus_string_delete (&loader->data, 0, header_len + body_len);
4626
4627 /* don't waste more than 2k of memory */
4628 _dbus_string_compact (&loader->data, 2048);
4629
4630 _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
4631 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
4632
4633 _dbus_verbose ("Loaded message %p\n", message);
4634
4635 _dbus_assert (!oom);
4636 _dbus_assert (!loader->corrupted);
4637 _dbus_assert (loader->messages != NULL);
4638 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4639
4640 return TRUE;
4641
4642 failed:
4643
4644 /* Clean up */
4645
4646 /* does nothing if the message isn't in the list */
4647 _dbus_list_remove_last (&loader->messages, message);
4648
4649 if (oom)
4650 _dbus_assert (!loader->corrupted);
4651 else
4652 _dbus_assert (loader->corrupted);
4653
4654 _dbus_verbose_bytes_of_string (&loader->data, 0, _dbus_string_get_length (&loader->data));
4655
4656 return FALSE;
4657}
4658
4673dbus_bool_t
4674_dbus_message_loader_queue_messages (DBusMessageLoader *loader)
4675{
4676 while (!loader->corrupted &&
4677 _dbus_string_get_length (&loader->data) >= DBUS_MINIMUM_HEADER_SIZE)
4678 {
4679 DBusValidity validity;
4680 int byte_order, fields_array_len, header_len, body_len;
4681
4682 if (_dbus_header_have_message_untrusted (loader->max_message_size,
4683 &validity,
4684 &byte_order,
4685 &fields_array_len,
4686 &header_len,
4687 &body_len,
4688 &loader->data, 0,
4689 _dbus_string_get_length (&loader->data)))
4690 {
4691 DBusMessage *message;
4692
4693 _dbus_assert (validity == DBUS_VALID);
4694
4695 message = dbus_message_new_empty_header ();
4696 if (message == NULL)
4697 return FALSE;
4698
4699 if (!load_message (loader, message,
4700 byte_order, fields_array_len,
4701 header_len, body_len))
4702 {
4703 dbus_message_unref (message);
4704 /* load_message() returns false if corrupted or OOM; if
4705 * corrupted then return TRUE for not OOM
4706 */
4707 return loader->corrupted;
4708 }
4709
4710 _dbus_assert (loader->messages != NULL);
4711 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4712 }
4713 else
4714 {
4715 _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
4716 validity);
4717 if (validity != DBUS_VALID)
4718 {
4719 loader->corrupted = TRUE;
4720 loader->corruption_reason = validity;
4721 }
4722 return TRUE;
4723 }
4724 }
4725
4726 return TRUE;
4727}
4728
4736 DBusMessage*
4737_dbus_message_loader_peek_message (DBusMessageLoader *loader)
4738{
4739 if (loader->messages)
4740 return loader->messages->data;
4741 else
4742 return NULL;
4743}
4744
4753 DBusMessage*
4754_dbus_message_loader_pop_message (DBusMessageLoader *loader)
4755{
4756 return _dbus_list_pop_first (&loader->messages);
4757}
4758
4767 DBusList*
4768_dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
4769{
4770 return _dbus_list_pop_first_link (&loader->messages);
4771}
4772
4779void
4780_dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
4781 DBusList *link)
4782{
4783 _dbus_list_prepend_link (&loader->messages, link);
4784}
4785
4795dbus_bool_t
4796_dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
4797{
4798 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
4799 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
4800 return loader->corrupted;
4801}
4802
4809 DBusValidity
4810_dbus_message_loader_get_corruption_reason (DBusMessageLoader *loader)
4811{
4812 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
4813 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
4814
4815 return loader->corruption_reason;
4816}
4817
4824void
4825_dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
4826 long size)
4827{
4828 if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
4829 {
4830 _dbus_verbose ("clamping requested max message size %ld to %d\n",
4831 size, DBUS_MAXIMUM_MESSAGE_LENGTH);
4832 size = DBUS_MAXIMUM_MESSAGE_LENGTH;
4833 }
4834 loader->max_message_size = size;
4835}
4836
4843long
4844_dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
4845{
4846 return loader->max_message_size;
4847}
4848
4855void
4856_dbus_message_loader_set_max_message_unix_fds (DBusMessageLoader *loader,
4857 long n)
4858{
4859 if (n > DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
4860 {
4861 _dbus_verbose ("clamping requested max message unix_fds %ld to %d\n",
4862 n, DBUS_MAXIMUM_MESSAGE_UNIX_FDS);
4863 n = DBUS_MAXIMUM_MESSAGE_UNIX_FDS;
4864 }
4865 loader->max_message_unix_fds = n;
4866}
4867
4874long
4875_dbus_message_loader_get_max_message_unix_fds (DBusMessageLoader *loader)
4876{
4877 return loader->max_message_unix_fds;
4878}
4879
4885int
4886_dbus_message_loader_get_pending_fds_count (DBusMessageLoader *loader)
4887{
4888#ifdef HAVE_UNIX_FD_PASSING
4889 return loader->n_unix_fds;
4890#else
4891 return 0;
4892#endif
4893}
4894
4903void
4904_dbus_message_loader_set_pending_fds_function (DBusMessageLoader *loader,
4905 void (* callback) (void *),
4906 void *data)
4907{
4908#ifdef HAVE_UNIX_FD_PASSING
4909 loader->unix_fds_change = callback;
4910 loader->unix_fds_change_data = data;
4911#endif
4912}
4913
4914static DBusDataSlotAllocator slot_allocator =
4915 _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (message_slots));
4916
4931dbus_bool_t
4932dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
4933{
4934 return _dbus_data_slot_allocator_alloc (&slot_allocator,
4935 slot_p);
4936}
4937
4949void
4950dbus_message_free_data_slot (dbus_int32_t *slot_p)
4951{
4952 _dbus_return_if_fail (*slot_p >= 0);
4953
4954 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
4955}
4956
4970dbus_bool_t
4971dbus_message_set_data (DBusMessage *message,
4972 dbus_int32_t slot,
4973 void *data,
4974 DBusFreeFunction free_data_func)
4975{
4976 DBusFreeFunction old_free_func;
4977 void *old_data;
4978 dbus_bool_t retval;
4979
4980 _dbus_return_val_if_fail (message != NULL, FALSE);
4981 _dbus_return_val_if_fail (slot >= 0, FALSE);
4982
4983 retval = _dbus_data_slot_list_set (&slot_allocator,
4984 &message->slot_list,
4985 slot, data, free_data_func,
4986 &old_free_func, &old_data);
4987
4988 if (retval)
4989 {
4990 /* Do the actual free outside the message lock */
4991 if (old_free_func)
4992 (* old_free_func) (old_data);
4993 }
4994
4995 return retval;
4996}
4997
5006void*
5007dbus_message_get_data (DBusMessage *message,
5008 dbus_int32_t slot)
5009{
5010 void *res;
5011
5012 _dbus_return_val_if_fail (message != NULL, NULL);
5013
5014 res = _dbus_data_slot_list_get (&slot_allocator,
5015 &message->slot_list,
5016 slot);
5017
5018 return res;
5019}
5020
5034int
5035dbus_message_type_from_string (const char *type_str)
5036{
5037 if (strcmp (type_str, "method_call") == 0)
5038 return DBUS_MESSAGE_TYPE_METHOD_CALL;
5039 if (strcmp (type_str, "method_return") == 0)
5040 return DBUS_MESSAGE_TYPE_METHOD_RETURN;
5041 else if (strcmp (type_str, "signal") == 0)
5042 return DBUS_MESSAGE_TYPE_SIGNAL;
5043 else if (strcmp (type_str, "error") == 0)
5044 return DBUS_MESSAGE_TYPE_ERROR;
5045 else
5046 return DBUS_MESSAGE_TYPE_INVALID;
5047}
5048
5062const char *
5063dbus_message_type_to_string (int type)
5064{
5065 switch (type)
5066 {
5067 case DBUS_MESSAGE_TYPE_METHOD_CALL:
5068 return "method_call";
5069 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
5070 return "method_return";
5071 case DBUS_MESSAGE_TYPE_SIGNAL:
5072 return "signal";
5073 case DBUS_MESSAGE_TYPE_ERROR:
5074 return "error";
5075 default:
5076 return "invalid";
5077 }
5078}
5079
5092dbus_bool_t
5093dbus_message_marshal (DBusMessage *msg,
5094 char **marshalled_data_p,
5095 int *len_p)
5096{
5097 DBusString tmp;
5098 dbus_bool_t was_locked;
5099
5100 _dbus_return_val_if_fail (msg != NULL, FALSE);
5101 _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
5102 _dbus_return_val_if_fail (len_p != NULL, FALSE);
5103
5104 if (!_dbus_string_init (&tmp))
5105 return FALSE;
5106
5107 /* Ensure the message is locked, to ensure the length header is filled in. */
5108 was_locked = msg->locked;
5109
5110 if (!was_locked)
5111 dbus_message_lock (msg);
5112
5113 if (!_dbus_string_copy (&(msg->header.data), 0, &tmp, 0))
5114 goto fail;
5115
5116 *len_p = _dbus_string_get_length (&tmp);
5117
5118 if (!_dbus_string_copy (&(msg->body), 0, &tmp, *len_p))
5119 goto fail;
5120
5121 *len_p = _dbus_string_get_length (&tmp);
5122
5123 if (!_dbus_string_steal_data (&tmp, marshalled_data_p))
5124 goto fail;
5125
5126 _dbus_string_free (&tmp);
5127
5128 if (!was_locked)
5129 msg->locked = FALSE;
5130
5131 return TRUE;
5132
5133 fail:
5134 _dbus_string_free (&tmp);
5135
5136 if (!was_locked)
5137 msg->locked = FALSE;
5138
5139 return FALSE;
5140}
5141
5154 DBusMessage *
5155dbus_message_demarshal (const char *str,
5156 int len,
5157 DBusError *error)
5158{
5159 DBusMessageLoader *loader = NULL;
5160 DBusString *buffer;
5161 DBusMessage *msg;
5162
5163 _dbus_return_val_if_fail (str != NULL, NULL);
5164
5165 loader = _dbus_message_loader_new ();
5166
5167 if (loader == NULL)
5168 goto fail_oom;
5169
5170 _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL);
5171
5172 if (!_dbus_string_append_len (buffer, str, len))
5173 goto fail_oom;
5174
5175 _dbus_message_loader_return_buffer (loader, buffer);
5176
5177 if (!_dbus_message_loader_queue_messages (loader))
5178 goto fail_oom;
5179
5180 if (_dbus_message_loader_get_is_corrupted (loader))
5181 goto fail_corrupt;
5182
5183 msg = _dbus_message_loader_pop_message (loader);
5184
5185 if (!msg)
5186 goto fail_oom;
5187
5188 _dbus_message_loader_unref (loader);
5189 return msg;
5190
5191 fail_corrupt:
5192 if (loader->corruption_reason == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
5193 goto fail_oom;
5194
5195 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted (%s)",
5196 _dbus_validity_to_error_message (loader->corruption_reason));
5197 _dbus_message_loader_unref (loader);
5198 return NULL;
5199
5200 fail_oom:
5201 _DBUS_SET_OOM (error);
5202
5203 if (loader != NULL)
5204 _dbus_message_loader_unref (loader);
5205
5206 return NULL;
5207}
5208
5221int
5222dbus_message_demarshal_bytes_needed(const char *buf,
5223 int len)
5224{
5225 DBusString str;
5226 int byte_order, fields_array_len, header_len, body_len;
5227 DBusValidity validity = DBUS_VALID;
5228 int have_message;
5229
5230 if (!buf || len < DBUS_MINIMUM_HEADER_SIZE)
5231 return 0;
5232
5233 if (len > DBUS_MAXIMUM_MESSAGE_LENGTH)
5234 len = DBUS_MAXIMUM_MESSAGE_LENGTH;
5235 _dbus_string_init_const_len (&str, buf, len);
5236
5237 validity = DBUS_VALID;
5238 have_message
5239 = _dbus_header_have_message_untrusted(DBUS_MAXIMUM_MESSAGE_LENGTH,
5240 &validity, &byte_order,
5241 &fields_array_len,
5242 &header_len,
5243 &body_len,
5244 &str, 0,
5245 len);
5246 _dbus_string_free (&str);
5247
5248 if (validity == DBUS_VALID)
5249 {
5250 _dbus_assert (have_message || (header_len + body_len) > len);
5251 (void) have_message; /* unused unless asserting */
5252 return header_len + body_len;
5253 }
5254 else
5255 {
5256 return -1; /* broken! */
5257 }
5258}
5259
5281void
5282dbus_message_set_allow_interactive_authorization (DBusMessage *message,
5283 dbus_bool_t allow)
5284{
5285 _dbus_return_if_fail (message != NULL);
5286 _dbus_return_if_fail (!message->locked);
5287
5288 _dbus_header_toggle_flag (&message->header,
5289 DBUS_HEADER_FLAG_ALLOW_INTERACTIVE_AUTHORIZATION,
5290 allow);
5291}
5292
5299dbus_bool_t
5300dbus_message_get_allow_interactive_authorization (DBusMessage *message)
5301{
5302 _dbus_return_val_if_fail (message != NULL, FALSE);
5303
5304 return _dbus_header_get_flag (&message->header,
5305 DBUS_HEADER_FLAG_ALLOW_INTERACTIVE_AUTHORIZATION);
5306}
5307
5314 struct DBusVariant
5315{
5316 DBusString data;
5317};
5318
5330 DBusVariant *
5331_dbus_variant_read (DBusMessageIter *reader)
5332{
5333 DBusVariant *self = NULL;
5334 /* Points to the single item we will read from the reader */
5335 DBusMessageRealIter *real_reader = (DBusMessageRealIter *) reader;
5336 /* The position in self at which we will write a single variant
5337 * (it is position 0) */
5338 DBusTypeWriter items_writer;
5339 /* The position in self at which we will write a copy of reader
5340 * (it is inside the variant) */
5341 DBusTypeWriter variant_writer;
5342 /* 'v' */
5343 DBusString variant_signature;
5344 /* Whatever is the signature of the item we will copy from the reader */
5345 DBusString contained_signature;
5346 /* TRUE if self->data needs to be freed */
5347 dbus_bool_t data_inited = FALSE;
5348 /* The type of the item we will read from the reader */
5349 int type;
5350 /* The string, start position within that string, and length of the signature
5351 * of the single complete type of the item reader points to */
5352 const DBusString *sig;
5353 int start, len;
5354
5355 _dbus_assert (_dbus_message_iter_check (real_reader));
5356 _dbus_assert (real_reader->iter_type == DBUS_MESSAGE_ITER_TYPE_READER);
5357 _dbus_string_init_const (&variant_signature, DBUS_TYPE_VARIANT_AS_STRING);
5358 type = dbus_message_iter_get_arg_type (reader);
5359 _dbus_type_reader_get_signature (&real_reader->u.reader, &sig, &start, &len);
5360
5361 if (!_dbus_string_init (&contained_signature))
5362 return NULL;
5363
5364 if (!_dbus_string_copy_len (sig, start, len, &contained_signature, 0))
5365 goto oom;
5366
5367 self = dbus_new0 (DBusVariant, 1);
5368
5369 if (self == NULL)
5370 goto oom;
5371
5372 if (!_dbus_string_init (&self->data))
5373 goto oom;
5374
5375 data_inited = TRUE;
5376
5377 _dbus_type_writer_init_values_only (&items_writer, DBUS_COMPILER_BYTE_ORDER,
5378 &variant_signature, 0, &self->data, 0);
5379
5380 if (!_dbus_type_writer_recurse (&items_writer, DBUS_TYPE_VARIANT,
5381 &contained_signature, 0, &variant_writer))
5382 goto oom;
5383
5384 if (type == DBUS_TYPE_ARRAY)
5385 {
5386 /* Points to each item in turn inside the array we are copying */
5387 DBusMessageIter array_reader;
5388 /* Same as array_reader */
5389 DBusMessageRealIter *real_array_reader = (DBusMessageRealIter *) &array_reader;
5390 /* The position inside the copied array at which we will write
5391 * the copy of array_reader */
5392 DBusTypeWriter array_writer;
5393
5394 dbus_message_iter_recurse (reader, &array_reader);
5395
5396 if (!_dbus_type_writer_recurse (&variant_writer, type,
5397 &contained_signature, 1, &array_writer))
5398 goto oom;
5399
5400 if (!_dbus_type_writer_write_reader (&array_writer,
5401 &real_array_reader->u.reader))
5402 goto oom;
5403
5404 if (!_dbus_type_writer_unrecurse (&variant_writer, &array_writer))
5405 goto oom;
5406 }
5407 else if (type == DBUS_TYPE_DICT_ENTRY || type == DBUS_TYPE_VARIANT ||
5408 type == DBUS_TYPE_STRUCT)
5409 {
5410 /* Points to each item in turn inside the container we are copying */
5411 DBusMessageIter inner_reader;
5412 /* Same as inner_reader */
5413 DBusMessageRealIter *real_inner_reader = (DBusMessageRealIter *) &inner_reader;
5414 /* The position inside the copied container at which we will write the
5415 * copy of inner_reader */
5416 DBusTypeWriter inner_writer;
5417
5418 dbus_message_iter_recurse (reader, &inner_reader);
5419
5420 if (!_dbus_type_writer_recurse (&variant_writer, type, NULL, 0,
5421 &inner_writer))
5422 goto oom;
5423
5424 if (!_dbus_type_writer_write_reader (&inner_writer,
5425 &real_inner_reader->u.reader))
5426 goto oom;
5427
5428 if (!_dbus_type_writer_unrecurse (&variant_writer, &inner_writer))
5429 goto oom;
5430 }
5431 else
5432 {
5433 DBusBasicValue value;
5434
5435 /* We eliminated all the container types above */
5436 _dbus_assert (dbus_type_is_basic (type));
5437
5438 dbus_message_iter_get_basic (reader, &value);
5439
5440 if (!_dbus_type_writer_write_basic (&variant_writer, type, &value))
5441 goto oom;
5442 }
5443
5444 _dbus_string_free (&contained_signature);
5445 return self;
5446
5447oom:
5448 if (self != NULL)
5449 {
5450 if (data_inited)
5451 _dbus_string_free (&self->data);
5452
5453 dbus_free (self);
5454 }
5455
5456 _dbus_string_free (&contained_signature);
5457 return NULL;
5458}
5459
5466const char *
5467_dbus_variant_get_signature (DBusVariant *self)
5468{
5469 unsigned char len;
5470 const char *ret;
5471
5472 _dbus_assert (self != NULL);
5473
5474 /* Here we make use of the fact that the serialization of a variant starts
5475 * with the 1-byte length, then that many bytes of signature, then \0. */
5476 len = _dbus_string_get_byte (&self->data, 0);
5477 ret = _dbus_string_get_const_data_len (&self->data, 1, len);
5478 _dbus_assert (strlen (ret) == len);
5479 return ret;
5480}
5481
5493dbus_bool_t
5494_dbus_variant_write (DBusVariant *self,
5495 DBusMessageIter *writer)
5496{
5497 /* 'v' */
5498 DBusString variant_signature;
5499 /* Points to the single item in self */
5500 DBusTypeReader variant_reader;
5501 /* Points to the single item (of whatever type) inside the variant */
5502 DBusTypeReader reader;
5503 /* The position at which we will copy reader */
5504 DBusMessageRealIter *real_writer = (DBusMessageRealIter *) writer;
5505 dbus_bool_t ret;
5506
5507 _dbus_assert (self != NULL);
5508 _dbus_assert (_dbus_message_iter_append_check (real_writer));
5509 _dbus_assert (real_writer->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
5510
5511 _dbus_string_init_const (&variant_signature, DBUS_TYPE_VARIANT_AS_STRING);
5512 _dbus_type_reader_init (&reader, DBUS_COMPILER_BYTE_ORDER,
5513 &variant_signature, 0, &self->data, 0);
5514 _dbus_type_reader_recurse (&reader, &variant_reader);
5515
5516 if (!_dbus_message_iter_open_signature (real_writer))
5517 return FALSE;
5518
5519 ret = _dbus_type_writer_write_reader (&real_writer->u.writer,
5520 &variant_reader);
5521
5522 if (!_dbus_message_iter_close_signature (real_writer))
5523 return FALSE;
5524
5525 return ret;
5526}
5527
5528int
5529_dbus_variant_get_length (DBusVariant *self)
5530{
5531 _dbus_assert (self != NULL);
5532 return _dbus_string_get_length (&self->data);
5533}
5534
5535const DBusString *
5536_dbus_variant_peek (DBusVariant *self)
5537{
5538 _dbus_assert (self != NULL);
5539 return &self->data;
5540}
5541
5542void
5543_dbus_variant_free (DBusVariant *self)
5544{
5545 _dbus_assert (self != NULL);
5546 _dbus_string_free (&self->data);
5547 dbus_free (self);
5548}
5549
5552/* tests in dbus-message-util.c */
_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:155
_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:318
_dbus_data_slot_list_init
void _dbus_data_slot_list_init(DBusDataSlotList *list)
Initializes a slot list.
Definition dbus-dataslot.c:198
_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:341
_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:286
_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:222
_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:70
dbus_error_init
void dbus_error_init(DBusError *error)
Initializes a DBusError structure.
Definition dbus-errors.c:188
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_error_free
void dbus_error_free(DBusError *error)
Frees an error that's been set (or just initialized), then reinitializes the error as in dbus_error_i...
Definition dbus-errors.c:211
_dbus_assert_not_reached
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
Definition dbus-internals.h:164
_dbus_assert
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
Definition dbus-internals.h:153
_DBUS_UNLOCK
#define _DBUS_UNLOCK(name)
Unlocks a global lock.
Definition dbus-internals.h:422
_DBUS_LOCK
#define _DBUS_LOCK(name)
Locks a global lock, initializing it first if necessary.
Definition dbus-internals.h:421
_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:270
_dbus_strdup
char * _dbus_strdup(const char *str)
Duplicates a string.
Definition dbus-internals.c:589
_dbus_warn
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
Definition dbus-internals.c:238
_DBUS_LOCK_NAME
#define _DBUS_LOCK_NAME(name)
Expands to name of a global lock variable.
Definition dbus-internals.h:420
_DBUS_ZERO
#define _DBUS_ZERO(object)
Sets all bits in an object to zero.
Definition dbus-internals.h:194
_dbus_memdup
void * _dbus_memdup(const void *mem, size_t n_bytes)
Duplicates a block of memory.
Definition dbus-internals.c:617
_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:656
_dbus_list_append_link
void _dbus_list_append_link(DBusList **list, DBusList *link)
Appends a link to the list.
Definition dbus-list.c:316
_dbus_list_clear_full
void _dbus_list_clear_full(DBusList **list, DBusFreeFunction function)
Free every link and every element in the list.
Definition dbus-list.c:568
_dbus_list_remove_link
void _dbus_list_remove_link(DBusList **list, DBusList *link)
Removes a link from the list.
Definition dbus-list.c:528
_dbus_list_find_last
DBusList * _dbus_list_find_last(DBusList **list, void *data)
Finds a value in the list.
Definition dbus-list.c:473
_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:677
_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:787
_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:543
_dbus_list_prepend_link
void _dbus_list_prepend_link(DBusList **list, DBusList *link)
Prepends a link to the list.
Definition dbus-list.c:334
_dbus_list_alloc_link
DBusList * _dbus_list_alloc_link(void *data)
Allocates a linked list node.
Definition dbus-list.c:243
_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:447
_dbus_list_append
dbus_bool_t _dbus_list_append(DBusList **list, void *data)
Appends a value to the list.
Definition dbus-list.c:271
NULL
#define NULL
A null pointer, defined appropriately for C or C++.
Definition dbus-macros.h:49
TRUE
#define TRUE
Expands to "1".
Definition dbus-macros.h:39
FALSE
#define FALSE
Expands to "0".
Definition dbus-macros.h:42
_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_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's a child of the curr...
Definition dbus-marshal-recursive.c:988
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:52
_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:1205
_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:493
_dbus_validate_signature_with_reason
DBusValidity _dbus_validate_signature_with_reason(const DBusString *type_str, int type_pos, int len)
Verifies that the range of type_str from type_pos to type_end is a valid signature.
Definition dbus-marshal-validate.c:51
_dbus_type_writer_init_values_only
void _dbus_type_writer_init_values_only(DBusTypeWriter *writer, int byte_order, const DBusString *type_str, int type_pos, DBusString *value_str, int value_pos)
Like _dbus_type_writer_init(), except the type string passed in should correspond to an existing sign...
Definition dbus-marshal-recursive.c:1584
_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:1236
_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_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_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:1421
_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:1282
_dbus_header_get_message_type
int _dbus_header_get_message_type(DBusHeader *header)
Gets the type of the message.
Definition dbus-marshal-header.c:389
_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_type_writer_write_reader
dbus_bool_t _dbus_type_writer_write_reader(DBusTypeWriter *writer, DBusTypeReader *reader)
Iterate through all values in the given reader, writing a copy of each value to the writer.
Definition dbus-marshal-recursive.c:2731
_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:1360
_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
_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:1488
_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:218
_dbus_type_reader_read_fixed_multi
void _dbus_type_reader_read_fixed_multi(const DBusTypeReader *reader, const 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_header_get_byte_order
char _dbus_header_get_byte_order(const DBusHeader *header)
Returns the header's byte order.
Definition dbus-marshal-header.c:177
_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,...
Definition dbus-marshal-header.c:679
_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:446
_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_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
_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:1425
_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_remove_unknown_fields
dbus_bool_t _dbus_header_remove_unknown_fields(DBusHeader *header)
Remove every header field not known to this version of dbus.
Definition dbus-marshal-header.c:1530
_dbus_header_get_serial
dbus_uint32_t _dbus_header_get_serial(DBusHeader *header)
See dbus_message_get_serial()
Definition dbus-marshal-header.c:430
_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_reader_has_next
dbus_bool_t _dbus_type_reader_has_next(const DBusTypeReader *reader)
Check whether there's another value on this "level".
Definition dbus-marshal-recursive.c:1094
_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
_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_type_to_string
const char * _dbus_type_to_string(int typecode)
Returns a string describing the given type.
Definition dbus-marshal-basic.c:1282
_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:755
_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
_dbus_header_free
void _dbus_header_free(DBusHeader *header)
Frees a header.
Definition dbus-marshal-header.c:479
_dbus_header_init
dbus_bool_t _dbus_header_init(DBusHeader *header)
Initializes a header, but doesn't prepare it for use; to make the header valid, you have to call _dbu...
Definition dbus-marshal-header.c:463
_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:531
_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_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_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:1466
_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:407
_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)
Creates a message header from potentially-untrusted data.
Definition dbus-marshal-header.c:979
_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:1505
_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:1401
DBusValidationMode
DBusValidationMode
This is used rather than a bool for high visibility.
Definition dbus-marshal-validate.h:39
DBUS_VALIDITY_UNKNOWN_OOM_ERROR
@ DBUS_VALIDITY_UNKNOWN_OOM_ERROR
can't determine validity due to OOM
Definition dbus-marshal-validate.h:54
DBUS_VALID
@ DBUS_VALID
the data is valid
Definition dbus-marshal-validate.h:58
_dbus_current_generation
int _dbus_current_generation
_dbus_current_generation is used to track each time that dbus_shutdown() is called,...
Definition dbus-memory.c:772
_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:801
DBusFreeFunction
void(* DBusFreeFunction)(void *memory)
The type of a function which frees a block of memory.
Definition dbus-memory.h:63
dbus_free
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition dbus-memory.c:692
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:592
dbus_new
#define dbus_new(type, count)
Safe macro for using dbus_malloc().
Definition dbus-memory.h:57
dbus_new0
#define dbus_new0(type, count)
Safe macro for using dbus_malloc0().
Definition dbus-memory.h:58
dbus_free_string_array
void dbus_free_string_array(char **str_array)
Frees a NULL-terminated array of strings.
Definition dbus-memory.c:740
_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:4825
_dbus_message_remove_unknown_fields
dbus_bool_t _dbus_message_remove_unknown_fields(DBusMessage *message)
Remove every header field not known to this version of dbus.
Definition dbus-message.c:272
_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:826
_dbus_variant_read
DBusVariant * _dbus_variant_read(DBusMessageIter *reader)
Copy a single D-Bus message item from reader into a newly-allocated DBusVariant.
Definition dbus-message.c:5331
ensure_byte_order
#define ensure_byte_order(message)
byte-swap the message if it doesn't match our byte order.
Definition dbus-message.c:218
MAX_MESSAGE_SIZE_TO_CACHE
#define MAX_MESSAGE_SIZE_TO_CACHE
Avoid caching huge messages.
Definition dbus-message.c:496
_dbus_variant_write
dbus_bool_t _dbus_variant_write(DBusVariant *self, DBusMessageIter *writer)
Copy the single D-Bus message item from self into writer.
Definition dbus-message.c:5494
dbus_message_iter_init_closed
void dbus_message_iter_init_closed(DBusMessageIter *iter)
Initialize iter as if with DBUS_MESSAGE_ITER_INIT_CLOSED.
Definition dbus-message.c:743
_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:4796
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:289
dbus_message_lock
void dbus_message_lock(DBusMessage *message)
Locks a message.
Definition dbus-message.c:419
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:5035
_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:4221
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:4932
_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
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:5155
_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:4754
_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_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:4904
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_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:4971
_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:4780
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:5007
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:5063
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:5282
_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:4886
_dbus_variant_get_signature
const char * _dbus_variant_get_signature(DBusVariant *self)
Return the signature of the item stored in self.
Definition dbus-message.c:5467
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:5222
_dbus_message_loader_get_buffer
void _dbus_message_loader_get_buffer(DBusMessageLoader *loader, DBusString **buffer, int *max_to_read, dbus_bool_t *may_read_fds)
Gets the buffer to use for reading data from the network.
Definition dbus-message.c:4256
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:4950
_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:387
INITIAL_LOADER_DATA_LEN
#define INITIAL_LOADER_DATA_LEN
The initial buffer size of the message loader.
Definition dbus-message.c:4150
_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,...
Definition dbus-message.c:364
_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:4737
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:5093
_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:4856
_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:4844
_dbus_message_loader_new
DBusMessageLoader * _dbus_message_loader_new(void)
Creates a new message loader.
Definition dbus-message.c:4159
MAX_MESSAGE_CACHE_SIZE
#define MAX_MESSAGE_CACHE_SIZE
Avoid caching too many messages.
Definition dbus-message.c:499
_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:4768
_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:4674
_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:4362
_dbus_message_loader_ref
DBusMessageLoader * _dbus_message_loader_ref(DBusMessageLoader *loader)
Increments the reference count of the loader.
Definition dbus-message.c:4207
_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:4875
_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,...
Definition dbus-message.c:315
_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:4810
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:5300
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:3935
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:3443
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:3494
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,...
Definition dbus-message.c:3229
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:1863
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:3755
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:3271
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:2753
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:3341
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:3472
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:1503
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:3970
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:1156
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:3531
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:2351
dbus_message_get_type
int dbus_message_get_type(DBusMessage *message)
Gets the type of a message.
Definition dbus-message.c:1755
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:1620
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:3642
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:2168
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:1831
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:2193
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:3248
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:1457
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:2904
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:3105
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:1575
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:3902
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:4070
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:2249
dbus_message_ref
DBusMessage * dbus_message_ref(DBusMessage *message)
Increments the reference count of a DBusMessage.
Definition dbus-message.c:1700
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:3290
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:2212
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:3616
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:3999
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.
Definition dbus-message.c:2968
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: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:1406
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:1366
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:2118
dbus_message_set_sender
dbus_bool_t dbus_message_set_sender(DBusMessage *message, const char *sender)
Sets the message sender.
Definition dbus-message.c:3724
dbus_message_iter_abandon_container_if_open
void dbus_message_iter_abandon_container_if_open(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:3164
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:3695
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:3312
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:2149
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:2049
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:2274
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:1723
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:2440
dbus_message_new
DBusMessage * dbus_message_new(int message_type)
Constructs a new message of the given message type.
Definition dbus-message.c:1322
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:4041
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:2396
dbus_message_set_destination
dbus_bool_t dbus_message_set_destination(DBusMessage *message, const char *destination)
Sets the message's destination.
Definition dbus-message.c:3670
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:3365
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:3580
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:2020
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:3847
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:2485
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:1172
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:3875
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:3788
dbus_message_set_container_instance
dbus_bool_t dbus_message_set_container_instance(DBusMessage *message, const char *object_path)
Sets the container instance this message was sent from.
Definition dbus-message.c:4092
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:3071
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:3409
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:3558
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:2515
dbus_message_get_container_instance
const char * dbus_message_get_container_instance(DBusMessage *message)
Gets the container instance this message was sent from, or NULL if none.
Definition dbus-message.c:4118
_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:1245
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_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_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_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_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
DBUS_HEADER_FIELD_CONTAINER_INSTANCE
#define DBUS_HEADER_FIELD_CONTAINER_INSTANCE
Header field code for the container instance that sent this message.
Definition dbus-protocol.h:306
DBUS_TYPE_SIGNATURE
#define DBUS_TYPE_SIGNATURE
Type code marking a D-Bus type signature.
Definition dbus-protocol.h:110
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_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
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_ERROR_INCONSISTENT_MESSAGE
#define DBUS_ERROR_INCONSISTENT_MESSAGE
The message meta data does not match the payload.
Definition dbus-protocol.h:457
DBUS_HEADER_FIELD_MEMBER
#define DBUS_HEADER_FIELD_MEMBER
Header field code for a member (method or signal).
Definition dbus-protocol.h:276
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_TYPE_OBJECT_PATH
#define DBUS_TYPE_OBJECT_PATH
Type code marking a D-Bus object path.
Definition dbus-protocol.h:106
DBUS_ERROR_NOT_SUPPORTED
#define DBUS_ERROR_NOT_SUPPORTED
Requested operation isn't supported (like ENOSYS on UNIX).
Definition dbus-protocol.h:373
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_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_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_TYPE_VARIANT
#define DBUS_TYPE_VARIANT
Type code marking a D-Bus variant type.
Definition dbus-protocol.h:124
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_TYPE_UNIX_FD
#define DBUS_TYPE_UNIX_FD
Type code marking a unix file descriptor.
Definition dbus-protocol.h:114
DBUS_TYPE_BOOLEAN
#define DBUS_TYPE_BOOLEAN
Type code marking a boolean.
Definition dbus-protocol.h:70
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_TYPE_STRING
#define DBUS_TYPE_STRING
Type code marking a UTF-8 encoded, nul-terminated Unicode string.
Definition dbus-protocol.h:102
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_TYPE_ARRAY
#define DBUS_TYPE_ARRAY
Type code marking a D-Bus array type.
Definition dbus-protocol.h:120
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_TYPE_INVALID
#define DBUS_TYPE_INVALID
Type code that is never equal to a legitimate type code.
Definition dbus-protocol.h:60
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
DBUS_TYPE_VARIANT_AS_STRING
#define DBUS_TYPE_VARIANT_AS_STRING
DBUS_TYPE_VARIANT as a string literal instead of a int literal
Definition dbus-protocol.h:126
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_ERROR_INVALID_ARGS
#define DBUS_ERROR_INVALID_ARGS
Invalid arguments passed to a method call.
Definition dbus-protocol.h:395
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_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_HEADER_FIELD_DESTINATION
#define DBUS_HEADER_FIELD_DESTINATION
Header field code for the destination bus name of a message.
Definition dbus-protocol.h:288
DBUS_TYPE_STRUCT
#define DBUS_TYPE_STRUCT
STRUCT and DICT_ENTRY are sort of special since their codes can't appear in a type string,...
Definition dbus-protocol.h:136
DBUS_TYPE_UINT32
#define DBUS_TYPE_UINT32
Type code marking a 32-bit unsigned integer.
Definition dbus-protocol.h:86
DBUS_MINIMUM_HEADER_SIZE
#define DBUS_MINIMUM_HEADER_SIZE
The smallest header size that can occur.
Definition dbus-protocol.h:350
_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_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_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_counter_ref
DBusCounter * _dbus_counter_ref(DBusCounter *counter)
Increments refcount of the counter.
Definition dbus-resources.c:116
_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
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:322
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:353
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:298
_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:833
_dbus_string_init
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition dbus-string.c:182
_dbus_string_init_const
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition dbus-string.c:197
_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's copied to the d...
Definition dbus-string.c:1343
_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:672
_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:139
_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:217
_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:1168
_dbus_string_free
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init(), and fills it with the same contents as _DBUS_STRING_IN...
Definition dbus-string.c:278
_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:1253
_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:1103
_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:420
_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:1435
_dbus_close
dbus_bool_t _dbus_close(int fd, DBusError *error)
Closes a file descriptor.
Definition dbus-sysdeps-unix.c:3561
_dbus_dup
int _dbus_dup(int fd, DBusError *error)
Duplicates a file descriptor.
Definition dbus-sysdeps-unix.c:3589
_dbus_atomic_dec
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
Definition dbus-sysdeps-unix.c:3052
_dbus_getenv
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition dbus-sysdeps.c:195
_dbus_atomic_get
dbus_int32_t _dbus_atomic_get(DBusAtomic *atomic)
Atomically get the value of an integer.
Definition dbus-sysdeps-unix.c:3076
_dbus_atomic_inc
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
Definition dbus-sysdeps-unix.c:3029
DBusCounter
Internals of DBusCounter.
Definition dbus-resources.c:55
DBusDataSlotAllocator
An allocator that tracks a set of slot IDs.
Definition dbus-dataslot.h:56
DBusError
Object representing an exception.
Definition dbus-errors.h:49
DBusError::message
const char * message
public error message field
Definition dbus-errors.h:51
DBusHeader
Message header data and some cached details of it.
Definition dbus-marshal-header.h:88
DBusHeader::data
DBusString data
Header network data, stored separately from body so we can independently realloc it.
Definition dbus-marshal-header.h:89
DBusList
A node in a linked list.
Definition dbus-list.h:35
DBusList::data
void * data
Data stored at this element.
Definition dbus-list.h:38
DBusMessageIter_1_10_0
Layout of a DBusMessageIter on the stack in dbus 1.10.0.
Definition dbus-message.c:145
DBusMessageIter
DBusMessageIter struct; contains no public fields.
Definition dbus-message.h:62
DBusMessageLoader
Implementation details of DBusMessageLoader.
Definition dbus-message-private.h:61
DBusMessageLoader::max_message_size
long max_message_size
Maximum size of a message.
Definition dbus-message-private.h:68
DBusMessageLoader::max_message_unix_fds
long max_message_unix_fds
Maximum unix fds in a message.
Definition dbus-message-private.h:69
DBusMessageLoader::data
DBusString data
Buffered data.
Definition dbus-message-private.h:64
DBusMessageLoader::messages
DBusList * messages
Complete messages.
Definition dbus-message-private.h:66
DBusMessageLoader::corrupted
unsigned int corrupted
We got broken data, and are no longer working.
Definition dbus-message-private.h:73
DBusMessageLoader::buffer_outstanding
unsigned int buffer_outstanding
Someone is using the buffer to read.
Definition dbus-message-private.h:75
DBusMessageLoader::corruption_reason
DBusValidity corruption_reason
why we were corrupted
Definition dbus-message-private.h:71
DBusMessageLoader::refcount
int refcount
Reference count.
Definition dbus-message-private.h:62
DBusMessageRealIter
Internals of DBusMessageIter.
Definition dbus-message.c:127
DBusMessageRealIter::u
union DBusMessageRealIter::@6 u
the type writer or reader that does all the work
DBusMessageRealIter::message
DBusMessage * message
Message used.
Definition dbus-message.c:128
DBusMessageRealIter::iter_type
dbus_uint32_t iter_type
whether this is a reader or writer iter
Definition dbus-message.c:130
DBusMessageRealIter::sig_refcount
dbus_uint32_t sig_refcount
depth of open_signature()
Definition dbus-message.c:131
DBusMessageRealIter::writer
DBusTypeWriter writer
writer
Definition dbus-message.c:134
DBusMessageRealIter::changed_stamp
dbus_uint32_t changed_stamp
stamp to detect invalid iters
Definition dbus-message.c:129
DBusMessageRealIter::reader
DBusTypeReader reader
reader
Definition dbus-message.c:135
DBusMessage
Internals of DBusMessage.
Definition dbus-message-private.h:100
DBusMessage::header
DBusHeader header
Header network data and associated cache.
Definition dbus-message-private.h:103
DBusMessage::body
DBusString body
Body network data.
Definition dbus-message-private.h:105
DBusMessage::slot_list
DBusDataSlotList slot_list
Data stored by allocated integer ID.
Definition dbus-message-private.h:118
DBusMessage::refcount
DBusAtomic refcount
Reference count.
Definition dbus-message-private.h:101
DBusMessage::changed_stamp
dbus_uint32_t changed_stamp
Incremented when iterators are invalidated.
Definition dbus-message-private.h:116
DBusMessage::generation
int generation
_dbus_current_generation when message was created
Definition dbus-message-private.h:121
DBusMessage::size_counter_delta
long size_counter_delta
Size we incremented the size counters by.
Definition dbus-message-private.h:114
DBusMessage::counters
DBusList * counters
0-N DBusCounter used to track message size/unix fds.
Definition dbus-message-private.h:113
DBusMessage::in_cache
unsigned int in_cache
Has been "freed" since it's in the cache (this is a debug feature)
Definition dbus-message-private.h:110
DBusMessage::locked
unsigned int locked
Message being sent, no modifications allowed.
Definition dbus-message-private.h:107
DBusString
Definition dbus-string.h:43
DBusTypeReader
The type reader is an iterator for reading values from a block of values.
Definition dbus-marshal-recursive.h:40
DBusTypeReader::byte_order
dbus_uint32_t byte_order
byte order of the block
Definition dbus-marshal-recursive.h:41
DBusTypeWriter
The type writer is an iterator for writing to a block of values.
Definition dbus-marshal-recursive.h:65
DBusTypeWriter::byte_order
dbus_uint32_t byte_order
byte order to write values with
Definition dbus-marshal-recursive.h:66
DBusTypeWriter::type_str
DBusString * type_str
where to write typecodes (or read type expectations)
Definition dbus-marshal-recursive.h:74
DBusTypeWriter::container_type
dbus_uint32_t container_type
what are we inside? (e.g.
Definition dbus-marshal-recursive.h:68
DBusVariant
An opaque data structure containing the serialized form of any single D-Bus message item,...
Definition dbus-message.c:5315
DBusBasicValue
A simple value union that lets you access bytes as if they were various types; useful when dealing wi...
Definition dbus-types.h:138
DBusBasicValue::u32
dbus_uint32_t u32
as int32
Definition dbus-types.h:143