D-Bus  1.7.6
dbus-message.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-message.c DBusMessage object
3  *
4  * Copyright (C) 2002, 2003, 2004, 2005 Red Hat Inc.
5  * Copyright (C) 2002, 2003 CodeFactory AB
6  *
7  * Licensed under the Academic Free License version 2.1
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 #include <config.h>
26 #include "dbus-internals.h"
27 #include "dbus-marshal-recursive.h"
28 #include "dbus-marshal-validate.h"
29 #include "dbus-marshal-byteswap.h"
30 #include "dbus-marshal-header.h"
31 #include "dbus-signature.h"
32 #include "dbus-message-private.h"
33 #include "dbus-object-tree.h"
34 #include "dbus-memory.h"
35 #include "dbus-list.h"
36 #include "dbus-threads-internal.h"
37 #ifdef HAVE_UNIX_FD_PASSING
38 #include "dbus-sysdeps-unix.h"
39 #endif
40 
41 #include <string.h>
42 
43 #define _DBUS_TYPE_IS_STRINGLIKE(type) \
44  (type == DBUS_TYPE_STRING || type == DBUS_TYPE_SIGNATURE || \
45  type == DBUS_TYPE_OBJECT_PATH)
46 
47 static void dbus_message_finalize (DBusMessage *message);
48 
59 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
60 static dbus_bool_t
61 _dbus_enable_message_cache (void)
62 {
63  static int enabled = -1;
64 
65  if (enabled < 0)
66  {
67  const char *s = _dbus_getenv ("DBUS_MESSAGE_CACHE");
68 
69  enabled = TRUE;
70 
71  if (s && *s)
72  {
73  if (*s == '0')
74  enabled = FALSE;
75  else if (*s == '1')
76  enabled = TRUE;
77  else
78  _dbus_warn ("DBUS_MESSAGE_CACHE should be 0 or 1 if set, not '%s'",
79  s);
80  }
81  }
82 
83  return enabled;
84 }
85 #else
86  /* constant expression, should be optimized away */
87 # define _dbus_enable_message_cache() (TRUE)
88 #endif
89 
90 #ifndef _dbus_message_trace_ref
91 void
92 _dbus_message_trace_ref (DBusMessage *message,
93  int old_refcount,
94  int new_refcount,
95  const char *why)
96 {
97  static int enabled = -1;
98 
99  _dbus_trace_ref ("DBusMessage", message, old_refcount, new_refcount, why,
100  "DBUS_MESSAGE_TRACE", &enabled);
101 }
102 #endif
103 
104 /* Not thread locked, but strictly const/read-only so should be OK
105  */
107 _DBUS_STRING_DEFINE_STATIC(_dbus_empty_signature_str, "");
108 
109 /* these have wacky values to help trap uninitialized iterators;
110  * but has to fit in 3 bits
111  */
112 enum {
113  DBUS_MESSAGE_ITER_TYPE_READER = 3,
114  DBUS_MESSAGE_ITER_TYPE_WRITER = 7
115 };
116 
119 
126 {
129  dbus_uint32_t iter_type : 3;
130  dbus_uint32_t sig_refcount : 8;
131  union
132  {
135  } u;
136 };
137 
138 static void
139 get_const_signature (DBusHeader *header,
140  const DBusString **type_str_p,
141  int *type_pos_p)
142 {
143  if (_dbus_header_get_field_raw (header,
145  type_str_p,
146  type_pos_p))
147  {
148  *type_pos_p += 1; /* skip the signature length which is 1 byte */
149  }
150  else
151  {
152  *type_str_p = &_dbus_empty_signature_str;
153  *type_pos_p = 0;
154  }
155 }
156 
162 static void
163 _dbus_message_byteswap (DBusMessage *message)
164 {
165  const DBusString *type_str;
166  int type_pos;
167  char byte_order;
168 
169  byte_order = _dbus_header_get_byte_order (&message->header);
170 
171  if (byte_order == DBUS_COMPILER_BYTE_ORDER)
172  return;
173 
174  _dbus_verbose ("Swapping message into compiler byte order\n");
175 
176  get_const_signature (&message->header, &type_str, &type_pos);
177 
178  _dbus_marshal_byteswap (type_str, type_pos,
179  byte_order,
180  DBUS_COMPILER_BYTE_ORDER,
181  &message->body, 0);
182 
183  _dbus_header_byteswap (&message->header, DBUS_COMPILER_BYTE_ORDER);
185  DBUS_COMPILER_BYTE_ORDER);
186 }
187 
194 #define ensure_byte_order(message) _dbus_message_byteswap (message)
195 
206 void
208  const DBusString **header,
209  const DBusString **body)
210 {
211  _dbus_assert (message->locked);
212 
213  *header = &message->header.data;
214  *body = &message->body;
215 }
216 
227  const int **fds,
228  unsigned *n_fds)
229 {
230  _dbus_assert (message->locked);
231 
232 #ifdef HAVE_UNIX_FD_PASSING
233  *fds = message->unix_fds;
234  *n_fds = message->n_unix_fds;
235 #else
236  *fds = NULL;
237  *n_fds = 0;
238 #endif
239 }
240 
252 void
254  dbus_uint32_t serial)
255 {
256  _dbus_return_if_fail (message != NULL);
257  _dbus_return_if_fail (!message->locked);
258 
259  _dbus_header_set_serial (&message->header, serial);
260 }
261 
278 void
280  DBusList *link)
281 {
282  /* right now we don't recompute the delta when message
283  * size changes, and that's OK for current purposes
284  * I think, but could be important to change later.
285  * Do recompute it whenever there are no outstanding counters,
286  * since it's basically free.
287  */
288  if (message->counters == NULL)
289  {
290  message->size_counter_delta =
291  _dbus_string_get_length (&message->header.data) +
292  _dbus_string_get_length (&message->body);
293 
294 #ifdef HAVE_UNIX_FD_PASSING
295  message->unix_fd_counter_delta = message->n_unix_fds;
296 #endif
297 
298 #if 0
299  _dbus_verbose ("message has size %ld\n",
300  message->size_counter_delta);
301 #endif
302  }
303 
304  _dbus_list_append_link (&message->counters, link);
305 
307 
308 #ifdef HAVE_UNIX_FD_PASSING
309  _dbus_counter_adjust_unix_fd (link->data, message->unix_fd_counter_delta);
310 #endif
311 }
312 
329  DBusCounter *counter)
330 {
331  DBusList *link;
332 
333  link = _dbus_list_alloc_link (counter);
334  if (link == NULL)
335  return FALSE;
336 
337  _dbus_counter_ref (counter);
338  _dbus_message_add_counter_link (message, link);
339 
340  return TRUE;
341 }
342 
350 void
352  DBusCounter *counter)
353 {
354  DBusList *link;
355 
356  link = _dbus_list_find_last (&message->counters,
357  counter);
358  _dbus_assert (link != NULL);
359 
360  _dbus_list_remove_link (&message->counters, link);
361 
362  _dbus_counter_adjust_size (counter, - message->size_counter_delta);
363 
364 #ifdef HAVE_UNIX_FD_PASSING
365  _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
366 #endif
367 
368  _dbus_counter_notify (counter);
369  _dbus_counter_unref (counter);
370 }
371 
382 void
384 {
385  if (!message->locked)
386  {
388  _dbus_string_get_length (&message->body));
389 
390  /* must have a signature if you have a body */
391  _dbus_assert (_dbus_string_get_length (&message->body) == 0 ||
392  dbus_message_get_signature (message) != NULL);
393 
394  message->locked = TRUE;
395  }
396 }
397 
398 static dbus_bool_t
399 set_or_delete_string_field (DBusMessage *message,
400  int field,
401  int typecode,
402  const char *value)
403 {
404  if (value == NULL)
405  return _dbus_header_delete_field (&message->header, field);
406  else
407  return _dbus_header_set_field_basic (&message->header,
408  field,
409  typecode,
410  &value);
411 }
412 
413 #if 0
414 /* Probably we don't need to use this */
438 static dbus_bool_t
439 _dbus_message_set_signature (DBusMessage *message,
440  const char *signature)
441 {
442  _dbus_return_val_if_fail (message != NULL, FALSE);
443  _dbus_return_val_if_fail (!message->locked, FALSE);
444  _dbus_return_val_if_fail (signature == NULL ||
445  _dbus_check_is_valid_signature (signature));
446  /* can't delete the signature if you have a message body */
447  _dbus_return_val_if_fail (_dbus_string_get_length (&message->body) == 0 ||
448  signature != NULL);
449 
450  return set_or_delete_string_field (message,
453  signature);
454 }
455 #endif
456 
457 /* Message Cache
458  *
459  * We cache some DBusMessage to reduce the overhead of allocating
460  * them. In my profiling this consistently made about an 8%
461  * difference. It avoids the malloc for the message, the malloc for
462  * the slot list, the malloc for the header string and body string,
463  * and the associated free() calls. It does introduce another global
464  * lock which could be a performance issue in certain cases.
465  *
466  * For the echo client/server the round trip time goes from around
467  * .000077 to .000069 with the message cache on my laptop. The sysprof
468  * change is as follows (numbers are cumulative percentage):
469  *
470  * with message cache implemented as array as it is now (0.000069 per):
471  * new_empty_header 1.46
472  * mutex_lock 0.56 # i.e. _DBUS_LOCK(message_cache)
473  * mutex_unlock 0.25
474  * self 0.41
475  * unref 2.24
476  * self 0.68
477  * list_clear 0.43
478  * mutex_lock 0.33 # i.e. _DBUS_LOCK(message_cache)
479  * mutex_unlock 0.25
480  *
481  * with message cache implemented as list (0.000070 per roundtrip):
482  * new_empty_header 2.72
483  * list_pop_first 1.88
484  * unref 3.3
485  * list_prepend 1.63
486  *
487  * without cache (0.000077 per roundtrip):
488  * new_empty_header 6.7
489  * string_init_preallocated 3.43
490  * dbus_malloc 2.43
491  * dbus_malloc0 2.59
492  *
493  * unref 4.02
494  * string_free 1.82
495  * dbus_free 1.63
496  * dbus_free 0.71
497  *
498  * If you implement the message_cache with a list, the primary reason
499  * it's slower is that you add another thread lock (on the DBusList
500  * mempool).
501  */
502 
504 #define MAX_MESSAGE_SIZE_TO_CACHE 10 * _DBUS_ONE_KILOBYTE
505 
507 #define MAX_MESSAGE_CACHE_SIZE 5
508 
509 /* Protected by _DBUS_LOCK (message_cache) */
510 static DBusMessage *message_cache[MAX_MESSAGE_CACHE_SIZE];
511 static int message_cache_count = 0;
512 static dbus_bool_t message_cache_shutdown_registered = FALSE;
513 
514 static void
515 dbus_message_cache_shutdown (void *data)
516 {
517  int i;
518 
519  if (!_DBUS_LOCK (message_cache))
520  _dbus_assert_not_reached ("we would have initialized global locks "
521  "before registering a shutdown function");
522 
523  i = 0;
524  while (i < MAX_MESSAGE_CACHE_SIZE)
525  {
526  if (message_cache[i])
527  dbus_message_finalize (message_cache[i]);
528 
529  ++i;
530  }
531 
532  message_cache_count = 0;
533  message_cache_shutdown_registered = FALSE;
534 
535  _DBUS_UNLOCK (message_cache);
536 }
537 
545 static DBusMessage*
546 dbus_message_get_cached (void)
547 {
548  DBusMessage *message;
549  int i;
550 
551  message = NULL;
552 
553  if (!_DBUS_LOCK (message_cache))
554  {
555  /* we'd have initialized global locks before caching anything,
556  * so there can't be anything in the cache */
557  return NULL;
558  }
559 
560  _dbus_assert (message_cache_count >= 0);
561 
562  if (message_cache_count == 0)
563  {
564  _DBUS_UNLOCK (message_cache);
565  return NULL;
566  }
567 
568  /* This is not necessarily true unless count > 0, and
569  * message_cache is uninitialized until the shutdown is
570  * registered
571  */
572  _dbus_assert (message_cache_shutdown_registered);
573 
574  i = 0;
575  while (i < MAX_MESSAGE_CACHE_SIZE)
576  {
577  if (message_cache[i])
578  {
579  message = message_cache[i];
580  message_cache[i] = NULL;
581  message_cache_count -= 1;
582  break;
583  }
584  ++i;
585  }
586  _dbus_assert (message_cache_count >= 0);
588  _dbus_assert (message != NULL);
589 
590  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
591 
592  _dbus_assert (message->counters == NULL);
593 
594  _DBUS_UNLOCK (message_cache);
595 
596  return message;
597 }
598 
599 #ifdef HAVE_UNIX_FD_PASSING
600 static void
601 close_unix_fds(int *fds, unsigned *n_fds)
602 {
603  DBusError e;
604  int i;
605 
606  if (*n_fds <= 0)
607  return;
608 
609  dbus_error_init(&e);
610 
611  for (i = 0; i < *n_fds; i++)
612  {
613  if (!_dbus_close(fds[i], &e))
614  {
615  _dbus_warn("Failed to close file descriptor: %s\n", e.message);
616  dbus_error_free(&e);
617  }
618  }
619 
620  *n_fds = 0;
621 
622  /* We don't free the array here, in case we can recycle it later */
623 }
624 #endif
625 
626 static void
627 free_counter (void *element,
628  void *data)
629 {
630  DBusCounter *counter = element;
631  DBusMessage *message = data;
632 
633  _dbus_counter_adjust_size (counter, - message->size_counter_delta);
634 #ifdef HAVE_UNIX_FD_PASSING
635  _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
636 #endif
637 
638  _dbus_counter_notify (counter);
639  _dbus_counter_unref (counter);
640 }
641 
647 static void
648 dbus_message_cache_or_finalize (DBusMessage *message)
649 {
650  dbus_bool_t was_cached;
651  int i;
652 
653  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
654 
655  /* This calls application code and has to be done first thing
656  * without holding the lock
657  */
659 
660  _dbus_list_foreach (&message->counters,
661  free_counter, message);
662  _dbus_list_clear (&message->counters);
663 
664 #ifdef HAVE_UNIX_FD_PASSING
665  close_unix_fds(message->unix_fds, &message->n_unix_fds);
666 #endif
667 
668  was_cached = FALSE;
669 
670  if (!_DBUS_LOCK (message_cache))
671  {
672  /* The only way to get a non-null message goes through
673  * dbus_message_get_cached() which takes the lock. */
674  _dbus_assert_not_reached ("we would have initialized global locks "
675  "the first time we constructed a message");
676  }
677 
678  if (!message_cache_shutdown_registered)
679  {
680  _dbus_assert (message_cache_count == 0);
681 
682  if (!_dbus_register_shutdown_func (dbus_message_cache_shutdown, NULL))
683  goto out;
684 
685  i = 0;
686  while (i < MAX_MESSAGE_CACHE_SIZE)
687  {
688  message_cache[i] = NULL;
689  ++i;
690  }
691 
692  message_cache_shutdown_registered = TRUE;
693  }
694 
695  _dbus_assert (message_cache_count >= 0);
696 
697  if (!_dbus_enable_message_cache ())
698  goto out;
699 
700  if ((_dbus_string_get_length (&message->header.data) +
701  _dbus_string_get_length (&message->body)) >
703  goto out;
704 
705  if (message_cache_count >= MAX_MESSAGE_CACHE_SIZE)
706  goto out;
707 
708  /* Find empty slot */
709  i = 0;
710  while (message_cache[i] != NULL)
711  ++i;
712 
714 
715  _dbus_assert (message_cache[i] == NULL);
716  message_cache[i] = message;
717  message_cache_count += 1;
718  was_cached = TRUE;
719 #ifndef DBUS_DISABLE_CHECKS
720  message->in_cache = TRUE;
721 #endif
722 
723  out:
724  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
725 
726  _DBUS_UNLOCK (message_cache);
727 
728  if (!was_cached)
729  dbus_message_finalize (message);
730 }
731 
732 #if defined(DBUS_ENABLE_CHECKS) || defined(DBUS_ENABLE_ASSERT)
733 static dbus_bool_t
734 _dbus_message_iter_check (DBusMessageRealIter *iter)
735 {
736  char byte_order;
737 
738  if (iter == NULL)
739  {
740  _dbus_warn_check_failed ("dbus message iterator is NULL\n");
741  return FALSE;
742  }
743 
744  byte_order = _dbus_header_get_byte_order (&iter->message->header);
745 
746  if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_READER)
747  {
748  if (iter->u.reader.byte_order != byte_order)
749  {
750  _dbus_warn_check_failed ("dbus message changed byte order since iterator was created\n");
751  return FALSE;
752  }
753  /* because we swap the message into compiler order when you init an iter */
754  _dbus_assert (iter->u.reader.byte_order == DBUS_COMPILER_BYTE_ORDER);
755  }
756  else if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER)
757  {
758  if (iter->u.writer.byte_order != byte_order)
759  {
760  _dbus_warn_check_failed ("dbus message changed byte order since append iterator was created\n");
761  return FALSE;
762  }
763  /* because we swap the message into compiler order when you init an iter */
764  _dbus_assert (iter->u.writer.byte_order == DBUS_COMPILER_BYTE_ORDER);
765  }
766  else
767  {
768  _dbus_warn_check_failed ("dbus message iterator looks uninitialized or corrupted\n");
769  return FALSE;
770  }
771 
772  if (iter->changed_stamp != iter->message->changed_stamp)
773  {
774  _dbus_warn_check_failed ("dbus message iterator invalid because the message has been modified (or perhaps the iterator is just uninitialized)\n");
775  return FALSE;
776  }
777 
778  return TRUE;
779 }
780 #endif /* DBUS_ENABLE_CHECKS || DBUS_ENABLE_ASSERT */
781 
798  DBusError *error,
799  int first_arg_type,
800  va_list var_args)
801 {
803  int spec_type, msg_type, i, j;
804  dbus_bool_t retval;
805 
806  _dbus_assert (_dbus_message_iter_check (real));
807 
808  retval = FALSE;
809 
810  spec_type = first_arg_type;
811  i = 0;
812 
813  while (spec_type != DBUS_TYPE_INVALID)
814  {
815  msg_type = dbus_message_iter_get_arg_type (iter);
816 
817  if (msg_type != spec_type)
818  {
820  "Argument %d is specified to be of type \"%s\", but "
821  "is actually of type \"%s\"\n", i,
822  _dbus_type_to_string (spec_type),
823  _dbus_type_to_string (msg_type));
824 
825  goto out;
826  }
827 
828  if (spec_type == DBUS_TYPE_UNIX_FD)
829  {
830 #ifdef HAVE_UNIX_FD_PASSING
831  DBusBasicValue idx;
832  int *pfd, nfd;
833 
834  pfd = va_arg (var_args, int*);
835  _dbus_assert(pfd);
836 
837  _dbus_type_reader_read_basic(&real->u.reader, &idx);
838 
839  if (idx.u32 >= real->message->n_unix_fds)
840  {
842  "Message refers to file descriptor at index %i,"
843  "but has only %i descriptors attached.\n",
844  idx.u32,
845  real->message->n_unix_fds);
846  goto out;
847  }
848 
849  if ((nfd = _dbus_dup(real->message->unix_fds[idx.u32], error)) < 0)
850  goto out;
851 
852  *pfd = nfd;
853 #else
855  "Platform does not support file desciptor passing.\n");
856  goto out;
857 #endif
858  }
859  else if (dbus_type_is_basic (spec_type))
860  {
861  DBusBasicValue *ptr;
862 
863  ptr = va_arg (var_args, DBusBasicValue*);
864 
865  _dbus_assert (ptr != NULL);
866 
868  ptr);
869  }
870  else if (spec_type == DBUS_TYPE_ARRAY)
871  {
872  int element_type;
873  int spec_element_type;
874  const DBusBasicValue **ptr;
875  int *n_elements_p;
876  DBusTypeReader array;
877 
878  spec_element_type = va_arg (var_args, int);
879  element_type = _dbus_type_reader_get_element_type (&real->u.reader);
880 
881  if (spec_element_type != element_type)
882  {
884  "Argument %d is specified to be an array of \"%s\", but "
885  "is actually an array of \"%s\"\n",
886  i,
887  _dbus_type_to_string (spec_element_type),
888  _dbus_type_to_string (element_type));
889 
890  goto out;
891  }
892 
893  if (dbus_type_is_fixed (spec_element_type) &&
894  element_type != DBUS_TYPE_UNIX_FD)
895  {
896  ptr = va_arg (var_args, const DBusBasicValue**);
897  n_elements_p = va_arg (var_args, int*);
898 
899  _dbus_assert (ptr != NULL);
900  _dbus_assert (n_elements_p != NULL);
901 
902  _dbus_type_reader_recurse (&real->u.reader, &array);
903 
905  (void *) ptr, n_elements_p);
906  }
907  else if (_DBUS_TYPE_IS_STRINGLIKE (spec_element_type))
908  {
909  char ***str_array_p;
910  int n_elements;
911  char **str_array;
912 
913  str_array_p = va_arg (var_args, char***);
914  n_elements_p = va_arg (var_args, int*);
915 
916  _dbus_assert (str_array_p != NULL);
917  _dbus_assert (n_elements_p != NULL);
918 
919  /* Count elements in the array */
920  _dbus_type_reader_recurse (&real->u.reader, &array);
921 
922  n_elements = 0;
924  {
925  ++n_elements;
926  _dbus_type_reader_next (&array);
927  }
928 
929  str_array = dbus_new0 (char*, n_elements + 1);
930  if (str_array == NULL)
931  {
932  _DBUS_SET_OOM (error);
933  goto out;
934  }
935 
936  /* Now go through and dup each string */
937  _dbus_type_reader_recurse (&real->u.reader, &array);
938 
939  j = 0;
940  while (j < n_elements)
941  {
942  const char *s;
944  (void *) &s);
945 
946  str_array[j] = _dbus_strdup (s);
947  if (str_array[j] == NULL)
948  {
949  dbus_free_string_array (str_array);
950  _DBUS_SET_OOM (error);
951  goto out;
952  }
953 
954  ++j;
955 
956  if (!_dbus_type_reader_next (&array))
957  _dbus_assert (j == n_elements);
958  }
959 
961  _dbus_assert (j == n_elements);
962  _dbus_assert (str_array[j] == NULL);
963 
964  *str_array_p = str_array;
965  *n_elements_p = n_elements;
966  }
967 #ifndef DBUS_DISABLE_CHECKS
968  else
969  {
970  _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now\n",
971  _DBUS_FUNCTION_NAME);
972  goto out;
973  }
974 #endif
975  }
976 #ifndef DBUS_DISABLE_CHECKS
977  else
978  {
979  _dbus_warn ("you can only read arrays and basic types with %s for now\n",
980  _DBUS_FUNCTION_NAME);
981  goto out;
982  }
983 #endif
984 
985  spec_type = va_arg (var_args, int);
986  if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID)
987  {
989  "Message has only %d arguments, but more were expected", i + 1);
990  goto out;
991  }
992 
993  i++;
994  }
995 
996  retval = TRUE;
997 
998  out:
999 
1000  return retval;
1001 }
1002 
1061 dbus_uint32_t
1063 {
1064  _dbus_return_val_if_fail (message != NULL, 0);
1065 
1066  return _dbus_header_get_serial (&message->header);
1067 }
1068 
1079  dbus_uint32_t reply_serial)
1080 {
1081  _dbus_return_val_if_fail (message != NULL, FALSE);
1082  _dbus_return_val_if_fail (!message->locked, FALSE);
1083  _dbus_return_val_if_fail (reply_serial != 0, FALSE); /* 0 is invalid */
1084 
1085  return _dbus_header_set_field_basic (&message->header,
1088  &reply_serial);
1089 }
1090 
1097 dbus_uint32_t
1099 {
1100  dbus_uint32_t v_UINT32;
1101 
1102  _dbus_return_val_if_fail (message != NULL, 0);
1103 
1104  if (_dbus_header_get_field_basic (&message->header,
1107  &v_UINT32))
1108  return v_UINT32;
1109  else
1110  return 0;
1111 }
1112 
1113 static void
1114 dbus_message_finalize (DBusMessage *message)
1115 {
1116  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
1117 
1118  /* This calls application callbacks! */
1120 
1121  _dbus_list_foreach (&message->counters,
1122  free_counter, message);
1123  _dbus_list_clear (&message->counters);
1124 
1125  _dbus_header_free (&message->header);
1126  _dbus_string_free (&message->body);
1127 
1128 #ifdef HAVE_UNIX_FD_PASSING
1129  close_unix_fds(message->unix_fds, &message->n_unix_fds);
1130  dbus_free(message->unix_fds);
1131 #endif
1132 
1133  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
1134 
1135  dbus_free (message);
1136 }
1137 
1138 static DBusMessage*
1139 dbus_message_new_empty_header (void)
1140 {
1141  DBusMessage *message;
1142  dbus_bool_t from_cache;
1143 
1144  message = dbus_message_get_cached ();
1145 
1146  if (message != NULL)
1147  {
1148  from_cache = TRUE;
1149  }
1150  else
1151  {
1152  from_cache = FALSE;
1153  message = dbus_new0 (DBusMessage, 1);
1154  if (message == NULL)
1155  return NULL;
1156 #ifndef DBUS_DISABLE_CHECKS
1158 #endif
1159 
1160 #ifdef HAVE_UNIX_FD_PASSING
1161  message->unix_fds = NULL;
1162  message->n_unix_fds_allocated = 0;
1163 #endif
1164  }
1165 
1166  _dbus_atomic_inc (&message->refcount);
1167 
1168  _dbus_message_trace_ref (message, 0, 1, "new_empty_header");
1169 
1170  message->locked = FALSE;
1171 #ifndef DBUS_DISABLE_CHECKS
1172  message->in_cache = FALSE;
1173 #endif
1174  message->counters = NULL;
1175  message->size_counter_delta = 0;
1176  message->changed_stamp = 0;
1177 
1178 #ifdef HAVE_UNIX_FD_PASSING
1179  message->n_unix_fds = 0;
1180  message->n_unix_fds_allocated = 0;
1181  message->unix_fd_counter_delta = 0;
1182 #endif
1183 
1184  if (!from_cache)
1186 
1187  if (from_cache)
1188  {
1189  _dbus_header_reinit (&message->header);
1190  _dbus_string_set_length (&message->body, 0);
1191  }
1192  else
1193  {
1194  if (!_dbus_header_init (&message->header))
1195  {
1196  dbus_free (message);
1197  return NULL;
1198  }
1199 
1200  if (!_dbus_string_init_preallocated (&message->body, 32))
1201  {
1202  _dbus_header_free (&message->header);
1203  dbus_free (message);
1204  return NULL;
1205  }
1206  }
1207 
1208  return message;
1209 }
1210 
1223 DBusMessage*
1224 dbus_message_new (int message_type)
1225 {
1226  DBusMessage *message;
1227 
1228  _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
1229 
1230  message = dbus_message_new_empty_header ();
1231  if (message == NULL)
1232  return NULL;
1233 
1234  if (!_dbus_header_create (&message->header,
1235  DBUS_COMPILER_BYTE_ORDER,
1236  message_type,
1237  NULL, NULL, NULL, NULL, NULL))
1238  {
1239  dbus_message_unref (message);
1240  return NULL;
1241  }
1242 
1243  return message;
1244 }
1245 
1267 DBusMessage*
1268 dbus_message_new_method_call (const char *destination,
1269  const char *path,
1270  const char *iface,
1271  const char *method)
1272 {
1273  DBusMessage *message;
1274 
1275  _dbus_return_val_if_fail (path != NULL, NULL);
1276  _dbus_return_val_if_fail (method != NULL, NULL);
1277  _dbus_return_val_if_fail (destination == NULL ||
1278  _dbus_check_is_valid_bus_name (destination), NULL);
1279  _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
1280  _dbus_return_val_if_fail (iface == NULL ||
1281  _dbus_check_is_valid_interface (iface), NULL);
1282  _dbus_return_val_if_fail (_dbus_check_is_valid_member (method), NULL);
1283 
1284  message = dbus_message_new_empty_header ();
1285  if (message == NULL)
1286  return NULL;
1287 
1288  if (!_dbus_header_create (&message->header,
1289  DBUS_COMPILER_BYTE_ORDER,
1291  destination, path, iface, method, NULL))
1292  {
1293  dbus_message_unref (message);
1294  return NULL;
1295  }
1296 
1297  return message;
1298 }
1299 
1307 DBusMessage*
1309 {
1310  DBusMessage *message;
1311  const char *sender;
1312 
1313  _dbus_return_val_if_fail (method_call != NULL, NULL);
1314 
1315  sender = dbus_message_get_sender (method_call);
1316 
1317  /* sender is allowed to be null here in peer-to-peer case */
1318 
1319  message = dbus_message_new_empty_header ();
1320  if (message == NULL)
1321  return NULL;
1322 
1323  if (!_dbus_header_create (&message->header,
1324  DBUS_COMPILER_BYTE_ORDER,
1326  sender, NULL, NULL, NULL, NULL))
1327  {
1328  dbus_message_unref (message);
1329  return NULL;
1330  }
1331 
1332  dbus_message_set_no_reply (message, TRUE);
1333 
1334  if (!dbus_message_set_reply_serial (message,
1335  dbus_message_get_serial (method_call)))
1336  {
1337  dbus_message_unref (message);
1338  return NULL;
1339  }
1340 
1341  return message;
1342 }
1343 
1358 DBusMessage*
1359 dbus_message_new_signal (const char *path,
1360  const char *iface,
1361  const char *name)
1362 {
1363  DBusMessage *message;
1364 
1365  _dbus_return_val_if_fail (path != NULL, NULL);
1366  _dbus_return_val_if_fail (iface != NULL, NULL);
1367  _dbus_return_val_if_fail (name != NULL, NULL);
1368  _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
1369  _dbus_return_val_if_fail (_dbus_check_is_valid_interface (iface), NULL);
1370  _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);
1371 
1372  message = dbus_message_new_empty_header ();
1373  if (message == NULL)
1374  return NULL;
1375 
1376  if (!_dbus_header_create (&message->header,
1377  DBUS_COMPILER_BYTE_ORDER,
1379  NULL, path, iface, name, NULL))
1380  {
1381  dbus_message_unref (message);
1382  return NULL;
1383  }
1384 
1385  dbus_message_set_no_reply (message, TRUE);
1386 
1387  return message;
1388 }
1389 
1404 DBusMessage*
1406  const char *error_name,
1407  const char *error_message)
1408 {
1409  DBusMessage *message;
1410  const char *sender;
1411  DBusMessageIter iter;
1412 
1413  _dbus_return_val_if_fail (reply_to != NULL, NULL);
1414  _dbus_return_val_if_fail (error_name != NULL, NULL);
1415  _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
1416 
1417  sender = dbus_message_get_sender (reply_to);
1418 
1419  /* sender may be NULL for non-message-bus case or
1420  * when the message bus is dealing with an unregistered
1421  * connection.
1422  */
1423  message = dbus_message_new_empty_header ();
1424  if (message == NULL)
1425  return NULL;
1426 
1427  if (!_dbus_header_create (&message->header,
1428  DBUS_COMPILER_BYTE_ORDER,
1430  sender, NULL, NULL, NULL, error_name))
1431  {
1432  dbus_message_unref (message);
1433  return NULL;
1434  }
1435 
1436  dbus_message_set_no_reply (message, TRUE);
1437 
1438  if (!dbus_message_set_reply_serial (message,
1439  dbus_message_get_serial (reply_to)))
1440  {
1441  dbus_message_unref (message);
1442  return NULL;
1443  }
1444 
1445  if (error_message != NULL)
1446  {
1447  dbus_message_iter_init_append (message, &iter);
1448  if (!dbus_message_iter_append_basic (&iter,
1450  &error_message))
1451  {
1452  dbus_message_unref (message);
1453  return NULL;
1454  }
1455  }
1456 
1457  return message;
1458 }
1459 
1476 DBusMessage*
1478  const char *error_name,
1479  const char *error_format,
1480  ...)
1481 {
1482  va_list args;
1483  DBusString str;
1484  DBusMessage *message;
1485 
1486  _dbus_return_val_if_fail (reply_to != NULL, NULL);
1487  _dbus_return_val_if_fail (error_name != NULL, NULL);
1488  _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
1489 
1490  if (!_dbus_string_init (&str))
1491  return NULL;
1492 
1493  va_start (args, error_format);
1494 
1495  if (_dbus_string_append_printf_valist (&str, error_format, args))
1496  message = dbus_message_new_error (reply_to, error_name,
1497  _dbus_string_get_const_data (&str));
1498  else
1499  message = NULL;
1500 
1501  _dbus_string_free (&str);
1502 
1503  va_end (args);
1504 
1505  return message;
1506 }
1507 
1508 
1521 DBusMessage *
1523 {
1524  DBusMessage *retval;
1525 
1526  _dbus_return_val_if_fail (message != NULL, NULL);
1527 
1528  retval = dbus_new0 (DBusMessage, 1);
1529  if (retval == NULL)
1530  return NULL;
1531 
1532  _dbus_atomic_inc (&retval->refcount);
1533 
1534  retval->locked = FALSE;
1535 #ifndef DBUS_DISABLE_CHECKS
1536  retval->generation = message->generation;
1537 #endif
1538 
1539  if (!_dbus_header_copy (&message->header, &retval->header))
1540  {
1541  dbus_free (retval);
1542  return NULL;
1543  }
1544 
1545  if (!_dbus_string_init_preallocated (&retval->body,
1546  _dbus_string_get_length (&message->body)))
1547  {
1548  _dbus_header_free (&retval->header);
1549  dbus_free (retval);
1550  return NULL;
1551  }
1552 
1553  if (!_dbus_string_copy (&message->body, 0,
1554  &retval->body, 0))
1555  goto failed_copy;
1556 
1557 #ifdef HAVE_UNIX_FD_PASSING
1558  retval->unix_fds = dbus_new(int, message->n_unix_fds);
1559  if (retval->unix_fds == NULL && message->n_unix_fds > 0)
1560  goto failed_copy;
1561 
1562  retval->n_unix_fds_allocated = message->n_unix_fds;
1563 
1564  for (retval->n_unix_fds = 0;
1565  retval->n_unix_fds < message->n_unix_fds;
1566  retval->n_unix_fds++)
1567  {
1568  retval->unix_fds[retval->n_unix_fds] = _dbus_dup(message->unix_fds[retval->n_unix_fds], NULL);
1569 
1570  if (retval->unix_fds[retval->n_unix_fds] < 0)
1571  goto failed_copy;
1572  }
1573 
1574 #endif
1575 
1576  _dbus_message_trace_ref (retval, 0, 1, "copy");
1577  return retval;
1578 
1579  failed_copy:
1580  _dbus_header_free (&retval->header);
1581  _dbus_string_free (&retval->body);
1582 
1583 #ifdef HAVE_UNIX_FD_PASSING
1584  close_unix_fds(retval->unix_fds, &retval->n_unix_fds);
1585  dbus_free(retval->unix_fds);
1586 #endif
1587 
1588  dbus_free (retval);
1589 
1590  return NULL;
1591 }
1592 
1593 
1601 DBusMessage *
1603 {
1604  dbus_int32_t old_refcount;
1605 
1606  _dbus_return_val_if_fail (message != NULL, NULL);
1607  _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
1608  _dbus_return_val_if_fail (!message->in_cache, NULL);
1609 
1610  old_refcount = _dbus_atomic_inc (&message->refcount);
1611  _dbus_assert (old_refcount >= 1);
1612  _dbus_message_trace_ref (message, old_refcount, old_refcount + 1, "ref");
1613 
1614  return message;
1615 }
1616 
1624 void
1626 {
1627  dbus_int32_t old_refcount;
1628 
1629  _dbus_return_if_fail (message != NULL);
1630  _dbus_return_if_fail (message->generation == _dbus_current_generation);
1631  _dbus_return_if_fail (!message->in_cache);
1632 
1633  old_refcount = _dbus_atomic_dec (&message->refcount);
1634 
1635  _dbus_assert (old_refcount >= 1);
1636 
1637  _dbus_message_trace_ref (message, old_refcount, old_refcount - 1, "unref");
1638 
1639  if (old_refcount == 1)
1640  {
1641  /* Calls application callbacks! */
1642  dbus_message_cache_or_finalize (message);
1643  }
1644 }
1645 
1656 int
1658 {
1659  _dbus_return_val_if_fail (message != NULL, DBUS_MESSAGE_TYPE_INVALID);
1660 
1661  return _dbus_header_get_message_type (&message->header);
1662 }
1663 
1728  int first_arg_type,
1729  ...)
1730 {
1731  dbus_bool_t retval;
1732  va_list var_args;
1733 
1734  _dbus_return_val_if_fail (message != NULL, FALSE);
1735 
1736  va_start (var_args, first_arg_type);
1737  retval = dbus_message_append_args_valist (message,
1738  first_arg_type,
1739  var_args);
1740  va_end (var_args);
1741 
1742  return retval;
1743 }
1744 
1760  int first_arg_type,
1761  va_list var_args)
1762 {
1763  int type;
1764  DBusMessageIter iter;
1765 
1766  _dbus_return_val_if_fail (message != NULL, FALSE);
1767 
1768  type = first_arg_type;
1769 
1770  dbus_message_iter_init_append (message, &iter);
1771 
1772  while (type != DBUS_TYPE_INVALID)
1773  {
1774  if (dbus_type_is_basic (type))
1775  {
1776  const DBusBasicValue *value;
1777  value = va_arg (var_args, const DBusBasicValue*);
1778 
1779  if (!dbus_message_iter_append_basic (&iter,
1780  type,
1781  value))
1782  goto failed;
1783  }
1784  else if (type == DBUS_TYPE_ARRAY)
1785  {
1786  int element_type;
1787  DBusMessageIter array;
1788  char buf[2];
1789 
1790  element_type = va_arg (var_args, int);
1791 
1792  buf[0] = element_type;
1793  buf[1] = '\0';
1796  buf,
1797  &array))
1798  goto failed;
1799 
1800  if (dbus_type_is_fixed (element_type) &&
1801  element_type != DBUS_TYPE_UNIX_FD)
1802  {
1803  const DBusBasicValue **value;
1804  int n_elements;
1805 
1806  value = va_arg (var_args, const DBusBasicValue**);
1807  n_elements = va_arg (var_args, int);
1808 
1810  element_type,
1811  value,
1812  n_elements)) {
1813  dbus_message_iter_abandon_container (&iter, &array);
1814  goto failed;
1815  }
1816  }
1817  else if (_DBUS_TYPE_IS_STRINGLIKE (element_type))
1818  {
1819  const char ***value_p;
1820  const char **value;
1821  int n_elements;
1822  int i;
1823 
1824  value_p = va_arg (var_args, const char***);
1825  n_elements = va_arg (var_args, int);
1826 
1827  value = *value_p;
1828 
1829  i = 0;
1830  while (i < n_elements)
1831  {
1832  if (!dbus_message_iter_append_basic (&array,
1833  element_type,
1834  &value[i])) {
1835  dbus_message_iter_abandon_container (&iter, &array);
1836  goto failed;
1837  }
1838  ++i;
1839  }
1840  }
1841  else
1842  {
1843  _dbus_warn ("arrays of %s can't be appended with %s for now\n",
1844  _dbus_type_to_string (element_type),
1845  _DBUS_FUNCTION_NAME);
1846  goto failed;
1847  }
1848 
1849  if (!dbus_message_iter_close_container (&iter, &array))
1850  goto failed;
1851  }
1852 #ifndef DBUS_DISABLE_CHECKS
1853  else
1854  {
1855  _dbus_warn ("type %s isn't supported yet in %s\n",
1856  _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
1857  goto failed;
1858  }
1859 #endif
1860 
1861  type = va_arg (var_args, int);
1862  }
1863 
1864  return TRUE;
1865 
1866  failed:
1867  return FALSE;
1868 }
1869 
1916  DBusError *error,
1917  int first_arg_type,
1918  ...)
1919 {
1920  dbus_bool_t retval;
1921  va_list var_args;
1922 
1923  _dbus_return_val_if_fail (message != NULL, FALSE);
1924  _dbus_return_val_if_error_is_set (error, FALSE);
1925 
1926  va_start (var_args, first_arg_type);
1927  retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
1928  va_end (var_args);
1929 
1930  return retval;
1931 }
1932 
1945  DBusError *error,
1946  int first_arg_type,
1947  va_list var_args)
1948 {
1949  DBusMessageIter iter;
1950 
1951  _dbus_return_val_if_fail (message != NULL, FALSE);
1952  _dbus_return_val_if_error_is_set (error, FALSE);
1953 
1954  dbus_message_iter_init (message, &iter);
1955  return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
1956 }
1957 
1958 static void
1959 _dbus_message_iter_init_common (DBusMessage *message,
1960  DBusMessageRealIter *real,
1961  int iter_type)
1962 {
1963  _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
1964 
1965  /* Since the iterator will read or write who-knows-what from the
1966  * message, we need to get in the right byte order
1967  */
1968  ensure_byte_order (message);
1969 
1970  real->message = message;
1971  real->changed_stamp = message->changed_stamp;
1972  real->iter_type = iter_type;
1973  real->sig_refcount = 0;
1974 }
1975 
2000  DBusMessageIter *iter)
2001 {
2002  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2003  const DBusString *type_str;
2004  int type_pos;
2005 
2006  _dbus_return_val_if_fail (message != NULL, FALSE);
2007  _dbus_return_val_if_fail (iter != NULL, FALSE);
2008 
2009  get_const_signature (&message->header, &type_str, &type_pos);
2010 
2011  _dbus_message_iter_init_common (message, real,
2012  DBUS_MESSAGE_ITER_TYPE_READER);
2013 
2015  _dbus_header_get_byte_order (&message->header),
2016  type_str, type_pos,
2017  &message->body,
2018  0);
2019 
2021 }
2022 
2031 {
2032  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2033 
2034  _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
2035  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2036 
2037  return _dbus_type_reader_has_next (&real->u.reader);
2038 }
2039 
2050 {
2051  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2052 
2053  _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
2054  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2055 
2056  return _dbus_type_reader_next (&real->u.reader);
2057 }
2058 
2073 int
2075 {
2076  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2077 
2078  _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2079  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2080 
2082 }
2083 
2092 int
2094 {
2095  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2096 
2097  _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2098  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
2099  _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
2100 
2102 }
2103 
2129 void
2131  DBusMessageIter *sub)
2132 {
2133  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2134  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2135 
2136  _dbus_return_if_fail (_dbus_message_iter_check (real));
2137  _dbus_return_if_fail (sub != NULL);
2138 
2139  *real_sub = *real;
2140  _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
2141 }
2142 
2154 char *
2156 {
2157  const DBusString *sig;
2158  DBusString retstr;
2159  char *ret;
2160  int start, len;
2161  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2162 
2163  _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
2164 
2165  if (!_dbus_string_init (&retstr))
2166  return NULL;
2167 
2169  &start, &len);
2170  if (!_dbus_string_append_len (&retstr,
2171  _dbus_string_get_const_data (sig) + start,
2172  len))
2173  return NULL;
2174  if (!_dbus_string_steal_data (&retstr, &ret))
2175  return NULL;
2176  _dbus_string_free (&retstr);
2177  return ret;
2178 }
2179 
2227 void
2229  void *value)
2230 {
2231  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2232 
2233  _dbus_return_if_fail (_dbus_message_iter_check (real));
2234  _dbus_return_if_fail (value != NULL);
2235 
2237  {
2238 #ifdef HAVE_UNIX_FD_PASSING
2239  DBusBasicValue idx;
2240 
2241  _dbus_type_reader_read_basic(&real->u.reader, &idx);
2242 
2243  if (idx.u32 >= real->message->n_unix_fds) {
2244  /* Hmm, we cannot really signal an error here, so let's make
2245  sure to return an invalid fd. */
2246  *((int*) value) = -1;
2247  return;
2248  }
2249 
2250  *((int*) value) = _dbus_dup(real->message->unix_fds[idx.u32], NULL);
2251 #else
2252  *((int*) value) = -1;
2253 #endif
2254  }
2255  else
2256  {
2258  value);
2259  }
2260 }
2261 
2280 int
2282 {
2283  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2284 
2285  _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
2286 
2288 }
2289 
2325 void
2327  void *value,
2328  int *n_elements)
2329 {
2330  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2331 #ifndef DBUS_DISABLE_CHECKS
2332  int subtype = _dbus_type_reader_get_current_type(&real->u.reader);
2333 
2334  _dbus_return_if_fail (_dbus_message_iter_check (real));
2335  _dbus_return_if_fail (value != NULL);
2336  _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) ||
2337  (dbus_type_is_fixed (subtype) && subtype != DBUS_TYPE_UNIX_FD));
2338 #endif
2339 
2341  value, n_elements);
2342 }
2343 
2355 void
2357  DBusMessageIter *iter)
2358 {
2359  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2360 
2361  _dbus_return_if_fail (message != NULL);
2362  _dbus_return_if_fail (iter != NULL);
2363 
2364  _dbus_message_iter_init_common (message, real,
2365  DBUS_MESSAGE_ITER_TYPE_WRITER);
2366 
2367  /* We create the signature string and point iterators at it "on demand"
2368  * when a value is actually appended. That means that init() never fails
2369  * due to OOM.
2370  */
2372  _dbus_header_get_byte_order (&message->header),
2373  &message->body,
2374  _dbus_string_get_length (&message->body));
2375 }
2376 
2385 static dbus_bool_t
2386 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
2387 {
2388  DBusString *str;
2389  const DBusString *current_sig;
2390  int current_sig_pos;
2391 
2392  _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2393 
2394  if (real->u.writer.type_str != NULL)
2395  {
2396  _dbus_assert (real->sig_refcount > 0);
2397  real->sig_refcount += 1;
2398  return TRUE;
2399  }
2400 
2401  str = dbus_new (DBusString, 1);
2402  if (str == NULL)
2403  return FALSE;
2404 
2407  &current_sig, &current_sig_pos))
2408  current_sig = NULL;
2409 
2410  if (current_sig)
2411  {
2412  int current_len;
2413 
2414  current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
2415  current_sig_pos += 1; /* move on to sig data */
2416 
2417  if (!_dbus_string_init_preallocated (str, current_len + 4))
2418  {
2419  dbus_free (str);
2420  return FALSE;
2421  }
2422 
2423  if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
2424  str, 0))
2425  {
2426  _dbus_string_free (str);
2427  dbus_free (str);
2428  return FALSE;
2429  }
2430  }
2431  else
2432  {
2433  if (!_dbus_string_init_preallocated (str, 4))
2434  {
2435  dbus_free (str);
2436  return FALSE;
2437  }
2438  }
2439 
2440  real->sig_refcount = 1;
2441 
2443  str, _dbus_string_get_length (str));
2444  return TRUE;
2445 }
2446 
2456 static dbus_bool_t
2457 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
2458 {
2459  DBusString *str;
2460  const char *v_STRING;
2461  dbus_bool_t retval;
2462 
2463  _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2464  _dbus_assert (real->u.writer.type_str != NULL);
2465  _dbus_assert (real->sig_refcount > 0);
2466 
2467  real->sig_refcount -= 1;
2468 
2469  if (real->sig_refcount > 0)
2470  return TRUE;
2471  _dbus_assert (real->sig_refcount == 0);
2472 
2473  retval = TRUE;
2474 
2475  str = real->u.writer.type_str;
2476 
2477  v_STRING = _dbus_string_get_const_data (str);
2481  &v_STRING))
2482  retval = FALSE;
2483 
2485  _dbus_string_free (str);
2486  dbus_free (str);
2487 
2488  return retval;
2489 }
2490 
2498 static void
2499 _dbus_message_iter_abandon_signature (DBusMessageRealIter *real)
2500 {
2501  DBusString *str;
2502 
2503  _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2504  _dbus_assert (real->u.writer.type_str != NULL);
2505  _dbus_assert (real->sig_refcount > 0);
2506 
2507  real->sig_refcount -= 1;
2508 
2509  if (real->sig_refcount > 0)
2510  return;
2511  _dbus_assert (real->sig_refcount == 0);
2512 
2513  str = real->u.writer.type_str;
2514 
2516  _dbus_string_free (str);
2517  dbus_free (str);
2518 }
2519 
2520 #ifndef DBUS_DISABLE_CHECKS
2521 static dbus_bool_t
2522 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
2523 {
2524  if (!_dbus_message_iter_check (iter))
2525  return FALSE;
2526 
2527  if (iter->message->locked)
2528  {
2529  _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)\n");
2530  return FALSE;
2531  }
2532 
2533  return TRUE;
2534 }
2535 #endif /* DBUS_DISABLE_CHECKS */
2536 
2537 #ifdef HAVE_UNIX_FD_PASSING
2538 static int *
2539 expand_fd_array(DBusMessage *m,
2540  unsigned n)
2541 {
2542  _dbus_assert(m);
2543 
2544  /* This makes space for adding n new fds to the array and returns a
2545  pointer to the place were the first fd should be put. */
2546 
2547  if (m->n_unix_fds + n > m->n_unix_fds_allocated)
2548  {
2549  unsigned k;
2550  int *p;
2551 
2552  /* Make twice as much space as necessary */
2553  k = (m->n_unix_fds + n) * 2;
2554 
2555  /* Allocate at least four */
2556  if (k < 4)
2557  k = 4;
2558 
2559  p = dbus_realloc(m->unix_fds, k * sizeof(int));
2560  if (p == NULL)
2561  return NULL;
2562 
2563  m->unix_fds = p;
2564  m->n_unix_fds_allocated = k;
2565  }
2566 
2567  return m->unix_fds + m->n_unix_fds;
2568 }
2569 #endif
2570 
2592  int type,
2593  const void *value)
2594 {
2595  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2596  dbus_bool_t ret;
2597 
2598  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2599  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2600  _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
2601  _dbus_return_val_if_fail (value != NULL, FALSE);
2602 
2603 #ifndef DBUS_DISABLE_CHECKS
2604  switch (type)
2605  {
2606  const char * const *string_p;
2607  const dbus_bool_t *bool_p;
2608 
2609  case DBUS_TYPE_STRING:
2610  string_p = value;
2611  _dbus_return_val_if_fail (_dbus_check_is_valid_utf8 (*string_p), FALSE);
2612  break;
2613 
2614  case DBUS_TYPE_OBJECT_PATH:
2615  string_p = value;
2616  _dbus_return_val_if_fail (_dbus_check_is_valid_path (*string_p), FALSE);
2617  break;
2618 
2619  case DBUS_TYPE_SIGNATURE:
2620  string_p = value;
2621  _dbus_return_val_if_fail (_dbus_check_is_valid_signature (*string_p), FALSE);
2622  break;
2623 
2624  case DBUS_TYPE_BOOLEAN:
2625  bool_p = value;
2626  _dbus_return_val_if_fail (*bool_p == 0 || *bool_p == 1, FALSE);
2627  break;
2628 
2629  default:
2630  {
2631  /* nothing to check, all possible values are allowed */
2632  }
2633  }
2634 #endif
2635 
2636  if (!_dbus_message_iter_open_signature (real))
2637  return FALSE;
2638 
2639  if (type == DBUS_TYPE_UNIX_FD)
2640  {
2641 #ifdef HAVE_UNIX_FD_PASSING
2642  int *fds;
2643  dbus_uint32_t u;
2644 
2645  /* First step, include the fd in the fd list of this message */
2646  if (!(fds = expand_fd_array(real->message, 1)))
2647  return FALSE;
2648 
2649  *fds = _dbus_dup(*(int*) value, NULL);
2650  if (*fds < 0)
2651  return FALSE;
2652 
2653  u = real->message->n_unix_fds;
2654 
2655  /* Second step, write the index to the fd */
2656  if (!(ret = _dbus_type_writer_write_basic (&real->u.writer, DBUS_TYPE_UNIX_FD, &u))) {
2657  _dbus_close(*fds, NULL);
2658  return FALSE;
2659  }
2660 
2661  real->message->n_unix_fds += 1;
2662  u += 1;
2663 
2664  /* Final step, update the header accordingly */
2668  &u);
2669 
2670  /* If any of these operations fail the message is
2671  hosed. However, no memory or fds should be leaked since what
2672  has been added to message has been added to the message, and
2673  can hence be accounted for when the message is being
2674  freed. */
2675 #else
2676  ret = FALSE;
2677 #endif
2678  }
2679  else
2680  {
2681  ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
2682  }
2683 
2684  if (!_dbus_message_iter_close_signature (real))
2685  ret = FALSE;
2686 
2687  return ret;
2688 }
2689 
2727  int element_type,
2728  const void *value,
2729  int n_elements)
2730 {
2731  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2732  dbus_bool_t ret;
2733 
2734  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2735  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2736  _dbus_return_val_if_fail (dbus_type_is_fixed (element_type) && element_type != DBUS_TYPE_UNIX_FD, FALSE);
2737  _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
2738  _dbus_return_val_if_fail (value != NULL, FALSE);
2739  _dbus_return_val_if_fail (n_elements >= 0, FALSE);
2740  _dbus_return_val_if_fail (n_elements <=
2742  FALSE);
2743 
2744 #ifndef DBUS_DISABLE_CHECKS
2745  if (element_type == DBUS_TYPE_BOOLEAN)
2746  {
2747  const dbus_bool_t * const *bools = value;
2748  int i;
2749 
2750  for (i = 0; i < n_elements; i++)
2751  {
2752  _dbus_return_val_if_fail ((*bools)[i] == 0 || (*bools)[i] == 1, FALSE);
2753  }
2754  }
2755 #endif
2756 
2757  ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
2758 
2759  return ret;
2760 }
2761 
2785  int type,
2786  const char *contained_signature,
2787  DBusMessageIter *sub)
2788 {
2789  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2790  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2791  DBusString contained_str;
2792 
2793  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2794  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2795  _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
2796  _dbus_return_val_if_fail (sub != NULL, FALSE);
2797  _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
2798  contained_signature == NULL) ||
2799  (type == DBUS_TYPE_DICT_ENTRY &&
2800  contained_signature == NULL) ||
2801  (type == DBUS_TYPE_VARIANT &&
2802  contained_signature != NULL) ||
2803  (type == DBUS_TYPE_ARRAY &&
2804  contained_signature != NULL), FALSE);
2805 
2806  /* this would fail if the contained_signature is a dict entry, since
2807  * dict entries are invalid signatures standalone (they must be in
2808  * an array)
2809  */
2810  _dbus_return_val_if_fail ((type == DBUS_TYPE_ARRAY && contained_signature && *contained_signature == DBUS_DICT_ENTRY_BEGIN_CHAR) ||
2811  (contained_signature == NULL ||
2812  _dbus_check_is_valid_signature (contained_signature)),
2813  FALSE);
2814 
2815  if (!_dbus_message_iter_open_signature (real))
2816  return FALSE;
2817 
2818  *real_sub = *real;
2819 
2820  if (contained_signature != NULL)
2821  {
2822  _dbus_string_init_const (&contained_str, contained_signature);
2823 
2824  return _dbus_type_writer_recurse (&real->u.writer,
2825  type,
2826  &contained_str, 0,
2827  &real_sub->u.writer);
2828  }
2829  else
2830  {
2831  return _dbus_type_writer_recurse (&real->u.writer,
2832  type,
2833  NULL, 0,
2834  &real_sub->u.writer);
2835  }
2836 }
2837 
2838 
2854  DBusMessageIter *sub)
2855 {
2856  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2857  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2858  dbus_bool_t ret;
2859 
2860  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2861  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2862  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
2863  _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2864 
2865  ret = _dbus_type_writer_unrecurse (&real->u.writer,
2866  &real_sub->u.writer);
2867 
2868  if (!_dbus_message_iter_close_signature (real))
2869  ret = FALSE;
2870 
2871  return ret;
2872 }
2873 
2885 void
2887  DBusMessageIter *sub)
2888 {
2889  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2890 #ifndef DBUS_DISABLE_CHECKS
2891  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2892 
2893  _dbus_return_if_fail (_dbus_message_iter_append_check (real));
2894  _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2895  _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
2896  _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2897 #endif
2898 
2899  _dbus_message_iter_abandon_signature (real);
2900 }
2901 
2918 void
2920  dbus_bool_t no_reply)
2921 {
2922  _dbus_return_if_fail (message != NULL);
2923  _dbus_return_if_fail (!message->locked);
2924 
2925  _dbus_header_toggle_flag (&message->header,
2927  no_reply);
2928 }
2929 
2939 {
2940  _dbus_return_val_if_fail (message != NULL, FALSE);
2941 
2942  return _dbus_header_get_flag (&message->header,
2944 }
2945 
2960 void
2962  dbus_bool_t auto_start)
2963 {
2964  _dbus_return_if_fail (message != NULL);
2965  _dbus_return_if_fail (!message->locked);
2966 
2967  _dbus_header_toggle_flag (&message->header,
2969  !auto_start);
2970 }
2971 
2981 {
2982  _dbus_return_val_if_fail (message != NULL, FALSE);
2983 
2984  return !_dbus_header_get_flag (&message->header,
2986 }
2987 
2988 
3003  const char *object_path)
3004 {
3005  _dbus_return_val_if_fail (message != NULL, FALSE);
3006  _dbus_return_val_if_fail (!message->locked, FALSE);
3007  _dbus_return_val_if_fail (object_path == NULL ||
3008  _dbus_check_is_valid_path (object_path),
3009  FALSE);
3010 
3011  return set_or_delete_string_field (message,
3014  object_path);
3015 }
3016 
3030 const char*
3032 {
3033  const char *v;
3034 
3035  _dbus_return_val_if_fail (message != NULL, NULL);
3036 
3037  v = NULL; /* in case field doesn't exist */
3041  (void *) &v);
3042  return v;
3043 }
3044 
3056  const char *path)
3057 {
3058  const char *msg_path;
3059  msg_path = dbus_message_get_path (message);
3060 
3061  if (msg_path == NULL)
3062  {
3063  if (path == NULL)
3064  return TRUE;
3065  else
3066  return FALSE;
3067  }
3068 
3069  if (path == NULL)
3070  return FALSE;
3071 
3072  if (strcmp (msg_path, path) == 0)
3073  return TRUE;
3074 
3075  return FALSE;
3076 }
3077 
3100  char ***path)
3101 {
3102  const char *v;
3103 
3104  _dbus_return_val_if_fail (message != NULL, FALSE);
3105  _dbus_return_val_if_fail (path != NULL, FALSE);
3106 
3107  *path = NULL;
3108 
3109  v = dbus_message_get_path (message);
3110  if (v != NULL)
3111  {
3112  if (!_dbus_decompose_path (v, strlen (v),
3113  path, NULL))
3114  return FALSE;
3115  }
3116  return TRUE;
3117 }
3118 
3134  const char *iface)
3135 {
3136  _dbus_return_val_if_fail (message != NULL, FALSE);
3137  _dbus_return_val_if_fail (!message->locked, FALSE);
3138  _dbus_return_val_if_fail (iface == NULL ||
3139  _dbus_check_is_valid_interface (iface),
3140  FALSE);
3141 
3142  return set_or_delete_string_field (message,
3145  iface);
3146 }
3147 
3161 const char*
3163 {
3164  const char *v;
3165 
3166  _dbus_return_val_if_fail (message != NULL, NULL);
3167 
3168  v = NULL; /* in case field doesn't exist */
3172  (void *) &v);
3173  return v;
3174 }
3175 
3185  const char *iface)
3186 {
3187  const char *msg_interface;
3188  msg_interface = dbus_message_get_interface (message);
3189 
3190  if (msg_interface == NULL)
3191  {
3192  if (iface == NULL)
3193  return TRUE;
3194  else
3195  return FALSE;
3196  }
3197 
3198  if (iface == NULL)
3199  return FALSE;
3200 
3201  if (strcmp (msg_interface, iface) == 0)
3202  return TRUE;
3203 
3204  return FALSE;
3205 
3206 }
3207 
3222  const char *member)
3223 {
3224  _dbus_return_val_if_fail (message != NULL, FALSE);
3225  _dbus_return_val_if_fail (!message->locked, FALSE);
3226  _dbus_return_val_if_fail (member == NULL ||
3227  _dbus_check_is_valid_member (member),
3228  FALSE);
3229 
3230  return set_or_delete_string_field (message,
3233  member);
3234 }
3235 
3247 const char*
3249 {
3250  const char *v;
3251 
3252  _dbus_return_val_if_fail (message != NULL, NULL);
3253 
3254  v = NULL; /* in case field doesn't exist */
3258  (void *) &v);
3259  return v;
3260 }
3261 
3271  const char *member)
3272 {
3273  const char *msg_member;
3274  msg_member = dbus_message_get_member (message);
3275 
3276  if (msg_member == NULL)
3277  {
3278  if (member == NULL)
3279  return TRUE;
3280  else
3281  return FALSE;
3282  }
3283 
3284  if (member == NULL)
3285  return FALSE;
3286 
3287  if (strcmp (msg_member, member) == 0)
3288  return TRUE;
3289 
3290  return FALSE;
3291 
3292 }
3293 
3307  const char *error_name)
3308 {
3309  _dbus_return_val_if_fail (message != NULL, FALSE);
3310  _dbus_return_val_if_fail (!message->locked, FALSE);
3311  _dbus_return_val_if_fail (error_name == NULL ||
3312  _dbus_check_is_valid_error_name (error_name),
3313  FALSE);
3314 
3315  return set_or_delete_string_field (message,
3318  error_name);
3319 }
3320 
3331 const char*
3333 {
3334  const char *v;
3335 
3336  _dbus_return_val_if_fail (message != NULL, NULL);
3337 
3338  v = NULL; /* in case field doesn't exist */
3342  (void *) &v);
3343  return v;
3344 }
3345 
3361  const char *destination)
3362 {
3363  _dbus_return_val_if_fail (message != NULL, FALSE);
3364  _dbus_return_val_if_fail (!message->locked, FALSE);
3365  _dbus_return_val_if_fail (destination == NULL ||
3366  _dbus_check_is_valid_bus_name (destination),
3367  FALSE);
3368 
3369  return set_or_delete_string_field (message,
3372  destination);
3373 }
3374 
3384 const char*
3386 {
3387  const char *v;
3388 
3389  _dbus_return_val_if_fail (message != NULL, NULL);
3390 
3391  v = NULL; /* in case field doesn't exist */
3395  (void *) &v);
3396  return v;
3397 }
3398 
3415  const char *sender)
3416 {
3417  _dbus_return_val_if_fail (message != NULL, FALSE);
3418  _dbus_return_val_if_fail (!message->locked, FALSE);
3419  _dbus_return_val_if_fail (sender == NULL ||
3420  _dbus_check_is_valid_bus_name (sender),
3421  FALSE);
3422 
3423  return set_or_delete_string_field (message,
3426  sender);
3427 }
3428 
3444 const char*
3446 {
3447  const char *v;
3448 
3449  _dbus_return_val_if_fail (message != NULL, NULL);
3450 
3451  v = NULL; /* in case field doesn't exist */
3455  (void *) &v);
3456  return v;
3457 }
3458 
3477 const char*
3479 {
3480  const DBusString *type_str;
3481  int type_pos;
3482 
3483  _dbus_return_val_if_fail (message != NULL, NULL);
3484 
3485  get_const_signature (&message->header, &type_str, &type_pos);
3486 
3487  return _dbus_string_get_const_data_len (type_str, type_pos, 0);
3488 }
3489 
3490 static dbus_bool_t
3491 _dbus_message_has_type_interface_member (DBusMessage *message,
3492  int type,
3493  const char *iface,
3494  const char *member)
3495 {
3496  const char *n;
3497 
3498  _dbus_assert (message != NULL);
3499  _dbus_assert (iface != NULL);
3500  _dbus_assert (member != NULL);
3501 
3502  if (dbus_message_get_type (message) != type)
3503  return FALSE;
3504 
3505  /* Optimize by checking the short member name first
3506  * instead of the longer interface name
3507  */
3508 
3509  n = dbus_message_get_member (message);
3510 
3511  if (n && strcmp (n, member) == 0)
3512  {
3513  n = dbus_message_get_interface (message);
3514 
3515  if (n == NULL || strcmp (n, iface) == 0)
3516  return TRUE;
3517  }
3518 
3519  return FALSE;
3520 }
3521 
3538  const char *iface,
3539  const char *method)
3540 {
3541  _dbus_return_val_if_fail (message != NULL, FALSE);
3542  _dbus_return_val_if_fail (iface != NULL, FALSE);
3543  _dbus_return_val_if_fail (method != NULL, FALSE);
3544  /* don't check that interface/method are valid since it would be
3545  * expensive, and not catch many common errors
3546  */
3547 
3548  return _dbus_message_has_type_interface_member (message,
3550  iface, method);
3551 }
3552 
3566  const char *iface,
3567  const char *signal_name)
3568 {
3569  _dbus_return_val_if_fail (message != NULL, FALSE);
3570  _dbus_return_val_if_fail (iface != NULL, FALSE);
3571  _dbus_return_val_if_fail (signal_name != NULL, FALSE);
3572  /* don't check that interface/name are valid since it would be
3573  * expensive, and not catch many common errors
3574  */
3575 
3576  return _dbus_message_has_type_interface_member (message,
3578  iface, signal_name);
3579 }
3580 
3593  const char *error_name)
3594 {
3595  const char *n;
3596 
3597  _dbus_return_val_if_fail (message != NULL, FALSE);
3598  _dbus_return_val_if_fail (error_name != NULL, FALSE);
3599  /* don't check that error_name is valid since it would be expensive,
3600  * and not catch many common errors
3601  */
3602 
3604  return FALSE;
3605 
3606  n = dbus_message_get_error_name (message);
3607 
3608  if (n && strcmp (n, error_name) == 0)
3609  return TRUE;
3610  else
3611  return FALSE;
3612 }
3613 
3626  const char *name)
3627 {
3628  const char *s;
3629 
3630  _dbus_return_val_if_fail (message != NULL, FALSE);
3631  _dbus_return_val_if_fail (name != NULL, FALSE);
3632  /* don't check that name is valid since it would be expensive, and
3633  * not catch many common errors
3634  */
3635 
3636  s = dbus_message_get_destination (message);
3637 
3638  if (s && strcmp (s, name) == 0)
3639  return TRUE;
3640  else
3641  return FALSE;
3642 }
3643 
3661  const char *name)
3662 {
3663  const char *s;
3664 
3665  _dbus_return_val_if_fail (message != NULL, FALSE);
3666  _dbus_return_val_if_fail (name != NULL, FALSE);
3667  /* don't check that name is valid since it would be expensive, and
3668  * not catch many common errors
3669  */
3670 
3671  s = dbus_message_get_sender (message);
3672 
3673  if (s && strcmp (s, name) == 0)
3674  return TRUE;
3675  else
3676  return FALSE;
3677 }
3678 
3690  const char *signature)
3691 {
3692  const char *s;
3693 
3694  _dbus_return_val_if_fail (message != NULL, FALSE);
3695  _dbus_return_val_if_fail (signature != NULL, FALSE);
3696  /* don't check that signature is valid since it would be expensive,
3697  * and not catch many common errors
3698  */
3699 
3700  s = dbus_message_get_signature (message);
3701 
3702  if (s && strcmp (s, signature) == 0)
3703  return TRUE;
3704  else
3705  return FALSE;
3706 }
3707 
3732  DBusMessage *message)
3733 {
3734  const char *str;
3735 
3736  _dbus_return_val_if_fail (message != NULL, FALSE);
3737  _dbus_return_val_if_error_is_set (error, FALSE);
3738 
3740  return FALSE;
3741 
3742  str = NULL;
3743  dbus_message_get_args (message, NULL,
3744  DBUS_TYPE_STRING, &str,
3746 
3747  dbus_set_error (error, dbus_message_get_error_name (message),
3748  str ? "%s" : NULL, str);
3749 
3750  return TRUE;
3751 }
3752 
3761 {
3762 #ifdef HAVE_UNIX_FD_PASSING
3763  _dbus_assert(message);
3764 
3765  return message->n_unix_fds > 0;
3766 #else
3767  return FALSE;
3768 #endif
3769 }
3770 
3789 #define INITIAL_LOADER_DATA_LEN 32
3790 
3799 {
3800  DBusMessageLoader *loader;
3801 
3802  loader = dbus_new0 (DBusMessageLoader, 1);
3803  if (loader == NULL)
3804  return NULL;
3805 
3806  loader->refcount = 1;
3807 
3808  loader->corrupted = FALSE;
3809  loader->corruption_reason = DBUS_VALID;
3810 
3811  /* this can be configured by the app, but defaults to the protocol max */
3813 
3814  /* We set a very relatively conservative default here since due to how
3815  SCM_RIGHTS works we need to preallocate an fd array of the maximum
3816  number of unix fds we want to receive in advance. A
3817  try-and-reallocate loop is not possible. */
3818  loader->max_message_unix_fds = DBUS_DEFAULT_MESSAGE_UNIX_FDS;
3819 
3820  if (!_dbus_string_init (&loader->data))
3821  {
3822  dbus_free (loader);
3823  return NULL;
3824  }
3825 
3826  /* preallocate the buffer for speed, ignore failure */
3828  _dbus_string_set_length (&loader->data, 0);
3829 
3830 #ifdef HAVE_UNIX_FD_PASSING
3831  loader->unix_fds = NULL;
3832  loader->n_unix_fds = loader->n_unix_fds_allocated = 0;
3833  loader->unix_fds_outstanding = FALSE;
3834 #endif
3835 
3836  return loader;
3837 }
3838 
3847 {
3848  loader->refcount += 1;
3849 
3850  return loader;
3851 }
3852 
3859 void
3861 {
3862  loader->refcount -= 1;
3863  if (loader->refcount == 0)
3864  {
3865 #ifdef HAVE_UNIX_FD_PASSING
3866  close_unix_fds(loader->unix_fds, &loader->n_unix_fds);
3867  dbus_free(loader->unix_fds);
3868 #endif
3869  _dbus_list_foreach (&loader->messages,
3871  NULL);
3872  _dbus_list_clear (&loader->messages);
3873  _dbus_string_free (&loader->data);
3874  dbus_free (loader);
3875  }
3876 }
3877 
3896 void
3898  DBusString **buffer)
3899 {
3900  _dbus_assert (!loader->buffer_outstanding);
3901 
3902  *buffer = &loader->data;
3903 
3904  loader->buffer_outstanding = TRUE;
3905 }
3906 
3916 void
3918  DBusString *buffer)
3919 {
3920  _dbus_assert (loader->buffer_outstanding);
3921  _dbus_assert (buffer == &loader->data);
3922 
3923  loader->buffer_outstanding = FALSE;
3924 }
3925 
3938  int **fds,
3939  unsigned *max_n_fds)
3940 {
3941 #ifdef HAVE_UNIX_FD_PASSING
3942  _dbus_assert (!loader->unix_fds_outstanding);
3943 
3944  /* Allocate space where we can put the fds we read. We allocate
3945  space for max_message_unix_fds since this is an
3946  upper limit how many fds can be received within a single
3947  message. Since SCM_RIGHTS doesn't allow a reallocate+retry logic
3948  we are allocating the maximum possible array size right from the
3949  beginning. This sucks a bit, however unless SCM_RIGHTS is fixed
3950  there is no better way. */
3951 
3952  if (loader->n_unix_fds_allocated < loader->max_message_unix_fds)
3953  {
3954  int *a = dbus_realloc(loader->unix_fds,
3955  loader->max_message_unix_fds * sizeof(loader->unix_fds[0]));
3956 
3957  if (!a)
3958  return FALSE;
3959 
3960  loader->unix_fds = a;
3961  loader->n_unix_fds_allocated = loader->max_message_unix_fds;
3962  }
3963 
3964  *fds = loader->unix_fds + loader->n_unix_fds;
3965  *max_n_fds = loader->n_unix_fds_allocated - loader->n_unix_fds;
3966 
3967  loader->unix_fds_outstanding = TRUE;
3968  return TRUE;
3969 #else
3970  _dbus_assert_not_reached("Platform doesn't support unix fd passing");
3971  return FALSE;
3972 #endif
3973 }
3974 
3985 void
3987  int *fds,
3988  unsigned n_fds)
3989 {
3990 #ifdef HAVE_UNIX_FD_PASSING
3991  _dbus_assert(loader->unix_fds_outstanding);
3992  _dbus_assert(loader->unix_fds + loader->n_unix_fds == fds);
3993  _dbus_assert(loader->n_unix_fds + n_fds <= loader->n_unix_fds_allocated);
3994 
3995  loader->n_unix_fds += n_fds;
3996  loader->unix_fds_outstanding = FALSE;
3997 #else
3998  _dbus_assert_not_reached("Platform doesn't support unix fd passing");
3999 #endif
4000 }
4001 
4002 /*
4003  * FIXME when we move the header out of the buffer, that memmoves all
4004  * buffered messages. Kind of crappy.
4005  *
4006  * Also we copy the header and body, which is kind of crappy. To
4007  * avoid this, we have to allow header and body to be in a single
4008  * memory block, which is good for messages we read and bad for
4009  * messages we are creating. But we could move_len() the buffer into
4010  * this single memory block, and move_len() will just swap the buffers
4011  * if you're moving the entire buffer replacing the dest string.
4012  *
4013  * We could also have the message loader tell the transport how many
4014  * bytes to read; so it would first ask for some arbitrary number like
4015  * 256, then if the message was incomplete it would use the
4016  * header/body len to ask for exactly the size of the message (or
4017  * blocks the size of a typical kernel buffer for the socket). That
4018  * way we don't get trailing bytes in the buffer that have to be
4019  * memmoved. Though I suppose we also don't have a chance of reading a
4020  * bunch of small messages at once, so the optimization may be stupid.
4021  *
4022  * Another approach would be to keep a "start" index into
4023  * loader->data and only delete it occasionally, instead of after
4024  * each message is loaded.
4025  *
4026  * load_message() returns FALSE if not enough memory OR the loader was corrupted
4027  */
4028 static dbus_bool_t
4029 load_message (DBusMessageLoader *loader,
4030  DBusMessage *message,
4031  int byte_order,
4032  int fields_array_len,
4033  int header_len,
4034  int body_len)
4035 {
4036  dbus_bool_t oom;
4037  DBusValidity validity;
4038  const DBusString *type_str;
4039  int type_pos;
4040  DBusValidationMode mode;
4041  dbus_uint32_t n_unix_fds = 0;
4042 
4043  mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
4044 
4045  oom = FALSE;
4046 
4047 #if 0
4048  _dbus_verbose_bytes_of_string (&loader->data, 0, header_len /* + body_len */);
4049 #endif
4050 
4051  /* 1. VALIDATE AND COPY OVER HEADER */
4052  _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
4053  _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
4054 
4055  if (!_dbus_header_load (&message->header,
4056  mode,
4057  &validity,
4058  byte_order,
4059  fields_array_len,
4060  header_len,
4061  body_len,
4062  &loader->data, 0,
4063  _dbus_string_get_length (&loader->data)))
4064  {
4065  _dbus_verbose ("Failed to load header for new message code %d\n", validity);
4066 
4067  /* assert here so we can catch any code that still uses DBUS_VALID to indicate
4068  oom errors. They should use DBUS_VALIDITY_UNKNOWN_OOM_ERROR instead */
4069  _dbus_assert (validity != DBUS_VALID);
4070 
4071  if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
4072  oom = TRUE;
4073  else
4074  {
4075  loader->corrupted = TRUE;
4076  loader->corruption_reason = validity;
4077  }
4078  goto failed;
4079  }
4080 
4081  _dbus_assert (validity == DBUS_VALID);
4082 
4083  /* 2. VALIDATE BODY */
4084  if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
4085  {
4086  get_const_signature (&message->header, &type_str, &type_pos);
4087 
4088  /* Because the bytes_remaining arg is NULL, this validates that the
4089  * body is the right length
4090  */
4091  validity = _dbus_validate_body_with_reason (type_str,
4092  type_pos,
4093  byte_order,
4094  NULL,
4095  &loader->data,
4096  header_len,
4097  body_len);
4098  if (validity != DBUS_VALID)
4099  {
4100  _dbus_verbose ("Failed to validate message body code %d\n", validity);
4101 
4102  loader->corrupted = TRUE;
4103  loader->corruption_reason = validity;
4104 
4105  goto failed;
4106  }
4107  }
4108 
4109  /* 3. COPY OVER UNIX FDS */
4113  &n_unix_fds);
4114 
4115 #ifdef HAVE_UNIX_FD_PASSING
4116 
4117  if (n_unix_fds > loader->n_unix_fds)
4118  {
4119  _dbus_verbose("Message contains references to more unix fds than were sent %u != %u\n",
4120  n_unix_fds, loader->n_unix_fds);
4121 
4122  loader->corrupted = TRUE;
4123  loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4124  goto failed;
4125  }
4126 
4127  /* If this was a recycled message there might still be
4128  some memory allocated for the fds */
4129  dbus_free(message->unix_fds);
4130 
4131  if (n_unix_fds > 0)
4132  {
4133  message->unix_fds = _dbus_memdup(loader->unix_fds, n_unix_fds * sizeof(message->unix_fds[0]));
4134  if (message->unix_fds == NULL)
4135  {
4136  _dbus_verbose ("Failed to allocate file descriptor array\n");
4137  oom = TRUE;
4138  goto failed;
4139  }
4140 
4141  message->n_unix_fds_allocated = message->n_unix_fds = n_unix_fds;
4142  loader->n_unix_fds -= n_unix_fds;
4143  memmove(loader->unix_fds + n_unix_fds, loader->unix_fds, loader->n_unix_fds);
4144  }
4145  else
4146  message->unix_fds = NULL;
4147 
4148 #else
4149 
4150  if (n_unix_fds > 0)
4151  {
4152  _dbus_verbose ("Hmm, message claims to come with file descriptors "
4153  "but that's not supported on our platform, disconnecting.\n");
4154 
4155  loader->corrupted = TRUE;
4156  loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4157  goto failed;
4158  }
4159 
4160 #endif
4161 
4162  /* 3. COPY OVER BODY AND QUEUE MESSAGE */
4163 
4164  if (!_dbus_list_append (&loader->messages, message))
4165  {
4166  _dbus_verbose ("Failed to append new message to loader queue\n");
4167  oom = TRUE;
4168  goto failed;
4169  }
4170 
4171  _dbus_assert (_dbus_string_get_length (&message->body) == 0);
4172  _dbus_assert (_dbus_string_get_length (&loader->data) >=
4173  (header_len + body_len));
4174 
4175  if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
4176  {
4177  _dbus_verbose ("Failed to move body into new message\n");
4178  oom = TRUE;
4179  goto failed;
4180  }
4181 
4182  _dbus_string_delete (&loader->data, 0, header_len + body_len);
4183 
4184  /* don't waste more than 2k of memory */
4185  _dbus_string_compact (&loader->data, 2048);
4186 
4187  _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
4188  _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
4189 
4190  _dbus_verbose ("Loaded message %p\n", message);
4191 
4192  _dbus_assert (!oom);
4193  _dbus_assert (!loader->corrupted);
4194  _dbus_assert (loader->messages != NULL);
4195  _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4196 
4197  return TRUE;
4198 
4199  failed:
4200 
4201  /* Clean up */
4202 
4203  /* does nothing if the message isn't in the list */
4204  _dbus_list_remove_last (&loader->messages, message);
4205 
4206  if (oom)
4207  _dbus_assert (!loader->corrupted);
4208  else
4209  _dbus_assert (loader->corrupted);
4210 
4211  _dbus_verbose_bytes_of_string (&loader->data, 0, _dbus_string_get_length (&loader->data));
4212 
4213  return FALSE;
4214 }
4215 
4232 {
4233  while (!loader->corrupted &&
4234  _dbus_string_get_length (&loader->data) >= DBUS_MINIMUM_HEADER_SIZE)
4235  {
4236  DBusValidity validity;
4237  int byte_order, fields_array_len, header_len, body_len;
4238 
4240  &validity,
4241  &byte_order,
4242  &fields_array_len,
4243  &header_len,
4244  &body_len,
4245  &loader->data, 0,
4246  _dbus_string_get_length (&loader->data)))
4247  {
4248  DBusMessage *message;
4249 
4250  _dbus_assert (validity == DBUS_VALID);
4251 
4252  message = dbus_message_new_empty_header ();
4253  if (message == NULL)
4254  return FALSE;
4255 
4256  if (!load_message (loader, message,
4257  byte_order, fields_array_len,
4258  header_len, body_len))
4259  {
4260  dbus_message_unref (message);
4261  /* load_message() returns false if corrupted or OOM; if
4262  * corrupted then return TRUE for not OOM
4263  */
4264  return loader->corrupted;
4265  }
4266 
4267  _dbus_assert (loader->messages != NULL);
4268  _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4269  }
4270  else
4271  {
4272  _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
4273  validity);
4274  if (validity != DBUS_VALID)
4275  {
4276  loader->corrupted = TRUE;
4277  loader->corruption_reason = validity;
4278  }
4279  return TRUE;
4280  }
4281  }
4282 
4283  return TRUE;
4284 }
4285 
4293 DBusMessage*
4295 {
4296  if (loader->messages)
4297  return loader->messages->data;
4298  else
4299  return NULL;
4300 }
4301 
4310 DBusMessage*
4312 {
4313  return _dbus_list_pop_first (&loader->messages);
4314 }
4315 
4324 DBusList*
4326 {
4327  return _dbus_list_pop_first_link (&loader->messages);
4328 }
4329 
4336 void
4338  DBusList *link)
4339 {
4340  _dbus_list_prepend_link (&loader->messages, link);
4341 }
4342 
4354 {
4355  _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
4356  (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
4357  return loader->corrupted;
4358 }
4359 
4368 {
4369  _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
4370  (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
4371 
4372  return loader->corruption_reason;
4373 }
4374 
4381 void
4383  long size)
4384 {
4385  if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
4386  {
4387  _dbus_verbose ("clamping requested max message size %ld to %d\n",
4390  }
4391  loader->max_message_size = size;
4392 }
4393 
4400 long
4402 {
4403  return loader->max_message_size;
4404 }
4405 
4412 void
4414  long n)
4415 {
4417  {
4418  _dbus_verbose ("clamping requested max message unix_fds %ld to %d\n",
4421  }
4422  loader->max_message_unix_fds = n;
4423 }
4424 
4431 long
4433 {
4434  return loader->max_message_unix_fds;
4435 }
4436 
4437 static DBusDataSlotAllocator slot_allocator =
4438  _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (message_slots));
4439 
4455 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
4456 {
4457  return _dbus_data_slot_allocator_alloc (&slot_allocator,
4458  slot_p);
4459 }
4460 
4472 void
4473 dbus_message_free_data_slot (dbus_int32_t *slot_p)
4474 {
4475  _dbus_return_if_fail (*slot_p >= 0);
4476 
4477  _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
4478 }
4479 
4495  dbus_int32_t slot,
4496  void *data,
4497  DBusFreeFunction free_data_func)
4498 {
4499  DBusFreeFunction old_free_func;
4500  void *old_data;
4501  dbus_bool_t retval;
4502 
4503  _dbus_return_val_if_fail (message != NULL, FALSE);
4504  _dbus_return_val_if_fail (slot >= 0, FALSE);
4505 
4506  retval = _dbus_data_slot_list_set (&slot_allocator,
4507  &message->slot_list,
4508  slot, data, free_data_func,
4509  &old_free_func, &old_data);
4510 
4511  if (retval)
4512  {
4513  /* Do the actual free outside the message lock */
4514  if (old_free_func)
4515  (* old_free_func) (old_data);
4516  }
4517 
4518  return retval;
4519 }
4520 
4529 void*
4531  dbus_int32_t slot)
4532 {
4533  void *res;
4534 
4535  _dbus_return_val_if_fail (message != NULL, NULL);
4536 
4537  res = _dbus_data_slot_list_get (&slot_allocator,
4538  &message->slot_list,
4539  slot);
4540 
4541  return res;
4542 }
4543 
4557 int
4558 dbus_message_type_from_string (const char *type_str)
4559 {
4560  if (strcmp (type_str, "method_call") == 0)
4562  if (strcmp (type_str, "method_return") == 0)
4564  else if (strcmp (type_str, "signal") == 0)
4565  return DBUS_MESSAGE_TYPE_SIGNAL;
4566  else if (strcmp (type_str, "error") == 0)
4567  return DBUS_MESSAGE_TYPE_ERROR;
4568  else
4570 }
4571 
4585 const char *
4587 {
4588  switch (type)
4589  {
4591  return "method_call";
4593  return "method_return";
4595  return "signal";
4597  return "error";
4598  default:
4599  return "invalid";
4600  }
4601 }
4602 
4617  char **marshalled_data_p,
4618  int *len_p)
4619 {
4620  DBusString tmp;
4621  dbus_bool_t was_locked;
4622 
4623  _dbus_return_val_if_fail (msg != NULL, FALSE);
4624  _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
4625  _dbus_return_val_if_fail (len_p != NULL, FALSE);
4626 
4627  if (!_dbus_string_init (&tmp))
4628  return FALSE;
4629 
4630  /* Ensure the message is locked, to ensure the length header is filled in. */
4631  was_locked = msg->locked;
4632 
4633  if (!was_locked)
4634  dbus_message_lock (msg);
4635 
4636  if (!_dbus_string_copy (&(msg->header.data), 0, &tmp, 0))
4637  goto fail;
4638 
4639  *len_p = _dbus_string_get_length (&tmp);
4640 
4641  if (!_dbus_string_copy (&(msg->body), 0, &tmp, *len_p))
4642  goto fail;
4643 
4644  *len_p = _dbus_string_get_length (&tmp);
4645 
4646  if (!_dbus_string_steal_data (&tmp, marshalled_data_p))
4647  goto fail;
4648 
4649  _dbus_string_free (&tmp);
4650 
4651  if (!was_locked)
4652  msg->locked = FALSE;
4653 
4654  return TRUE;
4655 
4656  fail:
4657  _dbus_string_free (&tmp);
4658 
4659  if (!was_locked)
4660  msg->locked = FALSE;
4661 
4662  return FALSE;
4663 }
4664 
4677 DBusMessage *
4678 dbus_message_demarshal (const char *str,
4679  int len,
4680  DBusError *error)
4681 {
4682  DBusMessageLoader *loader;
4683  DBusString *buffer;
4684  DBusMessage *msg;
4685 
4686  _dbus_return_val_if_fail (str != NULL, NULL);
4687 
4688  loader = _dbus_message_loader_new ();
4689 
4690  if (loader == NULL)
4691  return NULL;
4692 
4693  _dbus_message_loader_get_buffer (loader, &buffer);
4694  _dbus_string_append_len (buffer, str, len);
4695  _dbus_message_loader_return_buffer (loader, buffer);
4696 
4698  goto fail_oom;
4699 
4701  goto fail_corrupt;
4702 
4703  msg = _dbus_message_loader_pop_message (loader);
4704 
4705  if (!msg)
4706  goto fail_oom;
4707 
4708  _dbus_message_loader_unref (loader);
4709  return msg;
4710 
4711  fail_corrupt:
4712  dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted (%s)",
4713  _dbus_validity_to_error_message (loader->corruption_reason));
4714  _dbus_message_loader_unref (loader);
4715  return NULL;
4716 
4717  fail_oom:
4718  _DBUS_SET_OOM (error);
4719  _dbus_message_loader_unref (loader);
4720  return NULL;
4721 }
4722 
4735 int
4737  int len)
4738 {
4739  DBusString str;
4740  int byte_order, fields_array_len, header_len, body_len;
4741  DBusValidity validity = DBUS_VALID;
4742  int have_message;
4743 
4744  if (!buf || len < DBUS_MINIMUM_HEADER_SIZE)
4745  return 0;
4746 
4747  if (len > DBUS_MAXIMUM_MESSAGE_LENGTH)
4749  _dbus_string_init_const_len (&str, buf, len);
4750 
4751  validity = DBUS_VALID;
4752  have_message
4754  &validity, &byte_order,
4755  &fields_array_len,
4756  &header_len,
4757  &body_len,
4758  &str, 0,
4759  len);
4760  _dbus_string_free (&str);
4761 
4762  if (validity == DBUS_VALID)
4763  {
4764  _dbus_assert (have_message || (header_len + body_len) > len);
4765  (void) have_message; /* unused unless asserting */
4766  return header_len + body_len;
4767  }
4768  else
4769  {
4770  return -1; /* broken! */
4771  }
4772 }
4773 
4776 /* tests in dbus-message-util.c */