chiark / gitweb /
sd-bus: sync kdbus.h (ABI break)
[elogind.git] / src / libsystemd / sd-bus / bus-message.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <sys/mman.h>
25
26 #include "util.h"
27 #include "utf8.h"
28 #include "strv.h"
29 #include "time-util.h"
30 #include "cgroup-util.h"
31 #include "memfd.h"
32
33 #include "sd-bus.h"
34 #include "bus-message.h"
35 #include "bus-internal.h"
36 #include "bus-type.h"
37 #include "bus-signature.h"
38 #include "bus-gvariant.h"
39 #include "bus-util.h"
40
41 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
42
43 static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
44
45         if (p == NULL)
46                 return NULL;
47
48         if (old_base == new_base)
49                 return (void*) p;
50
51         if ((uint8_t*) p < (uint8_t*) old_base)
52                 return (void*) p;
53
54         if ((uint8_t*) p >= (uint8_t*) old_base + sz)
55                 return (void*) p;
56
57         return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base);
58 }
59
60 static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
61         assert(m);
62         assert(part);
63
64         if (part->memfd >= 0) {
65                 /* If we can reuse the memfd, try that. For that it
66                  * can't be sealed yet. */
67
68                 if (!part->sealed)
69                         bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped, part->allocated);
70                 else {
71                         if (part->mapped > 0)
72                                 assert_se(munmap(part->data, part->mapped) == 0);
73
74                         safe_close(part->memfd);
75                 }
76
77         } else if (part->munmap_this)
78                 munmap(part->data, part->mapped);
79         else if (part->free_this)
80                 free(part->data);
81
82         if (part != &m->body)
83                 free(part);
84 }
85
86 static void message_reset_parts(sd_bus_message *m) {
87         struct bus_body_part *part;
88
89         assert(m);
90
91         part = &m->body;
92         while (m->n_body_parts > 0) {
93                 struct bus_body_part *next = part->next;
94                 message_free_part(m, part);
95                 part = next;
96                 m->n_body_parts--;
97         }
98
99         m->body_end = NULL;
100
101         m->cached_rindex_part = NULL;
102         m->cached_rindex_part_begin = 0;
103 }
104
105 static void message_reset_containers(sd_bus_message *m) {
106         unsigned i;
107
108         assert(m);
109
110         for (i = 0; i < m->n_containers; i++) {
111                 free(m->containers[i].signature);
112                 free(m->containers[i].offsets);
113         }
114
115         free(m->containers);
116         m->containers = NULL;
117
118         m->n_containers = m->containers_allocated = 0;
119         m->root_container.index = 0;
120 }
121
122 static void message_free(sd_bus_message *m) {
123         assert(m);
124
125         if (m->free_header)
126                 free(m->header);
127
128         message_reset_parts(m);
129
130         if (m->release_kdbus) {
131                 struct kdbus_cmd_free cmd_free;
132
133                 cmd_free.flags = 0;
134                 cmd_free.offset = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
135                 (void) ioctl(m->bus->input_fd, KDBUS_CMD_FREE, &cmd_free);
136         }
137
138         if (m->free_kdbus)
139                 free(m->kdbus);
140
141         sd_bus_unref(m->bus);
142
143         if (m->free_fds) {
144                 close_many(m->fds, m->n_fds);
145                 free(m->fds);
146         }
147
148         if (m->iovec != m->iovec_fixed)
149                 free(m->iovec);
150
151         message_reset_containers(m);
152         free(m->root_container.signature);
153         free(m->root_container.offsets);
154
155         free(m->root_container.peeked_signature);
156
157         bus_creds_done(&m->creds);
158         free(m);
159 }
160
161 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
162         void *op, *np;
163         size_t old_size, new_size, start;
164
165         assert(m);
166
167         if (m->poisoned)
168                 return NULL;
169
170         old_size = sizeof(struct bus_header) + m->header->fields_size;
171         start = ALIGN_TO(old_size, align);
172         new_size = start + sz;
173
174         if (old_size == new_size)
175                 return (uint8_t*) m->header + old_size;
176
177         if (new_size > (size_t) ((uint32_t) -1))
178                 goto poison;
179
180         if (m->free_header) {
181                 np = realloc(m->header, ALIGN8(new_size));
182                 if (!np)
183                         goto poison;
184         } else {
185                 /* Initially, the header is allocated as part of of
186                  * the sd_bus_message itself, let's replace it by
187                  * dynamic data */
188
189                 np = malloc(ALIGN8(new_size));
190                 if (!np)
191                         goto poison;
192
193                 memcpy(np, m->header, sizeof(struct bus_header));
194         }
195
196         /* Zero out padding */
197         if (start > old_size)
198                 memzero((uint8_t*) np + old_size, start - old_size);
199
200         op = m->header;
201         m->header = np;
202         m->header->fields_size = new_size - sizeof(struct bus_header);
203
204         /* Adjust quick access pointers */
205         m->path = adjust_pointer(m->path, op, old_size, m->header);
206         m->interface = adjust_pointer(m->interface, op, old_size, m->header);
207         m->member = adjust_pointer(m->member, op, old_size, m->header);
208         m->destination = adjust_pointer(m->destination, op, old_size, m->header);
209         m->sender = adjust_pointer(m->sender, op, old_size, m->header);
210         m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
211
212         m->free_header = true;
213
214         if (add_offset) {
215                 if (m->n_header_offsets >= ELEMENTSOF(m->header_offsets))
216                         goto poison;
217
218                 m->header_offsets[m->n_header_offsets++] = new_size - sizeof(struct bus_header);
219         }
220
221         return (uint8_t*) np + start;
222
223 poison:
224         m->poisoned = true;
225         return NULL;
226 }
227
228 static int message_append_field_string(
229                 sd_bus_message *m,
230                 uint8_t h,
231                 char type,
232                 const char *s,
233                 const char **ret) {
234
235         size_t l;
236         uint8_t *p;
237
238         assert(m);
239
240         /* dbus1 doesn't allow strings over 32bit, let's enforce this
241          * globally, to not risk convertability */
242         l = strlen(s);
243         if (l > (size_t) (uint32_t) -1)
244                 return -EINVAL;
245
246         /* Signature "(yv)" where the variant contains "s" */
247
248         if (BUS_MESSAGE_IS_GVARIANT(m)) {
249
250                 /* (field id byte + 7x padding, ((string + NUL) + NUL + signature string 's') */
251                 p = message_extend_fields(m, 8, 1 + 7 + l + 1 + 1 + 1, true);
252                 if (!p)
253                         return -ENOMEM;
254
255                 p[0] = h;
256                 memzero(p+1, 7);
257                 memcpy(p+8, s, l);
258                 p[8+l] = 0;
259                 p[8+l+1] = 0;
260                 p[8+l+2] = type;
261
262                 if (ret)
263                         *ret = (char*) p + 8;
264
265         } else {
266                 /* (field id byte + (signature length + signature 's' + NUL) + (string length + string + NUL)) */
267                 p = message_extend_fields(m, 8, 4 + 4 + l + 1, false);
268                 if (!p)
269                         return -ENOMEM;
270
271                 p[0] = h;
272                 p[1] = 1;
273                 p[2] = type;
274                 p[3] = 0;
275
276                 ((uint32_t*) p)[1] = l;
277                 memcpy(p + 8, s, l + 1);
278
279                 if (ret)
280                         *ret = (char*) p + 8;
281         }
282
283         return 0;
284 }
285
286 static int message_append_field_signature(
287                 sd_bus_message *m,
288                 uint8_t h,
289                 const char *s,
290                 const char **ret) {
291
292         size_t l;
293         uint8_t *p;
294
295         assert(m);
296
297         /* dbus1 doesn't allow signatures over 32bit, let's enforce
298          * this globally, to not risk convertability */
299         l = strlen(s);
300         if (l > 255)
301                 return -EINVAL;
302
303         /* Signature "(yv)" where the variant contains "g" */
304
305         if (BUS_MESSAGE_IS_GVARIANT(m))
306                 /* For gvariant the serialization is the same as for normal strings */
307                 return message_append_field_string(m, h, 'g', s, ret);
308         else {
309                 /* (field id byte + (signature length + signature 'g' + NUL) + (string length + string + NUL)) */
310                 p = message_extend_fields(m, 8, 4 + 1 + l + 1, false);
311                 if (!p)
312                         return -ENOMEM;
313
314                 p[0] = h;
315                 p[1] = 1;
316                 p[2] = SD_BUS_TYPE_SIGNATURE;
317                 p[3] = 0;
318                 p[4] = l;
319                 memcpy(p + 5, s, l + 1);
320
321                 if (ret)
322                         *ret = (const char*) p + 5;
323         }
324
325         return 0;
326 }
327
328 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
329         uint8_t *p;
330
331         assert(m);
332
333         if (BUS_MESSAGE_IS_GVARIANT(m)) {
334                 /* (field id byte + 7x padding + ((value + NUL + signature string 'u') */
335
336                 p = message_extend_fields(m, 8, 1 + 7 + 4 + 1 + 1, true);
337                 if (!p)
338                         return -ENOMEM;
339
340                 p[0] = h;
341                 memzero(p+1, 7);
342                 *((uint32_t*) (p + 8)) = x;
343                 p[12] = 0;
344                 p[13] = 'u';
345         } else {
346                 /* (field id byte + (signature length + signature 'u' + NUL) + value) */
347                 p = message_extend_fields(m, 8, 4 + 4, false);
348                 if (!p)
349                         return -ENOMEM;
350
351                 p[0] = h;
352                 p[1] = 1;
353                 p[2] = SD_BUS_TYPE_UINT32;
354                 p[3] = 0;
355
356                 ((uint32_t*) p)[1] = x;
357         }
358
359         return 0;
360 }
361
362 int bus_message_from_header(
363                 sd_bus *bus,
364                 void *buffer,
365                 size_t length,
366                 int *fds,
367                 unsigned n_fds,
368                 const struct ucred *ucred,
369                 const char *label,
370                 size_t extra,
371                 sd_bus_message **ret) {
372
373         sd_bus_message *m;
374         struct bus_header *h;
375         size_t a, label_sz;
376
377         assert(bus);
378         assert(buffer || length <= 0);
379         assert(fds || n_fds <= 0);
380         assert(ret);
381
382         if (length < sizeof(struct bus_header))
383                 return -EBADMSG;
384
385         h = buffer;
386         if (h->version != 1 &&
387             h->version != 2)
388                 return -EBADMSG;
389
390         if (h->serial == 0)
391                 return -EBADMSG;
392
393         if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
394                 return -EBADMSG;
395
396         if (h->endian != BUS_LITTLE_ENDIAN &&
397             h->endian != BUS_BIG_ENDIAN)
398                 return -EBADMSG;
399
400         a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
401
402         if (label) {
403                 label_sz = strlen(label);
404                 a += label_sz + 1;
405         }
406
407         m = malloc0(a);
408         if (!m)
409                 return -ENOMEM;
410
411         m->n_ref = 1;
412         m->sealed = true;
413         m->header = h;
414         m->fds = fds;
415         m->n_fds = n_fds;
416
417         if (ucred) {
418                 m->creds.uid = ucred->uid;
419                 m->creds.pid = ucred->pid;
420                 m->creds.gid = ucred->gid;
421                 m->creds.mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_PID | SD_BUS_CREDS_GID;
422         }
423
424         if (label) {
425                 m->creds.label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
426                 memcpy(m->creds.label, label, label_sz + 1);
427
428                 m->creds.mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
429         }
430
431         m->bus = sd_bus_ref(bus);
432         *ret = m;
433
434         return 0;
435 }
436
437 int bus_message_from_malloc(
438                 sd_bus *bus,
439                 void *buffer,
440                 size_t length,
441                 int *fds,
442                 unsigned n_fds,
443                 const struct ucred *ucred,
444                 const char *label,
445                 sd_bus_message **ret) {
446
447         sd_bus_message *m;
448         size_t sz;
449         int r;
450
451         r = bus_message_from_header(bus, buffer, length, fds, n_fds, ucred, label, 0, &m);
452         if (r < 0)
453                 return r;
454
455         if (length != BUS_MESSAGE_SIZE(m)) {
456                 r = -EBADMSG;
457                 goto fail;
458         }
459
460         sz = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
461         if (sz > 0) {
462                 m->n_body_parts = 1;
463                 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
464                 m->body.size = sz;
465                 m->body.sealed = true;
466                 m->body.memfd = -1;
467         }
468
469         m->n_iovec = 1;
470         m->iovec = m->iovec_fixed;
471         m->iovec[0].iov_base = buffer;
472         m->iovec[0].iov_len = length;
473
474         r = bus_message_parse_fields(m);
475         if (r < 0)
476                 goto fail;
477
478         /* We take possession of the memory and fds now */
479         m->free_header = true;
480         m->free_fds = true;
481
482         *ret = m;
483         return 0;
484
485 fail:
486         message_free(m);
487         return r;
488 }
489
490 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
491         sd_bus_message *m;
492
493         assert(bus);
494
495         m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
496         if (!m)
497                 return NULL;
498
499         m->n_ref = 1;
500         m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
501         m->header->endian = BUS_NATIVE_ENDIAN;
502         m->header->type = type;
503         m->header->version = bus ? bus->message_version : 1;
504         m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
505         m->root_container.need_offsets = BUS_MESSAGE_IS_GVARIANT(m);
506         m->bus = sd_bus_ref(bus);
507
508         return m;
509 }
510
511 _public_ int sd_bus_message_new_signal(
512                 sd_bus *bus,
513                 sd_bus_message **m,
514                 const char *path,
515                 const char *interface,
516                 const char *member) {
517
518         sd_bus_message *t;
519         int r;
520
521         assert_return(bus, -ENOTCONN);
522         assert_return(bus->state != BUS_UNSET, -ENOTCONN);
523         assert_return(object_path_is_valid(path), -EINVAL);
524         assert_return(interface_name_is_valid(interface), -EINVAL);
525         assert_return(member_name_is_valid(member), -EINVAL);
526         assert_return(m, -EINVAL);
527
528         t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
529         if (!t)
530                 return -ENOMEM;
531
532         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
533
534         r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
535         if (r < 0)
536                 goto fail;
537         r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
538         if (r < 0)
539                 goto fail;
540         r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
541         if (r < 0)
542                 goto fail;
543
544         *m = t;
545         return 0;
546
547 fail:
548         sd_bus_message_unref(t);
549         return r;
550 }
551
552 _public_ int sd_bus_message_new_method_call(
553                 sd_bus *bus,
554                 sd_bus_message **m,
555                 const char *destination,
556                 const char *path,
557                 const char *interface,
558                 const char *member) {
559
560         sd_bus_message *t;
561         int r;
562
563         assert_return(bus, -ENOTCONN);
564         assert_return(bus->state != BUS_UNSET, -ENOTCONN);
565         assert_return(!destination || service_name_is_valid(destination), -EINVAL);
566         assert_return(object_path_is_valid(path), -EINVAL);
567         assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
568         assert_return(member_name_is_valid(member), -EINVAL);
569         assert_return(m, -EINVAL);
570
571         t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
572         if (!t)
573                 return -ENOMEM;
574
575         r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
576         if (r < 0)
577                 goto fail;
578         r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
579         if (r < 0)
580                 goto fail;
581
582         if (interface) {
583                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
584                 if (r < 0)
585                         goto fail;
586         }
587
588         if (destination) {
589                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
590                 if (r < 0)
591                         goto fail;
592         }
593
594         *m = t;
595         return 0;
596
597 fail:
598         message_free(t);
599         return r;
600 }
601
602 static int message_new_reply(
603                 sd_bus_message *call,
604                 uint8_t type,
605                 sd_bus_message **m) {
606
607         sd_bus_message *t;
608         int r;
609
610         assert_return(call, -EINVAL);
611         assert_return(call->sealed, -EPERM);
612         assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
613         assert_return(call->bus->state != BUS_UNSET, -ENOTCONN);
614         assert_return(m, -EINVAL);
615
616         t = message_new(call->bus, type);
617         if (!t)
618                 return -ENOMEM;
619
620         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
621         t->reply_cookie = BUS_MESSAGE_COOKIE(call);
622
623         r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) t->reply_cookie);
624         if (r < 0)
625                 goto fail;
626
627         if (call->sender) {
628                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
629                 if (r < 0)
630                         goto fail;
631         }
632
633         t->dont_send = !!(call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
634         t->enforced_reply_signature = call->enforced_reply_signature;
635
636         *m = t;
637         return 0;
638
639 fail:
640         message_free(t);
641         return r;
642 }
643
644 _public_ int sd_bus_message_new_method_return(
645                 sd_bus_message *call,
646                 sd_bus_message **m) {
647
648         return message_new_reply(call, SD_BUS_MESSAGE_METHOD_RETURN, m);
649 }
650
651 _public_ int sd_bus_message_new_method_error(
652                 sd_bus_message *call,
653                 sd_bus_message **m,
654                 const sd_bus_error *e) {
655
656         sd_bus_message *t;
657         int r;
658
659         assert_return(sd_bus_error_is_set(e), -EINVAL);
660         assert_return(m, -EINVAL);
661
662         r = message_new_reply(call, SD_BUS_MESSAGE_METHOD_ERROR, &t);
663         if (r < 0)
664                 return r;
665
666         r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
667         if (r < 0)
668                 goto fail;
669
670         if (e->message) {
671                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
672                 if (r < 0)
673                         goto fail;
674         }
675
676         t->error._need_free = -1;
677
678         *m = t;
679         return 0;
680
681 fail:
682         message_free(t);
683         return r;
684 }
685
686 _public_ int sd_bus_message_new_method_errorf(
687                 sd_bus_message *call,
688                 sd_bus_message **m,
689                 const char *name,
690                 const char *format,
691                 ...) {
692
693         _cleanup_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
694         va_list ap;
695
696         assert_return(name, -EINVAL);
697         assert_return(m, -EINVAL);
698
699         va_start(ap, format);
700         bus_error_setfv(&error, name, format, ap);
701         va_end(ap);
702
703         return sd_bus_message_new_method_error(call, m, &error);
704 }
705
706 _public_ int sd_bus_message_new_method_errno(
707                 sd_bus_message *call,
708                 sd_bus_message **m,
709                 int error,
710                 const sd_bus_error *p) {
711
712         _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
713
714         if (sd_bus_error_is_set(p))
715                 return sd_bus_message_new_method_error(call, m, p);
716
717         sd_bus_error_set_errno(&berror, error);
718
719         return sd_bus_message_new_method_error(call, m, &berror);
720 }
721
722 _public_ int sd_bus_message_new_method_errnof(
723                 sd_bus_message *call,
724                 sd_bus_message **m,
725                 int error,
726                 const char *format,
727                 ...) {
728
729         _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
730         va_list ap;
731
732         va_start(ap, format);
733         bus_error_set_errnofv(&berror, error, format, ap);
734         va_end(ap);
735
736         return sd_bus_message_new_method_error(call, m, &berror);
737 }
738
739 int bus_message_new_synthetic_error(
740                 sd_bus *bus,
741                 uint64_t cookie,
742                 const sd_bus_error *e,
743                 sd_bus_message **m) {
744
745         sd_bus_message *t;
746         int r;
747
748         assert(bus);
749         assert(sd_bus_error_is_set(e));
750         assert(m);
751
752         t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
753         if (!t)
754                 return -ENOMEM;
755
756         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
757         t->reply_cookie = cookie;
758
759         r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) t->reply_cookie);
760         if (r < 0)
761                 goto fail;
762
763         if (bus && bus->unique_name) {
764                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
765                 if (r < 0)
766                         goto fail;
767         }
768
769         r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
770         if (r < 0)
771                 goto fail;
772
773         if (e->message) {
774                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
775                 if (r < 0)
776                         goto fail;
777         }
778
779         t->error._need_free = -1;
780
781         *m = t;
782         return 0;
783
784 fail:
785         message_free(t);
786         return r;
787 }
788
789 _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
790         assert_return(m, NULL);
791
792         assert(m->n_ref > 0);
793         m->n_ref++;
794
795         return m;
796 }
797
798 _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
799
800         if (!m)
801                 return NULL;
802
803         assert(m->n_ref > 0);
804         m->n_ref--;
805
806         if (m->n_ref > 0)
807                 return NULL;
808
809         message_free(m);
810         return NULL;
811 }
812
813 _public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
814         assert_return(m, -EINVAL);
815         assert_return(type, -EINVAL);
816
817         *type = m->header->type;
818         return 0;
819 }
820
821 _public_ int sd_bus_message_get_cookie(sd_bus_message *m, uint64_t *cookie) {
822         assert_return(m, -EINVAL);
823         assert_return(cookie, -EINVAL);
824         assert_return(m->header->serial != 0, -ENODATA);
825
826         *cookie = BUS_MESSAGE_COOKIE(m);
827         return 0;
828 }
829
830 _public_ int sd_bus_message_get_reply_cookie(sd_bus_message *m, uint64_t *cookie) {
831         assert_return(m, -EINVAL);
832         assert_return(cookie, -EINVAL);
833         assert_return(m->reply_cookie != 0, -ENODATA);
834
835         *cookie = m->reply_cookie;
836         return 0;
837 }
838
839 _public_ int sd_bus_message_get_expect_reply(sd_bus_message *m) {
840         assert_return(m, -EINVAL);
841
842         return m->header->type == SD_BUS_MESSAGE_METHOD_CALL &&
843                 !(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
844 }
845
846 _public_ int sd_bus_message_get_auto_start(sd_bus_message *m) {
847         assert_return(m, -EINVAL);
848
849         return !(m->header->flags & BUS_MESSAGE_NO_AUTO_START);
850 }
851
852 _public_ 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 = ftruncate(part->memfd, new_allocated);
1101                         if (r < 0) {
1102                                 m->poisoned = true;
1103                                 return -errno;
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                                 if (ftruncate(part->memfd, sz) < 0)
2824                                         return -errno;
2825
2826                                 /* Finally, try to seal */
2827                                 if (fcntl(part->memfd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE) >= 0)
2828                                         part->sealed = true;
2829                         }
2830         }
2831
2832         m->root_container.end = BUS_MESSAGE_BODY_SIZE(m);
2833         m->root_container.index = 0;
2834         m->root_container.offset_index = 0;
2835         m->root_container.item_size = m->root_container.n_offsets > 0 ? m->root_container.offsets[0] : 0;
2836
2837         m->sealed = true;
2838
2839         return 0;
2840 }
2841
2842 int bus_body_part_map(struct bus_body_part *part) {
2843         void *p;
2844         size_t psz;
2845
2846         assert_se(part);
2847
2848         if (part->data)
2849                 return 0;
2850
2851         if (part->size <= 0)
2852                 return 0;
2853
2854         /* For smaller zero parts (as used for padding) we don't need to map anything... */
2855         if (part->memfd < 0 && part->is_zero && part->size < 8) {
2856                 static const uint8_t zeroes[7] = { };
2857                 part->data = (void*) zeroes;
2858                 return 0;
2859         }
2860
2861         psz = PAGE_ALIGN(part->size);
2862
2863         if (part->memfd >= 0)
2864                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE, part->memfd, 0);
2865         else if (part->is_zero)
2866                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2867         else
2868                 return -EINVAL;
2869
2870         if (p == MAP_FAILED)
2871                 return -errno;
2872
2873         part->mapped = psz;
2874         part->data = p;
2875         part->munmap_this = true;
2876
2877         return 0;
2878 }
2879
2880 void bus_body_part_unmap(struct bus_body_part *part) {
2881
2882         assert_se(part);
2883
2884         if (part->memfd < 0)
2885                 return;
2886
2887         if (!part->data)
2888                 return;
2889
2890         if (!part->munmap_this)
2891                 return;
2892
2893         assert_se(munmap(part->data, part->mapped) == 0);
2894
2895         part->data = NULL;
2896         part->mapped = 0;
2897         part->munmap_this = false;
2898
2899         return;
2900 }
2901
2902 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2903         size_t k, start, end;
2904
2905         assert(rindex);
2906         assert(align > 0);
2907
2908         start = ALIGN_TO((size_t) *rindex, align);
2909         end = start + nbytes;
2910
2911         if (end > sz)
2912                 return -EBADMSG;
2913
2914         /* Verify that padding is 0 */
2915         for (k = *rindex; k < start; k++)
2916                 if (((const uint8_t*) p)[k] != 0)
2917                         return -EBADMSG;
2918
2919         if (r)
2920                 *r = (uint8_t*) p + start;
2921
2922         *rindex = end;
2923
2924         return 1;
2925 }
2926
2927 static bool message_end_of_signature(sd_bus_message *m) {
2928         struct bus_container *c;
2929
2930         assert(m);
2931
2932         c = message_get_container(m);
2933         return !c->signature || c->signature[c->index] == 0;
2934 }
2935
2936 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2937         struct bus_container *c;
2938
2939         assert(m);
2940
2941         c = message_get_container(m);
2942         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2943                 return false;
2944
2945         if (BUS_MESSAGE_IS_GVARIANT(m))
2946                 return index >= c->end;
2947         else {
2948                 assert(c->array_size);
2949                 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2950         }
2951 }
2952
2953 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2954         assert_return(m, -EINVAL);
2955         assert_return(m->sealed, -EPERM);
2956
2957         if (complete && m->n_containers > 0)
2958                 return false;
2959
2960         if (message_end_of_signature(m))
2961                 return true;
2962
2963         if (message_end_of_array(m, m->rindex))
2964                 return true;
2965
2966         return false;
2967 }
2968
2969 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2970         struct bus_body_part *part;
2971         size_t begin;
2972         int r;
2973
2974         assert(m);
2975
2976         if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2977                 part = m->cached_rindex_part;
2978                 begin = m->cached_rindex_part_begin;
2979         } else {
2980                 part = &m->body;
2981                 begin = 0;
2982         }
2983
2984         while (part) {
2985                 if (index < begin)
2986                         return NULL;
2987
2988                 if (index + sz <= begin + part->size) {
2989
2990                         r = bus_body_part_map(part);
2991                         if (r < 0)
2992                                 return NULL;
2993
2994                         if (p)
2995                                 *p = (uint8_t*) part->data + index - begin;
2996
2997                         m->cached_rindex_part = part;
2998                         m->cached_rindex_part_begin = begin;
2999
3000                         return part;
3001                 }
3002
3003                 begin += part->size;
3004                 part = part->next;
3005         }
3006
3007         return NULL;
3008 }
3009
3010 static int container_next_item(sd_bus_message *m, struct bus_container *c, size_t *rindex) {
3011         int r;
3012
3013         assert(m);
3014         assert(c);
3015         assert(rindex);
3016
3017         if (!BUS_MESSAGE_IS_GVARIANT(m))
3018                 return 0;
3019
3020         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3021                 int sz;
3022
3023                 sz = bus_gvariant_get_size(c->signature);
3024                 if (sz < 0) {
3025                         int alignment;
3026
3027                         if (c->offset_index+1 >= c->n_offsets)
3028                                 goto end;
3029
3030                         /* Variable-size array */
3031
3032                         alignment = bus_gvariant_get_alignment(c->signature);
3033                         assert(alignment > 0);
3034
3035                         *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3036                         c->item_size = c->offsets[c->offset_index+1] - *rindex;
3037                 } else {
3038
3039                         if (c->offset_index+1 >= (c->end-c->begin)/sz)
3040                                 goto end;
3041
3042                         /* Fixed-size array */
3043                         *rindex = c->begin + (c->offset_index+1) * sz;
3044                         c->item_size = sz;
3045                 }
3046
3047                 c->offset_index++;
3048
3049         } else if (c->enclosing == 0 ||
3050                    c->enclosing == SD_BUS_TYPE_STRUCT ||
3051                    c->enclosing == SD_BUS_TYPE_DICT_ENTRY) {
3052
3053                 int alignment;
3054                 size_t n, j;
3055
3056                 if (c->offset_index+1 >= c->n_offsets)
3057                         goto end;
3058
3059                 r = signature_element_length(c->signature + c->index, &n);
3060                 if (r < 0)
3061                         return r;
3062
3063                 r = signature_element_length(c->signature + c->index + n, &j);
3064                 if (r < 0)
3065                         return r;
3066                 else {
3067                         char t[j+1];
3068                         memcpy(t, c->signature + c->index + n, j);
3069                         t[j] = 0;
3070
3071                         alignment = bus_gvariant_get_alignment(t);
3072                 }
3073
3074                 assert(alignment > 0);
3075
3076                 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3077                 c->item_size = c->offsets[c->offset_index+1] - *rindex;
3078
3079                 c->offset_index++;
3080
3081         } else if (c->enclosing == SD_BUS_TYPE_VARIANT)
3082                 goto end;
3083         else
3084                 assert_not_reached("Unknown container type");
3085
3086         return 0;
3087
3088 end:
3089         /* Reached the end */
3090         *rindex = c->end;
3091         c->item_size = 0;
3092         return 0;
3093 }
3094
3095
3096 static int message_peek_body(
3097                 sd_bus_message *m,
3098                 size_t *rindex,
3099                 size_t align,
3100                 size_t nbytes,
3101                 void **ret) {
3102
3103         size_t k, start, end, padding;
3104         struct bus_body_part *part;
3105         uint8_t *q;
3106
3107         assert(m);
3108         assert(rindex);
3109         assert(align > 0);
3110
3111         start = ALIGN_TO((size_t) *rindex, align);
3112         padding = start - *rindex;
3113         end = start + nbytes;
3114
3115         if (end > BUS_MESSAGE_BODY_SIZE(m))
3116                 return -EBADMSG;
3117
3118         part = find_part(m, *rindex, padding, (void**) &q);
3119         if (!part)
3120                 return -EBADMSG;
3121
3122         if (q) {
3123                 /* Verify padding */
3124                 for (k = 0; k < padding; k++)
3125                         if (q[k] != 0)
3126                                 return -EBADMSG;
3127         }
3128
3129         part = find_part(m, start, nbytes, (void**) &q);
3130         if (!part || (nbytes > 0 && !q))
3131                 return -EBADMSG;
3132
3133         *rindex = end;
3134
3135         if (ret)
3136                 *ret = q;
3137
3138         return 0;
3139 }
3140
3141 static bool validate_nul(const char *s, size_t l) {
3142
3143         /* Check for NUL chars in the string */
3144         if (memchr(s, 0, l))
3145                 return false;
3146
3147         /* Check for NUL termination */
3148         if (s[l] != 0)
3149                 return false;
3150
3151         return true;
3152 }
3153
3154 static bool validate_string(const char *s, size_t l) {
3155
3156         if (!validate_nul(s, l))
3157                 return false;
3158
3159         /* Check if valid UTF8 */
3160         if (!utf8_is_valid(s))
3161                 return false;
3162
3163         return true;
3164 }
3165
3166 static bool validate_signature(const char *s, size_t l) {
3167
3168         if (!validate_nul(s, l))
3169                 return false;
3170
3171         /* Check if valid signature */
3172         if (!signature_is_valid(s, true))
3173                 return false;
3174
3175         return true;
3176 }
3177
3178 static bool validate_object_path(const char *s, size_t l) {
3179
3180         if (!validate_nul(s, l))
3181                 return false;
3182
3183         if (!object_path_is_valid(s))
3184                 return false;
3185
3186         return true;
3187 }
3188
3189 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
3190         struct bus_container *c;
3191         size_t rindex;
3192         void *q;
3193         int r;
3194
3195         assert_return(m, -EINVAL);
3196         assert_return(m->sealed, -EPERM);
3197         assert_return(bus_type_is_basic(type), -EINVAL);
3198
3199         if (message_end_of_signature(m))
3200                 return -ENXIO;
3201
3202         if (message_end_of_array(m, m->rindex))
3203                 return 0;
3204
3205         c = message_get_container(m);
3206         if (c->signature[c->index] != type)
3207                 return -ENXIO;
3208
3209         rindex = m->rindex;
3210
3211         if (BUS_MESSAGE_IS_GVARIANT(m)) {
3212
3213                 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
3214                         bool ok;
3215
3216                         r = message_peek_body(m, &rindex, 1, c->item_size, &q);
3217                         if (r < 0)
3218                                 return r;
3219
3220                         if (type == SD_BUS_TYPE_STRING)
3221                                 ok = validate_string(q, c->item_size-1);
3222                         else if (type == SD_BUS_TYPE_OBJECT_PATH)
3223                                 ok = validate_object_path(q, c->item_size-1);
3224                         else
3225                                 ok = validate_signature(q, c->item_size-1);
3226
3227                         if (!ok)
3228                                 return -EBADMSG;
3229
3230                         if (p)
3231                                 *(const char**) p = q;
3232                 } else {
3233                         int sz, align;
3234
3235                         sz = bus_gvariant_get_size(CHAR_TO_STR(type));
3236                         assert(sz > 0);
3237                         if ((size_t) sz != c->item_size)
3238                                 return -EBADMSG;
3239
3240                         align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
3241                         assert(align > 0);
3242
3243                         r = message_peek_body(m, &rindex, align, c->item_size, &q);
3244                         if (r < 0)
3245                                 return r;
3246
3247                         switch (type) {
3248
3249                         case SD_BUS_TYPE_BYTE:
3250                                 if (p)
3251                                         *(uint8_t*) p = *(uint8_t*) q;
3252                                 break;
3253
3254                         case SD_BUS_TYPE_BOOLEAN:
3255                                 if (p)
3256                                         *(int*) p = !!*(uint8_t*) q;
3257                                 break;
3258
3259                         case SD_BUS_TYPE_INT16:
3260                         case SD_BUS_TYPE_UINT16:
3261                                 if (p)
3262                                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3263                                 break;
3264
3265                         case SD_BUS_TYPE_INT32:
3266                         case SD_BUS_TYPE_UINT32:
3267                                 if (p)
3268                                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3269                                 break;
3270
3271                         case SD_BUS_TYPE_INT64:
3272                         case SD_BUS_TYPE_UINT64:
3273                         case SD_BUS_TYPE_DOUBLE:
3274                                 if (p)
3275                                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3276                                 break;
3277
3278                         case SD_BUS_TYPE_UNIX_FD: {
3279                                 uint32_t j;
3280
3281                                 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3282                                 if (j >= m->n_fds)
3283                                         return -EBADMSG;
3284
3285                                 if (p)
3286                                         *(int*) p = m->fds[j];
3287
3288                                 break;
3289                         }
3290
3291                         default:
3292                                 assert_not_reached("unexpected type");
3293                         }
3294                 }
3295
3296                 r = container_next_item(m, c, &rindex);
3297                 if (r < 0)
3298                         return r;
3299         } else {
3300
3301                 rindex = m->rindex;
3302
3303                 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH)) {
3304                         uint32_t l;
3305                         bool ok;
3306
3307                         r = message_peek_body(m, &rindex, 4, 4, &q);
3308                         if (r < 0)
3309                                 return r;
3310
3311                         l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3312                         r = message_peek_body(m, &rindex, 1, l+1, &q);
3313                         if (r < 0)
3314                                 return r;
3315
3316                         if (type == SD_BUS_TYPE_OBJECT_PATH)
3317                                 ok = validate_object_path(q, l);
3318                         else
3319                                 ok = validate_string(q, l);
3320                         if (!ok)
3321                                 return -EBADMSG;
3322
3323                         if (p)
3324                                 *(const char**) p = q;
3325
3326                 } else if (type == SD_BUS_TYPE_SIGNATURE) {
3327                         uint8_t l;
3328
3329                         r = message_peek_body(m, &rindex, 1, 1, &q);
3330                         if (r < 0)
3331                                 return r;
3332
3333                         l = *(uint8_t*) q;
3334                         r = message_peek_body(m, &rindex, 1, l+1, &q);
3335                         if (r < 0)
3336                                 return r;
3337
3338                         if (!validate_signature(q, l))
3339                                 return -EBADMSG;
3340
3341                         if (p)
3342                                 *(const char**) p = q;
3343
3344                 } else {
3345                         ssize_t sz, align;
3346
3347                         align = bus_type_get_alignment(type);
3348                         assert(align > 0);
3349
3350                         sz = bus_type_get_size(type);
3351                         assert(sz > 0);
3352
3353                         r = message_peek_body(m, &rindex, align, sz, &q);
3354                         if (r < 0)
3355                                 return r;
3356
3357                         switch (type) {
3358
3359                         case SD_BUS_TYPE_BYTE:
3360                                 if (p)
3361                                         *(uint8_t*) p = *(uint8_t*) q;
3362                                 break;
3363
3364                         case SD_BUS_TYPE_BOOLEAN:
3365                                 if (p)
3366                                         *(int*) p = !!*(uint32_t*) q;
3367                                 break;
3368
3369                         case SD_BUS_TYPE_INT16:
3370                         case SD_BUS_TYPE_UINT16:
3371                                 if (p)
3372                                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3373                                 break;
3374
3375                         case SD_BUS_TYPE_INT32:
3376                         case SD_BUS_TYPE_UINT32:
3377                                 if (p)
3378                                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3379                                 break;
3380
3381                         case SD_BUS_TYPE_INT64:
3382                         case SD_BUS_TYPE_UINT64:
3383                         case SD_BUS_TYPE_DOUBLE:
3384                                 if (p)
3385                                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3386                                 break;
3387
3388                         case SD_BUS_TYPE_UNIX_FD: {
3389                                 uint32_t j;
3390
3391                                 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3392                                 if (j >= m->n_fds)
3393                                         return -EBADMSG;
3394
3395                                 if (p)
3396                                         *(int*) p = m->fds[j];
3397                                 break;
3398                         }
3399
3400                         default:
3401                                 assert_not_reached("Unknown basic type...");
3402                         }
3403                 }
3404         }
3405
3406         m->rindex = rindex;
3407
3408         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3409                 c->index++;
3410
3411         return 1;
3412 }
3413
3414 static int bus_message_enter_array(
3415                 sd_bus_message *m,
3416                 struct bus_container *c,
3417                 const char *contents,
3418                 uint32_t **array_size,
3419                 size_t *item_size,
3420                 size_t **offsets,
3421                 size_t *n_offsets) {
3422
3423         size_t rindex;
3424         void *q;
3425         int r, alignment;
3426
3427         assert(m);
3428         assert(c);
3429         assert(contents);
3430         assert(array_size);
3431         assert(item_size);
3432         assert(offsets);
3433         assert(n_offsets);
3434
3435         if (!signature_is_single(contents, true))
3436                 return -EINVAL;
3437
3438         if (!c->signature || c->signature[c->index] == 0)
3439                 return -ENXIO;
3440
3441         if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
3442                 return -ENXIO;
3443
3444         if (!startswith(c->signature + c->index + 1, contents))
3445                 return -ENXIO;
3446
3447         rindex = m->rindex;
3448
3449         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3450                 /* dbus1 */
3451
3452                 r = message_peek_body(m, &rindex, 4, 4, &q);
3453                 if (r < 0)
3454                         return r;
3455
3456                 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
3457                         return -EBADMSG;
3458
3459                 alignment = bus_type_get_alignment(contents[0]);
3460                 if (alignment < 0)
3461                         return alignment;
3462
3463                 r = message_peek_body(m, &rindex, alignment, 0, NULL);
3464                 if (r < 0)
3465                         return r;
3466
3467                 *array_size = (uint32_t*) q;
3468
3469         } else if (c->item_size <= 0) {
3470
3471                 /* gvariant: empty array */
3472                 *item_size = 0;
3473                 *offsets = NULL;
3474                 *n_offsets = 0;
3475
3476         } else if (bus_gvariant_is_fixed_size(contents)) {
3477
3478                 /* gvariant: fixed length array */
3479                 *item_size = bus_gvariant_get_size(contents);
3480                 *offsets = NULL;
3481                 *n_offsets = 0;
3482
3483         } else {
3484                 size_t where, p = 0, framing, sz;
3485                 unsigned i;
3486
3487                 /* gvariant: variable length array */
3488                 sz = determine_word_size(c->item_size, 0);
3489
3490                 where = rindex + c->item_size - sz;
3491                 r = message_peek_body(m, &where, 1, sz, &q);
3492                 if (r < 0)
3493                         return r;
3494
3495                 framing = read_word_le(q, sz);
3496                 if (framing > c->item_size - sz)
3497                         return -EBADMSG;
3498                 if ((c->item_size - framing) % sz != 0)
3499                         return -EBADMSG;
3500
3501                 *n_offsets = (c->item_size - framing) / sz;
3502
3503                 where = rindex + framing;
3504                 r = message_peek_body(m, &where, 1, *n_offsets * sz, &q);
3505                 if (r < 0)
3506                         return r;
3507
3508                 *offsets = new(size_t, *n_offsets);
3509                 if (!*offsets)
3510                         return -ENOMEM;
3511
3512                 for (i = 0; i < *n_offsets; i++) {
3513                         size_t x;
3514
3515                         x = read_word_le((uint8_t*) q + i * sz, sz);
3516                         if (x > c->item_size - sz)
3517                                 return -EBADMSG;
3518                         if (x < p)
3519                                 return -EBADMSG;
3520
3521                         (*offsets)[i] = rindex + x;
3522                         p = x;
3523                 }
3524
3525                 *item_size = (*offsets)[0] - rindex;
3526         }
3527
3528         m->rindex = rindex;
3529
3530         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3531                 c->index += 1 + strlen(contents);
3532
3533         return 1;
3534 }
3535
3536 static int bus_message_enter_variant(
3537                 sd_bus_message *m,
3538                 struct bus_container *c,
3539                 const char *contents,
3540                 size_t *item_size) {
3541
3542         size_t rindex;
3543         uint8_t l;
3544         void *q;
3545         int r;
3546
3547         assert(m);
3548         assert(c);
3549         assert(contents);
3550         assert(item_size);
3551
3552         if (!signature_is_single(contents, false))
3553                 return -EINVAL;
3554
3555         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
3556                 return -EINVAL;
3557
3558         if (!c->signature || c->signature[c->index] == 0)
3559                 return -ENXIO;
3560
3561         if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
3562                 return -ENXIO;
3563
3564         rindex = m->rindex;
3565
3566         if (BUS_MESSAGE_IS_GVARIANT(m)) {
3567                 size_t k, where;
3568
3569                 k = strlen(contents);
3570                 if (1+k > c->item_size)
3571                         return -EBADMSG;
3572
3573                 where = rindex + c->item_size - (1+k);
3574                 r = message_peek_body(m, &where, 1, 1+k, &q);
3575                 if (r < 0)
3576                         return r;
3577
3578                 if (*(char*) q != 0)
3579                         return -EBADMSG;
3580
3581                 if (memcmp((uint8_t*) q+1, contents, k))
3582                         return -ENXIO;
3583
3584                 *item_size = c->item_size - (1+k);
3585
3586         } else {
3587                 r = message_peek_body(m, &rindex, 1, 1, &q);
3588                 if (r < 0)
3589                         return r;
3590
3591                 l = *(uint8_t*) q;
3592                 r = message_peek_body(m, &rindex, 1, l+1, &q);
3593                 if (r < 0)
3594                         return r;
3595
3596                 if (!validate_signature(q, l))
3597                         return -EBADMSG;
3598
3599                 if (!streq(q, contents))
3600                         return -ENXIO;
3601         }
3602
3603         m->rindex = rindex;
3604
3605         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3606                 c->index++;
3607
3608         return 1;
3609 }
3610
3611 static int build_struct_offsets(
3612                 sd_bus_message *m,
3613                 const char *signature,
3614                 size_t size,
3615                 size_t *item_size,
3616                 size_t **offsets,
3617                 size_t *n_offsets) {
3618
3619         unsigned n_variable = 0, n_total = 0, v;
3620         size_t previous = 0, where;
3621         const char *p;
3622         size_t sz;
3623         void *q;
3624         int r;
3625
3626         assert(m);
3627         assert(item_size);
3628         assert(offsets);
3629         assert(n_offsets);
3630
3631         if (isempty(signature)) {
3632                 *item_size = 0;
3633                 *offsets = NULL;
3634                 *n_offsets = 0;
3635                 return 0;
3636         }
3637
3638         sz = determine_word_size(size, 0);
3639         if (sz <= 0)
3640                 return -EBADMSG;
3641
3642         /* First, loop over signature and count variable elements and
3643          * elements in general. We use this to know how large the
3644          * offset array is at the end of the structure. Note that
3645          * GVariant only stores offsets for all variable size elements
3646          * that are not the last item. */
3647
3648         p = signature;
3649         while (*p != 0) {
3650                 size_t n;
3651
3652                 r = signature_element_length(p, &n);
3653                 if (r < 0)
3654                         return r;
3655                 else {
3656                         char t[n+1];
3657
3658                         memcpy(t, p, n);
3659                         t[n] = 0;
3660
3661                         r = bus_gvariant_is_fixed_size(t);
3662                 }
3663
3664                 if (r < 0)
3665                         return r;
3666                 if (r == 0 && p[n] != 0) /* except the last item */
3667                         n_variable ++;
3668                 n_total++;
3669
3670                 p += n;
3671         }
3672
3673         if (size < n_variable * sz)
3674                 return -EBADMSG;
3675
3676         where = m->rindex + size - (n_variable * sz);
3677         r = message_peek_body(m, &where, 1, n_variable * sz, &q);
3678         if (r < 0)
3679                 return r;
3680
3681         v = n_variable;
3682
3683         *offsets = new(size_t, n_total);
3684         if (!*offsets)
3685                 return -ENOMEM;
3686
3687         *n_offsets = 0;
3688
3689         /* Second, loop again and build an offset table */
3690         p = signature;
3691         while (*p != 0) {
3692                 size_t n, offset;
3693                 int k;
3694
3695                 r = signature_element_length(p, &n);
3696                 if (r < 0)
3697                         return r;
3698                 else {
3699                         char t[n+1];
3700
3701                         memcpy(t, p, n);
3702                         t[n] = 0;
3703
3704                         k = bus_gvariant_get_size(t);
3705                         if (k < 0) {
3706                                 size_t x;
3707
3708                                 /* variable size */
3709                                 if (v > 0) {
3710                                         v--;
3711
3712                                         x = read_word_le((uint8_t*) q + v*sz, sz);
3713                                         if (x >= size)
3714                                                 return -EBADMSG;
3715                                         if (m->rindex + x < previous)
3716                                                 return -EBADMSG;
3717                                 } else
3718                                         /* The last item's end
3719                                          * is determined from
3720                                          * the start of the
3721                                          * offset array */
3722                                         x = size - (n_variable * sz);
3723
3724                                 offset = m->rindex + x;
3725
3726                         } else {
3727                                 size_t align;
3728
3729                                 /* fixed size */
3730                                 align = bus_gvariant_get_alignment(t);
3731                                 assert(align > 0);
3732
3733                                 offset = (*n_offsets == 0 ? m->rindex  : ALIGN_TO((*offsets)[*n_offsets-1], align)) + k;
3734                         }
3735                 }
3736
3737                 previous = (*offsets)[(*n_offsets)++] = offset;
3738                 p += n;
3739         }
3740
3741         assert(v == 0);
3742         assert(*n_offsets == n_total);
3743
3744         *item_size = (*offsets)[0] - m->rindex;
3745         return 0;
3746 }
3747
3748 static int enter_struct_or_dict_entry(
3749                 sd_bus_message *m,
3750                 struct bus_container *c,
3751                 const char *contents,
3752                 size_t *item_size,
3753                 size_t **offsets,
3754                 size_t *n_offsets) {
3755
3756         int r;
3757
3758         assert(m);
3759         assert(c);
3760         assert(contents);
3761         assert(item_size);
3762         assert(offsets);
3763         assert(n_offsets);
3764
3765         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3766
3767                 /* dbus1 */
3768                 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
3769                 if (r < 0)
3770                         return r;
3771
3772         } else if (c->item_size <= 0) {
3773
3774                 /* gvariant empty struct */
3775                 *item_size = 0;
3776                 *offsets = NULL;
3777                 *n_offsets = 0;
3778         } else
3779                 /* gvariant with contents */
3780                 return build_struct_offsets(m, contents, c->item_size, item_size, offsets, n_offsets);
3781
3782         return 0;
3783 }
3784
3785 static int bus_message_enter_struct(
3786                 sd_bus_message *m,
3787                 struct bus_container *c,
3788                 const char *contents,
3789                 size_t *item_size,
3790                 size_t **offsets,
3791                 size_t *n_offsets) {
3792
3793         size_t l;
3794         int r;
3795
3796         assert(m);
3797         assert(c);
3798         assert(contents);
3799         assert(item_size);
3800         assert(offsets);
3801         assert(n_offsets);
3802
3803         if (!signature_is_valid(contents, false))
3804                 return -EINVAL;
3805
3806         if (!c->signature || c->signature[c->index] == 0)
3807                 return -ENXIO;
3808
3809         l = strlen(contents);
3810
3811         if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
3812             !startswith(c->signature + c->index + 1, contents) ||
3813             c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
3814                 return -ENXIO;
3815
3816         r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
3817         if (r < 0)
3818                 return r;
3819
3820         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3821                 c->index += 1 + l + 1;
3822
3823         return 1;
3824 }
3825
3826 static int bus_message_enter_dict_entry(
3827                 sd_bus_message *m,
3828                 struct bus_container *c,
3829                 const char *contents,
3830                 size_t *item_size,
3831                 size_t **offsets,
3832                 size_t *n_offsets) {
3833
3834         size_t l;
3835         int r;
3836
3837         assert(m);
3838         assert(c);
3839         assert(contents);
3840
3841         if (!signature_is_pair(contents))
3842                 return -EINVAL;
3843
3844         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3845                 return -ENXIO;
3846
3847         if (!c->signature || c->signature[c->index] == 0)
3848                 return 0;
3849
3850         l = strlen(contents);
3851
3852         if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
3853             !startswith(c->signature + c->index + 1, contents) ||
3854             c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
3855                 return -ENXIO;
3856
3857         r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
3858         if (r < 0)
3859                 return r;
3860
3861         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3862                 c->index += 1 + l + 1;
3863
3864         return 1;
3865 }
3866
3867 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
3868                                             char type,
3869                                             const char *contents) {
3870         struct bus_container *c, *w;
3871         uint32_t *array_size = NULL;
3872         char *signature;
3873         size_t before;
3874         size_t *offsets = NULL;
3875         size_t n_offsets = 0, item_size = 0;
3876         int r;
3877
3878         assert_return(m, -EINVAL);
3879         assert_return(m->sealed, -EPERM);
3880         assert_return(type != 0 || !contents, -EINVAL);
3881
3882         if (type == 0 || !contents) {
3883                 const char *cc;
3884                 char tt;
3885
3886                 /* Allow entering into anonymous containers */
3887                 r = sd_bus_message_peek_type(m, &tt, &cc);
3888                 if (r < 0)
3889                         return r;
3890
3891                 if (type != 0 && type != tt)
3892                         return -ENXIO;
3893
3894                 if (contents && !streq(contents, cc))
3895                         return -ENXIO;
3896
3897                 type = tt;
3898                 contents = cc;
3899         }
3900
3901         /*
3902          * We enforce a global limit on container depth, that is much
3903          * higher than the 32 structs and 32 arrays the specification
3904          * mandates. This is simpler to implement for us, and we need
3905          * this only to ensure our container array doesn't grow
3906          * without bounds. We are happy to return any data from a
3907          * message as long as the data itself is valid, even if the
3908          * overall message might be not.
3909          *
3910          * Note that the message signature is validated when
3911          * parsing the headers, and that validation does check the
3912          * 32/32 limit.
3913          *
3914          * Note that the specification defines no limits on the depth
3915          * of stacked variants, but we do.
3916          */
3917         if (m->n_containers >= BUS_CONTAINER_DEPTH)
3918                 return -EBADMSG;
3919
3920         if (!GREEDY_REALLOC(m->containers, m->containers_allocated, m->n_containers + 1))
3921                 return -ENOMEM;
3922
3923         if (message_end_of_signature(m))
3924                 return -ENXIO;
3925
3926         if (message_end_of_array(m, m->rindex))
3927                 return 0;
3928
3929         c = message_get_container(m);
3930
3931         signature = strdup(contents);
3932         if (!signature)
3933                 return -ENOMEM;
3934
3935         c->saved_index = c->index;
3936         before = m->rindex;
3937
3938         if (type == SD_BUS_TYPE_ARRAY)
3939                 r = bus_message_enter_array(m, c, contents, &array_size, &item_size, &offsets, &n_offsets);
3940         else if (type == SD_BUS_TYPE_VARIANT)
3941                 r = bus_message_enter_variant(m, c, contents, &item_size);
3942         else if (type == SD_BUS_TYPE_STRUCT)
3943                 r = bus_message_enter_struct(m, c, contents, &item_size, &offsets, &n_offsets);
3944         else if (type == SD_BUS_TYPE_DICT_ENTRY)
3945                 r = bus_message_enter_dict_entry(m, c, contents, &item_size, &offsets, &n_offsets);
3946         else
3947                 r = -EINVAL;
3948
3949         if (r <= 0) {
3950                 free(signature);
3951                 free(offsets);
3952                 return r;
3953         }
3954
3955         /* OK, let's fill it in */
3956         w = m->containers + m->n_containers++;
3957         w->enclosing = type;
3958         w->signature = signature;
3959         w->peeked_signature = NULL;
3960         w->index = 0;
3961
3962         w->before = before;
3963         w->begin = m->rindex;
3964         w->end = m->rindex + c->item_size;
3965
3966         w->array_size = array_size;
3967         w->item_size = item_size;
3968         w->offsets = offsets;
3969         w->n_offsets = n_offsets;
3970         w->offset_index = 0;
3971
3972         return 1;
3973 }
3974
3975 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
3976         struct bus_container *c;
3977         unsigned saved;
3978         int r;
3979
3980         assert_return(m, -EINVAL);
3981         assert_return(m->sealed, -EPERM);
3982         assert_return(m->n_containers > 0, -ENXIO);
3983
3984         c = message_get_container(m);
3985
3986         if (c->enclosing != SD_BUS_TYPE_ARRAY) {
3987                 if (c->signature && c->signature[c->index] != 0)
3988                         return -EBUSY;
3989         }
3990
3991         if (BUS_MESSAGE_IS_GVARIANT(m)) {
3992                 if (m->rindex < c->end)
3993                         return -EBUSY;
3994
3995         } else if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3996                 uint32_t l;
3997
3998                 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3999                 if (c->begin + l != m->rindex)
4000                         return -EBUSY;
4001         }
4002
4003         free(c->signature);
4004         free(c->peeked_signature);
4005         free(c->offsets);
4006         m->n_containers--;
4007
4008         c = message_get_container(m);
4009
4010         saved = c->index;
4011         c->index = c->saved_index;
4012         r = container_next_item(m, c, &m->rindex);
4013         c->index = saved;
4014         if (r < 0)
4015                 return r;
4016
4017         return 1;
4018 }
4019
4020 static void message_quit_container(sd_bus_message *m) {
4021         struct bus_container *c;
4022
4023         assert(m);
4024         assert(m->sealed);
4025         assert(m->n_containers > 0);
4026
4027         c = message_get_container(m);
4028
4029         /* Undo seeks */
4030         assert(m->rindex >= c->before);
4031         m->rindex = c->before;
4032
4033         /* Free container */
4034         free(c->signature);
4035         free(c->offsets);
4036         m->n_containers--;
4037
4038         /* Correct index of new top-level container */
4039         c = message_get_container(m);
4040         c->index = c->saved_index;
4041 }
4042
4043 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
4044         struct bus_container *c;
4045         int r;
4046
4047         assert_return(m, -EINVAL);
4048         assert_return(m->sealed, -EPERM);
4049
4050         if (message_end_of_signature(m))
4051                 goto eof;
4052
4053         if (message_end_of_array(m, m->rindex))
4054                 goto eof;
4055
4056         c = message_get_container(m);
4057
4058         if (bus_type_is_basic(c->signature[c->index])) {
4059                 if (contents)
4060                         *contents = NULL;
4061                 if (type)
4062                         *type = c->signature[c->index];
4063                 return 1;
4064         }
4065
4066         if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
4067
4068                 if (contents) {
4069                         size_t l;
4070                         char *sig;
4071
4072                         r = signature_element_length(c->signature+c->index+1, &l);
4073                         if (r < 0)
4074                                 return r;
4075
4076                         assert(l >= 1);
4077
4078                         sig = strndup(c->signature + c->index + 1, l);
4079                         if (!sig)
4080                                 return -ENOMEM;
4081
4082                         free(c->peeked_signature);
4083                         *contents = c->peeked_signature = sig;
4084                 }
4085
4086                 if (type)
4087                         *type = SD_BUS_TYPE_ARRAY;
4088
4089                 return 1;
4090         }
4091
4092         if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
4093             c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
4094
4095                 if (contents) {
4096                         size_t l;
4097                         char *sig;
4098
4099                         r = signature_element_length(c->signature+c->index, &l);
4100                         if (r < 0)
4101                                 return r;
4102
4103                         assert(l >= 2);
4104                         sig = strndup(c->signature + c->index + 1, l - 2);
4105                         if (!sig)
4106                                 return -ENOMEM;
4107
4108                         free(c->peeked_signature);
4109                         *contents = c->peeked_signature = sig;
4110                 }
4111
4112                 if (type)
4113                         *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
4114
4115                 return 1;
4116         }
4117
4118         if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
4119                 if (contents) {
4120                         void *q;
4121
4122                         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4123                                 size_t k;
4124
4125                                 if (c->item_size < 2)
4126                                         return -EBADMSG;
4127
4128                                 /* Look for the NUL delimiter that
4129                                    separates the payload from the
4130                                    signature. Since the body might be
4131                                    in a different part that then the
4132                                    signature we map byte by byte. */
4133
4134                                 for (k = 2; k <= c->item_size; k++) {
4135                                         size_t where;
4136
4137                                         where = m->rindex + c->item_size - k;
4138                                         r = message_peek_body(m, &where, 1, k, &q);
4139                                         if (r < 0)
4140                                                 return r;
4141
4142                                         if (*(char*) q == 0)
4143                                                 break;
4144                                 }
4145
4146                                 if (k > c->item_size)
4147                                         return -EBADMSG;
4148
4149                                 free(c->peeked_signature);
4150                                 c->peeked_signature = strndup((char*) q + 1, k - 1);
4151                                 if (!c->peeked_signature)
4152                                         return -ENOMEM;
4153
4154                                 if (!signature_is_valid(c->peeked_signature, true))
4155                                         return -EBADMSG;
4156
4157                                 *contents = c->peeked_signature;
4158                         } else {
4159                                 size_t rindex, l;
4160
4161                                 rindex = m->rindex;
4162                                 r = message_peek_body(m, &rindex, 1, 1, &q);
4163                                 if (r < 0)
4164                                         return r;
4165
4166                                 l = *(uint8_t*) q;
4167                                 r = message_peek_body(m, &rindex, 1, l+1, &q);
4168                                 if (r < 0)
4169                                         return r;
4170
4171                                 if (!validate_signature(q, l))
4172                                         return -EBADMSG;
4173
4174                                 *contents = q;
4175                         }
4176                 }
4177
4178                 if (type)
4179                         *type = SD_BUS_TYPE_VARIANT;
4180
4181                 return 1;
4182         }
4183
4184         return -EINVAL;
4185
4186 eof:
4187         if (type)
4188                 *type = 0;
4189         if (contents)
4190                 *contents = NULL;
4191         return 0;
4192 }
4193
4194 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
4195         struct bus_container *c;
4196
4197         assert_return(m, -EINVAL);
4198         assert_return(m->sealed, -EPERM);
4199
4200         if (complete) {
4201                 message_reset_containers(m);
4202                 m->rindex = 0;
4203
4204                 c = message_get_container(m);
4205         } else {
4206                 c = message_get_container(m);
4207
4208                 c->offset_index = 0;
4209                 c->index = 0;
4210                 m->rindex = c->begin;
4211         }
4212
4213         c->offset_index = 0;
4214         c->item_size = (c->n_offsets > 0 ? c->offsets[0] : c->end) - c->begin;
4215
4216         return !isempty(c->signature);
4217 }
4218
4219 static int message_read_ap(
4220                 sd_bus_message *m,
4221                 const char *types,
4222                 va_list ap) {
4223
4224         unsigned n_array, n_struct;
4225         TypeStack stack[BUS_CONTAINER_DEPTH];
4226         unsigned stack_ptr = 0;
4227         unsigned n_loop = 0;
4228         int r;
4229
4230         assert(m);
4231
4232         if (isempty(types))
4233                 return 0;
4234
4235         /* Ideally, we'd just call ourselves recursively on every
4236          * complex type. However, the state of a va_list that is
4237          * passed to a function is undefined after that function
4238          * returns. This means we need to docode the va_list linearly
4239          * in a single stackframe. We hence implement our own
4240          * home-grown stack in an array. */
4241
4242         n_array = (unsigned) -1; /* length of current array entries */
4243         n_struct = strlen(types); /* length of current struct contents signature */
4244
4245         for (;;) {
4246                 const char *t;
4247
4248                 n_loop++;
4249
4250                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
4251                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
4252                         if (r < 0)
4253                                 return r;
4254                         if (r == 0)
4255                                 break;
4256
4257                         r = sd_bus_message_exit_container(m);
4258                         if (r < 0)
4259                                 return r;
4260
4261                         continue;
4262                 }
4263
4264                 t = types;
4265                 if (n_array != (unsigned) -1)
4266                         n_array --;
4267                 else {
4268                         types ++;
4269                         n_struct--;
4270                 }
4271
4272                 switch (*t) {
4273
4274                 case SD_BUS_TYPE_BYTE:
4275                 case SD_BUS_TYPE_BOOLEAN:
4276                 case SD_BUS_TYPE_INT16:
4277                 case SD_BUS_TYPE_UINT16:
4278                 case SD_BUS_TYPE_INT32:
4279                 case SD_BUS_TYPE_UINT32:
4280                 case SD_BUS_TYPE_INT64:
4281                 case SD_BUS_TYPE_UINT64:
4282                 case SD_BUS_TYPE_DOUBLE:
4283                 case SD_BUS_TYPE_STRING:
4284                 case SD_BUS_TYPE_OBJECT_PATH:
4285                 case SD_BUS_TYPE_SIGNATURE:
4286                 case SD_BUS_TYPE_UNIX_FD: {
4287                         void *p;
4288
4289                         p = va_arg(ap, void*);
4290                         r = sd_bus_message_read_basic(m, *t, p);
4291                         if (r < 0)
4292                                 return r;
4293                         if (r == 0) {
4294                                 if (n_loop <= 1)
4295                                         return 0;
4296
4297                                 return -ENXIO;
4298                         }
4299
4300                         break;
4301                 }
4302
4303                 case SD_BUS_TYPE_ARRAY: {
4304                         size_t k;
4305
4306                         r = signature_element_length(t + 1, &k);
4307                         if (r < 0)
4308                                 return r;
4309
4310                         {
4311                                 char s[k + 1];
4312                                 memcpy(s, t + 1, k);
4313                                 s[k] = 0;
4314
4315                                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4316                                 if (r < 0)
4317                                         return r;
4318                                 if (r == 0) {
4319                                         if (n_loop <= 1)
4320                                                 return 0;
4321
4322                                         return -ENXIO;
4323                                 }
4324                         }
4325
4326                         if (n_array == (unsigned) -1) {
4327                                 types += k;
4328                                 n_struct -= k;
4329                         }
4330
4331                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4332                         if (r < 0)
4333                                 return r;
4334
4335                         types = t + 1;
4336                         n_struct = k;
4337                         n_array = va_arg(ap, unsigned);
4338
4339                         break;
4340                 }
4341
4342                 case SD_BUS_TYPE_VARIANT: {
4343                         const char *s;
4344
4345                         s = va_arg(ap, const char *);
4346                         if (!s)
4347                                 return -EINVAL;
4348
4349                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
4350                         if (r < 0)
4351                                 return r;
4352                         if (r == 0) {
4353                                 if (n_loop <= 1)
4354                                         return 0;
4355
4356                                 return -ENXIO;
4357                         }
4358
4359                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4360                         if (r < 0)
4361                                 return r;
4362
4363                         types = s;
4364                         n_struct = strlen(s);
4365                         n_array = (unsigned) -1;
4366
4367                         break;
4368                 }
4369
4370                 case SD_BUS_TYPE_STRUCT_BEGIN:
4371                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4372                         size_t k;
4373
4374                         r = signature_element_length(t, &k);
4375                         if (r < 0)
4376                                 return r;
4377
4378                         {
4379                                 char s[k - 1];
4380                                 memcpy(s, t + 1, k - 2);
4381                                 s[k - 2] = 0;
4382
4383                                 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4384                                 if (r < 0)
4385                                         return r;
4386                                 if (r == 0) {
4387                                         if (n_loop <= 1)
4388                                                 return 0;
4389                                         return -ENXIO;
4390                                 }
4391                         }
4392
4393                         if (n_array == (unsigned) -1) {
4394                                 types += k - 1;
4395                                 n_struct -= k - 1;
4396                         }
4397
4398                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4399                         if (r < 0)
4400                                 return r;
4401
4402                         types = t + 1;
4403                         n_struct = k - 2;
4404                         n_array = (unsigned) -1;
4405
4406                         break;
4407                 }
4408
4409                 default:
4410                         return -EINVAL;
4411                 }
4412         }
4413
4414         return 1;
4415 }
4416
4417 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
4418         va_list ap;
4419         int r;
4420
4421         assert_return(m, -EINVAL);
4422         assert_return(m->sealed, -EPERM);
4423         assert_return(types, -EINVAL);
4424
4425         va_start(ap, types);
4426         r = message_read_ap(m, types, ap);
4427         va_end(ap);
4428
4429         return r;
4430 }
4431
4432 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
4433         int r;
4434
4435         assert_return(m, -EINVAL);
4436         assert_return(m->sealed, -EPERM);
4437         assert_return(types, -EINVAL);
4438
4439         if (isempty(types))
4440                 return 0;
4441
4442         switch (*types) {
4443
4444         case SD_BUS_TYPE_BYTE:
4445         case SD_BUS_TYPE_BOOLEAN:
4446         case SD_BUS_TYPE_INT16:
4447         case SD_BUS_TYPE_UINT16:
4448         case SD_BUS_TYPE_INT32:
4449         case SD_BUS_TYPE_UINT32:
4450         case SD_BUS_TYPE_INT64:
4451         case SD_BUS_TYPE_UINT64:
4452         case SD_BUS_TYPE_DOUBLE:
4453         case SD_BUS_TYPE_STRING:
4454         case SD_BUS_TYPE_OBJECT_PATH:
4455         case SD_BUS_TYPE_SIGNATURE:
4456         case SD_BUS_TYPE_UNIX_FD:
4457
4458                 r = sd_bus_message_read_basic(m, *types, NULL);
4459                 if (r <= 0)
4460                         return r;
4461
4462                 r = sd_bus_message_skip(m, types + 1);
4463                 if (r < 0)
4464                         return r;
4465
4466                 return 1;
4467
4468         case SD_BUS_TYPE_ARRAY: {
4469                 size_t k;
4470
4471                 r = signature_element_length(types + 1, &k);
4472                 if (r < 0)
4473                         return r;
4474
4475                 {
4476                         char s[k+1];
4477                         memcpy(s, types+1, k);
4478                         s[k] = 0;
4479
4480                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4481                         if (r <= 0)
4482                                 return r;
4483
4484                         for (;;) {
4485                                 r = sd_bus_message_skip(m, s);
4486                                 if (r < 0)
4487                                         return r;
4488                                 if (r == 0)
4489                                         break;
4490                         }
4491
4492                         r = sd_bus_message_exit_container(m);
4493                         if (r < 0)
4494                                 return r;
4495                 }
4496
4497                 r = sd_bus_message_skip(m, types + 1 + k);
4498                 if (r < 0)
4499                         return r;
4500
4501                 return 1;
4502         }
4503
4504         case SD_BUS_TYPE_VARIANT: {
4505                 const char *contents;
4506                 char x;
4507
4508                 r = sd_bus_message_peek_type(m, &x, &contents);
4509                 if (r <= 0)
4510                         return r;
4511
4512                 if (x != SD_BUS_TYPE_VARIANT)
4513                         return -ENXIO;
4514
4515                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
4516                 if (r <= 0)
4517                         return r;
4518
4519                 r = sd_bus_message_skip(m, contents);
4520                 if (r < 0)
4521                         return r;
4522                 assert(r != 0);
4523
4524                 r = sd_bus_message_exit_container(m);
4525                 if (r < 0)
4526                         return r;
4527
4528                 r = sd_bus_message_skip(m, types + 1);
4529                 if (r < 0)
4530                         return r;
4531
4532                 return 1;
4533         }
4534
4535         case SD_BUS_TYPE_STRUCT_BEGIN:
4536         case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4537                 size_t k;
4538
4539                 r = signature_element_length(types, &k);
4540                 if (r < 0)
4541                         return r;
4542
4543                 {
4544                         char s[k-1];
4545                         memcpy(s, types+1, k-2);
4546                         s[k-2] = 0;
4547
4548                         r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4549                         if (r <= 0)
4550                                 return r;
4551
4552                         r = sd_bus_message_skip(m, s);
4553                         if (r < 0)
4554                                 return r;
4555                         assert(r != 0);
4556
4557                         r = sd_bus_message_exit_container(m);
4558                         if (r < 0)
4559                                 return r;
4560                 }
4561
4562                 r = sd_bus_message_skip(m, types + k);
4563                 if (r < 0)
4564                         return r;
4565
4566                 return 1;
4567         }
4568
4569         default:
4570                 return -EINVAL;
4571         }
4572 }
4573
4574 _public_ int sd_bus_message_read_array(sd_bus_message *m,
4575                                        char type,
4576                                        const void **ptr,
4577                                        size_t *size) {
4578         struct bus_container *c;
4579         void *p;
4580         size_t sz;
4581         ssize_t align;
4582         int r;
4583
4584         assert_return(m, -EINVAL);
4585         assert_return(m->sealed, -EPERM);
4586         assert_return(bus_type_is_trivial(type), -EINVAL);
4587         assert_return(ptr, -EINVAL);
4588         assert_return(size, -EINVAL);
4589         assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
4590
4591         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
4592         if (r <= 0)
4593                 return r;
4594
4595         c = message_get_container(m);
4596
4597         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4598                 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
4599                 if (align < 0)
4600                         return align;
4601
4602                 sz = c->end - c->begin;
4603         } else {
4604                 align = bus_type_get_alignment(type);
4605                 if (align < 0)
4606                         return align;
4607
4608                 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
4609         }
4610
4611         if (sz == 0)
4612                 /* Zero length array, let's return some aligned
4613                  * pointer that is not NULL */
4614                 p = (uint8_t*) NULL + align;
4615         else {
4616                 r = message_peek_body(m, &m->rindex, align, sz, &p);
4617                 if (r < 0)
4618                         goto fail;
4619         }
4620
4621         r = sd_bus_message_exit_container(m);
4622         if (r < 0)
4623                 goto fail;
4624
4625         *ptr = (const void*) p;
4626         *size = sz;
4627
4628         return 1;
4629
4630 fail:
4631         message_quit_container(m);
4632         return r;
4633 }
4634
4635 static int message_peek_fields(
4636                 sd_bus_message *m,
4637                 size_t *rindex,
4638                 size_t align,
4639                 size_t nbytes,
4640                 void **ret) {
4641
4642         assert(m);
4643         assert(rindex);
4644         assert(align > 0);
4645
4646         return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
4647 }
4648
4649 static int message_peek_field_uint32(
4650                 sd_bus_message *m,
4651                 size_t *ri,
4652                 size_t item_size,
4653                 uint32_t *ret) {
4654
4655         int r;
4656         void *q;
4657
4658         assert(m);
4659         assert(ri);
4660
4661         if (BUS_MESSAGE_IS_GVARIANT(m) && item_size != 4)
4662                 return -EBADMSG;
4663
4664         /* identical for gvariant and dbus1 */
4665
4666         r = message_peek_fields(m, ri, 4, 4, &q);
4667         if (r < 0)
4668                 return r;
4669
4670         if (ret)
4671                 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
4672
4673         return 0;
4674 }
4675
4676 static int message_peek_field_string(
4677                 sd_bus_message *m,
4678                 bool (*validate)(const char *p),
4679                 size_t *ri,
4680                 size_t item_size,
4681                 const char **ret) {
4682
4683         uint32_t l;
4684         int r;
4685         void *q;
4686
4687         assert(m);
4688         assert(ri);
4689
4690         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4691
4692                 if (item_size <= 0)
4693                         return -EBADMSG;
4694
4695                 r = message_peek_fields(m, ri, 1, item_size, &q);
4696                 if (r < 0)
4697                         return r;
4698
4699                 l = item_size - 1;
4700         } else {
4701                 r = message_peek_field_uint32(m, ri, 4, &l);
4702                 if (r < 0)
4703                         return r;
4704
4705                 r = message_peek_fields(m, ri, 1, l+1, &q);
4706                 if (r < 0)
4707                         return r;
4708         }
4709
4710         if (validate) {
4711                 if (!validate_nul(q, l))
4712                         return -EBADMSG;
4713
4714                 if (!validate(q))
4715                         return -EBADMSG;
4716         } else {
4717                 if (!validate_string(q, l))
4718                         return -EBADMSG;
4719         }
4720
4721         if (ret)
4722                 *ret = q;
4723
4724         return 0;
4725 }
4726
4727 static int message_peek_field_signature(
4728                 sd_bus_message *m,
4729                 size_t *ri,
4730                 size_t item_size,
4731                 const char **ret) {
4732
4733         size_t l;
4734         int r;
4735         void *q;
4736
4737         assert(m);
4738         assert(ri);
4739
4740         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4741
4742                 if (item_size <= 0)
4743                         return -EBADMSG;
4744
4745                 r = message_peek_fields(m, ri, 1, item_size, &q);
4746                 if (r < 0)
4747                         return r;
4748
4749                 l = item_size - 1;
4750         } else {
4751                 r = message_peek_fields(m, ri, 1, 1, &q);
4752                 if (r < 0)
4753                         return r;
4754
4755                 l = *(uint8_t*) q;
4756                 r = message_peek_fields(m, ri, 1, l+1, &q);
4757                 if (r < 0)
4758                         return r;
4759         }
4760
4761         if (!validate_signature(q, l))
4762                 return -EBADMSG;
4763
4764         if (ret)
4765                 *ret = q;
4766
4767         return 0;
4768 }
4769
4770 static int message_skip_fields(
4771                 sd_bus_message *m,
4772                 size_t *ri,
4773                 uint32_t array_size,
4774                 const char **signature) {
4775
4776         size_t original_index;
4777         int r;
4778
4779         assert(m);
4780         assert(ri);
4781         assert(signature);
4782         assert(!BUS_MESSAGE_IS_GVARIANT(m));
4783
4784         original_index = *ri;
4785
4786         for (;;) {
4787                 char t;
4788                 size_t l;
4789
4790                 if (array_size != (uint32_t) -1 &&
4791                     array_size <= *ri - original_index)
4792                         return 0;
4793
4794                 t = **signature;
4795                 if (!t)
4796                         return 0;
4797
4798                 if (t == SD_BUS_TYPE_STRING) {
4799
4800                         r = message_peek_field_string(m, NULL, ri, 0, NULL);
4801                         if (r < 0)
4802                                 return r;
4803
4804                         (*signature)++;
4805
4806                 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
4807
4808                         r = message_peek_field_string(m, object_path_is_valid, ri, 0, NULL);
4809                         if (r < 0)
4810                                 return r;
4811
4812                         (*signature)++;
4813
4814                 } else if (t == SD_BUS_TYPE_SIGNATURE) {
4815
4816                         r = message_peek_field_signature(m, ri, 0, NULL);
4817                         if (r < 0)
4818                                 return r;
4819
4820                         (*signature)++;
4821
4822                 } else if (bus_type_is_basic(t)) {
4823                         ssize_t align, k;
4824
4825                         align = bus_type_get_alignment(t);
4826                         k = bus_type_get_size(t);
4827                         assert(align > 0 && k > 0);
4828
4829                         r = message_peek_fields(m, ri, align, k, NULL);
4830                         if (r < 0)
4831                                 return r;
4832
4833                         (*signature)++;
4834
4835                 } else if (t == SD_BUS_TYPE_ARRAY) {
4836
4837                         r = signature_element_length(*signature+1, &l);
4838                         if (r < 0)
4839                                 return r;
4840
4841                         assert(l >= 1);
4842                         {
4843                                 char sig[l-1], *s;
4844                                 uint32_t nas;
4845                                 int alignment;
4846
4847                                 strncpy(sig, *signature + 1, l-1);
4848                                 s = sig;
4849
4850                                 alignment = bus_type_get_alignment(sig[0]);
4851                                 if (alignment < 0)
4852                                         return alignment;
4853
4854                                 r = message_peek_field_uint32(m, ri, 0, &nas);
4855                                 if (r < 0)
4856                                         return r;
4857                                 if (nas > BUS_ARRAY_MAX_SIZE)
4858                                         return -EBADMSG;
4859
4860                                 r = message_peek_fields(m, ri, alignment, 0, NULL);
4861                                 if (r < 0)
4862                                         return r;
4863
4864                                 r = message_skip_fields(m, ri, nas, (const char**) &s);
4865                                 if (r < 0)
4866                                         return r;
4867                         }
4868
4869                         (*signature) += 1 + l;
4870
4871                 } else if (t == SD_BUS_TYPE_VARIANT) {
4872                         const char *s;
4873
4874                         r = message_peek_field_signature(m, ri, 0, &s);
4875                         if (r < 0)
4876                                 return r;
4877
4878                         r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
4879                         if (r < 0)
4880                                 return r;
4881
4882                         (*signature)++;
4883
4884                 } else if (t == SD_BUS_TYPE_STRUCT ||
4885                            t == SD_BUS_TYPE_DICT_ENTRY) {
4886
4887                         r = signature_element_length(*signature, &l);
4888                         if (r < 0)
4889                                 return r;
4890
4891                         assert(l >= 2);
4892                         {
4893                                 char sig[l-1], *s;
4894                                 strncpy(sig, *signature + 1, l-1);
4895                                 s = sig;
4896
4897                                 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
4898                                 if (r < 0)
4899                                         return r;
4900                         }
4901
4902                         *signature += l;
4903                 } else
4904                         return -EINVAL;
4905         }
4906 }
4907
4908 int bus_message_parse_fields(sd_bus_message *m) {
4909         size_t ri;
4910         int r;
4911         uint32_t unix_fds = 0;
4912         bool unix_fds_set = false;
4913         void *offsets = NULL;
4914         unsigned n_offsets = 0;
4915         size_t sz = 0;
4916         unsigned i = 0;
4917
4918         assert(m);
4919
4920         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4921                 void *q;
4922
4923                 sz = determine_word_size(BUS_MESSAGE_FIELDS_SIZE(m), 0);
4924                 if (sz > 0) {
4925                         size_t framing;
4926
4927                         ri = BUS_MESSAGE_FIELDS_SIZE(m) - sz;
4928                         r = message_peek_fields(m, &ri, 1, sz, &q);
4929                         if (r < 0)
4930                                 return r;
4931
4932                         framing = read_word_le(q, sz);
4933                         if (framing >= BUS_MESSAGE_FIELDS_SIZE(m) - sz)
4934                                 return -EBADMSG;
4935                         if ((BUS_MESSAGE_FIELDS_SIZE(m) - framing) % sz != 0)
4936                                 return -EBADMSG;
4937
4938                         ri = framing;
4939                         r = message_peek_fields(m, &ri, 1, BUS_MESSAGE_FIELDS_SIZE(m) - framing, &offsets);
4940                         if (r < 0)
4941                                 return r;
4942
4943                         n_offsets = (BUS_MESSAGE_FIELDS_SIZE(m) - framing) / sz;
4944                 }
4945         }
4946
4947         ri = 0;
4948         while (ri < BUS_MESSAGE_FIELDS_SIZE(m)) {
4949                 _cleanup_free_ char *sig = NULL;
4950                 const char *signature;
4951                 uint8_t *header;
4952                 size_t item_size = (size_t) -1;
4953
4954                 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4955                         if (i >= n_offsets)
4956                                 break;
4957
4958                         if (i == 0)
4959                                 ri = 0;
4960                         else
4961                                 ri = ALIGN_TO(read_word_le((uint8_t*) offsets + (i-1)*sz, sz), 8);
4962                 }
4963
4964                 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
4965                 if (r < 0)
4966                         return r;
4967
4968                 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4969                         size_t where, end;
4970                         char *b;
4971                         void *q;
4972
4973                         end = read_word_le((uint8_t*) offsets + i*sz, sz);
4974
4975                         if (end < ri)
4976                                 return -EBADMSG;
4977
4978                         where = ri = ALIGN_TO(ri, 8);
4979                         item_size = end - ri;
4980                         r = message_peek_fields(m, &where, 1, item_size, &q);
4981                         if (r < 0)
4982                                 return r;
4983
4984                         b = memrchr(q, 0, item_size);
4985                         if (!b)
4986                                 return -EBADMSG;
4987
4988                         sig = strndup(b+1, item_size - (b+1-(char*) q));
4989                         if (!sig)
4990                                 return -ENOMEM;
4991
4992                         signature = sig;
4993                         item_size = b - (char*) q;
4994                 } else {
4995                         r = message_peek_field_signature(m, &ri, 0, &signature);
4996                         if (r < 0)
4997                                 return r;
4998                 }
4999
5000                 switch (*header) {
5001                 case _BUS_MESSAGE_HEADER_INVALID:
5002                         return -EBADMSG;
5003
5004                 case BUS_MESSAGE_HEADER_PATH:
5005
5006                         if (m->path)
5007                                 return -EBADMSG;
5008
5009                         if (!streq(signature, "o"))
5010                                 return -EBADMSG;
5011
5012                         r = message_peek_field_string(m, object_path_is_valid, &ri, item_size, &m->path);
5013                         break;
5014
5015                 case BUS_MESSAGE_HEADER_INTERFACE:
5016
5017                         if (m->interface)
5018                                 return -EBADMSG;
5019
5020                         if (!streq(signature, "s"))
5021                                 return -EBADMSG;
5022
5023                         r = message_peek_field_string(m, interface_name_is_valid, &ri, item_size, &m->interface);
5024                         break;
5025
5026                 case BUS_MESSAGE_HEADER_MEMBER:
5027
5028                         if (m->member)
5029                                 return -EBADMSG;
5030
5031                         if (!streq(signature, "s"))
5032                                 return -EBADMSG;
5033
5034                         r = message_peek_field_string(m, member_name_is_valid, &ri, item_size, &m->member);
5035                         break;
5036
5037                 case BUS_MESSAGE_HEADER_ERROR_NAME:
5038
5039                         if (m->error.name)
5040                                 return -EBADMSG;
5041
5042                         if (!streq(signature, "s"))
5043                                 return -EBADMSG;
5044
5045                         r = message_peek_field_string(m, error_name_is_valid, &ri, item_size, &m->error.name);
5046                         if (r >= 0)
5047                                 m->error._need_free = -1;
5048
5049                         break;
5050
5051                 case BUS_MESSAGE_HEADER_DESTINATION:
5052
5053                         if (m->destination)
5054                                 return -EBADMSG;
5055
5056                         if (!streq(signature, "s"))
5057                                 return -EBADMSG;
5058
5059                         r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->destination);
5060                         break;
5061
5062                 case BUS_MESSAGE_HEADER_SENDER:
5063
5064                         if (m->sender)
5065                                 return -EBADMSG;
5066
5067                         if (!streq(signature, "s"))
5068                                 return -EBADMSG;
5069
5070                         r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->sender);
5071
5072                         if (r >= 0 && m->sender[0] == ':' && m->bus->bus_client && !m->bus->is_kernel) {
5073                                 m->creds.unique_name = (char*) m->sender;
5074                                 m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & m->bus->creds_mask;
5075                         }
5076
5077                         break;
5078
5079
5080                 case BUS_MESSAGE_HEADER_SIGNATURE: {
5081                         const char *s;
5082                         char *c;
5083
5084                         if (m->root_container.signature)
5085                                 return -EBADMSG;
5086
5087                         if (!streq(signature, "g"))
5088                                 return -EBADMSG;
5089
5090                         r = message_peek_field_signature(m, &ri, item_size, &s);
5091                         if (r < 0)
5092                                 return r;
5093
5094                         c = strdup(s);
5095                         if (!c)
5096                                 return -ENOMEM;
5097
5098                         free(m->root_container.signature);
5099                         m->root_container.signature = c;
5100                         break;
5101                 }
5102
5103                 case BUS_MESSAGE_HEADER_REPLY_SERIAL: {
5104                         uint32_t serial;
5105
5106                         if (m->reply_cookie != 0)
5107                                 return -EBADMSG;
5108
5109                         if (!streq(signature, "u"))
5110                                 return -EBADMSG;
5111
5112                         r = message_peek_field_uint32(m, &ri, item_size, &serial);
5113                         if (r < 0)
5114                                 return r;
5115
5116                         m->reply_cookie = serial;
5117
5118                         if (m->reply_cookie == 0)
5119                                 return -EBADMSG;
5120
5121                         break;
5122                 }
5123
5124                 case BUS_MESSAGE_HEADER_UNIX_FDS:
5125                         if (unix_fds_set)
5126                                 return -EBADMSG;
5127
5128                         if (!streq(signature, "u"))
5129                                 return -EBADMSG;
5130
5131                         r = message_peek_field_uint32(m, &ri, item_size, &unix_fds);
5132                         if (r < 0)
5133                                 return -EBADMSG;
5134
5135                         unix_fds_set = true;
5136                         break;
5137
5138                 default:
5139                         if (!BUS_MESSAGE_IS_GVARIANT(m))
5140                                 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
5141                 }
5142
5143                 if (r < 0)
5144                         return r;
5145
5146                 i++;
5147         }
5148
5149         if (m->n_fds != unix_fds)
5150                 return -EBADMSG;
5151
5152         switch (m->header->type) {
5153
5154         case SD_BUS_MESSAGE_SIGNAL:
5155                 if (!m->path || !m->interface || !m->member)
5156                         return -EBADMSG;
5157                 break;
5158
5159         case SD_BUS_MESSAGE_METHOD_CALL:
5160
5161                 if (!m->path || !m->member)
5162                         return -EBADMSG;
5163
5164                 break;
5165
5166         case SD_BUS_MESSAGE_METHOD_RETURN:
5167
5168                 if (m->reply_cookie == 0)
5169                         return -EBADMSG;
5170                 break;
5171
5172         case SD_BUS_MESSAGE_METHOD_ERROR:
5173
5174                 if (m->reply_cookie == 0 || !m->error.name)
5175                         return -EBADMSG;
5176                 break;
5177         }
5178
5179         /* Refuse non-local messages that claim they are local */
5180         if (streq_ptr(m->path, "/org/freedesktop/DBus/Local"))
5181                 return -EBADMSG;
5182         if (streq_ptr(m->interface, "org.freedesktop.DBus.Local"))
5183                 return -EBADMSG;
5184         if (streq_ptr(m->sender, "org.freedesktop.DBus.Local"))
5185                 return -EBADMSG;
5186
5187         m->root_container.end = BUS_MESSAGE_BODY_SIZE(m);
5188
5189         if (BUS_MESSAGE_IS_GVARIANT(m)) {
5190                 r = build_struct_offsets(
5191                                 m,
5192                                 m->root_container.signature,
5193                                 BUS_MESSAGE_BODY_SIZE(m),
5194                                 &m->root_container.item_size,
5195                                 &m->root_container.offsets,
5196                                 &m->root_container.n_offsets);
5197                 if (r < 0)
5198                         return r;
5199         }
5200
5201         /* Try to read the error message, but if we can't it's a non-issue */
5202         if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
5203                 sd_bus_message_read(m, "s", &m->error.message);
5204
5205         return 0;
5206 }
5207
5208 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
5209         assert_return(m, -EINVAL);
5210         assert_return(destination, -EINVAL);
5211         assert_return(!m->sealed, -EPERM);
5212         assert_return(!m->destination, -EEXIST);
5213
5214         return message_append_field_string(m, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
5215 }
5216
5217 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
5218         size_t total;
5219         void *p, *e;
5220         unsigned i;
5221         struct bus_body_part *part;
5222
5223         assert(m);
5224         assert(buffer);
5225         assert(sz);
5226
5227         total = BUS_MESSAGE_SIZE(m);
5228
5229         p = malloc(total);
5230         if (!p)
5231                 return -ENOMEM;
5232
5233         e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
5234         MESSAGE_FOREACH_PART(part, i, m)
5235                 e = mempcpy(e, part->data, part->size);
5236
5237         assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
5238
5239         *buffer = p;
5240         *sz = total;
5241
5242         return 0;
5243 }
5244
5245 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
5246         int r;
5247
5248         assert(m);
5249         assert(l);
5250
5251         r = sd_bus_message_enter_container(m, 'a', "s");
5252         if (r <= 0)
5253                 return r;
5254
5255         for (;;) {
5256                 const char *s;
5257
5258                 r = sd_bus_message_read_basic(m, 's', &s);
5259                 if (r < 0)
5260                         return r;
5261                 if (r == 0)
5262                         break;
5263
5264                 r = strv_extend(l, s);
5265                 if (r < 0)
5266                         return r;
5267         }
5268
5269         r = sd_bus_message_exit_container(m);
5270         if (r < 0)
5271                 return r;
5272
5273         return 1;
5274 }
5275
5276 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
5277         char **strv = NULL;
5278         int r;
5279
5280         assert_return(m, -EINVAL);
5281         assert_return(m->sealed, -EPERM);
5282         assert_return(l, -EINVAL);
5283
5284         r = bus_message_read_strv_extend(m, &strv);
5285         if (r <= 0) {
5286                 strv_free(strv);
5287                 return r;
5288         }
5289
5290         *l = strv;
5291         return 1;
5292 }
5293
5294 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
5295         int r;
5296         const char *t = NULL;
5297         unsigned j;
5298
5299         assert(m);
5300
5301         r = sd_bus_message_rewind(m, true);
5302         if (r < 0)
5303                 return NULL;
5304
5305         for (j = 0; j <= i; j++) {
5306                 char type;
5307
5308                 r = sd_bus_message_peek_type(m, &type, NULL);
5309                 if (r < 0)
5310                         return NULL;
5311
5312                 if (type != SD_BUS_TYPE_STRING &&
5313                     type != SD_BUS_TYPE_OBJECT_PATH &&
5314                     type != SD_BUS_TYPE_SIGNATURE)
5315                         return NULL;
5316
5317                 r = sd_bus_message_read_basic(m, type, &t);
5318                 if (r < 0)
5319                         return NULL;
5320         }
5321
5322         return t;
5323 }
5324
5325 bool bus_header_is_complete(struct bus_header *h, size_t size) {
5326         size_t full;
5327
5328         assert(h);
5329         assert(size);
5330
5331         if (size < sizeof(struct bus_header))
5332                 return false;
5333
5334         full = sizeof(struct bus_header) +
5335                 (h->endian == BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
5336
5337         return size >= full;
5338 }
5339
5340 int bus_header_message_size(struct bus_header *h, size_t *sum) {
5341         size_t fs, bs;
5342
5343         assert(h);
5344         assert(sum);
5345
5346         if (h->endian == BUS_NATIVE_ENDIAN) {
5347                 fs = h->fields_size;
5348                 bs = h->body_size;
5349         } else if (h->endian == BUS_REVERSE_ENDIAN) {
5350                 fs = bswap_32(h->fields_size);
5351                 bs = bswap_32(h->body_size);
5352         } else
5353                 return -EBADMSG;
5354
5355         *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
5356         return 0;
5357 }
5358
5359 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
5360         assert_return(m, EINVAL);
5361
5362         if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
5363                 return 0;
5364
5365         return sd_bus_error_get_errno(&m->error);
5366 }
5367
5368 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
5369         struct bus_container *c;
5370
5371         assert_return(m, NULL);
5372
5373         c = complete ? &m->root_container : message_get_container(m);
5374         return strempty(c->signature);
5375 }
5376
5377 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
5378         bool done_something = false;
5379         int r;
5380
5381         assert_return(m, -EINVAL);
5382         assert_return(source, -EINVAL);
5383         assert_return(!m->sealed, -EPERM);
5384         assert_return(source->sealed, -EPERM);
5385
5386         do {
5387                 const char *contents;
5388                 char type;
5389                 union {
5390                         uint8_t u8;
5391                         uint16_t u16;
5392                         int16_t s16;
5393                         uint32_t u32;
5394                         int32_t s32;
5395                         uint64_t u64;
5396                         int64_t s64;
5397                         double d64;
5398                         const char *string;
5399                         int i;
5400                 } basic;
5401
5402                 r = sd_bus_message_peek_type(source, &type, &contents);
5403                 if (r < 0)
5404                         return r;
5405                 if (r == 0)
5406                         break;
5407
5408                 done_something = true;
5409
5410                 if (bus_type_is_container(type) > 0) {
5411
5412                         r = sd_bus_message_enter_container(source, type, contents);
5413                         if (r < 0)
5414                                 return r;
5415
5416                         r = sd_bus_message_open_container(m, type, contents);
5417                         if (r < 0)
5418                                 return r;
5419
5420                         r = sd_bus_message_copy(m, source, true);
5421                         if (r < 0)
5422                                 return r;
5423
5424                         r = sd_bus_message_close_container(m);
5425                         if (r < 0)
5426                                 return r;
5427
5428                         r = sd_bus_message_exit_container(source);
5429                         if (r < 0)
5430                                 return r;
5431
5432                         continue;
5433                 }
5434
5435                 r = sd_bus_message_read_basic(source, type, &basic);
5436                 if (r < 0)
5437                         return r;
5438
5439                 assert(r > 0);
5440
5441                 if (type == SD_BUS_TYPE_OBJECT_PATH ||
5442                     type == SD_BUS_TYPE_SIGNATURE ||
5443                     type == SD_BUS_TYPE_STRING)
5444                         r = sd_bus_message_append_basic(m, type, basic.string);
5445                 else
5446                         r = sd_bus_message_append_basic(m, type, &basic);
5447
5448                 if (r < 0)
5449                         return r;
5450
5451         } while (all);
5452
5453         return done_something;
5454 }
5455
5456 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
5457         const char *c;
5458         char t;
5459         int r;
5460
5461         assert_return(m, -EINVAL);
5462         assert_return(m->sealed, -EPERM);
5463         assert_return(!type || bus_type_is_valid(type), -EINVAL);
5464         assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
5465         assert_return(type || contents, -EINVAL);
5466         assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
5467
5468         r = sd_bus_message_peek_type(m, &t, &c);
5469         if (r <= 0)
5470                 return r;
5471
5472         if (type != 0 && type != t)
5473                 return 0;
5474
5475         if (contents && !streq_ptr(contents, c))
5476                 return 0;
5477
5478         return 1;
5479 }
5480
5481 _public_ sd_bus *sd_bus_message_get_bus(sd_bus_message *m) {
5482         assert_return(m, NULL);
5483
5484         return m->bus;
5485 }
5486
5487 int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) {
5488         _cleanup_bus_message_unref_ sd_bus_message *n = NULL;
5489         usec_t timeout;
5490         int r;
5491
5492         assert(bus);
5493         assert(m);
5494         assert(*m);
5495
5496         switch ((*m)->header->type) {
5497
5498         case SD_BUS_MESSAGE_SIGNAL:
5499                 r = sd_bus_message_new_signal(bus, &n, (*m)->path, (*m)->interface, (*m)->member);
5500                 if (r < 0)
5501                         return r;
5502
5503                 break;
5504
5505         case SD_BUS_MESSAGE_METHOD_CALL:
5506                 r = sd_bus_message_new_method_call(bus, &n, (*m)->destination, (*m)->path, (*m)->interface, (*m)->member);
5507                 if (r < 0)
5508                         return r;
5509
5510                 break;
5511
5512         case SD_BUS_MESSAGE_METHOD_RETURN:
5513         case SD_BUS_MESSAGE_METHOD_ERROR:
5514
5515                 n = message_new(bus, (*m)->header->type);
5516                 if (!n)
5517                         return -ENOMEM;
5518
5519                 n->reply_cookie = (*m)->reply_cookie;
5520                 r = message_append_field_uint32(n, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) n->reply_cookie);
5521                 if (r < 0)
5522                         return r;
5523
5524                 if ((*m)->header->type == SD_BUS_MESSAGE_METHOD_ERROR && (*m)->error.name) {
5525                         r = message_append_field_string(n, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, (*m)->error.name, &n->error.message);
5526                         if (r < 0)
5527                                 return r;
5528
5529                         n->error._need_free = -1;
5530                 }
5531
5532                 break;
5533
5534         default:
5535                 return -EINVAL;
5536         }
5537
5538         if ((*m)->destination && !n->destination) {
5539                 r = message_append_field_string(n, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, (*m)->destination, &n->destination);
5540                 if (r < 0)
5541                         return r;
5542         }
5543
5544         if ((*m)->sender && !n->sender) {
5545                 r = message_append_field_string(n, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, (*m)->sender, &n->sender);
5546                 if (r < 0)
5547                         return r;
5548         }
5549
5550         n->header->flags |= (*m)->header->flags & (BUS_MESSAGE_NO_REPLY_EXPECTED|BUS_MESSAGE_NO_AUTO_START);
5551
5552         r = sd_bus_message_copy(n, *m, true);
5553         if (r < 0)
5554                 return r;
5555
5556         timeout = (*m)->timeout;
5557         if (timeout == 0 && !((*m)->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED))
5558                 timeout = BUS_DEFAULT_TIMEOUT;
5559
5560         r = bus_message_seal(n, BUS_MESSAGE_COOKIE(*m), timeout);
5561         if (r < 0)
5562                 return r;
5563
5564         sd_bus_message_unref(*m);
5565         *m = n;
5566         n = NULL;
5567
5568         return 0;
5569 }
5570
5571 int bus_message_append_sender(sd_bus_message *m, const char *sender) {
5572         assert(m);
5573         assert(sender);
5574
5575         assert_return(!m->sealed, -EPERM);
5576         assert_return(!m->sender, -EPERM);
5577
5578         return message_append_field_string(m, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, sender, &m->sender);
5579 }
5580
5581 _public_ int sd_bus_message_get_priority(sd_bus_message *m, int64_t *priority) {
5582         assert_return(m, -EINVAL);
5583         assert_return(priority, -EINVAL);
5584
5585         *priority = m->priority;
5586         return 0;
5587 }
5588
5589 _public_ int sd_bus_message_set_priority(sd_bus_message *m, int64_t priority) {
5590         assert_return(m, -EINVAL);
5591         assert_return(!m->sealed, -EPERM);
5592
5593         m->priority = priority;
5594         return 0;
5595 }