chiark / gitweb /
547fd5f8c075fe40290419710674442a55cbf81b
[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 #include <fcntl.h>
24 #include <sys/mman.h>
25
26 #include "util.h"
27 #include "utf8.h"
28 #include "strv.h"
29 #include "time-util.h"
30 #include "cgroup-util.h"
31
32 #include "sd-bus.h"
33 #include "bus-message.h"
34 #include "bus-internal.h"
35 #include "bus-type.h"
36 #include "bus-signature.h"
37 #include "bus-gvariant.h"
38
39 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
40
41 static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
42
43         if (p == NULL)
44                 return NULL;
45
46         if (old_base == new_base)
47                 return (void*) p;
48
49         if ((uint8_t*) p < (uint8_t*) old_base)
50                 return (void*) p;
51
52         if ((uint8_t*) p >= (uint8_t*) old_base + sz)
53                 return (void*) p;
54
55         return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base);
56 }
57
58 static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
59         assert(m);
60         assert(part);
61
62         if (part->memfd >= 0) {
63                 /* If we can reuse the memfd, try that. For that it
64                  * can't be sealed yet. */
65
66                 if (!part->sealed)
67                         bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped);
68                 else {
69                         if (part->mapped > 0)
70                                 assert_se(munmap(part->data, part->mapped) == 0);
71
72                         close_nointr_nofail(part->memfd);
73                 }
74
75         } else if (part->munmap_this)
76                 munmap(part->data, part->mapped);
77         else if (part->free_this)
78                 free(part->data);
79
80         if (part != &m->body)
81                 free(part);
82 }
83
84 static void message_reset_parts(sd_bus_message *m) {
85         struct bus_body_part *part;
86
87         assert(m);
88
89         part = &m->body;
90         while (m->n_body_parts > 0) {
91                 struct bus_body_part *next = part->next;
92                 message_free_part(m, part);
93                 part = next;
94                 m->n_body_parts--;
95         }
96
97         m->body_end = NULL;
98
99         m->cached_rindex_part = NULL;
100         m->cached_rindex_part_begin = 0;
101 }
102
103 static void message_reset_containers(sd_bus_message *m) {
104         unsigned i;
105
106         assert(m);
107
108         for (i = 0; i < m->n_containers; i++) {
109                 free(m->containers[i].signature);
110                 free(m->containers[i].offsets);
111         }
112
113         free(m->containers);
114         m->containers = NULL;
115
116         m->n_containers = 0;
117         m->root_container.index = 0;
118 }
119
120 static void message_free(sd_bus_message *m) {
121         assert(m);
122
123         if (m->free_header)
124                 free(m->header);
125
126         message_reset_parts(m);
127
128         if (m->free_kdbus)
129                 free(m->kdbus);
130
131         if (m->release_kdbus) {
132                 uint64_t off;
133
134                 off = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
135                 ioctl(m->bus->input_fd, KDBUS_CMD_FREE, &off);
136         }
137
138         if (m->bus)
139                 sd_bus_unref(m->bus);
140
141         if (m->free_fds) {
142                 close_many(m->fds, m->n_fds);
143                 free(m->fds);
144         }
145
146         if (m->iovec != m->iovec_fixed)
147                 free(m->iovec);
148
149         message_reset_containers(m);
150         free(m->root_container.signature);
151         free(m->root_container.offsets);
152
153         free(m->peeked_signature);
154
155         bus_creds_done(&m->creds);
156         free(m);
157 }
158
159 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
160         void *op, *np;
161         size_t old_size, new_size, start;
162
163         assert(m);
164
165         if (m->poisoned)
166                 return NULL;
167
168         old_size = sizeof(struct bus_header) + m->header->fields_size;
169         start = ALIGN_TO(old_size, align);
170         new_size = start + sz;
171
172         if (old_size == new_size)
173                 return (uint8_t*) m->header + old_size;
174
175         if (new_size > (size_t) ((uint32_t) -1))
176                 goto poison;
177
178         if (m->free_header) {
179                 np = realloc(m->header, ALIGN8(new_size));
180                 if (!np)
181                         goto poison;
182         } else {
183                 /* Initially, the header is allocated as part of of
184                  * the sd_bus_message itself, let's replace it by
185                  * dynamic data */
186
187                 np = malloc(ALIGN8(new_size));
188                 if (!np)
189                         goto poison;
190
191                 memcpy(np, m->header, sizeof(struct bus_header));
192         }
193
194         /* Zero out padding */
195         if (start > old_size)
196                 memset((uint8_t*) np + old_size, 0, start - old_size);
197
198         op = m->header;
199         m->header = np;
200         m->header->fields_size = new_size - sizeof(struct bus_header);
201
202         /* Adjust quick access pointers */
203         m->path = adjust_pointer(m->path, op, old_size, m->header);
204         m->interface = adjust_pointer(m->interface, op, old_size, m->header);
205         m->member = adjust_pointer(m->member, op, old_size, m->header);
206         m->destination = adjust_pointer(m->destination, op, old_size, m->header);
207         m->sender = adjust_pointer(m->sender, op, old_size, m->header);
208         m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
209
210         m->free_header = true;
211
212         if (add_offset) {
213                 if (m->n_header_offsets >= ELEMENTSOF(m->header_offsets))
214                         goto poison;
215
216                 m->header_offsets[m->n_header_offsets++] = new_size - sizeof(struct bus_header);
217         }
218
219         return (uint8_t*) np + start;
220
221 poison:
222         m->poisoned = true;
223         return NULL;
224 }
225
226 static int message_append_field_string(
227                 sd_bus_message *m,
228                 uint8_t h,
229                 char type,
230                 const char *s,
231                 const char **ret) {
232
233         size_t l;
234         uint8_t *p;
235
236         assert(m);
237
238         /* dbus1 doesn't allow strings over 32bit, let's enforce this
239          * globally, to not risk convertability */
240         l = strlen(s);
241         if (l > (size_t) (uint32_t) -1)
242                 return -EINVAL;
243
244         /* Signature "(yv)" where the variant contains "s" */
245
246         if (BUS_MESSAGE_IS_GVARIANT(m)) {
247
248                 /* (field id byte + 7x padding, ((string + NUL) + NUL + signature string 's') */
249                 p = message_extend_fields(m, 8, 1 + 7 + l + 1 + 1 + 1, true);
250                 if (!p)
251                         return -ENOMEM;
252
253                 p[0] = h;
254                 memset(p+1, 0, 7);
255                 memcpy(p+8, s, l);
256                 p[8+l] = 0;
257                 p[8+l+1] = 0;
258                 p[8+l+2] = type;
259
260                 if (ret)
261                         *ret = (char*) p + 8;
262
263         } else {
264                 /* (field id byte + (signature length + signature 's' + NUL) + (string length + string + NUL)) */
265                 p = message_extend_fields(m, 8, 4 + 4 + l + 1, false);
266                 if (!p)
267                         return -ENOMEM;
268
269                 p[0] = h;
270                 p[1] = 1;
271                 p[2] = type;
272                 p[3] = 0;
273
274                 ((uint32_t*) p)[1] = l;
275                 memcpy(p + 8, s, l + 1);
276
277                 if (ret)
278                         *ret = (char*) p + 8;
279         }
280
281         return 0;
282 }
283
284 static int message_append_field_signature(
285                 sd_bus_message *m,
286                 uint8_t h,
287                 const char *s,
288                 const char **ret) {
289
290         size_t l;
291         uint8_t *p;
292
293         assert(m);
294
295         /* dbus1 doesn't allow signatures over 32bit, let's enforce
296          * this globally, to not risk convertability */
297         l = strlen(s);
298         if (l > 255)
299                 return -EINVAL;
300
301         /* Signature "(yv)" where the variant contains "g" */
302
303         if (BUS_MESSAGE_IS_GVARIANT(m))
304                 /* For gvariant the serialization is the same as for normal strings */
305                 return message_append_field_string(m, h, 'g', s, ret);
306         else {
307                 /* (field id byte + (signature length + signature 'g' + NUL) + (string length + string + NUL)) */
308                 p = message_extend_fields(m, 8, 4 + 1 + l + 1, false);
309                 if (!p)
310                         return -ENOMEM;
311
312                 p[0] = h;
313                 p[1] = 1;
314                 p[2] = SD_BUS_TYPE_SIGNATURE;
315                 p[3] = 0;
316                 p[4] = l;
317                 memcpy(p + 5, s, l + 1);
318
319                 if (ret)
320                         *ret = (const char*) p + 5;
321         }
322
323         return 0;
324 }
325
326 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
327         uint8_t *p;
328
329         assert(m);
330
331         if (BUS_MESSAGE_IS_GVARIANT(m)) {
332                 /* (field id byte + 7x padding + ((value + NUL + signature string 'u') */
333
334                 p = message_extend_fields(m, 8, 1 + 7 + 4 + 1 + 1, true);
335                 if (!p)
336                         return -ENOMEM;
337
338                 p[0] = h;
339                 memset(p+1, 0, 7);
340                 *((uint32_t*) (p + 8)) = x;
341                 p[12] = 0;
342                 p[13] = 'u';
343         } else {
344                 /* (field id byte + (signature length + signature 'u' + NUL) + value) */
345                 p = message_extend_fields(m, 8, 4 + 4, false);
346                 if (!p)
347                         return -ENOMEM;
348
349                 p[0] = h;
350                 p[1] = 1;
351                 p[2] = SD_BUS_TYPE_UINT32;
352                 p[3] = 0;
353
354                 ((uint32_t*) p)[1] = x;
355         }
356
357         return 0;
358 }
359
360 int bus_message_from_header(
361                 sd_bus *bus,
362                 void *buffer,
363                 size_t length,
364                 int *fds,
365                 unsigned n_fds,
366                 const struct ucred *ucred,
367                 const char *label,
368                 size_t extra,
369                 sd_bus_message **ret) {
370
371         sd_bus_message *m;
372         struct bus_header *h;
373         size_t a, label_sz;
374
375         assert(buffer || length <= 0);
376         assert(fds || n_fds <= 0);
377         assert(ret);
378
379         if (length < sizeof(struct bus_header))
380                 return -EBADMSG;
381
382         h = buffer;
383         if (h->version != 1 &&
384             h->version != 2)
385                 return -EBADMSG;
386
387         if (h->serial == 0)
388                 return -EBADMSG;
389
390         if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
391                 return -EBADMSG;
392
393         if (h->endian != BUS_LITTLE_ENDIAN &&
394             h->endian != BUS_BIG_ENDIAN)
395                 return -EBADMSG;
396
397         a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
398
399         if (label) {
400                 label_sz = strlen(label);
401                 a += label_sz + 1;
402         }
403
404         m = malloc0(a);
405         if (!m)
406                 return -ENOMEM;
407
408         m->n_ref = 1;
409         m->sealed = true;
410         m->header = h;
411         m->fds = fds;
412         m->n_fds = n_fds;
413
414         if (ucred) {
415                 m->creds.uid = ucred->uid;
416                 m->creds.pid = ucred->pid;
417                 m->creds.gid = ucred->gid;
418                 m->creds.mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_PID | SD_BUS_CREDS_GID;
419         }
420
421         if (label) {
422                 m->creds.label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
423                 memcpy(m->creds.label, label, label_sz + 1);
424
425                 m->creds.mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
426         }
427
428         if (bus)
429                 m->bus = sd_bus_ref(bus);
430
431         *ret = m;
432         return 0;
433 }
434
435 int bus_message_from_malloc(
436                 sd_bus *bus,
437                 void *buffer,
438                 size_t length,
439                 int *fds,
440                 unsigned n_fds,
441                 const struct ucred *ucred,
442                 const char *label,
443                 sd_bus_message **ret) {
444
445         sd_bus_message *m;
446         size_t sz;
447         int r;
448
449         r = bus_message_from_header(bus, buffer, length, fds, n_fds, ucred, label, 0, &m);
450         if (r < 0)
451                 return r;
452
453         if (length != BUS_MESSAGE_SIZE(m)) {
454                 r = -EBADMSG;
455                 goto fail;
456         }
457
458         sz = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
459         if (sz > 0) {
460                 m->n_body_parts = 1;
461                 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
462                 m->body.size = sz;
463                 m->body.sealed = true;
464                 m->body.memfd = -1;
465         }
466
467         m->n_iovec = 1;
468         m->iovec = m->iovec_fixed;
469         m->iovec[0].iov_base = buffer;
470         m->iovec[0].iov_len = length;
471
472         r = bus_message_parse_fields(m);
473         if (r < 0)
474                 goto fail;
475
476         /* We take possession of the memory and fds now */
477         m->free_header = true;
478         m->free_fds = true;
479
480         *ret = m;
481         return 0;
482
483 fail:
484         message_free(m);
485         return r;
486 }
487
488 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
489         sd_bus_message *m;
490
491         m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
492         if (!m)
493                 return NULL;
494
495         m->n_ref = 1;
496         m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
497         m->header->endian = BUS_NATIVE_ENDIAN;
498         m->header->type = type;
499         m->header->version = bus ? bus->message_version : 1;
500         m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
501         m->root_container.need_offsets = BUS_MESSAGE_IS_GVARIANT(m);
502
503         if (bus)
504                 m->bus = sd_bus_ref(bus);
505
506         return m;
507 }
508
509 _public_ int sd_bus_message_new_signal(
510                 sd_bus *bus,
511                 const char *path,
512                 const char *interface,
513                 const char *member,
514                 sd_bus_message **m) {
515
516         sd_bus_message *t;
517         int r;
518
519         assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
520         assert_return(object_path_is_valid(path), -EINVAL);
521         assert_return(interface_name_is_valid(interface), -EINVAL);
522         assert_return(member_name_is_valid(member), -EINVAL);
523         assert_return(m, -EINVAL);
524
525         t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
526         if (!t)
527                 return -ENOMEM;
528
529         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
530
531         r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
532         if (r < 0)
533                 goto fail;
534         r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
535         if (r < 0)
536                 goto fail;
537         r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
538         if (r < 0)
539                 goto fail;
540
541         *m = t;
542         return 0;
543
544 fail:
545         sd_bus_message_unref(t);
546         return r;
547 }
548
549 _public_ int sd_bus_message_new_method_call(
550                 sd_bus *bus,
551                 const char *destination,
552                 const char *path,
553                 const char *interface,
554                 const char *member,
555                 sd_bus_message **m) {
556
557         sd_bus_message *t;
558         int r;
559
560         assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
561         assert_return(!destination || service_name_is_valid(destination), -EINVAL);
562         assert_return(object_path_is_valid(path), -EINVAL);
563         assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
564         assert_return(member_name_is_valid(member), -EINVAL);
565         assert_return(m, -EINVAL);
566
567         t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
568         if (!t)
569                 return -ENOMEM;
570
571         r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
572         if (r < 0)
573                 goto fail;
574         r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
575         if (r < 0)
576                 goto fail;
577
578         if (interface) {
579                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
580                 if (r < 0)
581                         goto fail;
582         }
583
584         if (destination) {
585                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
586                 if (r < 0)
587                         goto fail;
588         }
589
590         *m = t;
591         return 0;
592
593 fail:
594         message_free(t);
595         return r;
596 }
597
598 static int message_new_reply(
599                 sd_bus_message *call,
600                 uint8_t type,
601                 sd_bus_message **m) {
602
603         sd_bus_message *t;
604         int r;
605
606         assert_return(call, -EINVAL);
607         assert_return(call->sealed, -EPERM);
608         assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
609         assert_return(!call->bus || call->bus->state != BUS_UNSET, -ENOTCONN);
610         assert_return(m, -EINVAL);
611
612         t = message_new(call->bus, type);
613         if (!t)
614                 return -ENOMEM;
615
616         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
617         t->reply_serial = BUS_MESSAGE_SERIAL(call);
618
619         r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
620         if (r < 0)
621                 goto fail;
622
623         if (call->sender) {
624                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
625                 if (r < 0)
626                         goto fail;
627         }
628
629         t->dont_send = !!(call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
630         t->enforced_reply_signature = call->enforced_reply_signature;
631
632         *m = t;
633         return 0;
634
635 fail:
636         message_free(t);
637         return r;
638 }
639
640 _public_ int sd_bus_message_new_method_return(
641                 sd_bus_message *call,
642                 sd_bus_message **m) {
643
644         return message_new_reply(call, SD_BUS_MESSAGE_METHOD_RETURN, m);
645 }
646
647 _public_ int sd_bus_message_new_method_error(
648                 sd_bus_message *call,
649                 const sd_bus_error *e,
650                 sd_bus_message **m) {
651
652         sd_bus_message *t;
653         int r;
654
655         assert_return(sd_bus_error_is_set(e), -EINVAL);
656         assert_return(m, -EINVAL);
657
658         r = message_new_reply(call, SD_BUS_MESSAGE_METHOD_ERROR, &t);
659         if (r < 0)
660                 return r;
661
662         r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
663         if (r < 0)
664                 goto fail;
665
666         if (e->message) {
667                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
668                 if (r < 0)
669                         goto fail;
670         }
671
672         t->error._need_free = -1;
673
674         *m = t;
675         return 0;
676
677 fail:
678         message_free(t);
679         return r;
680 }
681
682 _public_ int sd_bus_message_new_method_errorf(
683                 sd_bus_message *call,
684                 sd_bus_message **m,
685                 const char *name,
686                 const char *format,
687                 ...) {
688
689         _cleanup_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
690         va_list ap;
691
692         assert_return(name, -EINVAL);
693         assert_return(m, -EINVAL);
694
695         va_start(ap, format);
696         bus_error_setfv(&error, name, format, ap);
697         va_end(ap);
698
699         return sd_bus_message_new_method_error(call, &error, m);
700 }
701
702 _public_ int sd_bus_message_new_method_errno(
703                 sd_bus_message *call,
704                 int error,
705                 const sd_bus_error *p,
706                 sd_bus_message **m) {
707
708         _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
709
710         if (sd_bus_error_is_set(p))
711                 return sd_bus_message_new_method_error(call, p, m);
712
713         sd_bus_error_set_errno(&berror, error);
714
715         return sd_bus_message_new_method_error(call, &berror, m);
716 }
717
718 _public_ int sd_bus_message_new_method_errnof(
719                 sd_bus_message *call,
720                 sd_bus_message **m,
721                 int error,
722                 const char *format,
723                 ...) {
724
725         _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
726         va_list ap;
727
728         va_start(ap, format);
729         bus_error_set_errnofv(&berror, error, format, ap);
730         va_end(ap);
731
732         return sd_bus_message_new_method_error(call, &berror, m);
733 }
734
735 int bus_message_new_synthetic_error(
736                 sd_bus *bus,
737                 uint64_t serial,
738                 const sd_bus_error *e,
739                 sd_bus_message **m) {
740
741         sd_bus_message *t;
742         int r;
743
744         assert(sd_bus_error_is_set(e));
745         assert(m);
746
747         t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
748         if (!t)
749                 return -ENOMEM;
750
751         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
752         t->reply_serial = serial;
753
754         r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
755         if (r < 0)
756                 goto fail;
757
758         if (bus && bus->unique_name) {
759                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
760                 if (r < 0)
761                         goto fail;
762         }
763
764         r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
765         if (r < 0)
766                 goto fail;
767
768         if (e->message) {
769                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
770                 if (r < 0)
771                         goto fail;
772         }
773
774         t->error._need_free = -1;
775
776         *m = t;
777         return 0;
778
779 fail:
780         message_free(t);
781         return r;
782 }
783
784 _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
785         assert_return(m, NULL);
786
787         assert(m->n_ref > 0);
788         m->n_ref++;
789
790         return m;
791 }
792
793 _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
794         assert_return(m, NULL);
795
796         assert(m->n_ref > 0);
797         m->n_ref--;
798
799         if (m->n_ref <= 0)
800                 message_free(m);
801
802         return NULL;
803 }
804
805 _public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
806         assert_return(m, -EINVAL);
807         assert_return(type, -EINVAL);
808
809         *type = m->header->type;
810         return 0;
811 }
812
813 _public_ int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
814         assert_return(m, -EINVAL);
815         assert_return(serial, -EINVAL);
816         assert_return(m->header->serial != 0, -ENOENT);
817
818         *serial = BUS_MESSAGE_SERIAL(m);
819         return 0;
820 }
821
822 _public_ int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
823         assert_return(m, -EINVAL);
824         assert_return(serial, -EINVAL);
825         assert_return(m->reply_serial != 0, -ENOENT);
826
827         *serial = m->reply_serial;
828         return 0;
829 }
830
831 _public_ int sd_bus_message_get_no_reply(sd_bus_message *m) {
832         assert_return(m, -EINVAL);
833
834         return m->header->type == SD_BUS_MESSAGE_METHOD_CALL ? !!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
835 }
836
837 _public_ int sd_bus_message_get_no_auto_start(sd_bus_message *m) {
838         assert_return(m, -EINVAL);
839
840         return !!(m->header->flags & BUS_MESSAGE_NO_AUTO_START);
841 }
842
843 _public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
844         assert_return(m, NULL);
845
846         return m->path;
847 }
848
849 _public_ const char *sd_bus_message_get_interface(sd_bus_message *m) {
850         assert_return(m, NULL);
851
852         return m->interface;
853 }
854
855 _public_ const char *sd_bus_message_get_member(sd_bus_message *m) {
856         assert_return(m, NULL);
857
858         return m->member;
859 }
860
861 _public_ const char *sd_bus_message_get_destination(sd_bus_message *m) {
862         assert_return(m, NULL);
863
864         return m->destination;
865 }
866
867 _public_ const char *sd_bus_message_get_sender(sd_bus_message *m) {
868         assert_return(m, NULL);
869
870         return m->sender;
871 }
872
873 _public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
874         assert_return(m, NULL);
875         assert_return(sd_bus_error_is_set(&m->error), NULL);
876
877         return &m->error;
878 }
879
880 _public_ int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
881         assert_return(m, -EINVAL);
882         assert_return(usec, -EINVAL);
883         assert_return(m->monotonic > 0, -ENODATA);
884
885         *usec = m->monotonic;
886         return 0;
887 }
888
889 _public_ int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
890         assert_return(m, -EINVAL);
891         assert_return(usec, -EINVAL);
892         assert_return(m->realtime > 0, -ENODATA);
893
894         *usec = m->realtime;
895         return 0;
896 }
897
898 _public_ sd_bus_creds *sd_bus_message_get_creds(sd_bus_message *m) {
899         assert_return(m, NULL);
900
901         if (m->creds.mask == 0)
902                 return NULL;
903
904         return &m->creds;
905 }
906
907 _public_ int sd_bus_message_is_signal(sd_bus_message *m,
908                                       const char *interface,
909                                       const char *member) {
910         assert_return(m, -EINVAL);
911
912         if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
913                 return 0;
914
915         if (interface && (!m->interface || !streq(m->interface, interface)))
916                 return 0;
917
918         if (member &&  (!m->member || !streq(m->member, member)))
919                 return 0;
920
921         return 1;
922 }
923
924 _public_ int sd_bus_message_is_method_call(sd_bus_message *m,
925                                            const char *interface,
926                                            const char *member) {
927         assert_return(m, -EINVAL);
928
929         if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
930                 return 0;
931
932         if (interface && (!m->interface || !streq(m->interface, interface)))
933                 return 0;
934
935         if (member &&  (!m->member || !streq(m->member, member)))
936                 return 0;
937
938         return 1;
939 }
940
941 _public_ int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
942         assert_return(m, -EINVAL);
943
944         if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
945                 return 0;
946
947         if (name && (!m->error.name || !streq(m->error.name, name)))
948                 return 0;
949
950         return 1;
951 }
952
953 _public_ int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
954         assert_return(m, -EINVAL);
955         assert_return(!m->sealed, -EPERM);
956         assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
957
958         if (b)
959                 m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
960         else
961                 m->header->flags &= ~BUS_MESSAGE_NO_REPLY_EXPECTED;
962
963         return 0;
964 }
965
966 _public_ int sd_bus_message_set_no_auto_start(sd_bus_message *m, int b) {
967         assert_return(m, -EINVAL);
968         assert_return(!m->sealed, -EPERM);
969
970         if (b)
971                 m->header->flags |= BUS_MESSAGE_NO_AUTO_START;
972         else
973                 m->header->flags &= ~BUS_MESSAGE_NO_AUTO_START;
974
975         return 0;
976 }
977
978 static struct bus_container *message_get_container(sd_bus_message *m) {
979         assert(m);
980
981         if (m->n_containers == 0)
982                 return &m->root_container;
983
984         assert(m->containers);
985         return m->containers + m->n_containers - 1;
986 }
987
988 struct bus_body_part *message_append_part(sd_bus_message *m) {
989         struct bus_body_part *part;
990
991         assert(m);
992
993         if (m->poisoned)
994                 return NULL;
995
996         if (m->n_body_parts <= 0) {
997                 part = &m->body;
998                 zero(*part);
999         } else {
1000                 assert(m->body_end);
1001
1002                 part = new0(struct bus_body_part, 1);
1003                 if (!part) {
1004                         m->poisoned = true;
1005                         return NULL;
1006                 }
1007
1008                 m->body_end->next = part;
1009         }
1010
1011         part->memfd = -1;
1012         m->body_end = part;
1013         m->n_body_parts ++;
1014
1015         return part;
1016 }
1017
1018 static void part_zero(struct bus_body_part *part, size_t sz) {
1019         assert(part);
1020         assert(sz > 0);
1021         assert(sz < 8);
1022
1023         /* All other fields can be left in their defaults */
1024         assert(!part->data);
1025         assert(part->memfd < 0);
1026
1027         part->size = sz;
1028         part->is_zero = true;
1029         part->sealed = true;
1030 }
1031
1032 static int part_make_space(
1033                 struct sd_bus_message *m,
1034                 struct bus_body_part *part,
1035                 size_t sz,
1036                 void **q) {
1037
1038         void *n;
1039         int r;
1040
1041         assert(m);
1042         assert(part);
1043         assert(!part->sealed);
1044
1045         if (m->poisoned)
1046                 return -ENOMEM;
1047
1048         if (!part->data && part->memfd < 0)
1049                 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1050
1051         if (part->memfd >= 0) {
1052                 uint64_t u = sz;
1053
1054                 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1055                 if (r < 0) {
1056                         m->poisoned = true;
1057                         return -errno;
1058                 }
1059
1060                 if (!part->data || sz > part->mapped) {
1061                         size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1062
1063                         if (part->mapped <= 0)
1064                                 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1065                         else
1066                                 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1067
1068                         if (n == MAP_FAILED) {
1069                                 m->poisoned = true;
1070                                 return -errno;
1071                         }
1072
1073                         part->mapped = psz;
1074                         part->data = n;
1075                 }
1076
1077                 part->munmap_this = true;
1078         } else {
1079                 n = realloc(part->data, MAX(sz, 1u));
1080                 if (!n) {
1081                         m->poisoned = true;
1082                         return -ENOMEM;
1083                 }
1084
1085                 part->data = n;
1086                 part->free_this = true;
1087         }
1088
1089         if (q)
1090                 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1091
1092         part->size = sz;
1093         return 0;
1094 }
1095
1096 static int message_add_offset(sd_bus_message *m, size_t offset) {
1097         struct bus_container *c;
1098
1099         assert(m);
1100         assert(BUS_MESSAGE_IS_GVARIANT(m));
1101
1102         /* Add offset to current container, unless this is the first
1103          * item in it, which will have the 0 offset, which we can
1104          * ignore. */
1105         c = message_get_container(m);
1106
1107         if (!c->need_offsets)
1108                 return 0;
1109
1110         if (!GREEDY_REALLOC(c->offsets, c->n_offsets_allocated, c->n_offsets + 1))
1111                 return -ENOMEM;
1112
1113         c->offsets[c->n_offsets++] = offset;
1114         return 0;
1115 }
1116
1117 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1118         struct bus_container *c;
1119
1120         assert(m);
1121
1122         if (expand <= 0)
1123                 return;
1124
1125         /* Update counters */
1126         for (c = m->containers; c < m->containers + m->n_containers; c++) {
1127
1128                 if (c->array_size)
1129                         *c->array_size += expand;
1130         }
1131 }
1132
1133 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
1134         struct bus_body_part *part = NULL;
1135         size_t start_body, end_body, padding, start_part, end_part, added;
1136         bool add_new_part;
1137         void *p;
1138         int r;
1139
1140         assert(m);
1141         assert(align > 0);
1142         assert(!m->sealed);
1143
1144         if (m->poisoned)
1145                 return NULL;
1146
1147         start_body = ALIGN_TO((size_t) m->header->body_size, align);
1148         end_body = start_body + sz;
1149
1150         padding = start_body - m->header->body_size;
1151         added = padding + sz;
1152
1153         /* Check for 32bit overflows */
1154         if (end_body > (size_t) ((uint32_t) -1)) {
1155                 m->poisoned = true;
1156                 return NULL;
1157         }
1158
1159         add_new_part =
1160                 m->n_body_parts <= 0 ||
1161                 m->body_end->sealed ||
1162                 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1163
1164         if (add_new_part) {
1165                 if (padding > 0) {
1166                         part = message_append_part(m);
1167                         if (!part)
1168                                 return NULL;
1169
1170                         part_zero(part, padding);
1171                 }
1172
1173                 part = message_append_part(m);
1174                 if (!part)
1175                         return NULL;
1176
1177                 r = part_make_space(m, part, sz, &p);
1178                 if (r < 0)
1179                         return NULL;
1180         } else {
1181                 struct bus_container *c;
1182                 void *op;
1183                 size_t os;
1184
1185                 part = m->body_end;
1186                 op = part->data;
1187                 os = part->size;
1188
1189                 start_part = ALIGN_TO(part->size, align);
1190                 end_part = start_part + sz;
1191
1192                 r = part_make_space(m, part, end_part, &p);
1193                 if (r < 0)
1194                         return NULL;
1195
1196                 if (padding > 0) {
1197                         memset(p, 0, padding);
1198                         p = (uint8_t*) p + padding;
1199                 }
1200
1201                 /* Readjust pointers */
1202                 for (c = m->containers; c < m->containers + m->n_containers; c++)
1203                         c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1204
1205                 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1206         }
1207
1208         m->header->body_size = end_body;
1209         message_extend_containers(m, added);
1210
1211         if (add_offset) {
1212                 r = message_add_offset(m, end_body);
1213                 if (r < 0) {
1214                         m->poisoned = true;
1215                         return NULL;
1216                 }
1217         }
1218
1219         return p;
1220 }
1221
1222 static int message_push_fd(sd_bus_message *m, int fd) {
1223         int *f, copy;
1224
1225         assert(m);
1226
1227         if (fd < 0)
1228                 return -EINVAL;
1229
1230         if (!m->allow_fds)
1231                 return -ENOTSUP;
1232
1233         copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
1234         if (copy < 0)
1235                 return -errno;
1236
1237         f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1238         if (!f) {
1239                 m->poisoned = true;
1240                 close_nointr_nofail(copy);
1241                 return -ENOMEM;
1242         }
1243
1244         m->fds = f;
1245         m->fds[m->n_fds] = copy;
1246         m->free_fds = true;
1247
1248         return copy;
1249 }
1250
1251 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1252         _cleanup_close_ int fd = -1;
1253         struct bus_container *c;
1254         ssize_t align, sz;
1255         void *a;
1256
1257         assert_return(m, -EINVAL);
1258         assert_return(!m->sealed, -EPERM);
1259         assert_return(bus_type_is_basic(type), -EINVAL);
1260         assert_return(!m->poisoned, -ESTALE);
1261
1262         c = message_get_container(m);
1263
1264         if (c->signature && c->signature[c->index]) {
1265                 /* Container signature is already set */
1266
1267                 if (c->signature[c->index] != type)
1268                         return -ENXIO;
1269         } else {
1270                 char *e;
1271
1272                 /* Maybe we can append to the signature? But only if this is the top-level container*/
1273                 if (c->enclosing != 0)
1274                         return -ENXIO;
1275
1276                 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1277                 if (!e) {
1278                         m->poisoned = true;
1279                         return -ENOMEM;
1280                 }
1281         }
1282
1283         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1284                 uint8_t u8;
1285                 uint32_t u32;
1286
1287                 switch (type) {
1288
1289                 case SD_BUS_TYPE_SIGNATURE:
1290                 case SD_BUS_TYPE_STRING:
1291                         p = strempty(p);
1292
1293                         /* Fall through... */
1294                 case SD_BUS_TYPE_OBJECT_PATH:
1295                         if (!p)
1296                                 return -EINVAL;
1297
1298                         align = 1;
1299                         sz = strlen(p) + 1;
1300                         break;
1301
1302                 case SD_BUS_TYPE_BOOLEAN:
1303
1304                         u8 = p && *(int*) p;
1305                         p = &u8;
1306
1307                         align = sz = 1;
1308                         break;
1309
1310                 case SD_BUS_TYPE_UNIX_FD:
1311
1312                         if (!p)
1313                                 return -EINVAL;
1314
1315                         fd = message_push_fd(m, *(int*) p);
1316                         if (fd < 0)
1317                                 return fd;
1318
1319                         u32 = m->n_fds;
1320                         p = &u32;
1321
1322                         align = sz = 4;
1323                         break;
1324
1325                 default:
1326                         align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
1327                         sz = bus_gvariant_get_size(CHAR_TO_STR(type));
1328                         break;
1329                 }
1330
1331                 assert(align > 0);
1332                 assert(sz > 0);
1333
1334                 a = message_extend_body(m, align, sz, true);
1335                 if (!a)
1336                         return -ENOMEM;
1337
1338                 memcpy(a, p, sz);
1339
1340                 if (stored)
1341                         *stored = (const uint8_t*) a;
1342
1343         } else {
1344                 uint32_t u32;
1345
1346                 switch (type) {
1347
1348                 case SD_BUS_TYPE_STRING:
1349                         /* To make things easy we'll serialize a NULL string
1350                          * into the empty string */
1351                         p = strempty(p);
1352
1353                         /* Fall through... */
1354                 case SD_BUS_TYPE_OBJECT_PATH:
1355
1356                         if (!p)
1357                                 return -EINVAL;
1358
1359                         align = 4;
1360                         sz = 4 + strlen(p) + 1;
1361                         break;
1362
1363                 case SD_BUS_TYPE_SIGNATURE:
1364
1365                         p = strempty(p);
1366
1367                         align = 1;
1368                         sz = 1 + strlen(p) + 1;
1369                         break;
1370
1371                 case SD_BUS_TYPE_BOOLEAN:
1372
1373                         u32 = p && *(int*) p;
1374                         p = &u32;
1375
1376                         align = sz = 4;
1377                         break;
1378
1379                 case SD_BUS_TYPE_UNIX_FD:
1380
1381                         if (!p)
1382                                 return -EINVAL;
1383
1384                         fd = message_push_fd(m, *(int*) p);
1385                         if (fd < 0)
1386                                 return fd;
1387
1388                         u32 = m->n_fds;
1389                         p = &u32;
1390
1391                         align = sz = 4;
1392                         break;
1393
1394                 default:
1395                         align = bus_type_get_alignment(type);
1396                         sz = bus_type_get_size(type);
1397                         break;
1398                 }
1399
1400                 assert(align > 0);
1401                 assert(sz > 0);
1402
1403                 a = message_extend_body(m, align, sz, false);
1404                 if (!a)
1405                         return -ENOMEM;
1406
1407                 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1408                         *(uint32_t*) a = sz - 5;
1409                         memcpy((uint8_t*) a + 4, p, sz - 4);
1410
1411                         if (stored)
1412                                 *stored = (const uint8_t*) a + 4;
1413
1414                 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1415                         *(uint8_t*) a = sz - 1;
1416                         memcpy((uint8_t*) a + 1, p, sz - 1);
1417
1418                         if (stored)
1419                                 *stored = (const uint8_t*) a + 1;
1420                 } else {
1421                         memcpy(a, p, sz);
1422
1423                         if (stored)
1424                                 *stored = a;
1425                 }
1426         }
1427
1428         if (type == SD_BUS_TYPE_UNIX_FD)
1429                 m->n_fds ++;
1430
1431         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1432                 c->index++;
1433
1434         fd = -1;
1435         return 0;
1436 }
1437
1438 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1439         return message_append_basic(m, type, p, NULL);
1440 }
1441
1442 _public_ int sd_bus_message_append_string_space(
1443                 sd_bus_message *m,
1444                 size_t size,
1445                 char **s) {
1446
1447         struct bus_container *c;
1448         void *a;
1449
1450         assert_return(m, -EINVAL);
1451         assert_return(s, -EINVAL);
1452         assert_return(!m->sealed, -EPERM);
1453         assert_return(!m->poisoned, -ESTALE);
1454
1455         c = message_get_container(m);
1456
1457         if (c->signature && c->signature[c->index]) {
1458                 /* Container signature is already set */
1459
1460                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1461                         return -ENXIO;
1462         } else {
1463                 char *e;
1464
1465                 /* Maybe we can append to the signature? But only if this is the top-level container*/
1466                 if (c->enclosing != 0)
1467                         return -ENXIO;
1468
1469                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1470                 if (!e) {
1471                         m->poisoned = true;
1472                         return -ENOMEM;
1473                 }
1474         }
1475
1476         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1477                 a = message_extend_body(m, 1, size + 1, true);
1478                 if (!a)
1479                         return -ENOMEM;
1480
1481                 *s = a;
1482         } else {
1483                 a = message_extend_body(m, 4, 4 + size + 1, false);
1484                 if (!a)
1485                         return -ENOMEM;
1486
1487                 *(uint32_t*) a = size;
1488                 *s = (char*) a + 4;
1489         }
1490
1491         (*s)[size] = 0;
1492
1493         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1494                 c->index++;
1495
1496         return 0;
1497 }
1498
1499 _public_ int sd_bus_message_append_string_iovec(
1500                 sd_bus_message *m,
1501                 const struct iovec *iov,
1502                 unsigned n) {
1503
1504         size_t size;
1505         unsigned i;
1506         char *p;
1507         int r;
1508
1509         assert_return(m, -EINVAL);
1510         assert_return(!m->sealed, -EPERM);
1511         assert_return(iov || n == 0, -EINVAL);
1512         assert_return(!m->poisoned, -ESTALE);
1513
1514         size = IOVEC_TOTAL_SIZE(iov, n);
1515
1516         r = sd_bus_message_append_string_space(m, size, &p);
1517         if (r < 0)
1518                 return r;
1519
1520         for (i = 0; i < n; i++) {
1521
1522                 if (iov[i].iov_base)
1523                         memcpy(p, iov[i].iov_base, iov[i].iov_len);
1524                 else
1525                         memset(p, ' ', iov[i].iov_len);
1526
1527                 p += iov[i].iov_len;
1528         }
1529
1530         return 0;
1531 }
1532
1533 static int bus_message_open_array(
1534                 sd_bus_message *m,
1535                 struct bus_container *c,
1536                 const char *contents,
1537                 uint32_t **array_size,
1538                 size_t *begin,
1539                 bool *need_offsets) {
1540
1541         unsigned nindex;
1542         int alignment, r;
1543
1544         assert(m);
1545         assert(c);
1546         assert(contents);
1547         assert(array_size);
1548         assert(begin);
1549         assert(need_offsets);
1550
1551         if (!signature_is_single(contents, true))
1552                 return -EINVAL;
1553
1554         if (c->signature && c->signature[c->index]) {
1555
1556                 /* Verify the existing signature */
1557
1558                 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1559                         return -ENXIO;
1560
1561                 if (!startswith(c->signature + c->index + 1, contents))
1562                         return -ENXIO;
1563
1564                 nindex = c->index + 1 + strlen(contents);
1565         } else {
1566                 char *e;
1567
1568                 if (c->enclosing != 0)
1569                         return -ENXIO;
1570
1571                 /* Extend the existing signature */
1572
1573                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1574                 if (!e) {
1575                         m->poisoned = true;
1576                         return -ENOMEM;
1577                 }
1578
1579                 nindex = e - c->signature;
1580         }
1581
1582         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1583                 alignment = bus_gvariant_get_alignment(contents);
1584                 if (alignment < 0)
1585                         return alignment;
1586
1587                 /* Add alignment padding and add to offset list */
1588                 if (!message_extend_body(m, alignment, 0, false))
1589                         return -ENOMEM;
1590
1591                 r = bus_gvariant_is_fixed_size(contents);
1592                 if (r < 0)
1593                         return r;
1594
1595                 *begin = m->header->body_size;
1596                 *need_offsets = r == 0;
1597         } else {
1598                 void *a, *op;
1599                 size_t os;
1600                 struct bus_body_part *o;
1601
1602                 alignment = bus_type_get_alignment(contents[0]);
1603                 if (alignment < 0)
1604                         return alignment;
1605
1606                 a = message_extend_body(m, 4, 4, false);
1607                 if (!a)
1608                         return -ENOMEM;
1609
1610                 o = m->body_end;
1611                 op = m->body_end->data;
1612                 os = m->body_end->size;
1613
1614                 /* Add alignment between size and first element */
1615                 if (!message_extend_body(m, alignment, 0, false))
1616                         return -ENOMEM;
1617
1618                 /* location of array size might have changed so let's readjust a */
1619                 if (o == m->body_end)
1620                         a = adjust_pointer(a, op, os, m->body_end->data);
1621
1622                 *(uint32_t*) a = 0;
1623                 *array_size = a;
1624         }
1625
1626         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1627                 c->index = nindex;
1628
1629         return 0;
1630 }
1631
1632 static int bus_message_open_variant(
1633                 sd_bus_message *m,
1634                 struct bus_container *c,
1635                 const char *contents) {
1636
1637         assert(m);
1638         assert(c);
1639         assert(contents);
1640
1641         if (!signature_is_single(contents, false))
1642                 return -EINVAL;
1643
1644         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1645                 return -EINVAL;
1646
1647         if (c->signature && c->signature[c->index]) {
1648
1649                 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1650                         return -ENXIO;
1651
1652         } else {
1653                 char *e;
1654
1655                 if (c->enclosing != 0)
1656                         return -ENXIO;
1657
1658                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1659                 if (!e) {
1660                         m->poisoned = true;
1661                         return -ENOMEM;
1662                 }
1663         }
1664
1665         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1666                 /* Variants are always aligned to 8 */
1667
1668                 if (!message_extend_body(m, 8, 0, false))
1669                         return -ENOMEM;
1670
1671         } else {
1672                 size_t l;
1673                 void *a;
1674
1675                 l = strlen(contents);
1676                 a = message_extend_body(m, 1, 1 + l + 1, false);
1677                 if (!a)
1678                         return -ENOMEM;
1679
1680                 *(uint8_t*) a = l;
1681                 memcpy((uint8_t*) a + 1, contents, l + 1);
1682         }
1683
1684         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1685                 c->index++;
1686
1687         return 0;
1688 }
1689
1690 static int bus_message_open_struct(
1691                 sd_bus_message *m,
1692                 struct bus_container *c,
1693                 const char *contents,
1694                 size_t *begin,
1695                 bool *need_offsets) {
1696
1697         size_t nindex;
1698         int r;
1699
1700         assert(m);
1701         assert(c);
1702         assert(contents);
1703         assert(begin);
1704         assert(need_offsets);
1705
1706         if (!signature_is_valid(contents, false))
1707                 return -EINVAL;
1708
1709         if (c->signature && c->signature[c->index]) {
1710                 size_t l;
1711
1712                 l = strlen(contents);
1713
1714                 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1715                     !startswith(c->signature + c->index + 1, contents) ||
1716                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1717                         return -ENXIO;
1718
1719                 nindex = c->index + 1 + l + 1;
1720         } else {
1721                 char *e;
1722
1723                 if (c->enclosing != 0)
1724                         return -ENXIO;
1725
1726                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1727                 if (!e) {
1728                         m->poisoned = true;
1729                         return -ENOMEM;
1730                 }
1731
1732                 nindex = e - c->signature;
1733         }
1734
1735         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1736                 int alignment;
1737
1738                 alignment = bus_gvariant_get_alignment(contents);
1739                 if (alignment < 0)
1740                         return alignment;
1741
1742                 if (!message_extend_body(m, alignment, 0, false))
1743                         return -ENOMEM;
1744
1745                 r = bus_gvariant_is_fixed_size(contents);
1746                 if (r < 0)
1747                         return r;
1748
1749                 *begin = m->header->body_size;
1750                 *need_offsets = r == 0;
1751         } else {
1752                 /* Align contents to 8 byte boundary */
1753                 if (!message_extend_body(m, 8, 0, false))
1754                         return -ENOMEM;
1755         }
1756
1757         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1758                 c->index = nindex;
1759
1760         return 0;
1761 }
1762
1763 static int bus_message_open_dict_entry(
1764                 sd_bus_message *m,
1765                 struct bus_container *c,
1766                 const char *contents,
1767                 size_t *begin,
1768                 bool *need_offsets) {
1769
1770         int r;
1771
1772         assert(m);
1773         assert(c);
1774         assert(contents);
1775         assert(begin);
1776         assert(need_offsets);
1777
1778         if (!signature_is_pair(contents))
1779                 return -EINVAL;
1780
1781         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1782                 return -ENXIO;
1783
1784         if (c->signature && c->signature[c->index]) {
1785                 size_t l;
1786
1787                 l = strlen(contents);
1788
1789                 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1790                     !startswith(c->signature + c->index + 1, contents) ||
1791                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1792                         return -ENXIO;
1793         } else
1794                 return -ENXIO;
1795
1796         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1797                 int alignment;
1798
1799                 alignment = bus_gvariant_get_alignment(contents);
1800                 if (alignment < 0)
1801                         return alignment;
1802
1803                 if (!message_extend_body(m, alignment, 0, false))
1804                         return -ENOMEM;
1805
1806                 r = bus_gvariant_is_fixed_size(contents);
1807                 if (r < 0)
1808                         return r;
1809
1810                 *begin = m->header->body_size;
1811                 *need_offsets = r == 0;
1812         } else {
1813                 /* Align contents to 8 byte boundary */
1814                 if (!message_extend_body(m, 8, 0, false))
1815                         return -ENOMEM;
1816         }
1817
1818         return 0;
1819 }
1820
1821 _public_ int sd_bus_message_open_container(
1822                 sd_bus_message *m,
1823                 char type,
1824                 const char *contents) {
1825
1826         struct bus_container *c, *w;
1827         uint32_t *array_size = NULL;
1828         char *signature;
1829         size_t before, begin;
1830         bool need_offsets = false;
1831         int r;
1832
1833         assert_return(m, -EINVAL);
1834         assert_return(!m->sealed, -EPERM);
1835         assert_return(contents, -EINVAL);
1836         assert_return(!m->poisoned, -ESTALE);
1837
1838         /* Make sure we have space for one more container */
1839         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1840         if (!w) {
1841                 m->poisoned = true;
1842                 return -ENOMEM;
1843         }
1844
1845         m->containers = w;
1846
1847         c = message_get_container(m);
1848
1849         signature = strdup(contents);
1850         if (!signature) {
1851                 m->poisoned = true;
1852                 return -ENOMEM;
1853         }
1854
1855         /* Save old index in the parent container, in case we have to
1856          * abort this container */
1857         c->saved_index = c->index;
1858         before = m->header->body_size;
1859
1860         if (type == SD_BUS_TYPE_ARRAY)
1861                 r = bus_message_open_array(m, c, contents, &array_size, &begin, &need_offsets);
1862         else if (type == SD_BUS_TYPE_VARIANT)
1863                 r = bus_message_open_variant(m, c, contents);
1864         else if (type == SD_BUS_TYPE_STRUCT)
1865                 r = bus_message_open_struct(m, c, contents, &begin, &need_offsets);
1866         else if (type == SD_BUS_TYPE_DICT_ENTRY)
1867                 r = bus_message_open_dict_entry(m, c, contents, &begin, &need_offsets);
1868         else
1869                 r = -EINVAL;
1870
1871         if (r < 0) {
1872                 free(signature);
1873                 return r;
1874         }
1875
1876         /* OK, let's fill it in */
1877         w += m->n_containers++;
1878         w->enclosing = type;
1879         w->signature = signature;
1880         w->index = 0;
1881         w->array_size = array_size;
1882         w->before = before;
1883         w->begin = begin;
1884         w->n_offsets = w->n_offsets_allocated = 0;
1885         w->offsets = NULL;
1886         w->need_offsets = need_offsets;
1887
1888         return 0;
1889 }
1890
1891 static size_t determine_word_size(size_t sz, size_t extra) {
1892         if (sz <= 0 && extra == 0)
1893                 return 0;
1894         else if (sz + extra <= 0xFF)
1895                 return 1;
1896         else if (sz + extra*2 <= 0xFFFF)
1897                 return 2;
1898         else if (sz + extra*4 <= 0xFFFFFFFF)
1899                 return 4;
1900         else
1901                 return 8;
1902 }
1903
1904 static size_t read_word_le(void *p, size_t sz) {
1905         union {
1906                 uint16_t u16;
1907                 uint32_t u32;
1908                 uint64_t u64;
1909         } x;
1910
1911         assert(p);
1912
1913         if (sz == 1)
1914                 return *(uint8_t*) p;
1915
1916         memcpy(&x, p, sz);
1917
1918         if (sz == 2)
1919                 return le16toh(x.u16);
1920         else if (sz == 4)
1921                 return le32toh(x.u32);
1922         else if (sz == 4)
1923                 return le64toh(x.u64);
1924
1925         assert_not_reached("unknown word width");
1926 }
1927
1928 static void write_word_le(void *p, size_t sz, size_t value) {
1929         union {
1930                 uint16_t u16;
1931                 uint32_t u32;
1932                 uint64_t u64;
1933         } x;
1934
1935         assert(p);
1936         assert(sz == 8 || (value < (1ULL << (sz*8))));
1937
1938         if (sz == 1) {
1939                 *(uint8_t*) p = value;
1940                 return;
1941         } else if (sz == 2)
1942                 x.u16 = htole16((uint16_t) value);
1943         else if (sz == 4)
1944                 x.u32 = htole32((uint32_t) value);
1945         else if (sz == 8)
1946                 x.u64 = htole64((uint64_t) value);
1947         else
1948                 assert_not_reached("unknown word width");
1949
1950         memcpy(p, &x, sz);
1951 }
1952
1953 static int bus_message_close_array(sd_bus_message *m, struct bus_container *c) {
1954
1955         assert(m);
1956         assert(c);
1957
1958         if (!BUS_MESSAGE_IS_GVARIANT(m))
1959                 return 0;
1960
1961         if (c->need_offsets) {
1962                 size_t payload, sz, i;
1963                 uint8_t *a;
1964
1965                 /* Variable-width arrays */
1966
1967                 payload = c->n_offsets > 0 ? c->offsets[c->n_offsets-1] - c->begin : 0;
1968                 sz = determine_word_size(payload, c->n_offsets);
1969
1970                 a = message_extend_body(m, 1, sz * c->n_offsets, true);
1971                 if (!a)
1972                         return -ENOMEM;
1973
1974                 for (i = 0; i < c->n_offsets; i++)
1975                         write_word_le(a + sz*i, sz, c->offsets[i] - c->begin);
1976         } else {
1977                 void *a;
1978
1979                 /* Fixed-width or empty arrays */
1980
1981                 a = message_extend_body(m, 1, 0, true); /* let's add offset to parent */
1982                 if (!a)
1983                         return -ENOMEM;
1984         }
1985
1986         return 0;
1987 }
1988
1989 static int bus_message_close_variant(sd_bus_message *m, struct bus_container *c) {
1990         uint8_t *a;
1991         size_t l;
1992
1993         assert(m);
1994         assert(c);
1995
1996         if (!BUS_MESSAGE_IS_GVARIANT(m))
1997                 return 0;
1998
1999         l = strlen(c->signature);
2000
2001         a = message_extend_body(m, 1, 1 + l, true);
2002         if (!a)
2003                 return -ENOMEM;
2004
2005         a[0] = 0;
2006         memcpy(a+1, c->signature, l);
2007
2008         return 0;
2009 }
2010
2011 static int bus_message_close_struct(sd_bus_message *m, struct bus_container *c, bool add_offset) {
2012         size_t n_variable = 0;
2013         unsigned i = 0;
2014         const char *p;
2015         uint8_t *a;
2016         int r;
2017
2018         assert(m);
2019         assert(c);
2020
2021         if (!BUS_MESSAGE_IS_GVARIANT(m))
2022                 return 0;
2023
2024         p = c->signature;
2025         while (*p != 0) {
2026                 size_t n;
2027
2028                 r = signature_element_length(p, &n);
2029                 if (r < 0)
2030                         return r;
2031                 else {
2032                         char t[n+1];
2033
2034                         memcpy(t, p, n);
2035                         t[n] = 0;
2036
2037                         r = bus_gvariant_is_fixed_size(t);
2038                         if (r < 0)
2039                                 return r;
2040                 }
2041
2042                 assert(i <= c->n_offsets);
2043
2044                 /* We need to add an offset for each item that has a
2045                  * variable size and that is not the last one in the
2046                  * list */
2047                 if (r == 0 && p[n] != 0)
2048                         n_variable++;
2049
2050                 i++;
2051                 p += n;
2052         }
2053
2054         assert(i == c->n_offsets);
2055
2056         if (n_variable <= 0) {
2057                 a = message_extend_body(m, 1, 0, add_offset);
2058                 if (!a)
2059                         return -ENOMEM;
2060         } else {
2061                 size_t sz;
2062                 unsigned j;
2063
2064                 assert(c->offsets[c->n_offsets-1] == m->header->body_size);
2065
2066                 sz = determine_word_size(m->header->body_size - c->begin, n_variable);
2067
2068                 a = message_extend_body(m, 1, sz * n_variable, add_offset);
2069                 if (!a)
2070                         return -ENOMEM;
2071
2072                 p = c->signature;
2073                 for (i = 0, j = 0; i < c->n_offsets; i++) {
2074                         unsigned k;
2075                         size_t n;
2076
2077                         r = signature_element_length(p, &n);
2078                         if (r < 0)
2079                                 return r;
2080                         else {
2081                                 char t[n+1];
2082
2083                                 memcpy(t, p, n);
2084                                 t[n] = 0;
2085
2086                                 p += n;
2087
2088                                 r = bus_gvariant_is_fixed_size(t);
2089                                 if (r < 0)
2090                                         return r;
2091                                 if (r > 0 || p[0] == 0)
2092                                         continue;
2093                         }
2094
2095                         k = n_variable - 1 - j;
2096
2097                         write_word_le(a + k * sz, sz, c->offsets[i] - c->begin);
2098
2099                         j++;
2100                 }
2101         }
2102
2103         return 0;
2104 }
2105
2106 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
2107         struct bus_container *c;
2108         int r;
2109
2110         assert_return(m, -EINVAL);
2111         assert_return(!m->sealed, -EPERM);
2112         assert_return(m->n_containers > 0, -EINVAL);
2113         assert_return(!m->poisoned, -ESTALE);
2114
2115         c = message_get_container(m);
2116
2117         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2118                 if (c->signature && c->signature[c->index] != 0)
2119                         return -EINVAL;
2120
2121         m->n_containers--;
2122
2123         if (c->enclosing == SD_BUS_TYPE_ARRAY)
2124                 r = bus_message_close_array(m, c);
2125         else if (c->enclosing == SD_BUS_TYPE_VARIANT)
2126                 r = bus_message_close_variant(m, c);
2127         else if (c->enclosing == SD_BUS_TYPE_STRUCT || c->enclosing == SD_BUS_TYPE_DICT_ENTRY)
2128                 r = bus_message_close_struct(m, c, true);
2129         else
2130                 assert_not_reached("Unknown container type");
2131
2132         free(c->signature);
2133         free(c->offsets);
2134
2135         return r;
2136 }
2137
2138 typedef struct {
2139         const char *types;
2140         unsigned n_struct;
2141         unsigned n_array;
2142 } TypeStack;
2143
2144 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
2145         assert(stack);
2146         assert(max > 0);
2147
2148         if (*i >= max)
2149                 return -EINVAL;
2150
2151         stack[*i].types = types;
2152         stack[*i].n_struct = n_struct;
2153         stack[*i].n_array = n_array;
2154         (*i)++;
2155
2156         return 0;
2157 }
2158
2159 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
2160         assert(stack);
2161         assert(max > 0);
2162         assert(types);
2163         assert(n_struct);
2164         assert(n_array);
2165
2166         if (*i <= 0)
2167                 return 0;
2168
2169         (*i)--;
2170         *types = stack[*i].types;
2171         *n_struct = stack[*i].n_struct;
2172         *n_array = stack[*i].n_array;
2173
2174         return 1;
2175 }
2176
2177 int bus_message_append_ap(
2178                 sd_bus_message *m,
2179                 const char *types,
2180                 va_list ap) {
2181
2182         unsigned n_array, n_struct;
2183         TypeStack stack[BUS_CONTAINER_DEPTH];
2184         unsigned stack_ptr = 0;
2185         int r;
2186
2187         assert(m);
2188
2189         if (!types)
2190                 return 0;
2191
2192         n_array = (unsigned) -1;
2193         n_struct = strlen(types);
2194
2195         for (;;) {
2196                 const char *t;
2197
2198                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2199                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2200                         if (r < 0)
2201                                 return r;
2202                         if (r == 0)
2203                                 break;
2204
2205                         r = sd_bus_message_close_container(m);
2206                         if (r < 0)
2207                                 return r;
2208
2209                         continue;
2210                 }
2211
2212                 t = types;
2213                 if (n_array != (unsigned) -1)
2214                         n_array --;
2215                 else {
2216                         types ++;
2217                         n_struct--;
2218                 }
2219
2220                 switch (*t) {
2221
2222                 case SD_BUS_TYPE_BYTE: {
2223                         uint8_t x;
2224
2225                         x = (uint8_t) va_arg(ap, int);
2226                         r = sd_bus_message_append_basic(m, *t, &x);
2227                         break;
2228                 }
2229
2230                 case SD_BUS_TYPE_BOOLEAN:
2231                 case SD_BUS_TYPE_INT32:
2232                 case SD_BUS_TYPE_UINT32:
2233                 case SD_BUS_TYPE_UNIX_FD: {
2234                         uint32_t x;
2235
2236                         /* We assume a boolean is the same as int32_t */
2237                         assert_cc(sizeof(int32_t) == sizeof(int));
2238
2239                         x = va_arg(ap, uint32_t);
2240                         r = sd_bus_message_append_basic(m, *t, &x);
2241                         break;
2242                 }
2243
2244                 case SD_BUS_TYPE_INT16:
2245                 case SD_BUS_TYPE_UINT16: {
2246                         uint16_t x;
2247
2248                         x = (uint16_t) va_arg(ap, int);
2249                         r = sd_bus_message_append_basic(m, *t, &x);
2250                         break;
2251                 }
2252
2253                 case SD_BUS_TYPE_INT64:
2254                 case SD_BUS_TYPE_UINT64:
2255                 case SD_BUS_TYPE_DOUBLE: {
2256                         uint64_t x;
2257
2258                         x = va_arg(ap, uint64_t);
2259                         r = sd_bus_message_append_basic(m, *t, &x);
2260                         break;
2261                 }
2262
2263                 case SD_BUS_TYPE_STRING:
2264                 case SD_BUS_TYPE_OBJECT_PATH:
2265                 case SD_BUS_TYPE_SIGNATURE: {
2266                         const char *x;
2267
2268                         x = va_arg(ap, const char*);
2269                         r = sd_bus_message_append_basic(m, *t, x);
2270                         break;
2271                 }
2272
2273                 case SD_BUS_TYPE_ARRAY: {
2274                         size_t k;
2275
2276                         r = signature_element_length(t + 1, &k);
2277                         if (r < 0)
2278                                 return r;
2279
2280                         {
2281                                 char s[k + 1];
2282                                 memcpy(s, t + 1, k);
2283                                 s[k] = 0;
2284
2285                                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2286                                 if (r < 0)
2287                                         return r;
2288                         }
2289
2290                         if (n_array == (unsigned) -1) {
2291                                 types += k;
2292                                 n_struct -= k;
2293                         }
2294
2295                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2296                         if (r < 0)
2297                                 return r;
2298
2299                         types = t + 1;
2300                         n_struct = k;
2301                         n_array = va_arg(ap, unsigned);
2302
2303                         break;
2304                 }
2305
2306                 case SD_BUS_TYPE_VARIANT: {
2307                         const char *s;
2308
2309                         s = va_arg(ap, const char*);
2310                         if (!s)
2311                                 return -EINVAL;
2312
2313                         r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2314                         if (r < 0)
2315                                 return r;
2316
2317                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2318                         if (r < 0)
2319                                 return r;
2320
2321                         types = s;
2322                         n_struct = strlen(s);
2323                         n_array = (unsigned) -1;
2324
2325                         break;
2326                 }
2327
2328                 case SD_BUS_TYPE_STRUCT_BEGIN:
2329                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2330                         size_t k;
2331
2332                         r = signature_element_length(t, &k);
2333                         if (r < 0)
2334                                 return r;
2335
2336                         {
2337                                 char s[k - 1];
2338
2339                                 memcpy(s, t + 1, k - 2);
2340                                 s[k - 2] = 0;
2341
2342                                 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2343                                 if (r < 0)
2344                                         return r;
2345                         }
2346
2347                         if (n_array == (unsigned) -1) {
2348                                 types += k - 1;
2349                                 n_struct -= k - 1;
2350                         }
2351
2352                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2353                         if (r < 0)
2354                                 return r;
2355
2356                         types = t + 1;
2357                         n_struct = k - 2;
2358                         n_array = (unsigned) -1;
2359
2360                         break;
2361                 }
2362
2363                 default:
2364                         r = -EINVAL;
2365                 }
2366
2367                 if (r < 0)
2368                         return r;
2369         }
2370
2371         return 1;
2372 }
2373
2374 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2375         va_list ap;
2376         int r;
2377
2378         assert_return(m, -EINVAL);
2379         assert_return(types, -EINVAL);
2380         assert_return(!m->sealed, -EPERM);
2381         assert_return(!m->poisoned, -ESTALE);
2382
2383         va_start(ap, types);
2384         r = bus_message_append_ap(m, types, ap);
2385         va_end(ap);
2386
2387         return r;
2388 }
2389
2390 _public_ int sd_bus_message_append_array_space(
2391                 sd_bus_message *m,
2392                 char type,
2393                 size_t size,
2394                 void **ptr) {
2395
2396         ssize_t align, sz;
2397         void *a;
2398         int r;
2399
2400         assert_return(m, -EINVAL);
2401         assert_return(!m->sealed, -EPERM);
2402         assert_return(bus_type_is_trivial(type), -EINVAL);
2403         assert_return(ptr || size == 0, -EINVAL);
2404         assert_return(!m->poisoned, -ESTALE);
2405
2406         align = bus_type_get_alignment(type);
2407         sz = bus_type_get_size(type);
2408
2409         assert_se(align > 0);
2410         assert_se(sz > 0);
2411
2412         if (size % sz != 0)
2413                 return -EINVAL;
2414
2415         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2416         if (r < 0)
2417                 return r;
2418
2419         a = message_extend_body(m, align, size, false);
2420         if (!a)
2421                 return -ENOMEM;
2422
2423         r = sd_bus_message_close_container(m);
2424         if (r < 0)
2425                 return r;
2426
2427         *ptr = a;
2428         return 0;
2429 }
2430
2431 _public_ int sd_bus_message_append_array(sd_bus_message *m,
2432                                          char type,
2433                                          const void *ptr,
2434                                          size_t size) {
2435         int r;
2436         void *p;
2437
2438         assert_return(m, -EINVAL);
2439         assert_return(!m->sealed, -EPERM);
2440         assert_return(bus_type_is_trivial(type), -EINVAL);
2441         assert_return(ptr || size == 0, -EINVAL);
2442         assert_return(!m->poisoned, -ESTALE);
2443
2444         r = sd_bus_message_append_array_space(m, type, size, &p);
2445         if (r < 0)
2446                 return r;
2447
2448         if (size > 0)
2449                 memcpy(p, ptr, size);
2450
2451         return 0;
2452 }
2453
2454 _public_ int sd_bus_message_append_array_iovec(
2455                 sd_bus_message *m,
2456                 char type,
2457                 const struct iovec *iov,
2458                 unsigned n) {
2459
2460         size_t size;
2461         unsigned i;
2462         void *p;
2463         int r;
2464
2465         assert_return(m, -EINVAL);
2466         assert_return(!m->sealed, -EPERM);
2467         assert_return(bus_type_is_trivial(type), -EINVAL);
2468         assert_return(iov || n == 0, -EINVAL);
2469         assert_return(!m->poisoned, -ESTALE);
2470
2471         size = IOVEC_TOTAL_SIZE(iov, n);
2472
2473         r = sd_bus_message_append_array_space(m, type, size, &p);
2474         if (r < 0)
2475                 return r;
2476
2477         for (i = 0; i < n; i++) {
2478
2479                 if (iov[i].iov_base)
2480                         memcpy(p, iov[i].iov_base, iov[i].iov_len);
2481                 else
2482                         memset(p, 0, iov[i].iov_len);
2483
2484                 p = (uint8_t*) p + iov[i].iov_len;
2485         }
2486
2487         return 0;
2488 }
2489
2490 _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
2491                                                char type,
2492                                                sd_memfd *memfd) {
2493         _cleanup_close_ int copy_fd = -1;
2494         struct bus_body_part *part;
2495         ssize_t align, sz;
2496         uint64_t size;
2497         void *a;
2498         int r;
2499
2500         if (!m)
2501                 return -EINVAL;
2502         if (!memfd)
2503                 return -EINVAL;
2504         if (m->sealed)
2505                 return -EPERM;
2506         if (!bus_type_is_trivial(type))
2507                 return -EINVAL;
2508         if (m->poisoned)
2509                 return -ESTALE;
2510
2511         r = sd_memfd_set_sealed(memfd, true);
2512         if (r < 0)
2513                 return r;
2514
2515         copy_fd = sd_memfd_dup_fd(memfd);
2516         if (copy_fd < 0)
2517                 return copy_fd;
2518
2519         r = sd_memfd_get_size(memfd, &size);
2520         if (r < 0)
2521                 return r;
2522
2523         align = bus_type_get_alignment(type);
2524         sz = bus_type_get_size(type);
2525
2526         assert_se(align > 0);
2527         assert_se(sz > 0);
2528
2529         if (size % sz != 0)
2530                 return -EINVAL;
2531
2532         if (size > (uint64_t) (uint32_t) -1)
2533                 return -EINVAL;
2534
2535         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2536         if (r < 0)
2537                 return r;
2538
2539         a = message_extend_body(m, align, 0, false);
2540         if (!a)
2541                 return -ENOMEM;
2542
2543         part = message_append_part(m);
2544         if (!part)
2545                 return -ENOMEM;
2546
2547         part->memfd = copy_fd;
2548         part->sealed = true;
2549         part->size = size;
2550         copy_fd = -1;
2551
2552         message_extend_containers(m, size);
2553         m->header->body_size += size;
2554
2555         return sd_bus_message_close_container(m);
2556 }
2557
2558 _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2559         _cleanup_close_ int copy_fd = -1;
2560         struct bus_body_part *part;
2561         struct bus_container *c;
2562         uint64_t size;
2563         void *a;
2564         int r;
2565
2566         assert_return(m, -EINVAL);
2567         assert_return(memfd, -EINVAL);
2568         assert_return(!m->sealed, -EPERM);
2569         assert_return(!m->poisoned, -ESTALE);
2570
2571         r = sd_memfd_set_sealed(memfd, true);
2572         if (r < 0)
2573                 return r;
2574
2575         copy_fd = sd_memfd_dup_fd(memfd);
2576         if (copy_fd < 0)
2577                 return copy_fd;
2578
2579         r = sd_memfd_get_size(memfd, &size);
2580         if (r < 0)
2581                 return r;
2582
2583         /* We require this to be NUL terminated */
2584         if (size == 0)
2585                 return -EINVAL;
2586
2587         if (size > (uint64_t) (uint32_t) -1)
2588                 return -EINVAL;
2589
2590         c = message_get_container(m);
2591         if (c->signature && c->signature[c->index]) {
2592                 /* Container signature is already set */
2593
2594                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2595                         return -ENXIO;
2596         } else {
2597                 char *e;
2598
2599                 /* Maybe we can append to the signature? But only if this is the top-level container*/
2600                 if (c->enclosing != 0)
2601                         return -ENXIO;
2602
2603                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2604                 if (!e) {
2605                         m->poisoned = true;
2606                         return -ENOMEM;
2607                 }
2608         }
2609
2610         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
2611                 a = message_extend_body(m, 4, 4, false);
2612                 if (!a)
2613                         return -ENOMEM;
2614
2615                 *(uint32_t*) a = size - 1;
2616         }
2617
2618         part = message_append_part(m);
2619         if (!part)
2620                 return -ENOMEM;
2621
2622         part->memfd = copy_fd;
2623         part->sealed = true;
2624         part->size = size;
2625         copy_fd = -1;
2626
2627         m->header->body_size += size;
2628         message_extend_containers(m, size);
2629
2630         if (BUS_MESSAGE_IS_GVARIANT(m)) {
2631                 r = message_add_offset(m, m->header->body_size);
2632                 if (r < 0) {
2633                         m->poisoned = true;
2634                         return -ENOMEM;
2635                 }
2636         }
2637
2638         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2639                 c->index++;
2640
2641         return 0;
2642 }
2643
2644 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2645         char **i;
2646         int r;
2647
2648         assert_return(m, -EINVAL);
2649         assert_return(!m->sealed, -EPERM);
2650         assert_return(!m->poisoned, -ESTALE);
2651
2652         r = sd_bus_message_open_container(m, 'a', "s");
2653         if (r < 0)
2654                 return r;
2655
2656         STRV_FOREACH(i, l) {
2657                 r = sd_bus_message_append_basic(m, 's', *i);
2658                 if (r < 0)
2659                         return r;
2660         }
2661
2662         return sd_bus_message_close_container(m);
2663 }
2664
2665 static int bus_message_close_header(sd_bus_message *m) {
2666         uint8_t *a;
2667         size_t sz, i;
2668
2669         assert(m);
2670
2671         if (!BUS_MESSAGE_IS_GVARIANT(m))
2672                 return 0;
2673
2674         if (m->n_header_offsets < 1)
2675                 return 0;
2676
2677         assert(m->header->fields_size == m->header_offsets[m->n_header_offsets-1]);
2678
2679         sz = determine_word_size(m->header->fields_size, m->n_header_offsets);
2680
2681         a = message_extend_fields(m, 1, sz * m->n_header_offsets, false);
2682         if (!a)
2683                 return -ENOMEM;
2684
2685         for (i = 0; i < m->n_header_offsets; i++)
2686                 write_word_le(a + sz*i, sz, m->header_offsets[i]);
2687
2688         return 0;
2689 }
2690
2691 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2692         struct bus_body_part *part;
2693         size_t l, a;
2694         unsigned i;
2695         int r;
2696
2697         assert(m);
2698
2699         if (m->sealed)
2700                 return -EPERM;
2701
2702         if (m->n_containers > 0)
2703                 return -EBADMSG;
2704
2705         if (m->poisoned)
2706                 return -ESTALE;
2707
2708         /* In vtables the return signature of method calls is listed,
2709          * let's check if they match if this is a response */
2710         if (m->header->type == SD_BUS_MESSAGE_METHOD_RETURN &&
2711             m->enforced_reply_signature &&
2712             !streq(strempty(m->root_container.signature), m->enforced_reply_signature))
2713                 return -ENOMSG;
2714
2715         /* If gvariant marshalling is used we need to close the body structure */
2716         r = bus_message_close_struct(m, &m->root_container, false);
2717         if (r < 0)
2718                 return r;
2719
2720         /* If there's a non-trivial signature set, then add it in here */
2721         if (!isempty(m->root_container.signature)) {
2722                 r = message_append_field_signature(m, BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2723                 if (r < 0)
2724                         return r;
2725         }
2726
2727         if (m->n_fds > 0) {
2728                 r = message_append_field_uint32(m, BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2729                 if (r < 0)
2730                         return r;
2731         }
2732
2733         r = bus_message_close_header(m);
2734         if (r < 0)
2735                 return r;
2736
2737         m->header->serial = serial;
2738
2739         /* Add padding at the end of the fields part, since we know
2740          * the body needs to start at an 8 byte alignment. We made
2741          * sure we allocated enough space for this, so all we need to
2742          * do here is to zero it out. */
2743         l = BUS_MESSAGE_FIELDS_SIZE(m);
2744         a = ALIGN8(l) - l;
2745         if (a > 0)
2746                 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
2747
2748         /* If this is something we can send as memfd, then let's seal
2749         the memfd now. Note that we can send memfds as payload only
2750         for directed messages, and not for broadcasts. */
2751         if (m->destination && m->bus && m->bus->use_memfd) {
2752                 MESSAGE_FOREACH_PART(part, i, m)
2753                         if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
2754                                 bus_body_part_unmap(part);
2755
2756                                 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
2757                                         part->sealed = true;
2758                         }
2759         }
2760
2761         m->root_container.end = BUS_MESSAGE_BODY_SIZE(m);
2762         m->root_container.index = 0;
2763         m->root_container.offset_index = 0;
2764         m->root_container.item_size = m->root_container.n_offsets > 0 ? m->root_container.offsets[0] : 0;
2765
2766         m->sealed = true;
2767
2768         return 0;
2769 }
2770
2771 int bus_body_part_map(struct bus_body_part *part) {
2772         void *p;
2773         size_t psz;
2774
2775         assert_se(part);
2776
2777         if (part->data)
2778                 return 0;
2779
2780         if (part->size <= 0)
2781                 return 0;
2782
2783         /* For smaller zero parts (as used for padding) we don't need to map anything... */
2784         if (part->memfd < 0 && part->is_zero && part->size < 8) {
2785                 static const uint8_t zeroes[7] = { };
2786                 part->data = (void*) zeroes;
2787                 return 0;
2788         }
2789
2790         psz = PAGE_ALIGN(part->size);
2791
2792         if (part->memfd >= 0)
2793                 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2794         else if (part->is_zero)
2795                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2796         else
2797                 return -EINVAL;
2798
2799         if (p == MAP_FAILED)
2800                 return -errno;
2801
2802         part->mapped = psz;
2803         part->data = p;
2804         part->munmap_this = true;
2805
2806         return 0;
2807 }
2808
2809 void bus_body_part_unmap(struct bus_body_part *part) {
2810
2811         assert_se(part);
2812
2813         if (part->memfd < 0)
2814                 return;
2815
2816         if (!part->data)
2817                 return;
2818
2819         if (!part->munmap_this)
2820                 return;
2821
2822         assert_se(munmap(part->data, part->mapped) == 0);
2823
2824         part->data = NULL;
2825         part->mapped = 0;
2826         part->munmap_this = false;
2827
2828         return;
2829 }
2830
2831 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2832         size_t k, start, end;
2833
2834         assert(rindex);
2835         assert(align > 0);
2836
2837         start = ALIGN_TO((size_t) *rindex, align);
2838         end = start + nbytes;
2839
2840         if (end > sz)
2841                 return -EBADMSG;
2842
2843         /* Verify that padding is 0 */
2844         for (k = *rindex; k < start; k++)
2845                 if (((const uint8_t*) p)[k] != 0)
2846                         return -EBADMSG;
2847
2848         if (r)
2849                 *r = (uint8_t*) p + start;
2850
2851         *rindex = end;
2852
2853         return 1;
2854 }
2855
2856 static bool message_end_of_signature(sd_bus_message *m) {
2857         struct bus_container *c;
2858
2859         assert(m);
2860
2861         c = message_get_container(m);
2862         return !c->signature || c->signature[c->index] == 0;
2863 }
2864
2865 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2866         struct bus_container *c;
2867
2868         assert(m);
2869
2870         c = message_get_container(m);
2871         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2872                 return false;
2873
2874         if (BUS_MESSAGE_IS_GVARIANT(m))
2875                 return index >= c->end;
2876         else {
2877                 assert(c->array_size);
2878                 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2879         }
2880 }
2881
2882 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2883         assert_return(m, -EINVAL);
2884         assert_return(m->sealed, -EPERM);
2885
2886         if (complete && m->n_containers > 0)
2887                 return false;
2888
2889         if (message_end_of_signature(m))
2890                 return true;
2891
2892         if (message_end_of_array(m, m->rindex))
2893                 return true;
2894
2895         return false;
2896 }
2897
2898 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2899         struct bus_body_part *part;
2900         size_t begin;
2901         int r;
2902
2903         assert(m);
2904
2905         if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2906                 part = m->cached_rindex_part;
2907                 begin = m->cached_rindex_part_begin;
2908         } else {
2909                 part = &m->body;
2910                 begin = 0;
2911         }
2912
2913         while (part) {
2914                 if (index < begin)
2915                         return NULL;
2916
2917                 if (index + sz <= begin + part->size) {
2918
2919                         r = bus_body_part_map(part);
2920                         if (r < 0)
2921                                 return NULL;
2922
2923                         if (p)
2924                                 *p = (uint8_t*) part->data + index - begin;
2925
2926                         m->cached_rindex_part = part;
2927                         m->cached_rindex_part_begin = begin;
2928
2929                         return part;
2930                 }
2931
2932                 begin += part->size;
2933                 part = part->next;
2934         }
2935
2936         return NULL;
2937 }
2938
2939 static int container_next_item(sd_bus_message *m, struct bus_container *c, size_t *rindex) {
2940         int r;
2941
2942         assert(m);
2943         assert(c);
2944         assert(rindex);
2945
2946         if (!BUS_MESSAGE_IS_GVARIANT(m))
2947                 return 0;
2948
2949         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2950                 int sz;
2951
2952                 sz = bus_gvariant_get_size(c->signature);
2953                 if (sz < 0) {
2954                         int alignment;
2955
2956                         if (c->offset_index+1 >= c->n_offsets)
2957                                 goto end;
2958
2959                         /* Variable-size array */
2960
2961                         alignment = bus_gvariant_get_alignment(c->signature);
2962                         assert(alignment > 0);
2963
2964                         *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
2965                         c->item_size = c->offsets[c->offset_index+1] - *rindex;
2966                 } else {
2967                         /* Fixed-size array */
2968                         *rindex += sz;
2969                         c->item_size = sz;
2970                 }
2971
2972                 c->offset_index++;
2973
2974         } else if (c->enclosing == 0 ||
2975                    c->enclosing == SD_BUS_TYPE_STRUCT ||
2976                    c->enclosing == SD_BUS_TYPE_DICT_ENTRY) {
2977
2978                 int alignment;
2979                 size_t n, j;
2980
2981                 if (c->offset_index+1 >= c->n_offsets)
2982                         goto end;
2983
2984                 r = signature_element_length(c->signature + c->index, &n);
2985                 if (r < 0)
2986                         return r;
2987
2988                 r = signature_element_length(c->signature + c->index + n, &j);
2989                 if (r < 0)
2990                         return r;
2991                 else {
2992                         char t[j+1];
2993                         memcpy(t, c->signature + c->index + n, j);
2994                         t[j] = 0;
2995
2996                         alignment = bus_gvariant_get_alignment(t);
2997                 }
2998
2999                 assert(alignment > 0);
3000
3001                 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3002                 c->item_size = c->offsets[c->offset_index+1] - *rindex;
3003
3004                 c->offset_index++;
3005
3006         } else if (c->enclosing == SD_BUS_TYPE_VARIANT)
3007                 goto end;
3008         else
3009                 assert_not_reached("Unknown container type");
3010
3011         return 0;
3012
3013 end:
3014         /* Reached the end */
3015         *rindex = c->end;
3016         c->item_size = 0;
3017         return 0;
3018 }
3019
3020
3021 static int message_peek_body(
3022                 sd_bus_message *m,
3023                 size_t *rindex,
3024                 size_t align,
3025                 size_t nbytes,
3026                 void **ret) {
3027
3028         size_t k, start, end, padding;
3029         struct bus_body_part *part;
3030         uint8_t *q;
3031
3032         assert(m);
3033         assert(rindex);
3034         assert(align > 0);
3035
3036         if (message_end_of_array(m, *rindex))
3037                 return 0;
3038
3039         start = ALIGN_TO((size_t) *rindex, align);
3040         padding = start - *rindex;
3041         end = start + nbytes;
3042
3043         if (end > BUS_MESSAGE_BODY_SIZE(m))
3044                 return -EBADMSG;
3045
3046         part = find_part(m, *rindex, padding, (void**) &q);
3047         if (!part)
3048                 return -EBADMSG;
3049
3050         if (q) {
3051                 /* Verify padding */
3052                 for (k = 0; k < padding; k++)
3053                         if (q[k] != 0)
3054                                 return -EBADMSG;
3055         }
3056
3057         part = find_part(m, start, nbytes, (void**) &q);
3058         if (!part || !q)
3059                 return -EBADMSG;
3060
3061         *rindex = end;
3062
3063         if (ret)
3064                 *ret = q;
3065
3066         return 1;
3067 }
3068
3069 static bool validate_nul(const char *s, size_t l) {
3070
3071         /* Check for NUL chars in the string */
3072         if (memchr(s, 0, l))
3073                 return false;
3074
3075         /* Check for NUL termination */
3076         if (s[l] != 0)
3077                 return false;
3078
3079         return true;
3080 }
3081
3082 static bool validate_string(const char *s, size_t l) {
3083
3084         if (!validate_nul(s, l))
3085                 return false;
3086
3087         /* Check if valid UTF8 */
3088         if (!utf8_is_valid(s))
3089                 return false;
3090
3091         return true;
3092 }
3093
3094 static bool validate_signature(const char *s, size_t l) {
3095
3096         if (!validate_nul(s, l))
3097                 return false;
3098
3099         /* Check if valid signature */
3100         if (!signature_is_valid(s, true))
3101                 return false;
3102
3103         return true;
3104 }
3105
3106 static bool validate_object_path(const char *s, size_t l) {
3107
3108         if (!validate_nul(s, l))
3109                 return false;
3110
3111         if (!object_path_is_valid(s))
3112                 return false;
3113
3114         return true;
3115 }
3116
3117 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
3118         struct bus_container *c;
3119         size_t rindex;
3120         void *q;
3121         int r;
3122
3123         assert_return(m, -EINVAL);
3124         assert_return(m->sealed, -EPERM);
3125         assert_return(bus_type_is_basic(type), -EINVAL);
3126
3127         if (message_end_of_signature(m))
3128                 return -ENXIO;
3129
3130         if (message_end_of_array(m, m->rindex))
3131                 return 0;
3132
3133         c = message_get_container(m);
3134         if (c->signature[c->index] != type)
3135                 return -ENXIO;
3136
3137         rindex = m->rindex;
3138
3139         if (BUS_MESSAGE_IS_GVARIANT(m)) {
3140
3141                 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
3142                         bool ok;
3143
3144                         r = message_peek_body(m, &rindex, 1, c->item_size, &q);
3145                         if (r <= 0)
3146                                 return r;
3147
3148                         if (type == SD_BUS_TYPE_STRING)
3149                                 ok = validate_string(q, c->item_size-1);
3150                         else if (type == SD_BUS_TYPE_OBJECT_PATH)
3151                                 ok = validate_object_path(q, c->item_size-1);
3152                         else
3153                                 ok = validate_signature(q, c->item_size-1);
3154
3155                         if (!ok)
3156                                 return -EBADMSG;
3157
3158                         if (p)
3159                                 *(const char**) p = q;
3160                 } else {
3161                         int sz, align;
3162
3163                         sz = bus_gvariant_get_size(CHAR_TO_STR(type));
3164                         assert(sz > 0);
3165                         if ((size_t) sz != c->item_size)
3166                                 return -EBADMSG;
3167
3168                         align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
3169                         assert(align > 0);
3170
3171                         r = message_peek_body(m, &rindex, align, c->item_size, &q);
3172                         if (r <= 0)
3173                                 return r;
3174
3175                         switch (type) {
3176
3177                         case SD_BUS_TYPE_BYTE:
3178                                 if (p)
3179                                         *(uint8_t*) p = *(uint8_t*) q;
3180                                 break;
3181
3182                         case SD_BUS_TYPE_BOOLEAN:
3183                                 if (p)
3184                                         *(int*) p = !!*(uint8_t*) q;
3185                                 break;
3186
3187                         case SD_BUS_TYPE_INT16:
3188                         case SD_BUS_TYPE_UINT16:
3189                                 if (p)
3190                                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3191                                 break;
3192
3193                         case SD_BUS_TYPE_INT32:
3194                         case SD_BUS_TYPE_UINT32:
3195                                 if (p)
3196                                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3197                                 break;
3198
3199                         case SD_BUS_TYPE_INT64:
3200                         case SD_BUS_TYPE_UINT64:
3201                         case SD_BUS_TYPE_DOUBLE:
3202                                 if (p)
3203                                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3204                                 break;
3205
3206                         case SD_BUS_TYPE_UNIX_FD: {
3207                                 uint32_t j;
3208
3209                                 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3210                                 if (j >= m->n_fds)
3211                                         return -EBADMSG;
3212
3213                                 if (p)
3214                                         *(int*) p = m->fds[j];
3215
3216                                 break;
3217                         }
3218
3219                         default:
3220                                 assert_not_reached("unexpected type");
3221                         }
3222                 }
3223
3224                 r = container_next_item(m, c, &rindex);
3225                 if (r < 0)
3226                         return r;
3227         } else {
3228
3229                 rindex = m->rindex;
3230
3231                 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH)) {
3232                         uint32_t l;
3233                         bool ok;
3234
3235                         r = message_peek_body(m, &rindex, 4, 4, &q);
3236                         if (r <= 0)
3237                                 return r;
3238
3239                         l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3240                         r = message_peek_body(m, &rindex, 1, l+1, &q);
3241                         if (r < 0)
3242                                 return r;
3243                         if (r == 0)
3244                                 return -EBADMSG;
3245
3246                         if (type == SD_BUS_TYPE_OBJECT_PATH)
3247                                 ok = validate_object_path(q, l);
3248                         else
3249                                 ok = validate_string(q, l);
3250                         if (!ok)
3251                                 return -EBADMSG;
3252
3253                         if (p)
3254                                 *(const char**) p = q;
3255
3256                 } else if (type == SD_BUS_TYPE_SIGNATURE) {
3257                         uint8_t l;
3258
3259                         r = message_peek_body(m, &rindex, 1, 1, &q);
3260                         if (r <= 0)
3261                                 return r;
3262
3263                         l = *(uint8_t*) q;
3264                         r = message_peek_body(m, &rindex, 1, l+1, &q);
3265                         if (r < 0)
3266                                 return r;
3267                         if (r == 0)
3268                                 return -EBADMSG;
3269
3270                         if (!validate_signature(q, l))
3271                                 return -EBADMSG;
3272
3273                         if (p)
3274                                 *(const char**) p = q;
3275
3276                 } else {
3277                         ssize_t sz, align;
3278
3279                         align = bus_type_get_alignment(type);
3280                         assert(align > 0);
3281
3282                         sz = bus_type_get_size(type);
3283                         assert(sz > 0);
3284
3285                         r = message_peek_body(m, &rindex, align, sz, &q);
3286                         if (r <= 0)
3287                                 return r;
3288
3289                         switch (type) {
3290
3291                         case SD_BUS_TYPE_BYTE:
3292                                 if (p)
3293                                         *(uint8_t*) p = *(uint8_t*) q;
3294                                 break;
3295
3296                         case SD_BUS_TYPE_BOOLEAN:
3297                                 if (p)
3298                                         *(int*) p = !!*(uint32_t*) q;
3299                                 break;
3300
3301                         case SD_BUS_TYPE_INT16:
3302                         case SD_BUS_TYPE_UINT16:
3303                                 if (p)
3304                                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3305                                 break;
3306
3307                         case SD_BUS_TYPE_INT32:
3308                         case SD_BUS_TYPE_UINT32:
3309                                 if (p)
3310                                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3311                                 break;
3312
3313                         case SD_BUS_TYPE_INT64:
3314                         case SD_BUS_TYPE_UINT64:
3315                         case SD_BUS_TYPE_DOUBLE:
3316                                 if (p)
3317                                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3318                                 break;
3319
3320                         case SD_BUS_TYPE_UNIX_FD: {
3321                                 uint32_t j;
3322
3323                                 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3324                                 if (j >= m->n_fds)
3325                                         return -EBADMSG;
3326
3327                                 if (p)
3328                                         *(int*) p = m->fds[j];
3329                                 break;
3330                         }
3331
3332                         default:
3333                                 assert_not_reached("Unknown basic type...");
3334                         }
3335                 }
3336         }
3337
3338         m->rindex = rindex;
3339
3340         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3341                 c->index++;
3342
3343         return 1;
3344 }
3345
3346 static int bus_message_enter_array(
3347                 sd_bus_message *m,
3348                 struct bus_container *c,
3349                 const char *contents,
3350                 uint32_t **array_size,
3351                 size_t *item_size,
3352                 size_t **offsets,
3353                 size_t *n_offsets) {
3354
3355         size_t rindex;
3356         void *q;
3357         int r, alignment;
3358
3359         assert(m);
3360         assert(c);
3361         assert(contents);
3362         assert(array_size);
3363         assert(item_size);
3364         assert(offsets);
3365         assert(n_offsets);
3366
3367         if (!signature_is_single(contents, true))
3368                 return -EINVAL;
3369
3370         if (!c->signature || c->signature[c->index] == 0)
3371                 return -ENXIO;
3372
3373         if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
3374                 return -ENXIO;
3375
3376         if (!startswith(c->signature + c->index + 1, contents))
3377                 return -ENXIO;
3378
3379         rindex = m->rindex;
3380
3381         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3382                 /* dbus1 */
3383
3384                 r = message_peek_body(m, &rindex, 4, 4, &q);
3385                 if (r <= 0)
3386                         return r;
3387
3388                 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
3389                         return -EBADMSG;
3390
3391                 alignment = bus_type_get_alignment(contents[0]);
3392                 if (alignment < 0)
3393                         return alignment;
3394
3395                 r = message_peek_body(m, &rindex, alignment, 0, NULL);
3396                 if (r < 0)
3397                         return r;
3398                 if (r == 0)
3399                         return -EBADMSG;
3400
3401                 *array_size = (uint32_t*) q;
3402
3403         } else if (c->item_size <= 0) {
3404
3405                 /* gvariant: empty array */
3406                 *item_size = 0;
3407                 *offsets = NULL;
3408                 *n_offsets = 0;
3409
3410         } else if (bus_gvariant_is_fixed_size(contents)) {
3411
3412                 /* gvariant: fixed length array */
3413                 *item_size = bus_gvariant_get_size(contents);
3414                 *offsets = NULL;
3415                 *n_offsets = 0;
3416
3417         } else {
3418                 size_t where, p = 0, framing, sz;
3419                 unsigned i;
3420
3421                 /* gvariant: variable length array */
3422                 sz = determine_word_size(c->item_size, 0);
3423
3424                 where = rindex + c->item_size - sz;
3425                 r = message_peek_body(m, &where, 1, sz, &q);
3426                 if (r < 0)
3427                         return r;
3428                 if (r == 0)
3429                         return -EBADMSG;
3430
3431                 framing = read_word_le(q, sz);
3432                 if (framing > c->item_size - sz)
3433                         return -EBADMSG;
3434                 if ((c->item_size - framing) % sz != 0)
3435                         return -EBADMSG;
3436
3437                 *n_offsets = (c->item_size - framing) / sz;
3438
3439                 where = rindex + framing;
3440                 r = message_peek_body(m, &where, 1, *n_offsets * sz, &q);
3441                 if (r < 0)
3442                         return r;
3443                 if (r == 0)
3444                         return -EBADMSG;
3445
3446                 *offsets = new(size_t, *n_offsets);
3447                 if (!*offsets)
3448                         return -ENOMEM;
3449
3450                 for (i = 0; i < *n_offsets; i++) {
3451                         size_t x;
3452
3453                         x = read_word_le((uint8_t*) q + i * sz, sz);
3454                         if (x > c->item_size - sz)
3455                                 return -EBADMSG;
3456                         if (x < p)
3457                                 return -EBADMSG;
3458
3459                         (*offsets)[i] = rindex + x;
3460                         p = x;
3461                 }
3462
3463                 *item_size = (*offsets)[0] - rindex;
3464         }
3465
3466         m->rindex = rindex;
3467
3468         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3469                 c->index += 1 + strlen(contents);
3470
3471         return 1;
3472 }
3473
3474 static int bus_message_enter_variant(
3475                 sd_bus_message *m,
3476                 struct bus_container *c,
3477                 const char *contents,
3478                 size_t *item_size) {
3479
3480         size_t rindex;
3481         uint8_t l;
3482         void *q;
3483         int r;
3484
3485         assert(m);
3486         assert(c);
3487         assert(contents);
3488         assert(item_size);
3489
3490         if (!signature_is_single(contents, false))
3491                 return -EINVAL;
3492
3493         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
3494                 return -EINVAL;
3495
3496         if (!c->signature || c->signature[c->index] == 0)
3497                 return -ENXIO;
3498
3499         if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
3500                 return -ENXIO;
3501
3502         rindex = m->rindex;
3503
3504         if (BUS_MESSAGE_IS_GVARIANT(m)) {
3505                 size_t k, where;
3506
3507                 k = strlen(contents);
3508                 if (1+k > c->item_size)
3509                         return -EBADMSG;
3510
3511                 where = rindex + c->item_size - (1+k);
3512                 r = message_peek_body(m, &where, 1, 1+k, &q);
3513                 if (r < 0)
3514                         return r;
3515                 if (r == 0)
3516                         return -EBADMSG;
3517
3518                 if (*(char*) q != 0)
3519                         return -EBADMSG;
3520
3521                 if (memcmp((uint8_t*) q+1, contents, k))
3522                         return -ENXIO;
3523
3524                 *item_size = c->item_size - (1+k);
3525
3526         } else {
3527                 r = message_peek_body(m, &rindex, 1, 1, &q);
3528                 if (r < 0)
3529                         return r;
3530                 if (r == 0)
3531                         return -EBADMSG;
3532
3533                 l = *(uint8_t*) q;
3534                 r = message_peek_body(m, &rindex, 1, l+1, &q);
3535                 if (r < 0)
3536                         return r;
3537                 if (r == 0)
3538                         return -EBADMSG;
3539
3540                 if (!validate_signature(q, l))
3541                         return -EBADMSG;
3542
3543                 if (!streq(q, contents))
3544                         return -ENXIO;
3545         }
3546
3547         m->rindex = rindex;
3548
3549         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3550                 c->index++;
3551
3552         return 1;
3553 }
3554
3555 static int build_struct_offsets(
3556                 sd_bus_message *m,
3557                 const char *signature,
3558                 size_t size,
3559                 size_t *item_size,
3560                 size_t **offsets,
3561                 size_t *n_offsets) {
3562
3563         unsigned n_variable = 0, n_total = 0, v;
3564         size_t previous = 0, where;
3565         const char *p;
3566         size_t sz;
3567         void *q;
3568         int r;
3569
3570         assert(m);
3571         assert(signature);
3572         assert(item_size);
3573         assert(offsets);
3574         assert(n_offsets);
3575
3576         sz = determine_word_size(size, 0);
3577
3578         /* First, loop over signature and count variable elements and
3579          * elements in general. We use this to know how large the
3580          * offset array is at the end of the structure. Note that
3581          * GVariant only stores offsets for all variable size elements
3582          * that are not the last item. */
3583
3584         p = signature;
3585         while (*p != 0) {
3586                 size_t n;
3587
3588                 r = signature_element_length(p, &n);
3589                 if (r < 0)
3590                         return r;
3591                 else {
3592                         char t[n+1];
3593
3594                         memcpy(t, p, n);
3595                         t[n] = 0;
3596
3597                         r = bus_gvariant_is_fixed_size(t);
3598                 }
3599
3600                 if (r < 0)
3601                         return r;
3602                 if (r == 0 && p[n] != 0) /* except the last item */
3603                         n_variable ++;
3604                 n_total++;
3605
3606                 p += n;
3607         }
3608
3609         if (size < n_variable * sz)
3610                 return -EBADMSG;
3611
3612         where = m->rindex + size - (n_variable * sz);
3613         r = message_peek_body(m, &where, 1, n_variable * sz, &q);
3614         if (r < 0)
3615                 return r;
3616         if (r == 0)
3617                 return -EBADMSG;
3618
3619         v = n_variable;
3620
3621         *offsets = new(size_t, n_total);
3622         if (!*offsets)
3623                 return -ENOMEM;
3624
3625         *n_offsets = 0;
3626
3627         /* Second, loop again and build an offset table */
3628         p = signature;
3629         while (*p != 0) {
3630                 size_t n, offset;
3631                 int k;
3632
3633                 r = signature_element_length(p, &n);
3634                 if (r < 0)
3635                         return r;
3636                 else {
3637                         char t[n+1];
3638
3639                         memcpy(t, p, n);
3640                         t[n] = 0;
3641
3642                         k = bus_gvariant_get_size(t);
3643                         if (k < 0) {
3644                                 size_t x;
3645
3646                                 /* variable size */
3647                                 if (v > 0) {
3648                                         v--;
3649
3650                                         x = read_word_le((uint8_t*) q + v*sz, sz);
3651                                         if (x >= size)
3652                                                 return -EBADMSG;
3653                                         if (m->rindex + x < previous)
3654                                                 return -EBADMSG;
3655                                 } else
3656                                         /* The last item's end
3657                                          * is determined from
3658                                          * the start of the
3659                                          * offset array */
3660                                         x = size - (n_variable * sz);
3661
3662                                 offset = m->rindex + x;
3663
3664                         } else {
3665                                 size_t align;
3666
3667                                 /* fixed size */
3668                                 align = bus_gvariant_get_alignment(t);
3669                                 assert(align > 0);
3670
3671                                 offset = (*n_offsets == 0 ? m->rindex  : ALIGN_TO((*offsets)[*n_offsets-1], align)) + k;
3672                         }
3673                 }
3674
3675                 previous = (*offsets)[(*n_offsets)++] = offset;
3676                 p += n;
3677         }
3678
3679         assert(v == 0);
3680         assert(*n_offsets == n_total);
3681
3682         *item_size = (*offsets)[0] - m->rindex;
3683         return 0;
3684 }
3685
3686 static int enter_struct_or_dict_entry(
3687                 sd_bus_message *m,
3688                 struct bus_container *c,
3689                 const char *contents,
3690                 size_t *item_size,
3691                 size_t **offsets,
3692                 size_t *n_offsets) {
3693
3694         int r;
3695
3696         assert(m);
3697         assert(c);
3698         assert(contents);
3699         assert(item_size);
3700         assert(offsets);
3701         assert(n_offsets);
3702
3703         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3704
3705                 /* dbus1 */
3706                 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
3707                 if (r <= 0)
3708                         return r;
3709
3710         } else if (c->item_size <= 0) {
3711
3712                 /* gvariant empty struct */
3713                 *item_size = 0;
3714                 *offsets = NULL;
3715                 *n_offsets = 0;
3716         } else
3717                 /* gvariant with contents */
3718                 return build_struct_offsets(m, contents, c->item_size, item_size, offsets, n_offsets);
3719
3720         return 0;
3721 }
3722
3723 static int bus_message_enter_struct(
3724                 sd_bus_message *m,
3725                 struct bus_container *c,
3726                 const char *contents,
3727                 size_t *item_size,
3728                 size_t **offsets,
3729                 size_t *n_offsets) {
3730
3731         size_t l;
3732         int r;
3733
3734         assert(m);
3735         assert(c);
3736         assert(contents);
3737         assert(item_size);
3738         assert(offsets);
3739         assert(n_offsets);
3740
3741         if (!signature_is_valid(contents, false))
3742                 return -EINVAL;
3743
3744         if (!c->signature || c->signature[c->index] == 0)
3745                 return -ENXIO;
3746
3747         l = strlen(contents);
3748
3749         if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
3750             !startswith(c->signature + c->index + 1, contents) ||
3751             c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
3752                 return -ENXIO;
3753
3754         r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
3755         if (r < 0)
3756                 return r;
3757
3758         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3759                 c->index += 1 + l + 1;
3760
3761         return 1;
3762 }
3763
3764 static int bus_message_enter_dict_entry(
3765                 sd_bus_message *m,
3766                 struct bus_container *c,
3767                 const char *contents,
3768                 size_t *item_size,
3769                 size_t **offsets,
3770                 size_t *n_offsets) {
3771
3772         size_t l;
3773         int r;
3774
3775         assert(m);
3776         assert(c);
3777         assert(contents);
3778
3779         if (!signature_is_pair(contents))
3780                 return -EINVAL;
3781
3782         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3783                 return -ENXIO;
3784
3785         if (!c->signature || c->signature[c->index] == 0)
3786                 return 0;
3787
3788         l = strlen(contents);
3789
3790         if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
3791             !startswith(c->signature + c->index + 1, contents) ||
3792             c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
3793                 return -ENXIO;
3794
3795         r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
3796         if (r < 0)
3797                 return r;
3798
3799         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3800                 c->index += 1 + l + 1;
3801
3802         return 1;
3803 }
3804
3805 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
3806                                             char type,
3807                                             const char *contents) {
3808         struct bus_container *c, *w;
3809         uint32_t *array_size = NULL;
3810         char *signature;
3811         size_t before;
3812         size_t *offsets = NULL;
3813         size_t n_offsets = 0, item_size = 0;
3814         int r;
3815
3816         assert_return(m, -EINVAL);
3817         assert_return(m->sealed, -EPERM);
3818         assert_return(type != 0 || !contents, -EINVAL);
3819
3820         if (type == 0 || !contents) {
3821                 const char *cc;
3822                 char tt;
3823
3824                 /* Allow entering into anonymous containers */
3825                 r = sd_bus_message_peek_type(m, &tt, &cc);
3826                 if (r <= 0)
3827                         return r;
3828
3829                 if (type != 0 && type != tt)
3830                         return -ENXIO;
3831
3832                 if (contents && !streq(contents, cc))
3833                         return -ENXIO;
3834
3835                 type = tt;
3836                 contents = cc;
3837         }
3838
3839         /*
3840          * We enforce a global limit on container depth, that is much
3841          * higher than the 32 structs and 32 arrays the specification
3842          * mandates. This is simpler to implement for us, and we need
3843          * this only to ensure our container array doesn't grow
3844          * without bounds. We are happy to return any data from a
3845          * message as long as the data itself is valid, even if the
3846          * overall message might be not.
3847          *
3848          * Note that the message signature is validated when
3849          * parsing the headers, and that validation does check the
3850          * 32/32 limit.
3851          *
3852          * Note that the specification defines no limits on the depth
3853          * of stacked variants, but we do.
3854          */
3855         if (m->n_containers >= BUS_CONTAINER_DEPTH)
3856                 return -EBADMSG;
3857
3858         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
3859         if (!w)
3860                 return -ENOMEM;
3861         m->containers = w;
3862
3863         if (message_end_of_signature(m))
3864                 return -ENXIO;
3865
3866         if (message_end_of_array(m, m->rindex))
3867                 return 0;
3868
3869         c = message_get_container(m);
3870
3871         signature = strdup(contents);
3872         if (!signature)
3873                 return -ENOMEM;
3874
3875         c->saved_index = c->index;
3876         before = m->rindex;
3877
3878         if (type == SD_BUS_TYPE_ARRAY)
3879                 r = bus_message_enter_array(m, c, contents, &array_size, &item_size, &offsets, &n_offsets);
3880         else if (type == SD_BUS_TYPE_VARIANT)
3881                 r = bus_message_enter_variant(m, c, contents, &item_size);
3882         else if (type == SD_BUS_TYPE_STRUCT)
3883                 r = bus_message_enter_struct(m, c, contents, &item_size, &offsets, &n_offsets);
3884         else if (type == SD_BUS_TYPE_DICT_ENTRY)
3885                 r = bus_message_enter_dict_entry(m, c, contents, &item_size, &offsets, &n_offsets);
3886         else
3887                 r = -EINVAL;
3888
3889         if (r <= 0) {
3890                 free(signature);
3891                 free(offsets);
3892                 return r;
3893         }
3894
3895         /* OK, let's fill it in */
3896         w += m->n_containers++;
3897         w->enclosing = type;
3898         w->signature = signature;
3899         w->index = 0;
3900
3901         w->before = before;
3902         w->begin = m->rindex;
3903         w->end = m->rindex + c->item_size;
3904
3905         w->array_size = array_size;
3906         w->item_size = item_size;
3907         w->offsets = offsets;
3908         w->n_offsets = n_offsets;
3909         w->offset_index = 0;
3910
3911         return 1;
3912 }
3913
3914 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
3915         struct bus_container *c;
3916         int r;
3917
3918         assert_return(m, -EINVAL);
3919         assert_return(m->sealed, -EPERM);
3920         assert_return(m->n_containers > 0, -ENXIO);
3921
3922         c = message_get_container(m);
3923
3924         if (c->enclosing != SD_BUS_TYPE_ARRAY) {
3925                 if (c->signature && c->signature[c->index] != 0)
3926                         return -EBUSY;
3927         }
3928
3929         if (BUS_MESSAGE_IS_GVARIANT(m)) {
3930                 if (m->rindex < c->end)
3931                         return -EBUSY;
3932
3933         } else if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3934                 uint32_t l;
3935
3936                 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3937                 if (c->begin + l != m->rindex)
3938                         return -EBUSY;
3939         }
3940
3941         free(c->signature);
3942         free(c->offsets);
3943         m->n_containers--;
3944
3945         c = message_get_container(m);
3946
3947         r = container_next_item(m, c, &m->rindex);
3948         if (r < 0)
3949                 return r;
3950
3951         return 1;
3952 }
3953
3954 static void message_quit_container(sd_bus_message *m) {
3955         struct bus_container *c;
3956
3957         assert(m);
3958         assert(m->sealed);
3959         assert(m->n_containers > 0);
3960
3961         c = message_get_container(m);
3962
3963         /* Undo seeks */
3964         assert(m->rindex >= c->before);
3965         m->rindex = c->before;
3966
3967         /* Free container */
3968         free(c->signature);
3969         free(c->offsets);
3970         m->n_containers--;
3971
3972         /* Correct index of new top-level container */
3973         c = message_get_container(m);
3974         c->index = c->saved_index;
3975 }
3976
3977 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3978         struct bus_container *c;
3979         int r;
3980
3981         assert_return(m, -EINVAL);
3982         assert_return(m->sealed, -EPERM);
3983
3984         if (message_end_of_signature(m))
3985                 goto eof;
3986
3987         if (message_end_of_array(m, m->rindex))
3988                 goto eof;
3989
3990         c = message_get_container(m);
3991
3992         if (bus_type_is_basic(c->signature[c->index])) {
3993                 if (contents)
3994                         *contents = NULL;
3995                 if (type)
3996                         *type = c->signature[c->index];
3997                 return 1;
3998         }
3999
4000         if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
4001
4002                 if (contents) {
4003                         size_t l;
4004                         char *sig;
4005
4006                         r = signature_element_length(c->signature+c->index+1, &l);
4007                         if (r < 0)
4008                                 return r;
4009
4010                         assert(l >= 1);
4011
4012                         sig = strndup(c->signature + c->index + 1, l);
4013                         if (!sig)
4014                                 return -ENOMEM;
4015
4016                         free(m->peeked_signature);
4017                         m->peeked_signature = sig;
4018
4019                         *contents = sig;
4020                 }
4021
4022                 if (type)
4023                         *type = SD_BUS_TYPE_ARRAY;
4024
4025                 return 1;
4026         }
4027
4028         if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
4029             c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
4030
4031                 if (contents) {
4032                         size_t l;
4033                         char *sig;
4034
4035                         r = signature_element_length(c->signature+c->index, &l);
4036                         if (r < 0)
4037                                 return r;
4038
4039                         assert(l >= 2);
4040                         sig = strndup(c->signature + c->index + 1, l - 2);
4041                         if (!sig)
4042                                 return -ENOMEM;
4043
4044                         free(m->peeked_signature);
4045                         m->peeked_signature = sig;
4046
4047                         *contents = sig;
4048                 }
4049
4050                 if (type)
4051                         *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
4052
4053                 return 1;
4054         }
4055
4056         if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
4057                 if (contents) {
4058                         void *q;
4059
4060                         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4061                                 size_t k;
4062
4063                                 if (c->item_size < 2)
4064                                         return -EBADMSG;
4065
4066                                 /* Look for the NUL delimiter that
4067                                    separates the payload from the
4068                                    signature. Since the body might be
4069                                    in a different part that then the
4070                                    signature we map byte by byte. */
4071
4072                                 for (k = 2; k <= c->item_size; k++) {
4073                                         size_t where;
4074
4075                                         where = m->rindex + c->item_size - k;
4076                                         r = message_peek_body(m, &where, 1, k, &q);
4077                                         if (r < 0)
4078                                                 return r;
4079                                         if (r == 0)
4080                                                 goto eof;
4081
4082                                         if (*(char*) q == 0)
4083                                                 break;
4084                                 }
4085
4086                                 if (k > c->item_size)
4087                                         return -EBADMSG;
4088
4089                                 free(m->peeked_signature);
4090                                 m->peeked_signature = strndup((char*) q + 1, k - 1);
4091                                 if (!m->peeked_signature)
4092                                         return -ENOMEM;
4093
4094                                 if (!signature_is_valid(m->peeked_signature, true))
4095                                         return -EBADMSG;
4096
4097                                 *contents = m->peeked_signature;
4098                         } else {
4099                                 size_t rindex, l;
4100
4101                                 rindex = m->rindex;
4102                                 r = message_peek_body(m, &rindex, 1, 1, &q);
4103                                 if (r < 0)
4104                                         return r;
4105                                 if (r == 0)
4106                                         goto eof;
4107
4108                                 l = *(uint8_t*) q;
4109                                 r = message_peek_body(m, &rindex, 1, l+1, &q);
4110                                 if (r < 0)
4111                                         return r;
4112                                 if (r == 0)
4113                                         return -EBADMSG;
4114
4115                                 if (!validate_signature(q, l))
4116                                         return -EBADMSG;
4117
4118                                 *contents = q;
4119                         }
4120                 }
4121
4122                 if (type)
4123                         *type = SD_BUS_TYPE_VARIANT;
4124
4125                 return 1;
4126         }
4127
4128         return -EINVAL;
4129
4130 eof:
4131         if (type)
4132                 *type = 0;
4133         if (contents)
4134                 *contents = NULL;
4135         return 0;
4136 }
4137
4138 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
4139         struct bus_container *c;
4140
4141         assert_return(m, -EINVAL);
4142         assert_return(m->sealed, -EPERM);
4143
4144         if (complete) {
4145                 message_reset_containers(m);
4146                 m->rindex = 0;
4147
4148                 c = message_get_container(m);
4149         } else {
4150                 c = message_get_container(m);
4151
4152                 c->offset_index = 0;
4153                 c->index = 0;
4154                 m->rindex = c->begin;
4155         }
4156
4157         return !isempty(c->signature);
4158 }
4159
4160 static int message_read_ap(
4161                 sd_bus_message *m,
4162                 const char *types,
4163                 va_list ap) {
4164
4165         unsigned n_array, n_struct;
4166         TypeStack stack[BUS_CONTAINER_DEPTH];
4167         unsigned stack_ptr = 0;
4168         unsigned n_loop = 0;
4169         int r;
4170
4171         assert(m);
4172
4173         if (isempty(types))
4174                 return 0;
4175
4176         /* Ideally, we'd just call ourselves recursively on every
4177          * complex type. However, the state of a va_list that is
4178          * passed to a function is undefined after that function
4179          * returns. This means we need to docode the va_list linearly
4180          * in a single stackframe. We hence implement our own
4181          * home-grown stack in an array. */
4182
4183         n_array = (unsigned) -1; /* lenght of current array entries */
4184         n_struct = strlen(types); /* length of current struct contents signature */
4185
4186         for (;;) {
4187                 const char *t;
4188
4189                 n_loop++;
4190
4191                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
4192                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
4193                         if (r < 0)
4194                                 return r;
4195                         if (r == 0)
4196                                 break;
4197
4198                         r = sd_bus_message_exit_container(m);
4199                         if (r < 0)
4200                                 return r;
4201
4202                         continue;
4203                 }
4204
4205                 t = types;
4206                 if (n_array != (unsigned) -1)
4207                         n_array --;
4208                 else {
4209                         types ++;
4210                         n_struct--;
4211                 }
4212
4213                 switch (*t) {
4214
4215                 case SD_BUS_TYPE_BYTE:
4216                 case SD_BUS_TYPE_BOOLEAN:
4217                 case SD_BUS_TYPE_INT16:
4218                 case SD_BUS_TYPE_UINT16:
4219                 case SD_BUS_TYPE_INT32:
4220                 case SD_BUS_TYPE_UINT32:
4221                 case SD_BUS_TYPE_INT64:
4222                 case SD_BUS_TYPE_UINT64:
4223                 case SD_BUS_TYPE_DOUBLE:
4224                 case SD_BUS_TYPE_STRING:
4225                 case SD_BUS_TYPE_OBJECT_PATH:
4226                 case SD_BUS_TYPE_SIGNATURE:
4227                 case SD_BUS_TYPE_UNIX_FD: {
4228                         void *p;
4229
4230                         p = va_arg(ap, void*);
4231                         r = sd_bus_message_read_basic(m, *t, p);
4232                         if (r < 0)
4233                                 return r;
4234                         if (r == 0) {
4235                                 if (n_loop <= 1)
4236                                         return 0;
4237
4238                                 return -ENXIO;
4239                         }
4240
4241                         break;
4242                 }
4243
4244                 case SD_BUS_TYPE_ARRAY: {
4245                         size_t k;
4246
4247                         r = signature_element_length(t + 1, &k);
4248                         if (r < 0)
4249                                 return r;
4250
4251                         {
4252                                 char s[k + 1];
4253                                 memcpy(s, t + 1, k);
4254                                 s[k] = 0;
4255
4256                                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4257                                 if (r < 0)
4258                                         return r;
4259                                 if (r == 0) {
4260                                         if (n_loop <= 1)
4261                                                 return 0;
4262
4263                                         return -ENXIO;
4264                                 }
4265                         }
4266
4267                         if (n_array == (unsigned) -1) {
4268                                 types += k;
4269                                 n_struct -= k;
4270                         }
4271
4272                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4273                         if (r < 0)
4274                                 return r;
4275
4276                         types = t + 1;
4277                         n_struct = k;
4278                         n_array = va_arg(ap, unsigned);
4279
4280                         break;
4281                 }
4282
4283                 case SD_BUS_TYPE_VARIANT: {
4284                         const char *s;
4285
4286                         s = va_arg(ap, const char *);
4287                         if (!s)
4288                                 return -EINVAL;
4289
4290                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
4291                         if (r < 0)
4292                                 return r;
4293                         if (r == 0) {
4294                                 if (n_loop <= 1)
4295                                         return 0;
4296
4297                                 return -ENXIO;
4298                         }
4299
4300                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4301                         if (r < 0)
4302                                 return r;
4303
4304                         types = s;
4305                         n_struct = strlen(s);
4306                         n_array = (unsigned) -1;
4307
4308                         break;
4309                 }
4310
4311                 case SD_BUS_TYPE_STRUCT_BEGIN:
4312                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4313                         size_t k;
4314
4315                         r = signature_element_length(t, &k);
4316                         if (r < 0)
4317                                 return r;
4318
4319                         {
4320                                 char s[k - 1];
4321                                 memcpy(s, t + 1, k - 2);
4322                                 s[k - 2] = 0;
4323
4324                                 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4325                                 if (r < 0)
4326                                         return r;
4327                                 if (r == 0) {
4328                                         if (n_loop <= 1)
4329                                                 return 0;
4330                                         return -ENXIO;
4331                                 }
4332                         }
4333
4334                         if (n_array == (unsigned) -1) {
4335                                 types += k - 1;
4336                                 n_struct -= k - 1;
4337                         }
4338
4339                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4340                         if (r < 0)
4341                                 return r;
4342
4343                         types = t + 1;
4344                         n_struct = k - 2;
4345                         n_array = (unsigned) -1;
4346
4347                         break;
4348                 }
4349
4350                 default:
4351                         return -EINVAL;
4352                 }
4353         }
4354
4355         return 1;
4356 }
4357
4358 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
4359         va_list ap;
4360         int r;
4361
4362         assert_return(m, -EINVAL);
4363         assert_return(m->sealed, -EPERM);
4364         assert_return(types, -EINVAL);
4365
4366         va_start(ap, types);
4367         r = message_read_ap(m, types, ap);
4368         va_end(ap);
4369
4370         return r;
4371 }
4372
4373 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
4374         int r;
4375
4376         assert_return(m, -EINVAL);
4377         assert_return(m->sealed, -EPERM);
4378         assert_return(types, -EINVAL);
4379
4380         if (isempty(types))
4381                 return 0;
4382
4383         switch (*types) {
4384
4385         case SD_BUS_TYPE_BYTE:
4386         case SD_BUS_TYPE_BOOLEAN:
4387         case SD_BUS_TYPE_INT16:
4388         case SD_BUS_TYPE_UINT16:
4389         case SD_BUS_TYPE_INT32:
4390         case SD_BUS_TYPE_UINT32:
4391         case SD_BUS_TYPE_INT64:
4392         case SD_BUS_TYPE_UINT64:
4393         case SD_BUS_TYPE_DOUBLE:
4394         case SD_BUS_TYPE_STRING:
4395         case SD_BUS_TYPE_OBJECT_PATH:
4396         case SD_BUS_TYPE_SIGNATURE:
4397         case SD_BUS_TYPE_UNIX_FD:
4398
4399                 r = sd_bus_message_read_basic(m, *types, NULL);
4400                 if (r <= 0)
4401                         return r;
4402
4403                 r = sd_bus_message_skip(m, types + 1);
4404                 if (r < 0)
4405                         return r;
4406
4407                 return 1;
4408
4409         case SD_BUS_TYPE_ARRAY: {
4410                 size_t k;
4411
4412                 r = signature_element_length(types + 1, &k);
4413                 if (r < 0)
4414                         return r;
4415
4416                 {
4417                         char s[k+1];
4418                         memcpy(s, types+1, k);
4419                         s[k] = 0;
4420
4421                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4422                         if (r <= 0)
4423                                 return r;
4424
4425                         for (;;) {
4426                                 r = sd_bus_message_skip(m, s);
4427                                 if (r < 0)
4428                                         return r;
4429                                 if (r == 0)
4430                                         break;
4431                         }
4432
4433                         r = sd_bus_message_exit_container(m);
4434                         if (r < 0)
4435                                 return r;
4436                 }
4437
4438                 r = sd_bus_message_skip(m, types + 1 + k);
4439                 if (r < 0)
4440                         return r;
4441
4442                 return 1;
4443         }
4444
4445         case SD_BUS_TYPE_VARIANT: {
4446                 const char *contents;
4447                 char x;
4448
4449                 r = sd_bus_message_peek_type(m, &x, &contents);
4450                 if (r <= 0)
4451                         return r;
4452
4453                 if (x != SD_BUS_TYPE_VARIANT)
4454                         return -ENXIO;
4455
4456                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
4457                 if (r <= 0)
4458                         return r;
4459
4460                 r = sd_bus_message_skip(m, contents);
4461                 if (r < 0)
4462                         return r;
4463                 assert(r != 0);
4464
4465                 r = sd_bus_message_exit_container(m);
4466                 if (r < 0)
4467                         return r;
4468
4469                 r = sd_bus_message_skip(m, types + 1);
4470                 if (r < 0)
4471                         return r;
4472
4473                 return 1;
4474         }
4475
4476         case SD_BUS_TYPE_STRUCT_BEGIN:
4477         case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4478                 size_t k;
4479
4480                 r = signature_element_length(types, &k);
4481                 if (r < 0)
4482                         return r;
4483
4484                 {
4485                         char s[k-1];
4486                         memcpy(s, types+1, k-2);
4487                         s[k-2] = 0;
4488
4489                         r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4490                         if (r <= 0)
4491                                 return r;
4492
4493                         r = sd_bus_message_skip(m, s);
4494                         if (r < 0)
4495                                 return r;
4496                         assert(r != 0);
4497
4498                         r = sd_bus_message_exit_container(m);
4499                         if (r < 0)
4500                                 return r;
4501                 }
4502
4503                 r = sd_bus_message_skip(m, types + k);
4504                 if (r < 0)
4505                         return r;
4506
4507                 return 1;
4508         }
4509
4510         default:
4511                 return -EINVAL;
4512         }
4513 }
4514
4515 _public_ int sd_bus_message_read_array(sd_bus_message *m,
4516                                        char type,
4517                                        const void **ptr,
4518                                        size_t *size) {
4519         struct bus_container *c;
4520         void *p;
4521         size_t sz;
4522         ssize_t align;
4523         int r;
4524
4525         assert_return(m, -EINVAL);
4526         assert_return(m->sealed, -EPERM);
4527         assert_return(bus_type_is_trivial(type), -EINVAL);
4528         assert_return(ptr, -EINVAL);
4529         assert_return(size, -EINVAL);
4530         assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
4531
4532         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
4533         if (r <= 0)
4534                 return r;
4535
4536         c = message_get_container(m);
4537
4538         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4539                 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
4540                 if (align < 0)
4541                         return align;
4542
4543                 sz = c->item_size;
4544         } else {
4545                 align = bus_type_get_alignment(type);
4546                 if (align < 0)
4547                         return align;
4548
4549                 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
4550         }
4551
4552         if (sz == 0)
4553                 /* Zero length array, let's return some aligned
4554                  * pointer that is not NULL */
4555                 p = (uint8_t*) NULL + align;
4556         else {
4557                 r = message_peek_body(m, &m->rindex, align, sz, &p);
4558                 if (r < 0)
4559                         goto fail;
4560                 if (r == 0) {
4561                         r = -EBADMSG;
4562                         goto fail;
4563                 }
4564         }
4565
4566         r = sd_bus_message_exit_container(m);
4567         if (r < 0)
4568                 goto fail;
4569
4570         *ptr = (const void*) p;
4571         *size = sz;
4572
4573         return 1;
4574
4575 fail:
4576         message_quit_container(m);
4577         return r;
4578 }
4579
4580 static int message_peek_fields(
4581                 sd_bus_message *m,
4582                 size_t *rindex,
4583                 size_t align,
4584                 size_t nbytes,
4585                 void **ret) {
4586
4587         assert(m);
4588         assert(rindex);
4589         assert(align > 0);
4590
4591         return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
4592 }
4593
4594 static int message_peek_field_uint32(
4595                 sd_bus_message *m,
4596                 size_t *ri,
4597                 size_t item_size,
4598                 uint32_t *ret) {
4599
4600         int r;
4601         void *q;
4602
4603         assert(m);
4604         assert(ri);
4605
4606         if (BUS_MESSAGE_IS_GVARIANT(m) && item_size != 4)
4607                 return -EBADMSG;
4608
4609         /* identical for gvariant and dbus1 */
4610
4611         r = message_peek_fields(m, ri, 4, 4, &q);
4612         if (r < 0)
4613                 return r;
4614
4615         if (ret)
4616                 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
4617
4618         return 0;
4619 }
4620
4621 static int message_peek_field_string(
4622                 sd_bus_message *m,
4623                 bool (*validate)(const char *p),
4624                 size_t *ri,
4625                 size_t item_size,
4626                 const char **ret) {
4627
4628         uint32_t l;
4629         int r;
4630         void *q;
4631
4632         assert(m);
4633         assert(ri);
4634
4635         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4636
4637                 if (item_size <= 0)
4638                         return -EBADMSG;
4639
4640                 r = message_peek_fields(m, ri, 1, item_size, &q);
4641                 if (r < 0)
4642                         return r;
4643
4644                 l = item_size - 1;
4645         } else {
4646                 r = message_peek_field_uint32(m, ri, 4, &l);
4647                 if (r < 0)
4648                         return r;
4649
4650                 r = message_peek_fields(m, ri, 1, l+1, &q);
4651                 if (r < 0)
4652                         return r;
4653         }
4654
4655         if (validate) {
4656                 if (!validate_nul(q, l))
4657                         return -EBADMSG;
4658
4659                 if (!validate(q))
4660                         return -EBADMSG;
4661         } else {
4662                 if (!validate_string(q, l))
4663                         return -EBADMSG;
4664         }
4665
4666         if (ret)
4667                 *ret = q;
4668
4669         return 0;
4670 }
4671
4672 static int message_peek_field_signature(
4673                 sd_bus_message *m,
4674                 size_t *ri,
4675                 size_t item_size,
4676                 const char **ret) {
4677
4678         size_t l;
4679         int r;
4680         void *q;
4681
4682         assert(m);
4683         assert(ri);
4684
4685         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4686
4687                 if (item_size <= 0)
4688                         return -EBADMSG;
4689
4690                 r = message_peek_fields(m, ri, 1, item_size, &q);
4691                 if (r < 0)
4692                         return r;
4693
4694                 l = item_size - 1;
4695         } else {
4696                 r = message_peek_fields(m, ri, 1, 1, &q);
4697                 if (r < 0)
4698                         return r;
4699
4700                 l = *(uint8_t*) q;
4701                 r = message_peek_fields(m, ri, 1, l+1, &q);
4702                 if (r < 0)
4703                         return r;
4704         }
4705
4706         if (!validate_signature(q, l))
4707                 return -EBADMSG;
4708
4709         if (ret)
4710                 *ret = q;
4711
4712         return 0;
4713 }
4714
4715 static int message_skip_fields(
4716                 sd_bus_message *m,
4717                 size_t *ri,
4718                 uint32_t array_size,
4719                 const char **signature) {
4720
4721         size_t original_index;
4722         int r;
4723
4724         assert(m);
4725         assert(ri);
4726         assert(signature);
4727         assert(!BUS_MESSAGE_IS_GVARIANT(m));
4728
4729         original_index = *ri;
4730
4731         for (;;) {
4732                 char t;
4733                 size_t l;
4734
4735                 if (array_size != (uint32_t) -1 &&
4736                     array_size <= *ri - original_index)
4737                         return 0;
4738
4739                 t = **signature;
4740                 if (!t)
4741                         return 0;
4742
4743                 if (t == SD_BUS_TYPE_STRING) {
4744
4745                         r = message_peek_field_string(m, NULL, ri, 0, NULL);
4746                         if (r < 0)
4747                                 return r;
4748
4749                         (*signature)++;
4750
4751                 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
4752
4753                         r = message_peek_field_string(m, object_path_is_valid, ri, 0, NULL);
4754                         if (r < 0)
4755                                 return r;
4756
4757                         (*signature)++;
4758
4759                 } else if (t == SD_BUS_TYPE_SIGNATURE) {
4760
4761                         r = message_peek_field_signature(m, ri, 0, NULL);
4762                         if (r < 0)
4763                                 return r;
4764
4765                         (*signature)++;
4766
4767                 } else if (bus_type_is_basic(t)) {
4768                         ssize_t align, k;
4769
4770                         align = bus_type_get_alignment(t);
4771                         k = bus_type_get_size(t);
4772                         assert(align > 0 && k > 0);
4773
4774                         r = message_peek_fields(m, ri, align, k, NULL);
4775                         if (r < 0)
4776                                 return r;
4777
4778                         (*signature)++;
4779
4780                 } else if (t == SD_BUS_TYPE_ARRAY) {
4781
4782                         r = signature_element_length(*signature+1, &l);
4783                         if (r < 0)
4784                                 return r;
4785
4786                         assert(l >= 1);
4787                         {
4788                                 char sig[l-1], *s;
4789                                 uint32_t nas;
4790                                 int alignment;
4791
4792                                 strncpy(sig, *signature + 1, l-1);
4793                                 s = sig;
4794
4795                                 alignment = bus_type_get_alignment(sig[0]);
4796                                 if (alignment < 0)
4797                                         return alignment;
4798
4799                                 r = message_peek_field_uint32(m, ri, 0, &nas);
4800                                 if (r < 0)
4801                                         return r;
4802                                 if (nas > BUS_ARRAY_MAX_SIZE)
4803                                         return -EBADMSG;
4804
4805                                 r = message_peek_fields(m, ri, alignment, 0, NULL);
4806                                 if (r < 0)
4807                                         return r;
4808
4809                                 r = message_skip_fields(m, ri, nas, (const char**) &s);
4810                                 if (r < 0)
4811                                         return r;
4812                         }
4813
4814                         (*signature) += 1 + l;
4815
4816                 } else if (t == SD_BUS_TYPE_VARIANT) {
4817                         const char *s;
4818
4819                         r = message_peek_field_signature(m, ri, 0, &s);
4820                         if (r < 0)
4821                                 return r;
4822
4823                         r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
4824                         if (r < 0)
4825                                 return r;
4826
4827                         (*signature)++;
4828
4829                 } else if (t == SD_BUS_TYPE_STRUCT ||
4830                            t == SD_BUS_TYPE_DICT_ENTRY) {
4831
4832                         r = signature_element_length(*signature, &l);
4833                         if (r < 0)
4834                                 return r;
4835
4836                         assert(l >= 2);
4837                         {
4838                                 char sig[l-1], *s;
4839                                 strncpy(sig, *signature + 1, l-1);
4840                                 s = sig;
4841
4842                                 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
4843                                 if (r < 0)
4844                                         return r;
4845                         }
4846
4847                         *signature += l;
4848                 } else
4849                         return -EINVAL;
4850         }
4851 }
4852
4853 int bus_message_parse_fields(sd_bus_message *m) {
4854         size_t ri;
4855         int r;
4856         uint32_t unix_fds = 0;
4857         void *offsets = NULL;
4858         unsigned n_offsets = 0;
4859         size_t sz;
4860         unsigned i = 0;
4861
4862         assert(m);
4863
4864         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4865                 void *q;
4866
4867                 sz = determine_word_size(BUS_MESSAGE_FIELDS_SIZE(m), 0);
4868                 if (sz > 0) {
4869                         size_t framing;
4870
4871                         ri = BUS_MESSAGE_FIELDS_SIZE(m) - sz;
4872                         r = message_peek_fields(m, &ri, 1, sz, &q);
4873                         if (r < 0)
4874                                 return r;
4875
4876                         framing = read_word_le(q, sz);
4877                         if (framing >= BUS_MESSAGE_FIELDS_SIZE(m) - sz)
4878                                 return -EBADMSG;
4879                         if ((BUS_MESSAGE_FIELDS_SIZE(m) - framing) % sz != 0)
4880                                 return -EBADMSG;
4881
4882                         ri = framing;
4883                         r = message_peek_fields(m, &ri, 1, BUS_MESSAGE_FIELDS_SIZE(m) - framing, &offsets);
4884                         if (r < 0)
4885                                 return r;
4886
4887                         n_offsets = (BUS_MESSAGE_FIELDS_SIZE(m) - framing) / sz;
4888                 }
4889         }
4890
4891         ri = 0;
4892         while (ri < BUS_MESSAGE_FIELDS_SIZE(m)) {
4893                 _cleanup_free_ char *sig = NULL;
4894                 const char *signature;
4895                 uint8_t *header;
4896                 size_t item_size = (size_t) -1;
4897
4898                 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4899                         if (i >= n_offsets)
4900                                 break;
4901
4902                         if (i == 0)
4903                                 ri = 0;
4904                         else
4905                                 ri = ALIGN_TO(read_word_le((uint8_t*) offsets + (i-1)*sz, sz), 8);
4906                 }
4907
4908                 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
4909                 if (r < 0)
4910                         return r;
4911
4912                 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4913                         size_t where, end;
4914                         char *b;
4915                         void *q;
4916
4917                         end = read_word_le((uint8_t*) offsets + i*sz, sz);
4918
4919                         if (end < ri)
4920                                 return -EBADMSG;
4921
4922                         where = ri = ALIGN_TO(ri, 8);
4923                         item_size = end - ri;
4924                         r = message_peek_fields(m, &where, 1, item_size, &q);
4925                         if (r < 0)
4926                                 return r;
4927
4928                         b = memrchr(q, 0, item_size);
4929                         if (!b)
4930                                 return -EBADMSG;
4931
4932                         sig = strndup(b+1, item_size - (b+1-(char*) q));
4933                         if (!sig)
4934                                 return -ENOMEM;
4935
4936                         signature = sig;
4937                         item_size = b - (char*) q;
4938                 } else {
4939                         r = message_peek_field_signature(m, &ri, 0, &signature);
4940                         if (r < 0)
4941                                 return r;
4942                 }
4943
4944                 switch (*header) {
4945                 case _BUS_MESSAGE_HEADER_INVALID:
4946                         return -EBADMSG;
4947
4948                 case BUS_MESSAGE_HEADER_PATH:
4949
4950                         if (m->path)
4951                                 return -EBADMSG;
4952
4953                         if (!streq(signature, "o"))
4954                                 return -EBADMSG;
4955
4956                         r = message_peek_field_string(m, object_path_is_valid, &ri, item_size, &m->path);
4957                         break;
4958
4959                 case BUS_MESSAGE_HEADER_INTERFACE:
4960
4961                         if (m->interface)
4962                                 return -EBADMSG;
4963
4964                         if (!streq(signature, "s"))
4965                                 return -EBADMSG;
4966
4967                         r = message_peek_field_string(m, interface_name_is_valid, &ri, item_size, &m->interface);
4968                         break;
4969
4970                 case BUS_MESSAGE_HEADER_MEMBER:
4971
4972                         if (m->member)
4973                                 return -EBADMSG;
4974
4975                         if (!streq(signature, "s"))
4976                                 return -EBADMSG;
4977
4978                         r = message_peek_field_string(m, member_name_is_valid, &ri, item_size, &m->member);
4979                         break;
4980
4981                 case BUS_MESSAGE_HEADER_ERROR_NAME:
4982
4983                         if (m->error.name)
4984                                 return -EBADMSG;
4985
4986                         if (!streq(signature, "s"))
4987                                 return -EBADMSG;
4988
4989                         r = message_peek_field_string(m, error_name_is_valid, &ri, item_size, &m->error.name);
4990                         if (r >= 0)
4991                                 m->error._need_free = -1;
4992
4993                         break;
4994
4995                 case BUS_MESSAGE_HEADER_DESTINATION:
4996
4997                         if (m->destination)
4998                                 return -EBADMSG;
4999
5000                         if (!streq(signature, "s"))
5001                                 return -EBADMSG;
5002
5003                         r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->destination);
5004                         break;
5005
5006                 case BUS_MESSAGE_HEADER_SENDER:
5007
5008                         if (m->sender)
5009                                 return -EBADMSG;
5010
5011                         if (!streq(signature, "s"))
5012                                 return -EBADMSG;
5013
5014                         r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->sender);
5015
5016                         if (r >= 0 && m->sender[0] == ':' && m->bus && m->bus->bus_client && !m->bus->is_kernel) {
5017                                 m->creds.unique_name = (char*) m->sender;
5018                                 m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & m->bus->creds_mask;
5019                         }
5020
5021                         break;
5022
5023
5024                 case BUS_MESSAGE_HEADER_SIGNATURE: {
5025                         const char *s;
5026                         char *c;
5027
5028                         if (m->root_container.signature)
5029                                 return -EBADMSG;
5030
5031                         if (!streq(signature, "g"))
5032                                 return -EBADMSG;
5033
5034                         r = message_peek_field_signature(m, &ri, item_size, &s);
5035                         if (r < 0)
5036                                 return r;
5037
5038                         c = strdup(s);
5039                         if (!c)
5040                                 return -ENOMEM;
5041
5042                         free(m->root_container.signature);
5043                         m->root_container.signature = c;
5044                         break;
5045                 }
5046
5047                 case BUS_MESSAGE_HEADER_REPLY_SERIAL:
5048                         if (m->reply_serial != 0)
5049                                 return -EBADMSG;
5050
5051                         if (!streq(signature, "u"))
5052                                 return -EBADMSG;
5053
5054                         r = message_peek_field_uint32(m, &ri, item_size, &m->reply_serial);
5055                         if (r < 0)
5056                                 return r;
5057
5058                         if (m->reply_serial == 0)
5059                                 return -EBADMSG;
5060
5061                         break;
5062
5063                 case BUS_MESSAGE_HEADER_UNIX_FDS:
5064                         if (unix_fds != 0)
5065                                 return -EBADMSG;
5066
5067                         if (!streq(signature, "u"))
5068                                 return -EBADMSG;
5069
5070                         r = message_peek_field_uint32(m, &ri, item_size, &unix_fds);
5071                         if (r < 0)
5072                                 return -EBADMSG;
5073
5074                         if (unix_fds == 0)
5075                                 return -EBADMSG;
5076
5077                         break;
5078
5079                 default:
5080                         if (!BUS_MESSAGE_IS_GVARIANT(m))
5081                                 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
5082                 }
5083
5084                 if (r < 0)
5085                         return r;
5086
5087                 i++;
5088         }
5089
5090         if (m->n_fds != unix_fds)
5091                 return -EBADMSG;
5092
5093         if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
5094                 return -EBADMSG;
5095
5096         switch (m->header->type) {
5097
5098         case SD_BUS_MESSAGE_SIGNAL:
5099                 if (!m->path || !m->interface || !m->member)
5100                         return -EBADMSG;
5101                 break;
5102
5103         case SD_BUS_MESSAGE_METHOD_CALL:
5104
5105                 if (!m->path || !m->member)
5106                         return -EBADMSG;
5107
5108                 break;
5109
5110         case SD_BUS_MESSAGE_METHOD_RETURN:
5111
5112                 if (m->reply_serial == 0)
5113                         return -EBADMSG;
5114                 break;
5115
5116         case SD_BUS_MESSAGE_METHOD_ERROR:
5117
5118                 if (m->reply_serial == 0 || !m->error.name)
5119                         return -EBADMSG;
5120                 break;
5121         }
5122
5123         m->root_container.end = BUS_MESSAGE_BODY_SIZE(m);
5124
5125         if (BUS_MESSAGE_IS_GVARIANT(m)) {
5126                 r = build_struct_offsets(
5127                                 m,
5128                                 m->root_container.signature,
5129                                 BUS_MESSAGE_BODY_SIZE(m),
5130                                 &m->root_container.item_size,
5131                                 &m->root_container.offsets,
5132                                 &m->root_container.n_offsets);
5133                 if (r < 0)
5134                         return r;
5135         }
5136
5137         /* Try to read the error message, but if we can't it's a non-issue */
5138         if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
5139                 sd_bus_message_read(m, "s", &m->error.message);
5140
5141         return 0;
5142 }
5143
5144 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
5145         assert_return(m, -EINVAL);
5146         assert_return(destination, -EINVAL);
5147         assert_return(!m->sealed, -EPERM);
5148         assert_return(!m->destination, -EEXIST);
5149
5150         return message_append_field_string(m, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
5151 }
5152
5153 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
5154         size_t total;
5155         void *p, *e;
5156         unsigned i;
5157         struct bus_body_part *part;
5158
5159         assert(m);
5160         assert(buffer);
5161         assert(sz);
5162
5163         total = BUS_MESSAGE_SIZE(m);
5164
5165         p = malloc(total);
5166         if (!p)
5167                 return -ENOMEM;
5168
5169         e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
5170         MESSAGE_FOREACH_PART(part, i, m)
5171                 e = mempcpy(e, part->data, part->size);
5172
5173         assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
5174
5175         *buffer = p;
5176         *sz = total;
5177
5178         return 0;
5179 }
5180
5181 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
5182         int r;
5183
5184         assert(m);
5185         assert(l);
5186
5187         r = sd_bus_message_enter_container(m, 'a', "s");
5188         if (r <= 0)
5189                 return r;
5190
5191         for (;;) {
5192                 const char *s;
5193
5194                 r = sd_bus_message_read_basic(m, 's', &s);
5195                 if (r < 0)
5196                         return r;
5197                 if (r == 0)
5198                         break;
5199
5200                 r = strv_extend(l, s);
5201                 if (r < 0)
5202                         return r;
5203         }
5204
5205         r = sd_bus_message_exit_container(m);
5206         if (r < 0)
5207                 return r;
5208
5209         return 1;
5210 }
5211
5212 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
5213         char **strv = NULL;
5214         int r;
5215
5216         assert_return(m, -EINVAL);
5217         assert_return(m->sealed, -EPERM);
5218         assert_return(l, -EINVAL);
5219
5220         r = bus_message_read_strv_extend(m, &strv);
5221         if (r <= 0) {
5222                 strv_free(strv);
5223                 return r;
5224         }
5225
5226         *l = strv;
5227         return 1;
5228 }
5229
5230 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
5231         int r;
5232         const char *t = NULL;
5233         unsigned j;
5234
5235         assert(m);
5236
5237         r = sd_bus_message_rewind(m, true);
5238         if (r < 0)
5239                 return NULL;
5240
5241         for (j = 0; j <= i; j++) {
5242                 char type;
5243
5244                 r = sd_bus_message_peek_type(m, &type, NULL);
5245                 if (r < 0)
5246                         return NULL;
5247
5248                 if (type != SD_BUS_TYPE_STRING &&
5249                     type != SD_BUS_TYPE_OBJECT_PATH &&
5250                     type != SD_BUS_TYPE_SIGNATURE)
5251                         return NULL;
5252
5253                 r = sd_bus_message_read_basic(m, type, &t);
5254                 if (r < 0)
5255                         return NULL;
5256         }
5257
5258         return t;
5259 }
5260
5261 bool bus_header_is_complete(struct bus_header *h, size_t size) {
5262         size_t full;
5263
5264         assert(h);
5265         assert(size);
5266
5267         if (size < sizeof(struct bus_header))
5268                 return false;
5269
5270         full = sizeof(struct bus_header) +
5271                 (h->endian == BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
5272
5273         return size >= full;
5274 }
5275
5276 int bus_header_message_size(struct bus_header *h, size_t *sum) {
5277         size_t fs, bs;
5278
5279         assert(h);
5280         assert(sum);
5281
5282         if (h->endian == BUS_NATIVE_ENDIAN) {
5283                 fs = h->fields_size;
5284                 bs = h->body_size;
5285         } else if (h->endian == BUS_REVERSE_ENDIAN) {
5286                 fs = bswap_32(h->fields_size);
5287                 bs = bswap_32(h->body_size);
5288         } else
5289                 return -EBADMSG;
5290
5291         *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
5292         return 0;
5293 }
5294
5295 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
5296         assert_return(m, -EINVAL);
5297
5298         if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
5299                 return 0;
5300
5301         return sd_bus_error_get_errno(&m->error);
5302 }
5303
5304 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
5305         struct bus_container *c;
5306
5307         assert_return(m, NULL);
5308
5309         c = complete ? &m->root_container : message_get_container(m);
5310         return c->signature ?: "";
5311 }
5312
5313 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
5314         bool done_something = false;
5315         int r;
5316
5317         assert_return(m, -EINVAL);
5318         assert_return(source, -EINVAL);
5319         assert_return(!m->sealed, -EPERM);
5320         assert_return(source->sealed, -EPERM);
5321
5322         do {
5323                 const char *contents;
5324                 char type;
5325                 union {
5326                         uint8_t u8;
5327                         uint16_t u16;
5328                         int16_t s16;
5329                         uint32_t u32;
5330                         int32_t s32;
5331                         uint64_t u64;
5332                         int64_t s64;
5333                         double d64;
5334                         const char *string;
5335                         int i;
5336                 } basic;
5337
5338                 r = sd_bus_message_peek_type(source, &type, &contents);
5339                 if (r < 0)
5340                         return r;
5341                 if (r == 0)
5342                         break;
5343
5344                 done_something = true;
5345
5346                 if (bus_type_is_container(type) > 0) {
5347
5348                         r = sd_bus_message_enter_container(source, type, contents);
5349                         if (r < 0)
5350                                 return r;
5351
5352                         r = sd_bus_message_open_container(m, type, contents);
5353                         if (r < 0)
5354                                 return r;
5355
5356                         r = sd_bus_message_copy(m, source, true);
5357                         if (r < 0)
5358                                 return r;
5359
5360                         r = sd_bus_message_close_container(m);
5361                         if (r < 0)
5362                                 return r;
5363
5364                         r = sd_bus_message_exit_container(source);
5365                         if (r < 0)
5366                                 return r;
5367
5368                         continue;
5369                 }
5370
5371                 r = sd_bus_message_read_basic(source, type, &basic);
5372                 if (r < 0)
5373                         return r;
5374
5375                 assert(r > 0);
5376
5377                 if (type == SD_BUS_TYPE_OBJECT_PATH ||
5378                     type == SD_BUS_TYPE_SIGNATURE ||
5379                     type == SD_BUS_TYPE_STRING)
5380                         r = sd_bus_message_append_basic(m, type, basic.string);
5381                 else
5382                         r = sd_bus_message_append_basic(m, type, &basic);
5383
5384                 if (r < 0)
5385                         return r;
5386
5387         } while (all);
5388
5389         return done_something;
5390 }
5391
5392 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
5393         const char *c;
5394         char t;
5395         int r;
5396
5397         assert_return(m, -EINVAL);
5398         assert_return(m->sealed, -EPERM);
5399         assert_return(!type || bus_type_is_valid(type), -EINVAL);
5400         assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
5401         assert_return(type || contents, -EINVAL);
5402         assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
5403
5404         r = sd_bus_message_peek_type(m, &t, &c);
5405         if (r <= 0)
5406                 return r;
5407
5408         if (type != 0 && type != t)
5409                 return 0;
5410
5411         if (contents && !streq_ptr(contents, c))
5412                 return 0;
5413
5414         return 1;
5415 }
5416
5417 _public_ sd_bus *sd_bus_message_get_bus(sd_bus_message *m) {
5418         assert_return(m, NULL);
5419
5420         return m->bus;
5421 }