chiark / gitweb /
bus: add support for serializing to gvariant
[elogind.git] / src / libsystemd-bus / bus-message.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <sys/mman.h>
25
26 #include "util.h"
27 #include "utf8.h"
28 #include "strv.h"
29 #include "time-util.h"
30 #include "cgroup-util.h"
31
32 #include "sd-bus.h"
33 #include "bus-message.h"
34 #include "bus-internal.h"
35 #include "bus-type.h"
36 #include "bus-signature.h"
37 #include "bus-gvariant.h"
38
39 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
40
41 static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
42
43         if (p == NULL)
44                 return NULL;
45
46         if (old_base == new_base)
47                 return (void*) p;
48
49         if ((uint8_t*) p < (uint8_t*) old_base)
50                 return (void*) p;
51
52         if ((uint8_t*) p >= (uint8_t*) old_base + sz)
53                 return (void*) p;
54
55         return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base);
56 }
57
58 static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
59         assert(m);
60         assert(part);
61
62         if (part->memfd >= 0) {
63                 /* If we can reuse the memfd, try that. For that it
64                  * can't be sealed yet. */
65
66                 if (!part->sealed)
67                         bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped);
68                 else {
69                         if (part->mapped > 0)
70                                 assert_se(munmap(part->data, part->mapped) == 0);
71
72                         close_nointr_nofail(part->memfd);
73                 }
74
75         } else if (part->munmap_this)
76                 munmap(part->data, part->mapped);
77         else if (part->free_this)
78                 free(part->data);
79
80         if (part != &m->body)
81                 free(part);
82 }
83
84 static void message_reset_parts(sd_bus_message *m) {
85         struct bus_body_part *part;
86
87         assert(m);
88
89         part = &m->body;
90         while (m->n_body_parts > 0) {
91                 struct bus_body_part *next = part->next;
92                 message_free_part(m, part);
93                 part = next;
94                 m->n_body_parts--;
95         }
96
97         m->body_end = NULL;
98
99         m->cached_rindex_part = NULL;
100         m->cached_rindex_part_begin = 0;
101 }
102
103 static void message_reset_containers(sd_bus_message *m) {
104         unsigned i;
105
106         assert(m);
107
108         for (i = 0; i < m->n_containers; i++)
109                 free(m->containers[i].signature);
110
111         free(m->containers);
112         m->containers = NULL;
113
114         m->n_containers = 0;
115         m->root_container.index = 0;
116 }
117
118 static void message_free(sd_bus_message *m) {
119         assert(m);
120
121         if (m->free_header)
122                 free(m->header);
123
124         message_reset_parts(m);
125
126         if (m->free_kdbus)
127                 free(m->kdbus);
128
129         if (m->release_kdbus) {
130                 uint64_t off;
131
132                 off = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
133                 ioctl(m->bus->input_fd, KDBUS_CMD_FREE, &off);
134         }
135
136         if (m->bus)
137                 sd_bus_unref(m->bus);
138
139         if (m->free_fds) {
140                 close_many(m->fds, m->n_fds);
141                 free(m->fds);
142         }
143
144         if (m->iovec != m->iovec_fixed)
145                 free(m->iovec);
146
147         message_reset_containers(m);
148         free(m->root_container.signature);
149
150         free(m->peeked_signature);
151
152         bus_creds_done(&m->creds);
153         free(m);
154 }
155
156 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
157         void *op, *np;
158         size_t old_size, new_size, start;
159
160         assert(m);
161
162         if (m->poisoned)
163                 return NULL;
164
165         old_size = sizeof(struct bus_header) + m->header->fields_size;
166         start = ALIGN_TO(old_size, align);
167         new_size = start + sz;
168
169         if (old_size == new_size)
170                 return (uint8_t*) m->header + old_size;
171
172         if (new_size > (size_t) ((uint32_t) -1))
173                 goto poison;
174
175         if (m->free_header) {
176                 np = realloc(m->header, ALIGN8(new_size));
177                 if (!np)
178                         goto poison;
179         } else {
180                 /* Initially, the header is allocated as part of of
181                  * the sd_bus_message itself, let's replace it by
182                  * dynamic data */
183
184                 np = malloc(ALIGN8(new_size));
185                 if (!np)
186                         goto poison;
187
188                 memcpy(np, m->header, sizeof(struct bus_header));
189         }
190
191         /* Zero out padding */
192         if (start > old_size)
193                 memset((uint8_t*) np + old_size, 0, start - old_size);
194
195         op = m->header;
196         m->header = np;
197         m->header->fields_size = new_size - sizeof(struct bus_header);
198
199         /* Adjust quick access pointers */
200         m->path = adjust_pointer(m->path, op, old_size, m->header);
201         m->interface = adjust_pointer(m->interface, op, old_size, m->header);
202         m->member = adjust_pointer(m->member, op, old_size, m->header);
203         m->destination = adjust_pointer(m->destination, op, old_size, m->header);
204         m->sender = adjust_pointer(m->sender, op, old_size, m->header);
205         m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
206
207         m->free_header = true;
208
209         if (add_offset) {
210                 if (m->n_header_offsets >= ELEMENTSOF(m->header_offsets))
211                         goto poison;
212
213                 m->header_offsets[m->n_header_offsets++] = new_size - sizeof(struct bus_header);
214         }
215
216         return (uint8_t*) np + start;
217
218 poison:
219         m->poisoned = true;
220         return NULL;
221 }
222
223 static int message_append_field_string(
224                 sd_bus_message *m,
225                 uint8_t h,
226                 char type,
227                 const char *s,
228                 const char **ret) {
229
230         size_t l;
231         uint8_t *p;
232
233         assert(m);
234
235         /* dbus1 doesn't allow strings over 32bit, let's enforce this
236          * globally, to not risk convertability */
237         l = strlen(s);
238         if (l > (size_t) (uint32_t) -1)
239                 return -EINVAL;
240
241         /* Signature "(yv)" where the variant contains "s" */
242
243         if (m->is_gvariant) {
244
245                 /* (field id byte + 7x padding, ((string + NUL) + NUL + signature string 's') */
246                 p = message_extend_fields(m, 8, 1 + 7 + l + 1 + 1 + 1, true);
247                 if (!p)
248                         return -ENOMEM;
249
250                 p[0] = h;
251                 memset(p+1, 0, 7);
252                 memcpy(p+8, s, l);
253                 p[8+l] = 0;
254                 p[8+l+1] = 0;
255                 p[8+l+2] = type;
256
257                 if (ret)
258                         *ret = (char*) p + 1;
259
260         } else {
261                 /* (field id byte + (signature length + signature 's' + NUL) + (string length + string + NUL)) */
262                 p = message_extend_fields(m, 8, 4 + 4 + l + 1, false);
263                 if (!p)
264                         return -ENOMEM;
265
266                 p[0] = h;
267                 p[1] = 1;
268                 p[2] = type;
269                 p[3] = 0;
270
271                 ((uint32_t*) p)[1] = l;
272                 memcpy(p + 8, s, l + 1);
273
274                 if (ret)
275                         *ret = (char*) p + 8;
276         }
277
278         return 0;
279 }
280
281 static int message_append_field_signature(
282                 sd_bus_message *m,
283                 uint8_t h,
284                 const char *s,
285                 const char **ret) {
286
287         size_t l;
288         uint8_t *p;
289
290         assert(m);
291
292         /* dbus1 doesn't allow signatures over 32bit, let's enforce
293          * this globally, to not risk convertability */
294         l = strlen(s);
295         if (l > 255)
296                 return -EINVAL;
297
298         /* Signature "(yv)" where the variant contains "g" */
299
300         if (m->is_gvariant)
301                 /* For gvariant the serialization is the same as for normal strings */
302                 return message_append_field_string(m, h, 'g', s, ret);
303         else {
304                 /* (field id byte + (signature length + signature 'g' + NUL) + (string length + string + NUL)) */
305                 p = message_extend_fields(m, 8, 4 + 1 + l + 1, false);
306                 if (!p)
307                         return -ENOMEM;
308
309                 p[0] = h;
310                 p[1] = 1;
311                 p[2] = SD_BUS_TYPE_SIGNATURE;
312                 p[3] = 0;
313                 p[4] = l;
314                 memcpy(p + 5, s, l + 1);
315
316                 if (ret)
317                         *ret = (const char*) p + 5;
318         }
319
320         return 0;
321 }
322
323 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
324         uint8_t *p;
325
326         assert(m);
327
328         if (m->is_gvariant) {
329                 /* (field id byte + 7x padding + ((value + NUL + signature string 'u') */
330
331                 p = message_extend_fields(m, 8, 1 + 7 + 4 + 1 + 1, true);
332                 if (!p)
333                         return -ENOMEM;
334
335                 p[0] = h;
336                 memset(p+1, 0, 7);
337                 *((uint32_t*) (p + 8)) = x;
338                 p[12] = 0;
339                 p[13] = 'u';
340         } else {
341                 /* (field id byte + (signature length + signature 'u' + NUL) + value) */
342                 p = message_extend_fields(m, 8, 4 + 4, false);
343                 if (!p)
344                         return -ENOMEM;
345
346                 p[0] = h;
347                 p[1] = 1;
348                 p[2] = SD_BUS_TYPE_UINT32;
349                 p[3] = 0;
350
351                 ((uint32_t*) p)[1] = x;
352         }
353
354         return 0;
355 }
356
357 int bus_message_from_header(
358                 sd_bus *bus,
359                 void *buffer,
360                 size_t length,
361                 int *fds,
362                 unsigned n_fds,
363                 const struct ucred *ucred,
364                 const char *label,
365                 size_t extra,
366                 sd_bus_message **ret) {
367
368         sd_bus_message *m;
369         struct bus_header *h;
370         size_t a, label_sz;
371
372         assert(buffer || length <= 0);
373         assert(fds || n_fds <= 0);
374         assert(ret);
375
376         if (length < sizeof(struct bus_header))
377                 return -EBADMSG;
378
379         h = buffer;
380         if (h->version != 1)
381                 return -EBADMSG;
382
383         if (h->serial == 0)
384                 return -EBADMSG;
385
386         if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
387                 return -EBADMSG;
388
389         if (h->endian != BUS_LITTLE_ENDIAN &&
390             h->endian != BUS_BIG_ENDIAN)
391                 return -EBADMSG;
392
393         a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
394
395         if (label) {
396                 label_sz = strlen(label);
397                 a += label_sz + 1;
398         }
399
400         m = malloc0(a);
401         if (!m)
402                 return -ENOMEM;
403
404         m->n_ref = 1;
405         m->sealed = true;
406         m->header = h;
407         m->fds = fds;
408         m->n_fds = n_fds;
409
410         if (ucred) {
411                 m->creds.uid = ucred->uid;
412                 m->creds.pid = ucred->pid;
413                 m->creds.gid = ucred->gid;
414                 m->creds.mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_PID | SD_BUS_CREDS_GID;
415         }
416
417         if (label) {
418                 m->creds.label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
419                 memcpy(m->creds.label, label, label_sz + 1);
420
421                 m->creds.mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
422         }
423
424         if (bus)
425                 m->bus = sd_bus_ref(bus);
426
427         *ret = m;
428         return 0;
429 }
430
431 int bus_message_from_malloc(
432                 sd_bus *bus,
433                 void *buffer,
434                 size_t length,
435                 int *fds,
436                 unsigned n_fds,
437                 const struct ucred *ucred,
438                 const char *label,
439                 sd_bus_message **ret) {
440
441         sd_bus_message *m;
442         size_t sz;
443         int r;
444
445         r = bus_message_from_header(bus, buffer, length, fds, n_fds, ucred, label, 0, &m);
446         if (r < 0)
447                 return r;
448
449         if (length != BUS_MESSAGE_SIZE(m)) {
450                 r = -EBADMSG;
451                 goto fail;
452         }
453
454         sz = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
455         if (sz > 0) {
456                 m->n_body_parts = 1;
457                 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
458                 m->body.size = sz;
459                 m->body.sealed = true;
460                 m->body.memfd = -1;
461         }
462
463         m->n_iovec = 1;
464         m->iovec = m->iovec_fixed;
465         m->iovec[0].iov_base = buffer;
466         m->iovec[0].iov_len = length;
467
468         r = bus_message_parse_fields(m);
469         if (r < 0)
470                 goto fail;
471
472         /* We take possession of the memory and fds now */
473         m->free_header = true;
474         m->free_fds = true;
475
476         *ret = m;
477         return 0;
478
479 fail:
480         message_free(m);
481         return r;
482 }
483
484 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
485         sd_bus_message *m;
486
487         m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
488         if (!m)
489                 return NULL;
490
491         m->n_ref = 1;
492         m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
493         m->header->endian = BUS_NATIVE_ENDIAN;
494         m->header->type = type;
495         m->header->version = bus ? bus->message_version : 1;
496         m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
497         m->root_container.need_offsets = m->is_gvariant = bus ? bus->use_gvariant : false;
498
499         if (bus)
500                 m->bus = sd_bus_ref(bus);
501
502         return m;
503 }
504
505 _public_ int sd_bus_message_new_signal(
506                 sd_bus *bus,
507                 const char *path,
508                 const char *interface,
509                 const char *member,
510                 sd_bus_message **m) {
511
512         sd_bus_message *t;
513         int r;
514
515         assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
516         assert_return(object_path_is_valid(path), -EINVAL);
517         assert_return(interface_name_is_valid(interface), -EINVAL);
518         assert_return(member_name_is_valid(member), -EINVAL);
519         assert_return(m, -EINVAL);
520
521         t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
522         if (!t)
523                 return -ENOMEM;
524
525         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
526
527         r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
528         if (r < 0)
529                 goto fail;
530         r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
531         if (r < 0)
532                 goto fail;
533         r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
534         if (r < 0)
535                 goto fail;
536
537         *m = t;
538         return 0;
539
540 fail:
541         sd_bus_message_unref(t);
542         return r;
543 }
544
545 _public_ int sd_bus_message_new_method_call(
546                 sd_bus *bus,
547                 const char *destination,
548                 const char *path,
549                 const char *interface,
550                 const char *member,
551                 sd_bus_message **m) {
552
553         sd_bus_message *t;
554         int r;
555
556         assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
557         assert_return(!destination || service_name_is_valid(destination), -EINVAL);
558         assert_return(object_path_is_valid(path), -EINVAL);
559         assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
560         assert_return(member_name_is_valid(member), -EINVAL);
561         assert_return(m, -EINVAL);
562
563         t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
564         if (!t)
565                 return -ENOMEM;
566
567         r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
568         if (r < 0)
569                 goto fail;
570         r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
571         if (r < 0)
572                 goto fail;
573
574         if (interface) {
575                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
576                 if (r < 0)
577                         goto fail;
578         }
579
580         if (destination) {
581                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
582                 if (r < 0)
583                         goto fail;
584         }
585
586         *m = t;
587         return 0;
588
589 fail:
590         message_free(t);
591         return r;
592 }
593
594 static int message_new_reply(
595                 sd_bus_message *call,
596                 uint8_t type,
597                 sd_bus_message **m) {
598
599         sd_bus_message *t;
600         int r;
601
602         assert_return(call, -EINVAL);
603         assert_return(call->sealed, -EPERM);
604         assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
605         assert_return(!call->bus || call->bus->state != BUS_UNSET, -ENOTCONN);
606         assert_return(m, -EINVAL);
607
608         t = message_new(call->bus, type);
609         if (!t)
610                 return -ENOMEM;
611
612         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
613         t->reply_serial = BUS_MESSAGE_SERIAL(call);
614
615         r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
616         if (r < 0)
617                 goto fail;
618
619         if (call->sender) {
620                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
621                 if (r < 0)
622                         goto fail;
623         }
624
625         t->dont_send = !!(call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
626         t->enforced_reply_signature = call->enforced_reply_signature;
627
628         *m = t;
629         return 0;
630
631 fail:
632         message_free(t);
633         return r;
634 }
635
636 _public_ int sd_bus_message_new_method_return(
637                 sd_bus_message *call,
638                 sd_bus_message **m) {
639
640         return message_new_reply(call, SD_BUS_MESSAGE_METHOD_RETURN, m);
641 }
642
643 _public_ int sd_bus_message_new_method_error(
644                 sd_bus_message *call,
645                 const sd_bus_error *e,
646                 sd_bus_message **m) {
647
648         sd_bus_message *t;
649         int r;
650
651         assert_return(sd_bus_error_is_set(e), -EINVAL);
652         assert_return(m, -EINVAL);
653
654         r = message_new_reply(call, SD_BUS_MESSAGE_METHOD_ERROR, &t);
655         if (r < 0)
656                 return r;
657
658         r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
659         if (r < 0)
660                 goto fail;
661
662         if (e->message) {
663                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
664                 if (r < 0)
665                         goto fail;
666         }
667
668         t->error._need_free = -1;
669
670         *m = t;
671         return 0;
672
673 fail:
674         message_free(t);
675         return r;
676 }
677
678 _public_ int sd_bus_message_new_method_errorf(
679                 sd_bus_message *call,
680                 sd_bus_message **m,
681                 const char *name,
682                 const char *format,
683                 ...) {
684
685         _cleanup_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
686         va_list ap;
687
688         assert_return(name, -EINVAL);
689         assert_return(m, -EINVAL);
690
691         va_start(ap, format);
692         bus_error_setfv(&error, name, format, ap);
693         va_end(ap);
694
695         return sd_bus_message_new_method_error(call, &error, m);
696 }
697
698 _public_ int sd_bus_message_new_method_errno(
699                 sd_bus_message *call,
700                 int error,
701                 const sd_bus_error *p,
702                 sd_bus_message **m) {
703
704         _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
705
706         if (sd_bus_error_is_set(p))
707                 return sd_bus_message_new_method_error(call, p, m);
708
709         sd_bus_error_set_errno(&berror, error);
710
711         return sd_bus_message_new_method_error(call, &berror, m);
712 }
713
714 _public_ int sd_bus_message_new_method_errnof(
715                 sd_bus_message *call,
716                 sd_bus_message **m,
717                 int error,
718                 const char *format,
719                 ...) {
720
721         _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
722         va_list ap;
723
724         va_start(ap, format);
725         bus_error_set_errnofv(&berror, error, format, ap);
726         va_end(ap);
727
728         return sd_bus_message_new_method_error(call, &berror, m);
729 }
730
731 int bus_message_new_synthetic_error(
732                 sd_bus *bus,
733                 uint64_t serial,
734                 const sd_bus_error *e,
735                 sd_bus_message **m) {
736
737         sd_bus_message *t;
738         int r;
739
740         assert(sd_bus_error_is_set(e));
741         assert(m);
742
743         t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
744         if (!t)
745                 return -ENOMEM;
746
747         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
748         t->reply_serial = serial;
749
750         r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
751         if (r < 0)
752                 goto fail;
753
754         if (bus && bus->unique_name) {
755                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
756                 if (r < 0)
757                         goto fail;
758         }
759
760         r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
761         if (r < 0)
762                 goto fail;
763
764         if (e->message) {
765                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
766                 if (r < 0)
767                         goto fail;
768         }
769
770         t->error._need_free = -1;
771
772         *m = t;
773         return 0;
774
775 fail:
776         message_free(t);
777         return r;
778 }
779
780 _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
781         assert_return(m, NULL);
782
783         assert(m->n_ref > 0);
784         m->n_ref++;
785
786         return m;
787 }
788
789 _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
790         assert_return(m, NULL);
791
792         assert(m->n_ref > 0);
793         m->n_ref--;
794
795         if (m->n_ref <= 0)
796                 message_free(m);
797
798         return NULL;
799 }
800
801 _public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
802         assert_return(m, -EINVAL);
803         assert_return(type, -EINVAL);
804
805         *type = m->header->type;
806         return 0;
807 }
808
809 _public_ int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
810         assert_return(m, -EINVAL);
811         assert_return(serial, -EINVAL);
812         assert_return(m->header->serial != 0, -ENOENT);
813
814         *serial = BUS_MESSAGE_SERIAL(m);
815         return 0;
816 }
817
818 _public_ int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
819         assert_return(m, -EINVAL);
820         assert_return(serial, -EINVAL);
821         assert_return(m->reply_serial != 0, -ENOENT);
822
823         *serial = m->reply_serial;
824         return 0;
825 }
826
827 _public_ int sd_bus_message_get_no_reply(sd_bus_message *m) {
828         assert_return(m, -EINVAL);
829
830         return m->header->type == SD_BUS_MESSAGE_METHOD_CALL ? !!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
831 }
832
833 _public_ int sd_bus_message_get_no_auto_start(sd_bus_message *m) {
834         assert_return(m, -EINVAL);
835
836         return !!(m->header->flags & BUS_MESSAGE_NO_AUTO_START);
837 }
838
839 _public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
840         assert_return(m, NULL);
841
842         return m->path;
843 }
844
845 _public_ const char *sd_bus_message_get_interface(sd_bus_message *m) {
846         assert_return(m, NULL);
847
848         return m->interface;
849 }
850
851 _public_ const char *sd_bus_message_get_member(sd_bus_message *m) {
852         assert_return(m, NULL);
853
854         return m->member;
855 }
856
857 _public_ const char *sd_bus_message_get_destination(sd_bus_message *m) {
858         assert_return(m, NULL);
859
860         return m->destination;
861 }
862
863 _public_ const char *sd_bus_message_get_sender(sd_bus_message *m) {
864         assert_return(m, NULL);
865
866         return m->sender;
867 }
868
869 _public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
870         assert_return(m, NULL);
871         assert_return(sd_bus_error_is_set(&m->error), NULL);
872
873         return &m->error;
874 }
875
876 _public_ int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
877         assert_return(m, -EINVAL);
878         assert_return(usec, -EINVAL);
879         assert_return(m->monotonic > 0, -ENODATA);
880
881         *usec = m->monotonic;
882         return 0;
883 }
884
885 _public_ int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
886         assert_return(m, -EINVAL);
887         assert_return(usec, -EINVAL);
888         assert_return(m->realtime > 0, -ENODATA);
889
890         *usec = m->realtime;
891         return 0;
892 }
893
894 _public_ sd_bus_creds *sd_bus_message_get_creds(sd_bus_message *m) {
895         assert_return(m, NULL);
896
897         if (m->creds.mask == 0)
898                 return NULL;
899
900         return &m->creds;
901 }
902
903 _public_ int sd_bus_message_is_signal(sd_bus_message *m,
904                                       const char *interface,
905                                       const char *member) {
906         assert_return(m, -EINVAL);
907
908         if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
909                 return 0;
910
911         if (interface && (!m->interface || !streq(m->interface, interface)))
912                 return 0;
913
914         if (member &&  (!m->member || !streq(m->member, member)))
915                 return 0;
916
917         return 1;
918 }
919
920 _public_ int sd_bus_message_is_method_call(sd_bus_message *m,
921                                            const char *interface,
922                                            const char *member) {
923         assert_return(m, -EINVAL);
924
925         if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
926                 return 0;
927
928         if (interface && (!m->interface || !streq(m->interface, interface)))
929                 return 0;
930
931         if (member &&  (!m->member || !streq(m->member, member)))
932                 return 0;
933
934         return 1;
935 }
936
937 _public_ int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
938         assert_return(m, -EINVAL);
939
940         if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
941                 return 0;
942
943         if (name && (!m->error.name || !streq(m->error.name, name)))
944                 return 0;
945
946         return 1;
947 }
948
949 _public_ int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
950         assert_return(m, -EINVAL);
951         assert_return(!m->sealed, -EPERM);
952         assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
953
954         if (b)
955                 m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
956         else
957                 m->header->flags &= ~BUS_MESSAGE_NO_REPLY_EXPECTED;
958
959         return 0;
960 }
961
962 _public_ int sd_bus_message_set_no_auto_start(sd_bus_message *m, int b) {
963         assert_return(m, -EINVAL);
964         assert_return(!m->sealed, -EPERM);
965
966         if (b)
967                 m->header->flags |= BUS_MESSAGE_NO_AUTO_START;
968         else
969                 m->header->flags &= ~BUS_MESSAGE_NO_AUTO_START;
970
971         return 0;
972 }
973
974 static struct bus_container *message_get_container(sd_bus_message *m) {
975         assert(m);
976
977         if (m->n_containers == 0)
978                 return &m->root_container;
979
980         assert(m->containers);
981         return m->containers + m->n_containers - 1;
982 }
983
984 struct bus_body_part *message_append_part(sd_bus_message *m) {
985         struct bus_body_part *part;
986
987         assert(m);
988
989         if (m->poisoned)
990                 return NULL;
991
992         if (m->n_body_parts <= 0) {
993                 part = &m->body;
994                 zero(*part);
995         } else {
996                 assert(m->body_end);
997
998                 part = new0(struct bus_body_part, 1);
999                 if (!part) {
1000                         m->poisoned = true;
1001                         return NULL;
1002                 }
1003
1004                 m->body_end->next = part;
1005         }
1006
1007         part->memfd = -1;
1008         m->body_end = part;
1009         m->n_body_parts ++;
1010
1011         return part;
1012 }
1013
1014 static void part_zero(struct bus_body_part *part, size_t sz) {
1015         assert(part);
1016         assert(sz > 0);
1017         assert(sz < 8);
1018
1019         /* All other fields can be left in their defaults */
1020         assert(!part->data);
1021         assert(part->memfd < 0);
1022
1023         part->size = sz;
1024         part->is_zero = true;
1025         part->sealed = true;
1026 }
1027
1028 static int part_make_space(
1029                 struct sd_bus_message *m,
1030                 struct bus_body_part *part,
1031                 size_t sz,
1032                 void **q) {
1033
1034         void *n;
1035         int r;
1036
1037         assert(m);
1038         assert(part);
1039         assert(!part->sealed);
1040
1041         if (m->poisoned)
1042                 return -ENOMEM;
1043
1044         if (!part->data && part->memfd < 0)
1045                 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1046
1047         if (part->memfd >= 0) {
1048                 uint64_t u = sz;
1049
1050                 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1051                 if (r < 0) {
1052                         m->poisoned = true;
1053                         return -errno;
1054                 }
1055
1056                 if (!part->data || sz > part->mapped) {
1057                         size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1058
1059                         if (part->mapped <= 0)
1060                                 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1061                         else
1062                                 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1063
1064                         if (n == MAP_FAILED) {
1065                                 m->poisoned = true;
1066                                 return -errno;
1067                         }
1068
1069                         part->mapped = psz;
1070                         part->data = n;
1071                 }
1072
1073                 part->munmap_this = true;
1074         } else {
1075                 n = realloc(part->data, MAX(sz, 1u));
1076                 if (!n) {
1077                         m->poisoned = true;
1078                         return -ENOMEM;
1079                 }
1080
1081                 part->data = n;
1082                 part->free_this = true;
1083         }
1084
1085         if (q)
1086                 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1087
1088         part->size = sz;
1089         return 0;
1090 }
1091
1092 static int message_add_offset(sd_bus_message *m, size_t offset) {
1093         struct bus_container *c;
1094
1095         assert(m);
1096         assert(m->is_gvariant);
1097
1098         /* Add offset to current container, unless this is the first
1099          * item in it, which will have the 0 offset, which we can
1100          * ignore. */
1101         c = message_get_container(m);
1102
1103         if (!c->need_offsets)
1104                 return 0;
1105
1106         if (!GREEDY_REALLOC(c->offsets, c->n_allocated, c->n_offsets + 1))
1107                 return -ENOMEM;
1108
1109         c->offsets[c->n_offsets++] = offset;
1110         return 0;
1111 }
1112
1113 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1114         struct bus_container *c;
1115
1116         assert(m);
1117
1118         if (expand <= 0)
1119                 return;
1120
1121         /* Update counters */
1122         for (c = m->containers; c < m->containers + m->n_containers; c++) {
1123
1124                 if (c->array_size)
1125                         *c->array_size += expand;
1126         }
1127 }
1128
1129 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
1130         struct bus_body_part *part = NULL;
1131         size_t start_body, end_body, padding, start_part, end_part, added;
1132         bool add_new_part;
1133         void *p;
1134         int r;
1135
1136         assert(m);
1137         assert(align > 0);
1138         assert(!m->sealed);
1139
1140         if (m->poisoned)
1141                 return NULL;
1142
1143         start_body = ALIGN_TO((size_t) m->header->body_size, align);
1144         end_body = start_body + sz;
1145
1146         padding = start_body - m->header->body_size;
1147         added = padding + sz;
1148
1149         /* Check for 32bit overflows */
1150         if (end_body > (size_t) ((uint32_t) -1)) {
1151                 m->poisoned = true;
1152                 return NULL;
1153         }
1154
1155         add_new_part =
1156                 m->n_body_parts <= 0 ||
1157                 m->body_end->sealed ||
1158                 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1159
1160         if (add_new_part) {
1161                 if (padding > 0) {
1162                         part = message_append_part(m);
1163                         if (!part)
1164                                 return NULL;
1165
1166                         part_zero(part, padding);
1167                 }
1168
1169                 part = message_append_part(m);
1170                 if (!part)
1171                         return NULL;
1172
1173                 r = part_make_space(m, part, sz, &p);
1174                 if (r < 0)
1175                         return NULL;
1176         } else {
1177                 struct bus_container *c;
1178                 void *op;
1179                 size_t os;
1180
1181                 part = m->body_end;
1182                 op = part->data;
1183                 os = part->size;
1184
1185                 start_part = ALIGN_TO(part->size, align);
1186                 end_part = start_part + sz;
1187
1188                 r = part_make_space(m, part, end_part, &p);
1189                 if (r < 0)
1190                         return NULL;
1191
1192                 if (padding > 0) {
1193                         memset(p, 0, padding);
1194                         p = (uint8_t*) p + padding;
1195                 }
1196
1197                 /* Readjust pointers */
1198                 for (c = m->containers; c < m->containers + m->n_containers; c++)
1199                         c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1200
1201                 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1202         }
1203
1204         m->header->body_size = end_body;
1205         message_extend_containers(m, added);
1206
1207         if (add_offset) {
1208                 r = message_add_offset(m, end_body);
1209                 if (r < 0) {
1210                         m->poisoned = true;
1211                         return NULL;
1212                 }
1213         }
1214
1215         return p;
1216 }
1217
1218 static int message_push_fd(sd_bus_message *m, int fd) {
1219         int *f, copy;
1220
1221         assert(m);
1222
1223         if (fd < 0)
1224                 return -EINVAL;
1225
1226         if (!m->allow_fds)
1227                 return -ENOTSUP;
1228
1229         copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
1230         if (copy < 0)
1231                 return -errno;
1232
1233         f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1234         if (!f) {
1235                 m->poisoned = true;
1236                 close_nointr_nofail(copy);
1237                 return -ENOMEM;
1238         }
1239
1240         m->fds = f;
1241         m->fds[m->n_fds] = copy;
1242         m->free_fds = true;
1243
1244         return copy;
1245 }
1246
1247 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1248         _cleanup_close_ int fd = -1;
1249         struct bus_container *c;
1250         ssize_t align, sz;
1251         void *a;
1252
1253         assert_return(m, -EINVAL);
1254         assert_return(!m->sealed, -EPERM);
1255         assert_return(bus_type_is_basic(type), -EINVAL);
1256         assert_return(!m->poisoned, -ESTALE);
1257
1258         c = message_get_container(m);
1259
1260         if (c->signature && c->signature[c->index]) {
1261                 /* Container signature is already set */
1262
1263                 if (c->signature[c->index] != type)
1264                         return -ENXIO;
1265         } else {
1266                 char *e;
1267
1268                 /* Maybe we can append to the signature? But only if this is the top-level container*/
1269                 if (c->enclosing != 0)
1270                         return -ENXIO;
1271
1272                 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1273                 if (!e) {
1274                         m->poisoned = true;
1275                         return -ENOMEM;
1276                 }
1277         }
1278
1279         if (m->is_gvariant) {
1280                 uint8_t u8;
1281                 uint32_t u32;
1282
1283                 switch (type) {
1284
1285                 case SD_BUS_TYPE_SIGNATURE:
1286                 case SD_BUS_TYPE_STRING:
1287                         p = strempty(p);
1288
1289                         /* Fall through... */
1290                 case SD_BUS_TYPE_OBJECT_PATH:
1291                         if (!p)
1292                                 return -EINVAL;
1293
1294                         align = 1;
1295                         sz = strlen(p) + 1;
1296                         break;
1297
1298                 case SD_BUS_TYPE_BOOLEAN:
1299
1300                         u8 = p && *(int*) p;
1301                         p = &u8;
1302
1303                         align = sz = 1;
1304                         break;
1305
1306                 case SD_BUS_TYPE_UNIX_FD:
1307
1308                         if (!p)
1309                                 return -EINVAL;
1310
1311                         fd = message_push_fd(m, *(int*) p);
1312                         if (fd < 0)
1313                                 return fd;
1314
1315                         u32 = m->n_fds;
1316                         p = &u32;
1317
1318                         align = sz = 4;
1319                         break;
1320
1321                 default:
1322                         align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
1323                         sz = bus_gvariant_get_size(type);
1324                         break;
1325                 }
1326
1327                 assert(align > 0);
1328                 assert(sz > 0);
1329
1330                 a = message_extend_body(m, align, sz, true);
1331                 if (!a)
1332                         return -ENOMEM;
1333
1334                 memcpy(a, p, sz);
1335
1336                 if (stored)
1337                         *stored = (const uint8_t*) a;
1338
1339         } else {
1340                 uint32_t u32;
1341
1342                 switch (type) {
1343
1344                 case SD_BUS_TYPE_STRING:
1345                         /* To make things easy we'll serialize a NULL string
1346                          * into the empty string */
1347                         p = strempty(p);
1348
1349                         /* Fall through... */
1350                 case SD_BUS_TYPE_OBJECT_PATH:
1351
1352                         if (!p)
1353                                 return -EINVAL;
1354
1355                         align = 4;
1356                         sz = 4 + strlen(p) + 1;
1357                         break;
1358
1359                 case SD_BUS_TYPE_SIGNATURE:
1360
1361                         p = strempty(p);
1362
1363                         align = 1;
1364                         sz = 1 + strlen(p) + 1;
1365                         break;
1366
1367                 case SD_BUS_TYPE_BOOLEAN:
1368
1369                         u32 = p && *(int*) p;
1370                         align = sz = 4;
1371                         break;
1372
1373                 case SD_BUS_TYPE_UNIX_FD:
1374
1375                         if (!p)
1376                                 return -EINVAL;
1377
1378                         fd = message_push_fd(m, *(int*) p);
1379                         if (fd < 0)
1380                                 return fd;
1381
1382                         u32 = m->n_fds;
1383                         p = &u32;
1384
1385                         align = sz = 4;
1386                         break;
1387
1388                 default:
1389                         align = bus_type_get_alignment(type);
1390                         sz = bus_type_get_size(type);
1391                         break;
1392                 }
1393
1394                 assert(align > 0);
1395                 assert(sz > 0);
1396
1397                 a = message_extend_body(m, align, sz, false);
1398                 if (!a)
1399                         return -ENOMEM;
1400
1401                 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1402                         *(uint32_t*) a = sz - 5;
1403                         memcpy((uint8_t*) a + 4, p, sz - 4);
1404
1405                         if (stored)
1406                                 *stored = (const uint8_t*) a + 4;
1407
1408                 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1409                         *(uint8_t*) a = sz - 1;
1410                         memcpy((uint8_t*) a + 1, p, sz - 1);
1411
1412                         if (stored)
1413                                 *stored = (const uint8_t*) a + 1;
1414                 } else {
1415                         memcpy(a, p, sz);
1416
1417                         if (stored)
1418                                 *stored = a;
1419                 }
1420         }
1421
1422         if (type == SD_BUS_TYPE_UNIX_FD)
1423                 m->n_fds ++;
1424
1425         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1426                 c->index++;
1427
1428         fd = -1;
1429         return 0;
1430 }
1431
1432 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1433         return message_append_basic(m, type, p, NULL);
1434 }
1435
1436 _public_ int sd_bus_message_append_string_space(
1437                 sd_bus_message *m,
1438                 size_t size,
1439                 char **s) {
1440
1441         struct bus_container *c;
1442         void *a;
1443
1444         assert_return(m, -EINVAL);
1445         assert_return(s, -EINVAL);
1446         assert_return(!m->sealed, -EPERM);
1447         assert_return(!m->poisoned, -ESTALE);
1448
1449         c = message_get_container(m);
1450
1451         if (c->signature && c->signature[c->index]) {
1452                 /* Container signature is already set */
1453
1454                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1455                         return -ENXIO;
1456         } else {
1457                 char *e;
1458
1459                 /* Maybe we can append to the signature? But only if this is the top-level container*/
1460                 if (c->enclosing != 0)
1461                         return -ENXIO;
1462
1463                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1464                 if (!e) {
1465                         m->poisoned = true;
1466                         return -ENOMEM;
1467                 }
1468         }
1469
1470         if (m->is_gvariant) {
1471                 a = message_extend_body(m, 1, size + 1, true);
1472                 if (!a)
1473                         return -ENOMEM;
1474
1475                 *s = a;
1476         } else {
1477                 a = message_extend_body(m, 4, 4 + size + 1, false);
1478                 if (!a)
1479                         return -ENOMEM;
1480
1481                 *(uint32_t*) a = size;
1482                 *s = (char*) a + 4;
1483         }
1484
1485         (*s)[size] = 0;
1486
1487         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1488                 c->index++;
1489
1490         return 0;
1491 }
1492
1493 _public_ int sd_bus_message_append_string_iovec(
1494                 sd_bus_message *m,
1495                 const struct iovec *iov,
1496                 unsigned n) {
1497
1498         size_t size;
1499         unsigned i;
1500         char *p;
1501         int r;
1502
1503         assert_return(m, -EINVAL);
1504         assert_return(!m->sealed, -EPERM);
1505         assert_return(iov || n == 0, -EINVAL);
1506         assert_return(!m->poisoned, -ESTALE);
1507
1508         size = IOVEC_TOTAL_SIZE(iov, n);
1509
1510         r = sd_bus_message_append_string_space(m, size, &p);
1511         if (r < 0)
1512                 return r;
1513
1514         for (i = 0; i < n; i++) {
1515
1516                 if (iov[i].iov_base)
1517                         memcpy(p, iov[i].iov_base, iov[i].iov_len);
1518                 else
1519                         memset(p, ' ', iov[i].iov_len);
1520
1521                 p += iov[i].iov_len;
1522         }
1523
1524         return 0;
1525 }
1526
1527 static int bus_message_open_array(
1528                 sd_bus_message *m,
1529                 struct bus_container *c,
1530                 const char *contents,
1531                 uint32_t **array_size,
1532                 size_t *begin,
1533                 bool *need_offsets) {
1534
1535         unsigned nindex;
1536         int alignment, r;
1537
1538         assert(m);
1539         assert(c);
1540         assert(contents);
1541         assert(array_size);
1542         assert(begin);
1543         assert(need_offsets);
1544
1545         if (!signature_is_single(contents, true))
1546                 return -EINVAL;
1547
1548         if (c->signature && c->signature[c->index]) {
1549
1550                 /* Verify the existing signature */
1551
1552                 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1553                         return -ENXIO;
1554
1555                 if (!startswith(c->signature + c->index + 1, contents))
1556                         return -ENXIO;
1557
1558                 nindex = c->index + 1 + strlen(contents);
1559         } else {
1560                 char *e;
1561
1562                 if (c->enclosing != 0)
1563                         return -ENXIO;
1564
1565                 /* Extend the existing signature */
1566
1567                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1568                 if (!e) {
1569                         m->poisoned = true;
1570                         return -ENOMEM;
1571                 }
1572
1573                 nindex = e - c->signature;
1574         }
1575
1576         if (m->is_gvariant) {
1577                 alignment = bus_gvariant_get_alignment(contents);
1578                 if (alignment < 0)
1579                         return alignment;
1580
1581                 /* Add alignment padding and add to offset list */
1582                 if (!message_extend_body(m, alignment, 0, false))
1583                         return -ENOMEM;
1584
1585                 r = bus_gvariant_is_fixed_size(contents);
1586                 if (r < 0)
1587                         return r;
1588
1589                 *begin = m->header->body_size;
1590                 *need_offsets = r == 0;
1591         } else {
1592                 void *a, *op;
1593                 size_t os;
1594                 struct bus_body_part *o;
1595
1596                 alignment = bus_type_get_alignment(contents[0]);
1597                 if (alignment < 0)
1598                         return alignment;
1599
1600                 a = message_extend_body(m, 4, 4, false);
1601                 if (!a)
1602                         return -ENOMEM;
1603
1604                 o = m->body_end;
1605                 op = m->body_end->data;
1606                 os = m->body_end->size;
1607
1608                 /* Add alignment between size and first element */
1609                 if (!message_extend_body(m, alignment, 0, false))
1610                         return -ENOMEM;
1611
1612                 /* location of array size might have changed so let's readjust a */
1613                 if (o == m->body_end)
1614                         a = adjust_pointer(a, op, os, m->body_end->data);
1615
1616                 *(uint32_t*) a = 0;
1617                 *array_size = a;
1618         }
1619
1620         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1621                 c->index = nindex;
1622
1623         return 0;
1624 }
1625
1626 static int bus_message_open_variant(
1627                 sd_bus_message *m,
1628                 struct bus_container *c,
1629                 const char *contents) {
1630
1631         assert(m);
1632         assert(c);
1633         assert(contents);
1634
1635         if (!signature_is_single(contents, false))
1636                 return -EINVAL;
1637
1638         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1639                 return -EINVAL;
1640
1641         if (c->signature && c->signature[c->index]) {
1642
1643                 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1644                         return -ENXIO;
1645
1646         } else {
1647                 char *e;
1648
1649                 if (c->enclosing != 0)
1650                         return -ENXIO;
1651
1652                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1653                 if (!e) {
1654                         m->poisoned = true;
1655                         return -ENOMEM;
1656                 }
1657         }
1658
1659         if (m->is_gvariant) {
1660                 /* Variants are always aligned to 8 */
1661
1662                 if (!message_extend_body(m, 8, 0, false))
1663                         return -ENOMEM;
1664
1665         } else {
1666                 size_t l;
1667                 void *a;
1668
1669                 l = strlen(contents);
1670                 a = message_extend_body(m, 1, 1 + l + 1, false);
1671                 if (!a)
1672                         return -ENOMEM;
1673
1674                 *(uint8_t*) a = l;
1675                 memcpy((uint8_t*) a + 1, contents, l + 1);
1676         }
1677
1678         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1679                 c->index++;
1680
1681         return 0;
1682 }
1683
1684 static int bus_message_open_struct(
1685                 sd_bus_message *m,
1686                 struct bus_container *c,
1687                 const char *contents,
1688                 size_t *begin,
1689                 bool *need_offsets) {
1690
1691         size_t nindex;
1692         int r;
1693
1694         assert(m);
1695         assert(c);
1696         assert(contents);
1697         assert(begin);
1698         assert(need_offsets);
1699
1700         if (!signature_is_valid(contents, false))
1701                 return -EINVAL;
1702
1703         if (c->signature && c->signature[c->index]) {
1704                 size_t l;
1705
1706                 l = strlen(contents);
1707
1708                 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1709                     !startswith(c->signature + c->index + 1, contents) ||
1710                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1711                         return -ENXIO;
1712
1713                 nindex = c->index + 1 + l + 1;
1714         } else {
1715                 char *e;
1716
1717                 if (c->enclosing != 0)
1718                         return -ENXIO;
1719
1720                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1721                 if (!e) {
1722                         m->poisoned = true;
1723                         return -ENOMEM;
1724                 }
1725
1726                 nindex = e - c->signature;
1727         }
1728
1729         if (m->is_gvariant) {
1730                 int alignment;
1731
1732                 alignment = bus_gvariant_get_alignment(contents);
1733                 if (alignment < 0)
1734                         return alignment;
1735
1736                 if (!message_extend_body(m, alignment, 0, false))
1737                         return -ENOMEM;
1738
1739                 r = bus_gvariant_is_fixed_size(contents);
1740                 if (r < 0)
1741                         return r;
1742
1743                 *begin = m->header->body_size;
1744                 *need_offsets = r == 0;
1745         } else {
1746                 /* Align contents to 8 byte boundary */
1747                 if (!message_extend_body(m, 8, 0, false))
1748                         return -ENOMEM;
1749         }
1750
1751         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1752                 c->index = nindex;
1753
1754         return 0;
1755 }
1756
1757 static int bus_message_open_dict_entry(
1758                 sd_bus_message *m,
1759                 struct bus_container *c,
1760                 const char *contents,
1761                 size_t *begin,
1762                 bool *need_offsets) {
1763
1764         int r;
1765
1766         assert(m);
1767         assert(c);
1768         assert(contents);
1769         assert(begin);
1770         assert(need_offsets);
1771
1772         if (!signature_is_pair(contents))
1773                 return -EINVAL;
1774
1775         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1776                 return -ENXIO;
1777
1778         if (c->signature && c->signature[c->index]) {
1779                 size_t l;
1780
1781                 l = strlen(contents);
1782
1783                 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1784                     !startswith(c->signature + c->index + 1, contents) ||
1785                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1786                         return -ENXIO;
1787         } else
1788                 return -ENXIO;
1789
1790         if (m->is_gvariant) {
1791                 int alignment;
1792
1793                 alignment = bus_gvariant_get_alignment(contents);
1794                 if (alignment < 0)
1795                         return alignment;
1796
1797                 if (!message_extend_body(m, alignment, 0, false))
1798                         return -ENOMEM;
1799
1800                 r = bus_gvariant_is_fixed_size(contents);
1801                 if (r < 0)
1802                         return r;
1803
1804                 *begin = m->header->body_size;
1805                 *need_offsets = r == 0;
1806         } else {
1807                 /* Align contents to 8 byte boundary */
1808                 if (!message_extend_body(m, 8, 0, false))
1809                         return -ENOMEM;
1810         }
1811
1812         return 0;
1813 }
1814
1815 _public_ int sd_bus_message_open_container(
1816                 sd_bus_message *m,
1817                 char type,
1818                 const char *contents) {
1819
1820         struct bus_container *c, *w;
1821         uint32_t *array_size = NULL;
1822         char *signature;
1823         size_t before, begin;
1824         bool need_offsets = false;
1825         int r;
1826
1827         assert_return(m, -EINVAL);
1828         assert_return(!m->sealed, -EPERM);
1829         assert_return(contents, -EINVAL);
1830         assert_return(!m->poisoned, -ESTALE);
1831
1832         /* Make sure we have space for one more container */
1833         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1834         if (!w) {
1835                 m->poisoned = true;
1836                 return -ENOMEM;
1837         }
1838
1839         m->containers = w;
1840
1841         c = message_get_container(m);
1842
1843         signature = strdup(contents);
1844         if (!signature) {
1845                 m->poisoned = true;
1846                 return -ENOMEM;
1847         }
1848
1849         /* Save old index in the parent container, in case we have to
1850          * abort this container */
1851         c->saved_index = c->index;
1852         before = m->header->body_size;
1853
1854         if (type == SD_BUS_TYPE_ARRAY)
1855                 r = bus_message_open_array(m, c, contents, &array_size, &begin, &need_offsets);
1856         else if (type == SD_BUS_TYPE_VARIANT)
1857                 r = bus_message_open_variant(m, c, contents);
1858         else if (type == SD_BUS_TYPE_STRUCT)
1859                 r = bus_message_open_struct(m, c, contents, &begin, &need_offsets);
1860         else if (type == SD_BUS_TYPE_DICT_ENTRY)
1861                 r = bus_message_open_dict_entry(m, c, contents, &begin, &need_offsets);
1862         else
1863                 r = -EINVAL;
1864
1865         if (r < 0) {
1866                 free(signature);
1867                 return r;
1868         }
1869
1870         /* OK, let's fill it in */
1871         w += m->n_containers++;
1872         w->enclosing = type;
1873         w->signature = signature;
1874         w->index = 0;
1875         w->array_size = array_size;
1876         w->before = before;
1877         w->begin = begin;
1878         w->n_offsets = w->n_allocated = 0;
1879         w->offsets = NULL;
1880         w->need_offsets = need_offsets;
1881
1882         return 0;
1883 }
1884
1885 static int bus_message_close_array(sd_bus_message *m, struct bus_container *c) {
1886
1887         assert(m);
1888         assert(c);
1889
1890         if (!m->is_gvariant)
1891                 return 0;
1892
1893         if (c->need_offsets) {
1894                 uint8_t *a;
1895                 unsigned i;
1896                 size_t sz;
1897
1898                 /* Variable-width arrays */
1899
1900                 sz = c->n_offsets > 0 ? c->offsets[c->n_offsets-1] - c->begin : 0;
1901                 if (sz + c->n_offsets <= 0xFF) {
1902                         a = message_extend_body(m, 1, c->n_offsets, true);
1903                         if (!a)
1904                                 return -ENOMEM;
1905
1906                         for (i = 0; i < c->n_offsets; i++)
1907                                 a[i] = (uint8_t) (c->offsets[i] - c->begin);
1908
1909                 } else if (sz + c->n_offsets*2 <= 0xFFFF) {
1910                         a = message_extend_body(m, 1, c->n_offsets * 2, true);
1911                         if (!a)
1912                                 return -ENOMEM;
1913
1914                         for (i = 0; i < c->n_offsets; i++) {
1915                                 uint16_t x = (uint16_t) (c->offsets[i] - c->begin);
1916                                 memcpy(a + (i*2), &x, 2);
1917                         }
1918
1919                 } else if (sz + c->n_offsets*4 <= 0xFFFFFFFF) {
1920                         a = message_extend_body(m, 1, c->n_offsets * 4, true);
1921                         if (!a)
1922                                 return -ENOMEM;
1923
1924                         for (i = 0; i < c->n_offsets; i++) {
1925                                 uint32_t x = (uint32_t) (c->offsets[i] - c->begin);
1926                                 memcpy(a + (i*4), &x, 4);
1927                         }
1928                 } else {
1929                         a = message_extend_body(m, 1, c->n_offsets * 8, true);
1930                         if (!a)
1931                                 return -ENOMEM;
1932
1933                         for (i = 0; i < c->n_offsets; i++) {
1934                                 uint64_t x = (uint64_t) (c->offsets[i] - c->begin);
1935                                 memcpy(a + (i*8), &x, 8);
1936                         }
1937                 }
1938
1939         } else {
1940                 void *a;
1941
1942                 /* Fixed-width or empty arrays */
1943
1944                 a = message_extend_body(m, 1, 0, true); /* let's add offset to parent */
1945                 if (!a)
1946                         return -ENOMEM;
1947         }
1948
1949         return 0;
1950 }
1951
1952 static int bus_message_close_variant(sd_bus_message *m, struct bus_container *c) {
1953         uint8_t *a;
1954         size_t l;
1955
1956         assert(m);
1957         assert(c);
1958
1959         if (!m->is_gvariant)
1960                 return 0;
1961
1962         l = strlen(c->signature);
1963
1964         a = message_extend_body(m, 1, 1 + l, true);
1965         if (!a)
1966                 return -ENOMEM;
1967
1968         a[0] = 0;
1969         memcpy(a+1, c->signature, l);
1970
1971         return 0;
1972 }
1973
1974 static int bus_message_close_struct(sd_bus_message *m, struct bus_container *c, bool add_offset) {
1975         size_t n_variable = 0;
1976         unsigned i = 0;
1977         const char *p;
1978         uint8_t *a;
1979         int r;
1980
1981         assert(m);
1982         assert(c);
1983
1984         if (!m->is_gvariant)
1985                 return 0;
1986
1987         p = c->signature;
1988         while (*p != 0) {
1989                 size_t n;
1990
1991                 r = signature_element_length(p, &n);
1992                 if (r < 0)
1993                         return r;
1994                 else {
1995                         char t[n+1];
1996
1997                         memcpy(t, p, n);
1998                         t[n] = 0;
1999
2000                         r = bus_gvariant_is_fixed_size(t);
2001                         if (r < 0)
2002                                 return r;
2003                 }
2004
2005                 assert(i <= c->n_offsets);
2006
2007                 /* We need to add an offset for each item that has a
2008                  * variable size and that is not the last one in the
2009                  * list */
2010                 if (r == 0 && p[n] != 0)
2011                         n_variable++;
2012                 else
2013                         c->offsets[i] = (size_t) -1;
2014
2015                 i++;
2016                 p += n;
2017         }
2018
2019         if (n_variable <= 0) {
2020                 a = message_extend_body(m, 1, 0, true);
2021                 if (!a)
2022                         return -ENOMEM;
2023         } else {
2024                 size_t sz, z;
2025                 unsigned j;
2026
2027                 assert(c->offsets[c->n_offsets-1] == m->header->body_size ||
2028                        c->offsets[c->n_offsets-1] == (size_t) -1);
2029
2030                 sz = m->header->body_size - c->begin;
2031                 if (sz + n_variable <= 0xFF)
2032                         z = 1;
2033                 else if (sz + (n_variable)*2 <= 0xFFFF)
2034                         z = 2;
2035                 else if (sz + (n_variable)*4 <= 0xFFFFFFFF)
2036                         z = 4;
2037                 else
2038                         z = 8;
2039
2040                 a = message_extend_body(m, 1, z * n_variable, add_offset);
2041                 if (!a)
2042                         return -ENOMEM;
2043
2044                 for (i = 0, j = 0; i < c->n_offsets; i++) {
2045                         size_t v;
2046                         unsigned k;
2047
2048                         if (c->offsets[i] == (size_t) -1)
2049                                 continue;
2050
2051                         v = c->offsets[i] - c->begin;
2052                         k = n_variable - 1 - j;
2053
2054                         if (z == 1)
2055                                 ((uint8_t*) a)[k] = (uint8_t) v;
2056                         else if (z == 2) {
2057                                 uint16_t x = (uint16_t) v;
2058                                 memcpy(a + k * 2, &x, 2);
2059                         } else if (z == 4) {
2060                                 uint32_t x = (uint32_t) v;
2061                                 memcpy(a + k * 4, &x, 4);
2062                         } else if (z == 8) {
2063                                 uint64_t x = (uint64_t) v;
2064                                 memcpy(a + k * 8, &x, 8);
2065                         } else
2066                                 assert_not_reached("Wrong offset width");
2067
2068                         j++;
2069                 }
2070         }
2071
2072         return 0;
2073 }
2074
2075 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
2076         struct bus_container *c;
2077         int r;
2078
2079         assert_return(m, -EINVAL);
2080         assert_return(!m->sealed, -EPERM);
2081         assert_return(m->n_containers > 0, -EINVAL);
2082         assert_return(!m->poisoned, -ESTALE);
2083
2084         c = message_get_container(m);
2085
2086         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2087                 if (c->signature && c->signature[c->index] != 0)
2088                         return -EINVAL;
2089
2090         m->n_containers--;
2091
2092         if (c->enclosing == SD_BUS_TYPE_ARRAY)
2093                 r = bus_message_close_array(m, c);
2094         else if (c->enclosing == SD_BUS_TYPE_VARIANT)
2095                 r = bus_message_close_variant(m, c);
2096         else if (c->enclosing == SD_BUS_TYPE_STRUCT || c->enclosing == SD_BUS_TYPE_DICT_ENTRY)
2097                 r = bus_message_close_struct(m, c, true);
2098         else
2099                 assert_not_reached("Unknown container type");
2100
2101         free(c->signature);
2102         return r;
2103 }
2104
2105 typedef struct {
2106         const char *types;
2107         unsigned n_struct;
2108         unsigned n_array;
2109 } TypeStack;
2110
2111 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
2112         assert(stack);
2113         assert(max > 0);
2114
2115         if (*i >= max)
2116                 return -EINVAL;
2117
2118         stack[*i].types = types;
2119         stack[*i].n_struct = n_struct;
2120         stack[*i].n_array = n_array;
2121         (*i)++;
2122
2123         return 0;
2124 }
2125
2126 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
2127         assert(stack);
2128         assert(max > 0);
2129         assert(types);
2130         assert(n_struct);
2131         assert(n_array);
2132
2133         if (*i <= 0)
2134                 return 0;
2135
2136         (*i)--;
2137         *types = stack[*i].types;
2138         *n_struct = stack[*i].n_struct;
2139         *n_array = stack[*i].n_array;
2140
2141         return 1;
2142 }
2143
2144 int bus_message_append_ap(
2145                 sd_bus_message *m,
2146                 const char *types,
2147                 va_list ap) {
2148
2149         unsigned n_array, n_struct;
2150         TypeStack stack[BUS_CONTAINER_DEPTH];
2151         unsigned stack_ptr = 0;
2152         int r;
2153
2154         assert(m);
2155
2156         if (!types)
2157                 return 0;
2158
2159         n_array = (unsigned) -1;
2160         n_struct = strlen(types);
2161
2162         for (;;) {
2163                 const char *t;
2164
2165                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2166                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2167                         if (r < 0)
2168                                 return r;
2169                         if (r == 0)
2170                                 break;
2171
2172                         r = sd_bus_message_close_container(m);
2173                         if (r < 0)
2174                                 return r;
2175
2176                         continue;
2177                 }
2178
2179                 t = types;
2180                 if (n_array != (unsigned) -1)
2181                         n_array --;
2182                 else {
2183                         types ++;
2184                         n_struct--;
2185                 }
2186
2187                 switch (*t) {
2188
2189                 case SD_BUS_TYPE_BYTE: {
2190                         uint8_t x;
2191
2192                         x = (uint8_t) va_arg(ap, int);
2193                         r = sd_bus_message_append_basic(m, *t, &x);
2194                         break;
2195                 }
2196
2197                 case SD_BUS_TYPE_BOOLEAN:
2198                 case SD_BUS_TYPE_INT32:
2199                 case SD_BUS_TYPE_UINT32:
2200                 case SD_BUS_TYPE_UNIX_FD: {
2201                         uint32_t x;
2202
2203                         /* We assume a boolean is the same as int32_t */
2204                         assert_cc(sizeof(int32_t) == sizeof(int));
2205
2206                         x = va_arg(ap, uint32_t);
2207                         r = sd_bus_message_append_basic(m, *t, &x);
2208                         break;
2209                 }
2210
2211                 case SD_BUS_TYPE_INT16:
2212                 case SD_BUS_TYPE_UINT16: {
2213                         uint16_t x;
2214
2215                         x = (uint16_t) va_arg(ap, int);
2216                         r = sd_bus_message_append_basic(m, *t, &x);
2217                         break;
2218                 }
2219
2220                 case SD_BUS_TYPE_INT64:
2221                 case SD_BUS_TYPE_UINT64:
2222                 case SD_BUS_TYPE_DOUBLE: {
2223                         uint64_t x;
2224
2225                         x = va_arg(ap, uint64_t);
2226                         r = sd_bus_message_append_basic(m, *t, &x);
2227                         break;
2228                 }
2229
2230                 case SD_BUS_TYPE_STRING:
2231                 case SD_BUS_TYPE_OBJECT_PATH:
2232                 case SD_BUS_TYPE_SIGNATURE: {
2233                         const char *x;
2234
2235                         x = va_arg(ap, const char*);
2236                         r = sd_bus_message_append_basic(m, *t, x);
2237                         break;
2238                 }
2239
2240                 case SD_BUS_TYPE_ARRAY: {
2241                         size_t k;
2242
2243                         r = signature_element_length(t + 1, &k);
2244                         if (r < 0)
2245                                 return r;
2246
2247                         {
2248                                 char s[k + 1];
2249                                 memcpy(s, t + 1, k);
2250                                 s[k] = 0;
2251
2252                                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2253                                 if (r < 0)
2254                                         return r;
2255                         }
2256
2257                         if (n_array == (unsigned) -1) {
2258                                 types += k;
2259                                 n_struct -= k;
2260                         }
2261
2262                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2263                         if (r < 0)
2264                                 return r;
2265
2266                         types = t + 1;
2267                         n_struct = k;
2268                         n_array = va_arg(ap, unsigned);
2269
2270                         break;
2271                 }
2272
2273                 case SD_BUS_TYPE_VARIANT: {
2274                         const char *s;
2275
2276                         s = va_arg(ap, const char*);
2277                         if (!s)
2278                                 return -EINVAL;
2279
2280                         r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2281                         if (r < 0)
2282                                 return r;
2283
2284                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2285                         if (r < 0)
2286                                 return r;
2287
2288                         types = s;
2289                         n_struct = strlen(s);
2290                         n_array = (unsigned) -1;
2291
2292                         break;
2293                 }
2294
2295                 case SD_BUS_TYPE_STRUCT_BEGIN:
2296                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2297                         size_t k;
2298
2299                         r = signature_element_length(t, &k);
2300                         if (r < 0)
2301                                 return r;
2302
2303                         {
2304                                 char s[k - 1];
2305
2306                                 memcpy(s, t + 1, k - 2);
2307                                 s[k - 2] = 0;
2308
2309                                 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2310                                 if (r < 0)
2311                                         return r;
2312                         }
2313
2314                         if (n_array == (unsigned) -1) {
2315                                 types += k - 1;
2316                                 n_struct -= k - 1;
2317                         }
2318
2319                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2320                         if (r < 0)
2321                                 return r;
2322
2323                         types = t + 1;
2324                         n_struct = k - 2;
2325                         n_array = (unsigned) -1;
2326
2327                         break;
2328                 }
2329
2330                 default:
2331                         r = -EINVAL;
2332                 }
2333
2334                 if (r < 0)
2335                         return r;
2336         }
2337
2338         return 1;
2339 }
2340
2341 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2342         va_list ap;
2343         int r;
2344
2345         assert_return(m, -EINVAL);
2346         assert_return(types, -EINVAL);
2347         assert_return(!m->sealed, -EPERM);
2348         assert_return(!m->poisoned, -ESTALE);
2349
2350         va_start(ap, types);
2351         r = bus_message_append_ap(m, types, ap);
2352         va_end(ap);
2353
2354         return r;
2355 }
2356
2357 _public_ int sd_bus_message_append_array_space(
2358                 sd_bus_message *m,
2359                 char type,
2360                 size_t size,
2361                 void **ptr) {
2362
2363         ssize_t align, sz;
2364         void *a;
2365         int r;
2366
2367         assert_return(m, -EINVAL);
2368         assert_return(!m->sealed, -EPERM);
2369         assert_return(bus_type_is_trivial(type), -EINVAL);
2370         assert_return(ptr || size == 0, -EINVAL);
2371         assert_return(!m->poisoned, -ESTALE);
2372
2373         align = bus_type_get_alignment(type);
2374         sz = bus_type_get_size(type);
2375
2376         assert_se(align > 0);
2377         assert_se(sz > 0);
2378
2379         if (size % sz != 0)
2380                 return -EINVAL;
2381
2382         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2383         if (r < 0)
2384                 return r;
2385
2386         a = message_extend_body(m, align, size, false);
2387         if (!a)
2388                 return -ENOMEM;
2389
2390         r = sd_bus_message_close_container(m);
2391         if (r < 0)
2392                 return r;
2393
2394         *ptr = a;
2395         return 0;
2396 }
2397
2398 _public_ int sd_bus_message_append_array(sd_bus_message *m,
2399                                          char type,
2400                                          const void *ptr,
2401                                          size_t size) {
2402         int r;
2403         void *p;
2404
2405         assert_return(m, -EINVAL);
2406         assert_return(!m->sealed, -EPERM);
2407         assert_return(bus_type_is_trivial(type), -EINVAL);
2408         assert_return(ptr || size == 0, -EINVAL);
2409         assert_return(!m->poisoned, -ESTALE);
2410
2411         r = sd_bus_message_append_array_space(m, type, size, &p);
2412         if (r < 0)
2413                 return r;
2414
2415         if (size > 0)
2416                 memcpy(p, ptr, size);
2417
2418         return 0;
2419 }
2420
2421 _public_ int sd_bus_message_append_array_iovec(
2422                 sd_bus_message *m,
2423                 char type,
2424                 const struct iovec *iov,
2425                 unsigned n) {
2426
2427         size_t size;
2428         unsigned i;
2429         void *p;
2430         int r;
2431
2432         assert_return(m, -EINVAL);
2433         assert_return(!m->sealed, -EPERM);
2434         assert_return(bus_type_is_trivial(type), -EINVAL);
2435         assert_return(iov || n == 0, -EINVAL);
2436         assert_return(!m->poisoned, -ESTALE);
2437
2438         size = IOVEC_TOTAL_SIZE(iov, n);
2439
2440         r = sd_bus_message_append_array_space(m, type, size, &p);
2441         if (r < 0)
2442                 return r;
2443
2444         for (i = 0; i < n; i++) {
2445
2446                 if (iov[i].iov_base)
2447                         memcpy(p, iov[i].iov_base, iov[i].iov_len);
2448                 else
2449                         memset(p, 0, iov[i].iov_len);
2450
2451                 p = (uint8_t*) p + iov[i].iov_len;
2452         }
2453
2454         return 0;
2455 }
2456
2457 _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
2458                                                char type,
2459                                                sd_memfd *memfd) {
2460         _cleanup_close_ int copy_fd = -1;
2461         struct bus_body_part *part;
2462         ssize_t align, sz;
2463         uint64_t size;
2464         void *a;
2465         int r;
2466
2467         if (!m)
2468                 return -EINVAL;
2469         if (!memfd)
2470                 return -EINVAL;
2471         if (m->sealed)
2472                 return -EPERM;
2473         if (!bus_type_is_trivial(type))
2474                 return -EINVAL;
2475         if (m->poisoned)
2476                 return -ESTALE;
2477
2478         r = sd_memfd_set_sealed(memfd, true);
2479         if (r < 0)
2480                 return r;
2481
2482         copy_fd = sd_memfd_dup_fd(memfd);
2483         if (copy_fd < 0)
2484                 return copy_fd;
2485
2486         r = sd_memfd_get_size(memfd, &size);
2487         if (r < 0)
2488                 return r;
2489
2490         align = bus_type_get_alignment(type);
2491         sz = bus_type_get_size(type);
2492
2493         assert_se(align > 0);
2494         assert_se(sz > 0);
2495
2496         if (size % sz != 0)
2497                 return -EINVAL;
2498
2499         if (size > (uint64_t) (uint32_t) -1)
2500                 return -EINVAL;
2501
2502         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2503         if (r < 0)
2504                 return r;
2505
2506         a = message_extend_body(m, align, 0, false);
2507         if (!a)
2508                 return -ENOMEM;
2509
2510         part = message_append_part(m);
2511         if (!part)
2512                 return -ENOMEM;
2513
2514         part->memfd = copy_fd;
2515         part->sealed = true;
2516         part->size = size;
2517         copy_fd = -1;
2518
2519         message_extend_containers(m, size);
2520         m->header->body_size += size;
2521
2522         return sd_bus_message_close_container(m);
2523 }
2524
2525 _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2526         _cleanup_close_ int copy_fd = -1;
2527         struct bus_body_part *part;
2528         struct bus_container *c;
2529         uint64_t size;
2530         void *a;
2531         int r;
2532
2533         assert_return(m, -EINVAL);
2534         assert_return(memfd, -EINVAL);
2535         assert_return(!m->sealed, -EPERM);
2536         assert_return(!m->poisoned, -ESTALE);
2537
2538         r = sd_memfd_set_sealed(memfd, true);
2539         if (r < 0)
2540                 return r;
2541
2542         copy_fd = sd_memfd_dup_fd(memfd);
2543         if (copy_fd < 0)
2544                 return copy_fd;
2545
2546         r = sd_memfd_get_size(memfd, &size);
2547         if (r < 0)
2548                 return r;
2549
2550         /* We require this to be NUL terminated */
2551         if (size == 0)
2552                 return -EINVAL;
2553
2554         if (size > (uint64_t) (uint32_t) -1)
2555                 return -EINVAL;
2556
2557         c = message_get_container(m);
2558         if (c->signature && c->signature[c->index]) {
2559                 /* Container signature is already set */
2560
2561                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2562                         return -ENXIO;
2563         } else {
2564                 char *e;
2565
2566                 /* Maybe we can append to the signature? But only if this is the top-level container*/
2567                 if (c->enclosing != 0)
2568                         return -ENXIO;
2569
2570                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2571                 if (!e) {
2572                         m->poisoned = true;
2573                         return -ENOMEM;
2574                 }
2575         }
2576
2577         if (!m->is_gvariant) {
2578                 a = message_extend_body(m, 4, 4, false);
2579                 if (!a)
2580                         return -ENOMEM;
2581
2582                 *(uint32_t*) a = size - 1;
2583         }
2584
2585         part = message_append_part(m);
2586         if (!part)
2587                 return -ENOMEM;
2588
2589         part->memfd = copy_fd;
2590         part->sealed = true;
2591         part->size = size;
2592         copy_fd = -1;
2593
2594         m->header->body_size += size;
2595         message_extend_containers(m, size);
2596
2597         if (m->is_gvariant) {
2598                 r = message_add_offset(m, m->header->body_size);
2599                 if (r < 0) {
2600                         m->poisoned = true;
2601                         return -ENOMEM;
2602                 }
2603         }
2604
2605         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2606                 c->index++;
2607
2608         return 0;
2609 }
2610
2611 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2612         char **i;
2613         int r;
2614
2615         assert_return(m, -EINVAL);
2616         assert_return(!m->sealed, -EPERM);
2617         assert_return(!m->poisoned, -ESTALE);
2618
2619         r = sd_bus_message_open_container(m, 'a', "s");
2620         if (r < 0)
2621                 return r;
2622
2623         STRV_FOREACH(i, l) {
2624                 r = sd_bus_message_append_basic(m, 's', *i);
2625                 if (r < 0)
2626                         return r;
2627         }
2628
2629         return sd_bus_message_close_container(m);
2630 }
2631
2632 int bus_body_part_map(struct bus_body_part *part) {
2633         void *p;
2634         size_t psz;
2635
2636         assert_se(part);
2637
2638         if (part->data)
2639                 return 0;
2640
2641         if (part->size <= 0)
2642                 return 0;
2643
2644         /* For smaller zero parts (as used for padding) we don't need to map anything... */
2645         if (part->memfd < 0 && part->is_zero && part->size < 8) {
2646                 static const uint8_t zeroes[7] = { };
2647                 part->data = (void*) zeroes;
2648                 return 0;
2649         }
2650
2651         psz = PAGE_ALIGN(part->size);
2652
2653         if (part->memfd >= 0)
2654                 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2655         else if (part->is_zero)
2656                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2657         else
2658                 return -EINVAL;
2659
2660         if (p == MAP_FAILED)
2661                 return -errno;
2662
2663         part->mapped = psz;
2664         part->data = p;
2665         part->munmap_this = true;
2666
2667         return 0;
2668 }
2669
2670 void bus_body_part_unmap(struct bus_body_part *part) {
2671
2672         assert_se(part);
2673
2674         if (part->memfd < 0)
2675                 return;
2676
2677         if (!part->data)
2678                 return;
2679
2680         if (!part->munmap_this)
2681                 return;
2682
2683         assert_se(munmap(part->data, part->mapped) == 0);
2684
2685         part->data = NULL;
2686         part->mapped = 0;
2687         part->munmap_this = false;
2688
2689         return;
2690 }
2691
2692 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2693         size_t k, start, end;
2694
2695         assert(rindex);
2696         assert(align > 0);
2697
2698         start = ALIGN_TO((size_t) *rindex, align);
2699         end = start + nbytes;
2700
2701         if (end > sz)
2702                 return -EBADMSG;
2703
2704         /* Verify that padding is 0 */
2705         for (k = *rindex; k < start; k++)
2706                 if (((const uint8_t*) p)[k] != 0)
2707                         return -EBADMSG;
2708
2709         if (r)
2710                 *r = (uint8_t*) p + start;
2711
2712         *rindex = end;
2713
2714         return 1;
2715 }
2716
2717 static bool message_end_of_signature(sd_bus_message *m) {
2718         struct bus_container *c;
2719
2720         assert(m);
2721
2722         c = message_get_container(m);
2723         return !c->signature || c->signature[c->index] == 0;
2724 }
2725
2726 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2727         struct bus_container *c;
2728
2729         assert(m);
2730
2731         c = message_get_container(m);
2732         if (!c->array_size)
2733                 return false;
2734
2735         return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2736 }
2737
2738 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2739         assert_return(m, -EINVAL);
2740         assert_return(m->sealed, -EPERM);
2741
2742         if (complete && m->n_containers > 0)
2743                 return false;
2744
2745         if (message_end_of_signature(m))
2746                 return true;
2747
2748         if (message_end_of_array(m, m->rindex))
2749                 return true;
2750
2751         return false;
2752 }
2753
2754 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2755         struct bus_body_part *part;
2756         size_t begin;
2757         int r;
2758
2759         assert(m);
2760
2761         if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2762                 part = m->cached_rindex_part;
2763                 begin = m->cached_rindex_part_begin;
2764         } else {
2765                 part = &m->body;
2766                 begin = 0;
2767         }
2768
2769         while (part) {
2770                 if (index < begin)
2771                         return NULL;
2772
2773                 if (index + sz <= begin + part->size) {
2774
2775                         r = bus_body_part_map(part);
2776                         if (r < 0)
2777                                 return NULL;
2778
2779                         if (p)
2780                                 *p = (uint8_t*) part->data + index - begin;
2781
2782                         m->cached_rindex_part = part;
2783                         m->cached_rindex_part_begin = begin;
2784
2785                         return part;
2786                 }
2787
2788                 begin += part->size;
2789                 part = part->next;
2790         }
2791
2792         return NULL;
2793 }
2794
2795 static int message_peek_body(
2796                 sd_bus_message *m,
2797                 size_t *rindex,
2798                 size_t align,
2799                 size_t nbytes,
2800                 void **ret) {
2801
2802         size_t k, start, end, padding;
2803         struct bus_body_part *part;
2804         uint8_t *q;
2805
2806         assert(m);
2807         assert(rindex);
2808         assert(align > 0);
2809
2810         if (message_end_of_array(m, *rindex))
2811                 return 0;
2812
2813         start = ALIGN_TO((size_t) *rindex, align);
2814         padding = start - *rindex;
2815         end = start + nbytes;
2816
2817         if (end > BUS_MESSAGE_BODY_SIZE(m))
2818                 return -EBADMSG;
2819
2820         part = find_part(m, *rindex, padding, (void**) &q);
2821         if (!part)
2822                 return -EBADMSG;
2823
2824         if (q) {
2825                 /* Verify padding */
2826                 for (k = 0; k < padding; k++)
2827                         if (q[k] != 0)
2828                                 return -EBADMSG;
2829         }
2830
2831         part = find_part(m, start, nbytes, (void**) &q);
2832         if (!part || !q)
2833                 return -EBADMSG;
2834
2835         *rindex = end;
2836
2837         if (ret)
2838                 *ret = q;
2839
2840         return 1;
2841 }
2842
2843 static bool validate_nul(const char *s, size_t l) {
2844
2845         /* Check for NUL chars in the string */
2846         if (memchr(s, 0, l))
2847                 return false;
2848
2849         /* Check for NUL termination */
2850         if (s[l] != 0)
2851                 return false;
2852
2853         return true;
2854 }
2855
2856 static bool validate_string(const char *s, size_t l) {
2857
2858         if (!validate_nul(s, l))
2859                 return false;
2860
2861         /* Check if valid UTF8 */
2862         if (!utf8_is_valid(s))
2863                 return false;
2864
2865         return true;
2866 }
2867
2868 static bool validate_signature(const char *s, size_t l) {
2869
2870         if (!validate_nul(s, l))
2871                 return false;
2872
2873         /* Check if valid signature */
2874         if (!signature_is_valid(s, true))
2875                 return false;
2876
2877         return true;
2878 }
2879
2880 static bool validate_object_path(const char *s, size_t l) {
2881
2882         if (!validate_nul(s, l))
2883                 return false;
2884
2885         if (!object_path_is_valid(s))
2886                 return false;
2887
2888         return true;
2889 }
2890
2891 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2892         struct bus_container *c;
2893         void *q;
2894         int r;
2895
2896         assert_return(m, -EINVAL);
2897         assert_return(m->sealed, -EPERM);
2898         assert_return(bus_type_is_basic(type), -EINVAL);
2899
2900         if (message_end_of_signature(m))
2901                 return -ENXIO;
2902
2903         if (message_end_of_array(m, m->rindex))
2904                 return 0;
2905
2906         c = message_get_container(m);
2907         if (c->signature[c->index] != type)
2908                 return -ENXIO;
2909
2910         switch (type) {
2911
2912         case SD_BUS_TYPE_STRING:
2913         case SD_BUS_TYPE_OBJECT_PATH: {
2914                 uint32_t l;
2915                 size_t rindex;
2916
2917                 rindex = m->rindex;
2918                 r = message_peek_body(m, &rindex, 4, 4, &q);
2919                 if (r <= 0)
2920                         return r;
2921
2922                 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2923                 r = message_peek_body(m, &rindex, 1, l+1, &q);
2924                 if (r < 0)
2925                         return r;
2926                 if (r == 0)
2927                         return -EBADMSG;
2928
2929                 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2930                         if (!validate_object_path(q, l))
2931                                 return -EBADMSG;
2932                 } else {
2933                         if (!validate_string(q, l))
2934                                 return -EBADMSG;
2935                 }
2936
2937                 m->rindex = rindex;
2938                 if (p)
2939                         *(const char**) p = q;
2940
2941                 break;
2942         }
2943
2944         case SD_BUS_TYPE_SIGNATURE: {
2945                 uint8_t l;
2946                 size_t rindex;
2947
2948                 rindex = m->rindex;
2949                 r = message_peek_body(m, &rindex, 1, 1, &q);
2950                 if (r <= 0)
2951                         return r;
2952
2953                 l = *(uint8_t*) q;
2954                 r = message_peek_body(m, &rindex, 1, l+1, &q);
2955                 if (r < 0)
2956                         return r;
2957                 if (r == 0)
2958                         return -EBADMSG;
2959
2960                 if (!validate_signature(q, l))
2961                         return -EBADMSG;
2962
2963                 m->rindex = rindex;
2964
2965                 if (p)
2966                         *(const char**) p = q;
2967                 break;
2968         }
2969
2970         default: {
2971                 ssize_t sz, align;
2972                 size_t rindex;
2973
2974                 align = bus_type_get_alignment(type);
2975                 sz = bus_type_get_size(type);
2976                 assert(align > 0 && sz > 0);
2977
2978                 rindex = m->rindex;
2979                 r = message_peek_body(m, &rindex, align, sz, &q);
2980                 if (r <= 0)
2981                         return r;
2982
2983                 switch (type) {
2984
2985                 case SD_BUS_TYPE_BYTE:
2986                         if (p)
2987                                 *(uint8_t*) p = *(uint8_t*) q;
2988                         break;
2989
2990                 case SD_BUS_TYPE_BOOLEAN:
2991                         if (p)
2992                                 *(int*) p = !!*(uint32_t*) q;
2993                         break;
2994
2995                 case SD_BUS_TYPE_INT16:
2996                 case SD_BUS_TYPE_UINT16:
2997                         if (p)
2998                                 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2999                         break;
3000
3001                 case SD_BUS_TYPE_INT32:
3002                 case SD_BUS_TYPE_UINT32:
3003                         if (p)
3004                                 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3005                         break;
3006
3007                 case SD_BUS_TYPE_INT64:
3008                 case SD_BUS_TYPE_UINT64:
3009                 case SD_BUS_TYPE_DOUBLE:
3010                         if (p)
3011                                 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3012                         break;
3013
3014                 case SD_BUS_TYPE_UNIX_FD: {
3015                         uint32_t j;
3016
3017                         j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3018                         if (j >= m->n_fds)
3019                                 return -EBADMSG;
3020
3021                         if (p)
3022                                 *(int*) p = m->fds[j];
3023                         break;
3024                 }
3025
3026                 default:
3027                         assert_not_reached("Unknown basic type...");
3028                 }
3029
3030                 m->rindex = rindex;
3031
3032                 break;
3033         }
3034         }
3035
3036         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3037                 c->index++;
3038
3039         return 1;
3040 }
3041
3042 static int bus_message_enter_array(
3043                 sd_bus_message *m,
3044                 struct bus_container *c,
3045                 const char *contents,
3046                 uint32_t **array_size) {
3047
3048         size_t rindex;
3049         void *q;
3050         int r, alignment;
3051
3052         assert(m);
3053         assert(c);
3054         assert(contents);
3055         assert(array_size);
3056
3057         if (!signature_is_single(contents, true))
3058                 return -EINVAL;
3059
3060         alignment = bus_type_get_alignment(contents[0]);
3061         if (alignment < 0)
3062                 return alignment;
3063
3064         if (!c->signature || c->signature[c->index] == 0)
3065                 return 0;
3066
3067         if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
3068                 return -ENXIO;
3069
3070         if (!startswith(c->signature + c->index + 1, contents))
3071                 return -ENXIO;
3072
3073         rindex = m->rindex;
3074         r = message_peek_body(m, &rindex, 4, 4, &q);
3075         if (r <= 0)
3076                 return r;
3077
3078         if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
3079                 return -EBADMSG;
3080
3081         r = message_peek_body(m, &rindex, alignment, 0, NULL);
3082         if (r < 0)
3083                 return r;
3084         if (r == 0)
3085                 return -EBADMSG;
3086
3087         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3088                 c->index += 1 + strlen(contents);
3089
3090         m->rindex = rindex;
3091
3092         *array_size = (uint32_t*) q;
3093
3094         return 1;
3095 }
3096
3097 static int bus_message_enter_variant(
3098                 sd_bus_message *m,
3099                 struct bus_container *c,
3100                 const char *contents) {
3101
3102         size_t rindex;
3103         uint8_t l;
3104         void *q;
3105         int r;
3106
3107         assert(m);
3108         assert(c);
3109         assert(contents);
3110
3111         if (!signature_is_single(contents, false))
3112                 return -EINVAL;
3113
3114         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
3115                 return -EINVAL;
3116
3117         if (!c->signature || c->signature[c->index] == 0)
3118                 return 0;
3119
3120         if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
3121                 return -ENXIO;
3122
3123         rindex = m->rindex;
3124         r = message_peek_body(m, &rindex, 1, 1, &q);
3125         if (r <= 0)
3126                 return r;
3127
3128         l = *(uint8_t*) q;
3129         r = message_peek_body(m, &rindex, 1, l+1, &q);
3130         if (r < 0)
3131                 return r;
3132         if (r == 0)
3133                 return -EBADMSG;
3134
3135         if (!validate_signature(q, l))
3136                 return -EBADMSG;
3137
3138         if (!streq(q, contents))
3139                 return -ENXIO;
3140
3141         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3142                 c->index++;
3143
3144         m->rindex = rindex;
3145
3146         return 1;
3147 }
3148
3149 static int bus_message_enter_struct(
3150                 sd_bus_message *m,
3151                 struct bus_container *c,
3152                 const char *contents) {
3153
3154         size_t l;
3155         int r;
3156
3157         assert(m);
3158         assert(c);
3159         assert(contents);
3160
3161         if (!signature_is_valid(contents, false))
3162                 return -EINVAL;
3163
3164         if (!c->signature || c->signature[c->index] == 0)
3165                 return 0;
3166
3167         l = strlen(contents);
3168
3169         if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
3170             !startswith(c->signature + c->index + 1, contents) ||
3171             c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
3172                 return -ENXIO;
3173
3174         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
3175         if (r <= 0)
3176                 return r;
3177
3178         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3179                 c->index += 1 + l + 1;
3180
3181         return 1;
3182 }
3183
3184 static int bus_message_enter_dict_entry(
3185                 sd_bus_message *m,
3186                 struct bus_container *c,
3187                 const char *contents) {
3188
3189         size_t l;
3190         int r;
3191
3192         assert(m);
3193         assert(c);
3194         assert(contents);
3195
3196         if (!signature_is_pair(contents))
3197                 return -EINVAL;
3198
3199         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3200                 return -ENXIO;
3201
3202         if (!c->signature || c->signature[c->index] == 0)
3203                 return 0;
3204
3205         l = strlen(contents);
3206
3207         if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
3208             !startswith(c->signature + c->index + 1, contents) ||
3209             c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
3210                 return -ENXIO;
3211
3212         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
3213         if (r <= 0)
3214                 return r;
3215
3216         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3217                 c->index += 1 + l + 1;
3218
3219         return 1;
3220 }
3221
3222 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
3223                                             char type,
3224                                             const char *contents) {
3225         struct bus_container *c, *w;
3226         uint32_t *array_size = NULL;
3227         char *signature;
3228         size_t before;
3229         int r;
3230
3231         assert_return(m, -EINVAL);
3232         assert_return(m->sealed, -EPERM);
3233         assert_return(type != 0 || !contents, -EINVAL);
3234
3235         if (type == 0 || !contents) {
3236                 const char *cc;
3237                 char tt;
3238
3239                 /* Allow entering into anonymous containers */
3240                 r = sd_bus_message_peek_type(m, &tt, &cc);
3241