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