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