D-Bus  1.12.16
dbus-message.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-message.c DBusMessage object
3  *
4  * Copyright (C) 2002, 2003, 2004, 2005 Red Hat Inc.
5  * Copyright (C) 2002, 2003 CodeFactory AB
6  *
7  * Licensed under the Academic Free License version 2.1
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 #include <config.h>
26 #include "dbus-internals.h"
27 #include "dbus-marshal-recursive.h"
28 #include "dbus-marshal-validate.h"
29 #include "dbus-marshal-byteswap.h"
30 #include "dbus-marshal-header.h"
31 #include "dbus-signature.h"
32 #include "dbus-message-private.h"
33 #include "dbus-object-tree.h"
34 #include "dbus-memory.h"
35 #include "dbus-list.h"
36 #include "dbus-threads-internal.h"
37 #ifdef HAVE_UNIX_FD_PASSING
38 #include "dbus-sysdeps.h"
39 #include "dbus-sysdeps-unix.h"
40 #endif
41 
42 #include <string.h>
43 #include <kysdk/kysdk-base/libkylog.h>
44 #include <kysdk/kysdk-base/cstring-extension.h>
45 // #include <kysdk/kysdk-base/libkylog.h>
46 #include <kysdk/kysdk-base/libkyconf.h>
47 #include <unistd.h>
48 #include <stdio.h>
49 #include <pwd.h>
50 #include <ctype.h>
51 #include <errno.h>
52 
53 #define LINEMAX 1024
54 
55 #define _DBUS_TYPE_IS_STRINGLIKE(type) \
56  (type == DBUS_TYPE_STRING || type == DBUS_TYPE_SIGNATURE || \
57  type == DBUS_TYPE_OBJECT_PATH)
58 
59 static void dbus_message_finalize (DBusMessage *message);
60 
71 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
72 static dbus_bool_t
73 _dbus_enable_message_cache (void)
74 {
75  static int enabled = -1;
76 
77  if (enabled < 0)
78  {
79  const char *s = _dbus_getenv ("DBUS_MESSAGE_CACHE");
80 
81  enabled = TRUE;
82 
83  if (s && *s)
84  {
85  if (*s == '0')
86  enabled = FALSE;
87  else if (*s == '1')
88  enabled = TRUE;
89  else
90  _dbus_warn ("DBUS_MESSAGE_CACHE should be 0 or 1 if set, not '%s'",
91  s);
92  }
93  }
94 
95  return enabled;
96 }
97 #else
98  /* constant expression, should be optimized away */
99 # define _dbus_enable_message_cache() (TRUE)
100 #endif
101 
102 #ifndef _dbus_message_trace_ref
103 void
104 _dbus_message_trace_ref (DBusMessage *message,
105  int old_refcount,
106  int new_refcount,
107  const char *why)
108 {
109  static int enabled = -1;
110 
111  _dbus_trace_ref ("DBusMessage", message, old_refcount, new_refcount, why,
112  "DBUS_MESSAGE_TRACE", &enabled);
113 }
114 #endif
115 
116 /* Not thread locked, but strictly const/read-only so should be OK
117  */
119 _DBUS_STRING_DEFINE_STATIC(_dbus_empty_signature_str, "");
120 
121 /* these have wacky values to help trap uninitialized iterators;
122  * but has to fit in 3 bits
123  */
124 enum {
125  DBUS_MESSAGE_ITER_TYPE_READER = 3,
126  DBUS_MESSAGE_ITER_TYPE_WRITER = 7
127 };
128 
131 
138 {
141  dbus_uint32_t iter_type : 3;
142  dbus_uint32_t sig_refcount : 8;
143  union
144  {
147  } u;
148 };
149 
155 typedef struct
156 {
157  void *dummy1;
158  void *dummy2;
159  dbus_uint32_t dummy3;
160  int dummy4;
161  int dummy5;
162  int dummy6;
163  int dummy7;
164  int dummy8;
165  int dummy9;
166  int dummy10;
167  int dummy11;
168  int pad1;
169  int pad2;
170  void *pad3;
172 
173 static void
174 get_const_signature (DBusHeader *header,
175  const DBusString **type_str_p,
176  int *type_pos_p)
177 {
178  if (_dbus_header_get_field_raw (header,
180  type_str_p,
181  type_pos_p))
182  {
183  *type_pos_p += 1; /* skip the signature length which is 1 byte */
184  }
185  else
186  {
187  *type_str_p = &_dbus_empty_signature_str;
188  *type_pos_p = 0;
189  }
190 }
191 
197 static void
198 _dbus_message_byteswap (DBusMessage *message)
199 {
200  const DBusString *type_str;
201  int type_pos;
202  char byte_order;
203 
204  byte_order = _dbus_header_get_byte_order (&message->header);
205 
206  if (byte_order == DBUS_COMPILER_BYTE_ORDER)
207  return;
208 
209  _dbus_verbose ("Swapping message into compiler byte order\n");
210 
211  get_const_signature (&message->header, &type_str, &type_pos);
212 
213  _dbus_marshal_byteswap (type_str, type_pos,
214  byte_order,
215  DBUS_COMPILER_BYTE_ORDER,
216  &message->body, 0);
217 
218  _dbus_header_byteswap (&message->header, DBUS_COMPILER_BYTE_ORDER);
220  DBUS_COMPILER_BYTE_ORDER);
221 }
222 
229 #define ensure_byte_order(message) _dbus_message_byteswap (message)
230 
241 void
243  const DBusString **header,
244  const DBusString **body)
245 {
246  _dbus_assert (message->locked);
247 
248  *header = &message->header.data;
249  *body = &message->body;
250 }
251 
262  const int **fds,
263  unsigned *n_fds)
264 {
265  _dbus_assert (message->locked);
266 
267 #ifdef HAVE_UNIX_FD_PASSING
268  *fds = message->unix_fds;
269  *n_fds = message->n_unix_fds;
270 #else
271  *fds = NULL;
272  *n_fds = 0;
273 #endif
274 }
275 
287 void
289  dbus_uint32_t serial)
290 {
291  _dbus_return_if_fail (message != NULL);
292  _dbus_return_if_fail (!message->locked);
293 
294  _dbus_header_set_serial (&message->header, serial);
295 }
296 
313 void
315  DBusList *link)
316 {
317  /* right now we don't recompute the delta when message
318  * size changes, and that's OK for current purposes
319  * I think, but could be important to change later.
320  * Do recompute it whenever there are no outstanding counters,
321  * since it's basically free.
322  */
323  if (message->counters == NULL)
324  {
325  message->size_counter_delta =
326  _dbus_string_get_length (&message->header.data) +
327  _dbus_string_get_length (&message->body);
328 
329 #ifdef HAVE_UNIX_FD_PASSING
330  message->unix_fd_counter_delta = message->n_unix_fds;
331 #endif
332 
333 #if 0
334  _dbus_verbose ("message has size %ld\n",
335  message->size_counter_delta);
336 #endif
337  }
338 
339  _dbus_list_append_link (&message->counters, link);
340 
342 
343 #ifdef HAVE_UNIX_FD_PASSING
344  _dbus_counter_adjust_unix_fd (link->data, message->unix_fd_counter_delta);
345 #endif
346 }
347 
364  DBusCounter *counter)
365 {
366  DBusList *link;
367 
368  link = _dbus_list_alloc_link (counter);
369  if (link == NULL)
370  return FALSE;
371 
372  _dbus_counter_ref (counter);
373  _dbus_message_add_counter_link (message, link);
374 
375  return TRUE;
376 }
377 
385 void
387  DBusCounter *counter)
388 {
389  DBusList *link;
390 
391  link = _dbus_list_find_last (&message->counters,
392  counter);
393  _dbus_assert (link != NULL);
394 
395  _dbus_list_remove_link (&message->counters, link);
396 
397  _dbus_counter_adjust_size (counter, - message->size_counter_delta);
398 
399 #ifdef HAVE_UNIX_FD_PASSING
400  _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
401 #endif
402 
403  _dbus_counter_notify (counter);
404  _dbus_counter_unref (counter);
405 }
406 
417 void
419 {
420  if (!message->locked)
421  {
423  _dbus_string_get_length (&message->body));
424 
425  /* must have a signature if you have a body */
426  _dbus_assert (_dbus_string_get_length (&message->body) == 0 ||
427  dbus_message_get_signature (message) != NULL);
428 
429  message->locked = TRUE;
430  }
431 }
432 
433 static dbus_bool_t
434 set_or_delete_string_field (DBusMessage *message,
435  int field,
436  int typecode,
437  const char *value)
438 {
439  if (value == NULL)
440  return _dbus_header_delete_field (&message->header, field);
441  else
442  return _dbus_header_set_field_basic (&message->header,
443  field,
444  typecode,
445  &value);
446 }
447 
448 /* Message Cache
449  *
450  * We cache some DBusMessage to reduce the overhead of allocating
451  * them. In my profiling this consistently made about an 8%
452  * difference. It avoids the malloc for the message, the malloc for
453  * the slot list, the malloc for the header string and body string,
454  * and the associated free() calls. It does introduce another global
455  * lock which could be a performance issue in certain cases.
456  *
457  * For the echo client/server the round trip time goes from around
458  * .000077 to .000069 with the message cache on my laptop. The sysprof
459  * change is as follows (numbers are cumulative percentage):
460  *
461  * with message cache implemented as array as it is now (0.000069 per):
462  * new_empty_header 1.46
463  * mutex_lock 0.56 # i.e. _DBUS_LOCK(message_cache)
464  * mutex_unlock 0.25
465  * self 0.41
466  * unref 2.24
467  * self 0.68
468  * list_clear 0.43
469  * mutex_lock 0.33 # i.e. _DBUS_LOCK(message_cache)
470  * mutex_unlock 0.25
471  *
472  * with message cache implemented as list (0.000070 per roundtrip):
473  * new_empty_header 2.72
474  * list_pop_first 1.88
475  * unref 3.3
476  * list_prepend 1.63
477  *
478  * without cache (0.000077 per roundtrip):
479  * new_empty_header 6.7
480  * string_init_preallocated 3.43
481  * dbus_malloc 2.43
482  * dbus_malloc0 2.59
483  *
484  * unref 4.02
485  * string_free 1.82
486  * dbus_free 1.63
487  * dbus_free 0.71
488  *
489  * If you implement the message_cache with a list, the primary reason
490  * it's slower is that you add another thread lock (on the DBusList
491  * mempool).
492  */
493 
495 #define MAX_MESSAGE_SIZE_TO_CACHE 10 * _DBUS_ONE_KILOBYTE
496 
498 #define MAX_MESSAGE_CACHE_SIZE 5
499 
500 /* Protected by _DBUS_LOCK (message_cache) */
501 static DBusMessage *message_cache[MAX_MESSAGE_CACHE_SIZE];
502 static int message_cache_count = 0;
503 static dbus_bool_t message_cache_shutdown_registered = FALSE;
504 
505 static void
506 dbus_message_cache_shutdown (void *data)
507 {
508  int i;
509 
510  if (!_DBUS_LOCK (message_cache))
511  _dbus_assert_not_reached ("we would have initialized global locks "
512  "before registering a shutdown function");
513 
514  i = 0;
515  while (i < MAX_MESSAGE_CACHE_SIZE)
516  {
517  if (message_cache[i])
518  dbus_message_finalize (message_cache[i]);
519 
520  ++i;
521  }
522 
523  message_cache_count = 0;
524  message_cache_shutdown_registered = FALSE;
525 
526  _DBUS_UNLOCK (message_cache);
527 }
528 
536 static DBusMessage*
537 dbus_message_get_cached (void)
538 {
539  DBusMessage *message;
540  int i;
541 
542  message = NULL;
543 
544  if (!_DBUS_LOCK (message_cache))
545  {
546  /* we'd have initialized global locks before caching anything,
547  * so there can't be anything in the cache */
548  return NULL;
549  }
550 
551  _dbus_assert (message_cache_count >= 0);
552 
553  if (message_cache_count == 0)
554  {
555  _DBUS_UNLOCK (message_cache);
556  return NULL;
557  }
558 
559  /* This is not necessarily true unless count > 0, and
560  * message_cache is uninitialized until the shutdown is
561  * registered
562  */
563  _dbus_assert (message_cache_shutdown_registered);
564 
565  i = 0;
566  while (i < MAX_MESSAGE_CACHE_SIZE)
567  {
568  if (message_cache[i])
569  {
570  message = message_cache[i];
571  message_cache[i] = NULL;
572  message_cache_count -= 1;
573  break;
574  }
575  ++i;
576  }
577  _dbus_assert (message_cache_count >= 0);
579  _dbus_assert (message != NULL);
580 
581  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
582 
583  _dbus_assert (message->counters == NULL);
584 
585  _DBUS_UNLOCK (message_cache);
586 
587  return message;
588 }
589 
590 #ifdef HAVE_UNIX_FD_PASSING
591 static void
592 close_unix_fds(int *fds, unsigned *n_fds)
593 {
594  DBusError e;
595  unsigned int i;
596 
597  if (*n_fds <= 0)
598  return;
599 
600  dbus_error_init(&e);
601 
602  for (i = 0; i < *n_fds; i++)
603  {
604  if (!_dbus_close(fds[i], &e))
605  {
606  _dbus_warn("Failed to close file descriptor: %s", e.message);
607  dbus_error_free(&e);
608  }
609  }
610 
611  *n_fds = 0;
612 
613  /* We don't free the array here, in case we can recycle it later */
614 }
615 #endif
616 
617 static void
618 free_counter (void *element,
619  void *data)
620 {
621  DBusCounter *counter = element;
622  DBusMessage *message = data;
623 
624  _dbus_counter_adjust_size (counter, - message->size_counter_delta);
625 #ifdef HAVE_UNIX_FD_PASSING
626  _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
627 #endif
628 
629  _dbus_counter_notify (counter);
630  _dbus_counter_unref (counter);
631 }
632 
638 static void
639 dbus_message_cache_or_finalize (DBusMessage *message)
640 {
641  dbus_bool_t was_cached;
642  int i;
643 
644  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
645 
646  /* This calls application code and has to be done first thing
647  * without holding the lock
648  */
650 
651  _dbus_list_foreach (&message->counters,
652  free_counter, message);
653  _dbus_list_clear (&message->counters);
654 
655 #ifdef HAVE_UNIX_FD_PASSING
656  close_unix_fds(message->unix_fds, &message->n_unix_fds);
657 #endif
658 
659  was_cached = FALSE;
660 
661  if (!_DBUS_LOCK (message_cache))
662  {
663  /* The only way to get a non-null message goes through
664  * dbus_message_get_cached() which takes the lock. */
665  _dbus_assert_not_reached ("we would have initialized global locks "
666  "the first time we constructed a message");
667  }
668 
669  if (!message_cache_shutdown_registered)
670  {
671  _dbus_assert (message_cache_count == 0);
672 
673  if (!_dbus_register_shutdown_func (dbus_message_cache_shutdown, NULL))
674  goto out;
675 
676  i = 0;
677  while (i < MAX_MESSAGE_CACHE_SIZE)
678  {
679  message_cache[i] = NULL;
680  ++i;
681  }
682 
683  message_cache_shutdown_registered = TRUE;
684  }
685 
686  _dbus_assert (message_cache_count >= 0);
687 
688  if (!_dbus_enable_message_cache ())
689  goto out;
690 
691  if ((_dbus_string_get_length (&message->header.data) +
692  _dbus_string_get_length (&message->body)) >
694  goto out;
695 
696  if (message_cache_count >= MAX_MESSAGE_CACHE_SIZE)
697  goto out;
698 
699  /* Find empty slot */
700  i = 0;
701  while (message_cache[i] != NULL)
702  ++i;
703 
705 
706  _dbus_assert (message_cache[i] == NULL);
707  message_cache[i] = message;
708  message_cache_count += 1;
709  was_cached = TRUE;
710 #ifndef DBUS_DISABLE_CHECKS
711  message->in_cache = TRUE;
712 #endif
713 
714  out:
715  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
716 
717  _DBUS_UNLOCK (message_cache);
718 
719  if (!was_cached)
720  dbus_message_finalize (message);
721 }
722 
723 /*
724  * Arrange for iter to be something that _dbus_message_iter_check() would
725  * reject as not a valid iterator.
726  */
727 static void
728 _dbus_message_real_iter_zero (DBusMessageRealIter *iter)
729 {
730  _dbus_assert (iter != NULL);
731  _DBUS_ZERO (*iter);
732  /* NULL is not, strictly speaking, guaranteed to be all-bits-zero */
733  iter->message = NULL;
734 }
735 
741 void
743 {
744  _dbus_return_if_fail (iter != NULL);
745  _dbus_message_real_iter_zero ((DBusMessageRealIter *) iter);
746 }
747 
748 static dbus_bool_t
749 _dbus_message_real_iter_is_zeroed (DBusMessageRealIter *iter)
750 {
751  return (iter != NULL && iter->message == NULL && iter->changed_stamp == 0 &&
752  iter->iter_type == 0 && iter->sig_refcount == 0);
753 }
754 
755 #if defined(DBUS_ENABLE_CHECKS) || defined(DBUS_ENABLE_ASSERT)
756 static dbus_bool_t
757 _dbus_message_iter_check (DBusMessageRealIter *iter)
758 {
759  char byte_order;
760 
761  if (iter == NULL)
762  {
763  _dbus_warn_check_failed ("dbus message iterator is NULL");
764  return FALSE;
765  }
766 
767  if (iter->message == NULL || iter->iter_type == 0)
768  {
769  _dbus_warn_check_failed ("dbus message iterator has already been "
770  "closed, or is uninitialized or corrupt");
771  return FALSE;
772  }
773 
774  byte_order = _dbus_header_get_byte_order (&iter->message->header);
775 
776  if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_READER)
777  {
778  if (iter->u.reader.byte_order != byte_order)
779  {
780  _dbus_warn_check_failed ("dbus message changed byte order since iterator was created");
781  return FALSE;
782  }
783  /* because we swap the message into compiler order when you init an iter */
784  _dbus_assert (iter->u.reader.byte_order == DBUS_COMPILER_BYTE_ORDER);
785  }
786  else if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER)
787  {
788  if (iter->u.writer.byte_order != byte_order)
789  {
790  _dbus_warn_check_failed ("dbus message changed byte order since append iterator was created");
791  return FALSE;
792  }
793  /* because we swap the message into compiler order when you init an iter */
794  _dbus_assert (iter->u.writer.byte_order == DBUS_COMPILER_BYTE_ORDER);
795  }
796  else
797  {
798  _dbus_warn_check_failed ("dbus message iterator looks uninitialized or corrupted");
799  return FALSE;
800  }
801 
802  if (iter->changed_stamp != iter->message->changed_stamp)
803  {
804  _dbus_warn_check_failed ("dbus message iterator invalid because the message has been modified (or perhaps the iterator is just uninitialized)");
805  return FALSE;
806  }
807 
808  return TRUE;
809 }
810 #endif /* DBUS_ENABLE_CHECKS || DBUS_ENABLE_ASSERT */
811 
826  DBusError *error,
827  int first_arg_type,
828  va_list var_args)
829 {
831  int spec_type, msg_type, i, j;
832  dbus_bool_t retval;
833  va_list copy_args;
834 
835  _dbus_assert (_dbus_message_iter_check (real));
836 
837  retval = FALSE;
838 
839  spec_type = first_arg_type;
840  i = 0;
841 
842  /* copy var_args first, then we can do another iteration over it to
843  * free memory and close unix fds if parse failed at some point.
844  */
845  DBUS_VA_COPY (copy_args, var_args);
846 
847  while (spec_type != DBUS_TYPE_INVALID)
848  {
849  msg_type = dbus_message_iter_get_arg_type (iter);
850 
851  if (msg_type != spec_type)
852  {
854  "Argument %d is specified to be of type \"%s\", but "
855  "is actually of type \"%s\"\n", i,
856  _dbus_type_to_string (spec_type),
857  _dbus_type_to_string (msg_type));
858 
859  goto out;
860  }
861 
862  if (spec_type == DBUS_TYPE_UNIX_FD)
863  {
864 #ifdef HAVE_UNIX_FD_PASSING
865  DBusBasicValue idx;
866  int *pfd, nfd;
867 
868  pfd = va_arg (var_args, int*);
869  _dbus_assert(pfd);
870 
871  _dbus_type_reader_read_basic(&real->u.reader, &idx);
872 
873  if (idx.u32 >= real->message->n_unix_fds)
874  {
876  "Message refers to file descriptor at index %i,"
877  "but has only %i descriptors attached.\n",
878  idx.u32,
879  real->message->n_unix_fds);
880  goto out;
881  }
882 
883  if ((nfd = _dbus_dup(real->message->unix_fds[idx.u32], error)) < 0)
884  goto out;
885 
886  *pfd = nfd;
887 #else
889  "Platform does not support file desciptor passing.\n");
890  goto out;
891 #endif
892  }
893  else if (dbus_type_is_basic (spec_type))
894  {
895  DBusBasicValue *ptr;
896 
897  ptr = va_arg (var_args, DBusBasicValue*);
898 
899  _dbus_assert (ptr != NULL);
900 
902  ptr);
903  }
904  else if (spec_type == DBUS_TYPE_ARRAY)
905  {
906  int element_type;
907  int spec_element_type;
908  const DBusBasicValue **ptr;
909  int *n_elements_p;
910  DBusTypeReader array;
911 
912  spec_element_type = va_arg (var_args, int);
913  element_type = _dbus_type_reader_get_element_type (&real->u.reader);
914 
915  if (spec_element_type != element_type)
916  {
918  "Argument %d is specified to be an array of \"%s\", but "
919  "is actually an array of \"%s\"\n",
920  i,
921  _dbus_type_to_string (spec_element_type),
922  _dbus_type_to_string (element_type));
923 
924  goto out;
925  }
926 
927  if (dbus_type_is_fixed (spec_element_type) &&
928  element_type != DBUS_TYPE_UNIX_FD)
929  {
930  ptr = va_arg (var_args, const DBusBasicValue**);
931  n_elements_p = va_arg (var_args, int*);
932 
933  _dbus_assert (ptr != NULL);
934  _dbus_assert (n_elements_p != NULL);
935 
936  _dbus_type_reader_recurse (&real->u.reader, &array);
937 
939  (void *) ptr, n_elements_p);
940  }
941  else if (_DBUS_TYPE_IS_STRINGLIKE (spec_element_type))
942  {
943  char ***str_array_p;
944  int n_elements;
945  char **str_array;
946 
947  str_array_p = va_arg (var_args, char***);
948  n_elements_p = va_arg (var_args, int*);
949 
950  _dbus_assert (str_array_p != NULL);
951  _dbus_assert (n_elements_p != NULL);
952 
953  /* Count elements in the array */
954  _dbus_type_reader_recurse (&real->u.reader, &array);
955 
956  n_elements = 0;
958  {
959  ++n_elements;
960  _dbus_type_reader_next (&array);
961  }
962 
963  str_array = dbus_new0 (char*, n_elements + 1);
964  if (str_array == NULL)
965  {
966  _DBUS_SET_OOM (error);
967  goto out;
968  }
969 
970  /* Now go through and dup each string */
971  _dbus_type_reader_recurse (&real->u.reader, &array);
972 
973  j = 0;
974  while (j < n_elements)
975  {
976  const char *s;
978  (void *) &s);
979 
980  str_array[j] = _dbus_strdup (s);
981  if (str_array[j] == NULL)
982  {
983  dbus_free_string_array (str_array);
984  _DBUS_SET_OOM (error);
985  goto out;
986  }
987 
988  ++j;
989 
990  if (!_dbus_type_reader_next (&array))
991  _dbus_assert (j == n_elements);
992  }
993 
995  _dbus_assert (j == n_elements);
996  _dbus_assert (str_array[j] == NULL);
997 
998  *str_array_p = str_array;
999  *n_elements_p = n_elements;
1000  }
1001 #ifndef DBUS_DISABLE_CHECKS
1002  else
1003  {
1004  _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now",
1005  _DBUS_FUNCTION_NAME);
1006  goto out;
1007  }
1008 #endif
1009  }
1010 #ifndef DBUS_DISABLE_CHECKS
1011  else
1012  {
1013  _dbus_warn ("you can only read arrays and basic types with %s for now",
1014  _DBUS_FUNCTION_NAME);
1015  goto out;
1016  }
1017 #endif
1018 
1019  /* how many arguments already handled */
1020  i++;
1021 
1022  spec_type = va_arg (var_args, int);
1023  if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID)
1024  {
1026  "Message has only %d arguments, but more were expected", i);
1027  goto out;
1028  }
1029  }
1030 
1031  retval = TRUE;
1032 
1033  out:
1034  /* there may memory or unix fd leak in the above iteration if parse failed.
1035  * so we have another iteration over copy_args to free memory and close
1036  * unix fds.
1037  */
1038  if (!retval)
1039  {
1040  spec_type = first_arg_type;
1041  j = 0;
1042 
1043  while (j < i)
1044  {
1045  if (spec_type == DBUS_TYPE_UNIX_FD)
1046  {
1047 #ifdef HAVE_UNIX_FD_PASSING
1048  int *pfd;
1049 
1050  pfd = va_arg (copy_args, int *);
1051  _dbus_assert(pfd);
1052  if (*pfd >= 0)
1053  {
1054  _dbus_close (*pfd, NULL);
1055  *pfd = -1;
1056  }
1057 #endif
1058  }
1059  else if (dbus_type_is_basic (spec_type))
1060  {
1061  /* move the index forward */
1062  va_arg (copy_args, DBusBasicValue *);
1063  }
1064  else if (spec_type == DBUS_TYPE_ARRAY)
1065  {
1066  int spec_element_type;
1067 
1068  spec_element_type = va_arg (copy_args, int);
1069  if (dbus_type_is_fixed (spec_element_type))
1070  {
1071  /* move the index forward */
1072  va_arg (copy_args, const DBusBasicValue **);
1073  va_arg (copy_args, int *);
1074  }
1075  else if (_DBUS_TYPE_IS_STRINGLIKE (spec_element_type))
1076  {
1077  char ***str_array_p;
1078 
1079  str_array_p = va_arg (copy_args, char ***);
1080  /* move the index forward */
1081  va_arg (copy_args, int *);
1082  _dbus_assert (str_array_p != NULL);
1083  dbus_free_string_array (*str_array_p);
1084  *str_array_p = NULL;
1085  }
1086  }
1087 
1088  spec_type = va_arg (copy_args, int);
1089  j++;
1090  }
1091  }
1092 
1093  va_end (copy_args);
1094  return retval;
1095 }
1096 
1155 dbus_uint32_t
1157 {
1158  _dbus_return_val_if_fail (message != NULL, 0);
1159 
1160  return _dbus_header_get_serial (&message->header);
1161 }
1162 
1173  dbus_uint32_t reply_serial)
1174 {
1175  DBusBasicValue value;
1176 
1177  _dbus_return_val_if_fail (message != NULL, FALSE);
1178  _dbus_return_val_if_fail (!message->locked, FALSE);
1179  _dbus_return_val_if_fail (reply_serial != 0, FALSE); /* 0 is invalid */
1180 
1181  value.u32 = reply_serial;
1182 
1183  return _dbus_header_set_field_basic (&message->header,
1186  &value);
1187 }
1188 
1195 dbus_uint32_t
1197 {
1198  dbus_uint32_t v_UINT32;
1199 
1200  _dbus_return_val_if_fail (message != NULL, 0);
1201 
1202  if (_dbus_header_get_field_basic (&message->header,
1205  &v_UINT32))
1206  return v_UINT32;
1207  else
1208  return 0;
1209 }
1210 
1211 static void
1212 dbus_message_finalize (DBusMessage *message)
1213 {
1214  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
1215 
1216  /* This calls application callbacks! */
1218 
1219  _dbus_list_foreach (&message->counters,
1220  free_counter, message);
1221  _dbus_list_clear (&message->counters);
1222 
1223  _dbus_header_free (&message->header);
1224  _dbus_string_free (&message->body);
1225 
1226 #ifdef HAVE_UNIX_FD_PASSING
1227  close_unix_fds(message->unix_fds, &message->n_unix_fds);
1228  dbus_free(message->unix_fds);
1229 #endif
1230 
1231  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
1232 
1233  dbus_free (message);
1234 }
1235 
1236 static DBusMessage*
1237 dbus_message_new_empty_header (void)
1238 {
1239  DBusMessage *message;
1240  dbus_bool_t from_cache;
1241 
1242  message = dbus_message_get_cached ();
1243 
1244  if (message != NULL)
1245  {
1246  from_cache = TRUE;
1247  }
1248  else
1249  {
1250  from_cache = FALSE;
1251  message = dbus_new0 (DBusMessage, 1);
1252  if (message == NULL)
1253  return NULL;
1254 #ifndef DBUS_DISABLE_CHECKS
1256 #endif
1257 
1258 #ifdef HAVE_UNIX_FD_PASSING
1259  message->unix_fds = NULL;
1260  message->n_unix_fds_allocated = 0;
1261 #endif
1262  }
1263 
1264  _dbus_atomic_inc (&message->refcount);
1265 
1266  _dbus_message_trace_ref (message, 0, 1, "new_empty_header");
1267 
1268  message->locked = FALSE;
1269 #ifndef DBUS_DISABLE_CHECKS
1270  message->in_cache = FALSE;
1271 #endif
1272  message->counters = NULL;
1273  message->size_counter_delta = 0;
1274  message->changed_stamp = 0;
1275 
1276 #ifdef HAVE_UNIX_FD_PASSING
1277  message->n_unix_fds = 0;
1278  message->n_unix_fds_allocated = 0;
1279  message->unix_fd_counter_delta = 0;
1280 #endif
1281 
1282  if (!from_cache)
1284 
1285  if (from_cache)
1286  {
1287  _dbus_header_reinit (&message->header);
1288  _dbus_string_set_length (&message->body, 0);
1289  }
1290  else
1291  {
1292  if (!_dbus_header_init (&message->header))
1293  {
1294  dbus_free (message);
1295  return NULL;
1296  }
1297 
1298  if (!_dbus_string_init_preallocated (&message->body, 32))
1299  {
1300  _dbus_header_free (&message->header);
1301  dbus_free (message);
1302  return NULL;
1303  }
1304  }
1305 
1306  return message;
1307 }
1308 
1321 DBusMessage*
1322 dbus_message_new (int message_type)
1323 {
1324  DBusMessage *message;
1325 
1326  _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
1327 
1328  message = dbus_message_new_empty_header ();
1329  if (message == NULL)
1330  return NULL;
1331 
1332  if (!_dbus_header_create (&message->header,
1333  DBUS_COMPILER_BYTE_ORDER,
1334  message_type,
1335  NULL, NULL, NULL, NULL, NULL))
1336  {
1337  dbus_message_unref (message);
1338  return NULL;
1339  }
1340 
1341  return message;
1342 }
1343 static int _dbus_message_get_buf_spos (const char *destination, char *configpath, char buf[], char **spos)
1344 {
1345  int pid;
1346  int result;
1347  char cmdline[LINEMAX] = "";
1348  char exe_path[LINEMAX] = "";
1349  char *new_spos;
1350  const char *configdir = "/etc/dbus-1/conf/";
1351 
1352  sprintf(configpath, "%s%s%s", configdir, destination, ".limit");
1353  pid = getpid();
1354  sprintf(exe_path, "/%s/%d/%s", "proc", pid, "exe");
1355  sprintf(cmdline, "/%s/%d/%s", "proc", pid, "cmdline");
1356  klog_debug("当前进程pid:%d\n调用用户:%d\n程序运行exe路径:%s\n程序cmdline命令:%s\n", getpid(), getuid(), exe_path, cmdline);
1357  if (access(exe_path, F_OK))
1358  {
1359  klog_err("exe_path文件打开失败,退出, %s\n", strerror(errno));
1360  return -1;
1361  }
1362  if (access(cmdline, F_OK))
1363  {
1364  klog_err("cmdline文件打开失败,退出,%s\n", strerror(errno));
1365  return -1;
1366  }
1367  result = readlink(exe_path, buf, LINEMAX - 1);
1368  if (result < 0 || (result >= LINEMAX - 1))
1369  {
1370  klog_err("在reaklink处报错了,退出,%s\n", strerror(errno));
1371  return -1;
1372  }
1373  buf[result] = '\0';
1374  if (!strstartswith(buf, "/usr/bin/python"))
1375  {
1376  FILE *fp;
1377  if ((fp = fopen(cmdline, "rb")) == NULL)
1378  {
1379  klog_err("读取cmdline文件失败,退出,%s\n", strerror(errno));
1380  return -1;
1381  }
1382  char tmp1[512];
1383  fscanf(fp, "%s", tmp1);
1384  new_spos = tmp1;
1385  new_spos += strlen(tmp1);
1386  while (*new_spos == '\0' || *new_spos == '.')
1387  {
1388  new_spos++;
1389  }
1390  if (strstartswith(new_spos, "/usr") && *new_spos == '/'){
1391  new_spos++;
1392  }
1393  // klog_debug("new_spos:%s\n", new_spos);
1394  *spos = strdup(new_spos);
1395  klog_debug("Python程序:%s\n", *spos);
1396  }
1397  klog_debug("程序执行命令:%s\n", buf);
1398  return 0;
1399 }
1400 
1401 static int _dbus_message_compare_list(int id, const char *list, char *buf, char *spos)
1402 {
1403  int k_index = 0;
1404  char *tmpkey;
1405  char **keylist = kdk_conf_list_key(id, list);
1406 
1407  if (*keylist == NULL){
1408  // klog_debug("All keys are allowed to use\n");
1409  return -2;
1410  }
1411 
1412  while ((tmpkey = keylist[k_index]))
1413  {
1414  const char *tmpval = kdk_conf_get_value(id, list, tmpkey);
1415  klog_debug("%s = %s\n", tmpkey, tmpval);
1416 
1417  if (strstartswith(tmpval, "/"))
1418  {
1419  klog_debug("It is not absolute path.\n");
1420  k_index++;
1421  continue;
1422  }
1423 
1424  if (spos)
1425  {
1426  klog_debug("%s spos :%s\n", list, spos);
1427  if (!strcmp(spos, tmpval))
1428  {
1429  klog_debug("On the %s:%s\n", list, spos);
1430  return 0;
1431  }
1432  else
1433  {
1434  klog_debug("Not on the %s:%s\n", list, spos);
1435  k_index++;
1436  continue;
1437  }
1438  }
1439  else if (buf)
1440  {
1441  klog_debug("%s buf :%s\n", list, buf);
1442  if (!strcmp(buf, tmpval))
1443  {
1444  klog_debug("On the %s :%s\n", list, buf);
1445  return 0;
1446  }
1447  else
1448  {
1449  klog_debug("Not on the %s:%s\n", list, buf);
1450  k_index++;
1451  continue;
1452  }
1453  }
1454  }
1455  return -1;
1456 }
1457 
1458 static int _dbus_message_compare_auth(int id, const char *auth)
1459 {
1460  struct passwd *my_info;
1461  my_info = getpwuid(getuid());
1462  char *uname;
1463  uname = my_info->pw_name;
1464  char **keylist;
1465  char *tmpkey;
1466  int k_index = 0;
1467 
1468  keylist = kdk_conf_list_key(id, auth);
1469  if (*keylist == NULL){
1470  // klog_debug("All users are allowed to use\n");
1471  return 0;
1472  }
1473  ASSERT_NOT_NULL(keylist, -1);
1474  while ((tmpkey = keylist[k_index]))
1475  {
1476  const char *tmpval = kdk_conf_get_value(id, auth, tmpkey);
1477  klog_debug("%s = %s\n", tmpkey, tmpval);
1478  if(tmpval != NULL)
1479  {
1480  if (!strcmp(tmpval, uname))
1481  {
1482  klog_debug("On the auth:%s\n", uname);
1483  return 0;
1484  }
1485  else
1486  {
1487  klog_debug("Not on the auth:%s\n", uname);
1488  k_index++;
1489  continue;
1490  }
1491  }
1492  }
1493  return -1;
1494 }
1495 
1496 static int _dbus_message_compare_group(const __CHAR16_TYPE__ **const grouplist, int id, const char *group, char *buf, char *spos)
1497 {
1498  int index = 0;
1499  int r = -1;
1500  int key = -1;
1501  char *tmpgroup;
1502  while ((tmpgroup = grouplist[index]))
1503  {
1504  if (!strcmp(tmpgroup, group))
1505  {
1506  // klog_debug("Cycle read %s list\n", group);
1507  if(!strcmp("auth", group))
1508  {
1509  r = _dbus_message_compare_auth(id, group);
1510  }
1511  else
1512  {
1513  r = _dbus_message_compare_list(id, group, buf, spos);
1514  if (r)
1515  {
1516  klog_debug("This value is not found in the %s\n", group);
1517  return -1;
1518  }
1519  }
1520  key = 0;
1521  if (r < 0)
1522  {
1523  return -1;
1524  }
1525  }
1526  index++;
1527  }
1528  if (key < 0)
1529  {
1530  klog_debug("The %s does not exist\n", group);
1531  return -2;
1532  }
1533  return 0;
1534 }
1535 
1536 static int _dbus_message_right_control(const char *configpath, char *buf, char *spos)
1537 {
1538  int id = 0;
1539  int r = -1;
1540  const char *whitelist = "whitelist";
1541  const char *blacklist = "blacklist";
1542  const char *auth = "auth";
1543 
1544 
1545  klog_debug("%s\n", configpath);
1546  id = kdk_conf_init(configpath);
1547  // klog_debug("初始化配置文件id:%d\n", id);
1548  if (id <= 0)
1549  return -1;
1550 
1551  const __CHAR16_TYPE__ **const grouplist = kdk_conf_list_group(id);
1552  ASSERT_NOT_NULL(grouplist, -1);
1553 
1554  // klog_debug("grouplist:%p\n", grouplist);
1555  // klog_debug("grouplist[0]:%p\n", grouplist[0]);
1556 
1557  r = _dbus_message_compare_group(grouplist, id, whitelist, buf, spos);
1558  if(r == -1)
1559  {
1560  goto exit;
1561  }
1562  else if (r == -2)
1563  {
1564  r = _dbus_message_compare_group(grouplist, id, blacklist, buf, spos);
1565  if(r == 0)
1566  {
1567  r = -1;
1568  goto exit;
1569  }
1570  }
1571 
1572  r = _dbus_message_compare_group(grouplist, id, auth, NULL, NULL);
1573  if(r == -1)
1574  {
1575  goto exit;
1576  }
1577 
1578  klog_debug("Allow access\n");
1579 
1580 exit:
1581  kdk_conf_destroy(id);
1582  return r;
1583 }
1584 
1585 
1607 DBusMessage*
1608 dbus_message_new_method_call (const char *destination,
1609  const char *path,
1610  const char *iface,
1611  const char *method)
1612 {
1613  DBusMessage *message = NULL;
1614  char buffer[LINEMAX] = {0};
1615  char configpath[LINEMAX] = {0};
1616  char *spos = NULL;
1617  int r;
1618 
1619  _dbus_return_val_if_fail(path != NULL, NULL);
1620  _dbus_return_val_if_fail(method != NULL, NULL);
1621  _dbus_return_val_if_fail(destination == NULL ||
1622  _dbus_check_is_valid_bus_name(destination),
1623  NULL);
1624  _dbus_return_val_if_fail(_dbus_check_is_valid_path(path), NULL);
1625  _dbus_return_val_if_fail(iface == NULL ||
1626  _dbus_check_is_valid_interface(iface),
1627  NULL);
1628  _dbus_return_val_if_fail(_dbus_check_is_valid_member(method), NULL);
1629 
1630  klog_debug("调用dbus服务:%s\ndbus路径:%s\ndbus接口:%s\n调用方法:%s\n", destination, path, iface, method);
1631 
1632  r = _dbus_message_get_buf_spos(destination, configpath, buffer, &spos);
1633 
1634  if (r < 0)
1635  goto exit;
1636 
1637  if (!access(configpath, F_OK|R_OK))
1638  {
1639  r = _dbus_message_right_control(configpath, buffer, spos);
1640  if (r == -1)
1641  {
1642  klog_debug("Not allow access\n");
1643  goto exit;
1644  }
1645  }
1646  // else
1647  // {
1648  // klog_debug("dbus服务限制配置文件路径:%s,权限错误\n", configpath);
1649  // goto exit;
1650  // }
1651 
1652  klog_debug("config close\n");
1653 
1654  message = dbus_message_new_empty_header ();
1655  if (message == NULL)
1656  goto exit;
1657 
1658  if (!_dbus_header_create (&message->header,
1659  DBUS_COMPILER_BYTE_ORDER,
1661  destination, path, iface, method, NULL))
1662  {
1663  dbus_message_unref (message);
1664  goto exit;
1665  }
1666 
1667 exit:
1668  if(spos != NULL)
1669  free(spos);
1670 
1671  if(message)
1672  {
1673  return message;
1674  }
1675  return NULL;
1676 }
1677 
1685 DBusMessage*
1687 {
1688  DBusMessage *message;
1689  const char *sender;
1690 
1691  _dbus_return_val_if_fail (method_call != NULL, NULL);
1692 
1693  sender = dbus_message_get_sender (method_call);
1694 
1695  /* sender is allowed to be null here in peer-to-peer case */
1696 
1697  message = dbus_message_new_empty_header ();
1698  if (message == NULL)
1699  return NULL;
1700 
1701  if (!_dbus_header_create (&message->header,
1702  DBUS_COMPILER_BYTE_ORDER,
1704  sender, NULL, NULL, NULL, NULL))
1705  {
1706  dbus_message_unref (message);
1707  return NULL;
1708  }
1709 
1710  dbus_message_set_no_reply (message, TRUE);
1711 
1712  if (!dbus_message_set_reply_serial (message,
1713  dbus_message_get_serial (method_call)))
1714  {
1715  dbus_message_unref (message);
1716  return NULL;
1717  }
1718 
1719  return message;
1720 }
1721 
1736 DBusMessage*
1737 dbus_message_new_signal (const char *path,
1738  const char *iface,
1739  const char *name)
1740 {
1741  DBusMessage *message;
1742 
1743  _dbus_return_val_if_fail (path != NULL, NULL);
1744  _dbus_return_val_if_fail (iface != NULL, NULL);
1745  _dbus_return_val_if_fail (name != NULL, NULL);
1746  _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
1747  _dbus_return_val_if_fail (_dbus_check_is_valid_interface (iface), NULL);
1748  _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);
1749 
1750  message = dbus_message_new_empty_header ();
1751  if (message == NULL)
1752  return NULL;
1753 
1754  if (!_dbus_header_create (&message->header,
1755  DBUS_COMPILER_BYTE_ORDER,
1757  NULL, path, iface, name, NULL))
1758  {
1759  dbus_message_unref (message);
1760  return NULL;
1761  }
1762 
1763  dbus_message_set_no_reply (message, TRUE);
1764 
1765  return message;
1766 }
1767 
1782 DBusMessage*
1784  const char *error_name,
1785  const char *error_message)
1786 {
1787  DBusMessage *message;
1788  const char *sender;
1789  DBusMessageIter iter;
1790 
1791  _dbus_return_val_if_fail (reply_to != NULL, NULL);
1792  _dbus_return_val_if_fail (error_name != NULL, NULL);
1793  _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
1794 
1795  sender = dbus_message_get_sender (reply_to);
1796 
1797  /* sender may be NULL for non-message-bus case or
1798  * when the message bus is dealing with an unregistered
1799  * connection.
1800  */
1801  message = dbus_message_new_empty_header ();
1802  if (message == NULL)
1803  return NULL;
1804 
1805  if (!_dbus_header_create (&message->header,
1806  DBUS_COMPILER_BYTE_ORDER,
1808  sender, NULL, NULL, NULL, error_name))
1809  {
1810  dbus_message_unref (message);
1811  return NULL;
1812  }
1813 
1814  dbus_message_set_no_reply (message, TRUE);
1815 
1816  if (!dbus_message_set_reply_serial (message,
1817  dbus_message_get_serial (reply_to)))
1818  {
1819  dbus_message_unref (message);
1820  return NULL;
1821  }
1822 
1823  if (error_message != NULL)
1824  {
1825  dbus_message_iter_init_append (message, &iter);
1826  if (!dbus_message_iter_append_basic (&iter,
1828  &error_message))
1829  {
1830  dbus_message_unref (message);
1831  return NULL;
1832  }
1833  }
1834 
1835  return message;
1836 }
1837 
1854 DBusMessage*
1856  const char *error_name,
1857  const char *error_format,
1858  ...)
1859 {
1860  va_list args;
1861  DBusString str;
1862  DBusMessage *message;
1863 
1864  _dbus_return_val_if_fail (reply_to != NULL, NULL);
1865  _dbus_return_val_if_fail (error_name != NULL, NULL);
1866  _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
1867 
1868  if (!_dbus_string_init (&str))
1869  return NULL;
1870 
1871  va_start (args, error_format);
1872 
1873  if (_dbus_string_append_printf_valist (&str, error_format, args))
1874  message = dbus_message_new_error (reply_to, error_name,
1875  _dbus_string_get_const_data (&str));
1876  else
1877  message = NULL;
1878 
1879  _dbus_string_free (&str);
1880 
1881  va_end (args);
1882 
1883  return message;
1884 }
1885 
1886 
1899 DBusMessage *
1901 {
1902  DBusMessage *retval;
1903 
1904  _dbus_return_val_if_fail (message != NULL, NULL);
1905 
1906  retval = dbus_new0 (DBusMessage, 1);
1907  if (retval == NULL)
1908  return NULL;
1909 
1910  _dbus_atomic_inc (&retval->refcount);
1911 
1912  retval->locked = FALSE;
1913 #ifndef DBUS_DISABLE_CHECKS
1914  retval->generation = message->generation;
1915 #endif
1916 
1917  if (!_dbus_header_copy (&message->header, &retval->header))
1918  {
1919  dbus_free (retval);
1920  return NULL;
1921  }
1922 
1923  if (!_dbus_string_init_preallocated (&retval->body,
1924  _dbus_string_get_length (&message->body)))
1925  {
1926  _dbus_header_free (&retval->header);
1927  dbus_free (retval);
1928  return NULL;
1929  }
1930 
1931  if (!_dbus_string_copy (&message->body, 0,
1932  &retval->body, 0))
1933  goto failed_copy;
1934 
1935 #ifdef HAVE_UNIX_FD_PASSING
1936  retval->unix_fds = dbus_new(int, message->n_unix_fds);
1937  if (retval->unix_fds == NULL && message->n_unix_fds > 0)
1938  goto failed_copy;
1939 
1940  retval->n_unix_fds_allocated = message->n_unix_fds;
1941 
1942  for (retval->n_unix_fds = 0;
1943  retval->n_unix_fds < message->n_unix_fds;
1944  retval->n_unix_fds++)
1945  {
1946  retval->unix_fds[retval->n_unix_fds] = _dbus_dup(message->unix_fds[retval->n_unix_fds], NULL);
1947 
1948  if (retval->unix_fds[retval->n_unix_fds] < 0)
1949  goto failed_copy;
1950  }
1951 
1952 #endif
1953 
1954  _dbus_message_trace_ref (retval, 0, 1, "copy");
1955  return retval;
1956 
1957  failed_copy:
1958  _dbus_header_free (&retval->header);
1959  _dbus_string_free (&retval->body);
1960 
1961 #ifdef HAVE_UNIX_FD_PASSING
1962  close_unix_fds(retval->unix_fds, &retval->n_unix_fds);
1963  dbus_free(retval->unix_fds);
1964 #endif
1965 
1966  dbus_free (retval);
1967 
1968  return NULL;
1969 }
1970 
1971 
1979 DBusMessage *
1981 {
1982  dbus_int32_t old_refcount;
1983 
1984  _dbus_return_val_if_fail (message != NULL, NULL);
1985  _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
1986  _dbus_return_val_if_fail (!message->in_cache, NULL);
1987 
1988  old_refcount = _dbus_atomic_inc (&message->refcount);
1989  _dbus_assert (old_refcount >= 1);
1990  _dbus_message_trace_ref (message, old_refcount, old_refcount + 1, "ref");
1991 
1992  return message;
1993 }
1994 
2002 void
2004 {
2005  dbus_int32_t old_refcount;
2006 
2007  _dbus_return_if_fail (message != NULL);
2008  _dbus_return_if_fail (message->generation == _dbus_current_generation);
2009  _dbus_return_if_fail (!message->in_cache);
2010 
2011  old_refcount = _dbus_atomic_dec (&message->refcount);
2012 
2013  _dbus_assert (old_refcount >= 1);
2014 
2015  _dbus_message_trace_ref (message, old_refcount, old_refcount - 1, "unref");
2016 
2017  if (old_refcount == 1)
2018  {
2019  /* Calls application callbacks! */
2020  dbus_message_cache_or_finalize (message);
2021  }
2022 }
2023 
2034 int
2036 {
2037  _dbus_return_val_if_fail (message != NULL, DBUS_MESSAGE_TYPE_INVALID);
2038 
2039  return _dbus_header_get_message_type (&message->header);
2040 }
2041 
2106  int first_arg_type,
2107  ...)
2108 {
2109  dbus_bool_t retval;
2110  va_list var_args;
2111 
2112  _dbus_return_val_if_fail (message != NULL, FALSE);
2113 
2114  va_start (var_args, first_arg_type);
2115  retval = dbus_message_append_args_valist (message,
2116  first_arg_type,
2117  var_args);
2118  va_end (var_args);
2119 
2120  return retval;
2121 }
2122 
2138  int first_arg_type,
2139  va_list var_args)
2140 {
2141  int type;
2142  DBusMessageIter iter;
2143 
2144  _dbus_return_val_if_fail (message != NULL, FALSE);
2145 
2146  type = first_arg_type;
2147 
2148  dbus_message_iter_init_append (message, &iter);
2149 
2150  while (type != DBUS_TYPE_INVALID)
2151  {
2152  if (dbus_type_is_basic (type))
2153  {
2154  const DBusBasicValue *value;
2155  value = va_arg (var_args, const DBusBasicValue*);
2156 
2157  if (!dbus_message_iter_append_basic (&iter,
2158  type,
2159  value))
2160  goto failed;
2161  }
2162  else if (type == DBUS_TYPE_ARRAY)
2163  {
2164  int element_type;
2165  DBusMessageIter array;
2166  char buf[2];
2167 
2168  element_type = va_arg (var_args, int);
2169 
2170  buf[0] = element_type;
2171  buf[1] = '\0';
2174  buf,
2175  &array))
2176  goto failed;
2177 
2178  if (dbus_type_is_fixed (element_type) &&
2179  element_type != DBUS_TYPE_UNIX_FD)
2180  {
2181  const DBusBasicValue **value;
2182  int n_elements;
2183 
2184  value = va_arg (var_args, const DBusBasicValue**);
2185  n_elements = va_arg (var_args, int);
2186 
2188  element_type,
2189  value,
2190  n_elements)) {
2191  dbus_message_iter_abandon_container (&iter, &array);
2192  goto failed;
2193  }
2194  }
2195  else if (_DBUS_TYPE_IS_STRINGLIKE (element_type))
2196  {
2197  const char ***value_p;
2198  const char **value;
2199  int n_elements;
2200  int i;
2201 
2202  value_p = va_arg (var_args, const char***);
2203  n_elements = va_arg (var_args, int);
2204 
2205  value = *value_p;
2206 
2207  i = 0;
2208  while (i < n_elements)
2209  {
2210  if (!dbus_message_iter_append_basic (&array,
2211  element_type,
2212  &value[i])) {
2213  dbus_message_iter_abandon_container (&iter, &array);
2214  goto failed;
2215  }
2216  ++i;
2217  }
2218  }
2219  else
2220  {
2221  _dbus_warn ("arrays of %s can't be appended with %s for now",
2222  _dbus_type_to_string (element_type),
2223  _DBUS_FUNCTION_NAME);
2224  dbus_message_iter_abandon_container (&iter, &array);
2225  goto failed;
2226  }
2227 
2228  if (!dbus_message_iter_close_container (&iter, &array))
2229  goto failed;
2230  }
2231 #ifndef DBUS_DISABLE_CHECKS
2232  else
2233  {
2234  _dbus_warn ("type %s isn't supported yet in %s",
2235  _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
2236  goto failed;
2237  }
2238 #endif
2239 
2240  type = va_arg (var_args, int);
2241  }
2242 
2243  return TRUE;
2244 
2245  failed:
2246  return FALSE;
2247 }
2248 
2295  DBusError *error,
2296  int first_arg_type,
2297  ...)
2298 {
2299  dbus_bool_t retval;
2300  va_list var_args;
2301 
2302  _dbus_return_val_if_fail (message != NULL, FALSE);
2303  _dbus_return_val_if_error_is_set (error, FALSE);
2304 
2305  va_start (var_args, first_arg_type);
2306  retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
2307  va_end (var_args);
2308 
2309  return retval;
2310 }
2311 
2324  DBusError *error,
2325  int first_arg_type,
2326  va_list var_args)
2327 {
2328  DBusMessageIter iter;
2329 
2330  _dbus_return_val_if_fail (message != NULL, FALSE);
2331  _dbus_return_val_if_error_is_set (error, FALSE);
2332 
2333  dbus_message_iter_init (message, &iter);
2334  return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
2335 }
2336 
2337 static void
2338 _dbus_message_iter_init_common (DBusMessage *message,
2339  DBusMessageRealIter *real,
2340  int iter_type)
2341 {
2342  /* If these static assertions fail on your platform, report it as a bug. */
2343  _DBUS_STATIC_ASSERT (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
2344  _DBUS_STATIC_ASSERT (_DBUS_ALIGNOF (DBusMessageRealIter) <=
2345  _DBUS_ALIGNOF (DBusMessageIter));
2346  /* A failure of these two assertions would indicate that we've broken
2347  * ABI on this platform since 1.10.0. */
2348  _DBUS_STATIC_ASSERT (sizeof (DBusMessageIter_1_10_0) ==
2349  sizeof (DBusMessageIter));
2350  _DBUS_STATIC_ASSERT (_DBUS_ALIGNOF (DBusMessageIter_1_10_0) ==
2351  _DBUS_ALIGNOF (DBusMessageIter));
2352  /* If this static assertion fails, it means the DBusMessageIter struct
2353  * is not "packed", which might result in "iter = other_iter" not copying
2354  * every byte. */
2355  _DBUS_STATIC_ASSERT (sizeof (DBusMessageIter) ==
2356  4 * sizeof (void *) + sizeof (dbus_uint32_t) + 9 * sizeof (int));
2357 
2358  /* Since the iterator will read or write who-knows-what from the
2359  * message, we need to get in the right byte order
2360  */
2361  ensure_byte_order (message);
2362 
2363  real->message = message;
2364  real->changed_stamp = message->changed_stamp;
2365  real->iter_type = iter_type;
2366  real->sig_refcount = 0;
2367 }
2368 
2393  DBusMessageIter *iter)
2394 {
2395  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2396  const DBusString *type_str;
2397  int type_pos;
2398 
2399  _dbus_return_val_if_fail (message != NULL, FALSE);
2400  _dbus_return_val_if_fail (iter != NULL, FALSE);
2401 
2402  get_const_signature (&message->header, &type_str, &type_pos);
2403 
2404  _dbus_message_iter_init_common (message, real,
2405  DBUS_MESSAGE_ITER_TYPE_READER);
2406 
2408  _dbus_header_get_byte_order (&message->header),
2409  type_str, type_pos,
2410  &message->body,
2411  0);
2412 
2414 }
2415 
2424 {
2425  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2426 
2427  _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
2428  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2429 
2430  return _dbus_type_reader_has_next (&real->u.reader);
2431 }
2432 
2443 {
2444  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2445 
2446  _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
2447  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2448 
2449  return _dbus_type_reader_next (&real->u.reader);
2450 }
2451 
2466 int
2468 {
2469  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2470 
2471  _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2472  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2473 
2475 }
2476 
2485 int
2487 {
2488  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2489 
2490  _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2491  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
2492  _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
2493 
2495 }
2496 
2522 void
2524  DBusMessageIter *sub)
2525 {
2526  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2527  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2528 
2529  _dbus_return_if_fail (_dbus_message_iter_check (real));
2530  _dbus_return_if_fail (sub != NULL);
2531 
2532  *real_sub = *real;
2533  _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
2534 }
2535 
2547 char *
2549 {
2550  const DBusString *sig;
2551  DBusString retstr;
2552  char *ret;
2553  int start, len;
2554  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2555 
2556  _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
2557 
2558  if (!_dbus_string_init (&retstr))
2559  return NULL;
2560 
2562  &start, &len);
2563  if (!_dbus_string_append_len (&retstr,
2564  _dbus_string_get_const_data (sig) + start,
2565  len))
2566  return NULL;
2567  if (!_dbus_string_steal_data (&retstr, &ret))
2568  return NULL;
2569  _dbus_string_free (&retstr);
2570  return ret;
2571 }
2572 
2620 void
2622  void *value)
2623 {
2624  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2625 
2626  _dbus_return_if_fail (_dbus_message_iter_check (real));
2627  _dbus_return_if_fail (value != NULL);
2628 
2630  {
2631 #ifdef HAVE_UNIX_FD_PASSING
2632  DBusBasicValue idx;
2633 
2634  _dbus_type_reader_read_basic(&real->u.reader, &idx);
2635 
2636  if (idx.u32 >= real->message->n_unix_fds) {
2637  /* Hmm, we cannot really signal an error here, so let's make
2638  sure to return an invalid fd. */
2639  *((int*) value) = -1;
2640  return;
2641  }
2642 
2643  *((int*) value) = _dbus_dup(real->message->unix_fds[idx.u32], NULL);
2644 #else
2645  *((int*) value) = -1;
2646 #endif
2647  }
2648  else
2649  {
2651  value);
2652  }
2653 }
2654 
2665 int
2667 {
2668  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2669  DBusTypeReader array;
2670  int element_type;
2671  int n_elements = 0;
2672 
2673  _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
2674  _dbus_return_val_if_fail (_dbus_type_reader_get_current_type (&real->u.reader)
2675  == DBUS_TYPE_ARRAY, 0);
2676 
2677  element_type = _dbus_type_reader_get_element_type (&real->u.reader);
2678  _dbus_type_reader_recurse (&real->u.reader, &array);
2679  if (dbus_type_is_fixed (element_type))
2680  {
2681  int alignment = _dbus_type_get_alignment (element_type);
2682  int total_len = _dbus_type_reader_get_array_length (&array);
2683  n_elements = total_len / alignment;
2684  }
2685  else
2686  {
2688  {
2689  ++n_elements;
2690  _dbus_type_reader_next (&array);
2691  }
2692  }
2693 
2694  return n_elements;
2695 }
2696 
2709 int
2711 {
2712  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2713 
2714  _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
2715 
2717 }
2718 
2754 void
2756  void *value,
2757  int *n_elements)
2758 {
2759  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2760 #ifndef DBUS_DISABLE_CHECKS
2761  int subtype = _dbus_type_reader_get_current_type(&real->u.reader);
2762 
2763  _dbus_return_if_fail (_dbus_message_iter_check (real));
2764  _dbus_return_if_fail (value != NULL);
2765  _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) ||
2766  (dbus_type_is_fixed (subtype) && subtype != DBUS_TYPE_UNIX_FD));
2767 #endif
2768 
2770  value, n_elements);
2771 }
2772 
2784 void
2786  DBusMessageIter *iter)
2787 {
2788  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2789 
2790  _dbus_return_if_fail (message != NULL);
2791  _dbus_return_if_fail (iter != NULL);
2792 
2793  _dbus_message_iter_init_common (message, real,
2794  DBUS_MESSAGE_ITER_TYPE_WRITER);
2795 
2796  /* We create the signature string and point iterators at it "on demand"
2797  * when a value is actually appended. That means that init() never fails
2798  * due to OOM.
2799  */
2801  _dbus_header_get_byte_order (&message->header),
2802  &message->body,
2803  _dbus_string_get_length (&message->body));
2804 }
2805 
2814 static dbus_bool_t
2815 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
2816 {
2817  DBusString *str;
2818  const DBusString *current_sig;
2819  int current_sig_pos;
2820 
2821  _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2822 
2823  if (real->u.writer.type_str != NULL)
2824  {
2825  _dbus_assert (real->sig_refcount > 0);
2826  real->sig_refcount += 1;
2827  return TRUE;
2828  }
2829 
2830  str = dbus_new (DBusString, 1);
2831  if (str == NULL)
2832  return FALSE;
2833 
2836  &current_sig, &current_sig_pos))
2837  current_sig = NULL;
2838 
2839  if (current_sig)
2840  {
2841  int current_len;
2842 
2843  current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
2844  current_sig_pos += 1; /* move on to sig data */
2845 
2846  if (!_dbus_string_init_preallocated (str, current_len + 4))
2847  {
2848  dbus_free (str);
2849  return FALSE;
2850  }
2851 
2852  if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
2853  str, 0))
2854  {
2855  _dbus_string_free (str);
2856  dbus_free (str);
2857  return FALSE;
2858  }
2859  }
2860  else
2861  {
2862  if (!_dbus_string_init_preallocated (str, 4))
2863  {
2864  dbus_free (str);
2865  return FALSE;
2866  }
2867  }
2868 
2869  real->sig_refcount = 1;
2870 
2871  /* If this assertion failed, then str would be neither stored in u.writer
2872  * nor freed by this function, resulting in a memory leak. */
2873  _dbus_assert (real->u.writer.type_str == NULL);
2875  str, _dbus_string_get_length (str));
2876  return TRUE;
2877 }
2878 
2888 static dbus_bool_t
2889 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
2890 {
2891  DBusString *str;
2892  const char *v_STRING;
2893  dbus_bool_t retval;
2894 
2895  _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2896  _dbus_assert (real->u.writer.type_str != NULL);
2897  _dbus_assert (real->sig_refcount > 0);
2898 
2899  real->sig_refcount -= 1;
2900 
2901  if (real->sig_refcount > 0)
2902  return TRUE;
2903  _dbus_assert (real->sig_refcount == 0);
2904 
2905  retval = TRUE;
2906 
2907  str = real->u.writer.type_str;
2908 
2909  v_STRING = _dbus_string_get_const_data (str);
2913  &v_STRING))
2914  retval = FALSE;
2915 
2917  _dbus_string_free (str);
2918  dbus_free (str);
2919 
2920  return retval;
2921 }
2922 
2930 static void
2931 _dbus_message_iter_abandon_signature (DBusMessageRealIter *real)
2932 {
2933  DBusString *str;
2934 
2935  _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2936  _dbus_assert (real->u.writer.type_str != NULL);
2937  _dbus_assert (real->sig_refcount > 0);
2938 
2939  real->sig_refcount -= 1;
2940 
2941  if (real->sig_refcount > 0)
2942  return;
2943  _dbus_assert (real->sig_refcount == 0);
2944 
2945  str = real->u.writer.type_str;
2946 
2948  _dbus_string_free (str);
2949  dbus_free (str);
2950 }
2951 
2952 #ifndef DBUS_DISABLE_CHECKS
2953 static dbus_bool_t
2954 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
2955 {
2956  if (!_dbus_message_iter_check (iter))
2957  return FALSE;
2958 
2959  if (iter->message->locked)
2960  {
2961  _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)");
2962  return FALSE;
2963  }
2964 
2965  return TRUE;
2966 }
2967 #endif /* DBUS_DISABLE_CHECKS */
2968 
2969 #ifdef HAVE_UNIX_FD_PASSING
2970 static int *
2971 expand_fd_array(DBusMessage *m,
2972  unsigned n)
2973 {
2974  _dbus_assert(m);
2975 
2976  /* This makes space for adding n new fds to the array and returns a
2977  pointer to the place were the first fd should be put. */
2978 
2979  if (m->n_unix_fds + n > m->n_unix_fds_allocated)
2980  {
2981  unsigned k;
2982  int *p;
2983 
2984  /* Make twice as much space as necessary */
2985  k = (m->n_unix_fds + n) * 2;
2986 
2987  /* Allocate at least four */
2988  if (k < 4)
2989  k = 4;
2990 
2991  p = dbus_realloc(m->unix_fds, k * sizeof(int));
2992  if (p == NULL)
2993  return NULL;
2994 
2995  m->unix_fds = p;
2996  m->n_unix_fds_allocated = k;
2997  }
2998 
2999  return m->unix_fds + m->n_unix_fds;
3000 }
3001 #endif
3002 
3024  int type,
3025  const void *value)
3026 {
3027  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3028  dbus_bool_t ret;
3029 
3030  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
3031  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
3032  _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
3033  _dbus_return_val_if_fail (value != NULL, FALSE);
3034 
3035 #ifndef DBUS_DISABLE_CHECKS
3036  switch (type)
3037  {
3038  DBusString str;
3039  DBusValidity signature_validity;
3040  const char * const *string_p;
3041  const dbus_bool_t *bool_p;
3042 
3043  case DBUS_TYPE_STRING:
3044  string_p = value;
3045  _dbus_return_val_if_fail (_dbus_check_is_valid_utf8 (*string_p), FALSE);
3046  break;
3047 
3048  case DBUS_TYPE_OBJECT_PATH:
3049  string_p = value;
3050  _dbus_return_val_if_fail (_dbus_check_is_valid_path (*string_p), FALSE);
3051  break;
3052 
3053  case DBUS_TYPE_SIGNATURE:
3054  string_p = value;
3055  _dbus_string_init_const (&str, *string_p);
3056  signature_validity = _dbus_validate_signature_with_reason (&str,
3057  0,
3058  _dbus_string_get_length (&str));
3059 
3060  if (signature_validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
3061  return FALSE;
3062 
3063  _dbus_return_val_if_fail (signature_validity == DBUS_VALID, FALSE);
3064  break;
3065 
3066  case DBUS_TYPE_BOOLEAN:
3067  bool_p = value;
3068  _dbus_return_val_if_fail (*bool_p == 0 || *bool_p == 1, FALSE);
3069  break;
3070 
3071  default:
3072  {
3073  /* nothing to check, all possible values are allowed */
3074  }
3075  }
3076 #endif
3077 
3078  if (!_dbus_message_iter_open_signature (real))
3079  return FALSE;
3080 
3081  if (type == DBUS_TYPE_UNIX_FD)
3082  {
3083 #ifdef HAVE_UNIX_FD_PASSING
3084  int *fds;
3085  dbus_uint32_t u;
3086 
3087  ret = FALSE;
3088 
3089  /* First step, include the fd in the fd list of this message */
3090  if (!(fds = expand_fd_array(real->message, 1)))
3091  goto out;
3092 
3093  *fds = _dbus_dup(*(int*) value, NULL);
3094  if (*fds < 0)
3095  goto out;
3096 
3097  u = real->message->n_unix_fds;
3098 
3099  /* Second step, write the index to the fd */
3100  if (!(ret = _dbus_type_writer_write_basic (&real->u.writer, DBUS_TYPE_UNIX_FD, &u))) {
3101  _dbus_close(*fds, NULL);
3102  goto out;
3103  }
3104 
3105  real->message->n_unix_fds += 1;
3106  u += 1;
3107 
3108  /* Final step, update the header accordingly */
3112  &u);
3113 
3114  /* If any of these operations fail the message is
3115  hosed. However, no memory or fds should be leaked since what
3116  has been added to message has been added to the message, and
3117  can hence be accounted for when the message is being
3118  freed. */
3119 #else
3120  ret = FALSE;
3121  /* This is redundant (we could just fall through), but it avoids
3122  * -Wunused-label in builds that don't HAVE_UNIX_FD_PASSING */
3123  goto out;
3124 #endif
3125  }
3126  else
3127  {
3128  ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
3129  }
3130 
3131 out:
3132  if (!_dbus_message_iter_close_signature (real))
3133  ret = FALSE;
3134 
3135  return ret;
3136 }
3137 
3175  int element_type,
3176  const void *value,
3177  int n_elements)
3178 {
3179  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3180  dbus_bool_t ret;
3181 
3182  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
3183  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
3184  _dbus_return_val_if_fail (dbus_type_is_fixed (element_type) && element_type != DBUS_TYPE_UNIX_FD, FALSE);
3185  _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
3186  _dbus_return_val_if_fail (value != NULL, FALSE);
3187  _dbus_return_val_if_fail (n_elements >= 0, FALSE);
3188  _dbus_return_val_if_fail (n_elements <=
3190  FALSE);
3191 
3192 #ifndef DBUS_DISABLE_CHECKS
3193  if (element_type == DBUS_TYPE_BOOLEAN)
3194  {
3195  const dbus_bool_t * const *bools = value;
3196  int i;
3197 
3198  for (i = 0; i < n_elements; i++)
3199  {
3200  _dbus_return_val_if_fail ((*bools)[i] == 0 || (*bools)[i] == 1, FALSE);
3201  }
3202  }
3203 #endif
3204 
3205  ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
3206 
3207  return ret;
3208 }
3209 
3239  int type,
3240  const char *contained_signature,
3241  DBusMessageIter *sub)
3242 {
3243  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3244  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
3245  DBusString contained_str;
3246  DBusValidity contained_signature_validity;
3247  dbus_bool_t ret;
3248 
3249  _dbus_return_val_if_fail (sub != NULL, FALSE);
3250  /* Do our best to make sure the sub-iterator doesn't contain something
3251  * valid-looking on failure */
3252  _dbus_message_real_iter_zero (real_sub);
3253 
3254  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
3255  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
3256  _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
3257  _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
3258  contained_signature == NULL) ||
3259  (type == DBUS_TYPE_DICT_ENTRY &&
3260  contained_signature == NULL) ||
3261  (type == DBUS_TYPE_VARIANT &&
3262  contained_signature != NULL) ||
3263  (type == DBUS_TYPE_ARRAY &&
3264  contained_signature != NULL), FALSE);
3265 
3266  /* this would fail if the contained_signature is a dict entry, since
3267  * dict entries are invalid signatures standalone (they must be in
3268  * an array)
3269  */
3270  if (contained_signature != NULL)
3271  {
3272  _dbus_string_init_const (&contained_str, contained_signature);
3273  contained_signature_validity = _dbus_validate_signature_with_reason (&contained_str,
3274  0,
3275  _dbus_string_get_length (&contained_str));
3276 
3277  if (contained_signature_validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
3278  return FALSE;
3279  }
3280  else
3281  {
3282  /* just some placeholder value */
3283  contained_signature_validity = DBUS_VALID_BUT_INCOMPLETE;
3284  }
3285 
3286  _dbus_return_val_if_fail ((type == DBUS_TYPE_ARRAY && contained_signature && *contained_signature == DBUS_DICT_ENTRY_BEGIN_CHAR) ||
3287  contained_signature == NULL ||
3288  contained_signature_validity == DBUS_VALID,
3289  FALSE);
3290 
3291  if (!_dbus_message_iter_open_signature (real))
3292  return FALSE;
3293 
3294  ret = FALSE;
3295  *real_sub = *real;
3296 
3297  if (contained_signature != NULL)
3298  {
3299  _dbus_string_init_const (&contained_str, contained_signature);
3300 
3301  ret = _dbus_type_writer_recurse (&real->u.writer,
3302  type,
3303  &contained_str, 0,
3304  &real_sub->u.writer);
3305  }
3306  else
3307  {
3308  ret = _dbus_type_writer_recurse (&real->u.writer,
3309  type,
3310  NULL, 0,
3311  &real_sub->u.writer);
3312  }
3313 
3314  if (!ret)
3315  _dbus_message_iter_abandon_signature (real);
3316 
3317  return ret;
3318 }
3319 
3320 
3342  DBusMessageIter *sub)
3343 {
3344  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3345  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
3346  dbus_bool_t ret;
3347 
3348  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
3349  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
3350  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
3351  _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
3352 
3353  ret = _dbus_type_writer_unrecurse (&real->u.writer,
3354  &real_sub->u.writer);
3355  _dbus_message_real_iter_zero (real_sub);
3356 
3357  if (!_dbus_message_iter_close_signature (real))
3358  ret = FALSE;
3359 
3360  return ret;
3361 }
3362 
3374 void
3376  DBusMessageIter *sub)
3377 {
3378  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3379  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
3380 
3381 #ifndef DBUS_DISABLE_CHECKS
3382  _dbus_return_if_fail (_dbus_message_iter_append_check (real));
3383  _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
3384  _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
3385  _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
3386 #endif
3387 
3388  _dbus_message_iter_abandon_signature (real);
3389  _dbus_message_real_iter_zero (real_sub);
3390 }
3391 
3433 void
3435  DBusMessageIter *sub)
3436 {
3437  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3438  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
3439 
3440  /* If both the parent and the child are zeroed out, then either we didn't
3441  * even get as far as successfully recursing into the parent, or we already
3442  * closed both the child and the parent. For example, in the code sample
3443  * in the doc-comment above, this happens for
3444  * abandon_container_if_open (&outer, &inner) if the first open_container
3445  * call failed, or if we reached result = TRUE and fell through. */
3446  if (_dbus_message_real_iter_is_zeroed (real) &&
3447  _dbus_message_real_iter_is_zeroed (real_sub))
3448  return;
3449 
3450 #ifndef DBUS_DISABLE_CHECKS
3451  /* If the child is not zeroed out, but the parent is, then something has
3452  * gone horribly wrong (in practice that would probably mean both are
3453  * uninitialized or corrupt, and the parent happens to have ended up
3454  * all-bytes-zero). */
3455  _dbus_return_if_fail (_dbus_message_iter_append_check (real));
3456  _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
3457 #endif
3458 
3459  /* If the parent is not zeroed out, but the child is, then either we did
3460  * not successfully open the child, or we already closed the child. This
3461  * means we do not own a reference to the parent's signature, so it would
3462  * be wrong to release it; so we must not call abandon_signature() here.
3463  * In the code sample in the doc-comment above, this happens for
3464  * abandon_container_if_open (&outer, &inner) if the second open_container
3465  * call failed, or if the second close_container call failed. */
3466  if (_dbus_message_real_iter_is_zeroed (real_sub))
3467  return;
3468 
3469 #ifndef DBUS_DISABLE_CHECKS
3470  _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
3471  _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
3472 #endif
3473 
3474  /* If neither the parent nor the child is zeroed out, then we genuinely
3475  * have an open container; close it. In the code sample in the doc-comment,
3476  * this happens for abandon_container_if_open (&outer, &inner) if the
3477  * append_basic call failed. */
3478  _dbus_message_iter_abandon_signature (real);
3479  _dbus_message_real_iter_zero (real_sub);
3480 }
3481 
3498 void
3500  dbus_bool_t no_reply)
3501 {
3502  _dbus_return_if_fail (message != NULL);
3503  _dbus_return_if_fail (!message->locked);
3504 
3505  _dbus_header_toggle_flag (&message->header,
3507  no_reply);
3508 }
3509 
3519 {
3520  _dbus_return_val_if_fail (message != NULL, FALSE);
3521 
3522  return _dbus_header_get_flag (&message->header,
3524 }
3525 
3540 void
3542  dbus_bool_t auto_start)
3543 {
3544  _dbus_return_if_fail (message != NULL);
3545  _dbus_return_if_fail (!message->locked);
3546 
3547  _dbus_header_toggle_flag (&message->header,
3549  !auto_start);
3550 }
3551 
3561 {
3562  _dbus_return_val_if_fail (message != NULL, FALSE);
3563 
3564  return !_dbus_header_get_flag (&message->header,
3566 }
3567 
3568 
3583  const char *object_path)
3584 {
3585  _dbus_return_val_if_fail (message != NULL, FALSE);
3586  _dbus_return_val_if_fail (!message->locked, FALSE);
3587  _dbus_return_val_if_fail (object_path == NULL ||
3588  _dbus_check_is_valid_path (object_path),
3589  FALSE);
3590 
3591  return set_or_delete_string_field (message,
3594  object_path);
3595 }
3596 
3610 const char*
3612 {
3613  const char *v;
3614 
3615  _dbus_return_val_if_fail (message != NULL, NULL);
3616 
3617  v = NULL; /* in case field doesn't exist */
3621  (void *) &v);
3622  return v;
3623 }
3624 
3636  const char *path)
3637 {
3638  const char *msg_path;
3639  msg_path = dbus_message_get_path (message);
3640 
3641  if (msg_path == NULL)
3642  {
3643  if (path == NULL)
3644  return TRUE;
3645  else
3646  return FALSE;
3647  }
3648 
3649  if (path == NULL)
3650  return FALSE;
3651 
3652  if (strcmp (msg_path, path) == 0)
3653  return TRUE;
3654 
3655  return FALSE;
3656 }
3657 
3680  char ***path)
3681 {
3682  const char *v;
3683 
3684  _dbus_return_val_if_fail (message != NULL, FALSE);
3685  _dbus_return_val_if_fail (path != NULL, FALSE);
3686 
3687  *path = NULL;
3688 
3689  v = dbus_message_get_path (message);
3690  if (v != NULL)
3691  {
3692  if (!_dbus_decompose_path (v, strlen (v),
3693  path, NULL))
3694  return FALSE;
3695  }
3696  return TRUE;
3697 }
3698 
3714  const char *iface)
3715 {
3716  _dbus_return_val_if_fail (message != NULL, FALSE);
3717  _dbus_return_val_if_fail (!message->locked, FALSE);
3718  _dbus_return_val_if_fail (iface == NULL ||
3719  _dbus_check_is_valid_interface (iface),
3720  FALSE);
3721 
3722  return set_or_delete_string_field (message,
3725  iface);
3726 }
3727 
3741 const char*
3743 {
3744  const char *v;
3745 
3746  _dbus_return_val_if_fail (message != NULL, NULL);
3747 
3748  v = NULL; /* in case field doesn't exist */
3752  (void *) &v);
3753  return v;
3754 }
3755 
3765  const char *iface)
3766 {
3767  const char *msg_interface;
3768  msg_interface = dbus_message_get_interface (message);
3769 
3770  if (msg_interface == NULL)
3771  {
3772  if (iface == NULL)
3773  return TRUE;
3774  else
3775  return FALSE;
3776  }
3777 
3778  if (iface == NULL)
3779  return FALSE;
3780 
3781  if (strcmp (msg_interface, iface) == 0)
3782  return TRUE;
3783 
3784  return FALSE;
3785 
3786 }
3787 
3802  const char *member)
3803 {
3804  _dbus_return_val_if_fail (message != NULL, FALSE);
3805  _dbus_return_val_if_fail (!message->locked, FALSE);
3806  _dbus_return_val_if_fail (member == NULL ||
3807  _dbus_check_is_valid_member (member),
3808  FALSE);
3809 
3810  return set_or_delete_string_field (message,
3813  member);
3814 }
3815 
3827 const char*
3829 {
3830  const char *v;
3831 
3832  _dbus_return_val_if_fail (message != NULL, NULL);
3833 
3834  v = NULL; /* in case field doesn't exist */
3838  (void *) &v);
3839  return v;
3840 }
3841 
3851  const char *member)
3852 {
3853  const char *msg_member;
3854  msg_member = dbus_message_get_member (message);
3855 
3856  if (msg_member == NULL)
3857  {
3858  if (member == NULL)
3859  return TRUE;
3860  else
3861  return FALSE;
3862  }
3863 
3864  if (member == NULL)
3865  return FALSE;
3866 
3867  if (strcmp (msg_member, member) == 0)
3868  return TRUE;
3869 
3870  return FALSE;
3871 
3872 }
3873 
3887  const char *error_name)
3888 {
3889  _dbus_return_val_if_fail (message != NULL, FALSE);
3890  _dbus_return_val_if_fail (!message->locked, FALSE);
3891  _dbus_return_val_if_fail (error_name == NULL ||
3892  _dbus_check_is_valid_error_name (error_name),
3893  FALSE);
3894 
3895  return set_or_delete_string_field (message,
3898  error_name);
3899 }
3900 
3911 const char*
3913 {
3914  const char *v;
3915 
3916  _dbus_return_val_if_fail (message != NULL, NULL);
3917 
3918  v = NULL; /* in case field doesn't exist */
3922  (void *) &v);
3923  return v;
3924 }
3925 
3941  const char *destination)
3942 {
3943  _dbus_return_val_if_fail (message != NULL, FALSE);
3944  _dbus_return_val_if_fail (!message->locked, FALSE);
3945  _dbus_return_val_if_fail (destination == NULL ||
3946  _dbus_check_is_valid_bus_name (destination),
3947  FALSE);
3948 
3949  return set_or_delete_string_field (message,
3952  destination);
3953 }
3954 
3964 const char*
3966 {
3967  const char *v;
3968 
3969  _dbus_return_val_if_fail (message != NULL, NULL);
3970 
3971  v = NULL; /* in case field doesn't exist */
3975  (void *) &v);
3976  return v;
3977 }
3978 
3995  const char *sender)
3996 {
3997  _dbus_return_val_if_fail (message != NULL, FALSE);
3998  _dbus_return_val_if_fail (!message->locked, FALSE);
3999  _dbus_return_val_if_fail (sender == NULL ||
4000  _dbus_check_is_valid_bus_name (sender),
4001  FALSE);
4002 
4003  return set_or_delete_string_field (message,
4006  sender);
4007 }
4008 
4024 const char*
4026 {
4027  const char *v;
4028 
4029  _dbus_return_val_if_fail (message != NULL, NULL);
4030 
4031  v = NULL; /* in case field doesn't exist */
4035  (void *) &v);
4036  return v;
4037 }
4038 
4057 const char*
4059 {
4060  const DBusString *type_str;
4061  int type_pos;
4062 
4063  _dbus_return_val_if_fail (message != NULL, NULL);
4064 
4065  get_const_signature (&message->header, &type_str, &type_pos);
4066 
4067  return _dbus_string_get_const_data_len (type_str, type_pos, 0);
4068 }
4069 
4070 static dbus_bool_t
4071 _dbus_message_has_type_interface_member (DBusMessage *message,
4072  int type,
4073  const char *iface,
4074  const char *member)
4075 {
4076  const char *n;
4077 
4078  _dbus_assert (message != NULL);
4079  _dbus_assert (iface != NULL);
4080  _dbus_assert (member != NULL);
4081 
4082  if (dbus_message_get_type (message) != type)
4083  return FALSE;
4084 
4085  /* Optimize by checking the short member name first
4086  * instead of the longer interface name
4087  */
4088 
4089  n = dbus_message_get_member (message);
4090 
4091  if (n && strcmp (n, member) == 0)
4092  {
4093  n = dbus_message_get_interface (message);
4094 
4095  if (n == NULL || strcmp (n, iface) == 0)
4096  return TRUE;
4097  }
4098 
4099  return FALSE;
4100 }
4101 
4118  const char *iface,
4119  const char *method)
4120 {
4121  _dbus_return_val_if_fail (message != NULL, FALSE);
4122  _dbus_return_val_if_fail (iface != NULL, FALSE);
4123  _dbus_return_val_if_fail (method != NULL, FALSE);
4124  /* don't check that interface/method are valid since it would be
4125  * expensive, and not catch many common errors
4126  */
4127 
4128  return _dbus_message_has_type_interface_member (message,
4130  iface, method);
4131 }
4132 
4146  const char *iface,
4147  const char *signal_name)
4148 {
4149  _dbus_return_val_if_fail (message != NULL, FALSE);
4150  _dbus_return_val_if_fail (iface != NULL, FALSE);
4151  _dbus_return_val_if_fail (signal_name != NULL, FALSE);
4152  /* don't check that interface/name are valid since it would be
4153  * expensive, and not catch many common errors
4154  */
4155 
4156  return _dbus_message_has_type_interface_member (message,
4158  iface, signal_name);
4159 }
4160 
4173  const char *error_name)
4174 {
4175  const char *n;
4176 
4177  _dbus_return_val_if_fail (message != NULL, FALSE);
4178  _dbus_return_val_if_fail (error_name != NULL, FALSE);
4179  /* don't check that error_name is valid since it would be expensive,
4180  * and not catch many common errors
4181  */
4182 
4184  return FALSE;
4185 
4186  n = dbus_message_get_error_name (message);
4187 
4188  if (n && strcmp (n, error_name) == 0)
4189  return TRUE;
4190  else
4191  return FALSE;
4192 }
4193 
4206  const char *name)
4207 {
4208  const char *s;
4209 
4210  _dbus_return_val_if_fail (message != NULL, FALSE);
4211  _dbus_return_val_if_fail (name != NULL, FALSE);
4212  /* don't check that name is valid since it would be expensive, and
4213  * not catch many common errors
4214  */
4215 
4216  s = dbus_message_get_destination (message);
4217 
4218  if (s && strcmp (s, name) == 0)
4219  return TRUE;
4220  else
4221  return FALSE;
4222 }
4223 
4241  const char *name)
4242 {
4243  const char *s;
4244 
4245  _dbus_return_val_if_fail (message != NULL, FALSE);
4246  _dbus_return_val_if_fail (name != NULL, FALSE);
4247  /* don't check that name is valid since it would be expensive, and
4248  * not catch many common errors
4249  */
4250 
4251  s = dbus_message_get_sender (message);
4252 
4253  if (s && strcmp (s, name) == 0)
4254  return TRUE;
4255  else
4256  return FALSE;
4257 }
4258 
4270  const char *signature)
4271 {
4272  const char *s;
4273 
4274  _dbus_return_val_if_fail (message != NULL, FALSE);
4275  _dbus_return_val_if_fail (signature != NULL, FALSE);
4276  /* don't check that signature is valid since it would be expensive,
4277  * and not catch many common errors
4278  */
4279 
4280  s = dbus_message_get_signature (message);
4281 
4282  if (s && strcmp (s, signature) == 0)
4283  return TRUE;
4284  else
4285  return FALSE;
4286 }
4287 
4312  DBusMessage *message)
4313 {
4314  const char *str;
4315 
4316  _dbus_return_val_if_fail (message != NULL, FALSE);
4317  _dbus_return_val_if_error_is_set (error, FALSE);
4318 
4320  return FALSE;
4321 
4322  str = NULL;
4323  dbus_message_get_args (message, NULL,
4324  DBUS_TYPE_STRING, &str,
4326 
4327  dbus_set_error (error, dbus_message_get_error_name (message),
4328  str ? "%s" : NULL, str);
4329 
4330  return TRUE;
4331 }
4332 
4341 {
4342 #ifdef HAVE_UNIX_FD_PASSING
4343  _dbus_assert(message);
4344 
4345  return message->n_unix_fds > 0;
4346 #else
4347  return FALSE;
4348 #endif
4349 }
4350 
4369 #define INITIAL_LOADER_DATA_LEN 32
4370 
4379 {
4380  DBusMessageLoader *loader;
4381 
4382  loader = dbus_new0 (DBusMessageLoader, 1);
4383  if (loader == NULL)
4384  return NULL;
4385 
4386  loader->refcount = 1;
4387 
4388  loader->corrupted = FALSE;
4389  loader->corruption_reason = DBUS_VALID;
4390 
4391  /* this can be configured by the app, but defaults to the protocol max */
4393 
4394  /* We set a very relatively conservative default here since due to how
4395  SCM_RIGHTS works we need to preallocate an fd array of the maximum
4396  number of unix fds we want to receive in advance. A
4397  try-and-reallocate loop is not possible. */
4398  loader->max_message_unix_fds = DBUS_DEFAULT_MESSAGE_UNIX_FDS;
4399 
4400  if (!_dbus_string_init (&loader->data))
4401  {
4402  dbus_free (loader);
4403  return NULL;
4404  }
4405 
4406  /* preallocate the buffer for speed, ignore failure */
4408  _dbus_string_set_length (&loader->data, 0);
4409 
4410 #ifdef HAVE_UNIX_FD_PASSING
4411  loader->unix_fds = NULL;
4412  loader->n_unix_fds = loader->n_unix_fds_allocated = 0;
4413  loader->unix_fds_outstanding = FALSE;
4414 #endif
4415 
4416  return loader;
4417 }
4418 
4427 {
4428  loader->refcount += 1;
4429 
4430  return loader;
4431 }
4432 
4439 void
4441 {
4442  loader->refcount -= 1;
4443  if (loader->refcount == 0)
4444  {
4445 #ifdef HAVE_UNIX_FD_PASSING
4446  close_unix_fds(loader->unix_fds, &loader->n_unix_fds);
4447  dbus_free(loader->unix_fds);
4448 #endif
4449  _dbus_list_foreach (&loader->messages,
4451  NULL);
4452  _dbus_list_clear (&loader->messages);
4453  _dbus_string_free (&loader->data);
4454  dbus_free (loader);
4455  }
4456 }
4457 
4476 void
4478  DBusString **buffer,
4479  int *max_to_read,
4480  dbus_bool_t *may_read_fds)
4481 {
4482  _dbus_assert (!loader->buffer_outstanding);
4483 
4484  *buffer = &loader->data;
4485 
4486  loader->buffer_outstanding = TRUE;
4487 
4488  if (max_to_read != NULL)
4489  {
4490 #ifdef HAVE_UNIX_FD_PASSING
4491  int offset = 0;
4492  int remain;
4493  int byte_order;
4494  int fields_array_len;
4495  int header_len;
4496  int body_len;
4497 #endif
4498 
4499  *max_to_read = DBUS_MAXIMUM_MESSAGE_LENGTH;
4500  *may_read_fds = TRUE;
4501 
4502 #ifdef HAVE_UNIX_FD_PASSING
4503  /* If we aren't holding onto any fds, we can read as much as we want
4504  * (fast path). */
4505  if (loader->n_unix_fds == 0)
4506  return;
4507 
4508  /* Slow path: we have a message with some fds in it. We don't want
4509  * to start on the next message until this one is out of the way;
4510  * otherwise a legitimate sender can keep us processing messages
4511  * containing fds, until we disconnect it for having had fds pending
4512  * for too long, a limit that is in place to stop malicious senders
4513  * from setting up recursive fd-passing that takes up our quota and
4514  * will never go away. */
4515 
4516  remain = _dbus_string_get_length (&loader->data);
4517 
4518  while (remain > 0)
4519  {
4520  DBusValidity validity = DBUS_VALIDITY_UNKNOWN;
4521  int needed;
4522 
4523  /* If 0 < remain < DBUS_MINIMUM_HEADER_SIZE, then we've had at
4524  * least the first byte of a message, but we don't know how
4525  * much more to read. Only read the rest of the
4526  * DBUS_MINIMUM_HEADER_SIZE for now; then we'll know. */
4527  if (remain < DBUS_MINIMUM_HEADER_SIZE)
4528  {
4529  *max_to_read = DBUS_MINIMUM_HEADER_SIZE - remain;
4530  *may_read_fds = FALSE;
4531  return;
4532  }
4533 
4535  &validity,
4536  &byte_order,
4537  &fields_array_len,
4538  &header_len,
4539  &body_len,
4540  &loader->data,
4541  offset,
4542  remain))
4543  {
4544  /* If a message in the buffer is invalid, we're going to
4545  * disconnect the sender anyway, so reading an arbitrary amount
4546  * is fine. */
4547  if (validity != DBUS_VALID)
4548  return;
4549 
4550  /* We have a partial message, with the
4551  * DBUS_MINIMUM_HEADER_SIZE-byte fixed part of the header (which
4552  * lets us work out how much more we need), but no more. Read
4553  * the rest of the message. */
4554  needed = header_len + body_len;
4555  _dbus_assert (needed > remain);
4556  *max_to_read = needed - remain;
4557  *may_read_fds = FALSE;
4558  return;
4559  }
4560 
4561  /* Skip over entire messages until we have less than a message
4562  * remaining. */
4563  needed = header_len + body_len;
4565  _dbus_assert (remain >= needed);
4566  remain -= needed;
4567  offset += needed;
4568  }
4569 #endif
4570  }
4571 }
4572 
4582 void
4584  DBusString *buffer)
4585 {
4586  _dbus_assert (loader->buffer_outstanding);
4587  _dbus_assert (buffer == &loader->data);
4588 
4589  loader->buffer_outstanding = FALSE;
4590 }
4591 
4592 #ifdef HAVE_UNIX_FD_PASSING
4593 
4604 _dbus_message_loader_get_unix_fds(DBusMessageLoader *loader,
4605  int **fds,
4606  unsigned *max_n_fds)
4607 {
4608  _dbus_assert (!loader->unix_fds_outstanding);
4609 
4610  /* Allocate space where we can put the fds we read. We allocate
4611  space for max_message_unix_fds since this is an
4612  upper limit how many fds can be received within a single
4613  message. Since SCM_RIGHTS doesn't allow a reallocate+retry logic
4614  we are allocating the maximum possible array size right from the
4615  beginning. This sucks a bit, however unless SCM_RIGHTS is fixed
4616  there is no better way. */
4617 
4618  if (loader->n_unix_fds_allocated < loader->max_message_unix_fds)
4619  {
4620  int *a = dbus_realloc(loader->unix_fds,
4621  loader->max_message_unix_fds * sizeof(loader->unix_fds[0]));
4622 
4623  if (!a)
4624  return FALSE;
4625 
4626  loader->unix_fds = a;
4627  loader->n_unix_fds_allocated = loader->max_message_unix_fds;
4628  }
4629 
4630  *fds = loader->unix_fds + loader->n_unix_fds;
4631  *max_n_fds = loader->n_unix_fds_allocated - loader->n_unix_fds;
4632 
4633  loader->unix_fds_outstanding = TRUE;
4634  return TRUE;
4635 }
4636 
4647 void
4648 _dbus_message_loader_return_unix_fds(DBusMessageLoader *loader,
4649  int *fds,
4650  unsigned n_fds)
4651 {
4652  _dbus_assert(loader->unix_fds_outstanding);
4653  _dbus_assert(loader->unix_fds + loader->n_unix_fds == fds);
4654  _dbus_assert(loader->n_unix_fds + n_fds <= loader->n_unix_fds_allocated);
4655 
4656  loader->n_unix_fds += n_fds;
4657  loader->unix_fds_outstanding = FALSE;
4658 
4659  if (n_fds && loader->unix_fds_change)
4660  loader->unix_fds_change (loader->unix_fds_change_data);
4661 }
4662 #endif
4663 
4664 /*
4665  * FIXME when we move the header out of the buffer, that memmoves all
4666  * buffered messages. Kind of crappy.
4667  *
4668  * Also we copy the header and body, which is kind of crappy. To
4669  * avoid this, we have to allow header and body to be in a single
4670  * memory block, which is good for messages we read and bad for
4671  * messages we are creating. But we could move_len() the buffer into
4672  * this single memory block, and move_len() will just swap the buffers
4673  * if you're moving the entire buffer replacing the dest string.
4674  *
4675  * We could also have the message loader tell the transport how many
4676  * bytes to read; so it would first ask for some arbitrary number like
4677  * 256, then if the message was incomplete it would use the
4678  * header/body len to ask for exactly the size of the message (or
4679  * blocks the size of a typical kernel buffer for the socket). That
4680  * way we don't get trailing bytes in the buffer that have to be
4681  * memmoved. Though I suppose we also don't have a chance of reading a
4682  * bunch of small messages at once, so the optimization may be stupid.
4683  *
4684  * Another approach would be to keep a "start" index into
4685  * loader->data and only delete it occasionally, instead of after
4686  * each message is loaded.
4687  *
4688  * load_message() returns FALSE if not enough memory OR the loader was corrupted
4689  */
4690 static dbus_bool_t
4691 load_message (DBusMessageLoader *loader,
4692  DBusMessage *message,
4693  int byte_order,
4694  int fields_array_len,
4695  int header_len,
4696  int body_len)
4697 {
4698  dbus_bool_t oom;
4699  DBusValidity validity;
4700  const DBusString *type_str;
4701  int type_pos;
4702  DBusValidationMode mode;
4703  dbus_uint32_t n_unix_fds = 0;
4704 
4705  mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
4706 
4707  oom = FALSE;
4708 
4709 #if 0
4710  _dbus_verbose_bytes_of_string (&loader->data, 0, header_len /* + body_len */);
4711 #endif
4712 
4713  /* 1. VALIDATE AND COPY OVER HEADER */
4714  _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
4715  _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
4716 
4717  if (!_dbus_header_load (&message->header,
4718  mode,
4719  &validity,
4720  byte_order,
4721  fields_array_len,
4722  header_len,
4723  body_len,
4724  &loader->data, 0,
4725  _dbus_string_get_length (&loader->data)))
4726  {
4727  _dbus_verbose ("Failed to load header for new message code %d\n", validity);
4728 
4729  /* assert here so we can catch any code that still uses DBUS_VALID to indicate
4730  oom errors. They should use DBUS_VALIDITY_UNKNOWN_OOM_ERROR instead */
4731  _dbus_assert (validity != DBUS_VALID);
4732 
4733  if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
4734  oom = TRUE;
4735  else
4736  {
4737  loader->corrupted = TRUE;
4738  loader->corruption_reason = validity;
4739  }
4740  goto failed;
4741  }
4742 
4743  _dbus_assert (validity == DBUS_VALID);
4744 
4745  /* 2. VALIDATE BODY */
4746  if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
4747  {
4748  get_const_signature (&message->header, &type_str, &type_pos);
4749 
4750  /* Because the bytes_remaining arg is NULL, this validates that the
4751  * body is the right length
4752  */
4753  validity = _dbus_validate_body_with_reason (type_str,
4754  type_pos,
4755  byte_order,
4756  NULL,
4757  &loader->data,
4758  header_len,
4759  body_len);
4760  if (validity != DBUS_VALID)
4761  {
4762  _dbus_verbose ("Failed to validate message body code %d\n", validity);
4763 
4764  loader->corrupted = TRUE;
4765  loader->corruption_reason = validity;
4766 
4767  goto failed;
4768  }
4769  }
4770 
4771  /* 3. COPY OVER UNIX FDS */
4775  &n_unix_fds);
4776 
4777 #ifdef HAVE_UNIX_FD_PASSING
4778 
4779  if (n_unix_fds > loader->n_unix_fds)
4780  {
4781  _dbus_verbose("Message contains references to more unix fds than were sent %u != %u\n",
4782  n_unix_fds, loader->n_unix_fds);
4783 
4784  loader->corrupted = TRUE;
4785  loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4786  goto failed;
4787  }
4788 
4789  /* If this was a recycled message there might still be
4790  some memory allocated for the fds */
4791  dbus_free(message->unix_fds);
4792 
4793  if (n_unix_fds > 0)
4794  {
4795  message->unix_fds = _dbus_memdup(loader->unix_fds, n_unix_fds * sizeof(message->unix_fds[0]));
4796  if (message->unix_fds == NULL)
4797  {
4798  _dbus_verbose ("Failed to allocate file descriptor array\n");
4799  oom = TRUE;
4800  goto failed;
4801  }
4802 
4803  message->n_unix_fds_allocated = message->n_unix_fds = n_unix_fds;
4804  loader->n_unix_fds -= n_unix_fds;
4805  memmove (loader->unix_fds, loader->unix_fds + n_unix_fds, loader->n_unix_fds * sizeof (loader->unix_fds[0]));
4806 
4807  if (loader->unix_fds_change)
4808  loader->unix_fds_change (loader->unix_fds_change_data);
4809  }
4810  else
4811  message->unix_fds = NULL;
4812 
4813 #else
4814 
4815  if (n_unix_fds > 0)
4816  {
4817  _dbus_verbose ("Hmm, message claims to come with file descriptors "
4818  "but that's not supported on our platform, disconnecting.\n");
4819 
4820  loader->corrupted = TRUE;
4821  loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4822  goto failed;
4823  }
4824 
4825 #endif
4826 
4827  /* 3. COPY OVER BODY AND QUEUE MESSAGE */
4828 
4829  if (!_dbus_list_append (&loader->messages, message))
4830  {
4831  _dbus_verbose ("Failed to append new message to loader queue\n");
4832  oom = TRUE;
4833  goto failed;
4834  }
4835 
4836  _dbus_assert (_dbus_string_get_length (&message->body) == 0);
4837  _dbus_assert (_dbus_string_get_length (&loader->data) >=
4838  (header_len + body_len));
4839 
4840  if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
4841  {
4842  _dbus_verbose ("Failed to move body into new message\n");
4843  oom = TRUE;
4844  goto failed;
4845  }
4846 
4847  _dbus_string_delete (&loader->data, 0, header_len + body_len);
4848 
4849  /* don't waste more than 2k of memory */
4850  _dbus_string_compact (&loader->data, 2048);
4851 
4852  _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
4853  _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
4854 
4855  _dbus_verbose ("Loaded message %p\n", message);
4856 
4857  _dbus_assert (!oom);
4858  _dbus_assert (!loader->corrupted);
4859  _dbus_assert (loader->messages != NULL);
4860  _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4861 
4862  return TRUE;
4863 
4864  failed:
4865 
4866  /* Clean up */
4867 
4868  /* does nothing if the message isn't in the list */
4869  _dbus_list_remove_last (&loader->messages, message);
4870 
4871  if (oom)
4872  _dbus_assert (!loader->corrupted);
4873  else
4874  _dbus_assert (loader->corrupted);
4875 
4876  _dbus_verbose_bytes_of_string (&loader->data, 0, _dbus_string_get_length (&loader->data));
4877 
4878  return FALSE;
4879 }
4880 
4897 {
4898  while (!loader->corrupted &&
4899  _dbus_string_get_length (&loader->data) >= DBUS_MINIMUM_HEADER_SIZE)
4900  {
4901  DBusValidity validity;
4902  int byte_order, fields_array_len, header_len, body_len;
4903 
4905  &validity,
4906  &byte_order,
4907  &fields_array_len,
4908  &header_len,
4909  &body_len,
4910  &loader->data, 0,
4911  _dbus_string_get_length (&loader->data)))
4912  {
4913  DBusMessage *message;
4914 
4915  _dbus_assert (validity == DBUS_VALID);
4916 
4917  message = dbus_message_new_empty_header ();
4918  if (message == NULL)
4919  return FALSE;
4920 
4921  if (!load_message (loader, message,
4922  byte_order, fields_array_len,
4923  header_len, body_len))
4924  {
4925  dbus_message_unref (message);
4926  /* load_message() returns false if corrupted or OOM; if
4927  * corrupted then return TRUE for not OOM
4928  */
4929  return loader->corrupted;
4930  }
4931 
4932  _dbus_assert (loader->messages != NULL);
4933  _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4934  }
4935  else
4936  {
4937  _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
4938  validity);
4939  if (validity != DBUS_VALID)
4940  {
4941  loader->corrupted = TRUE;
4942  loader->corruption_reason = validity;
4943  }
4944  return TRUE;
4945  }
4946  }
4947 
4948  return TRUE;
4949 }
4950 
4958 DBusMessage*
4960 {
4961  if (loader->messages)
4962  return loader->messages->data;
4963  else
4964  return NULL;
4965 }
4966 
4975 DBusMessage*
4977 {
4978  return _dbus_list_pop_first (&loader->messages);
4979 }
4980 
4989 DBusList*
4991 {
4992  return _dbus_list_pop_first_link (&loader->messages);
4993 }
4994 
5001 void
5003  DBusList *link)
5004 {
5005  _dbus_list_prepend_link (&loader->messages, link);
5006 }
5007 
5019 {
5020  _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
5021  (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
5022  return loader->corrupted;
5023 }
5024 
5033 {
5034  _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
5035  (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
5036 
5037  return loader->corruption_reason;
5038 }
5039 
5046 void
5048  long size)
5049 {
5050  if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
5051  {
5052  _dbus_verbose ("clamping requested max message size %ld to %d\n",
5055  }
5056  loader->max_message_size = size;
5057 }
5058 
5065 long
5067 {
5068  return loader->max_message_size;
5069 }
5070 
5077 void
5079  long n)
5080 {
5082  {
5083  _dbus_verbose ("clamping requested max message unix_fds %ld to %d\n",
5086  }
5087  loader->max_message_unix_fds = n;
5088 }
5089 
5096 long
5098 {
5099  return loader->max_message_unix_fds;
5100 }
5101 
5107 int
5109 {
5110 #ifdef HAVE_UNIX_FD_PASSING
5111  return loader->n_unix_fds;
5112 #else
5113  return 0;
5114 #endif
5115 }
5116 
5125 void
5127  void (* callback) (void *),
5128  void *data)
5129 {
5130 #ifdef HAVE_UNIX_FD_PASSING
5131  loader->unix_fds_change = callback;
5132  loader->unix_fds_change_data = data;
5133 #endif
5134 }
5135 
5136 static DBusDataSlotAllocator slot_allocator =
5137  _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (message_slots));
5138 
5154 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
5155 {
5156  return _dbus_data_slot_allocator_alloc (&slot_allocator,
5157  slot_p);
5158 }
5159 
5171 void
5172 dbus_message_free_data_slot (dbus_int32_t *slot_p)
5173 {
5174  _dbus_return_if_fail (*slot_p >= 0);
5175 
5176  _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
5177 }
5178 
5194  dbus_int32_t slot,
5195  void *data,
5196  DBusFreeFunction free_data_func)
5197 {
5198  DBusFreeFunction old_free_func;
5199  void *old_data;
5200  dbus_bool_t retval;
5201 
5202  _dbus_return_val_if_fail (message != NULL, FALSE);
5203  _dbus_return_val_if_fail (slot >= 0, FALSE);
5204 
5205  retval = _dbus_data_slot_list_set (&slot_allocator,
5206  &message->slot_list,
5207  slot, data, free_data_func,
5208  &old_free_func, &old_data);
5209 
5210  if (retval)
5211  {
5212  /* Do the actual free outside the message lock */
5213  if (old_free_func)
5214  (* old_free_func) (old_data);
5215  }
5216 
5217  return retval;
5218 }
5219 
5228 void*
5230  dbus_int32_t slot)
5231 {
5232  void *res;
5233 
5234  _dbus_return_val_if_fail (message != NULL, NULL);
5235 
5236  res = _dbus_data_slot_list_get (&slot_allocator,
5237  &message->slot_list,
5238  slot);
5239 
5240  return res;
5241 }
5242 
5256 int
5257 dbus_message_type_from_string (const char *type_str)
5258 {
5259  if (strcmp (type_str, "method_call") == 0)
5261  if (strcmp (type_str, "method_return") == 0)
5263  else if (strcmp (type_str, "signal") == 0)
5264  return DBUS_MESSAGE_TYPE_SIGNAL;
5265  else if (strcmp (type_str, "error") == 0)
5266  return DBUS_MESSAGE_TYPE_ERROR;
5267  else
5269 }
5270 
5284 const char *
5286 {
5287  switch (type)
5288  {
5290  return "method_call";
5292  return "method_return";
5294  return "signal";
5296  return "error";
5297  default:
5298  return "invalid";
5299  }
5300 }
5301 
5316  char **marshalled_data_p,
5317  int *len_p)
5318 {
5319  DBusString tmp;
5320  dbus_bool_t was_locked;
5321 
5322  _dbus_return_val_if_fail (msg != NULL, FALSE);
5323  _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
5324  _dbus_return_val_if_fail (len_p != NULL, FALSE);
5325 
5326  if (!_dbus_string_init (&tmp))
5327  return FALSE;
5328 
5329  /* Ensure the message is locked, to ensure the length header is filled in. */
5330  was_locked = msg->locked;
5331 
5332  if (!was_locked)
5333  dbus_message_lock (msg);
5334 
5335  if (!_dbus_string_copy (&(msg->header.data), 0, &tmp, 0))
5336  goto fail;
5337 
5338  *len_p = _dbus_string_get_length (&tmp);
5339 
5340  if (!_dbus_string_copy (&(msg->body), 0, &tmp, *len_p))
5341  goto fail;
5342 
5343  *len_p = _dbus_string_get_length (&tmp);
5344 
5345  if (!_dbus_string_steal_data (&tmp, marshalled_data_p))
5346  goto fail;
5347 
5348  _dbus_string_free (&tmp);
5349 
5350  if (!was_locked)
5351  msg->locked = FALSE;
5352 
5353  return TRUE;
5354 
5355  fail:
5356  _dbus_string_free (&tmp);
5357 
5358  if (!was_locked)
5359  msg->locked = FALSE;
5360 
5361  return FALSE;
5362 }
5363 
5376 DBusMessage *
5377 dbus_message_demarshal (const char *str,
5378  int len,
5379  DBusError *error)
5380 {
5381  DBusMessageLoader *loader;
5382  DBusString *buffer;
5383  DBusMessage *msg;
5384 
5385  _dbus_return_val_if_fail (str != NULL, NULL);
5386 
5387  loader = _dbus_message_loader_new ();
5388 
5389  if (loader == NULL)
5390  return NULL;
5391 
5392  _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL);
5393 
5394  if (!_dbus_string_append_len (buffer, str, len))
5395  goto fail_oom;
5396 
5397  _dbus_message_loader_return_buffer (loader, buffer);
5398 
5400  goto fail_oom;
5401 
5403  goto fail_corrupt;
5404 
5405  msg = _dbus_message_loader_pop_message (loader);
5406 
5407  if (!msg)
5408  goto fail_oom;
5409 
5410  _dbus_message_loader_unref (loader);
5411  return msg;
5412 
5413  fail_corrupt:
5414  dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted (%s)",
5415  _dbus_validity_to_error_message (loader->corruption_reason));
5416  _dbus_message_loader_unref (loader);
5417  return NULL;
5418 
5419  fail_oom:
5420  _DBUS_SET_OOM (error);
5421  _dbus_message_loader_unref (loader);
5422  return NULL;
5423 }
5424 
5437 int
5439  int len)
5440 {
5441  DBusString str;
5442  int byte_order, fields_array_len, header_len, body_len;
5443  DBusValidity validity = DBUS_VALID;
5444  int have_message;
5445 
5446  if (!buf || len < DBUS_MINIMUM_HEADER_SIZE)
5447  return 0;
5448 
5449  if (len > DBUS_MAXIMUM_MESSAGE_LENGTH)
5451  _dbus_string_init_const_len (&str, buf, len);
5452 
5453  validity = DBUS_VALID;
5454  have_message
5456  &validity, &byte_order,
5457  &fields_array_len,
5458  &header_len,
5459  &body_len,
5460  &str, 0,
5461  len);
5462  _dbus_string_free (&str);
5463 
5464  if (validity == DBUS_VALID)
5465  {
5466  _dbus_assert (have_message || (header_len + body_len) > len);
5467  (void) have_message; /* unused unless asserting */
5468  return header_len + body_len;
5469  }
5470  else
5471  {
5472  return -1; /* broken! */
5473  }
5474 }
5475 
5497 void
5499  dbus_bool_t allow)
5500 {
5501  _dbus_return_if_fail (message != NULL);
5502  _dbus_return_if_fail (!message->locked);
5503 
5504  _dbus_header_toggle_flag (&message->header,
5506  allow);
5507 }
5508 
5517 {
5518  _dbus_return_val_if_fail (message != NULL, FALSE);
5519 
5520  return _dbus_header_get_flag (&message->header,
5522 }
5523 
5531 {
5532  DBusString data;
5533 };
5534 
5546 DBusVariant *
5548 {
5549  DBusVariant *self = NULL;
5550  /* Points to the single item we will read from the reader */
5551  DBusMessageRealIter *real_reader = (DBusMessageRealIter *) reader;
5552  /* The position in self at which we will write a single variant
5553  * (it is position 0) */
5554  DBusTypeWriter items_writer;
5555  /* The position in self at which we will write a copy of reader
5556  * (it is inside the variant) */
5557  DBusTypeWriter variant_writer;
5558  /* 'v' */
5559  DBusString variant_signature;
5560  /* Whatever is the signature of the item we will copy from the reader */
5561  DBusString contained_signature;
5562  /* TRUE if self->data needs to be freed */
5563  dbus_bool_t data_inited = FALSE;
5564  /* The type of the item we will read from the reader */
5565  int type;
5566  /* The string, start position within that string, and length of the signature
5567  * of the single complete type of the item reader points to */
5568  const DBusString *sig;
5569  int start, len;
5570 
5571  _dbus_assert (_dbus_message_iter_check (real_reader));
5572  _dbus_assert (real_reader->iter_type == DBUS_MESSAGE_ITER_TYPE_READER);
5574  type = dbus_message_iter_get_arg_type (reader);
5575  _dbus_type_reader_get_signature (&real_reader->u.reader, &sig, &start, &len);
5576 
5577  if (!_dbus_string_init (&contained_signature))
5578  return NULL;
5579 
5580  if (!_dbus_string_copy_len (sig, start, len, &contained_signature, 0))
5581  goto oom;
5582 
5583  self = dbus_new0 (DBusVariant, 1);
5584 
5585  if (self == NULL)
5586  goto oom;
5587 
5588  if (!_dbus_string_init (&self->data))
5589  goto oom;
5590 
5591  data_inited = TRUE;
5592 
5593  _dbus_type_writer_init_values_only (&items_writer, DBUS_COMPILER_BYTE_ORDER,
5594  &variant_signature, 0, &self->data, 0);
5595 
5596  if (!_dbus_type_writer_recurse (&items_writer, DBUS_TYPE_VARIANT,
5597  &contained_signature, 0, &variant_writer))
5598  goto oom;
5599 
5600  if (type == DBUS_TYPE_ARRAY)
5601  {
5602  /* Points to each item in turn inside the array we are copying */
5603  DBusMessageIter array_reader;
5604  /* Same as array_reader */
5605  DBusMessageRealIter *real_array_reader = (DBusMessageRealIter *) &array_reader;
5606  /* The position inside the copied array at which we will write
5607  * the copy of array_reader */
5608  DBusTypeWriter array_writer;
5609 
5610  dbus_message_iter_recurse (reader, &array_reader);
5611 
5612  if (!_dbus_type_writer_recurse (&variant_writer, type,
5613  &contained_signature, 1, &array_writer))
5614  goto oom;
5615 
5616  if (!_dbus_type_writer_write_reader (&array_writer,
5617  &real_array_reader->u.reader))
5618  goto oom;
5619 
5620  if (!_dbus_type_writer_unrecurse (&variant_writer, &array_writer))
5621  goto oom;
5622  }
5623  else if (type == DBUS_TYPE_DICT_ENTRY || type == DBUS_TYPE_VARIANT ||
5624  type == DBUS_TYPE_STRUCT)
5625  {
5626  /* Points to each item in turn inside the container we are copying */
5627  DBusMessageIter inner_reader;
5628  /* Same as inner_reader */
5629  DBusMessageRealIter *real_inner_reader = (DBusMessageRealIter *) &inner_reader;
5630  /* The position inside the copied container at which we will write the
5631  * copy of inner_reader */
5632  DBusTypeWriter inner_writer;
5633 
5634  dbus_message_iter_recurse (reader, &inner_reader);
5635 
5636  if (!_dbus_type_writer_recurse (&variant_writer, type, NULL, 0,
5637  &inner_writer))
5638  goto oom;
5639 
5640  if (!_dbus_type_writer_write_reader (&inner_writer,
5641  &real_inner_reader->u.reader))
5642  goto oom;
5643 
5644  if (!_dbus_type_writer_unrecurse (&variant_writer, &inner_writer))
5645  goto oom;
5646  }
5647  else
5648  {
5649  DBusBasicValue value;
5650 
5651  /* We eliminated all the container types above */
5653 
5654  dbus_message_iter_get_basic (reader, &value);
5655 
5656  if (!_dbus_type_writer_write_basic (&variant_writer, type, &value))
5657  goto oom;
5658  }
5659 
5660  _dbus_string_free (&contained_signature);
5661  return self;
5662 
5663 oom:
5664  if (self != NULL)
5665  {
5666  if (data_inited)
5667  _dbus_string_free (&self->data);
5668 
5669  dbus_free (self);
5670  }
5671 
5672  _dbus_string_free (&contained_signature);
5673  return NULL;
5674 }
5675 
5682 const char *
5684 {
5685  unsigned char len;
5686  const char *ret;
5687 
5688  _dbus_assert (self != NULL);
5689 
5690  /* Here we make use of the fact that the serialization of a variant starts
5691  * with the 1-byte length, then that many bytes of signature, then \0. */
5692  len = _dbus_string_get_byte (&self->data, 0);
5693  ret = _dbus_string_get_const_data_len (&self->data, 1, len);
5694  _dbus_assert (strlen (ret) == len);
5695  return ret;
5696 }
5697 
5711  DBusMessageIter *writer)
5712 {
5713  /* 'v' */
5714  DBusString variant_signature;
5715  /* Points to the single item in self */
5716  DBusTypeReader variant_reader;
5717  /* Points to the single item (of whatever type) inside the variant */
5718  DBusTypeReader reader;
5719  /* The position at which we will copy reader */
5720  DBusMessageRealIter *real_writer = (DBusMessageRealIter *) writer;
5721  dbus_bool_t ret;
5722 
5723  _dbus_assert (self != NULL);
5724  _dbus_assert (_dbus_message_iter_append_check (real_writer));
5725  _dbus_assert (real_writer->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
5726 
5728  _dbus_type_reader_init (&reader, DBUS_COMPILER_BYTE_ORDER,
5729  &variant_signature, 0, &self->data, 0);
5730  _dbus_type_reader_recurse (&reader, &variant_reader);
5731 
5732  if (!_dbus_message_iter_open_signature (real_writer))
5733  return FALSE;
5734 
5735  ret = _dbus_type_writer_write_reader (&real_writer->u.writer,
5736  &variant_reader);
5737 
5738  if (!_dbus_message_iter_close_signature (real_writer))
5739  return FALSE;
5740 
5741  return ret;
5742 }
5743 
5744 int
5745 _dbus_variant_get_length (DBusVariant *self)
5746 {
5747  _dbus_assert (self != NULL);
5748  return _dbus_string_get_length (&self->data);
5749 }
5750 
5751 const DBusString *
5752 _dbus_variant_peek (DBusVariant *self)
5753 {
5754  _dbus_assert (self != NULL);
5755  return &self->data;
5756 }
5757 
5758 void
5759 _dbus_variant_free (DBusVariant *self)
5760 {
5761  _dbus_assert (self != NULL);
5762  _dbus_string_free (&self->data);
5763  dbus_free (self);
5764 }
5765 
5768 /* tests in dbus-message-util.c */
DBUS_TYPE_ARRAY
#define DBUS_TYPE_ARRAY
Type code marking a D-Bus array type.
Definition: dbus-protocol.h:120
_dbus_data_slot_list_clear
void _dbus_data_slot_list_clear(DBusDataSlotList *list)
Frees all data slots contained in the list, calling application-provided free functions if they exist...
Definition: dbus-dataslot.c:317
_dbus_atomic_dec
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
Definition: dbus-sysdeps-unix.c:2847
DBUS_TYPE_STRING
#define DBUS_TYPE_STRING
Type code marking a UTF-8 encoded, nul-terminated Unicode string.
Definition: dbus-protocol.h:102
dbus_message_set_no_reply
void dbus_message_set_no_reply(DBusMessage *message, dbus_bool_t no_reply)
Sets a flag indicating that the message does not want a reply; if this flag is set,...
Definition: dbus-message.c:3499
_dbus_data_slot_list_get
void * _dbus_data_slot_list_get(DBusDataSlotAllocator *allocator, DBusDataSlotList *list, int slot)
Retrieves data previously set with _dbus_data_slot_list_set_data().
Definition: dbus-dataslot.c:285
dbus_message_set_interface
dbus_bool_t dbus_message_set_interface(DBusMessage *message, const char *iface)
Sets the interface this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or the interface...
Definition: dbus-message.c:3713
dbus_message_get_allow_interactive_authorization
dbus_bool_t dbus_message_get_allow_interactive_authorization(DBusMessage *message)
Returns whether the flag controlled by dbus_message_set_allow_interactive_authorization() has been se...
Definition: dbus-message.c:5516
DBusMessageLoader::messages
DBusList * messages
Complete messages.
Definition: dbus-message-private.h:66
_dbus_type_reader_next
dbus_bool_t _dbus_type_reader_next(DBusTypeReader *reader)
Skip to the next value on this "level".
Definition: dbus-marshal-recursive.c:1055
DBusHeader::data
DBusString data
Header network data, stored separately from body so we can independently realloc it.
Definition: dbus-marshal-header.h:49
MAX_MESSAGE_SIZE_TO_CACHE
#define MAX_MESSAGE_SIZE_TO_CACHE
Avoid caching huge messages.
Definition: dbus-message.c:495
DBusValidationMode
DBusValidationMode
This is used rather than a bool for high visibility.
Definition: dbus-marshal-validate.h:36
DBUS_TYPE_INVALID
#define DBUS_TYPE_INVALID
Type code that is never equal to a legitimate type code.
Definition: dbus-protocol.h:60
DBUS_VALID
@ DBUS_VALID
the data is valid
Definition: dbus-marshal-validate.h:56
dbus_realloc
void * dbus_realloc(void *memory, size_t bytes)
Resizes a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:602
dbus_message_iter_close_container
dbus_bool_t dbus_message_iter_close_container(DBusMessageIter *iter, DBusMessageIter *sub)
Closes a container-typed value appended to the message; may write out more information to the message...
Definition: dbus-message.c:3341
_dbus_list_find_last
DBusList * _dbus_list_find_last(DBusList **list, void *data)
Finds a value in the list.
Definition: dbus-list.c:472
_dbus_message_loader_get_corruption_reason
DBusValidity _dbus_message_loader_get_corruption_reason(DBusMessageLoader *loader)
Checks what kind of bad data confused the loader.
Definition: dbus-message.c:5032
_dbus_header_update_lengths
void _dbus_header_update_lengths(DBusHeader *header, int body_len)
Fills in the correct body length.
Definition: dbus-marshal-header.c:1196
_dbus_verbose_bytes_of_string
DBUS_PRIVATE_EXPORT void _dbus_verbose_bytes_of_string(const DBusString *str, int start, int len)
Dump the given part of the string to verbose log.
Definition: dbus-marshal-basic.c:1362
dbus_message_ref
DBusMessage * dbus_message_ref(DBusMessage *message)
Increments the reference count of a DBusMessage.
Definition: dbus-message.c:1980
_dbus_list_remove_link
void _dbus_list_remove_link(DBusList **list, DBusList *link)
Removes a link from the list.
Definition: dbus-list.c:527
_dbus_message_loader_set_max_message_unix_fds
void _dbus_message_loader_set_max_message_unix_fds(DBusMessageLoader *loader, long n)
Sets the maximum unix fds per message we allow.
Definition: dbus-message.c:5078
_dbus_type_writer_init_values_only
void _dbus_type_writer_init_values_only(DBusTypeWriter *writer, int byte_order, const DBusString *type_str, int type_pos, DBusString *value_str, int value_pos)
Like _dbus_type_writer_init(), except the type string passed in should correspond to an existing sign...
Definition: dbus-marshal-recursive.c:1585
dbus_message_is_method_call
dbus_bool_t dbus_message_is_method_call(DBusMessage *message, const char *iface, const char *method)
Checks whether the message is a method call with the given interface and member fields.
Definition: dbus-message.c:4117
dbus_message_set_allow_interactive_authorization
void dbus_message_set_allow_interactive_authorization(DBusMessage *message, dbus_bool_t allow)
Sets a flag indicating that the caller of the method is prepared to wait for interactive authorizatio...
Definition: dbus-message.c:5498
DBusMessageRealIter::sig_refcount
dbus_uint32_t sig_refcount
depth of open_signature()
Definition: dbus-message.c:142
_dbus_string_free
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:259
_dbus_current_generation
int _dbus_current_generation
_dbus_current_generation is used to track each time that dbus_shutdown() is called,...
Definition: dbus-memory.c:782
dbus_message_iter_append_fixed_array
dbus_bool_t dbus_message_iter_append_fixed_array(DBusMessageIter *iter, int element_type, const void *value, int n_elements)
Appends a block of fixed-length values to an array.
Definition: dbus-message.c:3174
_dbus_list_append_link
void _dbus_list_append_link(DBusList **list, DBusList *link)
Appends a link to the list.
Definition: dbus-list.c:315
dbus_message_get_path
const char * dbus_message_get_path(DBusMessage *message)
Gets the object path this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitt...
Definition: dbus-message.c:3611
_dbus_message_loader_queue_messages
dbus_bool_t _dbus_message_loader_queue_messages(DBusMessageLoader *loader)
Converts buffered data into messages, if we have enough data.
Definition: dbus-message.c:4896
dbus_message_iter_open_container
dbus_bool_t dbus_message_iter_open_container(DBusMessageIter *iter, int type, const char *contained_signature, DBusMessageIter *sub)
Appends a container-typed value to the message.
Definition: dbus-message.c:3238
DBusMessageRealIter::u
union DBusMessageRealIter::@6 u
the type writer or reader that does all the work
_dbus_message_loader_get_pending_fds_count
int _dbus_message_loader_get_pending_fds_count(DBusMessageLoader *loader)
Return how many file descriptors are pending in the loader.
Definition: dbus-message.c:5108
_dbus_message_get_unix_fds
void _dbus_message_get_unix_fds(DBusMessage *message, const int **fds, unsigned *n_fds)
Gets the unix fds to be sent over the network for this message.
Definition: dbus-message.c:261
_dbus_list_clear
void _dbus_list_clear(DBusList **list)
Frees all links in the list and sets the list head to NULL.
Definition: dbus-list.c:542
dbus_message_demarshal_bytes_needed
int dbus_message_demarshal_bytes_needed(const char *buf, int len)
Returns the number of bytes required to be in the buffer to demarshal a D-Bus message.
Definition: dbus-message.c:5438
dbus_message_unref
void dbus_message_unref(DBusMessage *message)
Decrements the reference count of a DBusMessage, freeing the message if the count reaches 0.
Definition: dbus-message.c:2003
dbus_message_new_method_return
DBusMessage * dbus_message_new_method_return(DBusMessage *method_call)
Constructs a message that is a reply to a method call.
Definition: dbus-message.c:1686
DBUS_HEADER_FIELD_SENDER
#define DBUS_HEADER_FIELD_SENDER
Header field code for the sender of a message; usually initialized by the message bus.
Definition: dbus-protocol.h:293
DBUS_TYPE_UNIX_FD
#define DBUS_TYPE_UNIX_FD
Type code marking a unix file descriptor.
Definition: dbus-protocol.h:114
_dbus_string_compact
dbus_bool_t _dbus_string_compact(DBusString *str, int max_waste)
Compacts the string to avoid wasted memory.
Definition: dbus-string.c:389
_dbus_type_writer_recurse
dbus_bool_t _dbus_type_writer_recurse(DBusTypeWriter *writer, int container_type, const DBusString *contained_type, int contained_type_start, DBusTypeWriter *sub)
Opens a new container and writes out the initial information for that container.
Definition: dbus-marshal-recursive.c:2110
_dbus_type_reader_has_next
dbus_bool_t _dbus_type_reader_has_next(const DBusTypeReader *reader)
Check whether there's another value on this "level".
Definition: dbus-marshal-recursive.c:1095
_dbus_message_add_counter
dbus_bool_t _dbus_message_add_counter(DBusMessage *message, DBusCounter *counter)
Adds a counter to be incremented immediately with the size/unix fds of this message,...
Definition: dbus-message.c:363
DBusMessageLoader::buffer_outstanding
unsigned int buffer_outstanding
Someone is using the buffer to read.
Definition: dbus-message-private.h:75
DBusMessageLoader::max_message_size
long max_message_size
Maximum size of a message.
Definition: dbus-message-private.h:68
_dbus_type_reader_get_element_type
int _dbus_type_reader_get_element_type(const DBusTypeReader *reader)
Gets the type of an element of the array the reader is currently pointing to.
Definition: dbus-marshal-recursive.c:821
DBUS_TYPE_VARIANT_AS_STRING
#define DBUS_TYPE_VARIANT_AS_STRING
DBUS_TYPE_VARIANT as a string literal instead of a int literal
Definition: dbus-protocol.h:126
DBusFreeFunction
void(* DBusFreeFunction)(void *memory)
Definition: dbus-memory.h:63
DBUS_HEADER_FIELD_PATH
#define DBUS_HEADER_FIELD_PATH
Header field code for the path - the path is the object emitting a signal or the object receiving a m...
Definition: dbus-protocol.h:270
dbus_message_type_to_string
const char * dbus_message_type_to_string(int type)
Utility function to convert a D-Bus message type into a machine-readable string (not translated).
Definition: dbus-message.c:5285
dbus_message_get_args_valist
dbus_bool_t dbus_message_get_args_valist(DBusMessage *message, DBusError *error, int first_arg_type, va_list var_args)
Like dbus_message_get_args but takes a va_list for use by language bindings.
Definition: dbus-message.c:2323
dbus_message_contains_unix_fds
dbus_bool_t dbus_message_contains_unix_fds(DBusMessage *message)
Checks whether a message contains unix fds.
Definition: dbus-message.c:4340
_dbus_list_alloc_link
DBusList * _dbus_list_alloc_link(void *data)
Allocates a linked list node.
Definition: dbus-list.c:242
_dbus_counter_unref
void _dbus_counter_unref(DBusCounter *counter)
Decrements refcount of the counter and possibly finalizes the counter.
Definition: dbus-resources.c:136
_dbus_type_writer_init_types_delayed
void _dbus_type_writer_init_types_delayed(DBusTypeWriter *writer, int byte_order, DBusString *value_str, int value_pos)
Initialize a write iterator, with the signature to be provided later.
Definition: dbus-marshal-recursive.c:1529
_dbus_header_set_serial
void _dbus_header_set_serial(DBusHeader *header, dbus_uint32_t serial)
Sets the serial number of a header.
Definition: dbus-marshal-header.c:404
_dbus_string_copy
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that's copied to the d...
Definition: dbus-string.c:1283
DBusTypeWriter::type_str
DBusString * type_str
where to write typecodes (or read type expectations)
Definition: dbus-marshal-recursive.h:74
DBusMessageLoader::corruption_reason
DBusValidity corruption_reason
why we were corrupted
Definition: dbus-message-private.h:71
DBusTypeReader::byte_order
dbus_uint32_t byte_order
byte order of the block
Definition: dbus-marshal-recursive.h:41
_dbus_message_loader_putback_message_link
void _dbus_message_loader_putback_message_link(DBusMessageLoader *loader, DBusList *link)
Returns a popped message link, used to undo a pop.
Definition: dbus-message.c:5002
_dbus_type_reader_read_basic
void _dbus_type_reader_read_basic(const DBusTypeReader *reader, void *value)
Reads a basic-typed value, as with _dbus_marshal_read_basic().
Definition: dbus-marshal-recursive.c:870
_dbus_counter_adjust_unix_fd
void _dbus_counter_adjust_unix_fd(DBusCounter *counter, long delta)
Adjusts the value of the unix fd counter by the given delta which may be positive or negative.
Definition: dbus-resources.c:236
_dbus_message_remove_counter
void _dbus_message_remove_counter(DBusMessage *message, DBusCounter *counter)
Removes a counter tracking the size/unix fds of this message, and decrements the counter by the size/...
Definition: dbus-message.c:386
DBusMessageLoader::corrupted
unsigned int corrupted
We got broken data, and are no longer working.
Definition: dbus-message-private.h:73
_dbus_header_delete_field
dbus_bool_t _dbus_header_delete_field(DBusHeader *header, int field)
Deletes a field, if it exists.
Definition: dbus-marshal-header.c:1416
dbus_message_new
DBusMessage * dbus_message_new(int message_type)
Constructs a new message of the given message type.
Definition: dbus-message.c:1322
_dbus_header_get_serial
dbus_uint32_t _dbus_header_get_serial(DBusHeader *header)
See dbus_message_get_serial()
Definition: dbus-marshal-header.c:427
_dbus_type_get_alignment
int _dbus_type_get_alignment(int typecode)
Gets the alignment requirement for the given type; will be 1, 4, or 8.
Definition: dbus-marshal-basic.c:1177
_dbus_validate_body_with_reason
DBusValidity _dbus_validate_body_with_reason(const DBusString *expected_signature, int expected_signature_start, int byte_order, int *bytes_remaining, const DBusString *value_str, int value_pos, int len)
Verifies that the range of value_str from value_pos to value_end is a legitimate value of type expect...
Definition: dbus-marshal-validate.c:708
dbus_message_iter_init
dbus_bool_t dbus_message_iter_init(DBusMessage *message, DBusMessageIter *iter)
Initializes a DBusMessageIter for reading the arguments of the message passed in.
Definition: dbus-message.c:2392
DBUS_MESSAGE_TYPE_METHOD_CALL
#define DBUS_MESSAGE_TYPE_METHOD_CALL
Message type of a method call message, see dbus_message_get_type()
Definition: dbus-protocol.h:234
dbus_error_init
void dbus_error_init(DBusError *error)
Initializes a DBusError structure.
Definition: dbus-errors.c:188
dbus_message_has_interface
dbus_bool_t dbus_message_has_interface(DBusMessage *message, const char *iface)
Checks if the message has an interface.
Definition: dbus-message.c:3764
DBusHeader
Message header data and some cached details of it.
Definition: dbus-marshal-header.h:47
_dbus_message_loader_set_max_message_size
void _dbus_message_loader_set_max_message_size(DBusMessageLoader *loader, long size)
Sets the maximum size message we allow.
Definition: dbus-message.c:5047
_dbus_string_append_len
dbus_bool_t _dbus_string_append_len(DBusString *str, const char *buffer, int len)
Appends block of bytes with the given length to a DBusString.
Definition: dbus-string.c:1137
_dbus_message_loader_ref
DBusMessageLoader * _dbus_message_loader_ref(DBusMessageLoader *loader)
Increments the reference count of the loader.
Definition: dbus-message.c:4426
DBusMessage::locked
unsigned int locked
Message being sent, no modifications allowed.
Definition: dbus-message-private.h:107
_dbus_message_loader_set_pending_fds_function
void _dbus_message_loader_set_pending_fds_function(DBusMessageLoader *loader, void(*callback)(void *), void *data)
Register a function to be called whenever the number of pending file descriptors in the loader change...
Definition: dbus-message.c:5126
dbus_message_set_error_name
dbus_bool_t dbus_message_set_error_name(DBusMessage *message, const char *error_name)
Sets the name of the error (DBUS_MESSAGE_TYPE_ERROR).
Definition: dbus-message.c:3886
_dbus_header_load
dbus_bool_t _dbus_header_load(DBusHeader *header, DBusValidationMode mode, DBusValidity *validity, int byte_order, int fields_array_len, int header_len, int body_len, const DBusString *str, int start, int len)
Creates a message header from potentially-untrusted data.
Definition: dbus-marshal-header.c:970
DBUS_HEADER_FIELD_SIGNATURE
#define DBUS_HEADER_FIELD_SIGNATURE
Header field code for the type signature of a message.
Definition: dbus-protocol.h:297
_dbus_message_iter_get_args_valist
DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_message_iter_get_args_valist(DBusMessageIter *iter, DBusError *error, int first_arg_type, va_list var_args)
Implementation of the varargs arg-getting functions.
Definition: dbus-message.c:825
_dbus_header_get_byte_order
char _dbus_header_get_byte_order(const DBusHeader *header)
Returns the header's byte order.
Definition: dbus-marshal-header.c:174
_dbus_string_init
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
dbus_message_iter_init_closed
void dbus_message_iter_init_closed(DBusMessageIter *iter)
Initialize iter as if with DBUS_MESSAGE_ITER_INIT_CLOSED.
Definition: dbus-message.c:742
_dbus_string_append_printf_valist
dbus_bool_t _dbus_string_append_printf_valist(DBusString *str, const char *format, va_list args)
Appends a printf-style formatted string to the DBusString.
Definition: dbus-string.c:1072
_dbus_atomic_get
dbus_int32_t _dbus_atomic_get(DBusAtomic *atomic)
Atomically get the value of an integer.
Definition: dbus-sysdeps-unix.c:2871
DBUS_MAXIMUM_MESSAGE_LENGTH
#define DBUS_MAXIMUM_MESSAGE_LENGTH
The maximum total message size including header and body; similar rationale to max array size.
Definition: dbus-protocol.h:210
_dbus_message_loader_get_max_message_size
long _dbus_message_loader_get_max_message_size(DBusMessageLoader *loader)
Gets the maximum allowed message size in bytes.
Definition: dbus-message.c:5066
_dbus_header_get_message_type
int _dbus_header_get_message_type(DBusHeader *header)
Gets the type of the message.
Definition: dbus-marshal-header.c:386
_dbus_type_writer_add_types
void _dbus_type_writer_add_types(DBusTypeWriter *writer, DBusString *type_str, int type_pos)
Adds type string to the writer, if it had none.
Definition: dbus-marshal-recursive.c:1547
_DBUS_LOCK
#define _DBUS_LOCK(name)
Definition: dbus-internals.h:372
_dbus_variant_write
dbus_bool_t _dbus_variant_write(DBusVariant *self, DBusMessageIter *writer)
Copy the single D-Bus message item from self into writer.
Definition: dbus-message.c:5710
dbus_message_allocate_data_slot
dbus_bool_t dbus_message_allocate_data_slot(dbus_int32_t *slot_p)
Allocates an integer ID to be used for storing application-specific data on any DBusMessage.
Definition: dbus-message.c:5154
dbus_message_iter_has_next
dbus_bool_t dbus_message_iter_has_next(DBusMessageIter *iter)
Checks if an iterator has any more fields.
Definition: dbus-message.c:2423
DBusMessageLoader::refcount
int refcount
Reference count.
Definition: dbus-message-private.h:62
_dbus_dup
int _dbus_dup(int fd, DBusError *error)
Duplicates a file descriptor.
Definition: dbus-sysdeps-unix.c:3312
dbus_message_get_error_name
const char * dbus_message_get_error_name(DBusMessage *message)
Gets the error name (DBUS_MESSAGE_TYPE_ERROR only) or NULL if none.
Definition: dbus-message.c:3912
TRUE
#define TRUE
dbus_message_iter_get_element_type
int dbus_message_iter_get_element_type(DBusMessageIter *iter)
Returns the element type of the array that the message iterator points to.
Definition: dbus-message.c:2486
_dbus_list_pop_first_link
DBusList * _dbus_list_pop_first_link(DBusList **list)
Removes the first link in the list and returns it.
Definition: dbus-list.c:628
_dbus_list_append
dbus_bool_t _dbus_list_append(DBusList **list, void *data)
Appends a value to the list.
Definition: dbus-list.c:270
_dbus_message_loader_get_is_corrupted
dbus_bool_t _dbus_message_loader_get_is_corrupted(DBusMessageLoader *loader)
Checks whether the loader is confused due to bad data.
Definition: dbus-message.c:5018
DBUS_MINIMUM_HEADER_SIZE
#define DBUS_MINIMUM_HEADER_SIZE
The smallest header size that can occur.
Definition: dbus-protocol.h:346
dbus_message_iter_abandon_container
void dbus_message_iter_abandon_container(DBusMessageIter *iter, DBusMessageIter *sub)
Abandons creation of a contained-typed value and frees resources created by dbus_message_iter_open_co...
Definition: dbus-message.c:3375
dbus_message_set_reply_serial
dbus_bool_t dbus_message_set_reply_serial(DBusMessage *message, dbus_uint32_t reply_serial)
Sets the reply serial of a message (the serial of the message this is a reply to).
Definition: dbus-message.c:1172
dbus_message_is_error
dbus_bool_t dbus_message_is_error(DBusMessage *message, const char *error_name)
Checks whether the message is an error reply with the given error name.
Definition: dbus-message.c:4172
dbus_message_get_args
dbus_bool_t dbus_message_get_args(DBusMessage *message, DBusError *error, int first_arg_type,...)
Gets arguments from a message given a variable argument list.
Definition: dbus-message.c:2294
dbus_message_has_path
dbus_bool_t dbus_message_has_path(DBusMessage *message, const char *path)
Checks if the message has a particular object path.
Definition: dbus-message.c:3635
dbus_message_has_sender
dbus_bool_t dbus_message_has_sender(DBusMessage *message, const char *name)
Checks whether the message has the given unique name as its sender.
Definition: dbus-message.c:4240
DBusMessage::slot_list
DBusDataSlotList slot_list
Data stored by allocated integer ID.
Definition: dbus-message-private.h:118
_dbus_data_slot_list_set
dbus_bool_t _dbus_data_slot_list_set(DBusDataSlotAllocator *allocator, DBusDataSlotList *list, int slot, void *data, DBusFreeFunction free_data_func, DBusFreeFunction *old_free_func, void **old_data)
Stores a pointer in the data slot list, along with an optional function to be used for freeing the da...
Definition: dbus-dataslot.c:221
dbus_message_iter_get_basic
void dbus_message_iter_get_basic(DBusMessageIter *iter, void *value)
Reads a basic-typed value from the message iterator.
Definition: dbus-message.c:2621
DBusMessage::size_counter_delta
long size_counter_delta
Size we incremented the size counters by.
Definition: dbus-message-private.h:114
_dbus_counter_adjust_size
void _dbus_counter_adjust_size(DBusCounter *counter, long delta)
Adjusts the value of the size counter by the given delta which may be positive or negative.
Definition: dbus-resources.c:167
dbus_message_iter_append_basic
dbus_bool_t dbus_message_iter_append_basic(DBusMessageIter *iter, int type, const void *value)
Appends a basic-typed value to the message.
Definition: dbus-message.c:3023
DBusTypeReader
The type reader is an iterator for reading values from a block of values.
Definition: dbus-marshal-recursive.h:39
dbus_message_iter_get_arg_type
int dbus_message_iter_get_arg_type(DBusMessageIter *iter)
Returns the argument type of the argument that the message iterator points to.
Definition: dbus-message.c:2467
DBUS_TYPE_SIGNATURE
#define DBUS_TYPE_SIGNATURE
Type code marking a D-Bus type signature.
Definition: dbus-protocol.h:110
_dbus_header_toggle_flag
void _dbus_header_toggle_flag(DBusHeader *header, dbus_uint32_t flag, dbus_bool_t value)
Toggles a message flag bit, turning on the bit if value = TRUE and flipping it off if value = FALSE.
Definition: dbus-marshal-header.c:1457
dbus_message_get_signature
const char * dbus_message_get_signature(DBusMessage *message)
Gets the type signature of the message, i.e.
Definition: dbus-message.c:4058
dbus_free
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:702
DBUS_HEADER_FLAG_NO_AUTO_START
#define DBUS_HEADER_FLAG_NO_AUTO_START
If set, this flag means that even if the message bus knows how to start an owner for the destination ...
Definition: dbus-protocol.h:256
INITIAL_LOADER_DATA_LEN
#define INITIAL_LOADER_DATA_LEN
The initial buffer size of the message loader.
Definition: dbus-message.c:4369
DBusTypeWriter::container_type
dbus_uint32_t container_type
what are we inside? (e.g.
Definition: dbus-marshal-recursive.h:68
_dbus_decompose_path
dbus_bool_t _dbus_decompose_path(const char *data, int len, char ***path, int *path_len)
Decompose an object path.
Definition: dbus-object-tree.c:1244
_DBUS_LOCK_NAME
#define _DBUS_LOCK_NAME(name)
Definition: dbus-internals.h:371
dbus_message_set_destination
dbus_bool_t dbus_message_set_destination(DBusMessage *message, const char *destination)
Sets the message's destination.
Definition: dbus-message.c:3940
_dbus_string_init_preallocated
dbus_bool_t _dbus_string_init_preallocated(DBusString *str, int allocate_size)
Initializes a string that can be up to the given allocation size before it has to realloc.
Definition: dbus-string.c:132
DBUS_ERROR_INCONSISTENT_MESSAGE
#define DBUS_ERROR_INCONSISTENT_MESSAGE
The message meta data does not match the payload.
Definition: dbus-protocol.h:455
MAX_MESSAGE_CACHE_SIZE
#define MAX_MESSAGE_CACHE_SIZE
Avoid caching too many messages.
Definition: dbus-message.c:498
_dbus_register_shutdown_func
DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_register_shutdown_func(DBusShutdownFunction function, void *data)
Register a cleanup function to be called exactly once the next time dbus_shutdown() is called.
Definition: dbus-memory.c:811
DBusString
Definition: dbus-string.h:42
DBUS_HEADER_FIELD_INTERFACE
#define DBUS_HEADER_FIELD_INTERFACE
Header field code for the interface containing a member (method or signal).
Definition: dbus-protocol.h:274
_dbus_counter_notify
void _dbus_counter_notify(DBusCounter *counter)
Calls the notify function from _dbus_counter_set_notify(), if that function has been specified and th...
Definition: dbus-resources.c:207
_dbus_message_add_counter_link
void _dbus_message_add_counter_link(DBusMessage *message, DBusList *link)
Adds a counter to be incremented immediately with the size/unix fds of this message,...
Definition: dbus-message.c:314
dbus_message_set_sender
dbus_bool_t dbus_message_set_sender(DBusMessage *message, const char *sender)
Sets the message sender.
Definition: dbus-message.c:3994
dbus_message_get_data
void * dbus_message_get_data(DBusMessage *message, dbus_int32_t slot)
Retrieves data previously set with dbus_message_set_data().
Definition: dbus-message.c:5229
_dbus_message_loader_unref
void _dbus_message_loader_unref(DBusMessageLoader *loader)
Decrements the reference count of the loader and finalizes the loader when the count reaches zero.
Definition: dbus-message.c:4440
_dbus_type_reader_init
void _dbus_type_reader_init(DBusTypeReader *reader, int byte_order, const DBusString *type_str, int type_pos, const DBusString *value_str, int value_pos)
Initializes a type reader.
Definition: dbus-marshal-recursive.c:733
DBUS_HEADER_FLAG_ALLOW_INTERACTIVE_AUTHORIZATION
#define DBUS_HEADER_FLAG_ALLOW_INTERACTIVE_AUTHORIZATION
If set on a method call, this flag means that the caller is prepared to wait for interactive authoriz...
Definition: dbus-protocol.h:261
_dbus_message_loader_get_max_message_unix_fds
long _dbus_message_loader_get_max_message_unix_fds(DBusMessageLoader *loader)
Gets the maximum allowed number of unix fds per message.
Definition: dbus-message.c:5097
DBusMessage::generation
int generation
_dbus_current_generation when message was created
Definition: dbus-message-private.h:121
_dbus_type_writer_write_reader
dbus_bool_t _dbus_type_writer_write_reader(DBusTypeWriter *writer, DBusTypeReader *reader)
Iterate through all values in the given reader, writing a copy of each value to the writer.
Definition: dbus-marshal-recursive.c:2732
DBUS_MESSAGE_TYPE_SIGNAL
#define DBUS_MESSAGE_TYPE_SIGNAL
Message type of a signal message, see dbus_message_get_type()
Definition: dbus-protocol.h:240
_dbus_list_pop_first
void * _dbus_list_pop_first(DBusList **list)
Removes the first value in the list and returns it.
Definition: dbus-list.c:649
dbus_message_iter_init_append
void dbus_message_iter_init_append(DBusMessage *message, DBusMessageIter *iter)
Initializes a DBusMessageIter for appending arguments to the end of a message.
Definition: dbus-message.c:2785
DBUS_TYPE_STRUCT
#define DBUS_TYPE_STRUCT
STRUCT and DICT_ENTRY are sort of special since their codes can't appear in a type string,...
Definition: dbus-protocol.h:136
DBUS_TYPE_DICT_ENTRY
#define DBUS_TYPE_DICT_ENTRY
Type code used to represent a dict entry; however, this type code does not appear in type signatures,...
Definition: dbus-protocol.h:143
DBusBasicValue::u32
dbus_uint32_t u32
as int32
Definition: dbus-types.h:143
_dbus_header_get_flag
dbus_bool_t _dbus_header_get_flag(DBusHeader *header, dbus_uint32_t flag)
Gets a message flag bit, returning TRUE if the bit is set.
Definition: dbus-marshal-header.c:1479
_dbus_data_slot_list_init
void _dbus_data_slot_list_init(DBusDataSlotList *list)
Initializes a slot list.
Definition: dbus-dataslot.c:197
DBUS_MAXIMUM_MESSAGE_UNIX_FDS
#define DBUS_MAXIMUM_MESSAGE_UNIX_FDS
The maximum total number of unix fds in a message.
Definition: dbus-protocol.h:218
_dbus_type_reader_get_current_type
int _dbus_type_reader_get_current_type(const DBusTypeReader *reader)
Gets the type of the value the reader is currently pointing to; or for a types-only reader gets the t...
Definition: dbus-marshal-recursive.c:786
_DBUS_STRING_DEFINE_STATIC
_DBUS_STRING_DEFINE_STATIC(_dbus_empty_signature_str, "")
An static string representing an empty signature.
_dbus_list_remove_last
dbus_bool_t _dbus_list_remove_last(DBusList **list, void *data)
Removes a value from the list.
Definition: dbus-list.c:446
dbus_message_set_path
dbus_bool_t dbus_message_set_path(DBusMessage *message, const char *object_path)
Sets the object path this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or the one a s...
Definition: dbus-message.c:3582
dbus_message_has_signature
dbus_bool_t dbus_message_has_signature(DBusMessage *message, const char *signature)
Checks whether the message has the given signature; see dbus_message_get_signature() for more details...
Definition: dbus-message.c:4269
_dbus_data_slot_allocator_alloc
dbus_bool_t _dbus_data_slot_allocator_alloc(DBusDataSlotAllocator *allocator, dbus_int32_t *slot_id_p)
Allocates an integer ID to be used for storing data in a DBusDataSlotList.
Definition: dbus-dataslot.c:69
DBusVariant
An opaque data structure containing the serialized form of any single D-Bus message item,...
Definition: dbus-message.c:5530
FALSE
#define FALSE
DBusMessage::refcount
DBusAtomic refcount
Reference count.
Definition: dbus-message-private.h:101
_dbus_data_slot_list_free
void _dbus_data_slot_list_free(DBusDataSlotList *list)
Frees the data slot list and all data slots contained in it, calling application-provided free functi...
Definition: dbus-dataslot.c:340
_dbus_header_copy
dbus_bool_t _dbus_header_copy(const DBusHeader *header, DBusHeader *dest)
Initializes dest with a copy of the given header.
Definition: dbus-marshal-header.c:490
_dbus_type_reader_read_fixed_multi
void _dbus_type_reader_read_fixed_multi(const DBusTypeReader *reader, void *value, int *n_elements)
Reads a block of fixed-length basic values, from the current point in an array to the end of the arra...
Definition: dbus-marshal-recursive.c:924
dbus_message_get_interface
const char * dbus_message_get_interface(DBusMessage *message)
Gets the interface this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitted...
Definition: dbus-message.c:3742
dbus_message_has_destination
dbus_bool_t dbus_message_has_destination(DBusMessage *message, const char *name)
Checks whether the message was sent to the given name.
Definition: dbus-message.c:4205
dbus_message_get_destination
const char * dbus_message_get_destination(DBusMessage *message)
Gets the destination of a message or NULL if there is none set.
Definition: dbus-message.c:3965
DBusMessage::in_cache
unsigned int in_cache
Has been "freed" since it's in the cache (this is a debug feature)
Definition: dbus-message-private.h:110
DBusMessage
Internals of DBusMessage.
Definition: dbus-message-private.h:99
DBusList::data
void * data
Data stored at this element.
Definition: dbus-list.h:38
dbus_message_iter_abandon_container_if_open
void dbus_message_iter_abandon_container_if_open(DBusMessageIter *iter, DBusMessageIter *sub)
Abandons creation of a contained-typed value and frees resources created by dbus_message_iter_open_co...
Definition: dbus-message.c:3434
_dbus_string_delete
void _dbus_string_delete(DBusString *str, int start, int len)
Deletes a segment of a DBusString with length len starting at start.
Definition: dbus-string.c:1193
dbus_message_get_sender
const char * dbus_message_get_sender(DBusMessage *message)
Gets the unique name of the connection which originated this message, or NULL if unknown or inapplica...
Definition: dbus-message.c:4025
DBUS_MESSAGE_TYPE_ERROR
#define DBUS_MESSAGE_TYPE_ERROR
Message type of an error reply message, see dbus_message_get_type()
Definition: dbus-protocol.h:238
dbus_message_new_error_printf
DBusMessage * dbus_message_new_error_printf(DBusMessage *reply_to, const char *error_name, const char *error_format,...)
Creates a new message that is an error reply to another message, allowing you to use printf formattin...
Definition: dbus-message.c:1855
_dbus_message_loader_get_buffer
void _dbus_message_loader_get_buffer(DBusMessageLoader *loader, DBusString **buffer, int *max_to_read, dbus_bool_t *may_read_fds)
Gets the buffer to use for reading data from the network.
Definition: dbus-message.c:4477
dbus_type_is_container
dbus_bool_t dbus_type_is_container(int typecode)
A "container type" can contain basic types, or nested container types.
Definition: dbus-signature.c:295
ensure_byte_order
#define ensure_byte_order(message)
byte-swap the message if it doesn't match our byte order.
Definition: dbus-message.c:229
DBUS_MESSAGE_TYPE_METHOD_RETURN
#define DBUS_MESSAGE_TYPE_METHOD_RETURN
Message type of a method return message, see dbus_message_get_type()
Definition: dbus-protocol.h:236
_dbus_assert_not_reached
#define _dbus_assert_not_reached(explanation)
Definition: dbus-internals.h:163
_dbus_header_have_message_untrusted
dbus_bool_t _dbus_header_have_message_untrusted(int max_message_length, DBusValidity *validity, int *byte_order, int *fields_array_len, int *header_len, int *body_len, const DBusString *str, int start, int len)
Given data long enough to contain the length of the message body and the fields array,...
Definition: dbus-marshal-header.c:673
_dbus_string_set_length
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:802
_dbus_header_get_field_raw
dbus_bool_t _dbus_header_get_field_raw(DBusHeader *header, int field, const DBusString **str, int *pos)
Gets the raw marshaled data for a field.
Definition: dbus-marshal-header.c:1392
_dbus_message_loader_peek_message
DBusMessage * _dbus_message_loader_peek_message(DBusMessageLoader *loader)
Peeks at first loaded message, returns NULL if no messages have been queued.
Definition: dbus-message.c:4959
_dbus_marshal_byteswap
void _dbus_marshal_byteswap(const DBusString *signature, int signature_start, int old_byte_order, int new_byte_order, DBusString *value_str, int value_pos)
Byteswaps the marshaled data in the given value_str.
Definition: dbus-marshal-byteswap.c:222
dbus_message_has_member
dbus_bool_t dbus_message_has_member(DBusMessage *message, const char *member)
Checks if the message has an interface member.
Definition: dbus-message.c:3850
DBUS_DICT_ENTRY_BEGIN_CHAR
#define DBUS_DICT_ENTRY_BEGIN_CHAR
Code marking the start of a dict entry type in a type signature.
Definition: dbus-protocol.h:164
dbus_type_is_fixed
dbus_bool_t dbus_type_is_fixed(int typecode)
Tells you whether values of this type can change length if you set them to some other value.
Definition: dbus-signature.c:350
dbus_message_get_reply_serial
dbus_uint32_t dbus_message_get_reply_serial(DBusMessage *message)
Returns the serial that the message is a reply to or 0 if none.
Definition: dbus-message.c:1196
dbus_message_get_serial
dbus_uint32_t dbus_message_get_serial(DBusMessage *message)
Returns the serial of a message or 0 if none has been specified.
Definition: dbus-message.c:1156
dbus_message_get_member
const char * dbus_message_get_member(DBusMessage *message)
Gets the interface member being invoked (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted (DBUS_MESSAGE_TYPE...
Definition: dbus-message.c:3828
_dbus_header_free
void _dbus_header_free(DBusHeader *header)
Frees a header.
Definition: dbus-marshal-header.c:476
_dbus_message_loader_new
DBusMessageLoader * _dbus_message_loader_new(void)
Creates a new message loader.
Definition: dbus-message.c:4378
DBusMessageRealIter::writer
DBusTypeWriter writer
writer
Definition: dbus-message.c:145
DBusMessage::counters
DBusList * counters
0-N DBusCounter used to track message size/unix fds.
Definition: dbus-message-private.h:113
DBUS_ERROR_INVALID_ARGS
#define DBUS_ERROR_INVALID_ARGS
Invalid arguments passed to a method call.
Definition: dbus-protocol.h:391
_dbus_list_foreach
void _dbus_list_foreach(DBusList **list, DBusForeachFunction function, void *data)
Calls the given function for each element in the list.
Definition: dbus-list.c:759
_dbus_type_writer_write_basic
dbus_bool_t _dbus_type_writer_write_basic(DBusTypeWriter *writer, int type, const void *value)
Writes out a basic type.
Definition: dbus-marshal-recursive.c:2312
DBusCounter
Internals of DBusCounter.
Definition: dbus-resources.c:54
DBUS_HEADER_FIELD_ERROR_NAME
#define DBUS_HEADER_FIELD_ERROR_NAME
Header field code for an error name (found in DBUS_MESSAGE_TYPE_ERROR messages).
Definition: dbus-protocol.h:280
dbus_message_get_auto_start
dbus_bool_t dbus_message_get_auto_start(DBusMessage *message)
Returns TRUE if the message will cause an owner for destination name to be auto-started.
Definition: dbus-message.c:3560
DBusMessageLoader::data
DBusString data
Buffered data.
Definition: dbus-message-private.h:64
_dbus_header_get_field_basic
dbus_bool_t _dbus_header_get_field_basic(DBusHeader *header, int field, int type, void *value)
Gets the value of a field with basic type.
Definition: dbus-marshal-header.c:1351
DBUS_MESSAGE_TYPE_INVALID
#define DBUS_MESSAGE_TYPE_INVALID
This value is never a valid message type, see dbus_message_get_type()
Definition: dbus-protocol.h:232
DBUS_VALIDITY_UNKNOWN_OOM_ERROR
@ DBUS_VALIDITY_UNKNOWN_OOM_ERROR
can't determine validity due to OOM
Definition: dbus-marshal-validate.h:52
dbus_new
#define dbus_new(type, count)
Definition: dbus-memory.h:57
DBUS_TYPE_BOOLEAN
#define DBUS_TYPE_BOOLEAN
Type code marking a boolean.
Definition: dbus-protocol.h:70
_dbus_list_prepend_link
void _dbus_list_prepend_link(DBusList **list, DBusList *link)
Prepends a link to the list.
Definition: dbus-list.c:333
dbus_message_set_data
dbus_bool_t dbus_message_set_data(DBusMessage *message, dbus_int32_t slot, void *data, DBusFreeFunction free_data_func)
Stores a pointer on a DBusMessage, along with an optional function to be used for freeing the data wh...
Definition: dbus-message.c:5193
_dbus_type_reader_get_array_length
int _dbus_type_reader_get_array_length(const DBusTypeReader *reader)
Returns the number of bytes in the array.
Definition: dbus-marshal-recursive.c:900
_dbus_assert
#define _dbus_assert(condition)
Definition: dbus-internals.h:152
dbus_error_free
void dbus_error_free(DBusError *error)
Frees an error that's been set (or just initialized), then reinitializes the error as in dbus_error_i...
Definition: dbus-errors.c:211
_dbus_close
dbus_bool_t _dbus_close(int fd, DBusError *error)
Closes a file descriptor.
Definition: dbus-sysdeps-unix.c:3284
_dbus_warn
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
Definition: dbus-internals.c:230
dbus_message_iter_get_fixed_array
void dbus_message_iter_get_fixed_array(DBusMessageIter *iter, void *value, int *n_elements)
Reads a block of fixed-length values from the message iterator.
Definition: dbus-message.c:2755
DBUS_TYPE_OBJECT_PATH
#define DBUS_TYPE_OBJECT_PATH
Type code marking a D-Bus object path.
Definition: dbus-protocol.h:106
_dbus_strdup
char * _dbus_strdup(const char *str)
Duplicates a string.
Definition: dbus-internals.c:536
DBusMessage::header
DBusHeader header
Header network data and associated cache.
Definition: dbus-message-private.h:103
dbus_message_is_signal
dbus_bool_t dbus_message_is_signal(DBusMessage *message, const char *iface, const char *signal_name)
Checks whether the message is a signal with the given interface and member fields.
Definition: dbus-message.c:4145
_dbus_getenv
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:187
DBUS_TYPE_VARIANT
#define DBUS_TYPE_VARIANT
Type code marking a D-Bus variant type.
Definition: dbus-protocol.h:124
DBusError
Object representing an exception.
Definition: dbus-errors.h:48
DBusMessageIter
DBusMessageIter struct; contains no public fields.
Definition: dbus-message.h:61
_dbus_header_byteswap
void _dbus_header_byteswap(DBusHeader *header, int new_order)
Swaps the header into the given order if required.
Definition: dbus-marshal-header.c:1496
DBusDataSlotAllocator
An allocator that tracks a set of slot IDs.
Definition: dbus-dataslot.h:55
dbus_message_append_args
dbus_bool_t dbus_message_append_args(DBusMessage *message, int first_arg_type,...)
Appends fields to a message given a variable argument list.
Definition: dbus-message.c:2105
DBUS_HEADER_FIELD_MEMBER
#define DBUS_HEADER_FIELD_MEMBER
Header field code for a member (method or signal).
Definition: dbus-protocol.h:276
dbus_message_iter_next
dbus_bool_t dbus_message_iter_next(DBusMessageIter *iter)
Moves the iterator to the next field, if any.
Definition: dbus-message.c:2442
DBusBasicValue
A simple value union that lets you access bytes as if they were various types; useful when dealing wi...
Definition: dbus-types.h:137
dbus_message_marshal
dbus_bool_t dbus_message_marshal(DBusMessage *msg, char **marshalled_data_p, int *len_p)
Turn a DBusMessage into the marshalled form as described in the D-Bus specification.
Definition: dbus-message.c:5315
_dbus_message_get_network_data
void _dbus_message_get_network_data(DBusMessage *message, const DBusString **header, const DBusString **body)
Gets the data to be sent over the network for this message.
Definition: dbus-message.c:242
_dbus_type_writer_unrecurse
dbus_bool_t _dbus_type_writer_unrecurse(DBusTypeWriter *writer, DBusTypeWriter *sub)
Closes a container created by _dbus_type_writer_recurse() and writes any additional information to th...
Definition: dbus-marshal-recursive.c:2180
DBusList
Definition: dbus-list.h:34
_dbus_data_slot_allocator_free
void _dbus_data_slot_allocator_free(DBusDataSlotAllocator *allocator, dbus_int32_t *slot_id_p)
Deallocates an ID previously allocated with _dbus_data_slot_allocator_alloc().
Definition: dbus-dataslot.c:154
dbus_message_iter_recurse
void dbus_message_iter_recurse(DBusMessageIter *iter, DBusMessageIter *sub)
Recurses into a container value when reading values from a message, initializing a sub-iterator to us...
Definition: dbus-message.c:2523
CHANGED_STAMP_BITS
#define CHANGED_STAMP_BITS
How many bits are in the changed_stamp used to validate iterators.
Definition: dbus-message-private.h:90
DBusMessageRealIter::message
DBusMessage * message
Message used.
Definition: dbus-message.c:139
dbus_message_set_serial
void dbus_message_set_serial(DBusMessage *message, dbus_uint32_t serial)
Sets the serial number of a message.
Definition: dbus-message.c:288
_dbus_validate_signature_with_reason
DBusValidity _dbus_validate_signature_with_reason(const DBusString *type_str, int type_pos, int len)
Verifies that the range of type_str from type_pos to type_end is a valid signature.
Definition: dbus-marshal-validate.c:51
_dbus_message_loader_return_buffer
void _dbus_message_loader_return_buffer(DBusMessageLoader *loader, DBusString *buffer)
Returns a buffer obtained from _dbus_message_loader_get_buffer(), indicating to the loader how many b...
Definition: dbus-message.c:4583
dbus_message_iter_get_signature
char * dbus_message_iter_get_signature(DBusMessageIter *iter)
Returns the current signature of a message iterator.
Definition: dbus-message.c:2548
dbus_set_error
void dbus_set_error(DBusError *error, const char *name, const char *format,...)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:354
DBusForeachFunction
void(* DBusForeachFunction)(void *element, void *data)
Definition: dbus-internals.h:284
dbus_type_is_basic
dbus_bool_t dbus_type_is_basic(int typecode)
A "basic type" is a somewhat arbitrary concept, but the intent is to include those types that are ful...
Definition: dbus-signature.c:319
dbus_message_copy
DBusMessage * dbus_message_copy(const DBusMessage *message)
Creates a new message that is an exact replica of the message specified, except that its refcount is ...
Definition: dbus-message.c:1900
dbus_free_string_array
void dbus_free_string_array(char **str_array)
Frees a NULL-terminated array of strings.
Definition: dbus-memory.c:750
_dbus_string_steal_data
dbus_bool_t _dbus_string_steal_data(DBusString *str, char **data_return)
Like _dbus_string_get_data(), but removes the gotten data from the original string.
Definition: dbus-string.c:641
dbus_message_get_no_reply
dbus_bool_t dbus_message_get_no_reply(DBusMessage *message)
Returns TRUE if the message does not expect a reply.
Definition: dbus-message.c:3518
_dbus_type_to_string
const char * _dbus_type_to_string(int typecode)
Returns a string describing the given type.
Definition: dbus-marshal-basic.c:1223
_dbus_variant_read
DBusVariant * _dbus_variant_read(DBusMessageIter *reader)
Copy a single D-Bus message item from reader into a newly-allocated DBusVariant.
Definition: dbus-message.c:5547
dbus_message_set_auto_start
void dbus_message_set_auto_start(DBusMessage *message, dbus_bool_t auto_start)
Sets a flag indicating that an owner for the destination name will be automatically started before th...
Definition: dbus-message.c:3541
DBusMessage::body
DBusString body
Body network data.
Definition: dbus-message-private.h:105
dbus_message_type_from_string
int dbus_message_type_from_string(const char *type_str)
Utility function to convert a machine-readable (not translated) string into a D-Bus message type.
Definition: dbus-message.c:5257
_dbus_counter_ref
DBusCounter * _dbus_counter_ref(DBusCounter *counter)
Increments refcount of the counter.
Definition: dbus-resources.c:116
dbus_message_iter_get_element_count
int dbus_message_iter_get_element_count(DBusMessageIter *iter)
Returns the number of elements in the array-typed value pointed to by the iterator.
Definition: dbus-message.c:2666
DBusMessageLoader::max_message_unix_fds
long max_message_unix_fds
Maximum unix fds in a message.
Definition: dbus-message-private.h:69
_dbus_type_writer_remove_types
void _dbus_type_writer_remove_types(DBusTypeWriter *writer)
Removes type string from the writer.
Definition: dbus-marshal-recursive.c:1564
DBusMessageRealIter::changed_stamp
dbus_uint32_t changed_stamp
stamp to detect invalid iters
Definition: dbus-message.c:140
_dbus_atomic_inc
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
Definition: dbus-sysdeps-unix.c:2824
_dbus_message_loader_pop_message_link
DBusList * _dbus_message_loader_pop_message_link(DBusMessageLoader *loader)
Pops a loaded message inside a list link (passing ownership of the message and link to the caller).
Definition: dbus-message.c:4990
dbus_message_lock
void dbus_message_lock(DBusMessage *message)
Locks a message.
Definition: dbus-message.c:418
_dbus_type_reader_recurse
void _dbus_type_reader_recurse(DBusTypeReader *reader, DBusTypeReader *sub)
Initialize a new reader pointing to the first type and corresponding value that's a child of the curr...
Definition: dbus-marshal-recursive.c:989
dbus_message_free_data_slot
void dbus_message_free_data_slot(dbus_int32_t *slot_p)
Deallocates a global ID for message data slots.
Definition: dbus-message.c:5172
_DBUS_UNLOCK
#define _DBUS_UNLOCK(name)
Definition: dbus-internals.h:373
DBusMessageLoader
Implementation details of DBusMessageLoader.
Definition: dbus-message-private.h:60
DBUS_HEADER_FIELD_UNIX_FDS
#define DBUS_HEADER_FIELD_UNIX_FDS
Header field code for the number of unix file descriptors associated with this message.
Definition: dbus-protocol.h:302
dbus_message_get_type
int dbus_message_get_type(DBusMessage *message)
Gets the type of a message.
Definition: dbus-message.c:2035
DBusError::message
const char * message
public error message field
Definition: dbus-errors.h:51
_DBUS_ZERO
#define _DBUS_ZERO(object)
Definition: dbus-internals.h:193
_dbus_variant_get_signature
const char * _dbus_variant_get_signature(DBusVariant *self)
Return the signature of the item stored in self.
Definition: dbus-message.c:5683
dbus_message_new_signal
DBusMessage * dbus_message_new_signal(const char *path, const char *iface, const char *name)
Constructs a new message representing a signal emission.
Definition: dbus-message.c:1737
_dbus_string_init_const
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:190
DBUS_HEADER_FIELD_REPLY_SERIAL
#define DBUS_HEADER_FIELD_REPLY_SERIAL
Header field code for a reply serial, used to match a DBUS_MESSAGE_TYPE_METHOD_RETURN message with th...
Definition: dbus-protocol.h:284
_dbus_string_copy_len
dbus_bool_t _dbus_string_copy_len(const DBusString *source, int start, int len, DBusString *dest, int insert_at)
Like _dbus_string_copy(), but can copy a segment from the middle of the source string.
Definition: dbus-string.c:1375
dbus_new0
#define dbus_new0(type, count)
Definition: dbus-memory.h:58
_dbus_type_reader_get_signature
void _dbus_type_reader_get_signature(const DBusTypeReader *reader, const DBusString **str_p, int *start_p, int *len_p)
Gets the string and range of said string containing the signature of the current value.
Definition: dbus-marshal-recursive.c:1126
DBusMessageRealIter
Internals of DBusMessageIter.
Definition: dbus-message.c:137
_dbus_memdup
void * _dbus_memdup(const void *mem, size_t n_bytes)
Duplicates a block of memory.
Definition: dbus-internals.c:564
DBusMessageIter_1_10_0
Layout of a DBusMessageIter on the stack in dbus 1.10.0.
Definition: dbus-message.c:155
dbus_message_new_error
DBusMessage * dbus_message_new_error(DBusMessage *reply_to, const char *error_name, const char *error_message)
Creates a new message that is an error reply to another message.
Definition: dbus-message.c:1783
dbus_message_demarshal
DBusMessage * dbus_message_demarshal(const char *str, int len, DBusError *error)
Demarshal a D-Bus message from the format described in the D-Bus specification.
Definition: dbus-message.c:5377
DBusMessageRealIter::iter_type
dbus_uint32_t iter_type
whether this is a reader or writer iter
Definition: dbus-message.c:141
_dbus_header_reinit
void _dbus_header_reinit(DBusHeader *header)
Re-initializes a header that was previously initialized and never freed.
Definition: dbus-marshal-header.c:443
dbus_message_new_method_call
DBusMessage * dbus_message_new_method_call(const char *destination, const char *path, const char *iface, const char *method)
Constructs a new message to invoke a method on a remote object.
Definition: dbus-message.c:1608
DBusMessage::changed_stamp
dbus_uint32_t changed_stamp
Incremented when iterators are invalidated.
Definition: dbus-message-private.h:116
DBUS_ERROR_NOT_SUPPORTED
#define DBUS_ERROR_NOT_SUPPORTED
Requested operation isn't supported (like ENOSYS on UNIX).
Definition: dbus-protocol.h:369
DBUS_TYPE_UINT32
#define DBUS_TYPE_UINT32
Type code marking a 32-bit unsigned integer.
Definition: dbus-protocol.h:86
_dbus_type_writer_write_fixed_multi
dbus_bool_t _dbus_type_writer_write_fixed_multi(DBusTypeWriter *writer, int element_type, const void *value, int n_elements)
Writes a block of fixed-length basic values, i.e.
Definition: dbus-marshal-recursive.c:2360
_dbus_header_create
dbus_bool_t _dbus_header_create(DBusHeader *header, int byte_order, int message_type, const char *destination, const char *path, const char *interface, const char *member, const char *error_name)
Fills in the primary fields of the header, so the header is ready for use.
Definition: dbus-marshal-header.c:528
DBUS_HEADER_FIELD_DESTINATION
#define DBUS_HEADER_FIELD_DESTINATION
Header field code for the destination bus name of a message.
Definition: dbus-protocol.h:288
DBusTypeWriter
The type writer is an iterator for writing to a block of values.
Definition: dbus-marshal-recursive.h:64
DBusMessageRealIter::reader
DBusTypeReader reader
reader
Definition: dbus-message.c:146
DBusTypeWriter::byte_order
dbus_uint32_t byte_order
byte order to write values with
Definition: dbus-marshal-recursive.h:66
dbus_message_append_args_valist
dbus_bool_t dbus_message_append_args_valist(DBusMessage *message, int first_arg_type, va_list var_args)
Like dbus_message_append_args() but takes a va_list for use by language bindings.
Definition: dbus-message.c:2137
_dbus_message_loader_pop_message
DBusMessage * _dbus_message_loader_pop_message(DBusMessageLoader *loader)
Pops a loaded message (passing ownership of the message to the caller).
Definition: dbus-message.c:4976
_dbus_header_set_field_basic
dbus_bool_t _dbus_header_set_field_basic(DBusHeader *header, int field, int type, const void *value)
Sets the value of a field with basic type.
Definition: dbus-marshal-header.c:1273
_dbus_header_init
dbus_bool_t _dbus_header_init(DBusHeader *header)
Initializes a header, but doesn't prepare it for use; to make the header valid, you have to call _dbu...
Definition: dbus-marshal-header.c:460
dbus_set_error_from_message
dbus_bool_t dbus_set_error_from_message(DBusError *error, DBusMessage *message)
Sets a DBusError based on the contents of the given message.
Definition: dbus-message.c:4311
_dbus_string_init_const_len
void _dbus_string_init_const_len(DBusString *str, const char *value, int len)
Initializes a constant string with a length.
Definition: dbus-string.c:210
DBUS_HEADER_FLAG_NO_REPLY_EXPECTED
#define DBUS_HEADER_FLAG_NO_REPLY_EXPECTED
If set, this flag means that the sender of a message does not care about getting a reply,...
Definition: dbus-protocol.h:249
_dbus_warn_check_failed
void _dbus_warn_check_failed(const char *format,...)
Prints a "critical" warning to stderr when an assertion fails; differs from _dbus_warn primarily in t...
Definition: dbus-internals.c:262
DBUS_MAXIMUM_ARRAY_LENGTH
#define DBUS_MAXIMUM_ARRAY_LENGTH
Max length of a marshaled array in bytes (64M, 2^26) We use signed int for lengths so must be INT_MAX...
Definition: dbus-protocol.h:203
dbus_message_iter_get_array_len
int dbus_message_iter_get_array_len(DBusMessageIter *iter)
Returns the number of bytes in the array as marshaled in the wire protocol.
Definition: dbus-message.c:2710
dbus_bool_t
dbus_uint32_t dbus_bool_t
Definition: dbus-types.h:35
dbus_message_get_path_decomposed
dbus_bool_t dbus_message_get_path_decomposed(DBusMessage *message, char ***path)
Gets the object path this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitt...
Definition: dbus-message.c:3679
dbus_message_set_member
dbus_bool_t dbus_message_set_member(DBusMessage *message, const char *member)
Sets the interface member being invoked (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted (DBUS_MESSAGE_TYPE...
Definition: dbus-message.c:3801
DBusValidity
DBusValidity
This is primarily used in unit testing, so we can verify that each invalid message is invalid for the...
Definition: dbus-marshal-validate.h:49
NULL
#define NULL