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