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