D-Bus  1.6.18
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_BUILD_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 {
132  union
133  {
136  } u;
137 };
138 
139 static void
140 get_const_signature (DBusHeader *header,
141  const DBusString **type_str_p,
142  int *type_pos_p)
143 {
144  if (_dbus_header_get_field_raw (header,
146  type_str_p,
147  type_pos_p))
148  {
149  *type_pos_p += 1; /* skip the signature length which is 1 byte */
150  }
151  else
152  {
153  *type_str_p = &_dbus_empty_signature_str;
154  *type_pos_p = 0;
155  }
156 }
157 
163 static void
164 _dbus_message_byteswap (DBusMessage *message)
165 {
166  const DBusString *type_str;
167  int type_pos;
168  char byte_order;
169 
170  byte_order = _dbus_header_get_byte_order (&message->header);
171 
172  if (byte_order == DBUS_COMPILER_BYTE_ORDER)
173  return;
174 
175  _dbus_verbose ("Swapping message into compiler byte order\n");
176 
177  get_const_signature (&message->header, &type_str, &type_pos);
178 
179  _dbus_marshal_byteswap (type_str, type_pos,
180  byte_order,
181  DBUS_COMPILER_BYTE_ORDER,
182  &message->body, 0);
183 
184  _dbus_header_byteswap (&message->header, DBUS_COMPILER_BYTE_ORDER);
186  DBUS_COMPILER_BYTE_ORDER);
187 }
188 
195 #define ensure_byte_order(message) _dbus_message_byteswap (message)
196 
207 void
209  const DBusString **header,
210  const DBusString **body)
211 {
212  _dbus_assert (message->locked);
213 
214  *header = &message->header.data;
215  *body = &message->body;
216 }
217 
228  const int **fds,
229  unsigned *n_fds)
230 {
231  _dbus_assert (message->locked);
232 
233 #ifdef HAVE_UNIX_FD_PASSING
234  *fds = message->unix_fds;
235  *n_fds = message->n_unix_fds;
236 #else
237  *fds = NULL;
238  *n_fds = 0;
239 #endif
240 }
241 
253 void
255  dbus_uint32_t serial)
256 {
257  _dbus_return_if_fail (message != NULL);
258  _dbus_return_if_fail (!message->locked);
259 
260  _dbus_header_set_serial (&message->header, serial);
261 }
262 
279 void
281  DBusList *link)
282 {
283  /* right now we don't recompute the delta when message
284  * size changes, and that's OK for current purposes
285  * I think, but could be important to change later.
286  * Do recompute it whenever there are no outstanding counters,
287  * since it's basically free.
288  */
289  if (message->counters == NULL)
290  {
291  message->size_counter_delta =
292  _dbus_string_get_length (&message->header.data) +
293  _dbus_string_get_length (&message->body);
294 
295 #ifdef HAVE_UNIX_FD_PASSING
296  message->unix_fd_counter_delta = message->n_unix_fds;
297 #endif
298 
299 #if 0
300  _dbus_verbose ("message has size %ld\n",
301  message->size_counter_delta);
302 #endif
303  }
304 
305  _dbus_list_append_link (&message->counters, link);
306 
308 
309 #ifdef HAVE_UNIX_FD_PASSING
310  _dbus_counter_adjust_unix_fd (link->data, message->unix_fd_counter_delta);
311 #endif
312 }
313 
330  DBusCounter *counter)
331 {
332  DBusList *link;
333 
334  link = _dbus_list_alloc_link (counter);
335  if (link == NULL)
336  return FALSE;
337 
338  _dbus_counter_ref (counter);
339  _dbus_message_add_counter_link (message, link);
340 
341  return TRUE;
342 }
343 
351 void
353  DBusCounter *counter)
354 {
355  DBusList *link;
356 
357  link = _dbus_list_find_last (&message->counters,
358  counter);
359  _dbus_assert (link != NULL);
360 
361  _dbus_list_remove_link (&message->counters, link);
362 
363  _dbus_counter_adjust_size (counter, - message->size_counter_delta);
364 
365 #ifdef HAVE_UNIX_FD_PASSING
366  _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
367 #endif
368 
369  _dbus_counter_notify (counter);
370  _dbus_counter_unref (counter);
371 }
372 
383 void
385 {
386  if (!message->locked)
387  {
389  _dbus_string_get_length (&message->body));
390 
391  /* must have a signature if you have a body */
392  _dbus_assert (_dbus_string_get_length (&message->body) == 0 ||
393  dbus_message_get_signature (message) != NULL);
394 
395  message->locked = TRUE;
396  }
397 }
398 
399 static dbus_bool_t
400 set_or_delete_string_field (DBusMessage *message,
401  int field,
402  int typecode,
403  const char *value)
404 {
405  if (value == NULL)
406  return _dbus_header_delete_field (&message->header, field);
407  else
408  return _dbus_header_set_field_basic (&message->header,
409  field,
410  typecode,
411  &value);
412 }
413 
414 #if 0
415 /* Probably we don't need to use this */
439 static dbus_bool_t
440 _dbus_message_set_signature (DBusMessage *message,
441  const char *signature)
442 {
443  _dbus_return_val_if_fail (message != NULL, FALSE);
444  _dbus_return_val_if_fail (!message->locked, FALSE);
445  _dbus_return_val_if_fail (signature == NULL ||
446  _dbus_check_is_valid_signature (signature));
447  /* can't delete the signature if you have a message body */
448  _dbus_return_val_if_fail (_dbus_string_get_length (&message->body) == 0 ||
449  signature != NULL);
450 
451  return set_or_delete_string_field (message,
454  signature);
455 }
456 #endif
457 
458 /* Message Cache
459  *
460  * We cache some DBusMessage to reduce the overhead of allocating
461  * them. In my profiling this consistently made about an 8%
462  * difference. It avoids the malloc for the message, the malloc for
463  * the slot list, the malloc for the header string and body string,
464  * and the associated free() calls. It does introduce another global
465  * lock which could be a performance issue in certain cases.
466  *
467  * For the echo client/server the round trip time goes from around
468  * .000077 to .000069 with the message cache on my laptop. The sysprof
469  * change is as follows (numbers are cumulative percentage):
470  *
471  * with message cache implemented as array as it is now (0.000069 per):
472  * new_empty_header 1.46
473  * mutex_lock 0.56 # i.e. _DBUS_LOCK(message_cache)
474  * mutex_unlock 0.25
475  * self 0.41
476  * unref 2.24
477  * self 0.68
478  * list_clear 0.43
479  * mutex_lock 0.33 # i.e. _DBUS_LOCK(message_cache)
480  * mutex_unlock 0.25
481  *
482  * with message cache implemented as list (0.000070 per roundtrip):
483  * new_empty_header 2.72
484  * list_pop_first 1.88
485  * unref 3.3
486  * list_prepend 1.63
487  *
488  * without cache (0.000077 per roundtrip):
489  * new_empty_header 6.7
490  * string_init_preallocated 3.43
491  * dbus_malloc 2.43
492  * dbus_malloc0 2.59
493  *
494  * unref 4.02
495  * string_free 1.82
496  * dbus_free 1.63
497  * dbus_free 0.71
498  *
499  * If you implement the message_cache with a list, the primary reason
500  * it's slower is that you add another thread lock (on the DBusList
501  * mempool).
502  */
503 
505 #define MAX_MESSAGE_SIZE_TO_CACHE 10 * _DBUS_ONE_KILOBYTE
506 
508 #define MAX_MESSAGE_CACHE_SIZE 5
509 
510 _DBUS_DEFINE_GLOBAL_LOCK (message_cache);
511 static DBusMessage *message_cache[MAX_MESSAGE_CACHE_SIZE];
512 static int message_cache_count = 0;
513 static dbus_bool_t message_cache_shutdown_registered = FALSE;
514 
515 static void
516 dbus_message_cache_shutdown (void *data)
517 {
518  int i;
519 
520  _DBUS_LOCK (message_cache);
521 
522  i = 0;
523  while (i < MAX_MESSAGE_CACHE_SIZE)
524  {
525  if (message_cache[i])
526  dbus_message_finalize (message_cache[i]);
527 
528  ++i;
529  }
530 
531  message_cache_count = 0;
532  message_cache_shutdown_registered = FALSE;
533 
534  _DBUS_UNLOCK (message_cache);
535 }
536 
544 static DBusMessage*
545 dbus_message_get_cached (void)
546 {
547  DBusMessage *message;
548  int i;
549 
550  message = NULL;
551 
552  _DBUS_LOCK (message_cache);
553 
554  _dbus_assert (message_cache_count >= 0);
555 
556  if (message_cache_count == 0)
557  {
558  _DBUS_UNLOCK (message_cache);
559  return NULL;
560  }
561 
562  /* This is not necessarily true unless count > 0, and
563  * message_cache is uninitialized until the shutdown is
564  * registered
565  */
566  _dbus_assert (message_cache_shutdown_registered);
567 
568  i = 0;
569  while (i < MAX_MESSAGE_CACHE_SIZE)
570  {
571  if (message_cache[i])
572  {
573  message = message_cache[i];
574  message_cache[i] = NULL;
575  message_cache_count -= 1;
576  break;
577  }
578  ++i;
579  }
580  _dbus_assert (message_cache_count >= 0);
582  _dbus_assert (message != NULL);
583 
584  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
585 
586  _dbus_assert (message->counters == NULL);
587 
588  _DBUS_UNLOCK (message_cache);
589 
590  return message;
591 }
592 
593 #ifdef HAVE_UNIX_FD_PASSING
594 static void
595 close_unix_fds(int *fds, unsigned *n_fds)
596 {
597  DBusError e;
598  int i;
599 
600  if (*n_fds <= 0)
601  return;
602 
603  dbus_error_init(&e);
604 
605  for (i = 0; i < *n_fds; i++)
606  {
607  if (!_dbus_close(fds[i], &e))
608  {
609  _dbus_warn("Failed to close file descriptor: %s\n", e.message);
610  dbus_error_free(&e);
611  }
612  }
613 
614  *n_fds = 0;
615 
616  /* We don't free the array here, in case we can recycle it later */
617 }
618 #endif
619 
620 static void
621 free_counter (void *element,
622  void *data)
623 {
624  DBusCounter *counter = element;
625  DBusMessage *message = data;
626 
627  _dbus_counter_adjust_size (counter, - message->size_counter_delta);
628 #ifdef HAVE_UNIX_FD_PASSING
629  _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
630 #endif
631 
632  _dbus_counter_notify (counter);
633  _dbus_counter_unref (counter);
634 }
635 
641 static void
642 dbus_message_cache_or_finalize (DBusMessage *message)
643 {
644  dbus_bool_t was_cached;
645  int i;
646 
647  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
648 
649  /* This calls application code and has to be done first thing
650  * without holding the lock
651  */
653 
654  _dbus_list_foreach (&message->counters,
655  free_counter, message);
656  _dbus_list_clear (&message->counters);
657 
658 #ifdef HAVE_UNIX_FD_PASSING
659  close_unix_fds(message->unix_fds, &message->n_unix_fds);
660 #endif
661 
662  was_cached = FALSE;
663 
664  _DBUS_LOCK (message_cache);
665 
666  if (!message_cache_shutdown_registered)
667  {
668  _dbus_assert (message_cache_count == 0);
669 
670  if (!_dbus_register_shutdown_func (dbus_message_cache_shutdown, NULL))
671  goto out;
672 
673  i = 0;
674  while (i < MAX_MESSAGE_CACHE_SIZE)
675  {
676  message_cache[i] = NULL;
677  ++i;
678  }
679 
680  message_cache_shutdown_registered = TRUE;
681  }
682 
683  _dbus_assert (message_cache_count >= 0);
684 
685  if (!_dbus_enable_message_cache ())
686  goto out;
687 
688  if ((_dbus_string_get_length (&message->header.data) +
689  _dbus_string_get_length (&message->body)) >
691  goto out;
692 
693  if (message_cache_count >= MAX_MESSAGE_CACHE_SIZE)
694  goto out;
695 
696  /* Find empty slot */
697  i = 0;
698  while (message_cache[i] != NULL)
699  ++i;
700 
702 
703  _dbus_assert (message_cache[i] == NULL);
704  message_cache[i] = message;
705  message_cache_count += 1;
706  was_cached = TRUE;
707 #ifndef DBUS_DISABLE_CHECKS
708  message->in_cache = TRUE;
709 #endif
710 
711  out:
712  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
713 
714  _DBUS_UNLOCK (message_cache);
715 
716  if (!was_cached)
717  dbus_message_finalize (message);
718 }
719 
720 #ifndef DBUS_DISABLE_CHECKS
721 static dbus_bool_t
722 _dbus_message_iter_check (DBusMessageRealIter *iter)
723 {
724  char byte_order;
725 
726  if (iter == NULL)
727  {
728  _dbus_warn_check_failed ("dbus message iterator is NULL\n");
729  return FALSE;
730  }
731 
732  byte_order = _dbus_header_get_byte_order (&iter->message->header);
733 
734  if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_READER)
735  {
736  if (iter->u.reader.byte_order != byte_order)
737  {
738  _dbus_warn_check_failed ("dbus message changed byte order since iterator was created\n");
739  return FALSE;
740  }
741  /* because we swap the message into compiler order when you init an iter */
742  _dbus_assert (iter->u.reader.byte_order == DBUS_COMPILER_BYTE_ORDER);
743  }
744  else if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER)
745  {
746  if (iter->u.writer.byte_order != byte_order)
747  {
748  _dbus_warn_check_failed ("dbus message changed byte order since append iterator was created\n");
749  return FALSE;
750  }
751  /* because we swap the message into compiler order when you init an iter */
752  _dbus_assert (iter->u.writer.byte_order == DBUS_COMPILER_BYTE_ORDER);
753  }
754  else
755  {
756  _dbus_warn_check_failed ("dbus message iterator looks uninitialized or corrupted\n");
757  return FALSE;
758  }
759 
760  if (iter->changed_stamp != iter->message->changed_stamp)
761  {
762  _dbus_warn_check_failed ("dbus message iterator invalid because the message has been modified (or perhaps the iterator is just uninitialized)\n");
763  return FALSE;
764  }
765 
766  return TRUE;
767 }
768 #endif /* DBUS_DISABLE_CHECKS */
769 
786  DBusError *error,
787  int first_arg_type,
788  va_list var_args)
789 {
791  int spec_type, msg_type, i;
792  dbus_bool_t retval;
793 
794  _dbus_assert (_dbus_message_iter_check (real));
795 
796  retval = FALSE;
797 
798  spec_type = first_arg_type;
799  i = 0;
800 
801  while (spec_type != DBUS_TYPE_INVALID)
802  {
803  msg_type = dbus_message_iter_get_arg_type (iter);
804 
805  if (msg_type != spec_type)
806  {
808  "Argument %d is specified to be of type \"%s\", but "
809  "is actually of type \"%s\"\n", i,
810  _dbus_type_to_string (spec_type),
811  _dbus_type_to_string (msg_type));
812 
813  goto out;
814  }
815 
816  if (spec_type == DBUS_TYPE_UNIX_FD)
817  {
818 #ifdef HAVE_UNIX_FD_PASSING
819  DBusBasicValue idx;
820  int *pfd, nfd;
821 
822  pfd = va_arg (var_args, int*);
823  _dbus_assert(pfd);
824 
825  _dbus_type_reader_read_basic(&real->u.reader, &idx);
826 
827  if (idx.u32 >= real->message->n_unix_fds)
828  {
830  "Message refers to file descriptor at index %i,"
831  "but has only %i descriptors attached.\n",
832  idx.u32,
833  real->message->n_unix_fds);
834  goto out;
835  }
836 
837  if ((nfd = _dbus_dup(real->message->unix_fds[idx.u32], error)) < 0)
838  goto out;
839 
840  *pfd = nfd;
841 #else
843  "Platform does not support file desciptor passing.\n");
844  goto out;
845 #endif
846  }
847  else if (dbus_type_is_basic (spec_type))
848  {
849  DBusBasicValue *ptr;
850 
851  ptr = va_arg (var_args, DBusBasicValue*);
852 
853  _dbus_assert (ptr != NULL);
854 
856  ptr);
857  }
858  else if (spec_type == DBUS_TYPE_ARRAY)
859  {
860  int element_type;
861  int spec_element_type;
862  const DBusBasicValue **ptr;
863  int *n_elements_p;
864  DBusTypeReader array;
865 
866  spec_element_type = va_arg (var_args, int);
867  element_type = _dbus_type_reader_get_element_type (&real->u.reader);
868 
869  if (spec_element_type != element_type)
870  {
872  "Argument %d is specified to be an array of \"%s\", but "
873  "is actually an array of \"%s\"\n",
874  i,
875  _dbus_type_to_string (spec_element_type),
876  _dbus_type_to_string (element_type));
877 
878  goto out;
879  }
880 
881  if (dbus_type_is_fixed (spec_element_type) &&
882  element_type != DBUS_TYPE_UNIX_FD)
883  {
884  ptr = va_arg (var_args, const DBusBasicValue**);
885  n_elements_p = va_arg (var_args, int*);
886 
887  _dbus_assert (ptr != NULL);
888  _dbus_assert (n_elements_p != NULL);
889 
890  _dbus_type_reader_recurse (&real->u.reader, &array);
891 
893  (void *) ptr, n_elements_p);
894  }
895  else if (_DBUS_TYPE_IS_STRINGLIKE (spec_element_type))
896  {
897  char ***str_array_p;
898  int n_elements;
899  char **str_array;
900 
901  str_array_p = va_arg (var_args, char***);
902  n_elements_p = va_arg (var_args, int*);
903 
904  _dbus_assert (str_array_p != NULL);
905  _dbus_assert (n_elements_p != NULL);
906 
907  /* Count elements in the array */
908  _dbus_type_reader_recurse (&real->u.reader, &array);
909 
910  n_elements = 0;
912  {
913  ++n_elements;
914  _dbus_type_reader_next (&array);
915  }
916 
917  str_array = dbus_new0 (char*, n_elements + 1);
918  if (str_array == NULL)
919  {
920  _DBUS_SET_OOM (error);
921  goto out;
922  }
923 
924  /* Now go through and dup each string */
925  _dbus_type_reader_recurse (&real->u.reader, &array);
926 
927  i = 0;
928  while (i < n_elements)
929  {
930  const char *s;
932  (void *) &s);
933 
934  str_array[i] = _dbus_strdup (s);
935  if (str_array[i] == NULL)
936  {
937  dbus_free_string_array (str_array);
938  _DBUS_SET_OOM (error);
939  goto out;
940  }
941 
942  ++i;
943 
944  if (!_dbus_type_reader_next (&array))
945  _dbus_assert (i == n_elements);
946  }
947 
949  _dbus_assert (i == n_elements);
950  _dbus_assert (str_array[i] == NULL);
951 
952  *str_array_p = str_array;
953  *n_elements_p = n_elements;
954  }
955 #ifndef DBUS_DISABLE_CHECKS
956  else
957  {
958  _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now\n",
959  _DBUS_FUNCTION_NAME);
960  goto out;
961  }
962 #endif
963  }
964 #ifndef DBUS_DISABLE_CHECKS
965  else
966  {
967  _dbus_warn ("you can only read arrays and basic types with %s for now\n",
968  _DBUS_FUNCTION_NAME);
969  goto out;
970  }
971 #endif
972 
973  spec_type = va_arg (var_args, int);
974  if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID)
975  {
977  "Message has only %d arguments, but more were expected", i);
978  goto out;
979  }
980 
981  i++;
982  }
983 
984  retval = TRUE;
985 
986  out:
987 
988  return retval;
989 }
990 
1051 {
1052  _dbus_return_val_if_fail (message != NULL, 0);
1053 
1054  return _dbus_header_get_serial (&message->header);
1055 }
1056 
1067  dbus_uint32_t reply_serial)
1068 {
1069  _dbus_return_val_if_fail (message != NULL, FALSE);
1070  _dbus_return_val_if_fail (!message->locked, FALSE);
1071  _dbus_return_val_if_fail (reply_serial != 0, FALSE); /* 0 is invalid */
1072 
1073  return _dbus_header_set_field_basic (&message->header,
1076  &reply_serial);
1077 }
1078 
1087 {
1088  dbus_uint32_t v_UINT32;
1089 
1090  _dbus_return_val_if_fail (message != NULL, 0);
1091 
1092  if (_dbus_header_get_field_basic (&message->header,
1095  &v_UINT32))
1096  return v_UINT32;
1097  else
1098  return 0;
1099 }
1100 
1101 static void
1102 dbus_message_finalize (DBusMessage *message)
1103 {
1104  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
1105 
1106  /* This calls application callbacks! */
1108 
1109  _dbus_list_foreach (&message->counters,
1110  free_counter, message);
1111  _dbus_list_clear (&message->counters);
1112 
1113  _dbus_header_free (&message->header);
1114  _dbus_string_free (&message->body);
1115 
1116 #ifdef HAVE_UNIX_FD_PASSING
1117  close_unix_fds(message->unix_fds, &message->n_unix_fds);
1118  dbus_free(message->unix_fds);
1119 #endif
1120 
1121  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
1122 
1123  dbus_free (message);
1124 }
1125 
1126 static DBusMessage*
1127 dbus_message_new_empty_header (void)
1128 {
1129  DBusMessage *message;
1130  dbus_bool_t from_cache;
1131 
1132  message = dbus_message_get_cached ();
1133 
1134  if (message != NULL)
1135  {
1136  from_cache = TRUE;
1137  }
1138  else
1139  {
1140  from_cache = FALSE;
1141  message = dbus_new0 (DBusMessage, 1);
1142  if (message == NULL)
1143  return NULL;
1144 #ifndef DBUS_DISABLE_CHECKS
1146 #endif
1147 
1148 #ifdef HAVE_UNIX_FD_PASSING
1149  message->unix_fds = NULL;
1150  message->n_unix_fds_allocated = 0;
1151 #endif
1152  }
1153 
1154  _dbus_atomic_inc (&message->refcount);
1155 
1156  _dbus_message_trace_ref (message, 0, 1, "new_empty_header");
1157 
1158  message->locked = FALSE;
1159 #ifndef DBUS_DISABLE_CHECKS
1160  message->in_cache = FALSE;
1161 #endif
1162  message->counters = NULL;
1163  message->size_counter_delta = 0;
1164  message->changed_stamp = 0;
1165 
1166 #ifdef HAVE_UNIX_FD_PASSING
1167  message->n_unix_fds = 0;
1168  message->n_unix_fds_allocated = 0;
1169  message->unix_fd_counter_delta = 0;
1170 #endif
1171 
1172  if (!from_cache)
1174 
1175  if (from_cache)
1176  {
1177  _dbus_header_reinit (&message->header);
1178  _dbus_string_set_length (&message->body, 0);
1179  }
1180  else
1181  {
1182  if (!_dbus_header_init (&message->header))
1183  {
1184  dbus_free (message);
1185  return NULL;
1186  }
1187 
1188  if (!_dbus_string_init_preallocated (&message->body, 32))
1189  {
1190  _dbus_header_free (&message->header);
1191  dbus_free (message);
1192  return NULL;
1193  }
1194  }
1195 
1196  return message;
1197 }
1198 
1211 DBusMessage*
1212 dbus_message_new (int message_type)
1213 {
1214  DBusMessage *message;
1215 
1216  _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
1217 
1218  message = dbus_message_new_empty_header ();
1219  if (message == NULL)
1220  return NULL;
1221 
1222  if (!_dbus_header_create (&message->header,
1223  DBUS_COMPILER_BYTE_ORDER,
1224  message_type,
1225  NULL, NULL, NULL, NULL, NULL))
1226  {
1227  dbus_message_unref (message);
1228  return NULL;
1229  }
1230 
1231  return message;
1232 }
1233 
1255 DBusMessage*
1256 dbus_message_new_method_call (const char *destination,
1257  const char *path,
1258  const char *iface,
1259  const char *method)
1260 {
1261  DBusMessage *message;
1262 
1263  _dbus_return_val_if_fail (path != NULL, NULL);
1264  _dbus_return_val_if_fail (method != NULL, NULL);
1265  _dbus_return_val_if_fail (destination == NULL ||
1266  _dbus_check_is_valid_bus_name (destination), NULL);
1267  _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
1268  _dbus_return_val_if_fail (iface == NULL ||
1269  _dbus_check_is_valid_interface (iface), NULL);
1270  _dbus_return_val_if_fail (_dbus_check_is_valid_member (method), NULL);
1271 
1272  message = dbus_message_new_empty_header ();
1273  if (message == NULL)
1274  return NULL;
1275 
1276  if (!_dbus_header_create (&message->header,
1277  DBUS_COMPILER_BYTE_ORDER,
1279  destination, path, iface, method, NULL))
1280  {
1281  dbus_message_unref (message);
1282  return NULL;
1283  }
1284 
1285  return message;
1286 }
1287 
1295 DBusMessage*
1297 {
1298  DBusMessage *message;
1299  const char *sender;
1300 
1301  _dbus_return_val_if_fail (method_call != NULL, NULL);
1302 
1303  sender = dbus_message_get_sender (method_call);
1304 
1305  /* sender is allowed to be null here in peer-to-peer case */
1306 
1307  message = dbus_message_new_empty_header ();
1308  if (message == NULL)
1309  return NULL;
1310 
1311  if (!_dbus_header_create (&message->header,
1312  DBUS_COMPILER_BYTE_ORDER,
1314  sender, NULL, NULL, NULL, NULL))
1315  {
1316  dbus_message_unref (message);
1317  return NULL;
1318  }
1319 
1320  dbus_message_set_no_reply (message, TRUE);
1321 
1322  if (!dbus_message_set_reply_serial (message,
1323  dbus_message_get_serial (method_call)))
1324  {
1325  dbus_message_unref (message);
1326  return NULL;
1327  }
1328 
1329  return message;
1330 }
1331 
1346 DBusMessage*
1347 dbus_message_new_signal (const char *path,
1348  const char *iface,
1349  const char *name)
1350 {
1351  DBusMessage *message;
1352 
1353  _dbus_return_val_if_fail (path != NULL, NULL);
1354  _dbus_return_val_if_fail (iface != NULL, NULL);
1355  _dbus_return_val_if_fail (name != NULL, NULL);
1356  _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
1357  _dbus_return_val_if_fail (_dbus_check_is_valid_interface (iface), NULL);
1358  _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);
1359 
1360  message = dbus_message_new_empty_header ();
1361  if (message == NULL)
1362  return NULL;
1363 
1364  if (!_dbus_header_create (&message->header,
1365  DBUS_COMPILER_BYTE_ORDER,
1367  NULL, path, iface, name, NULL))
1368  {
1369  dbus_message_unref (message);
1370  return NULL;
1371  }
1372 
1373  dbus_message_set_no_reply (message, TRUE);
1374 
1375  return message;
1376 }
1377 
1392 DBusMessage*
1394  const char *error_name,
1395  const char *error_message)
1396 {
1397  DBusMessage *message;
1398  const char *sender;
1399  DBusMessageIter iter;
1400 
1401  _dbus_return_val_if_fail (reply_to != NULL, NULL);
1402  _dbus_return_val_if_fail (error_name != NULL, NULL);
1403  _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
1404 
1405  sender = dbus_message_get_sender (reply_to);
1406 
1407  /* sender may be NULL for non-message-bus case or
1408  * when the message bus is dealing with an unregistered
1409  * connection.
1410  */
1411  message = dbus_message_new_empty_header ();
1412  if (message == NULL)
1413  return NULL;
1414 
1415  if (!_dbus_header_create (&message->header,
1416  DBUS_COMPILER_BYTE_ORDER,
1418  sender, NULL, NULL, NULL, error_name))
1419  {
1420  dbus_message_unref (message);
1421  return NULL;
1422  }
1423 
1424  dbus_message_set_no_reply (message, TRUE);
1425 
1426  if (!dbus_message_set_reply_serial (message,
1427  dbus_message_get_serial (reply_to)))
1428  {
1429  dbus_message_unref (message);
1430  return NULL;
1431  }
1432 
1433  if (error_message != NULL)
1434  {
1435  dbus_message_iter_init_append (message, &iter);
1436  if (!dbus_message_iter_append_basic (&iter,
1438  &error_message))
1439  {
1440  dbus_message_unref (message);
1441  return NULL;
1442  }
1443  }
1444 
1445  return message;
1446 }
1447 
1464 DBusMessage*
1466  const char *error_name,
1467  const char *error_format,
1468  ...)
1469 {
1470  va_list args;
1471  DBusString str;
1472  DBusMessage *message;
1473 
1474  _dbus_return_val_if_fail (reply_to != NULL, NULL);
1475  _dbus_return_val_if_fail (error_name != NULL, NULL);
1476  _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
1477 
1478  if (!_dbus_string_init (&str))
1479  return NULL;
1480 
1481  va_start (args, error_format);
1482 
1483  if (_dbus_string_append_printf_valist (&str, error_format, args))
1484  message = dbus_message_new_error (reply_to, error_name,
1486  else
1487  message = NULL;
1488 
1489  _dbus_string_free (&str);
1490 
1491  va_end (args);
1492 
1493  return message;
1494 }
1495 
1496 
1509 DBusMessage *
1511 {
1512  DBusMessage *retval;
1513 
1514  _dbus_return_val_if_fail (message != NULL, NULL);
1515 
1516  retval = dbus_new0 (DBusMessage, 1);
1517  if (retval == NULL)
1518  return NULL;
1519 
1520  _dbus_atomic_inc (&retval->refcount);
1521 
1522  retval->locked = FALSE;
1523 #ifndef DBUS_DISABLE_CHECKS
1524  retval->generation = message->generation;
1525 #endif
1526 
1527  if (!_dbus_header_copy (&message->header, &retval->header))
1528  {
1529  dbus_free (retval);
1530  return NULL;
1531  }
1532 
1533  if (!_dbus_string_init_preallocated (&retval->body,
1534  _dbus_string_get_length (&message->body)))
1535  {
1536  _dbus_header_free (&retval->header);
1537  dbus_free (retval);
1538  return NULL;
1539  }
1540 
1541  if (!_dbus_string_copy (&message->body, 0,
1542  &retval->body, 0))
1543  goto failed_copy;
1544 
1545 #ifdef HAVE_UNIX_FD_PASSING
1546  retval->unix_fds = dbus_new(int, message->n_unix_fds);
1547  if (retval->unix_fds == NULL && message->n_unix_fds > 0)
1548  goto failed_copy;
1549 
1550  retval->n_unix_fds_allocated = message->n_unix_fds;
1551 
1552  for (retval->n_unix_fds = 0;
1553  retval->n_unix_fds < message->n_unix_fds;
1554  retval->n_unix_fds++)
1555  {
1556  retval->unix_fds[retval->n_unix_fds] = _dbus_dup(message->unix_fds[retval->n_unix_fds], NULL);
1557 
1558  if (retval->unix_fds[retval->n_unix_fds] < 0)
1559  goto failed_copy;
1560  }
1561 
1562 #endif
1563 
1564  _dbus_message_trace_ref (retval, 0, 1, "copy");
1565  return retval;
1566 
1567  failed_copy:
1568  _dbus_header_free (&retval->header);
1569  _dbus_string_free (&retval->body);
1570 
1571 #ifdef HAVE_UNIX_FD_PASSING
1572  close_unix_fds(retval->unix_fds, &retval->n_unix_fds);
1573  dbus_free(retval->unix_fds);
1574 #endif
1575 
1576  dbus_free (retval);
1577 
1578  return NULL;
1579 }
1580 
1581 
1589 DBusMessage *
1591 {
1592  dbus_int32_t old_refcount;
1593 
1594  _dbus_return_val_if_fail (message != NULL, NULL);
1595  _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
1596  _dbus_return_val_if_fail (!message->in_cache, NULL);
1597 
1598  old_refcount = _dbus_atomic_inc (&message->refcount);
1599  _dbus_assert (old_refcount >= 1);
1600  _dbus_message_trace_ref (message, old_refcount, old_refcount + 1, "ref");
1601 
1602  return message;
1603 }
1604 
1612 void
1614 {
1615  dbus_int32_t old_refcount;
1616 
1617  _dbus_return_if_fail (message != NULL);
1618  _dbus_return_if_fail (message->generation == _dbus_current_generation);
1619  _dbus_return_if_fail (!message->in_cache);
1620 
1621  old_refcount = _dbus_atomic_dec (&message->refcount);
1622 
1623  _dbus_assert (old_refcount >= 1);
1624 
1625  _dbus_message_trace_ref (message, old_refcount, old_refcount - 1, "unref");
1626 
1627  if (old_refcount == 1)
1628  {
1629  /* Calls application callbacks! */
1630  dbus_message_cache_or_finalize (message);
1631  }
1632 }
1633 
1644 int
1646 {
1647  _dbus_return_val_if_fail (message != NULL, DBUS_MESSAGE_TYPE_INVALID);
1648 
1649  return _dbus_header_get_message_type (&message->header);
1650 }
1651 
1716  int first_arg_type,
1717  ...)
1718 {
1719  dbus_bool_t retval;
1720  va_list var_args;
1721 
1722  _dbus_return_val_if_fail (message != NULL, FALSE);
1723 
1724  va_start (var_args, first_arg_type);
1725  retval = dbus_message_append_args_valist (message,
1726  first_arg_type,
1727  var_args);
1728  va_end (var_args);
1729 
1730  return retval;
1731 }
1732 
1748  int first_arg_type,
1749  va_list var_args)
1750 {
1751  int type;
1752  DBusMessageIter iter;
1753 
1754  _dbus_return_val_if_fail (message != NULL, FALSE);
1755 
1756  type = first_arg_type;
1757 
1758  dbus_message_iter_init_append (message, &iter);
1759 
1760  while (type != DBUS_TYPE_INVALID)
1761  {
1762  if (dbus_type_is_basic (type))
1763  {
1764  const DBusBasicValue *value;
1765  value = va_arg (var_args, const DBusBasicValue*);
1766 
1767  if (!dbus_message_iter_append_basic (&iter,
1768  type,
1769  value))
1770  goto failed;
1771  }
1772  else if (type == DBUS_TYPE_ARRAY)
1773  {
1774  int element_type;
1775  DBusMessageIter array;
1776  char buf[2];
1777 
1778  element_type = va_arg (var_args, int);
1779 
1780  buf[0] = element_type;
1781  buf[1] = '\0';
1784  buf,
1785  &array))
1786  goto failed;
1787 
1788  if (dbus_type_is_fixed (element_type) &&
1789  element_type != DBUS_TYPE_UNIX_FD)
1790  {
1791  const DBusBasicValue **value;
1792  int n_elements;
1793 
1794  value = va_arg (var_args, const DBusBasicValue**);
1795  n_elements = va_arg (var_args, int);
1796 
1798  element_type,
1799  value,
1800  n_elements)) {
1801  dbus_message_iter_abandon_container (&iter, &array);
1802  goto failed;
1803  }
1804  }
1805  else if (_DBUS_TYPE_IS_STRINGLIKE (element_type))
1806  {
1807  const char ***value_p;
1808  const char **value;
1809  int n_elements;
1810  int i;
1811 
1812  value_p = va_arg (var_args, const char***);
1813  n_elements = va_arg (var_args, int);
1814 
1815  value = *value_p;
1816 
1817  i = 0;
1818  while (i < n_elements)
1819  {
1820  if (!dbus_message_iter_append_basic (&array,
1821  element_type,
1822  &value[i])) {
1823  dbus_message_iter_abandon_container (&iter, &array);
1824  goto failed;
1825  }
1826  ++i;
1827  }
1828  }
1829  else
1830  {
1831  _dbus_warn ("arrays of %s can't be appended with %s for now\n",
1832  _dbus_type_to_string (element_type),
1833  _DBUS_FUNCTION_NAME);
1834  goto failed;
1835  }
1836 
1837  if (!dbus_message_iter_close_container (&iter, &array))
1838  goto failed;
1839  }
1840 #ifndef DBUS_DISABLE_CHECKS
1841  else
1842  {
1843  _dbus_warn ("type %s isn't supported yet in %s\n",
1844  _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
1845  goto failed;
1846  }
1847 #endif
1848 
1849  type = va_arg (var_args, int);
1850  }
1851 
1852  return TRUE;
1853 
1854  failed:
1855  return FALSE;
1856 }
1857 
1904  DBusError *error,
1905  int first_arg_type,
1906  ...)
1907 {
1908  dbus_bool_t retval;
1909  va_list var_args;
1910 
1911  _dbus_return_val_if_fail (message != NULL, FALSE);
1912  _dbus_return_val_if_error_is_set (error, FALSE);
1913 
1914  va_start (var_args, first_arg_type);
1915  retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
1916  va_end (var_args);
1917 
1918  return retval;
1919 }
1920 
1933  DBusError *error,
1934  int first_arg_type,
1935  va_list var_args)
1936 {
1937  DBusMessageIter iter;
1938 
1939  _dbus_return_val_if_fail (message != NULL, FALSE);
1940  _dbus_return_val_if_error_is_set (error, FALSE);
1941 
1942  dbus_message_iter_init (message, &iter);
1943  return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
1944 }
1945 
1946 static void
1947 _dbus_message_iter_init_common (DBusMessage *message,
1948  DBusMessageRealIter *real,
1949  int iter_type)
1950 {
1951  _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
1952 
1953  /* Since the iterator will read or write who-knows-what from the
1954  * message, we need to get in the right byte order
1955  */
1956  ensure_byte_order (message);
1957 
1958  real->message = message;
1959  real->changed_stamp = message->changed_stamp;
1960  real->iter_type = iter_type;
1961  real->sig_refcount = 0;
1962 }
1963 
1988  DBusMessageIter *iter)
1989 {
1990  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
1991  const DBusString *type_str;
1992  int type_pos;
1993 
1994  _dbus_return_val_if_fail (message != NULL, FALSE);
1995  _dbus_return_val_if_fail (iter != NULL, FALSE);
1996 
1997  get_const_signature (&message->header, &type_str, &type_pos);
1998 
1999  _dbus_message_iter_init_common (message, real,
2000  DBUS_MESSAGE_ITER_TYPE_READER);
2001 
2003  _dbus_header_get_byte_order (&message->header),
2004  type_str, type_pos,
2005  &message->body,
2006  0);
2007 
2009 }
2010 
2019 {
2020  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2021 
2022  _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
2023  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2024 
2025  return _dbus_type_reader_has_next (&real->u.reader);
2026 }
2027 
2038 {
2039  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2040 
2041  _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
2042  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2043 
2044  return _dbus_type_reader_next (&real->u.reader);
2045 }
2046 
2061 int
2063 {
2064  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2065 
2066  _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2067  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2068 
2070 }
2071 
2080 int
2082 {
2083  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2084 
2085  _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2086  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
2087  _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
2088 
2090 }
2091 
2117 void
2119  DBusMessageIter *sub)
2120 {
2121  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2122  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2123 
2124  _dbus_return_if_fail (_dbus_message_iter_check (real));
2125  _dbus_return_if_fail (sub != NULL);
2126 
2127  *real_sub = *real;
2128  _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
2129 }
2130 
2142 char *
2144 {
2145  const DBusString *sig;
2146  DBusString retstr;
2147  char *ret;
2148  int start, len;
2149  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2150 
2151  _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
2152 
2153  if (!_dbus_string_init (&retstr))
2154  return NULL;
2155 
2157  &start, &len);
2158  if (!_dbus_string_append_len (&retstr,
2159  _dbus_string_get_const_data (sig) + start,
2160  len))
2161  return NULL;
2162  if (!_dbus_string_steal_data (&retstr, &ret))
2163  return NULL;
2164  _dbus_string_free (&retstr);
2165  return ret;
2166 }
2167 
2215 void
2217  void *value)
2218 {
2219  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2220 
2221  _dbus_return_if_fail (_dbus_message_iter_check (real));
2222  _dbus_return_if_fail (value != NULL);
2223 
2225  {
2226 #ifdef HAVE_UNIX_FD_PASSING
2227  DBusBasicValue idx;
2228 
2229  _dbus_type_reader_read_basic(&real->u.reader, &idx);
2230 
2231  if (idx.u32 >= real->message->n_unix_fds) {
2232  /* Hmm, we cannot really signal an error here, so let's make
2233  sure to return an invalid fd. */
2234  *((int*) value) = -1;
2235  return;
2236  }
2237 
2238  *((int*) value) = _dbus_dup(real->message->unix_fds[idx.u32], NULL);
2239 #else
2240  *((int*) value) = -1;
2241 #endif
2242  }
2243  else
2244  {
2246  value);
2247  }
2248 }
2249 
2268 int
2270 {
2271  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2272 
2273  _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
2274 
2276 }
2277 
2313 void
2315  void *value,
2316  int *n_elements)
2317 {
2318  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2319 #ifndef DBUS_DISABLE_CHECKS
2320  int subtype = _dbus_type_reader_get_current_type(&real->u.reader);
2321 
2322  _dbus_return_if_fail (_dbus_message_iter_check (real));
2323  _dbus_return_if_fail (value != NULL);
2324  _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) ||
2325  (dbus_type_is_fixed (subtype) && subtype != DBUS_TYPE_UNIX_FD));
2326 #endif
2327 
2329  value, n_elements);
2330 }
2331 
2343 void
2345  DBusMessageIter *iter)
2346 {
2347  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2348 
2349  _dbus_return_if_fail (message != NULL);
2350  _dbus_return_if_fail (iter != NULL);
2351 
2352  _dbus_message_iter_init_common (message, real,
2353  DBUS_MESSAGE_ITER_TYPE_WRITER);
2354 
2355  /* We create the signature string and point iterators at it "on demand"
2356  * when a value is actually appended. That means that init() never fails
2357  * due to OOM.
2358  */
2360  _dbus_header_get_byte_order (&message->header),
2361  &message->body,
2362  _dbus_string_get_length (&message->body));
2363 }
2364 
2373 static dbus_bool_t
2374 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
2375 {
2376  DBusString *str;
2377  const DBusString *current_sig;
2378  int current_sig_pos;
2379 
2380  _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2381 
2382  if (real->u.writer.type_str != NULL)
2383  {
2384  _dbus_assert (real->sig_refcount > 0);
2385  real->sig_refcount += 1;
2386  return TRUE;
2387  }
2388 
2389  str = dbus_new (DBusString, 1);
2390  if (str == NULL)
2391  return FALSE;
2392 
2395  &current_sig, &current_sig_pos))
2396  current_sig = NULL;
2397 
2398  if (current_sig)
2399  {
2400  int current_len;
2401 
2402  current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
2403  current_sig_pos += 1; /* move on to sig data */
2404 
2405  if (!_dbus_string_init_preallocated (str, current_len + 4))
2406  {
2407  dbus_free (str);
2408  return FALSE;
2409  }
2410 
2411  if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
2412  str, 0))
2413  {
2414  _dbus_string_free (str);
2415  dbus_free (str);
2416  return FALSE;
2417  }
2418  }
2419  else
2420  {
2421  if (!_dbus_string_init_preallocated (str, 4))
2422  {
2423  dbus_free (str);
2424  return FALSE;
2425  }
2426  }
2427 
2428  real->sig_refcount = 1;
2429 
2431  str, _dbus_string_get_length (str));
2432  return TRUE;
2433 }
2434 
2444 static dbus_bool_t
2445 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
2446 {
2447  DBusString *str;
2448  const char *v_STRING;
2449  dbus_bool_t retval;
2450 
2451  _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2452  _dbus_assert (real->u.writer.type_str != NULL);
2453  _dbus_assert (real->sig_refcount > 0);
2454 
2455  real->sig_refcount -= 1;
2456 
2457  if (real->sig_refcount > 0)
2458  return TRUE;
2459  _dbus_assert (real->sig_refcount == 0);
2460 
2461  retval = TRUE;
2462 
2463  str = real->u.writer.type_str;
2464 
2465  v_STRING = _dbus_string_get_const_data (str);
2469  &v_STRING))
2470  retval = FALSE;
2471 
2473  _dbus_string_free (str);
2474  dbus_free (str);
2475 
2476  return retval;
2477 }
2478 
2486 static void
2487 _dbus_message_iter_abandon_signature (DBusMessageRealIter *real)
2488 {
2489  DBusString *str;
2490 
2491  _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2492  _dbus_assert (real->u.writer.type_str != NULL);
2493  _dbus_assert (real->sig_refcount > 0);
2494 
2495  real->sig_refcount -= 1;
2496 
2497  if (real->sig_refcount > 0)
2498  return;
2499  _dbus_assert (real->sig_refcount == 0);
2500 
2501  str = real->u.writer.type_str;
2502 
2504  _dbus_string_free (str);
2505  dbus_free (str);
2506 }
2507 
2508 #ifndef DBUS_DISABLE_CHECKS
2509 static dbus_bool_t
2510 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
2511 {
2512  if (!_dbus_message_iter_check (iter))
2513  return FALSE;
2514 
2515  if (iter->message->locked)
2516  {
2517  _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)\n");
2518  return FALSE;
2519  }
2520 
2521  return TRUE;
2522 }
2523 #endif /* DBUS_DISABLE_CHECKS */
2524 
2525 #ifdef HAVE_UNIX_FD_PASSING
2526 static int *
2527 expand_fd_array(DBusMessage *m,
2528  unsigned n)
2529 {
2530  _dbus_assert(m);
2531 
2532  /* This makes space for adding n new fds to the array and returns a
2533  pointer to the place were the first fd should be put. */
2534 
2535  if (m->n_unix_fds + n > m->n_unix_fds_allocated)
2536  {
2537  unsigned k;
2538  int *p;
2539 
2540  /* Make twice as much space as necessary */
2541  k = (m->n_unix_fds + n) * 2;
2542 
2543  /* Allocate at least four */
2544  if (k < 4)
2545  k = 4;
2546 
2547  p = dbus_realloc(m->unix_fds, k * sizeof(int));
2548  if (p == NULL)
2549  return NULL;
2550 
2551  m->unix_fds = p;
2552  m->n_unix_fds_allocated = k;
2553  }
2554 
2555  return m->unix_fds + m->n_unix_fds;
2556 }
2557 #endif
2558 
2580  int type,
2581  const void *value)
2582 {
2583  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2584  dbus_bool_t ret;
2585 
2586  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2587  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2588  _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
2589  _dbus_return_val_if_fail (value != NULL, FALSE);
2590 
2591 #ifndef DBUS_DISABLE_CHECKS
2592  switch (type)
2593  {
2594  const char * const *string_p;
2595  const dbus_bool_t *bool_p;
2596 
2597  case DBUS_TYPE_STRING:
2598  string_p = value;
2599  _dbus_return_val_if_fail (_dbus_check_is_valid_utf8 (*string_p), FALSE);
2600  break;
2601 
2602  case DBUS_TYPE_OBJECT_PATH:
2603  string_p = value;
2604  _dbus_return_val_if_fail (_dbus_check_is_valid_path (*string_p), FALSE);
2605  break;
2606 
2607  case DBUS_TYPE_SIGNATURE:
2608  string_p = value;
2609  _dbus_return_val_if_fail (_dbus_check_is_valid_signature (*string_p), FALSE);
2610  break;
2611 
2612  case DBUS_TYPE_BOOLEAN:
2613  bool_p = value;
2614  _dbus_return_val_if_fail (*bool_p == 0 || *bool_p == 1, FALSE);
2615  break;
2616 
2617  default:
2618  {
2619  /* nothing to check, all possible values are allowed */
2620  }
2621  }
2622 #endif
2623 
2624  if (!_dbus_message_iter_open_signature (real))
2625  return FALSE;
2626 
2627  if (type == DBUS_TYPE_UNIX_FD)
2628  {
2629 #ifdef HAVE_UNIX_FD_PASSING
2630  int *fds;
2631  dbus_uint32_t u;
2632 
2633  /* First step, include the fd in the fd list of this message */
2634  if (!(fds = expand_fd_array(real->message, 1)))
2635  return FALSE;
2636 
2637  *fds = _dbus_dup(*(int*) value, NULL);
2638  if (*fds < 0)
2639  return FALSE;
2640 
2641  u = real->message->n_unix_fds;
2642 
2643  /* Second step, write the index to the fd */
2644  if (!(ret = _dbus_type_writer_write_basic (&real->u.writer, DBUS_TYPE_UNIX_FD, &u))) {
2645  _dbus_close(*fds, NULL);
2646  return FALSE;
2647  }
2648 
2649  real->message->n_unix_fds += 1;
2650  u += 1;
2651 
2652  /* Final step, update the header accordingly */
2656  &u);
2657 
2658  /* If any of these operations fail the message is
2659  hosed. However, no memory or fds should be leaked since what
2660  has been added to message has been added to the message, and
2661  can hence be accounted for when the message is being
2662  freed. */
2663 #else
2664  ret = FALSE;
2665 #endif
2666  }
2667  else
2668  {
2669  ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
2670  }
2671 
2672  if (!_dbus_message_iter_close_signature (real))
2673  ret = FALSE;
2674 
2675  return ret;
2676 }
2677 
2715  int element_type,
2716  const void *value,
2717  int n_elements)
2718 {
2719  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2720  dbus_bool_t ret;
2721 
2722  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2723  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2724  _dbus_return_val_if_fail (dbus_type_is_fixed (element_type) && element_type != DBUS_TYPE_UNIX_FD, FALSE);
2725  _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
2726  _dbus_return_val_if_fail (value != NULL, FALSE);
2727  _dbus_return_val_if_fail (n_elements >= 0, FALSE);
2728  _dbus_return_val_if_fail (n_elements <=
2730  FALSE);
2731 
2732 #ifndef DBUS_DISABLE_CHECKS
2733  if (element_type == DBUS_TYPE_BOOLEAN)
2734  {
2735  const dbus_bool_t * const *bools = value;
2736  int i;
2737 
2738  for (i = 0; i < n_elements; i++)
2739  {
2740  _dbus_return_val_if_fail ((*bools)[i] == 0 || (*bools)[i] == 1, FALSE);
2741  }
2742  }
2743 #endif
2744 
2745  ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
2746 
2747  return ret;
2748 }
2749 
2773  int type,
2774  const char *contained_signature,
2775  DBusMessageIter *sub)
2776 {
2777  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2778  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2779  DBusString contained_str;
2780 
2781  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2782  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2783  _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
2784  _dbus_return_val_if_fail (sub != NULL, FALSE);
2785  _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
2786  contained_signature == NULL) ||
2787  (type == DBUS_TYPE_DICT_ENTRY &&
2788  contained_signature == NULL) ||
2789  (type == DBUS_TYPE_VARIANT &&
2790  contained_signature != NULL) ||
2791  (type == DBUS_TYPE_ARRAY &&
2792  contained_signature != NULL), FALSE);
2793 
2794  /* this would fail if the contained_signature is a dict entry, since
2795  * dict entries are invalid signatures standalone (they must be in
2796  * an array)
2797  */
2798  _dbus_return_val_if_fail ((type == DBUS_TYPE_ARRAY && contained_signature && *contained_signature == DBUS_DICT_ENTRY_BEGIN_CHAR) ||
2799  (contained_signature == NULL ||
2800  _dbus_check_is_valid_signature (contained_signature)),
2801  FALSE);
2802 
2803  if (!_dbus_message_iter_open_signature (real))
2804  return FALSE;
2805 
2806  *real_sub = *real;
2807 
2808  if (contained_signature != NULL)
2809  {
2810  _dbus_string_init_const (&contained_str, contained_signature);
2811 
2812  return _dbus_type_writer_recurse (&real->u.writer,
2813  type,
2814  &contained_str, 0,
2815  &real_sub->u.writer);
2816  }
2817  else
2818  {
2819  return _dbus_type_writer_recurse (&real->u.writer,
2820  type,
2821  NULL, 0,
2822  &real_sub->u.writer);
2823  }
2824 }
2825 
2826 
2842  DBusMessageIter *sub)
2843 {
2844  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2845  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2846  dbus_bool_t ret;
2847 
2848  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2849  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2850  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
2851  _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2852 
2853  ret = _dbus_type_writer_unrecurse (&real->u.writer,
2854  &real_sub->u.writer);
2855 
2856  if (!_dbus_message_iter_close_signature (real))
2857  ret = FALSE;
2858 
2859  return ret;
2860 }
2861 
2873 void
2875  DBusMessageIter *sub)
2876 {
2877  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2878 #ifndef DBUS_DISABLE_CHECKS
2879  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2880 
2881  _dbus_return_if_fail (_dbus_message_iter_append_check (real));
2882  _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2883  _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
2884  _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2885 #endif
2886 
2887  _dbus_message_iter_abandon_signature (real);
2888 }
2889 
2906 void
2908  dbus_bool_t no_reply)
2909 {
2910  _dbus_return_if_fail (message != NULL);
2911  _dbus_return_if_fail (!message->locked);
2912 
2913  _dbus_header_toggle_flag (&message->header,
2915  no_reply);
2916 }
2917 
2927 {
2928  _dbus_return_val_if_fail (message != NULL, FALSE);
2929 
2930  return _dbus_header_get_flag (&message->header,
2932 }
2933 
2948 void
2950  dbus_bool_t auto_start)
2951 {
2952  _dbus_return_if_fail (message != NULL);
2953  _dbus_return_if_fail (!message->locked);
2954 
2955  _dbus_header_toggle_flag (&message->header,
2957  !auto_start);
2958 }
2959 
2969 {
2970  _dbus_return_val_if_fail (message != NULL, FALSE);
2971 
2972  return !_dbus_header_get_flag (&message->header,
2974 }
2975 
2976 
2991  const char *object_path)
2992 {
2993  _dbus_return_val_if_fail (message != NULL, FALSE);
2994  _dbus_return_val_if_fail (!message->locked, FALSE);
2995  _dbus_return_val_if_fail (object_path == NULL ||
2996  _dbus_check_is_valid_path (object_path),
2997  FALSE);
2998 
2999  return set_or_delete_string_field (message,
3002  object_path);
3003 }
3004 
3018 const char*
3020 {
3021  const char *v;
3022 
3023  _dbus_return_val_if_fail (message != NULL, NULL);
3024 
3025  v = NULL; /* in case field doesn't exist */
3029  (void *) &v);
3030  return v;
3031 }
3032 
3044  const char *path)
3045 {
3046  const char *msg_path;
3047  msg_path = dbus_message_get_path (message);
3048 
3049  if (msg_path == NULL)
3050  {
3051  if (path == NULL)
3052  return TRUE;
3053  else
3054  return FALSE;
3055  }
3056 
3057  if (path == NULL)
3058  return FALSE;
3059 
3060  if (strcmp (msg_path, path) == 0)
3061  return TRUE;
3062 
3063  return FALSE;
3064 }
3065 
3088  char ***path)
3089 {
3090  const char *v;
3091 
3092  _dbus_return_val_if_fail (message != NULL, FALSE);
3093  _dbus_return_val_if_fail (path != NULL, FALSE);
3094 
3095  *path = NULL;
3096 
3097  v = dbus_message_get_path (message);
3098  if (v != NULL)
3099  {
3100  if (!_dbus_decompose_path (v, strlen (v),
3101  path, NULL))
3102  return FALSE;
3103  }
3104  return TRUE;
3105 }
3106 
3122  const char *iface)
3123 {
3124  _dbus_return_val_if_fail (message != NULL, FALSE);
3125  _dbus_return_val_if_fail (!message->locked, FALSE);
3126  _dbus_return_val_if_fail (iface == NULL ||
3127  _dbus_check_is_valid_interface (iface),
3128  FALSE);
3129 
3130  return set_or_delete_string_field (message,
3133  iface);
3134 }
3135 
3149 const char*
3151 {
3152  const char *v;
3153 
3154  _dbus_return_val_if_fail (message != NULL, NULL);
3155 
3156  v = NULL; /* in case field doesn't exist */
3160  (void *) &v);
3161  return v;
3162 }
3163 
3173  const char *iface)
3174 {
3175  const char *msg_interface;
3176  msg_interface = dbus_message_get_interface (message);
3177 
3178  if (msg_interface == NULL)
3179  {
3180  if (iface == NULL)
3181  return TRUE;
3182  else
3183  return FALSE;
3184  }
3185 
3186  if (iface == NULL)
3187  return FALSE;
3188 
3189  if (strcmp (msg_interface, iface) == 0)
3190  return TRUE;
3191 
3192  return FALSE;
3193 
3194 }
3195 
3210  const char *member)
3211 {
3212  _dbus_return_val_if_fail (message != NULL, FALSE);
3213  _dbus_return_val_if_fail (!message->locked, FALSE);
3214  _dbus_return_val_if_fail (member == NULL ||
3215  _dbus_check_is_valid_member (member),
3216  FALSE);
3217 
3218  return set_or_delete_string_field (message,
3221  member);
3222 }
3223 
3235 const char*
3237 {
3238  const char *v;
3239 
3240  _dbus_return_val_if_fail (message != NULL, NULL);
3241 
3242  v = NULL; /* in case field doesn't exist */
3246  (void *) &v);
3247  return v;
3248 }
3249 
3259  const char *member)
3260 {
3261  const char *msg_member;
3262  msg_member = dbus_message_get_member (message);
3263 
3264  if (msg_member == NULL)
3265  {
3266  if (member == NULL)
3267  return TRUE;
3268  else
3269  return FALSE;
3270  }
3271 
3272  if (member == NULL)
3273  return FALSE;
3274 
3275  if (strcmp (msg_member, member) == 0)
3276  return TRUE;
3277 
3278  return FALSE;
3279 
3280 }
3281 
3295  const char *error_name)
3296 {
3297  _dbus_return_val_if_fail (message != NULL, FALSE);
3298  _dbus_return_val_if_fail (!message->locked, FALSE);
3299  _dbus_return_val_if_fail (error_name == NULL ||
3300  _dbus_check_is_valid_error_name (error_name),
3301  FALSE);
3302 
3303  return set_or_delete_string_field (message,
3306  error_name);
3307 }
3308 
3319 const char*
3321 {
3322  const char *v;
3323 
3324  _dbus_return_val_if_fail (message != NULL, NULL);
3325 
3326  v = NULL; /* in case field doesn't exist */
3330  (void *) &v);
3331  return v;
3332 }
3333 
3349  const char *destination)
3350 {
3351  _dbus_return_val_if_fail (message != NULL, FALSE);
3352  _dbus_return_val_if_fail (!message->locked, FALSE);
3353  _dbus_return_val_if_fail (destination == NULL ||
3354  _dbus_check_is_valid_bus_name (destination),
3355  FALSE);
3356 
3357  return set_or_delete_string_field (message,
3360  destination);
3361 }
3362 
3372 const char*
3374 {
3375  const char *v;
3376 
3377  _dbus_return_val_if_fail (message != NULL, NULL);
3378 
3379  v = NULL; /* in case field doesn't exist */
3383  (void *) &v);
3384  return v;
3385 }
3386 
3403  const char *sender)
3404 {
3405  _dbus_return_val_if_fail (message != NULL, FALSE);
3406  _dbus_return_val_if_fail (!message->locked, FALSE);
3407  _dbus_return_val_if_fail (sender == NULL ||
3408  _dbus_check_is_valid_bus_name (sender),
3409  FALSE);
3410 
3411  return set_or_delete_string_field (message,
3414  sender);
3415 }
3416 
3432 const char*
3434 {
3435  const char *v;
3436 
3437  _dbus_return_val_if_fail (message != NULL, NULL);
3438 
3439  v = NULL; /* in case field doesn't exist */
3443  (void *) &v);
3444  return v;
3445 }
3446 
3465 const char*
3467 {
3468  const DBusString *type_str;
3469  int type_pos;
3470 
3471  _dbus_return_val_if_fail (message != NULL, NULL);
3472 
3473  get_const_signature (&message->header, &type_str, &type_pos);
3474 
3475  return _dbus_string_get_const_data_len (type_str, type_pos, 0);
3476 }
3477 
3478 static dbus_bool_t
3479 _dbus_message_has_type_interface_member (DBusMessage *message,
3480  int type,
3481  const char *iface,
3482  const char *member)
3483 {
3484  const char *n;
3485 
3486  _dbus_assert (message != NULL);
3487  _dbus_assert (iface != NULL);
3488  _dbus_assert (member != NULL);
3489 
3490  if (dbus_message_get_type (message) != type)
3491  return FALSE;
3492 
3493  /* Optimize by checking the short member name first
3494  * instead of the longer interface name
3495  */
3496 
3497  n = dbus_message_get_member (message);
3498 
3499  if (n && strcmp (n, member) == 0)
3500  {
3501  n = dbus_message_get_interface (message);
3502 
3503  if (n == NULL || strcmp (n, iface) == 0)
3504  return TRUE;
3505  }
3506 
3507  return FALSE;
3508 }
3509 
3526  const char *iface,
3527  const char *method)
3528 {
3529  _dbus_return_val_if_fail (message != NULL, FALSE);
3530  _dbus_return_val_if_fail (iface != NULL, FALSE);
3531  _dbus_return_val_if_fail (method != NULL, FALSE);
3532  /* don't check that interface/method are valid since it would be
3533  * expensive, and not catch many common errors
3534  */
3535 
3536  return _dbus_message_has_type_interface_member (message,
3538  iface, method);
3539 }
3540 
3554  const char *iface,
3555  const char *signal_name)
3556 {
3557  _dbus_return_val_if_fail (message != NULL, FALSE);
3558  _dbus_return_val_if_fail (iface != NULL, FALSE);
3559  _dbus_return_val_if_fail (signal_name != NULL, FALSE);
3560  /* don't check that interface/name are valid since it would be
3561  * expensive, and not catch many common errors
3562  */
3563 
3564  return _dbus_message_has_type_interface_member (message,
3566  iface, signal_name);
3567 }
3568 
3581  const char *error_name)
3582 {
3583  const char *n;
3584 
3585  _dbus_return_val_if_fail (message != NULL, FALSE);
3586  _dbus_return_val_if_fail (error_name != NULL, FALSE);
3587  /* don't check that error_name is valid since it would be expensive,
3588  * and not catch many common errors
3589  */
3590 
3592  return FALSE;
3593 
3594  n = dbus_message_get_error_name (message);
3595 
3596  if (n && strcmp (n, error_name) == 0)
3597  return TRUE;
3598  else
3599  return FALSE;
3600 }
3601 
3614  const char *name)
3615 {
3616  const char *s;
3617 
3618  _dbus_return_val_if_fail (message != NULL, FALSE);
3619  _dbus_return_val_if_fail (name != NULL, FALSE);
3620  /* don't check that name is valid since it would be expensive, and
3621  * not catch many common errors
3622  */
3623 
3624  s = dbus_message_get_destination (message);
3625 
3626  if (s && strcmp (s, name) == 0)
3627  return TRUE;
3628  else
3629  return FALSE;
3630 }
3631 
3649  const char *name)
3650 {
3651  const char *s;
3652 
3653  _dbus_return_val_if_fail (message != NULL, FALSE);
3654  _dbus_return_val_if_fail (name != NULL, FALSE);
3655  /* don't check that name is valid since it would be expensive, and
3656  * not catch many common errors
3657  */
3658 
3659  s = dbus_message_get_sender (message);
3660 
3661  if (s && strcmp (s, name) == 0)
3662  return TRUE;
3663  else
3664  return FALSE;
3665 }
3666 
3678  const char *signature)
3679 {
3680  const char *s;
3681 
3682  _dbus_return_val_if_fail (message != NULL, FALSE);
3683  _dbus_return_val_if_fail (signature != NULL, FALSE);
3684  /* don't check that signature is valid since it would be expensive,
3685  * and not catch many common errors
3686  */
3687 
3688  s = dbus_message_get_signature (message);
3689 
3690  if (s && strcmp (s, signature) == 0)
3691  return TRUE;
3692  else
3693  return FALSE;
3694 }
3695 
3720  DBusMessage *message)
3721 {
3722  const char *str;
3723 
3724  _dbus_return_val_if_fail (message != NULL, FALSE);
3725  _dbus_return_val_if_error_is_set (error, FALSE);
3726 
3728  return FALSE;
3729 
3730  str = NULL;
3731  dbus_message_get_args (message, NULL,
3732  DBUS_TYPE_STRING, &str,
3734 
3735  dbus_set_error (error, dbus_message_get_error_name (message),
3736  str ? "%s" : NULL, str);
3737 
3738  return TRUE;
3739 }
3740 
3749 {
3750 #ifdef HAVE_UNIX_FD_PASSING
3751  _dbus_assert(message);
3752 
3753  return message->n_unix_fds > 0;
3754 #else
3755  return FALSE;
3756 #endif
3757 }
3758 
3777 #define INITIAL_LOADER_DATA_LEN 32
3778 
3787 {
3788  DBusMessageLoader *loader;
3789 
3790  loader = dbus_new0 (DBusMessageLoader, 1);
3791  if (loader == NULL)
3792  return NULL;
3793 
3794  loader->refcount = 1;
3795 
3796  loader->corrupted = FALSE;
3797  loader->corruption_reason = DBUS_VALID;
3798 
3799  /* this can be configured by the app, but defaults to the protocol max */
3801 
3802  /* We set a very relatively conservative default here since due to how
3803  SCM_RIGHTS works we need to preallocate an fd array of the maximum
3804  number of unix fds we want to receive in advance. A
3805  try-and-reallocate loop is not possible. */
3806  loader->max_message_unix_fds = DBUS_DEFAULT_MESSAGE_UNIX_FDS;
3807 
3808  if (!_dbus_string_init (&loader->data))
3809  {
3810  dbus_free (loader);
3811  return NULL;
3812  }
3813 
3814  /* preallocate the buffer for speed, ignore failure */
3816  _dbus_string_set_length (&loader->data, 0);
3817 
3818 #ifdef HAVE_UNIX_FD_PASSING
3819  loader->unix_fds = NULL;
3820  loader->n_unix_fds = loader->n_unix_fds_allocated = 0;
3821  loader->unix_fds_outstanding = FALSE;
3822 #endif
3823 
3824  return loader;
3825 }
3826 
3835 {
3836  loader->refcount += 1;
3837 
3838  return loader;
3839 }
3840 
3847 void
3849 {
3850  loader->refcount -= 1;
3851  if (loader->refcount == 0)
3852  {
3853 #ifdef HAVE_UNIX_FD_PASSING
3854  close_unix_fds(loader->unix_fds, &loader->n_unix_fds);
3855  dbus_free(loader->unix_fds);
3856 #endif
3857  _dbus_list_foreach (&loader->messages,
3859  NULL);
3860  _dbus_list_clear (&loader->messages);
3861  _dbus_string_free (&loader->data);
3862  dbus_free (loader);
3863  }
3864 }
3865 
3884 void
3886  DBusString **buffer)
3887 {
3888  _dbus_assert (!loader->buffer_outstanding);
3889 
3890  *buffer = &loader->data;
3891 
3892  loader->buffer_outstanding = TRUE;
3893 }
3894 
3905 void
3907  DBusString *buffer,
3908  int bytes_read)
3909 {
3910  _dbus_assert (loader->buffer_outstanding);
3911  _dbus_assert (buffer == &loader->data);
3912 
3913  loader->buffer_outstanding = FALSE;
3914 }
3915 
3928  int **fds,
3929  unsigned *max_n_fds)
3930 {
3931 #ifdef HAVE_UNIX_FD_PASSING
3932  _dbus_assert (!loader->unix_fds_outstanding);
3933 
3934  /* Allocate space where we can put the fds we read. We allocate
3935  space for max_message_unix_fds since this is an
3936  upper limit how many fds can be received within a single
3937  message. Since SCM_RIGHTS doesn't allow a reallocate+retry logic
3938  we are allocating the maximum possible array size right from the
3939  beginning. This sucks a bit, however unless SCM_RIGHTS is fixed
3940  there is no better way. */
3941 
3942  if (loader->n_unix_fds_allocated < loader->max_message_unix_fds)
3943  {
3944  int *a = dbus_realloc(loader->unix_fds,
3945  loader->max_message_unix_fds * sizeof(loader->unix_fds[0]));
3946 
3947  if (!a)
3948  return FALSE;
3949 
3950  loader->unix_fds = a;
3951  loader->n_unix_fds_allocated = loader->max_message_unix_fds;
3952  }
3953 
3954  *fds = loader->unix_fds + loader->n_unix_fds;
3955  *max_n_fds = loader->n_unix_fds_allocated - loader->n_unix_fds;
3956 
3957  loader->unix_fds_outstanding = TRUE;
3958  return TRUE;
3959 #else
3960  _dbus_assert_not_reached("Platform doesn't support unix fd passing");
3961  return FALSE;
3962 #endif
3963 }
3964 
3975 void
3977  int *fds,
3978  unsigned n_fds)
3979 {
3980 #ifdef HAVE_UNIX_FD_PASSING
3981  _dbus_assert(loader->unix_fds_outstanding);
3982  _dbus_assert(loader->unix_fds + loader->n_unix_fds == fds);
3983  _dbus_assert(loader->n_unix_fds + n_fds <= loader->n_unix_fds_allocated);
3984 
3985  loader->n_unix_fds += n_fds;
3986  loader->unix_fds_outstanding = FALSE;
3987 
3988  if (n_fds && loader->unix_fds_change)
3989  loader->unix_fds_change (loader->unix_fds_change_data);
3990 #else
3991  _dbus_assert_not_reached("Platform doesn't support unix fd passing");
3992 #endif
3993 }
3994 
3995 /*
3996  * FIXME when we move the header out of the buffer, that memmoves all
3997  * buffered messages. Kind of crappy.
3998  *
3999  * Also we copy the header and body, which is kind of crappy. To
4000  * avoid this, we have to allow header and body to be in a single
4001  * memory block, which is good for messages we read and bad for
4002  * messages we are creating. But we could move_len() the buffer into
4003  * this single memory block, and move_len() will just swap the buffers
4004  * if you're moving the entire buffer replacing the dest string.
4005  *
4006  * We could also have the message loader tell the transport how many
4007  * bytes to read; so it would first ask for some arbitrary number like
4008  * 256, then if the message was incomplete it would use the
4009  * header/body len to ask for exactly the size of the message (or
4010  * blocks the size of a typical kernel buffer for the socket). That
4011  * way we don't get trailing bytes in the buffer that have to be
4012  * memmoved. Though I suppose we also don't have a chance of reading a
4013  * bunch of small messages at once, so the optimization may be stupid.
4014  *
4015  * Another approach would be to keep a "start" index into
4016  * loader->data and only delete it occasionally, instead of after
4017  * each message is loaded.
4018  *
4019  * load_message() returns FALSE if not enough memory OR the loader was corrupted
4020  */
4021 static dbus_bool_t
4022 load_message (DBusMessageLoader *loader,
4023  DBusMessage *message,
4024  int byte_order,
4025  int fields_array_len,
4026  int header_len,
4027  int body_len)
4028 {
4029  dbus_bool_t oom;
4030  DBusValidity validity;
4031  const DBusString *type_str;
4032  int type_pos;
4033  DBusValidationMode mode;
4034  dbus_uint32_t n_unix_fds = 0;
4035 
4036  mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
4037 
4038  oom = FALSE;
4039 
4040 #if 0
4041  _dbus_verbose_bytes_of_string (&loader->data, 0, header_len /* + body_len */);
4042 #endif
4043 
4044  /* 1. VALIDATE AND COPY OVER HEADER */
4045  _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
4046  _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
4047 
4048  if (!_dbus_header_load (&message->header,
4049  mode,
4050  &validity,
4051  byte_order,
4052  fields_array_len,
4053  header_len,
4054  body_len,
4055  &loader->data, 0,
4056  _dbus_string_get_length (&loader->data)))
4057  {
4058  _dbus_verbose ("Failed to load header for new message code %d\n", validity);
4059 
4060  /* assert here so we can catch any code that still uses DBUS_VALID to indicate
4061  oom errors. They should use DBUS_VALIDITY_UNKNOWN_OOM_ERROR instead */
4062  _dbus_assert (validity != DBUS_VALID);
4063 
4064  if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
4065  oom = TRUE;
4066  else
4067  {
4068  loader->corrupted = TRUE;
4069  loader->corruption_reason = validity;
4070  }
4071  goto failed;
4072  }
4073 
4074  _dbus_assert (validity == DBUS_VALID);
4075 
4076  /* 2. VALIDATE BODY */
4077  if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
4078  {
4079  get_const_signature (&message->header, &type_str, &type_pos);
4080 
4081  /* Because the bytes_remaining arg is NULL, this validates that the
4082  * body is the right length
4083  */
4084  validity = _dbus_validate_body_with_reason (type_str,
4085  type_pos,
4086  byte_order,
4087  NULL,
4088  &loader->data,
4089  header_len,
4090  body_len);
4091  if (validity != DBUS_VALID)
4092  {
4093  _dbus_verbose ("Failed to validate message body code %d\n", validity);
4094 
4095  loader->corrupted = TRUE;
4096  loader->corruption_reason = validity;
4097 
4098  goto failed;
4099  }
4100  }
4101 
4102  /* 3. COPY OVER UNIX FDS */
4106  &n_unix_fds);
4107 
4108 #ifdef HAVE_UNIX_FD_PASSING
4109 
4110  if (n_unix_fds > loader->n_unix_fds)
4111  {
4112  _dbus_verbose("Message contains references to more unix fds than were sent %u != %u\n",
4113  n_unix_fds, loader->n_unix_fds);
4114 
4115  loader->corrupted = TRUE;
4116  loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4117  goto failed;
4118  }
4119 
4120  /* If this was a recycled message there might still be
4121  some memory allocated for the fds */
4122  dbus_free(message->unix_fds);
4123 
4124  if (n_unix_fds > 0)
4125  {
4126  message->unix_fds = _dbus_memdup(loader->unix_fds, n_unix_fds * sizeof(message->unix_fds[0]));
4127  if (message->unix_fds == NULL)
4128  {
4129  _dbus_verbose ("Failed to allocate file descriptor array\n");
4130  oom = TRUE;
4131  goto failed;
4132  }
4133 
4134  message->n_unix_fds_allocated = message->n_unix_fds = n_unix_fds;
4135  loader->n_unix_fds -= n_unix_fds;
4136  memmove (loader->unix_fds, loader->unix_fds + n_unix_fds, loader->n_unix_fds * sizeof (loader->unix_fds[0]));
4137 
4138  if (loader->unix_fds_change)
4139  loader->unix_fds_change (loader->unix_fds_change_data);
4140  }
4141  else
4142  message->unix_fds = NULL;
4143 
4144 #else
4145 
4146  if (n_unix_fds > 0)
4147  {
4148  _dbus_verbose ("Hmm, message claims to come with file descriptors "
4149  "but that's not supported on our platform, disconnecting.\n");
4150 
4151  loader->corrupted = TRUE;
4152  loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4153  goto failed;
4154  }
4155 
4156 #endif
4157 
4158  /* 3. COPY OVER BODY AND QUEUE MESSAGE */
4159 
4160  if (!_dbus_list_append (&loader->messages, message))
4161  {
4162  _dbus_verbose ("Failed to append new message to loader queue\n");
4163  oom = TRUE;
4164  goto failed;
4165  }
4166 
4167  _dbus_assert (_dbus_string_get_length (&message->body) == 0);
4169  (header_len + body_len));
4170 
4171  if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
4172  {
4173  _dbus_verbose ("Failed to move body into new message\n");
4174  oom = TRUE;
4175  goto failed;
4176  }
4177 
4178  _dbus_string_delete (&loader->data, 0, header_len + body_len);
4179 
4180  /* don't waste more than 2k of memory */
4181  _dbus_string_compact (&loader->data, 2048);
4182 
4183  _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
4184  _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
4185 
4186  _dbus_verbose ("Loaded message %p\n", message);
4187 
4188  _dbus_assert (!oom);
4189  _dbus_assert (!loader->corrupted);
4190  _dbus_assert (loader->messages != NULL);
4191  _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4192 
4193  return TRUE;
4194 
4195  failed:
4196 
4197  /* Clean up */
4198 
4199  /* does nothing if the message isn't in the list */
4200  _dbus_list_remove_last (&loader->messages, message);
4201 
4202  if (oom)
4203  _dbus_assert (!loader->corrupted);
4204  else
4205  _dbus_assert (loader->corrupted);
4206 
4208 
4209  return FALSE;
4210 }
4211 
4228 {
4229  while (!loader->corrupted &&
4231  {
4232  DBusValidity validity;
4233  int byte_order, fields_array_len, header_len, body_len;
4234 
4236  &validity,
4237  &byte_order,
4238  &fields_array_len,
4239  &header_len,
4240  &body_len,
4241  &loader->data, 0,
4242  _dbus_string_get_length (&loader->data)))
4243  {
4244  DBusMessage *message;
4245 
4246  _dbus_assert (validity == DBUS_VALID);
4247 
4248  message = dbus_message_new_empty_header ();
4249  if (message == NULL)
4250  return FALSE;
4251 
4252  if (!load_message (loader, message,
4253  byte_order, fields_array_len,
4254  header_len, body_len))
4255  {
4256  dbus_message_unref (message);
4257  /* load_message() returns false if corrupted or OOM; if
4258  * corrupted then return TRUE for not OOM
4259  */
4260  return loader->corrupted;
4261  }
4262 
4263  _dbus_assert (loader->messages != NULL);
4264  _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4265  }
4266  else
4267  {
4268  _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
4269  validity);
4270  if (validity != DBUS_VALID)
4271  {
4272  loader->corrupted = TRUE;
4273  loader->corruption_reason = validity;
4274  }
4275  return TRUE;
4276  }
4277  }
4278 
4279  return TRUE;
4280 }
4281 
4289 DBusMessage*
4291 {
4292  if (loader->messages)
4293  return loader->messages->data;
4294  else
4295  return NULL;
4296 }
4297 
4306 DBusMessage*
4308 {
4309  return _dbus_list_pop_first (&loader->messages);
4310 }
4311 
4320 DBusList*
4322 {
4323  return _dbus_list_pop_first_link (&loader->messages);
4324 }
4325 
4332 void
4334  DBusList *link)
4335 {
4336  _dbus_list_prepend_link (&loader->messages, link);
4337 }
4338 
4350 {
4351  _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
4352  (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
4353  return loader->corrupted;
4354 }
4355 
4364 {
4365  _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
4366  (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
4367 
4368  return loader->corruption_reason;
4369 }
4370 
4377 void
4379  long size)
4380 {
4381  if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
4382  {
4383  _dbus_verbose ("clamping requested max message size %ld to %d\n",
4386  }
4387  loader->max_message_size = size;
4388 }
4389 
4396 long
4398 {
4399  return loader->max_message_size;
4400 }
4401 
4408 void
4410  long n)
4411 {
4413  {
4414  _dbus_verbose ("clamping requested max message unix_fds %ld to %d\n",
4417  }
4418  loader->max_message_unix_fds = n;
4419 }
4420 
4427 long
4429 {
4430  return loader->max_message_unix_fds;
4431 }
4432 
4433 static DBusDataSlotAllocator slot_allocator;
4434 _DBUS_DEFINE_GLOBAL_LOCK (message_slots);
4435 
4441 int
4443 {
4444 #ifdef HAVE_UNIX_FD_PASSING
4445  return loader->n_unix_fds;
4446 #else
4447  return 0;
4448 #endif
4449 }
4450 
4459 void
4461  void (* callback) (void *),
4462  void *data)
4463 {
4464 #ifdef HAVE_UNIX_FD_PASSING
4465  loader->unix_fds_change = callback;
4466  loader->unix_fds_change_data = data;
4467 #endif
4468 }
4469 
4486 {
4487  return _dbus_data_slot_allocator_alloc (&slot_allocator,
4488  &_DBUS_LOCK_NAME (message_slots),
4489  slot_p);
4490 }
4491 
4503 void
4505 {
4506  _dbus_return_if_fail (*slot_p >= 0);
4507 
4508  _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
4509 }
4510 
4526  dbus_int32_t slot,
4527  void *data,
4528  DBusFreeFunction free_data_func)
4529 {
4530  DBusFreeFunction old_free_func;
4531  void *old_data;
4532  dbus_bool_t retval;
4533 
4534  _dbus_return_val_if_fail (message != NULL, FALSE);
4535  _dbus_return_val_if_fail (slot >= 0, FALSE);
4536 
4537  retval = _dbus_data_slot_list_set (&slot_allocator,
4538  &message->slot_list,
4539  slot, data, free_data_func,
4540  &old_free_func, &old_data);
4541 
4542  if (retval)
4543  {
4544  /* Do the actual free outside the message lock */
4545  if (old_free_func)
4546  (* old_free_func) (old_data);
4547  }
4548 
4549  return retval;
4550 }
4551 
4560 void*
4562  dbus_int32_t slot)
4563 {
4564  void *res;
4565 
4566  _dbus_return_val_if_fail (message != NULL, NULL);
4567 
4568  res = _dbus_data_slot_list_get (&slot_allocator,
4569  &message->slot_list,
4570  slot);
4571 
4572  return res;
4573 }
4574 
4588 int
4589 dbus_message_type_from_string (const char *type_str)
4590 {
4591  if (strcmp (type_str, "method_call") == 0)
4593  if (strcmp (type_str, "method_return") == 0)
4595  else if (strcmp (type_str, "signal") == 0)
4596  return DBUS_MESSAGE_TYPE_SIGNAL;
4597  else if (strcmp (type_str, "error") == 0)
4598  return DBUS_MESSAGE_TYPE_ERROR;
4599  else
4601 }
4602 
4616 const char *
4618 {
4619  switch (type)
4620  {
4622  return "method_call";
4624  return "method_return";
4626  return "signal";
4628  return "error";
4629  default:
4630  return "invalid";
4631  }
4632 }
4633 
4648  char **marshalled_data_p,
4649  int *len_p)
4650 {
4651  DBusString tmp;
4652  dbus_bool_t was_locked;
4653 
4654  _dbus_return_val_if_fail (msg != NULL, FALSE);
4655  _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
4656  _dbus_return_val_if_fail (len_p != NULL, FALSE);
4657 
4658  if (!_dbus_string_init (&tmp))
4659  return FALSE;
4660 
4661  /* Ensure the message is locked, to ensure the length header is filled in. */
4662  was_locked = msg->locked;
4663 
4664  if (!was_locked)
4665  dbus_message_lock (msg);
4666 
4667  if (!_dbus_string_copy (&(msg->header.data), 0, &tmp, 0))
4668  goto fail;
4669 
4670  *len_p = _dbus_string_get_length (&tmp);
4671 
4672  if (!_dbus_string_copy (&(msg->body), 0, &tmp, *len_p))
4673  goto fail;
4674 
4675  *len_p = _dbus_string_get_length (&tmp);
4676 
4677  if (!_dbus_string_steal_data (&tmp, marshalled_data_p))
4678  goto fail;
4679 
4680  _dbus_string_free (&tmp);
4681 
4682  if (!was_locked)
4683  msg->locked = FALSE;
4684 
4685  return TRUE;
4686 
4687  fail:
4688  _dbus_string_free (&tmp);
4689 
4690  if (!was_locked)
4691  msg->locked = FALSE;
4692 
4693  return FALSE;
4694 }
4695 
4708 DBusMessage *
4709 dbus_message_demarshal (const char *str,
4710  int len,
4711  DBusError *error)
4712 {
4713  DBusMessageLoader *loader;
4714  DBusString *buffer;
4715  DBusMessage *msg;
4716 
4717  _dbus_return_val_if_fail (str != NULL, NULL);
4718 
4719  loader = _dbus_message_loader_new ();
4720 
4721  if (loader == NULL)
4722  return NULL;
4723 
4724  _dbus_message_loader_get_buffer (loader, &buffer);
4725  _dbus_string_append_len (buffer, str, len);
4726  _dbus_message_loader_return_buffer (loader, buffer, len);
4727 
4729  goto fail_oom;
4730 
4732  goto fail_corrupt;
4733 
4734  msg = _dbus_message_loader_pop_message (loader);
4735 
4736  if (!msg)
4737  goto fail_oom;
4738 
4739  _dbus_message_loader_unref (loader);
4740  return msg;
4741 
4742  fail_corrupt:
4743  dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted (%s)",
4744  _dbus_validity_to_error_message (loader->corruption_reason));
4745  _dbus_message_loader_unref (loader);
4746  return NULL;
4747 
4748  fail_oom:
4749  _DBUS_SET_OOM (error);
4750  _dbus_message_loader_unref (loader);
4751  return NULL;
4752 }
4753 
4767 int
4769  int len)
4770 {
4771  DBusString str;
4772  int byte_order, fields_array_len, header_len, body_len;
4773  DBusValidity validity = DBUS_VALID;
4774  int have_message;
4775 
4776  if (!buf || len < DBUS_MINIMUM_HEADER_SIZE)
4777  return 0;
4778 
4779  if (len > DBUS_MAXIMUM_MESSAGE_LENGTH)
4781  _dbus_string_init_const_len (&str, buf, len);
4782 
4783  validity = DBUS_VALID;
4784  have_message
4786  &validity, &byte_order,
4787  &fields_array_len,
4788  &header_len,
4789  &body_len,
4790  &str, 0,
4791  len);
4792  _dbus_string_free (&str);
4793 
4794  if (validity == DBUS_VALID)
4795  {
4796  _dbus_assert (have_message || (header_len + body_len) > len);
4797  (void) have_message; /* unused unless asserting */
4798  return header_len + body_len;
4799  }
4800  else
4801  {
4802  return -1; /* broken! */
4803  }
4804 }
4805 
4808 /* tests in dbus-message-util.c */
dbus_bool_t dbus_type_is_fixed(int typecode)
Tells you whether values of this type can change length if you set them to some other value...
void _dbus_type_reader_read_fixed_multi(const DBusTypeReader *reader, void *value, int *n_elements)
Reads a block of fixed-length basic values, from the current point in an array to the end of the arra...
int dbus_message_type_from_string(const char *type_str)
Utility function to convert a machine-readable (not translated) string into a D-Bus message type...
unsigned int dbus_uint32_t
A 32-bit unsigned integer on all platforms.
DBusMessage * dbus_message_ref(DBusMessage *message)
Increments the reference count of a DBusMessage.
void dbus_message_lock(DBusMessage *message)
Locks a message.
Definition: dbus-message.c:384
const char * message
public error message field
Definition: dbus-errors.h:51
dbus_bool_t dbus_message_has_path(DBusMessage *message, const char *path)
Checks if the message has a particular object path.
dbus_int32_t _dbus_atomic_get(DBusAtomic *atomic)
Atomically get the value of an integer.
dbus_uint32_t changed_stamp
Incremented when iterators are invalidated.
#define NULL
A null pointer, defined appropriately for C or C++.
dbus_bool_t dbus_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.
dbus_bool_t _dbus_header_load(DBusHeader *header, DBusValidationMode mode, DBusValidity *validity, int byte_order, int fields_array_len, int header_len, int body_len, const DBusString *str, int start, int len)
Creates a message header from potentially-untrusted data.
void(* DBusFreeFunction)(void *memory)
The type of a function which frees a block of memory.
Definition: dbus-memory.h:64
long _dbus_message_loader_get_max_message_size(DBusMessageLoader *loader)
Gets the maximum allowed message size in bytes.
void dbus_message_set_no_reply(DBusMessage *message, dbus_bool_t no_reply)
Sets a flag indicating that the message does not want a reply; if this flag is set, the other end of the connection may (but is not required to) optimize by not sending method return or error replies.
void _dbus_message_loader_putback_message_link(DBusMessageLoader *loader, DBusList *link)
Returns a popped message link, used to undo a pop.
dbus_bool_t _dbus_header_copy(const DBusHeader *header, DBusHeader *dest)
Initializes dest with a copy of the given header.
int dbus_message_iter_get_arg_type(DBusMessageIter *iter)
Returns the argument type of the argument that the message iterator points to.
dbus_uint32_t sig_refcount
depth of open_signature()
Definition: dbus-message.c:131
void _dbus_type_writer_remove_types(DBusTypeWriter *writer)
Removes type string from the writer.
void * dbus_realloc(void *memory, size_t bytes)
Resizes a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:600
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:700
void _dbus_message_loader_return_unix_fds(DBusMessageLoader *loader, int *fds, unsigned n_fds)
Returns a buffer obtained from _dbus_message_loader_get_unix_fds().
dbus_uint32_t dbus_message_get_serial(DBusMessage *message)
Returns the serial of a message or 0 if none has been specified.
DBusList * messages
Complete messages.
The type writer is an iterator for writing to a block of values.
void dbus_message_iter_recurse(DBusMessageIter *iter, DBusMessageIter *sub)
Recurses into a container value when reading values from a message, initializing a sub-iterator to us...
void _dbus_type_reader_recurse(DBusTypeReader *reader, DBusTypeReader *sub)
Initialize a new reader pointing to the first type and corresponding value that&#39;s a child of the curr...
DBusMessage * _dbus_message_loader_pop_message(DBusMessageLoader *loader)
Pops a loaded message (passing ownership of the message to the caller).
DBusList * _dbus_list_find_last(DBusList **list, void *data)
Finds a value in the list.
Definition: dbus-list.c:461
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:58
void dbus_message_free_data_slot(dbus_int32_t *slot_p)
Deallocates a global ID for message data slots.
#define DBUS_HEADER_FIELD_SIGNATURE
Header field code for the type signature of a message.
const char * dbus_message_get_error_name(DBusMessage *message)
Gets the error name (DBUS_MESSAGE_TYPE_ERROR only) or NULL if none.
dbus_bool_t dbus_message_iter_close_container(DBusMessageIter *iter, DBusMessageIter *sub)
Closes a container-typed value appended to the message; may write out more information to the message...
dbus_bool_t dbus_message_is_error(DBusMessage *message, const char *error_name)
Checks whether the message is an error reply with the given error name.
void _dbus_list_remove_link(DBusList **list, DBusList *link)
Removes a link from the list.
Definition: dbus-list.c:516
#define DBUS_TYPE_STRUCT
STRUCT and DICT_ENTRY are sort of special since their codes can&#39;t appear in a type string...
#define DBUS_TYPE_DICT_ENTRY
Type code used to represent a dict entry; however, this type code does not appear in type signatures...
const char * dbus_message_get_sender(DBusMessage *message)
Gets the unique name of the connection which originated this message, or NULL if unknown or inapplica...
dbus_bool_t _dbus_message_iter_get_args_valist(DBusMessageIter *iter, DBusError *error, int first_arg_type, va_list var_args)
Implementation of the varargs arg-getting functions.
Definition: dbus-message.c:785
#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:304
Internals of DBusCounter.
dbus_bool_t dbus_message_allocate_data_slot(dbus_int32_t *slot_p)
Allocates an integer ID to be used for storing application-specific data on any DBusMessage.
void * data
Data stored at this element.
Definition: dbus-list.h:38
#define MAX_MESSAGE_CACHE_SIZE
Avoid caching too many messages.
Definition: dbus-message.c:508
DBusMessage * dbus_message_new(int message_type)
Constructs a new message of the given message type.
#define DBUS_ERROR_INCONSISTENT_MESSAGE
The message meta data does not match the payload.
dbus_bool_t _dbus_header_init(DBusHeader *header)
Initializes a header, but doesn&#39;t prepare it for use; to make the header valid, you have to call _dbu...
void _dbus_warn_check_failed(const char *format,...)
Prints a &quot;critical&quot; warning to stderr when an assertion fails; differs from _dbus_warn primarily in t...
const char * dbus_message_get_signature(DBusMessage *message)
Gets the type signature of the message, i.e.
void dbus_message_iter_init_append(DBusMessage *message, DBusMessageIter *iter)
Initializes a DBusMessageIter for appending arguments to the end of a message.
void dbus_error_free(DBusError *error)
Frees an error that&#39;s been set (or just initialized), then reinitializes the error as in dbus_error_i...
Definition: dbus-errors.c:211
void dbus_message_set_auto_start(DBusMessage *message, dbus_bool_t auto_start)
Sets a flag indicating that an owner for the destination name will be automatically started before th...
union DBusMessageRealIter::@6 u
the type writer or reader that does all the work
void _dbus_message_loader_unref(DBusMessageLoader *loader)
Decrements the reference count of the loader and finalizes the loader when the count reaches zero...
DBusCounter * _dbus_counter_ref(DBusCounter *counter)
Increments refcount of the counter.
DBusString data
Header network data, stored separately from body so we can independently realloc it.
unsigned char _dbus_string_get_byte(const DBusString *str, int start)
Gets the byte at the given position.
Definition: dbus-string.c:548
dbus_bool_t dbus_message_has_interface(DBusMessage *message, const char *iface)
Checks if the message has an interface.
int _dbus_dup(int fd, DBusError *error)
Duplicates a file descriptor.
DBusValidity _dbus_message_loader_get_corruption_reason(DBusMessageLoader *loader)
Checks what kind of bad data confused the loader.
dbus_bool_t _dbus_type_writer_write_basic(DBusTypeWriter *writer, int type, const void *value)
Writes out a basic type.
#define DBUS_MESSAGE_TYPE_ERROR
Message type of an error reply message, see dbus_message_get_type()
DBusList * _dbus_list_alloc_link(void *data)
Allocates a linked list node.
Definition: dbus-list.c:231
#define DBUS_MAXIMUM_MESSAGE_UNIX_FDS
The maximum total number of unix fds in a message.
const char * dbus_message_get_path(DBusMessage *message)
Gets the object path this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitt...
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
#define DBUS_MESSAGE_TYPE_METHOD_RETURN
Message type of a method return message, see dbus_message_get_type()
DBusMessage * dbus_message_new_signal(const char *path, const char *iface, const char *name)
Constructs a new message representing a signal emission.
dbus_bool_t _dbus_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:1078
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_data_slot_allocator_alloc(DBusDataSlotAllocator *allocator, DBusRMutex **mutex_loc, dbus_int32_t *slot_id_p)
Allocates an integer ID to be used for storing data in a DBusDataSlotList.
Definition: dbus-dataslot.c:69
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that&#39;s copied to the d...
Definition: dbus-string.c:1288
#define DBUS_HEADER_FIELD_INTERFACE
Header field code for the interface containing a member (method or signal).
#define DBUS_DICT_ENTRY_BEGIN_CHAR
Code marking the start of a dict entry type in a type signature.
DBusList * _dbus_list_pop_first_link(DBusList **list)
Removes the first link in the list and returns it.
Definition: dbus-list.c:617
dbus_bool_t dbus_message_has_member(DBusMessage *message, const char *member)
Checks if the message has an interface member.
DBusValidity
This is primarily used in unit testing, so we can verify that each invalid message is invalid for the...
DBusMessageIter struct; contains no public fields.
Definition: dbus-message.h:51
dbus_bool_t dbus_message_iter_init(DBusMessage *message, DBusMessageIter *iter)
Initializes a DBusMessageIter for reading the arguments of the message passed in. ...
dbus_bool_t _dbus_message_add_counter(DBusMessage *message, DBusCounter *counter)
Adds a counter to be incremented immediately with the size/unix fds of this message, and decremented by the size/unix fds of this message when this message if finalized.
Definition: dbus-message.c:329
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:183
const char * dbus_message_get_destination(DBusMessage *message)
Gets the destination of a message or NULL if there is none set.
void _dbus_message_add_counter_link(DBusMessage *message, DBusList *link)
Adds a counter to be incremented immediately with the size/unix fds of this message, and decremented by the size/unix fds of this message when this message if finalized.
Definition: dbus-message.c:280
#define DBUS_TYPE_ARRAY
Type code marking a D-Bus array type.
DBusString * type_str
where to write typecodes (or read type expectations)
dbus_bool_t dbus_message_iter_append_fixed_array(DBusMessageIter *iter, int element_type, const void *value, int n_elements)
Appends a block of fixed-length values to an array.
dbus_bool_t dbus_message_set_error_name(DBusMessage *message, const char *error_name)
Sets the name of the error (DBUS_MESSAGE_TYPE_ERROR).
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
const char * dbus_message_get_member(DBusMessage *message)
Gets the interface member being invoked (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted (DBUS_MESSAGE_TYPE...
dbus_bool_t _dbus_list_remove_last(DBusList **list, void *data)
Removes a value from the list.
Definition: dbus-list.c:435
Internals of DBusMessage.
Internals of DBusMessageIter.
Definition: dbus-message.c:126
#define dbus_new0(type, count)
Safe macro for using dbus_malloc0().
Definition: dbus-memory.h:59
dbus_uint32_t changed_stamp
stamp to detect invalid iters
Definition: dbus-message.c: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:375
int _dbus_header_get_message_type(DBusHeader *header)
Gets the type of the message.
#define DBUS_HEADER_FIELD_ERROR_NAME
Header field code for an error name (found in DBUS_MESSAGE_TYPE_ERROR messages).
#define DBUS_MINIMUM_HEADER_SIZE
The smallest header size that can occur.
dbus_bool_t _dbus_type_writer_unrecurse(DBusTypeWriter *writer, DBusTypeWriter *sub)
Closes a container created by _dbus_type_writer_recurse() and writes any additional information to th...
dbus_bool_t dbus_type_is_basic(int typecode)
A &quot;basic type&quot; is a somewhat arbitrary concept, but the intent is to include those types that are ful...
void _dbus_message_loader_set_max_message_size(DBusMessageLoader *loader, long size)
Sets the maximum size message we allow.
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:190
DBusHeader header
Header network data and associated cache.
dbus_bool_t dbus_message_set_sender(DBusMessage *message, const char *sender)
Sets the message sender.
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:195
DBusMessageLoader * _dbus_message_loader_ref(DBusMessageLoader *loader)
Increments the reference count of the loader.
dbus_bool_t _dbus_header_get_field_basic(DBusHeader *header, int field, int type, void *value)
Gets the value of a field with basic type.
dbus_bool_t dbus_message_get_path_decomposed(DBusMessage *message, char ***path)
Gets the object path this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitt...
can&#39;t determine validity due to OOM
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
void _dbus_string_delete(DBusString *str, int start, int len)
Deletes a segment of a DBusString with length len starting at start.
Definition: dbus-string.c:1198
dbus_bool_t _dbus_string_init_preallocated(DBusString *str, int allocate_size)
Initializes a string that can be up to the given allocation size before it has to realloc...
Definition: dbus-string.c:132
void _dbus_counter_unref(DBusCounter *counter)
Decrements refcount of the counter and possibly finalizes the counter.
void _dbus_message_remove_counter(DBusMessage *message, DBusCounter *counter)
Removes a counter tracking the size/unix fds of this message, and decrements the counter by the size/...
Definition: dbus-message.c:352
dbus_bool_t _dbus_list_append(DBusList **list, void *data)
Appends a value to the list.
Definition: dbus-list.c:259
dbus_bool_t _dbus_decompose_path(const char *data, int len, char ***path, int *path_len)
Decompose an object path.
void * _dbus_memdup(const void *mem, size_t n_bytes)
Duplicates a block of memory.
dbus_bool_t _dbus_data_slot_list_set(DBusDataSlotAllocator *allocator, DBusDataSlotList *list, int slot, void *data, DBusFreeFunction free_data_func, DBusFreeFunction *old_free_func, void **old_data)
Stores a pointer in the data slot list, along with an optional function to be used for freeing the da...
dbus_bool_t dbus_message_set_path(DBusMessage *message, const char *object_path)
Sets the object path this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or the one a s...
void _dbus_list_foreach(DBusList **list, DBusForeachFunction function, void *data)
Calls the given function for each element in the list.
Definition: dbus-list.c:748
long max_message_size
Maximum size of a message.
void _dbus_counter_adjust_unix_fd(DBusCounter *counter, long delta)
Adjusts the value of the unix fd counter by the given delta which may be positive or negative...
int _dbus_string_get_length(const DBusString *str)
Gets the length of a string (not including nul termination).
Definition: dbus-string.c:725
dbus_bool_t _dbus_type_reader_next(DBusTypeReader *reader)
Skip to the next value on this &quot;level&quot;.
DBusList * counters
0-N DBusCounter used to track message size/unix fds.
DBusMessageLoader * _dbus_message_loader_new(void)
Creates a new message loader.
long size_counter_delta
Size we incremented the size counters by.
#define CHANGED_STAMP_BITS
How many bits are in the changed_stamp used to validate iterators.
void _dbus_header_byteswap(DBusHeader *header, int new_order)
Swaps the header into the given order if required.
dbus_bool_t _dbus_header_have_message_untrusted(int max_message_length, DBusValidity *validity, int *byte_order, int *fields_array_len, int *header_len, int *body_len, const DBusString *str, int start, int len)
Given data long enough to contain the length of the message body and the fields array, check whether the data is long enough to contain the entire message (assuming the claimed lengths are accurate).
#define DBUS_MESSAGE_TYPE_METHOD_CALL
Message type of a method call message, see dbus_message_get_type()
#define DBUS_HEADER_FIELD_UNIX_FDS
Header field code for the number of unix file descriptors associated with this message.
int _dbus_current_generation
_dbus_current_generation is used to track each time that dbus_shutdown() is called, so we can reinit things after it&#39;s been called.
Definition: dbus-memory.c:780
dbus_bool_t dbus_message_get_args(DBusMessage *message, DBusError *error, int first_arg_type,...)
Gets arguments from a message given a variable argument list.
Object representing an exception.
Definition: dbus-errors.h:48
unsigned int in_cache
Has been &quot;freed&quot; since it&#39;s in the cache (this is a debug feature)
void * _dbus_list_pop_first(DBusList **list)
Removes the first value in the list and returns it.
Definition: dbus-list.c:638
#define DBUS_TYPE_SIGNATURE
Type code marking a D-Bus type signature.
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_set_error(DBusError *error, const char *name, const char *format,...)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:354
dbus_uint32_t dbus_message_get_reply_serial(DBusMessage *message)
Returns the serial that the message is a reply to or 0 if none.
#define INITIAL_LOADER_DATA_LEN
The initial buffer size of the message loader.
dbus_bool_t dbus_message_has_signature(DBusMessage *message, const char *signature)
Checks whether the message has the given signature; see dbus_message_get_signature() for more details...
void _dbus_data_slot_list_clear(DBusDataSlotList *list)
Frees all data slots contained in the list, calling application-provided free functions if they exist...
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
dbus_bool_t _dbus_message_loader_get_is_corrupted(DBusMessageLoader *loader)
Checks whether the loader is confused due to bad data.
#define DBUS_TYPE_VARIANT
Type code marking a D-Bus variant type.
#define DBUS_TYPE_UINT32
Type code marking a 32-bit unsigned integer.
Definition: dbus-protocol.h:86
DBusValidity _dbus_validate_body_with_reason(const DBusString *expected_signature, int expected_signature_start, int byte_order, int *bytes_remaining, const DBusString *value_str, int value_pos, int len)
Verifies that the range of value_str from value_pos to value_end is a legitimate value of type expect...
void _dbus_header_reinit(DBusHeader *header)
Re-initializes a header that was previously initialized and never freed.
the data is valid
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_close(int fd, DBusError *error)
Closes a file descriptor.
dbus_bool_t dbus_message_has_destination(DBusMessage *message, const char *name)
Checks whether the message was sent to the given name.
#define DBUS_MESSAGE_TYPE_INVALID
This value is never a valid message type, see dbus_message_get_type()
dbus_bool_t dbus_message_get_auto_start(DBusMessage *message)
Returns TRUE if the message will cause an owner for destination name to be auto-started.
dbus_uint32_t byte_order
byte order to write values with
#define _DBUS_UNLOCK(name)
Unlocks a global lock.
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:242
The type reader is an iterator for reading values from a block of values.
void * _dbus_data_slot_list_get(DBusDataSlotAllocator *allocator, DBusDataSlotList *list, int slot)
Retrieves data previously set with _dbus_data_slot_list_set_data().
long _dbus_message_loader_get_max_message_unix_fds(DBusMessageLoader *loader)
Gets the maximum allowed number of unix fds per message.
#define TRUE
Expands to &quot;1&quot;.
dbus_bool_t dbus_message_marshal(DBusMessage *msg, char **marshalled_data_p, int *len_p)
Turn a DBusMessage into the marshalled form as described in the D-Bus specification.
dbus_bool_t _dbus_header_set_field_basic(DBusHeader *header, int field, int type, const void *value)
Sets the value of a field with basic type.
void _dbus_data_slot_list_init(DBusDataSlotList *list)
Initializes a slot list.
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
DBusMessage * dbus_message_copy(const DBusMessage *message)
Creates a new message that is an exact replica of the message specified, except that its refcount is ...
int dbus_message_iter_get_element_type(DBusMessageIter *iter)
Returns the element type of the array that the message iterator points to.
void _dbus_message_get_network_data(DBusMessage *message, const DBusString **header, const DBusString **body)
Gets the data to be sent over the network for this message.
Definition: dbus-message.c:208
#define DBUS_HEADER_FIELD_MEMBER
Header field code for a member (method or signal).
long max_message_unix_fds
Maximum unix fds in a message.
unsigned int corrupted
We got broken data, and are no longer working.
dbus_bool_t dbus_message_get_args_valist(DBusMessage *message, DBusError *error, int first_arg_type, va_list var_args)
Like dbus_message_get_args but takes a va_list for use by language bindings.
#define DBUS_HEADER_FIELD_SENDER
Header field code for the sender of a message; usually initialized by the message bus...
void _dbus_type_writer_add_types(DBusTypeWriter *writer, DBusString *type_str, int type_pos)
Adds type string to the writer, if it had none.
#define DBUS_TYPE_OBJECT_PATH
Type code marking a D-Bus object path.
dbus_bool_t dbus_set_error_from_message(DBusError *error, DBusMessage *message)
Sets a DBusError based on the contents of the given message.
DBusMessage * dbus_message_demarshal(const char *str, int len, DBusError *error)
Demarshal a D-Bus message from the format described in the D-Bus specification.
void dbus_message_iter_get_fixed_array(DBusMessageIter *iter, void *value, int *n_elements)
Reads a block of fixed-length values from the message iterator.
#define DBUS_TYPE_UNIX_FD
Type code marking a unix file descriptor.
void _dbus_message_loader_return_buffer(DBusMessageLoader *loader, DBusString *buffer, int bytes_read)
Returns a buffer obtained from _dbus_message_loader_get_buffer(), indicating to the loader how many b...
dbus_bool_t _dbus_header_create(DBusHeader *header, int byte_order, int message_type, const char *destination, const char *path, const char *interface, const char *member, const char *error_name)
Fills in the primary fields of the header, so the header is ready for use.
#define _DBUS_DEFINE_GLOBAL_LOCK(name)
Defines a global lock variable with the given name.
const char * dbus_message_get_interface(DBusMessage *message)
Gets the interface this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitted...
An allocator that tracks a set of slot IDs.
Definition: dbus-dataslot.h:55
#define DBUS_TYPE_INVALID
Type code that is never equal to a legitimate type code.
Definition: dbus-protocol.h:60
dbus_bool_t dbus_message_set_reply_serial(DBusMessage *message, dbus_uint32_t reply_serial)
Sets the reply serial of a message (the serial of the message this is a reply to).
void _dbus_counter_notify(DBusCounter *counter)
Calls the notify function from _dbus_counter_set_notify(), if that function has been specified and th...
dbus_bool_t dbus_message_has_sender(DBusMessage *message, const char *name)
Checks whether the message has the given unique name as its sender.
dbus_bool_t dbus_message_iter_next(DBusMessageIter *iter)
Moves the iterator to the next field, if any.
void dbus_message_iter_get_basic(DBusMessageIter *iter, void *value)
Reads a basic-typed value from the message iterator.
void * dbus_message_get_data(DBusMessage *message, dbus_int32_t slot)
Retrieves data previously set with dbus_message_set_data().
void _dbus_type_reader_init(DBusTypeReader *reader, int byte_order, const DBusString *type_str, int type_pos, const DBusString *value_str, int value_pos)
Initializes a type reader.
void _dbus_header_free(DBusHeader *header)
Frees a header.
DBusList * _dbus_message_loader_pop_message_link(DBusMessageLoader *loader)
Pops a loaded message inside a list link (passing ownership of the message and link to the caller)...
#define DBUS_MAXIMUM_ARRAY_LENGTH
Max length of a marshaled array in bytes (64M, 2^26) We use signed int for lengths so must be INT_MAX...
dbus_bool_t dbus_message_set_destination(DBusMessage *message, const char *destination)
Sets the message&#39;s destination.
void dbus_error_init(DBusError *error)
Initializes a DBusError structure.
Definition: dbus-errors.c:188
DBusAtomic refcount
Reference count.
dbus_bool_t dbus_message_get_no_reply(DBusMessage *message)
Returns TRUE if the message does not expect a reply.
const char * _dbus_string_get_const_data_len(const DBusString *str, int start, int len)
const version of _dbus_string_get_data_len().
Definition: dbus-string.c:500
A node in a linked list.
Definition: dbus-list.h:34
dbus_bool_t _dbus_message_loader_get_unix_fds(DBusMessageLoader *loader, int **fds, unsigned *max_n_fds)
Gets the buffer to use for reading unix fds from the network.
void dbus_free_string_array(char **str_array)
Frees a NULL-terminated array of strings.
Definition: dbus-memory.c:748
#define DBUS_TYPE_BOOLEAN
Type code marking a boolean.
Definition: dbus-protocol.h:70
void _dbus_message_loader_get_buffer(DBusMessageLoader *loader, DBusString **buffer)
Gets the buffer to use for reading data from the network.
dbus_bool_t _dbus_string_append_len(DBusString *str, const char *buffer, int len)
Appends block of bytes with the given length to a DBusString.
Definition: dbus-string.c:1142
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_STRING_DEFINE_STATIC(_dbus_header_signature_str, DBUS_HEADER_SIGNATURE)
Static DBusString containing the signature of a message header.
dbus_bool_t dbus_message_iter_open_container(DBusMessageIter *iter, int type, const char *contained_signature, DBusMessageIter *sub)
Appends a container-typed value to the message; you are required to append the contents of the contai...
dbus_bool_t _dbus_type_reader_has_next(const DBusTypeReader *reader)
Check whether there&#39;s another value on this &quot;level&quot;.
A simple value union that lets you access bytes as if they were various types; useful when dealing wi...
Definition: dbus-types.h:157
dbus_uint32_t container_type
what are we inside? (e.g.
int _dbus_type_reader_get_array_length(const DBusTypeReader *reader)
Returns the number of bytes in the array.
dbus_bool_t _dbus_header_get_field_raw(DBusHeader *header, int field, const DBusString **str, int *pos)
Gets the raw marshaled data for a field.
dbus_bool_t dbus_message_iter_append_basic(DBusMessageIter *iter, int type, const void *value)
Appends a basic-typed value to the message.
int dbus_message_iter_get_array_len(DBusMessageIter *iter)
Returns the number of bytes in the array as marshaled in the wire protocol.
void(* DBusForeachFunction)(void *element, void *data)
Used to iterate over each item in a collection, such as a DBusList.
int _dbus_type_reader_get_current_type(const DBusTypeReader *reader)
Gets the type of the value the reader is currently pointing to; or for a types-only reader gets the t...
#define FALSE
Expands to &quot;0&quot;.
Message header data and some cached details of it.
#define DBUS_HEADER_FIELD_PATH
Header field code for the path - the path is the object emitting a signal or the object receiving a m...
int dbus_message_get_type(DBusMessage *message)
Gets the type of a message.
#define DBUS_HEADER_FIELD_REPLY_SERIAL
Header field code for a reply serial, used to match a DBUS_MESSAGE_TYPE_METHOD_RETURN message with th...
unsigned int buffer_outstanding
Someone is using the buffer to read.
int generation
_dbus_current_generation when message was created
void _dbus_list_prepend_link(DBusList **list, DBusList *link)
Prepends a link to the list.
Definition: dbus-list.c:322
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:788
dbus_bool_t _dbus_register_shutdown_func(DBusShutdownFunction function, void *data)
Register a cleanup function to be called exactly once the next time dbus_shutdown() is called...
Definition: dbus-memory.c:809
#define _DBUS_LOCK(name)
Locks a global lock.
#define _DBUS_LOCK_NAME(name)
Expands to name of a global lock variable.
const char * _dbus_type_to_string(int typecode)
Returns a string describing the given type.
DBusMessage * _dbus_message_loader_peek_message(DBusMessageLoader *loader)
Peeks at first loaded message, returns NULL if no messages have been queued.
dbus_bool_t _dbus_string_copy_len(const DBusString *source, int start, int len, DBusString *dest, int insert_at)
Like _dbus_string_copy(), but can copy a segment from the middle of the source string.
Definition: dbus-string.c:1380
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:627
void _dbus_type_reader_get_signature(const DBusTypeReader *reader, const DBusString **str_p, int *start_p, int *len_p)
Gets the string and range of said string containing the signature of the current value.
dbus_bool_t dbus_message_append_args_valist(DBusMessage *message, int first_arg_type, va_list var_args)
Like dbus_message_append_args() but takes a va_list for use by language bindings. ...
int dbus_message_demarshal_bytes_needed(const char *buf, int len)
Returns the number of bytes required to be in the buffer to demarshal a D-Bus message.
char * dbus_message_iter_get_signature(DBusMessageIter *iter)
Returns the current signature of a message iterator.
dbus_bool_t _dbus_type_writer_write_fixed_multi(DBusTypeWriter *writer, int element_type, const void *value, int n_elements)
Writes a block of fixed-length basic values, i.e.
void dbus_message_iter_abandon_container(DBusMessageIter *iter, DBusMessageIter *sub)
Abandons creation of a contained-typed value and frees resources created by dbus_message_iter_open_co...
void _dbus_verbose_bytes_of_string(const DBusString *str, int start, int len)
Dump the given part of the string to verbose log.
dbus_bool_t dbus_message_contains_unix_fds(DBusMessage *message)
Checks whether a message contains unix fds.
#define DBUS_HEADER_FLAG_NO_AUTO_START
If set, this flag means that even if the message bus knows how to start an owner for the destination ...
dbus_bool_t _dbus_message_loader_queue_messages(DBusMessageLoader *loader)
Converts buffered data into messages, if we have enough data.
void _dbus_message_get_unix_fds(DBusMessage *message, const int **fds, unsigned *n_fds)
Gets the unix fds to be sent over the network for this message.
Definition: dbus-message.c:227
int refcount
Reference count.
int dbus_int32_t
A 32-bit signed integer on all platforms.
char * _dbus_strdup(const char *str)
Duplicates a string.
#define MAX_MESSAGE_SIZE_TO_CACHE
Avoid caching huge messages.
Definition: dbus-message.c:505
#define DBUS_ERROR_INVALID_ARGS
Invalid arguments passed to a method call.
void _dbus_data_slot_allocator_free(DBusDataSlotAllocator *allocator, dbus_int32_t *slot_id_p)
Deallocates an ID previously allocated with _dbus_data_slot_allocator_alloc().
int _dbus_type_get_alignment(int typecode)
Gets the alignment requirement for the given type; will be 1, 4, or 8.
DBusValidity corruption_reason
why we were corrupted
void _dbus_message_loader_set_max_message_unix_fds(DBusMessageLoader *loader, long n)
Sets the maximum unix fds per message we allow.
dbus_bool_t dbus_message_set_member(DBusMessage *message, const char *member)
Sets the interface member being invoked (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted (DBUS_MESSAGE_TYPE...
const char * _dbus_string_get_const_data(const DBusString *str)
Gets the raw character buffer from a const string.
Definition: dbus-string.c:454
const char * dbus_message_type_to_string(int type)
Utility function to convert a D-Bus message type into a machine-readable string (not translated)...
void dbus_message_unref(DBusMessage *message)
Decrements the reference count of a DBusMessage, freeing the message if the count reaches 0...
void _dbus_string_init_const_len(DBusString *str, const char *value, int len)
Initializes a constant string with a length.
Definition: dbus-string.c:210
Implementation details of DBusMessageLoader.
dbus_bool_t _dbus_type_writer_recurse(DBusTypeWriter *writer, int container_type, const DBusString *contained_type, int contained_type_start, DBusTypeWriter *sub)
Opens a new container and writes out the initial information for that container.
dbus_uint32_t u32
as int32
Definition: dbus-types.h:163
DBusMessage * dbus_message_new_error_printf(DBusMessage *reply_to, const char *error_name, const char *error_format,...)
Creates a new message that is an error reply to another message, allowing you to use printf formattin...
dbus_bool_t dbus_message_set_data(DBusMessage *message, dbus_int32_t slot, void *data, DBusFreeFunction free_data_func)
Stores a pointer on a DBusMessage, along with an optional function to be used for freeing the data wh...
void dbus_message_set_serial(DBusMessage *message, dbus_uint32_t serial)
Sets the serial number of a message.
Definition: dbus-message.c:254
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:531
void _dbus_marshal_byteswap(const DBusString *signature, int signature_start, int old_byte_order, int new_byte_order, DBusString *value_str, int value_pos)
Byteswaps the marshaled data in the given value_str.
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 &quot;container type&quot; can contain basic types, or nested container types.
DBusMessage * dbus_message_new_error(DBusMessage *reply_to, const char *error_name, const char *error_message)
Creates a new message that is an error reply to another message.
void _dbus_counter_adjust_size(DBusCounter *counter, long delta)
Adjusts the value of the size counter by the given delta which may be positive or negative...