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