D-Bus  1.6.12
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-unix.h"
39 #endif
40 
41 #include <string.h>
42 
43 #define _DBUS_TYPE_IS_STRINGLIKE(type) \
44  (type == DBUS_TYPE_STRING || type == DBUS_TYPE_SIGNATURE || \
45  type == DBUS_TYPE_OBJECT_PATH)
46 
47 static void dbus_message_finalize (DBusMessage *message);
48 
59 #ifdef DBUS_BUILD_TESTS
60 static dbus_bool_t
61 _dbus_enable_message_cache (void)
62 {
63  static int enabled = -1;
64 
65  if (enabled < 0)
66  {
67  const char *s = _dbus_getenv ("DBUS_MESSAGE_CACHE");
68 
69  enabled = TRUE;
70 
71  if (s && *s)
72  {
73  if (*s == '0')
74  enabled = FALSE;
75  else if (*s == '1')
76  enabled = TRUE;
77  else
78  _dbus_warn ("DBUS_MESSAGE_CACHE should be 0 or 1 if set, not '%s'",
79  s);
80  }
81  }
82 
83  return enabled;
84 }
85 #else
86  /* constant expression, should be optimized away */
87 # define _dbus_enable_message_cache() (TRUE)
88 #endif
89 
90 #ifndef _dbus_message_trace_ref
91 void
92 _dbus_message_trace_ref (DBusMessage *message,
93  int old_refcount,
94  int new_refcount,
95  const char *why)
96 {
97  static int enabled = -1;
98 
99  _dbus_trace_ref ("DBusMessage", message, old_refcount, new_refcount, why,
100  "DBUS_MESSAGE_TRACE", &enabled);
101 }
102 #endif
103 
104 /* Not thread locked, but strictly const/read-only so should be OK
105  */
107 _DBUS_STRING_DEFINE_STATIC(_dbus_empty_signature_str, "");
108 
109 /* these have wacky values to help trap uninitialized iterators;
110  * but has to fit in 3 bits
111  */
112 enum {
113  DBUS_MESSAGE_ITER_TYPE_READER = 3,
114  DBUS_MESSAGE_ITER_TYPE_WRITER = 7
115 };
116 
119 
126 {
131  union
132  {
135  } u;
136 };
137 
138 static void
139 get_const_signature (DBusHeader *header,
140  const DBusString **type_str_p,
141  int *type_pos_p)
142 {
143  if (_dbus_header_get_field_raw (header,
145  type_str_p,
146  type_pos_p))
147  {
148  *type_pos_p += 1; /* skip the signature length which is 1 byte */
149  }
150  else
151  {
152  *type_str_p = &_dbus_empty_signature_str;
153  *type_pos_p = 0;
154  }
155 }
156 
162 static void
163 _dbus_message_byteswap (DBusMessage *message)
164 {
165  const DBusString *type_str;
166  int type_pos;
167  char byte_order;
168 
169  byte_order = _dbus_header_get_byte_order (&message->header);
170 
171  if (byte_order == DBUS_COMPILER_BYTE_ORDER)
172  return;
173 
174  _dbus_verbose ("Swapping message into compiler byte order\n");
175 
176  get_const_signature (&message->header, &type_str, &type_pos);
177 
178  _dbus_marshal_byteswap (type_str, type_pos,
179  byte_order,
180  DBUS_COMPILER_BYTE_ORDER,
181  &message->body, 0);
182 
183  _dbus_header_byteswap (&message->header, DBUS_COMPILER_BYTE_ORDER);
185  DBUS_COMPILER_BYTE_ORDER);
186 }
187 
194 #define ensure_byte_order(message) _dbus_message_byteswap (message)
195 
206 void
208  const DBusString **header,
209  const DBusString **body)
210 {
211  _dbus_assert (message->locked);
212 
213  *header = &message->header.data;
214  *body = &message->body;
215 }
216 
227  const int **fds,
228  unsigned *n_fds)
229 {
230  _dbus_assert (message->locked);
231 
232 #ifdef HAVE_UNIX_FD_PASSING
233  *fds = message->unix_fds;
234  *n_fds = message->n_unix_fds;
235 #else
236  *fds = NULL;
237  *n_fds = 0;
238 #endif
239 }
240 
252 void
254  dbus_uint32_t serial)
255 {
256  _dbus_return_if_fail (message != NULL);
257  _dbus_return_if_fail (!message->locked);
258 
259  _dbus_header_set_serial (&message->header, serial);
260 }
261 
278 void
280  DBusList *link)
281 {
282  /* right now we don't recompute the delta when message
283  * size changes, and that's OK for current purposes
284  * I think, but could be important to change later.
285  * Do recompute it whenever there are no outstanding counters,
286  * since it's basically free.
287  */
288  if (message->counters == NULL)
289  {
290  message->size_counter_delta =
291  _dbus_string_get_length (&message->header.data) +
292  _dbus_string_get_length (&message->body);
293 
294 #ifdef HAVE_UNIX_FD_PASSING
295  message->unix_fd_counter_delta = message->n_unix_fds;
296 #endif
297 
298 #if 0
299  _dbus_verbose ("message has size %ld\n",
300  message->size_counter_delta);
301 #endif
302  }
303 
304  _dbus_list_append_link (&message->counters, link);
305 
307 
308 #ifdef HAVE_UNIX_FD_PASSING
309  _dbus_counter_adjust_unix_fd (link->data, message->unix_fd_counter_delta);
310 #endif
311 }
312 
329  DBusCounter *counter)
330 {
331  DBusList *link;
332 
333  link = _dbus_list_alloc_link (counter);
334  if (link == NULL)
335  return FALSE;
336 
337  _dbus_counter_ref (counter);
338  _dbus_message_add_counter_link (message, link);
339 
340  return TRUE;
341 }
342 
350 void
352  DBusCounter *counter)
353 {
354  DBusList *link;
355 
356  link = _dbus_list_find_last (&message->counters,
357  counter);
358  _dbus_assert (link != NULL);
359 
360  _dbus_list_remove_link (&message->counters, link);
361 
362  _dbus_counter_adjust_size (counter, - message->size_counter_delta);
363 
364 #ifdef HAVE_UNIX_FD_PASSING
365  _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
366 #endif
367 
368  _dbus_counter_notify (counter);
369  _dbus_counter_unref (counter);
370 }
371 
382 void
384 {
385  if (!message->locked)
386  {
388  _dbus_string_get_length (&message->body));
389 
390  /* must have a signature if you have a body */
391  _dbus_assert (_dbus_string_get_length (&message->body) == 0 ||
392  dbus_message_get_signature (message) != NULL);
393 
394  message->locked = TRUE;
395  }
396 }
397 
398 static dbus_bool_t
399 set_or_delete_string_field (DBusMessage *message,
400  int field,
401  int typecode,
402  const char *value)
403 {
404  if (value == NULL)
405  return _dbus_header_delete_field (&message->header, field);
406  else
407  return _dbus_header_set_field_basic (&message->header,
408  field,
409  typecode,
410  &value);
411 }
412 
413 #if 0
414 /* Probably we don't need to use this */
438 static dbus_bool_t
439 _dbus_message_set_signature (DBusMessage *message,
440  const char *signature)
441 {
442  _dbus_return_val_if_fail (message != NULL, FALSE);
443  _dbus_return_val_if_fail (!message->locked, FALSE);
444  _dbus_return_val_if_fail (signature == NULL ||
445  _dbus_check_is_valid_signature (signature));
446  /* can't delete the signature if you have a message body */
447  _dbus_return_val_if_fail (_dbus_string_get_length (&message->body) == 0 ||
448  signature != NULL);
449 
450  return set_or_delete_string_field (message,
453  signature);
454 }
455 #endif
456 
457 /* Message Cache
458  *
459  * We cache some DBusMessage to reduce the overhead of allocating
460  * them. In my profiling this consistently made about an 8%
461  * difference. It avoids the malloc for the message, the malloc for
462  * the slot list, the malloc for the header string and body string,
463  * and the associated free() calls. It does introduce another global
464  * lock which could be a performance issue in certain cases.
465  *
466  * For the echo client/server the round trip time goes from around
467  * .000077 to .000069 with the message cache on my laptop. The sysprof
468  * change is as follows (numbers are cumulative percentage):
469  *
470  * with message cache implemented as array as it is now (0.000069 per):
471  * new_empty_header 1.46
472  * mutex_lock 0.56 # i.e. _DBUS_LOCK(message_cache)
473  * mutex_unlock 0.25
474  * self 0.41
475  * unref 2.24
476  * self 0.68
477  * list_clear 0.43
478  * mutex_lock 0.33 # i.e. _DBUS_LOCK(message_cache)
479  * mutex_unlock 0.25
480  *
481  * with message cache implemented as list (0.000070 per roundtrip):
482  * new_empty_header 2.72
483  * list_pop_first 1.88
484  * unref 3.3
485  * list_prepend 1.63
486  *
487  * without cache (0.000077 per roundtrip):
488  * new_empty_header 6.7
489  * string_init_preallocated 3.43
490  * dbus_malloc 2.43
491  * dbus_malloc0 2.59
492  *
493  * unref 4.02
494  * string_free 1.82
495  * dbus_free 1.63
496  * dbus_free 0.71
497  *
498  * If you implement the message_cache with a list, the primary reason
499  * it's slower is that you add another thread lock (on the DBusList
500  * mempool).
501  */
502 
504 #define MAX_MESSAGE_SIZE_TO_CACHE 10 * _DBUS_ONE_KILOBYTE
505 
507 #define MAX_MESSAGE_CACHE_SIZE 5
508 
509 _DBUS_DEFINE_GLOBAL_LOCK (message_cache);
510 static DBusMessage *message_cache[MAX_MESSAGE_CACHE_SIZE];
511 static int message_cache_count = 0;
512 static dbus_bool_t message_cache_shutdown_registered = FALSE;
513 
514 static void
515 dbus_message_cache_shutdown (void *data)
516 {
517  int i;
518 
519  _DBUS_LOCK (message_cache);
520 
521  i = 0;
522  while (i < MAX_MESSAGE_CACHE_SIZE)
523  {
524  if (message_cache[i])
525  dbus_message_finalize (message_cache[i]);
526 
527  ++i;
528  }
529 
530  message_cache_count = 0;
531  message_cache_shutdown_registered = FALSE;
532 
533  _DBUS_UNLOCK (message_cache);
534 }
535 
543 static DBusMessage*
544 dbus_message_get_cached (void)
545 {
546  DBusMessage *message;
547  int i;
548 
549  message = NULL;
550 
551  _DBUS_LOCK (message_cache);
552 
553  _dbus_assert (message_cache_count >= 0);
554 
555  if (message_cache_count == 0)
556  {
557  _DBUS_UNLOCK (message_cache);
558  return NULL;
559  }
560 
561  /* This is not necessarily true unless count > 0, and
562  * message_cache is uninitialized until the shutdown is
563  * registered
564  */
565  _dbus_assert (message_cache_shutdown_registered);
566 
567  i = 0;
568  while (i < MAX_MESSAGE_CACHE_SIZE)
569  {
570  if (message_cache[i])
571  {
572  message = message_cache[i];
573  message_cache[i] = NULL;
574  message_cache_count -= 1;
575  break;
576  }
577  ++i;
578  }
579  _dbus_assert (message_cache_count >= 0);
581  _dbus_assert (message != NULL);
582 
583  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
584 
585  _dbus_assert (message->counters == NULL);
586 
587  _DBUS_UNLOCK (message_cache);
588 
589  return message;
590 }
591 
592 #ifdef HAVE_UNIX_FD_PASSING
593 static void
594 close_unix_fds(int *fds, unsigned *n_fds)
595 {
596  DBusError e;
597  int i;
598 
599  if (*n_fds <= 0)
600  return;
601 
602  dbus_error_init(&e);
603 
604  for (i = 0; i < *n_fds; i++)
605  {
606  if (!_dbus_close(fds[i], &e))
607  {
608  _dbus_warn("Failed to close file descriptor: %s\n", e.message);
609  dbus_error_free(&e);
610  }
611  }
612 
613  *n_fds = 0;
614 
615  /* We don't free the array here, in case we can recycle it later */
616 }
617 #endif
618 
619 static void
620 free_counter (void *element,
621  void *data)
622 {
623  DBusCounter *counter = element;
624  DBusMessage *message = data;
625 
626  _dbus_counter_adjust_size (counter, - message->size_counter_delta);
627 #ifdef HAVE_UNIX_FD_PASSING
628  _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
629 #endif
630 
631  _dbus_counter_notify (counter);
632  _dbus_counter_unref (counter);
633 }
634 
640 static void
641 dbus_message_cache_or_finalize (DBusMessage *message)
642 {
643  dbus_bool_t was_cached;
644  int i;
645 
646  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
647 
648  /* This calls application code and has to be done first thing
649  * without holding the lock
650  */
652 
653  _dbus_list_foreach (&message->counters,
654  free_counter, message);
655  _dbus_list_clear (&message->counters);
656 
657 #ifdef HAVE_UNIX_FD_PASSING
658  close_unix_fds(message->unix_fds, &message->n_unix_fds);
659 #endif
660 
661  was_cached = FALSE;
662 
663  _DBUS_LOCK (message_cache);
664 
665  if (!message_cache_shutdown_registered)
666  {
667  _dbus_assert (message_cache_count == 0);
668 
669  if (!_dbus_register_shutdown_func (dbus_message_cache_shutdown, NULL))
670  goto out;
671 
672  i = 0;
673  while (i < MAX_MESSAGE_CACHE_SIZE)
674  {
675  message_cache[i] = NULL;
676  ++i;
677  }
678 
679  message_cache_shutdown_registered = TRUE;
680  }
681 
682  _dbus_assert (message_cache_count >= 0);
683 
684  if (!_dbus_enable_message_cache ())
685  goto out;
686 
687  if ((_dbus_string_get_length (&message->header.data) +
688  _dbus_string_get_length (&message->body)) >
690  goto out;
691 
692  if (message_cache_count >= MAX_MESSAGE_CACHE_SIZE)
693  goto out;
694 
695  /* Find empty slot */
696  i = 0;
697  while (message_cache[i] != NULL)
698  ++i;
699 
701 
702  _dbus_assert (message_cache[i] == NULL);
703  message_cache[i] = message;
704  message_cache_count += 1;
705  was_cached = TRUE;
706 #ifndef DBUS_DISABLE_CHECKS
707  message->in_cache = TRUE;
708 #endif
709 
710  out:
711  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
712 
713  _DBUS_UNLOCK (message_cache);
714 
715  if (!was_cached)
716  dbus_message_finalize (message);
717 }
718 
719 #ifndef DBUS_DISABLE_CHECKS
720 static dbus_bool_t
721 _dbus_message_iter_check (DBusMessageRealIter *iter)
722 {
723  char byte_order;
724 
725  if (iter == NULL)
726  {
727  _dbus_warn_check_failed ("dbus message iterator is NULL\n");
728  return FALSE;
729  }
730 
731  byte_order = _dbus_header_get_byte_order (&iter->message->header);
732 
733  if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_READER)
734  {
735  if (iter->u.reader.byte_order != byte_order)
736  {
737  _dbus_warn_check_failed ("dbus message changed byte order since iterator was created\n");
738  return FALSE;
739  }
740  /* because we swap the message into compiler order when you init an iter */
741  _dbus_assert (iter->u.reader.byte_order == DBUS_COMPILER_BYTE_ORDER);
742  }
743  else if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER)
744  {
745  if (iter->u.writer.byte_order != byte_order)
746  {
747  _dbus_warn_check_failed ("dbus message changed byte order since append iterator was created\n");
748  return FALSE;
749  }
750  /* because we swap the message into compiler order when you init an iter */
751  _dbus_assert (iter->u.writer.byte_order == DBUS_COMPILER_BYTE_ORDER);
752  }
753  else
754  {
755  _dbus_warn_check_failed ("dbus message iterator looks uninitialized or corrupted\n");
756  return FALSE;
757  }
758 
759  if (iter->changed_stamp != iter->message->changed_stamp)
760  {
761  _dbus_warn_check_failed ("dbus message iterator invalid because the message has been modified (or perhaps the iterator is just uninitialized)\n");
762  return FALSE;
763  }
764 
765  return TRUE;
766 }
767 #endif /* DBUS_DISABLE_CHECKS */
768 
785  DBusError *error,
786  int first_arg_type,
787  va_list var_args)
788 {
790  int spec_type, msg_type, i;
791  dbus_bool_t retval;
792 
793  _dbus_assert (_dbus_message_iter_check (real));
794 
795  retval = FALSE;
796 
797  spec_type = first_arg_type;
798  i = 0;
799 
800  while (spec_type != DBUS_TYPE_INVALID)
801  {
802  msg_type = dbus_message_iter_get_arg_type (iter);
803 
804  if (msg_type != spec_type)
805  {
807  "Argument %d is specified to be of type \"%s\", but "
808  "is actually of type \"%s\"\n", i,
809  _dbus_type_to_string (spec_type),
810  _dbus_type_to_string (msg_type));
811 
812  goto out;
813  }
814 
815  if (spec_type == DBUS_TYPE_UNIX_FD)
816  {
817 #ifdef HAVE_UNIX_FD_PASSING
818  DBusBasicValue idx;
819  int *pfd, nfd;
820 
821  pfd = va_arg (var_args, int*);
822  _dbus_assert(pfd);
823 
824  _dbus_type_reader_read_basic(&real->u.reader, &idx);
825 
826  if (idx.u32 >= real->message->n_unix_fds)
827  {
829  "Message refers to file descriptor at index %i,"
830  "but has only %i descriptors attached.\n",
831  idx.u32,
832  real->message->n_unix_fds);
833  goto out;
834  }
835 
836  if ((nfd = _dbus_dup(real->message->unix_fds[idx.u32], error)) < 0)
837  goto out;
838 
839  *pfd = nfd;
840 #else
842  "Platform does not support file desciptor passing.\n");
843  goto out;
844 #endif
845  }
846  else if (dbus_type_is_basic (spec_type))
847  {
848  DBusBasicValue *ptr;
849 
850  ptr = va_arg (var_args, DBusBasicValue*);
851 
852  _dbus_assert (ptr != NULL);
853 
855  ptr);
856  }
857  else if (spec_type == DBUS_TYPE_ARRAY)
858  {
859  int element_type;
860  int spec_element_type;
861  const DBusBasicValue **ptr;
862  int *n_elements_p;
863  DBusTypeReader array;
864 
865  spec_element_type = va_arg (var_args, int);
866  element_type = _dbus_type_reader_get_element_type (&real->u.reader);
867 
868  if (spec_element_type != element_type)
869  {
871  "Argument %d is specified to be an array of \"%s\", but "
872  "is actually an array of \"%s\"\n",
873  i,
874  _dbus_type_to_string (spec_element_type),
875  _dbus_type_to_string (element_type));
876 
877  goto out;
878  }
879 
880  if (dbus_type_is_fixed (spec_element_type) &&
881  element_type != DBUS_TYPE_UNIX_FD)
882  {
883  ptr = va_arg (var_args, const DBusBasicValue**);
884  n_elements_p = va_arg (var_args, int*);
885 
886  _dbus_assert (ptr != NULL);
887  _dbus_assert (n_elements_p != NULL);
888 
889  _dbus_type_reader_recurse (&real->u.reader, &array);
890 
892  (void *) ptr, n_elements_p);
893  }
894  else if (_DBUS_TYPE_IS_STRINGLIKE (spec_element_type))
895  {
896  char ***str_array_p;
897  int n_elements;
898  char **str_array;
899 
900  str_array_p = va_arg (var_args, char***);
901  n_elements_p = va_arg (var_args, int*);
902 
903  _dbus_assert (str_array_p != NULL);
904  _dbus_assert (n_elements_p != NULL);
905 
906  /* Count elements in the array */
907  _dbus_type_reader_recurse (&real->u.reader, &array);
908 
909  n_elements = 0;
911  {
912  ++n_elements;
913  _dbus_type_reader_next (&array);
914  }
915 
916  str_array = dbus_new0 (char*, n_elements + 1);
917  if (str_array == NULL)
918  {
919  _DBUS_SET_OOM (error);
920  goto out;
921  }
922 
923  /* Now go through and dup each string */
924  _dbus_type_reader_recurse (&real->u.reader, &array);
925 
926  i = 0;
927  while (i < n_elements)
928  {
929  const char *s;
931  (void *) &s);
932 
933  str_array[i] = _dbus_strdup (s);
934  if (str_array[i] == NULL)
935  {
936  dbus_free_string_array (str_array);
937  _DBUS_SET_OOM (error);
938  goto out;
939  }
940 
941  ++i;
942 
943  if (!_dbus_type_reader_next (&array))
944  _dbus_assert (i == n_elements);
945  }
946 
948  _dbus_assert (i == n_elements);
949  _dbus_assert (str_array[i] == NULL);
950 
951  *str_array_p = str_array;
952  *n_elements_p = n_elements;
953  }
954 #ifndef DBUS_DISABLE_CHECKS
955  else
956  {
957  _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now\n",
958  _DBUS_FUNCTION_NAME);
959  goto out;
960  }
961 #endif
962  }
963 #ifndef DBUS_DISABLE_CHECKS
964  else
965  {
966  _dbus_warn ("you can only read arrays and basic types with %s for now\n",
967  _DBUS_FUNCTION_NAME);
968  goto out;
969  }
970 #endif
971 
972  spec_type = va_arg (var_args, int);
973  if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID)
974  {
976  "Message has only %d arguments, but more were expected", i);
977  goto out;
978  }
979 
980  i++;
981  }
982 
983  retval = TRUE;
984 
985  out:
986 
987  return retval;
988 }
989 
1050 {
1051  _dbus_return_val_if_fail (message != NULL, 0);
1052 
1053  return _dbus_header_get_serial (&message->header);
1054 }
1055 
1066  dbus_uint32_t reply_serial)
1067 {
1068  _dbus_return_val_if_fail (message != NULL, FALSE);
1069  _dbus_return_val_if_fail (!message->locked, FALSE);
1070  _dbus_return_val_if_fail (reply_serial != 0, FALSE); /* 0 is invalid */
1071 
1072  return _dbus_header_set_field_basic (&message->header,
1075  &reply_serial);
1076 }
1077 
1086 {
1087  dbus_uint32_t v_UINT32;
1088 
1089  _dbus_return_val_if_fail (message != NULL, 0);
1090 
1091  if (_dbus_header_get_field_basic (&message->header,
1094  &v_UINT32))
1095  return v_UINT32;
1096  else
1097  return 0;
1098 }
1099 
1100 static void
1101 dbus_message_finalize (DBusMessage *message)
1102 {
1103  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
1104 
1105  /* This calls application callbacks! */
1107 
1108  _dbus_list_foreach (&message->counters,
1109  free_counter, message);
1110  _dbus_list_clear (&message->counters);
1111 
1112  _dbus_header_free (&message->header);
1113  _dbus_string_free (&message->body);
1114 
1115 #ifdef HAVE_UNIX_FD_PASSING
1116  close_unix_fds(message->unix_fds, &message->n_unix_fds);
1117  dbus_free(message->unix_fds);
1118 #endif
1119 
1120  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
1121 
1122  dbus_free (message);
1123 }
1124 
1125 static DBusMessage*
1126 dbus_message_new_empty_header (void)
1127 {
1128  DBusMessage *message;
1129  dbus_bool_t from_cache;
1130 
1131  message = dbus_message_get_cached ();
1132 
1133  if (message != NULL)
1134  {
1135  from_cache = TRUE;
1136  }
1137  else
1138  {
1139  from_cache = FALSE;
1140  message = dbus_new0 (DBusMessage, 1);
1141  if (message == NULL)
1142  return NULL;
1143 #ifndef DBUS_DISABLE_CHECKS
1145 #endif
1146 
1147 #ifdef HAVE_UNIX_FD_PASSING
1148  message->unix_fds = NULL;
1149  message->n_unix_fds_allocated = 0;
1150 #endif
1151  }
1152 
1153  _dbus_atomic_inc (&message->refcount);
1154 
1155  _dbus_message_trace_ref (message, 0, 1, "new_empty_header");
1156 
1157  message->locked = FALSE;
1158 #ifndef DBUS_DISABLE_CHECKS
1159  message->in_cache = FALSE;
1160 #endif
1161  message->counters = NULL;
1162  message->size_counter_delta = 0;
1163  message->changed_stamp = 0;
1164 
1165 #ifdef HAVE_UNIX_FD_PASSING
1166  message->n_unix_fds = 0;
1167  message->n_unix_fds_allocated = 0;
1168  message->unix_fd_counter_delta = 0;
1169 #endif
1170 
1171  if (!from_cache)
1173 
1174  if (from_cache)
1175  {
1176  _dbus_header_reinit (&message->header);
1177  _dbus_string_set_length (&message->body, 0);
1178  }
1179  else
1180  {
1181  if (!_dbus_header_init (&message->header))
1182  {
1183  dbus_free (message);
1184  return NULL;
1185  }
1186 
1187  if (!_dbus_string_init_preallocated (&message->body, 32))
1188  {
1189  _dbus_header_free (&message->header);
1190  dbus_free (message);
1191  return NULL;
1192  }
1193  }
1194 
1195  return message;
1196 }
1197 
1210 DBusMessage*
1211 dbus_message_new (int message_type)
1212 {
1213  DBusMessage *message;
1214 
1215  _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
1216 
1217  message = dbus_message_new_empty_header ();
1218  if (message == NULL)
1219  return NULL;
1220 
1221  if (!_dbus_header_create (&message->header,
1222  DBUS_COMPILER_BYTE_ORDER,
1223  message_type,
1224  NULL, NULL, NULL, NULL, NULL))
1225  {
1226  dbus_message_unref (message);
1227  return NULL;
1228  }
1229 
1230  return message;
1231 }
1232 
1254 DBusMessage*
1255 dbus_message_new_method_call (const char *destination,
1256  const char *path,
1257  const char *interface,
1258  const char *method)
1259 {
1260  DBusMessage *message;
1261 
1262  _dbus_return_val_if_fail (path != NULL, NULL);
1263  _dbus_return_val_if_fail (method != NULL, NULL);
1264  _dbus_return_val_if_fail (destination == NULL ||
1265  _dbus_check_is_valid_bus_name (destination), NULL);
1266  _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
1267  _dbus_return_val_if_fail (interface == NULL ||
1268  _dbus_check_is_valid_interface (interface), NULL);
1269  _dbus_return_val_if_fail (_dbus_check_is_valid_member (method), NULL);
1270 
1271  message = dbus_message_new_empty_header ();
1272  if (message == NULL)
1273  return NULL;
1274 
1275  if (!_dbus_header_create (&message->header,
1276  DBUS_COMPILER_BYTE_ORDER,
1278  destination, path, interface, method, NULL))
1279  {
1280  dbus_message_unref (message);
1281  return NULL;
1282  }
1283 
1284  return message;
1285 }
1286 
1294 DBusMessage*
1296 {
1297  DBusMessage *message;
1298  const char *sender;
1299 
1300  _dbus_return_val_if_fail (method_call != NULL, NULL);
1301 
1302  sender = dbus_message_get_sender (method_call);
1303 
1304  /* sender is allowed to be null here in peer-to-peer case */
1305 
1306  message = dbus_message_new_empty_header ();
1307  if (message == NULL)
1308  return NULL;
1309 
1310  if (!_dbus_header_create (&message->header,
1311  DBUS_COMPILER_BYTE_ORDER,
1313  sender, NULL, NULL, NULL, NULL))
1314  {
1315  dbus_message_unref (message);
1316  return NULL;
1317  }
1318 
1319  dbus_message_set_no_reply (message, TRUE);
1320 
1321  if (!dbus_message_set_reply_serial (message,
1322  dbus_message_get_serial (method_call)))
1323  {
1324  dbus_message_unref (message);
1325  return NULL;
1326  }
1327 
1328  return message;
1329 }
1330 
1345 DBusMessage*
1346 dbus_message_new_signal (const char *path,
1347  const char *interface,
1348  const char *name)
1349 {
1350  DBusMessage *message;
1351 
1352  _dbus_return_val_if_fail (path != NULL, NULL);
1353  _dbus_return_val_if_fail (interface != NULL, NULL);
1354  _dbus_return_val_if_fail (name != NULL, NULL);
1355  _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
1356  _dbus_return_val_if_fail (_dbus_check_is_valid_interface (interface), NULL);
1357  _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);
1358 
1359  message = dbus_message_new_empty_header ();
1360  if (message == NULL)
1361  return NULL;
1362 
1363  if (!_dbus_header_create (&message->header,
1364  DBUS_COMPILER_BYTE_ORDER,
1366  NULL, path, interface, name, NULL))
1367  {
1368  dbus_message_unref (message);
1369  return NULL;
1370  }
1371 
1372  dbus_message_set_no_reply (message, TRUE);
1373 
1374  return message;
1375 }
1376 
1391 DBusMessage*
1393  const char *error_name,
1394  const char *error_message)
1395 {
1396  DBusMessage *message;
1397  const char *sender;
1398  DBusMessageIter iter;
1399 
1400  _dbus_return_val_if_fail (reply_to != NULL, NULL);
1401  _dbus_return_val_if_fail (error_name != NULL, NULL);
1402  _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
1403 
1404  sender = dbus_message_get_sender (reply_to);
1405 
1406  /* sender may be NULL for non-message-bus case or
1407  * when the message bus is dealing with an unregistered
1408  * connection.
1409  */
1410  message = dbus_message_new_empty_header ();
1411  if (message == NULL)
1412  return NULL;
1413 
1414  if (!_dbus_header_create (&message->header,
1415  DBUS_COMPILER_BYTE_ORDER,
1417  sender, NULL, NULL, NULL, error_name))
1418  {
1419  dbus_message_unref (message);
1420  return NULL;
1421  }
1422 
1423  dbus_message_set_no_reply (message, TRUE);
1424 
1425  if (!dbus_message_set_reply_serial (message,
1426  dbus_message_get_serial (reply_to)))
1427  {
1428  dbus_message_unref (message);
1429  return NULL;
1430  }
1431 
1432  if (error_message != NULL)
1433  {
1434  dbus_message_iter_init_append (message, &iter);
1435  if (!dbus_message_iter_append_basic (&iter,
1437  &error_message))
1438  {
1439  dbus_message_unref (message);
1440  return NULL;
1441  }
1442  }
1443 
1444  return message;
1445 }
1446 
1463 DBusMessage*
1465  const char *error_name,
1466  const char *error_format,
1467  ...)
1468 {
1469  va_list args;
1470  DBusString str;
1471  DBusMessage *message;
1472 
1473  _dbus_return_val_if_fail (reply_to != NULL, NULL);
1474  _dbus_return_val_if_fail (error_name != NULL, NULL);
1475  _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
1476 
1477  if (!_dbus_string_init (&str))
1478  return NULL;
1479 
1480  va_start (args, error_format);
1481 
1482  if (_dbus_string_append_printf_valist (&str, error_format, args))
1483  message = dbus_message_new_error (reply_to, error_name,
1485  else
1486  message = NULL;
1487 
1488  _dbus_string_free (&str);
1489 
1490  va_end (args);
1491 
1492  return message;
1493 }
1494 
1495 
1508 DBusMessage *
1510 {
1511  DBusMessage *retval;
1512 
1513  _dbus_return_val_if_fail (message != NULL, NULL);
1514 
1515  retval = dbus_new0 (DBusMessage, 1);
1516  if (retval == NULL)
1517  return NULL;
1518 
1519  _dbus_atomic_inc (&retval->refcount);
1520 
1521  retval->locked = FALSE;
1522 #ifndef DBUS_DISABLE_CHECKS
1523  retval->generation = message->generation;
1524 #endif
1525 
1526  if (!_dbus_header_copy (&message->header, &retval->header))
1527  {
1528  dbus_free (retval);
1529  return NULL;
1530  }
1531 
1532  if (!_dbus_string_init_preallocated (&retval->body,
1533  _dbus_string_get_length (&message->body)))
1534  {
1535  _dbus_header_free (&retval->header);
1536  dbus_free (retval);
1537  return NULL;
1538  }
1539 
1540  if (!_dbus_string_copy (&message->body, 0,
1541  &retval->body, 0))
1542  goto failed_copy;
1543 
1544 #ifdef HAVE_UNIX_FD_PASSING
1545  retval->unix_fds = dbus_new(int, message->n_unix_fds);
1546  if (retval->unix_fds == NULL && message->n_unix_fds > 0)
1547  goto failed_copy;
1548 
1549  retval->n_unix_fds_allocated = message->n_unix_fds;
1550 
1551  for (retval->n_unix_fds = 0;
1552  retval->n_unix_fds < message->n_unix_fds;
1553  retval->n_unix_fds++)
1554  {
1555  retval->unix_fds[retval->n_unix_fds] = _dbus_dup(message->unix_fds[retval->n_unix_fds], NULL);
1556 
1557  if (retval->unix_fds[retval->n_unix_fds] < 0)
1558  goto failed_copy;
1559  }
1560 
1561 #endif
1562 
1563  _dbus_message_trace_ref (retval, 0, 1, "copy");
1564  return retval;
1565 
1566  failed_copy:
1567  _dbus_header_free (&retval->header);
1568  _dbus_string_free (&retval->body);
1569 
1570 #ifdef HAVE_UNIX_FD_PASSING
1571  close_unix_fds(retval->unix_fds, &retval->n_unix_fds);
1572  dbus_free(retval->unix_fds);
1573 #endif
1574 
1575  dbus_free (retval);
1576 
1577  return NULL;
1578 }
1579 
1580 
1588 DBusMessage *
1590 {
1591  dbus_int32_t old_refcount;
1592 
1593  _dbus_return_val_if_fail (message != NULL, NULL);
1594  _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
1595  _dbus_return_val_if_fail (!message->in_cache, NULL);
1596 
1597  old_refcount = _dbus_atomic_inc (&message->refcount);
1598  _dbus_assert (old_refcount >= 1);
1599  _dbus_message_trace_ref (message, old_refcount, old_refcount + 1, "ref");
1600 
1601  return message;
1602 }
1603 
1611 void
1613 {
1614  dbus_int32_t old_refcount;
1615 
1616  _dbus_return_if_fail (message != NULL);
1617  _dbus_return_if_fail (message->generation == _dbus_current_generation);
1618  _dbus_return_if_fail (!message->in_cache);
1619 
1620  old_refcount = _dbus_atomic_dec (&message->refcount);
1621 
1622  _dbus_assert (old_refcount >= 1);
1623 
1624  _dbus_message_trace_ref (message, old_refcount, old_refcount - 1, "unref");
1625 
1626  if (old_refcount == 1)
1627  {
1628  /* Calls application callbacks! */
1629  dbus_message_cache_or_finalize (message);
1630  }
1631 }
1632 
1643 int
1645 {
1646  _dbus_return_val_if_fail (message != NULL, DBUS_MESSAGE_TYPE_INVALID);
1647 
1648  return _dbus_header_get_message_type (&message->header);
1649 }
1650 
1715  int first_arg_type,
1716  ...)
1717 {
1718  dbus_bool_t retval;
1719  va_list var_args;
1720 
1721  _dbus_return_val_if_fail (message != NULL, FALSE);
1722 
1723  va_start (var_args, first_arg_type);
1724  retval = dbus_message_append_args_valist (message,
1725  first_arg_type,
1726  var_args);
1727  va_end (var_args);
1728 
1729  return retval;
1730 }
1731 
1747  int first_arg_type,
1748  va_list var_args)
1749 {
1750  int type;
1751  DBusMessageIter iter;
1752 
1753  _dbus_return_val_if_fail (message != NULL, FALSE);
1754 
1755  type = first_arg_type;
1756 
1757  dbus_message_iter_init_append (message, &iter);
1758 
1759  while (type != DBUS_TYPE_INVALID)
1760  {
1761  if (dbus_type_is_basic (type))
1762  {
1763  const DBusBasicValue *value;
1764  value = va_arg (var_args, const DBusBasicValue*);
1765 
1766  if (!dbus_message_iter_append_basic (&iter,
1767  type,
1768  value))
1769  goto failed;
1770  }
1771  else if (type == DBUS_TYPE_ARRAY)
1772  {
1773  int element_type;
1774  DBusMessageIter array;
1775  char buf[2];
1776 
1777  element_type = va_arg (var_args, int);
1778 
1779  buf[0] = element_type;
1780  buf[1] = '\0';
1783  buf,
1784  &array))
1785  goto failed;
1786 
1787  if (dbus_type_is_fixed (element_type) &&
1788  element_type != DBUS_TYPE_UNIX_FD)
1789  {
1790  const DBusBasicValue **value;
1791  int n_elements;
1792 
1793  value = va_arg (var_args, const DBusBasicValue**);
1794  n_elements = va_arg (var_args, int);
1795 
1797  element_type,
1798  value,
1799  n_elements)) {
1800  dbus_message_iter_abandon_container (&iter, &array);
1801  goto failed;
1802  }
1803  }
1804  else if (_DBUS_TYPE_IS_STRINGLIKE (element_type))
1805  {
1806  const char ***value_p;
1807  const char **value;
1808  int n_elements;
1809  int i;
1810 
1811  value_p = va_arg (var_args, const char***);
1812  n_elements = va_arg (var_args, int);
1813 
1814  value = *value_p;
1815 
1816  i = 0;
1817  while (i < n_elements)
1818  {
1819  if (!dbus_message_iter_append_basic (&array,
1820  element_type,
1821  &value[i])) {
1822  dbus_message_iter_abandon_container (&iter, &array);
1823  goto failed;
1824  }
1825  ++i;
1826  }
1827  }
1828  else
1829  {
1830  _dbus_warn ("arrays of %s can't be appended with %s for now\n",
1831  _dbus_type_to_string (element_type),
1832  _DBUS_FUNCTION_NAME);
1833  goto failed;
1834  }
1835 
1836  if (!dbus_message_iter_close_container (&iter, &array))
1837  goto failed;
1838  }
1839 #ifndef DBUS_DISABLE_CHECKS
1840  else
1841  {
1842  _dbus_warn ("type %s isn't supported yet in %s\n",
1843  _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
1844  goto failed;
1845  }
1846 #endif
1847 
1848  type = va_arg (var_args, int);
1849  }
1850 
1851  return TRUE;
1852 
1853  failed:
1854  return FALSE;
1855 }
1856 
1903  DBusError *error,
1904  int first_arg_type,
1905  ...)
1906 {
1907  dbus_bool_t retval;
1908  va_list var_args;
1909 
1910  _dbus_return_val_if_fail (message != NULL, FALSE);
1911  _dbus_return_val_if_error_is_set (error, FALSE);
1912 
1913  va_start (var_args, first_arg_type);
1914  retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
1915  va_end (var_args);
1916 
1917  return retval;
1918 }
1919 
1932  DBusError *error,
1933  int first_arg_type,
1934  va_list var_args)
1935 {
1936  DBusMessageIter iter;
1937 
1938  _dbus_return_val_if_fail (message != NULL, FALSE);
1939  _dbus_return_val_if_error_is_set (error, FALSE);
1940 
1941  dbus_message_iter_init (message, &iter);
1942  return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
1943 }
1944 
1945 static void
1946 _dbus_message_iter_init_common (DBusMessage *message,
1947  DBusMessageRealIter *real,
1948  int iter_type)
1949 {
1950  _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
1951 
1952  /* Since the iterator will read or write who-knows-what from the
1953  * message, we need to get in the right byte order
1954  */
1955  ensure_byte_order (message);
1956 
1957  real->message = message;
1958  real->changed_stamp = message->changed_stamp;
1959  real->iter_type = iter_type;
1960  real->sig_refcount = 0;
1961 }
1962 
1987  DBusMessageIter *iter)
1988 {
1989  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
1990  const DBusString *type_str;
1991  int type_pos;
1992 
1993  _dbus_return_val_if_fail (message != NULL, FALSE);
1994  _dbus_return_val_if_fail (iter != NULL, FALSE);
1995 
1996  get_const_signature (&message->header, &type_str, &type_pos);
1997 
1998  _dbus_message_iter_init_common (message, real,
1999  DBUS_MESSAGE_ITER_TYPE_READER);
2000 
2002  _dbus_header_get_byte_order (&message->header),
2003  type_str, type_pos,
2004  &message->body,
2005  0);
2006 
2008 }
2009 
2018 {
2019  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2020 
2021  _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
2022  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2023 
2024  return _dbus_type_reader_has_next (&real->u.reader);
2025 }
2026 
2037 {
2038  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2039 
2040  _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
2041  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2042 
2043  return _dbus_type_reader_next (&real->u.reader);
2044 }
2045 
2060 int
2062 {
2063  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2064 
2065  _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2066  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2067 
2069 }
2070 
2079 int
2081 {
2082  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2083 
2084  _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2085  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
2086  _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
2087 
2089 }
2090 
2116 void
2118  DBusMessageIter *sub)
2119 {
2120  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2121  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2122 
2123  _dbus_return_if_fail (_dbus_message_iter_check (real));
2124  _dbus_return_if_fail (sub != NULL);
2125 
2126  *real_sub = *real;
2127  _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
2128 }
2129 
2141 char *
2143 {
2144  const DBusString *sig;
2145  DBusString retstr;
2146  char *ret;
2147  int start, len;
2148  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2149 
2150  _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
2151 
2152  if (!_dbus_string_init (&retstr))
2153  return NULL;
2154 
2156  &start, &len);
2157  if (!_dbus_string_append_len (&retstr,
2158  _dbus_string_get_const_data (sig) + start,
2159  len))
2160  return NULL;
2161  if (!_dbus_string_steal_data (&retstr, &ret))
2162  return NULL;
2163  _dbus_string_free (&retstr);
2164  return ret;
2165 }
2166 
2214 void
2216  void *value)
2217 {
2218  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2219 
2220  _dbus_return_if_fail (_dbus_message_iter_check (real));
2221  _dbus_return_if_fail (value != NULL);
2222 
2224  {
2225 #ifdef HAVE_UNIX_FD_PASSING
2226  DBusBasicValue idx;
2227 
2228  _dbus_type_reader_read_basic(&real->u.reader, &idx);
2229 
2230  if (idx.u32 >= real->message->n_unix_fds) {
2231  /* Hmm, we cannot really signal an error here, so let's make
2232  sure to return an invalid fd. */
2233  *((int*) value) = -1;
2234  return;
2235  }
2236 
2237  *((int*) value) = _dbus_dup(real->message->unix_fds[idx.u32], NULL);
2238 #else
2239  *((int*) value) = -1;
2240 #endif
2241  }
2242  else
2243  {
2245  value);
2246  }
2247 }
2248 
2267 int
2269 {
2270  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2271 
2272  _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
2273 
2275 }
2276 
2312 void
2314  void *value,
2315  int *n_elements)
2316 {
2317  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2318 #ifndef DBUS_DISABLE_CHECKS
2319  int subtype = _dbus_type_reader_get_current_type(&real->u.reader);
2320 
2321  _dbus_return_if_fail (_dbus_message_iter_check (real));
2322  _dbus_return_if_fail (value != NULL);
2323  _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) ||
2324  (dbus_type_is_fixed (subtype) && subtype != DBUS_TYPE_UNIX_FD));
2325 #endif
2326 
2328  value, n_elements);
2329 }
2330 
2342 void
2344  DBusMessageIter *iter)
2345 {
2346  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2347 
2348  _dbus_return_if_fail (message != NULL);
2349  _dbus_return_if_fail (iter != NULL);
2350 
2351  _dbus_message_iter_init_common (message, real,
2352  DBUS_MESSAGE_ITER_TYPE_WRITER);
2353 
2354  /* We create the signature string and point iterators at it "on demand"
2355  * when a value is actually appended. That means that init() never fails
2356  * due to OOM.
2357  */
2359  _dbus_header_get_byte_order (&message->header),
2360  &message->body,
2361  _dbus_string_get_length (&message->body));
2362 }
2363 
2372 static dbus_bool_t
2373 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
2374 {
2375  DBusString *str;
2376  const DBusString *current_sig;
2377  int current_sig_pos;
2378 
2379  _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2380 
2381  if (real->u.writer.type_str != NULL)
2382  {
2383  _dbus_assert (real->sig_refcount > 0);
2384  real->sig_refcount += 1;
2385  return TRUE;
2386  }
2387 
2388  str = dbus_new (DBusString, 1);
2389  if (str == NULL)
2390  return FALSE;
2391 
2394  &current_sig, &current_sig_pos))
2395  current_sig = NULL;
2396 
2397  if (current_sig)
2398  {
2399  int current_len;
2400 
2401  current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
2402  current_sig_pos += 1; /* move on to sig data */
2403 
2404  if (!_dbus_string_init_preallocated (str, current_len + 4))
2405  {
2406  dbus_free (str);
2407  return FALSE;
2408  }
2409 
2410  if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
2411  str, 0))
2412  {
2413  _dbus_string_free (str);
2414  dbus_free (str);
2415  return FALSE;
2416  }
2417  }
2418  else
2419  {
2420  if (!_dbus_string_init_preallocated (str, 4))
2421  {
2422  dbus_free (str);
2423  return FALSE;
2424  }
2425  }
2426 
2427  real->sig_refcount = 1;
2428 
2430  str, _dbus_string_get_length (str));
2431  return TRUE;
2432 }
2433 
2443 static dbus_bool_t
2444 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
2445 {
2446  DBusString *str;
2447  const char *v_STRING;
2448  dbus_bool_t retval;
2449 
2450  _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2451  _dbus_assert (real->u.writer.type_str != NULL);
2452  _dbus_assert (real->sig_refcount > 0);
2453 
2454  real->sig_refcount -= 1;
2455 
2456  if (real->sig_refcount > 0)
2457  return TRUE;
2458  _dbus_assert (real->sig_refcount == 0);
2459 
2460  retval = TRUE;
2461 
2462  str = real->u.writer.type_str;
2463 
2464  v_STRING = _dbus_string_get_const_data (str);
2468  &v_STRING))
2469  retval = FALSE;
2470 
2472  _dbus_string_free (str);
2473  dbus_free (str);
2474 
2475  return retval;
2476 }
2477 
2485 static void
2486 _dbus_message_iter_abandon_signature (DBusMessageRealIter *real)
2487 {
2488  DBusString *str;
2489 
2490  _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2491  _dbus_assert (real->u.writer.type_str != NULL);
2492  _dbus_assert (real->sig_refcount > 0);
2493 
2494  real->sig_refcount -= 1;
2495 
2496  if (real->sig_refcount > 0)
2497  return;
2498  _dbus_assert (real->sig_refcount == 0);
2499 
2500  str = real->u.writer.type_str;
2501 
2503  _dbus_string_free (str);
2504  dbus_free (str);
2505 }
2506 
2507 #ifndef DBUS_DISABLE_CHECKS
2508 static dbus_bool_t
2509 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
2510 {
2511  if (!_dbus_message_iter_check (iter))
2512  return FALSE;
2513 
2514  if (iter->message->locked)
2515  {
2516  _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)\n");
2517  return FALSE;
2518  }
2519 
2520  return TRUE;
2521 }
2522 #endif /* DBUS_DISABLE_CHECKS */
2523 
2524 #ifdef HAVE_UNIX_FD_PASSING
2525 static int *
2526 expand_fd_array(DBusMessage *m,
2527  unsigned n)
2528 {
2529  _dbus_assert(m);
2530 
2531  /* This makes space for adding n new fds to the array and returns a
2532  pointer to the place were the first fd should be put. */
2533 
2534  if (m->n_unix_fds + n > m->n_unix_fds_allocated)
2535  {
2536  unsigned k;
2537  int *p;
2538 
2539  /* Make twice as much space as necessary */
2540  k = (m->n_unix_fds + n) * 2;
2541 
2542  /* Allocate at least four */
2543  if (k < 4)
2544  k = 4;
2545 
2546  p = dbus_realloc(m->unix_fds, k * sizeof(int));
2547  if (p == NULL)
2548  return NULL;
2549 
2550  m->unix_fds = p;
2551  m->n_unix_fds_allocated = k;
2552  }
2553 
2554  return m->unix_fds + m->n_unix_fds;
2555 }
2556 #endif
2557 
2579  int type,
2580  const void *value)
2581 {
2582  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2583  dbus_bool_t ret;
2584 
2585  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2586  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2587  _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
2588  _dbus_return_val_if_fail (value != NULL, FALSE);
2589 
2590 #ifndef DBUS_DISABLE_CHECKS
2591  switch (type)
2592  {
2593  const char * const *string_p;
2594  const dbus_bool_t *bool_p;
2595 
2596  case DBUS_TYPE_STRING:
2597  string_p = value;
2598  _dbus_return_val_if_fail (_dbus_check_is_valid_utf8 (*string_p), FALSE);
2599  break;
2600 
2601  case DBUS_TYPE_OBJECT_PATH:
2602  string_p = value;
2603  _dbus_return_val_if_fail (_dbus_check_is_valid_path (*string_p), FALSE);
2604  break;
2605 
2606  case DBUS_TYPE_SIGNATURE:
2607  string_p = value;
2608  _dbus_return_val_if_fail (_dbus_check_is_valid_signature (*string_p), FALSE);
2609  break;
2610 
2611  case DBUS_TYPE_BOOLEAN:
2612  bool_p = value;
2613  _dbus_return_val_if_fail (*bool_p == 0 || *bool_p == 1, FALSE);
2614  break;
2615 
2616  default:
2617  {
2618  /* nothing to check, all possible values are allowed */
2619  }
2620  }
2621 #endif
2622 
2623  if (!_dbus_message_iter_open_signature (real))
2624  return FALSE;
2625 
2626  if (type == DBUS_TYPE_UNIX_FD)
2627  {
2628 #ifdef HAVE_UNIX_FD_PASSING
2629  int *fds;
2630  dbus_uint32_t u;
2631 
2632  /* First step, include the fd in the fd list of this message */
2633  if (!(fds = expand_fd_array(real->message, 1)))
2634  return FALSE;
2635 
2636  *fds = _dbus_dup(*(int*) value, NULL);
2637  if (*fds < 0)
2638  return FALSE;
2639 
2640  u = real->message->n_unix_fds;
2641 
2642  /* Second step, write the index to the fd */
2643  if (!(ret = _dbus_type_writer_write_basic (&real->u.writer, DBUS_TYPE_UNIX_FD, &u))) {
2644  _dbus_close(*fds, NULL);
2645  return FALSE;
2646  }
2647 
2648  real->message->n_unix_fds += 1;
2649  u += 1;
2650 
2651  /* Final step, update the header accordingly */
2655  &u);
2656 
2657  /* If any of these operations fail the message is
2658  hosed. However, no memory or fds should be leaked since what
2659  has been added to message has been added to the message, and
2660  can hence be accounted for when the message is being
2661  freed. */
2662 #else
2663  ret = FALSE;
2664 #endif
2665  }
2666  else
2667  {
2668  ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
2669  }
2670 
2671  if (!_dbus_message_iter_close_signature (real))
2672  ret = FALSE;
2673 
2674  return ret;
2675 }
2676 
2714  int element_type,
2715  const void *value,
2716  int n_elements)
2717 {
2718  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2719  dbus_bool_t ret;
2720 
2721  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2722  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2723  _dbus_return_val_if_fail (dbus_type_is_fixed (element_type) && element_type != DBUS_TYPE_UNIX_FD, FALSE);
2724  _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
2725  _dbus_return_val_if_fail (value != NULL, FALSE);
2726  _dbus_return_val_if_fail (n_elements >= 0, FALSE);
2727  _dbus_return_val_if_fail (n_elements <=
2729  FALSE);
2730 
2731 #ifndef DBUS_DISABLE_CHECKS
2732  if (element_type == DBUS_TYPE_BOOLEAN)
2733  {
2734  const dbus_bool_t * const *bools = value;
2735  int i;
2736 
2737  for (i = 0; i < n_elements; i++)
2738  {
2739  _dbus_return_val_if_fail ((*bools)[i] == 0 || (*bools)[i] == 1, FALSE);
2740  }
2741  }
2742 #endif
2743 
2744  ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
2745 
2746  return ret;
2747 }
2748 
2772  int type,
2773  const char *contained_signature,
2774  DBusMessageIter *sub)
2775 {
2776  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2777  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2778  DBusString contained_str;
2779 
2780  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2781  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2782  _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
2783  _dbus_return_val_if_fail (sub != NULL, FALSE);
2784  _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
2785  contained_signature == NULL) ||
2786  (type == DBUS_TYPE_DICT_ENTRY &&
2787  contained_signature == NULL) ||
2788  (type == DBUS_TYPE_VARIANT &&
2789  contained_signature != NULL) ||
2790  (type == DBUS_TYPE_ARRAY &&
2791  contained_signature != NULL), FALSE);
2792 
2793  /* this would fail if the contained_signature is a dict entry, since
2794  * dict entries are invalid signatures standalone (they must be in
2795  * an array)
2796  */
2797  _dbus_return_val_if_fail ((type == DBUS_TYPE_ARRAY && contained_signature && *contained_signature == DBUS_DICT_ENTRY_BEGIN_CHAR) ||
2798  (contained_signature == NULL ||
2799  _dbus_check_is_valid_signature (contained_signature)),
2800  FALSE);
2801 
2802  if (!_dbus_message_iter_open_signature (real))
2803  return FALSE;
2804 
2805  *real_sub = *real;
2806 
2807  if (contained_signature != NULL)
2808  {
2809  _dbus_string_init_const (&contained_str, contained_signature);
2810 
2811  return _dbus_type_writer_recurse (&real->u.writer,
2812  type,
2813  &contained_str, 0,
2814  &real_sub->u.writer);
2815  }
2816  else
2817  {
2818  return _dbus_type_writer_recurse (&real->u.writer,
2819  type,
2820  NULL, 0,
2821  &real_sub->u.writer);
2822  }
2823 }
2824 
2825 
2841  DBusMessageIter *sub)
2842 {
2843  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2844  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2845  dbus_bool_t ret;
2846 
2847  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2848  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2849  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
2850  _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2851 
2852  ret = _dbus_type_writer_unrecurse (&real->u.writer,
2853  &real_sub->u.writer);
2854 
2855  if (!_dbus_message_iter_close_signature (real))
2856  ret = FALSE;
2857 
2858  return ret;
2859 }
2860 
2872 void
2874  DBusMessageIter *sub)
2875 {
2876  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2877 #ifndef DBUS_DISABLE_CHECKS
2878  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2879 
2880  _dbus_return_if_fail (_dbus_message_iter_append_check (real));
2881  _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2882  _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
2883  _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2884 #endif
2885 
2886  _dbus_message_iter_abandon_signature (real);
2887 }
2888 
2905 void
2907  dbus_bool_t no_reply)
2908 {
2909  _dbus_return_if_fail (message != NULL);
2910  _dbus_return_if_fail (!message->locked);
2911 
2912  _dbus_header_toggle_flag (&message->header,
2914  no_reply);
2915 }
2916 
2926 {
2927  _dbus_return_val_if_fail (message != NULL, FALSE);
2928 
2929  return _dbus_header_get_flag (&message->header,
2931 }
2932 
2947 void
2949  dbus_bool_t auto_start)
2950 {
2951  _dbus_return_if_fail (message != NULL);
2952  _dbus_return_if_fail (!message->locked);
2953 
2954  _dbus_header_toggle_flag (&message->header,
2956  !auto_start);
2957 }
2958 
2968 {
2969  _dbus_return_val_if_fail (message != NULL, FALSE);
2970 
2971  return !_dbus_header_get_flag (&message->header,
2973 }
2974 
2975 
2990  const char *object_path)
2991 {
2992  _dbus_return_val_if_fail (message != NULL, FALSE);
2993  _dbus_return_val_if_fail (!message->locked, FALSE);
2994  _dbus_return_val_if_fail (object_path == NULL ||
2995  _dbus_check_is_valid_path (object_path),
2996  FALSE);
2997 
2998  return set_or_delete_string_field (message,
3001  object_path);
3002 }
3003 
3017 const char*
3019 {
3020  const char *v;
3021 
3022  _dbus_return_val_if_fail (message != NULL, NULL);
3023 
3024  v = NULL; /* in case field doesn't exist */
3028  (void *) &v);
3029  return v;
3030 }
3031 
3043  const char *path)
3044 {
3045  const char *msg_path;
3046  msg_path = dbus_message_get_path (message);
3047 
3048  if (msg_path == NULL)
3049  {
3050  if (path == NULL)
3051  return TRUE;
3052  else
3053  return FALSE;
3054  }
3055 
3056  if (path == NULL)
3057  return FALSE;
3058 
3059  if (strcmp (msg_path, path) == 0)
3060  return TRUE;
3061 
3062  return FALSE;
3063 }
3064 
3087  char ***path)
3088 {
3089  const char *v;
3090 
3091  _dbus_return_val_if_fail (message != NULL, FALSE);
3092  _dbus_return_val_if_fail (path != NULL, FALSE);
3093 
3094  *path = NULL;
3095 
3096  v = dbus_message_get_path (message);
3097  if (v != NULL)
3098  {
3099  if (!_dbus_decompose_path (v, strlen (v),
3100  path, NULL))
3101  return FALSE;
3102  }
3103  return TRUE;
3104 }
3105 
3121  const char *interface)
3122 {
3123  _dbus_return_val_if_fail (message != NULL, FALSE);
3124  _dbus_return_val_if_fail (!message->locked, FALSE);
3125  _dbus_return_val_if_fail (interface == NULL ||
3126  _dbus_check_is_valid_interface (interface),
3127  FALSE);
3128 
3129  return set_or_delete_string_field (message,
3132  interface);
3133 }
3134 
3148 const char*
3150 {
3151  const char *v;
3152 
3153  _dbus_return_val_if_fail (message != NULL, NULL);
3154 
3155  v = NULL; /* in case field doesn't exist */
3159  (void *) &v);
3160  return v;
3161 }
3162 
3172  const char *interface)
3173 {
3174  const char *msg_interface;
3175  msg_interface = dbus_message_get_interface (message);
3176 
3177  if (msg_interface == NULL)
3178  {
3179  if (interface == NULL)
3180  return TRUE;
3181  else
3182  return FALSE;
3183  }
3184 
3185  if (interface == NULL)
3186  return FALSE;
3187 
3188  if (strcmp (msg_interface, interface) == 0)
3189  return TRUE;
3190 
3191  return FALSE;
3192 
3193 }
3194 
3209  const char *member)
3210 {
3211  _dbus_return_val_if_fail (message != NULL, FALSE);
3212  _dbus_return_val_if_fail (!message->locked, FALSE);
3213  _dbus_return_val_if_fail (member == NULL ||
3214  _dbus_check_is_valid_member (member),
3215  FALSE);
3216 
3217  return set_or_delete_string_field (message,
3220  member);
3221 }
3222 
3234 const char*
3236 {
3237  const char *v;
3238 
3239  _dbus_return_val_if_fail (message != NULL, NULL);
3240 
3241  v = NULL; /* in case field doesn't exist */
3245  (void *) &v);
3246  return v;
3247 }
3248 
3258  const char *member)
3259 {
3260  const char *msg_member;
3261  msg_member = dbus_message_get_member (message);
3262 
3263  if (msg_member == NULL)
3264  {
3265  if (member == NULL)
3266  return TRUE;
3267  else
3268  return FALSE;
3269  }
3270 
3271  if (member == NULL)
3272  return FALSE;
3273 
3274  if (strcmp (msg_member, member) == 0)
3275  return TRUE;
3276 
3277  return FALSE;
3278 
3279 }
3280 
3294  const char *error_name)
3295 {
3296  _dbus_return_val_if_fail (message != NULL, FALSE);
3297  _dbus_return_val_if_fail (!message->locked, FALSE);
3298  _dbus_return_val_if_fail (error_name == NULL ||
3299  _dbus_check_is_valid_error_name (error_name),
3300  FALSE);
3301 
3302  return set_or_delete_string_field (message,
3305  error_name);
3306 }
3307 
3318 const char*
3320 {
3321  const char *v;
3322 
3323  _dbus_return_val_if_fail (message != NULL, NULL);
3324 
3325  v = NULL; /* in case field doesn't exist */
3329  (void *) &v);
3330  return v;
3331 }
3332 
3348  const char *destination)
3349 {
3350  _dbus_return_val_if_fail (message != NULL, FALSE);
3351  _dbus_return_val_if_fail (!message->locked, FALSE);
3352  _dbus_return_val_if_fail (destination == NULL ||
3353  _dbus_check_is_valid_bus_name (destination),
3354  FALSE);
3355 
3356  return set_or_delete_string_field (message,
3359  destination);
3360 }
3361 
3371 const char*
3373 {
3374  const char *v;
3375 
3376  _dbus_return_val_if_fail (message != NULL, NULL);
3377 
3378  v = NULL; /* in case field doesn't exist */
3382  (void *) &v);
3383  return v;
3384 }
3385 
3402  const char *sender)
3403 {
3404  _dbus_return_val_if_fail (message != NULL, FALSE);
3405  _dbus_return_val_if_fail (!message->locked, FALSE);
3406  _dbus_return_val_if_fail (sender == NULL ||
3407  _dbus_check_is_valid_bus_name (sender),
3408  FALSE);
3409 
3410  return set_or_delete_string_field (message,
3413  sender);
3414 }
3415 
3431 const char*
3433 {
3434  const char *v;
3435 
3436  _dbus_return_val_if_fail (message != NULL, NULL);
3437 
3438  v = NULL; /* in case field doesn't exist */
3442  (void *) &v);
3443  return v;
3444 }
3445 
3464 const char*
3466 {
3467  const DBusString *type_str;
3468  int type_pos;
3469 
3470  _dbus_return_val_if_fail (message != NULL, NULL);
3471 
3472  get_const_signature (&message->header, &type_str, &type_pos);
3473 
3474  return _dbus_string_get_const_data_len (type_str, type_pos, 0);
3475 }
3476 
3477 static dbus_bool_t
3478 _dbus_message_has_type_interface_member (DBusMessage *message,
3479  int type,
3480  const char *interface,
3481  const char *member)
3482 {
3483  const char *n;
3484 
3485  _dbus_assert (message != NULL);
3486  _dbus_assert (interface != NULL);
3487  _dbus_assert (member != NULL);
3488 
3489  if (dbus_message_get_type (message) != type)
3490  return FALSE;
3491 
3492  /* Optimize by checking the short member name first
3493  * instead of the longer interface name
3494  */
3495 
3496  n = dbus_message_get_member (message);
3497 
3498  if (n && strcmp (n, member) == 0)
3499  {
3500  n = dbus_message_get_interface (message);
3501 
3502  if (n == NULL || strcmp (n, interface) == 0)
3503  return TRUE;
3504  }
3505 
3506  return FALSE;
3507 }
3508 
3525  const char *interface,
3526  const char *method)
3527 {
3528  _dbus_return_val_if_fail (message != NULL, FALSE);
3529  _dbus_return_val_if_fail (interface != NULL, FALSE);
3530  _dbus_return_val_if_fail (method != NULL, FALSE);
3531  /* don't check that interface/method are valid since it would be
3532  * expensive, and not catch many common errors
3533  */
3534 
3535  return _dbus_message_has_type_interface_member (message,
3537  interface, method);
3538 }
3539 
3553  const char *interface,
3554  const char *signal_name)
3555 {
3556  _dbus_return_val_if_fail (message != NULL, FALSE);
3557  _dbus_return_val_if_fail (interface != NULL, FALSE);
3558  _dbus_return_val_if_fail (signal_name != NULL, FALSE);
3559  /* don't check that interface/name are valid since it would be
3560  * expensive, and not catch many common errors
3561  */
3562 
3563  return _dbus_message_has_type_interface_member (message,
3565  interface, signal_name);
3566 }
3567 
3580  const char *error_name)
3581 {
3582  const char *n;
3583 
3584  _dbus_return_val_if_fail (message != NULL, FALSE);
3585  _dbus_return_val_if_fail (error_name != NULL, FALSE);
3586  /* don't check that error_name is valid since it would be expensive,
3587  * and not catch many common errors
3588  */
3589 
3591  return FALSE;
3592 
3593  n = dbus_message_get_error_name (message);
3594 
3595  if (n && strcmp (n, error_name) == 0)
3596  return TRUE;
3597  else
3598  return FALSE;
3599 }
3600 
3613  const char *name)
3614 {
3615  const char *s;
3616 
3617  _dbus_return_val_if_fail (message != NULL, FALSE);
3618  _dbus_return_val_if_fail (name != NULL, FALSE);
3619  /* don't check that name is valid since it would be expensive, and
3620  * not catch many common errors
3621  */
3622 
3623  s = dbus_message_get_destination (message);
3624 
3625  if (s && strcmp (s, name) == 0)
3626  return TRUE;
3627  else
3628  return FALSE;
3629 }
3630 
3648  const char *name)
3649 {
3650  const char *s;
3651 
3652  _dbus_return_val_if_fail (message != NULL, FALSE);
3653  _dbus_return_val_if_fail (name != NULL, FALSE);
3654  /* don't check that name is valid since it would be expensive, and
3655  * not catch many common errors
3656  */
3657 
3658  s = dbus_message_get_sender (message);
3659 
3660  if (s && strcmp (s, name) == 0)
3661  return TRUE;
3662  else
3663  return FALSE;
3664 }
3665 
3677  const char *signature)
3678 {
3679  const char *s;
3680 
3681  _dbus_return_val_if_fail (message != NULL, FALSE);
3682  _dbus_return_val_if_fail (signature != NULL, FALSE);
3683  /* don't check that signature is valid since it would be expensive,
3684  * and not catch many common errors
3685  */
3686 
3687  s = dbus_message_get_signature (message);
3688 
3689  if (s && strcmp (s, signature) == 0)
3690  return TRUE;
3691  else
3692  return FALSE;
3693 }
3694 
3719  DBusMessage *message)
3720 {
3721  const char *str;
3722 
3723  _dbus_return_val_if_fail (message != NULL, FALSE);
3724  _dbus_return_val_if_error_is_set (error, FALSE);
3725 
3727  return FALSE;
3728 
3729  str = NULL;
3730  dbus_message_get_args (message, NULL,
3731  DBUS_TYPE_STRING, &str,
3733 
3734  dbus_set_error (error, dbus_message_get_error_name (message),
3735  str ? "%s" : NULL, str);
3736 
3737  return TRUE;
3738 }
3739 
3748 {
3749 #ifdef HAVE_UNIX_FD_PASSING
3750  _dbus_assert(message);
3751 
3752  return message->n_unix_fds > 0;
3753 #else
3754  return FALSE;
3755 #endif
3756 }
3757 
3776 #define INITIAL_LOADER_DATA_LEN 32
3777 
3786 {
3787  DBusMessageLoader *loader;
3788 
3789  loader = dbus_new0 (DBusMessageLoader, 1);
3790  if (loader == NULL)
3791  return NULL;
3792 
3793  loader->refcount = 1;
3794 
3795  loader->corrupted = FALSE;
3796  loader->corruption_reason = DBUS_VALID;
3797 
3798  /* this can be configured by the app, but defaults to the protocol max */
3800 
3801  /* We set a very relatively conservative default here since due to how
3802  SCM_RIGHTS works we need to preallocate an fd array of the maximum
3803  number of unix fds we want to receive in advance. A
3804  try-and-reallocate loop is not possible. */
3805  loader->max_message_unix_fds = 1024;
3806 
3807  if (!_dbus_string_init (&loader->data))
3808  {
3809  dbus_free (loader);
3810  return NULL;
3811  }
3812 
3813  /* preallocate the buffer for speed, ignore failure */
3815  _dbus_string_set_length (&loader->data, 0);
3816 
3817 #ifdef HAVE_UNIX_FD_PASSING
3818  loader->unix_fds = NULL;
3819  loader->n_unix_fds = loader->n_unix_fds_allocated = 0;
3820  loader->unix_fds_outstanding = FALSE;
3821 #endif
3822 
3823  return loader;
3824 }
3825 
3834 {
3835  loader->refcount += 1;
3836 
3837  return loader;
3838 }
3839 
3846 void
3848 {
3849  loader->refcount -= 1;
3850  if (loader->refcount == 0)
3851  {
3852 #ifdef HAVE_UNIX_FD_PASSING
3853  close_unix_fds(loader->unix_fds, &loader->n_unix_fds);
3854  dbus_free(loader->unix_fds);
3855 #endif
3856  _dbus_list_foreach (&loader->messages,
3858  NULL);
3859  _dbus_list_clear (&loader->messages);
3860  _dbus_string_free (&loader->data);
3861  dbus_free (loader);
3862  }
3863 }
3864 
3883 void
3885  DBusString **buffer)
3886 {
3887  _dbus_assert (!loader->buffer_outstanding);
3888 
3889  *buffer = &loader->data;
3890 
3891  loader->buffer_outstanding = TRUE;
3892 }
3893 
3904 void
3906  DBusString *buffer,
3907  int bytes_read)
3908 {
3909  _dbus_assert (loader->buffer_outstanding);
3910  _dbus_assert (buffer == &loader->data);
3911 
3912  loader->buffer_outstanding = FALSE;
3913 }
3914 
3927  int **fds,
3928  unsigned *max_n_fds)
3929 {
3930 #ifdef HAVE_UNIX_FD_PASSING
3931  _dbus_assert (!loader->unix_fds_outstanding);
3932 
3933  /* Allocate space where we can put the fds we read. We allocate
3934  space for max_message_unix_fds since this is an
3935  upper limit how many fds can be received within a single
3936  message. Since SCM_RIGHTS doesn't allow a reallocate+retry logic
3937  we are allocating the maximum possible array size right from the
3938  beginning. This sucks a bit, however unless SCM_RIGHTS is fixed
3939  there is no better way. */
3940 
3941  if (loader->n_unix_fds_allocated < loader->max_message_unix_fds)
3942  {
3943  int *a = dbus_realloc(loader->unix_fds,
3944  loader->max_message_unix_fds * sizeof(loader->unix_fds[0]));
3945 
3946  if (!a)
3947  return FALSE;
3948 
3949  loader->unix_fds = a;
3950  loader->n_unix_fds_allocated = loader->max_message_unix_fds;
3951  }
3952 
3953  *fds = loader->unix_fds + loader->n_unix_fds;
3954  *max_n_fds = loader->n_unix_fds_allocated - loader->n_unix_fds;
3955 
3956  loader->unix_fds_outstanding = TRUE;
3957  return TRUE;
3958 #else
3959  _dbus_assert_not_reached("Platform doesn't support unix fd passing");
3960  return FALSE;
3961 #endif
3962 }
3963 
3974 void
3976  int *fds,
3977  unsigned n_fds)
3978 {
3979 #ifdef HAVE_UNIX_FD_PASSING
3980  _dbus_assert(loader->unix_fds_outstanding);
3981  _dbus_assert(loader->unix_fds + loader->n_unix_fds == fds);
3982  _dbus_assert(loader->n_unix_fds + n_fds <= loader->n_unix_fds_allocated);
3983 
3984  loader->n_unix_fds += n_fds;
3985  loader->unix_fds_outstanding = FALSE;
3986 #else
3987  _dbus_assert_not_reached("Platform doesn't support unix fd passing");
3988 #endif
3989 }
3990 
3991 /*
3992  * FIXME when we move the header out of the buffer, that memmoves all
3993  * buffered messages. Kind of crappy.
3994  *
3995  * Also we copy the header and body, which is kind of crappy. To
3996  * avoid this, we have to allow header and body to be in a single
3997  * memory block, which is good for messages we read and bad for
3998  * messages we are creating. But we could move_len() the buffer into
3999  * this single memory block, and move_len() will just swap the buffers
4000  * if you're moving the entire buffer replacing the dest string.
4001  *
4002  * We could also have the message loader tell the transport how many
4003  * bytes to read; so it would first ask for some arbitrary number like
4004  * 256, then if the message was incomplete it would use the
4005  * header/body len to ask for exactly the size of the message (or
4006  * blocks the size of a typical kernel buffer for the socket). That
4007  * way we don't get trailing bytes in the buffer that have to be
4008  * memmoved. Though I suppose we also don't have a chance of reading a
4009  * bunch of small messages at once, so the optimization may be stupid.
4010  *
4011  * Another approach would be to keep a "start" index into
4012  * loader->data and only delete it occasionally, instead of after
4013  * each message is loaded.
4014  *
4015  * load_message() returns FALSE if not enough memory OR the loader was corrupted
4016  */
4017 static dbus_bool_t
4018 load_message (DBusMessageLoader *loader,
4019  DBusMessage *message,
4020  int byte_order,
4021  int fields_array_len,
4022  int header_len,
4023  int body_len)
4024 {
4025  dbus_bool_t oom;
4026  DBusValidity validity;
4027  const DBusString *type_str;
4028  int type_pos;
4029  DBusValidationMode mode;
4030  dbus_uint32_t n_unix_fds = 0;
4031 
4032  mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
4033 
4034  oom = FALSE;
4035 
4036 #if 0
4037  _dbus_verbose_bytes_of_string (&loader->data, 0, header_len /* + body_len */);
4038 #endif
4039 
4040  /* 1. VALIDATE AND COPY OVER HEADER */
4041  _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
4042  _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
4043 
4044  if (!_dbus_header_load (&message->header,
4045  mode,
4046  &validity,
4047  byte_order,
4048  fields_array_len,
4049  header_len,
4050  body_len,
4051  &loader->data, 0,
4052  _dbus_string_get_length (&loader->data)))
4053  {
4054  _dbus_verbose ("Failed to load header for new message code %d\n", validity);
4055 
4056  /* assert here so we can catch any code that still uses DBUS_VALID to indicate
4057  oom errors. They should use DBUS_VALIDITY_UNKNOWN_OOM_ERROR instead */
4058  _dbus_assert (validity != DBUS_VALID);
4059 
4060  if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
4061  oom = TRUE;
4062  else
4063  {
4064  loader->corrupted = TRUE;
4065  loader->corruption_reason = validity;
4066  }
4067  goto failed;
4068  }
4069 
4070  _dbus_assert (validity == DBUS_VALID);
4071 
4072  /* 2. VALIDATE BODY */
4073  if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
4074  {
4075  get_const_signature (&message->header, &type_str, &type_pos);
4076 
4077  /* Because the bytes_remaining arg is NULL, this validates that the
4078  * body is the right length
4079  */
4080  validity = _dbus_validate_body_with_reason (type_str,
4081  type_pos,
4082  byte_order,
4083  NULL,
4084  &loader->data,
4085  header_len,
4086  body_len);
4087  if (validity != DBUS_VALID)
4088  {
4089  _dbus_verbose ("Failed to validate message body code %d\n", validity);
4090 
4091  loader->corrupted = TRUE;
4092  loader->corruption_reason = validity;
4093 
4094  goto failed;
4095  }
4096  }
4097 
4098  /* 3. COPY OVER UNIX FDS */
4102  &n_unix_fds);
4103 
4104 #ifdef HAVE_UNIX_FD_PASSING
4105 
4106  if (n_unix_fds > loader->n_unix_fds)
4107  {
4108  _dbus_verbose("Message contains references to more unix fds than were sent %u != %u\n",
4109  n_unix_fds, loader->n_unix_fds);
4110 
4111  loader->corrupted = TRUE;
4112  loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4113  goto failed;
4114  }
4115 
4116  /* If this was a recycled message there might still be
4117  some memory allocated for the fds */
4118  dbus_free(message->unix_fds);
4119 
4120  if (n_unix_fds > 0)
4121  {
4122  message->unix_fds = _dbus_memdup(loader->unix_fds, n_unix_fds * sizeof(message->unix_fds[0]));
4123  if (message->unix_fds == NULL)
4124  {
4125  _dbus_verbose ("Failed to allocate file descriptor array\n");
4126  oom = TRUE;
4127  goto failed;
4128  }
4129 
4130  message->n_unix_fds_allocated = message->n_unix_fds = n_unix_fds;
4131  loader->n_unix_fds -= n_unix_fds;
4132  memmove(loader->unix_fds + n_unix_fds, loader->unix_fds, loader->n_unix_fds);
4133  }
4134  else
4135  message->unix_fds = NULL;
4136 
4137 #else
4138 
4139  if (n_unix_fds > 0)
4140  {
4141  _dbus_verbose ("Hmm, message claims to come with file descriptors "
4142  "but that's not supported on our platform, disconnecting.\n");
4143 
4144  loader->corrupted = TRUE;
4145  loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4146  goto failed;
4147  }
4148 
4149 #endif
4150 
4151  /* 3. COPY OVER BODY AND QUEUE MESSAGE */
4152 
4153  if (!_dbus_list_append (&loader->messages, message))
4154  {
4155  _dbus_verbose ("Failed to append new message to loader queue\n");
4156  oom = TRUE;
4157  goto failed;
4158  }
4159 
4160  _dbus_assert (_dbus_string_get_length (&message->body) == 0);
4162  (header_len + body_len));
4163 
4164  if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
4165  {
4166  _dbus_verbose ("Failed to move body into new message\n");
4167  oom = TRUE;
4168  goto failed;
4169  }
4170 
4171  _dbus_string_delete (&loader->data, 0, header_len + body_len);
4172 
4173  /* don't waste more than 2k of memory */
4174  _dbus_string_compact (&loader->data, 2048);
4175 
4176  _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
4177  _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
4178 
4179  _dbus_verbose ("Loaded message %p\n", message);
4180 
4181  _dbus_assert (!oom);
4182  _dbus_assert (!loader->corrupted);
4183  _dbus_assert (loader->messages != NULL);
4184  _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4185 
4186  return TRUE;
4187 
4188  failed:
4189 
4190  /* Clean up */
4191 
4192  /* does nothing if the message isn't in the list */
4193  _dbus_list_remove_last (&loader->messages, message);
4194 
4195  if (oom)
4196  _dbus_assert (!loader->corrupted);
4197  else
4198  _dbus_assert (loader->corrupted);
4199 
4201 
4202  return FALSE;
4203 }
4204 
4221 {
4222  while (!loader->corrupted &&
4224  {
4225  DBusValidity validity;
4226  int byte_order, fields_array_len, header_len, body_len;
4227 
4229  &validity,
4230  &byte_order,
4231  &fields_array_len,
4232  &header_len,
4233  &body_len,
4234  &loader->data, 0,
4235  _dbus_string_get_length (&loader->data)))
4236  {
4237  DBusMessage *message;
4238 
4239  _dbus_assert (validity == DBUS_VALID);
4240 
4241  message = dbus_message_new_empty_header ();
4242  if (message == NULL)
4243  return FALSE;
4244 
4245  if (!load_message (loader, message,
4246  byte_order, fields_array_len,
4247  header_len, body_len))
4248  {
4249  dbus_message_unref (message);
4250  /* load_message() returns false if corrupted or OOM; if
4251  * corrupted then return TRUE for not OOM
4252  */
4253  return loader->corrupted;
4254  }
4255 
4256  _dbus_assert (loader->messages != NULL);
4257  _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4258  }
4259  else
4260  {
4261  _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
4262  validity);
4263  if (validity != DBUS_VALID)
4264  {
4265  loader->corrupted = TRUE;
4266  loader->corruption_reason = validity;
4267  }
4268  return TRUE;
4269  }
4270  }
4271 
4272  return TRUE;
4273 }
4274 
4282 DBusMessage*
4284 {
4285  if (loader->messages)
4286  return loader->messages->data;
4287  else
4288  return NULL;
4289 }
4290 
4299 DBusMessage*
4301 {
4302  return _dbus_list_pop_first (&loader->messages);
4303 }
4304 
4313 DBusList*
4315 {
4316  return _dbus_list_pop_first_link (&loader->messages);
4317 }
4318 
4325 void
4327  DBusList *link)
4328 {
4329  _dbus_list_prepend_link (&loader->messages, link);
4330 }
4331 
4343 {
4344  _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
4345  (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
4346  return loader->corrupted;
4347 }
4348 
4357 {
4358  _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
4359  (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
4360 
4361  return loader->corruption_reason;
4362 }
4363 
4370 void
4372  long size)
4373 {
4374  if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
4375  {
4376  _dbus_verbose ("clamping requested max message size %ld to %d\n",
4379  }
4380  loader->max_message_size = size;
4381 }
4382 
4389 long
4391 {
4392  return loader->max_message_size;
4393 }
4394 
4401 void
4403  long n)
4404 {
4406  {
4407  _dbus_verbose ("clamping requested max message unix_fds %ld to %d\n",
4410  }
4411  loader->max_message_unix_fds = n;
4412 }
4413 
4420 long
4422 {
4423  return loader->max_message_unix_fds;
4424 }
4425 
4426 static DBusDataSlotAllocator slot_allocator;
4427 _DBUS_DEFINE_GLOBAL_LOCK (message_slots);
4428 
4445 {
4446  return _dbus_data_slot_allocator_alloc (&slot_allocator,
4447  &_DBUS_LOCK_NAME (message_slots),
4448  slot_p);
4449 }
4450 
4462 void
4464 {
4465  _dbus_return_if_fail (*slot_p >= 0);
4466 
4467  _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
4468 }
4469 
4485  dbus_int32_t slot,
4486  void *data,
4487  DBusFreeFunction free_data_func)
4488 {
4489  DBusFreeFunction old_free_func;
4490  void *old_data;
4491  dbus_bool_t retval;
4492 
4493  _dbus_return_val_if_fail (message != NULL, FALSE);
4494  _dbus_return_val_if_fail (slot >= 0, FALSE);
4495 
4496  retval = _dbus_data_slot_list_set (&slot_allocator,
4497  &message->slot_list,
4498  slot, data, free_data_func,
4499  &old_free_func, &old_data);
4500 
4501  if (retval)
4502  {
4503  /* Do the actual free outside the message lock */
4504  if (old_free_func)
4505  (* old_free_func) (old_data);
4506  }
4507 
4508  return retval;
4509 }
4510 
4519 void*
4521  dbus_int32_t slot)
4522 {
4523  void *res;
4524 
4525  _dbus_return_val_if_fail (message != NULL, NULL);
4526 
4527  res = _dbus_data_slot_list_get (&slot_allocator,
4528  &message->slot_list,
4529  slot);
4530 
4531  return res;
4532 }
4533 
4547 int
4548 dbus_message_type_from_string (const char *type_str)
4549 {
4550  if (strcmp (type_str, "method_call") == 0)
4552  if (strcmp (type_str, "method_return") == 0)
4554  else if (strcmp (type_str, "signal") == 0)
4555  return DBUS_MESSAGE_TYPE_SIGNAL;
4556  else if (strcmp (type_str, "error") == 0)
4557  return DBUS_MESSAGE_TYPE_ERROR;
4558  else
4560 }
4561 
4575 const char *
4577 {
4578  switch (type)
4579  {
4581  return "method_call";
4583  return "method_return";
4585  return "signal";
4587  return "error";
4588  default:
4589  return "invalid";
4590  }
4591 }
4592 
4607  char **marshalled_data_p,
4608  int *len_p)
4609 {
4610  DBusString tmp;
4611  dbus_bool_t was_locked;
4612 
4613  _dbus_return_val_if_fail (msg != NULL, FALSE);
4614  _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
4615  _dbus_return_val_if_fail (len_p != NULL, FALSE);
4616 
4617  if (!_dbus_string_init (&tmp))
4618  return FALSE;
4619 
4620  /* Ensure the message is locked, to ensure the length header is filled in. */
4621  was_locked = msg->locked;
4622 
4623  if (!was_locked)
4624  dbus_message_lock (msg);
4625 
4626  if (!_dbus_string_copy (&(msg->header.data), 0, &tmp, 0))
4627  goto fail;
4628 
4629  *len_p = _dbus_string_get_length (&tmp);
4630 
4631  if (!_dbus_string_copy (&(msg->body), 0, &tmp, *len_p))
4632  goto fail;
4633 
4634  *len_p = _dbus_string_get_length (&tmp);
4635 
4636  if (!_dbus_string_steal_data (&tmp, marshalled_data_p))
4637  goto fail;
4638 
4639  _dbus_string_free (&tmp);
4640 
4641  if (!was_locked)
4642  msg->locked = FALSE;
4643 
4644  return TRUE;
4645 
4646  fail:
4647  _dbus_string_free (&tmp);
4648 
4649  if (!was_locked)
4650  msg->locked = FALSE;
4651 
4652  return FALSE;
4653 }
4654 
4667 DBusMessage *
4668 dbus_message_demarshal (const char *str,
4669  int len,
4670  DBusError *error)
4671 {
4672  DBusMessageLoader *loader;
4673  DBusString *buffer;
4674  DBusMessage *msg;
4675 
4676  _dbus_return_val_if_fail (str != NULL, NULL);
4677 
4678  loader = _dbus_message_loader_new ();
4679 
4680  if (loader == NULL)
4681  return NULL;
4682 
4683  _dbus_message_loader_get_buffer (loader, &buffer);
4684  _dbus_string_append_len (buffer, str, len);
4685  _dbus_message_loader_return_buffer (loader, buffer, len);
4686 
4688  goto fail_oom;
4689 
4691  goto fail_corrupt;
4692 
4693  msg = _dbus_message_loader_pop_message (loader);
4694 
4695  if (!msg)
4696  goto fail_oom;
4697 
4698  _dbus_message_loader_unref (loader);
4699  return msg;
4700 
4701  fail_corrupt:
4702  dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted (%s)",
4703  _dbus_validity_to_error_message (loader->corruption_reason));
4704  _dbus_message_loader_unref (loader);
4705  return NULL;
4706 
4707  fail_oom:
4708  _DBUS_SET_OOM (error);
4709  _dbus_message_loader_unref (loader);
4710  return NULL;
4711 }
4712 
4726 int
4728  int len)
4729 {
4730  DBusString str;
4731  int byte_order, fields_array_len, header_len, body_len;
4732  DBusValidity validity = DBUS_VALID;
4733  int have_message;
4734 
4735  if (!buf || len < DBUS_MINIMUM_HEADER_SIZE)
4736  return 0;
4737 
4738  if (len > DBUS_MAXIMUM_MESSAGE_LENGTH)
4740  _dbus_string_init_const_len (&str, buf, len);
4741 
4742  validity = DBUS_VALID;
4743  have_message
4745  &validity, &byte_order,
4746  &fields_array_len,
4747  &header_len,
4748  &body_len,
4749  &str, 0,
4750  len);
4751  _dbus_string_free (&str);
4752 
4753  if (validity == DBUS_VALID)
4754  {
4755  _dbus_assert (have_message || (header_len + body_len) > len);
4756  (void) have_message; /* unused unless asserting */
4757  return header_len + body_len;
4758  }
4759  else
4760  {
4761  return -1; /* broken! */
4762  }
4763 }
4764 
4767 /* tests in dbus-message-util.c */
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...
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...
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...
unsigned int dbus_uint32_t
A 32-bit unsigned integer on all platforms.
DBusMessage * dbus_message_ref(DBusMessage *message)
Increments the reference count of a DBusMessage.
void dbus_message_lock(DBusMessage *message)
Locks a message.
Definition: dbus-message.c:383
const char * message
public error message field
Definition: dbus-errors.h:51
dbus_bool_t dbus_message_has_path(DBusMessage *message, const char *path)
Checks if the message has a particular object path.
dbus_int32_t _dbus_atomic_get(DBusAtomic *atomic)
Atomically get the value of an integer.
dbus_uint32_t changed_stamp
Incremented when iterators are invalidated.
#define NULL
A null pointer, defined appropriately for C or C++.
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.
void(* DBusFreeFunction)(void *memory)
The type of a function which frees a block of memory.
Definition: dbus-memory.h:64
long _dbus_message_loader_get_max_message_size(DBusMessageLoader *loader)
Gets the maximum allowed message size in bytes.
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.
void _dbus_message_loader_putback_message_link(DBusMessageLoader *loader, DBusList *link)
Returns a popped message link, used to undo a pop.
dbus_bool_t _dbus_header_copy(const DBusHeader *header, DBusHeader *dest)
Initializes dest with a copy of the given header.
int dbus_message_iter_get_arg_type(DBusMessageIter *iter)
Returns the argument type of the argument that the message iterator points to.
dbus_uint32_t sig_refcount
depth of open_signature()
Definition: dbus-message.c:130
void _dbus_type_writer_remove_types(DBusTypeWriter *writer)
Removes type string from the writer.
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:600
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:700
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().
dbus_uint32_t dbus_message_get_serial(DBusMessage *message)
Returns the serial of a message or 0 if none has been specified.
DBusList * messages
Complete messages.
The type writer is an iterator for writing to a block of values.
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...
void _dbus_type_reader_recurse(DBusTypeReader *reader, DBusTypeReader *sub)
Initialize a new reader pointing to the first type and corresponding value that&#39;s a child of the curr...
DBusMessage * _dbus_message_loader_pop_message(DBusMessageLoader *loader)
Pops a loaded message (passing ownership of the message to the caller).
DBusList * _dbus_list_find_last(DBusList **list, void *data)
Finds a value in the list.
Definition: dbus-list.c:461
#define DBUS_ERROR_NOT_SUPPORTED
Requested operation isn&#39;t supported (like ENOSYS on UNIX).
#define dbus_new(type, count)
Safe macro for using dbus_malloc().
Definition: dbus-memory.h:58
void dbus_message_free_data_slot(dbus_int32_t *slot_p)
Deallocates a global ID for message data slots.
#define DBUS_HEADER_FIELD_SIGNATURE
Header field code for the type signature of a message.
const char * dbus_message_get_error_name(DBusMessage *message)
Gets the error name (DBUS_MESSAGE_TYPE_ERROR only) or NULL if none.
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...
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.
void _dbus_list_remove_link(DBusList **list, DBusList *link)
Removes a link from the list.
Definition: dbus-list.c:516
#define DBUS_TYPE_STRUCT
STRUCT and DICT_ENTRY are sort of special since their codes can&#39;t appear in a type string...
#define DBUS_TYPE_DICT_ENTRY
Type code used to represent a dict entry; however, this type code does not appear in type signatures...
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...
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:784
#define DBUS_TYPE_STRING
Type code marking a UTF-8 encoded, nul-terminated Unicode string.
DBusString body
Body network data.
dbus_uint32_t _dbus_header_get_serial(DBusHeader *header)
See dbus_message_get_serial()
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.
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
#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...
dbus_bool_t dbus_message_has_interface(DBusMessage *message, const char *interface)
Checks if the message has an interface.
void _dbus_list_append_link(DBusList **list, DBusList *link)
Appends a link to the list.
Definition: dbus-list.c:304
Internals of DBusCounter.
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.
void * data
Data stored at this element.
Definition: dbus-list.h:38
#define MAX_MESSAGE_CACHE_SIZE
Avoid caching too many messages.
Definition: dbus-message.c:507
DBusMessage * dbus_message_new(int message_type)
Constructs a new message of the given message type.
#define DBUS_ERROR_INCONSISTENT_MESSAGE
The message meta data does not match the payload.
dbus_bool_t _dbus_header_init(DBusHeader *header)
Initializes a header, but doesn&#39;t prepare it for use; to make the header valid, you have to call _dbu...
void _dbus_warn_check_failed(const char *format,...)
Prints a &quot;critical&quot; warning to stderr when an assertion fails; differs from _dbus_warn primarily in t...
const char * dbus_message_get_signature(DBusMessage *message)
Gets the type signature of the message, i.e.
void dbus_message_iter_init_append(DBusMessage *message, DBusMessageIter *iter)
Initializes a DBusMessageIter for appending arguments to the end of a message.
void dbus_error_free(DBusError *error)
Frees an error that&#39;s been set (or just initialized), then reinitializes the error as in dbus_error_i...
Definition: dbus-errors.c:211
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...
union DBusMessageRealIter::@6 u
the type writer or reader that does all the work
void _dbus_message_loader_unref(DBusMessageLoader *loader)
Decrements the reference count of the loader and finalizes the loader when the count reaches zero...
DBusCounter * _dbus_counter_ref(DBusCounter *counter)
Increments refcount of the counter.
DBusString data
Header network data, stored separately from body so we can independently realloc it.
unsigned char _dbus_string_get_byte(const DBusString *str, int start)
Gets the byte at the given position.
Definition: dbus-string.c:540
int _dbus_dup(int fd, DBusError *error)
Duplicates a file descriptor.
DBusValidity _dbus_message_loader_get_corruption_reason(DBusMessageLoader *loader)
Checks what kind of bad data confused the loader.
dbus_bool_t _dbus_type_writer_write_basic(DBusTypeWriter *writer, int type, const void *value)
Writes out a basic type.
#define DBUS_MESSAGE_TYPE_ERROR
Message type of an error reply message, see dbus_message_get_type()
DBusList * _dbus_list_alloc_link(void *data)
Allocates a linked list node.
Definition: dbus-list.c:231
#define DBUS_MAXIMUM_MESSAGE_UNIX_FDS
The maximum total number of unix fds in a message.
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...
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
#define DBUS_MESSAGE_TYPE_METHOD_RETURN
Message type of a method return message, see dbus_message_get_type()
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:1070
DBusTypeReader reader
reader
Definition: dbus-message.c:134
DBusValidationMode
This is used rather than a bool for high visibility.
dbus_bool_t dbus_message_iter_has_next(DBusMessageIter *iter)
Checks if an iterator has any more fields.
DBusMessage * message
Message used.
Definition: dbus-message.c:127
dbus_bool_t _dbus_data_slot_allocator_alloc(DBusDataSlotAllocator *allocator, DBusRMutex **mutex_loc, 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_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that&#39;s copied to the d...
Definition: dbus-string.c:1280
#define DBUS_HEADER_FIELD_INTERFACE
Header field code for the interface containing a member (method or signal).
#define DBUS_DICT_ENTRY_BEGIN_CHAR
Code marking the start of a dict entry type in a type signature.
DBusList * _dbus_list_pop_first_link(DBusList **list)
Removes the first link in the list and returns it.
Definition: dbus-list.c:617
dbus_bool_t dbus_message_has_member(DBusMessage *message, const char *member)
Checks if the message has an interface member.
DBusValidity
This is primarily used in unit testing, so we can verify that each invalid message is invalid for the...
DBusMessageIter struct; contains no public fields.
Definition: dbus-message.h:51
dbus_bool_t dbus_message_iter_init(DBusMessage *message, DBusMessageIter *iter)
Initializes a DBusMessageIter for reading the arguments of the message passed in. ...
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:328
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:183
const char * dbus_message_get_destination(DBusMessage *message)
Gets the destination of a message or NULL if there is none set.
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:279
#define DBUS_TYPE_ARRAY
Type code marking a D-Bus array type.
DBusString * type_str
where to write typecodes (or read type expectations)
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.
dbus_bool_t dbus_message_set_error_name(DBusMessage *message, const char *error_name)
Sets the name of the error (DBUS_MESSAGE_TYPE_ERROR).
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
const char * dbus_message_get_member(DBusMessage *message)
Gets the interface member being invoked (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted (DBUS_MESSAGE_TYPE...
dbus_bool_t _dbus_list_remove_last(DBusList **list, void *data)
Removes a value from the list.
Definition: dbus-list.c:435
Internals of DBusMessage.
Internals of DBusMessageIter.
Definition: dbus-message.c:125
#define dbus_new0(type, count)
Safe macro for using dbus_malloc0().
Definition: dbus-memory.h:59
dbus_uint32_t changed_stamp
stamp to detect invalid iters
Definition: dbus-message.c:128
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.
dbus_bool_t _dbus_string_compact(DBusString *str, int max_waste)
Compacts the string to avoid wasted memory.
Definition: dbus-string.c:367
int _dbus_header_get_message_type(DBusHeader *header)
Gets the type of the message.
#define DBUS_HEADER_FIELD_ERROR_NAME
Header field code for an error name (found in DBUS_MESSAGE_TYPE_ERROR messages).
#define DBUS_MINIMUM_HEADER_SIZE
The smallest header size that can occur.
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...
dbus_bool_t dbus_type_is_basic(int typecode)
A &quot;basic type&quot; is a somewhat arbitrary concept, but the intent is to include those types that are ful...
void _dbus_message_loader_set_max_message_size(DBusMessageLoader *loader, long size)
Sets the maximum size message we allow.
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:190
DBusHeader header
Header network data and associated cache.
dbus_bool_t dbus_message_set_sender(DBusMessage *message, const char *sender)
Sets the message sender.
DBusString data
Buffered data.
void _dbus_type_reader_read_basic(const DBusTypeReader *reader, void *value)
Reads a basic-typed value, as with _dbus_marshal_read_basic().
unsigned int locked
Message being sent, no modifications allowed.
#define ensure_byte_order(message)
byte-swap the message if it doesn&#39;t match our byte order.
Definition: dbus-message.c:194
DBusMessageLoader * _dbus_message_loader_ref(DBusMessageLoader *loader)
Increments the reference count of the loader.
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.
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...
can&#39;t determine validity due to OOM
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
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:1190
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
void _dbus_counter_unref(DBusCounter *counter)
Decrements refcount of the counter and possibly finalizes the counter.
dbus_bool_t dbus_message_set_interface(DBusMessage *message, const char *interface)
Sets the interface this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or the interface...
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:351
dbus_bool_t _dbus_list_append(DBusList **list, void *data)
Appends a value to the list.
Definition: dbus-list.c:259
dbus_bool_t _dbus_decompose_path(const char *data, int len, char ***path, int *path_len)
Decompose an object path.
void * _dbus_memdup(const void *mem, size_t n_bytes)
Duplicates a block of memory.
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...
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...
void _dbus_list_foreach(DBusList **list, DBusForeachFunction function, void *data)
Calls the given function for each element in the list.
Definition: dbus-list.c:748
long max_message_size
Maximum size of a message.
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...
int _dbus_string_get_length(const DBusString *str)
Gets the length of a string (not including nul termination).
Definition: dbus-string.c:717
dbus_bool_t _dbus_type_reader_next(DBusTypeReader *reader)
Skip to the next value on this &quot;level&quot;.
DBusList * counters
0-N DBusCounter used to track message size/unix fds.
DBusMessageLoader * _dbus_message_loader_new(void)
Creates a new message loader.
long size_counter_delta
Size we incremented the size counters by.
#define CHANGED_STAMP_BITS
How many bits are in the changed_stamp used to validate iterators.
void _dbus_header_byteswap(DBusHeader *header, int new_order)
Swaps the header into the given order if required.
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).
#define DBUS_MESSAGE_TYPE_METHOD_CALL
Message type of a method call message, see dbus_message_get_type()
#define DBUS_HEADER_FIELD_UNIX_FDS
Header field code for the number of unix file descriptors associated with this message.
int _dbus_current_generation
_dbus_current_generation is used to track each time that dbus_shutdown() is called, so we can reinit things after it&#39;s been called.
Definition: dbus-memory.c:780
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.
Object representing an exception.
Definition: dbus-errors.h:48
unsigned int in_cache
Has been &quot;freed&quot; since it&#39;s in the cache (this is a debug feature)
void * _dbus_list_pop_first(DBusList **list)
Removes the first value in the list and returns it.
Definition: dbus-list.c:638
#define DBUS_TYPE_SIGNATURE
Type code marking a D-Bus type signature.
dbus_bool_t dbus_message_append_args(DBusMessage *message, int first_arg_type,...)
Appends fields to a message given a variable argument list.
#define DBUS_MESSAGE_TYPE_SIGNAL
Message type of a signal message, see dbus_message_get_type()
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_uint32_t dbus_message_get_reply_serial(DBusMessage *message)
Returns the serial that the message is a reply to or 0 if none.
#define INITIAL_LOADER_DATA_LEN
The initial buffer size of the message loader.
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...
void _dbus_data_slot_list_clear(DBusDataSlotList *list)
Frees all data slots contained in the list, calling application-provided free functions if they exist...
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
dbus_bool_t _dbus_message_loader_get_is_corrupted(DBusMessageLoader *loader)
Checks whether the loader is confused due to bad data.
#define DBUS_TYPE_VARIANT
Type code marking a D-Bus variant type.
#define DBUS_TYPE_UINT32
Type code marking a 32-bit unsigned integer.
Definition: dbus-protocol.h:86
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...
void _dbus_header_reinit(DBusHeader *header)
Re-initializes a header that was previously initialized and never freed.
the data is valid
#define DBUS_HEADER_FIELD_DESTINATION
Header field code for the destination bus name of a message.
dbus_uint32_t byte_order
byte order of the block
dbus_bool_t _dbus_header_delete_field(DBusHeader *header, int field)
Deletes a field, if it exists.
dbus_bool_t _dbus_close(int fd, DBusError *error)
Closes a file descriptor.
dbus_bool_t dbus_message_has_destination(DBusMessage *message, const char *name)
Checks whether the message was sent to the given name.
#define DBUS_MESSAGE_TYPE_INVALID
This value is never a valid message type, see dbus_message_get_type()
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.
dbus_uint32_t byte_order
byte order to write values with
#define _DBUS_UNLOCK(name)
Unlocks a global lock.
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:242
The type reader is an iterator for reading values from a block of values.
void * _dbus_data_slot_list_get(DBusDataSlotAllocator *allocator, DBusDataSlotList *list, int slot)
Retrieves data previously set with _dbus_data_slot_list_set_data().
long _dbus_message_loader_get_max_message_unix_fds(DBusMessageLoader *loader)
Gets the maximum allowed number of unix fds per message.
#define TRUE
Expands to &quot;1&quot;.
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.
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.
void _dbus_data_slot_list_init(DBusDataSlotList *list)
Initializes a slot list.
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
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 ...
int dbus_message_iter_get_element_type(DBusMessageIter *iter)
Returns the element type of the array that the message iterator points to.
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:207
dbus_bool_t dbus_message_is_method_call(DBusMessage *message, const char *interface, const char *method)
Checks whether the message is a method call with the given interface and member fields.
#define DBUS_HEADER_FIELD_MEMBER
Header field code for a member (method or signal).
long max_message_unix_fds
Maximum unix fds in a message.
unsigned int corrupted
We got broken data, and are no longer working.
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.
#define DBUS_HEADER_FIELD_SENDER
Header field code for the sender of a message; usually initialized by the message bus...
void _dbus_type_writer_add_types(DBusTypeWriter *writer, DBusString *type_str, int type_pos)
Adds type string to the writer, if it had none.
#define DBUS_TYPE_OBJECT_PATH
Type code marking a D-Bus object path.
dbus_bool_t dbus_set_error_from_message(DBusError *error, DBusMessage *message)
Sets a DBusError based on the contents of the given message.
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.
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.
#define DBUS_TYPE_UNIX_FD
Type code marking a unix file descriptor.
void _dbus_message_loader_return_buffer(DBusMessageLoader *loader, DBusString *buffer, int bytes_read)
Returns a buffer obtained from _dbus_message_loader_get_buffer(), indicating to the loader how many b...
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.
DBusMessage * dbus_message_new_signal(const char *path, const char *interface, const char *name)
Constructs a new message representing a signal emission.
#define _DBUS_DEFINE_GLOBAL_LOCK(name)
Defines a global lock variable with the given name.
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...
An allocator that tracks a set of slot IDs.
Definition: dbus-dataslot.h:55
#define DBUS_TYPE_INVALID
Type code that is never equal to a legitimate type code.
Definition: dbus-protocol.h:60
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).
void _dbus_counter_notify(DBusCounter *counter)
Calls the notify function from _dbus_counter_set_notify(), if that function has been specified and th...
dbus_bool_t dbus_message_has_sender(DBusMessage *message, const char *name)
Checks whether the message has the given unique name as its sender.
dbus_bool_t dbus_message_iter_next(DBusMessageIter *iter)
Moves the iterator to the next field, if any.
void dbus_message_iter_get_basic(DBusMessageIter *iter, void *value)
Reads a basic-typed value from the message iterator.
void * dbus_message_get_data(DBusMessage *message, dbus_int32_t slot)
Retrieves data previously set with dbus_message_set_data().
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.
void _dbus_header_free(DBusHeader *header)
Frees a header.
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)...
#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...
dbus_bool_t dbus_message_set_destination(DBusMessage *message, const char *destination)
Sets the message&#39;s destination.
void dbus_error_init(DBusError *error)
Initializes a DBusError structure.
Definition: dbus-errors.c:188
DBusAtomic refcount
Reference count.
dbus_bool_t dbus_message_get_no_reply(DBusMessage *message)
Returns TRUE if the message does not expect a reply.
const char * _dbus_string_get_const_data_len(const DBusString *str, int start, int len)
const version of _dbus_string_get_data_len().
Definition: dbus-string.c:492
A node in a linked list.
Definition: dbus-list.h:34
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.
void dbus_free_string_array(char **str_array)
Frees a NULL-terminated array of strings.
Definition: dbus-memory.c:748
#define DBUS_TYPE_BOOLEAN
Type code marking a boolean.
Definition: dbus-protocol.h:70
void _dbus_message_loader_get_buffer(DBusMessageLoader *loader, DBusString **buffer)
Gets the buffer to use for reading data from the network.
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:1134
dbus_uint32_t iter_type
whether this is a reader or writer iter
Definition: dbus-message.c:129
void _dbus_header_set_serial(DBusHeader *header, dbus_uint32_t serial)
Sets the serial number of a header.
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.
char _dbus_header_get_byte_order(const DBusHeader *header)
Returns the header&#39;s byte order.
_DBUS_STRING_DEFINE_STATIC(_dbus_header_signature_str, DBUS_HEADER_SIGNATURE)
Static DBusString containing the signature of a message header.
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...
dbus_bool_t dbus_message_is_signal(DBusMessage *message, const char *interface, const char *signal_name)
Checks whether the message is a signal with the given interface and member fields.
dbus_bool_t _dbus_type_reader_has_next(const DBusTypeReader *reader)
Check whether there&#39;s another value on this &quot;level&quot;.
A simple value union that lets you access bytes as if they were various types; useful when dealing wi...
Definition: dbus-types.h:157
dbus_uint32_t container_type
what are we inside? (e.g.
int _dbus_type_reader_get_array_length(const DBusTypeReader *reader)
Returns the number of bytes in the array.
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.
dbus_bool_t dbus_message_iter_append_basic(DBusMessageIter *iter, int type, const void *value)
Appends a basic-typed value to the message.
int dbus_message_iter_get_array_len(DBusMessageIter *iter)
Returns the number of bytes in the array as marshaled in the wire protocol.
void(* DBusForeachFunction)(void *element, void *data)
Used to iterate over each item in a collection, such as a DBusList.
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...
#define FALSE
Expands to &quot;0&quot;.
Message header data and some cached details of it.
#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...
int dbus_message_get_type(DBusMessage *message)
Gets the type of a message.
#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...
unsigned int buffer_outstanding
Someone is using the buffer to read.
int generation
_dbus_current_generation when message was created
void _dbus_list_prepend_link(DBusList **list, DBusList *link)
Prepends a link to the list.
Definition: dbus-list.c:322
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:780
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:809
#define _DBUS_LOCK(name)
Locks a global lock.
#define _DBUS_LOCK_NAME(name)
Expands to name of a global lock variable.
const char * _dbus_type_to_string(int typecode)
Returns a string describing the given type.
DBusMessage * _dbus_message_loader_peek_message(DBusMessageLoader *loader)
Peeks at first loaded message, returns NULL if no messages have been queued.
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:1372
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:619
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.
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. ...
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.
char * dbus_message_iter_get_signature(DBusMessageIter *iter)
Returns the current signature of a message iterator.
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.
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...
void _dbus_verbose_bytes_of_string(const DBusString *str, int start, int len)
Dump the given part of the string to verbose log.
dbus_bool_t dbus_message_contains_unix_fds(DBusMessage *message)
Checks whether a message contains unix fds.
#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 ...
dbus_bool_t _dbus_message_loader_queue_messages(DBusMessageLoader *loader)
Converts buffered data into messages, if we have enough data.
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:226
int refcount
Reference count.
int dbus_int32_t
A 32-bit signed integer on all platforms.
char * _dbus_strdup(const char *str)
Duplicates a string.
#define MAX_MESSAGE_SIZE_TO_CACHE
Avoid caching huge messages.
Definition: dbus-message.c:504
#define DBUS_ERROR_INVALID_ARGS
Invalid arguments passed to a method call.
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().
int _dbus_type_get_alignment(int typecode)
Gets the alignment requirement for the given type; will be 1, 4, or 8.
DBusValidity corruption_reason
why we were corrupted
void _dbus_message_loader_set_max_message_unix_fds(DBusMessageLoader *loader, long n)
Sets the maximum unix fds per message we allow.
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...
const char * _dbus_string_get_const_data(const DBusString *str)
Gets the raw character buffer from a const string.
Definition: dbus-string.c:446
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)...
void dbus_message_unref(DBusMessage *message)
Decrements the reference count of a DBusMessage, freeing the message if the count reaches 0...
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
Implementation details of DBusMessageLoader.
DBusMessage * dbus_message_new_method_call(const char *destination, const char *path, const char *interface, const char *method)
Constructs a new message to invoke a method on a remote object.
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.
dbus_uint32_t u32
as int32
Definition: dbus-types.h:163
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...
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...
void dbus_message_set_serial(DBusMessage *message, dbus_uint32_t serial)
Sets the serial number of a message.
Definition: dbus-message.c:253
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...
void _dbus_header_update_lengths(DBusHeader *header, int body_len)
Fills in the correct body length.
DBusMessage * dbus_message_new_method_return(DBusMessage *method_call)
Constructs a message that is a reply to a method call.
DBusTypeWriter writer
writer
Definition: dbus-message.c:133
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...
#define DBUS_MAXIMUM_MESSAGE_LENGTH
The maximum total message size including header and body; similar rationale to max array size...
DBusDataSlotList slot_list
Data stored by allocated integer ID.
void _dbus_list_clear(DBusList **list)
Frees all links in the list and sets the list head to NULL.
Definition: dbus-list.c:531
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.
dbus_bool_t dbus_type_is_container(int typecode)
A &quot;container type&quot; can contain basic types, or nested container types.
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.
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...