chiark / gitweb /
util: replace close_nointr_nofail() by a more useful safe_close()
[elogind.git] / src / libsystemd / sd-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 #include "bus-util.h"
39
40 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
41
42 static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
43
44         if (p == NULL)
45                 return NULL;
46
47         if (old_base == new_base)
48                 return (void*) p;
49
50         if ((uint8_t*) p < (uint8_t*) old_base)
51                 return (void*) p;
52
53         if ((uint8_t*) p >= (uint8_t*) old_base + sz)
54                 return (void*) p;
55
56         return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base);
57 }
58
59 static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
60         assert(m);
61         assert(part);
62
63         if (part->memfd >= 0) {
64                 /* If we can reuse the memfd, try that. For that it
65                  * can't be sealed yet. */
66
67                 if (!part->sealed)
68                         bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped, part->allocated);
69                 else {
70                         if (part->mapped > 0)
71                                 assert_se(munmap(part->data, part->mapped) == 0);
72
73                         safe_close(part->memfd);
74                 }
75
76         } else if (part->munmap_this)
77                 munmap(part->data, part->mapped);
78         else if (part->free_this)
79                 free(part->data);
80
81         if (part != &m->body)
82                 free(part);
83 }
84
85 static void message_reset_parts(sd_bus_message *m) {
86         struct bus_body_part *part;
87
88         assert(m);
89
90         part = &m->body;
91         while (m->n_body_parts > 0) {
92                 struct bus_body_part *next = part->next;
93                 message_free_part(m, part);
94                 part = next;
95                 m->n_body_parts--;
96         }
97
98         m->body_end = NULL;
99
100         m->cached_rindex_part = NULL;
101         m->cached_rindex_part_begin = 0;
102 }
103
104 static void message_reset_containers(sd_bus_message *m) {
105         unsigned i;
106
107         assert(m);
108
109         for (i = 0; i < m->n_containers; i++) {
110                 free(m->containers[i].signature);
111                 free(m->containers[i].offsets);
112         }
113
114         free(m->containers);
115         m->containers = NULL;
116
117         m->n_containers = m->containers_allocated = 0;
118         m->root_container.index = 0;
119 }
120
121 static void message_free(sd_bus_message *m) {
122         assert(m);
123
124         if (m->free_header)
125                 free(m->header);
126
127         message_reset_parts(m);
128
129         if (m->free_kdbus)
130                 free(m->kdbus);
131
132         if (m->release_kdbus) {
133                 uint64_t off;
134
135                 off = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
136                 ioctl(m->bus->input_fd, KDBUS_CMD_FREE, &off);
137         }
138
139         if (m->bus)
140                 sd_bus_unref(m->bus);
141
142         if (m->free_fds) {
143                 close_many(m->fds, m->n_fds);
144                 free(m->fds);
145         }
146
147         if (m->iovec != m->iovec_fixed)
148                 free(m->iovec);
149
150         message_reset_containers(m);
151         free(m->root_container.signature);
152         free(m->root_container.offsets);
153
154         free(m->root_container.peeked_signature);
155
156         bus_creds_done(&m->creds);
157         free(m);
158 }
159
160 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
161         void *op, *np;
162         size_t old_size, new_size, start;
163
164         assert(m);
165
166         if (m->poisoned)
167                 return NULL;
168
169         old_size = sizeof(struct bus_header) + m->header->fields_size;
170         start = ALIGN_TO(old_size, align);
171         new_size = start + sz;
172
173         if (old_size == new_size)
174                 return (uint8_t*) m->header + old_size;
175
176         if (new_size > (size_t) ((uint32_t) -1))
177                 goto poison;
178
179         if (m->free_header) {
180                 np = realloc(m->header, ALIGN8(new_size));
181                 if (!np)
182                         goto poison;
183         } else {
184                 /* Initially, the header is allocated as part of of
185                  * the sd_bus_message itself, let's replace it by
186                  * dynamic data */
187
188                 np = malloc(ALIGN8(new_size));
189                 if (!np)
190                         goto poison;
191
192                 memcpy(np, m->header, sizeof(struct bus_header));
193         }
194
195         /* Zero out padding */
196         if (start > old_size)
197                 memzero((uint8_t*) np + old_size, start - old_size);
198
199         op = m->header;
200         m->header = np;
201         m->header->fields_size = new_size - sizeof(struct bus_header);
202
203         /* Adjust quick access pointers */
204         m->path = adjust_pointer(m->path, op, old_size, m->header);
205         m->interface = adjust_pointer(m->interface, op, old_size, m->header);
206         m->member = adjust_pointer(m->member, op, old_size, m->header);
207         m->destination = adjust_pointer(m->destination, op, old_size, m->header);
208         m->sender = adjust_pointer(m->sender, op, old_size, m->header);
209         m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
210
211         m->free_header = true;
212
213         if (add_offset) {
214                 if (m->n_header_offsets >= ELEMENTSOF(m->header_offsets))
215                         goto poison;
216
217                 m->header_offsets[m->n_header_offsets++] = new_size - sizeof(struct bus_header);
218         }
219
220         return (uint8_t*) np + start;
221
222 poison:
223         m->poisoned = true;
224         return NULL;
225 }
226
227 static int message_append_field_string(
228                 sd_bus_message *m,
229                 uint8_t h,
230                 char type,
231                 const char *s,
232                 const char **ret) {
233
234         size_t l;
235         uint8_t *p;
236
237         assert(m);
238
239         /* dbus1 doesn't allow strings over 32bit, let's enforce this
240          * globally, to not risk convertability */
241         l = strlen(s);
242         if (l > (size_t) (uint32_t) -1)
243                 return -EINVAL;
244
245         /* Signature "(yv)" where the variant contains "s" */
246
247         if (BUS_MESSAGE_IS_GVARIANT(m)) {
248
249                 /* (field id byte + 7x padding, ((string + NUL) + NUL + signature string 's') */
250                 p = message_extend_fields(m, 8, 1 + 7 + l + 1 + 1 + 1, true);
251                 if (!p)
252                         return -ENOMEM;
253
254                 p[0] = h;
255                 memzero(p+1, 7);
256                 memcpy(p+8, s, l);
257                 p[8+l] = 0;
258                 p[8+l+1] = 0;
259                 p[8+l+2] = type;
260
261                 if (ret)
262                         *ret = (char*) p + 8;
263
264         } else {
265                 /* (field id byte + (signature length + signature 's' + NUL) + (string length + string + NUL)) */
266                 p = message_extend_fields(m, 8, 4 + 4 + l + 1, false);
267                 if (!p)
268                         return -ENOMEM;
269
270                 p[0] = h;
271                 p[1] = 1;
272                 p[2] = type;
273                 p[3] = 0;
274
275                 ((uint32_t*) p)[1] = l;
276                 memcpy(p + 8, s, l + 1);
277
278                 if (ret)
279                         *ret = (char*) p + 8;
280         }
281
282         return 0;
283 }
284
285 static int message_append_field_signature(
286                 sd_bus_message *m,
287                 uint8_t h,
288                 const char *s,
289                 const char **ret) {
290
291         size_t l;
292         uint8_t *p;
293
294         assert(m);
295
296         /* dbus1 doesn't allow signatures over 32bit, let's enforce
297          * this globally, to not risk convertability */
298         l = strlen(s);
299         if (l > 255)
300                 return -EINVAL;
301
302         /* Signature "(yv)" where the variant contains "g" */
303
304         if (BUS_MESSAGE_IS_GVARIANT(m))
305                 /* For gvariant the serialization is the same as for normal strings */
306                 return message_append_field_string(m, h, 'g', s, ret);
307         else {
308                 /* (field id byte + (signature length + signature 'g' + NUL) + (string length + string + NUL)) */
309                 p = message_extend_fields(m, 8, 4 + 1 + l + 1, false);
310                 if (!p)
311                         return -ENOMEM;
312
313                 p[0] = h;
314                 p[1] = 1;
315                 p[2] = SD_BUS_TYPE_SIGNATURE;
316                 p[3] = 0;
317                 p[4] = l;
318                 memcpy(p + 5, s, l + 1);
319
320                 if (ret)
321                         *ret = (const char*) p + 5;
322         }
323
324         return 0;
325 }
326
327 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
328         uint8_t *p;
329
330         assert(m);
331
332         if (BUS_MESSAGE_IS_GVARIANT(m)) {
333                 /* (field id byte + 7x padding + ((value + NUL + signature string 'u') */
334
335                 p = message_extend_fields(m, 8, 1 + 7 + 4 + 1 + 1, true);
336                 if (!p)
337                         return -ENOMEM;
338
339                 p[0] = h;
340                 memzero(p+1, 7);
341                 *((uint32_t*) (p + 8)) = x;
342                 p[12] = 0;
343                 p[13] = 'u';
344         } else {
345                 /* (field id byte + (signature length + signature 'u' + NUL) + value) */
346                 p = message_extend_fields(m, 8, 4 + 4, false);
347                 if (!p)
348                         return -ENOMEM;
349
350                 p[0] = h;
351                 p[1] = 1;
352                 p[2] = SD_BUS_TYPE_UINT32;
353                 p[3] = 0;
354
355                 ((uint32_t*) p)[1] = x;
356         }
357
358         return 0;
359 }
360
361 int bus_message_from_header(
362                 sd_bus *bus,
363                 void *buffer,
364                 size_t length,
365                 int *fds,
366                 unsigned n_fds,
367                 const struct ucred *ucred,
368                 const char *label,
369                 size_t extra,
370                 sd_bus_message **ret) {
371
372         sd_bus_message *m;
373         struct bus_header *h;
374         size_t a, label_sz;
375
376         assert(buffer || length <= 0);
377         assert(fds || n_fds <= 0);
378         assert(ret);
379
380         if (length < sizeof(struct bus_header))
381                 return -EBADMSG;
382
383         h = buffer;
384         if (h->version != 1 &&
385             h->version != 2)
386                 return -EBADMSG;
387
388         if (h->serial == 0)
389                 return -EBADMSG;
390
391         if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
392                 return -EBADMSG;
393
394         if (h->endian != BUS_LITTLE_ENDIAN &&
395             h->endian != BUS_BIG_ENDIAN)
396                 return -EBADMSG;
397
398         a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
399
400         if (label) {
401                 label_sz = strlen(label);
402                 a += label_sz + 1;
403         }
404
405         m = malloc0(a);
406         if (!m)
407                 return -ENOMEM;
408
409         m->n_ref = 1;
410         m->sealed = true;
411         m->header = h;
412         m->fds = fds;
413         m->n_fds = n_fds;
414
415         if (ucred) {
416                 m->creds.uid = ucred->uid;
417                 m->creds.pid = ucred->pid;
418                 m->creds.gid = ucred->gid;
419                 m->creds.mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_PID | SD_BUS_CREDS_GID;
420         }
421
422         if (label) {
423                 m->creds.label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
424                 memcpy(m->creds.label, label, label_sz + 1);
425
426                 m->creds.mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
427         }
428
429         if (bus)
430                 m->bus = sd_bus_ref(bus);
431
432         *ret = m;
433         return 0;
434 }
435
436 int bus_message_from_malloc(
437                 sd_bus *bus,
438                 void *buffer,
439                 size_t length,
440                 int *fds,
441                 unsigned n_fds,
442                 const struct ucred *ucred,
443                 const char *label,
444                 sd_bus_message **ret) {
445
446         sd_bus_message *m;
447         size_t sz;
448         int r;
449
450         r = bus_message_from_header(bus, buffer, length, fds, n_fds, ucred, label, 0, &m);
451         if (r < 0)
452                 return r;
453
454         if (length != BUS_MESSAGE_SIZE(m)) {
455                 r = -EBADMSG;
456                 goto fail;
457         }
458
459         sz = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
460         if (sz > 0) {
461                 m->n_body_parts = 1;
462                 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
463                 m->body.size = sz;
464                 m->body.sealed = true;
465                 m->body.memfd = -1;
466         }
467
468         m->n_iovec = 1;
469         m->iovec = m->iovec_fixed;
470         m->iovec[0].iov_base = buffer;
471         m->iovec[0].iov_len = length;
472
473         r = bus_message_parse_fields(m);
474         if (r < 0)
475                 goto fail;
476
477         /* We take possession of the memory and fds now */
478         m->free_header = true;
479         m->free_fds = true;
480
481         *ret = m;
482         return 0;
483
484 fail:
485         message_free(m);
486         return r;
487 }
488
489 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
490         sd_bus_message *m;
491
492         m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
493         if (!m)
494                 return NULL;
495
496         m->n_ref = 1;
497         m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
498         m->header->endian = BUS_NATIVE_ENDIAN;
499         m->header->type = type;
500         m->header->version = bus ? bus->message_version : 1;
501         m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
502         m->root_container.need_offsets = BUS_MESSAGE_IS_GVARIANT(m);
503
504         if (bus)
505                 m->bus = sd_bus_ref(bus);
506
507         return m;
508 }
509
510 _public_ int sd_bus_message_new_signal(
511                 sd_bus *bus,
512                 sd_bus_message **m,
513                 const char *path,
514                 const char *interface,
515                 const char *member) {
516
517         sd_bus_message *t;
518         int r;
519
520         assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
521         assert_return(object_path_is_valid(path), -EINVAL);
522         assert_return(interface_name_is_valid(interface), -EINVAL);
523         assert_return(member_name_is_valid(member), -EINVAL);
524         assert_return(m, -EINVAL);
525
526         t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
527         if (!t)
528                 return -ENOMEM;
529
530         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
531
532         r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
533         if (r < 0)
534                 goto fail;
535         r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
536         if (r < 0)
537                 goto fail;
538         r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
539         if (r < 0)
540                 goto fail;
541
542         *m = t;
543         return 0;
544
545 fail:
546         sd_bus_message_unref(t);
547         return r;
548 }
549
550 _public_ int sd_bus_message_new_method_call(
551                 sd_bus *bus,
552                 sd_bus_message **m,
553                 const char *destination,
554                 const char *path,
555                 const char *interface,
556                 const char *member) {
557
558         sd_bus_message *t;
559         int r;
560
561         assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
562         assert_return(!destination || service_name_is_valid(destination), -EINVAL);
563         assert_return(object_path_is_valid(path), -EINVAL);
564         assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
565         assert_return(member_name_is_valid(member), -EINVAL);
566         assert_return(m, -EINVAL);
567
568         t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
569         if (!t)
570                 return -ENOMEM;
571
572         r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
573         if (r < 0)
574                 goto fail;
575         r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
576         if (r < 0)
577                 goto fail;
578
579         if (interface) {
580                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
581                 if (r < 0)
582                         goto fail;
583         }
584
585         if (destination) {
586                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
587                 if (r < 0)
588                         goto fail;
589         }
590
591         *m = t;
592         return 0;
593
594 fail:
595         message_free(t);
596         return r;
597 }
598
599 static int message_new_reply(
600                 sd_bus_message *call,
601                 uint8_t type,
602                 sd_bus_message **m) {
603
604         sd_bus_message *t;
605         int r;
606
607         assert_return(call, -EINVAL);
608         assert_return(call->sealed, -EPERM);
609         assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
610         assert_return(!call->bus || call->bus->state != BUS_UNSET, -ENOTCONN);
611         assert_return(m, -EINVAL);
612
613         t = message_new(call->bus, type);
614         if (!t)
615                 return -ENOMEM;
616
617         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
618         t->reply_cookie = BUS_MESSAGE_COOKIE(call);
619
620         r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) t->reply_cookie);
621         if (r < 0)
622                 goto fail;
623
624         if (call->sender) {
625                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
626                 if (r < 0)
627                         goto fail;
628         }
629
630         t->dont_send = !!(call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
631         t->enforced_reply_signature = call->enforced_reply_signature;
632
633         *m = t;
634         return 0;
635
636 fail:
637         message_free(t);
638         return r;
639 }
640
641 _public_ int sd_bus_message_new_method_return(
642                 sd_bus_message *call,
643                 sd_bus_message **m) {
644
645         return message_new_reply(call, SD_BUS_MESSAGE_METHOD_RETURN, m);
646 }
647
648 _public_ int sd_bus_message_new_method_error(
649                 sd_bus_message *call,
650                 sd_bus_message **m,
651                 const sd_bus_error *e) {
652
653         sd_bus_message *t;
654         int r;
655
656         assert_return(sd_bus_error_is_set(e), -EINVAL);
657         assert_return(m, -EINVAL);
658
659         r = message_new_reply(call, SD_BUS_MESSAGE_METHOD_ERROR, &t);
660         if (r < 0)
661                 return r;
662
663         r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
664         if (r < 0)
665                 goto fail;
666
667         if (e->message) {
668                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
669                 if (r < 0)
670                         goto fail;
671         }
672
673         t->error._need_free = -1;
674
675         *m = t;
676         return 0;
677
678 fail:
679         message_free(t);
680         return r;
681 }
682
683 _public_ int sd_bus_message_new_method_errorf(
684                 sd_bus_message *call,
685                 sd_bus_message **m,
686                 const char *name,
687                 const char *format,
688                 ...) {
689
690         _cleanup_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
691         va_list ap;
692
693         assert_return(name, -EINVAL);
694         assert_return(m, -EINVAL);
695
696         va_start(ap, format);
697         bus_error_setfv(&error, name, format, ap);
698         va_end(ap);
699
700         return sd_bus_message_new_method_error(call, m, &error);
701 }
702
703 _public_ int sd_bus_message_new_method_errno(
704                 sd_bus_message *call,
705                 sd_bus_message **m,
706                 int error,
707                 const sd_bus_error *p) {
708
709         _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
710
711         if (sd_bus_error_is_set(p))
712                 return sd_bus_message_new_method_error(call, m, p);
713
714         sd_bus_error_set_errno(&berror, error);
715
716         return sd_bus_message_new_method_error(call, m, &berror);
717 }
718
719 _public_ int sd_bus_message_new_method_errnof(
720                 sd_bus_message *call,
721                 sd_bus_message **m,
722                 int error,
723                 const char *format,
724                 ...) {
725
726         _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
727         va_list ap;
728
729         va_start(ap, format);
730         bus_error_set_errnofv(&berror, error, format, ap);
731         va_end(ap);
732
733         return sd_bus_message_new_method_error(call, m, &berror);
734 }
735
736 int bus_message_new_synthetic_error(
737                 sd_bus *bus,
738                 uint64_t cookie,
739                 const sd_bus_error *e,
740                 sd_bus_message **m) {
741
742         sd_bus_message *t;
743         int r;
744
745         assert(sd_bus_error_is_set(e));
746         assert(m);
747
748         t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
749         if (!t)
750                 return -ENOMEM;
751
752         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
753         t->reply_cookie = cookie;
754
755         r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) t->reply_cookie);
756         if (r < 0)
757                 goto fail;
758
759         if (bus && bus->unique_name) {
760                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
761                 if (r < 0)
762                         goto fail;
763         }
764
765         r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
766         if (r < 0)
767                 goto fail;
768
769         if (e->message) {
770                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
771                 if (r < 0)
772                         goto fail;
773         }
774
775         t->error._need_free = -1;
776
777         *m = t;
778         return 0;
779
780 fail:
781         message_free(t);
782         return r;
783 }
784
785 _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
786         assert_return(m, NULL);
787
788         assert(m->n_ref > 0);
789         m->n_ref++;
790
791         return m;
792 }
793
794 _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
795
796         if (!m)
797                 return NULL;
798
799         assert(m->n_ref > 0);
800         m->n_ref--;
801
802         if (m->n_ref <= 0)
803                 message_free(m);
804
805         return NULL;
806 }
807
808 _public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
809         assert_return(m, -EINVAL);
810         assert_return(type, -EINVAL);
811
812         *type = m->header->type;
813         return 0;
814 }
815
816 _public_ int sd_bus_message_get_cookie(sd_bus_message *m, uint64_t *cookie) {
817         assert_return(m, -EINVAL);
818         assert_return(cookie, -EINVAL);
819         assert_return(m->header->serial != 0, -ENODATA);
820
821         *cookie = BUS_MESSAGE_COOKIE(m);
822         return 0;
823 }
824
825 _public_ int sd_bus_message_get_reply_cookie(sd_bus_message *m, uint64_t *cookie) {
826         assert_return(m, -EINVAL);
827         assert_return(cookie, -EINVAL);
828         assert_return(m->reply_cookie != 0, -ENODATA);
829
830         *cookie = m->reply_cookie;
831         return 0;
832 }
833
834 _public_ int sd_bus_message_get_expect_reply(sd_bus_message *m) {
835         assert_return(m, -EINVAL);
836
837         return m->header->type == SD_BUS_MESSAGE_METHOD_CALL &&
838                 !(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
839 }
840
841 _public_ int sd_bus_message_get_auto_start(sd_bus_message *m) {
842         assert_return(m, -EINVAL);
843
844         return !(m->header->flags & BUS_MESSAGE_NO_AUTO_START);
845 }
846
847 _public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
848         assert_return(m, NULL);
849
850         return m->path;
851 }
852
853 _public_ const char *sd_bus_message_get_interface(sd_bus_message *m) {
854         assert_return(m, NULL);
855
856         return m->interface;
857 }
858
859 _public_ const char *sd_bus_message_get_member(sd_bus_message *m) {
860         assert_return(m, NULL);
861
862         return m->member;
863 }
864
865 _public_ const char *sd_bus_message_get_destination(sd_bus_message *m) {
866         assert_return(m, NULL);
867
868         return m->destination;
869 }
870
871 _public_ const char *sd_bus_message_get_sender(sd_bus_message *m) {
872         assert_return(m, NULL);
873
874         return m->sender;
875 }
876
877 _public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
878         assert_return(m, NULL);
879         assert_return(sd_bus_error_is_set(&m->error), NULL);
880
881         return &m->error;
882 }
883
884 _public_ int sd_bus_message_get_monotonic_usec(sd_bus_message *m, uint64_t *usec) {
885         assert_return(m, -EINVAL);
886         assert_return(usec, -EINVAL);
887
888         if (m->monotonic <= 0)
889                 return -ENODATA;
890
891         *usec = m->monotonic;
892         return 0;
893 }
894
895 _public_ int sd_bus_message_get_realtime_usec(sd_bus_message *m, uint64_t *usec) {
896         assert_return(m, -EINVAL);
897         assert_return(usec, -EINVAL);
898
899         if (m->realtime <= 0)
900                 return -ENODATA;
901
902         *usec = m->realtime;
903         return 0;
904 }
905
906 _public_ int sd_bus_message_get_seqnum(sd_bus_message *m, uint64_t *seqnum) {
907         assert_return(m, -EINVAL);
908         assert_return(seqnum, -EINVAL);
909
910         if (m->seqnum <= 0)
911                 return -ENODATA;
912
913         *seqnum = m->seqnum;
914         return 0;
915 }
916
917 _public_ sd_bus_creds *sd_bus_message_get_creds(sd_bus_message *m) {
918         assert_return(m, NULL);
919
920         if (m->creds.mask == 0)
921                 return NULL;
922
923         return &m->creds;
924 }
925
926 _public_ int sd_bus_message_is_signal(sd_bus_message *m,
927                                       const char *interface,
928                                       const char *member) {
929         assert_return(m, -EINVAL);
930
931         if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
932                 return 0;
933
934         if (interface && (!m->interface || !streq(m->interface, interface)))
935                 return 0;
936
937         if (member &&  (!m->member || !streq(m->member, member)))
938                 return 0;
939
940         return 1;
941 }
942
943 _public_ int sd_bus_message_is_method_call(sd_bus_message *m,
944                                            const char *interface,
945                                            const char *member) {
946         assert_return(m, -EINVAL);
947
948         if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
949                 return 0;
950
951         if (interface && (!m->interface || !streq(m->interface, interface)))
952                 return 0;
953
954         if (member &&  (!m->member || !streq(m->member, member)))
955                 return 0;
956
957         return 1;
958 }
959
960 _public_ int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
961         assert_return(m, -EINVAL);
962
963         if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
964                 return 0;
965
966         if (name && (!m->error.name || !streq(m->error.name, name)))
967                 return 0;
968
969         return 1;
970 }
971
972 _public_ int sd_bus_message_set_expect_reply(sd_bus_message *m, int b) {
973         assert_return(m, -EINVAL);
974         assert_return(!m->sealed, -EPERM);
975         assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
976
977         if (b)
978                 m->header->flags &= ~BUS_MESSAGE_NO_REPLY_EXPECTED;
979         else
980                 m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
981
982         return 0;
983 }
984
985 _public_ int sd_bus_message_set_auto_start(sd_bus_message *m, int b) {
986         assert_return(m, -EINVAL);
987         assert_return(!m->sealed, -EPERM);
988
989         if (b)
990                 m->header->flags &= ~BUS_MESSAGE_NO_AUTO_START;
991         else
992                 m->header->flags |= BUS_MESSAGE_NO_AUTO_START;
993
994         return 0;
995 }
996
997 static struct bus_container *message_get_container(sd_bus_message *m) {
998         assert(m);
999
1000         if (m->n_containers == 0)
1001                 return &m->root_container;
1002
1003         assert(m->containers);
1004         return m->containers + m->n_containers - 1;
1005 }
1006
1007 struct bus_body_part *message_append_part(sd_bus_message *m) {
1008         struct bus_body_part *part;
1009
1010         assert(m);
1011
1012         if (m->poisoned)
1013                 return NULL;
1014
1015         if (m->n_body_parts <= 0) {
1016                 part = &m->body;
1017                 zero(*part);
1018         } else {
1019                 assert(m->body_end);
1020
1021                 part = new0(struct bus_body_part, 1);
1022                 if (!part) {
1023                         m->poisoned = true;
1024                         return NULL;
1025                 }
1026
1027                 m->body_end->next = part;
1028         }
1029
1030         part->memfd = -1;
1031         m->body_end = part;
1032         m->n_body_parts ++;
1033
1034         return part;
1035 }
1036
1037 static void part_zero(struct bus_body_part *part, size_t sz) {
1038         assert(part);
1039         assert(sz > 0);
1040         assert(sz < 8);
1041
1042         /* All other fields can be left in their defaults */
1043         assert(!part->data);
1044         assert(part->memfd < 0);
1045
1046         part->size = sz;
1047         part->is_zero = true;
1048         part->sealed = true;
1049 }
1050
1051 static int part_make_space(
1052                 struct sd_bus_message *m,
1053                 struct bus_body_part *part,
1054                 size_t sz,
1055                 void **q) {
1056
1057         void *n;
1058         int r;
1059
1060         assert(m);
1061         assert(part);
1062         assert(!part->sealed);
1063
1064         if (m->poisoned)
1065                 return -ENOMEM;
1066
1067         if (!part->data && part->memfd < 0)
1068                 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped, &part->allocated);
1069
1070         if (part->memfd >= 0) {
1071
1072                 if (part->allocated == 0 || sz > part->allocated) {
1073                         uint64_t new_allocated;
1074
1075                         new_allocated = PAGE_ALIGN(sz > 0 ? 2 * sz : 1);
1076                         r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &new_allocated);
1077                         if (r < 0) {
1078                                 m->poisoned = true;
1079                                 return -errno;
1080                         }
1081
1082                         part->allocated = new_allocated;
1083                 }
1084
1085                 if (!part->data || sz > part->mapped) {
1086                         size_t psz;
1087
1088                         psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1089                         if (part->mapped <= 0)
1090                                 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1091                         else
1092                                 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1093
1094                         if (n == MAP_FAILED) {
1095                                 m->poisoned = true;
1096                                 return -errno;
1097                         }
1098
1099                         part->mapped = psz;
1100                         part->data = n;
1101                 }
1102
1103                 part->munmap_this = true;
1104         } else {
1105                 if (part->allocated == 0 || sz > part->allocated) {
1106                         size_t new_allocated;
1107
1108                         new_allocated = sz > 0 ? 2 * sz : 64;
1109                         n = realloc(part->data, new_allocated);
1110                         if (!n) {
1111                                 m->poisoned = true;
1112                                 return -ENOMEM;
1113                         }
1114
1115                         part->data = n;
1116                         part->allocated = new_allocated;
1117                         part->free_this = true;
1118                 }
1119         }
1120
1121         if (q)
1122                 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1123
1124         part->size = sz;
1125         return 0;
1126 }
1127
1128 static int message_add_offset(sd_bus_message *m, size_t offset) {
1129         struct bus_container *c;
1130
1131         assert(m);
1132         assert(BUS_MESSAGE_IS_GVARIANT(m));
1133
1134         /* Add offset to current container, unless this is the first
1135          * item in it, which will have the 0 offset, which we can
1136          * ignore. */
1137         c = message_get_container(m);
1138
1139         if (!c->need_offsets)
1140                 return 0;
1141
1142         if (!GREEDY_REALLOC(c->offsets, c->offsets_allocated, c->n_offsets + 1))
1143                 return -ENOMEM;
1144
1145         c->offsets[c->n_offsets++] = offset;
1146         return 0;
1147 }
1148
1149 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1150         struct bus_container *c;
1151
1152         assert(m);
1153
1154         if (expand <= 0)
1155                 return;
1156
1157         /* Update counters */
1158         for (c = m->containers; c < m->containers + m->n_containers; c++) {
1159
1160                 if (c->array_size)
1161                         *c->array_size += expand;
1162         }
1163 }
1164
1165 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
1166         size_t start_body, end_body, padding, added;
1167         void *p;
1168         int r;
1169
1170         assert(m);
1171         assert(align > 0);
1172         assert(!m->sealed);
1173
1174         if (m->poisoned)
1175                 return NULL;
1176
1177         start_body = ALIGN_TO((size_t) m->header->body_size, align);
1178         end_body = start_body + sz;
1179
1180         padding = start_body - m->header->body_size;
1181         added = padding + sz;
1182
1183         /* Check for 32bit overflows */
1184         if (end_body > (size_t) ((uint32_t) -1)) {
1185                 m->poisoned = true;
1186                 return NULL;
1187         }
1188
1189         if (added > 0) {
1190                 struct bus_body_part *part = NULL;
1191                 bool add_new_part;
1192
1193                 add_new_part =
1194                         m->n_body_parts <= 0 ||
1195                         m->body_end->sealed ||
1196                         padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1197
1198                 if (add_new_part) {
1199                         if (padding > 0) {
1200                                 part = message_append_part(m);
1201                                 if (!part)
1202                                         return NULL;
1203
1204                                 part_zero(part, padding);
1205                         }
1206
1207                         part = message_append_part(m);
1208                         if (!part)
1209                                 return NULL;
1210
1211                         r = part_make_space(m, part, sz, &p);
1212                         if (r < 0)
1213                                 return NULL;
1214                 } else {
1215                         struct bus_container *c;
1216                         void *op;
1217                         size_t os, start_part, end_part;
1218
1219                         part = m->body_end;
1220                         op = part->data;
1221                         os = part->size;
1222
1223                         start_part = ALIGN_TO(part->size, align);
1224                         end_part = start_part + sz;
1225
1226                         r = part_make_space(m, part, end_part, &p);
1227                         if (r < 0)
1228                                 return NULL;
1229
1230                         if (padding > 0) {
1231                                 memzero(p, padding);
1232                                 p = (uint8_t*) p + padding;
1233                         }
1234
1235                         /* Readjust pointers */
1236                         for (c = m->containers; c < m->containers + m->n_containers; c++)
1237                                 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1238
1239                         m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1240                 }
1241         } else
1242                 /* Return something that is not NULL and is aligned */
1243                 p = (uint8_t *) NULL + align;
1244
1245         m->header->body_size = end_body;
1246         message_extend_containers(m, added);
1247
1248         if (add_offset) {
1249                 r = message_add_offset(m, end_body);
1250                 if (r < 0) {
1251                         m->poisoned = true;
1252                         return NULL;
1253                 }
1254         }
1255
1256         return p;
1257 }
1258
1259 static int message_push_fd(sd_bus_message *m, int fd) {
1260         int *f, copy;
1261
1262         assert(m);
1263
1264         if (fd < 0)
1265                 return -EINVAL;
1266
1267         if (!m->allow_fds)
1268                 return -ENOTSUP;
1269
1270         copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
1271         if (copy < 0)
1272                 return -errno;
1273
1274         f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1275         if (!f) {
1276                 m->poisoned = true;
1277                 safe_close(copy);
1278                 return -ENOMEM;
1279         }
1280
1281         m->fds = f;
1282         m->fds[m->n_fds] = copy;
1283         m->free_fds = true;
1284
1285         return copy;
1286 }
1287
1288 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1289         _cleanup_close_ int fd = -1;
1290         struct bus_container *c;
1291         ssize_t align, sz;
1292         void *a;
1293
1294         assert_return(m, -EINVAL);
1295         assert_return(!m->sealed, -EPERM);
1296         assert_return(bus_type_is_basic(type), -EINVAL);
1297         assert_return(!m->poisoned, -ESTALE);
1298
1299         c = message_get_container(m);
1300
1301         if (c->signature && c->signature[c->index]) {
1302                 /* Container signature is already set */
1303
1304                 if (c->signature[c->index] != type)
1305                         return -ENXIO;
1306         } else {
1307                 char *e;
1308
1309                 /* Maybe we can append to the signature? But only if this is the top-level container*/
1310                 if (c->enclosing != 0)
1311                         return -ENXIO;
1312
1313                 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1314                 if (!e) {
1315                         m->poisoned = true;
1316                         return -ENOMEM;
1317                 }
1318         }
1319
1320         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1321                 uint8_t u8;
1322                 uint32_t u32;
1323
1324                 switch (type) {
1325
1326                 case SD_BUS_TYPE_SIGNATURE:
1327                 case SD_BUS_TYPE_STRING:
1328                         p = strempty(p);
1329
1330                         /* Fall through... */
1331                 case SD_BUS_TYPE_OBJECT_PATH:
1332                         if (!p)
1333                                 return -EINVAL;
1334
1335                         align = 1;
1336                         sz = strlen(p) + 1;
1337                         break;
1338
1339                 case SD_BUS_TYPE_BOOLEAN:
1340
1341                         u8 = p && *(int*) p;
1342                         p = &u8;
1343
1344                         align = sz = 1;
1345                         break;
1346
1347                 case SD_BUS_TYPE_UNIX_FD:
1348
1349                         if (!p)
1350                                 return -EINVAL;
1351
1352                         fd = message_push_fd(m, *(int*) p);
1353                         if (fd < 0)
1354                                 return fd;
1355
1356                         u32 = m->n_fds;
1357                         p = &u32;
1358
1359                         align = sz = 4;
1360                         break;
1361
1362                 default:
1363                         align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
1364                         sz = bus_gvariant_get_size(CHAR_TO_STR(type));
1365                         break;
1366                 }
1367
1368                 assert(align > 0);
1369                 assert(sz > 0);
1370
1371                 a = message_extend_body(m, align, sz, true);
1372                 if (!a)
1373                         return -ENOMEM;
1374
1375                 memcpy(a, p, sz);
1376
1377                 if (stored)
1378                         *stored = (const uint8_t*) a;
1379
1380         } else {
1381                 uint32_t u32;
1382
1383                 switch (type) {
1384
1385                 case SD_BUS_TYPE_STRING:
1386                         /* To make things easy we'll serialize a NULL string
1387                          * into the empty string */
1388                         p = strempty(p);
1389
1390                         /* Fall through... */
1391                 case SD_BUS_TYPE_OBJECT_PATH:
1392
1393                         if (!p)
1394                                 return -EINVAL;
1395
1396                         align = 4;
1397                         sz = 4 + strlen(p) + 1;
1398                         break;
1399
1400                 case SD_BUS_TYPE_SIGNATURE:
1401
1402                         p = strempty(p);
1403
1404                         align = 1;
1405                         sz = 1 + strlen(p) + 1;
1406                         break;
1407
1408                 case SD_BUS_TYPE_BOOLEAN:
1409
1410                         u32 = p && *(int*) p;
1411                         p = &u32;
1412
1413                         align = sz = 4;
1414                         break;
1415
1416                 case SD_BUS_TYPE_UNIX_FD:
1417
1418                         if (!p)
1419                                 return -EINVAL;
1420
1421                         fd = message_push_fd(m, *(int*) p);
1422                         if (fd < 0)
1423                                 return fd;
1424
1425                         u32 = m->n_fds;
1426                         p = &u32;
1427
1428                         align = sz = 4;
1429                         break;
1430
1431                 default:
1432                         align = bus_type_get_alignment(type);
1433                         sz = bus_type_get_size(type);
1434                         break;
1435                 }
1436
1437                 assert(align > 0);
1438                 assert(sz > 0);
1439
1440                 a = message_extend_body(m, align, sz, false);
1441                 if (!a)
1442                         return -ENOMEM;
1443
1444                 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1445                         *(uint32_t*) a = sz - 5;
1446                         memcpy((uint8_t*) a + 4, p, sz - 4);
1447
1448                         if (stored)
1449                                 *stored = (const uint8_t*) a + 4;
1450
1451                 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1452                         *(uint8_t*) a = sz - 2;
1453                         memcpy((uint8_t*) a + 1, p, sz - 1);
1454
1455                         if (stored)
1456                                 *stored = (const uint8_t*) a + 1;
1457                 } else {
1458                         memcpy(a, p, sz);
1459
1460                         if (stored)
1461                                 *stored = a;
1462                 }
1463         }
1464
1465         if (type == SD_BUS_TYPE_UNIX_FD)
1466                 m->n_fds ++;
1467
1468         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1469                 c->index++;
1470
1471         fd = -1;
1472         return 0;
1473 }
1474
1475 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1476         return message_append_basic(m, type, p, NULL);
1477 }
1478
1479 _public_ int sd_bus_message_append_string_space(
1480                 sd_bus_message *m,
1481                 size_t size,
1482                 char **s) {
1483
1484         struct bus_container *c;
1485         void *a;
1486
1487         assert_return(m, -EINVAL);
1488         assert_return(s, -EINVAL);
1489         assert_return(!m->sealed, -EPERM);
1490         assert_return(!m->poisoned, -ESTALE);
1491
1492         c = message_get_container(m);
1493
1494         if (c->signature && c->signature[c->index]) {
1495                 /* Container signature is already set */
1496
1497                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1498                         return -ENXIO;
1499         } else {
1500                 char *e;
1501
1502                 /* Maybe we can append to the signature? But only if this is the top-level container*/
1503                 if (c->enclosing != 0)
1504                         return -ENXIO;
1505
1506                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1507                 if (!e) {
1508                         m->poisoned = true;
1509                         return -ENOMEM;
1510                 }
1511         }
1512
1513         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1514                 a = message_extend_body(m, 1, size + 1, true);
1515                 if (!a)
1516                         return -ENOMEM;
1517
1518                 *s = a;
1519         } else {
1520                 a = message_extend_body(m, 4, 4 + size + 1, false);
1521                 if (!a)
1522                         return -ENOMEM;
1523
1524                 *(uint32_t*) a = size;
1525                 *s = (char*) a + 4;
1526         }
1527
1528         (*s)[size] = 0;
1529
1530         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1531                 c->index++;
1532
1533         return 0;
1534 }
1535
1536 _public_ int sd_bus_message_append_string_iovec(
1537                 sd_bus_message *m,
1538                 const struct iovec *iov,
1539                 unsigned n) {
1540
1541         size_t size;
1542         unsigned i;
1543         char *p;
1544         int r;
1545
1546         assert_return(m, -EINVAL);
1547         assert_return(!m->sealed, -EPERM);
1548         assert_return(iov || n == 0, -EINVAL);
1549         assert_return(!m->poisoned, -ESTALE);
1550
1551         size = IOVEC_TOTAL_SIZE(iov, n);
1552
1553         r = sd_bus_message_append_string_space(m, size, &p);
1554         if (r < 0)
1555                 return r;
1556
1557         for (i = 0; i < n; i++) {
1558
1559                 if (iov[i].iov_base)
1560                         memcpy(p, iov[i].iov_base, iov[i].iov_len);
1561                 else
1562                         memset(p, ' ', iov[i].iov_len);
1563
1564                 p += iov[i].iov_len;
1565         }
1566
1567         return 0;
1568 }
1569
1570 static int bus_message_open_array(
1571                 sd_bus_message *m,
1572                 struct bus_container *c,
1573                 const char *contents,
1574                 uint32_t **array_size,
1575                 size_t *begin,
1576                 bool *need_offsets) {
1577
1578         unsigned nindex;
1579         int alignment, r;
1580
1581         assert(m);
1582         assert(c);
1583         assert(contents);
1584         assert(array_size);
1585         assert(begin);
1586         assert(need_offsets);
1587
1588         if (!signature_is_single(contents, true))
1589                 return -EINVAL;
1590
1591         if (c->signature && c->signature[c->index]) {
1592
1593                 /* Verify the existing signature */
1594
1595                 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1596                         return -ENXIO;
1597
1598                 if (!startswith(c->signature + c->index + 1, contents))
1599                         return -ENXIO;
1600
1601                 nindex = c->index + 1 + strlen(contents);
1602         } else {
1603                 char *e;
1604
1605                 if (c->enclosing != 0)
1606                         return -ENXIO;
1607
1608                 /* Extend the existing signature */
1609
1610                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1611                 if (!e) {
1612                         m->poisoned = true;
1613                         return -ENOMEM;
1614                 }
1615
1616                 nindex = e - c->signature;
1617         }
1618
1619         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1620                 alignment = bus_gvariant_get_alignment(contents);
1621                 if (alignment < 0)
1622                         return alignment;
1623
1624                 /* Add alignment padding and add to offset list */
1625                 if (!message_extend_body(m, alignment, 0, false))
1626                         return -ENOMEM;
1627
1628                 r = bus_gvariant_is_fixed_size(contents);
1629                 if (r < 0)
1630                         return r;
1631
1632                 *begin = m->header->body_size;
1633                 *need_offsets = r == 0;
1634         } else {
1635                 void *a, *op;
1636                 size_t os;
1637                 struct bus_body_part *o;
1638
1639                 alignment = bus_type_get_alignment(contents[0]);
1640                 if (alignment < 0)
1641                         return alignment;
1642
1643                 a = message_extend_body(m, 4, 4, false);
1644                 if (!a)
1645                         return -ENOMEM;
1646
1647                 o = m->body_end;
1648                 op = m->body_end->data;
1649                 os = m->body_end->size;
1650
1651                 /* Add alignment between size and first element */
1652                 if (!message_extend_body(m, alignment, 0, false))
1653                         return -ENOMEM;
1654
1655                 /* location of array size might have changed so let's readjust a */
1656                 if (o == m->body_end)
1657                         a = adjust_pointer(a, op, os, m->body_end->data);
1658
1659                 *(uint32_t*) a = 0;
1660                 *array_size = a;
1661         }
1662
1663         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1664                 c->index = nindex;
1665
1666         return 0;
1667 }
1668
1669 static int bus_message_open_variant(
1670                 sd_bus_message *m,
1671                 struct bus_container *c,
1672                 const char *contents) {
1673
1674         assert(m);
1675         assert(c);
1676         assert(contents);
1677
1678         if (!signature_is_single(contents, false))
1679                 return -EINVAL;
1680
1681         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1682                 return -EINVAL;
1683
1684         if (c->signature && c->signature[c->index]) {
1685
1686                 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1687                         return -ENXIO;
1688
1689         } else {
1690                 char *e;
1691
1692                 if (c->enclosing != 0)
1693                         return -ENXIO;
1694
1695                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1696                 if (!e) {
1697                         m->poisoned = true;
1698                         return -ENOMEM;
1699                 }
1700         }
1701
1702         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1703                 /* Variants are always aligned to 8 */
1704
1705                 if (!message_extend_body(m, 8, 0, false))
1706                         return -ENOMEM;
1707
1708         } else {
1709                 size_t l;
1710                 void *a;
1711
1712                 l = strlen(contents);
1713                 a = message_extend_body(m, 1, 1 + l + 1, false);
1714                 if (!a)
1715                         return -ENOMEM;
1716
1717                 *(uint8_t*) a = l;
1718                 memcpy((uint8_t*) a + 1, contents, l + 1);
1719         }
1720
1721         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1722                 c->index++;
1723
1724         return 0;
1725 }
1726
1727 static int bus_message_open_struct(
1728                 sd_bus_message *m,
1729                 struct bus_container *c,
1730                 const char *contents,
1731                 size_t *begin,
1732                 bool *need_offsets) {
1733
1734         size_t nindex;
1735         int r;
1736
1737         assert(m);
1738         assert(c);
1739         assert(contents);
1740         assert(begin);
1741         assert(need_offsets);
1742
1743         if (!signature_is_valid(contents, false))
1744                 return -EINVAL;
1745
1746         if (c->signature && c->signature[c->index]) {
1747                 size_t l;
1748
1749                 l = strlen(contents);
1750
1751                 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1752                     !startswith(c->signature + c->index + 1, contents) ||
1753                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1754                         return -ENXIO;
1755
1756                 nindex = c->index + 1 + l + 1;
1757         } else {
1758                 char *e;
1759
1760                 if (c->enclosing != 0)
1761                         return -ENXIO;
1762
1763                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1764                 if (!e) {
1765                         m->poisoned = true;
1766                         return -ENOMEM;
1767                 }
1768
1769                 nindex = e - c->signature;
1770         }
1771
1772         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1773                 int alignment;
1774
1775                 alignment = bus_gvariant_get_alignment(contents);
1776                 if (alignment < 0)
1777                         return alignment;
1778
1779                 if (!message_extend_body(m, alignment, 0, false))
1780                         return -ENOMEM;
1781
1782                 r = bus_gvariant_is_fixed_size(contents);
1783                 if (r < 0)
1784                         return r;
1785
1786                 *begin = m->header->body_size;
1787                 *need_offsets = r == 0;
1788         } else {
1789                 /* Align contents to 8 byte boundary */
1790                 if (!message_extend_body(m, 8, 0, false))
1791                         return -ENOMEM;
1792         }
1793
1794         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1795                 c->index = nindex;
1796
1797         return 0;
1798 }
1799
1800 static int bus_message_open_dict_entry(
1801                 sd_bus_message *m,
1802                 struct bus_container *c,
1803                 const char *contents,
1804                 size_t *begin,
1805                 bool *need_offsets) {
1806
1807         int r;
1808
1809         assert(m);
1810         assert(c);
1811         assert(contents);
1812         assert(begin);
1813         assert(need_offsets);
1814
1815         if (!signature_is_pair(contents))
1816                 return -EINVAL;
1817
1818         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1819                 return -ENXIO;
1820
1821         if (c->signature && c->signature[c->index]) {
1822                 size_t l;
1823
1824                 l = strlen(contents);
1825
1826                 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1827                     !startswith(c->signature + c->index + 1, contents) ||
1828                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1829                         return -ENXIO;
1830         } else
1831                 return -ENXIO;
1832
1833         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1834                 int alignment;
1835
1836                 alignment = bus_gvariant_get_alignment(contents);
1837                 if (alignment < 0)
1838                         return alignment;
1839
1840                 if (!message_extend_body(m, alignment, 0, false))
1841                         return -ENOMEM;
1842
1843                 r = bus_gvariant_is_fixed_size(contents);
1844                 if (r < 0)
1845                         return r;
1846
1847                 *begin = m->header->body_size;
1848                 *need_offsets = r == 0;
1849         } else {
1850                 /* Align contents to 8 byte boundary */
1851                 if (!message_extend_body(m, 8, 0, false))
1852                         return -ENOMEM;
1853         }
1854
1855         return 0;
1856 }
1857
1858 _public_ int sd_bus_message_open_container(
1859                 sd_bus_message *m,
1860                 char type,
1861                 const char *contents) {
1862
1863         struct bus_container *c, *w;
1864         uint32_t *array_size = NULL;
1865         char *signature;
1866         size_t before, begin = 0;
1867         bool need_offsets = false;
1868         int r;
1869
1870         assert_return(m, -EINVAL);
1871         assert_return(!m->sealed, -EPERM);
1872         assert_return(contents, -EINVAL);
1873         assert_return(!m->poisoned, -ESTALE);
1874
1875         /* Make sure we have space for one more container */
1876         if (!GREEDY_REALLOC(m->containers, m->containers_allocated, m->n_containers + 1)) {
1877                 m->poisoned = true;
1878                 return -ENOMEM;
1879         }
1880
1881         c = message_get_container(m);
1882
1883         signature = strdup(contents);
1884         if (!signature) {
1885                 m->poisoned = true;
1886                 return -ENOMEM;
1887         }
1888
1889         /* Save old index in the parent container, in case we have to
1890          * abort this container */
1891         c->saved_index = c->index;
1892         before = m->header->body_size;
1893
1894         if (type == SD_BUS_TYPE_ARRAY)
1895                 r = bus_message_open_array(m, c, contents, &array_size, &begin, &need_offsets);
1896         else if (type == SD_BUS_TYPE_VARIANT)
1897                 r = bus_message_open_variant(m, c, contents);
1898         else if (type == SD_BUS_TYPE_STRUCT)
1899                 r = bus_message_open_struct(m, c, contents, &begin, &need_offsets);
1900         else if (type == SD_BUS_TYPE_DICT_ENTRY)
1901                 r = bus_message_open_dict_entry(m, c, contents, &begin, &need_offsets);
1902         else
1903                 r = -EINVAL;
1904
1905         if (r < 0) {
1906                 free(signature);
1907                 return r;
1908         }
1909
1910         /* OK, let's fill it in */
1911         w = m->containers + m->n_containers++;
1912         w->enclosing = type;
1913         w->signature = signature;
1914         w->index = 0;
1915         w->array_size = array_size;
1916         w->before = before;
1917         w->begin = begin;
1918         w->n_offsets = w->offsets_allocated = 0;
1919         w->offsets = NULL;
1920         w->need_offsets = need_offsets;
1921
1922         return 0;
1923 }
1924
1925 static size_t determine_word_size(size_t sz, size_t extra) {
1926         if (sz + extra <= 0xFF)
1927                 return 1;
1928         else if (sz + extra*2 <= 0xFFFF)
1929                 return 2;
1930         else if (sz + extra*4 <= 0xFFFFFFFF)
1931                 return 4;
1932         else
1933                 return 8;
1934 }
1935
1936 static size_t read_word_le(void *p, size_t sz) {
1937         union {
1938                 uint16_t u16;
1939                 uint32_t u32;
1940                 uint64_t u64;
1941         } x;
1942
1943         assert(p);
1944
1945         if (sz == 1)
1946                 return *(uint8_t*) p;
1947
1948         memcpy(&x, p, sz);
1949
1950         if (sz == 2)
1951                 return le16toh(x.u16);
1952         else if (sz == 4)
1953                 return le32toh(x.u32);
1954         else if (sz == 8)
1955                 return le64toh(x.u64);
1956
1957         assert_not_reached("unknown word width");
1958 }
1959
1960 static void write_word_le(void *p, size_t sz, size_t value) {
1961         union {
1962                 uint16_t u16;
1963                 uint32_t u32;
1964                 uint64_t u64;
1965         } x;
1966
1967         assert(p);
1968         assert(sz == 8 || (value < (1ULL << (sz*8))));
1969
1970         if (sz == 1) {
1971                 *(uint8_t*) p = value;
1972                 return;
1973         } else if (sz == 2)
1974                 x.u16 = htole16((uint16_t) value);
1975         else if (sz == 4)
1976                 x.u32 = htole32((uint32_t) value);
1977         else if (sz == 8)
1978                 x.u64 = htole64((uint64_t) value);
1979         else
1980                 assert_not_reached("unknown word width");
1981
1982         memcpy(p, &x, sz);
1983 }
1984
1985 static int bus_message_close_array(sd_bus_message *m, struct bus_container *c) {
1986
1987         assert(m);
1988         assert(c);
1989
1990         if (!BUS_MESSAGE_IS_GVARIANT(m))
1991                 return 0;
1992
1993         if (c->need_offsets) {
1994                 size_t payload, sz, i;
1995                 uint8_t *a;
1996
1997                 /* Variable-width arrays */
1998
1999                 payload = c->n_offsets > 0 ? c->offsets[c->n_offsets-1] - c->begin : 0;
2000                 sz = determine_word_size(payload, c->n_offsets);
2001
2002                 a = message_extend_body(m, 1, sz * c->n_offsets, true);
2003                 if (!a)
2004                         return -ENOMEM;
2005
2006                 for (i = 0; i < c->n_offsets; i++)
2007                         write_word_le(a + sz*i, sz, c->offsets[i] - c->begin);
2008         } else {
2009                 void *a;
2010
2011                 /* Fixed-width or empty arrays */
2012
2013                 a = message_extend_body(m, 1, 0, true); /* let's add offset to parent */
2014                 if (!a)
2015                         return -ENOMEM;
2016         }
2017
2018         return 0;
2019 }
2020
2021 static int bus_message_close_variant(sd_bus_message *m, struct bus_container *c) {
2022         uint8_t *a;
2023         size_t l;
2024
2025         assert(m);
2026         assert(c);
2027
2028         if (!BUS_MESSAGE_IS_GVARIANT(m))
2029                 return 0;
2030
2031         l = strlen(c->signature);
2032
2033         a = message_extend_body(m, 1, 1 + l, true);
2034         if (!a)
2035                 return -ENOMEM;
2036
2037         a[0] = 0;
2038         memcpy(a+1, c->signature, l);
2039
2040         return 0;
2041 }
2042
2043 static int bus_message_close_struct(sd_bus_message *m, struct bus_container *c, bool add_offset) {
2044         size_t n_variable = 0;
2045         unsigned i = 0;
2046         const char *p;
2047         uint8_t *a;
2048         int r;
2049
2050         assert(m);
2051         assert(c);
2052
2053         if (!BUS_MESSAGE_IS_GVARIANT(m))
2054                 return 0;
2055
2056         p = strempty(c->signature);
2057         while (*p != 0) {
2058                 size_t n;
2059
2060                 r = signature_element_length(p, &n);
2061                 if (r < 0)
2062                         return r;
2063                 else {
2064                         char t[n+1];
2065
2066                         memcpy(t, p, n);
2067                         t[n] = 0;
2068
2069                         r = bus_gvariant_is_fixed_size(t);
2070                         if (r < 0)
2071                                 return r;
2072                 }
2073
2074                 assert(!c->need_offsets || i <= c->n_offsets);
2075
2076                 /* We need to add an offset for each item that has a
2077                  * variable size and that is not the last one in the
2078                  * list */
2079                 if (r == 0 && p[n] != 0)
2080                         n_variable++;
2081
2082                 i++;
2083                 p += n;
2084         }
2085
2086         assert(!c->need_offsets || i == c->n_offsets);
2087         assert(c->need_offsets || n_variable == 0);
2088
2089         if (n_variable <= 0) {
2090                 a = message_extend_body(m, 1, 0, add_offset);
2091                 if (!a)
2092                         return -ENOMEM;
2093         } else {
2094                 size_t sz;
2095                 unsigned j;
2096
2097                 assert(c->offsets[c->n_offsets-1] == m->header->body_size);
2098
2099                 sz = determine_word_size(m->header->body_size - c->begin, n_variable);
2100
2101                 a = message_extend_body(m, 1, sz * n_variable, add_offset);
2102                 if (!a)
2103                         return -ENOMEM;
2104
2105                 p = strempty(c->signature);
2106                 for (i = 0, j = 0; i < c->n_offsets; i++) {
2107                         unsigned k;
2108                         size_t n;
2109
2110                         r = signature_element_length(p, &n);
2111                         if (r < 0)
2112                                 return r;
2113                         else {
2114                                 char t[n+1];
2115
2116                                 memcpy(t, p, n);
2117                                 t[n] = 0;
2118
2119                                 p += n;
2120
2121                                 r = bus_gvariant_is_fixed_size(t);
2122                                 if (r < 0)
2123                                         return r;
2124                                 if (r > 0 || p[0] == 0)
2125                                         continue;
2126                         }
2127
2128                         k = n_variable - 1 - j;
2129
2130                         write_word_le(a + k * sz, sz, c->offsets[i] - c->begin);
2131
2132                         j++;
2133                 }
2134         }
2135
2136         return 0;
2137 }
2138
2139 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
2140         struct bus_container *c;
2141         int r;
2142
2143         assert_return(m, -EINVAL);
2144         assert_return(!m->sealed, -EPERM);
2145         assert_return(m->n_containers > 0, -EINVAL);
2146         assert_return(!m->poisoned, -ESTALE);
2147
2148         c = message_get_container(m);
2149
2150         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2151                 if (c->signature && c->signature[c->index] != 0)
2152                         return -EINVAL;
2153
2154         m->n_containers--;
2155
2156         if (c->enclosing == SD_BUS_TYPE_ARRAY)
2157                 r = bus_message_close_array(m, c);
2158         else if (c->enclosing == SD_BUS_TYPE_VARIANT)
2159                 r = bus_message_close_variant(m, c);
2160         else if (c->enclosing == SD_BUS_TYPE_STRUCT || c->enclosing == SD_BUS_TYPE_DICT_ENTRY)
2161                 r = bus_message_close_struct(m, c, true);
2162         else
2163                 assert_not_reached("Unknown container type");
2164
2165         free(c->signature);
2166         free(c->offsets);
2167
2168         return r;
2169 }
2170
2171 typedef struct {
2172         const char *types;
2173         unsigned n_struct;
2174         unsigned n_array;
2175 } TypeStack;
2176
2177 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
2178         assert(stack);
2179         assert(max > 0);
2180
2181         if (*i >= max)
2182                 return -EINVAL;
2183
2184         stack[*i].types = types;
2185         stack[*i].n_struct = n_struct;
2186         stack[*i].n_array = n_array;
2187         (*i)++;
2188
2189         return 0;
2190 }
2191
2192 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
2193         assert(stack);
2194         assert(max > 0);
2195         assert(types);
2196         assert(n_struct);
2197         assert(n_array);
2198
2199         if (*i <= 0)
2200                 return 0;
2201
2202         (*i)--;
2203         *types = stack[*i].types;
2204         *n_struct = stack[*i].n_struct;
2205         *n_array = stack[*i].n_array;
2206
2207         return 1;
2208 }
2209
2210 int bus_message_append_ap(
2211                 sd_bus_message *m,
2212                 const char *types,
2213                 va_list ap) {
2214
2215         unsigned n_array, n_struct;
2216         TypeStack stack[BUS_CONTAINER_DEPTH];
2217         unsigned stack_ptr = 0;
2218         int r;
2219
2220         assert(m);
2221
2222         if (!types)
2223                 return 0;
2224
2225         n_array = (unsigned) -1;
2226         n_struct = strlen(types);
2227
2228         for (;;) {
2229                 const char *t;
2230
2231                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2232                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2233                         if (r < 0)
2234                                 return r;
2235                         if (r == 0)
2236                                 break;
2237
2238                         r = sd_bus_message_close_container(m);
2239                         if (r < 0)
2240                                 return r;
2241
2242                         continue;
2243                 }
2244
2245                 t = types;
2246                 if (n_array != (unsigned) -1)
2247                         n_array --;
2248                 else {
2249                         types ++;
2250                         n_struct--;
2251                 }
2252
2253                 switch (*t) {
2254
2255                 case SD_BUS_TYPE_BYTE: {
2256                         uint8_t x;
2257
2258                         x = (uint8_t) va_arg(ap, int);
2259                         r = sd_bus_message_append_basic(m, *t, &x);
2260                         break;
2261                 }
2262
2263                 case SD_BUS_TYPE_BOOLEAN:
2264                 case SD_BUS_TYPE_INT32:
2265                 case SD_BUS_TYPE_UINT32:
2266                 case SD_BUS_TYPE_UNIX_FD: {
2267                         uint32_t x;
2268
2269                         /* We assume a boolean is the same as int32_t */
2270                         assert_cc(sizeof(int32_t) == sizeof(int));
2271
2272                         x = va_arg(ap, uint32_t);
2273                         r = sd_bus_message_append_basic(m, *t, &x);
2274                         break;
2275                 }
2276
2277                 case SD_BUS_TYPE_INT16:
2278                 case SD_BUS_TYPE_UINT16: {
2279                         uint16_t x;
2280
2281                         x = (uint16_t) va_arg(ap, int);
2282                         r = sd_bus_message_append_basic(m, *t, &x);
2283                         break;
2284                 }
2285
2286                 case SD_BUS_TYPE_INT64:
2287                 case SD_BUS_TYPE_UINT64:
2288                 case SD_BUS_TYPE_DOUBLE: {
2289                         uint64_t x;
2290
2291                         x = va_arg(ap, uint64_t);
2292                         r = sd_bus_message_append_basic(m, *t, &x);
2293                         break;
2294                 }
2295
2296                 case SD_BUS_TYPE_STRING:
2297                 case SD_BUS_TYPE_OBJECT_PATH:
2298                 case SD_BUS_TYPE_SIGNATURE: {
2299                         const char *x;
2300
2301                         x = va_arg(ap, const char*);
2302                         r = sd_bus_message_append_basic(m, *t, x);
2303                         break;
2304                 }
2305
2306                 case SD_BUS_TYPE_ARRAY: {
2307                         size_t k;
2308
2309                         r = signature_element_length(t + 1, &k);
2310                         if (r < 0)
2311                                 return r;
2312
2313                         {
2314                                 char s[k + 1];
2315                                 memcpy(s, t + 1, k);
2316                                 s[k] = 0;
2317
2318                                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2319                                 if (r < 0)
2320                                         return r;
2321                         }
2322
2323                         if (n_array == (unsigned) -1) {
2324                                 types += k;
2325                                 n_struct -= k;
2326                         }
2327
2328                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2329                         if (r < 0)
2330                                 return r;
2331
2332                         types = t + 1;
2333                         n_struct = k;
2334                         n_array = va_arg(ap, unsigned);
2335
2336                         break;
2337                 }
2338
2339                 case SD_BUS_TYPE_VARIANT: {
2340                         const char *s;
2341
2342                         s = va_arg(ap, const char*);
2343                         if (!s)
2344                                 return -EINVAL;
2345
2346                         r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2347                         if (r < 0)
2348                                 return r;
2349
2350                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2351                         if (r < 0)
2352                                 return r;
2353
2354                         types = s;
2355                         n_struct = strlen(s);
2356                         n_array = (unsigned) -1;
2357
2358                         break;
2359                 }
2360
2361                 case SD_BUS_TYPE_STRUCT_BEGIN:
2362                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2363                         size_t k;
2364
2365                         r = signature_element_length(t, &k);
2366                         if (r < 0)
2367                                 return r;
2368
2369                         {
2370                                 char s[k - 1];
2371
2372                                 memcpy(s, t + 1, k - 2);
2373                                 s[k - 2] = 0;
2374
2375                                 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2376                                 if (r < 0)
2377                                         return r;
2378                         }
2379
2380                         if (n_array == (unsigned) -1) {
2381                                 types += k - 1;
2382                                 n_struct -= k - 1;
2383                         }
2384
2385                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2386                         if (r < 0)
2387                                 return r;
2388
2389                         types = t + 1;
2390                         n_struct = k - 2;
2391                         n_array = (unsigned) -1;
2392
2393                         break;
2394                 }
2395
2396                 default:
2397                         r = -EINVAL;
2398                 }
2399
2400                 if (r < 0)
2401                         return r;
2402         }
2403
2404         return 1;
2405 }
2406
2407 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2408         va_list ap;
2409         int r;
2410
2411         assert_return(m, -EINVAL);
2412         assert_return(types, -EINVAL);
2413         assert_return(!m->sealed, -EPERM);
2414         assert_return(!m->poisoned, -ESTALE);
2415
2416         va_start(ap, types);
2417         r = bus_message_append_ap(m, types, ap);
2418         va_end(ap);
2419
2420         return r;
2421 }
2422
2423 _public_ int sd_bus_message_append_array_space(
2424                 sd_bus_message *m,
2425                 char type,
2426                 size_t size,
2427                 void **ptr) {
2428
2429         ssize_t align, sz;
2430         void *a;
2431         int r;
2432
2433         assert_return(m, -EINVAL);
2434         assert_return(!m->sealed, -EPERM);
2435         assert_return(bus_type_is_trivial(type) && type != SD_BUS_TYPE_BOOLEAN, -EINVAL);
2436         assert_return(ptr || size == 0, -EINVAL);
2437         assert_return(!m->poisoned, -ESTALE);
2438
2439         /* alignment and size of the trivial types (except bool) is
2440          * identical for gvariant and dbus1 marshalling */
2441         align = bus_type_get_alignment(type);
2442         sz = bus_type_get_size(type);
2443
2444         assert_se(align > 0);
2445         assert_se(sz > 0);
2446
2447         if (size % sz != 0)
2448                 return -EINVAL;
2449
2450         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2451         if (r < 0)
2452                 return r;
2453
2454         a = message_extend_body(m, align, size, false);
2455         if (!a)
2456                 return -ENOMEM;
2457
2458         r = sd_bus_message_close_container(m);
2459         if (r < 0)
2460                 return r;
2461
2462         *ptr = a;
2463         return 0;
2464 }
2465
2466 _public_ int sd_bus_message_append_array(sd_bus_message *m,
2467                                          char type,
2468                                          const void *ptr,
2469                                          size_t size) {
2470         int r;
2471         void *p;
2472
2473         assert_return(m, -EINVAL);
2474         assert_return(!m->sealed, -EPERM);
2475         assert_return(bus_type_is_trivial(type), -EINVAL);
2476         assert_return(ptr || size == 0, -EINVAL);
2477         assert_return(!m->poisoned, -ESTALE);
2478
2479         r = sd_bus_message_append_array_space(m, type, size, &p);
2480         if (r < 0)
2481                 return r;
2482
2483         if (size > 0)
2484                 memcpy(p, ptr, size);
2485
2486         return 0;
2487 }
2488
2489 _public_ int sd_bus_message_append_array_iovec(
2490                 sd_bus_message *m,
2491                 char type,
2492                 const struct iovec *iov,
2493                 unsigned n) {
2494
2495         size_t size;
2496         unsigned i;
2497         void *p;
2498         int r;
2499
2500         assert_return(m, -EINVAL);
2501         assert_return(!m->sealed, -EPERM);
2502         assert_return(bus_type_is_trivial(type), -EINVAL);
2503         assert_return(iov || n == 0, -EINVAL);
2504         assert_return(!m->poisoned, -ESTALE);
2505
2506         size = IOVEC_TOTAL_SIZE(iov, n);
2507
2508         r = sd_bus_message_append_array_space(m, type, size, &p);
2509         if (r < 0)
2510                 return r;
2511
2512         for (i = 0; i < n; i++) {
2513
2514                 if (iov[i].iov_base)
2515                         memcpy(p, iov[i].iov_base, iov[i].iov_len);
2516                 else
2517                         memzero(p, iov[i].iov_len);
2518
2519                 p = (uint8_t*) p + iov[i].iov_len;
2520         }
2521
2522         return 0;
2523 }
2524
2525 _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
2526                                                char type,
2527                                                sd_memfd *memfd) {
2528         _cleanup_close_ int copy_fd = -1;
2529         struct bus_body_part *part;
2530         ssize_t align, sz;
2531         uint64_t size;
2532         void *a;
2533         int r;
2534
2535         if (!m)
2536                 return -EINVAL;
2537         if (!memfd)
2538                 return -EINVAL;
2539         if (m->sealed)
2540                 return -EPERM;
2541         if (!bus_type_is_trivial(type))
2542                 return -EINVAL;
2543         if (m->poisoned)
2544                 return -ESTALE;
2545
2546         r = sd_memfd_set_sealed(memfd, true);
2547         if (r < 0)
2548                 return r;
2549
2550         copy_fd = sd_memfd_dup_fd(memfd);
2551         if (copy_fd < 0)
2552                 return copy_fd;
2553
2554         r = sd_memfd_get_size(memfd, &size);
2555         if (r < 0)
2556                 return r;
2557
2558         align = bus_type_get_alignment(type);
2559         sz = bus_type_get_size(type);
2560
2561         assert_se(align > 0);
2562         assert_se(sz > 0);
2563
2564         if (size % sz != 0)
2565                 return -EINVAL;
2566
2567         if (size > (uint64_t) (uint32_t) -1)
2568                 return -EINVAL;
2569
2570         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2571         if (r < 0)
2572                 return r;
2573
2574         a = message_extend_body(m, align, 0, false);
2575         if (!a)
2576                 return -ENOMEM;
2577
2578         part = message_append_part(m);
2579         if (!part)
2580                 return -ENOMEM;
2581
2582         part->memfd = copy_fd;
2583         part->sealed = true;
2584         part->size = size;
2585         copy_fd = -1;
2586
2587         m->header->body_size += size;
2588         message_extend_containers(m, size);
2589
2590         return sd_bus_message_close_container(m);
2591 }
2592
2593 _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2594         _cleanup_close_ int copy_fd = -1;
2595         struct bus_body_part *part;
2596         struct bus_container *c;
2597         uint64_t size;
2598         void *a;
2599         int r;
2600
2601         assert_return(m, -EINVAL);
2602         assert_return(memfd, -EINVAL);
2603         assert_return(!m->sealed, -EPERM);
2604         assert_return(!m->poisoned, -ESTALE);
2605
2606         r = sd_memfd_set_sealed(memfd, true);
2607         if (r < 0)
2608                 return r;
2609
2610         copy_fd = sd_memfd_dup_fd(memfd);
2611         if (copy_fd < 0)
2612                 return copy_fd;
2613
2614         r = sd_memfd_get_size(memfd, &size);
2615         if (r < 0)
2616                 return r;
2617
2618         /* We require this to be NUL terminated */
2619         if (size == 0)
2620                 return -EINVAL;
2621
2622         if (size > (uint64_t) (uint32_t) -1)
2623                 return -EINVAL;
2624
2625         c = message_get_container(m);
2626         if (c->signature && c->signature[c->index]) {
2627                 /* Container signature is already set */
2628
2629                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2630                         return -ENXIO;
2631         } else {
2632                 char *e;
2633
2634                 /* Maybe we can append to the signature? But only if this is the top-level container*/
2635                 if (c->enclosing != 0)
2636                         return -ENXIO;
2637
2638                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2639                 if (!e) {
2640                         m->poisoned = true;
2641                         return -ENOMEM;
2642                 }
2643         }
2644
2645         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
2646                 a = message_extend_body(m, 4, 4, false);
2647                 if (!a)
2648                         return -ENOMEM;
2649
2650                 *(uint32_t*) a = size - 1;
2651         }
2652
2653         part = message_append_part(m);
2654         if (!part)
2655                 return -ENOMEM;
2656
2657         part->memfd = copy_fd;
2658         part->sealed = true;
2659         part->size = size;
2660         copy_fd = -1;
2661
2662         m->header->body_size += size;
2663         message_extend_containers(m, size);
2664
2665         if (BUS_MESSAGE_IS_GVARIANT(m)) {
2666                 r = message_add_offset(m, m->header->body_size);
2667                 if (r < 0) {
2668                         m->poisoned = true;
2669                         return -ENOMEM;
2670                 }
2671         }
2672
2673         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2674                 c->index++;
2675
2676         return 0;
2677 }
2678
2679 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2680         char **i;
2681         int r;
2682
2683         assert_return(m, -EINVAL);
2684         assert_return(!m->sealed, -EPERM);
2685         assert_return(!m->poisoned, -ESTALE);
2686
2687         r = sd_bus_message_open_container(m, 'a', "s");
2688         if (r < 0)
2689                 return r;
2690
2691         STRV_FOREACH(i, l) {
2692                 r = sd_bus_message_append_basic(m, 's', *i);
2693                 if (r < 0)
2694                         return r;
2695         }
2696
2697         return sd_bus_message_close_container(m);
2698 }
2699
2700 static int bus_message_close_header(sd_bus_message *m) {
2701         uint8_t *a;
2702         size_t sz, i;
2703
2704         assert(m);
2705
2706         if (!BUS_MESSAGE_IS_GVARIANT(m))
2707                 return 0;
2708
2709         if (m->n_header_offsets < 1)
2710                 return 0;
2711
2712         assert(m->header->fields_size == m->header_offsets[m->n_header_offsets-1]);
2713
2714         sz = determine_word_size(m->header->fields_size, m->n_header_offsets);
2715
2716         a = message_extend_fields(m, 1, sz * m->n_header_offsets, false);
2717         if (!a)
2718                 return -ENOMEM;
2719
2720         for (i = 0; i < m->n_header_offsets; i++)
2721                 write_word_le(a + sz*i, sz, m->header_offsets[i]);
2722
2723         return 0;
2724 }
2725
2726 int bus_message_seal(sd_bus_message *m, uint64_t cookie, usec_t timeout) {
2727         struct bus_body_part *part;
2728         size_t l, a;
2729         unsigned i;
2730         int r;
2731
2732         assert(m);
2733
2734         if (m->sealed)
2735                 return -EPERM;
2736
2737         if (m->n_containers > 0)
2738                 return -EBADMSG;
2739
2740         if (m->poisoned)
2741                 return -ESTALE;
2742
2743         /* In vtables the return signature of method calls is listed,
2744          * let's check if they match if this is a response */
2745         if (m->header->type == SD_BUS_MESSAGE_METHOD_RETURN &&
2746             m->enforced_reply_signature &&
2747             !streq(strempty(m->root_container.signature), m->enforced_reply_signature))
2748                 return -ENOMSG;
2749
2750         /* If gvariant marshalling is used we need to close the body structure */
2751         r = bus_message_close_struct(m, &m->root_container, false);
2752         if (r < 0)
2753                 return r;
2754
2755         /* If there's a non-trivial signature set, then add it in here */
2756         if (!isempty(m->root_container.signature)) {
2757                 r = message_append_field_signature(m, BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2758                 if (r < 0)
2759                         return r;
2760         }
2761
2762         if (m->n_fds > 0) {
2763                 r = message_append_field_uint32(m, BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2764                 if (r < 0)
2765                         return r;
2766         }
2767
2768         r = bus_message_close_header(m);
2769         if (r < 0)
2770                 return r;
2771
2772         m->header->serial = (uint32_t) cookie;
2773         m->timeout = m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED ? 0 : timeout;
2774
2775         /* Add padding at the end of the fields part, since we know
2776          * the body needs to start at an 8 byte alignment. We made
2777          * sure we allocated enough space for this, so all we need to
2778          * do here is to zero it out. */
2779         l = BUS_MESSAGE_FIELDS_SIZE(m);
2780         a = ALIGN8(l) - l;
2781         if (a > 0)
2782                 memzero((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, a);
2783
2784         /* If this is something we can send as memfd, then let's seal
2785         the memfd now. Note that we can send memfds as payload only
2786         for directed messages, and not for broadcasts. */
2787         if (m->destination && m->bus && m->bus->use_memfd) {
2788                 MESSAGE_FOREACH_PART(part, i, m)
2789                         if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
2790                                 uint64_t sz;
2791
2792                                 /* Try to seal it if that makes
2793                                  * sense. First, unmap our own map to
2794                                  * make sure we don't keep it busy. */
2795                                 bus_body_part_unmap(part);
2796
2797                                 /* Then, sync up real memfd size */
2798                                 sz = part->size;
2799                                 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &sz) < 0)
2800                                         return -errno;
2801
2802                                 /* Finally, try to seal */
2803                                 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
2804                                         part->sealed = true;
2805                         }
2806         }
2807
2808         m->root_container.end = BUS_MESSAGE_BODY_SIZE(m);
2809         m->root_container.index = 0;
2810         m->root_container.offset_index = 0;
2811         m->root_container.item_size = m->root_container.n_offsets > 0 ? m->root_container.offsets[0] : 0;
2812
2813         m->sealed = true;
2814
2815         return 0;
2816 }
2817
2818 int bus_body_part_map(struct bus_body_part *part) {
2819         void *p;
2820         size_t psz;
2821
2822         assert_se(part);
2823
2824         if (part->data)
2825                 return 0;
2826
2827         if (part->size <= 0)
2828                 return 0;
2829
2830         /* For smaller zero parts (as used for padding) we don't need to map anything... */
2831         if (part->memfd < 0 && part->is_zero && part->size < 8) {
2832                 static const uint8_t zeroes[7] = { };
2833                 part->data = (void*) zeroes;
2834                 return 0;
2835         }
2836
2837         psz = PAGE_ALIGN(part->size);
2838
2839         if (part->memfd >= 0)
2840                 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2841         else if (part->is_zero)
2842                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2843         else
2844                 return -EINVAL;
2845
2846         if (p == MAP_FAILED)
2847                 return -errno;
2848
2849         part->mapped = psz;
2850         part->data = p;
2851         part->munmap_this = true;
2852
2853         return 0;
2854 }
2855
2856 void bus_body_part_unmap(struct bus_body_part *part) {
2857
2858         assert_se(part);
2859
2860         if (part->memfd < 0)
2861                 return;
2862
2863         if (!part->data)
2864                 return;
2865
2866         if (!part->munmap_this)
2867                 return;
2868
2869         assert_se(munmap(part->data, part->mapped) == 0);
2870
2871         part->data = NULL;
2872         part->mapped = 0;
2873         part->munmap_this = false;
2874
2875         return;
2876 }
2877
2878 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2879         size_t k, start, end;
2880
2881         assert(rindex);
2882         assert(align > 0);
2883
2884         start = ALIGN_TO((size_t) *rindex, align);
2885         end = start + nbytes;
2886
2887         if (end > sz)
2888                 return -EBADMSG;
2889
2890         /* Verify that padding is 0 */
2891         for (k = *rindex; k < start; k++)
2892                 if (((const uint8_t*) p)[k] != 0)
2893                         return -EBADMSG;
2894
2895         if (r)
2896                 *r = (uint8_t*) p + start;
2897
2898         *rindex = end;
2899
2900         return 1;
2901 }
2902
2903 static bool message_end_of_signature(sd_bus_message *m) {
2904         struct bus_container *c;
2905
2906         assert(m);
2907
2908         c = message_get_container(m);
2909         return !c->signature || c->signature[c->index] == 0;
2910 }
2911
2912 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2913         struct bus_container *c;
2914
2915         assert(m);
2916
2917         c = message_get_container(m);
2918         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2919                 return false;
2920
2921         if (BUS_MESSAGE_IS_GVARIANT(m))
2922                 return index >= c->end;
2923         else {
2924                 assert(c->array_size);
2925                 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2926         }
2927 }
2928
2929 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2930         assert_return(m, -EINVAL);
2931         assert_return(m->sealed, -EPERM);
2932
2933         if (complete && m->n_containers > 0)
2934                 return false;
2935
2936         if (message_end_of_signature(m))
2937                 return true;
2938
2939         if (message_end_of_array(m, m->rindex))
2940                 return true;
2941
2942         return false;
2943 }
2944
2945 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2946         struct bus_body_part *part;
2947         size_t begin;
2948         int r;
2949
2950         assert(m);
2951
2952         if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2953                 part = m->cached_rindex_part;
2954                 begin = m->cached_rindex_part_begin;
2955         } else {
2956                 part = &m->body;
2957                 begin = 0;
2958         }
2959
2960         while (part) {
2961                 if (index < begin)
2962                         return NULL;
2963
2964                 if (index + sz <= begin + part->size) {
2965
2966                         r = bus_body_part_map(part);
2967                         if (r < 0)
2968                                 return NULL;
2969
2970                         if (p)
2971                                 *p = (uint8_t*) part->data + index - begin;
2972
2973                         m->cached_rindex_part = part;
2974                         m->cached_rindex_part_begin = begin;
2975
2976                         return part;
2977                 }
2978
2979                 begin += part->size;
2980                 part = part->next;
2981         }
2982
2983         return NULL;
2984 }
2985
2986 static int container_next_item(sd_bus_message *m, struct bus_container *c, size_t *rindex) {
2987         int r;
2988
2989         assert(m);
2990         assert(c);
2991         assert(rindex);
2992
2993         if (!BUS_MESSAGE_IS_GVARIANT(m))
2994                 return 0;
2995
2996         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2997                 int sz;
2998
2999                 sz = bus_gvariant_get_size(c->signature);
3000                 if (sz < 0) {
3001                         int alignment;
3002
3003                         if (c->offset_index+1 >= c->n_offsets)
3004                                 goto end;
3005
3006                         /* Variable-size array */
3007
3008                         alignment = bus_gvariant_get_alignment(c->signature);
3009                         assert(alignment > 0);
3010
3011                         *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3012                         c->item_size = c->offsets[c->offset_index+1] - *rindex;
3013                 } else {
3014
3015                         if (c->offset_index+1 >= (c->end-c->begin)/sz)
3016                                 goto end;
3017
3018                         /* Fixed-size array */
3019                         *rindex = c->begin + (c->offset_index+1) * sz;
3020                         c->item_size = sz;
3021                 }
3022
3023                 c->offset_index++;
3024
3025         } else if (c->enclosing == 0 ||
3026                    c->enclosing == SD_BUS_TYPE_STRUCT ||
3027                    c->enclosing == SD_BUS_TYPE_DICT_ENTRY) {
3028
3029                 int alignment;
3030                 size_t n, j;
3031
3032                 if (c->offset_index+1 >= c->n_offsets)
3033                         goto end;
3034
3035                 r = signature_element_length(c->signature + c->index, &n);
3036                 if (r < 0)
3037                         return r;
3038
3039                 r = signature_element_length(c->signature + c->index + n, &j);
3040                 if (r < 0)
3041                         return r;
3042                 else {
3043                         char t[j+1];
3044                         memcpy(t, c->signature + c->index + n, j);
3045                         t[j] = 0;
3046
3047                         alignment = bus_gvariant_get_alignment(t);
3048                 }
3049
3050                 assert(alignment > 0);
3051
3052                 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3053                 c->item_size = c->offsets[c->offset_index+1] - *rindex;
3054
3055                 c->offset_index++;
3056
3057         } else if (c->enclosing == SD_BUS_TYPE_VARIANT)
3058                 goto end;
3059         else
3060                 assert_not_reached("Unknown container type");
3061
3062         return 0;
3063
3064 end:
3065         /* Reached the end */
3066         *rindex = c->end;
3067         c->item_size = 0;
3068         return 0;
3069 }
3070
3071
3072 static int message_peek_body(
3073                 sd_bus_message *m,
3074                 size_t *rindex,
3075                 size_t align,
3076                 size_t nbytes,
3077                 void **ret) {
3078
3079         size_t k, start, end, padding;
3080         struct bus_body_part *part;
3081         uint8_t *q;
3082
3083         assert(m);
3084         assert(rindex);
3085         assert(align > 0);
3086
3087         start = ALIGN_TO((size_t) *rindex, align);
3088         padding = start - *rindex;
3089         end = start + nbytes;
3090
3091         if (end > BUS_MESSAGE_BODY_SIZE(m))
3092                 return -EBADMSG;
3093
3094         part = find_part(m, *rindex, padding, (void**) &q);
3095         if (!part)
3096                 return -EBADMSG;
3097
3098         if (q) {
3099                 /* Verify padding */
3100                 for (k = 0; k < padding; k++)
3101                         if (q[k] != 0)
3102                                 return -EBADMSG;
3103         }
3104
3105         part = find_part(m, start, nbytes, (void**) &q);
3106         if (!part || (nbytes > 0 && !q))
3107                 return -EBADMSG;
3108
3109         *rindex = end;
3110
3111         if (ret)
3112                 *ret = q;
3113
3114         return 0;
3115 }
3116
3117 static bool validate_nul(const char *s, size_t l) {
3118
3119         /* Check for NUL chars in the string */
3120         if (memchr(s, 0, l))
3121                 return false;
3122
3123         /* Check for NUL termination */
3124         if (s[l] != 0)
3125                 return false;
3126
3127         return true;
3128 }
3129
3130 static bool validate_string(const char *s, size_t l) {
3131
3132         if (!validate_nul(s, l))
3133                 return false;
3134
3135         /* Check if valid UTF8 */
3136         if (!utf8_is_valid(s))
3137                 return false;
3138
3139         return true;
3140 }
3141
3142 static bool validate_signature(const char *s, size_t l) {
3143
3144         if (!validate_nul(s, l))
3145                 return false;
3146
3147         /* Check if valid signature */
3148         if (!signature_is_valid(s, true))
3149                 return false;
3150
3151         return true;
3152 }
3153
3154 static bool validate_object_path(const char *s, size_t l) {
3155
3156         if (!validate_nul(s, l))
3157                 return false;
3158
3159         if (!object_path_is_valid(s))
3160                 return false;
3161
3162         return true;
3163 }
3164
3165 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
3166         struct bus_container *c;
3167         size_t rindex;
3168         void *q;
3169         int r;
3170
3171         assert_return(m, -EINVAL);
3172         assert_return(m->sealed, -EPERM);
3173         assert_return(bus_type_is_basic(type), -EINVAL);
3174
3175         if (message_end_of_signature(m))
3176                 return -ENXIO;
3177
3178         if (message_end_of_array(m, m->rindex))
3179                 return 0;
3180
3181         c = message_get_container(m);
3182         if (c->signature[c->index] != type)
3183                 return -ENXIO;
3184
3185         rindex = m->rindex;
3186
3187         if (BUS_MESSAGE_IS_GVARIANT(m)) {
3188
3189                 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
3190                         bool ok;
3191
3192                         r = message_peek_body(m, &rindex, 1, c->item_size, &q);
3193                         if (r < 0)
3194                                 return r;
3195
3196                         if (type == SD_BUS_TYPE_STRING)
3197                                 ok = validate_string(q, c->item_size-1);
3198                         else if (type == SD_BUS_TYPE_OBJECT_PATH)
3199                                 ok = validate_object_path(q, c->item_size-1);
3200                         else
3201                                 ok = validate_signature(q, c->item_size-1);
3202
3203                         if (!ok)