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