chiark / gitweb /
bus-message: fix typo
[elogind.git] / src / libsystemd-bus / bus-message.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23
24 #include "util.h"
25 #include "utf8.h"
26 #include "strv.h"
27
28 #include "sd-bus.h"
29 #include "bus-message.h"
30 #include "bus-internal.h"
31 #include "bus-type.h"
32 #include "bus-signature.h"
33
34 static int message_parse_fields(sd_bus_message *m);
35 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
36
37 static void reset_containers(sd_bus_message *m) {
38         unsigned i;
39
40         assert(m);
41
42         for (i = 0; i < m->n_containers; i++)
43                 free(m->containers[i].signature);
44
45         free(m->containers);
46         m->containers = NULL;
47
48         m->n_containers = 0;
49         m->root_container.index = 0;
50 }
51
52 static void message_free(sd_bus_message *m) {
53         unsigned i;
54
55         assert(m);
56
57         if (m->free_header)
58                 free(m->header);
59
60         if (m->free_fields)
61                 free(m->fields);
62
63         if (m->free_body)
64                 free(m->body);
65
66         for (i = 0; i < m->n_fds; i++)
67                 close_nointr_nofail(m->fds[i]);
68
69         reset_containers(m);
70         free(m->root_container.signature);
71
72         free(m->peeked_signature);
73         free(m);
74 }
75
76 static void* buffer_extend(void **p, uint32_t *sz, size_t align, size_t extend) {
77         size_t start, n;
78         void *k;
79
80         assert(p);
81         assert(sz);
82         assert(align > 0);
83
84         start = ALIGN_TO((size_t) *sz, align);
85         n = start + extend;
86
87         if (n == *sz)
88                 return (uint8_t*) *p + start;
89
90         if (n > (size_t) ((uint32_t) -1))
91                 return NULL;
92
93         k = realloc(*p, n);
94         if (!k)
95                 return NULL;
96
97         /* Zero out padding */
98         if (start > *sz)
99                 memset((uint8_t*) k + *sz, 0, start - *sz);
100
101         *p = k;
102         *sz = n;
103
104         return (uint8_t*) k + start;
105 }
106
107 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
108         void *p, *o;
109
110         assert(m);
111
112         o = m->fields;
113         p = buffer_extend(&m->fields, &m->header->fields_size, align, sz);
114         if (!p)
115                 return NULL;
116
117         if (o != m->fields) {
118                 /* Adjust quick access pointers */
119
120                 if (m->path)
121                         m->path = (const char*) m->fields + (m->path - (const char*) o);
122                 if (m->interface)
123                         m->interface = (const char*) m->fields + (m->interface - (const char*) o);
124                 if (m->member)
125                         m->member = (const char*) m->fields + (m->member - (const char*) o);
126                 if (m->destination)
127                         m->destination = (const char*) m->fields + (m->destination - (const char*) o);
128                 if (m->sender)
129                         m->sender = (const char*) m->fields + (m->sender - (const char*) o);
130                 if (m->error.name)
131                         m->error.name = (const char*) m->fields + (m->error.name - (const char*) o);
132         }
133
134         m->free_fields = true;
135
136         return p;
137 }
138
139 static int message_append_field_string(
140                 sd_bus_message *m,
141                 uint8_t h,
142                 char type,
143                 const char *s,
144                 const char **ret) {
145
146         size_t l;
147         uint8_t *p;
148
149         assert(m);
150
151         l = strlen(s);
152         if (l > (size_t) (uint32_t) -1)
153                 return -EINVAL;
154
155         /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
156         p = message_extend_fields(m, 8, 4 + 4 + l + 1);
157         if (!p)
158                 return -ENOMEM;
159
160         p[0] = h;
161         p[1] = 1;
162         p[2] = type;
163         p[3] = 0;
164
165         ((uint32_t*) p)[1] = l;
166         memcpy(p + 8, s, l + 1);
167
168         if (ret)
169                 *ret = (const char*) p + 8;
170
171         return 0;
172 }
173
174 static int message_append_field_signature(
175                 sd_bus_message *m,
176                 uint8_t h,
177                 const char *s,
178                 const char **ret) {
179
180         size_t l;
181         uint8_t *p;
182
183         assert(m);
184
185         l = strlen(s);
186         if (l > 255)
187                 return -EINVAL;
188
189         /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
190         p = message_extend_fields(m, 8, 4 + 1 + l + 1);
191         if (!p)
192                 return -ENOMEM;
193
194         p[0] = h;
195         p[1] = 1;
196         p[2] = SD_BUS_TYPE_SIGNATURE;
197         p[3] = 0;
198         p[4] = l;
199         memcpy(p + 5, s, l + 1);
200
201         if (ret)
202                 *ret = (const char*) p + 5;
203
204         return 0;
205 }
206
207 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
208         uint8_t *p;
209
210         assert(m);
211
212         /* field id byte + signature length + signature 'u' + NUL + value */
213         p = message_extend_fields(m, 8, 4 + 4);
214         if (!p)
215                 return -ENOMEM;
216
217         p[0] = h;
218         p[1] = 1;
219         p[2] = SD_BUS_TYPE_UINT32;
220         p[3] = 0;
221
222         ((uint32_t*) p)[1] = x;
223
224         return 0;
225 }
226
227 int bus_message_from_malloc(void *buffer, size_t length, sd_bus_message **ret) {
228         sd_bus_message *m;
229         struct bus_header *h;
230         size_t total, fs, bs;
231         int r;
232
233         assert(buffer || length <= 0);
234         assert(ret);
235
236         if (length < sizeof(struct bus_header))
237                 return -EBADMSG;
238
239         h = buffer;
240         if (h->version != 1)
241                 return -EBADMSG;
242
243         if (h->serial == 0)
244                 return -EBADMSG;
245
246         if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
247                 return -EBADMSG;
248
249         if (h->endian == SD_BUS_NATIVE_ENDIAN) {
250                 fs = h->fields_size;
251                 bs = h->body_size;
252         } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
253                 fs = bswap_32(h->fields_size);
254                 bs = bswap_32(h->body_size);
255         } else
256                 return -EBADMSG;
257
258         total = sizeof(struct bus_header) + ALIGN_TO(fs, 8) + bs;
259         if (length != total)
260                 return -EBADMSG;
261
262         m = new0(sd_bus_message, 1);
263         if (!m)
264                 return -ENOMEM;
265
266         m->n_ref = 1;
267         m->header = h;
268         m->free_header = true;
269         m->fields = (uint8_t*) buffer + sizeof(struct bus_header);
270         m->body = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN_TO(fs, 8);
271         m->sealed = true;
272
273         m->n_iovec = 1;
274         m->iovec[0].iov_base = buffer;
275         m->iovec[0].iov_len = length;
276
277         r = message_parse_fields(m);
278         if (r < 0) {
279                 message_free(m);
280                 return r;
281         }
282
283         *ret = m;
284         return 0;
285 }
286
287 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
288         sd_bus_message *m;
289
290         m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
291         if (!m)
292                 return NULL;
293
294         m->n_ref = 1;
295         m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
296         m->header->endian = SD_BUS_NATIVE_ENDIAN;
297         m->header->type = type;
298         m->header->version = bus ? bus->message_version : 1;
299
300         return m;
301 }
302
303 int sd_bus_message_new_signal(
304                 sd_bus *bus,
305                 const char *path,
306                 const char *interface,
307                 const char *member,
308                 sd_bus_message **m) {
309
310         sd_bus_message *t;
311         int r;
312
313         if (!path)
314                 return -EINVAL;
315         if (!interface)
316                 return -EINVAL;
317         if (!member)
318                 return -EINVAL;
319         if (!m)
320                 return -EINVAL;
321
322         t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
323         if (!t)
324                 return -ENOMEM;
325
326         t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
327
328         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
329         if (r < 0)
330                 goto fail;
331         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
332         if (r < 0)
333                 goto fail;
334         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
335         if (r < 0)
336                 goto fail;
337
338         *m = t;
339         return 0;
340
341 fail:
342         sd_bus_message_unref(t);
343         return r;
344 }
345
346 int sd_bus_message_new_method_call(
347                 sd_bus *bus,
348                 const char *destination,
349                 const char *path,
350                 const char *interface,
351                 const char *member,
352                 sd_bus_message **m) {
353
354         sd_bus_message *t;
355         int r;
356
357         if (!path)
358                 return -EINVAL;
359         if (!member)
360                 return -EINVAL;
361         if (!m)
362                 return -EINVAL;
363
364         t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
365         if (!t)
366                 return -ENOMEM;
367
368         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
369         if (r < 0)
370                 goto fail;
371         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
372         if (r < 0)
373                 goto fail;
374
375         if (interface) {
376                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
377                 if (r < 0)
378                         goto fail;
379         }
380
381         if (destination) {
382                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
383                 if (r < 0)
384                         goto fail;
385         }
386
387         *m = t;
388         return 0;
389
390 fail:
391         message_free(t);
392         return r;
393 }
394
395 static int message_new_reply(
396                 sd_bus *bus,
397                 sd_bus_message *call,
398                 uint8_t type,
399                 sd_bus_message **m) {
400
401         sd_bus_message *t;
402         int r;
403
404         if (!call)
405                 return -EINVAL;
406         if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
407                 return -EINVAL;
408         if (!m)
409                 return -EINVAL;
410
411         t = message_new(bus, type);
412         if (!t)
413                 return -ENOMEM;
414
415         t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
416         t->reply_serial = BUS_MESSAGE_SERIAL(call);
417
418         r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
419         if (r < 0)
420                 goto fail;
421
422         if (call->sender) {
423                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
424                 if (r < 0)
425                         goto fail;
426         }
427
428         t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
429
430         *m = t;
431         return 0;
432
433 fail:
434         message_free(t);
435         return r;
436 }
437
438 int sd_bus_message_new_method_return(
439                 sd_bus *bus,
440                 sd_bus_message *call,
441                 sd_bus_message **m) {
442
443         return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
444 }
445
446 int sd_bus_message_new_method_error(
447                 sd_bus *bus,
448                 sd_bus_message *call,
449                 const sd_bus_error *e,
450                 sd_bus_message **m) {
451
452         sd_bus_message *t;
453         int r;
454
455         if (!sd_bus_error_is_set(e))
456                 return -EINVAL;
457         if (!m)
458                 return -EINVAL;
459
460         r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
461         if (r < 0)
462                 return r;
463
464         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
465         if (r < 0)
466                 goto fail;
467
468         if (e->message) {
469                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
470                 if (r < 0)
471                         goto fail;
472         }
473
474         *m = t;
475         return 0;
476
477 fail:
478         message_free(t);
479         return r;
480 }
481
482 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
483         if (!m)
484                 return NULL;
485
486         assert(m->n_ref > 0);
487         m->n_ref++;
488
489         return m;
490 }
491
492 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
493         if (!m)
494                 return NULL;
495
496         assert(m->n_ref > 0);
497         m->n_ref--;
498
499         if (m->n_ref <= 0)
500                 message_free(m);
501
502         return NULL;
503 }
504
505 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
506         if (!m)
507                 return -EINVAL;
508         if (!type)
509                 return -EINVAL;
510
511         *type = m->header->type;
512         return 0;
513 }
514
515 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
516         if (!m)
517                 return -EINVAL;
518         if (!serial)
519                 return -EINVAL;
520         if (m->header->serial == 0)
521                 return -ENOENT;
522
523         *serial = BUS_MESSAGE_SERIAL(m);
524         return 0;
525 }
526
527 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
528         if (!m)
529                 return -EINVAL;
530         if (!serial)
531                 return -EINVAL;
532         if (m->reply_serial == 0)
533                 return -ENOENT;
534
535         *serial = m->reply_serial;
536         return 0;
537 }
538
539 int sd_bus_message_get_no_reply(sd_bus_message *m) {
540         if (!m)
541                 return -EINVAL;
542
543         return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
544 }
545
546 const char *sd_bus_message_get_path(sd_bus_message *m) {
547         if (!m)
548                 return NULL;
549
550         return m->path;
551 }
552
553 const char *sd_bus_message_get_interface(sd_bus_message *m) {
554         if (!m)
555                 return NULL;
556
557         return m->interface;
558 }
559
560 const char *sd_bus_message_get_member(sd_bus_message *m) {
561         if (!m)
562                 return NULL;
563
564         return m->member;
565 }
566 const char *sd_bus_message_get_destination(sd_bus_message *m) {
567         if (!m)
568                 return NULL;
569
570         return m->destination;
571 }
572
573 const char *sd_bus_message_get_sender(sd_bus_message *m) {
574         if (!m)
575                 return NULL;
576
577         return m->sender;
578 }
579
580 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
581         if (!m)
582                 return NULL;
583
584         if (!sd_bus_error_is_set(&m->error))
585                 return NULL;
586
587         return &m->error;
588 }
589
590 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
591         if (!m)
592                 return -EINVAL;
593         if (!m->uid_valid)
594                 return -ENOENT;
595
596         *uid = m->uid;
597         return 0;
598 }
599
600 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
601         if (!m)
602                 return -EINVAL;
603         if (!m->gid_valid)
604                 return -ENOENT;
605
606         *gid = m->gid;
607         return 0;
608 }
609
610 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
611         if (!m)
612                 return -EINVAL;
613         if (m->pid <= 0)
614                 return -ENOENT;
615
616         *pid = m->pid;
617         return 0;
618 }
619
620 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
621         if (!m)
622                 return -EINVAL;
623         if (m->tid <= 0)
624                 return -ENOENT;
625
626         *tid = m->tid;
627         return 0;
628 }
629
630 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
631         if (!m)
632                 return -EINVAL;
633
634         if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
635                 return 0;
636
637         if (interface && (!m->interface || !streq(m->interface, interface)))
638                 return 0;
639
640         if (member &&  (!m->member || !streq(m->member, member)))
641                 return 0;
642
643         return 1;
644 }
645
646 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
647         if (!m)
648                 return -EINVAL;
649
650         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
651                 return 0;
652
653         if (interface && (!m->interface || !streq(m->interface, interface)))
654                 return 0;
655
656         if (member &&  (!m->member || !streq(m->member, member)))
657                 return 0;
658
659         return 1;
660 }
661
662 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
663         if (!m)
664                 return -EINVAL;
665
666         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
667                 return 0;
668
669         if (name && (!m->error.name || !streq(m->error.name, name)))
670                 return 0;
671
672         return 1;
673 }
674
675 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
676         if (!m)
677                 return -EINVAL;
678         if (m->sealed)
679                 return -EPERM;
680         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
681                 return -EPERM;
682
683         if (b)
684                 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
685         else
686                 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
687
688         return 0;
689 }
690
691 static struct bus_container *message_get_container(sd_bus_message *m) {
692         assert(m);
693
694         if (m->n_containers == 0)
695                 return &m->root_container;
696
697         assert(m->containers);
698         return m->containers + m->n_containers - 1;
699 }
700
701 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
702         void *p, *o;
703         size_t added;
704         struct bus_container *c;
705
706         assert(m);
707         assert(align > 0);
708
709         o = m->body;
710         added = m->header->body_size;
711
712         p = buffer_extend(&m->body, &m->header->body_size, align, sz);
713         if (!p)
714                 return NULL;
715
716         added = m->header->body_size - added;
717
718         for (c = m->containers; c < m->containers + m->n_containers; c++)
719                 if (c->array_size) {
720                         c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
721                         *c->array_size += added;
722                 }
723
724         if (o != m->body) {
725                 if (m->error.message)
726                         m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
727         }
728
729         m->free_body = true;
730
731         return p;
732 }
733
734 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
735         struct bus_container *c;
736         size_t sz, align;
737         uint32_t k;
738         void *a;
739         char *e = NULL;
740
741         if (!m)
742                 return -EINVAL;
743         if (m->sealed)
744                 return -EPERM;
745         if (!bus_type_is_basic(type))
746                 return -EINVAL;
747
748         c = message_get_container(m);
749
750         if (c->signature && c->signature[c->index]) {
751                 /* Container signature is already set */
752
753                 if (c->signature[c->index] != type)
754                         return -ENXIO;
755         } else {
756                 /* Maybe we can append to the signature? But only if this is the top-level container*/
757                 if (c->enclosing != 0)
758                         return -ENXIO;
759
760                 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
761                 if (!e)
762                         return -ENOMEM;
763         }
764
765         switch (type) {
766
767         case SD_BUS_TYPE_STRING:
768         case SD_BUS_TYPE_OBJECT_PATH:
769                 align = 4;
770                 sz = 4 + strlen(p) + 1;
771                 break;
772
773         case SD_BUS_TYPE_SIGNATURE:
774                 align = 1;
775                 sz = 1 + strlen(p) + 1;
776                 break;
777
778         case SD_BUS_TYPE_BOOLEAN:
779                 align = sz = 4;
780
781                 assert_cc(sizeof(int) == sizeof(uint32_t));
782                 memcpy(&k, p, 4);
783                 k = !!k;
784                 p = &k;
785                 break;
786
787         default:
788                 align = bus_type_get_alignment(type);
789                 sz = bus_type_get_size(type);
790                 break;
791         }
792
793         assert(align > 0);
794         assert(sz > 0);
795
796         a = message_extend_body(m, align, sz);
797         if (!a) {
798                 /* Truncate extended signature again */
799                 if (e)
800                         c->signature[c->index] = 0;
801
802                 return -ENOMEM;
803         }
804
805         if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
806                 *(uint32_t*) a = sz - 5;
807                 memcpy((uint8_t*) a + 4, p, sz - 4);
808
809                 if (stored)
810                         *stored = (const uint8_t*) a + 4;
811
812         } else if (type == SD_BUS_TYPE_SIGNATURE) {
813                 *(uint8_t*) a = sz - 1;
814                 memcpy((uint8_t*) a + 1, p, sz - 1);
815
816                 if (stored)
817                         *stored = (const uint8_t*) a + 1;
818
819         } else {
820                 memcpy(a, p, sz);
821
822                 if (stored)
823                         *stored = a;
824         }
825
826         if (c->enclosing != SD_BUS_TYPE_ARRAY)
827                 c->index++;
828
829         return 0;
830 }
831
832 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
833         return message_append_basic(m, type, p, NULL);
834 }
835
836 static int bus_message_open_array(
837                 sd_bus_message *m,
838                 struct bus_container *c,
839                 const char *contents,
840                 uint32_t **array_size) {
841
842         unsigned nindex;
843         char *e = NULL;
844         void *a, *b;
845         int alignment;
846         size_t saved;
847
848         assert(m);
849         assert(c);
850         assert(contents);
851         assert(array_size);
852
853         if (!signature_is_single(contents))
854                 return -EINVAL;
855
856         alignment = bus_type_get_alignment(contents[0]);
857         if (alignment < 0)
858                 return alignment;
859
860         if (c->signature && c->signature[c->index]) {
861
862                 /* Verify the existing signature */
863
864                 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
865                         return -ENXIO;
866
867                 if (!startswith(c->signature + c->index + 1, contents))
868                         return -ENXIO;
869
870                 nindex = c->index + 1 + strlen(contents);
871         } else {
872                 if (c->enclosing != 0)
873                         return -ENXIO;
874
875                 /* Extend the existing signature */
876
877                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
878                 if (!e)
879                         return -ENOMEM;
880
881                 nindex = e - c->signature;
882         }
883
884         saved = m->header->body_size;
885         a = message_extend_body(m, 4, 4);
886         if (!a) {
887                 /* Truncate extended signature again */
888                 if (e)
889                         c->signature[c->index] = 0;
890
891                 return -ENOMEM;
892         }
893         b = m->body;
894
895         if (!message_extend_body(m, alignment, 0)) {
896                 /* Add alignment between size and first element */
897                 if (e)
898                         c->signature[c->index] = 0;
899
900                 m->header->body_size = saved;
901                 return -ENOMEM;
902         }
903
904         if (c->enclosing != SD_BUS_TYPE_ARRAY)
905                 c->index = nindex;
906
907         /* m->body might have changed so let's readjust a */
908         a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
909         *(uint32_t*) a = 0;
910
911         *array_size = a;
912         return 0;
913 }
914
915 static int bus_message_open_variant(
916                 sd_bus_message *m,
917                 struct bus_container *c,
918                 const char *contents) {
919
920         char *e = NULL;
921         size_t l;
922         void *a;
923
924         assert(m);
925         assert(c);
926         assert(contents);
927
928         if (!signature_is_single(contents))
929                 return -EINVAL;
930
931         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
932                 return -EINVAL;
933
934         if (c->signature && c->signature[c->index]) {
935
936                 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
937                         return -ENXIO;
938
939         } else {
940                 if (c->enclosing != 0)
941                         return -ENXIO;
942
943                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
944                 if (!e)
945                         return -ENOMEM;
946         }
947
948         l = strlen(contents);
949         a = message_extend_body(m, 1, 1 + l + 1);
950         if (!a) {
951                 /* Truncate extended signature again */
952                 if (e)
953                         c->signature[c->index] = 0;
954
955                 return -ENOMEM;
956         }
957
958         *(uint8_t*) a = l;
959         memcpy((uint8_t*) a + 1, contents, l + 1);
960
961         if (c->enclosing != SD_BUS_TYPE_ARRAY)
962                 c->index++;
963
964         return 0;
965 }
966
967 static int bus_message_open_struct(
968                 sd_bus_message *m,
969                 struct bus_container *c,
970                 const char *contents) {
971
972         size_t nindex;
973         char *e = NULL;
974
975         assert(m);
976         assert(c);
977         assert(contents);
978
979         if (!signature_is_valid(contents, false))
980                 return -EINVAL;
981
982         if (c->signature && c->signature[c->index]) {
983                 size_t l;
984
985                 l = strlen(contents);
986
987                 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
988                     !startswith(c->signature + c->index + 1, contents) ||
989                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
990                         return -ENXIO;
991
992                 nindex = c->index + 1 + l + 1;
993         } else {
994                 if (c->enclosing != 0)
995                         return -ENXIO;
996
997                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
998                 if (!e)
999                         return -ENOMEM;
1000
1001                 nindex = e - c->signature;
1002         }
1003
1004         /* Align contents to 8 byte boundary */
1005         if (!message_extend_body(m, 8, 0)) {
1006                 if (e)
1007                         c->signature[c->index] = 0;
1008
1009                 return -ENOMEM;
1010         }
1011
1012         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1013                 c->index = nindex;
1014
1015         return 0;
1016 }
1017
1018 static int bus_message_open_dict_entry(
1019                 sd_bus_message *m,
1020                 struct bus_container *c,
1021                 const char *contents) {
1022
1023         size_t nindex;
1024
1025         assert(m);
1026         assert(c);
1027         assert(contents);
1028
1029         if (!signature_is_pair(contents))
1030                 return -EINVAL;
1031
1032         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1033                 return -ENXIO;
1034
1035         if (c->signature && c->signature[c->index]) {
1036                 size_t l;
1037
1038                 l = strlen(contents);
1039
1040                 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1041                     !startswith(c->signature + c->index + 1, contents) ||
1042                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1043                         return -ENXIO;
1044
1045                 nindex = c->index + 1 + l + 1;
1046         } else
1047                 return -ENXIO;
1048
1049         /* Align contents to 8 byte boundary */
1050         if (!message_extend_body(m, 8, 0))
1051                 return -ENOMEM;
1052
1053         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1054                 c->index = nindex;
1055
1056         return 0;
1057 }
1058
1059 int sd_bus_message_open_container(
1060                 sd_bus_message *m,
1061                 char type,
1062                 const char *contents) {
1063
1064         struct bus_container *c, *w;
1065         uint32_t *array_size = NULL;
1066         char *signature;
1067         int r;
1068
1069         if (!m)
1070                 return -EINVAL;
1071         if (m->sealed)
1072                 return -EPERM;
1073         if (!contents)
1074                 return -EINVAL;
1075
1076         /* Make sure we have space for one more container */
1077         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1078         if (!w)
1079                 return -ENOMEM;
1080         m->containers = w;
1081
1082         c = message_get_container(m);
1083
1084         signature = strdup(contents);
1085         if (!signature)
1086                 return -ENOMEM;
1087
1088         if (type == SD_BUS_TYPE_ARRAY)
1089                 r = bus_message_open_array(m, c, contents, &array_size);
1090         else if (type == SD_BUS_TYPE_VARIANT)
1091                 r = bus_message_open_variant(m, c, contents);
1092         else if (type == SD_BUS_TYPE_STRUCT)
1093                 r = bus_message_open_struct(m, c, contents);
1094         else if (type == SD_BUS_TYPE_DICT_ENTRY)
1095                 r = bus_message_open_dict_entry(m, c, contents);
1096         else
1097                 r = -EINVAL;
1098
1099         if (r < 0) {
1100                 free(signature);
1101                 return r;
1102         }
1103
1104         /* OK, let's fill it in */
1105         w += m->n_containers++;
1106         w->enclosing = type;
1107         w->signature = signature;
1108         w->index = 0;
1109         w->array_size = array_size;
1110         w->begin = 0;
1111
1112         return 0;
1113 }
1114
1115 int sd_bus_message_close_container(sd_bus_message *m) {
1116         struct bus_container *c;
1117
1118         if (!m)
1119                 return -EINVAL;
1120         if (m->sealed)
1121                 return -EPERM;
1122         if (m->n_containers <= 0)
1123                 return -EINVAL;
1124
1125         c = message_get_container(m);
1126         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1127                 if (c->signature && c->signature[c->index] != 0)
1128                         return -EINVAL;
1129
1130         free(c->signature);
1131         m->n_containers--;
1132
1133         return 0;
1134 }
1135
1136 static int message_append_ap(
1137                 sd_bus_message *m,
1138                 const char *types,
1139                 va_list ap) {
1140
1141         const char *t;
1142         int r;
1143
1144         assert(m);
1145         assert(types);
1146
1147         for (t = types; *t; t++) {
1148                 switch (*t) {
1149
1150                 case SD_BUS_TYPE_BYTE: {
1151                         uint8_t x;
1152
1153                         x = (uint8_t) va_arg(ap, int);
1154                         r = sd_bus_message_append_basic(m, *t, &x);
1155                         break;
1156                 }
1157
1158                 case SD_BUS_TYPE_BOOLEAN:
1159                 case SD_BUS_TYPE_INT32:
1160                 case SD_BUS_TYPE_UINT32:
1161                 case SD_BUS_TYPE_UNIX_FD: {
1162                         uint32_t x;
1163
1164                         /* We assume a boolean is the same as int32_t */
1165                         assert_cc(sizeof(int32_t) == sizeof(int));
1166
1167                         x = va_arg(ap, uint32_t);
1168                         r = sd_bus_message_append_basic(m, *t, &x);
1169                         break;
1170                 }
1171
1172                 case SD_BUS_TYPE_INT16:
1173                 case SD_BUS_TYPE_UINT16: {
1174                         uint16_t x;
1175
1176                         x = (uint16_t) va_arg(ap, int);
1177                         r = sd_bus_message_append_basic(m, *t, &x);
1178                         break;
1179                 }
1180
1181                 case SD_BUS_TYPE_INT64:
1182                 case SD_BUS_TYPE_UINT64:
1183                 case SD_BUS_TYPE_DOUBLE: {
1184                         uint64_t x;
1185
1186                         x = va_arg(ap, uint64_t);
1187                         r = sd_bus_message_append_basic(m, *t, &x);
1188                         break;
1189                 }
1190
1191                 case SD_BUS_TYPE_STRING:
1192                 case SD_BUS_TYPE_OBJECT_PATH:
1193                 case SD_BUS_TYPE_SIGNATURE: {
1194                         const char *x;
1195
1196                         x = va_arg(ap, const char*);
1197                         r = sd_bus_message_append_basic(m, *t, x);
1198                         break;
1199                 }
1200
1201                 case SD_BUS_TYPE_ARRAY: {
1202                         size_t k;
1203
1204                         r = signature_element_length(t + 1, &k);
1205                         if (r < 0)
1206                                 return r;
1207
1208                         {
1209                                 unsigned i, n;
1210                                 char s[k + 1];
1211
1212                                 memcpy(s, t + 1, k);
1213                                 s[k] = 0;
1214                                 t += k;
1215
1216                                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1217                                 if (r < 0)
1218                                         return r;
1219
1220                                 n = va_arg(ap, unsigned);
1221                                 for (i = 0; i < n; i++) {
1222                                         r = message_append_ap(m, s, ap);
1223                                         if (r < 0)
1224                                                 return r;
1225                                 }
1226
1227                                 r = sd_bus_message_close_container(m);
1228                         }
1229
1230                         break;
1231                 }
1232
1233                 case SD_BUS_TYPE_VARIANT: {
1234                         const char *s;
1235
1236                         s = va_arg(ap, const char*);
1237                         if (!s)
1238                                 return -EINVAL;
1239
1240                         r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1241                         if (r < 0)
1242                                 return r;
1243
1244                         r = message_append_ap(m, s, ap);
1245                         if (r < 0)
1246                                 return r;
1247
1248                         r = sd_bus_message_close_container(m);
1249                         break;
1250                 }
1251
1252                 case SD_BUS_TYPE_STRUCT_BEGIN:
1253                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1254                         size_t k;
1255
1256                         r = signature_element_length(t, &k);
1257                         if (r < 0)
1258                                 return r;
1259
1260                         {
1261                                 char s[k - 1];
1262
1263                                 memcpy(s, t + 1, k - 2);
1264                                 s[k - 2] = 0;
1265
1266                                 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1267                                 if (r < 0)
1268                                         return r;
1269
1270                                 t += k - 1;
1271
1272                                 r = message_append_ap(m, s, ap);
1273                                 if (r < 0)
1274                                         return r;
1275
1276                                 r = sd_bus_message_close_container(m);
1277                         }
1278
1279                         break;
1280                 }
1281
1282                 default:
1283                         r = -EINVAL;
1284                 }
1285
1286                 if (r < 0)
1287                         return r;
1288         }
1289
1290         return 0;
1291 }
1292
1293 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1294         va_list ap;
1295         int r;
1296
1297         if (!m)
1298                 return -EINVAL;
1299         if (m->sealed)
1300                 return -EPERM;
1301         if (!types)
1302                 return -EINVAL;
1303
1304         va_start(ap, types);
1305         r = message_append_ap(m, types, ap);
1306         va_end(ap);
1307
1308         return r;
1309 }
1310
1311 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1312         size_t k, start, n;
1313
1314         assert(rindex);
1315         assert(align > 0);
1316
1317         start = ALIGN_TO((size_t) *rindex, align);
1318         n = start + nbytes;
1319
1320         if (n > sz)
1321                 return -EBADMSG;
1322
1323         /* Verify that padding is 0 */
1324         for (k = *rindex; k < start; k++)
1325                 if (((const uint8_t*) p)[k] != 0)
1326                         return -EBADMSG;
1327
1328         if (r)
1329                 *r = (uint8_t*) p + start;
1330
1331         *rindex = n;
1332
1333         return 1;
1334 }
1335
1336 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1337         struct bus_container *c;
1338
1339         assert(m);
1340
1341         c = message_get_container(m);
1342         if (!c->array_size)
1343                 return false;
1344
1345         return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1346 }
1347
1348 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1349         assert(m);
1350         assert(rindex);
1351         assert(align > 0);
1352
1353         if (message_end_of_array(m, *rindex))
1354                 return 0;
1355
1356         return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1357 }
1358
1359 static bool validate_string(const char *s, size_t l) {
1360         assert(s);
1361
1362         /* Check for NUL chars in the string */
1363         if (memchr(s, 0, l))
1364                 return false;
1365
1366         /* Check for NUL termination */
1367         if (s[l] != 0)
1368                 return false;
1369
1370         /* Check if valid UTF8 */
1371         if (!utf8_is_valid(s))
1372                 return false;
1373
1374         return true;
1375 }
1376
1377 static bool validate_signature(const char *s, size_t l) {
1378         /* Check for NUL chars in the signature */
1379         if (memchr(s, 0, l))
1380                 return false;
1381
1382         /* Check for NUL termination */
1383         if (s[l] != 0)
1384                 return false;
1385
1386         /* Check if valid signature */
1387         if (!signature_is_valid(s, true))
1388                 return false;
1389
1390         return true;
1391 }
1392
1393 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1394         struct bus_container *c;
1395         int r;
1396         void *q;
1397
1398         if (!m)
1399                 return -EINVAL;
1400         if (!m->sealed)
1401                 return -EPERM;
1402         if (!bus_type_is_basic(type))
1403                 return -EINVAL;
1404
1405         c = message_get_container(m);
1406
1407         if (!c->signature || c->signature[c->index] == 0)
1408                 return 0;
1409
1410         if (c->signature[c->index] != type)
1411                 return -ENXIO;
1412
1413         switch (type) {
1414
1415         case SD_BUS_TYPE_STRING:
1416         case SD_BUS_TYPE_OBJECT_PATH: {
1417                 uint32_t l;
1418                 size_t rindex;
1419
1420                 rindex = m->rindex;
1421                 r = message_peek_body(m, &rindex, 4, 4, &q);
1422                 if (r <= 0)
1423                         return r;
1424
1425                 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1426                 r = message_peek_body(m, &rindex, 1, l+1, &q);
1427                 if (r < 0)
1428                         return r;
1429                 if (r == 0)
1430                         return -EBADMSG;
1431
1432                 if (!validate_string(q, l))
1433                         return -EBADMSG;
1434
1435                 m->rindex = rindex;
1436                 *(const char**) p = q;
1437                 break;
1438         }
1439
1440         case SD_BUS_TYPE_SIGNATURE: {
1441                 uint8_t l;
1442                 size_t rindex;
1443
1444                 rindex = m->rindex;
1445                 r = message_peek_body(m, &rindex, 1, 1, &q);
1446                 if (r <= 0)
1447                         return r;
1448
1449                 l = *(uint8_t*) q;
1450                 r = message_peek_body(m, &rindex, 1, l+1, &q);
1451                 if (r < 0)
1452                         return r;
1453                 if (r == 0)
1454                         return -EBADMSG;
1455
1456                 if (!validate_signature(q, l))
1457                         return -EBADMSG;
1458
1459                 m->rindex = rindex;
1460                 *(const char**) p = q;
1461                 break;
1462         }
1463
1464         default: {
1465                 size_t sz, align;
1466
1467                 align = bus_type_get_alignment(type);
1468                 sz = bus_type_get_size(type);
1469
1470                 r = message_peek_body(m, &m->rindex, align, sz, &q);
1471                 if (r <= 0)
1472                         return r;
1473
1474                 switch (type) {
1475
1476                 case SD_BUS_TYPE_BYTE:
1477                         *(uint8_t*) p = *(uint8_t*) q;
1478                         break;
1479
1480                 case SD_BUS_TYPE_BOOLEAN:
1481                         *(int*) p = !!*(uint32_t*) q;
1482                         break;
1483
1484                 case SD_BUS_TYPE_INT16:
1485                 case SD_BUS_TYPE_UINT16:
1486                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1487                         break;
1488
1489                 case SD_BUS_TYPE_INT32:
1490                 case SD_BUS_TYPE_UINT32:
1491                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1492                         break;
1493
1494                 case SD_BUS_TYPE_INT64:
1495                 case SD_BUS_TYPE_UINT64:
1496                 case SD_BUS_TYPE_DOUBLE:
1497                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1498                         break;
1499
1500                 default:
1501                         assert_not_reached("Unknown basic type...");
1502                 }
1503
1504                 break;
1505         }
1506         }
1507
1508         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1509                 c->index++;
1510
1511         return 1;
1512 }
1513
1514 static int bus_message_enter_array(
1515                 sd_bus_message *m,
1516                 struct bus_container *c,
1517                 const char *contents,
1518                 uint32_t **array_size) {
1519
1520         size_t rindex;
1521         void *q;
1522         int r, alignment;
1523
1524         assert(m);
1525         assert(c);
1526         assert(contents);
1527         assert(array_size);
1528
1529         if (!signature_is_single(contents))
1530                 return -EINVAL;
1531
1532         alignment = bus_type_get_alignment(contents[0]);
1533         if (alignment < 0)
1534                 return alignment;
1535
1536         if (!c->signature || c->signature[c->index] == 0)
1537                 return 0;
1538
1539         if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1540                 return -ENXIO;
1541
1542         if (!startswith(c->signature + c->index + 1, contents))
1543                 return -ENXIO;
1544
1545         rindex = m->rindex;
1546         r = message_peek_body(m, &rindex, 4, 4, &q);
1547         if (r <= 0)
1548                 return r;
1549
1550         if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > 67108864)
1551                 return -EBADMSG;
1552
1553         r = message_peek_body(m, &rindex, alignment, 0, NULL);
1554         if (r < 0)
1555                 return r;
1556         if (r == 0)
1557                 return -EBADMSG;
1558
1559         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1560                 c->index += 1 + strlen(contents);
1561
1562         m->rindex = rindex;
1563
1564         *array_size = (uint32_t*) q;
1565
1566         return 1;
1567 }
1568
1569 static int bus_message_enter_variant(
1570                 sd_bus_message *m,
1571                 struct bus_container *c,
1572                 const char *contents) {
1573
1574         size_t rindex;
1575         uint8_t l;
1576         void *q;
1577         int r;
1578
1579         assert(m);
1580         assert(c);
1581         assert(contents);
1582
1583         if (!signature_is_single(contents))
1584                 return -EINVAL;
1585
1586         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1587                 return -EINVAL;
1588
1589         if (!c->signature || c->signature[c->index] == 0)
1590                 return 0;
1591
1592         if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1593                 return -ENXIO;
1594
1595         rindex = m->rindex;
1596         r = message_peek_body(m, &rindex, 1, 1, &q);
1597         if (r <= 0)
1598                 return r;
1599
1600         l = *(uint8_t*) q;
1601         r = message_peek_body(m, &rindex, 1, l+1, &q);
1602         if (r < 0)
1603                 return r;
1604         if (r == 0)
1605                 return -EBADMSG;
1606
1607         if (!validate_signature(q, l))
1608                 return -EBADMSG;
1609
1610         if (!streq(q, contents))
1611                 return -ENXIO;
1612
1613         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1614                 c->index++;
1615
1616         m->rindex = rindex;
1617
1618         return 1;
1619 }
1620
1621 static int bus_message_enter_struct(
1622                 sd_bus_message *m,
1623                 struct bus_container *c,
1624                 const char *contents) {
1625
1626         size_t l;
1627         int r;
1628
1629         assert(m);
1630         assert(c);
1631         assert(contents);
1632
1633         if (!signature_is_valid(contents, false))
1634                 return -EINVAL;
1635
1636         if (!c->signature || c->signature[c->index] == 0)
1637                 return 0;
1638
1639         l = strlen(contents);
1640
1641         if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1642             !startswith(c->signature + c->index + 1, contents) ||
1643             c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1644                 return -ENXIO;
1645
1646         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1647         if (r <= 0)
1648                 return r;
1649
1650         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1651                 c->index += 1 + l + 1;
1652
1653         return 1;
1654 }
1655
1656 static int bus_message_enter_dict_entry(
1657                 sd_bus_message *m,
1658                 struct bus_container *c,
1659                 const char *contents) {
1660
1661         size_t l;
1662         int r;
1663
1664         assert(m);
1665         assert(c);
1666         assert(contents);
1667
1668         if (!signature_is_pair(contents))
1669                 return -EINVAL;
1670
1671         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1672                 return -ENXIO;
1673
1674         if (!c->signature || c->signature[c->index] == 0)
1675                 return 0;
1676
1677         l = strlen(contents);
1678
1679         if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1680             !startswith(c->signature + c->index + 1, contents) ||
1681             c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1682                 return -ENXIO;
1683
1684         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1685         if (r <= 0)
1686                 return r;
1687
1688         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1689                 c->index += 1 + l + 1;
1690
1691         return 1;
1692 }
1693
1694 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
1695         struct bus_container *c, *w;
1696         uint32_t *array_size = NULL;
1697         char *signature;
1698         int r;
1699
1700         if (!m)
1701                 return -EINVAL;
1702         if (!m->sealed)
1703                 return -EPERM;
1704         if (!contents)
1705                 return -EINVAL;
1706
1707         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1708         if (!w)
1709                 return -ENOMEM;
1710         m->containers = w;
1711
1712         c = message_get_container(m);
1713
1714         if (!c->signature || c->signature[c->index] == 0)
1715                 return 0;
1716
1717         signature = strdup(contents);
1718         if (!signature)
1719                 return -ENOMEM;
1720
1721         if (type == SD_BUS_TYPE_ARRAY)
1722                 r = bus_message_enter_array(m, c, contents, &array_size);
1723         else if (type == SD_BUS_TYPE_VARIANT)
1724                 r = bus_message_enter_variant(m, c, contents);
1725         else if (type == SD_BUS_TYPE_STRUCT)
1726                 r = bus_message_enter_struct(m, c, contents);
1727         else if (type == SD_BUS_TYPE_DICT_ENTRY)
1728                 r = bus_message_enter_dict_entry(m, c, contents);
1729         else
1730                 r = -EINVAL;
1731
1732         if (r <= 0) {
1733                 free(signature);
1734                 return r;
1735         }
1736
1737         /* OK, let's fill it in */
1738         w += m->n_containers++;
1739         w->enclosing = type;
1740         w->signature = signature;
1741         w->index = 0;
1742         w->array_size = array_size;
1743         w->begin = m->rindex;
1744
1745         return 1;
1746 }
1747
1748 int sd_bus_message_exit_container(sd_bus_message *m) {
1749         struct bus_container *c;
1750
1751         if (!m)
1752                 return -EINVAL;
1753         if (!m->sealed)
1754                 return -EPERM;
1755         if (m->n_containers <= 0)
1756                 return -EINVAL;
1757
1758         c = message_get_container(m);
1759         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
1760                 uint32_t l;
1761
1762                 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
1763                 if (c->begin + l != m->rindex)
1764                         return -EBUSY;
1765
1766         } else {
1767                 if (c->signature && c->signature[c->index] != 0)
1768                         return -EINVAL;
1769         }
1770
1771         free(c->signature);
1772         m->n_containers--;
1773
1774         return 1;
1775 }
1776
1777 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
1778         struct bus_container *c;
1779         int r;
1780
1781         if (!m)
1782                 return -EINVAL;
1783         if (!m->sealed)
1784                 return -EPERM;
1785
1786         c = message_get_container(m);
1787
1788         if (!c->signature || c->signature[c->index] == 0)
1789                 goto eof;
1790
1791         if (message_end_of_array(m, m->rindex))
1792                 goto eof;
1793
1794         if (bus_type_is_basic(c->signature[c->index])) {
1795                 if (contents)
1796                         *contents = NULL;
1797                 if (type)
1798                         *type = c->signature[c->index];
1799                 return 1;
1800         }
1801
1802         if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
1803
1804                 if (contents) {
1805                         size_t l;
1806                         char *sig;
1807
1808                         r = signature_element_length(c->signature+c->index+1, &l);
1809                         if (r < 0)
1810                                 return r;
1811
1812                         assert(l >= 1);
1813
1814                         sig = strndup(c->signature + c->index + 1, l);
1815                         if (!sig)
1816                                 return -ENOMEM;
1817
1818                         free(m->peeked_signature);
1819                         m->peeked_signature = sig;
1820
1821                         *contents = sig;
1822                 }
1823
1824                 if (type)
1825                         *type = SD_BUS_TYPE_ARRAY;
1826
1827                 return 1;
1828         }
1829
1830         if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
1831             c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
1832
1833                 if (contents) {
1834                         size_t l;
1835                         char *sig;
1836
1837                         r = signature_element_length(c->signature+c->index, &l);
1838                         if (r < 0)
1839                                 return r;
1840
1841                         assert(l >= 2);
1842                         sig = strndup(c->signature + c->index + 1, l - 2);
1843                         if (!sig)
1844                                 return -ENOMEM;
1845
1846                         free(m->peeked_signature);
1847                         m->peeked_signature = sig;
1848
1849                         *contents = sig;
1850                 }
1851
1852                 if (type)
1853                         *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
1854
1855                 return 1;
1856         }
1857
1858         if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
1859                 if (contents) {
1860                         size_t rindex, l;
1861                         void *q;
1862
1863                         rindex = m->rindex;
1864                         r = message_peek_body(m, &rindex, 1, 1, &q);
1865                         if (r < 0)
1866                                 return r;
1867                         if (r == 0)
1868                                 goto eof;
1869
1870                         l = *(uint8_t*) q;
1871                         r = message_peek_body(m, &rindex, 1, l+1, &q);
1872                         if (r < 0)
1873                                 return r;
1874                         if (r == 0)
1875                                 return -EBADMSG;
1876
1877                         if (!validate_signature(q, l))
1878                                 return -EBADMSG;
1879
1880                         *contents = q;
1881                 }
1882
1883                 if (type)
1884                         *type = SD_BUS_TYPE_VARIANT;
1885
1886                 return 1;
1887         }
1888
1889         return -EINVAL;
1890
1891 eof:
1892         if (type)
1893                 *type = c->enclosing;
1894         if (contents)
1895                 *contents = NULL;
1896         return 0;
1897 }
1898
1899 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
1900         struct bus_container *c;
1901
1902         if (!m)
1903                 return -EINVAL;
1904         if (!m->sealed)
1905                 return -EPERM;
1906
1907         if (complete) {
1908                 reset_containers(m);
1909                 m->rindex = 0;
1910                 m->root_container.index = 0;
1911
1912                 c = message_get_container(m);
1913         } else {
1914                 c = message_get_container(m);
1915
1916                 c->index = 0;
1917                 m->rindex = c->begin;
1918         }
1919
1920         return !isempty(c->signature);
1921 }
1922
1923 static int message_read_ap(sd_bus_message *m, const char *types, va_list ap) {
1924         const char *t;
1925         int r;
1926
1927         assert(m);
1928         assert(types);
1929
1930         for (t = types; *t; t++) {
1931                 switch (*t) {
1932
1933                 case SD_BUS_TYPE_BYTE:
1934                 case SD_BUS_TYPE_BOOLEAN:
1935                 case SD_BUS_TYPE_INT16:
1936                 case SD_BUS_TYPE_UINT16:
1937                 case SD_BUS_TYPE_INT32:
1938                 case SD_BUS_TYPE_UINT32:
1939                 case SD_BUS_TYPE_INT64:
1940                 case SD_BUS_TYPE_UINT64:
1941                 case SD_BUS_TYPE_DOUBLE:
1942                 case SD_BUS_TYPE_STRING:
1943                 case SD_BUS_TYPE_OBJECT_PATH:
1944                 case SD_BUS_TYPE_SIGNATURE: {
1945                         void *p;
1946
1947                         p = va_arg(ap, void*);
1948                         r = sd_bus_message_read_basic(m, *t, p);
1949                         break;
1950                 }
1951
1952                 case SD_BUS_TYPE_ARRAY: {
1953                         size_t k;
1954
1955                         r = signature_element_length(t + 1, &k);
1956                         if (r < 0)
1957                                 return r;
1958
1959                         {
1960                                 unsigned i, n;
1961                                 char s[k + 1];
1962
1963                                 memcpy(s, t + 1, k);
1964                                 s[k] = 0;
1965                                 t += k;
1966
1967                                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
1968                                 if (r < 0)
1969                                         return r;
1970                                 if (r == 0)
1971                                         return -ENXIO;
1972
1973                                 n = va_arg(ap, unsigned);
1974                                 for (i = 0; i < n; i++) {
1975                                         r = message_read_ap(m, s, ap);
1976                                         if (r < 0)
1977                                                 return r;
1978                                 }
1979
1980                                 r = sd_bus_message_exit_container(m);
1981                         }
1982
1983                         break;
1984                 }
1985
1986                 case SD_BUS_TYPE_VARIANT: {
1987                         const char *s;
1988
1989                         s = va_arg(ap, const char *);
1990                         if (!s)
1991                                 return -EINVAL;
1992
1993                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
1994                         if (r < 0)
1995                                 return r;
1996                         if (r == 0)
1997                                 return -ENXIO;
1998
1999                         r = message_read_ap(m, s, ap);
2000                         if (r < 0)
2001                                 return r;
2002                         if (r == 0)
2003                                 return -ENXIO;
2004
2005                         r = sd_bus_message_exit_container(m);
2006                         break;
2007                 }
2008
2009                 case SD_BUS_TYPE_STRUCT_BEGIN:
2010                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2011                         size_t k;
2012
2013                         r = signature_element_length(t, &k);
2014                         if (r < 0)
2015                                 return r;
2016
2017                         {
2018                                 char s[k - 1];
2019                                 memcpy(s, t + 1, k - 2);
2020                                 s[k - 2] = 0;
2021
2022                                 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2023                                 if (r < 0)
2024                                         return r;
2025                                 if (r == 0)
2026                                         return -ENXIO;
2027
2028                                 t += k - 1;
2029
2030                                 r = message_read_ap(m, s, ap);
2031                                 if (r < 0)
2032                                         return r;
2033                                 if (r == 0)
2034                                         return -ENXIO;
2035
2036                                 r = sd_bus_message_exit_container(m);
2037                         }
2038
2039                         break;
2040                 }
2041
2042                 default:
2043                         r = -EINVAL;
2044                 }
2045
2046                 if (r < 0)
2047                         return r;
2048                 if (r == 0)
2049                         return -ENXIO;
2050         }
2051
2052         return 1;
2053 }
2054
2055 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2056         va_list ap;
2057         int r;
2058
2059         if (!m)
2060                 return -EINVAL;
2061         if (!m->sealed)
2062                 return -EPERM;
2063         if (!types)
2064                 return -EINVAL;
2065
2066         va_start(ap, types);
2067         r = message_read_ap(m, types, ap);
2068         va_end(ap);
2069
2070         return r;
2071 }
2072
2073 static int message_peek_fields(
2074                 sd_bus_message *m,
2075                 size_t *rindex,
2076                 size_t align,
2077                 size_t nbytes,
2078                 void **ret) {
2079
2080         assert(m);
2081         assert(rindex);
2082         assert(align > 0);
2083
2084         return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2085 }
2086
2087 static int message_peek_field_string(
2088                 sd_bus_message *m,
2089                 size_t *ri,
2090                 const char **ret) {
2091
2092         size_t l;
2093         int r;
2094         void *q;
2095
2096         assert(m);
2097         assert(ri);
2098
2099         r = message_peek_fields(m, ri, 4, 4, &q);
2100         if (r < 0)
2101                 return r;
2102
2103         l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2104         r = message_peek_fields(m, ri, 1, l+1, &q);
2105         if (r < 0)
2106                 return r;
2107
2108         if (!validate_string(q, l))
2109                 return -EBADMSG;
2110
2111         if (ret)
2112                 *ret = q;
2113
2114         return 0;
2115 }
2116
2117 static int message_peek_field_signature(
2118                 sd_bus_message *m,
2119                 size_t *ri,
2120                 const char **ret) {
2121
2122         size_t l;
2123         int r;
2124         void *q;
2125
2126         assert(m);
2127         assert(ri);
2128
2129         r = message_peek_fields(m, ri, 1, 1, &q);
2130         if (r < 0)
2131                 return r;
2132
2133         l = *(uint8_t*) q;
2134         r = message_peek_fields(m, ri, 1, l+1, &q);
2135         if (r < 0)
2136                 return r;
2137
2138         if (!validate_signature(q, l))
2139                 return -EBADMSG;
2140
2141         if (ret)
2142                 *ret = q;
2143
2144         return 0;
2145 }
2146
2147 static int message_peek_field_uint32(
2148                 sd_bus_message *m,
2149                 size_t *ri,
2150                 uint32_t *ret) {
2151
2152         int r;
2153         void *q;
2154
2155         assert(m);
2156         assert(ri);
2157
2158         r = message_peek_fields(m, ri, 4, 4, &q);
2159         if (r < 0)
2160                 return r;
2161
2162         if (ret)
2163                 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2164
2165         return 0;
2166 }
2167
2168 static int message_skip_fields(
2169                 sd_bus_message *m,
2170                 size_t *ri,
2171                 uint32_t array_size,
2172                 const char **signature) {
2173
2174         size_t original_index;
2175         int r;
2176
2177         assert(m);
2178         assert(ri);
2179         assert(signature);
2180
2181         original_index = *ri;
2182
2183         for (;;) {
2184                 char t;
2185                 void *q;
2186                 size_t l;
2187
2188                 if (array_size != (uint32_t) -1 &&
2189                     array_size <= *ri - original_index)
2190                         return 0;
2191
2192                 t = **signature;
2193                 if (!t)
2194                         return 0;
2195
2196                 if (t == SD_BUS_TYPE_STRING ||
2197                     t == SD_BUS_TYPE_OBJECT_PATH) {
2198
2199                         r = message_peek_field_string(m, ri, NULL);
2200                         if (r < 0)
2201                                 return r;
2202
2203                         (*signature)++;
2204
2205                 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2206
2207                         r = message_peek_field_signature(m, ri, NULL);
2208                         if (r < 0)
2209                                 return r;
2210
2211                         (*signature)++;
2212
2213                 } else if (bus_type_is_basic(t)) {
2214                         size_t align, k;
2215
2216                         align = bus_type_get_alignment(t);
2217                         k = bus_type_get_size(t);
2218
2219                         r = message_peek_fields(m, ri, align, k, NULL);
2220                         if (r < 0)
2221                                 return r;
2222
2223                         (*signature)++;
2224
2225                 } else if (t == SD_BUS_TYPE_ARRAY) {
2226
2227                         r = signature_element_length(*signature+1, &l);
2228                         if (r < 0)
2229                                 return r;
2230
2231                         assert(l >= 1);
2232                         {
2233                                 char sig[l-1], *s;
2234                                 size_t nas;
2235                                 int alignment;
2236
2237                                 strncpy(sig, *signature + 1, l-1);
2238                                 s = sig;
2239
2240                                 alignment = bus_type_get_alignment(sig[0]);
2241                                 if (alignment < 0)
2242                                         return alignment;
2243
2244                                 r = message_peek_fields(m, ri, 4, 4, &q);
2245                                 if (r < 0)
2246                                         return r;
2247
2248                                 nas = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2249                                 if (nas > 67108864)
2250                                         return -EBADMSG;
2251
2252                                 r = message_peek_fields(m, ri, alignment, 0, NULL);
2253                                 if (r < 0)
2254                                         return r;
2255
2256                                 r = message_skip_fields(m, ri, nas, (const char**) &s);
2257                                 if (r < 0)
2258                                         return r;
2259                         }
2260
2261                         (*signature) += 1 + l;
2262
2263                 } else if (t == SD_BUS_TYPE_VARIANT) {
2264                         const char *s;
2265
2266                         r = message_peek_field_signature(m, ri, &s);
2267                         if (r < 0)
2268                                 return r;
2269
2270                         r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2271                         if (r < 0)
2272                                 return r;
2273
2274                         (*signature)++;
2275
2276                 } else if (t == SD_BUS_TYPE_STRUCT ||
2277                            t == SD_BUS_TYPE_DICT_ENTRY) {
2278
2279                         r = signature_element_length(*signature, &l);
2280                         if (r < 0)
2281                                 return r;
2282
2283                         assert(l >= 2);
2284                         {
2285                                 char sig[l-1], *s;
2286                                 strncpy(sig, *signature + 1, l-1);
2287                                 s = sig;
2288
2289                                 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2290                                 if (r < 0)
2291                                         return r;
2292                         }
2293
2294                         *signature += l;
2295                 } else
2296                         return -EINVAL;
2297         }
2298 }
2299
2300 static int message_parse_fields(sd_bus_message *m) {
2301         size_t ri;
2302         int r;
2303
2304         assert(m);
2305
2306         for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2307                 const char *signature;
2308                 uint8_t *header;
2309
2310                 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2311                 if (r < 0)
2312                         return r;
2313
2314                 r = message_peek_field_signature(m, &ri, &signature);
2315                 if (r < 0)
2316                         return r;
2317
2318                 switch (*header) {
2319                 case _SD_BUS_MESSAGE_HEADER_INVALID:
2320                         return -EBADMSG;
2321
2322                 case SD_BUS_MESSAGE_HEADER_PATH:
2323                         if (!streq(signature, "o"))
2324                                 return -EBADMSG;
2325
2326                         r = message_peek_field_string(m, &ri, &m->path);
2327                         break;
2328
2329                 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2330                         if (!streq(signature, "s"))
2331                                 return -EBADMSG;
2332
2333                         r = message_peek_field_string(m, &ri, &m->interface);
2334                         break;
2335
2336                 case SD_BUS_MESSAGE_HEADER_MEMBER:
2337                         if (!streq(signature, "s"))
2338                                 return -EBADMSG;
2339
2340                         r = message_peek_field_string(m, &ri, &m->member);
2341                         break;
2342
2343                 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2344                         if (!streq(signature, "s"))
2345                                 return -EBADMSG;
2346
2347                         r = message_peek_field_string(m, &ri, &m->error.name);
2348                         break;
2349
2350                 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2351                         if (!streq(signature, "s"))
2352                                 return -EBADMSG;
2353
2354                         r = message_peek_field_string(m, &ri, &m->destination);
2355                         break;
2356
2357                 case SD_BUS_MESSAGE_HEADER_SENDER:
2358                         if (!streq(signature, "s"))
2359                                 return -EBADMSG;
2360
2361                         r = message_peek_field_string(m, &ri, &m->sender);
2362                         break;
2363
2364
2365                 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2366                         const char *s;
2367                         char *c;
2368
2369                         if (!streq(signature, "g"))
2370                                 return -EBADMSG;
2371
2372                         r = message_peek_field_signature(m, &ri, &s);
2373                         if (r < 0)
2374                                 return r;
2375
2376                         c = strdup(s);
2377                         if (!c)
2378                                 return -ENOMEM;
2379
2380                         free(m->root_container.signature);
2381                         m->root_container.signature = c;
2382
2383                         r = 0;
2384                         break;
2385                 }
2386
2387                 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2388                         if (!streq(signature, "u"))
2389                                 return -EBADMSG;
2390
2391                         r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2392                         break;
2393
2394                 default:
2395                         r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2396                 }
2397
2398                 if (r < 0)
2399                         return r;
2400         }
2401
2402         if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2403                 return -EBADMSG;
2404
2405         switch (m->header->type) {
2406
2407         case SD_BUS_MESSAGE_TYPE_SIGNAL:
2408                 if (!m->path || !m->interface || !m->member)
2409                         return -EBADMSG;
2410                 break;
2411
2412         case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2413
2414                 if (!m->path || !m->member)
2415                         return -EBADMSG;
2416
2417                 break;
2418
2419         case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2420
2421                 if (m->reply_serial == 0)
2422                         return -EBADMSG;
2423                 break;
2424
2425         case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2426
2427                 if (m->reply_serial == 0 || !m->error.name)
2428                         return -EBADMSG;
2429                 break;
2430         }
2431
2432         /* Try to read the error message, but if we can't it's a non-issue */
2433         if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
2434                 sd_bus_message_read(m, "s", &m->error.message);
2435
2436         return 0;
2437 }
2438
2439 static void setup_iovec(sd_bus_message *m) {
2440         assert(m);
2441         assert(m->sealed);
2442
2443         m->n_iovec = 0;
2444
2445         m->iovec[m->n_iovec].iov_base = m->header;
2446         m->iovec[m->n_iovec].iov_len = sizeof(*m->header);
2447         m->n_iovec++;
2448
2449         if (m->fields) {
2450                 m->iovec[m->n_iovec].iov_base = m->fields;
2451                 m->iovec[m->n_iovec].iov_len = m->header->fields_size;
2452                 m->n_iovec++;
2453
2454                 if (m->header->fields_size % 8 != 0) {
2455                         static const uint8_t padding[7] = { 0, 0, 0, 0, 0, 0, 0 };
2456
2457                         m->iovec[m->n_iovec].iov_base = (void*) padding;
2458                         m->iovec[m->n_iovec].iov_len = 8 - m->header->fields_size % 8;
2459                         m->n_iovec++;
2460                 }
2461         }
2462
2463         if (m->body) {
2464                 m->iovec[m->n_iovec].iov_base = m->body;
2465                 m->iovec[m->n_iovec].iov_len = m->header->body_size;
2466                 m->n_iovec++;
2467         }
2468 }
2469
2470 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2471         int r;
2472
2473         assert(m);
2474
2475         if (m->sealed)
2476                 return -EPERM;
2477
2478         if (m->n_containers > 0)
2479                 return -EBADMSG;
2480
2481         /* If there's a non-trivial signature set, then add it in here */
2482         if (!isempty(m->root_container.signature)) {
2483                 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2484                 if (r < 0)
2485                         return r;
2486         }
2487
2488         if (m->n_fds > 0) {
2489                 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2490                 if (r < 0)
2491                         return r;
2492         }
2493
2494         m->header->serial = serial;
2495         m->sealed = true;
2496
2497         setup_iovec(m);
2498
2499         return 0;
2500 }
2501
2502 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2503         if (!m)
2504                 return -EINVAL;
2505         if (!destination)
2506                 return -EINVAL;
2507         if (m->sealed)
2508                 return -EPERM;
2509         if (m->destination)
2510                 return -EEXIST;
2511
2512         return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2513 }
2514
2515 int bus_message_dump(sd_bus_message *m) {
2516         unsigned level = 1;
2517         int r;
2518
2519         assert(m);
2520
2521         printf("Message %p\n"
2522                "\tn_ref=%u\n"
2523                "\tendian=%c\n"
2524                "\ttype=%i\n"
2525                "\tflags=%u\n"
2526                "\tversion=%u\n"
2527                "\tserial=%u\n"
2528                "\tfields_size=%u\n"
2529                "\tbody_size=%u\n"
2530                "\tpath=%s\n"
2531                "\tinterface=%s\n"
2532                "\tmember=%s\n"
2533                "\tdestination=%s\n"
2534                "\tsender=%s\n"
2535                "\tsignature=%s\n"
2536                "\treply_serial=%u\n"
2537                "\terror.name=%s\n"
2538                "\terror.message=%s\n"
2539                "\tsealed=%s\n",
2540                m,
2541                m->n_ref,
2542                m->header->endian,
2543                m->header->type,
2544                m->header->flags,
2545                m->header->version,
2546                BUS_MESSAGE_SERIAL(m),
2547                BUS_MESSAGE_FIELDS_SIZE(m),
2548                BUS_MESSAGE_BODY_SIZE(m),
2549                strna(m->path),
2550                strna(m->interface),
2551                strna(m->member),
2552                strna(m->destination),
2553                strna(m->sender),
2554                strna(m->root_container.signature),
2555                m->reply_serial,
2556                strna(m->error.name),
2557                strna(m->error.message),
2558                yes_no(m->sealed));
2559
2560         r = sd_bus_message_rewind(m, true);
2561         if (r < 0) {
2562                 log_error("Failed to rewind: %s", strerror(-r));
2563                 return r;
2564         }
2565
2566         printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
2567
2568         for(;;) {
2569                 _cleanup_free_ char *prefix = NULL;
2570                 const char *contents = NULL;
2571                 char type;
2572                 union {
2573                         uint8_t u8;
2574                         uint16_t u16;
2575                         int16_t s16;
2576                         uint32_t u32;
2577                         int32_t s32;
2578                         uint64_t u64;
2579                         int64_t s64;
2580                         double d64;
2581                         const char *string;
2582                         int i;
2583                 } basic;
2584
2585                 r = sd_bus_message_peek_type(m, &type, &contents);
2586                 if (r < 0) {
2587                         log_error("Failed to peek type: %s", strerror(-r));
2588                         return r;
2589                 }
2590                 if (r == 0) {
2591                         if (level <= 1)
2592                                 break;
2593
2594                         r = sd_bus_message_exit_container(m);
2595                         if (r < 0) {
2596                                 log_error("Failed to exit container: %s", strerror(-r));
2597                                 return r;
2598                         }
2599
2600                         level--;
2601
2602                         prefix = strrep("\t", level);
2603                         if (!prefix)
2604                                 return log_oom();
2605
2606                         if (type == SD_BUS_TYPE_ARRAY)
2607                                 printf("%s} END_ARRAY \n", prefix);
2608                         else if (type == SD_BUS_TYPE_VARIANT)
2609                                 printf("%s} END_VARIANT\n", prefix);
2610                         else if (type == SD_BUS_TYPE_STRUCT)
2611                                 printf("%s} END_STRUCT\n", prefix);
2612                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
2613                                 printf("%s} END_DICT_ENTRY\n", prefix);
2614
2615                         continue;
2616                 }
2617
2618                 prefix = strrep("\t", level);
2619                 if (!prefix)
2620                         return log_oom();
2621
2622                 if (bus_type_is_container(type) > 0) {
2623                         r = sd_bus_message_enter_container(m, type, contents);
2624                         if (r < 0) {
2625                                 log_error("Failed to enter container: %s", strerror(-r));
2626                                 return r;
2627                         }
2628
2629                         if (type == SD_BUS_TYPE_ARRAY)
2630                                 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
2631                         else if (type == SD_BUS_TYPE_VARIANT)
2632                                 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
2633                         else if (type == SD_BUS_TYPE_STRUCT)
2634                                 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
2635                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
2636                                 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
2637
2638                         level ++;
2639
2640                         continue;
2641                 }
2642
2643                 r = sd_bus_message_read_basic(m, type, &basic);
2644                 if (r < 0) {
2645                         log_error("Failed to get basic: %s", strerror(-r));
2646                         return r;
2647                 }
2648
2649                 switch (type) {
2650
2651                 case SD_BUS_TYPE_BYTE:
2652                         printf("%sBYTE: %u\n", prefix, basic.u8);
2653                         break;
2654
2655                 case SD_BUS_TYPE_BOOLEAN:
2656                         printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
2657                         break;
2658
2659                 case SD_BUS_TYPE_INT16:
2660                         printf("%sINT16: %i\n", prefix, basic.s16);
2661                         break;
2662
2663                 case SD_BUS_TYPE_UINT16:
2664                         printf("%sUINT16: %u\n", prefix, basic.u16);
2665                         break;
2666
2667                 case SD_BUS_TYPE_INT32:
2668                         printf("%sINT32: %i\n", prefix, basic.s32);
2669                         break;
2670
2671                 case SD_BUS_TYPE_UINT32:
2672                         printf("%sUINT32: %u\n", prefix, basic.u32);
2673                         break;
2674
2675                 case SD_BUS_TYPE_INT64:
2676                         printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
2677                         break;
2678
2679                 case SD_BUS_TYPE_UINT64:
2680                         printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
2681                         break;
2682
2683                 case SD_BUS_TYPE_DOUBLE:
2684                         printf("%sDOUBLE: %g\n", prefix, basic.d64);
2685                         break;
2686
2687                 case SD_BUS_TYPE_STRING:
2688                         printf("%sSTRING: \"%s\"\n", prefix, basic.string);
2689                         break;
2690
2691                 case SD_BUS_TYPE_OBJECT_PATH:
2692                         printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
2693                         break;
2694
2695                 case SD_BUS_TYPE_SIGNATURE:
2696                         printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
2697                         break;
2698
2699                 case SD_BUS_TYPE_UNIX_FD:
2700                         printf("%sUNIX_FD: %i\n", prefix, basic.i);
2701                         break;
2702
2703                 default:
2704                         assert_not_reached("Unknown basic type.");
2705                 }
2706         }
2707
2708         printf("} END_MESSAGE\n");
2709         return 0;
2710 }
2711
2712 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
2713         size_t total;
2714         unsigned i;
2715         void *p, *e;
2716
2717         assert(m);
2718         assert(buffer);
2719         assert(sz);
2720
2721         for (i = 0, total = 0; i < m->n_iovec; i++)
2722                 total += m->iovec[i].iov_len;
2723
2724         p = malloc(total);
2725         if (!p)
2726                 return -ENOMEM;
2727
2728         for (i = 0, e = p; i < m->n_iovec; i++)
2729                 e = mempcpy(e, m->iovec[i].iov_base, m->iovec[i].iov_len);
2730
2731         *buffer = p;
2732         *sz = total;
2733
2734         return 0;
2735 }
2736
2737 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
2738         int r;
2739
2740         assert(m);
2741         assert(l);
2742
2743         r = sd_bus_message_enter_container(m, 'a', "s");
2744         if (r < 0)
2745                 return r;
2746
2747         for (;;) {
2748                 const char *s;
2749
2750                 r = sd_bus_message_read_basic(m, 's', &s);
2751                 if (r < 0)
2752                         return r;
2753                 if (r == 0)
2754                         break;
2755
2756                 r = strv_extend(l, s);
2757                 if (r < 0)
2758                         return r;
2759         }
2760
2761         r = sd_bus_message_exit_container(m);
2762         if (r < 0)
2763                 return r;
2764
2765         return 0;
2766 }