D-Bus  1.13.12
dbus-message.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-message.c DBusMessage object
3  *
4  * Copyright (C) 2002, 2003, 2004, 2005 Red Hat Inc.
5  * Copyright (C) 2002, 2003 CodeFactory AB
6  *
7  * Licensed under the Academic Free License version 2.1
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 #include <config.h>
26 #include "dbus-internals.h"
27 #include "dbus-marshal-recursive.h"
28 #include "dbus-marshal-validate.h"
29 #include "dbus-marshal-byteswap.h"
30 #include "dbus-marshal-header.h"
31 #include "dbus-signature.h"
32 #include "dbus-message-private.h"
33 #include "dbus-object-tree.h"
34 #include "dbus-memory.h"
35 #include "dbus-list.h"
36 #include "dbus-threads-internal.h"
37 #ifdef HAVE_UNIX_FD_PASSING
38 #include "dbus-sysdeps.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  void *ptr;
897 
898  ptr = va_arg (var_args, void *);
899 
900  _dbus_assert (ptr != NULL);
901 
903  ptr);
904  }
905  else if (spec_type == DBUS_TYPE_ARRAY)
906  {
907  int element_type;
908  int spec_element_type;
909  const void **ptr;
910  int *n_elements_p;
911  DBusTypeReader array;
912 
913  spec_element_type = va_arg (var_args, int);
914  element_type = _dbus_type_reader_get_element_type (&real->u.reader);
915 
916  if (spec_element_type != element_type)
917  {
919  "Argument %d is specified to be an array of \"%s\", but "
920  "is actually an array of \"%s\"\n",
921  i,
922  _dbus_type_to_string (spec_element_type),
923  _dbus_type_to_string (element_type));
924 
925  goto out;
926  }
927 
928  if (dbus_type_is_fixed (spec_element_type) &&
929  element_type != DBUS_TYPE_UNIX_FD)
930  {
931  ptr = va_arg (var_args, const void **);
932  n_elements_p = va_arg (var_args, int*);
933 
934  _dbus_assert (ptr != NULL);
935  _dbus_assert (n_elements_p != NULL);
936 
937  _dbus_type_reader_recurse (&real->u.reader, &array);
938 
939  _dbus_type_reader_read_fixed_multi (&array, ptr, n_elements_p);
940  }
941  else if (_DBUS_TYPE_IS_STRINGLIKE (spec_element_type))
942  {
943  char ***str_array_p;
944  int n_elements;
945  char **str_array;
946 
947  str_array_p = va_arg (var_args, char***);
948  n_elements_p = va_arg (var_args, int*);
949 
950  _dbus_assert (str_array_p != NULL);
951  _dbus_assert (n_elements_p != NULL);
952 
953  /* Count elements in the array */
954  _dbus_type_reader_recurse (&real->u.reader, &array);
955 
956  n_elements = 0;
958  {
959  ++n_elements;
960  _dbus_type_reader_next (&array);
961  }
962 
963  str_array = dbus_new0 (char*, n_elements + 1);
964  if (str_array == NULL)
965  {
966  _DBUS_SET_OOM (error);
967  goto out;
968  }
969 
970  /* Now go through and dup each string */
971  _dbus_type_reader_recurse (&real->u.reader, &array);
972 
973  j = 0;
974  while (j < n_elements)
975  {
976  const char *s;
978  (void *) &s);
979 
980  str_array[j] = _dbus_strdup (s);
981  if (str_array[j] == NULL)
982  {
983  dbus_free_string_array (str_array);
984  _DBUS_SET_OOM (error);
985  goto out;
986  }
987 
988  ++j;
989 
990  if (!_dbus_type_reader_next (&array))
991  _dbus_assert (j == n_elements);
992  }
993 
995  _dbus_assert (j == n_elements);
996  _dbus_assert (str_array[j] == NULL);
997 
998  *str_array_p = str_array;
999  *n_elements_p = n_elements;
1000  }
1001 #ifndef DBUS_DISABLE_CHECKS
1002  else
1003  {
1004  _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now",
1005  _DBUS_FUNCTION_NAME);
1006  goto out;
1007  }
1008 #endif
1009  }
1010 #ifndef DBUS_DISABLE_CHECKS
1011  else
1012  {
1013  _dbus_warn ("you can only read arrays and basic types with %s for now",
1014  _DBUS_FUNCTION_NAME);
1015  goto out;
1016  }
1017 #endif
1018 
1019  /* how many arguments already handled */
1020  i++;
1021 
1022  spec_type = va_arg (var_args, int);
1023  if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID)
1024  {
1026  "Message has only %d arguments, but more were expected", i);
1027  goto out;
1028  }
1029  }
1030 
1031  retval = TRUE;
1032 
1033  out:
1034  /* there may memory or unix fd leak in the above iteration if parse failed.
1035  * so we have another iteration over copy_args to free memory and close
1036  * unix fds.
1037  */
1038  if (!retval)
1039  {
1040  spec_type = first_arg_type;
1041  j = 0;
1042 
1043  while (j < i)
1044  {
1045  if (spec_type == DBUS_TYPE_UNIX_FD)
1046  {
1047 #ifdef HAVE_UNIX_FD_PASSING
1048  int *pfd;
1049 
1050  pfd = va_arg (copy_args, int *);
1051  _dbus_assert(pfd);
1052  if (*pfd >= 0)
1053  {
1054  _dbus_close (*pfd, NULL);
1055  *pfd = -1;
1056  }
1057 #endif
1058  }
1059  else if (dbus_type_is_basic (spec_type))
1060  {
1061  /* move the index forward */
1062  va_arg (copy_args, const void *);
1063  }
1064  else if (spec_type == DBUS_TYPE_ARRAY)
1065  {
1066  int spec_element_type;
1067 
1068  spec_element_type = va_arg (copy_args, int);
1069  if (dbus_type_is_fixed (spec_element_type))
1070  {
1071  /* move the index forward */
1072  va_arg (copy_args, const void **);
1073  va_arg (copy_args, int *);
1074  }
1075  else if (_DBUS_TYPE_IS_STRINGLIKE (spec_element_type))
1076  {
1077  char ***str_array_p;
1078 
1079  str_array_p = va_arg (copy_args, char ***);
1080  /* move the index forward */
1081  va_arg (copy_args, int *);
1082  _dbus_assert (str_array_p != NULL);
1083  dbus_free_string_array (*str_array_p);
1084  *str_array_p = NULL;
1085  }
1086  }
1087 
1088  spec_type = va_arg (copy_args, int);
1089  j++;
1090  }
1091  }
1092 
1093  va_end (copy_args);
1094  return retval;
1095 }
1096 
1155 dbus_uint32_t
1157 {
1158  _dbus_return_val_if_fail (message != NULL, 0);
1159 
1160  return _dbus_header_get_serial (&message->header);
1161 }
1162 
1173  dbus_uint32_t reply_serial)
1174 {
1175  DBusBasicValue value;
1176 
1177  _dbus_return_val_if_fail (message != NULL, FALSE);
1178  _dbus_return_val_if_fail (!message->locked, FALSE);
1179  _dbus_return_val_if_fail (reply_serial != 0, FALSE); /* 0 is invalid */
1180 
1181  value.u32 = reply_serial;
1182 
1183  return _dbus_header_set_field_basic (&message->header,
1186  &value);
1187 }
1188 
1195 dbus_uint32_t
1197 {
1198  dbus_uint32_t v_UINT32;
1199 
1200  _dbus_return_val_if_fail (message != NULL, 0);
1201 
1202  if (_dbus_header_get_field_basic (&message->header,
1205  &v_UINT32))
1206  return v_UINT32;
1207  else
1208  return 0;
1209 }
1210 
1211 static void
1212 dbus_message_finalize (DBusMessage *message)
1213 {
1214  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
1215 
1216  /* This calls application callbacks! */
1218 
1219  _dbus_list_foreach (&message->counters,
1220  free_counter, message);
1221  _dbus_list_clear (&message->counters);
1222 
1223  _dbus_header_free (&message->header);
1224  _dbus_string_free (&message->body);
1225 
1226 #ifdef HAVE_UNIX_FD_PASSING
1227  close_unix_fds(message->unix_fds, &message->n_unix_fds);
1228  dbus_free(message->unix_fds);
1229 #endif
1230 
1231  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
1232 
1233  dbus_free (message);
1234 }
1235 
1236 static DBusMessage*
1237 dbus_message_new_empty_header (void)
1238 {
1240  dbus_bool_t from_cache;
1241 
1242  message = dbus_message_get_cached ();
1243 
1244  if (message != NULL)
1245  {
1246  from_cache = TRUE;
1247  }
1248  else
1249  {
1250  from_cache = FALSE;
1251  message = dbus_new0 (DBusMessage, 1);
1252  if (message == NULL)
1253  return NULL;
1254 #ifndef DBUS_DISABLE_CHECKS
1256 #endif
1257 
1258 #ifdef HAVE_UNIX_FD_PASSING
1259  message->unix_fds = NULL;
1260  message->n_unix_fds_allocated = 0;
1261 #endif
1262  }
1263 
1264  _dbus_atomic_inc (&message->refcount);
1265 
1266  _dbus_message_trace_ref (message, 0, 1, "new_empty_header");
1267 
1268  message->locked = FALSE;
1269 #ifndef DBUS_DISABLE_CHECKS
1270  message->in_cache = FALSE;
1271 #endif
1272  message->counters = NULL;
1273  message->size_counter_delta = 0;
1274  message->changed_stamp = 0;
1275 
1276 #ifdef HAVE_UNIX_FD_PASSING
1277  message->n_unix_fds = 0;
1278  message->n_unix_fds_allocated = 0;
1279  message->unix_fd_counter_delta = 0;
1280 #endif
1281 
1282  if (!from_cache)
1284 
1285  if (from_cache)
1286  {
1287  _dbus_header_reinit (&message->header);
1288  _dbus_string_set_length (&message->body, 0);
1289  }
1290  else
1291  {
1292  if (!_dbus_header_init (&message->header))
1293  {
1294  dbus_free (message);
1295  return NULL;
1296  }
1297 
1298  if (!_dbus_string_init_preallocated (&message->body, 32))
1299  {
1300  _dbus_header_free (&message->header);
1301  dbus_free (message);
1302  return NULL;
1303  }
1304  }
1305 
1306  return message;
1307 }
1308 
1321 DBusMessage*
1322 dbus_message_new (int message_type)
1323 {
1325 
1326  _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
1327 
1328  message = dbus_message_new_empty_header ();
1329  if (message == NULL)
1330  return NULL;
1331 
1332  if (!_dbus_header_create (&message->header,
1333  DBUS_COMPILER_BYTE_ORDER,
1334  message_type,
1335  NULL, NULL, NULL, NULL, NULL))
1336  {
1337  dbus_message_unref (message);
1338  return NULL;
1339  }
1340 
1341  return message;
1342 }
1343 
1365 DBusMessage*
1366 dbus_message_new_method_call (const char *destination,
1367  const char *path,
1368  const char *iface,
1369  const char *method)
1370 {
1372 
1373  _dbus_return_val_if_fail (path != NULL, NULL);
1374  _dbus_return_val_if_fail (method != NULL, NULL);
1375  _dbus_return_val_if_fail (destination == NULL ||
1376  _dbus_check_is_valid_bus_name (destination), NULL);
1377  _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
1378  _dbus_return_val_if_fail (iface == NULL ||
1379  _dbus_check_is_valid_interface (iface), NULL);
1380  _dbus_return_val_if_fail (_dbus_check_is_valid_member (method), NULL);
1381 
1382  message = dbus_message_new_empty_header ();
1383  if (message == NULL)
1384  return NULL;
1385 
1386  if (!_dbus_header_create (&message->header,
1387  DBUS_COMPILER_BYTE_ORDER,
1389  destination, path, iface, method, NULL))
1390  {
1391  dbus_message_unref (message);
1392  return NULL;
1393  }
1394 
1395  return message;
1396 }
1397 
1405 DBusMessage*
1407 {
1409  const char *sender;
1410 
1411  _dbus_return_val_if_fail (method_call != NULL, NULL);
1412 
1413  sender = dbus_message_get_sender (method_call);
1414 
1415  /* sender is allowed to be null here in peer-to-peer case */
1416 
1417  message = dbus_message_new_empty_header ();
1418  if (message == NULL)
1419  return NULL;
1420 
1421  if (!_dbus_header_create (&message->header,
1422  DBUS_COMPILER_BYTE_ORDER,
1424  sender, NULL, NULL, NULL, NULL))
1425  {
1426  dbus_message_unref (message);
1427  return NULL;
1428  }
1429 
1430  dbus_message_set_no_reply (message, TRUE);
1431 
1432  if (!dbus_message_set_reply_serial (message,
1433  dbus_message_get_serial (method_call)))
1434  {
1435  dbus_message_unref (message);
1436  return NULL;
1437  }
1438 
1439  return message;
1440 }
1441 
1456 DBusMessage*
1457 dbus_message_new_signal (const char *path,
1458  const char *iface,
1459  const char *name)
1460 {
1462 
1463  _dbus_return_val_if_fail (path != NULL, NULL);
1464  _dbus_return_val_if_fail (iface != NULL, NULL);
1465  _dbus_return_val_if_fail (name != NULL, NULL);
1466  _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
1467  _dbus_return_val_if_fail (_dbus_check_is_valid_interface (iface), NULL);
1468  _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);
1469 
1470  message = dbus_message_new_empty_header ();
1471  if (message == NULL)
1472  return NULL;
1473 
1474  if (!_dbus_header_create (&message->header,
1475  DBUS_COMPILER_BYTE_ORDER,
1477  NULL, path, iface, name, NULL))
1478  {
1479  dbus_message_unref (message);
1480  return NULL;
1481  }
1482 
1483  dbus_message_set_no_reply (message, TRUE);
1484 
1485  return message;
1486 }
1487 
1502 DBusMessage*
1504  const char *error_name,
1505  const char *error_message)
1506 {
1508  const char *sender;
1509  DBusMessageIter iter;
1510 
1511  _dbus_return_val_if_fail (reply_to != NULL, NULL);
1512  _dbus_return_val_if_fail (error_name != NULL, NULL);
1513  _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
1514 
1515  sender = dbus_message_get_sender (reply_to);
1516 
1517  /* sender may be NULL for non-message-bus case or
1518  * when the message bus is dealing with an unregistered
1519  * connection.
1520  */
1521  message = dbus_message_new_empty_header ();
1522  if (message == NULL)
1523  return NULL;
1524 
1525  if (!_dbus_header_create (&message->header,
1526  DBUS_COMPILER_BYTE_ORDER,
1528  sender, NULL, NULL, NULL, error_name))
1529  {
1530  dbus_message_unref (message);
1531  return NULL;
1532  }
1533 
1534  dbus_message_set_no_reply (message, TRUE);
1535 
1536  if (!dbus_message_set_reply_serial (message,
1537  dbus_message_get_serial (reply_to)))
1538  {
1539  dbus_message_unref (message);
1540  return NULL;
1541  }
1542 
1543  if (error_message != NULL)
1544  {
1545  dbus_message_iter_init_append (message, &iter);
1546  if (!dbus_message_iter_append_basic (&iter,
1548  &error_message))
1549  {
1550  dbus_message_unref (message);
1551  return NULL;
1552  }
1553  }
1554 
1555  return message;
1556 }
1557 
1574 DBusMessage*
1576  const char *error_name,
1577  const char *error_format,
1578  ...)
1579 {
1580  va_list args;
1581  DBusString str;
1583 
1584  _dbus_return_val_if_fail (reply_to != NULL, NULL);
1585  _dbus_return_val_if_fail (error_name != NULL, NULL);
1586  _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
1587 
1588  if (!_dbus_string_init (&str))
1589  return NULL;
1590 
1591  va_start (args, error_format);
1592 
1593  if (_dbus_string_append_printf_valist (&str, error_format, args))
1594  message = dbus_message_new_error (reply_to, error_name,
1595  _dbus_string_get_const_data (&str));
1596  else
1597  message = NULL;
1598 
1599  _dbus_string_free (&str);
1600 
1601  va_end (args);
1602 
1603  return message;
1604 }
1605 
1606 
1619 DBusMessage *
1621 {
1622  DBusMessage *retval;
1623 
1624  _dbus_return_val_if_fail (message != NULL, NULL);
1625 
1626  retval = dbus_new0 (DBusMessage, 1);
1627  if (retval == NULL)
1628  return NULL;
1629 
1630  _dbus_atomic_inc (&retval->refcount);
1631 
1632  retval->locked = FALSE;
1633 #ifndef DBUS_DISABLE_CHECKS
1634  retval->generation = message->generation;
1635 #endif
1636 
1637  if (!_dbus_header_copy (&message->header, &retval->header))
1638  {
1639  dbus_free (retval);
1640  return NULL;
1641  }
1642 
1643  if (!_dbus_string_init_preallocated (&retval->body,
1644  _dbus_string_get_length (&message->body)))
1645  {
1646  _dbus_header_free (&retval->header);
1647  dbus_free (retval);
1648  return NULL;
1649  }
1650 
1651  if (!_dbus_string_copy (&message->body, 0,
1652  &retval->body, 0))
1653  goto failed_copy;
1654 
1655 #ifdef HAVE_UNIX_FD_PASSING
1656  retval->unix_fds = dbus_new(int, message->n_unix_fds);
1657  if (retval->unix_fds == NULL && message->n_unix_fds > 0)
1658  goto failed_copy;
1659 
1660  retval->n_unix_fds_allocated = message->n_unix_fds;
1661 
1662  for (retval->n_unix_fds = 0;
1663  retval->n_unix_fds < message->n_unix_fds;
1664  retval->n_unix_fds++)
1665  {
1666  retval->unix_fds[retval->n_unix_fds] = _dbus_dup(message->unix_fds[retval->n_unix_fds], NULL);
1667 
1668  if (retval->unix_fds[retval->n_unix_fds] < 0)
1669  goto failed_copy;
1670  }
1671 
1672 #endif
1673 
1674  _dbus_message_trace_ref (retval, 0, 1, "copy");
1675  return retval;
1676 
1677  failed_copy:
1678  _dbus_header_free (&retval->header);
1679  _dbus_string_free (&retval->body);
1680 
1681 #ifdef HAVE_UNIX_FD_PASSING
1682  close_unix_fds(retval->unix_fds, &retval->n_unix_fds);
1683  dbus_free(retval->unix_fds);
1684 #endif
1685 
1686  dbus_free (retval);
1687 
1688  return NULL;
1689 }
1690 
1691 
1699 DBusMessage *
1701 {
1702  dbus_int32_t old_refcount;
1703 
1704  _dbus_return_val_if_fail (message != NULL, NULL);
1705  _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
1706  _dbus_return_val_if_fail (!message->in_cache, NULL);
1707 
1708  old_refcount = _dbus_atomic_inc (&message->refcount);
1709  _dbus_assert (old_refcount >= 1);
1710  _dbus_message_trace_ref (message, old_refcount, old_refcount + 1, "ref");
1711 
1712  return message;
1713 }
1714 
1722 void
1724 {
1725  dbus_int32_t old_refcount;
1726 
1727  _dbus_return_if_fail (message != NULL);
1728  _dbus_return_if_fail (message->generation == _dbus_current_generation);
1729  _dbus_return_if_fail (!message->in_cache);
1730 
1731  old_refcount = _dbus_atomic_dec (&message->refcount);
1732 
1733  _dbus_assert (old_refcount >= 1);
1734 
1735  _dbus_message_trace_ref (message, old_refcount, old_refcount - 1, "unref");
1736 
1737  if (old_refcount == 1)
1738  {
1739  /* Calls application callbacks! */
1740  dbus_message_cache_or_finalize (message);
1741  }
1742 }
1743 
1754 int
1756 {
1757  _dbus_return_val_if_fail (message != NULL, DBUS_MESSAGE_TYPE_INVALID);
1758 
1759  return _dbus_header_get_message_type (&message->header);
1760 }
1761 
1826  int first_arg_type,
1827  ...)
1828 {
1829  dbus_bool_t retval;
1830  va_list var_args;
1831 
1832  _dbus_return_val_if_fail (message != NULL, FALSE);
1833 
1834  va_start (var_args, first_arg_type);
1835  retval = dbus_message_append_args_valist (message,
1836  first_arg_type,
1837  var_args);
1838  va_end (var_args);
1839 
1840  return retval;
1841 }
1842 
1858  int first_arg_type,
1859  va_list var_args)
1860 {
1861  int type;
1862  DBusMessageIter iter;
1863 
1864  _dbus_return_val_if_fail (message != NULL, FALSE);
1865 
1866  type = first_arg_type;
1867 
1868  dbus_message_iter_init_append (message, &iter);
1869 
1870  while (type != DBUS_TYPE_INVALID)
1871  {
1872  if (dbus_type_is_basic (type))
1873  {
1874  const void *value;
1875  value = va_arg (var_args, const void *);
1876 
1877  if (!dbus_message_iter_append_basic (&iter,
1878  type,
1879  value))
1880  goto failed;
1881  }
1882  else if (type == DBUS_TYPE_ARRAY)
1883  {
1884  int element_type;
1885  DBusMessageIter array;
1886  char buf[2];
1887 
1888  element_type = va_arg (var_args, int);
1889 
1890  buf[0] = element_type;
1891  buf[1] = '\0';
1894  buf,
1895  &array))
1896  goto failed;
1897 
1898  if (dbus_type_is_fixed (element_type) &&
1899  element_type != DBUS_TYPE_UNIX_FD)
1900  {
1901  const void **value;
1902  int n_elements;
1903 
1904  value = va_arg (var_args, const void **);
1905  n_elements = va_arg (var_args, int);
1906 
1908  element_type,
1909  value,
1910  n_elements)) {
1911  dbus_message_iter_abandon_container (&iter, &array);
1912  goto failed;
1913  }
1914  }
1915  else if (_DBUS_TYPE_IS_STRINGLIKE (element_type))
1916  {
1917  const char ***value_p;
1918  const char **value;
1919  int n_elements;
1920  int i;
1921 
1922  value_p = va_arg (var_args, const char***);
1923  n_elements = va_arg (var_args, int);
1924 
1925  value = *value_p;
1926 
1927  i = 0;
1928  while (i < n_elements)
1929  {
1930  if (!dbus_message_iter_append_basic (&array,
1931  element_type,
1932  &value[i])) {
1933  dbus_message_iter_abandon_container (&iter, &array);
1934  goto failed;
1935  }
1936  ++i;
1937  }
1938  }
1939  else
1940  {
1941  _dbus_warn ("arrays of %s can't be appended with %s for now",
1942  _dbus_type_to_string (element_type),
1943  _DBUS_FUNCTION_NAME);
1944  dbus_message_iter_abandon_container (&iter, &array);
1945  goto failed;
1946  }
1947 
1948  if (!dbus_message_iter_close_container (&iter, &array))
1949  goto failed;
1950  }
1951 #ifndef DBUS_DISABLE_CHECKS
1952  else
1953  {
1954  _dbus_warn ("type %s isn't supported yet in %s",
1955  _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
1956  goto failed;
1957  }
1958 #endif
1959 
1960  type = va_arg (var_args, int);
1961  }
1962 
1963  return TRUE;
1964 
1965  failed:
1966  return FALSE;
1967 }
1968 
2015  DBusError *error,
2016  int first_arg_type,
2017  ...)
2018 {
2019  dbus_bool_t retval;
2020  va_list var_args;
2021 
2022  _dbus_return_val_if_fail (message != NULL, FALSE);
2023  _dbus_return_val_if_error_is_set (error, FALSE);
2024 
2025  va_start (var_args, first_arg_type);
2026  retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
2027  va_end (var_args);
2028 
2029  return retval;
2030 }
2031 
2044  DBusError *error,
2045  int first_arg_type,
2046  va_list var_args)
2047 {
2048  DBusMessageIter iter;
2049 
2050  _dbus_return_val_if_fail (message != NULL, FALSE);
2051  _dbus_return_val_if_error_is_set (error, FALSE);
2052 
2053  dbus_message_iter_init (message, &iter);
2054  return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
2055 }
2056 
2057 static void
2058 _dbus_message_iter_init_common (DBusMessage *message,
2059  DBusMessageRealIter *real,
2060  int iter_type)
2061 {
2062  /* If these static assertions fail on your platform, report it as a bug. */
2063  _DBUS_STATIC_ASSERT (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
2064  _DBUS_STATIC_ASSERT (_DBUS_ALIGNOF (DBusMessageRealIter) <=
2065  _DBUS_ALIGNOF (DBusMessageIter));
2066  /* A failure of these two assertions would indicate that we've broken
2067  * ABI on this platform since 1.10.0. */
2068  _DBUS_STATIC_ASSERT (sizeof (DBusMessageIter_1_10_0) ==
2069  sizeof (DBusMessageIter));
2070  _DBUS_STATIC_ASSERT (_DBUS_ALIGNOF (DBusMessageIter_1_10_0) ==
2071  _DBUS_ALIGNOF (DBusMessageIter));
2072  /* If this static assertion fails, it means the DBusMessageIter struct
2073  * is not "packed", which might result in "iter = other_iter" not copying
2074  * every byte. */
2075  _DBUS_STATIC_ASSERT (sizeof (DBusMessageIter) ==
2076  4 * sizeof (void *) + sizeof (dbus_uint32_t) + 9 * sizeof (int));
2077 
2078  /* Since the iterator will read or write who-knows-what from the
2079  * message, we need to get in the right byte order
2080  */
2081  ensure_byte_order (message);
2082 
2083  real->message = message;
2084  real->changed_stamp = message->changed_stamp;
2085  real->iter_type = iter_type;
2086  real->sig_refcount = 0;
2087 }
2088 
2113  DBusMessageIter *iter)
2114 {
2115  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2116  const DBusString *type_str;
2117  int type_pos;
2118 
2119  _dbus_return_val_if_fail (message != NULL, FALSE);
2120  _dbus_return_val_if_fail (iter != NULL, FALSE);
2121 
2122  get_const_signature (&message->header, &type_str, &type_pos);
2123 
2124  _dbus_message_iter_init_common (message, real,
2125  DBUS_MESSAGE_ITER_TYPE_READER);
2126 
2128  _dbus_header_get_byte_order (&message->header),
2129  type_str, type_pos,
2130  &message->body,
2131  0);
2132 
2134 }
2135 
2144 {
2145  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2146 
2147  _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
2148  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2149 
2150  return _dbus_type_reader_has_next (&real->u.reader);
2151 }
2152 
2163 {
2164  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2165 
2166  _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
2167  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2168 
2169  return _dbus_type_reader_next (&real->u.reader);
2170 }
2171 
2186 int
2188 {
2189  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2190 
2191  _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2192  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2193 
2195 }
2196 
2205 int
2207 {
2208  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2209 
2210  _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2211  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
2212  _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
2213 
2215 }
2216 
2242 void
2244  DBusMessageIter *sub)
2245 {
2246  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2247  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2248 
2249  _dbus_return_if_fail (_dbus_message_iter_check (real));
2250  _dbus_return_if_fail (sub != NULL);
2251 
2252  *real_sub = *real;
2253  _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
2254 }
2255 
2267 char *
2269 {
2270  const DBusString *sig;
2271  DBusString retstr;
2272  char *ret;
2273  int start, len;
2274  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2275 
2276  _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
2277 
2278  if (!_dbus_string_init (&retstr))
2279  return NULL;
2280 
2282  &start, &len);
2283  if (!_dbus_string_append_len (&retstr,
2284  _dbus_string_get_const_data (sig) + start,
2285  len))
2286  return NULL;
2287  if (!_dbus_string_steal_data (&retstr, &ret))
2288  return NULL;
2289  _dbus_string_free (&retstr);
2290  return ret;
2291 }
2292 
2340 void
2342  void *value)
2343 {
2344  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2345 
2346  _dbus_return_if_fail (_dbus_message_iter_check (real));
2347  _dbus_return_if_fail (value != NULL);
2348 
2350  {
2351 #ifdef HAVE_UNIX_FD_PASSING
2352  DBusBasicValue idx;
2353 
2354  _dbus_type_reader_read_basic(&real->u.reader, &idx);
2355 
2356  if (idx.u32 >= real->message->n_unix_fds) {
2357  /* Hmm, we cannot really signal an error here, so let's make
2358  sure to return an invalid fd. */
2359  *((int*) value) = -1;
2360  return;
2361  }
2362 
2363  *((int*) value) = _dbus_dup(real->message->unix_fds[idx.u32], NULL);
2364 #else
2365  *((int*) value) = -1;
2366 #endif
2367  }
2368  else
2369  {
2371  value);
2372  }
2373 }
2374 
2385 int
2387 {
2388  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2389  DBusTypeReader array;
2390  int element_type;
2391  int n_elements = 0;
2392 
2393  _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
2394  _dbus_return_val_if_fail (_dbus_type_reader_get_current_type (&real->u.reader)
2395  == DBUS_TYPE_ARRAY, 0);
2396 
2397  element_type = _dbus_type_reader_get_element_type (&real->u.reader);
2398  _dbus_type_reader_recurse (&real->u.reader, &array);
2399  if (dbus_type_is_fixed (element_type))
2400  {
2401  int alignment = _dbus_type_get_alignment (element_type);
2402  int total_len = _dbus_type_reader_get_array_length (&array);
2403  n_elements = total_len / alignment;
2404  }
2405  else
2406  {
2408  {
2409  ++n_elements;
2410  _dbus_type_reader_next (&array);
2411  }
2412  }
2413 
2414  return n_elements;
2415 }
2416 
2429 int
2431 {
2432  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2433 
2434  _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
2435 
2437 }
2438 
2474 void
2476  void *value,
2477  int *n_elements)
2478 {
2479  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2480 #ifndef DBUS_DISABLE_CHECKS
2481  int subtype = _dbus_type_reader_get_current_type(&real->u.reader);
2482 
2483  _dbus_return_if_fail (_dbus_message_iter_check (real));
2484  _dbus_return_if_fail (value != NULL);
2485  _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) ||
2486  (dbus_type_is_fixed (subtype) && subtype != DBUS_TYPE_UNIX_FD));
2487 #endif
2488 
2490  value, n_elements);
2491 }
2492 
2504 void
2506  DBusMessageIter *iter)
2507 {
2508  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2509 
2510  _dbus_return_if_fail (message != NULL);
2511  _dbus_return_if_fail (iter != NULL);
2512 
2513  _dbus_message_iter_init_common (message, real,
2514  DBUS_MESSAGE_ITER_TYPE_WRITER);
2515 
2516  /* We create the signature string and point iterators at it "on demand"
2517  * when a value is actually appended. That means that init() never fails
2518  * due to OOM.
2519  */
2521  _dbus_header_get_byte_order (&message->header),
2522  &message->body,
2523  _dbus_string_get_length (&message->body));
2524 }
2525 
2534 static dbus_bool_t
2535 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
2536 {
2537  DBusString *str;
2538  const DBusString *current_sig;
2539  int current_sig_pos;
2540 
2541  _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2542 
2543  if (real->u.writer.type_str != NULL)
2544  {
2545  _dbus_assert (real->sig_refcount > 0);
2546  real->sig_refcount += 1;
2547  return TRUE;
2548  }
2549 
2550  str = dbus_new (DBusString, 1);
2551  if (str == NULL)
2552  return FALSE;
2553 
2556  &current_sig, &current_sig_pos))
2557  current_sig = NULL;
2558 
2559  if (current_sig)
2560  {
2561  int current_len;
2562 
2563  current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
2564  current_sig_pos += 1; /* move on to sig data */
2565 
2566  if (!_dbus_string_init_preallocated (str, current_len + 4))
2567  {
2568  dbus_free (str);
2569  return FALSE;
2570  }
2571 
2572  if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
2573  str, 0))
2574  {
2575  _dbus_string_free (str);
2576  dbus_free (str);
2577  return FALSE;
2578  }
2579  }
2580  else
2581  {
2582  if (!_dbus_string_init_preallocated (str, 4))
2583  {
2584  dbus_free (str);
2585  return FALSE;
2586  }
2587  }
2588 
2589  real->sig_refcount = 1;
2590 
2591  /* If this assertion failed, then str would be neither stored in u.writer
2592  * nor freed by this function, resulting in a memory leak. */
2593  _dbus_assert (real->u.writer.type_str == NULL);
2595  str, _dbus_string_get_length (str));
2596  return TRUE;
2597 }
2598 
2608 static dbus_bool_t
2609 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
2610 {
2611  DBusString *str;
2612  const char *v_STRING;
2613  dbus_bool_t retval;
2614 
2615  _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2616  _dbus_assert (real->u.writer.type_str != NULL);
2617  _dbus_assert (real->sig_refcount > 0);
2618 
2619  real->sig_refcount -= 1;
2620 
2621  if (real->sig_refcount > 0)
2622  return TRUE;
2623  _dbus_assert (real->sig_refcount == 0);
2624 
2625  retval = TRUE;
2626 
2627  str = real->u.writer.type_str;
2628 
2629  v_STRING = _dbus_string_get_const_data (str);
2633  &v_STRING))
2634  retval = FALSE;
2635 
2637  _dbus_string_free (str);
2638  dbus_free (str);
2639 
2640  return retval;
2641 }
2642 
2650 static void
2651 _dbus_message_iter_abandon_signature (DBusMessageRealIter *real)
2652 {
2653  DBusString *str;
2654 
2655  _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2656  _dbus_assert (real->u.writer.type_str != NULL);
2657  _dbus_assert (real->sig_refcount > 0);
2658 
2659  real->sig_refcount -= 1;
2660 
2661  if (real->sig_refcount > 0)
2662  return;
2663  _dbus_assert (real->sig_refcount == 0);
2664 
2665  str = real->u.writer.type_str;
2666 
2668  _dbus_string_free (str);
2669  dbus_free (str);
2670 }
2671 
2672 #ifndef DBUS_DISABLE_CHECKS
2673 static dbus_bool_t
2674 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
2675 {
2676  if (!_dbus_message_iter_check (iter))
2677  return FALSE;
2678 
2679  if (iter->message->locked)
2680  {
2681  _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)");
2682  return FALSE;
2683  }
2684 
2685  return TRUE;
2686 }
2687 #endif /* DBUS_DISABLE_CHECKS */
2688 
2689 #ifdef HAVE_UNIX_FD_PASSING
2690 static int *
2691 expand_fd_array(DBusMessage *m,
2692  unsigned n)
2693 {
2694  _dbus_assert(m);
2695 
2696  /* This makes space for adding n new fds to the array and returns a
2697  pointer to the place were the first fd should be put. */
2698 
2699  if (m->n_unix_fds + n > m->n_unix_fds_allocated)
2700  {
2701  unsigned k;
2702  int *p;
2703 
2704  /* Make twice as much space as necessary */
2705  k = (m->n_unix_fds + n) * 2;
2706 
2707  /* Allocate at least four */
2708  if (k < 4)
2709  k = 4;
2710 
2711  p = dbus_realloc(m->unix_fds, k * sizeof(int));
2712  if (p == NULL)
2713  return NULL;
2714 
2715  m->unix_fds = p;
2716  m->n_unix_fds_allocated = k;
2717  }
2718 
2719  return m->unix_fds + m->n_unix_fds;
2720 }
2721 #endif
2722 
2744  int type,
2745  const void *value)
2746 {
2747  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2748  dbus_bool_t ret;
2749 
2750  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2751  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2752  _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
2753  _dbus_return_val_if_fail (value != NULL, FALSE);
2754 
2755 #ifndef DBUS_DISABLE_CHECKS
2756  switch (type)
2757  {
2758  DBusString str;
2759  DBusValidity signature_validity;
2760  const char * const *string_p;
2761  const dbus_bool_t *bool_p;
2762 
2763  case DBUS_TYPE_STRING:
2764  string_p = value;
2765  _dbus_return_val_if_fail (_dbus_check_is_valid_utf8 (*string_p), FALSE);
2766  break;
2767 
2768  case DBUS_TYPE_OBJECT_PATH:
2769  string_p = value;
2770  _dbus_return_val_if_fail (_dbus_check_is_valid_path (*string_p), FALSE);
2771  break;
2772 
2773  case DBUS_TYPE_SIGNATURE:
2774  string_p = value;
2775  _dbus_string_init_const (&str, *string_p);
2776  signature_validity = _dbus_validate_signature_with_reason (&str,
2777  0,
2778  _dbus_string_get_length (&str));
2779 
2780  if (signature_validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
2781  return FALSE;
2782 
2783  _dbus_return_val_if_fail (signature_validity == DBUS_VALID, FALSE);
2784  break;
2785 
2786  case DBUS_TYPE_BOOLEAN:
2787  bool_p = value;
2788  _dbus_return_val_if_fail (*bool_p == 0 || *bool_p == 1, FALSE);
2789  break;
2790 
2791  default:
2792  {
2793  /* nothing to check, all possible values are allowed */
2794  }
2795  }
2796 #endif
2797 
2798  if (!_dbus_message_iter_open_signature (real))
2799  return FALSE;
2800 
2801  if (type == DBUS_TYPE_UNIX_FD)
2802  {
2803 #ifdef HAVE_UNIX_FD_PASSING
2804  int *fds;
2805  dbus_uint32_t u;
2806 
2807  ret = FALSE;
2808 
2809  /* First step, include the fd in the fd list of this message */
2810  if (!(fds = expand_fd_array(real->message, 1)))
2811  goto out;
2812 
2813  *fds = _dbus_dup(*(int*) value, NULL);
2814  if (*fds < 0)
2815  goto out;
2816 
2817  u = real->message->n_unix_fds;
2818 
2819  /* Second step, write the index to the fd */
2820  if (!(ret = _dbus_type_writer_write_basic (&real->u.writer, DBUS_TYPE_UNIX_FD, &u))) {
2821  _dbus_close(*fds, NULL);
2822  goto out;
2823  }
2824 
2825  real->message->n_unix_fds += 1;
2826  u += 1;
2827 
2828  /* Final step, update the header accordingly */
2832  &u);
2833 
2834  /* If any of these operations fail the message is
2835  hosed. However, no memory or fds should be leaked since what
2836  has been added to message has been added to the message, and
2837  can hence be accounted for when the message is being
2838  freed. */
2839 #else
2840  ret = FALSE;
2841  /* This is redundant (we could just fall through), but it avoids
2842  * -Wunused-label in builds that don't HAVE_UNIX_FD_PASSING */
2843  goto out;
2844 #endif
2845  }
2846  else
2847  {
2848  ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
2849  }
2850 
2851 out:
2852  if (!_dbus_message_iter_close_signature (real))
2853  ret = FALSE;
2854 
2855  return ret;
2856 }
2857 
2895  int element_type,
2896  const void *value,
2897  int n_elements)
2898 {
2899  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2900  dbus_bool_t ret;
2901 
2902  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2903  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2904  _dbus_return_val_if_fail (dbus_type_is_fixed (element_type) && element_type != DBUS_TYPE_UNIX_FD, FALSE);
2905  _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
2906  _dbus_return_val_if_fail (value != NULL, FALSE);
2907  _dbus_return_val_if_fail (n_elements >= 0, FALSE);
2908  _dbus_return_val_if_fail (n_elements <=
2910  FALSE);
2911 
2912 #ifndef DBUS_DISABLE_CHECKS
2913  if (element_type == DBUS_TYPE_BOOLEAN)
2914  {
2915  const dbus_bool_t * const *bools = value;
2916  int i;
2917 
2918  for (i = 0; i < n_elements; i++)
2919  {
2920  _dbus_return_val_if_fail ((*bools)[i] == 0 || (*bools)[i] == 1, FALSE);
2921  }
2922  }
2923 #endif
2924 
2925  ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
2926 
2927  return ret;
2928 }
2929 
2959  int type,
2960  const char *contained_signature,
2961  DBusMessageIter *sub)
2962 {
2963  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2964  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2965  DBusString contained_str;
2966  DBusValidity contained_signature_validity;
2967  dbus_bool_t ret;
2968 
2969  _dbus_return_val_if_fail (sub != NULL, FALSE);
2970  /* Do our best to make sure the sub-iterator doesn't contain something
2971  * valid-looking on failure */
2972  _dbus_message_real_iter_zero (real_sub);
2973 
2974  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2975  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2976  _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
2977  _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
2978  contained_signature == NULL) ||
2979  (type == DBUS_TYPE_DICT_ENTRY &&
2980  contained_signature == NULL) ||
2981  (type == DBUS_TYPE_VARIANT &&
2982  contained_signature != NULL) ||
2983  (type == DBUS_TYPE_ARRAY &&
2984  contained_signature != NULL), FALSE);
2985 
2986  /* this would fail if the contained_signature is a dict entry, since
2987  * dict entries are invalid signatures standalone (they must be in
2988  * an array)
2989  */
2990  if (contained_signature != NULL)
2991  {
2992  _dbus_string_init_const (&contained_str, contained_signature);
2993  contained_signature_validity = _dbus_validate_signature_with_reason (&contained_str,
2994  0,
2995  _dbus_string_get_length (&contained_str));
2996 
2997  if (contained_signature_validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
2998  return FALSE;
2999  }
3000  else
3001  {
3002  /* just some placeholder value */
3003  contained_signature_validity = DBUS_VALID_BUT_INCOMPLETE;
3004  }
3005 
3006  _dbus_return_val_if_fail ((type == DBUS_TYPE_ARRAY && contained_signature && *contained_signature == DBUS_DICT_ENTRY_BEGIN_CHAR) ||
3007  contained_signature == NULL ||
3008  contained_signature_validity == DBUS_VALID,
3009  FALSE);
3010 
3011  if (!_dbus_message_iter_open_signature (real))
3012  return FALSE;
3013 
3014  ret = FALSE;
3015  *real_sub = *real;
3016 
3017  if (contained_signature != NULL)
3018  {
3019  _dbus_string_init_const (&contained_str, contained_signature);
3020 
3021  ret = _dbus_type_writer_recurse (&real->u.writer,
3022  type,
3023  &contained_str, 0,
3024  &real_sub->u.writer);
3025  }
3026  else
3027  {
3028  ret = _dbus_type_writer_recurse (&real->u.writer,
3029  type,
3030  NULL, 0,
3031  &real_sub->u.writer);
3032  }
3033 
3034  if (!ret)
3035  _dbus_message_iter_abandon_signature (real);
3036 
3037  return ret;
3038 }
3039 
3040 
3062  DBusMessageIter *sub)
3063 {
3064  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3065  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
3066  dbus_bool_t ret;
3067 
3068  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
3069  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
3070  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
3071  _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
3072 
3073  ret = _dbus_type_writer_unrecurse (&real->u.writer,
3074  &real_sub->u.writer);
3075  _dbus_message_real_iter_zero (real_sub);
3076 
3077  if (!_dbus_message_iter_close_signature (real))
3078  ret = FALSE;
3079 
3080  return ret;
3081 }
3082 
3094 void
3096  DBusMessageIter *sub)
3097 {
3098  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3099  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
3100 
3101 #ifndef DBUS_DISABLE_CHECKS
3102  _dbus_return_if_fail (_dbus_message_iter_append_check (real));
3103  _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
3104  _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
3105  _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
3106 #endif
3107 
3108  _dbus_message_iter_abandon_signature (real);
3109  _dbus_message_real_iter_zero (real_sub);
3110 }
3111 
3153 void
3155  DBusMessageIter *sub)
3156 {
3157  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3158  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
3159 
3160  /* If both the parent and the child are zeroed out, then either we didn't
3161  * even get as far as successfully recursing into the parent, or we already
3162  * closed both the child and the parent. For example, in the code sample
3163  * in the doc-comment above, this happens for
3164  * abandon_container_if_open (&outer, &inner) if the first open_container
3165  * call failed, or if we reached result = TRUE and fell through. */
3166  if (_dbus_message_real_iter_is_zeroed (real) &&
3167  _dbus_message_real_iter_is_zeroed (real_sub))
3168  return;
3169 
3170 #ifndef DBUS_DISABLE_CHECKS
3171  /* If the child is not zeroed out, but the parent is, then something has
3172  * gone horribly wrong (in practice that would probably mean both are
3173  * uninitialized or corrupt, and the parent happens to have ended up
3174  * all-bytes-zero). */
3175  _dbus_return_if_fail (_dbus_message_iter_append_check (real));
3176  _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
3177 #endif
3178 
3179  /* If the parent is not zeroed out, but the child is, then either we did
3180  * not successfully open the child, or we already closed the child. This
3181  * means we do not own a reference to the parent's signature, so it would
3182  * be wrong to release it; so we must not call abandon_signature() here.
3183  * In the code sample in the doc-comment above, this happens for
3184  * abandon_container_if_open (&outer, &inner) if the second open_container
3185  * call failed, or if the second close_container call failed. */
3186  if (_dbus_message_real_iter_is_zeroed (real_sub))
3187  return;
3188 
3189 #ifndef DBUS_DISABLE_CHECKS
3190  _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
3191  _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
3192 #endif
3193 
3194  /* If neither the parent nor the child is zeroed out, then we genuinely
3195  * have an open container; close it. In the code sample in the doc-comment,
3196  * this happens for abandon_container_if_open (&outer, &inner) if the
3197  * append_basic call failed. */
3198  _dbus_message_iter_abandon_signature (real);
3199  _dbus_message_real_iter_zero (real_sub);
3200 }
3201 
3218 void
3220  dbus_bool_t no_reply)
3221 {
3222  _dbus_return_if_fail (message != NULL);
3223  _dbus_return_if_fail (!message->locked);
3224 
3225  _dbus_header_toggle_flag (&message->header,
3227  no_reply);
3228 }
3229 
3239 {
3240  _dbus_return_val_if_fail (message != NULL, FALSE);
3241 
3242  return _dbus_header_get_flag (&message->header,
3244 }
3245 
3260 void
3262  dbus_bool_t auto_start)
3263 {
3264  _dbus_return_if_fail (message != NULL);
3265  _dbus_return_if_fail (!message->locked);
3266 
3267  _dbus_header_toggle_flag (&message->header,
3269  !auto_start);
3270 }
3271 
3281 {
3282  _dbus_return_val_if_fail (message != NULL, FALSE);
3283 
3284  return !_dbus_header_get_flag (&message->header,
3286 }
3287 
3288 
3303  const char *object_path)
3304 {
3305  _dbus_return_val_if_fail (message != NULL, FALSE);
3306  _dbus_return_val_if_fail (!message->locked, FALSE);
3307  _dbus_return_val_if_fail (object_path == NULL ||
3308  _dbus_check_is_valid_path (object_path),
3309  FALSE);
3310 
3311  return set_or_delete_string_field (message,
3314  object_path);
3315 }
3316 
3330 const char*
3332 {
3333  const char *v;
3334 
3335  _dbus_return_val_if_fail (message != NULL, NULL);
3336 
3337  v = NULL; /* in case field doesn't exist */
3341  (void *) &v);
3342  return v;
3343 }
3344 
3356  const char *path)
3357 {
3358  const char *msg_path;
3359  msg_path = dbus_message_get_path (message);
3360 
3361  if (msg_path == NULL)
3362  {
3363  if (path == NULL)
3364  return TRUE;
3365  else
3366  return FALSE;
3367  }
3368 
3369  if (path == NULL)
3370  return FALSE;
3371 
3372  if (strcmp (msg_path, path) == 0)
3373  return TRUE;
3374 
3375  return FALSE;
3376 }
3377 
3400  char ***path)
3401 {
3402  const char *v;
3403 
3404  _dbus_return_val_if_fail (message != NULL, FALSE);
3405  _dbus_return_val_if_fail (path != NULL, FALSE);
3406 
3407  *path = NULL;
3408 
3409  v = dbus_message_get_path (message);
3410  if (v != NULL)
3411  {
3412  if (!_dbus_decompose_path (v, strlen (v),
3413  path, NULL))
3414  return FALSE;
3415  }
3416  return TRUE;
3417 }
3418 
3434  const char *iface)
3435 {
3436  _dbus_return_val_if_fail (message != NULL, FALSE);
3437  _dbus_return_val_if_fail (!message->locked, FALSE);
3438  _dbus_return_val_if_fail (iface == NULL ||
3439  _dbus_check_is_valid_interface (iface),
3440  FALSE);
3441 
3442  return set_or_delete_string_field (message,
3445  iface);
3446 }
3447 
3461 const char*
3463 {
3464  const char *v;
3465 
3466  _dbus_return_val_if_fail (message != NULL, NULL);
3467 
3468  v = NULL; /* in case field doesn't exist */
3472  (void *) &v);
3473  return v;
3474 }
3475 
3485  const char *iface)
3486 {
3487  const char *msg_interface;
3488  msg_interface = dbus_message_get_interface (message);
3489 
3490  if (msg_interface == NULL)
3491  {
3492  if (iface == NULL)
3493  return TRUE;
3494  else
3495  return FALSE;
3496  }
3497 
3498  if (iface == NULL)
3499  return FALSE;
3500 
3501  if (strcmp (msg_interface, iface) == 0)
3502  return TRUE;
3503 
3504  return FALSE;
3505 
3506 }
3507 
3522  const char *member)
3523 {
3524  _dbus_return_val_if_fail (message != NULL, FALSE);
3525  _dbus_return_val_if_fail (!message->locked, FALSE);
3526  _dbus_return_val_if_fail (member == NULL ||
3527  _dbus_check_is_valid_member (member),
3528  FALSE);
3529 
3530  return set_or_delete_string_field (message,
3533  member);
3534 }
3535 
3547 const char*
3549 {
3550  const char *v;
3551 
3552  _dbus_return_val_if_fail (message != NULL, NULL);
3553 
3554  v = NULL; /* in case field doesn't exist */
3558  (void *) &v);
3559  return v;
3560 }
3561 
3571  const char *member)
3572 {
3573  const char *msg_member;
3574  msg_member = dbus_message_get_member (message);
3575 
3576  if (msg_member == NULL)
3577  {
3578  if (member == NULL)
3579  return TRUE;
3580  else
3581  return FALSE;
3582  }
3583 
3584  if (member == NULL)
3585  return FALSE;
3586 
3587  if (strcmp (msg_member, member) == 0)
3588  return TRUE;
3589 
3590  return FALSE;
3591 
3592 }
3593 
3607  const char *error_name)
3608 {
3609  _dbus_return_val_if_fail (message != NULL, FALSE);
3610  _dbus_return_val_if_fail (!message->locked, FALSE);
3611  _dbus_return_val_if_fail (error_name == NULL ||
3612  _dbus_check_is_valid_error_name (error_name),
3613  FALSE);
3614 
3615  return set_or_delete_string_field (message,
3618  error_name);
3619 }
3620 
3631 const char*
3633 {
3634  const char *v;
3635 
3636  _dbus_return_val_if_fail (message != NULL, NULL);
3637 
3638  v = NULL; /* in case field doesn't exist */
3642  (void *) &v);
3643  return v;
3644 }
3645 
3661  const char *destination)
3662 {
3663  _dbus_return_val_if_fail (message != NULL, FALSE);
3664  _dbus_return_val_if_fail (!message->locked, FALSE);
3665  _dbus_return_val_if_fail (destination == NULL ||
3666  _dbus_check_is_valid_bus_name (destination),
3667  FALSE);
3668 
3669  return set_or_delete_string_field (message,
3672  destination);
3673 }
3674 
3684 const char*
3686 {
3687  const char *v;
3688 
3689  _dbus_return_val_if_fail (message != NULL, NULL);
3690 
3691  v = NULL; /* in case field doesn't exist */
3695  (void *) &v);
3696  return v;
3697 }
3698 
3715  const char *sender)
3716 {
3717  _dbus_return_val_if_fail (message != NULL, FALSE);
3718  _dbus_return_val_if_fail (!message->locked, FALSE);
3719  _dbus_return_val_if_fail (sender == NULL ||
3720  _dbus_check_is_valid_bus_name (sender),
3721  FALSE);
3722 
3723  return set_or_delete_string_field (message,
3726  sender);
3727 }
3728 
3744 const char*
3746 {
3747  const char *v;
3748 
3749  _dbus_return_val_if_fail (message != NULL, NULL);
3750 
3751  v = NULL; /* in case field doesn't exist */
3755  (void *) &v);
3756  return v;
3757 }
3758 
3777 const char*
3779 {
3780  const DBusString *type_str;
3781  int type_pos;
3782 
3783  _dbus_return_val_if_fail (message != NULL, NULL);
3784 
3785  get_const_signature (&message->header, &type_str, &type_pos);
3786 
3787  return _dbus_string_get_const_data_len (type_str, type_pos, 0);
3788 }
3789 
3790 static dbus_bool_t
3791 _dbus_message_has_type_interface_member (DBusMessage *message,
3792  int type,
3793  const char *iface,
3794  const char *member)
3795 {
3796  const char *n;
3797 
3798  _dbus_assert (message != NULL);
3799  _dbus_assert (iface != NULL);
3800  _dbus_assert (member != NULL);
3801 
3802  if (dbus_message_get_type (message) != type)
3803  return FALSE;
3804 
3805  /* Optimize by checking the short member name first
3806  * instead of the longer interface name
3807  */
3808 
3809  n = dbus_message_get_member (message);
3810 
3811  if (n && strcmp (n, member) == 0)
3812  {
3813  n = dbus_message_get_interface (message);
3814 
3815  if (n == NULL || strcmp (n, iface) == 0)
3816  return TRUE;
3817  }
3818 
3819  return FALSE;
3820 }
3821 
3838  const char *iface,
3839  const char *method)
3840 {
3841  _dbus_return_val_if_fail (message != NULL, FALSE);
3842  _dbus_return_val_if_fail (iface != NULL, FALSE);
3843  _dbus_return_val_if_fail (method != NULL, FALSE);
3844  /* don't check that interface/method are valid since it would be
3845  * expensive, and not catch many common errors
3846  */
3847 
3848  return _dbus_message_has_type_interface_member (message,
3850  iface, method);
3851 }
3852 
3866  const char *iface,
3867  const char *signal_name)
3868 {
3869  _dbus_return_val_if_fail (message != NULL, FALSE);
3870  _dbus_return_val_if_fail (iface != NULL, FALSE);
3871  _dbus_return_val_if_fail (signal_name != NULL, FALSE);
3872  /* don't check that interface/name are valid since it would be
3873  * expensive, and not catch many common errors
3874  */
3875 
3876  return _dbus_message_has_type_interface_member (message,
3878  iface, signal_name);
3879 }
3880 
3893  const char *error_name)
3894 {
3895  const char *n;
3896 
3897  _dbus_return_val_if_fail (message != NULL, FALSE);
3898  _dbus_return_val_if_fail (error_name != NULL, FALSE);
3899  /* don't check that error_name is valid since it would be expensive,
3900  * and not catch many common errors
3901  */
3902 
3904  return FALSE;
3905 
3906  n = dbus_message_get_error_name (message);
3907 
3908  if (n && strcmp (n, error_name) == 0)
3909  return TRUE;
3910  else
3911  return FALSE;
3912 }
3913 
3926  const char *name)
3927 {
3928  const char *s;
3929 
3930  _dbus_return_val_if_fail (message != NULL, FALSE);
3931  _dbus_return_val_if_fail (name != NULL, FALSE);
3932  /* don't check that name is valid since it would be expensive, and
3933  * not catch many common errors
3934  */
3935 
3936  s = dbus_message_get_destination (message);
3937 
3938  if (s && strcmp (s, name) == 0)
3939  return TRUE;
3940  else
3941  return FALSE;
3942 }
3943 
3961  const char *name)
3962 {
3963  const char *s;
3964 
3965  _dbus_return_val_if_fail (message != NULL, FALSE);
3966  _dbus_return_val_if_fail (name != NULL, FALSE);
3967  /* don't check that name is valid since it would be expensive, and
3968  * not catch many common errors
3969  */
3970 
3971  s = dbus_message_get_sender (message);
3972 
3973  if (s && strcmp (s, name) == 0)
3974  return TRUE;
3975  else
3976  return FALSE;
3977 }
3978 
3990  const char *signature)
3991 {
3992  const char *s;
3993 
3994  _dbus_return_val_if_fail (message != NULL, FALSE);
3995  _dbus_return_val_if_fail (signature != NULL, FALSE);
3996  /* don't check that signature is valid since it would be expensive,
3997  * and not catch many common errors
3998  */
3999 
4000  s = dbus_message_get_signature (message);
4001 
4002  if (s && strcmp (s, signature) == 0)
4003  return TRUE;
4004  else
4005  return FALSE;
4006 }
4007 
4032  DBusMessage *message)
4033 {
4034  const char *str;
4035 
4036  _dbus_return_val_if_fail (message != NULL, FALSE);
4037  _dbus_return_val_if_error_is_set (error, FALSE);
4038 
4040  return FALSE;
4041 
4042  str = NULL;
4043  dbus_message_get_args (message, NULL,
4044  DBUS_TYPE_STRING, &str,
4046 
4047  dbus_set_error (error, dbus_message_get_error_name (message),
4048  str ? "%s" : NULL, str);
4049 
4050  return TRUE;
4051 }
4052 
4061 {
4062 #ifdef HAVE_UNIX_FD_PASSING
4063  _dbus_assert(message);
4064 
4065  return message->n_unix_fds > 0;
4066 #else
4067  return FALSE;
4068 #endif
4069 }
4070 
4083  const char *object_path)
4084 {
4085  _dbus_return_val_if_fail (message != NULL, FALSE);
4086  _dbus_return_val_if_fail (!message->locked, FALSE);
4087  _dbus_return_val_if_fail (object_path == NULL ||
4088  _dbus_check_is_valid_path (object_path),
4089  FALSE);
4090 
4091  return set_or_delete_string_field (message,
4094  object_path);
4095 }
4096 
4107 const char *
4109 {
4110  const char *v;
4111 
4112  _dbus_return_val_if_fail (message != NULL, NULL);
4113 
4114  v = NULL; /* in case field doesn't exist */
4118  (void *) &v);
4119  return v;
4120 }
4121 
4140 #define INITIAL_LOADER_DATA_LEN 32
4141 
4150 {
4151  DBusMessageLoader *loader;
4152 
4153  loader = dbus_new0 (DBusMessageLoader, 1);
4154  if (loader == NULL)
4155  return NULL;
4156 
4157  loader->refcount = 1;
4158 
4159  loader->corrupted = FALSE;
4160  loader->corruption_reason = DBUS_VALID;
4161 
4162  /* this can be configured by the app, but defaults to the protocol max */
4164 
4165  /* We set a very relatively conservative default here since due to how
4166  SCM_RIGHTS works we need to preallocate an fd array of the maximum
4167  number of unix fds we want to receive in advance. A
4168  try-and-reallocate loop is not possible. */
4169  loader->max_message_unix_fds = DBUS_DEFAULT_MESSAGE_UNIX_FDS;
4170 
4171  if (!_dbus_string_init (&loader->data))
4172  {
4173  dbus_free (loader);
4174  return NULL;
4175  }
4176 
4177  /* preallocate the buffer for speed, ignore failure */
4179  _dbus_string_set_length (&loader->data, 0);
4180 
4181 #ifdef HAVE_UNIX_FD_PASSING
4182  loader->unix_fds = NULL;
4183  loader->n_unix_fds = loader->n_unix_fds_allocated = 0;
4184  loader->unix_fds_outstanding = FALSE;
4185 #endif
4186 
4187  return loader;
4188 }
4189 
4198 {
4199  loader->refcount += 1;
4200 
4201  return loader;
4202 }
4203 
4210 void
4212 {
4213  loader->refcount -= 1;
4214  if (loader->refcount == 0)
4215  {
4216 #ifdef HAVE_UNIX_FD_PASSING
4217  close_unix_fds(loader->unix_fds, &loader->n_unix_fds);
4218  dbus_free(loader->unix_fds);
4219 #endif
4220  _dbus_list_clear_full (&loader->messages,
4222  _dbus_string_free (&loader->data);
4223  dbus_free (loader);
4224  }
4225 }
4226 
4245 void
4247  DBusString **buffer,
4248  int *max_to_read,
4249  dbus_bool_t *may_read_fds)
4250 {
4251  _dbus_assert (!loader->buffer_outstanding);
4252 
4253  *buffer = &loader->data;
4254 
4255  loader->buffer_outstanding = TRUE;
4256 
4257  if (max_to_read != NULL)
4258  {
4259 #ifdef HAVE_UNIX_FD_PASSING
4260  int offset = 0;
4261  int remain;
4262  int byte_order;
4263  int fields_array_len;
4264  int header_len;
4265  int body_len;
4266 #endif
4267 
4268  *max_to_read = DBUS_MAXIMUM_MESSAGE_LENGTH;
4269  *may_read_fds = TRUE;
4270 
4271 #ifdef HAVE_UNIX_FD_PASSING
4272  /* If we aren't holding onto any fds, we can read as much as we want
4273  * (fast path). */
4274  if (loader->n_unix_fds == 0)
4275  return;
4276 
4277  /* Slow path: we have a message with some fds in it. We don't want
4278  * to start on the next message until this one is out of the way;
4279  * otherwise a legitimate sender can keep us processing messages
4280  * containing fds, until we disconnect it for having had fds pending
4281  * for too long, a limit that is in place to stop malicious senders
4282  * from setting up recursive fd-passing that takes up our quota and
4283  * will never go away. */
4284 
4285  remain = _dbus_string_get_length (&loader->data);
4286 
4287  while (remain > 0)
4288  {
4289  DBusValidity validity = DBUS_VALIDITY_UNKNOWN;
4290  int needed;
4291 
4292  /* If 0 < remain < DBUS_MINIMUM_HEADER_SIZE, then we've had at
4293  * least the first byte of a message, but we don't know how
4294  * much more to read. Only read the rest of the
4295  * DBUS_MINIMUM_HEADER_SIZE for now; then we'll know. */
4296  if (remain < DBUS_MINIMUM_HEADER_SIZE)
4297  {
4298  *max_to_read = DBUS_MINIMUM_HEADER_SIZE - remain;
4299  *may_read_fds = FALSE;
4300  return;
4301  }
4302 
4304  &validity,
4305  &byte_order,
4306  &fields_array_len,
4307  &header_len,
4308  &body_len,
4309  &loader->data,
4310  offset,
4311  remain))
4312  {
4313  /* If a message in the buffer is invalid, we're going to
4314  * disconnect the sender anyway, so reading an arbitrary amount
4315  * is fine. */
4316  if (validity != DBUS_VALID)
4317  return;
4318 
4319  /* We have a partial message, with the
4320  * DBUS_MINIMUM_HEADER_SIZE-byte fixed part of the header (which
4321  * lets us work out how much more we need), but no more. Read
4322  * the rest of the message. */
4323  needed = header_len + body_len;
4324  _dbus_assert (needed > remain);
4325  *max_to_read = needed - remain;
4326  *may_read_fds = FALSE;
4327  return;
4328  }
4329 
4330  /* Skip over entire messages until we have less than a message
4331  * remaining. */
4332  needed = header_len + body_len;
4334  _dbus_assert (remain >= needed);
4335  remain -= needed;
4336  offset += needed;
4337  }
4338 #endif
4339  }
4340 }
4341 
4351 void
4353  DBusString *buffer)
4354 {
4355  _dbus_assert (loader->buffer_outstanding);
4356  _dbus_assert (buffer == &loader->data);
4357 
4358  loader->buffer_outstanding = FALSE;
4359 }
4360 
4361 #ifdef HAVE_UNIX_FD_PASSING
4362 
4373 _dbus_message_loader_get_unix_fds(DBusMessageLoader *loader,
4374  int **fds,
4375  unsigned *max_n_fds)
4376 {
4377  _dbus_assert (!loader->unix_fds_outstanding);
4378 
4379  /* Allocate space where we can put the fds we read. We allocate
4380  space for max_message_unix_fds since this is an
4381  upper limit how many fds can be received within a single
4382  message. Since SCM_RIGHTS doesn't allow a reallocate+retry logic
4383  we are allocating the maximum possible array size right from the
4384  beginning. This sucks a bit, however unless SCM_RIGHTS is fixed
4385  there is no better way. */
4386 
4387  if (loader->n_unix_fds_allocated < loader->max_message_unix_fds)
4388  {
4389  int *a = dbus_realloc(loader->unix_fds,
4390  loader->max_message_unix_fds * sizeof(loader->unix_fds[0]));
4391 
4392  if (!a)
4393  return FALSE;
4394 
4395  loader->unix_fds = a;
4396  loader->n_unix_fds_allocated = loader->max_message_unix_fds;
4397  }
4398 
4399  *fds = loader->unix_fds + loader->n_unix_fds;
4400  *max_n_fds = loader->n_unix_fds_allocated - loader->n_unix_fds;
4401 
4402  loader->unix_fds_outstanding = TRUE;
4403  return TRUE;
4404 }
4405 
4416 void
4417 _dbus_message_loader_return_unix_fds(DBusMessageLoader *loader,
4418  int *fds,
4419  unsigned n_fds)
4420 {
4421  _dbus_assert(loader->unix_fds_outstanding);
4422  _dbus_assert(loader->unix_fds + loader->n_unix_fds == fds);
4423  _dbus_assert(loader->n_unix_fds + n_fds <= loader->n_unix_fds_allocated);
4424 
4425  loader->n_unix_fds += n_fds;
4426  loader->unix_fds_outstanding = FALSE;
4427 
4428  if (n_fds && loader->unix_fds_change)
4429  loader->unix_fds_change (loader->unix_fds_change_data);
4430 }
4431 #endif
4432 
4433 /*
4434  * FIXME when we move the header out of the buffer, that memmoves all
4435  * buffered messages. Kind of crappy.
4436  *
4437  * Also we copy the header and body, which is kind of crappy. To
4438  * avoid this, we have to allow header and body to be in a single
4439  * memory block, which is good for messages we read and bad for
4440  * messages we are creating. But we could move_len() the buffer into
4441  * this single memory block, and move_len() will just swap the buffers
4442  * if you're moving the entire buffer replacing the dest string.
4443  *
4444  * We could also have the message loader tell the transport how many
4445  * bytes to read; so it would first ask for some arbitrary number like
4446  * 256, then if the message was incomplete it would use the
4447  * header/body len to ask for exactly the size of the message (or
4448  * blocks the size of a typical kernel buffer for the socket). That
4449  * way we don't get trailing bytes in the buffer that have to be
4450  * memmoved. Though I suppose we also don't have a chance of reading a
4451  * bunch of small messages at once, so the optimization may be stupid.
4452  *
4453  * Another approach would be to keep a "start" index into
4454  * loader->data and only delete it occasionally, instead of after
4455  * each message is loaded.
4456  *
4457  * load_message() returns FALSE if not enough memory OR the loader was corrupted
4458  */
4459 static dbus_bool_t
4460 load_message (DBusMessageLoader *loader,
4461  DBusMessage *message,
4462  int byte_order,
4463  int fields_array_len,
4464  int header_len,
4465  int body_len)
4466 {
4467  dbus_bool_t oom;
4468  DBusValidity validity;
4469  const DBusString *type_str;
4470  int type_pos;
4471  DBusValidationMode mode;
4472  dbus_uint32_t n_unix_fds = 0;
4473 
4474  mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
4475 
4476  oom = FALSE;
4477 
4478 #if 0
4479  _dbus_verbose_bytes_of_string (&loader->data, 0, header_len /* + body_len */);
4480 #endif
4481 
4482  /* 1. VALIDATE AND COPY OVER HEADER */
4483  _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
4484  _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
4485 
4486  if (!_dbus_header_load (&message->header,
4487  mode,
4488  &validity,
4489  byte_order,
4490  fields_array_len,
4491  header_len,
4492  body_len,
4493  &loader->data))
4494  {
4495  _dbus_verbose ("Failed to load header for new message code %d\n", validity);
4496 
4497  /* assert here so we can catch any code that still uses DBUS_VALID to indicate
4498  oom errors. They should use DBUS_VALIDITY_UNKNOWN_OOM_ERROR instead */
4499  _dbus_assert (validity != DBUS_VALID);
4500 
4501  if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
4502  oom = TRUE;
4503  else
4504  {
4505  loader->corrupted = TRUE;
4506  loader->corruption_reason = validity;
4507  }
4508  goto failed;
4509  }
4510 
4511  _dbus_assert (validity == DBUS_VALID);
4512 
4513  /* 2. VALIDATE BODY */
4514  if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
4515  {
4516  get_const_signature (&message->header, &type_str, &type_pos);
4517 
4518  /* Because the bytes_remaining arg is NULL, this validates that the
4519  * body is the right length
4520  */
4521  validity = _dbus_validate_body_with_reason (type_str,
4522  type_pos,
4523  byte_order,
4524  NULL,
4525  &loader->data,
4526  header_len,
4527  body_len);
4528  if (validity != DBUS_VALID)
4529  {
4530  _dbus_verbose ("Failed to validate message body code %d\n", validity);
4531 
4532  loader->corrupted = TRUE;
4533  loader->corruption_reason = validity;
4534 
4535  goto failed;
4536  }
4537  }
4538 
4539  /* 3. COPY OVER UNIX FDS */
4543  &n_unix_fds);
4544 
4545 #ifdef HAVE_UNIX_FD_PASSING
4546 
4547  if (n_unix_fds > loader->n_unix_fds)
4548  {
4549  _dbus_verbose("Message contains references to more unix fds than were sent %u != %u\n",
4550  n_unix_fds, loader->n_unix_fds);
4551 
4552  loader->corrupted = TRUE;
4553  loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4554  goto failed;
4555  }
4556 
4557  /* If this was a recycled message there might still be
4558  some memory allocated for the fds */
4559  dbus_free(message->unix_fds);
4560 
4561  if (n_unix_fds > 0)
4562  {
4563  message->unix_fds = _dbus_memdup(loader->unix_fds, n_unix_fds * sizeof(message->unix_fds[0]));
4564  if (message->unix_fds == NULL)
4565  {
4566  _dbus_verbose ("Failed to allocate file descriptor array\n");
4567  oom = TRUE;
4568  goto failed;
4569  }
4570 
4571  message->n_unix_fds_allocated = message->n_unix_fds = n_unix_fds;
4572  loader->n_unix_fds -= n_unix_fds;
4573  memmove (loader->unix_fds, loader->unix_fds + n_unix_fds, loader->n_unix_fds * sizeof (loader->unix_fds[0]));
4574 
4575  if (loader->unix_fds_change)
4576  loader->unix_fds_change (loader->unix_fds_change_data);
4577  }
4578  else
4579  message->unix_fds = NULL;
4580 
4581 #else
4582 
4583  if (n_unix_fds > 0)
4584  {
4585  _dbus_verbose ("Hmm, message claims to come with file descriptors "
4586  "but that's not supported on our platform, disconnecting.\n");
4587 
4588  loader->corrupted = TRUE;
4589  loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4590  goto failed;
4591  }
4592 
4593 #endif
4594 
4595  /* 3. COPY OVER BODY AND QUEUE MESSAGE */
4596 
4597  if (!_dbus_list_append (&loader->messages, message))
4598  {
4599  _dbus_verbose ("Failed to append new message to loader queue\n");
4600  oom = TRUE;
4601  goto failed;
4602  }
4603 
4604  _dbus_assert (_dbus_string_get_length (&message->body) == 0);
4605  _dbus_assert (_dbus_string_get_length (&loader->data) >=
4606  (header_len + body_len));
4607 
4608  if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
4609  {
4610  _dbus_verbose ("Failed to move body into new message\n");
4611  oom = TRUE;
4612  goto failed;
4613  }
4614 
4615  _dbus_string_delete (&loader->data, 0, header_len + body_len);
4616 
4617  /* don't waste more than 2k of memory */
4618  _dbus_string_compact (&loader->data, 2048);
4619 
4620  _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
4621  _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
4622 
4623  _dbus_verbose ("Loaded message %p\n", message);
4624 
4625  _dbus_assert (!oom);
4626  _dbus_assert (!loader->corrupted);
4627  _dbus_assert (loader->messages != NULL);
4628  _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4629 
4630  return TRUE;
4631 
4632  failed:
4633 
4634  /* Clean up */
4635 
4636  /* does nothing if the message isn't in the list */
4637  _dbus_list_remove_last (&loader->messages, message);
4638 
4639  if (oom)
4640  _dbus_assert (!loader->corrupted);
4641  else
4642  _dbus_assert (loader->corrupted);
4643 
4644  _dbus_verbose_bytes_of_string (&loader->data, 0, _dbus_string_get_length (&loader->data));
4645 
4646  return FALSE;
4647 }
4648 
4665 {
4666  while (!loader->corrupted &&
4667  _dbus_string_get_length (&loader->data) >= DBUS_MINIMUM_HEADER_SIZE)
4668  {
4669  DBusValidity validity;
4670  int byte_order, fields_array_len, header_len, body_len;
4671 
4673  &validity,
4674  &byte_order,
4675  &fields_array_len,
4676  &header_len,
4677  &body_len,
4678  &loader->data, 0,
4679  _dbus_string_get_length (&loader->data)))
4680  {
4682 
4683  _dbus_assert (validity == DBUS_VALID);
4684 
4685  message = dbus_message_new_empty_header ();
4686  if (message == NULL)
4687  return FALSE;
4688 
4689  if (!load_message (loader, message,
4690  byte_order, fields_array_len,
4691  header_len, body_len))
4692  {
4693  dbus_message_unref (message);
4694  /* load_message() returns false if corrupted or OOM; if
4695  * corrupted then return TRUE for not OOM
4696  */
4697  return loader->corrupted;
4698  }
4699 
4700  _dbus_assert (loader->messages != NULL);
4701  _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4702  }
4703  else
4704  {
4705  _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
4706  validity);
4707  if (validity != DBUS_VALID)
4708  {
4709  loader->corrupted = TRUE;
4710  loader->corruption_reason = validity;
4711  }
4712  return TRUE;
4713  }
4714  }
4715 
4716  return TRUE;
4717 }
4718 
4726 DBusMessage*
4728 {
4729  if (loader->messages)
4730  return loader->messages->data;
4731  else
4732  return NULL;
4733 }
4734 
4743 DBusMessage*
4745 {
4746  return _dbus_list_pop_first (&loader->messages);
4747 }
4748 
4757 DBusList*
4759 {
4760  return _dbus_list_pop_first_link (&loader->messages);
4761 }
4762 
4769 void
4771  DBusList *link)
4772 {
4773  _dbus_list_prepend_link (&loader->messages, link);
4774 }
4775 
4787 {
4788  _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
4789  (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
4790  return loader->corrupted;
4791 }
4792 
4801 {
4802  _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
4803  (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
4804 
4805  return loader->corruption_reason;
4806 }
4807 
4814 void
4816  long size)
4817 {
4818  if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
4819  {
4820  _dbus_verbose ("clamping requested max message size %ld to %d\n",
4823  }
4824  loader->max_message_size = size;
4825 }
4826 
4833 long
4835 {
4836  return loader->max_message_size;
4837 }
4838 
4845 void
4847  long n)
4848 {
4850  {
4851  _dbus_verbose ("clamping requested max message unix_fds %ld to %d\n",
4854  }
4855  loader->max_message_unix_fds = n;
4856 }
4857 
4864 long
4866 {
4867  return loader->max_message_unix_fds;
4868 }
4869 
4875 int
4877 {
4878 #ifdef HAVE_UNIX_FD_PASSING
4879  return loader->n_unix_fds;
4880 #else
4881  return 0;
4882 #endif
4883 }
4884 
4893 void
4895  void (* callback) (void *),
4896  void *data)
4897 {
4898 #ifdef HAVE_UNIX_FD_PASSING
4899  loader->unix_fds_change = callback;
4900  loader->unix_fds_change_data = data;
4901 #endif
4902 }
4903 
4904 static DBusDataSlotAllocator slot_allocator =
4905  _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (message_slots));
4906 
4922 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
4923 {
4924  return _dbus_data_slot_allocator_alloc (&slot_allocator,
4925  slot_p);
4926 }
4927 
4939 void
4940 dbus_message_free_data_slot (dbus_int32_t *slot_p)
4941 {
4942  _dbus_return_if_fail (*slot_p >= 0);
4943 
4944  _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
4945 }
4946 
4962  dbus_int32_t slot,
4963  void *data,
4964  DBusFreeFunction free_data_func)
4965 {
4966  DBusFreeFunction old_free_func;
4967  void *old_data;
4968  dbus_bool_t retval;
4969 
4970  _dbus_return_val_if_fail (message != NULL, FALSE);
4971  _dbus_return_val_if_fail (slot >= 0, FALSE);
4972 
4973  retval = _dbus_data_slot_list_set (&slot_allocator,
4974  &message->slot_list,
4975  slot, data, free_data_func,
4976  &old_free_func, &old_data);
4977 
4978  if (retval)
4979  {
4980  /* Do the actual free outside the message lock */
4981  if (old_free_func)
4982  (* old_free_func) (old_data);
4983  }
4984 
4985  return retval;
4986 }
4987 
4996 void*
4998  dbus_int32_t slot)
4999 {
5000  void *res;
5001 
5002  _dbus_return_val_if_fail (message != NULL, NULL);
5003 
5004  res = _dbus_data_slot_list_get (&slot_allocator,
5005  &message->slot_list,
5006  slot);
5007 
5008  return res;
5009 }
5010 
5024 int
5025 dbus_message_type_from_string (const char *type_str)
5026 {
5027  if (strcmp (type_str, "method_call") == 0)
5029  if (strcmp (type_str, "method_return") == 0)
5031  else if (strcmp (type_str, "signal") == 0)
5032  return DBUS_MESSAGE_TYPE_SIGNAL;
5033  else if (strcmp (type_str, "error") == 0)
5034  return DBUS_MESSAGE_TYPE_ERROR;
5035  else
5037 }
5038 
5052 const char *
5054 {
5055  switch (type)
5056  {
5058  return "method_call";
5060  return "method_return";
5062  return "signal";
5064  return "error";
5065  default:
5066  return "invalid";
5067  }
5068 }
5069 
5084  char **marshalled_data_p,
5085  int *len_p)
5086 {
5087  DBusString tmp;
5088  dbus_bool_t was_locked;
5089 
5090  _dbus_return_val_if_fail (msg != NULL, FALSE);
5091  _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
5092  _dbus_return_val_if_fail (len_p != NULL, FALSE);
5093 
5094  if (!_dbus_string_init (&tmp))
5095  return FALSE;
5096 
5097  /* Ensure the message is locked, to ensure the length header is filled in. */
5098  was_locked = msg->locked;
5099 
5100  if (!was_locked)
5101  dbus_message_lock (msg);
5102 
5103  if (!_dbus_string_copy (&(msg->header.data), 0, &tmp, 0))
5104  goto fail;
5105 
5106  *len_p = _dbus_string_get_length (&tmp);
5107 
5108  if (!_dbus_string_copy (&(msg->body), 0, &tmp, *len_p))
5109  goto fail;
5110 
5111  *len_p = _dbus_string_get_length (&tmp);
5112 
5113  if (!_dbus_string_steal_data (&tmp, marshalled_data_p))
5114  goto fail;
5115 
5116  _dbus_string_free (&tmp);
5117 
5118  if (!was_locked)
5119  msg->locked = FALSE;
5120 
5121  return TRUE;
5122 
5123  fail:
5124  _dbus_string_free (&tmp);
5125 
5126  if (!was_locked)
5127  msg->locked = FALSE;
5128 
5129  return FALSE;
5130 }
5131 
5144 DBusMessage *
5145 dbus_message_demarshal (const char *str,
5146  int len,
5147  DBusError *error)
5148 {
5149  DBusMessageLoader *loader = NULL;
5150  DBusString *buffer;
5151  DBusMessage *msg;
5152 
5153  _dbus_return_val_if_fail (str != NULL, NULL);
5154 
5155  loader = _dbus_message_loader_new ();
5156 
5157  if (loader == NULL)
5158  goto fail_oom;
5159 
5160  _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL);
5161 
5162  if (!_dbus_string_append_len (buffer, str, len))
5163  goto fail_oom;
5164 
5165  _dbus_message_loader_return_buffer (loader, buffer);
5166 
5168  goto fail_oom;
5169 
5171  goto fail_corrupt;
5172 
5173  msg = _dbus_message_loader_pop_message (loader);
5174 
5175  if (!msg)
5176  goto fail_oom;
5177 
5178  _dbus_message_loader_unref (loader);
5179  return msg;
5180 
5181  fail_corrupt:
5182  dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted (%s)",
5183  _dbus_validity_to_error_message (loader->corruption_reason));
5184  _dbus_message_loader_unref (loader);
5185  return NULL;
5186 
5187  fail_oom:
5188  _DBUS_SET_OOM (error);
5189 
5190  if (loader != NULL)
5191  _dbus_message_loader_unref (loader);
5192 
5193  return NULL;
5194 }
5195 
5208 int
5210  int len)
5211 {
5212  DBusString str;
5213  int byte_order, fields_array_len, header_len, body_len;
5214  DBusValidity validity = DBUS_VALID;
5215  int have_message;
5216 
5217  if (!buf || len < DBUS_MINIMUM_HEADER_SIZE)
5218  return 0;
5219 
5220  if (len > DBUS_MAXIMUM_MESSAGE_LENGTH)
5222  _dbus_string_init_const_len (&str, buf, len);
5223 
5224  validity = DBUS_VALID;
5225  have_message
5227  &validity, &byte_order,
5228  &fields_array_len,
5229  &header_len,
5230  &body_len,
5231  &str, 0,
5232  len);
5233  _dbus_string_free (&str);
5234 
5235  if (validity == DBUS_VALID)
5236  {
5237  _dbus_assert (have_message || (header_len + body_len) > len);
5238  (void) have_message; /* unused unless asserting */
5239  return header_len + body_len;
5240  }
5241  else
5242  {
5243  return -1; /* broken! */
5244  }
5245 }
5246 
5268 void
5270  dbus_bool_t allow)
5271 {
5272  _dbus_return_if_fail (message != NULL);
5273  _dbus_return_if_fail (!message->locked);
5274 
5275  _dbus_header_toggle_flag (&message->header,
5277  allow);
5278 }
5279 
5288 {
5289  _dbus_return_val_if_fail (message != NULL, FALSE);
5290 
5291  return _dbus_header_get_flag (&message->header,
5293 }
5294 
5302 {
5303  DBusString data;
5304 };
5305 
5317 DBusVariant *
5319 {
5320  DBusVariant *self = NULL;
5321  /* Points to the single item we will read from the reader */
5322  DBusMessageRealIter *real_reader = (DBusMessageRealIter *) reader;
5323  /* The position in self at which we will write a single variant
5324  * (it is position 0) */
5325  DBusTypeWriter items_writer;
5326  /* The position in self at which we will write a copy of reader
5327  * (it is inside the variant) */
5328  DBusTypeWriter variant_writer;
5329  /* 'v' */
5330  DBusString variant_signature;
5331  /* Whatever is the signature of the item we will copy from the reader */
5332  DBusString contained_signature;
5333  /* TRUE if self->data needs to be freed */
5334  dbus_bool_t data_inited = FALSE;
5335  /* The type of the item we will read from the reader */
5336  int type;
5337  /* The string, start position within that string, and length of the signature
5338  * of the single complete type of the item reader points to */
5339  const DBusString *sig;
5340  int start, len;
5341 
5342  _dbus_assert (_dbus_message_iter_check (real_reader));
5343  _dbus_assert (real_reader->iter_type == DBUS_MESSAGE_ITER_TYPE_READER);
5345  type = dbus_message_iter_get_arg_type (reader);
5346  _dbus_type_reader_get_signature (&real_reader->u.reader, &sig, &start, &len);
5347 
5348  if (!_dbus_string_init (&contained_signature))
5349  return NULL;
5350 
5351  if (!_dbus_string_copy_len (sig, start, len, &contained_signature, 0))
5352  goto oom;
5353 
5354  self = dbus_new0 (DBusVariant, 1);
5355 
5356  if (self == NULL)
5357  goto oom;
5358 
5359  if (!_dbus_string_init (&self->data))
5360  goto oom;
5361 
5362  data_inited = TRUE;
5363 
5364  _dbus_type_writer_init_values_only (&items_writer, DBUS_COMPILER_BYTE_ORDER,
5365  &variant_signature, 0, &self->data, 0);
5366 
5367  if (!_dbus_type_writer_recurse (&items_writer, DBUS_TYPE_VARIANT,
5368  &contained_signature, 0, &variant_writer))
5369  goto oom;
5370 
5371  if (type == DBUS_TYPE_ARRAY)
5372  {
5373  /* Points to each item in turn inside the array we are copying */
5374  DBusMessageIter array_reader;
5375  /* Same as array_reader */
5376  DBusMessageRealIter *real_array_reader = (DBusMessageRealIter *) &array_reader;
5377  /* The position inside the copied array at which we will write
5378  * the copy of array_reader */
5379  DBusTypeWriter array_writer;
5380 
5381  dbus_message_iter_recurse (reader, &array_reader);
5382 
5383  if (!_dbus_type_writer_recurse (&variant_writer, type,
5384  &contained_signature, 1, &array_writer))
5385  goto oom;
5386 
5387  if (!_dbus_type_writer_write_reader (&array_writer,
5388  &real_array_reader->u.reader))
5389  goto oom;
5390 
5391  if (!_dbus_type_writer_unrecurse (&variant_writer, &array_writer))
5392  goto oom;
5393  }
5394  else if (type == DBUS_TYPE_DICT_ENTRY || type == DBUS_TYPE_VARIANT ||
5395  type == DBUS_TYPE_STRUCT)
5396  {
5397  /* Points to each item in turn inside the container we are copying */
5398  DBusMessageIter inner_reader;
5399  /* Same as inner_reader */
5400  DBusMessageRealIter *real_inner_reader = (DBusMessageRealIter *) &inner_reader;
5401  /* The position inside the copied container at which we will write the
5402  * copy of inner_reader */
5403  DBusTypeWriter inner_writer;
5404 
5405  dbus_message_iter_recurse (reader, &inner_reader);
5406 
5407  if (!_dbus_type_writer_recurse (&variant_writer, type, NULL, 0,
5408  &inner_writer))
5409  goto oom;
5410 
5411  if (!_dbus_type_writer_write_reader (&inner_writer,
5412  &real_inner_reader->u.reader))
5413  goto oom;
5414 
5415  if (!_dbus_type_writer_unrecurse (&variant_writer, &inner_writer))
5416  goto oom;
5417  }
5418  else
5419  {
5420  DBusBasicValue value;
5421 
5422  /* We eliminated all the container types above */
5424 
5425  dbus_message_iter_get_basic (reader, &value);
5426 
5427  if (!_dbus_type_writer_write_basic (&variant_writer, type, &value))
5428  goto oom;
5429  }
5430 
5431  _dbus_string_free (&contained_signature);
5432  return self;
5433 
5434 oom:
5435  if (self != NULL)
5436  {
5437  if (data_inited)
5438  _dbus_string_free (&self->data);
5439 
5440  dbus_free (self);
5441  }
5442 
5443  _dbus_string_free (&contained_signature);
5444  return NULL;
5445 }
5446 
5453 const char *
5455 {
5456  unsigned char len;
5457  const char *ret;
5458 
5459  _dbus_assert (self != NULL);
5460 
5461  /* Here we make use of the fact that the serialization of a variant starts
5462  * with the 1-byte length, then that many bytes of signature, then \0. */
5463  len = _dbus_string_get_byte (&self->data, 0);
5464  ret = _dbus_string_get_const_data_len (&self->data, 1, len);
5465  _dbus_assert (strlen (ret) == len);
5466  return ret;
5467 }
5468 
5483 {
5484  /* 'v' */
5485  DBusString variant_signature;
5486  /* Points to the single item in self */
5487  DBusTypeReader variant_reader;
5488  /* Points to the single item (of whatever type) inside the variant */
5490  /* The position at which we will copy reader */
5491  DBusMessageRealIter *real_writer = (DBusMessageRealIter *) writer;
5492  dbus_bool_t ret;
5493 
5494  _dbus_assert (self != NULL);
5495  _dbus_assert (_dbus_message_iter_append_check (real_writer));
5496  _dbus_assert (real_writer->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
5497 
5499  _dbus_type_reader_init (&reader, DBUS_COMPILER_BYTE_ORDER,
5500  &variant_signature, 0, &self->data, 0);
5501  _dbus_type_reader_recurse (&reader, &variant_reader);
5502 
5503  if (!_dbus_message_iter_open_signature (real_writer))
5504  return FALSE;
5505 
5506  ret = _dbus_type_writer_write_reader (&real_writer->u.writer,
5507  &variant_reader);
5508 
5509  if (!_dbus_message_iter_close_signature (real_writer))
5510  return FALSE;
5511 
5512  return ret;
5513 }
5514 
5515 int
5516 _dbus_variant_get_length (DBusVariant *self)
5517 {
5518  _dbus_assert (self != NULL);
5519  return _dbus_string_get_length (&self->data);
5520 }
5521 
5522 const DBusString *
5523 _dbus_variant_peek (DBusVariant *self)
5524 {
5525  _dbus_assert (self != NULL);
5526  return &self->data;
5527 }
5528 
5529 void
5530 _dbus_variant_free (DBusVariant *self)
5531 {
5532  _dbus_assert (self != NULL);
5533  _dbus_string_free (&self->data);
5534  dbus_free (self);
5535 }
5536 
5539 /* 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...
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:182
#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:1096
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:1307
#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)
void _dbus_type_reader_read_fixed_multi(const DBusTypeReader *reader, const void **value, int *n_elements)
Reads a block of fixed-length basic values, from the current point in an array to the end of the arra...
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:413
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:197
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:1217
dbus_bool_t _dbus_string_init_preallocated(DBusString *str, int allocate_size)
Initializes a string that can be up to the given allocation size before it has to realloc...
Definition: dbus-string.c:139
void _dbus_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:271
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:1161
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:826
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:1399
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:665
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:217
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...