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