D-Bus  1.4.10
dbus-message.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-message.c DBusMessage object
3  *
4  * Copyright (C) 2002, 2003, 2004, 2005 Red Hat Inc.
5  * Copyright (C) 2002, 2003 CodeFactory AB
6  *
7  * Licensed under the Academic Free License version 2.1
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 #include <config.h>
26 #include "dbus-internals.h"
27 #include "dbus-marshal-recursive.h"
28 #include "dbus-marshal-validate.h"
29 #include "dbus-marshal-byteswap.h"
30 #include "dbus-marshal-header.h"
31 #include "dbus-signature.h"
32 #include "dbus-message-private.h"
33 #include "dbus-object-tree.h"
34 #include "dbus-memory.h"
35 #include "dbus-list.h"
36 #include "dbus-threads-internal.h"
37 #ifdef HAVE_UNIX_FD_PASSING
38 #include "dbus-sysdeps-unix.h"
39 #endif
40 
41 #include <string.h>
42 
43 static void dbus_message_finalize (DBusMessage *message);
44 
55 /* Not thread locked, but strictly const/read-only so should be OK
56  */
58 _DBUS_STRING_DEFINE_STATIC(_dbus_empty_signature_str, "");
59 
60 /* these have wacky values to help trap uninitialized iterators;
61  * but has to fit in 3 bits
62  */
63 enum {
64  DBUS_MESSAGE_ITER_TYPE_READER = 3,
65  DBUS_MESSAGE_ITER_TYPE_WRITER = 7
66 };
67 
70 
77 {
82  union
83  {
86  } u;
87 };
88 
89 static void
90 get_const_signature (DBusHeader *header,
91  const DBusString **type_str_p,
92  int *type_pos_p)
93 {
94  if (_dbus_header_get_field_raw (header,
96  type_str_p,
97  type_pos_p))
98  {
99  *type_pos_p += 1; /* skip the signature length which is 1 byte */
100  }
101  else
102  {
103  *type_str_p = &_dbus_empty_signature_str;
104  *type_pos_p = 0;
105  }
106 }
107 
113 static void
114 _dbus_message_byteswap (DBusMessage *message)
115 {
116  const DBusString *type_str;
117  int type_pos;
118 
119  if (message->byte_order == DBUS_COMPILER_BYTE_ORDER)
120  return;
121 
122  _dbus_verbose ("Swapping message into compiler byte order\n");
123 
124  get_const_signature (&message->header, &type_str, &type_pos);
125 
126  _dbus_marshal_byteswap (type_str, type_pos,
127  message->byte_order,
128  DBUS_COMPILER_BYTE_ORDER,
129  &message->body, 0);
130 
131  message->byte_order = DBUS_COMPILER_BYTE_ORDER;
132 
133  _dbus_header_byteswap (&message->header, DBUS_COMPILER_BYTE_ORDER);
134 }
135 
142 #define ensure_byte_order(message) \
143  if (message->byte_order != DBUS_COMPILER_BYTE_ORDER) \
144  _dbus_message_byteswap (message)
145 
156 void
158  const DBusString **header,
159  const DBusString **body)
160 {
161  _dbus_assert (message->locked);
162 
163  *header = &message->header.data;
164  *body = &message->body;
165 }
166 
177  const int **fds,
178  unsigned *n_fds)
179 {
180  _dbus_assert (message->locked);
181 
182 #ifdef HAVE_UNIX_FD_PASSING
183  *fds = message->unix_fds;
184  *n_fds = message->n_unix_fds;
185 #else
186  *fds = NULL;
187  *n_fds = 0;
188 #endif
189 }
190 
202 void
204  dbus_uint32_t serial)
205 {
206  _dbus_return_if_fail (message != NULL);
207  _dbus_return_if_fail (!message->locked);
208 
209  _dbus_header_set_serial (&message->header, serial);
210 }
211 
223 void
225  DBusList *link)
226 {
227  /* right now we don't recompute the delta when message
228  * size changes, and that's OK for current purposes
229  * I think, but could be important to change later.
230  * Do recompute it whenever there are no outstanding counters,
231  * since it's basically free.
232  */
233  if (message->counters == NULL)
234  {
235  message->size_counter_delta =
236  _dbus_string_get_length (&message->header.data) +
237  _dbus_string_get_length (&message->body);
238 
239 #ifdef HAVE_UNIX_FD_PASSING
240  message->unix_fd_counter_delta = message->n_unix_fds;
241 #endif
242 
243 #if 0
244  _dbus_verbose ("message has size %ld\n",
245  message->size_counter_delta);
246 #endif
247  }
248 
249  _dbus_list_append_link (&message->counters, link);
250 
252 
253 #ifdef HAVE_UNIX_FD_PASSING
254  _dbus_counter_adjust_unix_fd (link->data, message->unix_fd_counter_delta);
255 #endif
256 }
257 
269  DBusCounter *counter)
270 {
271  DBusList *link;
272 
273  link = _dbus_list_alloc_link (counter);
274  if (link == NULL)
275  return FALSE;
276 
277  _dbus_counter_ref (counter);
278  _dbus_message_add_counter_link (message, link);
279 
280  return TRUE;
281 }
282 
291 void
293  DBusCounter *counter,
294  DBusList **link_return)
295 {
296  DBusList *link;
297 
298  link = _dbus_list_find_last (&message->counters,
299  counter);
300  _dbus_assert (link != NULL);
301 
302  _dbus_list_unlink (&message->counters,
303  link);
304  if (link_return)
305  *link_return = link;
306  else
307  _dbus_list_free_link (link);
308 
309  _dbus_counter_adjust_size (counter, - message->size_counter_delta);
310 
311 #ifdef HAVE_UNIX_FD_PASSING
312  _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
313 #endif
314 
315  _dbus_counter_unref (counter);
316 }
317 
328 void
330 {
331  if (!message->locked)
332  {
334  _dbus_string_get_length (&message->body));
335 
336  /* must have a signature if you have a body */
337  _dbus_assert (_dbus_string_get_length (&message->body) == 0 ||
338  dbus_message_get_signature (message) != NULL);
339 
340  message->locked = TRUE;
341  }
342 }
343 
344 static dbus_bool_t
345 set_or_delete_string_field (DBusMessage *message,
346  int field,
347  int typecode,
348  const char *value)
349 {
350  if (value == NULL)
351  return _dbus_header_delete_field (&message->header, field);
352  else
353  return _dbus_header_set_field_basic (&message->header,
354  field,
355  typecode,
356  &value);
357 }
358 
359 #if 0
360 /* Probably we don't need to use this */
384 static dbus_bool_t
385 _dbus_message_set_signature (DBusMessage *message,
386  const char *signature)
387 {
388  _dbus_return_val_if_fail (message != NULL, FALSE);
389  _dbus_return_val_if_fail (!message->locked, FALSE);
390  _dbus_return_val_if_fail (signature == NULL ||
391  _dbus_check_is_valid_signature (signature));
392  /* can't delete the signature if you have a message body */
393  _dbus_return_val_if_fail (_dbus_string_get_length (&message->body) == 0 ||
394  signature != NULL);
395 
396  return set_or_delete_string_field (message,
399  signature);
400 }
401 #endif
402 
403 /* Message Cache
404  *
405  * We cache some DBusMessage to reduce the overhead of allocating
406  * them. In my profiling this consistently made about an 8%
407  * difference. It avoids the malloc for the message, the malloc for
408  * the slot list, the malloc for the header string and body string,
409  * and the associated free() calls. It does introduce another global
410  * lock which could be a performance issue in certain cases.
411  *
412  * For the echo client/server the round trip time goes from around
413  * .000077 to .000069 with the message cache on my laptop. The sysprof
414  * change is as follows (numbers are cumulative percentage):
415  *
416  * with message cache implemented as array as it is now (0.000069 per):
417  * new_empty_header 1.46
418  * mutex_lock 0.56 # i.e. _DBUS_LOCK(message_cache)
419  * mutex_unlock 0.25
420  * self 0.41
421  * unref 2.24
422  * self 0.68
423  * list_clear 0.43
424  * mutex_lock 0.33 # i.e. _DBUS_LOCK(message_cache)
425  * mutex_unlock 0.25
426  *
427  * with message cache implemented as list (0.000070 per roundtrip):
428  * new_empty_header 2.72
429  * list_pop_first 1.88
430  * unref 3.3
431  * list_prepend 1.63
432  *
433  * without cache (0.000077 per roundtrip):
434  * new_empty_header 6.7
435  * string_init_preallocated 3.43
436  * dbus_malloc 2.43
437  * dbus_malloc0 2.59
438  *
439  * unref 4.02
440  * string_free 1.82
441  * dbus_free 1.63
442  * dbus_free 0.71
443  *
444  * If you implement the message_cache with a list, the primary reason
445  * it's slower is that you add another thread lock (on the DBusList
446  * mempool).
447  */
448 
450 #define MAX_MESSAGE_SIZE_TO_CACHE 10 * _DBUS_ONE_KILOBYTE
451 
453 #define MAX_MESSAGE_CACHE_SIZE 5
454 
455 _DBUS_DEFINE_GLOBAL_LOCK (message_cache);
456 static DBusMessage *message_cache[MAX_MESSAGE_CACHE_SIZE];
457 static int message_cache_count = 0;
458 static dbus_bool_t message_cache_shutdown_registered = FALSE;
459 
460 static void
461 dbus_message_cache_shutdown (void *data)
462 {
463  int i;
464 
465  _DBUS_LOCK (message_cache);
466 
467  i = 0;
468  while (i < MAX_MESSAGE_CACHE_SIZE)
469  {
470  if (message_cache[i])
471  dbus_message_finalize (message_cache[i]);
472 
473  ++i;
474  }
475 
476  message_cache_count = 0;
477  message_cache_shutdown_registered = FALSE;
478 
479  _DBUS_UNLOCK (message_cache);
480 }
481 
489 static DBusMessage*
490 dbus_message_get_cached (void)
491 {
492  DBusMessage *message;
493  int i;
494 
495  message = NULL;
496 
497  _DBUS_LOCK (message_cache);
498 
499  _dbus_assert (message_cache_count >= 0);
500 
501  if (message_cache_count == 0)
502  {
503  _DBUS_UNLOCK (message_cache);
504  return NULL;
505  }
506 
507  /* This is not necessarily true unless count > 0, and
508  * message_cache is uninitialized until the shutdown is
509  * registered
510  */
511  _dbus_assert (message_cache_shutdown_registered);
512 
513  i = 0;
514  while (i < MAX_MESSAGE_CACHE_SIZE)
515  {
516  if (message_cache[i])
517  {
518  message = message_cache[i];
519  message_cache[i] = NULL;
520  message_cache_count -= 1;
521  break;
522  }
523  ++i;
524  }
525  _dbus_assert (message_cache_count >= 0);
527  _dbus_assert (message != NULL);
528 
529  _dbus_assert (message->refcount.value == 0);
530  _dbus_assert (message->counters == NULL);
531 
532  _DBUS_UNLOCK (message_cache);
533 
534  return message;
535 }
536 
537 #ifdef HAVE_UNIX_FD_PASSING
538 static void
539 close_unix_fds(int *fds, unsigned *n_fds)
540 {
541  DBusError e;
542  int i;
543 
544  if (*n_fds <= 0)
545  return;
546 
547  dbus_error_init(&e);
548 
549  for (i = 0; i < *n_fds; i++)
550  {
551  if (!_dbus_close(fds[i], &e))
552  {
553  _dbus_warn("Failed to close file descriptor: %s\n", e.message);
554  dbus_error_free(&e);
555  }
556  }
557 
558  *n_fds = 0;
559 
560  /* We don't free the array here, in case we can recycle it later */
561 }
562 #endif
563 
564 static void
565 free_counter (void *element,
566  void *data)
567 {
568  DBusCounter *counter = element;
569  DBusMessage *message = data;
570 
571  _dbus_counter_adjust_size (counter, - message->size_counter_delta);
572 #ifdef HAVE_UNIX_FD_PASSING
573  _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
574 #endif
575 
576  _dbus_counter_unref (counter);
577 }
578 
584 static void
585 dbus_message_cache_or_finalize (DBusMessage *message)
586 {
587  dbus_bool_t was_cached;
588  int i;
589 
590  _dbus_assert (message->refcount.value == 0);
591 
592  /* This calls application code and has to be done first thing
593  * without holding the lock
594  */
596 
597  _dbus_list_foreach (&message->counters,
598  free_counter, message);
599  _dbus_list_clear (&message->counters);
600 
601 #ifdef HAVE_UNIX_FD_PASSING
602  close_unix_fds(message->unix_fds, &message->n_unix_fds);
603 #endif
604 
605  was_cached = FALSE;
606 
607  _DBUS_LOCK (message_cache);
608 
609  if (!message_cache_shutdown_registered)
610  {
611  _dbus_assert (message_cache_count == 0);
612 
613  if (!_dbus_register_shutdown_func (dbus_message_cache_shutdown, NULL))
614  goto out;
615 
616  i = 0;
617  while (i < MAX_MESSAGE_CACHE_SIZE)
618  {
619  message_cache[i] = NULL;
620  ++i;
621  }
622 
623  message_cache_shutdown_registered = TRUE;
624  }
625 
626  _dbus_assert (message_cache_count >= 0);
627 
628  if ((_dbus_string_get_length (&message->header.data) +
629  _dbus_string_get_length (&message->body)) >
631  goto out;
632 
633  if (message_cache_count >= MAX_MESSAGE_CACHE_SIZE)
634  goto out;
635 
636  /* Find empty slot */
637  i = 0;
638  while (message_cache[i] != NULL)
639  ++i;
640 
642 
643  _dbus_assert (message_cache[i] == NULL);
644  message_cache[i] = message;
645  message_cache_count += 1;
646  was_cached = TRUE;
647 #ifndef DBUS_DISABLE_CHECKS
648  message->in_cache = TRUE;
649 #endif
650 
651  out:
652  _dbus_assert (message->refcount.value == 0);
653 
654  _DBUS_UNLOCK (message_cache);
655 
656  if (!was_cached)
657  dbus_message_finalize (message);
658 }
659 
660 #ifndef DBUS_DISABLE_CHECKS
661 static dbus_bool_t
662 _dbus_message_iter_check (DBusMessageRealIter *iter)
663 {
664  if (iter == NULL)
665  {
666  _dbus_warn_check_failed ("dbus message iterator is NULL\n");
667  return FALSE;
668  }
669 
670  if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_READER)
671  {
672  if (iter->u.reader.byte_order != iter->message->byte_order)
673  {
674  _dbus_warn_check_failed ("dbus message changed byte order since iterator was created\n");
675  return FALSE;
676  }
677  /* because we swap the message into compiler order when you init an iter */
678  _dbus_assert (iter->u.reader.byte_order == DBUS_COMPILER_BYTE_ORDER);
679  }
680  else if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER)
681  {
682  if (iter->u.writer.byte_order != iter->message->byte_order)
683  {
684  _dbus_warn_check_failed ("dbus message changed byte order since append iterator was created\n");
685  return FALSE;
686  }
687  /* because we swap the message into compiler order when you init an iter */
688  _dbus_assert (iter->u.writer.byte_order == DBUS_COMPILER_BYTE_ORDER);
689  }
690  else
691  {
692  _dbus_warn_check_failed ("dbus message iterator looks uninitialized or corrupted\n");
693  return FALSE;
694  }
695 
696  if (iter->changed_stamp != iter->message->changed_stamp)
697  {
698  _dbus_warn_check_failed ("dbus message iterator invalid because the message has been modified (or perhaps the iterator is just uninitialized)\n");
699  return FALSE;
700  }
701 
702  return TRUE;
703 }
704 #endif /* DBUS_DISABLE_CHECKS */
705 
722  DBusError *error,
723  int first_arg_type,
724  va_list var_args)
725 {
727  int spec_type, msg_type, i;
728  dbus_bool_t retval;
729 
730  _dbus_assert (_dbus_message_iter_check (real));
731 
732  retval = FALSE;
733 
734  spec_type = first_arg_type;
735  i = 0;
736 
737  while (spec_type != DBUS_TYPE_INVALID)
738  {
739  msg_type = dbus_message_iter_get_arg_type (iter);
740 
741  if (msg_type != spec_type)
742  {
744  "Argument %d is specified to be of type \"%s\", but "
745  "is actually of type \"%s\"\n", i,
746  _dbus_type_to_string (spec_type),
747  _dbus_type_to_string (msg_type));
748 
749  goto out;
750  }
751 
752  if (spec_type == DBUS_TYPE_UNIX_FD)
753  {
754 #ifdef HAVE_UNIX_FD_PASSING
755  DBusBasicValue idx;
756  int *pfd, nfd;
757 
758  pfd = va_arg (var_args, int*);
759  _dbus_assert(pfd);
760 
761  _dbus_type_reader_read_basic(&real->u.reader, &idx);
762 
763  if (idx.u32 >= real->message->n_unix_fds)
764  {
766  "Message refers to file descriptor at index %i,"
767  "but has only %i descriptors attached.\n",
768  idx.u32,
769  real->message->n_unix_fds);
770  goto out;
771  }
772 
773  if ((nfd = _dbus_dup(real->message->unix_fds[idx.u32], error)) < 0)
774  goto out;
775 
776  *pfd = nfd;
777 #else
779  "Platform does not support file desciptor passing.\n");
780  goto out;
781 #endif
782  }
783  else if (dbus_type_is_basic (spec_type))
784  {
785  DBusBasicValue *ptr;
786 
787  ptr = va_arg (var_args, DBusBasicValue*);
788 
789  _dbus_assert (ptr != NULL);
790 
792  ptr);
793  }
794  else if (spec_type == DBUS_TYPE_ARRAY)
795  {
796  int element_type;
797  int spec_element_type;
798  const DBusBasicValue **ptr;
799  int *n_elements_p;
800  DBusTypeReader array;
801 
802  spec_element_type = va_arg (var_args, int);
803  element_type = _dbus_type_reader_get_element_type (&real->u.reader);
804 
805  if (spec_element_type != element_type)
806  {
808  "Argument %d is specified to be an array of \"%s\", but "
809  "is actually an array of \"%s\"\n",
810  i,
811  _dbus_type_to_string (spec_element_type),
812  _dbus_type_to_string (element_type));
813 
814  goto out;
815  }
816 
817  if (dbus_type_is_fixed (spec_element_type) &&
818  element_type != DBUS_TYPE_UNIX_FD)
819  {
820  ptr = va_arg (var_args, const DBusBasicValue**);
821  n_elements_p = va_arg (var_args, int*);
822 
823  _dbus_assert (ptr != NULL);
824  _dbus_assert (n_elements_p != NULL);
825 
826  _dbus_type_reader_recurse (&real->u.reader, &array);
827 
829  (void *) ptr, n_elements_p);
830  }
831  else if (spec_element_type == DBUS_TYPE_STRING ||
832  spec_element_type == DBUS_TYPE_SIGNATURE ||
833  spec_element_type == DBUS_TYPE_OBJECT_PATH)
834  {
835  char ***str_array_p;
836  int n_elements;
837  char **str_array;
838 
839  str_array_p = va_arg (var_args, char***);
840  n_elements_p = va_arg (var_args, int*);
841 
842  _dbus_assert (str_array_p != NULL);
843  _dbus_assert (n_elements_p != NULL);
844 
845  /* Count elements in the array */
846  _dbus_type_reader_recurse (&real->u.reader, &array);
847 
848  n_elements = 0;
850  {
851  ++n_elements;
852  _dbus_type_reader_next (&array);
853  }
854 
855  str_array = dbus_new0 (char*, n_elements + 1);
856  if (str_array == NULL)
857  {
858  _DBUS_SET_OOM (error);
859  goto out;
860  }
861 
862  /* Now go through and dup each string */
863  _dbus_type_reader_recurse (&real->u.reader, &array);
864 
865  i = 0;
866  while (i < n_elements)
867  {
868  const char *s;
870  (void *) &s);
871 
872  str_array[i] = _dbus_strdup (s);
873  if (str_array[i] == NULL)
874  {
875  dbus_free_string_array (str_array);
876  _DBUS_SET_OOM (error);
877  goto out;
878  }
879 
880  ++i;
881 
882  if (!_dbus_type_reader_next (&array))
883  _dbus_assert (i == n_elements);
884  }
885 
887  _dbus_assert (i == n_elements);
888  _dbus_assert (str_array[i] == NULL);
889 
890  *str_array_p = str_array;
891  *n_elements_p = n_elements;
892  }
893 #ifndef DBUS_DISABLE_CHECKS
894  else
895  {
896  _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now\n",
897  _DBUS_FUNCTION_NAME);
898  goto out;
899  }
900 #endif
901  }
902 #ifndef DBUS_DISABLE_CHECKS
903  else
904  {
905  _dbus_warn ("you can only read arrays and basic types with %s for now\n",
906  _DBUS_FUNCTION_NAME);
907  goto out;
908  }
909 #endif
910 
911  spec_type = va_arg (var_args, int);
912  if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID)
913  {
915  "Message has only %d arguments, but more were expected", i);
916  goto out;
917  }
918 
919  i++;
920  }
921 
922  retval = TRUE;
923 
924  out:
925 
926  return retval;
927 }
928 
989 {
990  _dbus_return_val_if_fail (message != NULL, 0);
991 
992  return _dbus_header_get_serial (&message->header);
993 }
994 
1005  dbus_uint32_t reply_serial)
1006 {
1007  _dbus_return_val_if_fail (message != NULL, FALSE);
1008  _dbus_return_val_if_fail (!message->locked, FALSE);
1009  _dbus_return_val_if_fail (reply_serial != 0, FALSE); /* 0 is invalid */
1010 
1011  return _dbus_header_set_field_basic (&message->header,
1014  &reply_serial);
1015 }
1016 
1025 {
1026  dbus_uint32_t v_UINT32;
1027 
1028  _dbus_return_val_if_fail (message != NULL, 0);
1029 
1030  if (_dbus_header_get_field_basic (&message->header,
1033  &v_UINT32))
1034  return v_UINT32;
1035  else
1036  return 0;
1037 }
1038 
1039 static void
1040 dbus_message_finalize (DBusMessage *message)
1041 {
1042  _dbus_assert (message->refcount.value == 0);
1043 
1044  /* This calls application callbacks! */
1046 
1047  _dbus_list_foreach (&message->counters,
1048  free_counter, message);
1049  _dbus_list_clear (&message->counters);
1050 
1051  _dbus_header_free (&message->header);
1052  _dbus_string_free (&message->body);
1053 
1054 #ifdef HAVE_UNIX_FD_PASSING
1055  close_unix_fds(message->unix_fds, &message->n_unix_fds);
1056  dbus_free(message->unix_fds);
1057 #endif
1058 
1059  _dbus_assert (message->refcount.value == 0);
1060 
1061  dbus_free (message);
1062 }
1063 
1064 static DBusMessage*
1065 dbus_message_new_empty_header (void)
1066 {
1067  DBusMessage *message;
1068  dbus_bool_t from_cache;
1069 
1070  message = dbus_message_get_cached ();
1071 
1072  if (message != NULL)
1073  {
1074  from_cache = TRUE;
1075  }
1076  else
1077  {
1078  from_cache = FALSE;
1079  message = dbus_new (DBusMessage, 1);
1080  if (message == NULL)
1081  return NULL;
1082 #ifndef DBUS_DISABLE_CHECKS
1084 #endif
1085 
1086 #ifdef HAVE_UNIX_FD_PASSING
1087  message->unix_fds = NULL;
1088  message->n_unix_fds_allocated = 0;
1089 #endif
1090  }
1091 
1092  message->refcount.value = 1;
1093  message->byte_order = DBUS_COMPILER_BYTE_ORDER;
1094  message->locked = FALSE;
1095 #ifndef DBUS_DISABLE_CHECKS
1096  message->in_cache = FALSE;
1097 #endif
1098  message->counters = NULL;
1099  message->size_counter_delta = 0;
1100  message->changed_stamp = 0;
1101 
1102 #ifdef HAVE_UNIX_FD_PASSING
1103  message->n_unix_fds = 0;
1104  message->n_unix_fds_allocated = 0;
1105  message->unix_fd_counter_delta = 0;
1106 #endif
1107 
1108  if (!from_cache)
1110 
1111  if (from_cache)
1112  {
1113  _dbus_header_reinit (&message->header, message->byte_order);
1114  _dbus_string_set_length (&message->body, 0);
1115  }
1116  else
1117  {
1118  if (!_dbus_header_init (&message->header, message->byte_order))
1119  {
1120  dbus_free (message);
1121  return NULL;
1122  }
1123 
1124  if (!_dbus_string_init_preallocated (&message->body, 32))
1125  {
1126  _dbus_header_free (&message->header);
1127  dbus_free (message);
1128  return NULL;
1129  }
1130  }
1131 
1132  return message;
1133 }
1134 
1147 DBusMessage*
1148 dbus_message_new (int message_type)
1149 {
1150  DBusMessage *message;
1151 
1152  _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
1153 
1154  message = dbus_message_new_empty_header ();
1155  if (message == NULL)
1156  return NULL;
1157 
1158  if (!_dbus_header_create (&message->header,
1159  message_type,
1160  NULL, NULL, NULL, NULL, NULL))
1161  {
1162  dbus_message_unref (message);
1163  return NULL;
1164  }
1165 
1166  return message;
1167 }
1168 
1190 DBusMessage*
1191 dbus_message_new_method_call (const char *destination,
1192  const char *path,
1193  const char *interface,
1194  const char *method)
1195 {
1196  DBusMessage *message;
1197 
1198  _dbus_return_val_if_fail (path != NULL, NULL);
1199  _dbus_return_val_if_fail (method != NULL, NULL);
1200  _dbus_return_val_if_fail (destination == NULL ||
1201  _dbus_check_is_valid_bus_name (destination), NULL);
1202  _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
1203  _dbus_return_val_if_fail (interface == NULL ||
1204  _dbus_check_is_valid_interface (interface), NULL);
1205  _dbus_return_val_if_fail (_dbus_check_is_valid_member (method), NULL);
1206 
1207  message = dbus_message_new_empty_header ();
1208  if (message == NULL)
1209  return NULL;
1210 
1211  if (!_dbus_header_create (&message->header,
1213  destination, path, interface, method, NULL))
1214  {
1215  dbus_message_unref (message);
1216  return NULL;
1217  }
1218 
1219  return message;
1220 }
1221 
1229 DBusMessage*
1231 {
1232  DBusMessage *message;
1233  const char *sender;
1234 
1235  _dbus_return_val_if_fail (method_call != NULL, NULL);
1236 
1237  sender = dbus_message_get_sender (method_call);
1238 
1239  /* sender is allowed to be null here in peer-to-peer case */
1240 
1241  message = dbus_message_new_empty_header ();
1242  if (message == NULL)
1243  return NULL;
1244 
1245  if (!_dbus_header_create (&message->header,
1247  sender, NULL, NULL, NULL, NULL))
1248  {
1249  dbus_message_unref (message);
1250  return NULL;
1251  }
1252 
1253  dbus_message_set_no_reply (message, TRUE);
1254 
1255  if (!dbus_message_set_reply_serial (message,
1256  dbus_message_get_serial (method_call)))
1257  {
1258  dbus_message_unref (message);
1259  return NULL;
1260  }
1261 
1262  return message;
1263 }
1264 
1279 DBusMessage*
1280 dbus_message_new_signal (const char *path,
1281  const char *interface,
1282  const char *name)
1283 {
1284  DBusMessage *message;
1285 
1286  _dbus_return_val_if_fail (path != NULL, NULL);
1287  _dbus_return_val_if_fail (interface != NULL, NULL);
1288  _dbus_return_val_if_fail (name != NULL, NULL);
1289  _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
1290  _dbus_return_val_if_fail (_dbus_check_is_valid_interface (interface), NULL);
1291  _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);
1292 
1293  message = dbus_message_new_empty_header ();
1294  if (message == NULL)
1295  return NULL;
1296 
1297  if (!_dbus_header_create (&message->header,
1299  NULL, path, interface, name, NULL))
1300  {
1301  dbus_message_unref (message);
1302  return NULL;
1303  }
1304 
1305  dbus_message_set_no_reply (message, TRUE);
1306 
1307  return message;
1308 }
1309 
1324 DBusMessage*
1326  const char *error_name,
1327  const char *error_message)
1328 {
1329  DBusMessage *message;
1330  const char *sender;
1331  DBusMessageIter iter;
1332 
1333  _dbus_return_val_if_fail (reply_to != NULL, NULL);
1334  _dbus_return_val_if_fail (error_name != NULL, NULL);
1335  _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
1336 
1337  sender = dbus_message_get_sender (reply_to);
1338 
1339  /* sender may be NULL for non-message-bus case or
1340  * when the message bus is dealing with an unregistered
1341  * connection.
1342  */
1343  message = dbus_message_new_empty_header ();
1344  if (message == NULL)
1345  return NULL;
1346 
1347  if (!_dbus_header_create (&message->header,
1349  sender, NULL, NULL, NULL, error_name))
1350  {
1351  dbus_message_unref (message);
1352  return NULL;
1353  }
1354 
1355  dbus_message_set_no_reply (message, TRUE);
1356 
1357  if (!dbus_message_set_reply_serial (message,
1358  dbus_message_get_serial (reply_to)))
1359  {
1360  dbus_message_unref (message);
1361  return NULL;
1362  }
1363 
1364  if (error_message != NULL)
1365  {
1366  dbus_message_iter_init_append (message, &iter);
1367  if (!dbus_message_iter_append_basic (&iter,
1369  &error_message))
1370  {
1371  dbus_message_unref (message);
1372  return NULL;
1373  }
1374  }
1375 
1376  return message;
1377 }
1378 
1395 DBusMessage*
1397  const char *error_name,
1398  const char *error_format,
1399  ...)
1400 {
1401  va_list args;
1402  DBusString str;
1403  DBusMessage *message;
1404 
1405  _dbus_return_val_if_fail (reply_to != NULL, NULL);
1406  _dbus_return_val_if_fail (error_name != NULL, NULL);
1407  _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
1408 
1409  if (!_dbus_string_init (&str))
1410  return NULL;
1411 
1412  va_start (args, error_format);
1413 
1414  if (_dbus_string_append_printf_valist (&str, error_format, args))
1415  message = dbus_message_new_error (reply_to, error_name,
1417  else
1418  message = NULL;
1419 
1420  _dbus_string_free (&str);
1421 
1422  va_end (args);
1423 
1424  return message;
1425 }
1426 
1427 
1440 DBusMessage *
1442 {
1443  DBusMessage *retval;
1444 
1445  _dbus_return_val_if_fail (message != NULL, NULL);
1446 
1447  retval = dbus_new0 (DBusMessage, 1);
1448  if (retval == NULL)
1449  return NULL;
1450 
1451  retval->refcount.value = 1;
1452  retval->byte_order = message->byte_order;
1453  retval->locked = FALSE;
1454 #ifndef DBUS_DISABLE_CHECKS
1455  retval->generation = message->generation;
1456 #endif
1457 
1458  if (!_dbus_header_copy (&message->header, &retval->header))
1459  {
1460  dbus_free (retval);
1461  return NULL;
1462  }
1463 
1464  if (!_dbus_string_init_preallocated (&retval->body,
1465  _dbus_string_get_length (&message->body)))
1466  {
1467  _dbus_header_free (&retval->header);
1468  dbus_free (retval);
1469  return NULL;
1470  }
1471 
1472  if (!_dbus_string_copy (&message->body, 0,
1473  &retval->body, 0))
1474  goto failed_copy;
1475 
1476 #ifdef HAVE_UNIX_FD_PASSING
1477  retval->unix_fds = dbus_new(int, message->n_unix_fds);
1478  if (retval->unix_fds == NULL && message->n_unix_fds > 0)
1479  goto failed_copy;
1480 
1481  retval->n_unix_fds_allocated = message->n_unix_fds;
1482 
1483  for (retval->n_unix_fds = 0;
1484  retval->n_unix_fds < message->n_unix_fds;
1485  retval->n_unix_fds++)
1486  {
1487  retval->unix_fds[retval->n_unix_fds] = _dbus_dup(message->unix_fds[retval->n_unix_fds], NULL);
1488 
1489  if (retval->unix_fds[retval->n_unix_fds] < 0)
1490  goto failed_copy;
1491  }
1492 
1493 #endif
1494 
1495  return retval;
1496 
1497  failed_copy:
1498  _dbus_header_free (&retval->header);
1499  _dbus_string_free (&retval->body);
1500 
1501 #ifdef HAVE_UNIX_FD_PASSING
1502  close_unix_fds(retval->unix_fds, &retval->n_unix_fds);
1503  dbus_free(retval->unix_fds);
1504 #endif
1505 
1506  dbus_free (retval);
1507 
1508  return NULL;
1509 }
1510 
1511 
1519 DBusMessage *
1521 {
1522  dbus_int32_t old_refcount;
1523 
1524  _dbus_return_val_if_fail (message != NULL, NULL);
1525  _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
1526  _dbus_return_val_if_fail (!message->in_cache, NULL);
1527 
1528  old_refcount = _dbus_atomic_inc (&message->refcount);
1529  _dbus_assert (old_refcount >= 1);
1530 
1531  return message;
1532 }
1533 
1541 void
1543 {
1544  dbus_int32_t old_refcount;
1545 
1546  _dbus_return_if_fail (message != NULL);
1547  _dbus_return_if_fail (message->generation == _dbus_current_generation);
1548  _dbus_return_if_fail (!message->in_cache);
1549 
1550  old_refcount = _dbus_atomic_dec (&message->refcount);
1551 
1552  _dbus_assert (old_refcount >= 0);
1553 
1554  if (old_refcount == 1)
1555  {
1556  /* Calls application callbacks! */
1557  dbus_message_cache_or_finalize (message);
1558  }
1559 }
1560 
1571 int
1573 {
1574  _dbus_return_val_if_fail (message != NULL, DBUS_MESSAGE_TYPE_INVALID);
1575 
1576  return _dbus_header_get_message_type (&message->header);
1577 }
1578 
1643  int first_arg_type,
1644  ...)
1645 {
1646  dbus_bool_t retval;
1647  va_list var_args;
1648 
1649  _dbus_return_val_if_fail (message != NULL, FALSE);
1650 
1651  va_start (var_args, first_arg_type);
1652  retval = dbus_message_append_args_valist (message,
1653  first_arg_type,
1654  var_args);
1655  va_end (var_args);
1656 
1657  return retval;
1658 }
1659 
1675  int first_arg_type,
1676  va_list var_args)
1677 {
1678  int type;
1679  DBusMessageIter iter;
1680 
1681  _dbus_return_val_if_fail (message != NULL, FALSE);
1682 
1683  type = first_arg_type;
1684 
1685  dbus_message_iter_init_append (message, &iter);
1686 
1687  while (type != DBUS_TYPE_INVALID)
1688  {
1689  if (dbus_type_is_basic (type))
1690  {
1691  const DBusBasicValue *value;
1692  value = va_arg (var_args, const DBusBasicValue*);
1693 
1694  if (!dbus_message_iter_append_basic (&iter,
1695  type,
1696  value))
1697  goto failed;
1698  }
1699  else if (type == DBUS_TYPE_ARRAY)
1700  {
1701  int element_type;
1702  DBusMessageIter array;
1703  char buf[2];
1704 
1705  element_type = va_arg (var_args, int);
1706 
1707  buf[0] = element_type;
1708  buf[1] = '\0';
1711  buf,
1712  &array))
1713  goto failed;
1714 
1715  if (dbus_type_is_fixed (element_type) &&
1716  element_type != DBUS_TYPE_UNIX_FD)
1717  {
1718  const DBusBasicValue **value;
1719  int n_elements;
1720 
1721  value = va_arg (var_args, const DBusBasicValue**);
1722  n_elements = va_arg (var_args, int);
1723 
1725  element_type,
1726  value,
1727  n_elements)) {
1728  dbus_message_iter_abandon_container (&iter, &array);
1729  goto failed;
1730  }
1731  }
1732  else if (element_type == DBUS_TYPE_STRING ||
1733  element_type == DBUS_TYPE_SIGNATURE ||
1734  element_type == DBUS_TYPE_OBJECT_PATH)
1735  {
1736  const char ***value_p;
1737  const char **value;
1738  int n_elements;
1739  int i;
1740 
1741  value_p = va_arg (var_args, const char***);
1742  n_elements = va_arg (var_args, int);
1743 
1744  value = *value_p;
1745 
1746  i = 0;
1747  while (i < n_elements)
1748  {
1749  if (!dbus_message_iter_append_basic (&array,
1750  element_type,
1751  &value[i])) {
1752  dbus_message_iter_abandon_container (&iter, &array);
1753  goto failed;
1754  }
1755  ++i;
1756  }
1757  }
1758  else
1759  {
1760  _dbus_warn ("arrays of %s can't be appended with %s for now\n",
1761  _dbus_type_to_string (element_type),
1762  _DBUS_FUNCTION_NAME);
1763  goto failed;
1764  }
1765 
1766  if (!dbus_message_iter_close_container (&iter, &array))
1767  goto failed;
1768  }
1769 #ifndef DBUS_DISABLE_CHECKS
1770  else
1771  {
1772  _dbus_warn ("type %s isn't supported yet in %s\n",
1773  _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
1774  goto failed;
1775  }
1776 #endif
1777 
1778  type = va_arg (var_args, int);
1779  }
1780 
1781  return TRUE;
1782 
1783  failed:
1784  return FALSE;
1785 }
1786 
1833  DBusError *error,
1834  int first_arg_type,
1835  ...)
1836 {
1837  dbus_bool_t retval;
1838  va_list var_args;
1839 
1840  _dbus_return_val_if_fail (message != NULL, FALSE);
1841  _dbus_return_val_if_error_is_set (error, FALSE);
1842 
1843  va_start (var_args, first_arg_type);
1844  retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
1845  va_end (var_args);
1846 
1847  return retval;
1848 }
1849 
1862  DBusError *error,
1863  int first_arg_type,
1864  va_list var_args)
1865 {
1866  DBusMessageIter iter;
1867 
1868  _dbus_return_val_if_fail (message != NULL, FALSE);
1869  _dbus_return_val_if_error_is_set (error, FALSE);
1870 
1871  dbus_message_iter_init (message, &iter);
1872  return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
1873 }
1874 
1875 static void
1876 _dbus_message_iter_init_common (DBusMessage *message,
1877  DBusMessageRealIter *real,
1878  int iter_type)
1879 {
1880  _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
1881 
1882  /* Since the iterator will read or write who-knows-what from the
1883  * message, we need to get in the right byte order
1884  */
1885  ensure_byte_order (message);
1886 
1887  real->message = message;
1888  real->changed_stamp = message->changed_stamp;
1889  real->iter_type = iter_type;
1890  real->sig_refcount = 0;
1891 }
1892 
1917  DBusMessageIter *iter)
1918 {
1919  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
1920  const DBusString *type_str;
1921  int type_pos;
1922 
1923  _dbus_return_val_if_fail (message != NULL, FALSE);
1924  _dbus_return_val_if_fail (iter != NULL, FALSE);
1925 
1926  get_const_signature (&message->header, &type_str, &type_pos);
1927 
1928  _dbus_message_iter_init_common (message, real,
1929  DBUS_MESSAGE_ITER_TYPE_READER);
1930 
1932  message->byte_order,
1933  type_str, type_pos,
1934  &message->body,
1935  0);
1936 
1938 }
1939 
1948 {
1949  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
1950 
1951  _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
1952  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
1953 
1954  return _dbus_type_reader_has_next (&real->u.reader);
1955 }
1956 
1967 {
1968  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
1969 
1970  _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
1971  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
1972 
1973  return _dbus_type_reader_next (&real->u.reader);
1974 }
1975 
1990 int
1992 {
1993  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
1994 
1995  _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
1996  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
1997 
1999 }
2000 
2009 int
2011 {
2012  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2013 
2014  _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2015  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
2016  _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
2017 
2019 }
2020 
2046 void
2048  DBusMessageIter *sub)
2049 {
2050  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2051  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2052 
2053  _dbus_return_if_fail (_dbus_message_iter_check (real));
2054  _dbus_return_if_fail (sub != NULL);
2055 
2056  *real_sub = *real;
2057  _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
2058 }
2059 
2071 char *
2073 {
2074  const DBusString *sig;
2075  DBusString retstr;
2076  char *ret;
2077  int start, len;
2078  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2079 
2080  _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
2081 
2082  if (!_dbus_string_init (&retstr))
2083  return NULL;
2084 
2086  &start, &len);
2087  if (!_dbus_string_append_len (&retstr,
2088  _dbus_string_get_const_data (sig) + start,
2089  len))
2090  return NULL;
2091  if (!_dbus_string_steal_data (&retstr, &ret))
2092  return NULL;
2093  _dbus_string_free (&retstr);
2094  return ret;
2095 }
2096 
2144 void
2146  void *value)
2147 {
2148  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2149 
2150  _dbus_return_if_fail (_dbus_message_iter_check (real));
2151  _dbus_return_if_fail (value != NULL);
2152 
2154  {
2155 #ifdef HAVE_UNIX_FD_PASSING
2156  DBusBasicValue idx;
2157 
2158  _dbus_type_reader_read_basic(&real->u.reader, &idx);
2159 
2160  if (idx.u32 >= real->message->n_unix_fds) {
2161  /* Hmm, we cannot really signal an error here, so let's make
2162  sure to return an invalid fd. */
2163  *((int*) value) = -1;
2164  return;
2165  }
2166 
2167  *((int*) value) = _dbus_dup(real->message->unix_fds[idx.u32], NULL);
2168 #else
2169  *((int*) value) = -1;
2170 #endif
2171  }
2172  else
2173  {
2175  value);
2176  }
2177 }
2178 
2197 int
2199 {
2200  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2201 
2202  _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
2203 
2205 }
2206 
2242 void
2244  void *value,
2245  int *n_elements)
2246 {
2247  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2248  int subtype = _dbus_type_reader_get_current_type(&real->u.reader);
2249 
2250  _dbus_return_if_fail (_dbus_message_iter_check (real));
2251  _dbus_return_if_fail (value != NULL);
2252  _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) ||
2253  (dbus_type_is_fixed (subtype) && subtype != DBUS_TYPE_UNIX_FD));
2254 
2256  value, n_elements);
2257 }
2258 
2270 void
2272  DBusMessageIter *iter)
2273 {
2274  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2275 
2276  _dbus_return_if_fail (message != NULL);
2277  _dbus_return_if_fail (iter != NULL);
2278 
2279  _dbus_message_iter_init_common (message, real,
2280  DBUS_MESSAGE_ITER_TYPE_WRITER);
2281 
2282  /* We create the signature string and point iterators at it "on demand"
2283  * when a value is actually appended. That means that init() never fails
2284  * due to OOM.
2285  */
2287  message->byte_order,
2288  &message->body,
2289  _dbus_string_get_length (&message->body));
2290 }
2291 
2300 static dbus_bool_t
2301 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
2302 {
2303  DBusString *str;
2304  const DBusString *current_sig;
2305  int current_sig_pos;
2306 
2307  _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2308 
2309  if (real->u.writer.type_str != NULL)
2310  {
2311  _dbus_assert (real->sig_refcount > 0);
2312  real->sig_refcount += 1;
2313  return TRUE;
2314  }
2315 
2316  str = dbus_new (DBusString, 1);
2317  if (str == NULL)
2318  return FALSE;
2319 
2322  &current_sig, &current_sig_pos))
2323  current_sig = NULL;
2324 
2325  if (current_sig)
2326  {
2327  int current_len;
2328 
2329  current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
2330  current_sig_pos += 1; /* move on to sig data */
2331 
2332  if (!_dbus_string_init_preallocated (str, current_len + 4))
2333  {
2334  dbus_free (str);
2335  return FALSE;
2336  }
2337 
2338  if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
2339  str, 0))
2340  {
2341  _dbus_string_free (str);
2342  dbus_free (str);
2343  return FALSE;
2344  }
2345  }
2346  else
2347  {
2348  if (!_dbus_string_init_preallocated (str, 4))
2349  {
2350  dbus_free (str);
2351  return FALSE;
2352  }
2353  }
2354 
2355  real->sig_refcount = 1;
2356 
2358  str, _dbus_string_get_length (str));
2359  return TRUE;
2360 }
2361 
2371 static dbus_bool_t
2372 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
2373 {
2374  DBusString *str;
2375  const char *v_STRING;
2376  dbus_bool_t retval;
2377 
2378  _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2379  _dbus_assert (real->u.writer.type_str != NULL);
2380  _dbus_assert (real->sig_refcount > 0);
2381 
2382  real->sig_refcount -= 1;
2383 
2384  if (real->sig_refcount > 0)
2385  return TRUE;
2386  _dbus_assert (real->sig_refcount == 0);
2387 
2388  retval = TRUE;
2389 
2390  str = real->u.writer.type_str;
2391 
2392  v_STRING = _dbus_string_get_const_data (str);
2396  &v_STRING))
2397  retval = FALSE;
2398 
2400  _dbus_string_free (str);
2401  dbus_free (str);
2402 
2403  return retval;
2404 }
2405 
2413 static void
2414 _dbus_message_iter_abandon_signature (DBusMessageRealIter *real)
2415 {
2416  DBusString *str;
2417 
2418  _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2419  _dbus_assert (real->u.writer.type_str != NULL);
2420  _dbus_assert (real->sig_refcount > 0);
2421 
2422  real->sig_refcount -= 1;
2423 
2424  if (real->sig_refcount > 0)
2425  return;
2426  _dbus_assert (real->sig_refcount == 0);
2427 
2428  str = real->u.writer.type_str;
2429 
2431  _dbus_string_free (str);
2432  dbus_free (str);
2433 }
2434 
2435 #ifndef DBUS_DISABLE_CHECKS
2436 static dbus_bool_t
2437 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
2438 {
2439  if (!_dbus_message_iter_check (iter))
2440  return FALSE;
2441 
2442  if (iter->message->locked)
2443  {
2444  _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)\n");
2445  return FALSE;
2446  }
2447 
2448  return TRUE;
2449 }
2450 #endif /* DBUS_DISABLE_CHECKS */
2451 
2452 #ifdef HAVE_UNIX_FD_PASSING
2453 static int *
2454 expand_fd_array(DBusMessage *m,
2455  unsigned n)
2456 {
2457  _dbus_assert(m);
2458 
2459  /* This makes space for adding n new fds to the array and returns a
2460  pointer to the place were the first fd should be put. */
2461 
2462  if (m->n_unix_fds + n > m->n_unix_fds_allocated)
2463  {
2464  unsigned k;
2465  int *p;
2466 
2467  /* Make twice as much space as necessary */
2468  k = (m->n_unix_fds + n) * 2;
2469 
2470  /* Allocate at least four */
2471  if (k < 4)
2472  k = 4;
2473 
2474  p = dbus_realloc(m->unix_fds, k * sizeof(int));
2475  if (p == NULL)
2476  return NULL;
2477 
2478  m->unix_fds = p;
2479  m->n_unix_fds_allocated = k;
2480  }
2481 
2482  return m->unix_fds + m->n_unix_fds;
2483 }
2484 #endif
2485 
2507  int type,
2508  const void *value)
2509 {
2510  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2511  dbus_bool_t ret;
2512 
2513  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2514  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2515  _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
2516  _dbus_return_val_if_fail (value != NULL, FALSE);
2517 
2518 #ifndef DBUS_DISABLE_CHECKS
2519  switch (type)
2520  {
2521  const char * const *string_p;
2522  const dbus_bool_t *bool_p;
2523 
2524  case DBUS_TYPE_STRING:
2525  string_p = value;
2526  _dbus_return_val_if_fail (_dbus_check_is_valid_utf8 (*string_p), FALSE);
2527  break;
2528 
2529  case DBUS_TYPE_OBJECT_PATH:
2530  string_p = value;
2531  _dbus_return_val_if_fail (_dbus_check_is_valid_path (*string_p), FALSE);
2532  break;
2533 
2534  case DBUS_TYPE_SIGNATURE:
2535  string_p = value;
2536  _dbus_return_val_if_fail (_dbus_check_is_valid_signature (*string_p), FALSE);
2537  break;
2538 
2539  case DBUS_TYPE_BOOLEAN:
2540  bool_p = value;
2541  _dbus_return_val_if_fail (*bool_p == 0 || *bool_p == 1, FALSE);
2542  break;
2543 
2544  default:
2545  {
2546  /* nothing to check, all possible values are allowed */
2547  }
2548  }
2549 #endif
2550 
2551  if (!_dbus_message_iter_open_signature (real))
2552  return FALSE;
2553 
2554  if (type == DBUS_TYPE_UNIX_FD)
2555  {
2556 #ifdef HAVE_UNIX_FD_PASSING
2557  int *fds;
2558  dbus_uint32_t u;
2559 
2560  /* First step, include the fd in the fd list of this message */
2561  if (!(fds = expand_fd_array(real->message, 1)))
2562  return FALSE;
2563 
2564  *fds = _dbus_dup(*(int*) value, NULL);
2565  if (*fds < 0)
2566  return FALSE;
2567 
2568  u = real->message->n_unix_fds;
2569 
2570  /* Second step, write the index to the fd */
2571  if (!(ret = _dbus_type_writer_write_basic (&real->u.writer, DBUS_TYPE_UNIX_FD, &u))) {
2572  _dbus_close(*fds, NULL);
2573  return FALSE;
2574  }
2575 
2576  real->message->n_unix_fds += 1;
2577  u += 1;
2578 
2579  /* Final step, update the header accordingly */
2583  &u);
2584 
2585  /* If any of these operations fail the message is
2586  hosed. However, no memory or fds should be leaked since what
2587  has been added to message has been added to the message, and
2588  can hence be accounted for when the message is being
2589  freed. */
2590 #else
2591  ret = FALSE;
2592 #endif
2593  }
2594  else
2595  {
2596  ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
2597  }
2598 
2599  if (!_dbus_message_iter_close_signature (real))
2600  ret = FALSE;
2601 
2602  return ret;
2603 }
2604 
2642  int element_type,
2643  const void *value,
2644  int n_elements)
2645 {
2646  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2647  dbus_bool_t ret;
2648 
2649  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2650  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2651  _dbus_return_val_if_fail (dbus_type_is_fixed (element_type) && element_type != DBUS_TYPE_UNIX_FD, FALSE);
2652  _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
2653  _dbus_return_val_if_fail (value != NULL, FALSE);
2654  _dbus_return_val_if_fail (n_elements >= 0, FALSE);
2655  _dbus_return_val_if_fail (n_elements <=
2657  FALSE);
2658 
2659 #ifndef DBUS_DISABLE_CHECKS
2660  if (element_type == DBUS_TYPE_BOOLEAN)
2661  {
2662  const dbus_bool_t * const *bools = value;
2663  int i;
2664 
2665  for (i = 0; i < n_elements; i++)
2666  {
2667  _dbus_return_val_if_fail ((*bools)[i] == 0 || (*bools)[i] == 1, FALSE);
2668  }
2669  }
2670 #endif
2671 
2672  ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
2673 
2674  return ret;
2675 }
2676 
2700  int type,
2701  const char *contained_signature,
2702  DBusMessageIter *sub)
2703 {
2704  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2705  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2706  DBusString contained_str;
2707 
2708  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2709  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2710  _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
2711  _dbus_return_val_if_fail (sub != NULL, FALSE);
2712  _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
2713  contained_signature == NULL) ||
2714  (type == DBUS_TYPE_DICT_ENTRY &&
2715  contained_signature == NULL) ||
2716  (type == DBUS_TYPE_VARIANT &&
2717  contained_signature != NULL) ||
2718  (type == DBUS_TYPE_ARRAY &&
2719  contained_signature != NULL), FALSE);
2720 
2721  /* this would fail if the contained_signature is a dict entry, since
2722  * dict entries are invalid signatures standalone (they must be in
2723  * an array)
2724  */
2725  _dbus_return_val_if_fail ((type == DBUS_TYPE_ARRAY && contained_signature && *contained_signature == DBUS_DICT_ENTRY_BEGIN_CHAR) ||
2726  (contained_signature == NULL ||
2727  _dbus_check_is_valid_signature (contained_signature)),
2728  FALSE);
2729 
2730  if (!_dbus_message_iter_open_signature (real))
2731  return FALSE;
2732 
2733  *real_sub = *real;
2734 
2735  if (contained_signature != NULL)
2736  {
2737  _dbus_string_init_const (&contained_str, contained_signature);
2738 
2739  return _dbus_type_writer_recurse (&real->u.writer,
2740  type,
2741  &contained_str, 0,
2742  &real_sub->u.writer);
2743  }
2744  else
2745  {
2746  return _dbus_type_writer_recurse (&real->u.writer,
2747  type,
2748  NULL, 0,
2749  &real_sub->u.writer);
2750  }
2751 }
2752 
2753 
2769  DBusMessageIter *sub)
2770 {
2771  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2772  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2773  dbus_bool_t ret;
2774 
2775  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2776  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2777  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
2778  _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2779 
2780  ret = _dbus_type_writer_unrecurse (&real->u.writer,
2781  &real_sub->u.writer);
2782 
2783  if (!_dbus_message_iter_close_signature (real))
2784  ret = FALSE;
2785 
2786  return ret;
2787 }
2788 
2800 void
2802  DBusMessageIter *sub)
2803 {
2804  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2805  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2806 
2807  _dbus_return_if_fail (_dbus_message_iter_append_check (real));
2808  _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2809  _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
2810  _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2811 
2812  _dbus_message_iter_abandon_signature (real);
2813 }
2814 
2831 void
2833  dbus_bool_t no_reply)
2834 {
2835  _dbus_return_if_fail (message != NULL);
2836  _dbus_return_if_fail (!message->locked);
2837 
2838  _dbus_header_toggle_flag (&message->header,
2840  no_reply);
2841 }
2842 
2852 {
2853  _dbus_return_val_if_fail (message != NULL, FALSE);
2854 
2855  return _dbus_header_get_flag (&message->header,
2857 }
2858 
2873 void
2875  dbus_bool_t auto_start)
2876 {
2877  _dbus_return_if_fail (message != NULL);
2878  _dbus_return_if_fail (!message->locked);
2879 
2880  _dbus_header_toggle_flag (&message->header,
2882  !auto_start);
2883 }
2884 
2894 {
2895  _dbus_return_val_if_fail (message != NULL, FALSE);
2896 
2897  return !_dbus_header_get_flag (&message->header,
2899 }
2900 
2901 
2916  const char *object_path)
2917 {
2918  _dbus_return_val_if_fail (message != NULL, FALSE);
2919  _dbus_return_val_if_fail (!message->locked, FALSE);
2920  _dbus_return_val_if_fail (object_path == NULL ||
2921  _dbus_check_is_valid_path (object_path),
2922  FALSE);
2923 
2924  return set_or_delete_string_field (message,
2927  object_path);
2928 }
2929 
2943 const char*
2945 {
2946  const char *v;
2947 
2948  _dbus_return_val_if_fail (message != NULL, NULL);
2949 
2950  v = NULL; /* in case field doesn't exist */
2954  (void *) &v);
2955  return v;
2956 }
2957 
2969  const char *path)
2970 {
2971  const char *msg_path;
2972  msg_path = dbus_message_get_path (message);
2973 
2974  if (msg_path == NULL)
2975  {
2976  if (path == NULL)
2977  return TRUE;
2978  else
2979  return FALSE;
2980  }
2981 
2982  if (path == NULL)
2983  return FALSE;
2984 
2985  if (strcmp (msg_path, path) == 0)
2986  return TRUE;
2987 
2988  return FALSE;
2989 }
2990 
3013  char ***path)
3014 {
3015  const char *v;
3016 
3017  _dbus_return_val_if_fail (message != NULL, FALSE);
3018  _dbus_return_val_if_fail (path != NULL, FALSE);
3019 
3020  *path = NULL;
3021 
3022  v = dbus_message_get_path (message);
3023  if (v != NULL)
3024  {
3025  if (!_dbus_decompose_path (v, strlen (v),
3026  path, NULL))
3027  return FALSE;
3028  }
3029  return TRUE;
3030 }
3031 
3047  const char *interface)
3048 {
3049  _dbus_return_val_if_fail (message != NULL, FALSE);
3050  _dbus_return_val_if_fail (!message->locked, FALSE);
3051  _dbus_return_val_if_fail (interface == NULL ||
3052  _dbus_check_is_valid_interface (interface),
3053  FALSE);
3054 
3055  return set_or_delete_string_field (message,
3058  interface);
3059 }
3060 
3074 const char*
3076 {
3077  const char *v;
3078 
3079  _dbus_return_val_if_fail (message != NULL, NULL);
3080 
3081  v = NULL; /* in case field doesn't exist */
3085  (void *) &v);
3086  return v;
3087 }
3088 
3098  const char *interface)
3099 {
3100  const char *msg_interface;
3101  msg_interface = dbus_message_get_interface (message);
3102 
3103  if (msg_interface == NULL)
3104  {
3105  if (interface == NULL)
3106  return TRUE;
3107  else
3108  return FALSE;
3109  }
3110 
3111  if (interface == NULL)
3112  return FALSE;
3113 
3114  if (strcmp (msg_interface, interface) == 0)
3115  return TRUE;
3116 
3117  return FALSE;
3118 
3119 }
3120 
3135  const char *member)
3136 {
3137  _dbus_return_val_if_fail (message != NULL, FALSE);
3138  _dbus_return_val_if_fail (!message->locked, FALSE);
3139  _dbus_return_val_if_fail (member == NULL ||
3140  _dbus_check_is_valid_member (member),
3141  FALSE);
3142 
3143  return set_or_delete_string_field (message,
3146  member);
3147 }
3148 
3160 const char*
3162 {
3163  const char *v;
3164 
3165  _dbus_return_val_if_fail (message != NULL, NULL);
3166 
3167  v = NULL; /* in case field doesn't exist */
3171  (void *) &v);
3172  return v;
3173 }
3174 
3184  const char *member)
3185 {
3186  const char *msg_member;
3187  msg_member = dbus_message_get_member (message);
3188 
3189  if (msg_member == NULL)
3190  {
3191  if (member == NULL)
3192  return TRUE;
3193  else
3194  return FALSE;
3195  }
3196 
3197  if (member == NULL)
3198  return FALSE;
3199 
3200  if (strcmp (msg_member, member) == 0)
3201  return TRUE;
3202 
3203  return FALSE;
3204 
3205 }
3206 
3220  const char *error_name)
3221 {
3222  _dbus_return_val_if_fail (message != NULL, FALSE);
3223  _dbus_return_val_if_fail (!message->locked, FALSE);
3224  _dbus_return_val_if_fail (error_name == NULL ||
3225  _dbus_check_is_valid_error_name (error_name),
3226  FALSE);
3227 
3228  return set_or_delete_string_field (message,
3231  error_name);
3232 }
3233 
3244 const char*
3246 {
3247  const char *v;
3248 
3249  _dbus_return_val_if_fail (message != NULL, NULL);
3250 
3251  v = NULL; /* in case field doesn't exist */
3255  (void *) &v);
3256  return v;
3257 }
3258 
3274  const char *destination)
3275 {
3276  _dbus_return_val_if_fail (message != NULL, FALSE);
3277  _dbus_return_val_if_fail (!message->locked, FALSE);
3278  _dbus_return_val_if_fail (destination == NULL ||
3279  _dbus_check_is_valid_bus_name (destination),
3280  FALSE);
3281 
3282  return set_or_delete_string_field (message,
3285  destination);
3286 }
3287 
3297 const char*
3299 {
3300  const char *v;
3301 
3302  _dbus_return_val_if_fail (message != NULL, NULL);
3303 
3304  v = NULL; /* in case field doesn't exist */
3308  (void *) &v);
3309  return v;
3310 }
3311 
3328  const char *sender)
3329 {
3330  _dbus_return_val_if_fail (message != NULL, FALSE);
3331  _dbus_return_val_if_fail (!message->locked, FALSE);
3332  _dbus_return_val_if_fail (sender == NULL ||
3333  _dbus_check_is_valid_bus_name (sender),
3334  FALSE);
3335 
3336  return set_or_delete_string_field (message,
3339  sender);
3340 }
3341 
3357 const char*
3359 {
3360  const char *v;
3361 
3362  _dbus_return_val_if_fail (message != NULL, NULL);
3363 
3364  v = NULL; /* in case field doesn't exist */
3368  (void *) &v);
3369  return v;
3370 }
3371 
3390 const char*
3392 {
3393  const DBusString *type_str;
3394  int type_pos;
3395 
3396  _dbus_return_val_if_fail (message != NULL, NULL);
3397 
3398  get_const_signature (&message->header, &type_str, &type_pos);
3399 
3400  return _dbus_string_get_const_data_len (type_str, type_pos, 0);
3401 }
3402 
3403 static dbus_bool_t
3404 _dbus_message_has_type_interface_member (DBusMessage *message,
3405  int type,
3406  const char *interface,
3407  const char *member)
3408 {
3409  const char *n;
3410 
3411  _dbus_assert (message != NULL);
3412  _dbus_assert (interface != NULL);
3413  _dbus_assert (member != NULL);
3414 
3415  if (dbus_message_get_type (message) != type)
3416  return FALSE;
3417 
3418  /* Optimize by checking the short member name first
3419  * instead of the longer interface name
3420  */
3421 
3422  n = dbus_message_get_member (message);
3423 
3424  if (n && strcmp (n, member) == 0)
3425  {
3426  n = dbus_message_get_interface (message);
3427 
3428  if (n == NULL || strcmp (n, interface) == 0)
3429  return TRUE;
3430  }
3431 
3432  return FALSE;
3433 }
3434 
3451  const char *interface,
3452  const char *method)
3453 {
3454  _dbus_return_val_if_fail (message != NULL, FALSE);
3455  _dbus_return_val_if_fail (interface != NULL, FALSE);
3456  _dbus_return_val_if_fail (method != NULL, FALSE);
3457  /* don't check that interface/method are valid since it would be
3458  * expensive, and not catch many common errors
3459  */
3460 
3461  return _dbus_message_has_type_interface_member (message,
3463  interface, method);
3464 }
3465 
3479  const char *interface,
3480  const char *signal_name)
3481 {
3482  _dbus_return_val_if_fail (message != NULL, FALSE);
3483  _dbus_return_val_if_fail (interface != NULL, FALSE);
3484  _dbus_return_val_if_fail (signal_name != NULL, FALSE);
3485  /* don't check that interface/name are valid since it would be
3486  * expensive, and not catch many common errors
3487  */
3488 
3489  return _dbus_message_has_type_interface_member (message,
3491  interface, signal_name);
3492 }
3493 
3506  const char *error_name)
3507 {
3508  const char *n;
3509 
3510  _dbus_return_val_if_fail (message != NULL, FALSE);
3511  _dbus_return_val_if_fail (error_name != NULL, FALSE);
3512  /* don't check that error_name is valid since it would be expensive,
3513  * and not catch many common errors
3514  */
3515 
3517  return FALSE;
3518 
3519  n = dbus_message_get_error_name (message);
3520 
3521  if (n && strcmp (n, error_name) == 0)
3522  return TRUE;
3523  else
3524  return FALSE;
3525 }
3526 
3539  const char *name)
3540 {
3541  const char *s;
3542 
3543  _dbus_return_val_if_fail (message != NULL, FALSE);
3544  _dbus_return_val_if_fail (name != NULL, FALSE);
3545  /* don't check that name is valid since it would be expensive, and
3546  * not catch many common errors
3547  */
3548 
3549  s = dbus_message_get_destination (message);
3550 
3551  if (s && strcmp (s, name) == 0)
3552  return TRUE;
3553  else
3554  return FALSE;
3555 }
3556 
3574  const char *name)
3575 {
3576  const char *s;
3577 
3578  _dbus_return_val_if_fail (message != NULL, FALSE);
3579  _dbus_return_val_if_fail (name != NULL, FALSE);
3580  /* don't check that name is valid since it would be expensive, and
3581  * not catch many common errors
3582  */
3583 
3584  s = dbus_message_get_sender (message);
3585 
3586  if (s && strcmp (s, name) == 0)
3587  return TRUE;
3588  else
3589  return FALSE;
3590 }
3591 
3603  const char *signature)
3604 {
3605  const char *s;
3606 
3607  _dbus_return_val_if_fail (message != NULL, FALSE);
3608  _dbus_return_val_if_fail (signature != NULL, FALSE);
3609  /* don't check that signature is valid since it would be expensive,
3610  * and not catch many common errors
3611  */
3612 
3613  s = dbus_message_get_signature (message);
3614 
3615  if (s && strcmp (s, signature) == 0)
3616  return TRUE;
3617  else
3618  return FALSE;
3619 }
3620 
3645  DBusMessage *message)
3646 {
3647  const char *str;
3648 
3649  _dbus_return_val_if_fail (message != NULL, FALSE);
3650  _dbus_return_val_if_error_is_set (error, FALSE);
3651 
3653  return FALSE;
3654 
3655  str = NULL;
3656  dbus_message_get_args (message, NULL,
3657  DBUS_TYPE_STRING, &str,
3659 
3660  dbus_set_error (error, dbus_message_get_error_name (message),
3661  str ? "%s" : NULL, str);
3662 
3663  return TRUE;
3664 }
3665 
3674 {
3675 #ifdef HAVE_UNIX_FD_PASSING
3676  _dbus_assert(message);
3677 
3678  return message->n_unix_fds > 0;
3679 #else
3680  return FALSE;
3681 #endif
3682 }
3683 
3702 #define INITIAL_LOADER_DATA_LEN 32
3703 
3712 {
3713  DBusMessageLoader *loader;
3714 
3715  loader = dbus_new0 (DBusMessageLoader, 1);
3716  if (loader == NULL)
3717  return NULL;
3718 
3719  loader->refcount = 1;
3720 
3721  loader->corrupted = FALSE;
3722  loader->corruption_reason = DBUS_VALID;
3723 
3724  /* this can be configured by the app, but defaults to the protocol max */
3726 
3727  /* We set a very relatively conservative default here since due to how
3728  SCM_RIGHTS works we need to preallocate an fd array of the maximum
3729  number of unix fds we want to receive in advance. A
3730  try-and-reallocate loop is not possible. */
3731  loader->max_message_unix_fds = 1024;
3732 
3733  if (!_dbus_string_init (&loader->data))
3734  {
3735  dbus_free (loader);
3736  return NULL;
3737  }
3738 
3739  /* preallocate the buffer for speed, ignore failure */
3741  _dbus_string_set_length (&loader->data, 0);
3742 
3743 #ifdef HAVE_UNIX_FD_PASSING
3744  loader->unix_fds = NULL;
3745  loader->n_unix_fds = loader->n_unix_fds_allocated = 0;
3746  loader->unix_fds_outstanding = FALSE;
3747 #endif
3748 
3749  return loader;
3750 }
3751 
3760 {
3761  loader->refcount += 1;
3762 
3763  return loader;
3764 }
3765 
3772 void
3774 {
3775  loader->refcount -= 1;
3776  if (loader->refcount == 0)
3777  {
3778 #ifdef HAVE_UNIX_FD_PASSING
3779  close_unix_fds(loader->unix_fds, &loader->n_unix_fds);
3780  dbus_free(loader->unix_fds);
3781 #endif
3782  _dbus_list_foreach (&loader->messages,
3784  NULL);
3785  _dbus_list_clear (&loader->messages);
3786  _dbus_string_free (&loader->data);
3787  dbus_free (loader);
3788  }
3789 }
3790 
3809 void
3811  DBusString **buffer)
3812 {
3813  _dbus_assert (!loader->buffer_outstanding);
3814 
3815  *buffer = &loader->data;
3816 
3817  loader->buffer_outstanding = TRUE;
3818 }
3819 
3830 void
3832  DBusString *buffer,
3833  int bytes_read)
3834 {
3835  _dbus_assert (loader->buffer_outstanding);
3836  _dbus_assert (buffer == &loader->data);
3837 
3838  loader->buffer_outstanding = FALSE;
3839 }
3840 
3853  int **fds,
3854  unsigned *max_n_fds)
3855 {
3856 #ifdef HAVE_UNIX_FD_PASSING
3857  _dbus_assert (!loader->unix_fds_outstanding);
3858 
3859  /* Allocate space where we can put the fds we read. We allocate
3860  space for max_message_unix_fds since this is an
3861  upper limit how many fds can be received within a single
3862  message. Since SCM_RIGHTS doesn't allow a reallocate+retry logic
3863  we are allocating the maximum possible array size right from the
3864  beginning. This sucks a bit, however unless SCM_RIGHTS is fixed
3865  there is no better way. */
3866 
3867  if (loader->n_unix_fds_allocated < loader->max_message_unix_fds)
3868  {
3869  int *a = dbus_realloc(loader->unix_fds,
3870  loader->max_message_unix_fds * sizeof(loader->unix_fds[0]));
3871 
3872  if (!a)
3873  return FALSE;
3874 
3875  loader->unix_fds = a;
3876  loader->n_unix_fds_allocated = loader->max_message_unix_fds;
3877  }
3878 
3879  *fds = loader->unix_fds + loader->n_unix_fds;
3880  *max_n_fds = loader->n_unix_fds_allocated - loader->n_unix_fds;
3881 
3882  loader->unix_fds_outstanding = TRUE;
3883  return TRUE;
3884 #else
3885  _dbus_assert_not_reached("Platform doesn't support unix fd passing");
3886  return FALSE;
3887 #endif
3888 }
3889 
3900 void
3902  int *fds,
3903  unsigned n_fds)
3904 {
3905 #ifdef HAVE_UNIX_FD_PASSING
3906  _dbus_assert(loader->unix_fds_outstanding);
3907  _dbus_assert(loader->unix_fds + loader->n_unix_fds == fds);
3908  _dbus_assert(loader->n_unix_fds + n_fds <= loader->n_unix_fds_allocated);
3909 
3910  loader->n_unix_fds += n_fds;
3911  loader->unix_fds_outstanding = FALSE;
3912 #else
3913  _dbus_assert_not_reached("Platform doesn't support unix fd passing");
3914 #endif
3915 }
3916 
3917 /*
3918  * FIXME when we move the header out of the buffer, that memmoves all
3919  * buffered messages. Kind of crappy.
3920  *
3921  * Also we copy the header and body, which is kind of crappy. To
3922  * avoid this, we have to allow header and body to be in a single
3923  * memory block, which is good for messages we read and bad for
3924  * messages we are creating. But we could move_len() the buffer into
3925  * this single memory block, and move_len() will just swap the buffers
3926  * if you're moving the entire buffer replacing the dest string.
3927  *
3928  * We could also have the message loader tell the transport how many
3929  * bytes to read; so it would first ask for some arbitrary number like
3930  * 256, then if the message was incomplete it would use the
3931  * header/body len to ask for exactly the size of the message (or
3932  * blocks the size of a typical kernel buffer for the socket). That
3933  * way we don't get trailing bytes in the buffer that have to be
3934  * memmoved. Though I suppose we also don't have a chance of reading a
3935  * bunch of small messages at once, so the optimization may be stupid.
3936  *
3937  * Another approach would be to keep a "start" index into
3938  * loader->data and only delete it occasionally, instead of after
3939  * each message is loaded.
3940  *
3941  * load_message() returns FALSE if not enough memory OR the loader was corrupted
3942  */
3943 static dbus_bool_t
3944 load_message (DBusMessageLoader *loader,
3945  DBusMessage *message,
3946  int byte_order,
3947  int fields_array_len,
3948  int header_len,
3949  int body_len)
3950 {
3951  dbus_bool_t oom;
3952  DBusValidity validity;
3953  const DBusString *type_str;
3954  int type_pos;
3955  DBusValidationMode mode;
3956  dbus_uint32_t n_unix_fds = 0;
3957 
3958  mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
3959 
3960  oom = FALSE;
3961 
3962 #if 0
3963  _dbus_verbose_bytes_of_string (&loader->data, 0, header_len /* + body_len */);
3964 #endif
3965 
3966  /* 1. VALIDATE AND COPY OVER HEADER */
3967  _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
3968  _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
3969 
3970  if (!_dbus_header_load (&message->header,
3971  mode,
3972  &validity,
3973  byte_order,
3974  fields_array_len,
3975  header_len,
3976  body_len,
3977  &loader->data, 0,
3978  _dbus_string_get_length (&loader->data)))
3979  {
3980  _dbus_verbose ("Failed to load header for new message code %d\n", validity);
3981 
3982  /* assert here so we can catch any code that still uses DBUS_VALID to indicate
3983  oom errors. They should use DBUS_VALIDITY_UNKNOWN_OOM_ERROR instead */
3984  _dbus_assert (validity != DBUS_VALID);
3985 
3986  if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
3987  oom = TRUE;
3988  else
3989  {
3990  loader->corrupted = TRUE;
3991  loader->corruption_reason = validity;
3992  }
3993  goto failed;
3994  }
3995 
3996  _dbus_assert (validity == DBUS_VALID);
3997 
3998  message->byte_order = byte_order;
3999 
4000  /* 2. VALIDATE BODY */
4001  if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
4002  {
4003  get_const_signature (&message->header, &type_str, &type_pos);
4004 
4005  /* Because the bytes_remaining arg is NULL, this validates that the
4006  * body is the right length
4007  */
4008  validity = _dbus_validate_body_with_reason (type_str,
4009  type_pos,
4010  byte_order,
4011  NULL,
4012  &loader->data,
4013  header_len,
4014  body_len);
4015  if (validity != DBUS_VALID)
4016  {
4017  _dbus_verbose ("Failed to validate message body code %d\n", validity);
4018 
4019  loader->corrupted = TRUE;
4020  loader->corruption_reason = validity;
4021 
4022  goto failed;
4023  }
4024  }
4025 
4026  /* 3. COPY OVER UNIX FDS */
4030  &n_unix_fds);
4031 
4032 #ifdef HAVE_UNIX_FD_PASSING
4033 
4034  if (n_unix_fds > loader->n_unix_fds)
4035  {
4036  _dbus_verbose("Message contains references to more unix fds than were sent %u != %u\n",
4037  n_unix_fds, loader->n_unix_fds);
4038 
4039  loader->corrupted = TRUE;
4040  loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4041  goto failed;
4042  }
4043 
4044  /* If this was a recycled message there might still be
4045  some memory allocated for the fds */
4046  dbus_free(message->unix_fds);
4047 
4048  if (n_unix_fds > 0)
4049  {
4050  message->unix_fds = _dbus_memdup(loader->unix_fds, n_unix_fds * sizeof(message->unix_fds[0]));
4051  if (message->unix_fds == NULL)
4052  {
4053  _dbus_verbose ("Failed to allocate file descriptor array\n");
4054  oom = TRUE;
4055  goto failed;
4056  }
4057 
4058  message->n_unix_fds_allocated = message->n_unix_fds = n_unix_fds;
4059  loader->n_unix_fds -= n_unix_fds;
4060  memmove(loader->unix_fds + n_unix_fds, loader->unix_fds, loader->n_unix_fds);
4061  }
4062  else
4063  message->unix_fds = NULL;
4064 
4065 #else
4066 
4067  if (n_unix_fds > 0)
4068  {
4069  _dbus_verbose ("Hmm, message claims to come with file descriptors "
4070  "but that's not supported on our platform, disconnecting.\n");
4071 
4072  loader->corrupted = TRUE;
4073  loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4074  goto failed;
4075  }
4076 
4077 #endif
4078 
4079  /* 3. COPY OVER BODY AND QUEUE MESSAGE */
4080 
4081  if (!_dbus_list_append (&loader->messages, message))
4082  {
4083  _dbus_verbose ("Failed to append new message to loader queue\n");
4084  oom = TRUE;
4085  goto failed;
4086  }
4087 
4088  _dbus_assert (_dbus_string_get_length (&message->body) == 0);
4090  (header_len + body_len));
4091 
4092  if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
4093  {
4094  _dbus_verbose ("Failed to move body into new message\n");
4095  oom = TRUE;
4096  goto failed;
4097  }
4098 
4099  _dbus_string_delete (&loader->data, 0, header_len + body_len);
4100 
4101  /* don't waste more than 2k of memory */
4102  _dbus_string_compact (&loader->data, 2048);
4103 
4104  _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
4105  _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
4106 
4107  _dbus_verbose ("Loaded message %p\n", message);
4108 
4109  _dbus_assert (!oom);
4110  _dbus_assert (!loader->corrupted);
4111  _dbus_assert (loader->messages != NULL);
4112  _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4113 
4114  return TRUE;
4115 
4116  failed:
4117 
4118  /* Clean up */
4119 
4120  /* does nothing if the message isn't in the list */
4121  _dbus_list_remove_last (&loader->messages, message);
4122 
4123  if (oom)
4124  _dbus_assert (!loader->corrupted);
4125  else
4126  _dbus_assert (loader->corrupted);
4127 
4129 
4130  return FALSE;
4131 }
4132 
4149 {
4150  while (!loader->corrupted &&
4152  {
4153  DBusValidity validity;
4154  int byte_order, fields_array_len, header_len, body_len;
4155 
4157  &validity,
4158  &byte_order,
4159  &fields_array_len,
4160  &header_len,
4161  &body_len,
4162  &loader->data, 0,
4163  _dbus_string_get_length (&loader->data)))
4164  {
4165  DBusMessage *message;
4166 
4167  _dbus_assert (validity == DBUS_VALID);
4168 
4169  message = dbus_message_new_empty_header ();
4170  if (message == NULL)
4171  return FALSE;
4172 
4173  if (!load_message (loader, message,
4174  byte_order, fields_array_len,
4175  header_len, body_len))
4176  {
4177  dbus_message_unref (message);
4178  /* load_message() returns false if corrupted or OOM; if
4179  * corrupted then return TRUE for not OOM
4180  */
4181  return loader->corrupted;
4182  }
4183 
4184  _dbus_assert (loader->messages != NULL);
4185  _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4186  }
4187  else
4188  {
4189  _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
4190  validity);
4191  if (validity != DBUS_VALID)
4192  {
4193  loader->corrupted = TRUE;
4194  loader->corruption_reason = validity;
4195  }
4196  return TRUE;
4197  }
4198  }
4199 
4200  return TRUE;
4201 }
4202 
4210 DBusMessage*
4212 {
4213  if (loader->messages)
4214  return loader->messages->data;
4215  else
4216  return NULL;
4217 }
4218 
4227 DBusMessage*
4229 {
4230  return _dbus_list_pop_first (&loader->messages);
4231 }
4232 
4241 DBusList*
4243 {
4244  return _dbus_list_pop_first_link (&loader->messages);
4245 }
4246 
4253 void
4255  DBusList *link)
4256 {
4257  _dbus_list_prepend_link (&loader->messages, link);
4258 }
4259 
4271 {
4272  _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
4273  (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
4274  return loader->corrupted;
4275 }
4276 
4285 {
4286  _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
4287  (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
4288 
4289  return loader->corruption_reason;
4290 }
4291 
4298 void
4300  long size)
4301 {
4302  if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
4303  {
4304  _dbus_verbose ("clamping requested max message size %ld to %d\n",
4307  }
4308  loader->max_message_size = size;
4309 }
4310 
4317 long
4319 {
4320  return loader->max_message_size;
4321 }
4322 
4329 void
4331  long n)
4332 {
4334  {
4335  _dbus_verbose ("clamping requested max message unix_fds %ld to %d\n",
4338  }
4339  loader->max_message_unix_fds = n;
4340 }
4341 
4348 long
4350 {
4351  return loader->max_message_unix_fds;
4352 }
4353 
4354 static DBusDataSlotAllocator slot_allocator;
4355 _DBUS_DEFINE_GLOBAL_LOCK (message_slots);
4356 
4373 {
4374  return _dbus_data_slot_allocator_alloc (&slot_allocator,
4375  &_DBUS_LOCK_NAME (message_slots),
4376  slot_p);
4377 }
4378 
4390 void
4392 {
4393  _dbus_return_if_fail (*slot_p >= 0);
4394 
4395  _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
4396 }
4397 
4413  dbus_int32_t slot,
4414  void *data,
4415  DBusFreeFunction free_data_func)
4416 {
4417  DBusFreeFunction old_free_func;
4418  void *old_data;
4419  dbus_bool_t retval;
4420 
4421  _dbus_return_val_if_fail (message != NULL, FALSE);
4422  _dbus_return_val_if_fail (slot >= 0, FALSE);
4423 
4424  retval = _dbus_data_slot_list_set (&slot_allocator,
4425  &message->slot_list,
4426  slot, data, free_data_func,
4427  &old_free_func, &old_data);
4428 
4429  if (retval)
4430  {
4431  /* Do the actual free outside the message lock */
4432  if (old_free_func)
4433  (* old_free_func) (old_data);
4434  }
4435 
4436  return retval;
4437 }
4438 
4447 void*
4449  dbus_int32_t slot)
4450 {
4451  void *res;
4452 
4453  _dbus_return_val_if_fail (message != NULL, NULL);
4454 
4455  res = _dbus_data_slot_list_get (&slot_allocator,
4456  &message->slot_list,
4457  slot);
4458 
4459  return res;
4460 }
4461 
4475 int
4476 dbus_message_type_from_string (const char *type_str)
4477 {
4478  if (strcmp (type_str, "method_call") == 0)
4480  if (strcmp (type_str, "method_return") == 0)
4482  else if (strcmp (type_str, "signal") == 0)
4483  return DBUS_MESSAGE_TYPE_SIGNAL;
4484  else if (strcmp (type_str, "error") == 0)
4485  return DBUS_MESSAGE_TYPE_ERROR;
4486  else
4488 }
4489 
4503 const char *
4505 {
4506  switch (type)
4507  {
4509  return "method_call";
4511  return "method_return";
4513  return "signal";
4515  return "error";
4516  default:
4517  return "invalid";
4518  }
4519 }
4520 
4535  char **marshalled_data_p,
4536  int *len_p)
4537 {
4538  DBusString tmp;
4539  dbus_bool_t was_locked;
4540 
4541  _dbus_return_val_if_fail (msg != NULL, FALSE);
4542  _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
4543  _dbus_return_val_if_fail (len_p != NULL, FALSE);
4544 
4545  if (!_dbus_string_init (&tmp))
4546  return FALSE;
4547 
4548  /* Ensure the message is locked, to ensure the length header is filled in. */
4549  was_locked = msg->locked;
4550 
4551  if (!was_locked)
4552  dbus_message_lock (msg);
4553 
4554  if (!_dbus_string_copy (&(msg->header.data), 0, &tmp, 0))
4555  goto fail;
4556 
4557  *len_p = _dbus_string_get_length (&tmp);
4558 
4559  if (!_dbus_string_copy (&(msg->body), 0, &tmp, *len_p))
4560  goto fail;
4561 
4562  *len_p = _dbus_string_get_length (&tmp);
4563 
4564  if (!_dbus_string_steal_data (&tmp, marshalled_data_p))
4565  goto fail;
4566 
4567  _dbus_string_free (&tmp);
4568 
4569  if (!was_locked)
4570  msg->locked = FALSE;
4571 
4572  return TRUE;
4573 
4574  fail:
4575  _dbus_string_free (&tmp);
4576 
4577  if (!was_locked)
4578  msg->locked = FALSE;
4579 
4580  return FALSE;
4581 }
4582 
4595 DBusMessage *
4596 dbus_message_demarshal (const char *str,
4597  int len,
4598  DBusError *error)
4599 {
4600  DBusMessageLoader *loader;
4601  DBusString *buffer;
4602  DBusMessage *msg;
4603 
4604  _dbus_return_val_if_fail (str != NULL, NULL);
4605 
4606  loader = _dbus_message_loader_new ();
4607 
4608  if (loader == NULL)
4609  return NULL;
4610 
4611  _dbus_message_loader_get_buffer (loader, &buffer);
4612  _dbus_string_append_len (buffer, str, len);
4613  _dbus_message_loader_return_buffer (loader, buffer, len);
4614 
4616  goto fail_oom;
4617 
4619  goto fail_corrupt;
4620 
4621  msg = _dbus_message_loader_pop_message (loader);
4622 
4623  if (!msg)
4624  goto fail_oom;
4625 
4626  _dbus_message_loader_unref (loader);
4627  return msg;
4628 
4629  fail_corrupt:
4630  dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted (%s)",
4631  _dbus_validity_to_error_message (loader->corruption_reason));
4632  _dbus_message_loader_unref (loader);
4633  return NULL;
4634 
4635  fail_oom:
4636  _DBUS_SET_OOM (error);
4637  _dbus_message_loader_unref (loader);
4638  return NULL;
4639 }
4640 
4654 int
4656  int len)
4657 {
4658  DBusString str;
4659  int byte_order, fields_array_len, header_len, body_len;
4660  DBusValidity validity = DBUS_VALID;
4661  int have_message;
4662 
4663  if (!buf || len < DBUS_MINIMUM_HEADER_SIZE)
4664  return 0;
4665 
4666  if (len > DBUS_MAXIMUM_MESSAGE_LENGTH)
4668  _dbus_string_init_const_len (&str, buf, len);
4669 
4670  validity = DBUS_VALID;
4671  have_message
4673  &validity, &byte_order,
4674  &fields_array_len,
4675  &header_len,
4676  &body_len,
4677  &str, 0,
4678  len);
4679  _dbus_string_free (&str);
4680 
4681  if (validity == DBUS_VALID)
4682  {
4683  _dbus_assert(have_message);
4684  return header_len + body_len;
4685  }
4686  else
4687  {
4688  return -1; /* broken! */
4689  }
4690 }
4691 
4694 /* tests in dbus-message-util.c */