D-Bus  1.13.7
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 {
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  DBusBasicValue *ptr;
897 
898  ptr = va_arg (var_args, DBusBasicValue*);
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 DBusBasicValue **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 DBusBasicValue**);
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 
940  (void *) ptr, n_elements_p);
941  }
942  else if (_DBUS_TYPE_IS_STRINGLIKE (spec_element_type))
943  {
944  char ***str_array_p;
945  int n_elements;
946  char **str_array;
947 
948  str_array_p = va_arg (var_args, char***);
949  n_elements_p = va_arg (var_args, int*);
950 
951  _dbus_assert (str_array_p != NULL);
952  _dbus_assert (n_elements_p != NULL);
953 
954  /* Count elements in the array */
955  _dbus_type_reader_recurse (&real->u.reader, &array);
956 
957  n_elements = 0;
959  {
960  ++n_elements;
961  _dbus_type_reader_next (&array);
962  }
963 
964  str_array = dbus_new0 (char*, n_elements + 1);
965  if (str_array == NULL)
966  {
967  _DBUS_SET_OOM (error);
968  goto out;
969  }
970 
971  /* Now go through and dup each string */
972  _dbus_type_reader_recurse (&real->u.reader, &array);
973 
974  j = 0;
975  while (j < n_elements)
976  {
977  const char *s;
979  (void *) &s);
980 
981  str_array[j] = _dbus_strdup (s);
982  if (str_array[j] == NULL)
983  {
984  dbus_free_string_array (str_array);
985  _DBUS_SET_OOM (error);
986  goto out;
987  }
988 
989  ++j;
990 
991  if (!_dbus_type_reader_next (&array))
992  _dbus_assert (j == n_elements);
993  }
994 
996  _dbus_assert (j == n_elements);
997  _dbus_assert (str_array[j] == NULL);
998 
999  *str_array_p = str_array;
1000  *n_elements_p = n_elements;
1001  }
1002 #ifndef DBUS_DISABLE_CHECKS
1003  else
1004  {
1005  _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now",
1006  _DBUS_FUNCTION_NAME);
1007  goto out;
1008  }
1009 #endif
1010  }
1011 #ifndef DBUS_DISABLE_CHECKS
1012  else
1013  {
1014  _dbus_warn ("you can only read arrays and basic types with %s for now",
1015  _DBUS_FUNCTION_NAME);
1016  goto out;
1017  }
1018 #endif
1019 
1020  /* how many arguments already handled */
1021  i++;
1022 
1023  spec_type = va_arg (var_args, int);
1024  if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID)
1025  {
1027  "Message has only %d arguments, but more were expected", i);
1028  goto out;
1029  }
1030  }
1031 
1032  retval = TRUE;
1033 
1034  out:
1035  /* there may memory or unix fd leak in the above iteration if parse failed.
1036  * so we have another iteration over copy_args to free memory and close
1037  * unix fds.
1038  */
1039  if (!retval)
1040  {
1041  spec_type = first_arg_type;
1042  j = 0;
1043 
1044  while (j < i)
1045  {
1046  if (spec_type == DBUS_TYPE_UNIX_FD)
1047  {
1048 #ifdef HAVE_UNIX_FD_PASSING
1049  int *pfd;
1050 
1051  pfd = va_arg (copy_args, int *);
1052  _dbus_assert(pfd);
1053  if (*pfd >= 0)
1054  {
1055  _dbus_close (*pfd, NULL);
1056  *pfd = -1;
1057  }
1058 #endif
1059  }
1060  else if (dbus_type_is_basic (spec_type))
1061  {
1062  /* move the index forward */
1063  va_arg (copy_args, DBusBasicValue *);
1064  }
1065  else if (spec_type == DBUS_TYPE_ARRAY)
1066  {
1067  int spec_element_type;
1068 
1069  spec_element_type = va_arg (copy_args, int);
1070  if (dbus_type_is_fixed (spec_element_type))
1071  {
1072  /* move the index forward */
1073  va_arg (copy_args, const DBusBasicValue **);
1074  va_arg (copy_args, int *);
1075  }
1076  else if (_DBUS_TYPE_IS_STRINGLIKE (spec_element_type))
1077  {
1078  char ***str_array_p;
1079 
1080  str_array_p = va_arg (copy_args, char ***);
1081  /* move the index forward */
1082  va_arg (copy_args, int *);
1083  _dbus_assert (str_array_p != NULL);
1084  dbus_free_string_array (*str_array_p);
1085  *str_array_p = NULL;
1086  }
1087  }
1088 
1089  spec_type = va_arg (copy_args, int);
1090  j++;
1091  }
1092  }
1093 
1094  va_end (copy_args);
1095  return retval;
1096 }
1097 
1156 dbus_uint32_t
1158 {
1159  _dbus_return_val_if_fail (message != NULL, 0);
1160 
1161  return _dbus_header_get_serial (&message->header);
1162 }
1163 
1174  dbus_uint32_t reply_serial)
1175 {
1176  DBusBasicValue value;
1177 
1178  _dbus_return_val_if_fail (message != NULL, FALSE);
1179  _dbus_return_val_if_fail (!message->locked, FALSE);
1180  _dbus_return_val_if_fail (reply_serial != 0, FALSE); /* 0 is invalid */
1181 
1182  value.u32 = reply_serial;
1183 
1184  return _dbus_header_set_field_basic (&message->header,
1187  &value);
1188 }
1189 
1196 dbus_uint32_t
1198 {
1199  dbus_uint32_t v_UINT32;
1200 
1201  _dbus_return_val_if_fail (message != NULL, 0);
1202 
1203  if (_dbus_header_get_field_basic (&message->header,
1206  &v_UINT32))
1207  return v_UINT32;
1208  else
1209  return 0;
1210 }
1211 
1212 static void
1213 dbus_message_finalize (DBusMessage *message)
1214 {
1215  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
1216 
1217  /* This calls application callbacks! */
1219 
1220  _dbus_list_foreach (&message->counters,
1221  free_counter, message);
1222  _dbus_list_clear (&message->counters);
1223 
1224  _dbus_header_free (&message->header);
1225  _dbus_string_free (&message->body);
1226 
1227 #ifdef HAVE_UNIX_FD_PASSING
1228  close_unix_fds(message->unix_fds, &message->n_unix_fds);
1229  dbus_free(message->unix_fds);
1230 #endif
1231 
1232  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
1233 
1234  dbus_free (message);
1235 }
1236 
1237 static DBusMessage*
1238 dbus_message_new_empty_header (void)
1239 {
1241  dbus_bool_t from_cache;
1242 
1243  message = dbus_message_get_cached ();
1244 
1245  if (message != NULL)
1246  {
1247  from_cache = TRUE;
1248  }
1249  else
1250  {
1251  from_cache = FALSE;
1252  message = dbus_new0 (DBusMessage, 1);
1253  if (message == NULL)
1254  return NULL;
1255 #ifndef DBUS_DISABLE_CHECKS
1257 #endif
1258 
1259 #ifdef HAVE_UNIX_FD_PASSING
1260  message->unix_fds = NULL;
1261  message->n_unix_fds_allocated = 0;
1262 #endif
1263  }
1264 
1265  _dbus_atomic_inc (&message->refcount);
1266 
1267  _dbus_message_trace_ref (message, 0, 1, "new_empty_header");
1268 
1269  message->locked = FALSE;
1270 #ifndef DBUS_DISABLE_CHECKS
1271  message->in_cache = FALSE;
1272 #endif
1273  message->counters = NULL;
1274  message->size_counter_delta = 0;
1275  message->changed_stamp = 0;
1276 
1277 #ifdef HAVE_UNIX_FD_PASSING
1278  message->n_unix_fds = 0;
1279  message->n_unix_fds_allocated = 0;
1280  message->unix_fd_counter_delta = 0;
1281 #endif
1282 
1283  if (!from_cache)
1285 
1286  if (from_cache)
1287  {
1288  _dbus_header_reinit (&message->header);
1289  _dbus_string_set_length (&message->body, 0);
1290  }
1291  else
1292  {
1293  if (!_dbus_header_init (&message->header))
1294  {
1295  dbus_free (message);
1296  return NULL;
1297  }
1298 
1299  if (!_dbus_string_init_preallocated (&message->body, 32))
1300  {
1301  _dbus_header_free (&message->header);
1302  dbus_free (message);
1303  return NULL;
1304  }
1305  }
1306 
1307  return message;
1308 }
1309 
1322 DBusMessage*
1323 dbus_message_new (int message_type)
1324 {
1326 
1327  _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
1328 
1329  message = dbus_message_new_empty_header ();
1330  if (message == NULL)
1331  return NULL;
1332 
1333  if (!_dbus_header_create (&message->header,
1334  DBUS_COMPILER_BYTE_ORDER,
1335  message_type,
1336  NULL, NULL, NULL, NULL, NULL))
1337  {
1338  dbus_message_unref (message);
1339  return NULL;
1340  }
1341 
1342  return message;
1343 }
1344 
1366 DBusMessage*
1367 dbus_message_new_method_call (const char *destination,
1368  const char *path,
1369  const char *iface,
1370  const char *method)
1371 {
1373 
1374  _dbus_return_val_if_fail (path != NULL, NULL);
1375  _dbus_return_val_if_fail (method != NULL, NULL);
1376  _dbus_return_val_if_fail (destination == NULL ||
1377  _dbus_check_is_valid_bus_name (destination), NULL);
1378  _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
1379  _dbus_return_val_if_fail (iface == NULL ||
1380  _dbus_check_is_valid_interface (iface), NULL);
1381  _dbus_return_val_if_fail (_dbus_check_is_valid_member (method), NULL);
1382 
1383  message = dbus_message_new_empty_header ();
1384  if (message == NULL)
1385  return NULL;
1386 
1387  if (!_dbus_header_create (&message->header,
1388  DBUS_COMPILER_BYTE_ORDER,
1390  destination, path, iface, method, NULL))
1391  {
1392  dbus_message_unref (message);
1393  return NULL;
1394  }
1395 
1396  return message;
1397 }
1398 
1406 DBusMessage*
1408 {
1410  const char *sender;
1411 
1412  _dbus_return_val_if_fail (method_call != NULL, NULL);
1413 
1414  sender = dbus_message_get_sender (method_call);
1415 
1416  /* sender is allowed to be null here in peer-to-peer case */
1417 
1418  message = dbus_message_new_empty_header ();
1419  if (message == NULL)
1420  return NULL;
1421 
1422  if (!_dbus_header_create (&message->header,
1423  DBUS_COMPILER_BYTE_ORDER,
1425  sender, NULL, NULL, NULL, NULL))
1426  {
1427  dbus_message_unref (message);
1428  return NULL;
1429  }
1430 
1431  dbus_message_set_no_reply (message, TRUE);
1432 
1433  if (!dbus_message_set_reply_serial (message,
1434  dbus_message_get_serial (method_call)))
1435  {
1436  dbus_message_unref (message);
1437  return NULL;
1438  }
1439 
1440  return message;
1441 }
1442 
1457 DBusMessage*
1458 dbus_message_new_signal (const char *path,
1459  const char *iface,
1460  const char *name)
1461 {
1463 
1464  _dbus_return_val_if_fail (path != NULL, NULL);
1465  _dbus_return_val_if_fail (iface != NULL, NULL);
1466  _dbus_return_val_if_fail (name != NULL, NULL);
1467  _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
1468  _dbus_return_val_if_fail (_dbus_check_is_valid_interface (iface), NULL);
1469  _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);
1470 
1471  message = dbus_message_new_empty_header ();
1472  if (message == NULL)
1473  return NULL;
1474 
1475  if (!_dbus_header_create (&message->header,
1476  DBUS_COMPILER_BYTE_ORDER,
1478  NULL, path, iface, name, NULL))
1479  {
1480  dbus_message_unref (message);
1481  return NULL;
1482  }
1483 
1484  dbus_message_set_no_reply (message, TRUE);
1485 
1486  return message;
1487 }
1488 
1503 DBusMessage*
1505  const char *error_name,
1506  const char *error_message)
1507 {
1509  const char *sender;
1510  DBusMessageIter iter;
1511 
1512  _dbus_return_val_if_fail (reply_to != NULL, NULL);
1513  _dbus_return_val_if_fail (error_name != NULL, NULL);
1514  _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
1515 
1516  sender = dbus_message_get_sender (reply_to);
1517 
1518  /* sender may be NULL for non-message-bus case or
1519  * when the message bus is dealing with an unregistered
1520  * connection.
1521  */
1522  message = dbus_message_new_empty_header ();
1523  if (message == NULL)
1524  return NULL;
1525 
1526  if (!_dbus_header_create (&message->header,
1527  DBUS_COMPILER_BYTE_ORDER,
1529  sender, NULL, NULL, NULL, error_name))
1530  {
1531  dbus_message_unref (message);
1532  return NULL;
1533  }
1534 
1535  dbus_message_set_no_reply (message, TRUE);
1536 
1537  if (!dbus_message_set_reply_serial (message,
1538  dbus_message_get_serial (reply_to)))
1539  {
1540  dbus_message_unref (message);
1541  return NULL;
1542  }
1543 
1544  if (error_message != NULL)
1545  {
1546  dbus_message_iter_init_append (message, &iter);
1547  if (!dbus_message_iter_append_basic (&iter,
1549  &error_message))
1550  {
1551  dbus_message_unref (message);
1552  return NULL;
1553  }
1554  }
1555 
1556  return message;
1557 }
1558 
1575 DBusMessage*
1577  const char *error_name,
1578  const char *error_format,
1579  ...)
1580 {
1581  va_list args;
1582  DBusString str;
1584 
1585  _dbus_return_val_if_fail (reply_to != NULL, NULL);
1586  _dbus_return_val_if_fail (error_name != NULL, NULL);
1587  _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
1588 
1589  if (!_dbus_string_init (&str))
1590  return NULL;
1591 
1592  va_start (args, error_format);
1593 
1594  if (_dbus_string_append_printf_valist (&str, error_format, args))
1595  message = dbus_message_new_error (reply_to, error_name,
1596  _dbus_string_get_const_data (&str));
1597  else
1598  message = NULL;
1599 
1600  _dbus_string_free (&str);
1601 
1602  va_end (args);
1603 
1604  return message;
1605 }
1606 
1607 
1620 DBusMessage *
1622 {
1623  DBusMessage *retval;
1624 
1625  _dbus_return_val_if_fail (message != NULL, NULL);
1626 
1627  retval = dbus_new0 (DBusMessage, 1);
1628  if (retval == NULL)
1629  return NULL;
1630 
1631  _dbus_atomic_inc (&retval->refcount);
1632 
1633  retval->locked = FALSE;
1634 #ifndef DBUS_DISABLE_CHECKS
1635  retval->generation = message->generation;
1636 #endif
1637 
1638  if (!_dbus_header_copy (&message->header, &retval->header))
1639  {
1640  dbus_free (retval);
1641  return NULL;
1642  }
1643 
1644  if (!_dbus_string_init_preallocated (&retval->body,
1645  _dbus_string_get_length (&message->body)))
1646  {
1647  _dbus_header_free (&retval->header);
1648  dbus_free (retval);
1649  return NULL;
1650  }
1651 
1652  if (!_dbus_string_copy (&message->body, 0,
1653  &retval->body, 0))
1654  goto failed_copy;
1655 
1656 #ifdef HAVE_UNIX_FD_PASSING
1657  retval->unix_fds = dbus_new(int, message->n_unix_fds);
1658  if (retval->unix_fds == NULL && message->n_unix_fds > 0)
1659  goto failed_copy;
1660 
1661  retval->n_unix_fds_allocated = message->n_unix_fds;
1662 
1663  for (retval->n_unix_fds = 0;
1664  retval->n_unix_fds < message->n_unix_fds;
1665  retval->n_unix_fds++)
1666  {
1667  retval->unix_fds[retval->n_unix_fds] = _dbus_dup(message->unix_fds[retval->n_unix_fds], NULL);
1668 
1669  if (retval->unix_fds[retval->n_unix_fds] < 0)
1670  goto failed_copy;
1671  }
1672 
1673 #endif
1674 
1675  _dbus_message_trace_ref (retval, 0, 1, "copy");
1676  return retval;
1677 
1678  failed_copy:
1679  _dbus_header_free (&retval->header);
1680  _dbus_string_free (&retval->body);
1681 
1682 #ifdef HAVE_UNIX_FD_PASSING
1683  close_unix_fds(retval->unix_fds, &retval->n_unix_fds);
1684  dbus_free(retval->unix_fds);
1685 #endif
1686 
1687  dbus_free (retval);
1688 
1689  return NULL;
1690 }
1691 
1692 
1700 DBusMessage *
1702 {
1703  dbus_int32_t old_refcount;
1704 
1705  _dbus_return_val_if_fail (message != NULL, NULL);
1706  _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
1707  _dbus_return_val_if_fail (!message->in_cache, NULL);
1708 
1709  old_refcount = _dbus_atomic_inc (&message->refcount);
1710  _dbus_assert (old_refcount >= 1);
1711  _dbus_message_trace_ref (message, old_refcount, old_refcount + 1, "ref");
1712 
1713  return message;
1714 }
1715 
1723 void
1725 {
1726  dbus_int32_t old_refcount;
1727 
1728  _dbus_return_if_fail (message != NULL);
1729  _dbus_return_if_fail (message->generation == _dbus_current_generation);
1730  _dbus_return_if_fail (!message->in_cache);
1731 
1732  old_refcount = _dbus_atomic_dec (&message->refcount);
1733 
1734  _dbus_assert (old_refcount >= 1);
1735 
1736  _dbus_message_trace_ref (message, old_refcount, old_refcount - 1, "unref");
1737 
1738  if (old_refcount == 1)
1739  {
1740  /* Calls application callbacks! */
1741  dbus_message_cache_or_finalize (message);
1742  }
1743 }
1744 
1755 int
1757 {
1758  _dbus_return_val_if_fail (message != NULL, DBUS_MESSAGE_TYPE_INVALID);
1759 
1760  return _dbus_header_get_message_type (&message->header);
1761 }
1762 
1827  int first_arg_type,
1828  ...)
1829 {
1830  dbus_bool_t retval;
1831  va_list var_args;
1832 
1833  _dbus_return_val_if_fail (message != NULL, FALSE);
1834 
1835  va_start (var_args, first_arg_type);
1836  retval = dbus_message_append_args_valist (message,
1837  first_arg_type,
1838  var_args);
1839  va_end (var_args);
1840 
1841  return retval;
1842 }
1843 
1859  int first_arg_type,
1860  va_list var_args)
1861 {
1862  int type;
1863  DBusMessageIter iter;
1864 
1865  _dbus_return_val_if_fail (message != NULL, FALSE);
1866 
1867  type = first_arg_type;
1868 
1869  dbus_message_iter_init_append (message, &iter);
1870 
1871  while (type != DBUS_TYPE_INVALID)
1872  {
1873  if (dbus_type_is_basic (type))
1874  {
1875  const DBusBasicValue *value;
1876  value = va_arg (var_args, const DBusBasicValue*);
1877 
1878  if (!dbus_message_iter_append_basic (&iter,
1879  type,
1880  value))
1881  goto failed;
1882  }
1883  else if (type == DBUS_TYPE_ARRAY)
1884  {
1885  int element_type;
1886  DBusMessageIter array;
1887  char buf[2];
1888 
1889  element_type = va_arg (var_args, int);
1890 
1891  buf[0] = element_type;
1892  buf[1] = '\0';
1895  buf,
1896  &array))
1897  goto failed;
1898 
1899  if (dbus_type_is_fixed (element_type) &&
1900  element_type != DBUS_TYPE_UNIX_FD)
1901  {
1902  const DBusBasicValue **value;
1903  int n_elements;
1904 
1905  value = va_arg (var_args, const DBusBasicValue**);
1906  n_elements = va_arg (var_args, int);
1907 
1909  element_type,
1910  value,
1911  n_elements)) {
1912  dbus_message_iter_abandon_container (&iter, &array);
1913  goto failed;
1914  }
1915  }
1916  else if (_DBUS_TYPE_IS_STRINGLIKE (element_type))
1917  {
1918  const char ***value_p;
1919  const char **value;
1920  int n_elements;
1921  int i;
1922 
1923  value_p = va_arg (var_args, const char***);
1924  n_elements = va_arg (var_args, int);
1925 
1926  value = *value_p;
1927 
1928  i = 0;
1929  while (i < n_elements)
1930  {
1931  if (!dbus_message_iter_append_basic (&array,
1932  element_type,
1933  &value[i])) {
1934  dbus_message_iter_abandon_container (&iter, &array);
1935  goto failed;
1936  }
1937  ++i;
1938  }
1939  }
1940  else
1941  {
1942  _dbus_warn ("arrays of %s can't be appended with %s for now",
1943  _dbus_type_to_string (element_type),
1944  _DBUS_FUNCTION_NAME);
1945  dbus_message_iter_abandon_container (&iter, &array);
1946  goto failed;
1947  }
1948 
1949  if (!dbus_message_iter_close_container (&iter, &array))
1950  goto failed;
1951  }
1952 #ifndef DBUS_DISABLE_CHECKS
1953  else
1954  {
1955  _dbus_warn ("type %s isn't supported yet in %s",
1956  _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
1957  goto failed;
1958  }
1959 #endif
1960 
1961  type = va_arg (var_args, int);
1962  }
1963 
1964  return TRUE;
1965 
1966  failed:
1967  return FALSE;
1968 }
1969 
2016  DBusError *error,
2017  int first_arg_type,
2018  ...)
2019 {
2020  dbus_bool_t retval;
2021  va_list var_args;
2022 
2023  _dbus_return_val_if_fail (message != NULL, FALSE);
2024  _dbus_return_val_if_error_is_set (error, FALSE);
2025 
2026  va_start (var_args, first_arg_type);
2027  retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
2028  va_end (var_args);
2029 
2030  return retval;
2031 }
2032 
2045  DBusError *error,
2046  int first_arg_type,
2047  va_list var_args)
2048 {
2049  DBusMessageIter iter;
2050 
2051  _dbus_return_val_if_fail (message != NULL, FALSE);
2052  _dbus_return_val_if_error_is_set (error, FALSE);
2053 
2054  dbus_message_iter_init (message, &iter);
2055  return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
2056 }
2057 
2058 static void
2059 _dbus_message_iter_init_common (DBusMessage *message,
2060  DBusMessageRealIter *real,
2061  int iter_type)
2062 {
2063  /* If these static assertions fail on your platform, report it as a bug. */
2064  _DBUS_STATIC_ASSERT (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
2065  _DBUS_STATIC_ASSERT (_DBUS_ALIGNOF (DBusMessageRealIter) <=
2066  _DBUS_ALIGNOF (DBusMessageIter));
2067  /* A failure of these two assertions would indicate that we've broken
2068  * ABI on this platform since 1.10.0. */
2069  _DBUS_STATIC_ASSERT (sizeof (DBusMessageIter_1_10_0) ==
2070  sizeof (DBusMessageIter));
2071  _DBUS_STATIC_ASSERT (_DBUS_ALIGNOF (DBusMessageIter_1_10_0) ==
2072  _DBUS_ALIGNOF (DBusMessageIter));
2073  /* If this static assertion fails, it means the DBusMessageIter struct
2074  * is not "packed", which might result in "iter = other_iter" not copying
2075  * every byte. */
2076  _DBUS_STATIC_ASSERT (sizeof (DBusMessageIter) ==
2077  4 * sizeof (void *) + sizeof (dbus_uint32_t) + 9 * sizeof (int));
2078 
2079  /* Since the iterator will read or write who-knows-what from the
2080  * message, we need to get in the right byte order
2081  */
2082  ensure_byte_order (message);
2083 
2084  real->message = message;
2085  real->changed_stamp = message->changed_stamp;
2086  real->iter_type = iter_type;
2087  real->sig_refcount = 0;
2088 }
2089 
2114  DBusMessageIter *iter)
2115 {
2116  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2117  const DBusString *type_str;
2118  int type_pos;
2119 
2120  _dbus_return_val_if_fail (message != NULL, FALSE);
2121  _dbus_return_val_if_fail (iter != NULL, FALSE);
2122 
2123  get_const_signature (&message->header, &type_str, &type_pos);
2124 
2125  _dbus_message_iter_init_common (message, real,
2126  DBUS_MESSAGE_ITER_TYPE_READER);
2127 
2129  _dbus_header_get_byte_order (&message->header),
2130  type_str, type_pos,
2131  &message->body,
2132  0);
2133 
2135 }
2136 
2145 {
2146  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2147 
2148  _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
2149  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2150 
2151  return _dbus_type_reader_has_next (&real->u.reader);
2152 }
2153 
2164 {
2165  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2166 
2167  _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
2168  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2169 
2170  return _dbus_type_reader_next (&real->u.reader);
2171 }
2172 
2187 int
2189 {
2190  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2191 
2192  _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2193  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2194 
2196 }
2197 
2206 int
2208 {
2209  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2210 
2211  _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2212  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
2213  _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
2214 
2216 }
2217 
2243 void
2245  DBusMessageIter *sub)
2246 {
2247  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2248  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2249 
2250  _dbus_return_if_fail (_dbus_message_iter_check (real));
2251  _dbus_return_if_fail (sub != NULL);
2252 
2253  *real_sub = *real;
2254  _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
2255 }
2256 
2268 char *
2270 {
2271  const DBusString *sig;
2272  DBusString retstr;
2273  char *ret;
2274  int start, len;
2275  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2276 
2277  _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
2278 
2279  if (!_dbus_string_init (&retstr))
2280  return NULL;
2281 
2283  &start, &len);
2284  if (!_dbus_string_append_len (&retstr,
2285  _dbus_string_get_const_data (sig) + start,
2286  len))
2287  return NULL;
2288  if (!_dbus_string_steal_data (&retstr, &ret))
2289  return NULL;
2290  _dbus_string_free (&retstr);
2291  return ret;
2292 }
2293 
2341 void
2343  void *value)
2344 {
2345  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2346 
2347  _dbus_return_if_fail (_dbus_message_iter_check (real));
2348  _dbus_return_if_fail (value != NULL);
2349 
2351  {
2352 #ifdef HAVE_UNIX_FD_PASSING
2353  DBusBasicValue idx;
2354 
2355  _dbus_type_reader_read_basic(&real->u.reader, &idx);
2356 
2357  if (idx.u32 >= real->message->n_unix_fds) {
2358  /* Hmm, we cannot really signal an error here, so let's make
2359  sure to return an invalid fd. */
2360  *((int*) value) = -1;
2361  return;
2362  }
2363 
2364  *((int*) value) = _dbus_dup(real->message->unix_fds[idx.u32], NULL);
2365 #else
2366  *((int*) value) = -1;
2367 #endif
2368  }
2369  else
2370  {
2372  value);
2373  }
2374 }
2375 
2386 int
2388 {
2389  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2390  DBusTypeReader array;
2391  int element_type;
2392  int n_elements = 0;
2393 
2394  _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
2395  _dbus_return_val_if_fail (_dbus_type_reader_get_current_type (&real->u.reader)
2396  == DBUS_TYPE_ARRAY, 0);
2397 
2398  element_type = _dbus_type_reader_get_element_type (&real->u.reader);
2399  _dbus_type_reader_recurse (&real->u.reader, &array);
2400  if (dbus_type_is_fixed (element_type))
2401  {
2402  int alignment = _dbus_type_get_alignment (element_type);
2403  int total_len = _dbus_type_reader_get_array_length (&array);
2404  n_elements = total_len / alignment;
2405  }
2406  else
2407  {
2409  {
2410  ++n_elements;
2411  _dbus_type_reader_next (&array);
2412  }
2413  }
2414 
2415  return n_elements;
2416 }
2417 
2430 int
2432 {
2433  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2434 
2435  _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
2436 
2438 }
2439 
2475 void
2477  void *value,
2478  int *n_elements)
2479 {
2480  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2481 #ifndef DBUS_DISABLE_CHECKS
2482  int subtype = _dbus_type_reader_get_current_type(&real->u.reader);
2483 
2484  _dbus_return_if_fail (_dbus_message_iter_check (real));
2485  _dbus_return_if_fail (value != NULL);
2486  _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) ||
2487  (dbus_type_is_fixed (subtype) && subtype != DBUS_TYPE_UNIX_FD));
2488 #endif
2489 
2491  value, n_elements);
2492 }
2493 
2505 void
2507  DBusMessageIter *iter)
2508 {
2509  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2510 
2511  _dbus_return_if_fail (message != NULL);
2512  _dbus_return_if_fail (iter != NULL);
2513 
2514  _dbus_message_iter_init_common (message, real,
2515  DBUS_MESSAGE_ITER_TYPE_WRITER);
2516 
2517  /* We create the signature string and point iterators at it "on demand"
2518  * when a value is actually appended. That means that init() never fails
2519  * due to OOM.
2520  */
2522  _dbus_header_get_byte_order (&message->header),
2523  &message->body,
2524  _dbus_string_get_length (&message->body));
2525 }
2526 
2535 static dbus_bool_t
2536 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
2537 {
2538  DBusString *str;
2539  const DBusString *current_sig;
2540  int current_sig_pos;
2541 
2542  _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2543 
2544  if (real->u.writer.type_str != NULL)
2545  {
2546  _dbus_assert (real->sig_refcount > 0);
2547  real->sig_refcount += 1;
2548  return TRUE;
2549  }
2550 
2551  str = dbus_new (DBusString, 1);
2552  if (str == NULL)
2553  return FALSE;
2554 
2557  &current_sig, &current_sig_pos))
2558  current_sig = NULL;
2559 
2560  if (current_sig)
2561  {
2562  int current_len;
2563 
2564  current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
2565  current_sig_pos += 1; /* move on to sig data */
2566 
2567  if (!_dbus_string_init_preallocated (str, current_len + 4))
2568  {
2569  dbus_free (str);
2570  return FALSE;
2571  }
2572 
2573  if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
2574  str, 0))
2575  {
2576  _dbus_string_free (str);
2577  dbus_free (str);
2578  return FALSE;
2579  }
2580  }
2581  else
2582  {
2583  if (!_dbus_string_init_preallocated (str, 4))
2584  {
2585  dbus_free (str);
2586  return FALSE;
2587  }
2588  }
2589 
2590  real->sig_refcount = 1;
2591 
2592  /* If this assertion failed, then str would be neither stored in u.writer
2593  * nor freed by this function, resulting in a memory leak. */
2594  _dbus_assert (real->u.writer.type_str == NULL);
2596  str, _dbus_string_get_length (str));
2597  return TRUE;
2598 }
2599 
2609 static dbus_bool_t
2610 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
2611 {
2612  DBusString *str;
2613  const char *v_STRING;
2614  dbus_bool_t retval;
2615 
2616  _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2617  _dbus_assert (real->u.writer.type_str != NULL);
2618  _dbus_assert (real->sig_refcount > 0);
2619 
2620  real->sig_refcount -= 1;
2621 
2622  if (real->sig_refcount > 0)
2623  return TRUE;
2624  _dbus_assert (real->sig_refcount == 0);
2625 
2626  retval = TRUE;
2627 
2628  str = real->u.writer.type_str;
2629 
2630  v_STRING = _dbus_string_get_const_data (str);
2634  &v_STRING))
2635  retval = FALSE;
2636 
2638  _dbus_string_free (str);
2639  dbus_free (str);
2640 
2641  return retval;
2642 }
2643 
2651 static void
2652 _dbus_message_iter_abandon_signature (DBusMessageRealIter *real)
2653 {
2654  DBusString *str;
2655 
2656  _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2657  _dbus_assert (real->u.writer.type_str != NULL);
2658  _dbus_assert (real->sig_refcount > 0);
2659 
2660  real->sig_refcount -= 1;
2661 
2662  if (real->sig_refcount > 0)
2663  return;
2664  _dbus_assert (real->sig_refcount == 0);
2665 
2666  str = real->u.writer.type_str;
2667 
2669  _dbus_string_free (str);
2670  dbus_free (str);
2671 }
2672 
2673 #ifndef DBUS_DISABLE_CHECKS
2674 static dbus_bool_t
2675 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
2676 {
2677  if (!_dbus_message_iter_check (iter))
2678  return FALSE;
2679 
2680  if (iter->message->locked)
2681  {
2682  _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)");
2683  return FALSE;
2684  }
2685 
2686  return TRUE;
2687 }
2688 #endif /* DBUS_DISABLE_CHECKS */
2689 
2690 #ifdef HAVE_UNIX_FD_PASSING
2691 static int *
2692 expand_fd_array(DBusMessage *m,
2693  unsigned n)
2694 {
2695  _dbus_assert(m);
2696 
2697  /* This makes space for adding n new fds to the array and returns a
2698  pointer to the place were the first fd should be put. */
2699 
2700  if (m->n_unix_fds + n > m->n_unix_fds_allocated)
2701  {
2702  unsigned k;
2703  int *p;
2704 
2705  /* Make twice as much space as necessary */
2706  k = (m->n_unix_fds + n) * 2;
2707 
2708  /* Allocate at least four */
2709  if (k < 4)
2710  k = 4;
2711 
2712  p = dbus_realloc(m->unix_fds, k * sizeof(int));
2713  if (p == NULL)
2714  return NULL;
2715 
2716  m->unix_fds = p;
2717  m->n_unix_fds_allocated = k;
2718  }
2719 
2720  return m->unix_fds + m->n_unix_fds;
2721 }
2722 #endif
2723 
2745  int type,
2746  const void *value)
2747 {
2748  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2749  dbus_bool_t ret;
2750 
2751  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2752  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2753  _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
2754  _dbus_return_val_if_fail (value != NULL, FALSE);
2755 
2756 #ifndef DBUS_DISABLE_CHECKS
2757  switch (type)
2758  {
2759  DBusString str;
2760  DBusValidity signature_validity;
2761  const char * const *string_p;
2762  const dbus_bool_t *bool_p;
2763 
2764  case DBUS_TYPE_STRING:
2765  string_p = value;
2766  _dbus_return_val_if_fail (_dbus_check_is_valid_utf8 (*string_p), FALSE);
2767  break;
2768 
2769  case DBUS_TYPE_OBJECT_PATH:
2770  string_p = value;
2771  _dbus_return_val_if_fail (_dbus_check_is_valid_path (*string_p), FALSE);
2772  break;
2773 
2774  case DBUS_TYPE_SIGNATURE:
2775  string_p = value;
2776  _dbus_string_init_const (&str, *string_p);
2777  signature_validity = _dbus_validate_signature_with_reason (&str,
2778  0,
2779  _dbus_string_get_length (&str));
2780 
2781  if (signature_validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
2782  return FALSE;
2783 
2784  _dbus_return_val_if_fail (signature_validity == DBUS_VALID, FALSE);
2785  break;
2786 
2787  case DBUS_TYPE_BOOLEAN:
2788  bool_p = value;
2789  _dbus_return_val_if_fail (*bool_p == 0 || *bool_p == 1, FALSE);
2790  break;
2791 
2792  default:
2793  {
2794  /* nothing to check, all possible values are allowed */
2795  }
2796  }
2797 #endif
2798 
2799  if (!_dbus_message_iter_open_signature (real))
2800  return FALSE;
2801 
2802  if (type == DBUS_TYPE_UNIX_FD)
2803  {
2804 #ifdef HAVE_UNIX_FD_PASSING
2805  int *fds;
2806  dbus_uint32_t u;
2807 
2808  ret = FALSE;
2809 
2810  /* First step, include the fd in the fd list of this message */
2811  if (!(fds = expand_fd_array(real->message, 1)))
2812  goto out;
2813 
2814  *fds = _dbus_dup(*(int*) value, NULL);
2815  if (*fds < 0)
2816  goto out;
2817 
2818  u = real->message->n_unix_fds;
2819 
2820  /* Second step, write the index to the fd */
2821  if (!(ret = _dbus_type_writer_write_basic (&real->u.writer, DBUS_TYPE_UNIX_FD, &u))) {
2822  _dbus_close(*fds, NULL);
2823  goto out;
2824  }
2825 
2826  real->message->n_unix_fds += 1;
2827  u += 1;
2828 
2829  /* Final step, update the header accordingly */
2833  &u);
2834 
2835  /* If any of these operations fail the message is
2836  hosed. However, no memory or fds should be leaked since what
2837  has been added to message has been added to the message, and
2838  can hence be accounted for when the message is being
2839  freed. */
2840 #else
2841  ret = FALSE;
2842  /* This is redundant (we could just fall through), but it avoids
2843  * -Wunused-label in builds that don't HAVE_UNIX_FD_PASSING */
2844  goto out;
2845 #endif
2846  }
2847  else
2848  {
2849  ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
2850  }
2851 
2852 out:
2853  if (!_dbus_message_iter_close_signature (real))
2854  ret = FALSE;
2855 
2856  return ret;
2857 }
2858 
2896  int element_type,
2897  const void *value,
2898  int n_elements)
2899 {
2900  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2901  dbus_bool_t ret;
2902 
2903  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2904  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2905  _dbus_return_val_if_fail (dbus_type_is_fixed (element_type) && element_type != DBUS_TYPE_UNIX_FD, FALSE);
2906  _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
2907  _dbus_return_val_if_fail (value != NULL, FALSE);
2908  _dbus_return_val_if_fail (n_elements >= 0, FALSE);
2909  _dbus_return_val_if_fail (n_elements <=
2911  FALSE);
2912 
2913 #ifndef DBUS_DISABLE_CHECKS
2914  if (element_type == DBUS_TYPE_BOOLEAN)
2915  {
2916  const dbus_bool_t * const *bools = value;
2917  int i;
2918 
2919  for (i = 0; i < n_elements; i++)
2920  {
2921  _dbus_return_val_if_fail ((*bools)[i] == 0 || (*bools)[i] == 1, FALSE);
2922  }
2923  }
2924 #endif
2925 
2926  ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
2927 
2928  return ret;
2929 }
2930 
2960  int type,
2961  const char *contained_signature,
2962  DBusMessageIter *sub)
2963 {
2964  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2965  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2966  DBusString contained_str;
2967  DBusValidity contained_signature_validity;
2968  dbus_bool_t ret;
2969 
2970  _dbus_return_val_if_fail (sub != NULL, FALSE);
2971  /* Do our best to make sure the sub-iterator doesn't contain something
2972  * valid-looking on failure */
2973  _dbus_message_real_iter_zero (real_sub);
2974 
2975  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2976  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2977  _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
2978  _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
2979  contained_signature == NULL) ||
2980  (type == DBUS_TYPE_DICT_ENTRY &&
2981  contained_signature == NULL) ||
2982  (type == DBUS_TYPE_VARIANT &&
2983  contained_signature != NULL) ||
2984  (type == DBUS_TYPE_ARRAY &&
2985  contained_signature != NULL), FALSE);
2986 
2987  /* this would fail if the contained_signature is a dict entry, since
2988  * dict entries are invalid signatures standalone (they must be in
2989  * an array)
2990  */
2991  if (contained_signature != NULL)
2992  {
2993  _dbus_string_init_const (&contained_str, contained_signature);
2994  contained_signature_validity = _dbus_validate_signature_with_reason (&contained_str,
2995  0,
2996  _dbus_string_get_length (&contained_str));
2997 
2998  if (contained_signature_validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
2999  return FALSE;
3000  }
3001  else
3002  {
3003  /* just some placeholder value */
3004  contained_signature_validity = DBUS_VALID_BUT_INCOMPLETE;
3005  }
3006 
3007  _dbus_return_val_if_fail ((type == DBUS_TYPE_ARRAY && contained_signature && *contained_signature == DBUS_DICT_ENTRY_BEGIN_CHAR) ||
3008  contained_signature == NULL ||
3009  contained_signature_validity == DBUS_VALID,
3010  FALSE);
3011 
3012  if (!_dbus_message_iter_open_signature (real))
3013  return FALSE;
3014 
3015  ret = FALSE;
3016  *real_sub = *real;
3017 
3018  if (contained_signature != NULL)
3019  {
3020  _dbus_string_init_const (&contained_str, contained_signature);
3021 
3022  ret = _dbus_type_writer_recurse (&real->u.writer,
3023  type,
3024  &contained_str, 0,
3025  &real_sub->u.writer);
3026  }
3027  else
3028  {
3029  ret = _dbus_type_writer_recurse (&real->u.writer,
3030  type,
3031  NULL, 0,
3032  &real_sub->u.writer);
3033  }
3034 
3035  if (!ret)
3036  _dbus_message_iter_abandon_signature (real);
3037 
3038  return ret;
3039 }
3040 
3041 
3063  DBusMessageIter *sub)
3064 {
3065  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3066  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
3067  dbus_bool_t ret;
3068 
3069  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
3070  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
3071  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
3072  _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
3073 
3074  ret = _dbus_type_writer_unrecurse (&real->u.writer,
3075  &real_sub->u.writer);
3076  _dbus_message_real_iter_zero (real_sub);
3077 
3078  if (!_dbus_message_iter_close_signature (real))
3079  ret = FALSE;
3080 
3081  return ret;
3082 }
3083 
3095 void
3097  DBusMessageIter *sub)
3098 {
3099  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3100  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
3101 
3102 #ifndef DBUS_DISABLE_CHECKS
3103  _dbus_return_if_fail (_dbus_message_iter_append_check (real));
3104  _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
3105  _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
3106  _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
3107 #endif
3108 
3109  _dbus_message_iter_abandon_signature (real);
3110  _dbus_message_real_iter_zero (real_sub);
3111 }
3112 
3154 void
3156  DBusMessageIter *sub)
3157 {
3158  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3159  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
3160 
3161  /* If both the parent and the child are zeroed out, then either we didn't
3162  * even get as far as successfully recursing into the parent, or we already
3163  * closed both the child and the parent. For example, in the code sample
3164  * in the doc-comment above, this happens for
3165  * abandon_container_if_open (&outer, &inner) if the first open_container
3166  * call failed, or if we reached result = TRUE and fell through. */
3167  if (_dbus_message_real_iter_is_zeroed (real) &&
3168  _dbus_message_real_iter_is_zeroed (real_sub))
3169  return;
3170 
3171 #ifndef DBUS_DISABLE_CHECKS
3172  /* If the child is not zeroed out, but the parent is, then something has
3173  * gone horribly wrong (in practice that would probably mean both are
3174  * uninitialized or corrupt, and the parent happens to have ended up
3175  * all-bytes-zero). */
3176  _dbus_return_if_fail (_dbus_message_iter_append_check (real));
3177  _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
3178 #endif
3179 
3180  /* If the parent is not zeroed out, but the child is, then either we did
3181  * not successfully open the child, or we already closed the child. This
3182  * means we do not own a reference to the parent's signature, so it would
3183  * be wrong to release it; so we must not call abandon_signature() here.
3184  * In the code sample in the doc-comment above, this happens for
3185  * abandon_container_if_open (&outer, &inner) if the second open_container
3186  * call failed, or if the second close_container call failed. */
3187  if (_dbus_message_real_iter_is_zeroed (real_sub))
3188  return;
3189 
3190 #ifndef DBUS_DISABLE_CHECKS
3191  _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
3192  _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
3193 #endif
3194 
3195  /* If neither the parent nor the child is zeroed out, then we genuinely
3196  * have an open container; close it. In the code sample in the doc-comment,
3197  * this happens for abandon_container_if_open (&outer, &inner) if the
3198  * append_basic call failed. */
3199  _dbus_message_iter_abandon_signature (real);
3200  _dbus_message_real_iter_zero (real_sub);
3201 }
3202 
3219 void
3221  dbus_bool_t no_reply)
3222 {
3223  _dbus_return_if_fail (message != NULL);
3224  _dbus_return_if_fail (!message->locked);
3225 
3226  _dbus_header_toggle_flag (&message->header,
3228  no_reply);
3229 }
3230 
3240 {
3241  _dbus_return_val_if_fail (message != NULL, FALSE);
3242 
3243  return _dbus_header_get_flag (&message->header,
3245 }
3246 
3261 void
3263  dbus_bool_t auto_start)
3264 {
3265  _dbus_return_if_fail (message != NULL);
3266  _dbus_return_if_fail (!message->locked);
3267 
3268  _dbus_header_toggle_flag (&message->header,
3270  !auto_start);
3271 }
3272 
3282 {
3283  _dbus_return_val_if_fail (message != NULL, FALSE);
3284 
3285  return !_dbus_header_get_flag (&message->header,
3287 }
3288 
3289 
3304  const char *object_path)
3305 {
3306  _dbus_return_val_if_fail (message != NULL, FALSE);
3307  _dbus_return_val_if_fail (!message->locked, FALSE);
3308  _dbus_return_val_if_fail (object_path == NULL ||
3309  _dbus_check_is_valid_path (object_path),
3310  FALSE);
3311 
3312  return set_or_delete_string_field (message,
3315  object_path);
3316 }
3317 
3331 const char*
3333 {
3334  const char *v;
3335 
3336  _dbus_return_val_if_fail (message != NULL, NULL);
3337 
3338  v = NULL; /* in case field doesn't exist */
3342  (void *) &v);
3343  return v;
3344 }
3345 
3357  const char *path)
3358 {
3359  const char *msg_path;
3360  msg_path = dbus_message_get_path (message);
3361 
3362  if (msg_path == NULL)
3363  {
3364  if (path == NULL)
3365  return TRUE;
3366  else
3367  return FALSE;
3368  }
3369 
3370  if (path == NULL)
3371  return FALSE;
3372 
3373  if (strcmp (msg_path, path) == 0)
3374  return TRUE;
3375 
3376  return FALSE;
3377 }
3378 
3401  char ***path)
3402 {
3403  const char *v;
3404 
3405  _dbus_return_val_if_fail (message != NULL, FALSE);
3406  _dbus_return_val_if_fail (path != NULL, FALSE);
3407 
3408  *path = NULL;
3409 
3410  v = dbus_message_get_path (message);
3411  if (v != NULL)
3412  {
3413  if (!_dbus_decompose_path (v, strlen (v),
3414  path, NULL))
3415  return FALSE;
3416  }
3417  return TRUE;
3418 }
3419 
3435  const char *iface)
3436 {
3437  _dbus_return_val_if_fail (message != NULL, FALSE);
3438  _dbus_return_val_if_fail (!message->locked, FALSE);
3439  _dbus_return_val_if_fail (iface == NULL ||
3440  _dbus_check_is_valid_interface (iface),
3441  FALSE);
3442 
3443  return set_or_delete_string_field (message,
3446  iface);
3447 }
3448 
3462 const char*
3464 {
3465  const char *v;
3466 
3467  _dbus_return_val_if_fail (message != NULL, NULL);
3468 
3469  v = NULL; /* in case field doesn't exist */
3473  (void *) &v);
3474  return v;
3475 }
3476 
3486  const char *iface)
3487 {
3488  const char *msg_interface;
3489  msg_interface = dbus_message_get_interface (message);
3490 
3491  if (msg_interface == NULL)
3492  {
3493  if (iface == NULL)
3494  return TRUE;
3495  else
3496  return FALSE;
3497  }
3498 
3499  if (iface == NULL)
3500  return FALSE;
3501 
3502  if (strcmp (msg_interface, iface) == 0)
3503  return TRUE;
3504 
3505  return FALSE;
3506 
3507 }
3508 
3523  const char *member)
3524 {
3525  _dbus_return_val_if_fail (message != NULL, FALSE);
3526  _dbus_return_val_if_fail (!message->locked, FALSE);
3527  _dbus_return_val_if_fail (member == NULL ||
3528  _dbus_check_is_valid_member (member),
3529  FALSE);
3530 
3531  return set_or_delete_string_field (message,
3534  member);
3535 }
3536 
3548 const char*
3550 {
3551  const char *v;
3552 
3553  _dbus_return_val_if_fail (message != NULL, NULL);
3554 
3555  v = NULL; /* in case field doesn't exist */
3559  (void *) &v);
3560  return v;
3561 }
3562 
3572  const char *member)
3573 {
3574  const char *msg_member;
3575  msg_member = dbus_message_get_member (message);
3576 
3577  if (msg_member == NULL)
3578  {
3579  if (member == NULL)
3580  return TRUE;
3581  else
3582  return FALSE;
3583  }
3584 
3585  if (member == NULL)
3586  return FALSE;
3587 
3588  if (strcmp (msg_member, member) == 0)
3589  return TRUE;
3590 
3591  return FALSE;
3592 
3593 }
3594 
3608  const char *error_name)
3609 {
3610  _dbus_return_val_if_fail (message != NULL, FALSE);
3611  _dbus_return_val_if_fail (!message->locked, FALSE);
3612  _dbus_return_val_if_fail (error_name == NULL ||
3613  _dbus_check_is_valid_error_name (error_name),
3614  FALSE);
3615 
3616  return set_or_delete_string_field (message,
3619  error_name);
3620 }
3621 
3632 const char*
3634 {
3635  const char *v;
3636 
3637  _dbus_return_val_if_fail (message != NULL, NULL);
3638 
3639  v = NULL; /* in case field doesn't exist */
3643  (void *) &v);
3644  return v;
3645 }
3646 
3662  const char *destination)
3663 {
3664  _dbus_return_val_if_fail (message != NULL, FALSE);
3665  _dbus_return_val_if_fail (!message->locked, FALSE);
3666  _dbus_return_val_if_fail (destination == NULL ||
3667  _dbus_check_is_valid_bus_name (destination),
3668  FALSE);
3669 
3670  return set_or_delete_string_field (message,
3673  destination);
3674 }
3675 
3685 const char*
3687 {
3688  const char *v;
3689 
3690  _dbus_return_val_if_fail (message != NULL, NULL);
3691 
3692  v = NULL; /* in case field doesn't exist */
3696  (void *) &v);
3697  return v;
3698 }
3699 
3716  const char *sender)
3717 {
3718  _dbus_return_val_if_fail (message != NULL, FALSE);
3719  _dbus_return_val_if_fail (!message->locked, FALSE);
3720  _dbus_return_val_if_fail (sender == NULL ||
3721  _dbus_check_is_valid_bus_name (sender),
3722  FALSE);
3723 
3724  return set_or_delete_string_field (message,
3727  sender);
3728 }
3729 
3745 const char*
3747 {
3748  const char *v;
3749 
3750  _dbus_return_val_if_fail (message != NULL, NULL);
3751 
3752  v = NULL; /* in case field doesn't exist */
3756  (void *) &v);
3757  return v;
3758 }
3759 
3778 const char*
3780 {
3781  const DBusString *type_str;
3782  int type_pos;
3783 
3784  _dbus_return_val_if_fail (message != NULL, NULL);
3785 
3786  get_const_signature (&message->header, &type_str, &type_pos);
3787 
3788  return _dbus_string_get_const_data_len (type_str, type_pos, 0);
3789 }
3790 
3791 static dbus_bool_t
3792 _dbus_message_has_type_interface_member (DBusMessage *message,
3793  int type,
3794  const char *iface,
3795  const char *member)
3796 {
3797  const char *n;
3798 
3799  _dbus_assert (message != NULL);
3800  _dbus_assert (iface != NULL);
3801  _dbus_assert (member != NULL);
3802 
3803  if (dbus_message_get_type (message) != type)
3804  return FALSE;
3805 
3806  /* Optimize by checking the short member name first
3807  * instead of the longer interface name
3808  */
3809 
3810  n = dbus_message_get_member (message);
3811 
3812  if (n && strcmp (n, member) == 0)
3813  {
3814  n = dbus_message_get_interface (message);
3815 
3816  if (n == NULL || strcmp (n, iface) == 0)
3817  return TRUE;
3818  }
3819 
3820  return FALSE;
3821 }
3822 
3839  const char *iface,
3840  const char *method)
3841 {
3842  _dbus_return_val_if_fail (message != NULL, FALSE);
3843  _dbus_return_val_if_fail (iface != NULL, FALSE);
3844  _dbus_return_val_if_fail (method != NULL, FALSE);
3845  /* don't check that interface/method are valid since it would be
3846  * expensive, and not catch many common errors
3847  */
3848 
3849  return _dbus_message_has_type_interface_member (message,
3851  iface, method);
3852 }
3853 
3867  const char *iface,
3868  const char *signal_name)
3869 {
3870  _dbus_return_val_if_fail (message != NULL, FALSE);
3871  _dbus_return_val_if_fail (iface != NULL, FALSE);
3872  _dbus_return_val_if_fail (signal_name != NULL, FALSE);
3873  /* don't check that interface/name are valid since it would be
3874  * expensive, and not catch many common errors
3875  */
3876 
3877  return _dbus_message_has_type_interface_member (message,
3879  iface, signal_name);
3880 }
3881 
3894  const char *error_name)
3895 {
3896  const char *n;
3897 
3898  _dbus_return_val_if_fail (message != NULL, FALSE);
3899  _dbus_return_val_if_fail (error_name != NULL, FALSE);
3900  /* don't check that error_name is valid since it would be expensive,
3901  * and not catch many common errors
3902  */
3903 
3905  return FALSE;
3906 
3907  n = dbus_message_get_error_name (message);
3908 
3909  if (n && strcmp (n, error_name) == 0)
3910  return TRUE;
3911  else
3912  return FALSE;
3913 }
3914 
3927  const char *name)
3928 {
3929  const char *s;
3930 
3931  _dbus_return_val_if_fail (message != NULL, FALSE);
3932  _dbus_return_val_if_fail (name != NULL, FALSE);
3933  /* don't check that name is valid since it would be expensive, and
3934  * not catch many common errors
3935  */
3936 
3937  s = dbus_message_get_destination (message);
3938 
3939  if (s && strcmp (s, name) == 0)
3940  return TRUE;
3941  else
3942  return FALSE;
3943 }
3944 
3962  const char *name)
3963 {
3964  const char *s;
3965 
3966  _dbus_return_val_if_fail (message != NULL, FALSE);
3967  _dbus_return_val_if_fail (name != NULL, FALSE);
3968  /* don't check that name is valid since it would be expensive, and
3969  * not catch many common errors
3970  */
3971 
3972  s = dbus_message_get_sender (message);
3973 
3974  if (s && strcmp (s, name) == 0)
3975  return TRUE;
3976  else
3977  return FALSE;
3978 }
3979 
3991  const char *signature)
3992 {
3993  const char *s;
3994 
3995  _dbus_return_val_if_fail (message != NULL, FALSE);
3996  _dbus_return_val_if_fail (signature != NULL, FALSE);
3997  /* don't check that signature is valid since it would be expensive,
3998  * and not catch many common errors
3999  */
4000 
4001  s = dbus_message_get_signature (message);
4002 
4003  if (s && strcmp (s, signature) == 0)
4004  return TRUE;
4005  else
4006  return FALSE;
4007 }
4008 
4033  DBusMessage *message)
4034 {
4035  const char *str;
4036 
4037  _dbus_return_val_if_fail (message != NULL, FALSE);
4038  _dbus_return_val_if_error_is_set (error, FALSE);
4039 
4041  return FALSE;
4042 
4043  str = NULL;
4044  dbus_message_get_args (message, NULL,
4045  DBUS_TYPE_STRING, &str,
4047 
4048  dbus_set_error (error, dbus_message_get_error_name (message),
4049  str ? "%s" : NULL, str);
4050 
4051  return TRUE;
4052 }
4053 
4062 {
4063 #ifdef HAVE_UNIX_FD_PASSING
4064  _dbus_assert(message);
4065 
4066  return message->n_unix_fds > 0;
4067 #else
4068  return FALSE;
4069 #endif
4070 }
4071 
4084  const char *object_path)
4085 {
4086  _dbus_return_val_if_fail (message != NULL, FALSE);
4087  _dbus_return_val_if_fail (!message->locked, FALSE);
4088  _dbus_return_val_if_fail (object_path == NULL ||
4089  _dbus_check_is_valid_path (object_path),
4090  FALSE);
4091 
4092  return set_or_delete_string_field (message,
4095  object_path);
4096 }
4097 
4108 const char *
4110 {
4111  const char *v;
4112 
4113  _dbus_return_val_if_fail (message != NULL, NULL);
4114 
4115  v = NULL; /* in case field doesn't exist */
4119  (void *) &v);
4120  return v;
4121 }
4122 
4141 #define INITIAL_LOADER_DATA_LEN 32
4142 
4151 {
4152  DBusMessageLoader *loader;
4153 
4154  loader = dbus_new0 (DBusMessageLoader, 1);
4155  if (loader == NULL)
4156  return NULL;
4157 
4158  loader->refcount = 1;
4159 
4160  loader->corrupted = FALSE;
4161  loader->corruption_reason = DBUS_VALID;
4162 
4163  /* this can be configured by the app, but defaults to the protocol max */
4165 
4166  /* We set a very relatively conservative default here since due to how
4167  SCM_RIGHTS works we need to preallocate an fd array of the maximum
4168  number of unix fds we want to receive in advance. A
4169  try-and-reallocate loop is not possible. */
4170  loader->max_message_unix_fds = DBUS_DEFAULT_MESSAGE_UNIX_FDS;
4171 
4172  if (!_dbus_string_init (&loader->data))
4173  {
4174  dbus_free (loader);
4175  return NULL;
4176  }
4177 
4178  /* preallocate the buffer for speed, ignore failure */
4180  _dbus_string_set_length (&loader->data, 0);
4181 
4182 #ifdef HAVE_UNIX_FD_PASSING
4183  loader->unix_fds = NULL;
4184  loader->n_unix_fds = loader->n_unix_fds_allocated = 0;
4185  loader->unix_fds_outstanding = FALSE;
4186 #endif
4187 
4188  return loader;
4189 }
4190 
4199 {
4200  loader->refcount += 1;
4201 
4202  return loader;
4203 }
4204 
4211 void
4213 {
4214  loader->refcount -= 1;
4215  if (loader->refcount == 0)
4216  {
4217 #ifdef HAVE_UNIX_FD_PASSING
4218  close_unix_fds(loader->unix_fds, &loader->n_unix_fds);
4219  dbus_free(loader->unix_fds);
4220 #endif
4221  _dbus_list_clear_full (&loader->messages,
4223  _dbus_string_free (&loader->data);
4224  dbus_free (loader);
4225  }
4226 }
4227 
4246 void
4248  DBusString **buffer,
4249  int *max_to_read,
4250  dbus_bool_t *may_read_fds)
4251 {
4252  _dbus_assert (!loader->buffer_outstanding);
4253 
4254  *buffer = &loader->data;
4255 
4256  loader->buffer_outstanding = TRUE;
4257 
4258  if (max_to_read != NULL)
4259  {
4260 #ifdef HAVE_UNIX_FD_PASSING
4261  int offset = 0;
4262  int remain;
4263  int byte_order;
4264  int fields_array_len;
4265  int header_len;
4266  int body_len;
4267 #endif
4268 
4269  *max_to_read = DBUS_MAXIMUM_MESSAGE_LENGTH;
4270  *may_read_fds = TRUE;
4271 
4272 #ifdef HAVE_UNIX_FD_PASSING
4273  /* If we aren't holding onto any fds, we can read as much as we want
4274  * (fast path). */
4275  if (loader->n_unix_fds == 0)
4276  return;
4277 
4278  /* Slow path: we have a message with some fds in it. We don't want
4279  * to start on the next message until this one is out of the way;
4280  * otherwise a legitimate sender can keep us processing messages
4281  * containing fds, until we disconnect it for having had fds pending
4282  * for too long, a limit that is in place to stop malicious senders
4283  * from setting up recursive fd-passing that takes up our quota and
4284  * will never go away. */
4285 
4286  remain = _dbus_string_get_length (&loader->data);
4287 
4288  while (remain > 0)
4289  {
4290  DBusValidity validity = DBUS_VALIDITY_UNKNOWN;
4291  int needed;
4292 
4293  /* If 0 < remain < DBUS_MINIMUM_HEADER_SIZE, then we've had at
4294  * least the first byte of a message, but we don't know how
4295  * much more to read. Only read the rest of the
4296  * DBUS_MINIMUM_HEADER_SIZE for now; then we'll know. */
4297  if (remain < DBUS_MINIMUM_HEADER_SIZE)
4298  {
4299  *max_to_read = DBUS_MINIMUM_HEADER_SIZE - remain;
4300  *may_read_fds = FALSE;
4301  return;
4302  }
4303 
4305  &validity,
4306  &byte_order,
4307  &fields_array_len,
4308  &header_len,
4309  &body_len,
4310  &loader->data,
4311  offset,
4312  remain))
4313  {
4314  /* If a message in the buffer is invalid, we're going to
4315  * disconnect the sender anyway, so reading an arbitrary amount
4316  * is fine. */
4317  if (validity != DBUS_VALID)
4318  return;
4319 
4320  /* We have a partial message, with the
4321  * DBUS_MINIMUM_HEADER_SIZE-byte fixed part of the header (which
4322  * lets us work out how much more we need), but no more. Read
4323  * the rest of the message. */
4324  needed = header_len + body_len;
4325  _dbus_assert (needed > remain);
4326  *max_to_read = needed - remain;
4327  *may_read_fds = FALSE;
4328  return;
4329  }
4330 
4331  /* Skip over entire messages until we have less than a message
4332  * remaining. */
4333  needed = header_len + body_len;
4335  _dbus_assert (remain >= needed);
4336  remain -= needed;
4337  offset += needed;
4338  }
4339 #endif
4340  }
4341 }
4342 
4352 void
4354  DBusString *buffer)
4355 {
4356  _dbus_assert (loader->buffer_outstanding);
4357  _dbus_assert (buffer == &loader->data);
4358 
4359  loader->buffer_outstanding = FALSE;
4360 }
4361 
4362 #ifdef HAVE_UNIX_FD_PASSING
4363 
4374 _dbus_message_loader_get_unix_fds(DBusMessageLoader *loader,
4375  int **fds,
4376  unsigned *max_n_fds)
4377 {
4378  _dbus_assert (!loader->unix_fds_outstanding);
4379 
4380  /* Allocate space where we can put the fds we read. We allocate
4381  space for max_message_unix_fds since this is an
4382  upper limit how many fds can be received within a single
4383  message. Since SCM_RIGHTS doesn't allow a reallocate+retry logic
4384  we are allocating the maximum possible array size right from the
4385  beginning. This sucks a bit, however unless SCM_RIGHTS is fixed
4386  there is no better way. */
4387 
4388  if (loader->n_unix_fds_allocated < loader->max_message_unix_fds)
4389  {
4390  int *a = dbus_realloc(loader->unix_fds,
4391  loader->max_message_unix_fds * sizeof(loader->unix_fds[0]));
4392 
4393  if (!a)
4394  return FALSE;
4395 
4396  loader->unix_fds = a;
4397  loader->n_unix_fds_allocated = loader->max_message_unix_fds;
4398  }
4399 
4400  *fds = loader->unix_fds + loader->n_unix_fds;
4401  *max_n_fds = loader->n_unix_fds_allocated - loader->n_unix_fds;
4402 
4403  loader->unix_fds_outstanding = TRUE;
4404  return TRUE;
4405 }
4406 
4417 void
4418 _dbus_message_loader_return_unix_fds(DBusMessageLoader *loader,
4419  int *fds,
4420  unsigned n_fds)
4421 {
4422  _dbus_assert(loader->unix_fds_outstanding);
4423  _dbus_assert(loader->unix_fds + loader->n_unix_fds == fds);
4424  _dbus_assert(loader->n_unix_fds + n_fds <= loader->n_unix_fds_allocated);
4425 
4426  loader->n_unix_fds += n_fds;
4427  loader->unix_fds_outstanding = FALSE;
4428 
4429  if (n_fds && loader->unix_fds_change)
4430  loader->unix_fds_change (loader->unix_fds_change_data);
4431 }
4432 #endif
4433 
4434 /*
4435  * FIXME when we move the header out of the buffer, that memmoves all
4436  * buffered messages. Kind of crappy.
4437  *
4438  * Also we copy the header and body, which is kind of crappy. To
4439  * avoid this, we have to allow header and body to be in a single
4440  * memory block, which is good for messages we read and bad for
4441  * messages we are creating. But we could move_len() the buffer into
4442  * this single memory block, and move_len() will just swap the buffers
4443  * if you're moving the entire buffer replacing the dest string.
4444  *
4445  * We could also have the message loader tell the transport how many
4446  * bytes to read; so it would first ask for some arbitrary number like
4447  * 256, then if the message was incomplete it would use the
4448  * header/body len to ask for exactly the size of the message (or
4449  * blocks the size of a typical kernel buffer for the socket). That
4450  * way we don't get trailing bytes in the buffer that have to be
4451  * memmoved. Though I suppose we also don't have a chance of reading a
4452  * bunch of small messages at once, so the optimization may be stupid.
4453  *
4454  * Another approach would be to keep a "start" index into
4455  * loader->data and only delete it occasionally, instead of after
4456  * each message is loaded.
4457  *
4458  * load_message() returns FALSE if not enough memory OR the loader was corrupted
4459  */
4460 static dbus_bool_t
4461 load_message (DBusMessageLoader *loader,
4462  DBusMessage *message,
4463  int byte_order,
4464  int fields_array_len,
4465  int header_len,
4466  int body_len)
4467 {
4468  dbus_bool_t oom;
4469  DBusValidity validity;
4470  const DBusString *type_str;
4471  int type_pos;
4472  DBusValidationMode mode;
4473  dbus_uint32_t n_unix_fds = 0;
4474 
4475  mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
4476 
4477  oom = FALSE;
4478 
4479 #if 0
4480  _dbus_verbose_bytes_of_string (&loader->data, 0, header_len /* + body_len */);
4481 #endif
4482 
4483  /* 1. VALIDATE AND COPY OVER HEADER */
4484  _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
4485  _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
4486 
4487  if (!_dbus_header_load (&message->header,
4488  mode,
4489  &validity,
4490  byte_order,
4491  fields_array_len,
4492  header_len,
4493  body_len,
4494  &loader->data))
4495  {
4496  _dbus_verbose ("Failed to load header for new message code %d\n", validity);
4497 
4498  /* assert here so we can catch any code that still uses DBUS_VALID to indicate
4499  oom errors. They should use DBUS_VALIDITY_UNKNOWN_OOM_ERROR instead */
4500  _dbus_assert (validity != DBUS_VALID);
4501 
4502  if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
4503  oom = TRUE;
4504  else
4505  {
4506  loader->corrupted = TRUE;
4507  loader->corruption_reason = validity;
4508  }
4509  goto failed;
4510  }
4511 
4512  _dbus_assert (validity == DBUS_VALID);
4513 
4514  /* 2. VALIDATE BODY */
4515  if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
4516  {
4517  get_const_signature (&message->header, &type_str, &type_pos);
4518 
4519  /* Because the bytes_remaining arg is NULL, this validates that the
4520  * body is the right length
4521  */
4522  validity = _dbus_validate_body_with_reason (type_str,
4523  type_pos,
4524  byte_order,
4525  NULL,
4526  &loader->data,
4527  header_len,
4528  body_len);
4529  if (validity != DBUS_VALID)
4530  {
4531  _dbus_verbose ("Failed to validate message body code %d\n", validity);
4532 
4533  loader->corrupted = TRUE;
4534  loader->corruption_reason = validity;
4535 
4536  goto failed;
4537  }
4538  }
4539 
4540  /* 3. COPY OVER UNIX FDS */
4544  &n_unix_fds);
4545 
4546 #ifdef HAVE_UNIX_FD_PASSING
4547 
4548  if (n_unix_fds > loader->n_unix_fds)
4549  {
4550  _dbus_verbose("Message contains references to more unix fds than were sent %u != %u\n",
4551  n_unix_fds, loader->n_unix_fds);
4552 
4553  loader->corrupted = TRUE;
4554  loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4555  goto failed;
4556  }
4557 
4558  /* If this was a recycled message there might still be
4559  some memory allocated for the fds */
4560  dbus_free(message->unix_fds);
4561 
4562  if (n_unix_fds > 0)
4563  {
4564  message->unix_fds = _dbus_memdup(loader->unix_fds, n_unix_fds * sizeof(message->unix_fds[0]));
4565  if (message->unix_fds == NULL)
4566  {
4567  _dbus_verbose ("Failed to allocate file descriptor array\n");
4568  oom = TRUE;
4569  goto failed;
4570  }
4571 
4572  message->n_unix_fds_allocated = message->n_unix_fds = n_unix_fds;
4573  loader->n_unix_fds -= n_unix_fds;
4574  memmove (loader->unix_fds, loader->unix_fds + n_unix_fds, loader->n_unix_fds * sizeof (loader->unix_fds[0]));
4575 
4576  if (loader->unix_fds_change)
4577  loader->unix_fds_change (loader->unix_fds_change_data);
4578  }
4579  else
4580  message->unix_fds = NULL;
4581 
4582 #else
4583 
4584  if (n_unix_fds > 0)
4585  {
4586  _dbus_verbose ("Hmm, message claims to come with file descriptors "
4587  "but that's not supported on our platform, disconnecting.\n");
4588 
4589  loader->corrupted = TRUE;
4590  loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4591  goto failed;
4592  }
4593 
4594 #endif
4595 
4596  /* 3. COPY OVER BODY AND QUEUE MESSAGE */
4597 
4598  if (!_dbus_list_append (&loader->messages, message))
4599  {
4600  _dbus_verbose ("Failed to append new message to loader queue\n");
4601  oom = TRUE;
4602  goto failed;
4603  }
4604 
4605  _dbus_assert (_dbus_string_get_length (&message->body) == 0);
4606  _dbus_assert (_dbus_string_get_length (&loader->data) >=
4607  (header_len + body_len));
4608 
4609  if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
4610  {
4611  _dbus_verbose ("Failed to move body into new message\n");
4612  oom = TRUE;
4613  goto failed;
4614  }
4615 
4616  _dbus_string_delete (&loader->data, 0, header_len + body_len);
4617 
4618  /* don't waste more than 2k of memory */
4619  _dbus_string_compact (&loader->data, 2048);
4620 
4621  _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
4622  _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
4623 
4624  _dbus_verbose ("Loaded message %p\n", message);
4625 
4626  _dbus_assert (!oom);
4627  _dbus_assert (!loader->corrupted);
4628  _dbus_assert (loader->messages != NULL);
4629  _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4630 
4631  return TRUE;
4632 
4633  failed:
4634 
4635  /* Clean up */
4636 
4637  /* does nothing if the message isn't in the list */
4638  _dbus_list_remove_last (&loader->messages, message);
4639 
4640  if (oom)
4641  _dbus_assert (!loader->corrupted);
4642  else
4643  _dbus_assert (loader->corrupted);
4644 
4645  _dbus_verbose_bytes_of_string (&loader->data, 0, _dbus_string_get_length (&loader->data));
4646 
4647  return FALSE;
4648 }
4649 
4666 {
4667  while (!loader->corrupted &&
4668  _dbus_string_get_length (&loader->data) >= DBUS_MINIMUM_HEADER_SIZE)
4669  {
4670  DBusValidity validity;
4671  int byte_order, fields_array_len, header_len, body_len;
4672 
4674  &validity,
4675  &byte_order,
4676  &fields_array_len,
4677  &header_len,
4678  &body_len,
4679  &loader->data, 0,
4680  _dbus_string_get_length (&loader->data)))
4681  {
4683 
4684  _dbus_assert (validity == DBUS_VALID);
4685 
4686  message = dbus_message_new_empty_header ();
4687  if (message == NULL)
4688  return FALSE;
4689 
4690  if (!load_message (loader, message,
4691  byte_order, fields_array_len,
4692  header_len, body_len))
4693  {
4694  dbus_message_unref (message);
4695  /* load_message() returns false if corrupted or OOM; if
4696  * corrupted then return TRUE for not OOM
4697  */
4698  return loader->corrupted;
4699  }
4700 
4701  _dbus_assert (loader->messages != NULL);
4702  _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4703  }
4704  else
4705  {
4706  _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
4707  validity);
4708  if (validity != DBUS_VALID)
4709  {
4710  loader->corrupted = TRUE;
4711  loader->corruption_reason = validity;
4712  }
4713  return TRUE;
4714  }
4715  }
4716 
4717  return TRUE;
4718 }
4719 
4727 DBusMessage*
4729 {
4730  if (loader->messages)
4731  return loader->messages->data;
4732  else
4733  return NULL;
4734 }
4735 
4744 DBusMessage*
4746 {
4747  return _dbus_list_pop_first (&loader->messages);
4748 }
4749 
4758 DBusList*
4760 {
4761  return _dbus_list_pop_first_link (&loader->messages);
4762 }
4763 
4770 void
4772  DBusList *link)
4773 {
4774  _dbus_list_prepend_link (&loader->messages, link);
4775 }
4776 
4788 {
4789  _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
4790  (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
4791  return loader->corrupted;
4792 }
4793 
4802 {
4803  _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
4804  (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
4805 
4806  return loader->corruption_reason;
4807 }
4808 
4815 void
4817  long size)
4818 {
4819  if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
4820  {
4821  _dbus_verbose ("clamping requested max message size %ld to %d\n",
4824  }
4825  loader->max_message_size = size;
4826 }
4827 
4834 long
4836 {
4837  return loader->max_message_size;
4838 }
4839 
4846 void
4848  long n)
4849 {
4851  {
4852  _dbus_verbose ("clamping requested max message unix_fds %ld to %d\n",
4855  }
4856  loader->max_message_unix_fds = n;
4857 }
4858 
4865 long
4867 {
4868  return loader->max_message_unix_fds;
4869 }
4870 
4876 int
4878 {
4879 #ifdef HAVE_UNIX_FD_PASSING
4880  return loader->n_unix_fds;
4881 #else
4882  return 0;
4883 #endif
4884 }
4885 
4894 void
4896  void (* callback) (void *),
4897  void *data)
4898 {
4899 #ifdef HAVE_UNIX_FD_PASSING
4900  loader->unix_fds_change = callback;
4901  loader->unix_fds_change_data = data;
4902 #endif
4903 }
4904 
4905 static DBusDataSlotAllocator slot_allocator =
4906  _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (message_slots));
4907 
4923 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
4924 {
4925  return _dbus_data_slot_allocator_alloc (&slot_allocator,
4926  slot_p);
4927 }
4928 
4940 void
4941 dbus_message_free_data_slot (dbus_int32_t *slot_p)
4942 {
4943  _dbus_return_if_fail (*slot_p >= 0);
4944 
4945  _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
4946 }
4947 
4963  dbus_int32_t slot,
4964  void *data,
4965  DBusFreeFunction free_data_func)
4966 {
4967  DBusFreeFunction old_free_func;
4968  void *old_data;
4969  dbus_bool_t retval;
4970 
4971  _dbus_return_val_if_fail (message != NULL, FALSE);
4972  _dbus_return_val_if_fail (slot >= 0, FALSE);
4973 
4974  retval = _dbus_data_slot_list_set (&slot_allocator,
4975  &message->slot_list,
4976  slot, data, free_data_func,
4977  &old_free_func, &old_data);
4978 
4979  if (retval)
4980  {
4981  /* Do the actual free outside the message lock */
4982  if (old_free_func)
4983  (* old_free_func) (old_data);
4984  }
4985 
4986  return retval;
4987 }
4988 
4997 void*
4999  dbus_int32_t slot)
5000 {
5001  void *res;
5002 
5003  _dbus_return_val_if_fail (message != NULL, NULL);
5004 
5005  res = _dbus_data_slot_list_get (&slot_allocator,
5006  &message->slot_list,
5007  slot);
5008 
5009  return res;
5010 }
5011 
5025 int
5026 dbus_message_type_from_string (const char *type_str)
5027 {
5028  if (strcmp (type_str, "method_call") == 0)
5030  if (strcmp (type_str, "method_return") == 0)
5032  else if (strcmp (type_str, "signal") == 0)
5033  return DBUS_MESSAGE_TYPE_SIGNAL;
5034  else if (strcmp (type_str, "error") == 0)
5035  return DBUS_MESSAGE_TYPE_ERROR;
5036  else
5038 }
5039 
5053 const char *
5055 {
5056  switch (type)
5057  {
5059  return "method_call";
5061  return "method_return";
5063  return "signal";
5065  return "error";
5066  default:
5067  return "invalid";
5068  }
5069 }
5070 
5085  char **marshalled_data_p,
5086  int *len_p)
5087 {
5088  DBusString tmp;
5089  dbus_bool_t was_locked;
5090 
5091  _dbus_return_val_if_fail (msg != NULL, FALSE);
5092  _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
5093  _dbus_return_val_if_fail (len_p != NULL, FALSE);
5094 
5095  if (!_dbus_string_init (&tmp))
5096  return FALSE;
5097 
5098  /* Ensure the message is locked, to ensure the length header is filled in. */
5099  was_locked = msg->locked;
5100 
5101  if (!was_locked)
5102  dbus_message_lock (msg);
5103 
5104  if (!_dbus_string_copy (&(msg->header.data), 0, &tmp, 0))
5105  goto fail;
5106 
5107  *len_p = _dbus_string_get_length (&tmp);
5108 
5109  if (!_dbus_string_copy (&(msg->body), 0, &tmp, *len_p))
5110  goto fail;
5111 
5112  *len_p = _dbus_string_get_length (&tmp);
5113 
5114  if (!_dbus_string_steal_data (&tmp, marshalled_data_p))
5115  goto fail;
5116 
5117  _dbus_string_free (&tmp);
5118 
5119  if (!was_locked)
5120  msg->locked = FALSE;
5121 
5122  return TRUE;
5123 
5124  fail:
5125  _dbus_string_free (&tmp);
5126 
5127  if (!was_locked)
5128  msg->locked = FALSE;
5129 
5130  return FALSE;
5131 }
5132 
5145 DBusMessage *
5146 dbus_message_demarshal (const char *str,
5147  int len,
5148  DBusError *error)
5149 {
5150  DBusMessageLoader *loader = NULL;
5151  DBusString *buffer;
5152  DBusMessage *msg;
5153 
5154  _dbus_return_val_if_fail (str != NULL, NULL);
5155 
5156  loader = _dbus_message_loader_new ();
5157 
5158  if (loader == NULL)
5159  goto fail_oom;
5160 
5161  _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL);
5162 
5163  if (!_dbus_string_append_len (buffer, str, len))
5164  goto fail_oom;
5165 
5166  _dbus_message_loader_return_buffer (loader, buffer);
5167 
5169  goto fail_oom;
5170 
5172  goto fail_corrupt;
5173 
5174  msg = _dbus_message_loader_pop_message (loader);
5175 
5176  if (!msg)
5177  goto fail_oom;
5178 
5179  _dbus_message_loader_unref (loader);
5180  return msg;
5181 
5182  fail_corrupt:
5183  dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted (%s)",
5184  _dbus_validity_to_error_message (loader->corruption_reason));
5185  _dbus_message_loader_unref (loader);
5186  return NULL;
5187 
5188  fail_oom:
5189  _DBUS_SET_OOM (error);
5190 
5191  if (loader != NULL)
5192  _dbus_message_loader_unref (loader);
5193 
5194  return NULL;
5195 }
5196 
5209 int
5211  int len)
5212 {
5213  DBusString str;
5214  int byte_order, fields_array_len, header_len, body_len;
5215  DBusValidity validity = DBUS_VALID;
5216  int have_message;
5217 
5218  if (!buf || len < DBUS_MINIMUM_HEADER_SIZE)
5219  return 0;
5220 
5221  if (len > DBUS_MAXIMUM_MESSAGE_LENGTH)
5223  _dbus_string_init_const_len (&str, buf, len);
5224 
5225  validity = DBUS_VALID;
5226  have_message
5228  &validity, &byte_order,
5229  &fields_array_len,
5230  &header_len,
5231  &body_len,
5232  &str, 0,
5233  len);
5234  _dbus_string_free (&str);
5235 
5236  if (validity == DBUS_VALID)
5237  {
5238  _dbus_assert (have_message || (header_len + body_len) > len);
5239  (void) have_message; /* unused unless asserting */
5240  return header_len + body_len;
5241  }
5242  else
5243  {
5244  return -1; /* broken! */
5245  }
5246 }
5247 
5269 void
5271  dbus_bool_t allow)
5272 {
5273  _dbus_return_if_fail (message != NULL);
5274  _dbus_return_if_fail (!message->locked);
5275 
5276  _dbus_header_toggle_flag (&message->header,
5278  allow);
5279 }
5280 
5289 {
5290  _dbus_return_val_if_fail (message != NULL, FALSE);
5291 
5292  return _dbus_header_get_flag (&message->header,
5294 }
5295 
5303 {
5304  DBusString data;
5305 };
5306 
5318 DBusVariant *
5320 {
5321  DBusVariant *self = NULL;
5322  /* Points to the single item we will read from the reader */
5323  DBusMessageRealIter *real_reader = (DBusMessageRealIter *) reader;
5324  /* The position in self at which we will write a single variant
5325  * (it is position 0) */
5326  DBusTypeWriter items_writer;
5327  /* The position in self at which we will write a copy of reader
5328  * (it is inside the variant) */
5329  DBusTypeWriter variant_writer;
5330  /* 'v' */
5331  DBusString variant_signature;
5332  /* Whatever is the signature of the item we will copy from the reader */
5333  DBusString contained_signature;
5334  /* TRUE if self->data needs to be freed */
5335  dbus_bool_t data_inited = FALSE;
5336  /* The type of the item we will read from the reader */
5337  int type;
5338  /* The string, start position within that string, and length of the signature
5339  * of the single complete type of the item reader points to */
5340  const DBusString *sig;
5341  int start, len;
5342 
5343  _dbus_assert (_dbus_message_iter_check (real_reader));
5344  _dbus_assert (real_reader->iter_type == DBUS_MESSAGE_ITER_TYPE_READER);
5346  type = dbus_message_iter_get_arg_type (reader);
5347  _dbus_type_reader_get_signature (&real_reader->u.reader, &sig, &start, &len);
5348 
5349  if (!_dbus_string_init (&contained_signature))
5350  return NULL;
5351 
5352  if (!_dbus_string_copy_len (sig, start, len, &contained_signature, 0))
5353  goto oom;
5354 
5355  self = dbus_new0 (DBusVariant, 1);
5356 
5357  if (self == NULL)
5358  goto oom;
5359 
5360  if (!_dbus_string_init (&self->data))
5361  goto oom;
5362 
5363  data_inited = TRUE;
5364 
5365  _dbus_type_writer_init_values_only (&items_writer, DBUS_COMPILER_BYTE_ORDER,
5366  &variant_signature, 0, &self->data, 0);
5367 
5368  if (!_dbus_type_writer_recurse (&items_writer, DBUS_TYPE_VARIANT,
5369  &contained_signature, 0, &variant_writer))
5370  goto oom;
5371 
5372  if (type == DBUS_TYPE_ARRAY)
5373  {
5374  /* Points to each item in turn inside the array we are copying */
5375  DBusMessageIter array_reader;
5376  /* Same as array_reader */
5377  DBusMessageRealIter *real_array_reader = (DBusMessageRealIter *) &array_reader;
5378  /* The position inside the copied array at which we will write
5379  * the copy of array_reader */
5380  DBusTypeWriter array_writer;
5381 
5382  dbus_message_iter_recurse (reader, &array_reader);
5383 
5384  if (!_dbus_type_writer_recurse (&variant_writer, type,
5385  &contained_signature, 1, &array_writer))
5386  goto oom;
5387 
5388  if (!_dbus_type_writer_write_reader (&array_writer,
5389  &real_array_reader->u.reader))
5390  goto oom;
5391 
5392  if (!_dbus_type_writer_unrecurse (&variant_writer, &array_writer))
5393  goto oom;
5394  }
5395  else if (type == DBUS_TYPE_DICT_ENTRY || type == DBUS_TYPE_VARIANT ||
5396  type == DBUS_TYPE_STRUCT)
5397  {
5398  /* Points to each item in turn inside the container we are copying */
5399  DBusMessageIter inner_reader;
5400  /* Same as inner_reader */
5401  DBusMessageRealIter *real_inner_reader = (DBusMessageRealIter *) &inner_reader;
5402  /* The position inside the copied container at which we will write the
5403  * copy of inner_reader */
5404  DBusTypeWriter inner_writer;
5405 
5406  dbus_message_iter_recurse (reader, &inner_reader);
5407 
5408  if (!_dbus_type_writer_recurse (&variant_writer, type, NULL, 0,
5409  &inner_writer))
5410  goto oom;
5411 
5412  if (!_dbus_type_writer_write_reader (&inner_writer,
5413  &real_inner_reader->u.reader))
5414  goto oom;
5415 
5416  if (!_dbus_type_writer_unrecurse (&variant_writer, &inner_writer))
5417  goto oom;
5418  }
5419  else
5420  {
5421  DBusBasicValue value;
5422 
5423  /* We eliminated all the container types above */
5425 
5426  dbus_message_iter_get_basic (reader, &value);
5427 
5428  if (!_dbus_type_writer_write_basic (&variant_writer, type, &value))
5429  goto oom;
5430  }
5431 
5432  _dbus_string_free (&contained_signature);
5433  return self;
5434 
5435 oom:
5436  if (self != NULL)
5437  {
5438  if (data_inited)
5439  _dbus_string_free (&self->data);
5440 
5441  dbus_free (self);
5442  }
5443 
5444  _dbus_string_free (&contained_signature);
5445  return NULL;
5446 }
5447 
5454 const char *
5456 {
5457  unsigned char len;
5458  const char *ret;
5459 
5460  _dbus_assert (self != NULL);
5461 
5462  /* Here we make use of the fact that the serialization of a variant starts
5463  * with the 1-byte length, then that many bytes of signature, then \0. */
5464  len = _dbus_string_get_byte (&self->data, 0);
5465  ret = _dbus_string_get_const_data_len (&self->data, 1, len);
5466  _dbus_assert (strlen (ret) == len);
5467  return ret;
5468 }
5469 
5484 {
5485  /* 'v' */
5486  DBusString variant_signature;
5487  /* Points to the single item in self */
5488  DBusTypeReader variant_reader;
5489  /* Points to the single item (of whatever type) inside the variant */
5491  /* The position at which we will copy reader */
5492  DBusMessageRealIter *real_writer = (DBusMessageRealIter *) writer;
5493  dbus_bool_t ret;
5494 
5495  _dbus_assert (self != NULL);
5496  _dbus_assert (_dbus_message_iter_append_check (real_writer));
5497  _dbus_assert (real_writer->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
5498 
5500  _dbus_type_reader_init (&reader, DBUS_COMPILER_BYTE_ORDER,
5501  &variant_signature, 0, &self->data, 0);
5502  _dbus_type_reader_recurse (&reader, &variant_reader);
5503 
5504  if (!_dbus_message_iter_open_signature (real_writer))
5505  return FALSE;
5506 
5507  ret = _dbus_type_writer_write_reader (&real_writer->u.writer,
5508  &variant_reader);
5509 
5510  if (!_dbus_message_iter_close_signature (real_writer))
5511  return FALSE;
5512 
5513  return ret;
5514 }
5515 
5516 int
5517 _dbus_variant_get_length (DBusVariant *self)
5518 {
5519  _dbus_assert (self != NULL);
5520  return _dbus_string_get_length (&self->data);
5521 }
5522 
5523 const DBusString *
5524 _dbus_variant_peek (DBusVariant *self)
5525 {
5526  _dbus_assert (self != NULL);
5527  return &self->data;
5528 }
5529 
5530 void
5531 _dbus_variant_free (DBusVariant *self)
5532 {
5533  _dbus_assert (self != NULL);
5534  _dbus_string_free (&self->data);
5535  dbus_free (self);
5536 }
5537 
5540 /* tests in dbus-message-util.c */
dbus_bool_t dbus_type_is_fixed(int typecode)
Tells you whether values of this type can change length if you set them to some other value...
void _dbus_type_reader_read_fixed_multi(const DBusTypeReader *reader, void *value, int *n_elements)
Reads a block of fixed-length basic values, from the current point in an array to the end of the arra...
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_message_type_from_string(const char *type_str)
Utility function to convert a machine-readable (not translated) string into a D-Bus message type...
DBusMessage * dbus_message_ref(DBusMessage *message)
Increments the reference count of a DBusMessage.
void dbus_message_lock(DBusMessage *message)
Locks a message.
Definition: dbus-message.c:419
const char * message
public error message field
Definition: dbus-errors.h:51
dbus_bool_t dbus_message_has_path(DBusMessage *message, const char *path)
Checks if the message has a particular object path.
dbus_uint32_t changed_stamp
Incremented when iterators are invalidated.
#define NULL
A null pointer, defined appropriately for C or C++.
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(* DBusFreeFunction)(void *memory)
The type of a function which frees a block of memory.
Definition: dbus-memory.h:63
long _dbus_message_loader_get_max_message_size(DBusMessageLoader *loader)
Gets the maximum allowed message size in bytes.
void dbus_message_set_no_reply(DBusMessage *message, dbus_bool_t no_reply)
Sets a flag indicating that the message does not want a reply; if this flag is set, the other end of the connection may (but is not required to) optimize by not sending method return or error replies.
void _dbus_message_loader_putback_message_link(DBusMessageLoader *loader, DBusList *link)
Returns a popped message link, used to undo a pop.
dbus_bool_t _dbus_header_copy(const DBusHeader *header, DBusHeader *dest)
Initializes dest with a copy of the given header.
int dbus_message_iter_get_arg_type(DBusMessageIter *iter)
Returns the argument type of the argument that the message iterator points to.
dbus_uint32_t sig_refcount
depth of open_signature()
Definition: dbus-message.c:131
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...
void _dbus_type_writer_remove_types(DBusTypeWriter *writer)
Removes type string from the writer.
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:703
dbus_uint32_t dbus_message_get_serial(DBusMessage *message)
Returns the serial of a message or 0 if none has been specified.
DBusList * messages
Complete messages.
The type writer is an iterator for writing to a block of values.
void dbus_message_iter_recurse(DBusMessageIter *iter, DBusMessageIter *sub)
Recurses into a container value when reading values from a message, initializing a sub-iterator to us...
void _dbus_type_reader_recurse(DBusTypeReader *reader, DBusTypeReader *sub)
Initialize a new reader pointing to the first type and corresponding value that&#39;s a child of the curr...
DBusMessage * _dbus_message_loader_pop_message(DBusMessageLoader *loader)
Pops a loaded message (passing ownership of the message to the caller).
DBusList * _dbus_list_find_last(DBusList **list, void *data)
Finds a value in the list.
Definition: dbus-list.c:473
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...
#define DBUS_ERROR_NOT_SUPPORTED
Requested operation isn&#39;t supported (like ENOSYS on UNIX).
#define dbus_new(type, count)
Safe macro for using dbus_malloc().
Definition: dbus-memory.h:57
void dbus_message_free_data_slot(dbus_int32_t *slot_p)
Deallocates a global ID for message data slots.
#define DBUS_HEADER_FIELD_SIGNATURE
Header field code for the type signature of a message.
dbus_bool_t _dbus_header_remove_unknown_fields(DBusHeader *header)
Remove every header field not known to this version of dbus.
const char * dbus_message_get_error_name(DBusMessage *message)
Gets the error name (DBUS_MESSAGE_TYPE_ERROR only) or NULL if none.
dbus_bool_t dbus_message_iter_close_container(DBusMessageIter *iter, DBusMessageIter *sub)
Closes a container-typed value appended to the message; may write out more information to the message...
dbus_bool_t dbus_message_is_error(DBusMessage *message, const char *error_name)
Checks whether the message is an error reply with the given error name.
void _dbus_list_remove_link(DBusList **list, DBusList *link)
Removes a link from the list.
Definition: dbus-list.c:528
#define DBUS_TYPE_STRUCT
STRUCT and DICT_ENTRY are sort of special since their codes can&#39;t appear in a type string...
#define DBUS_TYPE_DICT_ENTRY
Type code used to represent a dict entry; however, this type code does not appear in type signatures...
const char * _dbus_variant_get_signature(DBusVariant *self)
Return the signature of the item stored in self.
const char * dbus_message_get_sender(DBusMessage *message)
Gets the unique name of the connection which originated this message, or NULL if unknown or inapplica...
DBUS_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 DBUS_TYPE_STRING
Type code marking a UTF-8 encoded, nul-terminated Unicode string.
DBusString body
Body network data.
dbus_uint32_t _dbus_header_get_serial(DBusHeader *header)
See dbus_message_get_serial()
dbus_bool_t _dbus_header_get_flag(DBusHeader *header, dbus_uint32_t flag)
Gets a message flag bit, returning TRUE if the bit is set.
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
#define DBUS_HEADER_FLAG_NO_REPLY_EXPECTED
If set, this flag means that the sender of a message does not care about getting a reply...
void _dbus_list_append_link(DBusList **list, DBusList *link)
Appends a link to the list.
Definition: dbus-list.c:316
Internals of DBusCounter.
dbus_bool_t dbus_message_allocate_data_slot(dbus_int32_t *slot_p)
Allocates an integer ID to be used for storing application-specific data on any DBusMessage.
void * data
Data stored at this element.
Definition: dbus-list.h:38
#define MAX_MESSAGE_CACHE_SIZE
Avoid caching too many messages.
Definition: dbus-message.c:499
DBusMessage * dbus_message_new(int message_type)
Constructs a new message of the given message type.
#define DBUS_ERROR_INCONSISTENT_MESSAGE
The message meta data does not match the payload.
dbus_bool_t _dbus_header_init(DBusHeader *header)
Initializes a header, but doesn&#39;t prepare it for use; to make the header valid, you have to call _dbu...
void _dbus_warn_check_failed(const char *format,...)
Prints a "critical" warning to stderr when an assertion fails; differs from _dbus_warn primarily in t...
const char * dbus_message_get_signature(DBusMessage *message)
Gets the type signature of the message, i.e.
void dbus_message_iter_init_append(DBusMessage *message, DBusMessageIter *iter)
Initializes a DBusMessageIter for appending arguments to the end of a message.
void dbus_error_free(DBusError *error)
Frees an error that&#39;s been set (or just initialized), then reinitializes the error as in dbus_error_i...
Definition: dbus-errors.c:211
void dbus_message_set_auto_start(DBusMessage *message, dbus_bool_t auto_start)
Sets a flag indicating that an owner for the destination name will be automatically started before th...
An opaque data structure containing the serialized form of any single D-Bus message item...
union DBusMessageRealIter::@6 u
the type writer or reader that does all the work
Layout of a DBusMessageIter on the stack in dbus 1.10.0.
Definition: dbus-message.c:144
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...
void _dbus_message_loader_unref(DBusMessageLoader *loader)
Decrements the reference count of the loader and finalizes the loader when the count reaches zero...
DBusCounter * _dbus_counter_ref(DBusCounter *counter)
Increments refcount of the counter.
DBusString data
Header network data, stored separately from body so we can independently realloc it.
dbus_bool_t dbus_message_has_interface(DBusMessage *message, const char *iface)
Checks if the message has an interface.
void _dbus_list_clear_full(DBusList **list, DBusFreeFunction function)
Free every link and every element in the list.
Definition: dbus-list.c:568
DBusValidity _dbus_message_loader_get_corruption_reason(DBusMessageLoader *loader)
Checks what kind of bad data confused the loader.
dbus_bool_t _dbus_type_writer_write_basic(DBusTypeWriter *writer, int type, const void *value)
Writes out a basic type.
#define DBUS_MESSAGE_TYPE_ERROR
Message type of an error reply message, see dbus_message_get_type()
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
DBusList * _dbus_list_alloc_link(void *data)
Allocates a linked list node.
Definition: dbus-list.c:243
#define DBUS_MAXIMUM_MESSAGE_UNIX_FDS
The maximum total number of unix fds in a message.
const char * dbus_message_get_path(DBusMessage *message)
Gets the object path this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitt...
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
#define DBUS_HEADER_FIELD_CONTAINER_INSTANCE
Header field code for the container instance that sent this message.
#define DBUS_MESSAGE_TYPE_METHOD_RETURN
Message type of a method return message, see dbus_message_get_type()
DBusMessage * dbus_message_new_signal(const char *path, const char *iface, const char *name)
Constructs a new message representing a signal emission.
_DBUS_STRING_DEFINE_STATIC(_dbus_empty_signature_str, "")
An static string representing an empty signature.
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:1089
int _dbus_dup(int fd, DBusError *error)
Duplicates a file descriptor.
DBusTypeReader reader
reader
Definition: dbus-message.c:135
DBusValidationMode
This is used rather than a bool for high visibility.
dbus_bool_t dbus_message_iter_has_next(DBusMessageIter *iter)
Checks if an iterator has any more fields.
DBusMessage * message
Message used.
Definition: dbus-message.c:128
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that&#39;s copied to the d...
Definition: dbus-string.c:1300
#define DBUS_HEADER_FIELD_INTERFACE
Header field code for the interface containing a member (method or signal).
#define DBUS_DICT_ENTRY_BEGIN_CHAR
Code marking the start of a dict entry type in a type signature.
DBusList * _dbus_list_pop_first_link(DBusList **list)
Removes the first link in the list and returns it.
Definition: dbus-list.c:656
dbus_bool_t dbus_message_has_member(DBusMessage *message, const char *member)
Checks if the message has an interface member.
DBusValidity
This is primarily used in unit testing, so we can verify that each invalid message is invalid for the...
DBusMessageIter struct; contains no public fields.
Definition: dbus-message.h:61
dbus_bool_t dbus_message_iter_init(DBusMessage *message, DBusMessageIter *iter)
Initializes a DBusMessageIter for reading the arguments of the message passed in. ...
dbus_bool_t _dbus_message_add_counter(DBusMessage *message, DBusCounter *counter)
Adds a counter to be incremented immediately with the size/unix fds of this message, and decremented by the size/unix fds of this message when this message if finalized.
Definition: dbus-message.c:364
const char * dbus_message_get_destination(DBusMessage *message)
Gets the destination of a message or NULL if there is none set.
void _dbus_message_add_counter_link(DBusMessage *message, DBusList *link)
Adds a counter to be incremented immediately with the size/unix fds of this message, and decremented by the size/unix fds of this message when this message if finalized.
Definition: dbus-message.c:315
#define DBUS_TYPE_ARRAY
Type code marking a D-Bus array type.
DBusString * type_str
where to write typecodes (or read type expectations)
dbus_bool_t dbus_message_iter_append_fixed_array(DBusMessageIter *iter, int element_type, const void *value, int n_elements)
Appends a block of fixed-length values to an array.
dbus_bool_t dbus_message_set_error_name(DBusMessage *message, const char *error_name)
Sets the name of the error (DBUS_MESSAGE_TYPE_ERROR).
dbus_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.
const char * dbus_message_get_member(DBusMessage *message)
Gets the interface member being invoked (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted (DBUS_MESSAGE_TYPE...
dbus_bool_t _dbus_list_remove_last(DBusList **list, void *data)
Removes a value from the list.
Definition: dbus-list.c:447
Internals of DBusMessage.
Internals of DBusMessageIter.
Definition: dbus-message.c:126
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...
#define dbus_new0(type, count)
Safe macro for using dbus_malloc0().
Definition: dbus-memory.h:58
dbus_uint32_t changed_stamp
stamp to detect invalid iters
Definition: dbus-message.c:129
void _dbus_type_writer_init_types_delayed(DBusTypeWriter *writer, int byte_order, DBusString *value_str, int value_pos)
Initialize a write iterator, with the signature to be provided later.
dbus_bool_t _dbus_string_compact(DBusString *str, int max_waste)
Compacts the string to avoid wasted memory.
Definition: dbus-string.c:406
int _dbus_header_get_message_type(DBusHeader *header)
Gets the type of the message.
#define DBUS_HEADER_FIELD_ERROR_NAME
Header field code for an error name (found in DBUS_MESSAGE_TYPE_ERROR messages).
#define DBUS_MINIMUM_HEADER_SIZE
The smallest header size that can occur.
dbus_bool_t _dbus_type_writer_unrecurse(DBusTypeWriter *writer, DBusTypeWriter *sub)
Closes a container created by _dbus_type_writer_recurse() and writes any additional information to th...
dbus_bool_t dbus_type_is_basic(int typecode)
A "basic type" is a somewhat arbitrary concept, but the intent is to include those types that are ful...
const char * dbus_message_get_container_instance(DBusMessage *message)
Gets the container instance this message was sent from, or NULL if none.
void _dbus_message_loader_set_max_message_size(DBusMessageLoader *loader, long size)
Sets the maximum size message we allow.
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:190
DBusHeader header
Header network data and associated cache.
dbus_bool_t dbus_message_set_sender(DBusMessage *message, const char *sender)
Sets the message sender.
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.
DBusString data
Buffered data.
void _dbus_type_reader_read_basic(const DBusTypeReader *reader, void *value)
Reads a basic-typed value, as with _dbus_marshal_read_basic().
unsigned int locked
Message being sent, no modifications allowed.
#define ensure_byte_order(message)
byte-swap the message if it doesn&#39;t match our byte order.
Definition: dbus-message.c:218
DBusMessageLoader * _dbus_message_loader_ref(DBusMessageLoader *loader)
Increments the reference count of the loader.
dbus_bool_t _dbus_header_get_field_basic(DBusHeader *header, int field, int type, void *value)
Gets the value of a field with basic type.
dbus_bool_t dbus_message_get_path_decomposed(DBusMessage *message, char ***path)
Gets the object path this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitt...
#define DBUS_TYPE_VARIANT_AS_STRING
DBUS_TYPE_VARIANT as a string literal instead of a int literal
can&#39;t determine validity due to OOM
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
void _dbus_string_delete(DBusString *str, int start, int len)
Deletes a segment of a DBusString with length len starting at start.
Definition: dbus-string.c:1210
dbus_bool_t _dbus_string_init_preallocated(DBusString *str, int allocate_size)
Initializes a string that can be up to the given allocation size before it has to realloc...
Definition: dbus-string.c:132
void _dbus_counter_unref(DBusCounter *counter)
Decrements refcount of the counter and possibly finalizes the counter.
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
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
dbus_bool_t _dbus_list_append(DBusList **list, void *data)
Appends a value to the list.
Definition: dbus-list.c:271
dbus_bool_t _dbus_decompose_path(const char *data, int len, char ***path, int *path_len)
Decompose an object path.
void * _dbus_memdup(const void *mem, size_t n_bytes)
Duplicates a block of memory.
dbus_bool_t _dbus_data_slot_list_set(DBusDataSlotAllocator *allocator, DBusDataSlotList *list, int slot, void *data, DBusFreeFunction free_data_func, DBusFreeFunction *old_free_func, void **old_data)
Stores a pointer in the data slot list, along with an optional function to be used for freeing the da...
dbus_bool_t dbus_message_set_path(DBusMessage *message, const char *object_path)
Sets the object path this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or the one a s...
void _dbus_list_foreach(DBusList **list, DBusForeachFunction function, void *data)
Calls the given function for each element in the list.
Definition: dbus-list.c:787
long max_message_size
Maximum size of a message.
void _dbus_counter_adjust_unix_fd(DBusCounter *counter, long delta)
Adjusts the value of the unix fd counter by the given delta which may be positive or negative...
dbus_bool_t _dbus_type_reader_next(DBusTypeReader *reader)
Skip to the next value on this "level".
DBusList * counters
0-N DBusCounter used to track message size/unix fds.
DBusMessageLoader * _dbus_message_loader_new(void)
Creates a new message loader.
dbus_bool_t dbus_message_set_container_instance(DBusMessage *message, const char *object_path)
Sets the container instance this message was sent from.
long size_counter_delta
Size we incremented the size counters by.
#define CHANGED_STAMP_BITS
How many bits are in the changed_stamp used to validate iterators.
void _dbus_header_byteswap(DBusHeader *header, int new_order)
Swaps the header into the given order if required.
dbus_bool_t _dbus_header_have_message_untrusted(int max_message_length, DBusValidity *validity, int *byte_order, int *fields_array_len, int *header_len, int *body_len, const DBusString *str, int start, int len)
Given data long enough to contain the length of the message body and the fields array, check whether the data is long enough to contain the entire message (assuming the claimed lengths are accurate).
#define DBUS_MESSAGE_TYPE_METHOD_CALL
Message type of a method call message, see dbus_message_get_type()
#define DBUS_HEADER_FIELD_UNIX_FDS
Header field code for the number of unix file descriptors associated with this message.
int _dbus_current_generation
_dbus_current_generation is used to track each time that dbus_shutdown() is called, so we can reinit things after it&#39;s been called.
Definition: dbus-memory.c:783
dbus_bool_t dbus_message_get_args(DBusMessage *message, DBusError *error, int first_arg_type,...)
Gets arguments from a message given a variable argument list.
Object representing an exception.
Definition: dbus-errors.h:48
unsigned int in_cache
Has been "freed" since it&#39;s in the cache (this is a debug feature)
int dbus_message_iter_get_element_count(DBusMessageIter *iter)
Returns the number of elements in the array-typed value pointed to by the iterator.
void * _dbus_list_pop_first(DBusList **list)
Removes the first value in the list and returns it.
Definition: dbus-list.c:677
#define DBUS_TYPE_SIGNATURE
Type code marking a D-Bus type signature.
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...
dbus_bool_t dbus_message_append_args(DBusMessage *message, int first_arg_type,...)
Appends fields to a message given a variable argument list.
#define DBUS_MESSAGE_TYPE_SIGNAL
Message type of a signal message, see dbus_message_get_type()
void dbus_message_iter_init_closed(DBusMessageIter *iter)
Initialize iter as if with DBUS_MESSAGE_ITER_INIT_CLOSED.
Definition: dbus-message.c:743
void dbus_set_error(DBusError *error, const char *name, const char *format,...)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:354
dbus_uint32_t dbus_message_get_reply_serial(DBusMessage *message)
Returns the serial that the message is a reply to or 0 if none.
#define INITIAL_LOADER_DATA_LEN
The initial buffer size of the message loader.
dbus_bool_t dbus_message_has_signature(DBusMessage *message, const char *signature)
Checks whether the message has the given signature; see dbus_message_get_signature() for more details...
void _dbus_data_slot_list_clear(DBusDataSlotList *list)
Frees all data slots contained in the list, calling application-provided free functions if they exist...
dbus_bool_t _dbus_message_loader_get_is_corrupted(DBusMessageLoader *loader)
Checks whether the loader is confused due to bad data.
#define DBUS_TYPE_VARIANT
Type code marking a D-Bus variant type.
dbus_bool_t _dbus_variant_write(DBusVariant *self, DBusMessageIter *writer)
Copy the single D-Bus message item from self into writer.
#define DBUS_TYPE_UINT32
Type code marking a 32-bit unsigned integer.
Definition: dbus-protocol.h:86
void _dbus_header_reinit(DBusHeader *header)
Re-initializes a header that was previously initialized and never freed.
the data is valid
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.
#define DBUS_HEADER_FIELD_DESTINATION
Header field code for the destination bus name of a message.
dbus_uint32_t byte_order
byte order of the block
dbus_bool_t _dbus_header_delete_field(DBusHeader *header, int field)
Deletes a field, if it exists.
dbus_bool_t dbus_message_has_destination(DBusMessage *message, const char *name)
Checks whether the message was sent to the given name.
#define DBUS_MESSAGE_TYPE_INVALID
This value is never a valid message type, see dbus_message_get_type()
#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...
dbus_bool_t dbus_message_get_auto_start(DBusMessage *message)
Returns TRUE if the message will cause an owner for destination name to be auto-started.
dbus_uint32_t byte_order
byte order to write values with
#define _DBUS_UNLOCK(name)
Unlocks a global lock.
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init(), and fills it with the same contents as #_DBUS_STRING_I...
Definition: dbus-string.c:264
The type reader is an iterator for reading values from a block of values.
void * _dbus_data_slot_list_get(DBusDataSlotAllocator *allocator, DBusDataSlotList *list, int slot)
Retrieves data previously set with _dbus_data_slot_list_set_data().
long _dbus_message_loader_get_max_message_unix_fds(DBusMessageLoader *loader)
Gets the maximum allowed number of unix fds per message.
#define TRUE
Expands to "1".
dbus_bool_t dbus_message_marshal(DBusMessage *msg, char **marshalled_data_p, int *len_p)
Turn a DBusMessage into the marshalled form as described in the D-Bus specification.
dbus_bool_t _dbus_header_set_field_basic(DBusHeader *header, int field, int type, const void *value)
Sets the value of a field with basic type.
void dbus_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...
void _dbus_data_slot_list_init(DBusDataSlotList *list)
Initializes a slot list.
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
DBusMessage * dbus_message_copy(const DBusMessage *message)
Creates a new message that is an exact replica of the message specified, except that its refcount is ...
int dbus_message_iter_get_element_type(DBusMessageIter *iter)
Returns the element type of the array that the message iterator points to.
void _dbus_message_get_network_data(DBusMessage *message, const DBusString **header, const DBusString **body)
Gets the data to be sent over the network for this message.
Definition: dbus-message.c:231
#define DBUS_HEADER_FIELD_MEMBER
Header field code for a member (method or signal).
long max_message_unix_fds
Maximum unix fds in a message.
unsigned int corrupted
We got broken data, and are no longer working.
dbus_bool_t dbus_message_get_args_valist(DBusMessage *message, DBusError *error, int first_arg_type, va_list var_args)
Like dbus_message_get_args but takes a va_list for use by language bindings.
#define DBUS_HEADER_FIELD_SENDER
Header field code for the sender of a message; usually initialized by the message bus...
void _dbus_type_writer_add_types(DBusTypeWriter *writer, DBusString *type_str, int type_pos)
Adds type string to the writer, if it had none.
#define DBUS_TYPE_OBJECT_PATH
Type code marking a D-Bus object path.
dbus_bool_t dbus_set_error_from_message(DBusError *error, DBusMessage *message)
Sets a DBusError based on the contents of the given message.
DBusMessage * dbus_message_demarshal(const char *str, int len, DBusError *error)
Demarshal a D-Bus message from the format described in the D-Bus specification.
void dbus_message_iter_get_fixed_array(DBusMessageIter *iter, void *value, int *n_elements)
Reads a block of fixed-length values from the message iterator.
#define DBUS_TYPE_UNIX_FD
Type code marking a unix file descriptor.
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.
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...
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...
An allocator that tracks a set of slot IDs.
Definition: dbus-dataslot.h:55
#define DBUS_TYPE_INVALID
Type code that is never equal to a legitimate type code.
Definition: dbus-protocol.h:60
dbus_bool_t dbus_message_set_reply_serial(DBusMessage *message, dbus_uint32_t reply_serial)
Sets the reply serial of a message (the serial of the message this is a reply to).
DBusVariant * _dbus_variant_read(DBusMessageIter *reader)
Copy a single D-Bus message item from reader into a newly-allocated DBusVariant.
void _dbus_counter_notify(DBusCounter *counter)
Calls the notify function from _dbus_counter_set_notify(), if that function has been specified and th...
dbus_bool_t dbus_message_has_sender(DBusMessage *message, const char *name)
Checks whether the message has the given unique name as its sender.
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.
dbus_bool_t dbus_message_iter_next(DBusMessageIter *iter)
Moves the iterator to the next field, if any.
void dbus_message_iter_get_basic(DBusMessageIter *iter, void *value)
Reads a basic-typed value from the message iterator.
void * dbus_message_get_data(DBusMessage *message, dbus_int32_t slot)
Retrieves data previously set with dbus_message_set_data().
void _dbus_type_reader_init(DBusTypeReader *reader, int byte_order, const DBusString *type_str, int type_pos, const DBusString *value_str, int value_pos)
Initializes a type reader.
void _dbus_header_free(DBusHeader *header)
Frees a header.
DBusList * _dbus_message_loader_pop_message_link(DBusMessageLoader *loader)
Pops a loaded message inside a list link (passing ownership of the message and link to the caller)...
#define DBUS_MAXIMUM_ARRAY_LENGTH
Max length of a marshaled array in bytes (64M, 2^26) We use signed int for lengths so must be INT_MAX...
dbus_bool_t dbus_message_set_destination(DBusMessage *message, const char *destination)
Sets the message&#39;s destination.
void dbus_error_init(DBusError *error)
Initializes a DBusError structure.
Definition: dbus-errors.c:188
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
DBusAtomic refcount
Reference count.
dbus_bool_t dbus_message_get_no_reply(DBusMessage *message)
Returns TRUE if the message does not expect a reply.
A node in a linked list.
Definition: dbus-list.h:34
void dbus_free_string_array(char **str_array)
Frees a NULL-terminated array of strings.
Definition: dbus-memory.c:751
#define DBUS_TYPE_BOOLEAN
Type code marking a boolean.
Definition: dbus-protocol.h:70
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:1154
dbus_uint32_t iter_type
whether this is a reader or writer iter
Definition: dbus-message.c:130
void _dbus_header_set_serial(DBusHeader *header, dbus_uint32_t serial)
Sets the serial number of a header.
int _dbus_type_reader_get_element_type(const DBusTypeReader *reader)
Gets the type of an element of the array the reader is currently pointing to.
char _dbus_header_get_byte_order(const DBusHeader *header)
Returns the header&#39;s byte order.
dbus_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_bool_t _dbus_type_reader_has_next(const DBusTypeReader *reader)
Check whether there&#39;s another value on this "level".
A simple value union that lets you access bytes as if they were various types; useful when dealing wi...
Definition: dbus-types.h:137
dbus_uint32_t container_type
what are we inside? (e.g.
int _dbus_type_reader_get_array_length(const DBusTypeReader *reader)
Returns the number of bytes in the array.
dbus_bool_t _dbus_header_get_field_raw(DBusHeader *header, int field, const DBusString **str, int *pos)
Gets the raw marshaled data for a field.
dbus_bool_t dbus_message_iter_append_basic(DBusMessageIter *iter, int type, const void *value)
Appends a basic-typed value to the message.
dbus_bool_t _dbus_close(int fd, DBusError *error)
Closes a file descriptor.
int dbus_message_iter_get_array_len(DBusMessageIter *iter)
Returns the number of bytes in the array as marshaled in the wire protocol.
int _dbus_type_reader_get_current_type(const DBusTypeReader *reader)
Gets the type of the value the reader is currently pointing to; or for a types-only reader gets the t...
#define FALSE
Expands to "0".
Message header data and some cached details of it.
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...
#define DBUS_HEADER_FIELD_PATH
Header field code for the path - the path is the object emitting a signal or the object receiving a m...
int dbus_message_get_type(DBusMessage *message)
Gets the type of a message.
#define DBUS_HEADER_FIELD_REPLY_SERIAL
Header field code for a reply serial, used to match a DBUS_MESSAGE_TYPE_METHOD_RETURN message with th...
unsigned int buffer_outstanding
Someone is using the buffer to read.
int generation
_dbus_current_generation when message was created
void _dbus_list_prepend_link(DBusList **list, DBusList *link)
Prepends a link to the list.
Definition: dbus-list.c:334
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:819
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:812
#define _DBUS_LOCK(name)
Locks a global lock, initializing it first if necessary.
#define _DBUS_LOCK_NAME(name)
Expands to name of a global lock variable.
const char * _dbus_type_to_string(int typecode)
Returns a string describing the given type.
DBusMessage * _dbus_message_loader_peek_message(DBusMessageLoader *loader)
Peeks at first loaded message, returns NULL if no messages have been queued.
dbus_bool_t _dbus_string_copy_len(const DBusString *source, int start, int len, DBusString *dest, int insert_at)
Like _dbus_string_copy(), but can copy a segment from the middle of the source string.
Definition: dbus-string.c:1392
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:658
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_type_reader_get_signature(const DBusTypeReader *reader, const DBusString **str_p, int *start_p, int *len_p)
Gets the string and range of said string containing the signature of the current value.
dbus_bool_t dbus_message_append_args_valist(DBusMessage *message, int first_arg_type, va_list var_args)
Like dbus_message_append_args() but takes a va_list for use by language bindings. ...
int dbus_message_demarshal_bytes_needed(const char *buf, int len)
Returns the number of bytes required to be in the buffer to demarshal a D-Bus message.
dbus_int32_t _dbus_atomic_get(DBusAtomic *atomic)
Atomically get the value of an integer.
char * dbus_message_iter_get_signature(DBusMessageIter *iter)
Returns the current signature of a message iterator.
dbus_bool_t _dbus_type_writer_write_fixed_multi(DBusTypeWriter *writer, int element_type, const void *value, int n_elements)
Writes a block of fixed-length basic values, i.e.
void dbus_message_iter_abandon_container(DBusMessageIter *iter, DBusMessageIter *sub)
Abandons creation of a contained-typed value and frees resources created by dbus_message_iter_open_co...
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_data_slot_allocator_alloc(DBusDataSlotAllocator *allocator, dbus_int32_t *slot_id_p)
Allocates an integer ID to be used for storing data in a DBusDataSlotList.
Definition: dbus-dataslot.c:70
dbus_bool_t dbus_message_contains_unix_fds(DBusMessage *message)
Checks whether a message contains unix fds.
#define DBUS_HEADER_FLAG_NO_AUTO_START
If set, this flag means that even if the message bus knows how to start an owner for the destination ...
dbus_bool_t _dbus_message_loader_queue_messages(DBusMessageLoader *loader)
Converts buffered data into messages, if we have enough data.
void * dbus_realloc(void *memory, size_t bytes)
Resizes a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:603
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
int refcount
Reference count.
char * _dbus_strdup(const char *str)
Duplicates a string.
#define _DBUS_ZERO(object)
Sets all bits in an object to zero.
#define MAX_MESSAGE_SIZE_TO_CACHE
Avoid caching huge messages.
Definition: dbus-message.c:496
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:195
#define DBUS_ERROR_INVALID_ARGS
Invalid arguments passed to a method call.
void _dbus_data_slot_allocator_free(DBusDataSlotAllocator *allocator, dbus_int32_t *slot_id_p)
Deallocates an ID previously allocated with _dbus_data_slot_allocator_alloc().
int _dbus_type_get_alignment(int typecode)
Gets the alignment requirement for the given type; will be 1, 4, or 8.
DBusValidity corruption_reason
why we were corrupted
void _dbus_message_loader_set_max_message_unix_fds(DBusMessageLoader *loader, long n)
Sets the maximum unix fds per message we allow.
dbus_bool_t dbus_message_set_member(DBusMessage *message, const char *member)
Sets the interface member being invoked (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted (DBUS_MESSAGE_TYPE...
const char * dbus_message_type_to_string(int type)
Utility function to convert a D-Bus message type into a machine-readable string (not translated)...
void dbus_message_unref(DBusMessage *message)
Decrements the reference count of a DBusMessage, freeing the message if the count reaches 0...
void _dbus_string_init_const_len(DBusString *str, const char *value, int len)
Initializes a constant string with a length.
Definition: dbus-string.c:210
Implementation details of DBusMessageLoader.
dbus_bool_t _dbus_type_writer_recurse(DBusTypeWriter *writer, int container_type, const DBusString *contained_type, int contained_type_start, DBusTypeWriter *sub)
Opens a new container and writes out the initial information for that container.
dbus_uint32_t u32
as int32
Definition: dbus-types.h:143
DBusMessage * dbus_message_new_error_printf(DBusMessage *reply_to, const char *error_name, const char *error_format,...)
Creates a new message that is an error reply to another message, allowing you to use printf formattin...
dbus_bool_t dbus_message_set_data(DBusMessage *message, dbus_int32_t slot, void *data, DBusFreeFunction free_data_func)
Stores a pointer on a DBusMessage, along with an optional function to be used for freeing the data wh...
void dbus_message_set_serial(DBusMessage *message, dbus_uint32_t serial)
Sets the serial number of a message.
Definition: dbus-message.c:289
void _dbus_header_toggle_flag(DBusHeader *header, dbus_uint32_t flag, dbus_bool_t value)
Toggles a message flag bit, turning on the bit if value = TRUE and flipping it off if value = FALSE...
void _dbus_header_update_lengths(DBusHeader *header, int body_len)
Fills in the correct body length.
DBusMessage * dbus_message_new_method_return(DBusMessage *method_call)
Constructs a message that is a reply to a method call.
DBusTypeWriter writer
writer
Definition: dbus-message.c:134
void _dbus_data_slot_list_free(DBusDataSlotList *list)
Frees the data slot list and all data slots contained in it, calling application-provided free functi...
#define DBUS_MAXIMUM_MESSAGE_LENGTH
The maximum total message size including header and body; similar rationale to max array size...
DBusDataSlotList slot_list
Data stored by allocated integer ID.
void _dbus_list_clear(DBusList **list)
Frees all links in the list and sets the list head to NULL.
Definition: dbus-list.c:543
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.
int _dbus_message_loader_get_pending_fds_count(DBusMessageLoader *loader)
Return how many file descriptors are pending in the loader.
dbus_bool_t dbus_type_is_container(int typecode)
A "container type" can contain basic types, or nested container types.
DBusMessage * dbus_message_new_error(DBusMessage *reply_to, const char *error_name, const char *error_message)
Creates a new message that is an error reply to another message.
void _dbus_counter_adjust_size(DBusCounter *counter, long delta)
Adjusts the value of the size counter by the given delta which may be positive or negative...