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