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