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