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