0c7e80d64b5df545731deebf70977e5ab45b9dbc
[platform/upstream/dbus.git] / dbus / dbus-message.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-message.c  DBusMessage object
3  *
4  * Copyright (C) 2002, 2003, 2004, 2005  Red Hat Inc.
5  * Copyright (C) 2002, 2003  CodeFactory AB
6  *
7  * Licensed under the Academic Free License version 2.1
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  *
23  */
24
25 #include <config.h>
26 #include "dbus-internals.h"
27 #include "dbus-marshal-recursive.h"
28 #include "dbus-marshal-validate.h"
29 #include "dbus-marshal-byteswap.h"
30 #include "dbus-marshal-header.h"
31 #include "dbus-signature.h"
32 #include "dbus-message-private.h"
33 #include "dbus-object-tree.h"
34 #include "dbus-memory.h"
35 #include "dbus-list.h"
36 #include "dbus-threads-internal.h"
37 #ifdef HAVE_UNIX_FD_PASSING
38 #include "dbus-sysdeps-unix.h"
39 #endif
40
41 #include <string.h>
42
43 static void dbus_message_finalize (DBusMessage *message);
44
45 /**
46  * @defgroup DBusMessageInternals DBusMessage implementation details
47  * @ingroup DBusInternals
48  * @brief DBusMessage private implementation details.
49  *
50  * The guts of DBusMessage and its methods.
51  *
52  * @{
53  */
54
55 /* Not thread locked, but strictly const/read-only so should be OK
56  */
57 /** An static string representing an empty signature */
58 _DBUS_STRING_DEFINE_STATIC(_dbus_empty_signature_str,  "");
59
60 /* these have wacky values to help trap uninitialized iterators;
61  * but has to fit in 3 bits
62  */
63 enum {
64   DBUS_MESSAGE_ITER_TYPE_READER = 3,
65   DBUS_MESSAGE_ITER_TYPE_WRITER = 7
66 };
67
68 /** typedef for internals of message iterator */
69 typedef struct DBusMessageRealIter DBusMessageRealIter;
70
71 /**
72  * @brief Internals of DBusMessageIter
73  *
74  * Object representing a position in a message. All fields are internal.
75  */
76 struct DBusMessageRealIter
77 {
78   DBusMessage *message; /**< Message used */
79   dbus_uint32_t changed_stamp : CHANGED_STAMP_BITS; /**< stamp to detect invalid iters */
80   dbus_uint32_t iter_type : 3;      /**< whether this is a reader or writer iter */
81   dbus_uint32_t sig_refcount : 8;   /**< depth of open_signature() */
82   union
83   {
84     DBusTypeWriter writer; /**< writer */
85     DBusTypeReader reader; /**< reader */
86   } u; /**< the type writer or reader that does all the work */
87 };
88
89 static void
90 get_const_signature (DBusHeader        *header,
91                      const DBusString **type_str_p,
92                      int               *type_pos_p)
93 {
94   if (_dbus_header_get_field_raw (header,
95                                   DBUS_HEADER_FIELD_SIGNATURE,
96                                   type_str_p,
97                                   type_pos_p))
98     {
99       *type_pos_p += 1; /* skip the signature length which is 1 byte */
100     }
101   else
102     {
103       *type_str_p = &_dbus_empty_signature_str;
104       *type_pos_p = 0;
105     }
106 }
107
108 /**
109  * Swaps the message to compiler byte order if required
110  *
111  * @param message the message
112  */
113 static void
114 _dbus_message_byteswap (DBusMessage *message)
115 {
116   const DBusString *type_str;
117   int type_pos;
118   char byte_order;
119
120   byte_order = _dbus_header_get_byte_order (&message->header);
121
122   if (byte_order == DBUS_COMPILER_BYTE_ORDER)
123     return;
124
125   _dbus_verbose ("Swapping message into compiler byte order\n");
126   
127   get_const_signature (&message->header, &type_str, &type_pos);
128   
129   _dbus_marshal_byteswap (type_str, type_pos,
130                           byte_order,
131                           DBUS_COMPILER_BYTE_ORDER,
132                           &message->body, 0);
133
134   _dbus_header_byteswap (&message->header, DBUS_COMPILER_BYTE_ORDER);
135   _dbus_assert (_dbus_header_get_byte_order (&message->header) ==
136                 DBUS_COMPILER_BYTE_ORDER);
137 }
138
139 /** byte-swap the message if it doesn't match our byte order.
140  *  Called only when we need the message in our own byte order,
141  *  normally when reading arrays of integers or doubles.
142  *  Otherwise should not be called since it would do needless
143  *  work.
144  */
145 #define ensure_byte_order(message) _dbus_message_byteswap (message)
146
147 /**
148  * Gets the data to be sent over the network for this message.
149  * The header and then the body should be written out.
150  * This function is guaranteed to always return the same
151  * data once a message is locked (with dbus_message_lock()).
152  *
153  * @param message the message.
154  * @param header return location for message header data.
155  * @param body return location for message body data.
156  */
157 void
158 _dbus_message_get_network_data (DBusMessage          *message,
159                                 const DBusString    **header,
160                                 const DBusString    **body)
161 {
162   _dbus_assert (message->locked);
163
164   *header = &message->header.data;
165   *body = &message->body;
166 }
167
168 /**
169  * Gets the unix fds to be sent over the network for this message.
170  * This function is guaranteed to always return the same data once a
171  * message is locked (with dbus_message_lock()).
172  *
173  * @param message the message.
174  * @param fds return location of unix fd array
175  * @param n_fds return number of entries in array
176  */
177 void _dbus_message_get_unix_fds(DBusMessage *message,
178                                 const int  **fds,
179                                 unsigned    *n_fds)
180 {
181   _dbus_assert (message->locked);
182
183 #ifdef HAVE_UNIX_FD_PASSING
184   *fds = message->unix_fds;
185   *n_fds = message->n_unix_fds;
186 #else
187   *fds = NULL;
188   *n_fds = 0;
189 #endif
190 }
191
192 /**
193  * Sets the serial number of a message.
194  * This can only be done once on a message.
195  *
196  * DBusConnection will automatically set the serial to an appropriate value 
197  * when the message is sent; this function is only needed when encapsulating 
198  * messages in another protocol, or otherwise bypassing DBusConnection.
199  *
200  * @param message the message
201  * @param serial the serial
202  */
203 void 
204 dbus_message_set_serial (DBusMessage   *message,
205                          dbus_uint32_t  serial)
206 {
207   _dbus_return_if_fail (message != NULL);
208   _dbus_return_if_fail (!message->locked);
209
210   _dbus_header_set_serial (&message->header, serial);
211 }
212
213 /**
214  * Adds a counter to be incremented immediately with the size/unix fds
215  * of this message, and decremented by the size/unix fds of this
216  * message when this message if finalized.  The link contains a
217  * counter with its refcount already incremented, but the counter
218  * itself not incremented.  Ownership of link and counter refcount is
219  * passed to the message.
220  *
221  * This function may be called with locks held. As a result, the counter's
222  * notify function is not called; the caller is expected to either call
223  * _dbus_counter_notify() on the counter when they are no longer holding
224  * locks, or take the same action that would be taken by the notify function.
225  *
226  * @param message the message
227  * @param link link with counter as data
228  */
229 void
230 _dbus_message_add_counter_link (DBusMessage  *message,
231                                 DBusList     *link)
232 {
233   /* right now we don't recompute the delta when message
234    * size changes, and that's OK for current purposes
235    * I think, but could be important to change later.
236    * Do recompute it whenever there are no outstanding counters,
237    * since it's basically free.
238    */
239   if (message->counters == NULL)
240     {
241       message->size_counter_delta =
242         _dbus_string_get_length (&message->header.data) +
243         _dbus_string_get_length (&message->body);
244
245 #ifdef HAVE_UNIX_FD_PASSING
246       message->unix_fd_counter_delta = message->n_unix_fds;
247 #endif
248
249 #if 0
250       _dbus_verbose ("message has size %ld\n",
251                      message->size_counter_delta);
252 #endif
253     }
254
255   _dbus_list_append_link (&message->counters, link);
256
257   _dbus_counter_adjust_size (link->data, message->size_counter_delta);
258
259 #ifdef HAVE_UNIX_FD_PASSING
260   _dbus_counter_adjust_unix_fd (link->data, message->unix_fd_counter_delta);
261 #endif
262 }
263
264 /**
265  * Adds a counter to be incremented immediately with the size/unix fds
266  * of this message, and decremented by the size/unix fds of this
267  * message when this message if finalized.
268  *
269  * This function may be called with locks held. As a result, the counter's
270  * notify function is not called; the caller is expected to either call
271  * _dbus_counter_notify() on the counter when they are no longer holding
272  * locks, or take the same action that would be taken by the notify function.
273  *
274  * @param message the message
275  * @param counter the counter
276  * @returns #FALSE if no memory
277  */
278 dbus_bool_t
279 _dbus_message_add_counter (DBusMessage *message,
280                            DBusCounter *counter)
281 {
282   DBusList *link;
283
284   link = _dbus_list_alloc_link (counter);
285   if (link == NULL)
286     return FALSE;
287
288   _dbus_counter_ref (counter);
289   _dbus_message_add_counter_link (message, link);
290
291   return TRUE;
292 }
293
294 /**
295  * Removes a counter tracking the size/unix fds of this message, and
296  * decrements the counter by the size/unix fds of this message.
297  *
298  * @param message the message
299  * @param counter the counter
300  */
301 void
302 _dbus_message_remove_counter (DBusMessage  *message,
303                               DBusCounter  *counter)
304 {
305   DBusList *link;
306
307   link = _dbus_list_find_last (&message->counters,
308                                counter);
309   _dbus_assert (link != NULL);
310
311   _dbus_list_remove_link (&message->counters, link);
312
313   _dbus_counter_adjust_size (counter, - message->size_counter_delta);
314
315 #ifdef HAVE_UNIX_FD_PASSING
316   _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
317 #endif
318
319   _dbus_counter_notify (counter);
320   _dbus_counter_unref (counter);
321 }
322
323 /**
324  * Locks a message. Allows checking that applications don't keep a
325  * reference to a message in the outgoing queue and change it
326  * underneath us. Messages are locked when they enter the outgoing
327  * queue (dbus_connection_send_message()), and the library complains
328  * if the message is modified while locked. This function may also 
329  * called externally, for applications wrapping D-Bus in another protocol.
330  *
331  * @param message the message to lock.
332  */
333 void
334 dbus_message_lock (DBusMessage  *message)
335 {
336   if (!message->locked)
337     {
338       _dbus_header_update_lengths (&message->header,
339                                    _dbus_string_get_length (&message->body));
340
341       /* must have a signature if you have a body */
342       _dbus_assert (_dbus_string_get_length (&message->body) == 0 ||
343                     dbus_message_get_signature (message) != NULL);
344
345       message->locked = TRUE;
346     }
347 }
348
349 static dbus_bool_t
350 set_or_delete_string_field (DBusMessage *message,
351                             int          field,
352                             int          typecode,
353                             const char  *value)
354 {
355   if (value == NULL)
356     return _dbus_header_delete_field (&message->header, field);
357   else
358     return _dbus_header_set_field_basic (&message->header,
359                                          field,
360                                          typecode,
361                                          &value);
362 }
363
364 #if 0
365 /* Probably we don't need to use this */
366 /**
367  * Sets the signature of the message, i.e. the arguments in the
368  * message payload. The signature includes only "in" arguments for
369  * #DBUS_MESSAGE_TYPE_METHOD_CALL and only "out" arguments for
370  * #DBUS_MESSAGE_TYPE_METHOD_RETURN, so is slightly different from
371  * what you might expect (it does not include the signature of the
372  * entire C++-style method).
373  *
374  * The signature is a string made up of type codes such as
375  * #DBUS_TYPE_INT32. The string is terminated with nul (nul is also
376  * the value of #DBUS_TYPE_INVALID). The macros such as
377  * #DBUS_TYPE_INT32 evaluate to integers; to assemble a signature you
378  * may find it useful to use the string forms, such as
379  * #DBUS_TYPE_INT32_AS_STRING.
380  *
381  * An "unset" or #NULL signature is considered the same as an empty
382  * signature. In fact dbus_message_get_signature() will never return
383  * #NULL.
384  *
385  * @param message the message
386  * @param signature the type signature or #NULL to unset
387  * @returns #FALSE if no memory
388  */
389 static dbus_bool_t
390 _dbus_message_set_signature (DBusMessage *message,
391                              const char  *signature)
392 {
393   _dbus_return_val_if_fail (message != NULL, FALSE);
394   _dbus_return_val_if_fail (!message->locked, FALSE);
395   _dbus_return_val_if_fail (signature == NULL ||
396                             _dbus_check_is_valid_signature (signature));
397   /* can't delete the signature if you have a message body */
398   _dbus_return_val_if_fail (_dbus_string_get_length (&message->body) == 0 ||
399                             signature != NULL);
400
401   return set_or_delete_string_field (message,
402                                      DBUS_HEADER_FIELD_SIGNATURE,
403                                      DBUS_TYPE_SIGNATURE,
404                                      signature);
405 }
406 #endif
407
408 /* Message Cache
409  *
410  * We cache some DBusMessage to reduce the overhead of allocating
411  * them.  In my profiling this consistently made about an 8%
412  * difference.  It avoids the malloc for the message, the malloc for
413  * the slot list, the malloc for the header string and body string,
414  * and the associated free() calls. It does introduce another global
415  * lock which could be a performance issue in certain cases.
416  *
417  * For the echo client/server the round trip time goes from around
418  * .000077 to .000069 with the message cache on my laptop. The sysprof
419  * change is as follows (numbers are cumulative percentage):
420  *
421  *  with message cache implemented as array as it is now (0.000069 per):
422  *    new_empty_header           1.46
423  *      mutex_lock               0.56    # i.e. _DBUS_LOCK(message_cache)
424  *      mutex_unlock             0.25
425  *      self                     0.41
426  *    unref                      2.24
427  *      self                     0.68
428  *      list_clear               0.43
429  *      mutex_lock               0.33    # i.e. _DBUS_LOCK(message_cache)
430  *      mutex_unlock             0.25
431  *
432  *  with message cache implemented as list (0.000070 per roundtrip):
433  *    new_empty_header           2.72
434  *      list_pop_first           1.88
435  *    unref                      3.3
436  *      list_prepend             1.63
437  *
438  * without cache (0.000077 per roundtrip):
439  *    new_empty_header           6.7
440  *      string_init_preallocated 3.43
441  *        dbus_malloc            2.43
442  *      dbus_malloc0             2.59
443  *
444  *    unref                      4.02
445  *      string_free              1.82
446  *        dbus_free              1.63
447  *      dbus_free                0.71
448  *
449  * If you implement the message_cache with a list, the primary reason
450  * it's slower is that you add another thread lock (on the DBusList
451  * mempool).
452  */
453
454 /** Avoid caching huge messages */
455 #define MAX_MESSAGE_SIZE_TO_CACHE 10 * _DBUS_ONE_KILOBYTE
456
457 /** Avoid caching too many messages */
458 #define MAX_MESSAGE_CACHE_SIZE    5
459
460 _DBUS_DEFINE_GLOBAL_LOCK (message_cache);
461 static DBusMessage *message_cache[MAX_MESSAGE_CACHE_SIZE];
462 static int message_cache_count = 0;
463 static dbus_bool_t message_cache_shutdown_registered = FALSE;
464
465 static void
466 dbus_message_cache_shutdown (void *data)
467 {
468   int i;
469
470   _DBUS_LOCK (message_cache);
471
472   i = 0;
473   while (i < MAX_MESSAGE_CACHE_SIZE)
474     {
475       if (message_cache[i])
476         dbus_message_finalize (message_cache[i]);
477
478       ++i;
479     }
480
481   message_cache_count = 0;
482   message_cache_shutdown_registered = FALSE;
483
484   _DBUS_UNLOCK (message_cache);
485 }
486
487 /**
488  * Tries to get a message from the message cache.  The retrieved
489  * message will have junk in it, so it still needs to be cleared out
490  * in dbus_message_new_empty_header()
491  *
492  * @returns the message, or #NULL if none cached
493  */
494 static DBusMessage*
495 dbus_message_get_cached (void)
496 {
497   DBusMessage *message;
498   int i;
499
500   message = NULL;
501
502   _DBUS_LOCK (message_cache);
503
504   _dbus_assert (message_cache_count >= 0);
505
506   if (message_cache_count == 0)
507     {
508       _DBUS_UNLOCK (message_cache);
509       return NULL;
510     }
511
512   /* This is not necessarily true unless count > 0, and
513    * message_cache is uninitialized until the shutdown is
514    * registered
515    */
516   _dbus_assert (message_cache_shutdown_registered);
517
518   i = 0;
519   while (i < MAX_MESSAGE_CACHE_SIZE)
520     {
521       if (message_cache[i])
522         {
523           message = message_cache[i];
524           message_cache[i] = NULL;
525           message_cache_count -= 1;
526           break;
527         }
528       ++i;
529     }
530   _dbus_assert (message_cache_count >= 0);
531   _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
532   _dbus_assert (message != NULL);
533
534   _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
535
536   _dbus_assert (message->counters == NULL);
537   
538   _DBUS_UNLOCK (message_cache);
539
540   return message;
541 }
542
543 #ifdef HAVE_UNIX_FD_PASSING
544 static void
545 close_unix_fds(int *fds, unsigned *n_fds)
546 {
547   DBusError e;
548   int i;
549
550   if (*n_fds <= 0)
551     return;
552
553   dbus_error_init(&e);
554
555   for (i = 0; i < *n_fds; i++)
556     {
557       if (!_dbus_close(fds[i], &e))
558         {
559           _dbus_warn("Failed to close file descriptor: %s\n", e.message);
560           dbus_error_free(&e);
561         }
562     }
563
564   *n_fds = 0;
565
566   /* We don't free the array here, in case we can recycle it later */
567 }
568 #endif
569
570 static void
571 free_counter (void *element,
572               void *data)
573 {
574   DBusCounter *counter = element;
575   DBusMessage *message = data;
576
577   _dbus_counter_adjust_size (counter, - message->size_counter_delta);
578 #ifdef HAVE_UNIX_FD_PASSING
579   _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
580 #endif
581
582   _dbus_counter_notify (counter);
583   _dbus_counter_unref (counter);
584 }
585
586 /**
587  * Tries to cache a message, otherwise finalize it.
588  *
589  * @param message the message
590  */
591 static void
592 dbus_message_cache_or_finalize (DBusMessage *message)
593 {
594   dbus_bool_t was_cached;
595   int i;
596
597   _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
598
599   /* This calls application code and has to be done first thing
600    * without holding the lock
601    */
602   _dbus_data_slot_list_clear (&message->slot_list);
603
604   _dbus_list_foreach (&message->counters,
605                       free_counter, message);
606   _dbus_list_clear (&message->counters);
607
608 #ifdef HAVE_UNIX_FD_PASSING
609   close_unix_fds(message->unix_fds, &message->n_unix_fds);
610 #endif
611
612   was_cached = FALSE;
613
614   _DBUS_LOCK (message_cache);
615
616   if (!message_cache_shutdown_registered)
617     {
618       _dbus_assert (message_cache_count == 0);
619
620       if (!_dbus_register_shutdown_func (dbus_message_cache_shutdown, NULL))
621         goto out;
622
623       i = 0;
624       while (i < MAX_MESSAGE_CACHE_SIZE)
625         {
626           message_cache[i] = NULL;
627           ++i;
628         }
629
630       message_cache_shutdown_registered = TRUE;
631     }
632
633   _dbus_assert (message_cache_count >= 0);
634
635   if ((_dbus_string_get_length (&message->header.data) +
636        _dbus_string_get_length (&message->body)) >
637       MAX_MESSAGE_SIZE_TO_CACHE)
638     goto out;
639
640   if (message_cache_count >= MAX_MESSAGE_CACHE_SIZE)
641     goto out;
642
643   /* Find empty slot */
644   i = 0;
645   while (message_cache[i] != NULL)
646     ++i;
647
648   _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
649
650   _dbus_assert (message_cache[i] == NULL);
651   message_cache[i] = message;
652   message_cache_count += 1;
653   was_cached = TRUE;
654 #ifndef DBUS_DISABLE_CHECKS
655   message->in_cache = TRUE;
656 #endif
657
658  out:
659   _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
660
661   _DBUS_UNLOCK (message_cache);
662   
663   if (!was_cached)
664     dbus_message_finalize (message);
665 }
666
667 #ifndef DBUS_DISABLE_CHECKS
668 static dbus_bool_t
669 _dbus_message_iter_check (DBusMessageRealIter *iter)
670 {
671   char byte_order;
672
673   if (iter == NULL)
674     {
675       _dbus_warn_check_failed ("dbus message iterator is NULL\n");
676       return FALSE;
677     }
678
679   byte_order = _dbus_header_get_byte_order (&iter->message->header);
680
681   if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_READER)
682     {
683       if (iter->u.reader.byte_order != byte_order)
684         {
685           _dbus_warn_check_failed ("dbus message changed byte order since iterator was created\n");
686           return FALSE;
687         }
688       /* because we swap the message into compiler order when you init an iter */
689       _dbus_assert (iter->u.reader.byte_order == DBUS_COMPILER_BYTE_ORDER);
690     }
691   else if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER)
692     {
693       if (iter->u.writer.byte_order != byte_order)
694         {
695           _dbus_warn_check_failed ("dbus message changed byte order since append iterator was created\n");
696           return FALSE;
697         }
698       /* because we swap the message into compiler order when you init an iter */
699       _dbus_assert (iter->u.writer.byte_order == DBUS_COMPILER_BYTE_ORDER);
700     }
701   else
702     {
703       _dbus_warn_check_failed ("dbus message iterator looks uninitialized or corrupted\n");
704       return FALSE;
705     }
706
707   if (iter->changed_stamp != iter->message->changed_stamp)
708     {
709       _dbus_warn_check_failed ("dbus message iterator invalid because the message has been modified (or perhaps the iterator is just uninitialized)\n");
710       return FALSE;
711     }
712
713   return TRUE;
714 }
715 #endif /* DBUS_DISABLE_CHECKS */
716
717 /**
718  * Implementation of the varargs arg-getting functions.
719  * dbus_message_get_args() is the place to go for complete
720  * documentation.
721  *
722  * @todo This may leak memory and file descriptors if parsing fails. See #21259
723  *
724  * @see dbus_message_get_args
725  * @param iter the message iter
726  * @param error error to be filled in
727  * @param first_arg_type type of the first argument
728  * @param var_args return location for first argument, followed by list of type/location pairs
729  * @returns #FALSE if error was set
730  */
731 dbus_bool_t
732 _dbus_message_iter_get_args_valist (DBusMessageIter *iter,
733                                     DBusError       *error,
734                                     int              first_arg_type,
735                                     va_list          var_args)
736 {
737   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
738   int spec_type, msg_type, i;
739   dbus_bool_t retval;
740
741   _dbus_assert (_dbus_message_iter_check (real));
742
743   retval = FALSE;
744
745   spec_type = first_arg_type;
746   i = 0;
747
748   while (spec_type != DBUS_TYPE_INVALID)
749     {
750       msg_type = dbus_message_iter_get_arg_type (iter);
751
752       if (msg_type != spec_type)
753         {
754           dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
755                           "Argument %d is specified to be of type \"%s\", but "
756                           "is actually of type \"%s\"\n", i,
757                           _dbus_type_to_string (spec_type),
758                           _dbus_type_to_string (msg_type));
759
760           goto out;
761         }
762
763       if (spec_type == DBUS_TYPE_UNIX_FD)
764         {
765 #ifdef HAVE_UNIX_FD_PASSING
766           DBusBasicValue idx;
767           int *pfd, nfd;
768
769           pfd = va_arg (var_args, int*);
770           _dbus_assert(pfd);
771
772           _dbus_type_reader_read_basic(&real->u.reader, &idx);
773
774           if (idx.u32 >= real->message->n_unix_fds)
775             {
776               dbus_set_error (error, DBUS_ERROR_INCONSISTENT_MESSAGE,
777                               "Message refers to file descriptor at index %i,"
778                               "but has only %i descriptors attached.\n",
779                               idx.u32,
780                               real->message->n_unix_fds);
781               goto out;
782             }
783
784           if ((nfd = _dbus_dup(real->message->unix_fds[idx.u32], error)) < 0)
785             goto out;
786
787           *pfd = nfd;
788 #else
789           dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
790                           "Platform does not support file desciptor passing.\n");
791           goto out;
792 #endif
793         }
794       else if (dbus_type_is_basic (spec_type))
795         {
796           DBusBasicValue *ptr;
797
798           ptr = va_arg (var_args, DBusBasicValue*);
799
800           _dbus_assert (ptr != NULL);
801
802           _dbus_type_reader_read_basic (&real->u.reader,
803                                         ptr);
804         }
805       else if (spec_type == DBUS_TYPE_ARRAY)
806         {
807           int element_type;
808           int spec_element_type;
809           const DBusBasicValue **ptr;
810           int *n_elements_p;
811           DBusTypeReader array;
812
813           spec_element_type = va_arg (var_args, int);
814           element_type = _dbus_type_reader_get_element_type (&real->u.reader);
815
816           if (spec_element_type != element_type)
817             {
818               dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
819                               "Argument %d is specified to be an array of \"%s\", but "
820                               "is actually an array of \"%s\"\n",
821                               i,
822                               _dbus_type_to_string (spec_element_type),
823                               _dbus_type_to_string (element_type));
824
825               goto out;
826             }
827
828           if (dbus_type_is_fixed (spec_element_type) &&
829               element_type != DBUS_TYPE_UNIX_FD)
830             {
831               ptr = va_arg (var_args, const DBusBasicValue**);
832               n_elements_p = va_arg (var_args, int*);
833
834               _dbus_assert (ptr != NULL);
835               _dbus_assert (n_elements_p != NULL);
836
837               _dbus_type_reader_recurse (&real->u.reader, &array);
838
839               _dbus_type_reader_read_fixed_multi (&array,
840                                                   (void *) ptr, n_elements_p);
841             }
842           else if (spec_element_type == DBUS_TYPE_STRING ||
843                    spec_element_type == DBUS_TYPE_SIGNATURE ||
844                    spec_element_type == DBUS_TYPE_OBJECT_PATH)
845             {
846               char ***str_array_p;
847               int n_elements;
848               char **str_array;
849
850               str_array_p = va_arg (var_args, char***);
851               n_elements_p = va_arg (var_args, int*);
852
853               _dbus_assert (str_array_p != NULL);
854               _dbus_assert (n_elements_p != NULL);
855
856               /* Count elements in the array */
857               _dbus_type_reader_recurse (&real->u.reader, &array);
858
859               n_elements = 0;
860               while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
861                 {
862                   ++n_elements;
863                   _dbus_type_reader_next (&array);
864                 }
865
866               str_array = dbus_new0 (char*, n_elements + 1);
867               if (str_array == NULL)
868                 {
869                   _DBUS_SET_OOM (error);
870                   goto out;
871                 }
872
873               /* Now go through and dup each string */
874               _dbus_type_reader_recurse (&real->u.reader, &array);
875
876               i = 0;
877               while (i < n_elements)
878                 {
879                   const char *s;
880                   _dbus_type_reader_read_basic (&array,
881                                                 (void *) &s);
882                   
883                   str_array[i] = _dbus_strdup (s);
884                   if (str_array[i] == NULL)
885                     {
886                       dbus_free_string_array (str_array);
887                       _DBUS_SET_OOM (error);
888                       goto out;
889                     }
890                   
891                   ++i;
892                   
893                   if (!_dbus_type_reader_next (&array))
894                     _dbus_assert (i == n_elements);
895                 }
896
897               _dbus_assert (_dbus_type_reader_get_current_type (&array) == DBUS_TYPE_INVALID);
898               _dbus_assert (i == n_elements);
899               _dbus_assert (str_array[i] == NULL);
900
901               *str_array_p = str_array;
902               *n_elements_p = n_elements;
903             }
904 #ifndef DBUS_DISABLE_CHECKS
905           else
906             {
907               _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now\n",
908                           _DBUS_FUNCTION_NAME);
909               goto out;
910             }
911 #endif
912         }
913 #ifndef DBUS_DISABLE_CHECKS
914       else
915         {
916           _dbus_warn ("you can only read arrays and basic types with %s for now\n",
917                       _DBUS_FUNCTION_NAME);
918           goto out;
919         }
920 #endif
921
922       spec_type = va_arg (var_args, int);
923       if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID)
924         {
925           dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
926                           "Message has only %d arguments, but more were expected", i);
927           goto out;
928         }
929
930       i++;
931     }
932
933   retval = TRUE;
934
935  out:
936
937   return retval;
938 }
939
940 /** @} */
941
942 /**
943  * @defgroup DBusMessage DBusMessage
944  * @ingroup  DBus
945  * @brief Message to be sent or received over a #DBusConnection.
946  *
947  * A DBusMessage is the most basic unit of communication over a
948  * DBusConnection. A DBusConnection represents a stream of messages
949  * received from a remote application, and a stream of messages
950  * sent to a remote application.
951  *
952  * A message has a message type, returned from
953  * dbus_message_get_type().  This indicates whether the message is a
954  * method call, a reply to a method call, a signal, or an error reply.
955  *
956  * A message has header fields such as the sender, destination, method
957  * or signal name, and so forth. DBusMessage has accessor functions for
958  * these, such as dbus_message_get_member().
959  *
960  * Convenience functions dbus_message_is_method_call(), dbus_message_is_signal(),
961  * and dbus_message_is_error() check several header fields at once and are
962  * slightly more efficient than checking the header fields with individual
963  * accessor functions.
964  *
965  * Finally, a message has arguments. The number and types of arguments
966  * are in the message's signature header field (accessed with
967  * dbus_message_get_signature()).  Simple argument values are usually
968  * retrieved with dbus_message_get_args() but more complex values such
969  * as structs may require the use of #DBusMessageIter.
970  *
971  * The D-Bus specification goes into some more detail about header fields and
972  * message types.
973  * 
974  * @{
975  */
976
977 /**
978  * @typedef DBusMessage
979  *
980  * Opaque data type representing a message received from or to be
981  * sent to another application.
982  */
983
984 /**
985  * Returns the serial of a message or 0 if none has been specified.
986  * The message's serial number is provided by the application sending
987  * the message and is used to identify replies to this message.
988  *
989  * All messages received on a connection will have a serial provided
990  * by the remote application.
991  *
992  * For messages you're sending, dbus_connection_send() will assign a
993  * serial and return it to you.
994  *
995  * @param message the message
996  * @returns the serial
997  */
998 dbus_uint32_t
999 dbus_message_get_serial (DBusMessage *message)
1000 {
1001   _dbus_return_val_if_fail (message != NULL, 0);
1002
1003   return _dbus_header_get_serial (&message->header);
1004 }
1005
1006 /**
1007  * Sets the reply serial of a message (the serial of the message this
1008  * is a reply to).
1009  *
1010  * @param message the message
1011  * @param reply_serial the serial we're replying to
1012  * @returns #FALSE if not enough memory
1013  */
1014 dbus_bool_t
1015 dbus_message_set_reply_serial (DBusMessage   *message,
1016                                dbus_uint32_t  reply_serial)
1017 {
1018   _dbus_return_val_if_fail (message != NULL, FALSE);
1019   _dbus_return_val_if_fail (!message->locked, FALSE);
1020   _dbus_return_val_if_fail (reply_serial != 0, FALSE); /* 0 is invalid */
1021
1022   return _dbus_header_set_field_basic (&message->header,
1023                                        DBUS_HEADER_FIELD_REPLY_SERIAL,
1024                                        DBUS_TYPE_UINT32,
1025                                        &reply_serial);
1026 }
1027
1028 /**
1029  * Returns the serial that the message is a reply to or 0 if none.
1030  *
1031  * @param message the message
1032  * @returns the reply serial
1033  */
1034 dbus_uint32_t
1035 dbus_message_get_reply_serial  (DBusMessage *message)
1036 {
1037   dbus_uint32_t v_UINT32;
1038
1039   _dbus_return_val_if_fail (message != NULL, 0);
1040
1041   if (_dbus_header_get_field_basic (&message->header,
1042                                     DBUS_HEADER_FIELD_REPLY_SERIAL,
1043                                     DBUS_TYPE_UINT32,
1044                                     &v_UINT32))
1045     return v_UINT32;
1046   else
1047     return 0;
1048 }
1049
1050 static void
1051 dbus_message_finalize (DBusMessage *message)
1052 {
1053   _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
1054
1055   /* This calls application callbacks! */
1056   _dbus_data_slot_list_free (&message->slot_list);
1057
1058   _dbus_list_foreach (&message->counters,
1059                       free_counter, message);
1060   _dbus_list_clear (&message->counters);
1061
1062   _dbus_header_free (&message->header);
1063   _dbus_string_free (&message->body);
1064
1065 #ifdef HAVE_UNIX_FD_PASSING
1066   close_unix_fds(message->unix_fds, &message->n_unix_fds);
1067   dbus_free(message->unix_fds);
1068 #endif
1069
1070   _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
1071
1072   dbus_free (message);
1073 }
1074
1075 static DBusMessage*
1076 dbus_message_new_empty_header (void)
1077 {
1078   DBusMessage *message;
1079   dbus_bool_t from_cache;
1080
1081   message = dbus_message_get_cached ();
1082
1083   if (message != NULL)
1084     {
1085       from_cache = TRUE;
1086     }
1087   else
1088     {
1089       from_cache = FALSE;
1090       message = dbus_new0 (DBusMessage, 1);
1091       if (message == NULL)
1092         return NULL;
1093 #ifndef DBUS_DISABLE_CHECKS
1094       message->generation = _dbus_current_generation;
1095 #endif
1096
1097 #ifdef HAVE_UNIX_FD_PASSING
1098       message->unix_fds = NULL;
1099       message->n_unix_fds_allocated = 0;
1100 #endif
1101     }
1102
1103   _dbus_atomic_inc (&message->refcount);
1104
1105   message->locked = FALSE;
1106 #ifndef DBUS_DISABLE_CHECKS
1107   message->in_cache = FALSE;
1108 #endif
1109   message->counters = NULL;
1110   message->size_counter_delta = 0;
1111   message->changed_stamp = 0;
1112
1113 #ifdef HAVE_UNIX_FD_PASSING
1114   message->n_unix_fds = 0;
1115   message->n_unix_fds_allocated = 0;
1116   message->unix_fd_counter_delta = 0;
1117 #endif
1118
1119   if (!from_cache)
1120     _dbus_data_slot_list_init (&message->slot_list);
1121
1122   if (from_cache)
1123     {
1124       _dbus_header_reinit (&message->header);
1125       _dbus_string_set_length (&message->body, 0);
1126     }
1127   else
1128     {
1129       if (!_dbus_header_init (&message->header))
1130         {
1131           dbus_free (message);
1132           return NULL;
1133         }
1134
1135       if (!_dbus_string_init_preallocated (&message->body, 32))
1136         {
1137           _dbus_header_free (&message->header);
1138           dbus_free (message);
1139           return NULL;
1140         }
1141     }
1142
1143   return message;
1144 }
1145
1146 /**
1147  * Constructs a new message of the given message type.
1148  * Types include #DBUS_MESSAGE_TYPE_METHOD_CALL,
1149  * #DBUS_MESSAGE_TYPE_SIGNAL, and so forth.
1150  *
1151  * Usually you want to use dbus_message_new_method_call(),
1152  * dbus_message_new_method_return(), dbus_message_new_signal(),
1153  * or dbus_message_new_error() instead.
1154  * 
1155  * @param message_type type of message
1156  * @returns new message or #NULL if no memory
1157  */
1158 DBusMessage*
1159 dbus_message_new (int message_type)
1160 {
1161   DBusMessage *message;
1162
1163   _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
1164
1165   message = dbus_message_new_empty_header ();
1166   if (message == NULL)
1167     return NULL;
1168
1169   if (!_dbus_header_create (&message->header,
1170                             DBUS_COMPILER_BYTE_ORDER,
1171                             message_type,
1172                             NULL, NULL, NULL, NULL, NULL))
1173     {
1174       dbus_message_unref (message);
1175       return NULL;
1176     }
1177
1178   return message;
1179 }
1180
1181 /**
1182  * Constructs a new message to invoke a method on a remote
1183  * object. Returns #NULL if memory can't be allocated for the
1184  * message. The destination may be #NULL in which case no destination
1185  * is set; this is appropriate when using D-Bus in a peer-to-peer
1186  * context (no message bus). The interface may be #NULL, which means
1187  * that if multiple methods with the given name exist it is undefined
1188  * which one will be invoked.
1189  *
1190  * The path and method names may not be #NULL.
1191  *
1192  * Destination, path, interface, and method name can't contain
1193  * any invalid characters (see the D-Bus specification).
1194  * 
1195  * @param destination name that the message should be sent to or #NULL
1196  * @param path object path the message should be sent to
1197  * @param interface interface to invoke method on, or #NULL
1198  * @param method method to invoke
1199  *
1200  * @returns a new DBusMessage, free with dbus_message_unref()
1201  */
1202 DBusMessage*
1203 dbus_message_new_method_call (const char *destination,
1204                               const char *path,
1205                               const char *interface,
1206                               const char *method)
1207 {
1208   DBusMessage *message;
1209
1210   _dbus_return_val_if_fail (path != NULL, NULL);
1211   _dbus_return_val_if_fail (method != NULL, NULL);
1212   _dbus_return_val_if_fail (destination == NULL ||
1213                             _dbus_check_is_valid_bus_name (destination), NULL);
1214   _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
1215   _dbus_return_val_if_fail (interface == NULL ||
1216                             _dbus_check_is_valid_interface (interface), NULL);
1217   _dbus_return_val_if_fail (_dbus_check_is_valid_member (method), NULL);
1218
1219   message = dbus_message_new_empty_header ();
1220   if (message == NULL)
1221     return NULL;
1222
1223   if (!_dbus_header_create (&message->header,
1224                             DBUS_COMPILER_BYTE_ORDER,
1225                             DBUS_MESSAGE_TYPE_METHOD_CALL,
1226                             destination, path, interface, method, NULL))
1227     {
1228       dbus_message_unref (message);
1229       return NULL;
1230     }
1231
1232   return message;
1233 }
1234
1235 /**
1236  * Constructs a message that is a reply to a method call. Returns
1237  * #NULL if memory can't be allocated for the message.
1238  *
1239  * @param method_call the message being replied to
1240  * @returns a new DBusMessage, free with dbus_message_unref()
1241  */
1242 DBusMessage*
1243 dbus_message_new_method_return (DBusMessage *method_call)
1244 {
1245   DBusMessage *message;
1246   const char *sender;
1247
1248   _dbus_return_val_if_fail (method_call != NULL, NULL);
1249
1250   sender = dbus_message_get_sender (method_call);
1251
1252   /* sender is allowed to be null here in peer-to-peer case */
1253
1254   message = dbus_message_new_empty_header ();
1255   if (message == NULL)
1256     return NULL;
1257
1258   if (!_dbus_header_create (&message->header,
1259                             DBUS_COMPILER_BYTE_ORDER,
1260                             DBUS_MESSAGE_TYPE_METHOD_RETURN,
1261                             sender, NULL, NULL, NULL, NULL))
1262     {
1263       dbus_message_unref (message);
1264       return NULL;
1265     }
1266
1267   dbus_message_set_no_reply (message, TRUE);
1268
1269   if (!dbus_message_set_reply_serial (message,
1270                                       dbus_message_get_serial (method_call)))
1271     {
1272       dbus_message_unref (message);
1273       return NULL;
1274     }
1275
1276   return message;
1277 }
1278
1279 /**
1280  * Constructs a new message representing a signal emission. Returns
1281  * #NULL if memory can't be allocated for the message.  A signal is
1282  * identified by its originating object path, interface, and the name
1283  * of the signal.
1284  *
1285  * Path, interface, and signal name must all be valid (the D-Bus
1286  * specification defines the syntax of these fields).
1287  * 
1288  * @param path the path to the object emitting the signal
1289  * @param interface the interface the signal is emitted from
1290  * @param name name of the signal
1291  * @returns a new DBusMessage, free with dbus_message_unref()
1292  */
1293 DBusMessage*
1294 dbus_message_new_signal (const char *path,
1295                          const char *interface,
1296                          const char *name)
1297 {
1298   DBusMessage *message;
1299
1300   _dbus_return_val_if_fail (path != NULL, NULL);
1301   _dbus_return_val_if_fail (interface != NULL, NULL);
1302   _dbus_return_val_if_fail (name != NULL, NULL);
1303   _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
1304   _dbus_return_val_if_fail (_dbus_check_is_valid_interface (interface), NULL);
1305   _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);
1306
1307   message = dbus_message_new_empty_header ();
1308   if (message == NULL)
1309     return NULL;
1310
1311   if (!_dbus_header_create (&message->header,
1312                             DBUS_COMPILER_BYTE_ORDER,
1313                             DBUS_MESSAGE_TYPE_SIGNAL,
1314                             NULL, path, interface, name, NULL))
1315     {
1316       dbus_message_unref (message);
1317       return NULL;
1318     }
1319
1320   dbus_message_set_no_reply (message, TRUE);
1321
1322   return message;
1323 }
1324
1325 /**
1326  * Creates a new message that is an error reply to another message.
1327  * Error replies are most common in response to method calls, but
1328  * can be returned in reply to any message.
1329  *
1330  * The error name must be a valid error name according to the syntax
1331  * given in the D-Bus specification. If you don't want to make
1332  * up an error name just use #DBUS_ERROR_FAILED.
1333  *
1334  * @param reply_to the message we're replying to
1335  * @param error_name the error name
1336  * @param error_message the error message string (or #NULL for none, but please give a message)
1337  * @returns a new error message object, free with dbus_message_unref()
1338  */
1339 DBusMessage*
1340 dbus_message_new_error (DBusMessage *reply_to,
1341                         const char  *error_name,
1342                         const char  *error_message)
1343 {
1344   DBusMessage *message;
1345   const char *sender;
1346   DBusMessageIter iter;
1347
1348   _dbus_return_val_if_fail (reply_to != NULL, NULL);
1349   _dbus_return_val_if_fail (error_name != NULL, NULL);
1350   _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
1351
1352   sender = dbus_message_get_sender (reply_to);
1353
1354   /* sender may be NULL for non-message-bus case or
1355    * when the message bus is dealing with an unregistered
1356    * connection.
1357    */
1358   message = dbus_message_new_empty_header ();
1359   if (message == NULL)
1360     return NULL;
1361
1362   if (!_dbus_header_create (&message->header,
1363                             DBUS_COMPILER_BYTE_ORDER,
1364                             DBUS_MESSAGE_TYPE_ERROR,
1365                             sender, NULL, NULL, NULL, error_name))
1366     {
1367       dbus_message_unref (message);
1368       return NULL;
1369     }
1370
1371   dbus_message_set_no_reply (message, TRUE);
1372
1373   if (!dbus_message_set_reply_serial (message,
1374                                       dbus_message_get_serial (reply_to)))
1375     {
1376       dbus_message_unref (message);
1377       return NULL;
1378     }
1379
1380   if (error_message != NULL)
1381     {
1382       dbus_message_iter_init_append (message, &iter);
1383       if (!dbus_message_iter_append_basic (&iter,
1384                                            DBUS_TYPE_STRING,
1385                                            &error_message))
1386         {
1387           dbus_message_unref (message);
1388           return NULL;
1389         }
1390     }
1391
1392   return message;
1393 }
1394
1395 /**
1396  * Creates a new message that is an error reply to another message, allowing
1397  * you to use printf formatting.
1398  *
1399  * See dbus_message_new_error() for details - this function is the same
1400  * aside from the printf formatting.
1401  *
1402  * @todo add _DBUS_GNUC_PRINTF to this (requires moving _DBUS_GNUC_PRINTF to
1403  * public header, see DBUS_DEPRECATED for an example)
1404  * 
1405  * @param reply_to the original message
1406  * @param error_name the error name
1407  * @param error_format the error message format as with printf
1408  * @param ... format string arguments
1409  * @returns a new error message
1410  */
1411 DBusMessage*
1412 dbus_message_new_error_printf (DBusMessage *reply_to,
1413                                const char  *error_name,
1414                                const char  *error_format,
1415                                ...)
1416 {
1417   va_list args;
1418   DBusString str;
1419   DBusMessage *message;
1420
1421   _dbus_return_val_if_fail (reply_to != NULL, NULL);
1422   _dbus_return_val_if_fail (error_name != NULL, NULL);
1423   _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
1424
1425   if (!_dbus_string_init (&str))
1426     return NULL;
1427
1428   va_start (args, error_format);
1429
1430   if (_dbus_string_append_printf_valist (&str, error_format, args))
1431     message = dbus_message_new_error (reply_to, error_name,
1432                                       _dbus_string_get_const_data (&str));
1433   else
1434     message = NULL;
1435
1436   _dbus_string_free (&str);
1437
1438   va_end (args);
1439
1440   return message;
1441 }
1442
1443
1444 /**
1445  * Creates a new message that is an exact replica of the message
1446  * specified, except that its refcount is set to 1, its message serial
1447  * is reset to 0, and if the original message was "locked" (in the
1448  * outgoing message queue and thus not modifiable) the new message
1449  * will not be locked.
1450  *
1451  * @todo This function can't be used in programs that try to recover from OOM errors.
1452  *
1453  * @param message the message
1454  * @returns the new message.or #NULL if not enough memory or Unix file descriptors (in case the message to copy includes Unix file descriptors) can be allocated.
1455  */
1456 DBusMessage *
1457 dbus_message_copy (const DBusMessage *message)
1458 {
1459   DBusMessage *retval;
1460
1461   _dbus_return_val_if_fail (message != NULL, NULL);
1462
1463   retval = dbus_new0 (DBusMessage, 1);
1464   if (retval == NULL)
1465     return NULL;
1466
1467   _dbus_atomic_inc (&retval->refcount);
1468
1469   retval->locked = FALSE;
1470 #ifndef DBUS_DISABLE_CHECKS
1471   retval->generation = message->generation;
1472 #endif
1473
1474   if (!_dbus_header_copy (&message->header, &retval->header))
1475     {
1476       dbus_free (retval);
1477       return NULL;
1478     }
1479
1480   if (!_dbus_string_init_preallocated (&retval->body,
1481                                        _dbus_string_get_length (&message->body)))
1482     {
1483       _dbus_header_free (&retval->header);
1484       dbus_free (retval);
1485       return NULL;
1486     }
1487
1488   if (!_dbus_string_copy (&message->body, 0,
1489                           &retval->body, 0))
1490     goto failed_copy;
1491
1492 #ifdef HAVE_UNIX_FD_PASSING
1493   retval->unix_fds = dbus_new(int, message->n_unix_fds);
1494   if (retval->unix_fds == NULL && message->n_unix_fds > 0)
1495     goto failed_copy;
1496
1497   retval->n_unix_fds_allocated = message->n_unix_fds;
1498
1499   for (retval->n_unix_fds = 0;
1500        retval->n_unix_fds < message->n_unix_fds;
1501        retval->n_unix_fds++)
1502     {
1503       retval->unix_fds[retval->n_unix_fds] = _dbus_dup(message->unix_fds[retval->n_unix_fds], NULL);
1504
1505       if (retval->unix_fds[retval->n_unix_fds] < 0)
1506         goto failed_copy;
1507     }
1508
1509 #endif
1510
1511   return retval;
1512
1513  failed_copy:
1514   _dbus_header_free (&retval->header);
1515   _dbus_string_free (&retval->body);
1516
1517 #ifdef HAVE_UNIX_FD_PASSING
1518   close_unix_fds(retval->unix_fds, &retval->n_unix_fds);
1519   dbus_free(retval->unix_fds);
1520 #endif
1521
1522   dbus_free (retval);
1523
1524   return NULL;
1525 }
1526
1527
1528 /**
1529  * Increments the reference count of a DBusMessage.
1530  *
1531  * @param message the message
1532  * @returns the message
1533  * @see dbus_message_unref
1534  */
1535 DBusMessage *
1536 dbus_message_ref (DBusMessage *message)
1537 {
1538 #ifndef DBUS_DISABLE_ASSERT
1539   dbus_int32_t old_refcount;
1540 #endif
1541
1542   _dbus_return_val_if_fail (message != NULL, NULL);
1543   _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
1544   _dbus_return_val_if_fail (!message->in_cache, NULL);
1545
1546 #ifdef DBUS_DISABLE_ASSERT
1547   _dbus_atomic_inc (&message->refcount);
1548 #else
1549   old_refcount = _dbus_atomic_inc (&message->refcount);
1550   _dbus_assert (old_refcount >= 1);
1551 #endif
1552
1553   return message;
1554 }
1555
1556 /**
1557  * Decrements the reference count of a DBusMessage, freeing the
1558  * message if the count reaches 0.
1559  *
1560  * @param message the message
1561  * @see dbus_message_ref
1562  */
1563 void
1564 dbus_message_unref (DBusMessage *message)
1565 {
1566  dbus_int32_t old_refcount;
1567
1568   _dbus_return_if_fail (message != NULL);
1569   _dbus_return_if_fail (message->generation == _dbus_current_generation);
1570   _dbus_return_if_fail (!message->in_cache);
1571
1572   old_refcount = _dbus_atomic_dec (&message->refcount);
1573
1574   _dbus_assert (old_refcount >= 1);
1575
1576   if (old_refcount == 1)
1577     {
1578       /* Calls application callbacks! */
1579       dbus_message_cache_or_finalize (message);
1580     }
1581 }
1582
1583 /**
1584  * Gets the type of a message. Types include
1585  * #DBUS_MESSAGE_TYPE_METHOD_CALL, #DBUS_MESSAGE_TYPE_METHOD_RETURN,
1586  * #DBUS_MESSAGE_TYPE_ERROR, #DBUS_MESSAGE_TYPE_SIGNAL, but other
1587  * types are allowed and all code must silently ignore messages of
1588  * unknown type. #DBUS_MESSAGE_TYPE_INVALID will never be returned.
1589  *
1590  * @param message the message
1591  * @returns the type of the message
1592  */
1593 int
1594 dbus_message_get_type (DBusMessage *message)
1595 {
1596   _dbus_return_val_if_fail (message != NULL, DBUS_MESSAGE_TYPE_INVALID);
1597
1598   return _dbus_header_get_message_type (&message->header);
1599 }
1600
1601 /**
1602  * Appends fields to a message given a variable argument list. The
1603  * variable argument list should contain the type of each argument
1604  * followed by the value to append. Appendable types are basic types,
1605  * and arrays of fixed-length basic types (except arrays of Unix file
1606  * descriptors). To append variable-length basic types, or any more
1607  * complex value, you have to use an iterator rather than this
1608  * function.
1609  *
1610  * To append a basic type, specify its type code followed by the
1611  * address of the value. For example:
1612  *
1613  * @code
1614  *
1615  * dbus_int32_t v_INT32 = 42;
1616  * const char *v_STRING = "Hello World";
1617  * dbus_message_append_args (message,
1618  *                           DBUS_TYPE_INT32, &v_INT32,
1619  *                           DBUS_TYPE_STRING, &v_STRING,
1620  *                           DBUS_TYPE_INVALID);
1621  * @endcode
1622  *
1623  * To append an array of fixed-length basic types (except Unix file
1624  * descriptors), pass in the DBUS_TYPE_ARRAY typecode, the element
1625  * typecode, the address of the array pointer, and a 32-bit integer
1626  * giving the number of elements in the array. So for example: @code
1627  * const dbus_int32_t array[] = { 1, 2, 3 }; const dbus_int32_t
1628  * *v_ARRAY = array; dbus_message_append_args (message,
1629  * DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &v_ARRAY, 3, DBUS_TYPE_INVALID);
1630  * @endcode
1631  *
1632  * This function does not support arrays of Unix file descriptors. If
1633  * you need those you need to manually recurse into the array.
1634  *
1635  * For Unix file descriptors this function will internally duplicate
1636  * the descriptor you passed in. Hence you may close the descriptor
1637  * immediately after this call.
1638  *
1639  * @warning in C, given "int array[]", "&array == array" (the
1640  * comp.lang.c FAQ says otherwise, but gcc and the FAQ don't agree).
1641  * So if you're using an array instead of a pointer you have to create
1642  * a pointer variable, assign the array to it, then take the address
1643  * of the pointer variable. For strings it works to write
1644  * const char *array = "Hello" and then use &array though.
1645  *
1646  * The last argument to this function must be #DBUS_TYPE_INVALID,
1647  * marking the end of the argument list. If you don't do this
1648  * then libdbus won't know to stop and will read invalid memory.
1649  *
1650  * String/signature/path arrays should be passed in as "const char***
1651  * address_of_array" and "int n_elements"
1652  *
1653  * @todo support DBUS_TYPE_STRUCT and DBUS_TYPE_VARIANT and complex arrays
1654  *
1655  * @todo If this fails due to lack of memory, the message is hosed and
1656  * you have to start over building the whole message.
1657  *
1658  * @param message the message
1659  * @param first_arg_type type of the first argument
1660  * @param ... value of first argument, list of additional type-value pairs
1661  * @returns #TRUE on success
1662  */
1663 dbus_bool_t
1664 dbus_message_append_args (DBusMessage *message,
1665                           int          first_arg_type,
1666                           ...)
1667 {
1668   dbus_bool_t retval;
1669   va_list var_args;
1670
1671   _dbus_return_val_if_fail (message != NULL, FALSE);
1672
1673   va_start (var_args, first_arg_type);
1674   retval = dbus_message_append_args_valist (message,
1675                                             first_arg_type,
1676                                             var_args);
1677   va_end (var_args);
1678
1679   return retval;
1680 }
1681
1682 /**
1683  * Like dbus_message_append_args() but takes a va_list for use by language bindings.
1684  *
1685  * @todo for now, if this function fails due to OOM it will leave
1686  * the message half-written and you have to discard the message
1687  * and start over.
1688  *
1689  * @see dbus_message_append_args.
1690  * @param message the message
1691  * @param first_arg_type type of first argument
1692  * @param var_args value of first argument, then list of type/value pairs
1693  * @returns #TRUE on success
1694  */
1695 dbus_bool_t
1696 dbus_message_append_args_valist (DBusMessage *message,
1697                                  int          first_arg_type,
1698                                  va_list      var_args)
1699 {
1700   int type;
1701   DBusMessageIter iter;
1702
1703   _dbus_return_val_if_fail (message != NULL, FALSE);
1704
1705   type = first_arg_type;
1706
1707   dbus_message_iter_init_append (message, &iter);
1708
1709   while (type != DBUS_TYPE_INVALID)
1710     {
1711       if (dbus_type_is_basic (type))
1712         {
1713           const DBusBasicValue *value;
1714           value = va_arg (var_args, const DBusBasicValue*);
1715
1716           if (!dbus_message_iter_append_basic (&iter,
1717                                                type,
1718                                                value))
1719             goto failed;
1720         }
1721       else if (type == DBUS_TYPE_ARRAY)
1722         {
1723           int element_type;
1724           DBusMessageIter array;
1725           char buf[2];
1726
1727           element_type = va_arg (var_args, int);
1728               
1729           buf[0] = element_type;
1730           buf[1] = '\0';
1731           if (!dbus_message_iter_open_container (&iter,
1732                                                  DBUS_TYPE_ARRAY,
1733                                                  buf,
1734                                                  &array))
1735             goto failed;
1736
1737           if (dbus_type_is_fixed (element_type) &&
1738               element_type != DBUS_TYPE_UNIX_FD)
1739             {
1740               const DBusBasicValue **value;
1741               int n_elements;
1742
1743               value = va_arg (var_args, const DBusBasicValue**);
1744               n_elements = va_arg (var_args, int);
1745               
1746               if (!dbus_message_iter_append_fixed_array (&array,
1747                                                          element_type,
1748                                                          value,
1749                                                          n_elements)) {
1750                 dbus_message_iter_abandon_container (&iter, &array);
1751                 goto failed;
1752               }
1753             }
1754           else if (element_type == DBUS_TYPE_STRING ||
1755                    element_type == DBUS_TYPE_SIGNATURE ||
1756                    element_type == DBUS_TYPE_OBJECT_PATH)
1757             {
1758               const char ***value_p;
1759               const char **value;
1760               int n_elements;
1761               int i;
1762               
1763               value_p = va_arg (var_args, const char***);
1764               n_elements = va_arg (var_args, int);
1765
1766               value = *value_p;
1767               
1768               i = 0;
1769               while (i < n_elements)
1770                 {
1771                   if (!dbus_message_iter_append_basic (&array,
1772                                                        element_type,
1773                                                        &value[i])) {
1774                     dbus_message_iter_abandon_container (&iter, &array);
1775                     goto failed;
1776                   }
1777                   ++i;
1778                 }
1779             }
1780           else
1781             {
1782               _dbus_warn ("arrays of %s can't be appended with %s for now\n",
1783                           _dbus_type_to_string (element_type),
1784                           _DBUS_FUNCTION_NAME);
1785               goto failed;
1786             }
1787
1788           if (!dbus_message_iter_close_container (&iter, &array))
1789             goto failed;
1790         }
1791 #ifndef DBUS_DISABLE_CHECKS
1792       else
1793         {
1794           _dbus_warn ("type %s isn't supported yet in %s\n",
1795                       _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
1796           goto failed;
1797         }
1798 #endif
1799
1800       type = va_arg (var_args, int);
1801     }
1802
1803   return TRUE;
1804
1805  failed:
1806   return FALSE;
1807 }
1808
1809 /**
1810  * Gets arguments from a message given a variable argument list.  The
1811  * supported types include those supported by
1812  * dbus_message_append_args(); that is, basic types and arrays of
1813  * fixed-length basic types.  The arguments are the same as they would
1814  * be for dbus_message_iter_get_basic() or
1815  * dbus_message_iter_get_fixed_array().
1816  *
1817  * In addition to those types, arrays of string, object path, and
1818  * signature are supported; but these are returned as allocated memory
1819  * and must be freed with dbus_free_string_array(), while the other
1820  * types are returned as const references. To get a string array
1821  * pass in "char ***array_location" and "int *n_elements".
1822  *
1823  * Similar to dbus_message_get_fixed_array() this function does not
1824  * support arrays of type DBUS_TYPE_UNIX_FD. If you need to parse
1825  * messages with arrays of Unix file descriptors you need to recurse
1826  * into the array manually.
1827  *
1828  * Unix file descriptors that are read with this function will have
1829  * the FD_CLOEXEC flag set. If you need them without this flag set,
1830  * make sure to unset it with fcntl().
1831  *
1832  * The variable argument list should contain the type of the argument
1833  * followed by a pointer to where the value should be stored. The list
1834  * is terminated with #DBUS_TYPE_INVALID.
1835  *
1836  * Except for string arrays, the returned values are constant; do not
1837  * free them. They point into the #DBusMessage.
1838  *
1839  * If the requested arguments are not present, or do not have the
1840  * requested types, then an error will be set.
1841  *
1842  * If more arguments than requested are present, the requested
1843  * arguments are returned and the extra arguments are ignored.
1844  * 
1845  * @todo support DBUS_TYPE_STRUCT and DBUS_TYPE_VARIANT and complex arrays
1846  *
1847  * @param message the message
1848  * @param error error to be filled in on failure
1849  * @param first_arg_type the first argument type
1850  * @param ... location for first argument value, then list of type-location pairs
1851  * @returns #FALSE if the error was set
1852  */
1853 dbus_bool_t
1854 dbus_message_get_args (DBusMessage     *message,
1855                        DBusError       *error,
1856                        int              first_arg_type,
1857                        ...)
1858 {
1859   dbus_bool_t retval;
1860   va_list var_args;
1861
1862   _dbus_return_val_if_fail (message != NULL, FALSE);
1863   _dbus_return_val_if_error_is_set (error, FALSE);
1864
1865   va_start (var_args, first_arg_type);
1866   retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
1867   va_end (var_args);
1868
1869   return retval;
1870 }
1871
1872 /**
1873  * Like dbus_message_get_args but takes a va_list for use by language bindings.
1874  *
1875  * @see dbus_message_get_args
1876  * @param message the message
1877  * @param error error to be filled in
1878  * @param first_arg_type type of the first argument
1879  * @param var_args return location for first argument, followed by list of type/location pairs
1880  * @returns #FALSE if error was set
1881  */
1882 dbus_bool_t
1883 dbus_message_get_args_valist (DBusMessage     *message,
1884                               DBusError       *error,
1885                               int              first_arg_type,
1886                               va_list          var_args)
1887 {
1888   DBusMessageIter iter;
1889
1890   _dbus_return_val_if_fail (message != NULL, FALSE);
1891   _dbus_return_val_if_error_is_set (error, FALSE);
1892
1893   dbus_message_iter_init (message, &iter);
1894   return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
1895 }
1896
1897 static void
1898 _dbus_message_iter_init_common (DBusMessage         *message,
1899                                 DBusMessageRealIter *real,
1900                                 int                  iter_type)
1901 {
1902   _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
1903
1904   /* Since the iterator will read or write who-knows-what from the
1905    * message, we need to get in the right byte order
1906    */
1907   ensure_byte_order (message);
1908   
1909   real->message = message;
1910   real->changed_stamp = message->changed_stamp;
1911   real->iter_type = iter_type;
1912   real->sig_refcount = 0;
1913 }
1914
1915 /**
1916  * Initializes a #DBusMessageIter for reading the arguments of the
1917  * message passed in.
1918  *
1919  * When possible, dbus_message_get_args() is much more convenient.
1920  * Some types of argument can only be read with #DBusMessageIter
1921  * however.
1922  *
1923  * The easiest way to iterate is like this: 
1924  * @code
1925  * dbus_message_iter_init (message, &iter);
1926  * while ((current_type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID)
1927  *   dbus_message_iter_next (&iter);
1928  * @endcode
1929  *
1930  * #DBusMessageIter contains no allocated memory; it need not be
1931  * freed, and can be copied by assignment or memcpy().
1932  * 
1933  * @param message the message
1934  * @param iter pointer to an iterator to initialize
1935  * @returns #FALSE if the message has no arguments
1936  */
1937 dbus_bool_t
1938 dbus_message_iter_init (DBusMessage     *message,
1939                         DBusMessageIter *iter)
1940 {
1941   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
1942   const DBusString *type_str;
1943   int type_pos;
1944
1945   _dbus_return_val_if_fail (message != NULL, FALSE);
1946   _dbus_return_val_if_fail (iter != NULL, FALSE);
1947
1948   get_const_signature (&message->header, &type_str, &type_pos);
1949
1950   _dbus_message_iter_init_common (message, real,
1951                                   DBUS_MESSAGE_ITER_TYPE_READER);
1952
1953   _dbus_type_reader_init (&real->u.reader,
1954                           _dbus_header_get_byte_order (&message->header),
1955                           type_str, type_pos,
1956                           &message->body,
1957                           0);
1958
1959   return _dbus_type_reader_get_current_type (&real->u.reader) != DBUS_TYPE_INVALID;
1960 }
1961
1962 /**
1963  * Checks if an iterator has any more fields.
1964  *
1965  * @param iter the message iter
1966  * @returns #TRUE if there are more fields following
1967  */
1968 dbus_bool_t
1969 dbus_message_iter_has_next (DBusMessageIter *iter)
1970 {
1971   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
1972
1973   _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
1974   _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
1975
1976   return _dbus_type_reader_has_next (&real->u.reader);
1977 }
1978
1979 /**
1980  * Moves the iterator to the next field, if any. If there's no next
1981  * field, returns #FALSE. If the iterator moves forward, returns
1982  * #TRUE.
1983  *
1984  * @param iter the message iter
1985  * @returns #TRUE if the iterator was moved to the next field
1986  */
1987 dbus_bool_t
1988 dbus_message_iter_next (DBusMessageIter *iter)
1989 {
1990   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
1991
1992   _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
1993   _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
1994
1995   return _dbus_type_reader_next (&real->u.reader);
1996 }
1997
1998 /**
1999  * Returns the argument type of the argument that the message iterator
2000  * points to. If the iterator is at the end of the message, returns
2001  * #DBUS_TYPE_INVALID. You can thus write a loop as follows:
2002  *
2003  * @code
2004  * dbus_message_iter_init (message, &iter);
2005  * while ((current_type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID)
2006  *   dbus_message_iter_next (&iter);
2007  * @endcode
2008  *
2009  * @param iter the message iter
2010  * @returns the argument type
2011  */
2012 int
2013 dbus_message_iter_get_arg_type (DBusMessageIter *iter)
2014 {
2015   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2016
2017   _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2018   _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2019
2020   return _dbus_type_reader_get_current_type (&real->u.reader);
2021 }
2022
2023 /**
2024  * Returns the element type of the array that the message iterator
2025  * points to. Note that you need to check that the iterator points to
2026  * an array prior to using this function.
2027  *
2028  * @param iter the message iter
2029  * @returns the array element type
2030  */
2031 int
2032 dbus_message_iter_get_element_type (DBusMessageIter *iter)
2033 {
2034   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2035
2036   _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2037   _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
2038   _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
2039
2040   return _dbus_type_reader_get_element_type (&real->u.reader);
2041 }
2042
2043 /**
2044  * Recurses into a container value when reading values from a message,
2045  * initializing a sub-iterator to use for traversing the child values
2046  * of the container.
2047  *
2048  * Note that this recurses into a value, not a type, so you can only
2049  * recurse if the value exists. The main implication of this is that
2050  * if you have for example an empty array of array of int32, you can
2051  * recurse into the outermost array, but it will have no values, so
2052  * you won't be able to recurse further. There's no array of int32 to
2053  * recurse into.
2054  *
2055  * If a container is an array of fixed-length types (except Unix file
2056  * descriptors), it is much more efficient to use
2057  * dbus_message_iter_get_fixed_array() to get the whole array in one
2058  * shot, rather than individually walking over the array elements.
2059  *
2060  * Be sure you have somehow checked that
2061  * dbus_message_iter_get_arg_type() matches the type you are expecting
2062  * to recurse into. Results of this function are undefined if there is
2063  * no container to recurse into at the current iterator position.
2064  *
2065  * @param iter the message iterator
2066  * @param sub the sub-iterator to initialize
2067  */
2068 void
2069 dbus_message_iter_recurse (DBusMessageIter  *iter,
2070                            DBusMessageIter  *sub)
2071 {
2072   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2073   DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2074
2075   _dbus_return_if_fail (_dbus_message_iter_check (real));
2076   _dbus_return_if_fail (sub != NULL);
2077
2078   *real_sub = *real;
2079   _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
2080 }
2081
2082 /**
2083  * Returns the current signature of a message iterator.  This
2084  * is useful primarily for dealing with variants; one can
2085  * recurse into a variant and determine the signature of
2086  * the variant's value.
2087  *
2088  * The returned string must be freed with dbus_free().
2089  * 
2090  * @param iter the message iterator
2091  * @returns the contained signature, or NULL if out of memory
2092  */
2093 char *
2094 dbus_message_iter_get_signature (DBusMessageIter *iter)
2095 {
2096   const DBusString *sig;
2097   DBusString retstr;
2098   char *ret;
2099   int start, len;
2100   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2101
2102   _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
2103
2104   if (!_dbus_string_init (&retstr))
2105     return NULL;
2106
2107   _dbus_type_reader_get_signature (&real->u.reader, &sig,
2108                                    &start, &len);
2109   if (!_dbus_string_append_len (&retstr,
2110                                 _dbus_string_get_const_data (sig) + start,
2111                                 len))
2112     return NULL;
2113   if (!_dbus_string_steal_data (&retstr, &ret))
2114     return NULL;
2115   _dbus_string_free (&retstr);
2116   return ret;
2117 }
2118
2119 /**
2120  * Reads a basic-typed value from the message iterator.
2121  * Basic types are the non-containers such as integer and string.
2122  *
2123  * The value argument should be the address of a location to store
2124  * the returned value. So for int32 it should be a "dbus_int32_t*"
2125  * and for string a "const char**". The returned value is
2126  * by reference and should not be freed.
2127  *
2128  * This call duplicates Unix file descriptors when reading them. It is
2129  * your job to close them when you don't need them anymore.
2130  *
2131  * Unix file descriptors that are read with this function will have
2132  * the FD_CLOEXEC flag set. If you need them without this flag set,
2133  * make sure to unset it with fcntl().
2134  *
2135  * Be sure you have somehow checked that
2136  * dbus_message_iter_get_arg_type() matches the type you are
2137  * expecting, or you'll crash when you try to use an integer as a
2138  * string or something.
2139  *
2140  * To read any container type (array, struct, dict) you will need to
2141  * recurse into the container with dbus_message_iter_recurse().  If
2142  * the container is an array of fixed-length values (except Unix file
2143  * descriptors), you can get all the array elements at once with
2144  * dbus_message_iter_get_fixed_array(). Otherwise, you have to iterate
2145  * over the container's contents one value at a time.
2146  * 
2147  * All basic-typed values are guaranteed to fit in 8 bytes. So you can
2148  * write code like this:
2149  *
2150  * @code
2151  * dbus_uint64_t value;
2152  * int type;
2153  * dbus_message_iter_get_basic (&read_iter, &value);
2154  * type = dbus_message_iter_get_arg_type (&read_iter);
2155  * dbus_message_iter_append_basic (&write_iter, type, &value);
2156  * @endcode
2157  *
2158  * On some really obscure platforms dbus_uint64_t might not exist, if
2159  * you need to worry about this you will know.  dbus_uint64_t is just
2160  * one example of a type that's large enough to hold any possible
2161  * value, you could use a struct or char[8] instead if you like.
2162  *
2163  * @param iter the iterator
2164  * @param value location to store the value
2165  */
2166 void
2167 dbus_message_iter_get_basic (DBusMessageIter  *iter,
2168                              void             *value)
2169 {
2170   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2171
2172   _dbus_return_if_fail (_dbus_message_iter_check (real));
2173   _dbus_return_if_fail (value != NULL);
2174
2175   if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_UNIX_FD)
2176     {
2177 #ifdef HAVE_UNIX_FD_PASSING
2178       DBusBasicValue idx;
2179
2180       _dbus_type_reader_read_basic(&real->u.reader, &idx);
2181
2182       if (idx.u32 >= real->message->n_unix_fds) {
2183         /* Hmm, we cannot really signal an error here, so let's make
2184            sure to return an invalid fd. */
2185         *((int*) value) = -1;
2186         return;
2187       }
2188
2189       *((int*) value) = _dbus_dup(real->message->unix_fds[idx.u32], NULL);
2190 #else
2191       *((int*) value) = -1;
2192 #endif
2193     }
2194   else
2195     {
2196       _dbus_type_reader_read_basic (&real->u.reader,
2197                                     value);
2198     }
2199 }
2200
2201 /**
2202  * Returns the number of bytes in the array as marshaled in the wire
2203  * protocol. The iterator must currently be inside an array-typed
2204  * value.
2205  *
2206  * This function is deprecated on the grounds that it is stupid.  Why
2207  * would you want to know how many bytes are in the array as marshaled
2208  * in the wire protocol?  For now, use the n_elements returned from
2209  * dbus_message_iter_get_fixed_array() instead, or iterate over the
2210  * array values and count them.
2211  *
2212  * @todo introduce a variant of this get_n_elements that returns
2213  * the number of elements, though with a non-fixed array it will not
2214  * be very efficient, so maybe it's not good.
2215  * 
2216  * @param iter the iterator
2217  * @returns the number of bytes in the array
2218  */
2219 int
2220 dbus_message_iter_get_array_len (DBusMessageIter *iter)
2221 {
2222   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2223
2224   _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
2225
2226   return _dbus_type_reader_get_array_length (&real->u.reader);
2227 }
2228
2229 /**
2230  * Reads a block of fixed-length values from the message iterator.
2231  * Fixed-length values are those basic types that are not string-like,
2232  * such as integers, bool, double. The returned block will be from the
2233  * current position in the array until the end of the array.
2234  *
2235  * There is one exception here: although DBUS_TYPE_UNIX_FD is
2236  * considered a 'fixed' type arrays of this type may not be read with
2237  * this function.
2238  *
2239  * The message iter should be "in" the array (that is, you recurse into the
2240  * array, and then you call dbus_message_iter_get_fixed_array() on the
2241  * "sub-iterator" created by dbus_message_iter_recurse()).
2242  *
2243  * The value argument should be the address of a location to store the
2244  * returned array. So for int32 it should be a "const dbus_int32_t**"
2245  * The returned value is by reference and should not be freed.
2246  * 
2247  * This function should only be used if dbus_type_is_fixed() returns
2248  * #TRUE for the element type.
2249  *
2250  * If an array's elements are not fixed in size, you have to recurse
2251  * into the array with dbus_message_iter_recurse() and read the
2252  * elements one by one.
2253  * 
2254  * Because the array is not copied, this function runs in constant
2255  * time and is fast; it's much preferred over walking the entire array
2256  * with an iterator. (However, you can always use
2257  * dbus_message_iter_recurse(), even for fixed-length types;
2258  * dbus_message_iter_get_fixed_array() is just an optimization.)
2259  * 
2260  * @param iter the iterator
2261  * @param value location to store the block
2262  * @param n_elements number of elements in the block
2263  */
2264 void
2265 dbus_message_iter_get_fixed_array (DBusMessageIter  *iter,
2266                                    void             *value,
2267                                    int              *n_elements)
2268 {
2269   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2270 #ifndef DBUS_DISABLE_CHECKS
2271   int subtype = _dbus_type_reader_get_current_type(&real->u.reader);
2272
2273   _dbus_return_if_fail (_dbus_message_iter_check (real));
2274   _dbus_return_if_fail (value != NULL);
2275   _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) ||
2276                         (dbus_type_is_fixed (subtype) && subtype != DBUS_TYPE_UNIX_FD));
2277 #endif
2278
2279   _dbus_type_reader_read_fixed_multi (&real->u.reader,
2280                                       value, n_elements);
2281 }
2282
2283 /**
2284  * Initializes a #DBusMessageIter for appending arguments to the end
2285  * of a message.
2286  *
2287  * @todo If appending any of the arguments fails due to lack of
2288  * memory, the message is hosed and you have to start over building
2289  * the whole message.
2290  *
2291  * @param message the message
2292  * @param iter pointer to an iterator to initialize
2293  */
2294 void
2295 dbus_message_iter_init_append (DBusMessage     *message,
2296                                DBusMessageIter *iter)
2297 {
2298   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2299
2300   _dbus_return_if_fail (message != NULL);
2301   _dbus_return_if_fail (iter != NULL);
2302
2303   _dbus_message_iter_init_common (message, real,
2304                                   DBUS_MESSAGE_ITER_TYPE_WRITER);
2305
2306   /* We create the signature string and point iterators at it "on demand"
2307    * when a value is actually appended. That means that init() never fails
2308    * due to OOM.
2309    */
2310   _dbus_type_writer_init_types_delayed (&real->u.writer,
2311                                         _dbus_header_get_byte_order (&message->header),
2312                                         &message->body,
2313                                         _dbus_string_get_length (&message->body));
2314 }
2315
2316 /**
2317  * Creates a temporary signature string containing the current
2318  * signature, stores it in the iterator, and points the iterator to
2319  * the end of it. Used any time we write to the message.
2320  *
2321  * @param real an iterator without a type_str
2322  * @returns #FALSE if no memory
2323  */
2324 static dbus_bool_t
2325 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
2326 {
2327   DBusString *str;
2328   const DBusString *current_sig;
2329   int current_sig_pos;
2330
2331   _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2332
2333   if (real->u.writer.type_str != NULL)
2334     {
2335       _dbus_assert (real->sig_refcount > 0);
2336       real->sig_refcount += 1;
2337       return TRUE;
2338     }
2339
2340   str = dbus_new (DBusString, 1);
2341   if (str == NULL)
2342     return FALSE;
2343
2344   if (!_dbus_header_get_field_raw (&real->message->header,
2345                                    DBUS_HEADER_FIELD_SIGNATURE,
2346                                    &current_sig, &current_sig_pos))
2347     current_sig = NULL;
2348
2349   if (current_sig)
2350     {
2351       int current_len;
2352
2353       current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
2354       current_sig_pos += 1; /* move on to sig data */
2355
2356       if (!_dbus_string_init_preallocated (str, current_len + 4))
2357         {
2358           dbus_free (str);
2359           return FALSE;
2360         }
2361
2362       if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
2363                                   str, 0))
2364         {
2365           _dbus_string_free (str);
2366           dbus_free (str);
2367           return FALSE;
2368         }
2369     }
2370   else
2371     {
2372       if (!_dbus_string_init_preallocated (str, 4))
2373         {
2374           dbus_free (str);
2375           return FALSE;
2376         }
2377     }
2378
2379   real->sig_refcount = 1;
2380
2381   _dbus_type_writer_add_types (&real->u.writer,
2382                                str, _dbus_string_get_length (str));
2383   return TRUE;
2384 }
2385
2386 /**
2387  * Sets the new signature as the message signature, frees the
2388  * signature string, and marks the iterator as not having a type_str
2389  * anymore. Frees the signature even if it fails, so you can't
2390  * really recover from failure. Kinda busted.
2391  *
2392  * @param real an iterator without a type_str
2393  * @returns #FALSE if no memory
2394  */
2395 static dbus_bool_t
2396 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
2397 {
2398   DBusString *str;
2399   const char *v_STRING;
2400   dbus_bool_t retval;
2401
2402   _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2403   _dbus_assert (real->u.writer.type_str != NULL);
2404   _dbus_assert (real->sig_refcount > 0);
2405
2406   real->sig_refcount -= 1;
2407
2408   if (real->sig_refcount > 0)
2409     return TRUE;
2410   _dbus_assert (real->sig_refcount == 0);
2411
2412   retval = TRUE;
2413
2414   str = real->u.writer.type_str;
2415
2416   v_STRING = _dbus_string_get_const_data (str);
2417   if (!_dbus_header_set_field_basic (&real->message->header,
2418                                      DBUS_HEADER_FIELD_SIGNATURE,
2419                                      DBUS_TYPE_SIGNATURE,
2420                                      &v_STRING))
2421     retval = FALSE;
2422
2423   _dbus_type_writer_remove_types (&real->u.writer);
2424   _dbus_string_free (str);
2425   dbus_free (str);
2426
2427   return retval;
2428 }
2429
2430 /**
2431  * Frees the signature string and marks the iterator as not having a
2432  * type_str anymore.  Since the new signature is not set, the message
2433  * will generally be hosed after this is called.
2434  *
2435  * @param real an iterator without a type_str
2436  */
2437 static void
2438 _dbus_message_iter_abandon_signature (DBusMessageRealIter *real)
2439 {
2440   DBusString *str;
2441
2442   _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2443   _dbus_assert (real->u.writer.type_str != NULL);
2444   _dbus_assert (real->sig_refcount > 0);
2445
2446   real->sig_refcount -= 1;
2447
2448   if (real->sig_refcount > 0)
2449     return;
2450   _dbus_assert (real->sig_refcount == 0);
2451
2452   str = real->u.writer.type_str;
2453
2454   _dbus_type_writer_remove_types (&real->u.writer);
2455   _dbus_string_free (str);
2456   dbus_free (str);
2457 }
2458
2459 #ifndef DBUS_DISABLE_CHECKS
2460 static dbus_bool_t
2461 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
2462 {
2463   if (!_dbus_message_iter_check (iter))
2464     return FALSE;
2465
2466   if (iter->message->locked)
2467     {
2468       _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)\n");
2469       return FALSE;
2470     }
2471
2472   return TRUE;
2473 }
2474 #endif /* DBUS_DISABLE_CHECKS */
2475
2476 #ifdef HAVE_UNIX_FD_PASSING
2477 static int *
2478 expand_fd_array(DBusMessage *m,
2479                 unsigned     n)
2480 {
2481   _dbus_assert(m);
2482
2483   /* This makes space for adding n new fds to the array and returns a
2484      pointer to the place were the first fd should be put. */
2485
2486   if (m->n_unix_fds + n > m->n_unix_fds_allocated)
2487     {
2488       unsigned k;
2489       int *p;
2490
2491       /* Make twice as much space as necessary */
2492       k = (m->n_unix_fds + n) * 2;
2493
2494       /* Allocate at least four */
2495       if (k < 4)
2496         k = 4;
2497
2498       p = dbus_realloc(m->unix_fds, k * sizeof(int));
2499       if (p == NULL)
2500         return NULL;
2501
2502       m->unix_fds = p;
2503       m->n_unix_fds_allocated = k;
2504     }
2505
2506   return m->unix_fds + m->n_unix_fds;
2507 }
2508 #endif
2509
2510 /**
2511  * Appends a basic-typed value to the message. The basic types are the
2512  * non-container types such as integer and string.
2513  *
2514  * The "value" argument should be the address of a basic-typed value.
2515  * So for string, const char**. For integer, dbus_int32_t*.
2516  *
2517  * For Unix file descriptors this function will internally duplicate
2518  * the descriptor you passed in. Hence you may close the descriptor
2519  * immediately after this call.
2520  *
2521  * @todo If this fails due to lack of memory, the message is hosed and
2522  * you have to start over building the whole message.
2523  *
2524  * @param iter the append iterator
2525  * @param type the type of the value
2526  * @param value the address of the value
2527  * @returns #FALSE if not enough memory
2528  */
2529 dbus_bool_t
2530 dbus_message_iter_append_basic (DBusMessageIter *iter,
2531                                 int              type,
2532                                 const void      *value)
2533 {
2534   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2535   dbus_bool_t ret;
2536
2537   _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2538   _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2539   _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
2540   _dbus_return_val_if_fail (value != NULL, FALSE);
2541
2542 #ifndef DBUS_DISABLE_CHECKS
2543   switch (type)
2544     {
2545       const char * const *string_p;
2546       const dbus_bool_t *bool_p;
2547
2548       case DBUS_TYPE_STRING:
2549         string_p = value;
2550         _dbus_return_val_if_fail (_dbus_check_is_valid_utf8 (*string_p), FALSE);
2551         break;
2552
2553       case DBUS_TYPE_OBJECT_PATH:
2554         string_p = value;
2555         _dbus_return_val_if_fail (_dbus_check_is_valid_path (*string_p), FALSE);
2556         break;
2557
2558       case DBUS_TYPE_SIGNATURE:
2559         string_p = value;
2560         _dbus_return_val_if_fail (_dbus_check_is_valid_signature (*string_p), FALSE);
2561         break;
2562
2563       case DBUS_TYPE_BOOLEAN:
2564         bool_p = value;
2565         _dbus_return_val_if_fail (*bool_p == 0 || *bool_p == 1, FALSE);
2566         break;
2567
2568       default:
2569           {
2570             /* nothing to check, all possible values are allowed */
2571           }
2572     }
2573 #endif
2574
2575   if (!_dbus_message_iter_open_signature (real))
2576     return FALSE;
2577
2578   if (type == DBUS_TYPE_UNIX_FD)
2579     {
2580 #ifdef HAVE_UNIX_FD_PASSING
2581       int *fds;
2582       dbus_uint32_t u;
2583
2584       /* First step, include the fd in the fd list of this message */
2585       if (!(fds = expand_fd_array(real->message, 1)))
2586         return FALSE;
2587
2588       *fds = _dbus_dup(*(int*) value, NULL);
2589       if (*fds < 0)
2590         return FALSE;
2591
2592       u = real->message->n_unix_fds;
2593
2594       /* Second step, write the index to the fd */
2595       if (!(ret = _dbus_type_writer_write_basic (&real->u.writer, DBUS_TYPE_UNIX_FD, &u))) {
2596         _dbus_close(*fds, NULL);
2597         return FALSE;
2598       }
2599
2600       real->message->n_unix_fds += 1;
2601       u += 1;
2602
2603       /* Final step, update the header accordingly */
2604       ret = _dbus_header_set_field_basic (&real->message->header,
2605                                           DBUS_HEADER_FIELD_UNIX_FDS,
2606                                           DBUS_TYPE_UINT32,
2607                                           &u);
2608
2609       /* If any of these operations fail the message is
2610          hosed. However, no memory or fds should be leaked since what
2611          has been added to message has been added to the message, and
2612          can hence be accounted for when the message is being
2613          freed. */
2614 #else
2615       ret = FALSE;
2616 #endif
2617     }
2618   else
2619     {
2620       ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
2621     }
2622
2623   if (!_dbus_message_iter_close_signature (real))
2624     ret = FALSE;
2625
2626   return ret;
2627 }
2628
2629 /**
2630  * Appends a block of fixed-length values to an array. The
2631  * fixed-length types are all basic types that are not string-like. So
2632  * int32, double, bool, etc. (Unix file descriptors however are not
2633  * supported.) You must call dbus_message_iter_open_container() to
2634  * open an array of values before calling this function. You may call
2635  * this function multiple times (and intermixed with calls to
2636  * dbus_message_iter_append_basic()) for the same array.
2637  *
2638  * The "value" argument should be the address of the array.  So for
2639  * integer, "dbus_int32_t**" is expected for example.
2640  *
2641  * @warning in C, given "int array[]", "&array == array" (the
2642  * comp.lang.c FAQ says otherwise, but gcc and the FAQ don't agree).
2643  * So if you're using an array instead of a pointer you have to create
2644  * a pointer variable, assign the array to it, then take the address
2645  * of the pointer variable.
2646  * @code
2647  * const dbus_int32_t array[] = { 1, 2, 3 };
2648  * const dbus_int32_t *v_ARRAY = array;
2649  * if (!dbus_message_iter_append_fixed_array (&iter, DBUS_TYPE_INT32, &v_ARRAY, 3))
2650  *   fprintf (stderr, "No memory!\n");
2651  * @endcode
2652  * For strings it works to write const char *array = "Hello" and then
2653  * use &array though.
2654  *
2655  * @todo If this fails due to lack of memory, the message is hosed and
2656  * you have to start over building the whole message.
2657  *
2658  * @param iter the append iterator
2659  * @param element_type the type of the array elements
2660  * @param value the address of the array
2661  * @param n_elements the number of elements to append
2662  * @returns #FALSE if not enough memory
2663  */
2664 dbus_bool_t
2665 dbus_message_iter_append_fixed_array (DBusMessageIter *iter,
2666                                       int              element_type,
2667                                       const void      *value,
2668                                       int              n_elements)
2669 {
2670   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2671   dbus_bool_t ret;
2672
2673   _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2674   _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2675   _dbus_return_val_if_fail (dbus_type_is_fixed (element_type) && element_type != DBUS_TYPE_UNIX_FD, FALSE);
2676   _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
2677   _dbus_return_val_if_fail (value != NULL, FALSE);
2678   _dbus_return_val_if_fail (n_elements >= 0, FALSE);
2679   _dbus_return_val_if_fail (n_elements <=
2680                             DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type),
2681                             FALSE);
2682
2683 #ifndef DBUS_DISABLE_CHECKS
2684   if (element_type == DBUS_TYPE_BOOLEAN)
2685     {
2686       const dbus_bool_t * const *bools = value;
2687       int i;
2688
2689       for (i = 0; i < n_elements; i++)
2690         {
2691           _dbus_return_val_if_fail ((*bools)[i] == 0 || (*bools)[i] == 1, FALSE);
2692         }
2693     }
2694 #endif
2695
2696   ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
2697
2698   return ret;
2699 }
2700
2701 /**
2702  * Appends a container-typed value to the message; you are required to
2703  * append the contents of the container using the returned
2704  * sub-iterator, and then call
2705  * dbus_message_iter_close_container(). Container types are for
2706  * example struct, variant, and array. For variants, the
2707  * contained_signature should be the type of the single value inside
2708  * the variant. For structs and dict entries, contained_signature
2709  * should be #NULL; it will be set to whatever types you write into
2710  * the struct.  For arrays, contained_signature should be the type of
2711  * the array elements.
2712  *
2713  * @todo If this fails due to lack of memory, the message is hosed and
2714  * you have to start over building the whole message.
2715  *
2716  * @param iter the append iterator
2717  * @param type the type of the value
2718  * @param contained_signature the type of container contents
2719  * @param sub sub-iterator to initialize
2720  * @returns #FALSE if not enough memory
2721  */
2722 dbus_bool_t
2723 dbus_message_iter_open_container (DBusMessageIter *iter,
2724                                   int              type,
2725                                   const char      *contained_signature,
2726                                   DBusMessageIter *sub)
2727 {
2728   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2729   DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2730   DBusString contained_str;
2731
2732   _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2733   _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2734   _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
2735   _dbus_return_val_if_fail (sub != NULL, FALSE);
2736   _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
2737                              contained_signature == NULL) ||
2738                             (type == DBUS_TYPE_DICT_ENTRY &&
2739                              contained_signature == NULL) ||
2740                             (type == DBUS_TYPE_VARIANT &&
2741                              contained_signature != NULL) ||
2742                             (type == DBUS_TYPE_ARRAY &&
2743                              contained_signature != NULL), FALSE);
2744   
2745   /* this would fail if the contained_signature is a dict entry, since
2746    * dict entries are invalid signatures standalone (they must be in
2747    * an array)
2748    */
2749   _dbus_return_val_if_fail ((type == DBUS_TYPE_ARRAY && contained_signature && *contained_signature == DBUS_DICT_ENTRY_BEGIN_CHAR) ||
2750                             (contained_signature == NULL ||
2751                              _dbus_check_is_valid_signature (contained_signature)),
2752                             FALSE);
2753
2754   if (!_dbus_message_iter_open_signature (real))
2755     return FALSE;
2756
2757   *real_sub = *real;
2758
2759   if (contained_signature != NULL)
2760     {
2761       _dbus_string_init_const (&contained_str, contained_signature);
2762
2763       return _dbus_type_writer_recurse (&real->u.writer,
2764                                         type,
2765                                         &contained_str, 0,
2766                                         &real_sub->u.writer);
2767     }
2768   else
2769     {
2770       return _dbus_type_writer_recurse (&real->u.writer,
2771                                         type,
2772                                         NULL, 0,
2773                                         &real_sub->u.writer);
2774     } 
2775 }
2776
2777
2778 /**
2779  * Closes a container-typed value appended to the message; may write
2780  * out more information to the message known only after the entire
2781  * container is written, and may free resources created by
2782  * dbus_message_iter_open_container().
2783  *
2784  * @todo If this fails due to lack of memory, the message is hosed and
2785  * you have to start over building the whole message.
2786  *
2787  * @param iter the append iterator
2788  * @param sub sub-iterator to close
2789  * @returns #FALSE if not enough memory
2790  */
2791 dbus_bool_t
2792 dbus_message_iter_close_container (DBusMessageIter *iter,
2793                                    DBusMessageIter *sub)
2794 {
2795   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2796   DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2797   dbus_bool_t ret;
2798
2799   _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2800   _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2801   _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
2802   _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2803
2804   ret = _dbus_type_writer_unrecurse (&real->u.writer,
2805                                      &real_sub->u.writer);
2806
2807   if (!_dbus_message_iter_close_signature (real))
2808     ret = FALSE;
2809
2810   return ret;
2811 }
2812
2813 /**
2814  * Abandons creation of a contained-typed value and frees resources created
2815  * by dbus_message_iter_open_container().  Once this returns, the message
2816  * is hosed and you have to start over building the whole message.
2817  *
2818  * This should only be used to abandon creation of a message when you have
2819  * open containers.
2820  *
2821  * @param iter the append iterator
2822  * @param sub sub-iterator to close
2823  */
2824 void
2825 dbus_message_iter_abandon_container (DBusMessageIter *iter,
2826                                      DBusMessageIter *sub)
2827 {
2828   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2829 #ifndef DBUS_DISABLE_CHECKS
2830   DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2831
2832   _dbus_return_if_fail (_dbus_message_iter_append_check (real));
2833   _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2834   _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
2835   _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2836 #endif
2837
2838   _dbus_message_iter_abandon_signature (real);
2839 }
2840
2841 /**
2842  * Sets a flag indicating that the message does not want a reply; if
2843  * this flag is set, the other end of the connection may (but is not
2844  * required to) optimize by not sending method return or error
2845  * replies. If this flag is set, there is no way to know whether the
2846  * message successfully arrived at the remote end. Normally you know a
2847  * message was received when you receive the reply to it.
2848  *
2849  * The flag is #FALSE by default, that is by default the other end is
2850  * required to reply.
2851  *
2852  * On the protocol level this toggles #DBUS_HEADER_FLAG_NO_REPLY_EXPECTED
2853  * 
2854  * @param message the message
2855  * @param no_reply #TRUE if no reply is desired
2856  */
2857 void
2858 dbus_message_set_no_reply (DBusMessage *message,
2859                            dbus_bool_t  no_reply)
2860 {
2861   _dbus_return_if_fail (message != NULL);
2862   _dbus_return_if_fail (!message->locked);
2863
2864   _dbus_header_toggle_flag (&message->header,
2865                             DBUS_HEADER_FLAG_NO_REPLY_EXPECTED,
2866                             no_reply);
2867 }
2868
2869 /**
2870  * Returns #TRUE if the message does not expect
2871  * a reply.
2872  *
2873  * @param message the message
2874  * @returns #TRUE if the message sender isn't waiting for a reply
2875  */
2876 dbus_bool_t
2877 dbus_message_get_no_reply (DBusMessage *message)
2878 {
2879   _dbus_return_val_if_fail (message != NULL, FALSE);
2880
2881   return _dbus_header_get_flag (&message->header,
2882                                 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED);
2883 }
2884
2885 /**
2886  * Sets a flag indicating that an owner for the destination name will
2887  * be automatically started before the message is delivered. When this
2888  * flag is set, the message is held until a name owner finishes
2889  * starting up, or fails to start up. In case of failure, the reply
2890  * will be an error.
2891  *
2892  * The flag is set to #TRUE by default, i.e. auto starting is the default.
2893  *
2894  * On the protocol level this toggles #DBUS_HEADER_FLAG_NO_AUTO_START
2895  * 
2896  * @param message the message
2897  * @param auto_start #TRUE if auto-starting is desired
2898  */
2899 void
2900 dbus_message_set_auto_start (DBusMessage *message,
2901                              dbus_bool_t  auto_start)
2902 {
2903   _dbus_return_if_fail (message != NULL);
2904   _dbus_return_if_fail (!message->locked);
2905
2906   _dbus_header_toggle_flag (&message->header,
2907                             DBUS_HEADER_FLAG_NO_AUTO_START,
2908                             !auto_start);
2909 }
2910
2911 /**
2912  * Returns #TRUE if the message will cause an owner for
2913  * destination name to be auto-started.
2914  *
2915  * @param message the message
2916  * @returns #TRUE if the message will use auto-start
2917  */
2918 dbus_bool_t
2919 dbus_message_get_auto_start (DBusMessage *message)
2920 {
2921   _dbus_return_val_if_fail (message != NULL, FALSE);
2922
2923   return !_dbus_header_get_flag (&message->header,
2924                                  DBUS_HEADER_FLAG_NO_AUTO_START);
2925 }
2926
2927
2928 /**
2929  * Sets the object path this message is being sent to (for
2930  * DBUS_MESSAGE_TYPE_METHOD_CALL) or the one a signal is being
2931  * emitted from (for DBUS_MESSAGE_TYPE_SIGNAL).
2932  *
2933  * The path must contain only valid characters as defined
2934  * in the D-Bus specification.
2935  *
2936  * @param message the message
2937  * @param object_path the path or #NULL to unset
2938  * @returns #FALSE if not enough memory
2939  */
2940 dbus_bool_t
2941 dbus_message_set_path (DBusMessage   *message,
2942                        const char    *object_path)
2943 {
2944   _dbus_return_val_if_fail (message != NULL, FALSE);
2945   _dbus_return_val_if_fail (!message->locked, FALSE);
2946   _dbus_return_val_if_fail (object_path == NULL ||
2947                             _dbus_check_is_valid_path (object_path),
2948                             FALSE);
2949
2950   return set_or_delete_string_field (message,
2951                                      DBUS_HEADER_FIELD_PATH,
2952                                      DBUS_TYPE_OBJECT_PATH,
2953                                      object_path);
2954 }
2955
2956 /**
2957  * Gets the object path this message is being sent to (for
2958  * DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitted from (for
2959  * DBUS_MESSAGE_TYPE_SIGNAL). Returns #NULL if none.
2960  *
2961  * See also dbus_message_get_path_decomposed().
2962  *
2963  * The returned string becomes invalid if the message is
2964  * modified, since it points into the wire-marshaled message data.
2965  * 
2966  * @param message the message
2967  * @returns the path (should not be freed) or #NULL
2968  */
2969 const char*
2970 dbus_message_get_path (DBusMessage   *message)
2971 {
2972   const char *v;
2973
2974   _dbus_return_val_if_fail (message != NULL, NULL);
2975
2976   v = NULL; /* in case field doesn't exist */
2977   _dbus_header_get_field_basic (&message->header,
2978                                 DBUS_HEADER_FIELD_PATH,
2979                                 DBUS_TYPE_OBJECT_PATH,
2980                                 (void *) &v);
2981   return v;
2982 }
2983
2984 /**
2985  * Checks if the message has a particular object path.  The object
2986  * path is the destination object for a method call or the emitting
2987  * object for a signal.
2988  *
2989  * @param message the message
2990  * @param path the path name
2991  * @returns #TRUE if there is a path field in the header
2992  */
2993 dbus_bool_t
2994 dbus_message_has_path (DBusMessage   *message,
2995                        const char    *path)
2996 {
2997   const char *msg_path;
2998   msg_path = dbus_message_get_path (message);
2999   
3000   if (msg_path == NULL)
3001     {
3002       if (path == NULL)
3003         return TRUE;
3004       else
3005         return FALSE;
3006     }
3007
3008   if (path == NULL)
3009     return FALSE;
3010    
3011   if (strcmp (msg_path, path) == 0)
3012     return TRUE;
3013
3014   return FALSE;
3015 }
3016
3017 /**
3018  * Gets the object path this message is being sent to
3019  * (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitted
3020  * from (for DBUS_MESSAGE_TYPE_SIGNAL) in a decomposed
3021  * format (one array element per path component).
3022  * Free the returned array with dbus_free_string_array().
3023  *
3024  * An empty but non-NULL path array means the path "/".
3025  * So the path "/foo/bar" becomes { "foo", "bar", NULL }
3026  * and the path "/" becomes { NULL }.
3027  *
3028  * See also dbus_message_get_path().
3029  * 
3030  * @todo this could be optimized by using the len from the message
3031  * instead of calling strlen() again
3032  *
3033  * @param message the message
3034  * @param path place to store allocated array of path components; #NULL set here if no path field exists
3035  * @returns #FALSE if no memory to allocate the array
3036  */
3037 dbus_bool_t
3038 dbus_message_get_path_decomposed (DBusMessage   *message,
3039                                   char        ***path)
3040 {
3041   const char *v;
3042
3043   _dbus_return_val_if_fail (message != NULL, FALSE);
3044   _dbus_return_val_if_fail (path != NULL, FALSE);
3045
3046   *path = NULL;
3047
3048   v = dbus_message_get_path (message);
3049   if (v != NULL)
3050     {
3051       if (!_dbus_decompose_path (v, strlen (v),
3052                                  path, NULL))
3053         return FALSE;
3054     }
3055   return TRUE;
3056 }
3057
3058 /**
3059  * Sets the interface this message is being sent to
3060  * (for DBUS_MESSAGE_TYPE_METHOD_CALL) or
3061  * the interface a signal is being emitted from
3062  * (for DBUS_MESSAGE_TYPE_SIGNAL).
3063  *
3064  * The interface name must contain only valid characters as defined
3065  * in the D-Bus specification.
3066  * 
3067  * @param message the message
3068  * @param interface the interface or #NULL to unset
3069  * @returns #FALSE if not enough memory
3070  */
3071 dbus_bool_t
3072 dbus_message_set_interface (DBusMessage  *message,
3073                             const char   *interface)
3074 {
3075   _dbus_return_val_if_fail (message != NULL, FALSE);
3076   _dbus_return_val_if_fail (!message->locked, FALSE);
3077   _dbus_return_val_if_fail (interface == NULL ||
3078                             _dbus_check_is_valid_interface (interface),
3079                             FALSE);
3080
3081   return set_or_delete_string_field (message,
3082                                      DBUS_HEADER_FIELD_INTERFACE,
3083                                      DBUS_TYPE_STRING,
3084                                      interface);
3085 }
3086
3087 /**
3088  * Gets the interface this message is being sent to
3089  * (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitted
3090  * from (for DBUS_MESSAGE_TYPE_SIGNAL).
3091  * The interface name is fully-qualified (namespaced).
3092  * Returns #NULL if none.
3093  *
3094  * The returned string becomes invalid if the message is
3095  * modified, since it points into the wire-marshaled message data.
3096  *
3097  * @param message the message
3098  * @returns the message interface (should not be freed) or #NULL
3099  */
3100 const char*
3101 dbus_message_get_interface (DBusMessage *message)
3102 {
3103   const char *v;
3104
3105   _dbus_return_val_if_fail (message != NULL, NULL);
3106
3107   v = NULL; /* in case field doesn't exist */
3108   _dbus_header_get_field_basic (&message->header,
3109                                 DBUS_HEADER_FIELD_INTERFACE,
3110                                 DBUS_TYPE_STRING,
3111                                 (void *) &v);
3112   return v;
3113 }
3114
3115 /**
3116  * Checks if the message has an interface
3117  *
3118  * @param message the message
3119  * @param interface the interface name
3120  * @returns #TRUE if the interface field in the header matches
3121  */
3122 dbus_bool_t
3123 dbus_message_has_interface (DBusMessage   *message,
3124                             const char    *interface)
3125 {
3126   const char *msg_interface;
3127   msg_interface = dbus_message_get_interface (message);
3128    
3129   if (msg_interface == NULL)
3130     {
3131       if (interface == NULL)
3132         return TRUE;
3133       else
3134         return FALSE;
3135     }
3136
3137   if (interface == NULL)
3138     return FALSE;
3139      
3140   if (strcmp (msg_interface, interface) == 0)
3141     return TRUE;
3142
3143   return FALSE;
3144
3145 }
3146
3147 /**
3148  * Sets the interface member being invoked
3149  * (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted
3150  * (DBUS_MESSAGE_TYPE_SIGNAL).
3151  *
3152  * The member name must contain only valid characters as defined
3153  * in the D-Bus specification.
3154  *
3155  * @param message the message
3156  * @param member the member or #NULL to unset
3157  * @returns #FALSE if not enough memory
3158  */
3159 dbus_bool_t
3160 dbus_message_set_member (DBusMessage  *message,
3161                          const char   *member)
3162 {
3163   _dbus_return_val_if_fail (message != NULL, FALSE);
3164   _dbus_return_val_if_fail (!message->locked, FALSE);
3165   _dbus_return_val_if_fail (member == NULL ||
3166                             _dbus_check_is_valid_member (member),
3167                             FALSE);
3168
3169   return set_or_delete_string_field (message,
3170                                      DBUS_HEADER_FIELD_MEMBER,
3171                                      DBUS_TYPE_STRING,
3172                                      member);
3173 }
3174
3175 /**
3176  * Gets the interface member being invoked
3177  * (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted
3178  * (DBUS_MESSAGE_TYPE_SIGNAL). Returns #NULL if none.
3179  *
3180  * The returned string becomes invalid if the message is
3181  * modified, since it points into the wire-marshaled message data.
3182  * 
3183  * @param message the message
3184  * @returns the member name (should not be freed) or #NULL
3185  */
3186 const char*
3187 dbus_message_get_member (DBusMessage *message)
3188 {
3189   const char *v;
3190
3191   _dbus_return_val_if_fail (message != NULL, NULL);
3192
3193   v = NULL; /* in case field doesn't exist */
3194   _dbus_header_get_field_basic (&message->header,
3195                                 DBUS_HEADER_FIELD_MEMBER,
3196                                 DBUS_TYPE_STRING,
3197                                 (void *) &v);
3198   return v;
3199 }
3200
3201 /**
3202  * Checks if the message has an interface member
3203  *
3204  * @param message the message
3205  * @param member the member name
3206  * @returns #TRUE if there is a member field in the header
3207  */
3208 dbus_bool_t
3209 dbus_message_has_member (DBusMessage   *message,
3210                          const char    *member)
3211 {
3212   const char *msg_member;
3213   msg_member = dbus_message_get_member (message);
3214  
3215   if (msg_member == NULL)
3216     {
3217       if (member == NULL)
3218         return TRUE;
3219       else
3220         return FALSE;
3221     }
3222
3223   if (member == NULL)
3224     return FALSE;
3225     
3226   if (strcmp (msg_member, member) == 0)
3227     return TRUE;
3228
3229   return FALSE;
3230
3231 }
3232
3233 /**
3234  * Sets the name of the error (DBUS_MESSAGE_TYPE_ERROR).
3235  * The name is fully-qualified (namespaced).
3236  *
3237  * The error name must contain only valid characters as defined
3238  * in the D-Bus specification.
3239  *
3240  * @param message the message
3241  * @param error_name the name or #NULL to unset
3242  * @returns #FALSE if not enough memory
3243  */
3244 dbus_bool_t
3245 dbus_message_set_error_name (DBusMessage  *message,
3246                              const char   *error_name)
3247 {
3248   _dbus_return_val_if_fail (message != NULL, FALSE);
3249   _dbus_return_val_if_fail (!message->locked, FALSE);
3250   _dbus_return_val_if_fail (error_name == NULL ||
3251                             _dbus_check_is_valid_error_name (error_name),
3252                             FALSE);
3253
3254   return set_or_delete_string_field (message,
3255                                      DBUS_HEADER_FIELD_ERROR_NAME,
3256                                      DBUS_TYPE_STRING,
3257                                      error_name);
3258 }
3259
3260 /**
3261  * Gets the error name (DBUS_MESSAGE_TYPE_ERROR only)
3262  * or #NULL if none.
3263  *
3264  * The returned string becomes invalid if the message is
3265  * modified, since it points into the wire-marshaled message data.
3266  * 
3267  * @param message the message
3268  * @returns the error name (should not be freed) or #NULL
3269  */
3270 const char*
3271 dbus_message_get_error_name (DBusMessage *message)
3272 {
3273   const char *v;
3274
3275   _dbus_return_val_if_fail (message != NULL, NULL);
3276
3277   v = NULL; /* in case field doesn't exist */
3278   _dbus_header_get_field_basic (&message->header,
3279                                 DBUS_HEADER_FIELD_ERROR_NAME,
3280                                 DBUS_TYPE_STRING,
3281                                 (void *) &v);
3282   return v;
3283 }
3284
3285 /**
3286  * Sets the message's destination. The destination is the name of
3287  * another connection on the bus and may be either the unique name
3288  * assigned by the bus to each connection, or a well-known name
3289  * specified in advance.
3290  *
3291  * The destination name must contain only valid characters as defined
3292  * in the D-Bus specification.
3293  * 
3294  * @param message the message
3295  * @param destination the destination name or #NULL to unset
3296  * @returns #FALSE if not enough memory
3297  */
3298 dbus_bool_t
3299 dbus_message_set_destination (DBusMessage  *message,
3300                               const char   *destination)
3301 {
3302   _dbus_return_val_if_fail (message != NULL, FALSE);
3303   _dbus_return_val_if_fail (!message->locked, FALSE);
3304   _dbus_return_val_if_fail (destination == NULL ||
3305                             _dbus_check_is_valid_bus_name (destination),
3306                             FALSE);
3307
3308   return set_or_delete_string_field (message,
3309                                      DBUS_HEADER_FIELD_DESTINATION,
3310                                      DBUS_TYPE_STRING,
3311                                      destination);
3312 }
3313
3314 /**
3315  * Gets the destination of a message or #NULL if there is none set.
3316  *
3317  * The returned string becomes invalid if the message is
3318  * modified, since it points into the wire-marshaled message data.
3319  *
3320  * @param message the message
3321  * @returns the message destination (should not be freed) or #NULL
3322  */
3323 const char*
3324 dbus_message_get_destination (DBusMessage *message)
3325 {
3326   const char *v;
3327
3328   _dbus_return_val_if_fail (message != NULL, NULL);
3329
3330   v = NULL; /* in case field doesn't exist */
3331   _dbus_header_get_field_basic (&message->header,
3332                                 DBUS_HEADER_FIELD_DESTINATION,
3333                                 DBUS_TYPE_STRING,
3334                                 (void *) &v);
3335   return v;
3336 }
3337
3338 /**
3339  * Sets the message sender.
3340  *
3341  * The sender must be a valid bus name as defined in the D-Bus
3342  * specification.
3343  *
3344  * Usually you don't want to call this. The message bus daemon will
3345  * call it to set the origin of each message. If you aren't implementing
3346  * a message bus daemon you shouldn't need to set the sender.
3347  *
3348  * @param message the message
3349  * @param sender the sender or #NULL to unset
3350  * @returns #FALSE if not enough memory
3351  */
3352 dbus_bool_t
3353 dbus_message_set_sender (DBusMessage  *message,
3354                          const char   *sender)
3355 {
3356   _dbus_return_val_if_fail (message != NULL, FALSE);
3357   _dbus_return_val_if_fail (!message->locked, FALSE);
3358   _dbus_return_val_if_fail (sender == NULL ||
3359                             _dbus_check_is_valid_bus_name (sender),
3360                             FALSE);
3361
3362   return set_or_delete_string_field (message,
3363                                      DBUS_HEADER_FIELD_SENDER,
3364                                      DBUS_TYPE_STRING,
3365                                      sender);
3366 }
3367
3368 /**
3369  * Gets the unique name of the connection which originated this
3370  * message, or #NULL if unknown or inapplicable. The sender is filled
3371  * in by the message bus.
3372  *
3373  * Note, the returned sender is always the unique bus name.
3374  * Connections may own multiple other bus names, but those
3375  * are not found in the sender field.
3376  * 
3377  * The returned string becomes invalid if the message is
3378  * modified, since it points into the wire-marshaled message data.
3379  *
3380  * @param message the message
3381  * @returns the unique name of the sender or #NULL
3382  */
3383 const char*
3384 dbus_message_get_sender (DBusMessage *message)
3385 {
3386   const char *v;
3387
3388   _dbus_return_val_if_fail (message != NULL, NULL);
3389
3390   v = NULL; /* in case field doesn't exist */
3391   _dbus_header_get_field_basic (&message->header,
3392                                 DBUS_HEADER_FIELD_SENDER,
3393                                 DBUS_TYPE_STRING,
3394                                 (void *) &v);
3395   return v;
3396 }
3397
3398 /**
3399  * Gets the type signature of the message, i.e. the arguments in the
3400  * message payload. The signature includes only "in" arguments for
3401  * #DBUS_MESSAGE_TYPE_METHOD_CALL and only "out" arguments for
3402  * #DBUS_MESSAGE_TYPE_METHOD_RETURN, so is slightly different from
3403  * what you might expect (that is, it does not include the signature of the
3404  * entire C++-style method).
3405  *
3406  * The signature is a string made up of type codes such as
3407  * #DBUS_TYPE_INT32. The string is terminated with nul (nul is also
3408  * the value of #DBUS_TYPE_INVALID).
3409  *
3410  * The returned string becomes invalid if the message is
3411  * modified, since it points into the wire-marshaled message data.
3412  *
3413  * @param message the message
3414  * @returns the type signature
3415  */
3416 const char*
3417 dbus_message_get_signature (DBusMessage *message)
3418 {
3419   const DBusString *type_str;
3420   int type_pos;
3421
3422   _dbus_return_val_if_fail (message != NULL, NULL);
3423
3424   get_const_signature (&message->header, &type_str, &type_pos);
3425
3426   return _dbus_string_get_const_data_len (type_str, type_pos, 0);
3427 }
3428
3429 static dbus_bool_t
3430 _dbus_message_has_type_interface_member (DBusMessage *message,
3431                                          int          type,
3432                                          const char  *interface,
3433                                          const char  *member)
3434 {
3435   const char *n;
3436
3437   _dbus_assert (message != NULL);
3438   _dbus_assert (interface != NULL);
3439   _dbus_assert (member != NULL);
3440
3441   if (dbus_message_get_type (message) != type)
3442     return FALSE;
3443
3444   /* Optimize by checking the short member name first
3445    * instead of the longer interface name
3446    */
3447
3448   n = dbus_message_get_member (message);
3449
3450   if (n && strcmp (n, member) == 0)
3451     {
3452       n = dbus_message_get_interface (message);
3453
3454       if (n == NULL || strcmp (n, interface) == 0)
3455         return TRUE;
3456     }
3457
3458   return FALSE;
3459 }
3460
3461 /**
3462  * Checks whether the message is a method call with the given
3463  * interface and member fields.  If the message is not
3464  * #DBUS_MESSAGE_TYPE_METHOD_CALL, or has a different interface or
3465  * member field, returns #FALSE. If the interface field is missing,
3466  * then it will be assumed equal to the provided interface.  The D-Bus
3467  * protocol allows method callers to leave out the interface name.
3468  *
3469  * @param message the message
3470  * @param interface the name to check (must not be #NULL)
3471  * @param method the name to check (must not be #NULL)
3472  *
3473  * @returns #TRUE if the message is the specified method call
3474  */
3475 dbus_bool_t
3476 dbus_message_is_method_call (DBusMessage *message,
3477                              const char  *interface,
3478                              const char  *method)
3479 {
3480   _dbus_return_val_if_fail (message != NULL, FALSE);
3481   _dbus_return_val_if_fail (interface != NULL, FALSE);
3482   _dbus_return_val_if_fail (method != NULL, FALSE);
3483   /* don't check that interface/method are valid since it would be
3484    * expensive, and not catch many common errors
3485    */
3486
3487   return _dbus_message_has_type_interface_member (message,
3488                                                   DBUS_MESSAGE_TYPE_METHOD_CALL,
3489                                                   interface, method);
3490 }
3491
3492 /**
3493  * Checks whether the message is a signal with the given interface and
3494  * member fields.  If the message is not #DBUS_MESSAGE_TYPE_SIGNAL, or
3495  * has a different interface or member field, returns #FALSE.
3496  *
3497  * @param message the message
3498  * @param interface the name to check (must not be #NULL)
3499  * @param signal_name the name to check (must not be #NULL)
3500  *
3501  * @returns #TRUE if the message is the specified signal
3502  */
3503 dbus_bool_t
3504 dbus_message_is_signal (DBusMessage *message,
3505                         const char  *interface,
3506                         const char  *signal_name)
3507 {
3508   _dbus_return_val_if_fail (message != NULL, FALSE);
3509   _dbus_return_val_if_fail (interface != NULL, FALSE);
3510   _dbus_return_val_if_fail (signal_name != NULL, FALSE);
3511   /* don't check that interface/name are valid since it would be
3512    * expensive, and not catch many common errors
3513    */
3514
3515   return _dbus_message_has_type_interface_member (message,
3516                                                   DBUS_MESSAGE_TYPE_SIGNAL,
3517                                                   interface, signal_name);
3518 }
3519
3520 /**
3521  * Checks whether the message is an error reply with the given error
3522  * name.  If the message is not #DBUS_MESSAGE_TYPE_ERROR, or has a
3523  * different name, returns #FALSE.
3524  *
3525  * @param message the message
3526  * @param error_name the name to check (must not be #NULL)
3527  *
3528  * @returns #TRUE if the message is the specified error
3529  */
3530 dbus_bool_t
3531 dbus_message_is_error (DBusMessage *message,
3532                        const char  *error_name)
3533 {
3534   const char *n;
3535
3536   _dbus_return_val_if_fail (message != NULL, FALSE);
3537   _dbus_return_val_if_fail (error_name != NULL, FALSE);
3538   /* don't check that error_name is valid since it would be expensive,
3539    * and not catch many common errors
3540    */
3541
3542   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
3543     return FALSE;
3544
3545   n = dbus_message_get_error_name (message);
3546
3547   if (n && strcmp (n, error_name) == 0)
3548     return TRUE;
3549   else
3550     return FALSE;
3551 }
3552
3553 /**
3554  * Checks whether the message was sent to the given name.  If the
3555  * message has no destination specified or has a different
3556  * destination, returns #FALSE.
3557  *
3558  * @param message the message
3559  * @param name the name to check (must not be #NULL)
3560  *
3561  * @returns #TRUE if the message has the given destination name
3562  */
3563 dbus_bool_t
3564 dbus_message_has_destination (DBusMessage  *message,
3565                               const char   *name)
3566 {
3567   const char *s;
3568
3569   _dbus_return_val_if_fail (message != NULL, FALSE);
3570   _dbus_return_val_if_fail (name != NULL, FALSE);
3571   /* don't check that name is valid since it would be expensive, and
3572    * not catch many common errors
3573    */
3574
3575   s = dbus_message_get_destination (message);
3576
3577   if (s && strcmp (s, name) == 0)
3578     return TRUE;
3579   else
3580     return FALSE;
3581 }
3582
3583 /**
3584  * Checks whether the message has the given unique name as its sender.
3585  * If the message has no sender specified or has a different sender,
3586  * returns #FALSE. Note that a peer application will always have the
3587  * unique name of the connection as the sender. So you can't use this
3588  * function to see whether a sender owned a well-known name.
3589  *
3590  * Messages from the bus itself will have #DBUS_SERVICE_DBUS
3591  * as the sender.
3592  *
3593  * @param message the message
3594  * @param name the name to check (must not be #NULL)
3595  *
3596  * @returns #TRUE if the message has the given sender
3597  */
3598 dbus_bool_t
3599 dbus_message_has_sender (DBusMessage  *message,
3600                          const char   *name)
3601 {
3602   const char *s;
3603
3604   _dbus_return_val_if_fail (message != NULL, FALSE);
3605   _dbus_return_val_if_fail (name != NULL, FALSE);
3606   /* don't check that name is valid since it would be expensive, and
3607    * not catch many common errors
3608    */
3609
3610   s = dbus_message_get_sender (message);
3611
3612   if (s && strcmp (s, name) == 0)
3613     return TRUE;
3614   else
3615     return FALSE;
3616 }
3617
3618 /**
3619  * Checks whether the message has the given signature; see
3620  * dbus_message_get_signature() for more details on what the signature
3621  * looks like.
3622  *
3623  * @param message the message
3624  * @param signature typecode array
3625  * @returns #TRUE if message has the given signature
3626 */
3627 dbus_bool_t
3628 dbus_message_has_signature (DBusMessage   *message,
3629                             const char    *signature)
3630 {
3631   const char *s;
3632
3633   _dbus_return_val_if_fail (message != NULL, FALSE);
3634   _dbus_return_val_if_fail (signature != NULL, FALSE);
3635   /* don't check that signature is valid since it would be expensive,
3636    * and not catch many common errors
3637    */
3638
3639   s = dbus_message_get_signature (message);
3640
3641   if (s && strcmp (s, signature) == 0)
3642     return TRUE;
3643   else
3644     return FALSE;
3645 }
3646
3647 /**
3648  * Sets a #DBusError based on the contents of the given
3649  * message. The error is only set if the message
3650  * is an error message, as in #DBUS_MESSAGE_TYPE_ERROR.
3651  * The name of the error is set to the name of the message,
3652  * and the error message is set to the first argument
3653  * if the argument exists and is a string.
3654  *
3655  * The return value indicates whether the error was set (the error is
3656  * set if and only if the message is an error message).  So you can
3657  * check for an error reply and convert it to DBusError in one go:
3658  * @code
3659  *  if (dbus_set_error_from_message (error, reply))
3660  *    return error;
3661  *  else
3662  *    process reply;
3663  * @endcode
3664  *
3665  * @param error the error to set
3666  * @param message the message to set it from
3667  * @returns #TRUE if the message had type #DBUS_MESSAGE_TYPE_ERROR
3668  */
3669 dbus_bool_t
3670 dbus_set_error_from_message (DBusError   *error,
3671                              DBusMessage *message)
3672 {
3673   const char *str;
3674
3675   _dbus_return_val_if_fail (message != NULL, FALSE);
3676   _dbus_return_val_if_error_is_set (error, FALSE);
3677
3678   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
3679     return FALSE;
3680
3681   str = NULL;
3682   dbus_message_get_args (message, NULL,
3683                          DBUS_TYPE_STRING, &str,
3684                          DBUS_TYPE_INVALID);
3685
3686   dbus_set_error (error, dbus_message_get_error_name (message),
3687                   str ? "%s" : NULL, str);
3688
3689   return TRUE;
3690 }
3691
3692 /**
3693  * Checks whether a message contains unix fds
3694  *
3695  * @param message the message
3696  * @returns #TRUE if the message contains unix fds
3697  */
3698 dbus_bool_t
3699 dbus_message_contains_unix_fds(DBusMessage *message)
3700 {
3701 #ifdef HAVE_UNIX_FD_PASSING
3702   _dbus_assert(message);
3703
3704   return message->n_unix_fds > 0;
3705 #else
3706   return FALSE;
3707 #endif
3708 }
3709
3710 /** @} */
3711
3712 /**
3713  * @addtogroup DBusMessageInternals
3714  *
3715  * @{
3716  */
3717
3718 /**
3719  * The initial buffer size of the message loader.
3720  *
3721  * @todo this should be based on min header size plus some average
3722  * body size, or something. Or rather, the min header size only, if we
3723  * want to try to read only the header, store that in a DBusMessage,
3724  * then read only the body and store that, etc., depends on
3725  * how we optimize _dbus_message_loader_get_buffer() and what
3726  * the exact message format is.
3727  */
3728 #define INITIAL_LOADER_DATA_LEN 32
3729
3730 /**
3731  * Creates a new message loader. Returns #NULL if memory can't
3732  * be allocated.
3733  *
3734  * @returns new loader, or #NULL.
3735  */
3736 DBusMessageLoader*
3737 _dbus_message_loader_new (void)
3738 {
3739   DBusMessageLoader *loader;
3740
3741   loader = dbus_new0 (DBusMessageLoader, 1);
3742   if (loader == NULL)
3743     return NULL;
3744   
3745   loader->refcount = 1;
3746
3747   loader->corrupted = FALSE;
3748   loader->corruption_reason = DBUS_VALID;
3749
3750   /* this can be configured by the app, but defaults to the protocol max */
3751   loader->max_message_size = DBUS_MAXIMUM_MESSAGE_LENGTH;
3752
3753   /* We set a very relatively conservative default here since due to how
3754   SCM_RIGHTS works we need to preallocate an fd array of the maximum
3755   number of unix fds we want to receive in advance. A
3756   try-and-reallocate loop is not possible. */
3757   loader->max_message_unix_fds = 1024;
3758
3759   if (!_dbus_string_init (&loader->data))
3760     {
3761       dbus_free (loader);
3762       return NULL;
3763     }
3764
3765   /* preallocate the buffer for speed, ignore failure */
3766   _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
3767   _dbus_string_set_length (&loader->data, 0);
3768
3769 #ifdef HAVE_UNIX_FD_PASSING
3770   loader->unix_fds = NULL;
3771   loader->n_unix_fds = loader->n_unix_fds_allocated = 0;
3772   loader->unix_fds_outstanding = FALSE;
3773 #endif
3774
3775   return loader;
3776 }
3777
3778 /**
3779  * Increments the reference count of the loader.
3780  *
3781  * @param loader the loader.
3782  * @returns the loader
3783  */
3784 DBusMessageLoader *
3785 _dbus_message_loader_ref (DBusMessageLoader *loader)
3786 {
3787   loader->refcount += 1;
3788
3789   return loader;
3790 }
3791
3792 /**
3793  * Decrements the reference count of the loader and finalizes the
3794  * loader when the count reaches zero.
3795  *
3796  * @param loader the loader.
3797  */
3798 void
3799 _dbus_message_loader_unref (DBusMessageLoader *loader)
3800 {
3801   loader->refcount -= 1;
3802   if (loader->refcount == 0)
3803     {
3804 #ifdef HAVE_UNIX_FD_PASSING
3805       close_unix_fds(loader->unix_fds, &loader->n_unix_fds);
3806       dbus_free(loader->unix_fds);
3807 #endif
3808       _dbus_list_foreach (&loader->messages,
3809                           (DBusForeachFunction) dbus_message_unref,
3810                           NULL);
3811       _dbus_list_clear (&loader->messages);
3812       _dbus_string_free (&loader->data);
3813       dbus_free (loader);
3814     }
3815 }
3816
3817 /**
3818  * Gets the buffer to use for reading data from the network.  Network
3819  * data is read directly into an allocated buffer, which is then used
3820  * in the DBusMessage, to avoid as many extra memcpy's as possible.
3821  * The buffer must always be returned immediately using
3822  * _dbus_message_loader_return_buffer(), even if no bytes are
3823  * successfully read.
3824  *
3825  * @todo this function can be a lot more clever. For example
3826  * it can probably always return a buffer size to read exactly
3827  * the body of the next message, thus avoiding any memory wastage
3828  * or reallocs.
3829  *
3830  * @todo we need to enforce a max length on strings in header fields.
3831  *
3832  * @param loader the message loader.
3833  * @param buffer the buffer
3834  */
3835 void
3836 _dbus_message_loader_get_buffer (DBusMessageLoader  *loader,
3837                                  DBusString        **buffer)
3838 {
3839   _dbus_assert (!loader->buffer_outstanding);
3840
3841   *buffer = &loader->data;
3842
3843   loader->buffer_outstanding = TRUE;
3844 }
3845
3846 /**
3847  * Returns a buffer obtained from _dbus_message_loader_get_buffer(),
3848  * indicating to the loader how many bytes of the buffer were filled
3849  * in. This function must always be called, even if no bytes were
3850  * successfully read.
3851  *
3852  * @param loader the loader.
3853  * @param buffer the buffer.
3854  * @param bytes_read number of bytes that were read into the buffer.
3855  */
3856 void
3857 _dbus_message_loader_return_buffer (DBusMessageLoader  *loader,
3858                                     DBusString         *buffer,
3859                                     int                 bytes_read)
3860 {
3861   _dbus_assert (loader->buffer_outstanding);
3862   _dbus_assert (buffer == &loader->data);
3863
3864   loader->buffer_outstanding = FALSE;
3865 }
3866
3867 /**
3868  * Gets the buffer to use for reading unix fds from the network.
3869  *
3870  * This works similar to _dbus_message_loader_get_buffer()
3871  *
3872  * @param loader the message loader.
3873  * @param fds the array to read fds into
3874  * @param max_n_fds how many fds to read at most
3875  * @return TRUE on success, FALSE on OOM
3876  */
3877 dbus_bool_t
3878 _dbus_message_loader_get_unix_fds(DBusMessageLoader  *loader,
3879                                   int               **fds,
3880                                   unsigned           *max_n_fds)
3881 {
3882 #ifdef HAVE_UNIX_FD_PASSING
3883   _dbus_assert (!loader->unix_fds_outstanding);
3884
3885   /* Allocate space where we can put the fds we read. We allocate
3886      space for max_message_unix_fds since this is an
3887      upper limit how many fds can be received within a single
3888      message. Since SCM_RIGHTS doesn't allow a reallocate+retry logic
3889      we are allocating the maximum possible array size right from the
3890      beginning. This sucks a bit, however unless SCM_RIGHTS is fixed
3891      there is no better way. */
3892
3893   if (loader->n_unix_fds_allocated < loader->max_message_unix_fds)
3894     {
3895       int *a = dbus_realloc(loader->unix_fds,
3896                             loader->max_message_unix_fds * sizeof(loader->unix_fds[0]));
3897
3898       if (!a)
3899         return FALSE;
3900
3901       loader->unix_fds = a;
3902       loader->n_unix_fds_allocated = loader->max_message_unix_fds;
3903     }
3904
3905   *fds = loader->unix_fds + loader->n_unix_fds;
3906   *max_n_fds = loader->n_unix_fds_allocated - loader->n_unix_fds;
3907
3908   loader->unix_fds_outstanding = TRUE;
3909   return TRUE;
3910 #else
3911   _dbus_assert_not_reached("Platform doesn't support unix fd passing");
3912   return FALSE;
3913 #endif
3914 }
3915
3916 /**
3917  * Returns a buffer obtained from _dbus_message_loader_get_unix_fds().
3918  *
3919  * This works similar to _dbus_message_loader_return_buffer()
3920  *
3921  * @param loader the message loader.
3922  * @param fds the array fds were read into
3923  * @param max_n_fds how many fds were read
3924  */
3925
3926 void
3927 _dbus_message_loader_return_unix_fds(DBusMessageLoader  *loader,
3928                                      int                *fds,
3929                                      unsigned            n_fds)
3930 {
3931 #ifdef HAVE_UNIX_FD_PASSING
3932   _dbus_assert(loader->unix_fds_outstanding);
3933   _dbus_assert(loader->unix_fds + loader->n_unix_fds == fds);
3934   _dbus_assert(loader->n_unix_fds + n_fds <= loader->n_unix_fds_allocated);
3935
3936   loader->n_unix_fds += n_fds;
3937   loader->unix_fds_outstanding = FALSE;
3938 #else
3939   _dbus_assert_not_reached("Platform doesn't support unix fd passing");
3940 #endif
3941 }
3942
3943 /*
3944  * FIXME when we move the header out of the buffer, that memmoves all
3945  * buffered messages. Kind of crappy.
3946  *
3947  * Also we copy the header and body, which is kind of crappy.  To
3948  * avoid this, we have to allow header and body to be in a single
3949  * memory block, which is good for messages we read and bad for
3950  * messages we are creating. But we could move_len() the buffer into
3951  * this single memory block, and move_len() will just swap the buffers
3952  * if you're moving the entire buffer replacing the dest string.
3953  *
3954  * We could also have the message loader tell the transport how many
3955  * bytes to read; so it would first ask for some arbitrary number like
3956  * 256, then if the message was incomplete it would use the
3957  * header/body len to ask for exactly the size of the message (or
3958  * blocks the size of a typical kernel buffer for the socket). That
3959  * way we don't get trailing bytes in the buffer that have to be
3960  * memmoved. Though I suppose we also don't have a chance of reading a
3961  * bunch of small messages at once, so the optimization may be stupid.
3962  *
3963  * Another approach would be to keep a "start" index into
3964  * loader->data and only delete it occasionally, instead of after
3965  * each message is loaded.
3966  *
3967  * load_message() returns FALSE if not enough memory OR the loader was corrupted
3968  */
3969 static dbus_bool_t
3970 load_message (DBusMessageLoader *loader,
3971               DBusMessage       *message,
3972               int                byte_order,
3973               int                fields_array_len,
3974               int                header_len,
3975               int                body_len)
3976 {
3977   dbus_bool_t oom;
3978   DBusValidity validity;
3979   const DBusString *type_str;
3980   int type_pos;
3981   DBusValidationMode mode;
3982   dbus_uint32_t n_unix_fds = 0;
3983
3984   mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
3985   
3986   oom = FALSE;
3987
3988 #if 0
3989   _dbus_verbose_bytes_of_string (&loader->data, 0, header_len /* + body_len */);
3990 #endif
3991
3992   /* 1. VALIDATE AND COPY OVER HEADER */
3993   _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
3994   _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
3995
3996   if (!_dbus_header_load (&message->header,
3997                           mode,
3998                           &validity,
3999                           byte_order,
4000                           fields_array_len,
4001                           header_len,
4002                           body_len,
4003                           &loader->data, 0,
4004                           _dbus_string_get_length (&loader->data)))
4005     {
4006       _dbus_verbose ("Failed to load header for new message code %d\n", validity);
4007
4008       /* assert here so we can catch any code that still uses DBUS_VALID to indicate
4009          oom errors.  They should use DBUS_VALIDITY_UNKNOWN_OOM_ERROR instead */
4010       _dbus_assert (validity != DBUS_VALID);
4011
4012       if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
4013         oom = TRUE;
4014       else
4015         {
4016           loader->corrupted = TRUE;
4017           loader->corruption_reason = validity;
4018         }
4019       goto failed;
4020     }
4021
4022   _dbus_assert (validity == DBUS_VALID);
4023
4024   /* 2. VALIDATE BODY */
4025   if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
4026     {
4027       get_const_signature (&message->header, &type_str, &type_pos);
4028       
4029       /* Because the bytes_remaining arg is NULL, this validates that the
4030        * body is the right length
4031        */
4032       validity = _dbus_validate_body_with_reason (type_str,
4033                                                   type_pos,
4034                                                   byte_order,
4035                                                   NULL,
4036                                                   &loader->data,
4037                                                   header_len,
4038                                                   body_len);
4039       if (validity != DBUS_VALID)
4040         {
4041           _dbus_verbose ("Failed to validate message body code %d\n", validity);
4042
4043           loader->corrupted = TRUE;
4044           loader->corruption_reason = validity;
4045           
4046           goto failed;
4047         }
4048     }
4049
4050   /* 3. COPY OVER UNIX FDS */
4051   _dbus_header_get_field_basic(&message->header,
4052                                DBUS_HEADER_FIELD_UNIX_FDS,
4053                                DBUS_TYPE_UINT32,
4054                                &n_unix_fds);
4055
4056 #ifdef HAVE_UNIX_FD_PASSING
4057
4058   if (n_unix_fds > loader->n_unix_fds)
4059     {
4060       _dbus_verbose("Message contains references to more unix fds than were sent %u != %u\n",
4061                     n_unix_fds, loader->n_unix_fds);
4062
4063       loader->corrupted = TRUE;
4064       loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4065       goto failed;
4066     }
4067
4068   /* If this was a recycled message there might still be
4069      some memory allocated for the fds */
4070   dbus_free(message->unix_fds);
4071
4072   if (n_unix_fds > 0)
4073     {
4074       message->unix_fds = _dbus_memdup(loader->unix_fds, n_unix_fds * sizeof(message->unix_fds[0]));
4075       if (message->unix_fds == NULL)
4076         {
4077           _dbus_verbose ("Failed to allocate file descriptor array\n");
4078           oom = TRUE;
4079           goto failed;
4080         }
4081
4082       message->n_unix_fds_allocated = message->n_unix_fds = n_unix_fds;
4083       loader->n_unix_fds -= n_unix_fds;
4084       memmove(loader->unix_fds + n_unix_fds, loader->unix_fds, loader->n_unix_fds);
4085     }
4086   else
4087     message->unix_fds = NULL;
4088
4089 #else
4090
4091   if (n_unix_fds > 0)
4092     {
4093       _dbus_verbose ("Hmm, message claims to come with file descriptors "
4094                      "but that's not supported on our platform, disconnecting.\n");
4095
4096       loader->corrupted = TRUE;
4097       loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4098       goto failed;
4099     }
4100
4101 #endif
4102
4103   /* 3. COPY OVER BODY AND QUEUE MESSAGE */
4104
4105   if (!_dbus_list_append (&loader->messages, message))
4106     {
4107       _dbus_verbose ("Failed to append new message to loader queue\n");
4108       oom = TRUE;
4109       goto failed;
4110     }
4111
4112   _dbus_assert (_dbus_string_get_length (&message->body) == 0);
4113   _dbus_assert (_dbus_string_get_length (&loader->data) >=
4114                 (header_len + body_len));
4115
4116   if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
4117     {
4118       _dbus_verbose ("Failed to move body into new message\n");
4119       oom = TRUE;
4120       goto failed;
4121     }
4122
4123   _dbus_string_delete (&loader->data, 0, header_len + body_len);
4124
4125   /* don't waste more than 2k of memory */
4126   _dbus_string_compact (&loader->data, 2048);
4127
4128   _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
4129   _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
4130
4131   _dbus_verbose ("Loaded message %p\n", message);
4132
4133   _dbus_assert (!oom);
4134   _dbus_assert (!loader->corrupted);
4135   _dbus_assert (loader->messages != NULL);
4136   _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4137
4138   return TRUE;
4139
4140  failed:
4141
4142   /* Clean up */
4143
4144   /* does nothing if the message isn't in the list */
4145   _dbus_list_remove_last (&loader->messages, message);
4146   
4147   if (oom)
4148     _dbus_assert (!loader->corrupted);
4149   else
4150     _dbus_assert (loader->corrupted);
4151
4152   _dbus_verbose_bytes_of_string (&loader->data, 0, _dbus_string_get_length (&loader->data));
4153
4154   return FALSE;
4155 }
4156
4157 /**
4158  * Converts buffered data into messages, if we have enough data.  If
4159  * we don't have enough data, does nothing.
4160  *
4161  * @todo we need to check that the proper named header fields exist
4162  * for each message type.
4163  *
4164  * @todo If a message has unknown type, we should probably eat it
4165  * right here rather than passing it out to applications.  However
4166  * it's not an error to see messages of unknown type.
4167  *
4168  * @param loader the loader.
4169  * @returns #TRUE if we had enough memory to finish.
4170  */
4171 dbus_bool_t
4172 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
4173 {
4174   while (!loader->corrupted &&
4175          _dbus_string_get_length (&loader->data) >= DBUS_MINIMUM_HEADER_SIZE)
4176     {
4177       DBusValidity validity;
4178       int byte_order, fields_array_len, header_len, body_len;
4179
4180       if (_dbus_header_have_message_untrusted (loader->max_message_size,
4181                                                &validity,
4182                                                &byte_order,
4183                                                &fields_array_len,
4184                                                &header_len,
4185                                                &body_len,
4186                                                &loader->data, 0,
4187                                                _dbus_string_get_length (&loader->data)))
4188         {
4189           DBusMessage *message;
4190
4191           _dbus_assert (validity == DBUS_VALID);
4192
4193           message = dbus_message_new_empty_header ();
4194           if (message == NULL)
4195             return FALSE;
4196
4197           if (!load_message (loader, message,
4198                              byte_order, fields_array_len,
4199                              header_len, body_len))
4200             {
4201               dbus_message_unref (message);
4202               /* load_message() returns false if corrupted or OOM; if
4203                * corrupted then return TRUE for not OOM
4204                */
4205               return loader->corrupted;
4206             }
4207
4208           _dbus_assert (loader->messages != NULL);
4209           _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4210         }
4211       else
4212         {
4213           _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
4214                          validity);
4215           if (validity != DBUS_VALID)
4216             {
4217               loader->corrupted = TRUE;
4218               loader->corruption_reason = validity;
4219             }
4220           return TRUE;
4221         }
4222     }
4223
4224   return TRUE;
4225 }
4226
4227 /**
4228  * Peeks at first loaded message, returns #NULL if no messages have
4229  * been queued.
4230  *
4231  * @param loader the loader.
4232  * @returns the next message, or #NULL if none.
4233  */
4234 DBusMessage*
4235 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
4236 {
4237   if (loader->messages)
4238     return loader->messages->data;
4239   else
4240     return NULL;
4241 }
4242
4243 /**
4244  * Pops a loaded message (passing ownership of the message
4245  * to the caller). Returns #NULL if no messages have been
4246  * queued.
4247  *
4248  * @param loader the loader.
4249  * @returns the next message, or #NULL if none.
4250  */
4251 DBusMessage*
4252 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
4253 {
4254   return _dbus_list_pop_first (&loader->messages);
4255 }
4256
4257 /**
4258  * Pops a loaded message inside a list link (passing ownership of the
4259  * message and link to the caller). Returns #NULL if no messages have
4260  * been loaded.
4261  *
4262  * @param loader the loader.
4263  * @returns the next message link, or #NULL if none.
4264  */
4265 DBusList*
4266 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
4267 {
4268   return _dbus_list_pop_first_link (&loader->messages);
4269 }
4270
4271 /**
4272  * Returns a popped message link, used to undo a pop.
4273  *
4274  * @param loader the loader
4275  * @param link the link with a message in it
4276  */
4277 void
4278 _dbus_message_loader_putback_message_link (DBusMessageLoader  *loader,
4279                                            DBusList           *link)
4280 {
4281   _dbus_list_prepend_link (&loader->messages, link);
4282 }
4283
4284 /**
4285  * Checks whether the loader is confused due to bad data.
4286  * If messages are received that are invalid, the
4287  * loader gets confused and gives up permanently.
4288  * This state is called "corrupted."
4289  *
4290  * @param loader the loader
4291  * @returns #TRUE if the loader is hosed.
4292  */
4293 dbus_bool_t
4294 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
4295 {
4296   _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
4297                 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
4298   return loader->corrupted;
4299 }
4300
4301 /**
4302  * Checks what kind of bad data confused the loader.
4303  *
4304  * @param loader the loader
4305  * @returns why the loader is hosed, or DBUS_VALID if it isn't.
4306  */
4307 DBusValidity
4308 _dbus_message_loader_get_corruption_reason (DBusMessageLoader *loader)
4309 {
4310   _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
4311                 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
4312
4313   return loader->corruption_reason;
4314 }
4315
4316 /**
4317  * Sets the maximum size message we allow.
4318  *
4319  * @param loader the loader
4320  * @param size the max message size in bytes
4321  */
4322 void
4323 _dbus_message_loader_set_max_message_size (DBusMessageLoader  *loader,
4324                                            long                size)
4325 {
4326   if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
4327     {
4328       _dbus_verbose ("clamping requested max message size %ld to %d\n",
4329                      size, DBUS_MAXIMUM_MESSAGE_LENGTH);
4330       size = DBUS_MAXIMUM_MESSAGE_LENGTH;
4331     }
4332   loader->max_message_size = size;
4333 }
4334
4335 /**
4336  * Gets the maximum allowed message size in bytes.
4337  *
4338  * @param loader the loader
4339  * @returns max size in bytes
4340  */
4341 long
4342 _dbus_message_loader_get_max_message_size (DBusMessageLoader  *loader)
4343 {
4344   return loader->max_message_size;
4345 }
4346
4347 /**
4348  * Sets the maximum unix fds per message we allow.
4349  *
4350  * @param loader the loader
4351  * @param size the max number of unix fds in a message
4352  */
4353 void
4354 _dbus_message_loader_set_max_message_unix_fds (DBusMessageLoader  *loader,
4355                                                long                n)
4356 {
4357   if (n > DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
4358     {
4359       _dbus_verbose ("clamping requested max message unix_fds %ld to %d\n",
4360                      n, DBUS_MAXIMUM_MESSAGE_UNIX_FDS);
4361       n = DBUS_MAXIMUM_MESSAGE_UNIX_FDS;
4362     }
4363   loader->max_message_unix_fds = n;
4364 }
4365
4366 /**
4367  * Gets the maximum allowed number of unix fds per message
4368  *
4369  * @param loader the loader
4370  * @returns max unix fds
4371  */
4372 long
4373 _dbus_message_loader_get_max_message_unix_fds (DBusMessageLoader  *loader)
4374 {
4375   return loader->max_message_unix_fds;
4376 }
4377
4378 static DBusDataSlotAllocator slot_allocator;
4379 _DBUS_DEFINE_GLOBAL_LOCK (message_slots);
4380
4381 /**
4382  * Allocates an integer ID to be used for storing application-specific
4383  * data on any DBusMessage. The allocated ID may then be used
4384  * with dbus_message_set_data() and dbus_message_get_data().
4385  * The passed-in slot must be initialized to -1, and is filled in
4386  * with the slot ID. If the passed-in slot is not -1, it's assumed
4387  * to be already allocated, and its refcount is incremented.
4388  *
4389  * The allocated slot is global, i.e. all DBusMessage objects will
4390  * have a slot with the given integer ID reserved.
4391  *
4392  * @param slot_p address of a global variable storing the slot
4393  * @returns #FALSE on failure (no memory)
4394  */
4395 dbus_bool_t
4396 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
4397 {
4398   return _dbus_data_slot_allocator_alloc (&slot_allocator,
4399                                           &_DBUS_LOCK_NAME (message_slots),
4400                                           slot_p);
4401 }
4402
4403 /**
4404  * Deallocates a global ID for message data slots.
4405  * dbus_message_get_data() and dbus_message_set_data() may no
4406  * longer be used with this slot.  Existing data stored on existing
4407  * DBusMessage objects will be freed when the message is
4408  * finalized, but may not be retrieved (and may only be replaced if
4409  * someone else reallocates the slot).  When the refcount on the
4410  * passed-in slot reaches 0, it is set to -1.
4411  *
4412  * @param slot_p address storing the slot to deallocate
4413  */
4414 void
4415 dbus_message_free_data_slot (dbus_int32_t *slot_p)
4416 {
4417   _dbus_return_if_fail (*slot_p >= 0);
4418
4419   _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
4420 }
4421
4422 /**
4423  * Stores a pointer on a DBusMessage, along
4424  * with an optional function to be used for freeing
4425  * the data when the data is set again, or when
4426  * the message is finalized. The slot number
4427  * must have been allocated with dbus_message_allocate_data_slot().
4428  *
4429  * @param message the message
4430  * @param slot the slot number
4431  * @param data the data to store
4432  * @param free_data_func finalizer function for the data
4433  * @returns #TRUE if there was enough memory to store the data
4434  */
4435 dbus_bool_t
4436 dbus_message_set_data (DBusMessage     *message,
4437                        dbus_int32_t     slot,
4438                        void            *data,
4439                        DBusFreeFunction free_data_func)
4440 {
4441   DBusFreeFunction old_free_func;
4442   void *old_data;
4443   dbus_bool_t retval;
4444
4445   _dbus_return_val_if_fail (message != NULL, FALSE);
4446   _dbus_return_val_if_fail (slot >= 0, FALSE);
4447
4448   retval = _dbus_data_slot_list_set (&slot_allocator,
4449                                      &message->slot_list,
4450                                      slot, data, free_data_func,
4451                                      &old_free_func, &old_data);
4452
4453   if (retval)
4454     {
4455       /* Do the actual free outside the message lock */
4456       if (old_free_func)
4457         (* old_free_func) (old_data);
4458     }
4459
4460   return retval;
4461 }
4462
4463 /**
4464  * Retrieves data previously set with dbus_message_set_data().
4465  * The slot must still be allocated (must not have been freed).
4466  *
4467  * @param message the message
4468  * @param slot the slot to get data from
4469  * @returns the data, or #NULL if not found
4470  */
4471 void*
4472 dbus_message_get_data (DBusMessage   *message,
4473                        dbus_int32_t   slot)
4474 {
4475   void *res;
4476
4477   _dbus_return_val_if_fail (message != NULL, NULL);
4478
4479   res = _dbus_data_slot_list_get (&slot_allocator,
4480                                   &message->slot_list,
4481                                   slot);
4482
4483   return res;
4484 }
4485
4486 /**
4487  * Utility function to convert a machine-readable (not translated)
4488  * string into a D-Bus message type.
4489  *
4490  * @code
4491  *   "method_call"    -> DBUS_MESSAGE_TYPE_METHOD_CALL
4492  *   "method_return"  -> DBUS_MESSAGE_TYPE_METHOD_RETURN
4493  *   "signal"         -> DBUS_MESSAGE_TYPE_SIGNAL
4494  *   "error"          -> DBUS_MESSAGE_TYPE_ERROR
4495  *   anything else    -> DBUS_MESSAGE_TYPE_INVALID
4496  * @endcode
4497  *
4498  */
4499 int
4500 dbus_message_type_from_string (const char *type_str)
4501 {
4502   if (strcmp (type_str, "method_call") == 0)
4503     return DBUS_MESSAGE_TYPE_METHOD_CALL;
4504   if (strcmp (type_str, "method_return") == 0)
4505     return DBUS_MESSAGE_TYPE_METHOD_RETURN;
4506   else if (strcmp (type_str, "signal") == 0)
4507     return DBUS_MESSAGE_TYPE_SIGNAL;
4508   else if (strcmp (type_str, "error") == 0)
4509     return DBUS_MESSAGE_TYPE_ERROR;
4510   else
4511     return DBUS_MESSAGE_TYPE_INVALID;
4512 }
4513
4514 /**
4515  * Utility function to convert a D-Bus message type into a
4516  * machine-readable string (not translated).
4517  *
4518  * @code
4519  *   DBUS_MESSAGE_TYPE_METHOD_CALL    -> "method_call"
4520  *   DBUS_MESSAGE_TYPE_METHOD_RETURN  -> "method_return"
4521  *   DBUS_MESSAGE_TYPE_SIGNAL         -> "signal"
4522  *   DBUS_MESSAGE_TYPE_ERROR          -> "error"
4523  *   DBUS_MESSAGE_TYPE_INVALID        -> "invalid"
4524  * @endcode
4525  *
4526  */
4527 const char *
4528 dbus_message_type_to_string (int type)
4529 {
4530   switch (type)
4531     {
4532     case DBUS_MESSAGE_TYPE_METHOD_CALL:
4533       return "method_call";
4534     case DBUS_MESSAGE_TYPE_METHOD_RETURN:
4535       return "method_return";
4536     case DBUS_MESSAGE_TYPE_SIGNAL:
4537       return "signal";
4538     case DBUS_MESSAGE_TYPE_ERROR:
4539       return "error";
4540     default:
4541       return "invalid";
4542     }
4543 }
4544
4545 /**
4546  * Turn a DBusMessage into the marshalled form as described in the D-Bus
4547  * specification.
4548  *
4549  * Generally, this function is only useful for encapsulating D-Bus messages in
4550  * a different protocol.
4551  *
4552  * @param msg the DBusMessage
4553  * @param marshalled_data_p the location to save the marshalled form to
4554  * @param len_p the location to save the length of the marshalled form to
4555  * @returns #FALSE if there was not enough memory
4556  */
4557 dbus_bool_t
4558 dbus_message_marshal (DBusMessage  *msg,
4559                       char        **marshalled_data_p,
4560                       int          *len_p)
4561 {
4562   DBusString tmp;
4563   dbus_bool_t was_locked;
4564
4565   _dbus_return_val_if_fail (msg != NULL, FALSE);
4566   _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
4567   _dbus_return_val_if_fail (len_p != NULL, FALSE);
4568   
4569   if (!_dbus_string_init (&tmp))
4570     return FALSE;
4571
4572   /* Ensure the message is locked, to ensure the length header is filled in. */
4573   was_locked = msg->locked;
4574
4575   if (!was_locked)
4576     dbus_message_lock (msg);
4577
4578   if (!_dbus_string_copy (&(msg->header.data), 0, &tmp, 0))
4579     goto fail;
4580
4581   *len_p = _dbus_string_get_length (&tmp);
4582
4583   if (!_dbus_string_copy (&(msg->body), 0, &tmp, *len_p))
4584     goto fail;
4585
4586   *len_p = _dbus_string_get_length (&tmp);
4587
4588   if (!_dbus_string_steal_data (&tmp, marshalled_data_p))
4589     goto fail;
4590
4591   _dbus_string_free (&tmp);
4592
4593   if (!was_locked)
4594     msg->locked = FALSE;
4595
4596   return TRUE;
4597
4598  fail:
4599   _dbus_string_free (&tmp);
4600
4601   if (!was_locked)
4602     msg->locked = FALSE;
4603
4604   return FALSE;
4605 }
4606
4607 /**
4608  * Demarshal a D-Bus message from the format described in the D-Bus
4609  * specification.
4610  *
4611  * Generally, this function is only useful for encapsulating D-Bus messages in
4612  * a different protocol.
4613  *
4614  * @param str the marshalled DBusMessage
4615  * @param len the length of str
4616  * @param error the location to save errors to
4617  * @returns #NULL if there was an error
4618  */
4619 DBusMessage *
4620 dbus_message_demarshal (const char *str,
4621                         int         len,
4622                         DBusError  *error)
4623 {
4624   DBusMessageLoader *loader;
4625   DBusString *buffer;
4626   DBusMessage *msg;
4627
4628   _dbus_return_val_if_fail (str != NULL, NULL);
4629
4630   loader = _dbus_message_loader_new ();
4631
4632   if (loader == NULL)
4633     return NULL;
4634
4635   _dbus_message_loader_get_buffer (loader, &buffer);
4636   _dbus_string_append_len (buffer, str, len);
4637   _dbus_message_loader_return_buffer (loader, buffer, len);
4638
4639   if (!_dbus_message_loader_queue_messages (loader))
4640     goto fail_oom;
4641
4642   if (_dbus_message_loader_get_is_corrupted (loader))
4643     goto fail_corrupt;
4644
4645   msg = _dbus_message_loader_pop_message (loader);
4646
4647   if (!msg)
4648     goto fail_oom;
4649
4650   _dbus_message_loader_unref (loader);
4651   return msg;
4652
4653  fail_corrupt:
4654   dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted (%s)",
4655                   _dbus_validity_to_error_message (loader->corruption_reason));
4656   _dbus_message_loader_unref (loader);
4657   return NULL;
4658
4659  fail_oom:
4660   _DBUS_SET_OOM (error);
4661   _dbus_message_loader_unref (loader);
4662   return NULL;
4663 }
4664
4665 /**
4666  * Returns the number of bytes required to be in the buffer to demarshal a
4667  * D-Bus message.
4668  *
4669  * Generally, this function is only useful for encapsulating D-Bus messages in
4670  * a different protocol.
4671  *
4672  * @param str data to be marshalled
4673  * @param len the length of str
4674  * @param error the location to save errors to
4675  * @returns -1 if there was no valid data to be demarshalled, 0 if there wasn't enough data to determine how much should be demarshalled. Otherwise returns the number of bytes to be demarshalled
4676  * 
4677  */
4678 int 
4679 dbus_message_demarshal_bytes_needed(const char *buf, 
4680                                     int         len)
4681 {
4682   DBusString str;
4683   int byte_order, fields_array_len, header_len, body_len;
4684   DBusValidity validity = DBUS_VALID;
4685   int have_message;
4686
4687   if (!buf || len < DBUS_MINIMUM_HEADER_SIZE)
4688     return 0;
4689
4690   if (len > DBUS_MAXIMUM_MESSAGE_LENGTH)
4691     len = DBUS_MAXIMUM_MESSAGE_LENGTH;
4692   _dbus_string_init_const_len (&str, buf, len);
4693   
4694   validity = DBUS_VALID;
4695   have_message
4696     = _dbus_header_have_message_untrusted(DBUS_MAXIMUM_MESSAGE_LENGTH,
4697                                           &validity, &byte_order,
4698                                           &fields_array_len,
4699                                           &header_len,
4700                                           &body_len,
4701                                           &str, 0,
4702                                           len);
4703   _dbus_string_free (&str);
4704
4705   if (validity == DBUS_VALID)
4706     {
4707       _dbus_assert (have_message || (header_len + body_len) > len);
4708       (void) have_message; /* unused unless asserting */
4709       return header_len + body_len;
4710     }
4711   else
4712     {
4713       return -1; /* broken! */
4714     }
4715 }
4716
4717 /** @} */
4718
4719 /* tests in dbus-message-util.c */