chiark / gitweb /
core: epoll and signalfd has been moved into sd event loop
[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) {
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
2746         /* Add padding at the end of the fields part, since we know
2747          * the body needs to start at an 8 byte alignment. We made
2748          * sure we allocated enough space for this, so all we need to
2749          * do here is to zero it out. */
2750         l = BUS_MESSAGE_FIELDS_SIZE(m);
2751         a = ALIGN8(l) - l;
2752         if (a > 0)
2753                 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
2754
2755         /* If this is something we can send as memfd, then let's seal
2756         the memfd now. Note that we can send memfds as payload only
2757         for directed messages, and not for broadcasts. */
2758         if (m->destination && m->bus && m->bus->use_memfd) {
2759                 MESSAGE_FOREACH_PART(part, i, m)
2760                         if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
2761                                 bus_body_part_unmap(part);
2762
2763                                 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
2764                                         part->sealed = true;
2765                         }
2766         }
2767
2768         m->root_container.end = BUS_MESSAGE_BODY_SIZE(m);
2769         m->root_container.index = 0;
2770         m->root_container.offset_index = 0;
2771         m->root_container.item_size = m->root_container.n_offsets > 0 ? m->root_container.offsets[0] : 0;
2772
2773         m->sealed = true;
2774
2775         return 0;
2776 }
2777
2778 int bus_body_part_map(struct bus_body_part *part) {
2779         void *p;
2780         size_t psz;
2781
2782         assert_se(part);
2783
2784         if (part->data)
2785                 return 0;
2786
2787         if (part->size <= 0)
2788                 return 0;
2789
2790         /* For smaller zero parts (as used for padding) we don't need to map anything... */
2791         if (part->memfd < 0 && part->is_zero && part->size < 8) {
2792                 static const uint8_t zeroes[7] = { };
2793                 part->data = (void*) zeroes;
2794                 return 0;
2795         }
2796
2797         psz = PAGE_ALIGN(part->size);
2798
2799         if (part->memfd >= 0)
2800                 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2801         else if (part->is_zero)
2802                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2803         else
2804                 return -EINVAL;
2805
2806         if (p == MAP_FAILED)
2807                 return -errno;
2808
2809         part->mapped = psz;
2810         part->data = p;
2811         part->munmap_this = true;
2812
2813         return 0;
2814 }
2815
2816 void bus_body_part_unmap(struct bus_body_part *part) {
2817
2818         assert_se(part);
2819
2820         if (part->memfd < 0)
2821                 return;
2822
2823         if (!part->data)
2824                 return;
2825
2826         if (!part->munmap_this)
2827                 return;
2828
2829         assert_se(munmap(part->data, part->mapped) == 0);
2830
2831         part->data = NULL;
2832         part->mapped = 0;
2833         part->munmap_this = false;
2834
2835         return;
2836 }
2837
2838 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2839         size_t k, start, end;
2840
2841         assert(rindex);
2842         assert(align > 0);
2843
2844         start = ALIGN_TO((size_t) *rindex, align);
2845         end = start + nbytes;
2846
2847         if (end > sz)
2848                 return -EBADMSG;
2849
2850         /* Verify that padding is 0 */
2851         for (k = *rindex; k < start; k++)
2852                 if (((const uint8_t*) p)[k] != 0)
2853                         return -EBADMSG;
2854
2855         if (r)
2856                 *r = (uint8_t*) p + start;
2857
2858         *rindex = end;
2859
2860         return 1;
2861 }
2862
2863 static bool message_end_of_signature(sd_bus_message *m) {
2864         struct bus_container *c;
2865
2866         assert(m);
2867
2868         c = message_get_container(m);
2869         return !c->signature || c->signature[c->index] == 0;
2870 }
2871
2872 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2873         struct bus_container *c;
2874
2875         assert(m);
2876
2877         c = message_get_container(m);
2878         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2879                 return false;
2880
2881         if (BUS_MESSAGE_IS_GVARIANT(m))
2882                 return index >= c->end;
2883         else {
2884                 assert(c->array_size);
2885                 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2886         }
2887 }
2888
2889 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2890         assert_return(m, -EINVAL);
2891         assert_return(m->sealed, -EPERM);
2892
2893         if (complete && m->n_containers > 0)
2894                 return false;
2895
2896         if (message_end_of_signature(m))
2897                 return true;
2898
2899         if (message_end_of_array(m, m->rindex))
2900                 return true;
2901
2902         return false;
2903 }
2904
2905 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2906         struct bus_body_part *part;
2907         size_t begin;
2908         int r;
2909
2910         assert(m);
2911
2912         if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2913                 part = m->cached_rindex_part;
2914                 begin = m->cached_rindex_part_begin;
2915         } else {
2916                 part = &m->body;
2917                 begin = 0;
2918         }
2919
2920         while (part) {
2921                 if (index < begin)
2922                         return NULL;
2923
2924                 if (index + sz <= begin + part->size) {
2925
2926                         r = bus_body_part_map(part);
2927                         if (r < 0)
2928                                 return NULL;
2929
2930                         if (p)
2931                                 *p = (uint8_t*) part->data + index - begin;
2932
2933                         m->cached_rindex_part = part;
2934                         m->cached_rindex_part_begin = begin;
2935
2936                         return part;
2937                 }
2938
2939                 begin += part->size;
2940                 part = part->next;
2941         }
2942
2943         return NULL;
2944 }
2945
2946 static int container_next_item(sd_bus_message *m, struct bus_container *c, size_t *rindex) {
2947         int r;
2948
2949         assert(m);
2950         assert(c);
2951         assert(rindex);
2952
2953         if (!BUS_MESSAGE_IS_GVARIANT(m))
2954                 return 0;
2955
2956         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2957                 int sz;
2958
2959                 sz = bus_gvariant_get_size(c->signature);
2960                 if (sz < 0) {
2961                         int alignment;
2962
2963                         if (c->offset_index+1 >= c->n_offsets)
2964                                 goto end;
2965
2966                         /* Variable-size array */
2967
2968                         alignment = bus_gvariant_get_alignment(c->signature);
2969                         assert(alignment > 0);
2970
2971                         *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
2972                         c->item_size = c->offsets[c->offset_index+1] - *rindex;
2973                 } else {
2974
2975                         if (c->offset_index+1 >= (c->end-c->begin)/sz)
2976                                 goto end;
2977
2978                         /* Fixed-size array */
2979                         *rindex = c->begin + (c->offset_index+1) * sz;
2980                         c->item_size = sz;
2981                 }
2982
2983                 c->offset_index++;
2984
2985         } else if (c->enclosing == 0 ||
2986                    c->enclosing == SD_BUS_TYPE_STRUCT ||
2987                    c->enclosing == SD_BUS_TYPE_DICT_ENTRY) {
2988
2989                 int alignment;
2990                 size_t n, j;
2991
2992                 if (c->offset_index+1 >= c->n_offsets)
2993                         goto end;
2994
2995                 r = signature_element_length(c->signature + c->index, &n);
2996                 if (r < 0)
2997                         return r;
2998
2999                 r = signature_element_length(c->signature + c->index + n, &j);
3000                 if (r < 0)
3001                         return r;
3002                 else {
3003                         char t[j+1];
3004                         memcpy(t, c->signature + c->index + n, j);
3005                         t[j] = 0;
3006
3007                         alignment = bus_gvariant_get_alignment(t);
3008                 }
3009
3010                 assert(alignment > 0);
3011
3012                 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3013                 c->item_size = c->offsets[c->offset_index+1] - *rindex;
3014
3015                 c->offset_index++;
3016
3017         } else if (c->enclosing == SD_BUS_TYPE_VARIANT)
3018                 goto end;
3019         else
3020                 assert_not_reached("Unknown container type");
3021
3022         return 0;
3023
3024 end:
3025         /* Reached the end */
3026         *rindex = c->end;
3027         c->item_size = 0;
3028         return 0;
3029 }
3030
3031
3032 static int message_peek_body(
3033                 sd_bus_message *m,
3034                 size_t *rindex,
3035                 size_t align,
3036                 size_t nbytes,
3037                 void **ret) {
3038
3039         size_t k, start, end, padding;
3040         struct bus_body_part *part;
3041         uint8_t *q;
3042
3043         assert(m);
3044         assert(rindex);
3045         assert(align > 0);
3046
3047         start = ALIGN_TO((size_t) *rindex, align);
3048         padding = start - *rindex;
3049         end = start + nbytes;
3050
3051         if (end > BUS_MESSAGE_BODY_SIZE(m))
3052                 return -EBADMSG;
3053
3054         part = find_part(m, *rindex, padding, (void**) &q);
3055         if (!part)
3056                 return -EBADMSG;
3057
3058         if (q) {
3059                 /* Verify padding */
3060                 for (k = 0; k < padding; k++)
3061                         if (q[k] != 0)
3062                                 return -EBADMSG;
3063         }
3064
3065         part = find_part(m, start, nbytes, (void**) &q);
3066         if (!part || (nbytes > 0 && !q))
3067                 return -EBADMSG;
3068
3069         *rindex = end;
3070
3071         if (ret)
3072                 *ret = q;
3073
3074         return 0;
3075 }
3076
3077 static bool validate_nul(const char *s, size_t l) {
3078
3079         /* Check for NUL chars in the string */
3080         if (memchr(s, 0, l))
3081                 return false;
3082
3083         /* Check for NUL termination */
3084         if (s[l] != 0)
3085                 return false;
3086
3087         return true;
3088 }
3089
3090 static bool validate_string(const char *s, size_t l) {
3091
3092         if (!validate_nul(s, l))
3093                 return false;
3094
3095         /* Check if valid UTF8 */
3096         if (!utf8_is_valid(s))
3097                 return false;
3098
3099         return true;
3100 }
3101
3102 static bool validate_signature(const char *s, size_t l) {
3103
3104         if (!validate_nul(s, l))
3105                 return false;
3106
3107         /* Check if valid signature */
3108         if (!signature_is_valid(s, true))
3109                 return false;
3110
3111         return true;
3112 }
3113
3114 static bool validate_object_path(const char *s, size_t l) {
3115
3116         if (!validate_nul(s, l))
3117                 return false;
3118
3119         if (!object_path_is_valid(s))
3120                 return false;
3121
3122         return true;
3123 }
3124
3125 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
3126         struct bus_container *c;
3127         size_t rindex;
3128         void *q;
3129         int r;
3130
3131         assert_return(m, -EINVAL);
3132         assert_return(m->sealed, -EPERM);
3133         assert_return(bus_type_is_basic(type), -EINVAL);
3134
3135         if (message_end_of_signature(m))
3136                 return -ENXIO;
3137
3138         if (message_end_of_array(m, m->rindex))
3139                 return 0;
3140
3141         c = message_get_container(m);
3142         if (c->signature[c->index] != type)
3143                 return -ENXIO;
3144
3145         rindex = m->rindex;
3146
3147         if (BUS_MESSAGE_IS_GVARIANT(m)) {
3148
3149                 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
3150                         bool ok;
3151
3152                         r = message_peek_body(m, &rindex, 1, c->item_size, &q);
3153                         if (r < 0)
3154                                 return r;
3155
3156                         if (type == SD_BUS_TYPE_STRING)
3157                                 ok = validate_string(q, c->item_size-1);
3158                         else if (type == SD_BUS_TYPE_OBJECT_PATH)
3159                                 ok = validate_object_path(q, c->item_size-1);
3160                         else
3161                                 ok = validate_signature(q, c->item_size-1);
3162
3163                         if (!ok)
3164                                 return -EBADMSG;
3165
3166                         if (p)
3167                                 *(const char**) p = q;
3168                 } else {
3169                         int sz, align;
3170
3171                         sz = bus_gvariant_get_size(CHAR_TO_STR(type));
3172                         assert(sz > 0);
3173                         if ((size_t) sz != c->item_size)
3174                                 return -EBADMSG;
3175
3176                         align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
3177                         assert(align > 0);
3178
3179                         r = message_peek_body(m, &rindex, align, c->item_size, &q);
3180                         if (r < 0)
3181                                 return r;
3182
3183                         switch (type) {
3184
3185                         case SD_BUS_TYPE_BYTE:
3186                                 if (p)
3187                                         *(uint8_t*) p = *(uint8_t*) q;
3188                                 break;
3189
3190                         case SD_BUS_TYPE_BOOLEAN:
3191                                 if (p)
3192                                         *(int*) p = !!*(uint8_t*) q;
3193                                 break;
3194
3195                         case SD_BUS_TYPE_INT16:
3196                         case SD_BUS_TYPE_UINT16:
3197                                 if (p)
3198                                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3199                                 break;
3200
3201                         case SD_BUS_TYPE_INT32:
3202                         case SD_BUS_TYPE_UINT32:
3203                                 if (p)
3204                                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3205                                 break;
3206
3207                         case SD_BUS_TYPE_INT64:
3208                         case SD_BUS_TYPE_UINT64:
3209                         case SD_BUS_TYPE_DOUBLE:
3210                                 if (p)
3211                                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3212                                 break;
3213
3214                         case SD_BUS_TYPE_UNIX_FD: {
3215                                 uint32_t j;
3216
3217                                 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3218                                 if (j >= m->n_fds)
3219                                         return -EBADMSG;
3220
3221                                 if (p)
3222                                         *(int*) p = m->fds[j];
3223
3224                                 break;
3225                         }
3226
3227                         default:
3228                                 assert_not_reached("unexpected type");
3229                         }
3230                 }
3231
3232                 r = container_next_item(m, c, &rindex);
3233                 if (r < 0)
3234                         return r;
3235         } else {
3236
3237                 rindex = m->rindex;
3238
3239                 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH)) {
3240                         uint32_t l;
3241                         bool ok;
3242
3243                         r = message_peek_body(m, &rindex, 4, 4, &q);
3244                         if (r < 0)
3245                                 return r;
3246
3247                         l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3248                         r = message_peek_body(m, &rindex, 1, l+1, &q);
3249                         if (r < 0)
3250                                 return r;
3251
3252                         if (type == SD_BUS_TYPE_OBJECT_PATH)
3253                                 ok = validate_object_path(q, l);
3254                         else
3255                                 ok = validate_string(q, l);
3256                         if (!ok)
3257                                 return -EBADMSG;
3258
3259                         if (p)
3260                                 *(const char**) p = q;
3261
3262                 } else if (type == SD_BUS_TYPE_SIGNATURE) {
3263                         uint8_t l;
3264
3265                         r = message_peek_body(m, &rindex, 1, 1, &q);
3266                         if (r < 0)
3267                                 return r;
3268
3269                         l = *(uint8_t*) q;
3270                         r = message_peek_body(m, &rindex, 1, l+1, &q);
3271                         if (r < 0)
3272                                 return r;
3273
3274                         if (!validate_signature(q, l))
3275                                 return -EBADMSG;
3276
3277                         if (p)
3278                                 *(const char**) p = q;
3279
3280                 } else {
3281                         ssize_t sz, align;
3282
3283                         align = bus_type_get_alignment(type);
3284                         assert(align > 0);
3285
3286                         sz = bus_type_get_size(type);
3287                         assert(sz > 0);
3288
3289                         r = message_peek_body(m, &rindex, align, sz, &q);
3290                         if (r < 0)
3291                                 return r;
3292
3293                         switch (type) {
3294
3295                         case SD_BUS_TYPE_BYTE:
3296                                 if (p)
3297                                         *(uint8_t*) p = *(uint8_t*) q;
3298                                 break;
3299
3300                         case SD_BUS_TYPE_BOOLEAN:
3301                                 if (p)
3302                                         *(int*) p = !!*(uint32_t*) q;
3303                                 break;
3304
3305                         case SD_BUS_TYPE_INT16:
3306                         case SD_BUS_TYPE_UINT16:
3307                                 if (p)
3308                                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3309                                 break;
3310
3311                         case SD_BUS_TYPE_INT32:
3312                         case SD_BUS_TYPE_UINT32:
3313                                 if (p)
3314                                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3315                                 break;
3316
3317                         case SD_BUS_TYPE_INT64:
3318                         case SD_BUS_TYPE_UINT64:
3319                         case SD_BUS_TYPE_DOUBLE:
3320                                 if (p)
3321                                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3322                                 break;
3323
3324                         case SD_BUS_TYPE_UNIX_FD: {
3325                                 uint32_t j;
3326
3327                                 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3328                                 if (j >= m->n_fds)
3329                                         return -EBADMSG;
3330
3331                                 if (p)
3332                                         *(int*) p = m->fds[j];
3333                                 break;
3334                         }
3335
3336                         default:
3337                                 assert_not_reached("Unknown basic type...");
3338                         }
3339                 }
3340         }
3341
3342         m->rindex = rindex;
3343
3344         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3345                 c->index++;
3346
3347         return 1;
3348 }
3349
3350 static int bus_message_enter_array(
3351                 sd_bus_message *m,
3352                 struct bus_container *c,
3353                 const char *contents,
3354                 uint32_t **array_size,
3355                 size_t *item_size,
3356                 size_t **offsets,
3357                 size_t *n_offsets) {
3358
3359         size_t rindex;
3360         void *q;
3361         int r, alignment;
3362
3363         assert(m);
3364         assert(c);
3365         assert(contents);
3366         assert(array_size);
3367         assert(item_size);
3368         assert(offsets);
3369         assert(n_offsets);
3370
3371         if (!signature_is_single(contents, true))
3372                 return -EINVAL;
3373
3374         if (!c->signature || c->signature[c->index] == 0)
3375                 return -ENXIO;
3376
3377         if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
3378                 return -ENXIO;
3379
3380         if (!startswith(c->signature + c->index + 1, contents))
3381                 return -ENXIO;
3382
3383         rindex = m->rindex;
3384
3385         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3386                 /* dbus1 */
3387
3388                 r = message_peek_body(m, &rindex, 4, 4, &q);
3389                 if (r < 0)
3390                         return r;
3391
3392                 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
3393                         return -EBADMSG;
3394
3395                 alignment = bus_type_get_alignment(contents[0]);
3396                 if (alignment < 0)
3397                         return alignment;
3398
3399                 r = message_peek_body(m, &rindex, alignment, 0, NULL);
3400                 if (r < 0)
3401                         return r;
3402
3403                 *array_size = (uint32_t*) q;
3404
3405         } else if (c->item_size <= 0) {
3406
3407                 /* gvariant: empty array */
3408                 *item_size = 0;
3409                 *offsets = NULL;
3410                 *n_offsets = 0;
3411
3412         } else if (bus_gvariant_is_fixed_size(contents)) {
3413
3414                 /* gvariant: fixed length array */
3415                 *item_size = bus_gvariant_get_size(contents);
3416                 *offsets = NULL;
3417                 *n_offsets = 0;
3418
3419         } else {
3420                 size_t where, p = 0, framing, sz;
3421                 unsigned i;
3422
3423                 /* gvariant: variable length array */
3424                 sz = determine_word_size(c->item_size, 0);
3425
3426                 where = rindex + c->item_size - sz;
3427                 r = message_peek_body(m, &where, 1, sz, &q);
3428                 if (r < 0)
3429                         return r;
3430
3431                 framing = read_word_le(q, sz);
3432                 if (framing > c->item_size - sz)
3433                         return -EBADMSG;
3434                 if ((c->item_size - framing) % sz != 0)
3435                         return -EBADMSG;
3436
3437                 *n_offsets = (c->item_size - framing) / sz;
3438
3439                 where = rindex + framing;
3440                 r = message_peek_body(m, &where, 1, *n_offsets * sz, &q);
3441                 if (r < 0)
3442                         return r;
3443
3444                 *offsets = new(size_t, *n_offsets);
3445                 if (!*offsets)
3446                         return -ENOMEM;
3447
3448                 for (i = 0; i < *n_offsets; i++) {
3449                         size_t x;
3450
3451                         x = read_word_le((uint8_t*) q + i * sz, sz);
3452                         if (x > c->item_size - sz)
3453                                 return -EBADMSG;
3454                         if (x < p)
3455                                 return -EBADMSG;
3456
3457                         (*offsets)[i] = rindex + x;
3458                         p = x;
3459                 }
3460
3461                 *item_size = (*offsets)[0] - rindex;
3462         }
3463
3464         m->rindex = rindex;
3465
3466         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3467                 c->index += 1 + strlen(contents);
3468
3469         return 1;
3470 }
3471
3472 static int bus_message_enter_variant(
3473                 sd_bus_message *m,
3474                 struct bus_container *c,
3475                 const char *contents,
3476                 size_t *item_size) {
3477
3478         size_t rindex;
3479         uint8_t l;
3480         void *q;
3481         int r;
3482
3483         assert(m);
3484         assert(c);
3485         assert(contents);
3486         assert(item_size);
3487
3488         if (!signature_is_single(contents, false))
3489                 return -EINVAL;
3490
3491         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
3492                 return -EINVAL;
3493
3494         if (!c->signature || c->signature[c->index] == 0)
3495                 return -ENXIO;
3496
3497         if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
3498                 return -ENXIO;
3499
3500         rindex = m->rindex;
3501
3502         if (BUS_MESSAGE_IS_GVARIANT(m)) {
3503                 size_t k, where;
3504
3505                 k = strlen(contents);
3506                 if (1+k > c->item_size)
3507                         return -EBADMSG;
3508
3509                 where = rindex + c->item_size - (1+k);
3510                 r = message_peek_body(m, &where, 1, 1+k, &q);
3511                 if (r < 0)
3512                         return r;
3513
3514                 if (*(char*) q != 0)
3515                         return -EBADMSG;
3516
3517                 if (memcmp((uint8_t*) q+1, contents, k))
3518                         return -ENXIO;
3519
3520                 *item_size = c->item_size - (1+k);
3521
3522         } else {
3523                 r = message_peek_body(m, &rindex, 1, 1, &q);
3524                 if (r < 0)
3525                         return r;
3526
3527                 l = *(uint8_t*) q;
3528                 r = message_peek_body(m, &rindex, 1, l+1, &q);
3529                 if (r < 0)
3530                         return r;
3531
3532                 if (!validate_signature(q, l))
3533                         return -EBADMSG;
3534
3535                 if (!streq(q, contents))
3536                         return -ENXIO;
3537         }
3538
3539         m->rindex = rindex;
3540
3541         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3542                 c->index++;
3543
3544         return 1;
3545 }
3546
3547 static int build_struct_offsets(
3548                 sd_bus_message *m,
3549                 const char *signature,
3550                 size_t size,
3551                 size_t *item_size,
3552                 size_t **offsets,
3553                 size_t *n_offsets) {
3554
3555         unsigned n_variable = 0, n_total = 0, v;
3556         size_t previous = 0, where;
3557         const char *p;
3558         size_t sz;
3559         void *q;
3560         int r;
3561
3562         assert(m);
3563         assert(item_size);
3564         assert(offsets);
3565         assert(n_offsets);
3566
3567         if (isempty(signature)) {
3568                 *item_size = 0;
3569                 *offsets = NULL;
3570                 *n_offsets = 0;
3571                 return 0;
3572         }
3573
3574         sz = determine_word_size(size, 0);
3575         if (sz <= 0)
3576                 return -EBADMSG;
3577
3578         /* First, loop over signature and count variable elements and
3579          * elements in general. We use this to know how large the
3580          * offset array is at the end of the structure. Note that
3581          * GVariant only stores offsets for all variable size elements
3582          * that are not the last item. */
3583
3584         p = signature;
3585         while (*p != 0) {
3586                 size_t n;
3587
3588                 r = signature_element_length(p, &n);
3589                 if (r < 0)
3590                         return r;
3591                 else {
3592                         char t[n+1];
3593
3594                         memcpy(t, p, n);
3595                         t[n] = 0;
3596
3597                         r = bus_gvariant_is_fixed_size(t);
3598                 }
3599
3600                 if (r < 0)
3601                         return r;
3602                 if (r == 0 && p[n] != 0) /* except the last item */
3603                         n_variable ++;
3604                 n_total++;
3605
3606                 p += n;
3607         }
3608
3609         if (size < n_variable * sz)
3610                 return -EBADMSG;
3611
3612         where = m->rindex + size - (n_variable * sz);
3613         r = message_peek_body(m, &where, 1, n_variable * sz, &q);
3614         if (r < 0)
3615                 return r;
3616
3617         v = n_variable;
3618
3619         *offsets = new(size_t, n_total);
3620         if (!*offsets)
3621                 return -ENOMEM;
3622
3623         *n_offsets = 0;
3624
3625         /* Second, loop again and build an offset table */
3626         p = signature;
3627         while (*p != 0) {
3628                 size_t n, offset;
3629                 int k;
3630
3631                 r = signature_element_length(p, &n);
3632                 if (r < 0)
3633                         return r;
3634                 else {
3635                         char t[n+1];
3636
3637                         memcpy(t, p, n);
3638                         t[n] = 0;
3639
3640                         k = bus_gvariant_get_size(t);
3641                         if (k < 0) {
3642                                 size_t x;
3643
3644                                 /* variable size */
3645                                 if (v > 0) {
3646                                         v--;
3647
3648                                         x = read_word_le((uint8_t*) q + v*sz, sz);
3649                                         if (x >= size)
3650                                                 return -EBADMSG;
3651                                         if (m->rindex + x < previous)
3652                                                 return -EBADMSG;
3653                                 } else
3654                                         /* The last item's end
3655                                          * is determined from
3656                                          * the start of the
3657                                          * offset array */
3658                                         x = size - (n_variable * sz);
3659
3660                                 offset = m->rindex + x;
3661
3662                         } else {
3663                                 size_t align;
3664
3665                                 /* fixed size */
3666                                 align = bus_gvariant_get_alignment(t);
3667                                 assert(align > 0);
3668
3669                                 offset = (*n_offsets == 0 ? m->rindex  : ALIGN_TO((*offsets)[*n_offsets-1], align)) + k;
3670                         }
3671                 }
3672
3673                 previous = (*offsets)[(*n_offsets)++] = offset;
3674                 p += n;
3675         }
3676
3677         assert(v == 0);
3678         assert(*n_offsets == n_total);
3679
3680         *item_size = (*offsets)[0] - m->rindex;
3681         return 0;
3682 }
3683
3684 static int enter_struct_or_dict_entry(
3685                 sd_bus_message *m,
3686                 struct bus_container *c,
3687                 const char *contents,
3688                 size_t *item_size,
3689                 size_t **offsets,
3690                 size_t *n_offsets) {
3691
3692         int r;
3693
3694         assert(m);
3695         assert(c);
3696         assert(contents);
3697         assert(item_size);
3698         assert(offsets);
3699         assert(n_offsets);
3700
3701         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3702
3703                 /* dbus1 */
3704                 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
3705                 if (r < 0)
3706                         return r;
3707
3708         } else if (c->item_size <= 0) {
3709
3710                 /* gvariant empty struct */
3711                 *item_size = 0;
3712                 *offsets = NULL;
3713                 *n_offsets = 0;
3714         } else
3715                 /* gvariant with contents */
3716                 return build_struct_offsets(m, contents, c->item_size, item_size, offsets, n_offsets);
3717
3718         return 0;
3719 }
3720
3721 static int bus_message_enter_struct(
3722                 sd_bus_message *m,
3723                 struct bus_container *c,
3724                 const char *contents,
3725                 size_t *item_size,
3726                 size_t **offsets,
3727                 size_t *n_offsets) {
3728
3729         size_t l;
3730         int r;
3731
3732         assert(m);
3733         assert(c);
3734         assert(contents);
3735         assert(item_size);
3736         assert(offsets);
3737         assert(n_offsets);
3738
3739         if (!signature_is_valid(contents, false))
3740                 return -EINVAL;
3741
3742         if (!c->signature || c->signature[c->index] == 0)
3743                 return -ENXIO;
3744
3745         l = strlen(contents);
3746
3747         if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
3748             !startswith(c->signature + c->index + 1, contents) ||
3749             c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
3750                 return -ENXIO;
3751
3752         r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
3753         if (r < 0)
3754                 return r;
3755
3756         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3757                 c->index += 1 + l + 1;
3758
3759         return 1;
3760 }
3761
3762 static int bus_message_enter_dict_entry(
3763                 sd_bus_message *m,
3764                 struct bus_container *c,
3765                 const char *contents,
3766                 size_t *item_size,
3767                 size_t **offsets,
3768                 size_t *n_offsets) {
3769
3770         size_t l;
3771         int r;
3772
3773         assert(m);
3774         assert(c);
3775         assert(contents);
3776
3777         if (!signature_is_pair(contents))
3778                 return -EINVAL;
3779
3780         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3781                 return -ENXIO;
3782
3783         if (!c->signature || c->signature[c->index] == 0)
3784                 return 0;
3785
3786         l = strlen(contents);
3787
3788         if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
3789             !startswith(c->signature + c->index + 1, contents) ||
3790             c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
3791                 return -ENXIO;
3792
3793         r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
3794         if (r < 0)
3795                 return r;
3796
3797         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3798                 c->index += 1 + l + 1;
3799
3800         return 1;
3801 }
3802
3803 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
3804                                             char type,
3805                                             const char *contents) {
3806         struct bus_container *c, *w;
3807         uint32_t *array_size = NULL;
3808         char *signature;
3809         size_t before;
3810         size_t *offsets = NULL;
3811         size_t n_offsets = 0, item_size = 0;
3812         int r;
3813
3814         assert_return(m, -EINVAL);
3815         assert_return(m->sealed, -EPERM);
3816         assert_return(type != 0 || !contents, -EINVAL);
3817
3818         if (type == 0 || !contents) {
3819                 const char *cc;
3820                 char tt;
3821
3822                 /* Allow entering into anonymous containers */
3823                 r = sd_bus_message_peek_type(m, &tt, &cc);
3824                 if (r < 0)
3825                         return r;
3826
3827                 if (type != 0 && type != tt)
3828                         return -ENXIO;
3829
3830                 if (contents && !streq(contents, cc))
3831                         return -ENXIO;
3832
3833                 type = tt;
3834                 contents = cc;
3835         }
3836
3837         /*
3838          * We enforce a global limit on container depth, that is much
3839          * higher than the 32 structs and 32 arrays the specification
3840          * mandates. This is simpler to implement for us, and we need
3841          * this only to ensure our container array doesn't grow
3842          * without bounds. We are happy to return any data from a
3843          * message as long as the data itself is valid, even if the
3844          * overall message might be not.
3845          *
3846          * Note that the message signature is validated when
3847          * parsing the headers, and that validation does check the
3848          * 32/32 limit.
3849          *
3850          * Note that the specification defines no limits on the depth
3851          * of stacked variants, but we do.
3852          */
3853         if (m->n_containers >= BUS_CONTAINER_DEPTH)
3854                 return -EBADMSG;
3855
3856         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
3857         if (!w)
3858                 return -ENOMEM;
3859         m->containers = w;
3860
3861         if (message_end_of_signature(m))
3862                 return -ENXIO;
3863
3864         if (message_end_of_array(m, m->rindex))
3865                 return 0;
3866
3867         c = message_get_container(m);
3868
3869         signature = strdup(contents);
3870         if (!signature)
3871                 return -ENOMEM;
3872
3873         c->saved_index = c->index;
3874         before = m->rindex;
3875
3876         if (type == SD_BUS_TYPE_ARRAY)
3877                 r = bus_message_enter_array(m, c, contents, &array_size, &item_size, &offsets, &n_offsets);
3878         else if (type == SD_BUS_TYPE_VARIANT)
3879                 r = bus_message_enter_variant(m, c, contents, &item_size);
3880         else if (type == SD_BUS_TYPE_STRUCT)
3881                 r = bus_message_enter_struct(m, c, contents, &item_size, &offsets, &n_offsets);
3882         else if (type == SD_BUS_TYPE_DICT_ENTRY)
3883                 r = bus_message_enter_dict_entry(m, c, contents, &item_size, &offsets, &n_offsets);
3884         else
3885                 r = -EINVAL;
3886
3887         if (r <= 0) {
3888                 free(signature);
3889                 free(offsets);
3890                 return r;
3891         }
3892
3893         /* OK, let's fill it in */
3894         w += m->n_containers++;
3895         w->enclosing = type;
3896         w->signature = signature;
3897         w->index = 0;
3898
3899         w->before = before;
3900         w->begin = m->rindex;
3901         w->end = m->rindex + c->item_size;
3902
3903         w->array_size = array_size;
3904         w->item_size = item_size;
3905         w->offsets = offsets;
3906         w->n_offsets = n_offsets;
3907         w->offset_index = 0;
3908
3909         return 1;
3910 }
3911
3912 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
3913         struct bus_container *c;
3914         unsigned saved;
3915         int r;
3916
3917         assert_return(m, -EINVAL);
3918         assert_return(m->sealed, -EPERM);
3919         assert_return(m->n_containers > 0, -ENXIO);
3920
3921         c = message_get_container(m);
3922
3923         if (c->enclosing != SD_BUS_TYPE_ARRAY) {
3924                 if (c->signature && c->signature[c->index] != 0)
3925                         return -EBUSY;
3926         }
3927
3928         if (BUS_MESSAGE_IS_GVARIANT(m)) {
3929                 if (m->rindex < c->end)
3930                         return -EBUSY;
3931
3932         } else if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3933                 uint32_t l;
3934
3935                 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3936                 if (c->begin + l != m->rindex)
3937                         return -EBUSY;
3938         }
3939
3940         free(c->signature);
3941         free(c->offsets);
3942         m->n_containers--;
3943
3944         c = message_get_container(m);
3945
3946         saved = c->index;
3947         c->index = c->saved_index;
3948         r = container_next_item(m, c, &m->rindex);
3949         c->index = saved;
3950         if (r < 0)
3951                 return r;
3952
3953         return 1;
3954 }
3955
3956 static void message_quit_container(sd_bus_message *m) {
3957         struct bus_container *c;
3958
3959         assert(m);
3960         assert(m->sealed);
3961         assert(m->n_containers > 0);
3962
3963         c = message_get_container(m);
3964
3965         /* Undo seeks */
3966         assert(m->rindex >= c->before);
3967         m->rindex = c->before;
3968
3969         /* Free container */
3970         free(c->signature);
3971         free(c->offsets);
3972         m->n_containers--;
3973
3974         /* Correct index of new top-level container */
3975         c = message_get_container(m);
3976         c->index = c->saved_index;
3977 }
3978
3979 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3980         struct bus_container *c;
3981         int r;
3982
3983         assert_return(m, -EINVAL);
3984         assert_return(m->sealed, -EPERM);
3985
3986         if (message_end_of_signature(m))
3987                 goto eof;
3988
3989         if (message_end_of_array(m, m->rindex))
3990                 goto eof;
3991
3992         c = message_get_container(m);
3993
3994         if (bus_type_is_basic(c->signature[c->index])) {
3995                 if (contents)
3996                         *contents = NULL;
3997                 if (type)
3998                         *type = c->signature[c->index];
3999                 return 1;
4000         }
4001
4002         if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
4003
4004                 if (contents) {
4005                         size_t l;
4006                         char *sig;
4007
4008                         r = signature_element_length(c->signature+c->index+1, &l);
4009                         if (r < 0)
4010                                 return r;
4011
4012                         assert(l >= 1);
4013
4014                         sig = strndup(c->signature + c->index + 1, l);
4015                         if (!sig)
4016                                 return -ENOMEM;
4017
4018                         free(m->peeked_signature);
4019                         m->peeked_signature = sig;
4020
4021                         *contents = sig;
4022                 }
4023
4024                 if (type)
4025                         *type = SD_BUS_TYPE_ARRAY;
4026
4027                 return 1;
4028         }
4029
4030         if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
4031             c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
4032
4033                 if (contents) {
4034                         size_t l;
4035                         char *sig;
4036
4037                         r = signature_element_length(c->signature+c->index, &l);
4038                         if (r < 0)
4039                                 return r;
4040
4041                         assert(l >= 2);
4042                         sig = strndup(c->signature + c->index + 1, l - 2);
4043                         if (!sig)
4044                                 return -ENOMEM;
4045
4046                         free(m->peeked_signature);
4047                         m->peeked_signature = sig;
4048
4049                         *contents = sig;
4050                 }
4051
4052                 if (type)
4053                         *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
4054
4055                 return 1;
4056         }
4057
4058         if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
4059                 if (contents) {
4060                         void *q;
4061
4062                         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4063                                 size_t k;
4064
4065                                 if (c->item_size < 2)
4066                                         return -EBADMSG;
4067
4068                                 /* Look for the NUL delimiter that
4069                                    separates the payload from the
4070                                    signature. Since the body might be
4071                                    in a different part that then the
4072                                    signature we map byte by byte. */
4073
4074                                 for (k = 2; k <= c->item_size; k++) {
4075                                         size_t where;
4076
4077                                         where = m->rindex + c->item_size - k;
4078                                         r = message_peek_body(m, &where, 1, k, &q);
4079                                         if (r < 0)
4080                                                 return r;
4081
4082                                         if (*(char*) q == 0)
4083                                                 break;
4084                                 }
4085
4086                                 if (k > c->item_size)
4087                                         return -EBADMSG;
4088
4089                                 free(m->peeked_signature);
4090                                 m->peeked_signature = strndup((char*) q + 1, k - 1);
4091                                 if (!m->peeked_signature)
4092                                         return -ENOMEM;
4093
4094                                 if (!signature_is_valid(m->peeked_signature, true))
4095                                         return -EBADMSG;
4096
4097                                 *contents = m->peeked_signature;
4098                         } else {
4099                                 size_t rindex, l;
4100
4101                                 rindex = m->rindex;
4102                                 r = message_peek_body(m, &rindex, 1, 1, &q);
4103                                 if (r < 0)
4104                                         return r;
4105
4106                                 l = *(uint8_t*) q;
4107                                 r = message_peek_body(m, &rindex, 1, l+1, &q);
4108                                 if (r < 0)
4109                                         return r;
4110
4111                                 if (!validate_signature(q, l))
4112                                         return -EBADMSG;
4113
4114                                 *contents = q;
4115                         }
4116                 }
4117
4118                 if (type)
4119                         *type = SD_BUS_TYPE_VARIANT;
4120
4121                 return 1;
4122         }
4123
4124         return -EINVAL;
4125
4126 eof:
4127         if (type)
4128                 *type = 0;
4129         if (contents)
4130                 *contents = NULL;
4131         return 0;
4132 }
4133
4134 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
4135         struct bus_container *c;
4136
4137         assert_return(m, -EINVAL);
4138         assert_return(m->sealed, -EPERM);
4139
4140         if (complete) {
4141                 message_reset_containers(m);
4142                 m->rindex = 0;
4143
4144                 c = message_get_container(m);
4145         } else {
4146                 c = message_get_container(m);
4147
4148                 c->offset_index = 0;
4149                 c->index = 0;
4150                 m->rindex = c->begin;
4151         }
4152
4153         c->offset_index = 0;
4154         c->item_size = c->n_offsets > 0 ? c->offsets[0] : c->end;
4155
4156         return !isempty(c->signature);
4157 }
4158
4159 static int message_read_ap(
4160                 sd_bus_message *m,
4161                 const char *types,
4162                 va_list ap) {
4163
4164         unsigned n_array, n_struct;
4165         TypeStack stack[BUS_CONTAINER_DEPTH];
4166         unsigned stack_ptr = 0;
4167         unsigned n_loop = 0;
4168         int r;
4169
4170         assert(m);
4171
4172         if (isempty(types))
4173                 return 0;
4174
4175         /* Ideally, we'd just call ourselves recursively on every
4176          * complex type. However, the state of a va_list that is
4177          * passed to a function is undefined after that function
4178          * returns. This means we need to docode the va_list linearly
4179          * in a single stackframe. We hence implement our own
4180          * home-grown stack in an array. */
4181
4182         n_array = (unsigned) -1; /* lenght of current array entries */
4183         n_struct = strlen(types); /* length of current struct contents signature */
4184
4185         for (;;) {
4186                 const char *t;
4187
4188                 n_loop++;
4189
4190                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
4191                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
4192                         if (r < 0)
4193                                 return r;
4194                         if (r == 0)
4195                                 break;
4196
4197                         r = sd_bus_message_exit_container(m);
4198                         if (r < 0)
4199                                 return r;
4200
4201                         continue;
4202                 }
4203
4204                 t = types;
4205                 if (n_array != (unsigned) -1)
4206                         n_array --;
4207                 else {
4208                         types ++;
4209                         n_struct--;
4210                 }
4211
4212                 switch (*t) {
4213
4214                 case SD_BUS_TYPE_BYTE:
4215                 case SD_BUS_TYPE_BOOLEAN:
4216                 case SD_BUS_TYPE_INT16:
4217                 case SD_BUS_TYPE_UINT16:
4218                 case SD_BUS_TYPE_INT32:
4219                 case SD_BUS_TYPE_UINT32:
4220                 case SD_BUS_TYPE_INT64:
4221                 case SD_BUS_TYPE_UINT64:
4222                 case SD_BUS_TYPE_DOUBLE:
4223                 case SD_BUS_TYPE_STRING:
4224                 case SD_BUS_TYPE_OBJECT_PATH:
4225                 case SD_BUS_TYPE_SIGNATURE:
4226                 case SD_BUS_TYPE_UNIX_FD: {
4227                         void *p;
4228
4229                         p = va_arg(ap, void*);
4230                         r = sd_bus_message_read_basic(m, *t, p);
4231                         if (r < 0)
4232                                 return r;
4233                         if (r == 0) {
4234                                 if (n_loop <= 1)
4235                                         return 0;
4236
4237                                 return -ENXIO;
4238                         }
4239
4240                         break;
4241                 }
4242
4243                 case SD_BUS_TYPE_ARRAY: {
4244                         size_t k;
4245
4246                         r = signature_element_length(t + 1, &k);
4247                         if (r < 0)
4248                                 return r;
4249
4250                         {
4251                                 char s[k + 1];
4252                                 memcpy(s, t + 1, k);
4253                                 s[k] = 0;
4254
4255                                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4256                                 if (r < 0)
4257                                         return r;
4258                                 if (r == 0) {
4259                                         if (n_loop <= 1)
4260                                                 return 0;
4261
4262                                         return -ENXIO;
4263                                 }
4264                         }
4265
4266                         if (n_array == (unsigned) -1) {
4267                                 types += k;
4268                                 n_struct -= k;
4269                         }
4270
4271                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4272                         if (r < 0)
4273                                 return r;
4274
4275                         types = t + 1;
4276                         n_struct = k;
4277                         n_array = va_arg(ap, unsigned);
4278
4279                         break;
4280                 }
4281
4282                 case SD_BUS_TYPE_VARIANT: {
4283                         const char *s;
4284
4285                         s = va_arg(ap, const char *);
4286                         if (!s)
4287                                 return -EINVAL;
4288
4289                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
4290                         if (r < 0)
4291                                 return r;
4292                         if (r == 0) {
4293                                 if (n_loop <= 1)
4294                                         return 0;
4295
4296                                 return -ENXIO;
4297                         }
4298
4299                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4300                         if (r < 0)
4301                                 return r;
4302
4303                         types = s;
4304                         n_struct = strlen(s);
4305                         n_array = (unsigned) -1;
4306
4307                         break;
4308                 }
4309
4310                 case SD_BUS_TYPE_STRUCT_BEGIN:
4311                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4312                         size_t k;
4313
4314                         r = signature_element_length(t, &k);
4315                         if (r < 0)
4316                                 return r;
4317
4318                         {
4319                                 char s[k - 1];
4320                                 memcpy(s, t + 1, k - 2);
4321                                 s[k - 2] = 0;
4322
4323                                 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4324                                 if (r < 0)
4325                                         return r;
4326                                 if (r == 0) {
4327                                         if (n_loop <= 1)
4328                                                 return 0;
4329                                         return -ENXIO;
4330                                 }
4331                         }
4332
4333                         if (n_array == (unsigned) -1) {
4334                                 types += k - 1;
4335                                 n_struct -= k - 1;
4336                         }
4337
4338                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4339                         if (r < 0)
4340                                 return r;
4341
4342                         types = t + 1;
4343                         n_struct = k - 2;
4344                         n_array = (unsigned) -1;
4345
4346                         break;
4347                 }
4348
4349                 default:
4350                         return -EINVAL;
4351                 }
4352         }
4353
4354         return 1;
4355 }
4356
4357 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
4358         va_list ap;
4359         int r;
4360
4361         assert_return(m, -EINVAL);
4362         assert_return(m->sealed, -EPERM);
4363         assert_return(types, -EINVAL);
4364
4365         va_start(ap, types);
4366         r = message_read_ap(m, types, ap);
4367         va_end(ap);
4368
4369         return r;
4370 }
4371
4372 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
4373         int r;
4374
4375         assert_return(m, -EINVAL);
4376         assert_return(m->sealed, -EPERM);
4377         assert_return(types, -EINVAL);
4378
4379         if (isempty(types))
4380                 return 0;
4381
4382         switch (*types) {
4383
4384         case SD_BUS_TYPE_BYTE:
4385         case SD_BUS_TYPE_BOOLEAN:
4386         case SD_BUS_TYPE_INT16:
4387         case SD_BUS_TYPE_UINT16:
4388         case SD_BUS_TYPE_INT32:
4389         case SD_BUS_TYPE_UINT32:
4390         case SD_BUS_TYPE_INT64:
4391         case SD_BUS_TYPE_UINT64:
4392         case SD_BUS_TYPE_DOUBLE:
4393         case SD_BUS_TYPE_STRING:
4394         case SD_BUS_TYPE_OBJECT_PATH:
4395         case SD_BUS_TYPE_SIGNATURE:
4396         case SD_BUS_TYPE_UNIX_FD:
4397
4398                 r = sd_bus_message_read_basic(m, *types, NULL);
4399                 if (r <= 0)
4400                         return r;
4401
4402                 r = sd_bus_message_skip(m, types + 1);
4403                 if (r < 0)
4404                         return r;
4405
4406                 return 1;
4407
4408         case SD_BUS_TYPE_ARRAY: {
4409                 size_t k;
4410
4411                 r = signature_element_length(types + 1, &k);
4412                 if (r < 0)
4413                         return r;
4414
4415                 {
4416                         char s[k+1];
4417                         memcpy(s, types+1, k);
4418                         s[k] = 0;
4419
4420                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4421                         if (r <= 0)
4422                                 return r;
4423
4424                         for (;;) {
4425                                 r = sd_bus_message_skip(m, s);
4426                                 if (r < 0)
4427                                         return r;
4428                                 if (r == 0)
4429                                         break;
4430                         }
4431
4432                         r = sd_bus_message_exit_container(m);
4433                         if (r < 0)
4434                                 return r;
4435                 }
4436
4437                 r = sd_bus_message_skip(m, types + 1 + k);
4438                 if (r < 0)
4439                         return r;
4440
4441                 return 1;
4442         }
4443
4444         case SD_BUS_TYPE_VARIANT: {
4445                 const char *contents;
4446                 char x;
4447
4448                 r = sd_bus_message_peek_type(m, &x, &contents);
4449                 if (r <= 0)
4450                         return r;
4451
4452                 if (x != SD_BUS_TYPE_VARIANT)
4453                         return -ENXIO;
4454
4455                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
4456                 if (r <= 0)
4457                         return r;
4458
4459                 r = sd_bus_message_skip(m, contents);
4460                 if (r < 0)
4461                         return r;
4462                 assert(r != 0);
4463
4464                 r = sd_bus_message_exit_container(m);
4465                 if (r < 0)
4466                         return r;
4467
4468                 r = sd_bus_message_skip(m, types + 1);
4469                 if (r < 0)
4470                         return r;
4471
4472                 return 1;
4473         }
4474
4475         case SD_BUS_TYPE_STRUCT_BEGIN:
4476         case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4477                 size_t k;
4478
4479                 r = signature_element_length(types, &k);
4480                 if (r < 0)
4481                         return r;
4482
4483                 {
4484                         char s[k-1];
4485                         memcpy(s, types+1, k-2);
4486                         s[k-2] = 0;
4487
4488                         r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4489                         if (r <= 0)
4490                                 return r;
4491
4492                         r = sd_bus_message_skip(m, s);
4493                         if (r < 0)
4494                                 return r;
4495                         assert(r != 0);
4496
4497                         r = sd_bus_message_exit_container(m);
4498                         if (r < 0)
4499                                 return r;
4500                 }
4501
4502                 r = sd_bus_message_skip(m, types + k);
4503                 if (r < 0)
4504                         return r;
4505
4506                 return 1;
4507         }
4508
4509         default:
4510                 return -EINVAL;
4511         }
4512 }
4513
4514 _public_ int sd_bus_message_read_array(sd_bus_message *m,
4515                                        char type,
4516                                        const void **ptr,
4517                                        size_t *size) {
4518         struct bus_container *c;
4519         void *p;
4520         size_t sz;
4521         ssize_t align;
4522         int r;
4523
4524         assert_return(m, -EINVAL);
4525         assert_return(m->sealed, -EPERM);
4526         assert_return(bus_type_is_trivial(type), -EINVAL);
4527         assert_return(ptr, -EINVAL);
4528         assert_return(size, -EINVAL);
4529         assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
4530
4531         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
4532         if (r <= 0)
4533                 return r;
4534
4535         c = message_get_container(m);
4536
4537         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4538                 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
4539                 if (align < 0)
4540                         return align;
4541
4542                 sz = c->end - c->begin;
4543         } else {
4544                 align = bus_type_get_alignment(type);
4545                 if (align < 0)
4546                         return align;
4547
4548                 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
4549         }
4550
4551         if (sz == 0)
4552                 /* Zero length array, let's return some aligned
4553                  * pointer that is not NULL */
4554                 p = (uint8_t*) NULL + align;
4555         else {
4556                 r = message_peek_body(m, &m->rindex, align, sz, &p);
4557                 if (r < 0)
4558                         goto fail;
4559         }
4560
4561         r = sd_bus_message_exit_container(m);
4562         if (r < 0)
4563                 goto fail;
4564
4565         *ptr = (const void*) p;
4566         *size = sz;
4567
4568         return 1;
4569
4570 fail:
4571         message_quit_container(m);
4572         return r;
4573 }
4574
4575 static int message_peek_fields(
4576                 sd_bus_message *m,
4577                 size_t *rindex,
4578                 size_t align,
4579                 size_t nbytes,
4580                 void **ret) {
4581
4582         assert(m);
4583         assert(rindex);
4584         assert(align > 0);
4585
4586         return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
4587 }
4588
4589 static int message_peek_field_uint32(
4590                 sd_bus_message *m,
4591                 size_t *ri,
4592                 size_t item_size,
4593                 uint32_t *ret) {
4594
4595         int r;
4596         void *q;
4597
4598         assert(m);
4599         assert(ri);
4600
4601         if (BUS_MESSAGE_IS_GVARIANT(m) && item_size != 4)
4602                 return -EBADMSG;
4603
4604         /* identical for gvariant and dbus1 */
4605
4606         r = message_peek_fields(m, ri, 4, 4, &q);
4607         if (r < 0)
4608                 return r;
4609
4610         if (ret)
4611                 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
4612
4613         return 0;
4614 }
4615
4616 static int message_peek_field_string(
4617                 sd_bus_message *m,
4618                 bool (*validate)(const char *p),
4619                 size_t *ri,
4620                 size_t item_size,
4621                 const char **ret) {
4622
4623         uint32_t l;
4624         int r;
4625         void *q;
4626
4627         assert(m);
4628         assert(ri);
4629
4630         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4631
4632                 if (item_size <= 0)
4633                         return -EBADMSG;
4634
4635                 r = message_peek_fields(m, ri, 1, item_size, &q);
4636                 if (r < 0)
4637                         return r;
4638
4639                 l = item_size - 1;
4640         } else {
4641                 r = message_peek_field_uint32(m, ri, 4, &l);
4642                 if (r < 0)
4643                         return r;
4644
4645                 r = message_peek_fields(m, ri, 1, l+1, &q);
4646                 if (r < 0)
4647                         return r;
4648         }
4649
4650         if (validate) {
4651                 if (!validate_nul(q, l))
4652                         return -EBADMSG;
4653
4654                 if (!validate(q))
4655                         return -EBADMSG;
4656         } else {
4657                 if (!validate_string(q, l))
4658                         return -EBADMSG;
4659         }
4660
4661         if (ret)
4662                 *ret = q;
4663
4664         return 0;
4665 }
4666
4667 static int message_peek_field_signature(
4668                 sd_bus_message *m,
4669                 size_t *ri,
4670                 size_t item_size,
4671                 const char **ret) {
4672
4673         size_t l;
4674         int r;
4675         void *q;
4676
4677         assert(m);
4678         assert(ri);
4679
4680         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4681
4682                 if (item_size <= 0)
4683                         return -EBADMSG;
4684
4685                 r = message_peek_fields(m, ri, 1, item_size, &q);
4686                 if (r < 0)
4687                         return r;
4688
4689                 l = item_size - 1;
4690         } else {
4691                 r = message_peek_fields(m, ri, 1, 1, &q);
4692                 if (r < 0)
4693                         return r;
4694
4695                 l = *(uint8_t*) q;
4696                 r = message_peek_fields(m, ri, 1, l+1, &q);
4697                 if (r < 0)
4698                         return r;
4699         }
4700
4701         if (!validate_signature(q, l))
4702                 return -EBADMSG;
4703
4704         if (ret)
4705                 *ret = q;
4706
4707         return 0;
4708 }
4709
4710 static int message_skip_fields(
4711                 sd_bus_message *m,
4712                 size_t *ri,
4713                 uint32_t array_size,
4714                 const char **signature) {
4715
4716         size_t original_index;
4717         int r;
4718
4719         assert(m);
4720         assert(ri);
4721         assert(signature);
4722         assert(!BUS_MESSAGE_IS_GVARIANT(m));
4723
4724         original_index = *ri;
4725
4726         for (;;) {
4727                 char t;
4728                 size_t l;
4729
4730                 if (array_size != (uint32_t) -1 &&
4731                     array_size <= *ri - original_index)
4732                         return 0;
4733
4734                 t = **signature;
4735                 if (!t)
4736                         return 0;
4737
4738                 if (t == SD_BUS_TYPE_STRING) {
4739
4740                         r = message_peek_field_string(m, NULL, ri, 0, NULL);
4741                         if (r < 0)
4742                                 return r;
4743
4744                         (*signature)++;
4745
4746                 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
4747
4748                         r = message_peek_field_string(m, object_path_is_valid, ri, 0, NULL);
4749                         if (r < 0)
4750                                 return r;
4751
4752                         (*signature)++;
4753
4754                 } else if (t == SD_BUS_TYPE_SIGNATURE) {
4755
4756                         r = message_peek_field_signature(m, ri, 0, NULL);
4757                         if (r < 0)
4758                                 return r;
4759
4760                         (*signature)++;
4761
4762                 } else if (bus_type_is_basic(t)) {
4763                         ssize_t align, k;
4764
4765                         align = bus_type_get_alignment(t);
4766                         k = bus_type_get_size(t);
4767                         assert(align > 0 && k > 0);
4768
4769                         r = message_peek_fields(m, ri, align, k, NULL);
4770                         if (r < 0)
4771                                 return r;
4772
4773                         (*signature)++;
4774
4775                 } else if (t == SD_BUS_TYPE_ARRAY) {
4776
4777                         r = signature_element_length(*signature+1, &l);
4778                         if (r < 0)
4779                                 return r;
4780
4781                         assert(l >= 1);
4782                         {
4783                                 char sig[l-1], *s;
4784                                 uint32_t nas;
4785                                 int alignment;
4786
4787                                 strncpy(sig, *signature + 1, l-1);
4788                                 s = sig;
4789
4790                                 alignment = bus_type_get_alignment(sig[0]);
4791                                 if (alignment < 0)
4792                                         return alignment;
4793
4794                                 r = message_peek_field_uint32(m, ri, 0, &nas);
4795                                 if (r < 0)
4796                                         return r;
4797                                 if (nas > BUS_ARRAY_MAX_SIZE)
4798                                         return -EBADMSG;
4799
4800                                 r = message_peek_fields(m, ri, alignment, 0, NULL);
4801                                 if (r < 0)
4802                                         return r;
4803
4804                                 r = message_skip_fields(m, ri, nas, (const char**) &s);
4805                                 if (r < 0)
4806                                         return r;
4807                         }
4808
4809                         (*signature) += 1 + l;
4810
4811                 } else if (t == SD_BUS_TYPE_VARIANT) {
4812                         const char *s;
4813
4814                         r = message_peek_field_signature(m, ri, 0, &s);
4815                         if (r < 0)
4816                                 return r;
4817
4818                         r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
4819                         if (r < 0)
4820                                 return r;
4821
4822                         (*signature)++;
4823
4824                 } else if (t == SD_BUS_TYPE_STRUCT ||
4825                            t == SD_BUS_TYPE_DICT_ENTRY) {
4826
4827                         r = signature_element_length(*signature, &l);
4828                         if (r < 0)
4829                                 return r;
4830
4831                         assert(l >= 2);
4832                         {
4833                                 char sig[l-1], *s;
4834                                 strncpy(sig, *signature + 1, l-1);
4835                                 s = sig;
4836
4837                                 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
4838                                 if (r < 0)
4839                                         return r;
4840                         }
4841
4842                         *signature += l;
4843                 } else
4844                         return -EINVAL;
4845         }
4846 }
4847
4848 int bus_message_parse_fields(sd_bus_message *m) {
4849         size_t ri;
4850         int r;
4851         uint32_t unix_fds = 0;
4852         void *offsets = NULL;
4853         unsigned n_offsets = 0;
4854         size_t sz = 0;
4855         unsigned i = 0;
4856
4857         assert(m);
4858
4859         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4860                 void *q;
4861
4862                 sz = determine_word_size(BUS_MESSAGE_FIELDS_SIZE(m), 0);
4863                 if (sz > 0) {
4864                         size_t framing;
4865
4866                         ri = BUS_MESSAGE_FIELDS_SIZE(m) - sz;
4867                         r = message_peek_fields(m, &ri, 1, sz, &q);
4868                         if (r < 0)
4869                                 return r;
4870
4871                         framing = read_word_le(q, sz);
4872                         if (framing >= BUS_MESSAGE_FIELDS_SIZE(m) - sz)
4873                                 return -EBADMSG;
4874                         if ((BUS_MESSAGE_FIELDS_SIZE(m) - framing) % sz != 0)
4875                                 return -EBADMSG;
4876
4877                         ri = framing;
4878                         r = message_peek_fields(m, &ri, 1, BUS_MESSAGE_FIELDS_SIZE(m) - framing, &offsets);
4879                         if (r < 0)
4880                                 return r;
4881
4882                         n_offsets = (BUS_MESSAGE_FIELDS_SIZE(m) - framing) / sz;
4883                 }
4884         }
4885
4886         ri = 0;
4887         while (ri < BUS_MESSAGE_FIELDS_SIZE(m)) {
4888                 _cleanup_free_ char *sig = NULL;
4889                 const char *signature;
4890                 uint8_t *header;
4891                 size_t item_size = (size_t) -1;
4892
4893                 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4894                         if (i >= n_offsets)
4895                                 break;
4896
4897                         if (i == 0)
4898                                 ri = 0;
4899                         else
4900                                 ri = ALIGN_TO(read_word_le((uint8_t*) offsets + (i-1)*sz, sz), 8);
4901                 }
4902
4903                 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
4904                 if (r < 0)
4905                         return r;
4906
4907                 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4908                         size_t where, end;
4909                         char *b;
4910                         void *q;
4911
4912                         end = read_word_le((uint8_t*) offsets + i*sz, sz);
4913
4914                         if (end < ri)
4915                                 return -EBADMSG;
4916
4917                         where = ri = ALIGN_TO(ri, 8);
4918                         item_size = end - ri;
4919                         r = message_peek_fields(m, &where, 1, item_size, &q);
4920                         if (r < 0)
4921                                 return r;
4922
4923                         b = memrchr(q, 0, item_size);
4924                         if (!b)
4925                                 return -EBADMSG;
4926
4927                         sig = strndup(b+1, item_size - (b+1-(char*) q));
4928                         if (!sig)
4929                                 return -ENOMEM;
4930
4931                         signature = sig;
4932                         item_size = b - (char*) q;
4933                 } else {
4934                         r = message_peek_field_signature(m, &ri, 0, &signature);
4935                         if (r < 0)
4936                                 return r;
4937                 }
4938
4939                 switch (*header) {
4940                 case _BUS_MESSAGE_HEADER_INVALID:
4941                         return -EBADMSG;
4942
4943                 case BUS_MESSAGE_HEADER_PATH:
4944
4945                         if (m->path)
4946                                 return -EBADMSG;
4947
4948                         if (!streq(signature, "o"))
4949                                 return -EBADMSG;
4950
4951                         r = message_peek_field_string(m, object_path_is_valid, &ri, item_size, &m->path);
4952                         break;
4953
4954                 case BUS_MESSAGE_HEADER_INTERFACE:
4955
4956                         if (m->interface)
4957                                 return -EBADMSG;
4958
4959                         if (!streq(signature, "s"))
4960                                 return -EBADMSG;
4961
4962                         r = message_peek_field_string(m, interface_name_is_valid, &ri, item_size, &m->interface);
4963                         break;
4964
4965                 case BUS_MESSAGE_HEADER_MEMBER:
4966
4967                         if (m->member)
4968                                 return -EBADMSG;
4969
4970                         if (!streq(signature, "s"))
4971                                 return -EBADMSG;
4972
4973                         r = message_peek_field_string(m, member_name_is_valid, &ri, item_size, &m->member);
4974                         break;
4975
4976                 case BUS_MESSAGE_HEADER_ERROR_NAME:
4977
4978                         if (m->error.name)
4979                                 return -EBADMSG;
4980
4981                         if (!streq(signature, "s"))
4982                                 return -EBADMSG;
4983
4984                         r = message_peek_field_string(m, error_name_is_valid, &ri, item_size, &m->error.name);
4985                         if (r >= 0)
4986                                 m->error._need_free = -1;
4987
4988                         break;
4989
4990                 case BUS_MESSAGE_HEADER_DESTINATION:
4991
4992                         if (m->destination)
4993                                 return -EBADMSG;
4994
4995                         if (!streq(signature, "s"))
4996                                 return -EBADMSG;
4997
4998                         r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->destination);
4999                         break;
5000
5001                 case BUS_MESSAGE_HEADER_SENDER:
5002
5003                         if (m->sender)
5004                                 return -EBADMSG;
5005
5006                         if (!streq(signature, "s"))
5007                                 return -EBADMSG;
5008
5009                         r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->sender);
5010
5011                         if (r >= 0 && m->sender[0] == ':' && m->bus && m->bus->bus_client && !m->bus->is_kernel) {
5012                                 m->creds.unique_name = (char*) m->sender;
5013                                 m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & m->bus->creds_mask;
5014                         }
5015
5016                         break;
5017
5018
5019                 case BUS_MESSAGE_HEADER_SIGNATURE: {
5020                         const char *s;
5021                         char *c;
5022
5023                         if (m->root_container.signature)
5024                                 return -EBADMSG;
5025
5026                         if (!streq(signature, "g"))
5027                                 return -EBADMSG;
5028
5029                         r = message_peek_field_signature(m, &ri, item_size, &s);
5030                         if (r < 0)
5031                                 return r;
5032
5033                         c = strdup(s);
5034                         if (!c)
5035                                 return -ENOMEM;
5036
5037                         free(m->root_container.signature);
5038                         m->root_container.signature = c;
5039                         break;
5040                 }
5041
5042                 case BUS_MESSAGE_HEADER_REPLY_SERIAL:
5043                         if (m->reply_serial != 0)
5044                                 return -EBADMSG;
5045
5046                         if (!streq(signature, "u"))
5047                                 return -EBADMSG;
5048
5049                         r = message_peek_field_uint32(m, &ri, item_size, &m->reply_serial);
5050                         if (r < 0)
5051                                 return r;
5052
5053                         if (m->reply_serial == 0)
5054                                 return -EBADMSG;
5055
5056                         break;
5057
5058                 case BUS_MESSAGE_HEADER_UNIX_FDS:
5059                         if (unix_fds != 0)
5060                                 return -EBADMSG;
5061
5062                         if (!streq(signature, "u"))
5063                                 return -EBADMSG;
5064
5065                         r = message_peek_field_uint32(m, &ri, item_size, &unix_fds);
5066                         if (r < 0)
5067                                 return -EBADMSG;
5068
5069                         if (unix_fds == 0)
5070                                 return -EBADMSG;
5071
5072                         break;
5073
5074                 default:
5075                         if (!BUS_MESSAGE_IS_GVARIANT(m))
5076                                 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
5077                 }
5078
5079                 if (r < 0)
5080                         return r;
5081
5082                 i++;
5083         }
5084
5085         if (m->n_fds != unix_fds)
5086                 return -EBADMSG;
5087
5088         switch (m->header->type) {
5089
5090         case SD_BUS_MESSAGE_SIGNAL:
5091                 if (!m->path || !m->interface || !m->member)
5092                         return -EBADMSG;
5093                 break;
5094
5095         case SD_BUS_MESSAGE_METHOD_CALL:
5096
5097                 if (!m->path || !m->member)
5098                         return -EBADMSG;
5099
5100                 break;
5101
5102         case SD_BUS_MESSAGE_METHOD_RETURN:
5103
5104                 if (m->reply_serial == 0)
5105                         return -EBADMSG;
5106                 break;
5107
5108         case SD_BUS_MESSAGE_METHOD_ERROR:
5109
5110                 if (m->reply_serial == 0 || !m->error.name)
5111                         return -EBADMSG;
5112                 break;
5113         }
5114
5115         m->root_container.end = BUS_MESSAGE_BODY_SIZE(m);
5116
5117         if (BUS_MESSAGE_IS_GVARIANT(m)) {
5118                 r = build_struct_offsets(
5119                                 m,
5120                                 m->root_container.signature,
5121                                 BUS_MESSAGE_BODY_SIZE(m),
5122                                 &m->root_container.item_size,
5123                                 &m->root_container.offsets,
5124                                 &m->root_container.n_offsets);
5125                 if (r < 0)
5126                         return r;
5127         }
5128
5129         /* Try to read the error message, but if we can't it's a non-issue */
5130         if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
5131                 sd_bus_message_read(m, "s", &m->error.message);
5132
5133         return 0;
5134 }
5135
5136 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
5137         assert_return(m, -EINVAL);
5138         assert_return(destination, -EINVAL);
5139         assert_return(!m->sealed, -EPERM);
5140         assert_return(!m->destination, -EEXIST);
5141
5142         return message_append_field_string(m, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
5143 }
5144
5145 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
5146         size_t total;
5147         void *p, *e;
5148         unsigned i;
5149         struct bus_body_part *part;
5150
5151         assert(m);
5152         assert(buffer);
5153         assert(sz);
5154
5155         total = BUS_MESSAGE_SIZE(m);
5156
5157         p = malloc(total);
5158         if (!p)
5159                 return -ENOMEM;
5160
5161         e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
5162         MESSAGE_FOREACH_PART(part, i, m)
5163                 e = mempcpy(e, part->data, part->size);
5164
5165         assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
5166
5167         *buffer = p;
5168         *sz = total;
5169
5170         return 0;
5171 }
5172
5173 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
5174         int r;
5175
5176         assert(m);
5177         assert(l);
5178
5179         r = sd_bus_message_enter_container(m, 'a', "s");
5180         if (r <= 0)
5181                 return r;
5182
5183         for (;;) {
5184                 const char *s;
5185
5186                 r = sd_bus_message_read_basic(m, 's', &s);
5187                 if (r < 0)
5188                         return r;
5189                 if (r == 0)
5190                         break;
5191
5192                 r = strv_extend(l, s);
5193                 if (r < 0)
5194                         return r;
5195         }
5196
5197         r = sd_bus_message_exit_container(m);
5198         if (r < 0)
5199                 return r;
5200
5201         return 1;
5202 }
5203
5204 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
5205         char **strv = NULL;
5206         int r;
5207
5208         assert_return(m, -EINVAL);
5209         assert_return(m->sealed, -EPERM);
5210         assert_return(l, -EINVAL);
5211
5212         r = bus_message_read_strv_extend(m, &strv);
5213         if (r <= 0) {
5214                 strv_free(strv);
5215                 return r;
5216         }
5217
5218         *l = strv;
5219         return 1;
5220 }
5221
5222 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
5223         int r;
5224         const char *t = NULL;
5225         unsigned j;
5226
5227         assert(m);
5228
5229         r = sd_bus_message_rewind(m, true);
5230         if (r < 0)
5231                 return NULL;
5232
5233         for (j = 0; j <= i; j++) {
5234                 char type;
5235
5236                 r = sd_bus_message_peek_type(m, &type, NULL);
5237                 if (r < 0)
5238                         return NULL;
5239
5240                 if (type != SD_BUS_TYPE_STRING &&
5241                     type != SD_BUS_TYPE_OBJECT_PATH &&
5242                     type != SD_BUS_TYPE_SIGNATURE)
5243                         return NULL;
5244
5245                 r = sd_bus_message_read_basic(m, type, &t);
5246                 if (r < 0)
5247                         return NULL;
5248         }
5249
5250         return t;
5251 }
5252
5253 bool bus_header_is_complete(struct bus_header *h, size_t size) {
5254         size_t full;
5255
5256         assert(h);
5257         assert(size);
5258
5259         if (size < sizeof(struct bus_header))
5260                 return false;
5261
5262         full = sizeof(struct bus_header) +
5263                 (h->endian == BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
5264
5265         return size >= full;
5266 }
5267
5268 int bus_header_message_size(struct bus_header *h, size_t *sum) {
5269         size_t fs, bs;
5270
5271         assert(h);
5272         assert(sum);
5273
5274         if (h->endian == BUS_NATIVE_ENDIAN) {
5275                 fs = h->fields_size;
5276                 bs = h->body_size;
5277         } else if (h->endian == BUS_REVERSE_ENDIAN) {
5278                 fs = bswap_32(h->fields_size);
5279                 bs = bswap_32(h->body_size);
5280         } else
5281                 return -EBADMSG;
5282
5283         *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
5284         return 0;
5285 }
5286
5287 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
5288         assert_return(m, -EINVAL);
5289
5290         if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
5291                 return 0;
5292
5293         return sd_bus_error_get_errno(&m->error);
5294 }
5295
5296 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
5297         struct bus_container *c;
5298
5299         assert_return(m, NULL);
5300
5301         c = complete ? &m->root_container : message_get_container(m);
5302         return strempty(c->signature);
5303 }
5304
5305 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
5306         bool done_something = false;
5307         int r;
5308
5309         assert_return(m, -EINVAL);
5310         assert_return(source, -EINVAL);
5311         assert_return(!m->sealed, -EPERM);
5312         assert_return(source->sealed, -EPERM);
5313
5314         do {
5315                 const char *contents;
5316                 char type;
5317                 union {
5318                         uint8_t u8;
5319                         uint16_t u16;
5320                         int16_t s16;
5321                         uint32_t u32;
5322                         int32_t s32;
5323                         uint64_t u64;
5324                         int64_t s64;
5325                         double d64;
5326                         const char *string;
5327                         int i;
5328                 } basic;
5329
5330                 r = sd_bus_message_peek_type(source, &type, &contents);
5331                 if (r < 0)
5332                         return r;
5333                 if (r == 0)
5334                         break;
5335
5336                 done_something = true;
5337
5338                 if (bus_type_is_container(type) > 0) {
5339
5340                         r = sd_bus_message_enter_container(source, type, contents);
5341                         if (r < 0)
5342                                 return r;
5343
5344                         r = sd_bus_message_open_container(m, type, contents);
5345                         if (r < 0)
5346                                 return r;
5347
5348                         r = sd_bus_message_copy(m, source, true);
5349                         if (r < 0)
5350                                 return r;
5351
5352                         r = sd_bus_message_close_container(m);
5353                         if (r < 0)
5354                                 return r;
5355
5356                         r = sd_bus_message_exit_container(source);
5357                         if (r < 0)
5358                                 return r;
5359
5360                         continue;
5361                 }
5362
5363                 r = sd_bus_message_read_basic(source, type, &basic);
5364                 if (r < 0)
5365                         return r;
5366
5367                 assert(r > 0);
5368
5369                 if (type == SD_BUS_TYPE_OBJECT_PATH ||
5370                     type == SD_BUS_TYPE_SIGNATURE ||
5371                     type == SD_BUS_TYPE_STRING)
5372                         r = sd_bus_message_append_basic(m, type, basic.string);
5373                 else
5374                         r = sd_bus_message_append_basic(m, type, &basic);
5375
5376                 if (r < 0)
5377                         return r;
5378
5379         } while (all);
5380
5381         return done_something;
5382 }
5383
5384 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
5385         const char *c;
5386         char t;
5387         int r;
5388
5389         assert_return(m, -EINVAL);
5390         assert_return(m->sealed, -EPERM);
5391         assert_return(!type || bus_type_is_valid(type), -EINVAL);
5392         assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
5393         assert_return(type || contents, -EINVAL);
5394         assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
5395
5396         r = sd_bus_message_peek_type(m, &t, &c);
5397         if (r <= 0)
5398                 return r;
5399
5400         if (type != 0 && type != t)
5401                 return 0;
5402
5403         if (contents && !streq_ptr(contents, c))
5404                 return 0;
5405
5406         return 1;
5407 }
5408
5409 _public_ sd_bus *sd_bus_message_get_bus(sd_bus_message *m) {
5410         assert_return(m, NULL);
5411
5412         return m->bus;
5413 }