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