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