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