D-Bus: dbus-message.c Source File

D-Bus 1.8.16

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List

dbus-message.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-message.c DBusMessage object
3 *
4 * Copyright (C) 2002, 2003, 2004, 2005 Red Hat Inc.
5 * Copyright (C) 2002, 2003 CodeFactory AB
6 *
7 * Licensed under the Academic Free License version 2.1
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 *
23 */
24
25 #include <config.h>
26 #include "dbus-internals.h"
27 #include "dbus-marshal-recursive.h"
28 #include "dbus-marshal-validate.h"
29 #include "dbus-marshal-byteswap.h"
30 #include "dbus-marshal-header.h"
31 #include "dbus-signature.h"
32 #include "dbus-message-private.h"
33 #include "dbus-object-tree.h"
34 #include "dbus-memory.h"
35 #include "dbus-list.h"
36 #include "dbus-threads-internal.h"
37 #ifdef HAVE_UNIX_FD_PASSING
38 #include "dbus-sysdeps.h"
39 #include "dbus-sysdeps-unix.h"
40 #endif
41
42 #include <string.h>
43
44 #define _DBUS_TYPE_IS_STRINGLIKE(type) \
45 (type == DBUS_TYPE_STRING || type == DBUS_TYPE_SIGNATURE || \
46 type == DBUS_TYPE_OBJECT_PATH)
47
48 static void dbus_message_finalize (DBusMessage *message);
49
60 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
61 static dbus_bool_t
62 _dbus_enable_message_cache (void)
63 {
64 static int enabled = -1;
65
66 if (enabled < 0)
67 {
68 const char *s = _dbus_getenv ("DBUS_MESSAGE_CACHE");
69
70 enabled = TRUE;
71
72 if (s && *s)
73 {
74 if (*s == '0')
75 enabled = FALSE;
76 else if (*s == '1')
77 enabled = TRUE;
78 else
79 _dbus_warn ("DBUS_MESSAGE_CACHE should be 0 or 1 if set, not '%s'",
80 s);
81 }
82 }
83
84 return enabled;
85 }
86 #else
87 /* constant expression, should be optimized away */
88 # define _dbus_enable_message_cache() (TRUE)
89 #endif
90
91 #ifndef _dbus_message_trace_ref
92 void
93 _dbus_message_trace_ref (DBusMessage *message,
94 int old_refcount,
95 int new_refcount,
96 const char *why)
97 {
98 static int enabled = -1;
99
100 _dbus_trace_ref ("DBusMessage", message, old_refcount, new_refcount, why,
101 "DBUS_MESSAGE_TRACE", &enabled);
102 }
103 #endif
104
105 /* Not thread locked, but strictly const/read-only so should be OK
106 */
108 _DBUS_STRING_DEFINE_STATIC(_dbus_empty_signature_str, "");
109
110 /* these have wacky values to help trap uninitialized iterators;
111 * but has to fit in 3 bits
112 */
113 enum {
114 DBUS_MESSAGE_ITER_TYPE_READER = 3,
115 DBUS_MESSAGE_ITER_TYPE_WRITER = 7
116 };
117
119 typedef struct DBusMessageRealIter DBusMessageRealIter;
120
126 struct DBusMessageRealIter
127 {
128 DBusMessage *message;
129 dbus_uint32_t changed_stamp : CHANGED_STAMP_BITS;
130 dbus_uint32_t iter_type : 3;
131 dbus_uint32_t sig_refcount : 8;
132 union
133 {
134 DBusTypeWriter writer;
135 DBusTypeReader reader;
136 } u;
137 };
138
139 static void
140 get_const_signature (DBusHeader *header,
141 const DBusString **type_str_p,
142 int *type_pos_p)
143 {
144 if (_dbus_header_get_field_raw (header,
145 DBUS_HEADER_FIELD_SIGNATURE,
146 type_str_p,
147 type_pos_p))
148 {
149 *type_pos_p += 1; /* skip the signature length which is 1 byte */
150 }
151 else
152 {
153 *type_str_p = &_dbus_empty_signature_str;
154 *type_pos_p = 0;
155 }
156 }
157
163 static void
164 _dbus_message_byteswap (DBusMessage *message)
165 {
166 const DBusString *type_str;
167 int type_pos;
168 char byte_order;
169
170 byte_order = _dbus_header_get_byte_order (&message->header);
171
172 if (byte_order == DBUS_COMPILER_BYTE_ORDER)
173 return;
174
175 _dbus_verbose ("Swapping message into compiler byte order\n");
176
177 get_const_signature (&message->header, &type_str, &type_pos);
178
179 _dbus_marshal_byteswap (type_str, type_pos,
180 byte_order,
181 DBUS_COMPILER_BYTE_ORDER,
182 &message->body, 0);
183
184 _dbus_header_byteswap (&message->header, DBUS_COMPILER_BYTE_ORDER);
185 _dbus_assert (_dbus_header_get_byte_order (&message->header) ==
186 DBUS_COMPILER_BYTE_ORDER);
187 }
188
195 #define ensure_byte_order(message) _dbus_message_byteswap (message)
196
207 void
208 _dbus_message_get_network_data (DBusMessage *message,
209 const DBusString **header,
210 const DBusString **body)
211 {
212 _dbus_assert (message->locked);
213
214 *header = &message->header.data;
215 *body = &message->body;
216 }
217
227 void _dbus_message_get_unix_fds(DBusMessage *message,
228 const int **fds,
229 unsigned *n_fds)
230 {
231 _dbus_assert (message->locked);
232
233 #ifdef HAVE_UNIX_FD_PASSING
234 *fds = message->unix_fds;
235 *n_fds = message->n_unix_fds;
236 #else
237 *fds = NULL;
238 *n_fds = 0;
239 #endif
240 }
241
253 void
254 dbus_message_set_serial (DBusMessage *message,
255 dbus_uint32_t serial)
256 {
257 _dbus_return_if_fail (message != NULL);
258 _dbus_return_if_fail (!message->locked);
259
260 _dbus_header_set_serial (&message->header, serial);
261 }
262
279 void
280 _dbus_message_add_counter_link (DBusMessage *message,
281 DBusList *link)
282 {
283 /* right now we don't recompute the delta when message
284 * size changes, and that's OK for current purposes
285 * I think, but could be important to change later.
286 * Do recompute it whenever there are no outstanding counters,
287 * since it's basically free.
288 */
289 if (message->counters == NULL)
290 {
291 message->size_counter_delta =
292 _dbus_string_get_length (&message->header.data) +
293 _dbus_string_get_length (&message->body);
294
295 #ifdef HAVE_UNIX_FD_PASSING
296 message->unix_fd_counter_delta = message->n_unix_fds;
297 #endif
298
299 #if 0
300 _dbus_verbose ("message has size %ld\n",
301 message->size_counter_delta);
302 #endif
303 }
304
305 _dbus_list_append_link (&message->counters, link);
306
307 _dbus_counter_adjust_size (link->data, message->size_counter_delta);
308
309 #ifdef HAVE_UNIX_FD_PASSING
310 _dbus_counter_adjust_unix_fd (link->data, message->unix_fd_counter_delta);
311 #endif
312 }
313
328 dbus_bool_t
329 _dbus_message_add_counter (DBusMessage *message,
330 DBusCounter *counter)
331 {
332 DBusList *link;
333
334 link = _dbus_list_alloc_link (counter);
335 if (link == NULL)
336 return FALSE;
337
338 _dbus_counter_ref (counter);
339 _dbus_message_add_counter_link (message, link);
340
341 return TRUE;
342 }
343
351 void
352 _dbus_message_remove_counter (DBusMessage *message,
353 DBusCounter *counter)
354 {
355 DBusList *link;
356
357 link = _dbus_list_find_last (&message->counters,
358 counter);
359 _dbus_assert (link != NULL);
360
361 _dbus_list_remove_link (&message->counters, link);
362
363 _dbus_counter_adjust_size (counter, - message->size_counter_delta);
364
365 #ifdef HAVE_UNIX_FD_PASSING
366 _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
367 #endif
368
369 _dbus_counter_notify (counter);
370 _dbus_counter_unref (counter);
371 }
372
383 void
384 dbus_message_lock (DBusMessage *message)
385 {
386 if (!message->locked)
387 {
388 _dbus_header_update_lengths (&message->header,
389 _dbus_string_get_length (&message->body));
390
391 /* must have a signature if you have a body */
392 _dbus_assert (_dbus_string_get_length (&message->body) == 0 ||
393 dbus_message_get_signature (message) != NULL);
394
395 message->locked = TRUE;
396 }
397 }
398
399 static dbus_bool_t
400 set_or_delete_string_field (DBusMessage *message,
401 int field,
402 int typecode,
403 const char *value)
404 {
405 if (value == NULL)
406 return _dbus_header_delete_field (&message->header, field);
407 else
408 return _dbus_header_set_field_basic (&message->header,
409 field,
410 typecode,
411 &value);
412 }
413
414 #if 0
415 /* Probably we don't need to use this */
439 static dbus_bool_t
440 _dbus_message_set_signature (DBusMessage *message,
441 const char *signature)
442 {
443 _dbus_return_val_if_fail (message != NULL, FALSE);
444 _dbus_return_val_if_fail (!message->locked, FALSE);
445 _dbus_return_val_if_fail (signature == NULL ||
446 _dbus_check_is_valid_signature (signature));
447 /* can't delete the signature if you have a message body */
448 _dbus_return_val_if_fail (_dbus_string_get_length (&message->body) == 0 ||
449 signature != NULL);
450
451 return set_or_delete_string_field (message,
452 DBUS_HEADER_FIELD_SIGNATURE,
453 DBUS_TYPE_SIGNATURE,
454 signature);
455 }
456 #endif
457
458 /* Message Cache
459 *
460 * We cache some DBusMessage to reduce the overhead of allocating
461 * them. In my profiling this consistently made about an 8%
462 * difference. It avoids the malloc for the message, the malloc for
463 * the slot list, the malloc for the header string and body string,
464 * and the associated free() calls. It does introduce another global
465 * lock which could be a performance issue in certain cases.
466 *
467 * For the echo client/server the round trip time goes from around
468 * .000077 to .000069 with the message cache on my laptop. The sysprof
469 * change is as follows (numbers are cumulative percentage):
470 *
471 * with message cache implemented as array as it is now (0.000069 per):
472 * new_empty_header 1.46
473 * mutex_lock 0.56 # i.e. _DBUS_LOCK(message_cache)
474 * mutex_unlock 0.25
475 * self 0.41
476 * unref 2.24
477 * self 0.68
478 * list_clear 0.43
479 * mutex_lock 0.33 # i.e. _DBUS_LOCK(message_cache)
480 * mutex_unlock 0.25
481 *
482 * with message cache implemented as list (0.000070 per roundtrip):
483 * new_empty_header 2.72
484 * list_pop_first 1.88
485 * unref 3.3
486 * list_prepend 1.63
487 *
488 * without cache (0.000077 per roundtrip):
489 * new_empty_header 6.7
490 * string_init_preallocated 3.43
491 * dbus_malloc 2.43
492 * dbus_malloc0 2.59
493 *
494 * unref 4.02
495 * string_free 1.82
496 * dbus_free 1.63
497 * dbus_free 0.71
498 *
499 * If you implement the message_cache with a list, the primary reason
500 * it's slower is that you add another thread lock (on the DBusList
501 * mempool).
502 */
503
505 #define MAX_MESSAGE_SIZE_TO_CACHE 10 * _DBUS_ONE_KILOBYTE
506
508 #define MAX_MESSAGE_CACHE_SIZE 5
509
510 /* Protected by _DBUS_LOCK (message_cache) */
511 static DBusMessage *message_cache[MAX_MESSAGE_CACHE_SIZE];
512 static int message_cache_count = 0;
513 static dbus_bool_t message_cache_shutdown_registered = FALSE;
514
515 static void
516 dbus_message_cache_shutdown (void *data)
517 {
518 int i;
519
520 if (!_DBUS_LOCK (message_cache))
521 _dbus_assert_not_reached ("we would have initialized global locks "
522 "before registering a shutdown function");
523
524 i = 0;
525 while (i < MAX_MESSAGE_CACHE_SIZE)
526 {
527 if (message_cache[i])
528 dbus_message_finalize (message_cache[i]);
529
530 ++i;
531 }
532
533 message_cache_count = 0;
534 message_cache_shutdown_registered = FALSE;
535
536 _DBUS_UNLOCK (message_cache);
537 }
538
546 static DBusMessage*
547 dbus_message_get_cached (void)
548 {
549 DBusMessage *message;
550 int i;
551
552 message = NULL;
553
554 if (!_DBUS_LOCK (message_cache))
555 {
556 /* we'd have initialized global locks before caching anything,
557 * so there can't be anything in the cache */
558 return NULL;
559 }
560
561 _dbus_assert (message_cache_count >= 0);
562
563 if (message_cache_count == 0)
564 {
565 _DBUS_UNLOCK (message_cache);
566 return NULL;
567 }
568
569 /* This is not necessarily true unless count > 0, and
570 * message_cache is uninitialized until the shutdown is
571 * registered
572 */
573 _dbus_assert (message_cache_shutdown_registered);
574
575 i = 0;
576 while (i < MAX_MESSAGE_CACHE_SIZE)
577 {
578 if (message_cache[i])
579 {
580 message = message_cache[i];
581 message_cache[i] = NULL;
582 message_cache_count -= 1;
583 break;
584 }
585 ++i;
586 }
587 _dbus_assert (message_cache_count >= 0);
588 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
589 _dbus_assert (message != NULL);
590
591 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
592
593 _dbus_assert (message->counters == NULL);
594
595 _DBUS_UNLOCK (message_cache);
596
597 return message;
598 }
599
600 #ifdef HAVE_UNIX_FD_PASSING
601 static void
602 close_unix_fds(int *fds, unsigned *n_fds)
603 {
604 DBusError e;
605 int i;
606
607 if (*n_fds <= 0)
608 return;
609
610 dbus_error_init(&e);
611
612 for (i = 0; i < *n_fds; i++)
613 {
614 if (!_dbus_close(fds[i], &e))
615 {
616 _dbus_warn("Failed to close file descriptor: %s\n", e.message);
617 dbus_error_free(&e);
618 }
619 }
620
621 *n_fds = 0;
622
623 /* We don't free the array here, in case we can recycle it later */
624 }
625 #endif
626
627 static void
628 free_counter (void *element,
629 void *data)
630 {
631 DBusCounter *counter = element;
632 DBusMessage *message = data;
633
634 _dbus_counter_adjust_size (counter, - message->size_counter_delta);
635 #ifdef HAVE_UNIX_FD_PASSING
636 _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
637 #endif
638
639 _dbus_counter_notify (counter);
640 _dbus_counter_unref (counter);
641 }
642
648 static void
649 dbus_message_cache_or_finalize (DBusMessage *message)
650 {
651 dbus_bool_t was_cached;
652 int i;
653
654 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
655
656 /* This calls application code and has to be done first thing
657 * without holding the lock
658 */
659 _dbus_data_slot_list_clear (&message->slot_list);
660
661 _dbus_list_foreach (&message->counters,
662 free_counter, message);
663 _dbus_list_clear (&message->counters);
664
665 #ifdef HAVE_UNIX_FD_PASSING
666 close_unix_fds(message->unix_fds, &message->n_unix_fds);
667 #endif
668
669 was_cached = FALSE;
670
671 if (!_DBUS_LOCK (message_cache))
672 {
673 /* The only way to get a non-null message goes through
674 * dbus_message_get_cached() which takes the lock. */
675 _dbus_assert_not_reached ("we would have initialized global locks "
676 "the first time we constructed a message");
677 }
678
679 if (!message_cache_shutdown_registered)
680 {
681 _dbus_assert (message_cache_count == 0);
682
683 if (!_dbus_register_shutdown_func (dbus_message_cache_shutdown, NULL))
684 goto out;
685
686 i = 0;
687 while (i < MAX_MESSAGE_CACHE_SIZE)
688 {
689 message_cache[i] = NULL;
690 ++i;
691 }
692
693 message_cache_shutdown_registered = TRUE;
694 }
695
696 _dbus_assert (message_cache_count >= 0);
697
698 if (!_dbus_enable_message_cache ())
699 goto out;
700
701 if ((_dbus_string_get_length (&message->header.data) +
702 _dbus_string_get_length (&message->body)) >
703 MAX_MESSAGE_SIZE_TO_CACHE)
704 goto out;
705
706 if (message_cache_count >= MAX_MESSAGE_CACHE_SIZE)
707 goto out;
708
709 /* Find empty slot */
710 i = 0;
711 while (message_cache[i] != NULL)
712 ++i;
713
714 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
715
716 _dbus_assert (message_cache[i] == NULL);
717 message_cache[i] = message;
718 message_cache_count += 1;
719 was_cached = TRUE;
720 #ifndef DBUS_DISABLE_CHECKS
721 message->in_cache = TRUE;
722 #endif
723
724 out:
725 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
726
727 _DBUS_UNLOCK (message_cache);
728
729 if (!was_cached)
730 dbus_message_finalize (message);
731 }
732
733 #if defined(DBUS_ENABLE_CHECKS) || defined(DBUS_ENABLE_ASSERT)
734 static dbus_bool_t
735 _dbus_message_iter_check (DBusMessageRealIter *iter)
736 {
737 char byte_order;
738
739 if (iter == NULL)
740 {
741 _dbus_warn_check_failed ("dbus message iterator is NULL\n");
742 return FALSE;
743 }
744
745 byte_order = _dbus_header_get_byte_order (&iter->message->header);
746
747 if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_READER)
748 {
749 if (iter->u.reader.byte_order != byte_order)
750 {
751 _dbus_warn_check_failed ("dbus message changed byte order since iterator was created\n");
752 return FALSE;
753 }
754 /* because we swap the message into compiler order when you init an iter */
755 _dbus_assert (iter->u.reader.byte_order == DBUS_COMPILER_BYTE_ORDER);
756 }
757 else if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER)
758 {
759 if (iter->u.writer.byte_order != byte_order)
760 {
761 _dbus_warn_check_failed ("dbus message changed byte order since append iterator was created\n");
762 return FALSE;
763 }
764 /* because we swap the message into compiler order when you init an iter */
765 _dbus_assert (iter->u.writer.byte_order == DBUS_COMPILER_BYTE_ORDER);
766 }
767 else
768 {
769 _dbus_warn_check_failed ("dbus message iterator looks uninitialized or corrupted\n");
770 return FALSE;
771 }
772
773 if (iter->changed_stamp != iter->message->changed_stamp)
774 {
775 _dbus_warn_check_failed ("dbus message iterator invalid because the message has been modified (or perhaps the iterator is just uninitialized)\n");
776 return FALSE;
777 }
778
779 return TRUE;
780 }
781 #endif /* DBUS_ENABLE_CHECKS || DBUS_ENABLE_ASSERT */
782
795 dbus_bool_t
796 _dbus_message_iter_get_args_valist (DBusMessageIter *iter,
797 DBusError *error,
798 int first_arg_type,
799 va_list var_args)
800 {
801 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
802 int spec_type, msg_type, i, j;
803 dbus_bool_t retval;
804 va_list copy_args;
805
806 _dbus_assert (_dbus_message_iter_check (real));
807
808 retval = FALSE;
809
810 spec_type = first_arg_type;
811 i = 0;
812
813 /* copy var_args first, then we can do another iteration over it to
814 * free memory and close unix fds if parse failed at some point.
815 */
816 DBUS_VA_COPY (copy_args, var_args);
817
818 while (spec_type != DBUS_TYPE_INVALID)
819 {
820 msg_type = dbus_message_iter_get_arg_type (iter);
821
822 if (msg_type != spec_type)
823 {
824 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
825 "Argument %d is specified to be of type \"%s\", but "
826 "is actually of type \"%s\"\n", i,
827 _dbus_type_to_string (spec_type),
828 _dbus_type_to_string (msg_type));
829
830 goto out;
831 }
832
833 if (spec_type == DBUS_TYPE_UNIX_FD)
834 {
835 #ifdef HAVE_UNIX_FD_PASSING
836 DBusBasicValue idx;
837 int *pfd, nfd;
838
839 pfd = va_arg (var_args, int*);
840 _dbus_assert(pfd);
841
842 _dbus_type_reader_read_basic(&real->u.reader, &idx);
843
844 if (idx.u32 >= real->message->n_unix_fds)
845 {
846 dbus_set_error (error, DBUS_ERROR_INCONSISTENT_MESSAGE,
847 "Message refers to file descriptor at index %i,"
848 "but has only %i descriptors attached.\n",
849 idx.u32,
850 real->message->n_unix_fds);
851 goto out;
852 }
853
854 if ((nfd = _dbus_dup(real->message->unix_fds[idx.u32], error)) < 0)
855 goto out;
856
857 *pfd = nfd;
858 #else
859 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
860 "Platform does not support file desciptor passing.\n");
861 goto out;
862 #endif
863 }
864 else if (dbus_type_is_basic (spec_type))
865 {
866 DBusBasicValue *ptr;
867
868 ptr = va_arg (var_args, DBusBasicValue*);
869
870 _dbus_assert (ptr != NULL);
871
872 _dbus_type_reader_read_basic (&real->u.reader,
873 ptr);
874 }
875 else if (spec_type == DBUS_TYPE_ARRAY)
876 {
877 int element_type;
878 int spec_element_type;
879 const DBusBasicValue **ptr;
880 int *n_elements_p;
881 DBusTypeReader array;
882
883 spec_element_type = va_arg (var_args, int);
884 element_type = _dbus_type_reader_get_element_type (&real->u.reader);
885
886 if (spec_element_type != element_type)
887 {
888 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
889 "Argument %d is specified to be an array of \"%s\", but "
890 "is actually an array of \"%s\"\n",
891 i,
892 _dbus_type_to_string (spec_element_type),
893 _dbus_type_to_string (element_type));
894
895 goto out;
896 }
897
898 if (dbus_type_is_fixed (spec_element_type) &&
899 element_type != DBUS_TYPE_UNIX_FD)
900 {
901 ptr = va_arg (var_args, const DBusBasicValue**);
902 n_elements_p = va_arg (var_args, int*);
903
904 _dbus_assert (ptr != NULL);
905 _dbus_assert (n_elements_p != NULL);
906
907 _dbus_type_reader_recurse (&real->u.reader, &array);
908
909 _dbus_type_reader_read_fixed_multi (&array,
910 (void *) ptr, n_elements_p);
911 }
912 else if (_DBUS_TYPE_IS_STRINGLIKE (spec_element_type))
913 {
914 char ***str_array_p;
915 int n_elements;
916 char **str_array;
917
918 str_array_p = va_arg (var_args, char***);
919 n_elements_p = va_arg (var_args, int*);
920
921 _dbus_assert (str_array_p != NULL);
922 _dbus_assert (n_elements_p != NULL);
923
924 /* Count elements in the array */
925 _dbus_type_reader_recurse (&real->u.reader, &array);
926
927 n_elements = 0;
928 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
929 {
930 ++n_elements;
931 _dbus_type_reader_next (&array);
932 }
933
934 str_array = dbus_new0 (char*, n_elements + 1);
935 if (str_array == NULL)
936 {
937 _DBUS_SET_OOM (error);
938 goto out;
939 }
940
941 /* Now go through and dup each string */
942 _dbus_type_reader_recurse (&real->u.reader, &array);
943
944 j = 0;
945 while (j < n_elements)
946 {
947 const char *s;
948 _dbus_type_reader_read_basic (&array,
949 (void *) &s);
950
951 str_array[j] = _dbus_strdup (s);
952 if (str_array[j] == NULL)
953 {
954 dbus_free_string_array (str_array);
955 _DBUS_SET_OOM (error);
956 goto out;
957 }
958
959 ++j;
960
961 if (!_dbus_type_reader_next (&array))
962 _dbus_assert (j == n_elements);
963 }
964
965 _dbus_assert (_dbus_type_reader_get_current_type (&array) == DBUS_TYPE_INVALID);
966 _dbus_assert (j == n_elements);
967 _dbus_assert (str_array[j] == NULL);
968
969 *str_array_p = str_array;
970 *n_elements_p = n_elements;
971 }
972 #ifndef DBUS_DISABLE_CHECKS
973 else
974 {
975 _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now\n",
976 _DBUS_FUNCTION_NAME);
977 goto out;
978 }
979 #endif
980 }
981 #ifndef DBUS_DISABLE_CHECKS
982 else
983 {
984 _dbus_warn ("you can only read arrays and basic types with %s for now\n",
985 _DBUS_FUNCTION_NAME);
986 goto out;
987 }
988 #endif
989
990 /* how many arguments already handled */
991 i++;
992
993 spec_type = va_arg (var_args, int);
994 if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID)
995 {
996 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
997 "Message has only %d arguments, but more were expected", i);
998 goto out;
999 }
1000 }
1001
1002 retval = TRUE;
1003
1004 out:
1005 /* there may memory or unix fd leak in the above iteration if parse failed.
1006 * so we have another iteration over copy_args to free memory and close
1007 * unix fds.
1008 */
1009 if (!retval)
1010 {
1011 spec_type = first_arg_type;
1012 j = 0;
1013
1014 while (j < i)
1015 {
1016 if (spec_type == DBUS_TYPE_UNIX_FD)
1017 {
1018 #ifdef HAVE_UNIX_FD_PASSING
1019 int *pfd;
1020
1021 pfd = va_arg (copy_args, int *);
1022 _dbus_assert(pfd);
1023 if (*pfd >= 0)
1024 {
1025 _dbus_close (*pfd, NULL);
1026 *pfd = -1;
1027 }
1028 #endif
1029 }
1030 else if (dbus_type_is_basic (spec_type))
1031 {
1032 /* move the index forward */
1033 va_arg (copy_args, DBusBasicValue *);
1034 }
1035 else if (spec_type == DBUS_TYPE_ARRAY)
1036 {
1037 int spec_element_type;
1038
1039 spec_element_type = va_arg (copy_args, int);
1040 if (dbus_type_is_fixed (spec_element_type))
1041 {
1042 /* move the index forward */
1043 va_arg (copy_args, const DBusBasicValue **);
1044 va_arg (copy_args, int *);
1045 }
1046 else if (_DBUS_TYPE_IS_STRINGLIKE (spec_element_type))
1047 {
1048 char ***str_array_p;
1049
1050 str_array_p = va_arg (copy_args, char ***);
1051 /* move the index forward */
1052 va_arg (copy_args, int *);
1053 _dbus_assert (str_array_p != NULL);
1054 dbus_free_string_array (*str_array_p);
1055 *str_array_p = NULL;
1056 }
1057 }
1058
1059 spec_type = va_arg (copy_args, int);
1060 j++;
1061 }
1062 }
1063
1064 va_end (copy_args);
1065 return retval;
1066 }
1067
1126 dbus_uint32_t
1127 dbus_message_get_serial (DBusMessage *message)
1128 {
1129 _dbus_return_val_if_fail (message != NULL, 0);
1130
1131 return _dbus_header_get_serial (&message->header);
1132 }
1133
1142 dbus_bool_t
1143 dbus_message_set_reply_serial (DBusMessage *message,
1144 dbus_uint32_t reply_serial)
1145 {
1146 _dbus_return_val_if_fail (message != NULL, FALSE);
1147 _dbus_return_val_if_fail (!message->locked, FALSE);
1148 _dbus_return_val_if_fail (reply_serial != 0, FALSE); /* 0 is invalid */
1149
1150 return _dbus_header_set_field_basic (&message->header,
1151 DBUS_HEADER_FIELD_REPLY_SERIAL,
1152 DBUS_TYPE_UINT32,
1153 &reply_serial);
1154 }
1155
1162 dbus_uint32_t
1163 dbus_message_get_reply_serial (DBusMessage *message)
1164 {
1165 dbus_uint32_t v_UINT32;
1166
1167 _dbus_return_val_if_fail (message != NULL, 0);
1168
1169 if (_dbus_header_get_field_basic (&message->header,
1170 DBUS_HEADER_FIELD_REPLY_SERIAL,
1171 DBUS_TYPE_UINT32,
1172 &v_UINT32))
1173 return v_UINT32;
1174 else
1175 return 0;
1176 }
1177
1178 static void
1179 dbus_message_finalize (DBusMessage *message)
1180 {
1181 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
1182
1183 /* This calls application callbacks! */
1184 _dbus_data_slot_list_free (&message->slot_list);
1185
1186 _dbus_list_foreach (&message->counters,
1187 free_counter, message);
1188 _dbus_list_clear (&message->counters);
1189
1190 _dbus_header_free (&message->header);
1191 _dbus_string_free (&message->body);
1192
1193 #ifdef HAVE_UNIX_FD_PASSING
1194 close_unix_fds(message->unix_fds, &message->n_unix_fds);
1195 dbus_free(message->unix_fds);
1196 #endif
1197
1198 _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
1199
1200 dbus_free (message);
1201 }
1202
1203 static DBusMessage*
1204 dbus_message_new_empty_header (void)
1205 {
1206 DBusMessage *message;
1207 dbus_bool_t from_cache;
1208
1209 message = dbus_message_get_cached ();
1210
1211 if (message != NULL)
1212 {
1213 from_cache = TRUE;
1214 }
1215 else
1216 {
1217 from_cache = FALSE;
1218 message = dbus_new0 (DBusMessage, 1);
1219 if (message == NULL)
1220 return NULL;
1221 #ifndef DBUS_DISABLE_CHECKS
1222 message->generation = _dbus_current_generation;
1223 #endif
1224
1225 #ifdef HAVE_UNIX_FD_PASSING
1226 message->unix_fds = NULL;
1227 message->n_unix_fds_allocated = 0;
1228 #endif
1229 }
1230
1231 _dbus_atomic_inc (&message->refcount);
1232
1233 _dbus_message_trace_ref (message, 0, 1, "new_empty_header");
1234
1235 message->locked = FALSE;
1236 #ifndef DBUS_DISABLE_CHECKS
1237 message->in_cache = FALSE;
1238 #endif
1239 message->counters = NULL;
1240 message->size_counter_delta = 0;
1241 message->changed_stamp = 0;
1242
1243 #ifdef HAVE_UNIX_FD_PASSING
1244 message->n_unix_fds = 0;
1245 message->n_unix_fds_allocated = 0;
1246 message->unix_fd_counter_delta = 0;
1247 #endif
1248
1249 if (!from_cache)
1250 _dbus_data_slot_list_init (&message->slot_list);
1251
1252 if (from_cache)
1253 {
1254 _dbus_header_reinit (&message->header);
1255 _dbus_string_set_length (&message->body, 0);
1256 }
1257 else
1258 {
1259 if (!_dbus_header_init (&message->header))
1260 {
1261 dbus_free (message);
1262 return NULL;
1263 }
1264
1265 if (!_dbus_string_init_preallocated (&message->body, 32))
1266 {
1267 _dbus_header_free (&message->header);
1268 dbus_free (message);
1269 return NULL;
1270 }
1271 }
1272
1273 return message;
1274 }
1275
1288 DBusMessage*
1289 dbus_message_new (int message_type)
1290 {
1291 DBusMessage *message;
1292
1293 _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
1294
1295 message = dbus_message_new_empty_header ();
1296 if (message == NULL)
1297 return NULL;
1298
1299 if (!_dbus_header_create (&message->header,
1300 DBUS_COMPILER_BYTE_ORDER,
1301 message_type,
1302 NULL, NULL, NULL, NULL, NULL))
1303 {
1304 dbus_message_unref (message);
1305 return NULL;
1306 }
1307
1308 return message;
1309 }
1310
1332 DBusMessage*
1333 dbus_message_new_method_call (const char *destination,
1334 const char *path,
1335 const char *iface,
1336 const char *method)
1337 {
1338 DBusMessage *message;
1339
1340 _dbus_return_val_if_fail (path != NULL, NULL);
1341 _dbus_return_val_if_fail (method != NULL, NULL);
1342 _dbus_return_val_if_fail (destination == NULL ||
1343 _dbus_check_is_valid_bus_name (destination), NULL);
1344 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
1345 _dbus_return_val_if_fail (iface == NULL ||
1346 _dbus_check_is_valid_interface (iface), NULL);
1347 _dbus_return_val_if_fail (_dbus_check_is_valid_member (method), NULL);
1348
1349 message = dbus_message_new_empty_header ();
1350 if (message == NULL)
1351 return NULL;
1352
1353 if (!_dbus_header_create (&message->header,
1354 DBUS_COMPILER_BYTE_ORDER,
1355 DBUS_MESSAGE_TYPE_METHOD_CALL,
1356 destination, path, iface, method, NULL))
1357 {
1358 dbus_message_unref (message);
1359 return NULL;
1360 }
1361
1362 return message;
1363 }
1364
1372 DBusMessage*
1373 dbus_message_new_method_return (DBusMessage *method_call)
1374 {
1375 DBusMessage *message;
1376 const char *sender;
1377
1378 _dbus_return_val_if_fail (method_call != NULL, NULL);
1379
1380 sender = dbus_message_get_sender (method_call);
1381
1382 /* sender is allowed to be null here in peer-to-peer case */
1383
1384 message = dbus_message_new_empty_header ();
1385 if (message == NULL)
1386 return NULL;
1387
1388 if (!_dbus_header_create (&message->header,
1389 DBUS_COMPILER_BYTE_ORDER,
1390 DBUS_MESSAGE_TYPE_METHOD_RETURN,
1391 sender, NULL, NULL, NULL, NULL))
1392 {
1393 dbus_message_unref (message);
1394 return NULL;
1395 }
1396
1397 dbus_message_set_no_reply (message, TRUE);
1398
1399 if (!dbus_message_set_reply_serial (message,
1400 dbus_message_get_serial (method_call)))
1401 {
1402 dbus_message_unref (message);
1403 return NULL;
1404 }
1405
1406 return message;
1407 }
1408
1423 DBusMessage*
1424 dbus_message_new_signal (const char *path,
1425 const char *iface,
1426 const char *name)
1427 {
1428 DBusMessage *message;
1429
1430 _dbus_return_val_if_fail (path != NULL, NULL);
1431 _dbus_return_val_if_fail (iface != NULL, NULL);
1432 _dbus_return_val_if_fail (name != NULL, NULL);
1433 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
1434 _dbus_return_val_if_fail (_dbus_check_is_valid_interface (iface), NULL);
1435 _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);
1436
1437 message = dbus_message_new_empty_header ();
1438 if (message == NULL)
1439 return NULL;
1440
1441 if (!_dbus_header_create (&message->header,
1442 DBUS_COMPILER_BYTE_ORDER,
1443 DBUS_MESSAGE_TYPE_SIGNAL,
1444 NULL, path, iface, name, NULL))
1445 {
1446 dbus_message_unref (message);
1447 return NULL;
1448 }
1449
1450 dbus_message_set_no_reply (message, TRUE);
1451
1452 return message;
1453 }
1454
1469 DBusMessage*
1470 dbus_message_new_error (DBusMessage *reply_to,
1471 const char *error_name,
1472 const char *error_message)
1473 {
1474 DBusMessage *message;
1475 const char *sender;
1476 DBusMessageIter iter;
1477
1478 _dbus_return_val_if_fail (reply_to != NULL, NULL);
1479 _dbus_return_val_if_fail (error_name != NULL, NULL);
1480 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
1481
1482 sender = dbus_message_get_sender (reply_to);
1483
1484 /* sender may be NULL for non-message-bus case or
1485 * when the message bus is dealing with an unregistered
1486 * connection.
1487 */
1488 message = dbus_message_new_empty_header ();
1489 if (message == NULL)
1490 return NULL;
1491
1492 if (!_dbus_header_create (&message->header,
1493 DBUS_COMPILER_BYTE_ORDER,
1494 DBUS_MESSAGE_TYPE_ERROR,
1495 sender, NULL, NULL, NULL, error_name))
1496 {
1497 dbus_message_unref (message);
1498 return NULL;
1499 }
1500
1501 dbus_message_set_no_reply (message, TRUE);
1502
1503 if (!dbus_message_set_reply_serial (message,
1504 dbus_message_get_serial (reply_to)))
1505 {
1506 dbus_message_unref (message);
1507 return NULL;
1508 }
1509
1510 if (error_message != NULL)
1511 {
1512 dbus_message_iter_init_append (message, &iter);
1513 if (!dbus_message_iter_append_basic (&iter,
1514 DBUS_TYPE_STRING,
1515 &error_message))
1516 {
1517 dbus_message_unref (message);
1518 return NULL;
1519 }
1520 }
1521
1522 return message;
1523 }
1524
1541 DBusMessage*
1542 dbus_message_new_error_printf (DBusMessage *reply_to,
1543 const char *error_name,
1544 const char *error_format,
1545 ...)
1546 {
1547 va_list args;
1548 DBusString str;
1549 DBusMessage *message;
1550
1551 _dbus_return_val_if_fail (reply_to != NULL, NULL);
1552 _dbus_return_val_if_fail (error_name != NULL, NULL);
1553 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
1554
1555 if (!_dbus_string_init (&str))
1556 return NULL;
1557
1558 va_start (args, error_format);
1559
1560 if (_dbus_string_append_printf_valist (&str, error_format, args))
1561 message = dbus_message_new_error (reply_to, error_name,
1562 _dbus_string_get_const_data (&str));
1563 else
1564 message = NULL;
1565
1566 _dbus_string_free (&str);
1567
1568 va_end (args);
1569
1570 return message;
1571 }
1572
1573
1586 DBusMessage *
1587 dbus_message_copy (const DBusMessage *message)
1588 {
1589 DBusMessage *retval;
1590
1591 _dbus_return_val_if_fail (message != NULL, NULL);
1592
1593 retval = dbus_new0 (DBusMessage, 1);
1594 if (retval == NULL)
1595 return NULL;
1596
1597 _dbus_atomic_inc (&retval->refcount);
1598
1599 retval->locked = FALSE;
1600 #ifndef DBUS_DISABLE_CHECKS
1601 retval->generation = message->generation;
1602 #endif
1603
1604 if (!_dbus_header_copy (&message->header, &retval->header))
1605 {
1606 dbus_free (retval);
1607 return NULL;
1608 }
1609
1610 if (!_dbus_string_init_preallocated (&retval->body,
1611 _dbus_string_get_length (&message->body)))
1612 {
1613 _dbus_header_free (&retval->header);
1614 dbus_free (retval);
1615 return NULL;
1616 }
1617
1618 if (!_dbus_string_copy (&message->body, 0,
1619 &retval->body, 0))
1620 goto failed_copy;
1621
1622 #ifdef HAVE_UNIX_FD_PASSING
1623 retval->unix_fds = dbus_new(int, message->n_unix_fds);
1624 if (retval->unix_fds == NULL && message->n_unix_fds > 0)
1625 goto failed_copy;
1626
1627 retval->n_unix_fds_allocated = message->n_unix_fds;
1628
1629 for (retval->n_unix_fds = 0;
1630 retval->n_unix_fds < message->n_unix_fds;
1631 retval->n_unix_fds++)
1632 {
1633 retval->unix_fds[retval->n_unix_fds] = _dbus_dup(message->unix_fds[retval->n_unix_fds], NULL);
1634
1635 if (retval->unix_fds[retval->n_unix_fds] < 0)
1636 goto failed_copy;
1637 }
1638
1639 #endif
1640
1641 _dbus_message_trace_ref (retval, 0, 1, "copy");
1642 return retval;
1643
1644 failed_copy:
1645 _dbus_header_free (&retval->header);
1646 _dbus_string_free (&retval->body);
1647
1648 #ifdef HAVE_UNIX_FD_PASSING
1649 close_unix_fds(retval->unix_fds, &retval->n_unix_fds);
1650 dbus_free(retval->unix_fds);
1651 #endif
1652
1653 dbus_free (retval);
1654
1655 return NULL;
1656 }
1657
1658
1666 DBusMessage *
1667 dbus_message_ref (DBusMessage *message)
1668 {
1669 dbus_int32_t old_refcount;
1670
1671 _dbus_return_val_if_fail (message != NULL, NULL);
1672 _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
1673 _dbus_return_val_if_fail (!message->in_cache, NULL);
1674
1675 old_refcount = _dbus_atomic_inc (&message->refcount);
1676 _dbus_assert (old_refcount >= 1);
1677 _dbus_message_trace_ref (message, old_refcount, old_refcount + 1, "ref");
1678
1679 return message;
1680 }
1681
1689 void
1690 dbus_message_unref (DBusMessage *message)
1691 {
1692 dbus_int32_t old_refcount;
1693
1694 _dbus_return_if_fail (message != NULL);
1695 _dbus_return_if_fail (message->generation == _dbus_current_generation);
1696 _dbus_return_if_fail (!message->in_cache);
1697
1698 old_refcount = _dbus_atomic_dec (&message->refcount);
1699
1700 _dbus_assert (old_refcount >= 1);
1701
1702 _dbus_message_trace_ref (message, old_refcount, old_refcount - 1, "unref");
1703
1704 if (old_refcount == 1)
1705 {
1706 /* Calls application callbacks! */
1707 dbus_message_cache_or_finalize (message);
1708 }
1709 }
1710
1721 int
1722 dbus_message_get_type (DBusMessage *message)
1723 {
1724 _dbus_return_val_if_fail (message != NULL, DBUS_MESSAGE_TYPE_INVALID);
1725
1726 return _dbus_header_get_message_type (&message->header);
1727 }
1728
1791 dbus_bool_t
1792 dbus_message_append_args (DBusMessage *message,
1793 int first_arg_type,
1794 ...)
1795 {
1796 dbus_bool_t retval;
1797 va_list var_args;
1798
1799 _dbus_return_val_if_fail (message != NULL, FALSE);
1800
1801 va_start (var_args, first_arg_type);
1802 retval = dbus_message_append_args_valist (message,
1803 first_arg_type,
1804 var_args);
1805 va_end (var_args);
1806
1807 return retval;
1808 }
1809
1823 dbus_bool_t
1824 dbus_message_append_args_valist (DBusMessage *message,
1825 int first_arg_type,
1826 va_list var_args)
1827 {
1828 int type;
1829 DBusMessageIter iter;
1830
1831 _dbus_return_val_if_fail (message != NULL, FALSE);
1832
1833 type = first_arg_type;
1834
1835 dbus_message_iter_init_append (message, &iter);
1836
1837 while (type != DBUS_TYPE_INVALID)
1838 {
1839 if (dbus_type_is_basic (type))
1840 {
1841 const DBusBasicValue *value;
1842 value = va_arg (var_args, const DBusBasicValue*);
1843
1844 if (!dbus_message_iter_append_basic (&iter,
1845 type,
1846 value))
1847 goto failed;
1848 }
1849 else if (type == DBUS_TYPE_ARRAY)
1850 {
1851 int element_type;
1852 DBusMessageIter array;
1853 char buf[2];
1854
1855 element_type = va_arg (var_args, int);
1856
1857 buf[0] = element_type;
1858 buf[1] = '\0';
1859 if (!dbus_message_iter_open_container (&iter,
1860 DBUS_TYPE_ARRAY,
1861 buf,
1862 &array))
1863 goto failed;
1864
1865 if (dbus_type_is_fixed (element_type) &&
1866 element_type != DBUS_TYPE_UNIX_FD)
1867 {
1868 const DBusBasicValue **value;
1869 int n_elements;
1870
1871 value = va_arg (var_args, const DBusBasicValue**);
1872 n_elements = va_arg (var_args, int);
1873
1874 if (!dbus_message_iter_append_fixed_array (&array,
1875 element_type,
1876 value,
1877 n_elements)) {
1878 dbus_message_iter_abandon_container (&iter, &array);
1879 goto failed;
1880 }
1881 }
1882 else if (_DBUS_TYPE_IS_STRINGLIKE (element_type))
1883 {
1884 const char ***value_p;
1885 const char **value;
1886 int n_elements;
1887 int i;
1888
1889 value_p = va_arg (var_args, const char***);
1890 n_elements = va_arg (var_args, int);
1891
1892 value = *value_p;
1893
1894 i = 0;
1895 while (i < n_elements)
1896 {
1897 if (!dbus_message_iter_append_basic (&array,
1898 element_type,
1899 &value[i])) {
1900 dbus_message_iter_abandon_container (&iter, &array);
1901 goto failed;
1902 }
1903 ++i;
1904 }
1905 }
1906 else
1907 {
1908 _dbus_warn ("arrays of %s can't be appended with %s for now\n",
1909 _dbus_type_to_string (element_type),
1910 _DBUS_FUNCTION_NAME);
1911 goto failed;
1912 }
1913
1914 if (!dbus_message_iter_close_container (&iter, &array))
1915 goto failed;
1916 }
1917 #ifndef DBUS_DISABLE_CHECKS
1918 else
1919 {
1920 _dbus_warn ("type %s isn't supported yet in %s\n",
1921 _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
1922 goto failed;
1923 }
1924 #endif
1925
1926 type = va_arg (var_args, int);
1927 }
1928
1929 return TRUE;
1930
1931 failed:
1932 return FALSE;
1933 }
1934
1979 dbus_bool_t
1980 dbus_message_get_args (DBusMessage *message,
1981 DBusError *error,
1982 int first_arg_type,
1983 ...)
1984 {
1985 dbus_bool_t retval;
1986 va_list var_args;
1987
1988 _dbus_return_val_if_fail (message != NULL, FALSE);
1989 _dbus_return_val_if_error_is_set (error, FALSE);
1990
1991 va_start (var_args, first_arg_type);
1992 retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
1993 va_end (var_args);
1994
1995 return retval;
1996 }
1997
2008 dbus_bool_t
2009 dbus_message_get_args_valist (DBusMessage *message,
2010 DBusError *error,
2011 int first_arg_type,
2012 va_list var_args)
2013 {
2014 DBusMessageIter iter;
2015
2016 _dbus_return_val_if_fail (message != NULL, FALSE);
2017 _dbus_return_val_if_error_is_set (error, FALSE);
2018
2019 dbus_message_iter_init (message, &iter);
2020 return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
2021 }
2022
2023 static void
2024 _dbus_message_iter_init_common (DBusMessage *message,
2025 DBusMessageRealIter *real,
2026 int iter_type)
2027 {
2028 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
2029
2030 /* Since the iterator will read or write who-knows-what from the
2031 * message, we need to get in the right byte order
2032 */
2033 ensure_byte_order (message);
2034
2035 real->message = message;
2036 real->changed_stamp = message->changed_stamp;
2037 real->iter_type = iter_type;
2038 real->sig_refcount = 0;
2039 }
2040
2063 dbus_bool_t
2064 dbus_message_iter_init (DBusMessage *message,
2065 DBusMessageIter *iter)
2066 {
2067 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2068 const DBusString *type_str;
2069 int type_pos;
2070
2071 _dbus_return_val_if_fail (message != NULL, FALSE);
2072 _dbus_return_val_if_fail (iter != NULL, FALSE);
2073
2074 get_const_signature (&message->header, &type_str, &type_pos);
2075
2076 _dbus_message_iter_init_common (message, real,
2077 DBUS_MESSAGE_ITER_TYPE_READER);
2078
2079 _dbus_type_reader_init (&real->u.reader,
2080 _dbus_header_get_byte_order (&message->header),
2081 type_str, type_pos,
2082 &message->body,
2083 0);
2084
2085 return _dbus_type_reader_get_current_type (&real->u.reader) != DBUS_TYPE_INVALID;
2086 }
2087
2094 dbus_bool_t
2095 dbus_message_iter_has_next (DBusMessageIter *iter)
2096 {
2097 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2098
2099 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
2100 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2101
2102 return _dbus_type_reader_has_next (&real->u.reader);
2103 }
2104
2113 dbus_bool_t
2114 dbus_message_iter_next (DBusMessageIter *iter)
2115 {
2116 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2117
2118 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
2119 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2120
2121 return _dbus_type_reader_next (&real->u.reader);
2122 }
2123
2138 int
2139 dbus_message_iter_get_arg_type (DBusMessageIter *iter)
2140 {
2141 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2142
2143 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2144 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2145
2146 return _dbus_type_reader_get_current_type (&real->u.reader);
2147 }
2148
2157 int
2158 dbus_message_iter_get_element_type (DBusMessageIter *iter)
2159 {
2160 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2161
2162 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2163 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
2164 _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
2165
2166 return _dbus_type_reader_get_element_type (&real->u.reader);
2167 }
2168
2194 void
2195 dbus_message_iter_recurse (DBusMessageIter *iter,
2196 DBusMessageIter *sub)
2197 {
2198 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2199 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2200
2201 _dbus_return_if_fail (_dbus_message_iter_check (real));
2202 _dbus_return_if_fail (sub != NULL);
2203
2204 *real_sub = *real;
2205 _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
2206 }
2207
2219 char *
2220 dbus_message_iter_get_signature (DBusMessageIter *iter)
2221 {
2222 const DBusString *sig;
2223 DBusString retstr;
2224 char *ret;
2225 int start, len;
2226 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2227
2228 _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
2229
2230 if (!_dbus_string_init (&retstr))
2231 return NULL;
2232
2233 _dbus_type_reader_get_signature (&real->u.reader, &sig,
2234 &start, &len);
2235 if (!_dbus_string_append_len (&retstr,
2236 _dbus_string_get_const_data (sig) + start,
2237 len))
2238 return NULL;
2239 if (!_dbus_string_steal_data (&retstr, &ret))
2240 return NULL;
2241 _dbus_string_free (&retstr);
2242 return ret;
2243 }
2244
2292 void
2293 dbus_message_iter_get_basic (DBusMessageIter *iter,
2294 void *value)
2295 {
2296 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2297
2298 _dbus_return_if_fail (_dbus_message_iter_check (real));
2299 _dbus_return_if_fail (value != NULL);
2300
2301 if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_UNIX_FD)
2302 {
2303 #ifdef HAVE_UNIX_FD_PASSING
2304 DBusBasicValue idx;
2305
2306 _dbus_type_reader_read_basic(&real->u.reader, &idx);
2307
2308 if (idx.u32 >= real->message->n_unix_fds) {
2309 /* Hmm, we cannot really signal an error here, so let's make
2310 sure to return an invalid fd. */
2311 *((int*) value) = -1;
2312 return;
2313 }
2314
2315 *((int*) value) = _dbus_dup(real->message->unix_fds[idx.u32], NULL);
2316 #else
2317 *((int*) value) = -1;
2318 #endif
2319 }
2320 else
2321 {
2322 _dbus_type_reader_read_basic (&real->u.reader,
2323 value);
2324 }
2325 }
2326
2345 int
2346 dbus_message_iter_get_array_len (DBusMessageIter *iter)
2347 {
2348 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2349
2350 _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
2351
2352 return _dbus_type_reader_get_array_length (&real->u.reader);
2353 }
2354
2390 void
2391 dbus_message_iter_get_fixed_array (DBusMessageIter *iter,
2392 void *value,
2393 int *n_elements)
2394 {
2395 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2396 #ifndef DBUS_DISABLE_CHECKS
2397 int subtype = _dbus_type_reader_get_current_type(&real->u.reader);
2398
2399 _dbus_return_if_fail (_dbus_message_iter_check (real));
2400 _dbus_return_if_fail (value != NULL);
2401 _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) ||
2402 (dbus_type_is_fixed (subtype) && subtype != DBUS_TYPE_UNIX_FD));
2403 #endif
2404
2405 _dbus_type_reader_read_fixed_multi (&real->u.reader,
2406 value, n_elements);
2407 }
2408
2420 void
2421 dbus_message_iter_init_append (DBusMessage *message,
2422 DBusMessageIter *iter)
2423 {
2424 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2425
2426 _dbus_return_if_fail (message != NULL);
2427 _dbus_return_if_fail (iter != NULL);
2428
2429 _dbus_message_iter_init_common (message, real,
2430 DBUS_MESSAGE_ITER_TYPE_WRITER);
2431
2432 /* We create the signature string and point iterators at it "on demand"
2433 * when a value is actually appended. That means that init() never fails
2434 * due to OOM.
2435 */
2436 _dbus_type_writer_init_types_delayed (&real->u.writer,
2437 _dbus_header_get_byte_order (&message->header),
2438 &message->body,
2439 _dbus_string_get_length (&message->body));
2440 }
2441
2450 static dbus_bool_t
2451 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
2452 {
2453 DBusString *str;
2454 const DBusString *current_sig;
2455 int current_sig_pos;
2456
2457 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2458
2459 if (real->u.writer.type_str != NULL)
2460 {
2461 _dbus_assert (real->sig_refcount > 0);
2462 real->sig_refcount += 1;
2463 return TRUE;
2464 }
2465
2466 str = dbus_new (DBusString, 1);
2467 if (str == NULL)
2468 return FALSE;
2469
2470 if (!_dbus_header_get_field_raw (&real->message->header,
2471 DBUS_HEADER_FIELD_SIGNATURE,
2472 &current_sig, &current_sig_pos))
2473 current_sig = NULL;
2474
2475 if (current_sig)
2476 {
2477 int current_len;
2478
2479 current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
2480 current_sig_pos += 1; /* move on to sig data */
2481
2482 if (!_dbus_string_init_preallocated (str, current_len + 4))
2483 {
2484 dbus_free (str);
2485 return FALSE;
2486 }
2487
2488 if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
2489 str, 0))
2490 {
2491 _dbus_string_free (str);
2492 dbus_free (str);
2493 return FALSE;
2494 }
2495 }
2496 else
2497 {
2498 if (!_dbus_string_init_preallocated (str, 4))
2499 {
2500 dbus_free (str);
2501 return FALSE;
2502 }
2503 }
2504
2505 real->sig_refcount = 1;
2506
2507 _dbus_type_writer_add_types (&real->u.writer,
2508 str, _dbus_string_get_length (str));
2509 return TRUE;
2510 }
2511
2521 static dbus_bool_t
2522 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
2523 {
2524 DBusString *str;
2525 const char *v_STRING;
2526 dbus_bool_t retval;
2527
2528 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2529 _dbus_assert (real->u.writer.type_str != NULL);
2530 _dbus_assert (real->sig_refcount > 0);
2531
2532 real->sig_refcount -= 1;
2533
2534 if (real->sig_refcount > 0)
2535 return TRUE;
2536 _dbus_assert (real->sig_refcount == 0);
2537
2538 retval = TRUE;
2539
2540 str = real->u.writer.type_str;
2541
2542 v_STRING = _dbus_string_get_const_data (str);
2543 if (!_dbus_header_set_field_basic (&real->message->header,
2544 DBUS_HEADER_FIELD_SIGNATURE,
2545 DBUS_TYPE_SIGNATURE,
2546 &v_STRING))
2547 retval = FALSE;
2548
2549 _dbus_type_writer_remove_types (&real->u.writer);
2550 _dbus_string_free (str);
2551 dbus_free (str);
2552
2553 return retval;
2554 }
2555
2563 static void
2564 _dbus_message_iter_abandon_signature (DBusMessageRealIter *real)
2565 {
2566 DBusString *str;
2567
2568 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2569 _dbus_assert (real->u.writer.type_str != NULL);
2570 _dbus_assert (real->sig_refcount > 0);
2571
2572 real->sig_refcount -= 1;
2573
2574 if (real->sig_refcount > 0)
2575 return;
2576 _dbus_assert (real->sig_refcount == 0);
2577
2578 str = real->u.writer.type_str;
2579
2580 _dbus_type_writer_remove_types (&real->u.writer);
2581 _dbus_string_free (str);
2582 dbus_free (str);
2583 }
2584
2585 #ifndef DBUS_DISABLE_CHECKS
2586 static dbus_bool_t
2587 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
2588 {
2589 if (!_dbus_message_iter_check (iter))
2590 return FALSE;
2591
2592 if (iter->message->locked)
2593 {
2594 _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)\n");
2595 return FALSE;
2596 }
2597
2598 return TRUE;
2599 }
2600 #endif /* DBUS_DISABLE_CHECKS */
2601
2602 #ifdef HAVE_UNIX_FD_PASSING
2603 static int *
2604 expand_fd_array(DBusMessage *m,
2605 unsigned n)
2606 {
2607 _dbus_assert(m);
2608
2609 /* This makes space for adding n new fds to the array and returns a
2610 pointer to the place were the first fd should be put. */
2611
2612 if (m->n_unix_fds + n > m->n_unix_fds_allocated)
2613 {
2614 unsigned k;
2615 int *p;
2616
2617 /* Make twice as much space as necessary */
2618 k = (m->n_unix_fds + n) * 2;
2619
2620 /* Allocate at least four */
2621 if (k < 4)
2622 k = 4;
2623
2624 p = dbus_realloc(m->unix_fds, k * sizeof(int));
2625 if (p == NULL)
2626 return NULL;
2627
2628 m->unix_fds = p;
2629 m->n_unix_fds_allocated = k;
2630 }
2631
2632 return m->unix_fds + m->n_unix_fds;
2633 }
2634 #endif
2635
2655 dbus_bool_t
2656 dbus_message_iter_append_basic (DBusMessageIter *iter,
2657 int type,
2658 const void *value)
2659 {
2660 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2661 dbus_bool_t ret;
2662
2663 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2664 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2665 _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
2666 _dbus_return_val_if_fail (value != NULL, FALSE);
2667
2668 #ifndef DBUS_DISABLE_CHECKS
2669 switch (type)
2670 {
2671 const char * const *string_p;
2672 const dbus_bool_t *bool_p;
2673
2674 case DBUS_TYPE_STRING:
2675 string_p = value;
2676 _dbus_return_val_if_fail (_dbus_check_is_valid_utf8 (*string_p), FALSE);
2677 break;
2678
2679 case DBUS_TYPE_OBJECT_PATH:
2680 string_p = value;
2681 _dbus_return_val_if_fail (_dbus_check_is_valid_path (*string_p), FALSE);
2682 break;
2683
2684 case DBUS_TYPE_SIGNATURE:
2685 string_p = value;
2686 _dbus_return_val_if_fail (_dbus_check_is_valid_signature (*string_p), FALSE);
2687 break;
2688
2689 case DBUS_TYPE_BOOLEAN:
2690 bool_p = value;
2691 _dbus_return_val_if_fail (*bool_p == 0 || *bool_p == 1, FALSE);
2692 break;
2693
2694 default:
2695 {
2696 /* nothing to check, all possible values are allowed */
2697 }
2698 }
2699 #endif
2700
2701 if (!_dbus_message_iter_open_signature (real))
2702 return FALSE;
2703
2704 if (type == DBUS_TYPE_UNIX_FD)
2705 {
2706 #ifdef HAVE_UNIX_FD_PASSING
2707 int *fds;
2708 dbus_uint32_t u;
2709
2710 /* First step, include the fd in the fd list of this message */
2711 if (!(fds = expand_fd_array(real->message, 1)))
2712 return FALSE;
2713
2714 *fds = _dbus_dup(*(int*) value, NULL);
2715 if (*fds < 0)
2716 return FALSE;
2717
2718 u = real->message->n_unix_fds;
2719
2720 /* Second step, write the index to the fd */
2721 if (!(ret = _dbus_type_writer_write_basic (&real->u.writer, DBUS_TYPE_UNIX_FD, &u))) {
2722 _dbus_close(*fds, NULL);
2723 return FALSE;
2724 }
2725
2726 real->message->n_unix_fds += 1;
2727 u += 1;
2728
2729 /* Final step, update the header accordingly */
2730 ret = _dbus_header_set_field_basic (&real->message->header,
2731 DBUS_HEADER_FIELD_UNIX_FDS,
2732 DBUS_TYPE_UINT32,
2733 &u);
2734
2735 /* If any of these operations fail the message is
2736 hosed. However, no memory or fds should be leaked since what
2737 has been added to message has been added to the message, and
2738 can hence be accounted for when the message is being
2739 freed. */
2740 #else
2741 ret = FALSE;
2742 #endif
2743 }
2744 else
2745 {
2746 ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
2747 }
2748
2749 if (!_dbus_message_iter_close_signature (real))
2750 ret = FALSE;
2751
2752 return ret;
2753 }
2754
2790 dbus_bool_t
2791 dbus_message_iter_append_fixed_array (DBusMessageIter *iter,
2792 int element_type,
2793 const void *value,
2794 int n_elements)
2795 {
2796 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2797 dbus_bool_t ret;
2798
2799 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2800 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2801 _dbus_return_val_if_fail (dbus_type_is_fixed (element_type) && element_type != DBUS_TYPE_UNIX_FD, FALSE);
2802 _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
2803 _dbus_return_val_if_fail (value != NULL, FALSE);
2804 _dbus_return_val_if_fail (n_elements >= 0, FALSE);
2805 _dbus_return_val_if_fail (n_elements <=
2806 DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type),
2807 FALSE);
2808
2809 #ifndef DBUS_DISABLE_CHECKS
2810 if (element_type == DBUS_TYPE_BOOLEAN)
2811 {
2812 const dbus_bool_t * const *bools = value;
2813 int i;
2814
2815 for (i = 0; i < n_elements; i++)
2816 {
2817 _dbus_return_val_if_fail ((*bools)[i] == 0 || (*bools)[i] == 1, FALSE);
2818 }
2819 }
2820 #endif
2821
2822 ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
2823
2824 return ret;
2825 }
2826
2848 dbus_bool_t
2849 dbus_message_iter_open_container (DBusMessageIter *iter,
2850 int type,
2851 const char *contained_signature,
2852 DBusMessageIter *sub)
2853 {
2854 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2855 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2856 DBusString contained_str;
2857
2858 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2859 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2860 _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
2861 _dbus_return_val_if_fail (sub != NULL, FALSE);
2862 _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
2863 contained_signature == NULL) ||
2864 (type == DBUS_TYPE_DICT_ENTRY &&
2865 contained_signature == NULL) ||
2866 (type == DBUS_TYPE_VARIANT &&
2867 contained_signature != NULL) ||
2868 (type == DBUS_TYPE_ARRAY &&
2869 contained_signature != NULL), FALSE);
2870
2871 /* this would fail if the contained_signature is a dict entry, since
2872 * dict entries are invalid signatures standalone (they must be in
2873 * an array)
2874 */
2875 _dbus_return_val_if_fail ((type == DBUS_TYPE_ARRAY && contained_signature && *contained_signature == DBUS_DICT_ENTRY_BEGIN_CHAR) ||
2876 (contained_signature == NULL ||
2877 _dbus_check_is_valid_signature (contained_signature)),
2878 FALSE);
2879
2880 if (!_dbus_message_iter_open_signature (real))
2881 return FALSE;
2882
2883 *real_sub = *real;
2884
2885 if (contained_signature != NULL)
2886 {
2887 _dbus_string_init_const (&contained_str, contained_signature);
2888
2889 return _dbus_type_writer_recurse (&real->u.writer,
2890 type,
2891 &contained_str, 0,
2892 &real_sub->u.writer);
2893 }
2894 else
2895 {
2896 return _dbus_type_writer_recurse (&real->u.writer,
2897 type,
2898 NULL, 0,
2899 &real_sub->u.writer);
2900 }
2901 }
2902
2903
2917 dbus_bool_t
2918 dbus_message_iter_close_container (DBusMessageIter *iter,
2919 DBusMessageIter *sub)
2920 {
2921 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2922 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2923 dbus_bool_t ret;
2924
2925 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2926 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2927 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
2928 _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2929
2930 ret = _dbus_type_writer_unrecurse (&real->u.writer,
2931 &real_sub->u.writer);
2932
2933 if (!_dbus_message_iter_close_signature (real))
2934 ret = FALSE;
2935
2936 return ret;
2937 }
2938
2950 void
2951 dbus_message_iter_abandon_container (DBusMessageIter *iter,
2952 DBusMessageIter *sub)
2953 {
2954 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2955 #ifndef DBUS_DISABLE_CHECKS
2956 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2957
2958 _dbus_return_if_fail (_dbus_message_iter_append_check (real));
2959 _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2960 _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
2961 _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2962 #endif
2963
2964 _dbus_message_iter_abandon_signature (real);
2965 }
2966
2983 void
2984 dbus_message_set_no_reply (DBusMessage *message,
2985 dbus_bool_t no_reply)
2986 {
2987 _dbus_return_if_fail (message != NULL);
2988 _dbus_return_if_fail (!message->locked);
2989
2990 _dbus_header_toggle_flag (&message->header,
2991 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED,
2992 no_reply);
2993 }
2994
3002 dbus_bool_t
3003 dbus_message_get_no_reply (DBusMessage *message)
3004 {
3005 _dbus_return_val_if_fail (message != NULL, FALSE);
3006
3007 return _dbus_header_get_flag (&message->header,
3008 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED);
3009 }
3010
3025 void
3026 dbus_message_set_auto_start (DBusMessage *message,
3027 dbus_bool_t auto_start)
3028 {
3029 _dbus_return_if_fail (message != NULL);
3030 _dbus_return_if_fail (!message->locked);
3031
3032 _dbus_header_toggle_flag (&message->header,
3033 DBUS_HEADER_FLAG_NO_AUTO_START,
3034 !auto_start);
3035 }
3036
3044 dbus_bool_t
3045 dbus_message_get_auto_start (DBusMessage *message)
3046 {
3047 _dbus_return_val_if_fail (message != NULL, FALSE);
3048
3049 return !_dbus_header_get_flag (&message->header,
3050 DBUS_HEADER_FLAG_NO_AUTO_START);
3051 }
3052
3053
3066 dbus_bool_t
3067 dbus_message_set_path (DBusMessage *message,
3068 const char *object_path)
3069 {
3070 _dbus_return_val_if_fail (message != NULL, FALSE);
3071 _dbus_return_val_if_fail (!message->locked, FALSE);
3072 _dbus_return_val_if_fail (object_path == NULL ||
3073 _dbus_check_is_valid_path (object_path),
3074 FALSE);
3075
3076 return set_or_delete_string_field (message,
3077 DBUS_HEADER_FIELD_PATH,
3078 DBUS_TYPE_OBJECT_PATH,
3079 object_path);
3080 }
3081
3095 const char*
3096 dbus_message_get_path (DBusMessage *message)
3097 {
3098 const char *v;
3099
3100 _dbus_return_val_if_fail (message != NULL, NULL);
3101
3102 v = NULL; /* in case field doesn't exist */
3103 _dbus_header_get_field_basic (&message->header,
3104 DBUS_HEADER_FIELD_PATH,
3105 DBUS_TYPE_OBJECT_PATH,
3106 (void *) &v);
3107 return v;
3108 }
3109
3119 dbus_bool_t
3120 dbus_message_has_path (DBusMessage *message,
3121 const char *path)
3122 {
3123 const char *msg_path;
3124 msg_path = dbus_message_get_path (message);
3125
3126 if (msg_path == NULL)
3127 {
3128 if (path == NULL)
3129 return TRUE;
3130 else
3131 return FALSE;
3132 }
3133
3134 if (path == NULL)
3135 return FALSE;
3136
3137 if (strcmp (msg_path, path) == 0)
3138 return TRUE;
3139
3140 return FALSE;
3141 }
3142
3163 dbus_bool_t
3164 dbus_message_get_path_decomposed (DBusMessage *message,
3165 char ***path)
3166 {
3167 const char *v;
3168
3169 _dbus_return_val_if_fail (message != NULL, FALSE);
3170 _dbus_return_val_if_fail (path != NULL, FALSE);
3171
3172 *path = NULL;
3173
3174 v = dbus_message_get_path (message);
3175 if (v != NULL)
3176 {
3177 if (!_dbus_decompose_path (v, strlen (v),
3178 path, NULL))
3179 return FALSE;
3180 }
3181 return TRUE;
3182 }
3183
3197 dbus_bool_t
3198 dbus_message_set_interface (DBusMessage *message,
3199 const char *iface)
3200 {
3201 _dbus_return_val_if_fail (message != NULL, FALSE);
3202 _dbus_return_val_if_fail (!message->locked, FALSE);
3203 _dbus_return_val_if_fail (iface == NULL ||
3204 _dbus_check_is_valid_interface (iface),
3205 FALSE);
3206
3207 return set_or_delete_string_field (message,
3208 DBUS_HEADER_FIELD_INTERFACE,
3209 DBUS_TYPE_STRING,
3210 iface);
3211 }
3212
3226 const char*
3227 dbus_message_get_interface (DBusMessage *message)
3228 {
3229 const char *v;
3230
3231 _dbus_return_val_if_fail (message != NULL, NULL);
3232
3233 v = NULL; /* in case field doesn't exist */
3234 _dbus_header_get_field_basic (&message->header,
3235 DBUS_HEADER_FIELD_INTERFACE,
3236 DBUS_TYPE_STRING,
3237 (void *) &v);
3238 return v;
3239 }
3240
3248 dbus_bool_t
3249 dbus_message_has_interface (DBusMessage *message,
3250 const char *iface)
3251 {
3252 const char *msg_interface;
3253 msg_interface = dbus_message_get_interface (message);
3254
3255 if (msg_interface == NULL)
3256 {
3257 if (iface == NULL)
3258 return TRUE;
3259 else
3260 return FALSE;
3261 }
3262
3263 if (iface == NULL)
3264 return FALSE;
3265
3266 if (strcmp (msg_interface, iface) == 0)
3267 return TRUE;
3268
3269 return FALSE;
3270
3271 }
3272
3285 dbus_bool_t
3286 dbus_message_set_member (DBusMessage *message,
3287 const char *member)
3288 {
3289 _dbus_return_val_if_fail (message != NULL, FALSE);
3290 _dbus_return_val_if_fail (!message->locked, FALSE);
3291 _dbus_return_val_if_fail (member == NULL ||
3292 _dbus_check_is_valid_member (member),
3293 FALSE);
3294
3295 return set_or_delete_string_field (message,
3296 DBUS_HEADER_FIELD_MEMBER,
3297 DBUS_TYPE_STRING,
3298 member);
3299 }
3300
3312 const char*
3313 dbus_message_get_member (DBusMessage *message)
3314 {
3315 const char *v;
3316
3317 _dbus_return_val_if_fail (message != NULL, NULL);
3318
3319 v = NULL; /* in case field doesn't exist */
3320 _dbus_header_get_field_basic (&message->header,
3321 DBUS_HEADER_FIELD_MEMBER,
3322 DBUS_TYPE_STRING,
3323 (void *) &v);
3324 return v;
3325 }
3326
3334 dbus_bool_t
3335 dbus_message_has_member (DBusMessage *message,
3336 const char *member)
3337 {
3338 const char *msg_member;
3339 msg_member = dbus_message_get_member (message);
3340
3341 if (msg_member == NULL)
3342 {
3343 if (member == NULL)
3344 return TRUE;
3345 else
3346 return FALSE;
3347 }
3348
3349 if (member == NULL)
3350 return FALSE;
3351
3352 if (strcmp (msg_member, member) == 0)
3353 return TRUE;
3354
3355 return FALSE;
3356
3357 }
3358
3370 dbus_bool_t
3371 dbus_message_set_error_name (DBusMessage *message,
3372 const char *error_name)
3373 {
3374 _dbus_return_val_if_fail (message != NULL, FALSE);
3375 _dbus_return_val_if_fail (!message->locked, FALSE);
3376 _dbus_return_val_if_fail (error_name == NULL ||
3377 _dbus_check_is_valid_error_name (error_name),
3378 FALSE);
3379
3380 return set_or_delete_string_field (message,
3381 DBUS_HEADER_FIELD_ERROR_NAME,
3382 DBUS_TYPE_STRING,
3383 error_name);
3384 }
3385
3396 const char*
3397 dbus_message_get_error_name (DBusMessage *message)
3398 {
3399 const char *v;
3400
3401 _dbus_return_val_if_fail (message != NULL, NULL);
3402
3403 v = NULL; /* in case field doesn't exist */
3404 _dbus_header_get_field_basic (&message->header,
3405 DBUS_HEADER_FIELD_ERROR_NAME,
3406 DBUS_TYPE_STRING,
3407 (void *) &v);
3408 return v;
3409 }
3410
3424 dbus_bool_t
3425 dbus_message_set_destination (DBusMessage *message,
3426 const char *destination)
3427 {
3428 _dbus_return_val_if_fail (message != NULL, FALSE);
3429 _dbus_return_val_if_fail (!message->locked, FALSE);
3430 _dbus_return_val_if_fail (destination == NULL ||
3431 _dbus_check_is_valid_bus_name (destination),
3432 FALSE);
3433
3434 return set_or_delete_string_field (message,
3435 DBUS_HEADER_FIELD_DESTINATION,
3436 DBUS_TYPE_STRING,
3437 destination);
3438 }
3439
3449 const char*
3450 dbus_message_get_destination (DBusMessage *message)
3451 {
3452 const char *v;
3453
3454 _dbus_return_val_if_fail (message != NULL, NULL);
3455
3456 v = NULL; /* in case field doesn't exist */
3457 _dbus_header_get_field_basic (&message->header,
3458 DBUS_HEADER_FIELD_DESTINATION,
3459 DBUS_TYPE_STRING,
3460 (void *) &v);
3461 return v;
3462 }
3463
3478 dbus_bool_t
3479 dbus_message_set_sender (DBusMessage *message,
3480 const char *sender)
3481 {
3482 _dbus_return_val_if_fail (message != NULL, FALSE);
3483 _dbus_return_val_if_fail (!message->locked, FALSE);
3484 _dbus_return_val_if_fail (sender == NULL ||
3485 _dbus_check_is_valid_bus_name (sender),
3486 FALSE);
3487
3488 return set_or_delete_string_field (message,
3489 DBUS_HEADER_FIELD_SENDER,
3490 DBUS_TYPE_STRING,
3491 sender);
3492 }
3493
3509 const char*
3510 dbus_message_get_sender (DBusMessage *message)
3511 {
3512 const char *v;
3513
3514 _dbus_return_val_if_fail (message != NULL, NULL);
3515
3516 v = NULL; /* in case field doesn't exist */
3517 _dbus_header_get_field_basic (&message->header,
3518 DBUS_HEADER_FIELD_SENDER,
3519 DBUS_TYPE_STRING,
3520 (void *) &v);
3521 return v;
3522 }
3523
3542 const char*
3543 dbus_message_get_signature (DBusMessage *message)
3544 {
3545 const DBusString *type_str;
3546 int type_pos;
3547
3548 _dbus_return_val_if_fail (message != NULL, NULL);
3549
3550 get_const_signature (&message->header, &type_str, &type_pos);
3551
3552 return _dbus_string_get_const_data_len (type_str, type_pos, 0);
3553 }
3554
3555 static dbus_bool_t
3556 _dbus_message_has_type_interface_member (DBusMessage *message,
3557 int type,
3558 const char *iface,
3559 const char *member)
3560 {
3561 const char *n;
3562
3563 _dbus_assert (message != NULL);
3564 _dbus_assert (iface != NULL);
3565 _dbus_assert (member != NULL);
3566
3567 if (dbus_message_get_type (message) != type)
3568 return FALSE;
3569
3570 /* Optimize by checking the short member name first
3571 * instead of the longer interface name
3572 */
3573
3574 n = dbus_message_get_member (message);
3575
3576 if (n && strcmp (n, member) == 0)
3577 {
3578 n = dbus_message_get_interface (message);
3579
3580 if (n == NULL || strcmp (n, iface) == 0)
3581 return TRUE;
3582 }
3583
3584 return FALSE;
3585 }
3586
3601 dbus_bool_t
3602 dbus_message_is_method_call (DBusMessage *message,
3603 const char *iface,
3604 const char *method)
3605 {
3606 _dbus_return_val_if_fail (message != NULL, FALSE);
3607 _dbus_return_val_if_fail (iface != NULL, FALSE);
3608 _dbus_return_val_if_fail (method != NULL, FALSE);
3609 /* don't check that interface/method are valid since it would be
3610 * expensive, and not catch many common errors
3611 */
3612
3613 return _dbus_message_has_type_interface_member (message,
3614 DBUS_MESSAGE_TYPE_METHOD_CALL,
3615 iface, method);
3616 }
3617
3629 dbus_bool_t
3630 dbus_message_is_signal (DBusMessage *message,
3631 const char *iface,
3632 const char *signal_name)
3633 {
3634 _dbus_return_val_if_fail (message != NULL, FALSE);
3635 _dbus_return_val_if_fail (iface != NULL, FALSE);
3636 _dbus_return_val_if_fail (signal_name != NULL, FALSE);
3637 /* don't check that interface/name are valid since it would be
3638 * expensive, and not catch many common errors
3639 */
3640
3641 return _dbus_message_has_type_interface_member (message,
3642 DBUS_MESSAGE_TYPE_SIGNAL,
3643 iface, signal_name);
3644 }
3645
3656 dbus_bool_t
3657 dbus_message_is_error (DBusMessage *message,
3658 const char *error_name)
3659 {
3660 const char *n;
3661
3662 _dbus_return_val_if_fail (message != NULL, FALSE);
3663 _dbus_return_val_if_fail (error_name != NULL, FALSE);
3664 /* don't check that error_name is valid since it would be expensive,
3665 * and not catch many common errors
3666 */
3667
3668 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
3669 return FALSE;
3670
3671 n = dbus_message_get_error_name (message);
3672
3673 if (n && strcmp (n, error_name) == 0)
3674 return TRUE;
3675 else
3676 return FALSE;
3677 }
3678
3689 dbus_bool_t
3690 dbus_message_has_destination (DBusMessage *message,
3691 const char *name)
3692 {
3693 const char *s;
3694
3695 _dbus_return_val_if_fail (message != NULL, FALSE);
3696 _dbus_return_val_if_fail (name != NULL, FALSE);
3697 /* don't check that name is valid since it would be expensive, and
3698 * not catch many common errors
3699 */
3700
3701 s = dbus_message_get_destination (message);
3702
3703 if (s && strcmp (s, name) == 0)
3704 return TRUE;
3705 else
3706 return FALSE;
3707 }
3708
3724 dbus_bool_t
3725 dbus_message_has_sender (DBusMessage *message,
3726 const char *name)
3727 {
3728 const char *s;
3729
3730 _dbus_return_val_if_fail (message != NULL, FALSE);
3731 _dbus_return_val_if_fail (name != NULL, FALSE);
3732 /* don't check that name is valid since it would be expensive, and
3733 * not catch many common errors
3734 */
3735
3736 s = dbus_message_get_sender (message);
3737
3738 if (s && strcmp (s, name) == 0)
3739 return TRUE;
3740 else
3741 return FALSE;
3742 }
3743
3753 dbus_bool_t
3754 dbus_message_has_signature (DBusMessage *message,
3755 const char *signature)
3756 {
3757 const char *s;
3758
3759 _dbus_return_val_if_fail (message != NULL, FALSE);
3760 _dbus_return_val_if_fail (signature != NULL, FALSE);
3761 /* don't check that signature is valid since it would be expensive,
3762 * and not catch many common errors
3763 */
3764
3765 s = dbus_message_get_signature (message);
3766
3767 if (s && strcmp (s, signature) == 0)
3768 return TRUE;
3769 else
3770 return FALSE;
3771 }
3772
3795 dbus_bool_t
3796 dbus_set_error_from_message (DBusError *error,
3797 DBusMessage *message)
3798 {
3799 const char *str;
3800
3801 _dbus_return_val_if_fail (message != NULL, FALSE);
3802 _dbus_return_val_if_error_is_set (error, FALSE);
3803
3804 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
3805 return FALSE;
3806
3807 str = NULL;
3808 dbus_message_get_args (message, NULL,
3809 DBUS_TYPE_STRING, &str,
3810 DBUS_TYPE_INVALID);
3811
3812 dbus_set_error (error, dbus_message_get_error_name (message),
3813 str ? "%s" : NULL, str);
3814
3815 return TRUE;
3816 }
3817
3824 dbus_bool_t
3825 dbus_message_contains_unix_fds(DBusMessage *message)
3826 {
3827 #ifdef HAVE_UNIX_FD_PASSING
3828 _dbus_assert(message);
3829
3830 return message->n_unix_fds > 0;
3831 #else
3832 return FALSE;
3833 #endif
3834 }
3835
3854 #define INITIAL_LOADER_DATA_LEN 32
3855
3862 DBusMessageLoader*
3863 _dbus_message_loader_new (void)
3864 {
3865 DBusMessageLoader *loader;
3866
3867 loader = dbus_new0 (DBusMessageLoader, 1);
3868 if (loader == NULL)
3869 return NULL;
3870
3871 loader->refcount = 1;
3872
3873 loader->corrupted = FALSE;
3874 loader->corruption_reason = DBUS_VALID;
3875
3876 /* this can be configured by the app, but defaults to the protocol max */
3877 loader->max_message_size = DBUS_MAXIMUM_MESSAGE_LENGTH;
3878
3879 /* We set a very relatively conservative default here since due to how
3880 SCM_RIGHTS works we need to preallocate an fd array of the maximum
3881 number of unix fds we want to receive in advance. A
3882 try-and-reallocate loop is not possible. */
3883 loader->max_message_unix_fds = DBUS_DEFAULT_MESSAGE_UNIX_FDS;
3884
3885 if (!_dbus_string_init (&loader->data))
3886 {
3887 dbus_free (loader);
3888 return NULL;
3889 }
3890
3891 /* preallocate the buffer for speed, ignore failure */
3892 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
3893 _dbus_string_set_length (&loader->data, 0);
3894
3895 #ifdef HAVE_UNIX_FD_PASSING
3896 loader->unix_fds = NULL;
3897 loader->n_unix_fds = loader->n_unix_fds_allocated = 0;
3898 loader->unix_fds_outstanding = FALSE;
3899 #endif
3900
3901 return loader;
3902 }
3903
3910 DBusMessageLoader *
3911 _dbus_message_loader_ref (DBusMessageLoader *loader)
3912 {
3913 loader->refcount += 1;
3914
3915 return loader;
3916 }
3917
3924 void
3925 _dbus_message_loader_unref (DBusMessageLoader *loader)
3926 {
3927 loader->refcount -= 1;
3928 if (loader->refcount == 0)
3929 {
3930 #ifdef HAVE_UNIX_FD_PASSING
3931 close_unix_fds(loader->unix_fds, &loader->n_unix_fds);
3932 dbus_free(loader->unix_fds);
3933 #endif
3934 _dbus_list_foreach (&loader->messages,
3935 (DBusForeachFunction) dbus_message_unref,
3936 NULL);
3937 _dbus_list_clear (&loader->messages);
3938 _dbus_string_free (&loader->data);
3939 dbus_free (loader);
3940 }
3941 }
3942
3961 void
3962 _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
3963 DBusString **buffer)
3964 {
3965 _dbus_assert (!loader->buffer_outstanding);
3966
3967 *buffer = &loader->data;
3968
3969 loader->buffer_outstanding = TRUE;
3970 }
3971
3981 void
3982 _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
3983 DBusString *buffer)
3984 {
3985 _dbus_assert (loader->buffer_outstanding);
3986 _dbus_assert (buffer == &loader->data);
3987
3988 loader->buffer_outstanding = FALSE;
3989 }
3990
4001 dbus_bool_t
4002 _dbus_message_loader_get_unix_fds(DBusMessageLoader *loader,
4003 int **fds,
4004 unsigned *max_n_fds)
4005 {
4006 #ifdef HAVE_UNIX_FD_PASSING
4007 _dbus_assert (!loader->unix_fds_outstanding);
4008
4009 /* Allocate space where we can put the fds we read. We allocate
4010 space for max_message_unix_fds since this is an
4011 upper limit how many fds can be received within a single
4012 message. Since SCM_RIGHTS doesn't allow a reallocate+retry logic
4013 we are allocating the maximum possible array size right from the
4014 beginning. This sucks a bit, however unless SCM_RIGHTS is fixed
4015 there is no better way. */
4016
4017 if (loader->n_unix_fds_allocated < loader->max_message_unix_fds)
4018 {
4019 int *a = dbus_realloc(loader->unix_fds,
4020 loader->max_message_unix_fds * sizeof(loader->unix_fds[0]));
4021
4022 if (!a)
4023 return FALSE;
4024
4025 loader->unix_fds = a;
4026 loader->n_unix_fds_allocated = loader->max_message_unix_fds;
4027 }
4028
4029 *fds = loader->unix_fds + loader->n_unix_fds;
4030 *max_n_fds = loader->n_unix_fds_allocated - loader->n_unix_fds;
4031
4032 loader->unix_fds_outstanding = TRUE;
4033 return TRUE;
4034 #else
4035 _dbus_assert_not_reached("Platform doesn't support unix fd passing");
4036 return FALSE;
4037 #endif
4038 }
4039
4050 void
4051 _dbus_message_loader_return_unix_fds(DBusMessageLoader *loader,
4052 int *fds,
4053 unsigned n_fds)
4054 {
4055 #ifdef HAVE_UNIX_FD_PASSING
4056 _dbus_assert(loader->unix_fds_outstanding);
4057 _dbus_assert(loader->unix_fds + loader->n_unix_fds == fds);
4058 _dbus_assert(loader->n_unix_fds + n_fds <= loader->n_unix_fds_allocated);
4059
4060 loader->n_unix_fds += n_fds;
4061 loader->unix_fds_outstanding = FALSE;
4062
4063 if (n_fds && loader->unix_fds_change)
4064 loader->unix_fds_change (loader->unix_fds_change_data);
4065 #else
4066 _dbus_assert_not_reached("Platform doesn't support unix fd passing");
4067 #endif
4068 }
4069
4070 /*
4071 * FIXME when we move the header out of the buffer, that memmoves all
4072 * buffered messages. Kind of crappy.
4073 *
4074 * Also we copy the header and body, which is kind of crappy. To
4075 * avoid this, we have to allow header and body to be in a single
4076 * memory block, which is good for messages we read and bad for
4077 * messages we are creating. But we could move_len() the buffer into
4078 * this single memory block, and move_len() will just swap the buffers
4079 * if you're moving the entire buffer replacing the dest string.
4080 *
4081 * We could also have the message loader tell the transport how many
4082 * bytes to read; so it would first ask for some arbitrary number like
4083 * 256, then if the message was incomplete it would use the
4084 * header/body len to ask for exactly the size of the message (or
4085 * blocks the size of a typical kernel buffer for the socket). That
4086 * way we don't get trailing bytes in the buffer that have to be
4087 * memmoved. Though I suppose we also don't have a chance of reading a
4088 * bunch of small messages at once, so the optimization may be stupid.
4089 *
4090 * Another approach would be to keep a "start" index into
4091 * loader->data and only delete it occasionally, instead of after
4092 * each message is loaded.
4093 *
4094 * load_message() returns FALSE if not enough memory OR the loader was corrupted
4095 */
4096 static dbus_bool_t
4097 load_message (DBusMessageLoader *loader,
4098 DBusMessage *message,
4099 int byte_order,
4100 int fields_array_len,
4101 int header_len,
4102 int body_len)
4103 {
4104 dbus_bool_t oom;
4105 DBusValidity validity;
4106 const DBusString *type_str;
4107 int type_pos;
4108 DBusValidationMode mode;
4109 dbus_uint32_t n_unix_fds = 0;
4110
4111 mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
4112
4113 oom = FALSE;
4114
4115 #if 0
4116 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len /* + body_len */);
4117 #endif
4118
4119 /* 1. VALIDATE AND COPY OVER HEADER */
4120 _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
4121 _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
4122
4123 if (!_dbus_header_load (&message->header,
4124 mode,
4125 &validity,
4126 byte_order,
4127 fields_array_len,
4128 header_len,
4129 body_len,
4130 &loader->data, 0,
4131 _dbus_string_get_length (&loader->data)))
4132 {
4133 _dbus_verbose ("Failed to load header for new message code %d\n", validity);
4134
4135 /* assert here so we can catch any code that still uses DBUS_VALID to indicate
4136 oom errors. They should use DBUS_VALIDITY_UNKNOWN_OOM_ERROR instead */
4137 _dbus_assert (validity != DBUS_VALID);
4138
4139 if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
4140 oom = TRUE;
4141 else
4142 {
4143 loader->corrupted = TRUE;
4144 loader->corruption_reason = validity;
4145 }
4146 goto failed;
4147 }
4148
4149 _dbus_assert (validity == DBUS_VALID);
4150
4151 /* 2. VALIDATE BODY */
4152 if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
4153 {
4154 get_const_signature (&message->header, &type_str, &type_pos);
4155
4156 /* Because the bytes_remaining arg is NULL, this validates that the
4157 * body is the right length
4158 */
4159 validity = _dbus_validate_body_with_reason (type_str,
4160 type_pos,
4161 byte_order,
4162 NULL,
4163 &loader->data,
4164 header_len,
4165 body_len);
4166 if (validity != DBUS_VALID)
4167 {
4168 _dbus_verbose ("Failed to validate message body code %d\n", validity);
4169
4170 loader->corrupted = TRUE;
4171 loader->corruption_reason = validity;
4172
4173 goto failed;
4174 }
4175 }
4176
4177 /* 3. COPY OVER UNIX FDS */
4178 _dbus_header_get_field_basic(&message->header,
4179 DBUS_HEADER_FIELD_UNIX_FDS,
4180 DBUS_TYPE_UINT32,
4181 &n_unix_fds);
4182
4183 #ifdef HAVE_UNIX_FD_PASSING
4184
4185 if (n_unix_fds > loader->n_unix_fds)
4186 {
4187 _dbus_verbose("Message contains references to more unix fds than were sent %u != %u\n",
4188 n_unix_fds, loader->n_unix_fds);
4189
4190 loader->corrupted = TRUE;
4191 loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4192 goto failed;
4193 }
4194
4195 /* If this was a recycled message there might still be
4196 some memory allocated for the fds */
4197 dbus_free(message->unix_fds);
4198
4199 if (n_unix_fds > 0)
4200 {
4201 message->unix_fds = _dbus_memdup(loader->unix_fds, n_unix_fds * sizeof(message->unix_fds[0]));
4202 if (message->unix_fds == NULL)
4203 {
4204 _dbus_verbose ("Failed to allocate file descriptor array\n");
4205 oom = TRUE;
4206 goto failed;
4207 }
4208
4209 message->n_unix_fds_allocated = message->n_unix_fds = n_unix_fds;
4210 loader->n_unix_fds -= n_unix_fds;
4211 memmove (loader->unix_fds, loader->unix_fds + n_unix_fds, loader->n_unix_fds * sizeof (loader->unix_fds[0]));
4212
4213 if (loader->unix_fds_change)
4214 loader->unix_fds_change (loader->unix_fds_change_data);
4215 }
4216 else
4217 message->unix_fds = NULL;
4218
4219 #else
4220
4221 if (n_unix_fds > 0)
4222 {
4223 _dbus_verbose ("Hmm, message claims to come with file descriptors "
4224 "but that's not supported on our platform, disconnecting.\n");
4225
4226 loader->corrupted = TRUE;
4227 loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4228 goto failed;
4229 }
4230
4231 #endif
4232
4233 /* 3. COPY OVER BODY AND QUEUE MESSAGE */
4234
4235 if (!_dbus_list_append (&loader->messages, message))
4236 {
4237 _dbus_verbose ("Failed to append new message to loader queue\n");
4238 oom = TRUE;
4239 goto failed;
4240 }
4241
4242 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
4243 _dbus_assert (_dbus_string_get_length (&loader->data) >=
4244 (header_len + body_len));
4245
4246 if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
4247 {
4248 _dbus_verbose ("Failed to move body into new message\n");
4249 oom = TRUE;
4250 goto failed;
4251 }
4252
4253 _dbus_string_delete (&loader->data, 0, header_len + body_len);
4254
4255 /* don't waste more than 2k of memory */
4256 _dbus_string_compact (&loader->data, 2048);
4257
4258 _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
4259 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
4260
4261 _dbus_verbose ("Loaded message %p\n", message);
4262
4263 _dbus_assert (!oom);
4264 _dbus_assert (!loader->corrupted);
4265 _dbus_assert (loader->messages != NULL);
4266 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4267
4268 return TRUE;
4269
4270 failed:
4271
4272 /* Clean up */
4273
4274 /* does nothing if the message isn't in the list */
4275 _dbus_list_remove_last (&loader->messages, message);
4276
4277 if (oom)
4278 _dbus_assert (!loader->corrupted);
4279 else
4280 _dbus_assert (loader->corrupted);
4281
4282 _dbus_verbose_bytes_of_string (&loader->data, 0, _dbus_string_get_length (&loader->data));
4283
4284 return FALSE;
4285 }
4286
4301 dbus_bool_t
4302 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
4303 {
4304 while (!loader->corrupted &&
4305 _dbus_string_get_length (&loader->data) >= DBUS_MINIMUM_HEADER_SIZE)
4306 {
4307 DBusValidity validity;
4308 int byte_order, fields_array_len, header_len, body_len;
4309
4310 if (_dbus_header_have_message_untrusted (loader->max_message_size,
4311 &validity,
4312 &byte_order,
4313 &fields_array_len,
4314 &header_len,
4315 &body_len,
4316 &loader->data, 0,
4317 _dbus_string_get_length (&loader->data)))
4318 {
4319 DBusMessage *message;
4320
4321 _dbus_assert (validity == DBUS_VALID);
4322
4323 message = dbus_message_new_empty_header ();
4324 if (message == NULL)
4325 return FALSE;
4326
4327 if (!load_message (loader, message,
4328 byte_order, fields_array_len,
4329 header_len, body_len))
4330 {
4331 dbus_message_unref (message);
4332 /* load_message() returns false if corrupted or OOM; if
4333 * corrupted then return TRUE for not OOM
4334 */
4335 return loader->corrupted;
4336 }
4337
4338 _dbus_assert (loader->messages != NULL);
4339 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4340 }
4341 else
4342 {
4343 _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
4344 validity);
4345 if (validity != DBUS_VALID)
4346 {
4347 loader->corrupted = TRUE;
4348 loader->corruption_reason = validity;
4349 }
4350 return TRUE;
4351 }
4352 }
4353
4354 return TRUE;
4355 }
4356
4364 DBusMessage*
4365 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
4366 {
4367 if (loader->messages)
4368 return loader->messages->data;
4369 else
4370 return NULL;
4371 }
4372
4381 DBusMessage*
4382 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
4383 {
4384 return _dbus_list_pop_first (&loader->messages);
4385 }
4386
4395 DBusList*
4396 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
4397 {
4398 return _dbus_list_pop_first_link (&loader->messages);
4399 }
4400
4407 void
4408 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
4409 DBusList *link)
4410 {
4411 _dbus_list_prepend_link (&loader->messages, link);
4412 }
4413
4423 dbus_bool_t
4424 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
4425 {
4426 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
4427 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
4428 return loader->corrupted;
4429 }
4430
4437 DBusValidity
4438 _dbus_message_loader_get_corruption_reason (DBusMessageLoader *loader)
4439 {
4440 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
4441 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
4442
4443 return loader->corruption_reason;
4444 }
4445
4452 void
4453 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
4454 long size)
4455 {
4456 if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
4457 {
4458 _dbus_verbose ("clamping requested max message size %ld to %d\n",
4459 size, DBUS_MAXIMUM_MESSAGE_LENGTH);
4460 size = DBUS_MAXIMUM_MESSAGE_LENGTH;
4461 }
4462 loader->max_message_size = size;
4463 }
4464
4471 long
4472 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
4473 {
4474 return loader->max_message_size;
4475 }
4476
4483 void
4484 _dbus_message_loader_set_max_message_unix_fds (DBusMessageLoader *loader,
4485 long n)
4486 {
4487 if (n > DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
4488 {
4489 _dbus_verbose ("clamping requested max message unix_fds %ld to %d\n",
4490 n, DBUS_MAXIMUM_MESSAGE_UNIX_FDS);
4491 n = DBUS_MAXIMUM_MESSAGE_UNIX_FDS;
4492 }
4493 loader->max_message_unix_fds = n;
4494 }
4495
4502 long
4503 _dbus_message_loader_get_max_message_unix_fds (DBusMessageLoader *loader)
4504 {
4505 return loader->max_message_unix_fds;
4506 }
4507
4513 int
4514 _dbus_message_loader_get_pending_fds_count (DBusMessageLoader *loader)
4515 {
4516 #ifdef HAVE_UNIX_FD_PASSING
4517 return loader->n_unix_fds;
4518 #else
4519 return 0;
4520 #endif
4521 }
4522
4531 void
4532 _dbus_message_loader_set_pending_fds_function (DBusMessageLoader *loader,
4533 void (* callback) (void *),
4534 void *data)
4535 {
4536 #ifdef HAVE_UNIX_FD_PASSING
4537 loader->unix_fds_change = callback;
4538 loader->unix_fds_change_data = data;
4539 #endif
4540 }
4541
4542 static DBusDataSlotAllocator slot_allocator =
4543 _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (message_slots));
4544
4559 dbus_bool_t
4560 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
4561 {
4562 return _dbus_data_slot_allocator_alloc (&slot_allocator,
4563 slot_p);
4564 }
4565
4577 void
4578 dbus_message_free_data_slot (dbus_int32_t *slot_p)
4579 {
4580 _dbus_return_if_fail (*slot_p >= 0);
4581
4582 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
4583 }
4584
4598 dbus_bool_t
4599 dbus_message_set_data (DBusMessage *message,
4600 dbus_int32_t slot,
4601 void *data,
4602 DBusFreeFunction free_data_func)
4603 {
4604 DBusFreeFunction old_free_func;
4605 void *old_data;
4606 dbus_bool_t retval;
4607
4608 _dbus_return_val_if_fail (message != NULL, FALSE);
4609 _dbus_return_val_if_fail (slot >= 0, FALSE);
4610
4611 retval = _dbus_data_slot_list_set (&slot_allocator,
4612 &message->slot_list,
4613 slot, data, free_data_func,
4614 &old_free_func, &old_data);
4615
4616 if (retval)
4617 {
4618 /* Do the actual free outside the message lock */
4619 if (old_free_func)
4620 (* old_free_func) (old_data);
4621 }
4622
4623 return retval;
4624 }
4625
4634 void*
4635 dbus_message_get_data (DBusMessage *message,
4636 dbus_int32_t slot)
4637 {
4638 void *res;
4639
4640 _dbus_return_val_if_fail (message != NULL, NULL);
4641
4642 res = _dbus_data_slot_list_get (&slot_allocator,
4643 &message->slot_list,
4644 slot);
4645
4646 return res;
4647 }
4648
4662 int
4663 dbus_message_type_from_string (const char *type_str)
4664 {
4665 if (strcmp (type_str, "method_call") == 0)
4666 return DBUS_MESSAGE_TYPE_METHOD_CALL;
4667 if (strcmp (type_str, "method_return") == 0)
4668 return DBUS_MESSAGE_TYPE_METHOD_RETURN;
4669 else if (strcmp (type_str, "signal") == 0)
4670 return DBUS_MESSAGE_TYPE_SIGNAL;
4671 else if (strcmp (type_str, "error") == 0)
4672 return DBUS_MESSAGE_TYPE_ERROR;
4673 else
4674 return DBUS_MESSAGE_TYPE_INVALID;
4675 }
4676
4690 const char *
4691 dbus_message_type_to_string (int type)
4692 {
4693 switch (type)
4694 {
4695 case DBUS_MESSAGE_TYPE_METHOD_CALL:
4696 return "method_call";
4697 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
4698 return "method_return";
4699 case DBUS_MESSAGE_TYPE_SIGNAL:
4700 return "signal";
4701 case DBUS_MESSAGE_TYPE_ERROR:
4702 return "error";
4703 default:
4704 return "invalid";
4705 }
4706 }
4707
4720 dbus_bool_t
4721 dbus_message_marshal (DBusMessage *msg,
4722 char **marshalled_data_p,
4723 int *len_p)
4724 {
4725 DBusString tmp;
4726 dbus_bool_t was_locked;
4727
4728 _dbus_return_val_if_fail (msg != NULL, FALSE);
4729 _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
4730 _dbus_return_val_if_fail (len_p != NULL, FALSE);
4731
4732 if (!_dbus_string_init (&tmp))
4733 return FALSE;
4734
4735 /* Ensure the message is locked, to ensure the length header is filled in. */
4736 was_locked = msg->locked;
4737
4738 if (!was_locked)
4739 dbus_message_lock (msg);
4740
4741 if (!_dbus_string_copy (&(msg->header.data), 0, &tmp, 0))
4742 goto fail;
4743
4744 *len_p = _dbus_string_get_length (&tmp);
4745
4746 if (!_dbus_string_copy (&(msg->body), 0, &tmp, *len_p))
4747 goto fail;
4748
4749 *len_p = _dbus_string_get_length (&tmp);
4750
4751 if (!_dbus_string_steal_data (&tmp, marshalled_data_p))
4752 goto fail;
4753
4754 _dbus_string_free (&tmp);
4755
4756 if (!was_locked)
4757 msg->locked = FALSE;
4758
4759 return TRUE;
4760
4761 fail:
4762 _dbus_string_free (&tmp);
4763
4764 if (!was_locked)
4765 msg->locked = FALSE;
4766
4767 return FALSE;
4768 }
4769
4782 DBusMessage *
4783 dbus_message_demarshal (const char *str,
4784 int len,
4785 DBusError *error)
4786 {
4787 DBusMessageLoader *loader;
4788 DBusString *buffer;
4789 DBusMessage *msg;
4790
4791 _dbus_return_val_if_fail (str != NULL, NULL);
4792
4793 loader = _dbus_message_loader_new ();
4794
4795 if (loader == NULL)
4796 return NULL;
4797
4798 _dbus_message_loader_get_buffer (loader, &buffer);
4799 _dbus_string_append_len (buffer, str, len);
4800 _dbus_message_loader_return_buffer (loader, buffer);
4801
4802 if (!_dbus_message_loader_queue_messages (loader))
4803 goto fail_oom;
4804
4805 if (_dbus_message_loader_get_is_corrupted (loader))
4806 goto fail_corrupt;
4807
4808 msg = _dbus_message_loader_pop_message (loader);
4809
4810 if (!msg)
4811 goto fail_oom;
4812
4813 _dbus_message_loader_unref (loader);
4814 return msg;
4815
4816 fail_corrupt:
4817 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted (%s)",
4818 _dbus_validity_to_error_message (loader->corruption_reason));
4819 _dbus_message_loader_unref (loader);
4820 return NULL;
4821
4822 fail_oom:
4823 _DBUS_SET_OOM (error);
4824 _dbus_message_loader_unref (loader);
4825 return NULL;
4826 }
4827
4840 int
4841 dbus_message_demarshal_bytes_needed(const char *buf,
4842 int len)
4843 {
4844 DBusString str;
4845 int byte_order, fields_array_len, header_len, body_len;
4846 DBusValidity validity = DBUS_VALID;
4847 int have_message;
4848
4849 if (!buf || len < DBUS_MINIMUM_HEADER_SIZE)
4850 return 0;
4851
4852 if (len > DBUS_MAXIMUM_MESSAGE_LENGTH)
4853 len = DBUS_MAXIMUM_MESSAGE_LENGTH;
4854 _dbus_string_init_const_len (&str, buf, len);
4855
4856 validity = DBUS_VALID;
4857 have_message
4858 = _dbus_header_have_message_untrusted(DBUS_MAXIMUM_MESSAGE_LENGTH,
4859 &validity, &byte_order,
4860 &fields_array_len,
4861 &header_len,
4862 &body_len,
4863 &str, 0,
4864 len);
4865 _dbus_string_free (&str);
4866
4867 if (validity == DBUS_VALID)
4868 {
4869 _dbus_assert (have_message || (header_len + body_len) > len);
4870 (void) have_message; /* unused unless asserting */
4871 return header_len + body_len;
4872 }
4873 else
4874 {
4875 return -1; /* broken! */
4876 }
4877 }
4878
4881 /* tests in dbus-message-util.c */
dbus_type_is_fixed
dbus_bool_t dbus_type_is_fixed(int typecode)
Tells you whether values of this type can change length if you set them to some other value...
Definition: dbus-signature.c:349
_dbus_type_reader_read_fixed_multi
void _dbus_type_reader_read_fixed_multi(const DBusTypeReader *reader, void *value, int *n_elements)
Reads a block of fixed-length basic values, from the current point in an array to the end of the arra...
Definition: dbus-marshal-recursive.c:923
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:4663
dbus_message_ref
DBusMessage * dbus_message_ref(DBusMessage *message)
Increments the reference count of a DBusMessage.
Definition: dbus-message.c:1667
dbus_message_lock
void dbus_message_lock(DBusMessage *message)
Locks a message.
Definition: dbus-message.c:384
DBusError::message
const char * message
public error message field
Definition: dbus-errors.h:51
dbus_message_has_path
dbus_bool_t dbus_message_has_path(DBusMessage *message, const char *path)
Checks if the message has a particular object path.
Definition: dbus-message.c:3120
_dbus_atomic_get
dbus_int32_t _dbus_atomic_get(DBusAtomic *atomic)
Atomically get the value of an integer.
Definition: dbus-sysdeps-unix.c:2547
DBusMessage::changed_stamp
dbus_uint32_t changed_stamp
Incremented when iterators are invalidated.
Definition: dbus-message-private.h:116
NULL
#define NULL
A null pointer, defined appropriately for C or C++.
dbus_message_is_method_call
dbus_bool_t dbus_message_is_method_call(DBusMessage *message, const char *iface, const char *method)
Checks whether the message is a method call with the given interface and member fields.
Definition: dbus-message.c:3602
_dbus_header_load
dbus_bool_t _dbus_header_load(DBusHeader *header, DBusValidationMode mode, DBusValidity *validity, int byte_order, int fields_array_len, int header_len, int body_len, const DBusString *str, int start, int len)
Creates a message header from potentially-untrusted data.
Definition: dbus-marshal-header.c:970
DBusFreeFunction
void(* DBusFreeFunction)(void *memory)
The type of a function which frees a block of memory.
Definition: dbus-memory.h:64
_dbus_message_loader_get_max_message_size
long _dbus_message_loader_get_max_message_size(DBusMessageLoader *loader)
Gets the maximum allowed message size in bytes.
Definition: dbus-message.c:4472
dbus_message_set_no_reply
void dbus_message_set_no_reply(DBusMessage *message, dbus_bool_t no_reply)
Sets a flag indicating that the message does not want a reply; if this flag is set, the other end of the connection may (but is not required to) optimize by not sending method return or error replies.
Definition: dbus-message.c:2984
_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:4408
_dbus_header_copy
dbus_bool_t _dbus_header_copy(const DBusHeader *header, DBusHeader *dest)
Initializes dest with a copy of the given header.
Definition: dbus-marshal-header.c:490
dbus_message_iter_get_arg_type
int dbus_message_iter_get_arg_type(DBusMessageIter *iter)
Returns the argument type of the argument that the message iterator points to.
Definition: dbus-message.c:2139
DBusMessageRealIter::sig_refcount
dbus_uint32_t sig_refcount
depth of open_signature()
Definition: dbus-message.c:131
_dbus_message_loader_return_buffer
void _dbus_message_loader_return_buffer(DBusMessageLoader *loader, DBusString *buffer)
Returns a buffer obtained from _dbus_message_loader_get_buffer(), indicating to the loader how many b...
Definition: dbus-message.c:3982
_dbus_type_writer_remove_types
void _dbus_type_writer_remove_types(DBusTypeWriter *writer)
Removes type string from the writer.
Definition: dbus-marshal-recursive.c:1560
dbus_realloc
void * dbus_realloc(void *memory, size_t bytes)
Resizes a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:601
dbus_free
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:701
_dbus_message_loader_return_unix_fds
void _dbus_message_loader_return_unix_fds(DBusMessageLoader *loader, int *fds, unsigned n_fds)
Returns a buffer obtained from _dbus_message_loader_get_unix_fds().
Definition: dbus-message.c:4051
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:1127
DBusMessageLoader::messages
DBusList * messages
Complete messages.
Definition: dbus-message-private.h:66
DBusTypeWriter
The type writer is an iterator for writing to a block of values.
Definition: dbus-marshal-recursive.h:64
dbus_message_iter_recurse
void dbus_message_iter_recurse(DBusMessageIter *iter, DBusMessageIter *sub)
Recurses into a container value when reading values from a message, initializing a sub-iterator to us...
Definition: dbus-message.c:2195
_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
_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:4382
_dbus_list_find_last
DBusList * _dbus_list_find_last(DBusList **list, void *data)
Finds a value in the list.
Definition: dbus-list.c:472
dbus_message_set_interface
dbus_bool_t dbus_message_set_interface(DBusMessage *message, const char *iface)
Sets the interface this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or the interface...
Definition: dbus-message.c:3198
DBUS_ERROR_NOT_SUPPORTED
#define DBUS_ERROR_NOT_SUPPORTED
Requested operation isn't supported (like ENOSYS on UNIX).
Definition: dbus-protocol.h:364
dbus_new
#define dbus_new(type, count)
Safe macro for using dbus_malloc().
Definition: dbus-memory.h:58
dbus_message_free_data_slot
void dbus_message_free_data_slot(dbus_int32_t *slot_p)
Deallocates a global ID for message data slots.
Definition: dbus-message.c:4578
DBUS_HEADER_FIELD_SIGNATURE
#define DBUS_HEADER_FIELD_SIGNATURE
Header field code for the type signature of a message.
Definition: dbus-protocol.h:292
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:3397
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:2918
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:3657
_dbus_list_remove_link
void _dbus_list_remove_link(DBusList **list, DBusList *link)
Removes a link from the list.
Definition: dbus-list.c:527
DBUS_TYPE_STRUCT
#define DBUS_TYPE_STRUCT
STRUCT and DICT_ENTRY are sort of special since their codes can't appear in a type string...
Definition: dbus-protocol.h:136
DBUS_TYPE_DICT_ENTRY
#define DBUS_TYPE_DICT_ENTRY
Type code used to represent a dict entry; however, this type code does not appear in type signatures...
Definition: dbus-protocol.h:143
dbus_message_get_sender
const char * dbus_message_get_sender(DBusMessage *message)
Gets the unique name of the connection which originated this message, or NULL if unknown or inapplica...
Definition: dbus-message.c:3510
_dbus_message_iter_get_args_valist
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:796
DBUS_TYPE_STRING
#define DBUS_TYPE_STRING
Type code marking a UTF-8 encoded, nul-terminated Unicode string.
Definition: dbus-protocol.h:102
DBusMessage::body
DBusString body
Body network data.
Definition: dbus-message-private.h:105
_dbus_header_get_serial
dbus_uint32_t _dbus_header_get_serial(DBusHeader *header)
See dbus_message_get_serial()
Definition: dbus-marshal-header.c:427
_dbus_header_get_flag
dbus_bool_t _dbus_header_get_flag(DBusHeader *header, dbus_uint32_t flag)
Gets a message flag bit, returning TRUE if the bit is set.
Definition: dbus-marshal-header.c:1479
_dbus_assert
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
Definition: dbus-internals.h:135
DBUS_HEADER_FLAG_NO_REPLY_EXPECTED
#define DBUS_HEADER_FLAG_NO_REPLY_EXPECTED
If set, this flag means that the sender of a message does not care about getting a reply...
Definition: dbus-protocol.h:249
_dbus_list_append_link
void _dbus_list_append_link(DBusList **list, DBusList *link)
Appends a link to the list.
Definition: dbus-list.c:315
DBusCounter
Internals of DBusCounter.
Definition: dbus-resources.c:54
dbus_message_allocate_data_slot
dbus_bool_t dbus_message_allocate_data_slot(dbus_int32_t *slot_p)
Allocates an integer ID to be used for storing application-specific data on any DBusMessage.
Definition: dbus-message.c:4560
DBusList::data
void * data
Data stored at this element.
Definition: dbus-list.h:38
MAX_MESSAGE_CACHE_SIZE
#define MAX_MESSAGE_CACHE_SIZE
Avoid caching too many messages.
Definition: dbus-message.c:508
dbus_message_new
DBusMessage * dbus_message_new(int message_type)
Constructs a new message of the given message type.
Definition: dbus-message.c:1289
DBUS_ERROR_INCONSISTENT_MESSAGE
#define DBUS_ERROR_INCONSISTENT_MESSAGE
The message meta data does not match the payload.
Definition: dbus-protocol.h:448
_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:460
_dbus_warn_check_failed
void _dbus_warn_check_failed(const char *format,...)
Prints a "critical" warning to stderr when an assertion fails; differs from _dbus_warn primarily in t...
Definition: dbus-internals.c:258
dbus_message_get_signature
const char * dbus_message_get_signature(DBusMessage *message)
Gets the type signature of the message, i.e.
Definition: dbus-message.c:3543
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:2421
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_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:3026
DBusMessageRealIter::u
union DBusMessageRealIter::@6 u
the type writer or reader that does all the work
_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:3925
_dbus_counter_ref
DBusCounter * _dbus_counter_ref(DBusCounter *counter)
Increments refcount of the counter.
Definition: dbus-resources.c:108
DBusHeader::data
DBusString data
Header network data, stored separately from body so we can independently realloc it.
Definition: dbus-marshal-header.h:49
dbus_message_has_interface
dbus_bool_t dbus_message_has_interface(DBusMessage *message, const char *iface)
Checks if the message has an interface.
Definition: dbus-message.c:3249
_dbus_dup
int _dbus_dup(int fd, DBusError *error)
Duplicates a file descriptor.
Definition: dbus-sysdeps-unix.c:2986
_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:4438
_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:2308
DBUS_MESSAGE_TYPE_ERROR
#define DBUS_MESSAGE_TYPE_ERROR
Message type of an error reply message, see dbus_message_get_type()
Definition: dbus-protocol.h:238
_dbus_list_alloc_link
DBusList * _dbus_list_alloc_link(void *data)
Allocates a linked list node.
Definition: dbus-list.c:242
DBUS_MAXIMUM_MESSAGE_UNIX_FDS
#define DBUS_MAXIMUM_MESSAGE_UNIX_FDS
The maximum total number of unix fds in a message.
Definition: dbus-protocol.h:218
dbus_message_get_path
const char * dbus_message_get_path(DBusMessage *message)
Gets the object path this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitt...
Definition: dbus-message.c:3096
_dbus_string_init
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
DBUS_MESSAGE_TYPE_METHOD_RETURN
#define DBUS_MESSAGE_TYPE_METHOD_RETURN
Message type of a method return message, see dbus_message_get_type()
Definition: dbus-protocol.h:236
dbus_message_new_signal
DBusMessage * dbus_message_new_signal(const char *path, const char *iface, const char *name)
Constructs a new message representing a signal emission.
Definition: dbus-message.c:1424
_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:1055
DBusMessageRealIter::reader
DBusTypeReader reader
reader
Definition: dbus-message.c:135
DBusValidationMode
DBusValidationMode
This is used rather than a bool for high visibility.
Definition: dbus-marshal-validate.h:36
dbus_message_iter_has_next
dbus_bool_t dbus_message_iter_has_next(DBusMessageIter *iter)
Checks if an iterator has any more fields.
Definition: dbus-message.c:2095
DBusMessageRealIter::message
DBusMessage * message
Message used.
Definition: dbus-message.c:128
_dbus_string_copy
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that's copied to the d...
Definition: dbus-string.c:1265
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:269
DBUS_DICT_ENTRY_BEGIN_CHAR
#define DBUS_DICT_ENTRY_BEGIN_CHAR
Code marking the start of a dict entry type in a type signature.
Definition: dbus-protocol.h:164
_dbus_list_pop_first_link
DBusList * _dbus_list_pop_first_link(DBusList **list)
Removes the first link in the list and returns it.
Definition: dbus-list.c:628
dbus_message_has_member
dbus_bool_t dbus_message_has_member(DBusMessage *message, const char *member)
Checks if the message has an interface member.
Definition: dbus-message.c:3335
DBusValidity
DBusValidity
This is primarily used in unit testing, so we can verify that each invalid message is invalid for the...
Definition: dbus-marshal-validate.h:49
DBusMessageIter
DBusMessageIter struct; contains no public fields.
Definition: dbus-message.h:51
dbus_message_iter_init
dbus_bool_t dbus_message_iter_init(DBusMessage *message, DBusMessageIter *iter)
Initializes a DBusMessageIter for reading the arguments of the message passed in. ...
Definition: dbus-message.c:2064
_dbus_message_add_counter
dbus_bool_t _dbus_message_add_counter(DBusMessage *message, DBusCounter *counter)
Adds a counter to be incremented immediately with the size/unix fds of this message, and decremented by the size/unix fds of this message when this message if finalized.
Definition: dbus-message.c:329
_dbus_getenv
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:185
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:3450
_dbus_message_add_counter_link
void _dbus_message_add_counter_link(DBusMessage *message, DBusList *link)
Adds a counter to be incremented immediately with the size/unix fds of this message, and decremented by the size/unix fds of this message when this message if finalized.
Definition: dbus-message.c:280
DBUS_TYPE_ARRAY
#define DBUS_TYPE_ARRAY
Type code marking a D-Bus array type.
Definition: dbus-protocol.h:120
DBusTypeWriter::type_str
DBusString * type_str
where to write typecodes (or read type expectations)
Definition: dbus-marshal-recursive.h:74
dbus_message_iter_append_fixed_array
dbus_bool_t dbus_message_iter_append_fixed_array(DBusMessageIter *iter, int element_type, const void *value, int n_elements)
Appends a block of fixed-length values to an array.
Definition: dbus-message.c:2791
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:3371
_dbus_atomic_dec
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
Definition: dbus-sysdeps-unix.c:2523
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:3313
_dbus_list_remove_last
dbus_bool_t _dbus_list_remove_last(DBusList **list, void *data)
Removes a value from the list.
Definition: dbus-list.c:446
DBusMessage
Internals of DBusMessage.
Definition: dbus-message-private.h:99
DBusMessageRealIter
Internals of DBusMessageIter.
Definition: dbus-message.c:126
dbus_new0
#define dbus_new0(type, count)
Safe macro for using dbus_malloc0().
Definition: dbus-memory.h:59
DBusMessageRealIter::changed_stamp
dbus_uint32_t changed_stamp
stamp to detect invalid iters
Definition: dbus-message.c:129
_dbus_type_writer_init_types_delayed
void _dbus_type_writer_init_types_delayed(DBusTypeWriter *writer, int byte_order, DBusString *value_str, int value_pos)
Initialize a write iterator, with the signature to be provided later.
Definition: dbus-marshal-recursive.c:1525
_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:372
_dbus_header_get_message_type
int _dbus_header_get_message_type(DBusHeader *header)
Gets the type of the message.
Definition: dbus-marshal-header.c:386
DBUS_HEADER_FIELD_ERROR_NAME
#define DBUS_HEADER_FIELD_ERROR_NAME
Header field code for an error name (found in DBUS_MESSAGE_TYPE_ERROR messages).
Definition: dbus-protocol.h:275
DBusString
Definition: dbus-string.h:42
DBUS_MINIMUM_HEADER_SIZE
#define DBUS_MINIMUM_HEADER_SIZE
The smallest header size that can occur.
Definition: dbus-protocol.h:341
_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:2176
dbus_type_is_basic
dbus_bool_t dbus_type_is_basic(int typecode)
A "basic type" is a somewhat arbitrary concept, but the intent is to include those types that are ful...
Definition: dbus-signature.c:318
_dbus_message_loader_set_max_message_size
void _dbus_message_loader_set_max_message_size(DBusMessageLoader *loader, long size)
Sets the maximum size message we allow.
Definition: dbus-message.c:4453
dbus_bool_t
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
_dbus_string_init_const
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:190
DBusMessage::header
DBusHeader header
Header network data and associated cache.
Definition: dbus-message-private.h:103
dbus_message_set_sender
dbus_bool_t dbus_message_set_sender(DBusMessage *message, const char *sender)
Sets the message sender.
Definition: dbus-message.c:3479
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:3630
DBusMessageLoader::data
DBusString data
Buffered data.
Definition: dbus-message-private.h:64
_dbus_type_reader_read_basic
void _dbus_type_reader_read_basic(const DBusTypeReader *reader, void *value)
Reads a basic-typed value, as with _dbus_marshal_read_basic().
Definition: dbus-marshal-recursive.c:869
DBusMessage::locked
unsigned int locked
Message being sent, no modifications allowed.
Definition: dbus-message-private.h:107
ensure_byte_order
#define ensure_byte_order(message)
byte-swap the message if it doesn't match our byte order.
Definition: dbus-message.c:195
_dbus_message_loader_ref
DBusMessageLoader * _dbus_message_loader_ref(DBusMessageLoader *loader)
Increments the reference count of the loader.
Definition: dbus-message.c:3911
_dbus_header_get_field_basic
dbus_bool_t _dbus_header_get_field_basic(DBusHeader *header, int field, int type, void *value)
Gets the value of a field with basic type.
Definition: dbus-marshal-header.c:1351
dbus_message_get_path_decomposed
dbus_bool_t dbus_message_get_path_decomposed(DBusMessage *message, char ***path)
Gets the object path this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitt...
Definition: dbus-message.c:3164
DBUS_VALIDITY_UNKNOWN_OOM_ERROR
can't determine validity due to OOM
Definition: dbus-marshal-validate.h:52
_dbus_warn
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
Definition: dbus-internals.c:230
_dbus_string_delete
void _dbus_string_delete(DBusString *str, int start, int len)
Deletes a segment of a DBusString with length len starting at start.
Definition: dbus-string.c:1175
_dbus_string_init_preallocated
dbus_bool_t _dbus_string_init_preallocated(DBusString *str, int allocate_size)
Initializes a string that can be up to the given allocation size before it has to realloc...
Definition: dbus-string.c:132
_dbus_counter_unref
void _dbus_counter_unref(DBusCounter *counter)
Decrements refcount of the counter and possibly finalizes the counter.
Definition: dbus-resources.c:124
_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:352
_dbus_list_append
dbus_bool_t _dbus_list_append(DBusList **list, void *data)
Appends a value to the list.
Definition: dbus-list.c:270
_dbus_decompose_path
dbus_bool_t _dbus_decompose_path(const char *data, int len, char ***path, int *path_len)
Decompose an object path.
Definition: dbus-object-tree.c:1242
_dbus_memdup
void * _dbus_memdup(const void *mem, size_t n_bytes)
Duplicates a block of memory.
Definition: dbus-internals.c:555
_dbus_data_slot_list_set
dbus_bool_t _dbus_data_slot_list_set(DBusDataSlotAllocator *allocator, DBusDataSlotList *list, int slot, void *data, DBusFreeFunction free_data_func, DBusFreeFunction *old_free_func, void **old_data)
Stores a pointer in the data slot list, along with an optional function to be used for freeing the da...
Definition: dbus-dataslot.c:221
dbus_message_set_path
dbus_bool_t dbus_message_set_path(DBusMessage *message, const char *object_path)
Sets the object path this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or the one a s...
Definition: dbus-message.c:3067
_dbus_list_foreach
void _dbus_list_foreach(DBusList **list, DBusForeachFunction function, void *data)
Calls the given function for each element in the list.
Definition: dbus-list.c:759
DBusMessageLoader::max_message_size
long max_message_size
Maximum size of a message.
Definition: dbus-message-private.h:68
_dbus_counter_adjust_unix_fd
void _dbus_counter_adjust_unix_fd(DBusCounter *counter, long delta)
Adjusts the value of the unix fd counter by the given delta which may be positive or negative...
Definition: dbus-resources.c:202
_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:1051
DBusMessage::counters
DBusList * counters
0-N DBusCounter used to track message size/unix fds.
Definition: dbus-message-private.h:113
_dbus_message_loader_new
DBusMessageLoader * _dbus_message_loader_new(void)
Creates a new message loader.
Definition: dbus-message.c:3863
DBusMessage::size_counter_delta
long size_counter_delta
Size we incremented the size counters by.
Definition: dbus-message-private.h:114
CHANGED_STAMP_BITS
#define CHANGED_STAMP_BITS
How many bits are in the changed_stamp used to validate iterators.
Definition: dbus-message-private.h:90
_dbus_header_byteswap
void _dbus_header_byteswap(DBusHeader *header, int new_order)
Swaps the header into the given order if required.
Definition: dbus-marshal-header.c:1496
_dbus_header_have_message_untrusted
dbus_bool_t _dbus_header_have_message_untrusted(int max_message_length, DBusValidity *validity, int *byte_order, int *fields_array_len, int *header_len, int *body_len, const DBusString *str, int start, int len)
Given data long enough to contain the length of the message body and the fields array, check whether the data is long enough to contain the entire message (assuming the claimed lengths are accurate).
Definition: dbus-marshal-header.c:673
DBUS_MESSAGE_TYPE_METHOD_CALL
#define DBUS_MESSAGE_TYPE_METHOD_CALL
Message type of a method call message, see dbus_message_get_type()
Definition: dbus-protocol.h:234
DBUS_HEADER_FIELD_UNIX_FDS
#define DBUS_HEADER_FIELD_UNIX_FDS
Header field code for the number of unix file descriptors associated with this message.
Definition: dbus-protocol.h:297
_dbus_current_generation
int _dbus_current_generation
_dbus_current_generation is used to track each time that dbus_shutdown() is called, so we can reinit things after it's been called.
Definition: dbus-memory.c:781
dbus_message_get_args
dbus_bool_t dbus_message_get_args(DBusMessage *message, DBusError *error, int first_arg_type,...)
Gets arguments from a message given a variable argument list.
Definition: dbus-message.c:1980
DBusError
Object representing an exception.
Definition: dbus-errors.h:48
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
_dbus_list_pop_first
void * _dbus_list_pop_first(DBusList **list)
Removes the first value in the list and returns it.
Definition: dbus-list.c:649
DBUS_TYPE_SIGNATURE
#define DBUS_TYPE_SIGNATURE
Type code marking a D-Bus type signature.
Definition: dbus-protocol.h:110
_dbus_message_loader_set_pending_fds_function
void _dbus_message_loader_set_pending_fds_function(DBusMessageLoader *loader, void(*callback)(void *), void *data)
Register a function to be called whenever the number of pending file descriptors in the loader change...
Definition: dbus-message.c:4532
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:1792
DBUS_MESSAGE_TYPE_SIGNAL
#define DBUS_MESSAGE_TYPE_SIGNAL
Message type of a signal message, see dbus_message_get_type()
Definition: dbus-protocol.h:240
dbus_set_error
void dbus_set_error(DBusError *error, const char *name, const char *format,...)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:354
dbus_message_get_reply_serial
dbus_uint32_t dbus_message_get_reply_serial(DBusMessage *message)
Returns the serial that the message is a reply to or 0 if none.
Definition: dbus-message.c:1163
INITIAL_LOADER_DATA_LEN
#define INITIAL_LOADER_DATA_LEN
The initial buffer size of the message loader.
Definition: dbus-message.c:3854
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:3754
_dbus_data_slot_list_clear
void _dbus_data_slot_list_clear(DBusDataSlotList *list)
Frees all data slots contained in the list, calling application-provided free functions if they exist...
Definition: dbus-dataslot.c:317
_dbus_atomic_inc
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
Definition: dbus-sysdeps-unix.c:2500
_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:4424
DBUS_TYPE_VARIANT
#define DBUS_TYPE_VARIANT
Type code marking a D-Bus variant type.
Definition: dbus-protocol.h:124
DBUS_TYPE_UINT32
#define DBUS_TYPE_UINT32
Type code marking a 32-bit unsigned integer.
Definition: dbus-protocol.h:86
_dbus_validate_body_with_reason
DBusValidity _dbus_validate_body_with_reason(const DBusString *expected_signature, int expected_signature_start, int byte_order, int *bytes_remaining, const DBusString *value_str, int value_pos, int len)
Verifies that the range of value_str from value_pos to value_end is a legitimate value of type expect...
Definition: dbus-marshal-validate.c:703
_dbus_header_reinit
void _dbus_header_reinit(DBusHeader *header)
Re-initializes a header that was previously initialized and never freed.
Definition: dbus-marshal-header.c:443
DBUS_VALID
the data is valid
Definition: dbus-marshal-validate.h:56
dbus_message_new_method_call
DBusMessage * dbus_message_new_method_call(const char *destination, const char *path, const char *iface, const char *method)
Constructs a new message to invoke a method on a remote object.
Definition: dbus-message.c:1333
DBUS_HEADER_FIELD_DESTINATION
#define DBUS_HEADER_FIELD_DESTINATION
Header field code for the destination bus name of a message.
Definition: dbus-protocol.h:283
DBusTypeReader::byte_order
dbus_uint32_t byte_order
byte order of the block
Definition: dbus-marshal-recursive.h:41
_dbus_header_delete_field
dbus_bool_t _dbus_header_delete_field(DBusHeader *header, int field)
Deletes a field, if it exists.
Definition: dbus-marshal-header.c:1416
_dbus_close
dbus_bool_t _dbus_close(int fd, DBusError *error)
Closes a file descriptor.
Definition: dbus-sysdeps-unix.c:2958
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:3690
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_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:3045
DBusTypeWriter::byte_order
dbus_uint32_t byte_order
byte order to write values with
Definition: dbus-marshal-recursive.h:66
_DBUS_UNLOCK
#define _DBUS_UNLOCK(name)
Unlocks a global lock.
Definition: dbus-internals.h:330
_dbus_string_free
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:242
DBusTypeReader
The type reader is an iterator for reading values from a block of values.
Definition: dbus-marshal-recursive.h:39
_dbus_data_slot_list_get
void * _dbus_data_slot_list_get(DBusDataSlotAllocator *allocator, DBusDataSlotList *list, int slot)
Retrieves data previously set with _dbus_data_slot_list_set_data().
Definition: dbus-dataslot.c:285
_dbus_message_loader_get_max_message_unix_fds
long _dbus_message_loader_get_max_message_unix_fds(DBusMessageLoader *loader)
Gets the maximum allowed number of unix fds per message.
Definition: dbus-message.c:4503
TRUE
#define TRUE
Expands to "1".
dbus_message_marshal
dbus_bool_t dbus_message_marshal(DBusMessage *msg, char **marshalled_data_p, int *len_p)
Turn a DBusMessage into the marshalled form as described in the D-Bus specification.
Definition: dbus-message.c:4721
_dbus_header_set_field_basic
dbus_bool_t _dbus_header_set_field_basic(DBusHeader *header, int field, int type, const void *value)
Sets the value of a field with basic type.
Definition: dbus-marshal-header.c:1273
_dbus_data_slot_list_init
void _dbus_data_slot_list_init(DBusDataSlotList *list)
Initializes a slot list.
Definition: dbus-dataslot.c:197
_dbus_assert_not_reached
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
Definition: dbus-internals.h:145
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:1587
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:2158
_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:208
DBUS_HEADER_FIELD_MEMBER
#define DBUS_HEADER_FIELD_MEMBER
Header field code for a member (method or signal).
Definition: dbus-protocol.h:271
DBusMessageLoader::max_message_unix_fds
long max_message_unix_fds
Maximum unix fds in a message.
Definition: dbus-message-private.h:69
DBusMessageLoader::corrupted
unsigned int corrupted
We got broken data, and are no longer working.
Definition: dbus-message-private.h:73
dbus_message_get_args_valist
dbus_bool_t dbus_message_get_args_valist(DBusMessage *message, DBusError *error, int first_arg_type, va_list var_args)
Like dbus_message_get_args but takes a va_list for use by language bindings.
Definition: dbus-message.c:2009
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:288
_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:1543
DBUS_TYPE_OBJECT_PATH
#define DBUS_TYPE_OBJECT_PATH
Type code marking a D-Bus object path.
Definition: dbus-protocol.h:106
dbus_set_error_from_message
dbus_bool_t dbus_set_error_from_message(DBusError *error, DBusMessage *message)
Sets a DBusError based on the contents of the given message.
Definition: dbus-message.c:3796
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:4783
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:2391
DBUS_TYPE_UNIX_FD
#define DBUS_TYPE_UNIX_FD
Type code marking a unix file descriptor.
Definition: dbus-protocol.h:114
_dbus_header_create
dbus_bool_t _dbus_header_create(DBusHeader *header, int byte_order, int message_type, const char *destination, const char *path, const char *interface, const char *member, const char *error_name)
Fills in the primary fields of the header, so the header is ready for use.
Definition: dbus-marshal-header.c:528
dbus_message_get_interface
const char * dbus_message_get_interface(DBusMessage *message)
Gets the interface this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitted...
Definition: dbus-message.c:3227
DBusDataSlotAllocator
An allocator that tracks a set of slot IDs.
Definition: dbus-dataslot.h:55
DBUS_TYPE_INVALID
#define DBUS_TYPE_INVALID
Type code that is never equal to a legitimate type code.
Definition: dbus-protocol.h:60
dbus_message_set_reply_serial
dbus_bool_t dbus_message_set_reply_serial(DBusMessage *message, dbus_uint32_t reply_serial)
Sets the reply serial of a message (the serial of the message this is a reply to).
Definition: dbus-message.c:1143
_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:182
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:3725
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:2114
_DBUS_STRING_DEFINE_STATIC
_DBUS_STRING_DEFINE_STATIC(_dbus_empty_signature_str,"")
An static string representing an empty signature.
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:2293
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:4635
_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:732
_dbus_header_free
void _dbus_header_free(DBusHeader *header)
Frees a header.
Definition: dbus-marshal-header.c:476
_dbus_message_loader_pop_message_link
DBusList * _dbus_message_loader_pop_message_link(DBusMessageLoader *loader)
Pops a loaded message inside a list link (passing ownership of the message and link to the caller)...
Definition: dbus-message.c:4396
DBUS_MAXIMUM_ARRAY_LENGTH
#define DBUS_MAXIMUM_ARRAY_LENGTH
Max length of a marshaled array in bytes (64M, 2^26) We use signed int for lengths so must be INT_MAX...
Definition: dbus-protocol.h:203
dbus_message_set_destination
dbus_bool_t dbus_message_set_destination(DBusMessage *message, const char *destination)
Sets the message's destination.
Definition: dbus-message.c:3425
dbus_error_init
void dbus_error_init(DBusError *error)
Initializes a DBusError structure.
Definition: dbus-errors.c:188
DBusMessage::refcount
DBusAtomic refcount
Reference count.
Definition: dbus-message-private.h:101
dbus_message_get_no_reply
dbus_bool_t dbus_message_get_no_reply(DBusMessage *message)
Returns TRUE if the message does not expect a reply.
Definition: dbus-message.c:3003
DBusList
A node in a linked list.
Definition: dbus-list.h:34
_dbus_message_loader_get_unix_fds
dbus_bool_t _dbus_message_loader_get_unix_fds(DBusMessageLoader *loader, int **fds, unsigned *max_n_fds)
Gets the buffer to use for reading unix fds from the network.
Definition: dbus-message.c:4002
dbus_free_string_array
void dbus_free_string_array(char **str_array)
Frees a NULL-terminated array of strings.
Definition: dbus-memory.c:749
DBUS_TYPE_BOOLEAN
#define DBUS_TYPE_BOOLEAN
Type code marking a boolean.
Definition: dbus-protocol.h:70
_dbus_message_loader_get_buffer
void _dbus_message_loader_get_buffer(DBusMessageLoader *loader, DBusString **buffer)
Gets the buffer to use for reading data from the network.
Definition: dbus-message.c:3962
_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:1119
DBusMessageRealIter::iter_type
dbus_uint32_t iter_type
whether this is a reader or writer iter
Definition: dbus-message.c:130
_dbus_header_set_serial
void _dbus_header_set_serial(DBusHeader *header, dbus_uint32_t serial)
Sets the serial number of a header.
Definition: dbus-marshal-header.c:404
_dbus_type_reader_get_element_type
int _dbus_type_reader_get_element_type(const DBusTypeReader *reader)
Gets the type of an element of the array the reader is currently pointing to.
Definition: dbus-marshal-recursive.c:820
_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:174
dbus_message_iter_open_container
dbus_bool_t dbus_message_iter_open_container(DBusMessageIter *iter, int type, const char *contained_signature, DBusMessageIter *sub)
Appends a container-typed value to the message; you are required to append the contents of the contai...
Definition: dbus-message.c:2849
_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:1091
DBusBasicValue
A simple value union that lets you access bytes as if they were various types; useful when dealing wi...
Definition: dbus-types.h:137
DBusTypeWriter::container_type
dbus_uint32_t container_type
what are we inside? (e.g.
Definition: dbus-marshal-recursive.h:68
_dbus_type_reader_get_array_length
int _dbus_type_reader_get_array_length(const DBusTypeReader *reader)
Returns the number of bytes in the array.
Definition: dbus-marshal-recursive.c:899
_dbus_header_get_field_raw
dbus_bool_t _dbus_header_get_field_raw(DBusHeader *header, int field, const DBusString **str, int *pos)
Gets the raw marshaled data for a field.
Definition: dbus-marshal-header.c:1392
dbus_message_iter_append_basic
dbus_bool_t dbus_message_iter_append_basic(DBusMessageIter *iter, int type, const void *value)
Appends a basic-typed value to the message.
Definition: dbus-message.c:2656
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:2346
DBusForeachFunction
void(* DBusForeachFunction)(void *element, void *data)
Used to iterate over each item in a collection, such as a DBusList.
Definition: dbus-internals.h:251
_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:785
FALSE
#define FALSE
Expands to "0".
DBusHeader
Message header data and some cached details of it.
Definition: dbus-marshal-header.h:47
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:265
dbus_message_get_type
int dbus_message_get_type(DBusMessage *message)
Gets the type of a message.
Definition: dbus-message.c:1722
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:279
DBusMessageLoader::buffer_outstanding
unsigned int buffer_outstanding
Someone is using the buffer to read.
Definition: dbus-message-private.h:75
DBusMessage::generation
int generation
_dbus_current_generation when message was created
Definition: dbus-message-private.h:121
_dbus_list_prepend_link
void _dbus_list_prepend_link(DBusList **list, DBusList *link)
Prepends a link to the list.
Definition: dbus-list.c:333
_dbus_string_set_length
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:785
_dbus_register_shutdown_func
dbus_bool_t _dbus_register_shutdown_func(DBusShutdownFunction function, void *data)
Register a cleanup function to be called exactly once the next time dbus_shutdown() is called...
Definition: dbus-memory.c:810
_DBUS_LOCK
#define _DBUS_LOCK(name)
Locks a global lock, initializing it first if necessary.
Definition: dbus-internals.h:329
_DBUS_LOCK_NAME
#define _DBUS_LOCK_NAME(name)
Expands to name of a global lock variable.
Definition: dbus-internals.h:328
_dbus_type_to_string
const char * _dbus_type_to_string(int typecode)
Returns a string describing the given type.
Definition: dbus-marshal-basic.c:1219
_dbus_message_loader_peek_message
DBusMessage * _dbus_message_loader_peek_message(DBusMessageLoader *loader)
Peeks at first loaded message, returns NULL if no messages have been queued.
Definition: dbus-message.c:4365
_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:1357
_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:624
_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:1122
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:1824
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:4841
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:2220
_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:2356
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:2951
_dbus_verbose_bytes_of_string
void _dbus_verbose_bytes_of_string(const DBusString *str, int start, int len)
Dump the given part of the string to verbose log.
Definition: dbus-marshal-basic.c:1360
_dbus_data_slot_allocator_alloc
dbus_bool_t _dbus_data_slot_allocator_alloc(DBusDataSlotAllocator *allocator, dbus_int32_t *slot_id_p)
Allocates an integer ID to be used for storing data in a DBusDataSlotList.
Definition: dbus-dataslot.c:69
dbus_message_contains_unix_fds
dbus_bool_t dbus_message_contains_unix_fds(DBusMessage *message)
Checks whether a message contains unix fds.
Definition: dbus-message.c:3825
DBUS_HEADER_FLAG_NO_AUTO_START
#define DBUS_HEADER_FLAG_NO_AUTO_START
If set, this flag means that even if the message bus knows how to start an owner for the destination ...
Definition: dbus-protocol.h:256
_dbus_message_loader_queue_messages
dbus_bool_t _dbus_message_loader_queue_messages(DBusMessageLoader *loader)
Converts buffered data into messages, if we have enough data.
Definition: dbus-message.c:4302
_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:227
DBusMessageLoader::refcount
int refcount
Reference count.
Definition: dbus-message-private.h:62
_dbus_strdup
char * _dbus_strdup(const char *str)
Duplicates a string.
Definition: dbus-internals.c:527
MAX_MESSAGE_SIZE_TO_CACHE
#define MAX_MESSAGE_SIZE_TO_CACHE
Avoid caching huge messages.
Definition: dbus-message.c:505
DBUS_ERROR_INVALID_ARGS
#define DBUS_ERROR_INVALID_ARGS
Invalid arguments passed to a method call.
Definition: dbus-protocol.h:386
_dbus_data_slot_allocator_free
void _dbus_data_slot_allocator_free(DBusDataSlotAllocator *allocator, dbus_int32_t *slot_id_p)
Deallocates an ID previously allocated with _dbus_data_slot_allocator_alloc().
Definition: dbus-dataslot.c:154
_dbus_type_get_alignment
int _dbus_type_get_alignment(int typecode)
Gets the alignment requirement for the given type; will be 1, 4, or 8.
Definition: dbus-marshal-basic.c:1173
DBusMessageLoader::corruption_reason
DBusValidity corruption_reason
why we were corrupted
Definition: dbus-message-private.h:71
_dbus_message_loader_set_max_message_unix_fds
void _dbus_message_loader_set_max_message_unix_fds(DBusMessageLoader *loader, long n)
Sets the maximum unix fds per message we allow.
Definition: dbus-message.c:4484
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:3286
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:4691
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:1690
_dbus_string_init_const_len
void _dbus_string_init_const_len(DBusString *str, const char *value, int len)
Initializes a constant string with a length.
Definition: dbus-string.c:210
DBusMessageLoader
Implementation details of DBusMessageLoader.
Definition: dbus-message-private.h:60
_dbus_type_writer_recurse
dbus_bool_t _dbus_type_writer_recurse(DBusTypeWriter *writer, int container_type, const DBusString *contained_type, int contained_type_start, DBusTypeWriter *sub)
Opens a new container and writes out the initial information for that container.
Definition: dbus-marshal-recursive.c:2106
DBusBasicValue::u32
dbus_uint32_t u32
as int32
Definition: dbus-types.h:143
dbus_message_new_error_printf
DBusMessage * dbus_message_new_error_printf(DBusMessage *reply_to, const char *error_name, const char *error_format,...)
Creates a new message that is an error reply to another message, allowing you to use printf formattin...
Definition: dbus-message.c:1542
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:4599
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:254
_dbus_header_toggle_flag
void _dbus_header_toggle_flag(DBusHeader *header, dbus_uint32_t flag, dbus_bool_t value)
Toggles a message flag bit, turning on the bit if value = TRUE and flipping it off if value = FALSE...
Definition: dbus-marshal-header.c:1457
_dbus_header_update_lengths
void _dbus_header_update_lengths(DBusHeader *header, int body_len)
Fills in the correct body length.
Definition: dbus-marshal-header.c:1196
dbus_message_new_method_return
DBusMessage * dbus_message_new_method_return(DBusMessage *method_call)
Constructs a message that is a reply to a method call.
Definition: dbus-message.c:1373
DBusMessageRealIter::writer
DBusTypeWriter writer
writer
Definition: dbus-message.c:134
_dbus_data_slot_list_free
void _dbus_data_slot_list_free(DBusDataSlotList *list)
Frees the data slot list and all data slots contained in it, calling application-provided free functi...
Definition: dbus-dataslot.c:340
DBUS_MAXIMUM_MESSAGE_LENGTH
#define DBUS_MAXIMUM_MESSAGE_LENGTH
The maximum total message size including header and body; similar rationale to max array size...
Definition: dbus-protocol.h:210
DBusMessage::slot_list
DBusDataSlotList slot_list
Data stored by allocated integer ID.
Definition: dbus-message-private.h:118
_dbus_list_clear
void _dbus_list_clear(DBusList **list)
Frees all links in the list and sets the list head to NULL.
Definition: dbus-list.c:542
_dbus_marshal_byteswap
void _dbus_marshal_byteswap(const DBusString *signature, int signature_start, int old_byte_order, int new_byte_order, DBusString *value_str, int value_pos)
Byteswaps the marshaled data in the given value_str.
Definition: dbus-marshal-byteswap.c:222
_dbus_message_loader_get_pending_fds_count
int _dbus_message_loader_get_pending_fds_count(DBusMessageLoader *loader)
Return how many file descriptors are pending in the loader.
Definition: dbus-message.c:4514
dbus_type_is_container
dbus_bool_t dbus_type_is_container(int typecode)
A "container type" can contain basic types, or nested container types.
Definition: dbus-signature.c:294
dbus_message_new_error
DBusMessage * dbus_message_new_error(DBusMessage *reply_to, const char *error_name, const char *error_message)
Creates a new message that is an error reply to another message.
Definition: dbus-message.c:1470
_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:148